@venizia/dev-configs 0.4.2 → 0.4.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (106) hide show
  1. package/LICENSE.md +2 -5
  2. package/README.md +20 -5
  3. package/dist/checks/catalog.d.ts +39 -0
  4. package/dist/checks/catalog.d.ts.map +1 -0
  5. package/dist/checks/catalog.js +94 -0
  6. package/dist/checks/catalog.js.map +1 -0
  7. package/dist/checks/index.d.ts +11 -0
  8. package/dist/checks/index.d.ts.map +1 -0
  9. package/dist/checks/index.js +27 -0
  10. package/dist/checks/index.js.map +1 -0
  11. package/dist/checks/module-cycles.d.ts +22 -0
  12. package/dist/checks/module-cycles.d.ts.map +1 -0
  13. package/dist/checks/module-cycles.js +149 -0
  14. package/dist/checks/module-cycles.js.map +1 -0
  15. package/dist/checks/purity/manifest.d.ts +94 -0
  16. package/dist/checks/purity/manifest.d.ts.map +1 -0
  17. package/dist/checks/purity/manifest.js +177 -0
  18. package/dist/checks/purity/manifest.js.map +1 -0
  19. package/dist/checks/purity/probe.d.ts +68 -0
  20. package/dist/checks/purity/probe.d.ts.map +1 -0
  21. package/dist/checks/purity/probe.js +295 -0
  22. package/dist/checks/purity/probe.js.map +1 -0
  23. package/dist/checks/purity/run.d.ts +47 -0
  24. package/dist/checks/purity/run.d.ts.map +1 -0
  25. package/dist/checks/purity/run.js +121 -0
  26. package/dist/checks/purity/run.js.map +1 -0
  27. package/dist/checks/split-report.d.ts +19 -0
  28. package/dist/checks/split-report.d.ts.map +1 -0
  29. package/dist/checks/split-report.js +123 -0
  30. package/dist/checks/split-report.js.map +1 -0
  31. package/dist/cli/check.d.ts +10 -0
  32. package/dist/cli/check.d.ts.map +1 -0
  33. package/dist/cli/check.js +206 -0
  34. package/dist/cli/check.js.map +1 -0
  35. package/dist/cli/clean.d.ts +2 -1
  36. package/dist/cli/clean.d.ts.map +1 -1
  37. package/dist/cli/clean.js +18 -1
  38. package/dist/cli/clean.js.map +1 -1
  39. package/dist/cli/codemod/const-classes.d.ts +80 -0
  40. package/dist/cli/codemod/const-classes.d.ts.map +1 -0
  41. package/dist/cli/codemod/const-classes.js +603 -0
  42. package/dist/cli/codemod/const-classes.js.map +1 -0
  43. package/dist/cli/codemod/drop-redundant-casts.d.ts +112 -0
  44. package/dist/cli/codemod/drop-redundant-casts.d.ts.map +1 -0
  45. package/dist/cli/codemod/drop-redundant-casts.js +780 -0
  46. package/dist/cli/codemod/drop-redundant-casts.js.map +1 -0
  47. package/dist/cli/codemod/files.d.ts +22 -0
  48. package/dist/cli/codemod/files.d.ts.map +1 -0
  49. package/dist/cli/codemod/files.js +68 -0
  50. package/dist/cli/codemod/files.js.map +1 -0
  51. package/dist/cli/codemod/index.d.ts +5 -4
  52. package/dist/cli/codemod/index.d.ts.map +1 -1
  53. package/dist/cli/codemod/index.js +77 -36
  54. package/dist/cli/codemod/index.js.map +1 -1
  55. package/dist/cli/codemod/model-settings.d.ts +2 -1
  56. package/dist/cli/codemod/model-settings.d.ts.map +1 -1
  57. package/dist/cli/codemod/model-settings.js +77 -3
  58. package/dist/cli/codemod/model-settings.js.map +1 -1
  59. package/dist/cli/index.js +21 -2
  60. package/dist/cli/index.js.map +1 -1
  61. package/dist/linters/house/common.d.ts +1 -0
  62. package/dist/linters/house/common.d.ts.map +1 -1
  63. package/dist/linters/house/common.js +1 -0
  64. package/dist/linters/house/common.js.map +1 -1
  65. package/dist/linters/house/configs.d.ts.map +1 -1
  66. package/dist/linters/house/configs.js +20 -1
  67. package/dist/linters/house/configs.js.map +1 -1
  68. package/dist/linters/house/const-class-values.rule.d.ts +7 -4
  69. package/dist/linters/house/const-class-values.rule.d.ts.map +1 -1
  70. package/dist/linters/house/const-class-values.rule.js +73 -21
  71. package/dist/linters/house/const-class-values.rule.js.map +1 -1
  72. package/dist/linters/rules/common.d.ts +48 -1
  73. package/dist/linters/rules/common.d.ts.map +1 -1
  74. package/dist/linters/rules/common.js +53 -0
  75. package/dist/linters/rules/common.js.map +1 -1
  76. package/dist/linters/rules/eqeqeq.rule.d.ts +2 -2
  77. package/dist/linters/rules/eqeqeq.rule.d.ts.map +1 -1
  78. package/dist/linters/rules/eqeqeq.rule.js +2 -1
  79. package/dist/linters/rules/eqeqeq.rule.js.map +1 -1
  80. package/dist/linters/rules/no-unused-vars.rule.d.ts +3 -3
  81. package/dist/linters/rules/no-unused-vars.rule.d.ts.map +1 -1
  82. package/dist/linters/rules/no-unused-vars.rule.js +2 -1
  83. package/dist/linters/rules/no-unused-vars.rule.js.map +1 -1
  84. package/dist/linters/rules/switch-case-braces.rule.d.ts +2 -2
  85. package/dist/linters/rules/switch-case-braces.rule.d.ts.map +1 -1
  86. package/dist/linters/rules/switch-case-braces.rule.js +2 -1
  87. package/dist/linters/rules/switch-case-braces.rule.js.map +1 -1
  88. package/dist/testing/index.d.ts +2 -0
  89. package/dist/testing/index.d.ts.map +1 -1
  90. package/dist/testing/index.js +2 -0
  91. package/dist/testing/index.js.map +1 -1
  92. package/dist/testing/repo-tmp.d.ts +12 -0
  93. package/dist/testing/repo-tmp.d.ts.map +1 -0
  94. package/dist/testing/repo-tmp.js +67 -0
  95. package/dist/testing/repo-tmp.js.map +1 -0
  96. package/dist/testing/spawn.helper.d.ts +13 -0
  97. package/dist/testing/spawn.helper.d.ts.map +1 -0
  98. package/dist/testing/spawn.helper.js +22 -0
  99. package/dist/testing/spawn.helper.js.map +1 -0
  100. package/dist/testing/tmpdir-preload.d.ts +2 -0
  101. package/dist/testing/tmpdir-preload.d.ts.map +1 -0
  102. package/dist/testing/tmpdir-preload.js +9 -0
  103. package/dist/testing/tmpdir-preload.js.map +1 -0
  104. package/package.json +9 -1
  105. package/src/tsconfig/tsconfig.base.json +5 -2
  106. package/src/tsconfig/tsconfig.common.json +2 -2
