From 09722e4be657d550567f8e62c5a2d9a99f72bf72 Mon Sep 17 00:00:00 2001 From: Christopher Hiller Date: Tue, 6 Jan 2026 14:36:38 -0800 Subject: [PATCH 1/2] chore: add @function tags to all arrow functions --- ...require-function-tag-in-arrow-functions.js | 389 ++++++++++++++++++ cspell.json | 5 +- eslint.config.js | 25 +- src/bargs.ts | 41 ++ src/help.ts | 20 + src/opt.ts | 38 ++ src/osc.ts | 12 + src/parser.ts | 10 + src/theme.ts | 6 + src/validate.ts | 17 + src/version.ts | 16 + test/bargs.test.ts | 6 + 12 files changed, 579 insertions(+), 6 deletions(-) create mode 100644 .config/require-function-tag-in-arrow-functions.js diff --git a/.config/require-function-tag-in-arrow-functions.js b/.config/require-function-tag-in-arrow-functions.js new file mode 100644 index 0000000..3794a3c --- /dev/null +++ b/.config/require-function-tag-in-arrow-functions.js @@ -0,0 +1,389 @@ +/** + * ESLint rule to require `@function` tag in JSDoc comments for arrow functions + * + * @packageDocumentation + */ + +import { + AST_NODE_TYPES, + AST_TOKEN_TYPES, + ESLintUtils, +} from '@typescript-eslint/utils'; + +/** + * @import {TSESTree} from "@typescript-eslint/typescript-estree" + */ +/** + * ESLint rule to require `@function` tag in JSDoc comments for arrow functions + * + * This rule enforces the presence of `@function` tags in JSDoc comments for + * arrow functions to improve code documentation and maintain consistency with + * the project's documentation standards. + * + * The rule supports: + * + * - Named arrow functions (`const foo = () => {}`) + * - Arrow functions in object properties (`{ method: () => {} }`) + * - Arrow functions in assignments (`obj.method = () => {}`) + * - Export declarations (`export const foo = () => {}`) + * + * Configuration options: + * + * - `requireForNamed`: Whether to require `@function` tags for named arrow + * functions (default: `true`) + * - `requireForAnonymous`: Whether to require `@function` tags for anonymous + * arrow functions (default: `false`) + */ +export default ESLintUtils.RuleCreator.withoutDocs({ + create(context, [options]) { + const sourceCode = context.sourceCode; + + /** + * Determines if an arrow function should require a @function tag based on + * its context. + * + * This function identifies "named" arrow functions, which are arrow + * functions that are assigned to a variable, property, or exported. These + * are distinguished from anonymous arrow functions used in callbacks or + * inline expressions. + * + * Supported patterns: + * + * - Variable declarations: `const foo = () => {}` + * - Object properties: `{ method: () => {} }` + * - Property assignments: `obj.method = () => {}` + * - Export declarations: `export const foo = () => {}` + * + * @example + * + * ```ts + * // Returns true for these patterns: + * const myFunc = () => {}; // Variable declaration + * obj.method = () => {}; // Property assignment + * const obj = { method: () => {} }; // Object property + * export const func = () => {}; // Export declaration + * + * // Returns false for these patterns: + * [1, 2, 3].map(() => {}); // Anonymous callback + * setTimeout(() => {}, 100); // Anonymous callback + * ``` + * + * @function + * @param {TSESTree.ArrowFunctionExpression} node - The arrow function AST + * node to check + * @returns {boolean} True if this arrow function should be considered + * "named" and potentially require a @function tag based on its syntactic + * context + */ + const shouldRequireTag = + /** + * @function + */ + (node) => { + const parent = node.parent; + + if ( + parent?.type === AST_NODE_TYPES.VariableDeclarator && + parent.id?.type === AST_NODE_TYPES.Identifier + ) { + return true; + } + + if ( + parent?.type === AST_NODE_TYPES.AssignmentExpression && + parent.left?.type === AST_NODE_TYPES.MemberExpression + ) { + return true; + } + + if (parent?.type === AST_NODE_TYPES.Property && parent.key) { + return true; + } + + if ( + parent?.type === AST_NODE_TYPES.VariableDeclarator && + parent.parent?.parent?.type === AST_NODE_TYPES.ExportNamedDeclaration + ) { + return true; + } + + return false; + }; + + /** + * Determines whether a specific arrow function should be flagged by this + * rule based on the configured options and the function's naming context. + * + * This function combines the result of `shouldRequireTag()` (which + * determines if an arrow function is "named") with the user's configuration + * options to decide if the rule should be applied to this specific arrow + * function. + * + * @example + * + * ```ts + * // With options: { requireForNamed: true, requireForAnonymous: false } + * + * const namedFunc = () => {}; // Returns true (named + requireForNamed) + * [1, 2].map(() => {}); // Returns false (anonymous + !requireForAnonymous) + * + * // With options: { requireForNamed: false, requireForAnonymous: true } + * + * const namedFunc = () => {}; // Returns false (named + !requireForNamed) + * [1, 2].map(() => {}); // Returns true (anonymous + requireForAnonymous) + * ``` + * + * @function + * @param {TSESTree.ArrowFunctionExpression} node - The arrow function AST + * node to evaluate + * @returns {boolean} True if this arrow function should be flagged for + * missing `@function` tag, false if it should be ignored by this rule + */ + const isNamedArrowFunction = + /** + * @function + */ + (node) => { + const isNamed = shouldRequireTag(node); + + if (isNamed && options.requireForNamed) { + return true; + } + + if (!isNamed && options.requireForAnonymous) { + return true; + } + + return false; + }; + + /** + * Finds the JSDoc comment associated with an arrow function, if any exists. + * + * This function is crucial for the rule's functionality because arrow + * functions don't have JSDoc comments directly attached to them. Instead, + * the JSDoc comment is typically attached to the parent node (variable + * declaration, object property, etc.). + * + * The function looks for JSDoc comments in the appropriate location based + * on the arrow function's syntactic context: + * + * - For variable declarations: Looks before the entire variable declaration + * - For object properties: Looks before the property definition + * - For assignments: Looks before the assignment expression + * - For other cases: Falls back to looking before the arrow function itself + * + * @example + * + * ```ts + * // These patterns will find the JSDoc comment: + * + * // Pattern 1: Variable declaration + * // JSDoc here + * // const func = () => {}; // Finds comment before variable declaration + * + * // Pattern 2: Object property + * // const obj = { + * // // JSDoc here + * // method: () => {} // Finds comment before property + * // }; + * + * // Pattern 3: Assignment expression + * // // JSDoc here + * // obj.method = () => {}; // Finds comment before assignment + * ``` + * + * @function + * @param {TSESTree.ArrowFunctionExpression} node - The arrow function AST + * node + * @returns {TSESTree.Comment | undefined} The JSDoc comment node if found, + * undefined otherwise + */ + const getJSDocComment = + /** + * @function + */ + (node) => { + // For named arrow functions (variable declarations), look for JSDoc on the variable declarator + const parent = node.parent; + /** @type {TSESTree.Node} */ + let targetNode = node; + + switch (parent?.type) { + case AST_NODE_TYPES.AssignmentExpression: { + // For assignments like obj.foo = () => {}, look before the assignment + targetNode = parent; + break; + } + case AST_NODE_TYPES.Property: { + // For object properties, look before the property + targetNode = parent; + break; + } + case AST_NODE_TYPES.VariableDeclarator: { + // Look for comments before the variable declaration + const variableDeclaration = parent.parent; + if ( + variableDeclaration?.type === AST_NODE_TYPES.VariableDeclaration + ) { + // Check if the variable declaration is exported + if ( + variableDeclaration.parent?.type === + AST_NODE_TYPES.ExportNamedDeclaration + ) { + targetNode = variableDeclaration.parent; + } else { + targetNode = variableDeclaration; + } + } + break; + } + } + + const comments = sourceCode.getCommentsBefore(targetNode); + const comment = comments.findLast( + (comment) => + comment.type === AST_TOKEN_TYPES.Block && + comment.value.startsWith('*'), + ); + + // If we didn't find a comment and we're dealing with an exported variable, + // also try looking before the variable declarator itself + if (!comment && parent?.type === AST_NODE_TYPES.VariableDeclarator) { + const declaratorComments = sourceCode.getCommentsBefore(parent); + return declaratorComments.findLast( + (comment) => + comment.type === AST_TOKEN_TYPES.Block && + comment.value.startsWith('*'), + ); + } + + return comment; + }; + return { + ArrowFunctionExpression(node) { + if (!isNamedArrowFunction(node)) { + return; + } + + const comment = getJSDocComment(node); + + if (!comment) { + context.report({ + fix(fixer) { + // Insert JSDoc before the appropriate node (variable declaration, assignment, etc.) + const parent = node.parent; + /** @type {TSESTree.Node} */ + let insertTarget = node; + + switch (parent?.type) { + case AST_NODE_TYPES.AssignmentExpression: { + insertTarget = parent; + break; + } + case AST_NODE_TYPES.Property: { + insertTarget = parent; + break; + } + case AST_NODE_TYPES.VariableDeclarator: { + const variableDeclaration = parent.parent; + if ( + variableDeclaration?.type === + AST_NODE_TYPES.VariableDeclaration + ) { + // Check if the variable declaration is exported + if ( + variableDeclaration.parent?.type === + AST_NODE_TYPES.ExportNamedDeclaration + ) { + insertTarget = variableDeclaration.parent; + } else { + insertTarget = variableDeclaration; + } + } + break; + } + } + + return fixer.insertTextBefore( + insertTarget, + '/**\n * @function\n */\n', + ); + }, + messageId: 'missingJSDoc', + node, + }); + return; + } + + if (!/^\s*\*\s*@function\s*$/m.test(comment.value)) { + context.report({ + fix(fixer) { + // Add @function tag to existing JSDoc + const value = comment.value; + + // For JSDoc comments, insert @function before the last line + // The comment.value doesn't include /* and */, so we need to add them back + const lines = value.split('\n'); + + // Find where to insert @function (before the closing line) + // Look for the last line that contains content (not just whitespace) + let insertIndex = lines.length; + for (let i = lines.length - 1; i >= 0; i--) { + const line = lines[i]?.trim(); + if (line && !line.match(/^\s*$/)) { + insertIndex = i + 1; + break; + } + } + + // Insert @function at the appropriate position + const beforeLines = lines.slice(0, insertIndex); + const afterLines = lines.slice(insertIndex); + + const newLines = [...beforeLines, ' * @function', ...afterLines]; + + const updatedValue = newLines.join('\n'); + return fixer.replaceText(comment, `/*${updatedValue}*/`); + }, + messageId: 'missingFunctionTag', + node, + }); + } + }, + }; + }, + defaultOptions: [ + { + requireForAnonymous: false, + requireForNamed: true, + }, + ], + meta: { + docs: { + description: + 'Require @function tag in JSDoc comments for arrow functions', + }, + fixable: 'code', + messages: { + missingFunctionTag: 'JSDoc comment should include @function tag', + missingJSDoc: + 'Arrow function should have JSDoc comment with @function tag', + }, + schema: [ + { + additionalProperties: false, + properties: { + requireForAnonymous: { + type: 'boolean', + }, + requireForNamed: { + type: 'boolean', + }, + }, + type: 'object', + }, + ], + type: 'suggestion', + }, +}); diff --git a/cspell.json b/cspell.json index b94ecd1..88ce513 100644 --- a/cspell.json +++ b/cspell.json @@ -59,11 +59,12 @@ "nargs", "vitesse", "realfavicongenerator", - "frickin" + "frickin", + "TSES", + "ghostty" ], "words": [ "bupkis", - "ghostty", "linkified", "linkifies", "linkify", diff --git a/eslint.config.js b/eslint.config.js index ae6d9fa..7e0970d 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -6,6 +6,8 @@ import { defineConfig } from 'eslint/config'; import globals from 'globals'; import tseslint from 'typescript-eslint'; +import requireFunctionTagInArrowFunctions from './.config/require-function-tag-in-arrow-functions.js'; + export default defineConfig( jsPlugin.configs.recommended, ...tseslint.configs.recommendedTypeChecked, @@ -24,7 +26,15 @@ export default defineConfig( plugins: { '@perfectionist': perfectionist, '@stylistic': stylistic, + custom: { + rules: { + 'require-function-tag-in-arrow-functions': /** @type {any} */ ( + requireFunctionTagInArrowFunctions + ), + }, + }, }, + rules: { '@perfectionist/sort-classes': ['error', { partitionByNewLine: true }], '@stylistic/lines-around-comment': [ @@ -41,7 +51,6 @@ export default defineConfig( ], '@stylistic/lines-between-class-members': ['error', 'always'], '@stylistic/semi': 'error', - '@typescript-eslint/consistent-type-exports': [ 'error', { fixMixedExportsWithInlineTypeSpecifier: true }, @@ -57,9 +66,9 @@ export default defineConfig( ], '@typescript-eslint/no-explicit-any': 'off', + '@typescript-eslint/no-invalid-void-type': 'off', '@typescript-eslint/no-non-null-assertion': 'off', - '@typescript-eslint/no-unnecessary-boolean-literal-compare': [ 'error', { @@ -69,8 +78,8 @@ export default defineConfig( ], '@typescript-eslint/no-unnecessary-condition': 'off', - '@typescript-eslint/no-unsafe-assignment': 'warn', + '@typescript-eslint/no-unsafe-assignment': 'warn', '@typescript-eslint/no-unused-vars': [ 'error', { @@ -83,8 +92,8 @@ export default defineConfig( ], '@typescript-eslint/require-await': 'off', - '@typescript-eslint/restrict-template-expressions': 'off', + '@typescript-eslint/restrict-template-expressions': 'off', '@typescript-eslint/unified-signatures': [ 'error', { @@ -93,6 +102,14 @@ export default defineConfig( ], curly: 'error', + + 'custom/require-function-tag-in-arrow-functions': [ + 'error', + { + requireForAnonymous: false, + requireForNamed: true, + }, + ], 'func-style': ['error', 'expression'], 'new-cap': ['error', { capIsNew: true, newIsCap: true }], 'no-constructor-return': 'error', diff --git a/src/bargs.ts b/src/bargs.ts index a01179b..c793d1b 100644 --- a/src/bargs.ts +++ b/src/bargs.ts @@ -157,6 +157,9 @@ export function map< maybeFn?: TransformFn, ): ((parser: Parser) => Parser) | Parser { // Helper to compose transforms (chains existing + new) + /** + * @function + */ const composeTransform = ( parser: Parser, fn: TransformFn, @@ -344,6 +347,8 @@ export function merge( /** * Convert kebab-case string to camelCase. + * + * @function */ const kebabToCamel = (s: string): string => s.replace(/-([a-zA-Z])/g, (_, c: string) => c.toUpperCase()); @@ -366,6 +371,8 @@ const kebabToCamel = (s: string): string => * * console.log(values.outputDir); // camelCased! * ``` + * + * @function */ export const camelCaseValues = ( result: ParseResult, @@ -404,6 +411,8 @@ export const camelCaseValues = ( * ) * .parseAsync(); * ``` + * + * @function */ const create = ( name: string, @@ -421,6 +430,8 @@ const create = ( /** * Check if something is a Command (has __brand: 'Command'). + * + * @function */ const isCommand = (x: unknown): x is Command => { if (x === null || x === undefined) { @@ -443,6 +454,8 @@ type InternalCliBuilder = CliBuilder & { /** * Create a CLI builder. + * + * @function */ const createCliBuilder = ( state: InternalCliState, @@ -614,6 +627,8 @@ const createCliBuilder = ( /** * Core parse logic shared between parse() and parseAsync(). + * + * @function */ const parseCore = ( state: InternalCliState, @@ -661,6 +676,8 @@ const parseCore = ( /** * Generate command-specific help. + * + * @function */ const generateCommandHelpNew = ( state: InternalCliState, @@ -698,6 +715,8 @@ const generateCommandHelpNew = ( /** * Generate help for the new CLI structure. + * + * @function */ const generateHelpNew = (state: InternalCliState, theme: Theme): string => { // TODO: Implement proper help generation for new structure @@ -720,6 +739,8 @@ const generateHelpNew = (state: InternalCliState, theme: Theme): string => { /** * Check if something is a Parser (has __brand: 'Parser'). Parsers can be either * objects or functions (CallableParser). + * + * @function */ const isParser = (x: unknown): x is Parser => { if (x === null || x === undefined) { @@ -733,6 +754,8 @@ const isParser = (x: unknown): x is Parser => { /** * Check if something is a CliBuilder (has command, globals, parse, parseAsync * methods). + * + * @function */ const isCliBuilder = ( x: unknown, @@ -751,6 +774,8 @@ const isCliBuilder = ( /** * Run a simple CLI (no commands). + * + * @function */ const runSimple = ( state: InternalCliState, @@ -817,6 +842,8 @@ const runSimple = ( /** * Delegate parsing to a nested CliBuilder, passing down parent globals. + * + * @function */ const delegateToNestedBuilder = ( builder: CliBuilder, @@ -850,6 +877,8 @@ const delegateToNestedBuilder = ( /** * Run a CLI with commands. + * + * @function */ const runWithCommands = ( state: InternalCliState, @@ -978,6 +1007,9 @@ const runWithCommands = ( }; // Helper to check for async and throw if not allowed + /** + * @function + */ const checkAsync = (value: unknown, context: string): void => { if (value instanceof Promise && !allowAsync) { throw new BargsError( @@ -1008,6 +1040,9 @@ const runWithCommands = ( )?.__transform; // Apply transforms and run handler + /** + * @function + */ const applyTransformsAndHandle = (): | (ParseResult & { command?: string }) | Promise< @@ -1030,6 +1065,9 @@ const runWithCommands = ( return continueWithCommandTransform(); }; + /** + * @function + */ const continueWithCommandTransform = (): | (ParseResult & { command?: string }) | Promise< @@ -1052,6 +1090,9 @@ const runWithCommands = ( return runHandler(); }; + /** + * @function + */ const runHandler = (): | (ParseResult & { command?: string }) | Promise< diff --git a/src/help.ts b/src/help.ts index 4b05590..e38179d 100644 --- a/src/help.ts +++ b/src/help.ts @@ -54,6 +54,8 @@ const URL_PATTERN = /https?:\/\/[^\s<>"\])}]+/g; /** * Linkify URLs in text if terminal supports hyperlinks. Applies URL styling. + * + * @function */ const linkifyText = ( text: string, @@ -70,6 +72,8 @@ const linkifyText = ( /** * Generate default epilog from package.json (homepage and repository). + * + * @function */ const generateDefaultEpilog = (styler: Styler): string[] => { const pkgInfo = readPackageInfoSync(); @@ -97,6 +101,8 @@ const generateDefaultEpilog = (styler: Styler): string[] => { /** * Format epilog based on config. Returns empty array if epilog is disabled, * custom epilog lines if provided, or default epilog from package.json. + * + * @function */ const formatEpilog = ( config: { epilog?: false | string }, @@ -120,6 +126,8 @@ const formatEpilog = ( /** * Format a single positional for help usage line. Required positionals use * , optional use [name]. Variadic positionals append "...". + * + * @function */ const formatPositionalUsage = (def: PositionalDef, index: number): string => { const name = def.name ?? `arg${index}`; @@ -132,6 +140,8 @@ const formatPositionalUsage = (def: PositionalDef, index: number): string => { /** * Build the positionals usage string from a schema. + * + * @function */ const buildPositionalsUsage = (schema?: PositionalsSchema): string => { if (!schema || schema.length === 0) { @@ -145,6 +155,8 @@ const buildPositionalsUsage = (schema?: PositionalsSchema): string => { /** * Get type label for help display. + * + * @function */ const getTypeLabel = (def: OptionDef): string => { switch (def.type) { @@ -175,6 +187,8 @@ const getTypeLabel = (def: OptionDef): string => { * * For boolean options with `default: true`, shows `--no-` instead of * `--` since that's how users would turn it off. + * + * @function */ const formatOptionHelp = ( name: string, @@ -222,6 +236,8 @@ const formatOptionHelp = ( /** * Check if config has commands. + * + * @function */ const hasCommands = ( config: HelpConfig, @@ -231,6 +247,8 @@ const hasCommands = ( /** * Generate help text for a bargs config. + * + * @function */ export const generateHelp = ( config: HelpConfig, @@ -362,6 +380,8 @@ export const generateHelp = ( /** * Generate help text for a specific command. + * + * @function */ export const generateCommandHelp = ( config: HelpConfig, diff --git a/src/opt.ts b/src/opt.ts index 69c990d..bfd6e32 100644 --- a/src/opt.ts +++ b/src/opt.ts @@ -33,6 +33,8 @@ import { BargsError } from './errors.js'; /** * Validate that no alias conflicts exist in a merged options schema. + * + * @function */ const validateAliasConflicts = (schema: OptionsSchema): void => { const aliasToOption = new Map(); @@ -77,6 +79,8 @@ export type CallableOptionsParser = (( * 1. Standalone: `opt.options({ ... })` - returns a Parser * 2. Merging: `pos.positionals(...)(opt.options(...))` - merges positionals into * options + * + * @function */ const optionsImpl = ( schema: T, @@ -84,6 +88,9 @@ const optionsImpl = ( validateAliasConflicts(schema); // Create the merge function + /** + * @function + */ const merger = ( parser: Parser, ): Parser & V2, P2> => { @@ -185,6 +192,8 @@ export const opt = { /** * Define a boolean option. + * + * @function */ boolean: < P extends Omit = Omit, @@ -198,6 +207,8 @@ export const opt = { /** * Define a count option (--verbose --verbose = 2). + * + * @function */ count: (props: Omit = {}): CountOption => ({ type: 'count', @@ -206,6 +217,8 @@ export const opt = { /** * Define an enum option with string choices. + * + * @function */ enum: < const T extends readonly string[], @@ -225,6 +238,8 @@ export const opt = { /** * Define an enum positional argument with string choices. + * + * @function */ enumPos: < const T extends readonly string[], @@ -244,6 +259,8 @@ export const opt = { /** * Define a number option. + * + * @function */ number:

= Omit>( props: P = {} as P, @@ -255,6 +272,8 @@ export const opt = { /** * Define a number positional argument. + * + * @function */ numberPos: < P extends Omit = Omit, @@ -283,6 +302,8 @@ export const opt = { /** * Define a string option. + * + * @function */ string:

= Omit>( props: P = {} as P, @@ -294,6 +315,8 @@ export const opt = { /** * Define a string positional argument. + * + * @function */ stringPos: < P extends Omit = Omit, @@ -307,6 +330,8 @@ export const opt = { /** * Define a variadic positional (rest args). + * + * @function */ variadic: ( items: 'number' | 'string', @@ -346,11 +371,16 @@ export type CallablePositionalsParser

= (< * 1. Standalone: `pos.positionals(...)` - returns a Parser * 2. Merging: `pos.positionals(...)(opt.options(...))` - merges positionals into * options + * + * @function */ const positionalsImpl = ( ...positionals: T ): CallablePositionalsParser> => { // Create the merge function - just passes through V2, no intersection needed + /** + * @function + */ const merger = ( parser: Parser, ): Parser]> => { @@ -402,6 +432,8 @@ const positionalsImpl = ( export const pos = { /** * Define an enum positional argument with string choices. + * + * @function */ enum: < const T extends readonly string[], @@ -421,6 +453,8 @@ export const pos = { /** * Define a number positional argument. + * + * @function */ number: < P extends Omit = Omit, @@ -476,6 +510,8 @@ export const pos = { /** * Define a string positional argument. + * + * @function */ string: < P extends Omit = Omit, @@ -489,6 +525,8 @@ export const pos = { /** * Define a variadic positional (rest args). + * + * @function */ variadic: ( items: 'number' | 'string', diff --git a/src/osc.ts b/src/osc.ts index 204bf04..4eb3e61 100644 --- a/src/osc.ts +++ b/src/osc.ts @@ -32,6 +32,8 @@ const SEP = ';'; /** * Check if running inside tmux. + * + * @function */ const isTmux = (): boolean => 'TMUX' in process.env; @@ -39,6 +41,8 @@ const isTmux = (): boolean => 'TMUX' in process.env; * Wrap an OSC sequence for tmux compatibility. Tmux requires OSC sequences to * be wrapped with DCS tmux; ST and all ESCs in to be * replaced with ESC ESC. + * + * @function */ const wrapOsc = (sequence: string): string => { if (isTmux()) { @@ -50,6 +54,8 @@ const wrapOsc = (sequence: string): string => { /** * Parse a version string into major/minor/patch components. Handles both dotted * versions (1.72.0) and compact versions (4601 -> 46.1.0). + * + * @function */ const parseVersion = ( versionString = '', @@ -77,6 +83,8 @@ const parseVersion = ( /** * Detect if the terminal supports hyperlinks (OSC 8). Based on the logic from * supports-hyperlinks package but implemented inline without dependencies. + * + * @function */ export const supportsHyperlinks = ( stream: NodeJS.WriteStream = process.stdout, @@ -199,6 +207,8 @@ export const supportsHyperlinks = ( /** * Create an OSC 8 hyperlink. The link text is displayed, and clicking it opens * the URL in supported terminals. + * + * @function */ export const link = (text: string, url: string): string => { const openLink = wrapOsc(`${OSC}8${SEP}${SEP}${url}${BEL}`); @@ -215,6 +225,8 @@ const URL_PATTERN = /https?:\/\/[^\s<>"\])}]+/g; /** * Auto-linkify URLs in text. If terminal supports hyperlinks, URLs become * clickable. Otherwise, text is returned unchanged. + * + * @function */ export const linkifyUrls = ( text: string, diff --git a/src/parser.ts b/src/parser.ts index 6cae3cc..be933a4 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -27,6 +27,8 @@ import { HelpError } from './errors.js'; * * For boolean options, also adds `no-` variants to support explicit * negation (e.g., `--no-verbose` sets `verbose` to `false`). + * + * @function */ const buildParseArgsConfig = ( schema: OptionsSchema, @@ -72,6 +74,8 @@ const buildParseArgsConfig = ( /** * Coerce parsed values to their expected types. + * + * @function */ const coerceValues = ( values: Record, @@ -144,6 +148,8 @@ const coerceValues = ( /** * Coerce positional values. + * + * @function */ const coercePositionals = ( positionals: string[], @@ -199,6 +205,8 @@ const coercePositionals = ( * - If `--no-` is true and `--` is not set, sets `` to false * - If both `--` and `--no-` are set, throws an error * - Removes all `no-` keys from the result + * + * @function */ const processNegatedBooleans = ( values: Record, @@ -246,6 +254,8 @@ interface ParseSimpleOptions< /** * Parse arguments for a simple CLI (no commands). + * + * @function */ export const parseSimple = < TOptions extends OptionsSchema = OptionsSchema, diff --git a/src/theme.ts b/src/theme.ts index a7bf0ad..7e13857 100644 --- a/src/theme.ts +++ b/src/theme.ts @@ -212,6 +212,8 @@ export const defaultTheme = themes.default; /** * Resolve a theme input to a fully resolved Theme with all colors defined. * Missing colors fall back to the default theme. + * + * @function */ export const getTheme = (input: ThemeInput): ResolvedTheme => { if (typeof input === 'string') { @@ -255,6 +257,8 @@ const RESET = '\x1b[0m'; /** * Create a style function from a color code. Returns passthrough if color is * empty. + * + * @function */ const makeStyleFn = (color: string): StyleFn => { if (!color) { @@ -266,6 +270,8 @@ const makeStyleFn = (color: string): StyleFn => { /** * Create a Styler from a Theme. If the theme has missing colors, they fall back * to the default theme. + * + * @function */ export const createStyler = (theme: Theme): Styler => { const resolved = getTheme(theme as ThemeInput); diff --git a/src/validate.ts b/src/validate.ts index 70d8d48..684926f 100644 --- a/src/validate.ts +++ b/src/validate.ts @@ -34,12 +34,21 @@ const VALID_ITEM_TYPES = ['string', 'number'] as const; // ─── Primitive Helpers ────────────────────────────────────────────────────── +/** + * @function + */ const isObject = (value: unknown): value is Record => value !== null && typeof value === 'object' && !Array.isArray(value); +/** + * @function + */ const isStringArray = (value: unknown): value is string[] => Array.isArray(value) && value.every((v) => typeof v === 'string'); +/** + * @function + */ const isNumberArray = (value: unknown): value is number[] => Array.isArray(value) && value.every((v) => typeof v === 'number'); @@ -47,6 +56,8 @@ const isNumberArray = (value: unknown): value is number[] => /** * Validate a single option definition. + * + * @function */ const validateOption = ( name: string, @@ -245,6 +256,8 @@ const validateOption = ( /** * Validate an options schema. + * + * @function */ export const validateOptionsSchema = ( schema: unknown, @@ -268,6 +281,8 @@ export const validateOptionsSchema = ( /** * Validate a single positional definition. + * + * @function */ const validatePositional = ( index: number, @@ -374,6 +389,8 @@ const validatePositional = ( /** * Validate a positionals schema. + * + * @function */ export const validatePositionalsSchema = ( schema: unknown, diff --git a/src/version.ts b/src/version.ts index 874cb5b..60e2746 100644 --- a/src/version.ts +++ b/src/version.ts @@ -41,6 +41,8 @@ interface RepositoryField { /** * Normalize a repository URL to clean HTTPS format. Strips leading `git+` and * trailing `.git`. + * + * @function */ const normalizeRepoUrl = (url: string): string => { return url.replace(/^git\+/, '').replace(/\.git$/, ''); @@ -48,6 +50,8 @@ const normalizeRepoUrl = (url: string): string => { /** * Validate that a URL is HTTPS. Returns the URL if valid, undefined otherwise. + * + * @function */ const validateHttpsUrl = (url: string | undefined): string | undefined => { if (!url) { @@ -59,6 +63,8 @@ const validateHttpsUrl = (url: string | undefined): string | undefined => { /** * Extract repository URL from package.json repository field. Handles both * string and object forms. + * + * @function */ const extractRepoUrl = ( repository: RepositoryField | string | undefined, @@ -78,6 +84,8 @@ const extractRepoUrl = ( /** * Find package.json by walking up from startDir (async). + * + * @function */ const findPackageJson = async ( startDir: string, @@ -101,6 +109,8 @@ const findPackageJson = async ( /** * Find package.json by walking up from startDir (sync). + * + * @function */ const findPackageJsonSync = (startDir: string): string | undefined => { let dir = startDir; @@ -122,6 +132,8 @@ const findPackageJsonSync = (startDir: string): string | undefined => { /** * Read version from package.json (async). + * + * @function */ const readVersionFromPackageJson = async ( pkgPath: string, @@ -137,6 +149,8 @@ const readVersionFromPackageJson = async ( /** * Detect version: use provided version or read from nearest package.json. + * + * @function */ export const detectVersion = async ( providedVersion: string | undefined, @@ -157,6 +171,8 @@ export const detectVersion = async ( /** * Read package info (homepage, repository) from package.json synchronously. * Returns only HTTPS URLs; other URL schemes are omitted. + * + * @function */ export const readPackageInfoSync = ( startDir: string = process.cwd(), diff --git a/test/bargs.test.ts b/test/bargs.test.ts index f3ddd83..6a49d89 100644 --- a/test/bargs.test.ts +++ b/test/bargs.test.ts @@ -248,11 +248,17 @@ describe('transforms via map()', () => { // Note: For async transforms, we work around the type system limitations // by defining the transform separately with explicit typing + /** + * @function + */ const asyncTransform = ( parser: ReturnType< typeof opt.options<{ name: StringOption & { default: string } }> >, ) => { + /** + * @function + */ const transform = async (result: { positionals: readonly []; values: { name: string }; From 73344d0543c05b2c7fd7a1f06a69b00539ce1d56 Mon Sep 17 00:00:00 2001 From: Christopher Hiller Date: Tue, 6 Jan 2026 14:52:58 -0800 Subject: [PATCH 2/2] chore(deps): add missing packages --- package-lock.json | 919 ++++++++++++++++++++++++++++++++-------------- package.json | 2 + 2 files changed, 649 insertions(+), 272 deletions(-) diff --git a/package-lock.json b/package-lock.json index 0a59657..8a9516e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,6 +15,8 @@ "@stylistic/eslint-plugin": "5.6.1", "@types/node": "24.10.4", "@types/wallabyjs": "0.0.15", + "@typescript-eslint/typescript-estree": "8.52.0", + "@typescript-eslint/utils": "8.52.0", "bupkis": "0.14.0", "cspell": "9.4.0", "eslint": "9.39.2", @@ -2440,6 +2442,107 @@ "typescript": ">=4.8.4 <6.0.0" } }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/project-service": { + "version": "8.50.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.50.0.tgz", + "integrity": "sha512-Cg/nQcL1BcoTijEWyx4mkVC56r8dj44bFDvBdygifuS20f3OZCHmFbjF34DPSi07kwlFvqfv/xOLnJ5DquxSGQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/tsconfig-utils": "^8.50.0", + "@typescript-eslint/types": "^8.50.0", + "debug": "^4.3.4" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/tsconfig-utils": { + "version": "8.50.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.50.0.tgz", + "integrity": "sha512-vxd3G/ybKTSlm31MOA96gqvrRGv9RJ7LGtZCn2Vrc5htA0zCDvcMqUkifcjrWNNKXHUU3WCkYOzzVSFBd0wa2w==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/typescript-estree": { + "version": "8.50.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.50.0.tgz", + "integrity": "sha512-W7SVAGBR/IX7zm1t70Yujpbk+zdPq/u4soeFSknWFdXIFuWsBGBOUu/Tn/I6KHSKvSh91OiMuaSnYp3mtPt5IQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/project-service": "8.50.0", + "@typescript-eslint/tsconfig-utils": "8.50.0", + "@typescript-eslint/types": "8.50.0", + "@typescript-eslint/visitor-keys": "8.50.0", + "debug": "^4.3.4", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "tinyglobby": "^0.2.15", + "ts-api-utils": "^2.1.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/utils": { + "version": "8.50.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.50.0.tgz", + "integrity": "sha512-87KgUXET09CRjGCi2Ejxy3PULXna63/bMYv72tCAlDJC3Yqwln0HiFJ3VJMst2+mEtNtZu5oFvX4qJGjKsnAgg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.7.0", + "@typescript-eslint/scope-manager": "8.50.0", + "@typescript-eslint/types": "8.50.0", + "@typescript-eslint/typescript-estree": "8.50.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": { "version": "7.0.5", "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", @@ -2450,6 +2553,22 @@ "node": ">= 4" } }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/@typescript-eslint/parser": { "version": "8.50.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.50.0.tgz", @@ -2476,7 +2595,7 @@ "typescript": ">=4.8.4 <6.0.0" } }, - "node_modules/@typescript-eslint/project-service": { + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/project-service": { "version": "8.50.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.50.0.tgz", "integrity": "sha512-Cg/nQcL1BcoTijEWyx4mkVC56r8dj44bFDvBdygifuS20f3OZCHmFbjF34DPSi07kwlFvqfv/xOLnJ5DquxSGQ==", @@ -2498,6 +2617,113 @@ "typescript": ">=4.8.4 <6.0.0" } }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/tsconfig-utils": { + "version": "8.50.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.50.0.tgz", + "integrity": "sha512-vxd3G/ybKTSlm31MOA96gqvrRGv9RJ7LGtZCn2Vrc5htA0zCDvcMqUkifcjrWNNKXHUU3WCkYOzzVSFBd0wa2w==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree": { + "version": "8.50.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.50.0.tgz", + "integrity": "sha512-W7SVAGBR/IX7zm1t70Yujpbk+zdPq/u4soeFSknWFdXIFuWsBGBOUu/Tn/I6KHSKvSh91OiMuaSnYp3mtPt5IQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/project-service": "8.50.0", + "@typescript-eslint/tsconfig-utils": "8.50.0", + "@typescript-eslint/types": "8.50.0", + "@typescript-eslint/visitor-keys": "8.50.0", + "debug": "^4.3.4", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "tinyglobby": "^0.2.15", + "ts-api-utils": "^2.1.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@typescript-eslint/project-service": { + "version": "8.52.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.52.0.tgz", + "integrity": "sha512-xD0MfdSdEmeFa3OmVqonHi+Cciab96ls1UhIF/qX/O/gPu5KXD0bY9lu33jj04fjzrXHcuvjBcBC+D3SNSadaw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/tsconfig-utils": "^8.52.0", + "@typescript-eslint/types": "^8.52.0", + "debug": "^4.4.3" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/project-service/node_modules/@typescript-eslint/types": { + "version": "8.52.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.52.0.tgz", + "integrity": "sha512-LWQV1V4q9V4cT4H5JCIx3481iIFxH1UkVk+ZkGGAV1ZGcjGI9IoFOfg3O6ywz8QqCDEp7Inlg6kovMofsNRaGg==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, "node_modules/@typescript-eslint/scope-manager": { "version": "8.50.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.50.0.tgz", @@ -2517,9 +2743,168 @@ } }, "node_modules/@typescript-eslint/tsconfig-utils": { + "version": "8.52.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.52.0.tgz", + "integrity": "sha512-jl+8fzr/SdzdxWJznq5nvoI7qn2tNYV/ZBAEcaFMVXf+K6jmXvAFrgo/+5rxgnL152f//pDEAYAhhBAZGrVfwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "8.50.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.50.0.tgz", + "integrity": "sha512-7OciHT2lKCewR0mFoBrvZJ4AXTMe/sYOe87289WAViOocEmDjjv8MvIOT2XESuKj9jp8u3SZYUSh89QA4S1kQw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.50.0", + "@typescript-eslint/typescript-estree": "8.50.0", + "@typescript-eslint/utils": "8.50.0", + "debug": "^4.3.4", + "ts-api-utils": "^2.1.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/project-service": { + "version": "8.50.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.50.0.tgz", + "integrity": "sha512-Cg/nQcL1BcoTijEWyx4mkVC56r8dj44bFDvBdygifuS20f3OZCHmFbjF34DPSi07kwlFvqfv/xOLnJ5DquxSGQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/tsconfig-utils": "^8.50.0", + "@typescript-eslint/types": "^8.50.0", + "debug": "^4.3.4" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/tsconfig-utils": { + "version": "8.50.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.50.0.tgz", + "integrity": "sha512-vxd3G/ybKTSlm31MOA96gqvrRGv9RJ7LGtZCn2Vrc5htA0zCDvcMqUkifcjrWNNKXHUU3WCkYOzzVSFBd0wa2w==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/typescript-estree": { + "version": "8.50.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.50.0.tgz", + "integrity": "sha512-W7SVAGBR/IX7zm1t70Yujpbk+zdPq/u4soeFSknWFdXIFuWsBGBOUu/Tn/I6KHSKvSh91OiMuaSnYp3mtPt5IQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/project-service": "8.50.0", + "@typescript-eslint/tsconfig-utils": "8.50.0", + "@typescript-eslint/types": "8.50.0", + "@typescript-eslint/visitor-keys": "8.50.0", + "debug": "^4.3.4", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "tinyglobby": "^0.2.15", + "ts-api-utils": "^2.1.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/utils": { + "version": "8.50.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.50.0.tgz", + "integrity": "sha512-87KgUXET09CRjGCi2Ejxy3PULXna63/bMYv72tCAlDJC3Yqwln0HiFJ3VJMst2+mEtNtZu5oFvX4qJGjKsnAgg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.7.0", + "@typescript-eslint/scope-manager": "8.50.0", + "@typescript-eslint/types": "8.50.0", + "@typescript-eslint/typescript-estree": "8.50.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/type-utils/node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@typescript-eslint/type-utils/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@typescript-eslint/types": { "version": "8.50.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.50.0.tgz", - "integrity": "sha512-vxd3G/ybKTSlm31MOA96gqvrRGv9RJ7LGtZCn2Vrc5htA0zCDvcMqUkifcjrWNNKXHUU3WCkYOzzVSFBd0wa2w==", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.50.0.tgz", + "integrity": "sha512-iX1mgmGrXdANhhITbpp2QQM2fGehBse9LbTf0sidWK6yg/NE+uhV5dfU1g6EYPlcReYmkE9QLPq/2irKAmtS9w==", "dev": true, "license": "MIT", "engines": { @@ -2528,23 +2913,24 @@ "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "typescript": ">=4.8.4 <6.0.0" } }, - "node_modules/@typescript-eslint/type-utils": { - "version": "8.50.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.50.0.tgz", - "integrity": "sha512-7OciHT2lKCewR0mFoBrvZJ4AXTMe/sYOe87289WAViOocEmDjjv8MvIOT2XESuKj9jp8u3SZYUSh89QA4S1kQw==", + "node_modules/@typescript-eslint/typescript-estree": { + "version": "8.52.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.52.0.tgz", + "integrity": "sha512-XP3LClsCc0FsTK5/frGjolyADTh3QmsLp6nKd476xNI9CsSsLnmn4f0jrzNoAulmxlmNIpeXuHYeEQv61Q6qeQ==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.50.0", - "@typescript-eslint/typescript-estree": "8.50.0", - "@typescript-eslint/utils": "8.50.0", - "debug": "^4.3.4", - "ts-api-utils": "^2.1.0" + "@typescript-eslint/project-service": "8.52.0", + "@typescript-eslint/tsconfig-utils": "8.52.0", + "@typescript-eslint/types": "8.52.0", + "@typescript-eslint/visitor-keys": "8.52.0", + "debug": "^4.4.3", + "minimatch": "^9.0.5", + "semver": "^7.7.3", + "tinyglobby": "^0.2.15", + "ts-api-utils": "^2.4.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2554,14 +2940,13 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, - "node_modules/@typescript-eslint/types": { - "version": "8.50.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.50.0.tgz", - "integrity": "sha512-iX1mgmGrXdANhhITbpp2QQM2fGehBse9LbTf0sidWK6yg/NE+uhV5dfU1g6EYPlcReYmkE9QLPq/2irKAmtS9w==", + "node_modules/@typescript-eslint/typescript-estree/node_modules/@typescript-eslint/types": { + "version": "8.52.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.52.0.tgz", + "integrity": "sha512-LWQV1V4q9V4cT4H5JCIx3481iIFxH1UkVk+ZkGGAV1ZGcjGI9IoFOfg3O6ywz8QqCDEp7Inlg6kovMofsNRaGg==", "dev": true, "license": "MIT", "engines": { @@ -2572,22 +2957,15 @@ "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.50.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.50.0.tgz", - "integrity": "sha512-W7SVAGBR/IX7zm1t70Yujpbk+zdPq/u4soeFSknWFdXIFuWsBGBOUu/Tn/I6KHSKvSh91OiMuaSnYp3mtPt5IQ==", + "node_modules/@typescript-eslint/typescript-estree/node_modules/@typescript-eslint/visitor-keys": { + "version": "8.52.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.52.0.tgz", + "integrity": "sha512-ink3/Zofus34nmBsPjow63FP5M7IGff0RKAgqR6+CFpdk22M7aLwC9gOcLGYqr7MczLPzZVERW9hRog3O4n1sQ==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/project-service": "8.50.0", - "@typescript-eslint/tsconfig-utils": "8.50.0", - "@typescript-eslint/types": "8.50.0", - "@typescript-eslint/visitor-keys": "8.50.0", - "debug": "^4.3.4", - "minimatch": "^9.0.4", - "semver": "^7.6.0", - "tinyglobby": "^0.2.15", - "ts-api-utils": "^2.1.0" + "@typescript-eslint/types": "8.52.0", + "eslint-visitor-keys": "^4.2.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2595,9 +2973,6 @@ "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "typescript": ">=4.8.4 <6.0.0" } }, "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { @@ -2627,16 +3002,16 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "8.50.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.50.0.tgz", - "integrity": "sha512-87KgUXET09CRjGCi2Ejxy3PULXna63/bMYv72tCAlDJC3Yqwln0HiFJ3VJMst2+mEtNtZu5oFvX4qJGjKsnAgg==", + "version": "8.52.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.52.0.tgz", + "integrity": "sha512-wYndVMWkweqHpEpwPhwqE2lnD2DxC6WVLupU/DOt/0/v+/+iQbbzO3jOHjmBMnhu0DgLULvOaU4h4pwHYi2oRQ==", "dev": true, "license": "MIT", "dependencies": { - "@eslint-community/eslint-utils": "^4.7.0", - "@typescript-eslint/scope-manager": "8.50.0", - "@typescript-eslint/types": "8.50.0", - "@typescript-eslint/typescript-estree": "8.50.0" + "@eslint-community/eslint-utils": "^4.9.1", + "@typescript-eslint/scope-manager": "8.52.0", + "@typescript-eslint/types": "8.52.0", + "@typescript-eslint/typescript-estree": "8.52.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2650,6 +3025,56 @@ "typescript": ">=4.8.4 <6.0.0" } }, + "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/scope-manager": { + "version": "8.52.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.52.0.tgz", + "integrity": "sha512-ixxqmmCcc1Nf8S0mS0TkJ/3LKcC8mruYJPOU6Ia2F/zUUR4pApW7LzrpU3JmtePbRUTes9bEqRc1Gg4iyRnDzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.52.0", + "@typescript-eslint/visitor-keys": "8.52.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/types": { + "version": "8.52.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.52.0.tgz", + "integrity": "sha512-LWQV1V4q9V4cT4H5JCIx3481iIFxH1UkVk+ZkGGAV1ZGcjGI9IoFOfg3O6ywz8QqCDEp7Inlg6kovMofsNRaGg==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/visitor-keys": { + "version": "8.52.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.52.0.tgz", + "integrity": "sha512-ink3/Zofus34nmBsPjow63FP5M7IGff0RKAgqR6+CFpdk22M7aLwC9gOcLGYqr7MczLPzZVERW9hRog3O4n1sQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.52.0", + "eslint-visitor-keys": "^4.2.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, "node_modules/@typescript-eslint/visitor-keys": { "version": "8.50.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.50.0.tgz", @@ -4150,279 +4575,112 @@ "find-up": "^5.0.0", "glob-parent": "^6.0.2", "ignore": "^5.2.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", - "natural-compare": "^1.4.0", - "optionator": "^0.9.3" - }, - "bin": { - "eslint": "bin/eslint.js" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://eslint.org/donate" - }, - "peerDependencies": { - "jiti": "*" - }, - "peerDependenciesMeta": { - "jiti": { - "optional": true - } - } - }, - "node_modules/eslint-compat-utils": { - "version": "0.6.5", - "resolved": "https://registry.npmjs.org/eslint-compat-utils/-/eslint-compat-utils-0.6.5.tgz", - "integrity": "sha512-vAUHYzue4YAa2hNACjB8HvUQj5yehAZgiClyFVVom9cP8z5NSFq3PwB/TtJslN2zAMgRX6FCFCjYBbQh71g5RQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "semver": "^7.5.4" - }, - "engines": { - "node": ">=12" - }, - "peerDependencies": { - "eslint": ">=6.0.0" - } - }, - "node_modules/eslint-json-compat-utils": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/eslint-json-compat-utils/-/eslint-json-compat-utils-0.2.1.tgz", - "integrity": "sha512-YzEodbDyW8DX8bImKhAcCeu/L31Dd/70Bidx2Qex9OFUtgzXLqtfWL4Hr5fM/aCCB8QUZLuJur0S9k6UfgFkfg==", - "dev": true, - "license": "MIT", - "dependencies": { - "esquery": "^1.6.0" - }, - "engines": { - "node": ">=12" - }, - "peerDependencies": { - "eslint": "*", - "jsonc-eslint-parser": "^2.4.0" - }, - "peerDependenciesMeta": { - "@eslint/json": { - "optional": true - } - } - }, - "node_modules/eslint-plugin-jsonc": { - "version": "2.21.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsonc/-/eslint-plugin-jsonc-2.21.0.tgz", - "integrity": "sha512-HttlxdNG5ly3YjP1cFMP62R4qKLxJURfBZo2gnMY+yQojZxkLyOpY1H1KRTKBmvQeSG9pIpSGEhDjE17vvYosg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@eslint-community/eslint-utils": "^4.5.1", - "diff-sequences": "^27.5.1", - "eslint-compat-utils": "^0.6.4", - "eslint-json-compat-utils": "^0.2.1", - "espree": "^9.6.1 || ^10.3.0", - "graphemer": "^1.4.0", - "jsonc-eslint-parser": "^2.4.0", - "natural-compare": "^1.4.0", - "synckit": "^0.6.2 || ^0.7.3 || ^0.11.5" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ota-meshi" - }, - "peerDependencies": { - "eslint": ">=6.0.0" - } - }, - "node_modules/eslint-plugin-perfectionist": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-perfectionist/-/eslint-plugin-perfectionist-5.2.0.tgz", - "integrity": "sha512-rLD4VyA6sxcCPlG/koqjp0D46JTNRURSDs22Jr1JeVbOiu1BoeRdROnJoqDoGESuXbwxvGEnMSqClX/Q3HSMig==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/utils": "^8.51.0", - "natural-orderby": "^5.0.0" - }, - "engines": { - "node": "^20.0.0 || >=22.0.0" - }, - "peerDependencies": { - "eslint": ">=8.45.0" - } - }, - "node_modules/eslint-plugin-perfectionist/node_modules/@typescript-eslint/project-service": { - "version": "8.52.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.52.0.tgz", - "integrity": "sha512-xD0MfdSdEmeFa3OmVqonHi+Cciab96ls1UhIF/qX/O/gPu5KXD0bY9lu33jj04fjzrXHcuvjBcBC+D3SNSadaw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/tsconfig-utils": "^8.52.0", - "@typescript-eslint/types": "^8.52.0", - "debug": "^4.4.3" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "typescript": ">=4.8.4 <6.0.0" - } - }, - "node_modules/eslint-plugin-perfectionist/node_modules/@typescript-eslint/scope-manager": { - "version": "8.52.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.52.0.tgz", - "integrity": "sha512-ixxqmmCcc1Nf8S0mS0TkJ/3LKcC8mruYJPOU6Ia2F/zUUR4pApW7LzrpU3JmtePbRUTes9bEqRc1Gg4iyRnDzA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "8.52.0", - "@typescript-eslint/visitor-keys": "8.52.0" + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3" }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "bin": { + "eslint": "bin/eslint.js" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/eslint-plugin-perfectionist/node_modules/@typescript-eslint/tsconfig-utils": { - "version": "8.52.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.52.0.tgz", - "integrity": "sha512-jl+8fzr/SdzdxWJznq5nvoI7qn2tNYV/ZBAEcaFMVXf+K6jmXvAFrgo/+5rxgnL152f//pDEAYAhhBAZGrVfwg==", - "dev": true, - "license": "MIT", "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "url": "https://eslint.org/donate" }, "peerDependencies": { - "typescript": ">=4.8.4 <6.0.0" - } - }, - "node_modules/eslint-plugin-perfectionist/node_modules/@typescript-eslint/types": { - "version": "8.52.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.52.0.tgz", - "integrity": "sha512-LWQV1V4q9V4cT4H5JCIx3481iIFxH1UkVk+ZkGGAV1ZGcjGI9IoFOfg3O6ywz8QqCDEp7Inlg6kovMofsNRaGg==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "jiti": "*" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "peerDependenciesMeta": { + "jiti": { + "optional": true + } } }, - "node_modules/eslint-plugin-perfectionist/node_modules/@typescript-eslint/typescript-estree": { - "version": "8.52.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.52.0.tgz", - "integrity": "sha512-XP3LClsCc0FsTK5/frGjolyADTh3QmsLp6nKd476xNI9CsSsLnmn4f0jrzNoAulmxlmNIpeXuHYeEQv61Q6qeQ==", + "node_modules/eslint-compat-utils": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/eslint-compat-utils/-/eslint-compat-utils-0.6.5.tgz", + "integrity": "sha512-vAUHYzue4YAa2hNACjB8HvUQj5yehAZgiClyFVVom9cP8z5NSFq3PwB/TtJslN2zAMgRX6FCFCjYBbQh71g5RQ==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/project-service": "8.52.0", - "@typescript-eslint/tsconfig-utils": "8.52.0", - "@typescript-eslint/types": "8.52.0", - "@typescript-eslint/visitor-keys": "8.52.0", - "debug": "^4.4.3", - "minimatch": "^9.0.5", - "semver": "^7.7.3", - "tinyglobby": "^0.2.15", - "ts-api-utils": "^2.4.0" + "semver": "^7.5.4" }, "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "node": ">=12" }, "peerDependencies": { - "typescript": ">=4.8.4 <6.0.0" + "eslint": ">=6.0.0" } }, - "node_modules/eslint-plugin-perfectionist/node_modules/@typescript-eslint/utils": { - "version": "8.52.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.52.0.tgz", - "integrity": "sha512-wYndVMWkweqHpEpwPhwqE2lnD2DxC6WVLupU/DOt/0/v+/+iQbbzO3jOHjmBMnhu0DgLULvOaU4h4pwHYi2oRQ==", + "node_modules/eslint-json-compat-utils": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/eslint-json-compat-utils/-/eslint-json-compat-utils-0.2.1.tgz", + "integrity": "sha512-YzEodbDyW8DX8bImKhAcCeu/L31Dd/70Bidx2Qex9OFUtgzXLqtfWL4Hr5fM/aCCB8QUZLuJur0S9k6UfgFkfg==", "dev": true, "license": "MIT", "dependencies": { - "@eslint-community/eslint-utils": "^4.9.1", - "@typescript-eslint/scope-manager": "8.52.0", - "@typescript-eslint/types": "8.52.0", - "@typescript-eslint/typescript-estree": "8.52.0" + "esquery": "^1.6.0" }, "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "node": ">=12" }, "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <6.0.0" + "eslint": "*", + "jsonc-eslint-parser": "^2.4.0" + }, + "peerDependenciesMeta": { + "@eslint/json": { + "optional": true + } } }, - "node_modules/eslint-plugin-perfectionist/node_modules/@typescript-eslint/visitor-keys": { - "version": "8.52.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.52.0.tgz", - "integrity": "sha512-ink3/Zofus34nmBsPjow63FP5M7IGff0RKAgqR6+CFpdk22M7aLwC9gOcLGYqr7MczLPzZVERW9hRog3O4n1sQ==", + "node_modules/eslint-plugin-jsonc": { + "version": "2.21.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsonc/-/eslint-plugin-jsonc-2.21.0.tgz", + "integrity": "sha512-HttlxdNG5ly3YjP1cFMP62R4qKLxJURfBZo2gnMY+yQojZxkLyOpY1H1KRTKBmvQeSG9pIpSGEhDjE17vvYosg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.52.0", - "eslint-visitor-keys": "^4.2.1" + "@eslint-community/eslint-utils": "^4.5.1", + "diff-sequences": "^27.5.1", + "eslint-compat-utils": "^0.6.4", + "eslint-json-compat-utils": "^0.2.1", + "espree": "^9.6.1 || ^10.3.0", + "graphemer": "^1.4.0", + "jsonc-eslint-parser": "^2.4.0", + "natural-compare": "^1.4.0", + "synckit": "^0.6.2 || ^0.7.3 || ^0.11.5" }, "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "url": "https://github.com/sponsors/ota-meshi" + }, + "peerDependencies": { + "eslint": ">=6.0.0" } }, - "node_modules/eslint-plugin-perfectionist/node_modules/brace-expansion": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", - "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "node_modules/eslint-plugin-perfectionist": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-perfectionist/-/eslint-plugin-perfectionist-5.2.0.tgz", + "integrity": "sha512-rLD4VyA6sxcCPlG/koqjp0D46JTNRURSDs22Jr1JeVbOiu1BoeRdROnJoqDoGESuXbwxvGEnMSqClX/Q3HSMig==", "dev": true, "license": "MIT", "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/eslint-plugin-perfectionist/node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.1" + "@typescript-eslint/utils": "^8.51.0", + "natural-orderby": "^5.0.0" }, "engines": { - "node": ">=16 || 14 >=14.17" + "node": "^20.0.0 || >=22.0.0" }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "peerDependencies": { + "eslint": ">=8.45.0" } }, "node_modules/eslint-scope": { @@ -9128,6 +9386,123 @@ "typescript": ">=4.8.4 <6.0.0" } }, + "node_modules/typescript-eslint/node_modules/@typescript-eslint/project-service": { + "version": "8.50.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.50.0.tgz", + "integrity": "sha512-Cg/nQcL1BcoTijEWyx4mkVC56r8dj44bFDvBdygifuS20f3OZCHmFbjF34DPSi07kwlFvqfv/xOLnJ5DquxSGQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/tsconfig-utils": "^8.50.0", + "@typescript-eslint/types": "^8.50.0", + "debug": "^4.3.4" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/typescript-eslint/node_modules/@typescript-eslint/tsconfig-utils": { + "version": "8.50.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.50.0.tgz", + "integrity": "sha512-vxd3G/ybKTSlm31MOA96gqvrRGv9RJ7LGtZCn2Vrc5htA0zCDvcMqUkifcjrWNNKXHUU3WCkYOzzVSFBd0wa2w==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/typescript-eslint/node_modules/@typescript-eslint/typescript-estree": { + "version": "8.50.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.50.0.tgz", + "integrity": "sha512-W7SVAGBR/IX7zm1t70Yujpbk+zdPq/u4soeFSknWFdXIFuWsBGBOUu/Tn/I6KHSKvSh91OiMuaSnYp3mtPt5IQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/project-service": "8.50.0", + "@typescript-eslint/tsconfig-utils": "8.50.0", + "@typescript-eslint/types": "8.50.0", + "@typescript-eslint/visitor-keys": "8.50.0", + "debug": "^4.3.4", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "tinyglobby": "^0.2.15", + "ts-api-utils": "^2.1.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/typescript-eslint/node_modules/@typescript-eslint/utils": { + "version": "8.50.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.50.0.tgz", + "integrity": "sha512-87KgUXET09CRjGCi2Ejxy3PULXna63/bMYv72tCAlDJC3Yqwln0HiFJ3VJMst2+mEtNtZu5oFvX4qJGjKsnAgg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.7.0", + "@typescript-eslint/scope-manager": "8.50.0", + "@typescript-eslint/types": "8.50.0", + "@typescript-eslint/typescript-estree": "8.50.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/typescript-eslint/node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/typescript-eslint/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/uc.micro": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz", diff --git a/package.json b/package.json index 05a4da6..cabac27 100644 --- a/package.json +++ b/package.json @@ -69,6 +69,8 @@ "@stylistic/eslint-plugin": "5.6.1", "@types/node": "24.10.4", "@types/wallabyjs": "0.0.15", + "@typescript-eslint/typescript-estree": "8.52.0", + "@typescript-eslint/utils": "8.52.0", "bupkis": "0.14.0", "cspell": "9.4.0", "eslint": "9.39.2",