@@ -1 +1 @@
1
- {"version":3,"file":"model-settings.js","sourceRoot":"","sources":["../../../src/cli/codemod/model-settings.ts"],"names":[],"mappings":"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","sourcesContent":["import type ts from 'typescript';\n\ntype TTypeScript = typeof ts;\n\n/** One thing the codemod could not decide and left alone. */\nexport interface IModelSettingsReport {\n line: number;\n column: number;\n reason: string;\n}\n\nexport interface IModelSettingsResult {\n /** The source after the migration; equal to the input when nothing changed. */\n output: string;\n changed: boolean;\n /** How many `@model` settings objects were rewritten. */\n rewritten: number;\n reports: IModelSettingsReport[];\n}\n\ninterface IEdit {\n start: number;\n end: number;\n text: string;\n}\n\nconst QUERY_KEYS = { defaultFilter: 'filter', defaultLimit: 'default', maxLimit: 'max' } as const;\nconst OLD_KEYS = new Set<string>([...Object.keys(QUERY_KEYS), 'scopeFilter']);\n\n/**\n * Rewrites the `settings` object literal of `@model({ ... })` from the flat keys to the grouped ones:\n * `defaultFilter` to `query.filter`, `defaultLimit` and `maxLimit` to `query.limit.default` and\n * `query.limit.max`, `scopeFilter` to `access` (`writeGuard` to `write.mode`, `sharedRows` to\n * `write.sharedRows`).\n *\n * It edits by source range, so comments and formatting outside the rewritten properties stay. It\n * never guesses: a `settings` value that is not an object literal, a spread, a computed key, or a\n * `scopeFilter` that is not an object literal is reported and the model is left untouched.\n */\nexport const migrateModelSettings = (opts: {\n typescript: TTypeScript;\n fileName: string;\n source: string;\n}): IModelSettingsResult => {\n const { typescript, fileName, source } = opts;\n const sourceFile = typescript.createSourceFile(\n fileName,\n source,\n typescript.ScriptTarget.Latest,\n true,\n );\n const edits: IEdit[] = [];\n const reports: IModelSettingsReport[] = [];\n let rewritten = 0;\n\n const report = (node: ts.Node, reason: string) => {\n const { line, character } = sourceFile.getLineAndCharacterOfPosition(node.getStart(sourceFile));\n reports.push({ line: line + 1, column: character + 1, reason });\n };\n\n const nameOf = (property: ts.ObjectLiteralElementLike): string | undefined => {\n if (\n !typescript.isPropertyAssignment(property) &&\n !typescript.isShorthandPropertyAssignment(property)\n ) {\n return undefined;\n }\n\n const { name } = property;\n if (typescript.isIdentifier(name) || typescript.isStringLiteral(name)) {\n return name.text;\n }\n\n return undefined;\n };\n\n const text = (node: ts.Node) => source.slice(node.getStart(sourceFile), node.end);\n\n /**\n * The leading trivia of `first` (its own comments and indentation) followed by the comments that\n * were above the properties being merged into it, so no comment is dropped.\n */\n const composeLeading = (first: ts.Node, merged: ts.Node[]): string => {\n const trivia = source.slice(first.getFullStart(), first.getStart(sourceFile));\n const indent = /[ \\t]*$/.exec(trivia)?.[0] ?? '';\n const extra = merged\n .flatMap((node) => typescript.getLeadingCommentRanges(source, node.getFullStart()) ?? [])\n .map((range) => `${source.slice(range.pos, range.end)}\\n${indent}`)\n .join('');\n\n return trivia + extra;\n };\n\n /**\n * Removes a property with the comma after it; the last property has none, so the comma before it\n * goes instead, leaving no dangling `, }`.\n */\n const removal = (node: ts.Node): IEdit => {\n const after = /^\\s*,/.exec(source.slice(node.end));\n if (after) {\n return { start: node.getFullStart(), end: node.end + after[0].length, text: '' };\n }\n\n const before = /,\\s*$/.exec(source.slice(0, node.getFullStart()));\n const start = before ? node.getFullStart() - before[0].length : node.getFullStart();\n\n return { start, end: node.end, text: '' };\n };\n\n /** Appends members to an object literal: after its last member, or inside empty braces. */\n const append = (object: ts.ObjectLiteralExpression, members: string[]): IEdit => {\n const last = object.properties[object.properties.length - 1];\n if (last) {\n return { start: last.end, end: last.end, text: `, ${members.join(', ')}` };\n }\n\n const at = object.getStart(sourceFile) + 1;\n return { start: at, end: at, text: ` ${members.join(', ')} ` };\n };\n\n const migrateSettings = (settings: ts.ObjectLiteralExpression) => {\n const properties = [...settings.properties];\n const old = new Map<string, ts.PropertyAssignment>();\n let existingQuery: ts.PropertyAssignment | undefined;\n\n for (const property of properties) {\n if (typescript.isSpreadAssignment(property)) {\n // A spread can carry old keys we cannot see.\n report(property, 'settings contains a spread, so its keys are unknown; left untouched');\n return;\n }\n\n if (typescript.isMethodDeclaration(property)) {\n continue;\n }\n\n const name = nameOf(property);\n if (name === undefined) {\n report(property, 'settings contains a computed key; left untouched');\n return;\n }\n\n if (OLD_KEYS.has(name)) {\n if (!typescript.isPropertyAssignment(property)) {\n report(property, `settings.${name} is a shorthand property; left untouched`);\n return;\n }\n old.set(name, property);\n }\n\n if (name === 'query' && typescript.isPropertyAssignment(property)) {\n existingQuery = property;\n }\n }\n\n if (old.size === 0) {\n return;\n }\n\n const queryOld = [...old.keys()].filter((key) => key in QUERY_KEYS);\n const localEdits: IEdit[] = [];\n\n // ---- scopeFilter -> access (rename the key, rewrite writeGuard / sharedRows inside)\n const scopeFilter = old.get('scopeFilter');\n if (scopeFilter) {\n if (!typescript.isObjectLiteralExpression(scopeFilter.initializer)) {\n report(scopeFilter, 'settings.scopeFilter is not an object literal; left untouched');\n return;\n }\n\n const inner = scopeFilter.initializer;\n const guard = inner.properties.find(\n (property) =>\n nameOf(property) === 'writeGuard' && typescript.isPropertyAssignment(property),\n ) as ts.PropertyAssignment | undefined;\n const shared = inner.properties.find(\n (property) =>\n nameOf(property) === 'sharedRows' && typescript.isPropertyAssignment(property),\n ) as ts.PropertyAssignment | undefined;\n const hasSpread = inner.properties.some((property) =>\n typescript.isSpreadAssignment(property),\n );\n\n if (hasSpread) {\n report(scopeFilter, 'settings.scopeFilter contains a spread; left untouched');\n return;\n }\n\n if (inner.properties.some((property) => nameOf(property) === 'write')) {\n report(scopeFilter, 'settings.scopeFilter already has a write key; left untouched');\n return;\n }\n\n localEdits.push({\n start: scopeFilter.name.getStart(sourceFile),\n end: scopeFilter.name.end,\n text: 'access',\n });\n\n if (guard || shared) {\n const members = [\n guard ? `mode: ${text(guard.initializer)}` : undefined,\n shared ? `sharedRows: ${text(shared.initializer)}` : undefined,\n ].filter((member): member is string => member !== undefined);\n const ordered = [guard, shared]\n .filter((property): property is ts.PropertyAssignment => property !== undefined)\n .sort((a, b) => a.getStart(sourceFile) - b.getStart(sourceFile));\n const [first, ...merged] = ordered;\n\n localEdits.push({\n start: first.getFullStart(),\n end: first.end,\n text: `${composeLeading(first, merged)}write: { ${members.join(', ')} }`,\n });\n\n for (const second of merged) {\n localEdits.push(removal(second));\n }\n }\n }\n\n // ---- defaultFilter / defaultLimit / maxLimit -> query\n if (queryOld.length > 0) {\n const filter = old.get('defaultFilter');\n const defaultLimit = old.get('defaultLimit');\n const maxLimit = old.get('maxLimit');\n\n if (existingQuery) {\n if (!typescript.isObjectLiteralExpression(existingQuery.initializer)) {\n report(existingQuery, 'settings.query is not an object literal; left untouched');\n return;\n }\n\n const queryObject = existingQuery.initializer;\n const queryKeys = new Set(queryObject.properties.map((property) => nameOf(property)));\n const existingLimit = queryObject.properties.find(\n (property) => nameOf(property) === 'limit',\n ) as ts.PropertyAssignment | undefined;\n\n if (filter && queryKeys.has('filter')) {\n report(\n filter,\n 'settings.defaultFilter and settings.query.filter are both set; left untouched',\n );\n return;\n }\n\n if ((defaultLimit || maxLimit) && existingLimit) {\n if (!typescript.isObjectLiteralExpression(existingLimit.initializer)) {\n report(existingLimit, 'settings.query.limit is not an object literal; left untouched');\n return;\n }\n\n const limitKeys = new Set(\n existingLimit.initializer.properties.map((property) => nameOf(property)),\n );\n if ((defaultLimit && limitKeys.has('default')) || (maxLimit && limitKeys.has('max'))) {\n report(existingLimit, 'an old limit key and its new key are both set; left untouched');\n return;\n }\n }\n\n const additions: string[] = [];\n if (filter) {\n additions.push(`filter: ${text(filter.initializer)}`);\n }\n\n const limitMembers = [\n defaultLimit ? `default: ${text(defaultLimit.initializer)}` : undefined,\n maxLimit ? `max: ${text(maxLimit.initializer)}` : undefined,\n ].filter((member): member is string => member !== undefined);\n\n if (limitMembers.length > 0 && existingLimit) {\n localEdits.push(\n append(existingLimit.initializer as ts.ObjectLiteralExpression, limitMembers),\n );\n } else if (limitMembers.length > 0) {\n additions.push(`limit: { ${limitMembers.join(', ')} }`);\n }\n\n if (additions.length > 0) {\n localEdits.push(append(queryObject, additions));\n }\n\n for (const key of queryOld) {\n const property = old.get(key) as ts.PropertyAssignment;\n localEdits.push(removal(property));\n }\n } else {\n const members: string[] = [];\n if (filter) {\n members.push(`filter: ${text(filter.initializer)}`);\n }\n\n const limitMembers = [\n defaultLimit ? `default: ${text(defaultLimit.initializer)}` : undefined,\n maxLimit ? `max: ${text(maxLimit.initializer)}` : undefined,\n ].filter((member): member is string => member !== undefined);\n if (limitMembers.length > 0) {\n members.push(`limit: { ${limitMembers.join(', ')} }`);\n }\n\n const ordered = queryOld\n .map((key) => old.get(key) as ts.PropertyAssignment)\n .sort((a, b) => a.getStart(sourceFile) - b.getStart(sourceFile));\n const [first, ...others] = ordered;\n\n localEdits.push({\n start: first.getFullStart(),\n end: first.end,\n text: `${composeLeading(first, others)}query: { ${members.join(', ')} }`,\n });\n\n for (const other of others) {\n localEdits.push(removal(other));\n }\n }\n }\n\n edits.push(...localEdits);\n rewritten += 1;\n };\n\n const visit = (node: ts.Node) => {\n if (\n typescript.isDecorator(node) &&\n typescript.isCallExpression(node.expression) &&\n typescript.isIdentifier(node.expression.expression) &&\n node.expression.expression.text === 'model'\n ) {\n const argument = node.expression.arguments[0];\n\n if (argument && typescript.isObjectLiteralExpression(argument)) {\n const settingsProperty = argument.properties.find(\n (property) => nameOf(property) === 'settings',\n );\n\n if (settingsProperty) {\n if (\n typescript.isPropertyAssignment(settingsProperty) &&\n typescript.isObjectLiteralExpression(settingsProperty.initializer)\n ) {\n migrateSettings(settingsProperty.initializer);\n } else {\n report(\n settingsProperty,\n 'settings is not an object literal (a variable, a call or a shorthand); left untouched',\n );\n }\n }\n }\n }\n\n typescript.forEachChild(node, visit);\n };\n\n visit(sourceFile);\n\n // Neighbouring removals can touch the same comma: merge those, then apply from the end so\n // earlier offsets stay valid.\n const ascending = [...edits].sort((a, b) => a.start - b.start || a.end - b.end);\n const merged: IEdit[] = [];\n for (const edit of ascending) {\n const previous = merged[merged.length - 1];\n if (previous && edit.start < previous.end && previous.text === '' && edit.text === '') {\n previous.end = Math.max(previous.end, edit.end);\n continue;\n }\n\n merged.push({ ...edit });\n }\n\n let output = source;\n for (const edit of merged.reverse()) {\n output = output.slice(0, edit.start) + edit.text + output.slice(edit.end);\n }\n\n return { output, changed: output !== source, rewritten, reports };\n};\n"]}
1
+ {"version":3,"file":"model-settings.js","sourceRoot":"","sources":["../../../src/cli/codemod/model-settings.ts"],"names":[],"mappings":"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","sourcesContent":["import type ts from 'typescript';\n\ntype TTypeScript = typeof ts;\n\n/** The packages that export the `@model` decorator, so an aliased import of it is recognised. */\nconst MODEL_MODULES = new Set<string>(['@venizia/ignis', '@venizia/ignis-kernel']);\n\n/** One thing the codemod could not decide and left alone. */\nexport interface IModelSettingsReport {\n line: number;\n column: number;\n reason: string;\n}\n\nexport interface IModelSettingsResult {\n /** The source after the migration; equal to the input when nothing changed. */\n output: string;\n changed: boolean;\n /** How many `@model` settings objects were rewritten. */\n rewritten: number;\n reports: IModelSettingsReport[];\n}\n\ninterface IEdit {\n start: number;\n end: number;\n text: string;\n}\n\nconst QUERY_KEYS = { defaultFilter: 'filter', defaultLimit: 'default', maxLimit: 'max' } as const;\nconst OLD_KEYS = new Set<string>([...Object.keys(QUERY_KEYS), 'scopeFilter']);\n\n/**\n * Rewrites `@model({ ... })` from the old keys to the grouped ones. `skipMigrate` becomes\n * `migration: { use: false }`. In the `settings` object literal:\n * `defaultFilter` to `query.filter`, `defaultLimit` and `maxLimit` to `query.limit.default` and\n * `query.limit.max`, `scopeFilter` to `access` (`writeGuard` to `write.mode`, `sharedRows` to\n * `write.sharedRows`).\n *\n * It edits by source range, so comments and formatting outside the rewritten properties stay. It\n * never guesses: a `settings` value that is not an object literal, a spread, a computed key, or a\n * `scopeFilter` that is not an object literal is reported and the model is left untouched.\n */\nexport const migrateModelSettings = (opts: {\n typescript: TTypeScript;\n fileName: string;\n source: string;\n}): IModelSettingsResult => {\n const { typescript, fileName, source } = opts;\n const sourceFile = typescript.createSourceFile(\n fileName,\n source,\n typescript.ScriptTarget.Latest,\n true,\n );\n const edits: IEdit[] = [];\n const reports: IModelSettingsReport[] = [];\n let rewritten = 0;\n\n const report = (node: ts.Node, reason: string) => {\n const { line, character } = sourceFile.getLineAndCharacterOfPosition(node.getStart(sourceFile));\n reports.push({ line: line + 1, column: character + 1, reason });\n };\n\n const nameOf = (property: ts.ObjectLiteralElementLike): string | undefined => {\n if (\n !typescript.isPropertyAssignment(property) &&\n !typescript.isShorthandPropertyAssignment(property)\n ) {\n return undefined;\n }\n\n const { name } = property;\n if (typescript.isIdentifier(name) || typescript.isStringLiteral(name)) {\n return name.text;\n }\n\n return undefined;\n };\n\n const text = (node: ts.Node) => source.slice(node.getStart(sourceFile), node.end);\n\n // Names that mean `@model`: the identifier itself, an alias of a named import from IGNIS, and the\n // namespace of `import * as ignis` (`@ignis.model(...)`).\n const modelNames = new Set<string>(['model']);\n const namespaces = new Set<string>();\n for (const statement of sourceFile.statements) {\n if (\n !typescript.isImportDeclaration(statement) ||\n !typescript.isStringLiteral(statement.moduleSpecifier) ||\n !MODEL_MODULES.has(statement.moduleSpecifier.text)\n ) {\n continue;\n }\n\n const bindings = statement.importClause?.namedBindings;\n if (!bindings) {\n continue;\n }\n\n if (typescript.isNamespaceImport(bindings)) {\n namespaces.add(bindings.name.text);\n continue;\n }\n\n for (const element of bindings.elements) {\n if ((element.propertyName ?? element.name).text === 'model') {\n modelNames.add(element.name.text);\n }\n }\n }\n\n const isModelCallee = (callee: ts.Expression): boolean => {\n if (typescript.isIdentifier(callee)) {\n return modelNames.has(callee.text);\n }\n\n return (\n typescript.isPropertyAccessExpression(callee) &&\n typescript.isIdentifier(callee.expression) &&\n namespaces.has(callee.expression.text) &&\n callee.name.text === 'model'\n );\n };\n\n /**\n * The leading trivia of `first` (its own comments and indentation) followed by the comments that\n * were above the properties being merged into it, so no comment is dropped.\n */\n const composeLeading = (first: ts.Node, merged: ts.Node[]): string => {\n const trivia = source.slice(first.getFullStart(), first.getStart(sourceFile));\n const indent = /[ \\t]*$/.exec(trivia)?.[0] ?? '';\n const extra = merged\n .flatMap((node) => typescript.getLeadingCommentRanges(source, node.getFullStart()) ?? [])\n .map((range) => `${source.slice(range.pos, range.end)}\\n${indent}`)\n .join('');\n\n return trivia + extra;\n };\n\n /**\n * Removes a property with the comma after it; the last property has none, so the comma before it\n * goes instead, leaving no dangling `, }`.\n */\n const removal = (node: ts.Node): IEdit => {\n const after = /^\\s*,/.exec(source.slice(node.end));\n if (after) {\n return { start: node.getFullStart(), end: node.end + after[0].length, text: '' };\n }\n\n const before = /,\\s*$/.exec(source.slice(0, node.getFullStart()));\n const start = before ? node.getFullStart() - before[0].length : node.getFullStart();\n\n return { start, end: node.end, text: '' };\n };\n\n /** Appends members to an object literal: after its last member, or inside empty braces. */\n const append = (object: ts.ObjectLiteralExpression, members: string[]): IEdit => {\n const last = object.properties[object.properties.length - 1];\n if (last) {\n return { start: last.end, end: last.end, text: `, ${members.join(', ')}` };\n }\n\n const at = object.getStart(sourceFile) + 1;\n return { start: at, end: at, text: ` ${members.join(', ')} ` };\n };\n\n const migrateSettings = (settings: ts.ObjectLiteralExpression) => {\n const properties = [...settings.properties];\n const old = new Map<string, ts.PropertyAssignment>();\n let existingQuery: ts.PropertyAssignment | undefined;\n\n for (const property of properties) {\n if (typescript.isSpreadAssignment(property)) {\n // A spread can carry old keys we cannot see.\n report(property, 'settings contains a spread, so its keys are unknown; left untouched');\n return;\n }\n\n if (typescript.isMethodDeclaration(property)) {\n continue;\n }\n\n const name = nameOf(property);\n if (name === undefined) {\n report(property, 'settings contains a computed key; left untouched');\n return;\n }\n\n if (OLD_KEYS.has(name)) {\n if (!typescript.isPropertyAssignment(property)) {\n report(property, `settings.${name} is a shorthand property; left untouched`);\n return;\n }\n old.set(name, property);\n }\n\n if (name === 'query' && typescript.isPropertyAssignment(property)) {\n existingQuery = property;\n }\n }\n\n if (old.size === 0) {\n return;\n }\n\n const queryOld = [...old.keys()].filter((key) => key in QUERY_KEYS);\n const localEdits: IEdit[] = [];\n\n // ---- scopeFilter -> access (rename the key, rewrite writeGuard / sharedRows inside)\n const scopeFilter = old.get('scopeFilter');\n if (scopeFilter) {\n if (!typescript.isObjectLiteralExpression(scopeFilter.initializer)) {\n report(scopeFilter, 'settings.scopeFilter is not an object literal; left untouched');\n return;\n }\n\n const inner = scopeFilter.initializer;\n const guard = inner.properties.find(\n (property) =>\n nameOf(property) === 'writeGuard' && typescript.isPropertyAssignment(property),\n ) as ts.PropertyAssignment | undefined;\n const shared = inner.properties.find(\n (property) =>\n nameOf(property) === 'sharedRows' && typescript.isPropertyAssignment(property),\n ) as ts.PropertyAssignment | undefined;\n const hasSpread = inner.properties.some((property) =>\n typescript.isSpreadAssignment(property),\n );\n\n if (hasSpread) {\n report(scopeFilter, 'settings.scopeFilter contains a spread; left untouched');\n return;\n }\n\n if (inner.properties.some((property) => nameOf(property) === 'write')) {\n report(scopeFilter, 'settings.scopeFilter already has a write key; left untouched');\n return;\n }\n\n localEdits.push({\n start: scopeFilter.name.getStart(sourceFile),\n end: scopeFilter.name.end,\n text: 'access',\n });\n\n if (guard || shared) {\n const members = [\n guard ? `mode: ${text(guard.initializer)}` : undefined,\n shared ? `sharedRows: ${text(shared.initializer)}` : undefined,\n ].filter((member): member is string => member !== undefined);\n const ordered = [guard, shared]\n .filter((property): property is ts.PropertyAssignment => property !== undefined)\n .sort((a, b) => a.getStart(sourceFile) - b.getStart(sourceFile));\n const [first, ...merged] = ordered;\n\n localEdits.push({\n start: first.getFullStart(),\n end: first.end,\n text: `${composeLeading(first, merged)}write: { ${members.join(', ')} }`,\n });\n\n for (const second of merged) {\n localEdits.push(removal(second));\n }\n }\n }\n\n // ---- defaultFilter / defaultLimit / maxLimit -> query\n if (queryOld.length > 0) {\n const filter = old.get('defaultFilter');\n const defaultLimit = old.get('defaultLimit');\n const maxLimit = old.get('maxLimit');\n\n if (existingQuery) {\n if (!typescript.isObjectLiteralExpression(existingQuery.initializer)) {\n report(existingQuery, 'settings.query is not an object literal; left untouched');\n return;\n }\n\n const queryObject = existingQuery.initializer;\n const queryKeys = new Set(queryObject.properties.map((property) => nameOf(property)));\n const existingLimit = queryObject.properties.find(\n (property) => nameOf(property) === 'limit',\n ) as ts.PropertyAssignment | undefined;\n\n if (filter && queryKeys.has('filter')) {\n report(\n filter,\n 'settings.defaultFilter and settings.query.filter are both set; left untouched',\n );\n return;\n }\n\n if ((defaultLimit || maxLimit) && existingLimit) {\n if (!typescript.isObjectLiteralExpression(existingLimit.initializer)) {\n report(existingLimit, 'settings.query.limit is not an object literal; left untouched');\n return;\n }\n\n const limitKeys = new Set(\n existingLimit.initializer.properties.map((property) => nameOf(property)),\n );\n if ((defaultLimit && limitKeys.has('default')) || (maxLimit && limitKeys.has('max'))) {\n report(existingLimit, 'an old limit key and its new key are both set; left untouched');\n return;\n }\n }\n\n const additions: string[] = [];\n if (filter) {\n additions.push(`filter: ${text(filter.initializer)}`);\n }\n\n const limitMembers = [\n defaultLimit ? `default: ${text(defaultLimit.initializer)}` : undefined,\n maxLimit ? `max: ${text(maxLimit.initializer)}` : undefined,\n ].filter((member): member is string => member !== undefined);\n\n if (limitMembers.length > 0 && existingLimit) {\n localEdits.push(\n append(existingLimit.initializer as ts.ObjectLiteralExpression, limitMembers),\n );\n } else if (limitMembers.length > 0) {\n additions.push(`limit: { ${limitMembers.join(', ')} }`);\n }\n\n if (additions.length > 0) {\n localEdits.push(append(queryObject, additions));\n }\n\n for (const key of queryOld) {\n const property = old.get(key) as ts.PropertyAssignment;\n localEdits.push(removal(property));\n }\n } else {\n const members: string[] = [];\n if (filter) {\n members.push(`filter: ${text(filter.initializer)}`);\n }\n\n const limitMembers = [\n defaultLimit ? `default: ${text(defaultLimit.initializer)}` : undefined,\n maxLimit ? `max: ${text(maxLimit.initializer)}` : undefined,\n ].filter((member): member is string => member !== undefined);\n if (limitMembers.length > 0) {\n members.push(`limit: { ${limitMembers.join(', ')} }`);\n }\n\n const ordered = queryOld\n .map((key) => old.get(key) as ts.PropertyAssignment)\n .sort((a, b) => a.getStart(sourceFile) - b.getStart(sourceFile));\n const [first, ...others] = ordered;\n\n localEdits.push({\n start: first.getFullStart(),\n end: first.end,\n text: `${composeLeading(first, others)}query: { ${members.join(', ')} }`,\n });\n\n for (const other of others) {\n localEdits.push(removal(other));\n }\n }\n }\n\n edits.push(...localEdits);\n rewritten += 1;\n };\n\n /**\n * `skipMigrate: true` becomes `migration: { use: false }`; `skipMigrate: false` is the default and\n * is removed. Anything that is not a boolean literal, or a model that already has `migration`, is\n * reported and left alone.\n */\n const migrateSkipMigrate = (argument: ts.ObjectLiteralExpression) => {\n const property = argument.properties.find((candidate) => nameOf(candidate) === 'skipMigrate');\n if (!property) {\n return;\n }\n\n if (!typescript.isPropertyAssignment(property)) {\n report(property, 'skipMigrate is a shorthand property; left untouched');\n return;\n }\n\n if (argument.properties.some((candidate) => nameOf(candidate) === 'migration')) {\n report(property, 'skipMigrate and migration are both set; left untouched');\n return;\n }\n\n const { initializer } = property;\n if (initializer.kind === typescript.SyntaxKind.TrueKeyword) {\n edits.push({\n start: property.getStart(sourceFile),\n end: property.end,\n text: 'migration: { use: false }',\n });\n } else if (initializer.kind === typescript.SyntaxKind.FalseKeyword) {\n edits.push(removal(property));\n } else {\n report(property, 'skipMigrate is not a boolean literal; left untouched');\n return;\n }\n\n rewritten += 1;\n };\n\n const visit = (node: ts.Node) => {\n if (\n typescript.isDecorator(node) &&\n typescript.isCallExpression(node.expression) &&\n isModelCallee(node.expression.expression)\n ) {\n const argument = node.expression.arguments[0];\n\n if (argument && typescript.isObjectLiteralExpression(argument)) {\n const settingsProperty = argument.properties.find(\n (property) => nameOf(property) === 'settings',\n );\n\n if (settingsProperty) {\n if (\n typescript.isPropertyAssignment(settingsProperty) &&\n typescript.isObjectLiteralExpression(settingsProperty.initializer)\n ) {\n migrateSettings(settingsProperty.initializer);\n } else {\n report(\n settingsProperty,\n 'settings is not an object literal (a variable, a call or a shorthand); left untouched',\n );\n }\n }\n\n migrateSkipMigrate(argument);\n } else if (argument) {\n report(\n argument,\n '@model argument is not an object literal (a variable or a call); left untouched',\n );\n }\n }\n\n typescript.forEachChild(node, visit);\n };\n\n visit(sourceFile);\n\n // Neighbouring removals can touch the same comma: merge those, then apply from the end so\n // earlier offsets stay valid.\n const ascending = [...edits].sort((a, b) => a.start - b.start || a.end - b.end);\n const merged: IEdit[] = [];\n for (const edit of ascending) {\n const previous = merged[merged.length - 1];\n if (previous && edit.start < previous.end && previous.text === '' && edit.text === '') {\n previous.end = Math.max(previous.end, edit.end);\n continue;\n }\n\n merged.push({ ...edit });\n }\n\n let output = source;\n for (const edit of merged.reverse()) {\n output = output.slice(0, edit.start) + edit.text + output.slice(edit.end);\n }\n\n return { output, changed: output !== source, rewritten, reports };\n};\n"]}
package/dist/cli/index.js CHANGED
@@ -1,17 +1,36 @@
1
1
  #!/usr/bin/env bun
2
2
  "use strict";
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
+ const check_1 = require("./check");
4
5
  const clean_1 = require("./clean");
5
6
  const codemod_1 = require("./codemod");
6
7
  const lint_1 = require("./lint");
7
- const USAGE = 'Usage: devz lint [--fix] [files] | devz clean | devz codemod model-settings [paths...] [--check]';
8
+ const USAGE = `Usage: devz <command> [options]
9
+
10
+ Commands:
11
+ lint [--fix] [files] oxlint, ESLint and the formatter; --fix writes
12
+ check purity --claims <file> [package] [--json] probe every entry claimed browser-pure (needs a build)
13
+ check module-cycles | split-report | catalog shared repository gates; devz check --help lists their options
14
+ clean remove dist, node_modules/.cache and *.tsbuildinfo
15
+ codemod model-settings [paths...] [--write] move @model settings to the grouped shape (dry run unless --write)
16
+ codemod drop-redundant-casts [paths...] remove \`as X\` casts the compiler no longer needs (dry run unless --write)
17
+ codemod const-classes [paths...] turn a string-literal union into a const class (dry run unless --write)
18
+
19
+ Run \`devz clean --help\` or \`devz codemod --help\` for a command's options.`;
8
20
  const main = async (opts) => {
9
21
  const [command, ...args] = opts.argv;
22
+ if (command === undefined || command === '--help' || command === '-h') {
23
+ console.log(USAGE);
24
+ return 0;
25
+ }
10
26
  if (command === 'lint') {
11
27
  return lint_1.LintCommand.run({ root: process.cwd(), args });
12
28
  }
29
+ if (command === 'check') {
30
+ return check_1.CheckCommand.run({ root: process.cwd(), args });
31
+ }
13
32
  if (command === 'clean') {
14
- return clean_1.CleanCommand.run({ root: process.cwd() });
33
+ return clean_1.CleanCommand.run({ root: process.cwd(), args });
15
34
  }
16
35
  if (command === 'codemod') {
17
36
  return codemod_1.CodemodCommand.run({ root: process.cwd(), args });
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":";;;AACA,mCAAuC;AACvC,uCAA2C;AAC3C,iCAAqC;AAErC,MAAM,KAAK,GACT,kGAAkG,CAAC;AAErG,MAAM,IAAI,GAAG,KAAK,EAAE,IAAwB,EAAmB,EAAE;IAC/D,MAAM,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC;IAErC,IAAI,OAAO,KAAK,MAAM,EAAE,CAAC;QACvB,OAAO,kBAAW,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,GAAG,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;IACxD,CAAC;IAED,IAAI,OAAO,KAAK,OAAO,EAAE,CAAC;QACxB,OAAO,oBAAY,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;IACnD,CAAC;IAED,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QAC1B,OAAO,wBAAc,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,GAAG,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;IAC3D,CAAC;IAED,OAAO,CAAC,KAAK,CAAC,0BAA0B,OAAO,IAAI,EAAE,MAAM,KAAK,EAAE,CAAC,CAAC;IACpE,OAAO,CAAC,CAAC;AACX,CAAC,CAAC;AAEF,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CACxC,CAAC,QAAQ,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,EACpC,CAAC,KAAc,EAAE,EAAE;IACjB,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IACrB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CACF,CAAC","sourcesContent":["#!/usr/bin/env bun\nimport { CleanCommand } from './clean';\nimport { CodemodCommand } from './codemod';\nimport { LintCommand } from './lint';\n\nconst USAGE =\n 'Usage: devz lint [--fix] [files] | devz clean | devz codemod model-settings [paths...] [--check]';\n\nconst main = async (opts: { argv: string[] }): Promise<number> => {\n const [command, ...args] = opts.argv;\n\n if (command === 'lint') {\n return LintCommand.run({ root: process.cwd(), args });\n }\n\n if (command === 'clean') {\n return CleanCommand.run({ root: process.cwd() });\n }\n\n if (command === 'codemod') {\n return CodemodCommand.run({ root: process.cwd(), args });\n }\n\n console.error(`devz: unknown command \"${command ?? ''}\"\\n${USAGE}`);\n return 1;\n};\n\nmain({ argv: process.argv.slice(2) }).then(\n (exitCode) => process.exit(exitCode),\n (error: unknown) => {\n console.error(error);\n process.exit(1);\n },\n);\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":";;;AACA,mCAAuC;AACvC,mCAAuC;AACvC,uCAA2C;AAC3C,iCAAqC;AAErC,MAAM,KAAK,GAAG;;;;;;;;;;;8EAWgE,CAAC;AAE/E,MAAM,IAAI,GAAG,KAAK,EAAE,IAAwB,EAAmB,EAAE;IAC/D,MAAM,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC;IAErC,IAAI,OAAO,KAAK,SAAS,IAAI,OAAO,KAAK,QAAQ,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;QACtE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QACnB,OAAO,CAAC,CAAC;IACX,CAAC;IAED,IAAI,OAAO,KAAK,MAAM,EAAE,CAAC;QACvB,OAAO,kBAAW,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,GAAG,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;IACxD,CAAC;IAED,IAAI,OAAO,KAAK,OAAO,EAAE,CAAC;QACxB,OAAO,oBAAY,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,GAAG,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;IACzD,CAAC;IAED,IAAI,OAAO,KAAK,OAAO,EAAE,CAAC;QACxB,OAAO,oBAAY,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,GAAG,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;IACzD,CAAC;IAED,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QAC1B,OAAO,wBAAc,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,GAAG,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;IAC3D,CAAC;IAED,OAAO,CAAC,KAAK,CAAC,0BAA0B,OAAO,IAAI,EAAE,MAAM,KAAK,EAAE,CAAC,CAAC;IACpE,OAAO,CAAC,CAAC;AACX,CAAC,CAAC;AAEF,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CACxC,CAAC,QAAQ,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,EACpC,CAAC,KAAc,EAAE,EAAE;IACjB,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IACrB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CACF,CAAC","sourcesContent":["#!/usr/bin/env bun\nimport { CheckCommand } from './check';\nimport { CleanCommand } from './clean';\nimport { CodemodCommand } from './codemod';\nimport { LintCommand } from './lint';\n\nconst USAGE = `Usage: devz <command> [options]\n\nCommands:\n lint [--fix] [files] oxlint, ESLint and the formatter; --fix writes\n check purity --claims <file> [package] [--json] probe every entry claimed browser-pure (needs a build)\n check module-cycles | split-report | catalog shared repository gates; devz check --help lists their options\n clean remove dist, node_modules/.cache and *.tsbuildinfo\n codemod model-settings [paths...] [--write] move @model settings to the grouped shape (dry run unless --write)\n codemod drop-redundant-casts [paths...] remove \\`as X\\` casts the compiler no longer needs (dry run unless --write)\n codemod const-classes [paths...] turn a string-literal union into a const class (dry run unless --write)\n\nRun \\`devz clean --help\\` or \\`devz codemod --help\\` for a command's options.`;\n\nconst main = async (opts: { argv: string[] }): Promise<number> => {\n const [command, ...args] = opts.argv;\n\n if (command === undefined || command === '--help' || command === '-h') {\n console.log(USAGE);\n return 0;\n }\n\n if (command === 'lint') {\n return LintCommand.run({ root: process.cwd(), args });\n }\n\n if (command === 'check') {\n return CheckCommand.run({ root: process.cwd(), args });\n }\n\n if (command === 'clean') {\n return CleanCommand.run({ root: process.cwd(), args });\n }\n\n if (command === 'codemod') {\n return CodemodCommand.run({ root: process.cwd(), args });\n }\n\n console.error(`devz: unknown command \"${command ?? ''}\"\\n${USAGE}`);\n return 1;\n};\n\nmain({ argv: process.argv.slice(2) }).then(\n (exitCode) => process.exit(exitCode),\n (error: unknown) => {\n console.error(error);\n process.exit(1);\n },\n);\n"]}
@@ -6,6 +6,7 @@ export declare class AstNodeTypes {
6
6
  static readonly FUNCTION_EXPRESSION = "FunctionExpression";
7
7
  static readonly ARROW_FUNCTION_EXPRESSION = "ArrowFunctionExpression";
8
8
  static readonly EXPORT_NAMED_DECLARATION = "ExportNamedDeclaration";
9
+ static readonly UNION_TYPE = "TSUnionType";
9
10
  }
10
11
  /** The ESLint namespace the house rules live under: `venizia/<rule>`. */
11
12
  export declare const HOUSE_PLUGIN_NAMESPACE = "venizia";
@@ -1 +1 @@
1
- {"version":3,"file":"common.d.ts","sourceRoot":"","sources":["../../../src/linters/house/common.ts"],"names":[],"mappings":"AAAA,8HAA8H;AAC9H,qBAAa,YAAY;IACvB,MAAM,CAAC,QAAQ,CAAC,cAAc,mBAAmB;IACjD,MAAM,CAAC,QAAQ,CAAC,eAAe,oBAAoB;IACnD,MAAM,CAAC,QAAQ,CAAC,oBAAoB,yBAAyB;IAC7D,MAAM,CAAC,QAAQ,CAAC,mBAAmB,wBAAwB;IAC3D,MAAM,CAAC,QAAQ,CAAC,yBAAyB,6BAA6B;IACtE,MAAM,CAAC,QAAQ,CAAC,wBAAwB,4BAA4B;CACrE;AAED,yEAAyE;AACzE,eAAO,MAAM,sBAAsB,YAAY,CAAC;AAEhD,qHAAqH;AACrH,eAAO,MAAM,SAAS,GAAI,MAAM;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,KAAG,OAKhE,CAAC;AAEF,8EAA8E;AAC9E,eAAO,MAAM,QAAQ,GAAI,MAAM;IAAE,IAAI,EAAE,OAAO,CAAA;CAAE,KAAG,MAAM,GAAG,SAG3D,CAAC"}
1
+ {"version":3,"file":"common.d.ts","sourceRoot":"","sources":["../../../src/linters/house/common.ts"],"names":[],"mappings":"AAAA,8HAA8H;AAC9H,qBAAa,YAAY;IACvB,MAAM,CAAC,QAAQ,CAAC,cAAc,mBAAmB;IACjD,MAAM,CAAC,QAAQ,CAAC,eAAe,oBAAoB;IACnD,MAAM,CAAC,QAAQ,CAAC,oBAAoB,yBAAyB;IAC7D,MAAM,CAAC,QAAQ,CAAC,mBAAmB,wBAAwB;IAC3D,MAAM,CAAC,QAAQ,CAAC,yBAAyB,6BAA6B;IACtE,MAAM,CAAC,QAAQ,CAAC,wBAAwB,4BAA4B;IACpE,MAAM,CAAC,QAAQ,CAAC,UAAU,iBAAiB;CAC5C;AAED,yEAAyE;AACzE,eAAO,MAAM,sBAAsB,YAAY,CAAC;AAEhD,qHAAqH;AACrH,eAAO,MAAM,SAAS,GAAI,MAAM;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,KAAG,OAKhE,CAAC;AAEF,8EAA8E;AAC9E,eAAO,MAAM,QAAQ,GAAI,MAAM;IAAE,IAAI,EAAE,OAAO,CAAA;CAAE,KAAG,MAAM,GAAG,SAG3D,CAAC"}
@@ -9,6 +9,7 @@ class AstNodeTypes {
9
9
  static { this.FUNCTION_EXPRESSION = 'FunctionExpression'; }
10
10
  static { this.ARROW_FUNCTION_EXPRESSION = 'ArrowFunctionExpression'; }
11
11
  static { this.EXPORT_NAMED_DECLARATION = 'ExportNamedDeclaration'; }
12
+ static { this.UNION_TYPE = 'TSUnionType'; }
12
13
  }
13
14
  exports.AstNodeTypes = AstNodeTypes;
14
15
  /** The ESLint namespace the house rules live under: `venizia/<rule>`. */
@@ -1 +1 @@
1
- {"version":3,"file":"common.js","sourceRoot":"","sources":["../../../src/linters/house/common.ts"],"names":[],"mappings":";;;AAAA,8HAA8H;AAC9H,MAAa,YAAY;aACP,mBAAc,GAAG,eAAe,CAAC;aACjC,oBAAe,GAAG,gBAAgB,CAAC;aACnC,yBAAoB,GAAG,qBAAqB,CAAC;aAC7C,wBAAmB,GAAG,oBAAoB,CAAC;aAC3C,8BAAyB,GAAG,yBAAyB,CAAC;aACtD,6BAAwB,GAAG,wBAAwB,CAAC;;AANtE,oCAOC;AAED,yEAAyE;AAC5D,QAAA,sBAAsB,GAAG,SAAS,CAAC;AAEhD,qHAAqH;AAC9G,MAAM,SAAS,GAAG,CAAC,IAAoC,EAAW,EAAE;IACzE,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;IAC3B,OAAO,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,IAAI,IAAI,GAAG,IAAI,IAAI;QAC7D,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC;QACxB,CAAC,CAAC,SAAS,CAAC;AAChB,CAAC,CAAC;AALW,QAAA,SAAS,aAKpB;AAEF,8EAA8E;AACvE,MAAM,QAAQ,GAAG,CAAC,IAAuB,EAAsB,EAAE;IACtE,MAAM,IAAI,GAAG,IAAA,iBAAS,EAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC,CAAC;IACzD,OAAO,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC;AACrD,CAAC,CAAC;AAHW,QAAA,QAAQ,YAGnB","sourcesContent":["/** The estree node types the house rules visit - computed visitor keys, so the names stay PascalCase as ESLint needs them. */\nexport class AstNodeTypes {\n static readonly NEW_EXPRESSION = 'NewExpression';\n static readonly CALL_EXPRESSION = 'CallExpression';\n static readonly FUNCTION_DECLARATION = 'FunctionDeclaration';\n static readonly FUNCTION_EXPRESSION = 'FunctionExpression';\n static readonly ARROW_FUNCTION_EXPRESSION = 'ArrowFunctionExpression';\n static readonly EXPORT_NAMED_DECLARATION = 'ExportNamedDeclaration';\n}\n\n/** The ESLint namespace the house rules live under: `venizia/<rule>`. */\nexport const HOUSE_PLUGIN_NAMESPACE = 'venizia';\n\n/** A field of an AST node, read without trusting its type: TypeScript nodes carry fields estree does not declare. */\nexport const readField = (opts: { node: unknown; key: string }): unknown => {\n const { node, key } = opts;\n return typeof node === 'object' && node !== null && key in node\n ? Reflect.get(node, key)\n : undefined;\n};\n\n/** The node's `type`, or `undefined` for anything that is not an AST node. */\nexport const nodeType = (opts: { node: unknown }): string | undefined => {\n const type = readField({ node: opts.node, key: 'type' });\n return typeof type === 'string' ? type : undefined;\n};\n"]}
1
+ {"version":3,"file":"common.js","sourceRoot":"","sources":["../../../src/linters/house/common.ts"],"names":[],"mappings":";;;AAAA,8HAA8H;AAC9H,MAAa,YAAY;aACP,mBAAc,GAAG,eAAe,CAAC;aACjC,oBAAe,GAAG,gBAAgB,CAAC;aACnC,yBAAoB,GAAG,qBAAqB,CAAC;aAC7C,wBAAmB,GAAG,oBAAoB,CAAC;aAC3C,8BAAyB,GAAG,yBAAyB,CAAC;aACtD,6BAAwB,GAAG,wBAAwB,CAAC;aACpD,eAAU,GAAG,aAAa,CAAC;;AAP7C,oCAQC;AAED,yEAAyE;AAC5D,QAAA,sBAAsB,GAAG,SAAS,CAAC;AAEhD,qHAAqH;AAC9G,MAAM,SAAS,GAAG,CAAC,IAAoC,EAAW,EAAE;IACzE,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;IAC3B,OAAO,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,IAAI,IAAI,GAAG,IAAI,IAAI;QAC7D,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC;QACxB,CAAC,CAAC,SAAS,CAAC;AAChB,CAAC,CAAC;AALW,QAAA,SAAS,aAKpB;AAEF,8EAA8E;AACvE,MAAM,QAAQ,GAAG,CAAC,IAAuB,EAAsB,EAAE;IACtE,MAAM,IAAI,GAAG,IAAA,iBAAS,EAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC,CAAC;IACzD,OAAO,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC;AACrD,CAAC,CAAC;AAHW,QAAA,QAAQ,YAGnB","sourcesContent":["/** The estree node types the house rules visit - computed visitor keys, so the names stay PascalCase as ESLint needs them. */\nexport class AstNodeTypes {\n static readonly NEW_EXPRESSION = 'NewExpression';\n static readonly CALL_EXPRESSION = 'CallExpression';\n static readonly FUNCTION_DECLARATION = 'FunctionDeclaration';\n static readonly FUNCTION_EXPRESSION = 'FunctionExpression';\n static readonly ARROW_FUNCTION_EXPRESSION = 'ArrowFunctionExpression';\n static readonly EXPORT_NAMED_DECLARATION = 'ExportNamedDeclaration';\n static readonly UNION_TYPE = 'TSUnionType';\n}\n\n/** The ESLint namespace the house rules live under: `venizia/<rule>`. */\nexport const HOUSE_PLUGIN_NAMESPACE = 'venizia';\n\n/** A field of an AST node, read without trusting its type: TypeScript nodes carry fields estree does not declare. */\nexport const readField = (opts: { node: unknown; key: string }): unknown => {\n const { node, key } = opts;\n return typeof node === 'object' && node !== null && key in node\n ? Reflect.get(node, key)\n : undefined;\n};\n\n/** The node's `type`, or `undefined` for anything that is not an AST node. */\nexport const nodeType = (opts: { node: unknown }): string | undefined => {\n const type = readField({ node: opts.node, key: 'type' });\n return typeof type === 'string' ? type : undefined;\n};\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"configs.d.ts","sourceRoot":"","sources":["../../../src/linters/house/configs.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AA8BrC;;;;;;;;;;GAUG;AACH,eAAO,MAAM,YAAY,EAAE,MAAM,CAAC,MAAM,EAAsD,CAAC;AAc/F,kHAAkH;AAClH,eAAO,MAAM,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAI5C,CAAC"}
1
+ {"version":3,"file":"configs.d.ts","sourceRoot":"","sources":["../../../src/linters/house/configs.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAkDrC;;;;;;;;;;GAUG;AACH,eAAO,MAAM,YAAY,EAAE,MAAM,CAAC,MAAM,EAAsD,CAAC;AAc/F,kHAAkH;AAClH,eAAO,MAAM,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAI5C,CAAC"}
@@ -5,16 +5,26 @@ const eslint_1 = require("../eslint");
5
5
  const jsx_files_1 = require("../jsx-files");
6
6
  const react_eslint_1 = require("../react-eslint");
7
7
  const common_1 = require("./common");
8
+ const const_class_values_rule_1 = require("./const-class-values.rule");
8
9
  const max_params_own_rule_1 = require("./max-params-own.rule");
9
10
  const no_leaked_render_rule_1 = require("./no-leaked-render.rule");
10
11
  const no_new_error_rule_1 = require("./no-new-error.rule");
11
12
  const plugin_1 = require("./plugin");
12
13
  const SOURCE_FILES = ['**/*.{ts,tsx,mts,cts}'];
13
14
  const TEST_FILES = ['**/__tests__/**', '**/*.test.{ts,tsx}', '**/*.spec.{ts,tsx}'];
15
+ /**
16
+ * V-C-10: no explicit cast. `as const` is always allowed; `satisfies`, a generic or a narrower type
17
+ * replaces the rest.
18
+ */
19
+ const NO_CAST_RULE = '@typescript-eslint/consistent-type-assertions';
14
20
  /**
15
21
  * The house rules: at most 5 positional parameters on a function we write, and errors thrown through
16
22
  * `getError` only. Tests are exempt from `no-new-error`: a test throws a plain `Error` on purpose, to
17
23
  * stand in for what a driver or a third-party library throws.
24
+ *
25
+ * Two rules only warn, so a project adopts them without failing its lint: `const-class-values` (V-C-08, a
26
+ * string-literal union in an exported declaration) and `consistent-type-assertions` (V-C-10, an `as X`
27
+ * cast). Tests are exempt from both: a test stubs what it does not build.
18
28
  */
19
29
  const houseRuleConfigs = [
20
30
  {
@@ -23,9 +33,18 @@ const houseRuleConfigs = [
23
33
  rules: {
24
34
  [max_params_own_rule_1.MaxParamsOwnRule.NAME]: max_params_own_rule_1.MaxParamsOwnRule.build(),
25
35
  [no_new_error_rule_1.NoNewErrorRule.NAME]: no_new_error_rule_1.NoNewErrorRule.build(),
36
+ [const_class_values_rule_1.ConstClassValuesRule.NAME]: const_class_values_rule_1.ConstClassValuesRule.build({ severity: 'warn' }),
37
+ [NO_CAST_RULE]: ['warn', { assertionStyle: 'never' }],
38
+ },
39
+ },
40
+ {
41
+ files: TEST_FILES,
42
+ rules: {
43
+ [no_new_error_rule_1.NoNewErrorRule.NAME]: 'off',
44
+ [const_class_values_rule_1.ConstClassValuesRule.NAME]: 'off',
45
+ [NO_CAST_RULE]: 'off',
26
46
  },
27
47
  },
28
- { files: TEST_FILES, rules: { [no_new_error_rule_1.NoNewErrorRule.NAME]: 'off' } },
29
48
  ];
30
49
  /**
31
50
  * The ESLint side of a project that lints with oxlint: the naming convention plus the house rules -
@@ -1 +1 @@
1
- {"version":3,"file":"configs.js","sourceRoot":"","sources":["../../../src/linters/house/configs.ts"],"names":[],"mappings":";;;AACA,sCAAoD;AACpD,4CAAyC;AACzC,kDAA+D;AAC/D,qCAAkD;AAClD,+DAAyD;AACzD,mEAA6D;AAC7D,2DAAqD;AACrD,qCAA6C;AAE7C,MAAM,YAAY,GAAG,CAAC,uBAAuB,CAAC,CAAC;AAC/C,MAAM,UAAU,GAAG,CAAC,iBAAiB,EAAE,oBAAoB,EAAE,oBAAoB,CAAC,CAAC;AAEnF;;;;GAIG;AACH,MAAM,gBAAgB,GAAoB;IACxC;QACE,KAAK,EAAE,YAAY;QACnB,OAAO,EAAE,EAAE,CAAC,+BAAsB,CAAC,EAAE,0BAAiB,EAAE;QACxD,KAAK,EAAE;YACL,CAAC,sCAAgB,CAAC,IAAI,CAAC,EAAE,sCAAgB,CAAC,KAAK,EAAE;YACjD,CAAC,kCAAc,CAAC,IAAI,CAAC,EAAE,kCAAc,CAAC,KAAK,EAAE;SAC9C;KACF;IACD,EAAE,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,EAAE,CAAC,kCAAc,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,EAAE;CAC/D,CAAC;AAEF;;;;;;;;;;GAUG;AACU,QAAA,YAAY,GAAoB,CAAC,GAAG,gCAAuB,EAAE,GAAG,gBAAgB,CAAC,CAAC;AAE/F;;;GAGG;AACH,MAAM,gBAAgB,GAAoB;IACxC;QACE,KAAK,EAAE,qBAAS;QAChB,OAAO,EAAE,EAAE,CAAC,+BAAsB,CAAC,EAAE,0BAAiB,EAAE;QACxD,KAAK,EAAE,EAAE,CAAC,0CAAkB,CAAC,IAAI,CAAC,EAAE,0CAAkB,CAAC,KAAK,EAAE,EAAE;KACjE;CACF,CAAC;AAEF,kHAAkH;AACrG,QAAA,iBAAiB,GAAoB;IAChD,GAAG,2CAA4B;IAC/B,GAAG,gBAAgB;IACnB,GAAG,gBAAgB;CACpB,CAAC","sourcesContent":["import type { Linter } from 'eslint';\nimport { namingConventionConfigs } from '../eslint';\nimport { JSX_FILES } from '../jsx-files';\nimport { reactNamingConventionConfigs } from '../react-eslint';\nimport { HOUSE_PLUGIN_NAMESPACE } from './common';\nimport { MaxParamsOwnRule } from './max-params-own.rule';\nimport { NoLeakedRenderRule } from './no-leaked-render.rule';\nimport { NoNewErrorRule } from './no-new-error.rule';\nimport { houseEslintPlugin } from './plugin';\n\nconst SOURCE_FILES = ['**/*.{ts,tsx,mts,cts}'];\nconst TEST_FILES = ['**/__tests__/**', '**/*.test.{ts,tsx}', '**/*.spec.{ts,tsx}'];\n\n/**\n * The house rules: at most 5 positional parameters on a function we write, and errors thrown through\n * `getError` only. Tests are exempt from `no-new-error`: a test throws a plain `Error` on purpose, to\n * stand in for what a driver or a third-party library throws.\n */\nconst houseRuleConfigs: Linter.Config[] = [\n {\n files: SOURCE_FILES,\n plugins: { [HOUSE_PLUGIN_NAMESPACE]: houseEslintPlugin },\n rules: {\n [MaxParamsOwnRule.NAME]: MaxParamsOwnRule.build(),\n [NoNewErrorRule.NAME]: NoNewErrorRule.build(),\n },\n },\n { files: TEST_FILES, rules: { [NoNewErrorRule.NAME]: 'off' } },\n];\n\n/**\n * The ESLint side of a project that lints with oxlint: the naming convention plus the house rules -\n * everything oxlint cannot express. Run it next to `oxlintConfigs`.\n *\n * ```js\n * // .configs/lints/eslint.config.mjs\n * import { houseConfigs } from '@venizia/dev-configs/linters';\n *\n * export default houseConfigs;\n * ```\n */\nexport const houseConfigs: Linter.Config[] = [...namingConventionConfigs, ...houseRuleConfigs];\n\n/**\n * The React house rule: a JSX child is drawn with `cond ? <X /> : null`, never `cond && <X />`, which\n * draws `0` when `cond` is `0`.\n */\nconst reactRuleConfigs: Linter.Config[] = [\n {\n files: JSX_FILES,\n plugins: { [HOUSE_PLUGIN_NAMESPACE]: houseEslintPlugin },\n rules: { [NoLeakedRenderRule.NAME]: NoLeakedRenderRule.build() },\n },\n];\n\n/** `houseConfigs` for a React project: `reactNamingConventionConfigs`, the house rules and `no-leaked-render`. */\nexport const reactHouseConfigs: Linter.Config[] = [\n ...reactNamingConventionConfigs,\n ...houseRuleConfigs,\n ...reactRuleConfigs,\n];\n"]}
1
+ {"version":3,"file":"configs.js","sourceRoot":"","sources":["../../../src/linters/house/configs.ts"],"names":[],"mappings":";;;AACA,sCAAoD;AACpD,4CAAyC;AACzC,kDAA+D;AAC/D,qCAAkD;AAClD,uEAAiE;AACjE,+DAAyD;AACzD,mEAA6D;AAC7D,2DAAqD;AACrD,qCAA6C;AAE7C,MAAM,YAAY,GAAG,CAAC,uBAAuB,CAAC,CAAC;AAC/C,MAAM,UAAU,GAAG,CAAC,iBAAiB,EAAE,oBAAoB,EAAE,oBAAoB,CAAC,CAAC;AAEnF;;;GAGG;AACH,MAAM,YAAY,GAAG,+CAA+C,CAAC;AAErE;;;;;;;;GAQG;AACH,MAAM,gBAAgB,GAAoB;IACxC;QACE,KAAK,EAAE,YAAY;QACnB,OAAO,EAAE,EAAE,CAAC,+BAAsB,CAAC,EAAE,0BAAiB,EAAE;QACxD,KAAK,EAAE;YACL,CAAC,sCAAgB,CAAC,IAAI,CAAC,EAAE,sCAAgB,CAAC,KAAK,EAAE;YACjD,CAAC,kCAAc,CAAC,IAAI,CAAC,EAAE,kCAAc,CAAC,KAAK,EAAE;YAC7C,CAAC,8CAAoB,CAAC,IAAI,CAAC,EAAE,8CAAoB,CAAC,KAAK,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC;YAC7E,CAAC,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,cAAc,EAAE,OAAO,EAAE,CAAC;SACtD;KACF;IACD;QACE,KAAK,EAAE,UAAU;QACjB,KAAK,EAAE;YACL,CAAC,kCAAc,CAAC,IAAI,CAAC,EAAE,KAAK;YAC5B,CAAC,8CAAoB,CAAC,IAAI,CAAC,EAAE,KAAK;YAClC,CAAC,YAAY,CAAC,EAAE,KAAK;SACtB;KACF;CACF,CAAC;AAEF;;;;;;;;;;GAUG;AACU,QAAA,YAAY,GAAoB,CAAC,GAAG,gCAAuB,EAAE,GAAG,gBAAgB,CAAC,CAAC;AAE/F;;;GAGG;AACH,MAAM,gBAAgB,GAAoB;IACxC;QACE,KAAK,EAAE,qBAAS;QAChB,OAAO,EAAE,EAAE,CAAC,+BAAsB,CAAC,EAAE,0BAAiB,EAAE;QACxD,KAAK,EAAE,EAAE,CAAC,0CAAkB,CAAC,IAAI,CAAC,EAAE,0CAAkB,CAAC,KAAK,EAAE,EAAE;KACjE;CACF,CAAC;AAEF,kHAAkH;AACrG,QAAA,iBAAiB,GAAoB;IAChD,GAAG,2CAA4B;IAC/B,GAAG,gBAAgB;IACnB,GAAG,gBAAgB;CACpB,CAAC","sourcesContent":["import type { Linter } from 'eslint';\nimport { namingConventionConfigs } from '../eslint';\nimport { JSX_FILES } from '../jsx-files';\nimport { reactNamingConventionConfigs } from '../react-eslint';\nimport { HOUSE_PLUGIN_NAMESPACE } from './common';\nimport { ConstClassValuesRule } from './const-class-values.rule';\nimport { MaxParamsOwnRule } from './max-params-own.rule';\nimport { NoLeakedRenderRule } from './no-leaked-render.rule';\nimport { NoNewErrorRule } from './no-new-error.rule';\nimport { houseEslintPlugin } from './plugin';\n\nconst SOURCE_FILES = ['**/*.{ts,tsx,mts,cts}'];\nconst TEST_FILES = ['**/__tests__/**', '**/*.test.{ts,tsx}', '**/*.spec.{ts,tsx}'];\n\n/**\n * V-C-10: no explicit cast. `as const` is always allowed; `satisfies`, a generic or a narrower type\n * replaces the rest.\n */\nconst NO_CAST_RULE = '@typescript-eslint/consistent-type-assertions';\n\n/**\n * The house rules: at most 5 positional parameters on a function we write, and errors thrown through\n * `getError` only. Tests are exempt from `no-new-error`: a test throws a plain `Error` on purpose, to\n * stand in for what a driver or a third-party library throws.\n *\n * Two rules only warn, so a project adopts them without failing its lint: `const-class-values` (V-C-08, a\n * string-literal union in an exported declaration) and `consistent-type-assertions` (V-C-10, an `as X`\n * cast). Tests are exempt from both: a test stubs what it does not build.\n */\nconst houseRuleConfigs: Linter.Config[] = [\n {\n files: SOURCE_FILES,\n plugins: { [HOUSE_PLUGIN_NAMESPACE]: houseEslintPlugin },\n rules: {\n [MaxParamsOwnRule.NAME]: MaxParamsOwnRule.build(),\n [NoNewErrorRule.NAME]: NoNewErrorRule.build(),\n [ConstClassValuesRule.NAME]: ConstClassValuesRule.build({ severity: 'warn' }),\n [NO_CAST_RULE]: ['warn', { assertionStyle: 'never' }],\n },\n },\n {\n files: TEST_FILES,\n rules: {\n [NoNewErrorRule.NAME]: 'off',\n [ConstClassValuesRule.NAME]: 'off',\n [NO_CAST_RULE]: 'off',\n },\n },\n];\n\n/**\n * The ESLint side of a project that lints with oxlint: the naming convention plus the house rules -\n * everything oxlint cannot express. Run it next to `oxlintConfigs`.\n *\n * ```js\n * // .configs/lints/eslint.config.mjs\n * import { houseConfigs } from '@venizia/dev-configs/linters';\n *\n * export default houseConfigs;\n * ```\n */\nexport const houseConfigs: Linter.Config[] = [...namingConventionConfigs, ...houseRuleConfigs];\n\n/**\n * The React house rule: a JSX child is drawn with `cond ? <X /> : null`, never `cond && <X />`, which\n * draws `0` when `cond` is `0`.\n */\nconst reactRuleConfigs: Linter.Config[] = [\n {\n files: JSX_FILES,\n plugins: { [HOUSE_PLUGIN_NAMESPACE]: houseEslintPlugin },\n rules: { [NoLeakedRenderRule.NAME]: NoLeakedRenderRule.build() },\n },\n];\n\n/** `houseConfigs` for a React project: `reactNamingConventionConfigs`, the house rules and `no-leaked-render`. */\nexport const reactHouseConfigs: Linter.Config[] = [\n ...reactNamingConventionConfigs,\n ...houseRuleConfigs,\n ...reactRuleConfigs,\n];\n"]}
@@ -2,13 +2,16 @@ import type { Linter, Rule } from 'eslint';
2
2
  import type { TRuleSeverity } from '../rules/common';
3
3
  /**
4
4
  * `venizia/const-class-values`. An enumerable string is a const class plus `TConstValue<typeof X>`,
5
- * never an exported union of string literals. Only a type whose name ends like a logic value is
6
- * checked (`State`, `Status`, `Stage`, `Mode`, `Kind`, `Type` by default): any other string union may
7
- * be a plain parameter type.
5
+ * never a union of string literals in an exported declaration: a type alias, an interface member, a
6
+ * generic constraint, a parameter or a return type of an exported function or class.
7
+ *
8
+ * Not counted: a union that is not all string literals (a `null` or `undefined` member is ignored),
9
+ * a key set (`Pick`, `Omit`, `Extract`, `Exclude`, `Record` arguments and mapped-type keys), and a
10
+ * declaration that is not exported. `namePattern` narrows the rule to exported type aliases whose name
11
+ * matches it (`(State|Status)$`), for a project that adopts the rule one name at a time.
8
12
  */
9
13
  export declare class ConstClassValuesRule {
10
14
  static readonly NAME = "venizia/const-class-values";
11
- static readonly DEFAULT_NAME_PATTERN = "(State|Status|Stage|Mode|Kind|Type)$";
12
15
  static readonly RULE: Rule.RuleModule;
13
16
  static build(opts?: {
14
17
  severity?: TRuleSeverity;
@@ -1 +1 @@
1
- {"version":3,"file":"const-class-values.rule.d.ts","sourceRoot":"","sources":["../../../src/linters/house/const-class-values.rule.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAC3C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAGrD;;;;;GAKG;AACH,qBAAa,oBAAoB;IAC/B,MAAM,CAAC,QAAQ,CAAC,IAAI,gCAAkD;IAEtE,MAAM,CAAC,QAAQ,CAAC,oBAAoB,0CAA0C;IAE9E,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,UAAU,CA0CnC;IAEF,MAAM,CAAC,KAAK,CAAC,IAAI,GAAE;QAAE,QAAQ,CAAC,EAAE,aAAa,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAO,GAAG,MAAM,CAAC,SAAS;CAI9F"}
1
+ {"version":3,"file":"const-class-values.rule.d.ts","sourceRoot":"","sources":["../../../src/linters/house/const-class-values.rule.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAC3C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAoDrD;;;;;;;;;GASG;AACH,qBAAa,oBAAoB;IAC/B,MAAM,CAAC,QAAQ,CAAC,IAAI,gCAAkD;IAEtE,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,UAAU,CAsDnC;IAEF,MAAM,CAAC,KAAK,CAAC,IAAI,GAAE;QAAE,QAAQ,CAAC,EAAE,aAAa,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAO,GAAG,MAAM,CAAC,SAAS;CAI9F"}
@@ -2,15 +2,55 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ConstClassValuesRule = void 0;
4
4
  const common_1 = require("./common");
5
+ /** Utility types whose type argument is a set of keys, not an enumerable value: `Pick<T, 'a' | 'b'>`. */
6
+ const KEY_SET_TYPES = new Set(['Pick', 'Omit', 'Extract', 'Exclude', 'Record']);
7
+ /** The union is a type argument of a key-set utility type, or the key range of a mapped type. */
8
+ const isKeySet = (opts) => {
9
+ const parent = (0, common_1.readField)({ node: opts.node, key: 'parent' });
10
+ if ((0, common_1.nodeType)({ node: parent }) === 'TSMappedType') {
11
+ return true;
12
+ }
13
+ if ((0, common_1.nodeType)({ node: parent }) !== 'TSTypeParameterInstantiation') {
14
+ return false;
15
+ }
16
+ const reference = (0, common_1.readField)({ node: parent, key: 'parent' });
17
+ const name = (0, common_1.readField)({ node: (0, common_1.readField)({ node: reference, key: 'typeName' }), key: 'name' });
18
+ return (0, common_1.nodeType)({ node: reference }) === 'TSTypeReference' && KEY_SET_TYPES.has(String(name));
19
+ };
20
+ /** The statement of the module that holds the node: the node's last ancestor before `Program`. */
21
+ const topLevelStatement = (opts) => {
22
+ let current = opts.node;
23
+ while (current) {
24
+ const parent = (0, common_1.readField)({ node: current, key: 'parent' });
25
+ if ((0, common_1.nodeType)({ node: parent }) === 'Program') {
26
+ return current;
27
+ }
28
+ current = parent;
29
+ }
30
+ return undefined;
31
+ };
32
+ const isStringLiteral = (opts) => {
33
+ const { member } = opts;
34
+ return ((0, common_1.nodeType)({ node: member }) === 'TSLiteralType' &&
35
+ typeof (0, common_1.readField)({ node: (0, common_1.readField)({ node: member, key: 'literal' }), key: 'value' }) ===
36
+ 'string');
37
+ };
38
+ const isNullish = (opts) => {
39
+ const type = (0, common_1.nodeType)({ node: opts.member });
40
+ return type === 'TSNullKeyword' || type === 'TSUndefinedKeyword';
41
+ };
5
42
  /**
6
43
  * `venizia/const-class-values`. An enumerable string is a const class plus `TConstValue<typeof X>`,
7
- * never an exported union of string literals. Only a type whose name ends like a logic value is
8
- * checked (`State`, `Status`, `Stage`, `Mode`, `Kind`, `Type` by default): any other string union may
9
- * be a plain parameter type.
44
+ * never a union of string literals in an exported declaration: a type alias, an interface member, a
45
+ * generic constraint, a parameter or a return type of an exported function or class.
46
+ *
47
+ * Not counted: a union that is not all string literals (a `null` or `undefined` member is ignored),
48
+ * a key set (`Pick`, `Omit`, `Extract`, `Exclude`, `Record` arguments and mapped-type keys), and a
49
+ * declaration that is not exported. `namePattern` narrows the rule to exported type aliases whose name
50
+ * matches it (`(State|Status)$`), for a project that adopts the rule one name at a time.
10
51
  */
11
52
  class ConstClassValuesRule {
12
53
  static { this.NAME = `${common_1.HOUSE_PLUGIN_NAMESPACE}/const-class-values`; }
13
- static { this.DEFAULT_NAME_PATTERN = '(State|Status|Stage|Mode|Kind|Type)$'; }
14
54
  static { this.RULE = {
15
55
  meta: {
16
56
  type: 'suggestion',
@@ -22,30 +62,42 @@ class ConstClassValuesRule {
22
62
  create: (context) => {
23
63
  const options = context.options[0];
24
64
  const configured = (0, common_1.readField)({ node: options, key: 'namePattern' });
25
- const namePattern = new RegExp(typeof configured === 'string' ? configured : ConstClassValuesRule.DEFAULT_NAME_PATTERN);
26
- const isStringLiteral = (member) => (0, common_1.nodeType)({ node: member }) === 'TSLiteralType' &&
27
- typeof (0, common_1.readField)({ node: (0, common_1.readField)({ node: member, key: 'literal' }), key: 'value' }) ===
28
- 'string';
65
+ const namePattern = typeof configured === 'string' ? new RegExp(configured) : undefined;
66
+ const isNamed = (opts) => {
67
+ const { statement, node } = opts;
68
+ const declaration = (0, common_1.readField)({ node: statement, key: 'declaration' });
69
+ const name = (0, common_1.readField)({ node: (0, common_1.readField)({ node: declaration, key: 'id' }), key: 'name' });
70
+ return (namePattern === undefined ||
71
+ ((0, common_1.nodeType)({ node: declaration }) === 'TSTypeAliasDeclaration' &&
72
+ (0, common_1.readField)({ node: declaration, key: 'typeAnnotation' }) === node &&
73
+ typeof name === 'string' &&
74
+ namePattern.test(name)));
75
+ };
29
76
  return {
30
- [`${common_1.AstNodeTypes.EXPORT_NAMED_DECLARATION} > TSTypeAliasDeclaration`]: (node) => {
31
- const id = (0, common_1.readField)({ node, key: 'id' });
32
- const name = (0, common_1.readField)({ node: id, key: 'name' });
33
- const typeAnnotation = (0, common_1.readField)({ node, key: 'typeAnnotation' });
34
- const members = (0, common_1.readField)({ node: typeAnnotation, key: 'types' });
35
- if (typeof name === 'string' &&
36
- namePattern.test(name) &&
37
- (0, common_1.nodeType)({ node: typeAnnotation }) === 'TSUnionType' &&
38
- Array.isArray(members) &&
39
- members.every(isStringLiteral)) {
40
- context.report({ node, messageId: 'constClass' });
77
+ [common_1.AstNodeTypes.UNION_TYPE]: (node) => {
78
+ const members = (0, common_1.readField)({ node, key: 'types' });
79
+ if (!Array.isArray(members)) {
80
+ return;
81
+ }
82
+ const values = members.filter((member) => !isNullish({ member }));
83
+ if (values.length < 2 || !values.every((member) => isStringLiteral({ member }))) {
84
+ return;
85
+ }
86
+ const statement = topLevelStatement({ node });
87
+ const statementType = (0, common_1.nodeType)({ node: statement });
88
+ const isExported = statementType === common_1.AstNodeTypes.EXPORT_NAMED_DECLARATION ||
89
+ statementType === 'ExportDefaultDeclaration';
90
+ if (!isExported || isKeySet({ node }) || !isNamed({ statement, node })) {
91
+ return;
41
92
  }
93
+ context.report({ node, messageId: 'constClass' });
42
94
  },
43
95
  };
44
96
  },
45
97
  }; }
46
98
  static build(opts = {}) {
47
- const { severity = 'error', namePattern = ConstClassValuesRule.DEFAULT_NAME_PATTERN } = opts;
48
- return [severity, { namePattern }];
99
+ const { severity = 'error', namePattern } = opts;
100
+ return namePattern === undefined ? [severity] : [severity, { namePattern }];
49
101
  }
50
102
  }
51
103
  exports.ConstClassValuesRule = ConstClassValuesRule;
@@ -1 +1 @@
1
- {"version":3,"file":"const-class-values.rule.js","sourceRoot":"","sources":["../../../src/linters/house/const-class-values.rule.ts"],"names":[],"mappings":";;;AAEA,qCAAqF;AAErF;;;;;GAKG;AACH,MAAa,oBAAoB;aACf,SAAI,GAAG,GAAG,+BAAsB,qBAAqB,CAAC;aAEtD,yBAAoB,GAAG,sCAAsC,CAAC;aAE9D,SAAI,GAAoB;QACtC,IAAI,EAAE;YACJ,IAAI,EAAE,YAAY;YAClB,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,EAAE,WAAW,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC;YAC7E,QAAQ,EAAE;gBACR,UAAU,EACR,mGAAmG;aACtG;SACF;QACD,MAAM,EAAE,CAAC,OAAO,EAAE,EAAE;YAClB,MAAM,OAAO,GAAY,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;YAC5C,MAAM,UAAU,GAAG,IAAA,kBAAS,EAAC,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,aAAa,EAAE,CAAC,CAAC;YACpE,MAAM,WAAW,GAAG,IAAI,MAAM,CAC5B,OAAO,UAAU,KAAK,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,oBAAoB,CAAC,oBAAoB,CACxF,CAAC;YAEF,MAAM,eAAe,GAAG,CAAC,MAAe,EAAE,EAAE,CAC1C,IAAA,iBAAQ,EAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,KAAK,eAAe;gBAC9C,OAAO,IAAA,kBAAS,EAAC,EAAE,IAAI,EAAE,IAAA,kBAAS,EAAC,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,SAAS,EAAE,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC;oBACnF,QAAQ,CAAC;YAEb,OAAO;gBACL,CAAC,GAAG,qBAAY,CAAC,wBAAwB,2BAA2B,CAAC,EAAE,CACrE,IAAe,EACf,EAAE;oBACF,MAAM,EAAE,GAAG,IAAA,kBAAS,EAAC,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC;oBAC1C,MAAM,IAAI,GAAG,IAAA,kBAAS,EAAC,EAAE,IAAI,EAAE,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC,CAAC;oBAClD,MAAM,cAAc,GAAG,IAAA,kBAAS,EAAC,EAAE,IAAI,EAAE,GAAG,EAAE,gBAAgB,EAAE,CAAC,CAAC;oBAClE,MAAM,OAAO,GAAG,IAAA,kBAAS,EAAC,EAAE,IAAI,EAAE,cAAc,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC,CAAC;oBAElE,IACE,OAAO,IAAI,KAAK,QAAQ;wBACxB,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC;wBACtB,IAAA,iBAAQ,EAAC,EAAE,IAAI,EAAE,cAAc,EAAE,CAAC,KAAK,aAAa;wBACpD,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC;wBACtB,OAAO,CAAC,KAAK,CAAC,eAAe,CAAC,EAC9B,CAAC;wBACD,OAAO,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,YAAY,EAAE,CAAC,CAAC;oBACpD,CAAC;gBACH,CAAC;aACF,CAAC;QACJ,CAAC;KACF,CAAC;IAEF,MAAM,CAAC,KAAK,CAAC,OAA2D,EAAE;QACxE,MAAM,EAAE,QAAQ,GAAG,OAAO,EAAE,WAAW,GAAG,oBAAoB,CAAC,oBAAoB,EAAE,GAAG,IAAI,CAAC;QAC7F,OAAO,CAAC,QAAQ,EAAE,EAAE,WAAW,EAAE,CAAC,CAAC;IACrC,CAAC;;AApDH,oDAqDC","sourcesContent":["import type { Linter, Rule } from 'eslint';\nimport type { TRuleSeverity } from '../rules/common';\nimport { AstNodeTypes, HOUSE_PLUGIN_NAMESPACE, nodeType, readField } from './common';\n\n/**\n * `venizia/const-class-values`. An enumerable string is a const class plus `TConstValue<typeof X>`,\n * never an exported union of string literals. Only a type whose name ends like a logic value is\n * checked (`State`, `Status`, `Stage`, `Mode`, `Kind`, `Type` by default): any other string union may\n * be a plain parameter type.\n */\nexport class ConstClassValuesRule {\n static readonly NAME = `${HOUSE_PLUGIN_NAMESPACE}/const-class-values`;\n\n static readonly DEFAULT_NAME_PATTERN = '(State|Status|Stage|Mode|Kind|Type)$';\n\n static readonly RULE: Rule.RuleModule = {\n meta: {\n type: 'suggestion',\n schema: [{ type: 'object', properties: { namePattern: { type: 'string' } } }],\n messages: {\n constClass:\n 'An enumerable string is a const class plus TConstValue<typeof X>, not a union of string literals.',\n },\n },\n create: (context) => {\n const options: unknown = context.options[0];\n const configured = readField({ node: options, key: 'namePattern' });\n const namePattern = new RegExp(\n typeof configured === 'string' ? configured : ConstClassValuesRule.DEFAULT_NAME_PATTERN,\n );\n\n const isStringLiteral = (member: unknown) =>\n nodeType({ node: member }) === 'TSLiteralType' &&\n typeof readField({ node: readField({ node: member, key: 'literal' }), key: 'value' }) ===\n 'string';\n\n return {\n [`${AstNodeTypes.EXPORT_NAMED_DECLARATION} > TSTypeAliasDeclaration`]: (\n node: Rule.Node,\n ) => {\n const id = readField({ node, key: 'id' });\n const name = readField({ node: id, key: 'name' });\n const typeAnnotation = readField({ node, key: 'typeAnnotation' });\n const members = readField({ node: typeAnnotation, key: 'types' });\n\n if (\n typeof name === 'string' &&\n namePattern.test(name) &&\n nodeType({ node: typeAnnotation }) === 'TSUnionType' &&\n Array.isArray(members) &&\n members.every(isStringLiteral)\n ) {\n context.report({ node, messageId: 'constClass' });\n }\n },\n };\n },\n };\n\n static build(opts: { severity?: TRuleSeverity; namePattern?: string } = {}): Linter.RuleEntry {\n const { severity = 'error', namePattern = ConstClassValuesRule.DEFAULT_NAME_PATTERN } = opts;\n return [severity, { namePattern }];\n }\n}\n"]}
1
+ {"version":3,"file":"const-class-values.rule.js","sourceRoot":"","sources":["../../../src/linters/house/const-class-values.rule.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Linter, Rule } from 'eslint';\nimport type { TRuleSeverity } from '../rules/common';\nimport { AstNodeTypes, HOUSE_PLUGIN_NAMESPACE, nodeType, readField } from './common';\n\n/** Utility types whose type argument is a set of keys, not an enumerable value: `Pick<T, 'a' | 'b'>`. */\nconst KEY_SET_TYPES = new Set(['Pick', 'Omit', 'Extract', 'Exclude', 'Record']);\n\n/** The union is a type argument of a key-set utility type, or the key range of a mapped type. */\nconst isKeySet = (opts: { node: unknown }): boolean => {\n const parent = readField({ node: opts.node, key: 'parent' });\n\n if (nodeType({ node: parent }) === 'TSMappedType') {\n return true;\n }\n\n if (nodeType({ node: parent }) !== 'TSTypeParameterInstantiation') {\n return false;\n }\n\n const reference = readField({ node: parent, key: 'parent' });\n const name = readField({ node: readField({ node: reference, key: 'typeName' }), key: 'name' });\n return nodeType({ node: reference }) === 'TSTypeReference' && KEY_SET_TYPES.has(String(name));\n};\n\n/** The statement of the module that holds the node: the node's last ancestor before `Program`. */\nconst topLevelStatement = (opts: { node: unknown }): unknown => {\n let current = opts.node;\n\n while (current) {\n const parent = readField({ node: current, key: 'parent' });\n if (nodeType({ node: parent }) === 'Program') {\n return current;\n }\n current = parent;\n }\n\n return undefined;\n};\n\nconst isStringLiteral = (opts: { member: unknown }): boolean => {\n const { member } = opts;\n return (\n nodeType({ node: member }) === 'TSLiteralType' &&\n typeof readField({ node: readField({ node: member, key: 'literal' }), key: 'value' }) ===\n 'string'\n );\n};\n\nconst isNullish = (opts: { member: unknown }): boolean => {\n const type = nodeType({ node: opts.member });\n return type === 'TSNullKeyword' || type === 'TSUndefinedKeyword';\n};\n\n/**\n * `venizia/const-class-values`. An enumerable string is a const class plus `TConstValue<typeof X>`,\n * never a union of string literals in an exported declaration: a type alias, an interface member, a\n * generic constraint, a parameter or a return type of an exported function or class.\n *\n * Not counted: a union that is not all string literals (a `null` or `undefined` member is ignored),\n * a key set (`Pick`, `Omit`, `Extract`, `Exclude`, `Record` arguments and mapped-type keys), and a\n * declaration that is not exported. `namePattern` narrows the rule to exported type aliases whose name\n * matches it (`(State|Status)$`), for a project that adopts the rule one name at a time.\n */\nexport class ConstClassValuesRule {\n static readonly NAME = `${HOUSE_PLUGIN_NAMESPACE}/const-class-values`;\n\n static readonly RULE: Rule.RuleModule = {\n meta: {\n type: 'suggestion',\n schema: [{ type: 'object', properties: { namePattern: { type: 'string' } } }],\n messages: {\n constClass:\n 'An enumerable string is a const class plus TConstValue<typeof X>, not a union of string literals.',\n },\n },\n create: (context) => {\n const options: unknown = context.options[0];\n const configured = readField({ node: options, key: 'namePattern' });\n const namePattern = typeof configured === 'string' ? new RegExp(configured) : undefined;\n\n const isNamed = (opts: { statement: unknown; node: unknown }) => {\n const { statement, node } = opts;\n const declaration = readField({ node: statement, key: 'declaration' });\n const name = readField({ node: readField({ node: declaration, key: 'id' }), key: 'name' });\n\n return (\n namePattern === undefined ||\n (nodeType({ node: declaration }) === 'TSTypeAliasDeclaration' &&\n readField({ node: declaration, key: 'typeAnnotation' }) === node &&\n typeof name === 'string' &&\n namePattern.test(name))\n );\n };\n\n return {\n [AstNodeTypes.UNION_TYPE]: (node: Rule.Node) => {\n const members = readField({ node, key: 'types' });\n if (!Array.isArray(members)) {\n return;\n }\n\n const values = members.filter((member) => !isNullish({ member }));\n if (values.length < 2 || !values.every((member) => isStringLiteral({ member }))) {\n return;\n }\n\n const statement = topLevelStatement({ node });\n const statementType = nodeType({ node: statement });\n const isExported =\n statementType === AstNodeTypes.EXPORT_NAMED_DECLARATION ||\n statementType === 'ExportDefaultDeclaration';\n\n if (!isExported || isKeySet({ node }) || !isNamed({ statement, node })) {\n return;\n }\n\n context.report({ node, messageId: 'constClass' });\n },\n };\n },\n };\n\n static build(opts: { severity?: TRuleSeverity; namePattern?: string } = {}): Linter.RuleEntry {\n const { severity = 'error', namePattern } = opts;\n return namePattern === undefined ? [severity] : [severity, { namePattern }];\n }\n}\n"]}
@@ -1,6 +1,53 @@
1
1
  import type { OxlintConfig } from 'oxlint';
2
+ /** The string values of a const class: its static members that are strings, as literal types. */
3
+ export type TConstValue<T> = Extract<T[keyof T], string> & {};
2
4
  /** A rule's severity, as both oxlint and ESLint accept it. */
3
- export type TRuleSeverity = 'off' | 'warn' | 'error';
5
+ export declare class RuleSeverities {
6
+ static readonly OFF = "off";
7
+ static readonly WARN = "warn";
8
+ static readonly ERROR = "error";
9
+ static readonly SCHEME_SET: Set<string>;
10
+ static isValid(value: string): value is TRuleSeverity;
11
+ }
12
+ /** Valid rule severity values. */
13
+ export type TRuleSeverity = TConstValue<typeof RuleSeverities>;
14
+ /** `eqeqeq` modes: ALWAYS wants `===` everywhere, SMART still allows `== null` and comparing two literals. */
15
+ export declare class EqeqeqModes {
16
+ static readonly ALWAYS = "always";
17
+ static readonly SMART = "smart";
18
+ static readonly SCHEME_SET: Set<string>;
19
+ static isValid(value: string): value is TEqeqeqMode;
20
+ }
21
+ /** Valid eqeqeq mode values. */
22
+ export type TEqeqeqMode = TConstValue<typeof EqeqeqModes>;
23
+ /** `no-unused-vars` `vars`: ALL checks globals too, LOCAL only the variables of the file. */
24
+ export declare class UnusedVarsScopes {
25
+ static readonly ALL = "all";
26
+ static readonly LOCAL = "local";
27
+ static readonly SCHEME_SET: Set<string>;
28
+ static isValid(value: string): value is TUnusedVarsScope;
29
+ }
30
+ /** Valid unused vars scope values. */
31
+ export type TUnusedVarsScope = TConstValue<typeof UnusedVarsScopes>;
32
+ /** `no-unused-vars` `args`: ALL checks every argument, AFTER_USED those after the last used one, NONE no argument. */
33
+ export declare class UnusedArgsModes {
34
+ static readonly ALL = "all";
35
+ static readonly AFTER_USED = "after-used";
36
+ static readonly NONE = "none";
37
+ static readonly SCHEME_SET: Set<string>;
38
+ static isValid(value: string): value is TUnusedArgsMode;
39
+ }
40
+ /** Valid unused args mode values. */
41
+ export type TUnusedArgsMode = TConstValue<typeof UnusedArgsModes>;
42
+ /** `switch-case-braces` modes: ALWAYS gives every case its own block, AVOID drops braces that hold nothing that needs a scope. */
43
+ export declare class SwitchCaseBracesModes {
44
+ static readonly ALWAYS = "always";
45
+ static readonly AVOID = "avoid";
46
+ static readonly SCHEME_SET: Set<string>;
47
+ static isValid(value: string): value is TSwitchCaseBracesMode;
48
+ }
49
+ /** Valid switch case braces mode values. */
50
+ export type TSwitchCaseBracesMode = TConstValue<typeof SwitchCaseBracesModes>;
4
51
  /** The entry oxlint's own types allow for rule `TName`, options included. */
5
52
  export type TOxlintRuleEntry<TName extends string> = NonNullable<NonNullable<OxlintConfig['rules']>[TName]>;
6
53
  //# sourceMappingURL=common.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"common.d.ts","sourceRoot":"","sources":["../../../src/linters/rules/common.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAE3C,8DAA8D;AAC9D,MAAM,MAAM,aAAa,GAAG,KAAK,GAAG,MAAM,GAAG,OAAO,CAAC;AAErD,6EAA6E;AAC7E,MAAM,MAAM,gBAAgB,CAAC,KAAK,SAAS,MAAM,IAAI,WAAW,CAC9D,WAAW,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAC1C,CAAC"}
1
+ {"version":3,"file":"common.d.ts","sourceRoot":"","sources":["../../../src/linters/rules/common.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAE3C,iGAAiG;AACjG,MAAM,MAAM,WAAW,CAAC,CAAC,IAAI,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,MAAM,CAAC,GAAG,EAAE,CAAC;AAE9D,8DAA8D;AAC9D,qBAAa,cAAc;IACzB,MAAM,CAAC,QAAQ,CAAC,GAAG,SAAS;IAC5B,MAAM,CAAC,QAAQ,CAAC,IAAI,UAAU;IAC9B,MAAM,CAAC,QAAQ,CAAC,KAAK,WAAW;IAEhC,MAAM,CAAC,QAAQ,CAAC,UAAU,cAAsD;IAEhF,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,IAAI,aAAa;CAGtD;AAED,kCAAkC;AAClC,MAAM,MAAM,aAAa,GAAG,WAAW,CAAC,OAAO,cAAc,CAAC,CAAC;AAE/D,8GAA8G;AAC9G,qBAAa,WAAW;IACtB,MAAM,CAAC,QAAQ,CAAC,MAAM,YAAY;IAClC,MAAM,CAAC,QAAQ,CAAC,KAAK,WAAW;IAEhC,MAAM,CAAC,QAAQ,CAAC,UAAU,cAA8C;IAExE,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,IAAI,WAAW;CAGpD;AAED,gCAAgC;AAChC,MAAM,MAAM,WAAW,GAAG,WAAW,CAAC,OAAO,WAAW,CAAC,CAAC;AAE1D,6FAA6F;AAC7F,qBAAa,gBAAgB;IAC3B,MAAM,CAAC,QAAQ,CAAC,GAAG,SAAS;IAC5B,MAAM,CAAC,QAAQ,CAAC,KAAK,WAAW;IAEhC,MAAM,CAAC,QAAQ,CAAC,UAAU,cAA2C;IAErE,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,IAAI,gBAAgB;CAGzD;AAED,sCAAsC;AACtC,MAAM,MAAM,gBAAgB,GAAG,WAAW,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAEpE,sHAAsH;AACtH,qBAAa,eAAe;IAC1B,MAAM,CAAC,QAAQ,CAAC,GAAG,SAAS;IAC5B,MAAM,CAAC,QAAQ,CAAC,UAAU,gBAAgB;IAC1C,MAAM,CAAC,QAAQ,CAAC,IAAI,UAAU;IAE9B,MAAM,CAAC,QAAQ,CAAC,UAAU,cAA2D;IAErF,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,IAAI,eAAe;CAGxD;AAED,qCAAqC;AACrC,MAAM,MAAM,eAAe,GAAG,WAAW,CAAC,OAAO,eAAe,CAAC,CAAC;AAElE,kIAAkI;AAClI,qBAAa,qBAAqB;IAChC,MAAM,CAAC,QAAQ,CAAC,MAAM,YAAY;IAClC,MAAM,CAAC,QAAQ,CAAC,KAAK,WAAW;IAEhC,MAAM,CAAC,QAAQ,CAAC,UAAU,cAA8C;IAExE,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,IAAI,qBAAqB;CAG9D;AAED,4CAA4C;AAC5C,MAAM,MAAM,qBAAqB,GAAG,WAAW,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAE9E,6EAA6E;AAC7E,MAAM,MAAM,gBAAgB,CAAC,KAAK,SAAS,MAAM,IAAI,WAAW,CAC9D,WAAW,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAC1C,CAAC"}