@webpieces/code-rules 0.4.636 → 0.4.638

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 (41) hide show
  1. package/package.json +2 -2
  2. package/src/validate-catch-error-pattern.js +1 -1
  3. package/src/validate-catch-error-pattern.js.map +1 -1
  4. package/src/validate-dtos.js +1 -1
  5. package/src/validate-dtos.js.map +1 -1
  6. package/src/validate-framework-tag.js +1 -1
  7. package/src/validate-framework-tag.js.map +1 -1
  8. package/src/validate-inject-annotation-not-needed-for-concrete-class.js +1 -1
  9. package/src/validate-inject-annotation-not-needed-for-concrete-class.js.map +1 -1
  10. package/src/validate-modified-files.js +1 -1
  11. package/src/validate-modified-files.js.map +1 -1
  12. package/src/validate-modified-methods.js +1 -1
  13. package/src/validate-modified-methods.js.map +1 -1
  14. package/src/validate-no-any-unknown.js +1 -1
  15. package/src/validate-no-any-unknown.js.map +1 -1
  16. package/src/validate-no-client-creation-outside-server-or-client.js +1 -1
  17. package/src/validate-no-client-creation-outside-server-or-client.js.map +1 -1
  18. package/src/validate-no-custom-css.js +1 -1
  19. package/src/validate-no-custom-css.js.map +1 -1
  20. package/src/validate-no-destructure.js +1 -1
  21. package/src/validate-no-destructure.js.map +1 -1
  22. package/src/validate-no-direct-api-resolver.js +1 -1
  23. package/src/validate-no-direct-api-resolver.js.map +1 -1
  24. package/src/validate-no-function-outside-class.js +1 -1
  25. package/src/validate-no-function-outside-class.js.map +1 -1
  26. package/src/validate-no-implicit-any.js +1 -1
  27. package/src/validate-no-implicit-any.js.map +1 -1
  28. package/src/validate-no-inline-types.js +1 -1
  29. package/src/validate-no-inline-types.js.map +1 -1
  30. package/src/validate-no-process-exit-outside-main.js +1 -1
  31. package/src/validate-no-process-exit-outside-main.js.map +1 -1
  32. package/src/validate-no-symbol-di-tokens.js +1 -1
  33. package/src/validate-no-symbol-di-tokens.js.map +1 -1
  34. package/src/validate-no-unmanaged-exceptions.js +1 -1
  35. package/src/validate-no-unmanaged-exceptions.js.map +1 -1
  36. package/src/validate-prisma-converters.js +1 -1
  37. package/src/validate-prisma-converters.js.map +1 -1
  38. package/src/validate-return-types.js +1 -1
  39. package/src/validate-return-types.js.map +1 -1
  40. package/src/validate-role-tag.js +1 -1
  41. package/src/validate-role-tag.js.map +1 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@webpieces/code-rules",
3
- "version": "0.4.636",
3
+ "version": "0.4.638",
4
4
  "description": "Standalone code validation rules extracted from architecture-validators, no Nx dependency required",
5
5
  "type": "commonjs",
6
6
  "main": "./src/index.js",
@@ -16,7 +16,7 @@
16
16
  "directory": "packages/tooling/code-rules"
17
17
  },
18
18
  "dependencies": {
19
- "@webpieces/rules-config": "0.4.636",
19
+ "@webpieces/rules-config": "0.4.638",
20
20
  "@inversifyjs/binding-decorators": "1.1.5",
21
21
  "inversify": "7.10.4",
22
22
  "reflect-metadata": "0.2.2"
@@ -375,7 +375,7 @@ async function runValidatorImpl(options, workspaceRoot) {
375
375
  }
376
376
  let CatchErrorPatternValidator = class CatchErrorPatternValidator extends code_validator_1.CodeValidator {
377
377
  constructor(config) {
378
- super(config, 'catch-error-pattern');
378
+ super(config, 'catch-error-pattern', 'catch-error-pattern');
379
379
  }
380
380
  async run(workspaceRoot) {
381
381
  return runValidatorImpl(this.config, workspaceRoot);
@@ -1 +1 @@
1
- {"version":3,"file":"validate-catch-error-pattern.js","sourceRoot":"","sources":["../../../../../packages/tooling/code-rules/src/validate-catch-error-pattern.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Validate Catch Error Pattern Executor\n *\n * Validates that catch blocks follow the standardized error handling pattern.\n * Uses TypeScript AST for detection and LINE-BASED git diff filtering.\n *\n * ============================================================================\n * REQUIRED PATTERN\n * ============================================================================\n *\n * Standard: catch (err: unknown) { const error = toError(err); ... }\n * Ignored: catch (err: unknown) { //const error = toError(err); ... }\n * Nested: catch (err2: unknown) { const error2 = toError(err2); ... }\n *\n * ============================================================================\n * VIOLATIONS (BAD) - These patterns are flagged:\n * ============================================================================\n *\n * - catch (e) { ... } — wrong parameter name\n * - catch (err) { ... } — missing : unknown type annotation\n * - catch (err: unknown) { ... } — missing toError() as first statement\n * - catch (err: unknown) { const x = toError(err); } — wrong variable name\n *\n * ============================================================================\n * MODES (LINE-BASED)\n * ============================================================================\n * - OFF: Skip validation entirely\n * - NEW_AND_MODIFIED_CODE: Flag catch violations on changed lines (lines in diff hunks)\n * - NEW_AND_MODIFIED_FILES: Flag ALL catch violations in files that were modified\n *\n * ============================================================================\n * ESCAPE HATCH\n * ============================================================================\n * Add comment above the violation:\n * // webpieces-disable catch-error-pattern -- [your justification]\n * } catch (err: unknown) {\n */\n\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport * as ts from 'typescript';\nimport { hasDisable, RULE_NAMES, CatchErrorPatternConfig, ModifiedCodeMode, detectBase, getChangedFiles, getFileDiff, getChangedLineNumbers } from '@webpieces/rules-config';\nimport { CodeValidator, ExecutorResult } from './code-validator';\nimport { injectable, bindingScopeValues } from 'inversify';\nimport { shouldSkipRule } from './resolve-mode';\n\ninterface CatchViolation {\n file: string;\n line: number;\n message: string;\n context: string;\n}\n\ninterface CatchViolationInfo {\n line: number;\n message: string;\n context: string;\n hasDisableComment: boolean;\n}\n\n/**\n * Check if a line contains a disable comment for catch-error-pattern.\n * Recognizes both webpieces-disable and eslint-disable-next-line @webpieces/ formats.\n */\nfunction hasDisableComment(lines: string[], lineNumber: number): boolean {\n const startCheck = Math.max(0, lineNumber - 5);\n for (let i = lineNumber - 2; i >= startCheck; i--) {\n const line = lines[i]?.trim() ?? '';\n if (line.startsWith('function ') || line.startsWith('class ') || line.endsWith('}')) {\n break;\n }\n if (hasDisable(line, RULE_NAMES.CATCH_ERROR_PATTERN)) {\n return true;\n }\n if (line.includes('@webpieces/catch-error-pattern')) {\n return true;\n }\n }\n return false;\n}\n\n/**\n * Check if the catch block contains a disable comment for catch-error-pattern.\n */\nfunction hasBlockLevelDisable(sourceText: string, blockStart: number, blockEnd: number): boolean {\n const blockText = sourceText.substring(blockStart, blockEnd);\n return hasDisable(blockText, RULE_NAMES.CATCH_ERROR_PATTERN) ||\n blockText.includes('@webpieces/catch-error-pattern');\n}\n\n/**\n * Check if the catch block body text contains the commented-out ignore pattern.\n */\nfunction hasIgnoreComment(\n sourceText: string,\n blockStart: number,\n blockEnd: number,\n expectedVarName: string,\n actualParamName: string,\n): boolean {\n const blockText = sourceText.substring(blockStart, blockEnd);\n const ignorePattern = new RegExp(\n `//\\\\s*const\\\\s+${expectedVarName}\\\\s*=\\\\s*toError\\\\(${actualParamName}\\\\)`,\n );\n return ignorePattern.test(blockText);\n}\n\n/**\n * Validate a single CatchClause node.\n */\n// webpieces-disable max-lines-new-methods -- AST validation with multiple check paths for param name, type, and toError\nfunction validateCatchClause(\n node: ts.CatchClause,\n sourceFile: ts.SourceFile,\n fileLines: string[],\n depth: number,\n disableAllowed: boolean,\n): CatchViolationInfo[] {\n const violations: CatchViolationInfo[] = [];\n const suffix = depth === 1 ? '' : String(depth);\n const expectedParam = 'err' + suffix;\n const expectedVar = 'error' + suffix;\n\n const catchLine = sourceFile.getLineAndCharacterOfPosition(node.getStart(sourceFile)).line + 1;\n const catchContext = fileLines[catchLine - 1]?.trim() ?? '';\n const blockStart = node.block.getStart(sourceFile);\n const blockEnd = node.block.getEnd();\n const disabled = hasDisableComment(fileLines, catchLine) ||\n hasBlockLevelDisable(sourceFile.text, blockStart, blockEnd);\n\n const varDecl = node.variableDeclaration;\n if (!varDecl) {\n violations.push({\n line: catchLine, context: catchContext,\n message: `Catch clause must declare a parameter: catch (${expectedParam}: unknown)`,\n hasDisableComment: resolveDisable(disabled, disableAllowed),\n });\n return violations;\n }\n\n const actualParam = ts.isIdentifier(varDecl.name) ? varDecl.name.text : expectedParam;\n\n // Check parameter name\n if (ts.isIdentifier(varDecl.name) && varDecl.name.text !== expectedParam) {\n violations.push({\n line: catchLine, context: catchContext,\n message: `Catch parameter must be named \"${expectedParam}\" (or \"err2\", \"err3\" for nested), got \"${varDecl.name.text}\"`,\n hasDisableComment: resolveDisable(disabled, disableAllowed),\n });\n }\n\n // Check type annotation is : unknown\n if (!varDecl.type || varDecl.type.kind !== ts.SyntaxKind.UnknownKeyword) {\n violations.push({\n line: catchLine, context: catchContext,\n message: `Catch parameter must be typed as \"unknown\": catch (${actualParam}: unknown)`,\n hasDisableComment: resolveDisable(disabled, disableAllowed),\n });\n }\n\n // Check for commented-out ignore pattern\n if (hasIgnoreComment(sourceFile.text, blockStart, blockEnd, expectedVar, actualParam)) {\n return violations;\n }\n\n // Check first statement is const error = toError(err)\n if (node.block.statements.length === 0) {\n violations.push({\n line: catchLine, context: catchContext,\n message: `Catch block must call toError(${actualParam}) as first statement: const ${expectedVar} = toError(${actualParam});`,\n hasDisableComment: resolveDisable(disabled, disableAllowed),\n });\n return violations;\n }\n\n const firstStmt = node.block.statements[0];\n const toErrorViolation = validateToErrorStatement(firstStmt, sourceFile, fileLines, expectedParam, expectedVar, actualParam, disabled, disableAllowed);\n if (toErrorViolation) {\n violations.push(toErrorViolation);\n }\n\n return violations;\n}\n\nfunction resolveDisable(disabled: boolean, disableAllowed: boolean): boolean {\n if (!disableAllowed && disabled) {\n return false;\n }\n return disabled;\n}\n\n/**\n * Validate that the first statement is `const error = toError(err);`\n */\n// webpieces-disable max-lines-new-methods -- Deep AST check for variable declaration with toError call expression\nfunction validateToErrorStatement(\n stmt: ts.Statement,\n sourceFile: ts.SourceFile,\n fileLines: string[],\n expectedParam: string,\n expectedVar: string,\n actualParam: string,\n disabled: boolean,\n disableAllowed: boolean,\n): CatchViolationInfo | null {\n const stmtLine = sourceFile.getLineAndCharacterOfPosition(stmt.getStart(sourceFile)).line + 1;\n const stmtContext = fileLines[stmtLine - 1]?.trim() ?? '';\n\n if (!ts.isVariableStatement(stmt)) {\n return {\n line: stmtLine,\n message: `First statement in catch must be: const ${expectedVar} = toError(${actualParam});`,\n context: stmtContext,\n hasDisableComment: resolveDisable(disabled, disableAllowed),\n };\n }\n\n const declarations = stmt.declarationList.declarations;\n if (declarations.length === 0) {\n return {\n line: stmtLine,\n message: `First statement in catch must be: const ${expectedVar} = toError(${actualParam});`,\n context: stmtContext,\n hasDisableComment: resolveDisable(disabled, disableAllowed),\n };\n }\n\n const decl = declarations[0];\n\n // Check variable name\n if (ts.isIdentifier(decl.name) && decl.name.text !== expectedVar) {\n return {\n line: stmtLine,\n message: `Error variable must be named \"${expectedVar}\", got \"${decl.name.text}\"`,\n context: stmtContext,\n hasDisableComment: resolveDisable(disabled, disableAllowed),\n };\n }\n\n // Check initializer is toError(actualParam)\n const init = decl.initializer;\n if (!init || !ts.isCallExpression(init)) {\n return {\n line: stmtLine,\n message: `First statement in catch must be: const ${expectedVar} = toError(${actualParam});`,\n context: stmtContext,\n hasDisableComment: resolveDisable(disabled, disableAllowed),\n };\n }\n\n if (!ts.isIdentifier(init.expression) || init.expression.text !== 'toError') {\n return {\n line: stmtLine,\n message: `First statement in catch must call toError(), not \"${init.expression.getText(sourceFile)}\"`,\n context: stmtContext,\n hasDisableComment: resolveDisable(disabled, disableAllowed),\n };\n }\n\n // Check argument\n const args = init.arguments;\n if (args.length !== 1 || !ts.isIdentifier(args[0]) || args[0].text !== actualParam) {\n return {\n line: stmtLine,\n message: `toError() must be called with \"${actualParam}\"`,\n context: stmtContext,\n hasDisableComment: resolveDisable(disabled, disableAllowed),\n };\n }\n\n return null;\n}\n\n/**\n * Find all catch pattern violations in a file using AST.\n */\nfunction findCatchViolationsInFile(\n filePath: string,\n workspaceRoot: string,\n disableAllowed: boolean,\n): CatchViolationInfo[] {\n const fullPath = path.join(workspaceRoot, filePath);\n if (!fs.existsSync(fullPath)) return [];\n\n const content = fs.readFileSync(fullPath, 'utf-8');\n const fileLines = content.split('\\n');\n const sourceFile = ts.createSourceFile(filePath, content, ts.ScriptTarget.Latest, true);\n\n const violations: CatchViolationInfo[] = [];\n let catchDepth = 0;\n\n function visit(node: ts.Node): void {\n if (ts.isCatchClause(node)) {\n catchDepth++;\n const clauseViolations = validateCatchClause(node, sourceFile, fileLines, catchDepth, disableAllowed);\n violations.push(...clauseViolations);\n ts.forEachChild(node, visit);\n catchDepth--;\n return;\n }\n ts.forEachChild(node, visit);\n }\n\n visit(sourceFile);\n return violations;\n}\n\n/**\n * NEW_AND_MODIFIED_CODE mode: Flag violations on changed lines.\n */\nfunction findViolationsForModifiedCode(\n workspaceRoot: string,\n changedFiles: string[],\n base: string,\n head: string | undefined,\n disableAllowed: boolean,\n): CatchViolation[] {\n const violations: CatchViolation[] = [];\n\n for (const file of changedFiles) {\n const diff = getFileDiff(workspaceRoot, file, base, head);\n const changedLines = getChangedLineNumbers(diff);\n\n if (changedLines.size === 0) continue;\n\n const allViolations = findCatchViolationsInFile(file, workspaceRoot, disableAllowed);\n\n for (const v of allViolations) {\n if (disableAllowed && v.hasDisableComment) continue;\n if (!changedLines.has(v.line)) continue;\n\n violations.push({ file, line: v.line, message: v.message, context: v.context });\n }\n }\n\n return violations;\n}\n\n/**\n * NEW_AND_MODIFIED_FILES mode: Flag ALL violations in modified files.\n */\nfunction findViolationsForModifiedFiles(\n workspaceRoot: string,\n changedFiles: string[],\n disableAllowed: boolean,\n): CatchViolation[] {\n const violations: CatchViolation[] = [];\n\n for (const file of changedFiles) {\n const allViolations = findCatchViolationsInFile(file, workspaceRoot, disableAllowed);\n\n for (const v of allViolations) {\n if (disableAllowed && v.hasDisableComment) continue;\n violations.push({ file, line: v.line, message: v.message, context: v.context });\n }\n }\n\n return violations;\n}\n\n/**\n * Report violations to console.\n */\n// webpieces-disable max-lines-new-methods -- Console output with pattern examples and escape hatch\nfunction reportViolations(violations: CatchViolation[], mode: ModifiedCodeMode, disableAllowed: boolean): void {\n console.error('');\n console.error('\\u274c Catch blocks must follow the standardized error handling pattern!');\n console.error('');\n console.error('\\ud83d\\udcda Required pattern:');\n console.error('');\n console.error(' catch (err: unknown) {');\n console.error(' const error = toError(err);');\n console.error(' // ... use error ...');\n console.error(' }');\n console.error('');\n console.error(' Or to explicitly ignore:');\n console.error(' catch (err: unknown) {');\n console.error(' //const error = toError(err);');\n console.error(' }');\n console.error('');\n console.error(' For nested catches: err2/error2, err3/error3, etc.');\n console.error('');\n\n for (const v of violations) {\n console.error(` \\u274c ${v.file}:${v.line}`);\n console.error(` ${v.message}`);\n console.error(` ${v.context}`);\n }\n console.error('');\n\n if (disableAllowed) {\n console.error(' Escape hatch (use sparingly):');\n console.error(' // webpieces-disable catch-error-pattern -- [your reason]');\n } else {\n console.error(' Escape hatch: DISABLED (disableAllowed: false)');\n console.error(' Disable comments are ignored. Fix the catch block directly.');\n }\n console.error('');\n console.error(` Current mode: ${mode}`);\n console.error('');\n}\n\n/**\n * Resolve mode considering turnOffRuleUntilEpoch override.\n */\nfunction resolveMode(normalMode: ModifiedCodeMode, epoch: number | undefined, branchPattern: string | undefined): ModifiedCodeMode {\n if (normalMode === 'OFF') {\n return normalMode;\n }\n const skip = shouldSkipRule(epoch, branchPattern);\n if (skip.skip) {\n console.log(`\\n\\u23ed\\ufe0f Skipping catch-error-pattern validation (${skip.reason})`);\n console.log('');\n return 'OFF';\n }\n return normalMode;\n}\n\nasync function runValidatorImpl(\n options: CatchErrorPatternConfig,\n workspaceRoot: string\n): Promise<ExecutorResult> {\n const mode: ModifiedCodeMode = resolveMode(options.mode ?? 'OFF', options.turnOffRuleUntilEpoch, (options.turnOffRuleWhileOnBranch ?? undefined));\n const disableAllowed = options.disableAllowed ?? true;\n\n if (mode === 'OFF') {\n console.log('\\n\\u23ed\\ufe0f Skipping catch-error-pattern validation (mode: OFF)');\n console.log('');\n return { success: true };\n }\n\n console.log('\\n\\ud83d\\udccf Validating Catch Error Pattern\\n');\n console.log(` Mode: ${mode}`);\n\n let base = process.env['NX_BASE'];\n const head = process.env['NX_HEAD'];\n\n if (!base) {\n base = detectBase(workspaceRoot) ?? undefined;\n\n if (!base) {\n console.log('\\n\\u23ed\\ufe0f Skipping catch-error-pattern validation (could not detect base branch)');\n console.log('');\n return { success: true };\n }\n }\n\n console.log(` Base: ${base}`);\n console.log(` Head: ${head ?? 'working tree (includes uncommitted changes)'}`);\n console.log('');\n\n const changedFiles = getChangedFiles(workspaceRoot, base, head);\n\n if (changedFiles.length === 0) {\n console.log('\\u2705 No TypeScript files changed');\n return { success: true };\n }\n\n console.log(`\\ud83d\\udcc2 Checking ${changedFiles.length} changed file(s)...`);\n\n let violations: CatchViolation[] = [];\n\n if (mode === 'NEW_AND_MODIFIED_CODE') {\n violations = findViolationsForModifiedCode(workspaceRoot, changedFiles, base, head, disableAllowed);\n } else if (mode === 'NEW_AND_MODIFIED_FILES') {\n violations = findViolationsForModifiedFiles(workspaceRoot, changedFiles, disableAllowed);\n }\n\n if (violations.length === 0) {\n console.log('\\u2705 No catch error pattern violations found');\n return { success: true };\n }\n\n reportViolations(violations, mode, disableAllowed);\n\n return { success: false };\n}\n\n@injectable(bindingScopeValues.Singleton)\nexport class CatchErrorPatternValidator extends CodeValidator<CatchErrorPatternConfig> {\n constructor(config: CatchErrorPatternConfig) {\n super(config, 'catch-error-pattern');\n }\n\n async run(workspaceRoot: string): Promise<ExecutorResult> {\n return runValidatorImpl(this.config, workspaceRoot);\n }\n}\n"]}
1
+ {"version":3,"file":"validate-catch-error-pattern.js","sourceRoot":"","sources":["../../../../../packages/tooling/code-rules/src/validate-catch-error-pattern.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Validate Catch Error Pattern Executor\n *\n * Validates that catch blocks follow the standardized error handling pattern.\n * Uses TypeScript AST for detection and LINE-BASED git diff filtering.\n *\n * ============================================================================\n * REQUIRED PATTERN\n * ============================================================================\n *\n * Standard: catch (err: unknown) { const error = toError(err); ... }\n * Ignored: catch (err: unknown) { //const error = toError(err); ... }\n * Nested: catch (err2: unknown) { const error2 = toError(err2); ... }\n *\n * ============================================================================\n * VIOLATIONS (BAD) - These patterns are flagged:\n * ============================================================================\n *\n * - catch (e) { ... } — wrong parameter name\n * - catch (err) { ... } — missing : unknown type annotation\n * - catch (err: unknown) { ... } — missing toError() as first statement\n * - catch (err: unknown) { const x = toError(err); } — wrong variable name\n *\n * ============================================================================\n * MODES (LINE-BASED)\n * ============================================================================\n * - OFF: Skip validation entirely\n * - NEW_AND_MODIFIED_CODE: Flag catch violations on changed lines (lines in diff hunks)\n * - NEW_AND_MODIFIED_FILES: Flag ALL catch violations in files that were modified\n *\n * ============================================================================\n * ESCAPE HATCH\n * ============================================================================\n * Add comment above the violation:\n * // webpieces-disable catch-error-pattern -- [your justification]\n * } catch (err: unknown) {\n */\n\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport * as ts from 'typescript';\nimport { hasDisable, RULE_NAMES, CatchErrorPatternConfig, ModifiedCodeMode, detectBase, getChangedFiles, getFileDiff, getChangedLineNumbers } from '@webpieces/rules-config';\nimport { CodeValidator, ExecutorResult } from './code-validator';\nimport { injectable, bindingScopeValues } from 'inversify';\nimport { shouldSkipRule } from './resolve-mode';\n\ninterface CatchViolation {\n file: string;\n line: number;\n message: string;\n context: string;\n}\n\ninterface CatchViolationInfo {\n line: number;\n message: string;\n context: string;\n hasDisableComment: boolean;\n}\n\n/**\n * Check if a line contains a disable comment for catch-error-pattern.\n * Recognizes both webpieces-disable and eslint-disable-next-line @webpieces/ formats.\n */\nfunction hasDisableComment(lines: string[], lineNumber: number): boolean {\n const startCheck = Math.max(0, lineNumber - 5);\n for (let i = lineNumber - 2; i >= startCheck; i--) {\n const line = lines[i]?.trim() ?? '';\n if (line.startsWith('function ') || line.startsWith('class ') || line.endsWith('}')) {\n break;\n }\n if (hasDisable(line, RULE_NAMES.CATCH_ERROR_PATTERN)) {\n return true;\n }\n if (line.includes('@webpieces/catch-error-pattern')) {\n return true;\n }\n }\n return false;\n}\n\n/**\n * Check if the catch block contains a disable comment for catch-error-pattern.\n */\nfunction hasBlockLevelDisable(sourceText: string, blockStart: number, blockEnd: number): boolean {\n const blockText = sourceText.substring(blockStart, blockEnd);\n return hasDisable(blockText, RULE_NAMES.CATCH_ERROR_PATTERN) ||\n blockText.includes('@webpieces/catch-error-pattern');\n}\n\n/**\n * Check if the catch block body text contains the commented-out ignore pattern.\n */\nfunction hasIgnoreComment(\n sourceText: string,\n blockStart: number,\n blockEnd: number,\n expectedVarName: string,\n actualParamName: string,\n): boolean {\n const blockText = sourceText.substring(blockStart, blockEnd);\n const ignorePattern = new RegExp(\n `//\\\\s*const\\\\s+${expectedVarName}\\\\s*=\\\\s*toError\\\\(${actualParamName}\\\\)`,\n );\n return ignorePattern.test(blockText);\n}\n\n/**\n * Validate a single CatchClause node.\n */\n// webpieces-disable max-lines-new-methods -- AST validation with multiple check paths for param name, type, and toError\nfunction validateCatchClause(\n node: ts.CatchClause,\n sourceFile: ts.SourceFile,\n fileLines: string[],\n depth: number,\n disableAllowed: boolean,\n): CatchViolationInfo[] {\n const violations: CatchViolationInfo[] = [];\n const suffix = depth === 1 ? '' : String(depth);\n const expectedParam = 'err' + suffix;\n const expectedVar = 'error' + suffix;\n\n const catchLine = sourceFile.getLineAndCharacterOfPosition(node.getStart(sourceFile)).line + 1;\n const catchContext = fileLines[catchLine - 1]?.trim() ?? '';\n const blockStart = node.block.getStart(sourceFile);\n const blockEnd = node.block.getEnd();\n const disabled = hasDisableComment(fileLines, catchLine) ||\n hasBlockLevelDisable(sourceFile.text, blockStart, blockEnd);\n\n const varDecl = node.variableDeclaration;\n if (!varDecl) {\n violations.push({\n line: catchLine, context: catchContext,\n message: `Catch clause must declare a parameter: catch (${expectedParam}: unknown)`,\n hasDisableComment: resolveDisable(disabled, disableAllowed),\n });\n return violations;\n }\n\n const actualParam = ts.isIdentifier(varDecl.name) ? varDecl.name.text : expectedParam;\n\n // Check parameter name\n if (ts.isIdentifier(varDecl.name) && varDecl.name.text !== expectedParam) {\n violations.push({\n line: catchLine, context: catchContext,\n message: `Catch parameter must be named \"${expectedParam}\" (or \"err2\", \"err3\" for nested), got \"${varDecl.name.text}\"`,\n hasDisableComment: resolveDisable(disabled, disableAllowed),\n });\n }\n\n // Check type annotation is : unknown\n if (!varDecl.type || varDecl.type.kind !== ts.SyntaxKind.UnknownKeyword) {\n violations.push({\n line: catchLine, context: catchContext,\n message: `Catch parameter must be typed as \"unknown\": catch (${actualParam}: unknown)`,\n hasDisableComment: resolveDisable(disabled, disableAllowed),\n });\n }\n\n // Check for commented-out ignore pattern\n if (hasIgnoreComment(sourceFile.text, blockStart, blockEnd, expectedVar, actualParam)) {\n return violations;\n }\n\n // Check first statement is const error = toError(err)\n if (node.block.statements.length === 0) {\n violations.push({\n line: catchLine, context: catchContext,\n message: `Catch block must call toError(${actualParam}) as first statement: const ${expectedVar} = toError(${actualParam});`,\n hasDisableComment: resolveDisable(disabled, disableAllowed),\n });\n return violations;\n }\n\n const firstStmt = node.block.statements[0];\n const toErrorViolation = validateToErrorStatement(firstStmt, sourceFile, fileLines, expectedParam, expectedVar, actualParam, disabled, disableAllowed);\n if (toErrorViolation) {\n violations.push(toErrorViolation);\n }\n\n return violations;\n}\n\nfunction resolveDisable(disabled: boolean, disableAllowed: boolean): boolean {\n if (!disableAllowed && disabled) {\n return false;\n }\n return disabled;\n}\n\n/**\n * Validate that the first statement is `const error = toError(err);`\n */\n// webpieces-disable max-lines-new-methods -- Deep AST check for variable declaration with toError call expression\nfunction validateToErrorStatement(\n stmt: ts.Statement,\n sourceFile: ts.SourceFile,\n fileLines: string[],\n expectedParam: string,\n expectedVar: string,\n actualParam: string,\n disabled: boolean,\n disableAllowed: boolean,\n): CatchViolationInfo | null {\n const stmtLine = sourceFile.getLineAndCharacterOfPosition(stmt.getStart(sourceFile)).line + 1;\n const stmtContext = fileLines[stmtLine - 1]?.trim() ?? '';\n\n if (!ts.isVariableStatement(stmt)) {\n return {\n line: stmtLine,\n message: `First statement in catch must be: const ${expectedVar} = toError(${actualParam});`,\n context: stmtContext,\n hasDisableComment: resolveDisable(disabled, disableAllowed),\n };\n }\n\n const declarations = stmt.declarationList.declarations;\n if (declarations.length === 0) {\n return {\n line: stmtLine,\n message: `First statement in catch must be: const ${expectedVar} = toError(${actualParam});`,\n context: stmtContext,\n hasDisableComment: resolveDisable(disabled, disableAllowed),\n };\n }\n\n const decl = declarations[0];\n\n // Check variable name\n if (ts.isIdentifier(decl.name) && decl.name.text !== expectedVar) {\n return {\n line: stmtLine,\n message: `Error variable must be named \"${expectedVar}\", got \"${decl.name.text}\"`,\n context: stmtContext,\n hasDisableComment: resolveDisable(disabled, disableAllowed),\n };\n }\n\n // Check initializer is toError(actualParam)\n const init = decl.initializer;\n if (!init || !ts.isCallExpression(init)) {\n return {\n line: stmtLine,\n message: `First statement in catch must be: const ${expectedVar} = toError(${actualParam});`,\n context: stmtContext,\n hasDisableComment: resolveDisable(disabled, disableAllowed),\n };\n }\n\n if (!ts.isIdentifier(init.expression) || init.expression.text !== 'toError') {\n return {\n line: stmtLine,\n message: `First statement in catch must call toError(), not \"${init.expression.getText(sourceFile)}\"`,\n context: stmtContext,\n hasDisableComment: resolveDisable(disabled, disableAllowed),\n };\n }\n\n // Check argument\n const args = init.arguments;\n if (args.length !== 1 || !ts.isIdentifier(args[0]) || args[0].text !== actualParam) {\n return {\n line: stmtLine,\n message: `toError() must be called with \"${actualParam}\"`,\n context: stmtContext,\n hasDisableComment: resolveDisable(disabled, disableAllowed),\n };\n }\n\n return null;\n}\n\n/**\n * Find all catch pattern violations in a file using AST.\n */\nfunction findCatchViolationsInFile(\n filePath: string,\n workspaceRoot: string,\n disableAllowed: boolean,\n): CatchViolationInfo[] {\n const fullPath = path.join(workspaceRoot, filePath);\n if (!fs.existsSync(fullPath)) return [];\n\n const content = fs.readFileSync(fullPath, 'utf-8');\n const fileLines = content.split('\\n');\n const sourceFile = ts.createSourceFile(filePath, content, ts.ScriptTarget.Latest, true);\n\n const violations: CatchViolationInfo[] = [];\n let catchDepth = 0;\n\n function visit(node: ts.Node): void {\n if (ts.isCatchClause(node)) {\n catchDepth++;\n const clauseViolations = validateCatchClause(node, sourceFile, fileLines, catchDepth, disableAllowed);\n violations.push(...clauseViolations);\n ts.forEachChild(node, visit);\n catchDepth--;\n return;\n }\n ts.forEachChild(node, visit);\n }\n\n visit(sourceFile);\n return violations;\n}\n\n/**\n * NEW_AND_MODIFIED_CODE mode: Flag violations on changed lines.\n */\nfunction findViolationsForModifiedCode(\n workspaceRoot: string,\n changedFiles: string[],\n base: string,\n head: string | undefined,\n disableAllowed: boolean,\n): CatchViolation[] {\n const violations: CatchViolation[] = [];\n\n for (const file of changedFiles) {\n const diff = getFileDiff(workspaceRoot, file, base, head);\n const changedLines = getChangedLineNumbers(diff);\n\n if (changedLines.size === 0) continue;\n\n const allViolations = findCatchViolationsInFile(file, workspaceRoot, disableAllowed);\n\n for (const v of allViolations) {\n if (disableAllowed && v.hasDisableComment) continue;\n if (!changedLines.has(v.line)) continue;\n\n violations.push({ file, line: v.line, message: v.message, context: v.context });\n }\n }\n\n return violations;\n}\n\n/**\n * NEW_AND_MODIFIED_FILES mode: Flag ALL violations in modified files.\n */\nfunction findViolationsForModifiedFiles(\n workspaceRoot: string,\n changedFiles: string[],\n disableAllowed: boolean,\n): CatchViolation[] {\n const violations: CatchViolation[] = [];\n\n for (const file of changedFiles) {\n const allViolations = findCatchViolationsInFile(file, workspaceRoot, disableAllowed);\n\n for (const v of allViolations) {\n if (disableAllowed && v.hasDisableComment) continue;\n violations.push({ file, line: v.line, message: v.message, context: v.context });\n }\n }\n\n return violations;\n}\n\n/**\n * Report violations to console.\n */\n// webpieces-disable max-lines-new-methods -- Console output with pattern examples and escape hatch\nfunction reportViolations(violations: CatchViolation[], mode: ModifiedCodeMode, disableAllowed: boolean): void {\n console.error('');\n console.error('\\u274c Catch blocks must follow the standardized error handling pattern!');\n console.error('');\n console.error('\\ud83d\\udcda Required pattern:');\n console.error('');\n console.error(' catch (err: unknown) {');\n console.error(' const error = toError(err);');\n console.error(' // ... use error ...');\n console.error(' }');\n console.error('');\n console.error(' Or to explicitly ignore:');\n console.error(' catch (err: unknown) {');\n console.error(' //const error = toError(err);');\n console.error(' }');\n console.error('');\n console.error(' For nested catches: err2/error2, err3/error3, etc.');\n console.error('');\n\n for (const v of violations) {\n console.error(` \\u274c ${v.file}:${v.line}`);\n console.error(` ${v.message}`);\n console.error(` ${v.context}`);\n }\n console.error('');\n\n if (disableAllowed) {\n console.error(' Escape hatch (use sparingly):');\n console.error(' // webpieces-disable catch-error-pattern -- [your reason]');\n } else {\n console.error(' Escape hatch: DISABLED (disableAllowed: false)');\n console.error(' Disable comments are ignored. Fix the catch block directly.');\n }\n console.error('');\n console.error(` Current mode: ${mode}`);\n console.error('');\n}\n\n/**\n * Resolve mode considering turnOffRuleUntilEpoch override.\n */\nfunction resolveMode(normalMode: ModifiedCodeMode, epoch: number | undefined, branchPattern: string | undefined): ModifiedCodeMode {\n if (normalMode === 'OFF') {\n return normalMode;\n }\n const skip = shouldSkipRule(epoch, branchPattern);\n if (skip.skip) {\n console.log(`\\n\\u23ed\\ufe0f Skipping catch-error-pattern validation (${skip.reason})`);\n console.log('');\n return 'OFF';\n }\n return normalMode;\n}\n\nasync function runValidatorImpl(\n options: CatchErrorPatternConfig,\n workspaceRoot: string\n): Promise<ExecutorResult> {\n const mode: ModifiedCodeMode = resolveMode(options.mode ?? 'OFF', options.turnOffRuleUntilEpoch, (options.turnOffRuleWhileOnBranch ?? undefined));\n const disableAllowed = options.disableAllowed ?? true;\n\n if (mode === 'OFF') {\n console.log('\\n\\u23ed\\ufe0f Skipping catch-error-pattern validation (mode: OFF)');\n console.log('');\n return { success: true };\n }\n\n console.log('\\n\\ud83d\\udccf Validating Catch Error Pattern\\n');\n console.log(` Mode: ${mode}`);\n\n let base = process.env['NX_BASE'];\n const head = process.env['NX_HEAD'];\n\n if (!base) {\n base = detectBase(workspaceRoot) ?? undefined;\n\n if (!base) {\n console.log('\\n\\u23ed\\ufe0f Skipping catch-error-pattern validation (could not detect base branch)');\n console.log('');\n return { success: true };\n }\n }\n\n console.log(` Base: ${base}`);\n console.log(` Head: ${head ?? 'working tree (includes uncommitted changes)'}`);\n console.log('');\n\n const changedFiles = getChangedFiles(workspaceRoot, base, head);\n\n if (changedFiles.length === 0) {\n console.log('\\u2705 No TypeScript files changed');\n return { success: true };\n }\n\n console.log(`\\ud83d\\udcc2 Checking ${changedFiles.length} changed file(s)...`);\n\n let violations: CatchViolation[] = [];\n\n if (mode === 'NEW_AND_MODIFIED_CODE') {\n violations = findViolationsForModifiedCode(workspaceRoot, changedFiles, base, head, disableAllowed);\n } else if (mode === 'NEW_AND_MODIFIED_FILES') {\n violations = findViolationsForModifiedFiles(workspaceRoot, changedFiles, disableAllowed);\n }\n\n if (violations.length === 0) {\n console.log('\\u2705 No catch error pattern violations found');\n return { success: true };\n }\n\n reportViolations(violations, mode, disableAllowed);\n\n return { success: false };\n}\n\n@injectable(bindingScopeValues.Singleton)\nexport class CatchErrorPatternValidator extends CodeValidator<CatchErrorPatternConfig> {\n constructor(config: CatchErrorPatternConfig) {\n super(config, 'catch-error-pattern', 'catch-error-pattern');\n }\n\n async run(workspaceRoot: string): Promise<ExecutorResult> {\n return runValidatorImpl(this.config, workspaceRoot);\n }\n}\n"]}
@@ -436,7 +436,7 @@ async function runValidatorImpl(options, workspaceRoot) {
436
436
  }
437
437
  let PrismaValidateDtosValidator = class PrismaValidateDtosValidator extends code_validator_1.CodeValidator {
438
438
  constructor(config) {
439
- super(config, 'prisma-validate-dtos');
439
+ super(config, 'prisma-validate-dtos', 'prisma-validate-dtos');
440
440
  }
441
441
  async run(workspaceRoot) {
442
442
  return runValidatorImpl(this.config, workspaceRoot);
@@ -1 +1 @@
1
- {"version":3,"file":"validate-dtos.js","sourceRoot":"","sources":["../../../../../packages/tooling/code-rules/src/validate-dtos.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Validate DTOs Executor\n *\n * Validates that every non-deprecated field in a XxxDto class/interface exists\n * in the corresponding XxxDbo Prisma model. This catches AI agents inventing\n * field names that don't match the database schema.\n *\n * ============================================================================\n * MODES\n * ============================================================================\n * - OFF: Skip validation entirely\n * - MODIFIED_CLASS: Only validate Dto classes that have changed lines in the diff\n * - NEW_AND_MODIFIED_FILES: Validate ALL Dto classes in files that were modified\n *\n * ============================================================================\n * SKIP CONDITIONS\n * ============================================================================\n * - If schema.prisma itself is modified, validation is skipped (schema in flux)\n * - Dto classes ending with \"JoinDto\" are skipped (they compose other Dtos)\n * - Fields marked @deprecated in a comment are exempt\n *\n * ============================================================================\n * MATCHING\n * ============================================================================\n * - UserDto matches UserDbo by case-insensitive prefix (\"user\")\n * - Dbo field names are converted from snake_case to camelCase for comparison\n * - Dto fields must be a subset of Dbo fields\n * - Extra Dbo fields are allowed (e.g., password)\n */\n\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport * as ts from 'typescript';\nimport { PrismaValidateDtosConfig, PrismaValidateDtosMode, detectBase, getChangedFiles, getFileDiff, getChangedLineNumbers } from '@webpieces/rules-config';\nimport { CodeValidator, ExecutorResult } from './code-validator';\nimport { injectable, bindingScopeValues } from 'inversify';\nimport { shouldSkipRule } from './resolve-mode';\n\ninterface DtoFieldInfo {\n name: string;\n line: number;\n deprecated: boolean;\n}\n\ninterface DtoInfo {\n name: string;\n file: string;\n startLine: number;\n endLine: number;\n fields: DtoFieldInfo[];\n}\n\ninterface DtoViolation {\n file: string;\n line: number;\n dtoName: string;\n fieldName: string;\n dboName: string;\n availableFields: string[];\n}\n\ninterface DboEntry {\n name: string;\n fields: Set<string>;\n}\n\n/**\n * Convert a snake_case string to camelCase.\n * e.g., \"version_number\" -> \"versionNumber\", \"id\" -> \"id\"\n */\nfunction snakeToCamel(s: string): string {\n return s.replace(/_([a-z])/g, (_, letter: string) => letter.toUpperCase());\n}\n\n/**\n * Parse schema.prisma to build a map of Dbo model name -> set of field names (camelCase).\n * Only models whose name ends with \"Dbo\" are included.\n * Field names are converted from snake_case to camelCase since Dto fields use camelCase.\n */\nfunction parsePrismaSchema(schemaPath: string): Map<string, Set<string>> {\n const models = new Map<string, Set<string>>();\n\n if (!fs.existsSync(schemaPath)) {\n return models;\n }\n\n const content = fs.readFileSync(schemaPath, 'utf-8');\n const lines = content.split('\\n');\n\n let currentModel: string | null = null;\n let currentFields: Set<string> | null = null;\n\n for (const line of lines) {\n const trimmed = line.trim();\n\n // Match model declaration: model XxxDbo {\n const modelMatch = trimmed.match(/^model\\s+(\\w+Dbo)\\s*\\{/);\n if (modelMatch) {\n currentModel = modelMatch[1];\n currentFields = new Set<string>();\n continue;\n }\n\n // End of model block\n if (currentModel && trimmed === '}') {\n models.set(currentModel, currentFields!);\n currentModel = null;\n currentFields = null;\n continue;\n }\n\n // Inside a model block - extract field names\n if (currentModel && currentFields) {\n // Skip empty lines, comments, and model-level attributes (@@)\n if (!trimmed || trimmed.startsWith('//') || trimmed.startsWith('@@')) {\n continue;\n }\n\n // Field name is the first word on the line, converted to camelCase\n const fieldMatch = trimmed.match(/^(\\w+)\\s/);\n if (fieldMatch) {\n currentFields.add(snakeToCamel(fieldMatch[1]));\n }\n }\n }\n\n return models;\n}\n\n/**\n * Check if a field has @deprecated in a comment above it (within 3 lines).\n */\nfunction isFieldDeprecated(fileLines: string[], fieldLine: number): boolean {\n const start = Math.max(0, fieldLine - 4);\n for (let i = start; i <= fieldLine - 1; i++) {\n const line = fileLines[i]?.trim() ?? '';\n if (line.includes('@deprecated')) return true;\n }\n return false;\n}\n\n/**\n * Parse a TypeScript file to find Dto class/interface declarations and their fields.\n * Skips classes ending with \"JoinDto\" since they compose other Dtos.\n */\n// webpieces-disable max-lines-new-methods -- AST traversal for both class and interface Dto detection with field extraction\nfunction findDtosInFile(filePath: string, workspaceRoot: string): DtoInfo[] {\n const fullPath = path.join(workspaceRoot, filePath);\n if (!fs.existsSync(fullPath)) return [];\n\n const content = fs.readFileSync(fullPath, 'utf-8');\n const fileLines = content.split('\\n');\n const sourceFile = ts.createSourceFile(filePath, content, ts.ScriptTarget.Latest, true);\n\n const dtos: DtoInfo[] = [];\n\n function visit(node: ts.Node): void {\n const isClass = ts.isClassDeclaration(node);\n const isInterface = ts.isInterfaceDeclaration(node);\n\n if ((isClass || isInterface) && node.name) {\n const name = node.name.text;\n\n // Must end with Dto but NOT with JoinDto\n if (name.endsWith('Dto') && !name.endsWith('JoinDto')) {\n const fields: DtoFieldInfo[] = [];\n const nodeStart = sourceFile.getLineAndCharacterOfPosition(node.getStart(sourceFile));\n const nodeEnd = sourceFile.getLineAndCharacterOfPosition(node.getEnd());\n\n for (const member of node.members) {\n if (ts.isPropertyDeclaration(member) || ts.isPropertySignature(member)) {\n if (member.name && ts.isIdentifier(member.name)) {\n const fieldName = member.name.text;\n const startPos = member.getStart(sourceFile);\n const pos = sourceFile.getLineAndCharacterOfPosition(startPos);\n const line = pos.line + 1;\n const deprecated = isFieldDeprecated(fileLines, line);\n\n fields.push({ name: fieldName, line, deprecated });\n }\n }\n }\n\n dtos.push({\n name,\n file: filePath,\n startLine: nodeStart.line + 1,\n endLine: nodeEnd.line + 1,\n fields,\n });\n }\n }\n\n ts.forEachChild(node, visit);\n }\n\n visit(sourceFile);\n return dtos;\n}\n\n/**\n * Extract the prefix from a Dto/Dbo name by removing the suffix.\n * e.g., \"UserDto\" -> \"user\", \"UserDbo\" -> \"user\"\n */\nfunction extractPrefix(name: string, suffix: string): string {\n return name.slice(0, -suffix.length).toLowerCase();\n}\n\n/**\n * Find violations: Dto fields that don't exist in the corresponding Dbo.\n */\nfunction findViolations(\n dtos: DtoInfo[],\n dboModels: Map<string, Set<string>>\n): DtoViolation[] {\n const violations: DtoViolation[] = [];\n\n // Build a lowercase prefix -> Dbo info map\n const dboByPrefix = new Map<string, DboEntry>();\n dboModels.forEach((fields, dboName) => {\n const prefix = extractPrefix(dboName, 'Dbo');\n dboByPrefix.set(prefix, { name: dboName, fields });\n });\n\n for (const dto of dtos) {\n const prefix = extractPrefix(dto.name, 'Dto');\n const dbo = dboByPrefix.get(prefix);\n\n if (!dbo) {\n // No matching Dbo found - skip (might be a Dto without a DB table)\n continue;\n }\n\n for (const field of dto.fields) {\n if (field.deprecated) continue;\n\n if (!dbo.fields.has(field.name)) {\n violations.push({\n file: dto.file,\n line: field.line,\n dtoName: dto.name,\n fieldName: field.name,\n dboName: dbo.name,\n availableFields: Array.from(dbo.fields).sort(),\n });\n }\n }\n }\n\n return violations;\n}\n\n/**\n * Compute similarity between two strings using longest common subsequence ratio.\n * Returns a value between 0 and 1, where 1 is an exact match.\n */\nfunction similarity(a: string, b: string): number {\n const al = a.toLowerCase();\n const bl = b.toLowerCase();\n if (al === bl) return 1;\n\n const m = al.length;\n const n = bl.length;\n const prev = new Array<number>(n + 1).fill(0);\n const curr = new Array<number>(n + 1).fill(0);\n\n for (let i = 1; i <= m; i++) {\n for (let j = 1; j <= n; j++) {\n if (al[i - 1] === bl[j - 1]) {\n curr[j] = prev[j - 1] + 1;\n } else {\n curr[j] = Math.max(prev[j], curr[j - 1]);\n }\n }\n for (let j = 0; j <= n; j++) {\n prev[j] = curr[j];\n curr[j] = 0;\n }\n }\n\n const lcsLen = prev[n];\n return (2 * lcsLen) / (m + n);\n}\n\n/**\n * Find the closest matching Dbo field for a given Dto field name.\n * Returns the best match or null if nothing scores above the threshold.\n */\nfunction suggestClosestField(fieldName: string, availableFields: string[]): string | null {\n let bestMatch: string | null = null;\n let bestScore = 0.4; // minimum threshold\n\n for (const candidate of availableFields) {\n const score = similarity(fieldName, candidate);\n if (score > bestScore) {\n bestScore = score;\n bestMatch = candidate;\n }\n }\n\n return bestMatch;\n}\n\n/**\n * Report violations to console with prominent AI warning and rename suggestions.\n */\nfunction reportViolations(violations: DtoViolation[]): void {\n console.error('');\n console.error('❌❌❌ DTO FIELD MISMATCH - AI AGENT: READ THIS CAREFULLY ❌❌❌');\n console.error('');\n console.error('🛑 DO NOT attempt find/replace or manual renaming. Instead:');\n console.error(' 1. IDE rename is 10x faster than AI renaming PLUS 100% correct vs. AI\\'s 80%');\n console.error(' 2. Based on errors below, suggest renames to the user');\n console.error(' 3. Ask the human to use IDE rename-refactoring (F2 / right-click → Rename Symbol)');\n console.error('');\n console.error('📚 Every non-deprecated field in a Dto must exist in the corresponding Dbo.');\n console.error(' Dbo can have extra fields (e.g., password) — Dto fields cannot be invented.');\n console.error('');\n console.error(' When needing fields from multiple tables (e.g., a join), use a XxxJoinDto that');\n console.error(' contains YYDto and ZZDto fields from the other tables instead of flattening.');\n console.error(' Fields marked @deprecated in the Dto are exempt from this check.');\n console.error('');\n\n for (const v of violations) {\n console.error(` ❌ ${v.file}:${v.line}`);\n console.error(` ${v.dtoName}.${v.fieldName} does not exist in ${v.dboName}`);\n\n const suggestion = suggestClosestField(v.fieldName, v.availableFields);\n if (suggestion) {\n console.error(` 💡 Suggested rename: ${v.fieldName} → ${suggestion} (Use IDE rename on ${v.dtoName}.${v.fieldName})`);\n } else {\n const preview = v.availableFields.slice(0, 8).join(', ');\n const ellipsis = v.availableFields.length > 8 ? ', ...' : '';\n console.error(` 💡 No close match found. Available: ${preview}${ellipsis}`);\n }\n }\n console.error('');\n\n console.error('❌❌❌ AI AGENT: Suggest to the human which are the most likely renames needed and list them ❌❌❌');\n console.error('');\n}\n\n/**\n * Filter changed files to only TypeScript Dto source files within configured paths.\n */\nfunction filterDtoFiles(changedFiles: string[], dtoSourcePaths: string[]): string[] {\n return changedFiles.filter((f) => {\n if (!f.endsWith('.ts') && !f.endsWith('.tsx')) return false;\n if (f.includes('.spec.ts') || f.includes('.test.ts')) return false;\n return dtoSourcePaths.some((srcPath) => f.startsWith(srcPath));\n });\n}\n\n/**\n * Collect all Dto definitions from the given files.\n */\nfunction collectDtos(dtoFiles: string[], workspaceRoot: string): DtoInfo[] {\n const allDtos: DtoInfo[] = [];\n for (const file of dtoFiles) {\n const dtos = findDtosInFile(file, workspaceRoot);\n allDtos.push(...dtos);\n }\n return allDtos;\n}\n\n/**\n * Check if a Dto class overlaps with any changed lines in the diff.\n */\nfunction isDtoTouched(dto: DtoInfo, changedLines: Set<number>): boolean {\n for (let line = dto.startLine; line <= dto.endLine; line++) {\n if (changedLines.has(line)) return true;\n }\n return false;\n}\n\n/**\n * Filter Dtos to only those that have changed lines in the diff (MODIFIED_CLASS mode).\n */\nfunction filterTouchedDtos(\n dtos: DtoInfo[],\n workspaceRoot: string,\n base: string,\n head?: string\n): DtoInfo[] {\n // Group dtos by file to avoid re-fetching diffs\n const byFile = new Map<string, DtoInfo[]>();\n for (const dto of dtos) {\n const list = byFile.get(dto.file) ?? [];\n list.push(dto);\n byFile.set(dto.file, list);\n }\n\n const touched: DtoInfo[] = [];\n byFile.forEach((fileDtos, file) => {\n const diff = getFileDiff(workspaceRoot, file, base, head);\n const changedLines = getChangedLineNumbers(diff);\n for (const dto of fileDtos) {\n if (isDtoTouched(dto, changedLines)) {\n touched.push(dto);\n }\n }\n });\n return touched;\n}\n\n/**\n * Resolve git base ref from env vars or auto-detection.\n */\nfunction resolveBase(workspaceRoot: string): string | undefined {\n const envBase = process.env['NX_BASE'];\n if (envBase) return envBase;\n return detectBase(workspaceRoot) ?? undefined;\n}\n\n/**\n * Run the core validation after early-exit checks have passed.\n */\n// webpieces-disable max-lines-new-methods -- Core validation orchestration with multiple early-exit checks\nfunction validateDtoFiles(\n workspaceRoot: string,\n prismaSchemaPath: string,\n changedFiles: string[],\n dtoSourcePaths: string[],\n mode: PrismaValidateDtosMode,\n base: string,\n head?: string\n): ExecutorResult {\n if (changedFiles.some((f) => f.endsWith(prismaSchemaPath))) {\n console.log('⏭️ Skipping validate-dtos (schema.prisma is modified - schema in flux)');\n console.log('');\n return { success: true };\n }\n\n const dtoFiles = filterDtoFiles(changedFiles, dtoSourcePaths);\n\n if (dtoFiles.length === 0) {\n console.log('✅ No Dto files changed');\n return { success: true };\n }\n\n console.log(`📂 Checking ${dtoFiles.length} changed file(s) for Dto definitions...`);\n\n const fullSchemaPath = path.join(workspaceRoot, prismaSchemaPath);\n const dboModels = parsePrismaSchema(fullSchemaPath);\n\n if (dboModels.size === 0) {\n console.log('⏭️ No Dbo models found in schema.prisma');\n console.log('');\n return { success: true };\n }\n\n console.log(` Found ${dboModels.size} Dbo model(s) in schema.prisma`);\n\n let allDtos = collectDtos(dtoFiles, workspaceRoot);\n\n if (allDtos.length === 0) {\n console.log('✅ No Dto definitions found in changed files');\n return { success: true };\n }\n\n // In MODIFIED_CLASS mode, narrow to only Dtos with changed lines\n if (mode === 'MODIFIED_CLASS') {\n allDtos = filterTouchedDtos(allDtos, workspaceRoot, base, head);\n if (allDtos.length === 0) {\n console.log('✅ No Dto classes were modified');\n return { success: true };\n }\n }\n\n console.log(` Validating ${allDtos.length} Dto definition(s)`);\n\n const violations = findViolations(allDtos, dboModels);\n\n if (violations.length === 0) {\n console.log('✅ All Dto fields match their Dbo models');\n return { success: true };\n }\n\n reportViolations(violations);\n return { success: false };\n}\n\n/**\n * Resolve mode considering turnOffRuleUntilEpoch override.\n * When active, downgrades to OFF. When expired, logs a warning.\n */\nfunction resolveMode(normalMode: PrismaValidateDtosMode, epoch: number | undefined, branchPattern: string | undefined): PrismaValidateDtosMode {\n if (normalMode === 'OFF') {\n return normalMode;\n }\n const skip = shouldSkipRule(epoch, branchPattern);\n if (skip.skip) {\n console.log(`\\n⏭️ Skipping validate-dtos (${skip.reason})`);\n console.log('');\n return 'OFF';\n }\n return normalMode;\n}\n\nasync function runValidatorImpl(\n options: PrismaValidateDtosConfig,\n workspaceRoot: string\n): Promise<ExecutorResult> {\n const mode = resolveMode(options.mode ?? 'OFF', options.turnOffRuleUntilEpoch, (options.turnOffRuleWhileOnBranch ?? undefined));\n\n if (mode === 'OFF') {\n console.log('\\n⏭️ Skipping validate-dtos (mode: OFF)');\n console.log('');\n return { success: true };\n }\n\n const prismaSchemaPath = options.prismaSchemaPath;\n const dtoSourcePaths = options.dtoSourcePaths ?? [];\n\n if (!prismaSchemaPath || dtoSourcePaths.length === 0) {\n const reason = !prismaSchemaPath ? 'no prismaSchemaPath configured' : 'no dtoSourcePaths configured';\n console.log(`\\n⏭️ Skipping validate-dtos (${reason})`);\n console.log('');\n return { success: true };\n }\n\n console.log('\\n📏 Validating DTOs match Prisma Dbo models\\n');\n console.log(` Mode: ${mode}`);\n console.log(` Schema: ${prismaSchemaPath}`);\n console.log(` Dto paths: ${dtoSourcePaths.join(', ')}`);\n\n const base = resolveBase(workspaceRoot);\n const head = process.env['NX_HEAD'];\n\n if (!base) {\n console.log('\\n⏭️ Skipping validate-dtos (could not detect base branch)');\n console.log('');\n return { success: true };\n }\n\n console.log(` Base: ${base}`);\n console.log(` Head: ${head ?? 'working tree (includes uncommitted changes)'}`);\n console.log('');\n\n const changedFiles = getChangedFiles(workspaceRoot, base, head, { tsOnly: false });\n\n return validateDtoFiles(workspaceRoot, prismaSchemaPath, changedFiles, dtoSourcePaths, mode, base, head);\n}\n\n@injectable(bindingScopeValues.Singleton)\nexport class PrismaValidateDtosValidator extends CodeValidator<PrismaValidateDtosConfig> {\n constructor(config: PrismaValidateDtosConfig) {\n super(config, 'prisma-validate-dtos');\n }\n\n async run(workspaceRoot: string): Promise<ExecutorResult> {\n return runValidatorImpl(this.config, workspaceRoot);\n }\n}\n"]}
1
+ {"version":3,"file":"validate-dtos.js","sourceRoot":"","sources":["../../../../../packages/tooling/code-rules/src/validate-dtos.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Validate DTOs Executor\n *\n * Validates that every non-deprecated field in a XxxDto class/interface exists\n * in the corresponding XxxDbo Prisma model. This catches AI agents inventing\n * field names that don't match the database schema.\n *\n * ============================================================================\n * MODES\n * ============================================================================\n * - OFF: Skip validation entirely\n * - MODIFIED_CLASS: Only validate Dto classes that have changed lines in the diff\n * - NEW_AND_MODIFIED_FILES: Validate ALL Dto classes in files that were modified\n *\n * ============================================================================\n * SKIP CONDITIONS\n * ============================================================================\n * - If schema.prisma itself is modified, validation is skipped (schema in flux)\n * - Dto classes ending with \"JoinDto\" are skipped (they compose other Dtos)\n * - Fields marked @deprecated in a comment are exempt\n *\n * ============================================================================\n * MATCHING\n * ============================================================================\n * - UserDto matches UserDbo by case-insensitive prefix (\"user\")\n * - Dbo field names are converted from snake_case to camelCase for comparison\n * - Dto fields must be a subset of Dbo fields\n * - Extra Dbo fields are allowed (e.g., password)\n */\n\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport * as ts from 'typescript';\nimport { PrismaValidateDtosConfig, PrismaValidateDtosMode, detectBase, getChangedFiles, getFileDiff, getChangedLineNumbers } from '@webpieces/rules-config';\nimport { CodeValidator, ExecutorResult } from './code-validator';\nimport { injectable, bindingScopeValues } from 'inversify';\nimport { shouldSkipRule } from './resolve-mode';\n\ninterface DtoFieldInfo {\n name: string;\n line: number;\n deprecated: boolean;\n}\n\ninterface DtoInfo {\n name: string;\n file: string;\n startLine: number;\n endLine: number;\n fields: DtoFieldInfo[];\n}\n\ninterface DtoViolation {\n file: string;\n line: number;\n dtoName: string;\n fieldName: string;\n dboName: string;\n availableFields: string[];\n}\n\ninterface DboEntry {\n name: string;\n fields: Set<string>;\n}\n\n/**\n * Convert a snake_case string to camelCase.\n * e.g., \"version_number\" -> \"versionNumber\", \"id\" -> \"id\"\n */\nfunction snakeToCamel(s: string): string {\n return s.replace(/_([a-z])/g, (_, letter: string) => letter.toUpperCase());\n}\n\n/**\n * Parse schema.prisma to build a map of Dbo model name -> set of field names (camelCase).\n * Only models whose name ends with \"Dbo\" are included.\n * Field names are converted from snake_case to camelCase since Dto fields use camelCase.\n */\nfunction parsePrismaSchema(schemaPath: string): Map<string, Set<string>> {\n const models = new Map<string, Set<string>>();\n\n if (!fs.existsSync(schemaPath)) {\n return models;\n }\n\n const content = fs.readFileSync(schemaPath, 'utf-8');\n const lines = content.split('\\n');\n\n let currentModel: string | null = null;\n let currentFields: Set<string> | null = null;\n\n for (const line of lines) {\n const trimmed = line.trim();\n\n // Match model declaration: model XxxDbo {\n const modelMatch = trimmed.match(/^model\\s+(\\w+Dbo)\\s*\\{/);\n if (modelMatch) {\n currentModel = modelMatch[1];\n currentFields = new Set<string>();\n continue;\n }\n\n // End of model block\n if (currentModel && trimmed === '}') {\n models.set(currentModel, currentFields!);\n currentModel = null;\n currentFields = null;\n continue;\n }\n\n // Inside a model block - extract field names\n if (currentModel && currentFields) {\n // Skip empty lines, comments, and model-level attributes (@@)\n if (!trimmed || trimmed.startsWith('//') || trimmed.startsWith('@@')) {\n continue;\n }\n\n // Field name is the first word on the line, converted to camelCase\n const fieldMatch = trimmed.match(/^(\\w+)\\s/);\n if (fieldMatch) {\n currentFields.add(snakeToCamel(fieldMatch[1]));\n }\n }\n }\n\n return models;\n}\n\n/**\n * Check if a field has @deprecated in a comment above it (within 3 lines).\n */\nfunction isFieldDeprecated(fileLines: string[], fieldLine: number): boolean {\n const start = Math.max(0, fieldLine - 4);\n for (let i = start; i <= fieldLine - 1; i++) {\n const line = fileLines[i]?.trim() ?? '';\n if (line.includes('@deprecated')) return true;\n }\n return false;\n}\n\n/**\n * Parse a TypeScript file to find Dto class/interface declarations and their fields.\n * Skips classes ending with \"JoinDto\" since they compose other Dtos.\n */\n// webpieces-disable max-lines-new-methods -- AST traversal for both class and interface Dto detection with field extraction\nfunction findDtosInFile(filePath: string, workspaceRoot: string): DtoInfo[] {\n const fullPath = path.join(workspaceRoot, filePath);\n if (!fs.existsSync(fullPath)) return [];\n\n const content = fs.readFileSync(fullPath, 'utf-8');\n const fileLines = content.split('\\n');\n const sourceFile = ts.createSourceFile(filePath, content, ts.ScriptTarget.Latest, true);\n\n const dtos: DtoInfo[] = [];\n\n function visit(node: ts.Node): void {\n const isClass = ts.isClassDeclaration(node);\n const isInterface = ts.isInterfaceDeclaration(node);\n\n if ((isClass || isInterface) && node.name) {\n const name = node.name.text;\n\n // Must end with Dto but NOT with JoinDto\n if (name.endsWith('Dto') && !name.endsWith('JoinDto')) {\n const fields: DtoFieldInfo[] = [];\n const nodeStart = sourceFile.getLineAndCharacterOfPosition(node.getStart(sourceFile));\n const nodeEnd = sourceFile.getLineAndCharacterOfPosition(node.getEnd());\n\n for (const member of node.members) {\n if (ts.isPropertyDeclaration(member) || ts.isPropertySignature(member)) {\n if (member.name && ts.isIdentifier(member.name)) {\n const fieldName = member.name.text;\n const startPos = member.getStart(sourceFile);\n const pos = sourceFile.getLineAndCharacterOfPosition(startPos);\n const line = pos.line + 1;\n const deprecated = isFieldDeprecated(fileLines, line);\n\n fields.push({ name: fieldName, line, deprecated });\n }\n }\n }\n\n dtos.push({\n name,\n file: filePath,\n startLine: nodeStart.line + 1,\n endLine: nodeEnd.line + 1,\n fields,\n });\n }\n }\n\n ts.forEachChild(node, visit);\n }\n\n visit(sourceFile);\n return dtos;\n}\n\n/**\n * Extract the prefix from a Dto/Dbo name by removing the suffix.\n * e.g., \"UserDto\" -> \"user\", \"UserDbo\" -> \"user\"\n */\nfunction extractPrefix(name: string, suffix: string): string {\n return name.slice(0, -suffix.length).toLowerCase();\n}\n\n/**\n * Find violations: Dto fields that don't exist in the corresponding Dbo.\n */\nfunction findViolations(\n dtos: DtoInfo[],\n dboModels: Map<string, Set<string>>\n): DtoViolation[] {\n const violations: DtoViolation[] = [];\n\n // Build a lowercase prefix -> Dbo info map\n const dboByPrefix = new Map<string, DboEntry>();\n dboModels.forEach((fields, dboName) => {\n const prefix = extractPrefix(dboName, 'Dbo');\n dboByPrefix.set(prefix, { name: dboName, fields });\n });\n\n for (const dto of dtos) {\n const prefix = extractPrefix(dto.name, 'Dto');\n const dbo = dboByPrefix.get(prefix);\n\n if (!dbo) {\n // No matching Dbo found - skip (might be a Dto without a DB table)\n continue;\n }\n\n for (const field of dto.fields) {\n if (field.deprecated) continue;\n\n if (!dbo.fields.has(field.name)) {\n violations.push({\n file: dto.file,\n line: field.line,\n dtoName: dto.name,\n fieldName: field.name,\n dboName: dbo.name,\n availableFields: Array.from(dbo.fields).sort(),\n });\n }\n }\n }\n\n return violations;\n}\n\n/**\n * Compute similarity between two strings using longest common subsequence ratio.\n * Returns a value between 0 and 1, where 1 is an exact match.\n */\nfunction similarity(a: string, b: string): number {\n const al = a.toLowerCase();\n const bl = b.toLowerCase();\n if (al === bl) return 1;\n\n const m = al.length;\n const n = bl.length;\n const prev = new Array<number>(n + 1).fill(0);\n const curr = new Array<number>(n + 1).fill(0);\n\n for (let i = 1; i <= m; i++) {\n for (let j = 1; j <= n; j++) {\n if (al[i - 1] === bl[j - 1]) {\n curr[j] = prev[j - 1] + 1;\n } else {\n curr[j] = Math.max(prev[j], curr[j - 1]);\n }\n }\n for (let j = 0; j <= n; j++) {\n prev[j] = curr[j];\n curr[j] = 0;\n }\n }\n\n const lcsLen = prev[n];\n return (2 * lcsLen) / (m + n);\n}\n\n/**\n * Find the closest matching Dbo field for a given Dto field name.\n * Returns the best match or null if nothing scores above the threshold.\n */\nfunction suggestClosestField(fieldName: string, availableFields: string[]): string | null {\n let bestMatch: string | null = null;\n let bestScore = 0.4; // minimum threshold\n\n for (const candidate of availableFields) {\n const score = similarity(fieldName, candidate);\n if (score > bestScore) {\n bestScore = score;\n bestMatch = candidate;\n }\n }\n\n return bestMatch;\n}\n\n/**\n * Report violations to console with prominent AI warning and rename suggestions.\n */\nfunction reportViolations(violations: DtoViolation[]): void {\n console.error('');\n console.error('❌❌❌ DTO FIELD MISMATCH - AI AGENT: READ THIS CAREFULLY ❌❌❌');\n console.error('');\n console.error('🛑 DO NOT attempt find/replace or manual renaming. Instead:');\n console.error(' 1. IDE rename is 10x faster than AI renaming PLUS 100% correct vs. AI\\'s 80%');\n console.error(' 2. Based on errors below, suggest renames to the user');\n console.error(' 3. Ask the human to use IDE rename-refactoring (F2 / right-click → Rename Symbol)');\n console.error('');\n console.error('📚 Every non-deprecated field in a Dto must exist in the corresponding Dbo.');\n console.error(' Dbo can have extra fields (e.g., password) — Dto fields cannot be invented.');\n console.error('');\n console.error(' When needing fields from multiple tables (e.g., a join), use a XxxJoinDto that');\n console.error(' contains YYDto and ZZDto fields from the other tables instead of flattening.');\n console.error(' Fields marked @deprecated in the Dto are exempt from this check.');\n console.error('');\n\n for (const v of violations) {\n console.error(` ❌ ${v.file}:${v.line}`);\n console.error(` ${v.dtoName}.${v.fieldName} does not exist in ${v.dboName}`);\n\n const suggestion = suggestClosestField(v.fieldName, v.availableFields);\n if (suggestion) {\n console.error(` 💡 Suggested rename: ${v.fieldName} → ${suggestion} (Use IDE rename on ${v.dtoName}.${v.fieldName})`);\n } else {\n const preview = v.availableFields.slice(0, 8).join(', ');\n const ellipsis = v.availableFields.length > 8 ? ', ...' : '';\n console.error(` 💡 No close match found. Available: ${preview}${ellipsis}`);\n }\n }\n console.error('');\n\n console.error('❌❌❌ AI AGENT: Suggest to the human which are the most likely renames needed and list them ❌❌❌');\n console.error('');\n}\n\n/**\n * Filter changed files to only TypeScript Dto source files within configured paths.\n */\nfunction filterDtoFiles(changedFiles: string[], dtoSourcePaths: string[]): string[] {\n return changedFiles.filter((f) => {\n if (!f.endsWith('.ts') && !f.endsWith('.tsx')) return false;\n if (f.includes('.spec.ts') || f.includes('.test.ts')) return false;\n return dtoSourcePaths.some((srcPath) => f.startsWith(srcPath));\n });\n}\n\n/**\n * Collect all Dto definitions from the given files.\n */\nfunction collectDtos(dtoFiles: string[], workspaceRoot: string): DtoInfo[] {\n const allDtos: DtoInfo[] = [];\n for (const file of dtoFiles) {\n const dtos = findDtosInFile(file, workspaceRoot);\n allDtos.push(...dtos);\n }\n return allDtos;\n}\n\n/**\n * Check if a Dto class overlaps with any changed lines in the diff.\n */\nfunction isDtoTouched(dto: DtoInfo, changedLines: Set<number>): boolean {\n for (let line = dto.startLine; line <= dto.endLine; line++) {\n if (changedLines.has(line)) return true;\n }\n return false;\n}\n\n/**\n * Filter Dtos to only those that have changed lines in the diff (MODIFIED_CLASS mode).\n */\nfunction filterTouchedDtos(\n dtos: DtoInfo[],\n workspaceRoot: string,\n base: string,\n head?: string\n): DtoInfo[] {\n // Group dtos by file to avoid re-fetching diffs\n const byFile = new Map<string, DtoInfo[]>();\n for (const dto of dtos) {\n const list = byFile.get(dto.file) ?? [];\n list.push(dto);\n byFile.set(dto.file, list);\n }\n\n const touched: DtoInfo[] = [];\n byFile.forEach((fileDtos, file) => {\n const diff = getFileDiff(workspaceRoot, file, base, head);\n const changedLines = getChangedLineNumbers(diff);\n for (const dto of fileDtos) {\n if (isDtoTouched(dto, changedLines)) {\n touched.push(dto);\n }\n }\n });\n return touched;\n}\n\n/**\n * Resolve git base ref from env vars or auto-detection.\n */\nfunction resolveBase(workspaceRoot: string): string | undefined {\n const envBase = process.env['NX_BASE'];\n if (envBase) return envBase;\n return detectBase(workspaceRoot) ?? undefined;\n}\n\n/**\n * Run the core validation after early-exit checks have passed.\n */\n// webpieces-disable max-lines-new-methods -- Core validation orchestration with multiple early-exit checks\nfunction validateDtoFiles(\n workspaceRoot: string,\n prismaSchemaPath: string,\n changedFiles: string[],\n dtoSourcePaths: string[],\n mode: PrismaValidateDtosMode,\n base: string,\n head?: string\n): ExecutorResult {\n if (changedFiles.some((f) => f.endsWith(prismaSchemaPath))) {\n console.log('⏭️ Skipping validate-dtos (schema.prisma is modified - schema in flux)');\n console.log('');\n return { success: true };\n }\n\n const dtoFiles = filterDtoFiles(changedFiles, dtoSourcePaths);\n\n if (dtoFiles.length === 0) {\n console.log('✅ No Dto files changed');\n return { success: true };\n }\n\n console.log(`📂 Checking ${dtoFiles.length} changed file(s) for Dto definitions...`);\n\n const fullSchemaPath = path.join(workspaceRoot, prismaSchemaPath);\n const dboModels = parsePrismaSchema(fullSchemaPath);\n\n if (dboModels.size === 0) {\n console.log('⏭️ No Dbo models found in schema.prisma');\n console.log('');\n return { success: true };\n }\n\n console.log(` Found ${dboModels.size} Dbo model(s) in schema.prisma`);\n\n let allDtos = collectDtos(dtoFiles, workspaceRoot);\n\n if (allDtos.length === 0) {\n console.log('✅ No Dto definitions found in changed files');\n return { success: true };\n }\n\n // In MODIFIED_CLASS mode, narrow to only Dtos with changed lines\n if (mode === 'MODIFIED_CLASS') {\n allDtos = filterTouchedDtos(allDtos, workspaceRoot, base, head);\n if (allDtos.length === 0) {\n console.log('✅ No Dto classes were modified');\n return { success: true };\n }\n }\n\n console.log(` Validating ${allDtos.length} Dto definition(s)`);\n\n const violations = findViolations(allDtos, dboModels);\n\n if (violations.length === 0) {\n console.log('✅ All Dto fields match their Dbo models');\n return { success: true };\n }\n\n reportViolations(violations);\n return { success: false };\n}\n\n/**\n * Resolve mode considering turnOffRuleUntilEpoch override.\n * When active, downgrades to OFF. When expired, logs a warning.\n */\nfunction resolveMode(normalMode: PrismaValidateDtosMode, epoch: number | undefined, branchPattern: string | undefined): PrismaValidateDtosMode {\n if (normalMode === 'OFF') {\n return normalMode;\n }\n const skip = shouldSkipRule(epoch, branchPattern);\n if (skip.skip) {\n console.log(`\\n⏭️ Skipping validate-dtos (${skip.reason})`);\n console.log('');\n return 'OFF';\n }\n return normalMode;\n}\n\nasync function runValidatorImpl(\n options: PrismaValidateDtosConfig,\n workspaceRoot: string\n): Promise<ExecutorResult> {\n const mode = resolveMode(options.mode ?? 'OFF', options.turnOffRuleUntilEpoch, (options.turnOffRuleWhileOnBranch ?? undefined));\n\n if (mode === 'OFF') {\n console.log('\\n⏭️ Skipping validate-dtos (mode: OFF)');\n console.log('');\n return { success: true };\n }\n\n const prismaSchemaPath = options.prismaSchemaPath;\n const dtoSourcePaths = options.dtoSourcePaths ?? [];\n\n if (!prismaSchemaPath || dtoSourcePaths.length === 0) {\n const reason = !prismaSchemaPath ? 'no prismaSchemaPath configured' : 'no dtoSourcePaths configured';\n console.log(`\\n⏭️ Skipping validate-dtos (${reason})`);\n console.log('');\n return { success: true };\n }\n\n console.log('\\n📏 Validating DTOs match Prisma Dbo models\\n');\n console.log(` Mode: ${mode}`);\n console.log(` Schema: ${prismaSchemaPath}`);\n console.log(` Dto paths: ${dtoSourcePaths.join(', ')}`);\n\n const base = resolveBase(workspaceRoot);\n const head = process.env['NX_HEAD'];\n\n if (!base) {\n console.log('\\n⏭️ Skipping validate-dtos (could not detect base branch)');\n console.log('');\n return { success: true };\n }\n\n console.log(` Base: ${base}`);\n console.log(` Head: ${head ?? 'working tree (includes uncommitted changes)'}`);\n console.log('');\n\n const changedFiles = getChangedFiles(workspaceRoot, base, head, { tsOnly: false });\n\n return validateDtoFiles(workspaceRoot, prismaSchemaPath, changedFiles, dtoSourcePaths, mode, base, head);\n}\n\n@injectable(bindingScopeValues.Singleton)\nexport class PrismaValidateDtosValidator extends CodeValidator<PrismaValidateDtosConfig> {\n constructor(config: PrismaValidateDtosConfig) {\n super(config, 'prisma-validate-dtos', 'prisma-validate-dtos');\n }\n\n async run(workspaceRoot: string): Promise<ExecutorResult> {\n return runValidatorImpl(this.config, workspaceRoot);\n }\n}\n"]}
@@ -95,7 +95,7 @@ function reportInvalidValues(invalid, knownTypes, mode) {
95
95
  const FRAMEWORK_TAG_SPEC = new tag_rule_1.TagRuleSpec(FRAMEWORK_TAG_PREFIX, 'framework-tag', 'Framework Tag', DEFAULT_KNOWN_TYPES, reportViolations, true, reportInvalidValues);
96
96
  let FrameworkTagValidator = class FrameworkTagValidator extends code_validator_1.CodeValidator {
97
97
  constructor(config) {
98
- super(config, 'framework-tag');
98
+ super(config, 'framework-tag', 'framework-tag');
99
99
  }
100
100
  async run(workspaceRoot) {
101
101
  return (0, tag_rule_1.runTagValidator)(this.config, workspaceRoot, FRAMEWORK_TAG_SPEC);
@@ -1 +1 @@
1
- {"version":3,"file":"validate-framework-tag.js","sourceRoot":"","sources":["../../../../../packages/tooling/code-rules/src/validate-framework-tag.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Validate Framework Tag Executor\n *\n * Every project that a changed source file belongs to must carry at least one\n * `framework:<value>` nx tag in its project.json. Those tags are the project's\n * \"libType\" — the SET of runtime environments it is validated to run in, drawn\n * from the atomic values:\n *\n * framework:browser | framework:react | framework:angular\n * framework:node | framework:express\n *\n * A project lists EVERY environment it promises to run in (e.g.\n * `framework:browser` + `framework:node`). This env set is the source of truth\n * for the `framework` field written into architecture/dependencies.json and for\n * the `library-types-match-client` rule, which uses the compatibility lattice\n * (react/angular→browser, express→node) to keep an express project from\n * depending on a browser-only library (and vice-versa).\n *\n * The legacy single-value `framework:all` \"usable by any side\" bucket is\n * REMOVED — it is a hard error, and the author must declare the actual env set.\n *\n * The project-walking + diff-scoping + mode logic is shared with the `role-tag`\n * rule in `tag-rule.ts`; this file supplies only the framework-specific prefix,\n * known values, and violation messages. Unlike role-tag, framework-tag ALSO\n * validates tag VALUES (allowing multiple) via {@link TagRuleSpec.validateValues}.\n *\n * ============================================================================\n * MODES (PROJECT-LEVEL)\n * ============================================================================\n * - OFF: Skip validation entirely.\n * - MODIFIED_PROJECTS: Require >=1 valid framework tag on every project that\n * owns ANY changed file (not just .ts, and not line-scoped).\n */\n\nimport { ProjectMode, FrameworkTagConfig } from '@webpieces/rules-config';\nimport { CodeValidator, ExecutorResult } from './code-validator';\nimport { injectable, bindingScopeValues } from 'inversify';\nimport {\n InvalidTagProject,\n MissingTagProject,\n TagRuleSpec,\n findProjectsMissingTag,\n runTagValidator,\n} from './tag-rule';\n\nconst FRAMEWORK_TAG_PREFIX = 'framework:';\nconst DEFAULT_KNOWN_TYPES = ['browser', 'react', 'angular', 'node', 'express'];\n\n/** The removed legacy libType, kept only to emit a targeted migration message. */\nconst REMOVED_ALL_VALUE = 'all';\n\n/**\n * Back-compat export used by tests: the framework-tag flavor of the shared\n * missing-tag scan.\n */\nexport function findUntaggedProjects(workspaceRoot: string, changedFiles: string[]): MissingTagProject[] {\n return findProjectsMissingTag(workspaceRoot, changedFiles, FRAMEWORK_TAG_PREFIX);\n}\n\nfunction reportViolations(untagged: MissingTagProject[], knownTypes: string[], mode: ProjectMode): void {\n const suggestion = knownTypes.map((t: string) => `${FRAMEWORK_TAG_PREFIX}${t}`).join(' | ');\n console.error('');\n console.error('❌ Every modified project must declare the env set it runs in (>=1 framework tag)!');\n console.error('');\n console.error(` Add ONE OR MORE of these to the project's project.json \"tags\" array: ${suggestion}`);\n console.error(' (react/angular specialize browser; express specializes node. A project that runs in');\n console.error(' both the browser and node declares BOTH, e.g. framework:browser + framework:node.)');\n console.error(' This libType drives architecture/dependencies.json and the library-types-match-client rule.');\n console.error('');\n\n for (const project of untagged) {\n console.error(` ❌ ${project.name} — ${project.projectJsonPath}`);\n console.error(` add e.g. \"tags\": [\"${FRAMEWORK_TAG_PREFIX}browser\", \"${FRAMEWORK_TAG_PREFIX}node\"]`);\n }\n console.error('');\n console.error(` Current mode: ${mode}`);\n console.error('');\n}\n\nfunction reportInvalidValues(invalid: InvalidTagProject[], knownTypes: string[], mode: ProjectMode): void {\n const known = knownTypes.map((t: string) => `${FRAMEWORK_TAG_PREFIX}${t}`).join(' | ');\n console.error('');\n console.error('❌ Some modified projects carry an unknown framework tag value!');\n console.error('');\n console.error(` Allowed values: ${known}`);\n console.error('');\n\n for (const project of invalid) {\n console.error(` ❌ ${project.name} — ${project.projectJsonPath}`);\n for (const bad of project.badValues) {\n if (bad === REMOVED_ALL_VALUE) {\n console.error(\n ` framework:all is removed — declare the actual env set, ` +\n `e.g. framework:browser + framework:node`\n );\n } else {\n console.error(` unknown value \"${FRAMEWORK_TAG_PREFIX}${bad}\" — use one of: ${known}`);\n }\n }\n }\n console.error('');\n console.error(` Current mode: ${mode}`);\n console.error('');\n}\n\nconst FRAMEWORK_TAG_SPEC = new TagRuleSpec(\n FRAMEWORK_TAG_PREFIX,\n 'framework-tag',\n 'Framework Tag',\n DEFAULT_KNOWN_TYPES,\n reportViolations,\n true,\n reportInvalidValues\n);\n\n@injectable(bindingScopeValues.Singleton)\nexport class FrameworkTagValidator extends CodeValidator<FrameworkTagConfig> {\n constructor(config: FrameworkTagConfig) {\n super(config, 'framework-tag');\n }\n\n async run(workspaceRoot: string): Promise<ExecutorResult> {\n return runTagValidator(this.config, workspaceRoot, FRAMEWORK_TAG_SPEC);\n }\n}\n"]}
1
+ {"version":3,"file":"validate-framework-tag.js","sourceRoot":"","sources":["../../../../../packages/tooling/code-rules/src/validate-framework-tag.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Validate Framework Tag Executor\n *\n * Every project that a changed source file belongs to must carry at least one\n * `framework:<value>` nx tag in its project.json. Those tags are the project's\n * \"libType\" — the SET of runtime environments it is validated to run in, drawn\n * from the atomic values:\n *\n * framework:browser | framework:react | framework:angular\n * framework:node | framework:express\n *\n * A project lists EVERY environment it promises to run in (e.g.\n * `framework:browser` + `framework:node`). This env set is the source of truth\n * for the `framework` field written into architecture/dependencies.json and for\n * the `library-types-match-client` rule, which uses the compatibility lattice\n * (react/angular→browser, express→node) to keep an express project from\n * depending on a browser-only library (and vice-versa).\n *\n * The legacy single-value `framework:all` \"usable by any side\" bucket is\n * REMOVED — it is a hard error, and the author must declare the actual env set.\n *\n * The project-walking + diff-scoping + mode logic is shared with the `role-tag`\n * rule in `tag-rule.ts`; this file supplies only the framework-specific prefix,\n * known values, and violation messages. Unlike role-tag, framework-tag ALSO\n * validates tag VALUES (allowing multiple) via {@link TagRuleSpec.validateValues}.\n *\n * ============================================================================\n * MODES (PROJECT-LEVEL)\n * ============================================================================\n * - OFF: Skip validation entirely.\n * - MODIFIED_PROJECTS: Require >=1 valid framework tag on every project that\n * owns ANY changed file (not just .ts, and not line-scoped).\n */\n\nimport { ProjectMode, FrameworkTagConfig } from '@webpieces/rules-config';\nimport { CodeValidator, ExecutorResult } from './code-validator';\nimport { injectable, bindingScopeValues } from 'inversify';\nimport {\n InvalidTagProject,\n MissingTagProject,\n TagRuleSpec,\n findProjectsMissingTag,\n runTagValidator,\n} from './tag-rule';\n\nconst FRAMEWORK_TAG_PREFIX = 'framework:';\nconst DEFAULT_KNOWN_TYPES = ['browser', 'react', 'angular', 'node', 'express'];\n\n/** The removed legacy libType, kept only to emit a targeted migration message. */\nconst REMOVED_ALL_VALUE = 'all';\n\n/**\n * Back-compat export used by tests: the framework-tag flavor of the shared\n * missing-tag scan.\n */\nexport function findUntaggedProjects(workspaceRoot: string, changedFiles: string[]): MissingTagProject[] {\n return findProjectsMissingTag(workspaceRoot, changedFiles, FRAMEWORK_TAG_PREFIX);\n}\n\nfunction reportViolations(untagged: MissingTagProject[], knownTypes: string[], mode: ProjectMode): void {\n const suggestion = knownTypes.map((t: string) => `${FRAMEWORK_TAG_PREFIX}${t}`).join(' | ');\n console.error('');\n console.error('❌ Every modified project must declare the env set it runs in (>=1 framework tag)!');\n console.error('');\n console.error(` Add ONE OR MORE of these to the project's project.json \"tags\" array: ${suggestion}`);\n console.error(' (react/angular specialize browser; express specializes node. A project that runs in');\n console.error(' both the browser and node declares BOTH, e.g. framework:browser + framework:node.)');\n console.error(' This libType drives architecture/dependencies.json and the library-types-match-client rule.');\n console.error('');\n\n for (const project of untagged) {\n console.error(` ❌ ${project.name} — ${project.projectJsonPath}`);\n console.error(` add e.g. \"tags\": [\"${FRAMEWORK_TAG_PREFIX}browser\", \"${FRAMEWORK_TAG_PREFIX}node\"]`);\n }\n console.error('');\n console.error(` Current mode: ${mode}`);\n console.error('');\n}\n\nfunction reportInvalidValues(invalid: InvalidTagProject[], knownTypes: string[], mode: ProjectMode): void {\n const known = knownTypes.map((t: string) => `${FRAMEWORK_TAG_PREFIX}${t}`).join(' | ');\n console.error('');\n console.error('❌ Some modified projects carry an unknown framework tag value!');\n console.error('');\n console.error(` Allowed values: ${known}`);\n console.error('');\n\n for (const project of invalid) {\n console.error(` ❌ ${project.name} — ${project.projectJsonPath}`);\n for (const bad of project.badValues) {\n if (bad === REMOVED_ALL_VALUE) {\n console.error(\n ` framework:all is removed — declare the actual env set, ` +\n `e.g. framework:browser + framework:node`\n );\n } else {\n console.error(` unknown value \"${FRAMEWORK_TAG_PREFIX}${bad}\" — use one of: ${known}`);\n }\n }\n }\n console.error('');\n console.error(` Current mode: ${mode}`);\n console.error('');\n}\n\nconst FRAMEWORK_TAG_SPEC = new TagRuleSpec(\n FRAMEWORK_TAG_PREFIX,\n 'framework-tag',\n 'Framework Tag',\n DEFAULT_KNOWN_TYPES,\n reportViolations,\n true,\n reportInvalidValues\n);\n\n@injectable(bindingScopeValues.Singleton)\nexport class FrameworkTagValidator extends CodeValidator<FrameworkTagConfig> {\n constructor(config: FrameworkTagConfig) {\n super(config, 'framework-tag', 'framework-tag');\n }\n\n async run(workspaceRoot: string): Promise<ExecutorResult> {\n return runTagValidator(this.config, workspaceRoot, FRAMEWORK_TAG_SPEC);\n }\n}\n"]}
@@ -260,7 +260,7 @@ async function runValidatorImpl(options, workspaceRoot) {
260
260
  }
261
261
  let InjectAnnotationNotNeededForConcreteClassValidator = class InjectAnnotationNotNeededForConcreteClassValidator extends code_validator_1.CodeValidator {
262
262
  constructor(config) {
263
- super(config, RULE_NAME);
263
+ super(config, RULE_NAME, RULE_NAME);
264
264
  }
265
265
  async run(workspaceRoot) {
266
266
  return runValidatorImpl(this.config, workspaceRoot);
@@ -1 +1 @@
1
- {"version":3,"file":"validate-inject-annotation-not-needed-for-concrete-class.js","sourceRoot":"","sources":["../../../../../packages/tooling/code-rules/src/validate-inject-annotation-not-needed-for-concrete-class.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Validate Inject Annotation Not Needed For Concrete Class\n *\n * Flags a REDUNDANT `@inject(X)` on a CONSTRUCTOR parameter whose token is textually identical to the\n * parameter's own declared type:\n *\n * BAD: constructor(@inject(RequestContextHeaders) private readonly h: RequestContextHeaders) {}\n * GOOD: constructor(private readonly h: RequestContextHeaders) {}\n *\n * WHY: in this inversify setup a constructor parameter is auto-resolved by its class TYPE via\n * reflect-metadata (`emitDecoratorMetadata` emits `design:paramtypes`). So `private readonly h: Foo`\n * already binds `Foo` — the `@inject(Foo)` adds nothing (see CLAUDE.md, and the sibling\n * no-symbol-di-tokens rule that pushes the same inject-by-type pattern). AI keeps carpet-bombing\n * `@inject`; this fails the build on the redundant form so it stops.\n *\n * Uses the TypeScript AST (not a regex) so \"token equals the parameter type\" is decided precisely.\n * That single rule is what makes every LEGITIMATE token pass untouched — a real token never equals the\n * type it resolves:\n * - `@inject(TASK_PROXY_CLIENT_PROVIDER) x: Provider<TaskProxyClient>` (Symbol token ≠ type)\n * - `@inject(WEBPIECES_CONFIG_TOKEN) c: WebpiecesConfig` (Symbol ≠ interface type)\n * - `@inject('some-string') x: Foo` (string token ≠ type)\n * - `@inject(Symbol.for('X')) x: Foo` (not a bare identifier)\n *\n * SCOPE: only CONSTRUCTOR parameters. Property injection (`@inject(Foo) private foo: Foo` on a class\n * field) genuinely REQUIRES `@inject` in inversify — there is no design:type auto-wiring for properties\n * — so it is left alone.\n *\n * ALLOWED (skip — NOT violations)\n * - Any `@inject(TOKEN)` whose token differs from the parameter's type (Symbols, string tokens,\n * provider tokens, interface tokens).\n * - Property/field injection, and any parameter without an `@inject` decorator.\n * - Test files (*.test.ts, *.spec.ts, __tests__/**).\n * - Files under a configured `allowedPaths` glob (shared isPathExcluded glob/prefix/segment semantics).\n * - Lines with `// webpieces-disable inject-annotation-not-needed-for-concrete-class -- <reason>`\n * (only when disableAllowed).\n *\n * MODES (AST + LINE-SCOPED)\n * - OFF: Skip.\n * - NEW_AND_MODIFIED_CODE: Flag only on changed lines (diff hunks).\n * - NEW_AND_MODIFIED_FILES: Flag every occurrence in any modified file.\n */\n\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport * as ts from 'typescript';\nimport { hasDisable, RULE_NAMES, InjectAnnotationNotNeededForConcreteClassConfig, ModifiedCodeMode, detectBase, getChangedFiles, getFileDiff, getChangedLineNumbers, isPathExcluded } from '@webpieces/rules-config';\nimport { CodeValidator, ExecutorResult } from './code-validator';\nimport { injectable, bindingScopeValues } from 'inversify';\nimport { shouldSkipRule } from './resolve-mode';\n\nconst RULE_NAME = RULE_NAMES.INJECT_ANNOTATION_NOT_NEEDED_FOR_CONCRETE_CLASS;\n\nconst SHARED_MESSAGE = `@inject(Foo) on a constructor parameter typed \\`: Foo\\` is noise — inversify resolves a constructor\nparameter by its class type via reflect-metadata, so \\`private readonly foo: Foo\\` already binds it\n(see CLAUDE.md). Pick one:\n Fix Option 1 (PREFERRED): delete the decorator — constructor(private readonly foo: Foo) {}\n Fix Option 2: if you actually need a DIFFERENT binding token (a Symbol for a generated\n http-client-node / cloud-tasks client, or an interface/config with multiple impls), inject that\n token so it DIFFERS from the type: @inject(FOO_TOKEN) foo: SomeInterface.\nProperty injection (@inject on a class field, not a constructor param) is NOT flagged — it genuinely\nneeds @inject. Only a constructor param whose token equals its own type is redundant.`;\n\ninterface InjectViolation {\n file: string;\n line: number;\n column: number;\n context: string;\n}\n\ninterface InjectViolationInfo {\n line: number;\n column: number;\n context: string;\n hasDisableComment: boolean;\n}\n\n// webpieces-disable no-function-outside-class -- the rule engine is inherently functional; validators can't be class members\nfunction isTestFile(filePath: string): boolean {\n return filePath.includes('.spec.ts') || filePath.includes('.test.ts') || filePath.includes('__tests__/');\n}\n\n// webpieces-disable no-function-outside-class -- the rule engine is inherently functional; validators can't be class members\nfunction isDeclarationFile(filePath: string): boolean {\n return filePath.endsWith('.d.ts');\n}\n\n// The violation line (or the line just above it) carries the disable comment.\n// webpieces-disable no-function-outside-class -- the rule engine is inherently functional; validators can't be class members\nfunction hasDisableOnLine(fileLines: string[], lineNumber: number): boolean {\n const current = fileLines[lineNumber - 1] ?? '';\n const previous = lineNumber >= 2 ? (fileLines[lineNumber - 2] ?? '') : '';\n return hasDisable(current, RULE_NAME) || hasDisable(previous, RULE_NAME);\n}\n\n// The `@inject(X)` decorator's single argument, when it is a BARE identifier (a class/token name).\n// Returns null for Symbol.for(...), property-access (`Symbol.x`), string literals, or a non-inject\n// decorator — those can never equal the parameter type, so they are never redundant.\n// webpieces-disable no-function-outside-class -- the rule engine is inherently functional; validators can't be class members\nfunction injectIdentifierArg(decorator: ts.Decorator): string | null {\n const expr = decorator.expression;\n if (!ts.isCallExpression(expr)) return null;\n if (!ts.isIdentifier(expr.expression) || expr.expression.text !== 'inject') return null;\n if (expr.arguments.length !== 1) return null;\n const arg = expr.arguments[0];\n return arg && ts.isIdentifier(arg) ? arg.text : null;\n}\n\n// The parameter's declared type when it is a simple `TypeReference` with an identifier name\n// (`Foo`, or `Foo<Bar>` → `Foo`). Qualified names (`ns.Foo`) and non-references return null.\n// webpieces-disable no-function-outside-class -- the rule engine is inherently functional; validators can't be class members\nfunction paramTypeName(param: ts.ParameterDeclaration): string | null {\n const typeNode = param.type;\n if (!typeNode || !ts.isTypeReferenceNode(typeNode)) return null;\n return ts.isIdentifier(typeNode.typeName) ? typeNode.typeName.text : null;\n}\n\n// AST scan: a CONSTRUCTOR parameter is a violation when it carries `@inject(X)` and its declared type\n// is exactly `X`. Property injection and method params are ignored (only constructor params).\n// webpieces-disable no-function-outside-class -- the rule engine is inherently functional; validators can't be class members\nexport function findRedundantInjectInSource(content: string, filePath: string, disableAllowed: boolean): InjectViolationInfo[] {\n if (isDeclarationFile(filePath)) return [];\n const fileLines = content.split('\\n');\n const sourceFile = ts.createSourceFile(filePath, content, ts.ScriptTarget.Latest, true);\n const violations: InjectViolationInfo[] = [];\n\n function checkParameter(param: ts.ParameterDeclaration): void {\n const decorators = ts.canHaveDecorators(param) ? ts.getDecorators(param) : undefined;\n if (!decorators) return;\n const typeName = paramTypeName(param);\n if (!typeName) return;\n for (const decorator of decorators) {\n if (injectIdentifierArg(decorator) === typeName) {\n recordViolation(param, `@inject(${typeName}) is redundant — the parameter is typed \\`: ${typeName}\\` and resolves by type`, fileLines, sourceFile, violations, disableAllowed);\n return;\n }\n }\n }\n\n function visit(node: ts.Node): void {\n if (ts.isConstructorDeclaration(node)) {\n for (const param of node.parameters) checkParameter(param);\n }\n ts.forEachChild(node, visit);\n }\n\n visit(sourceFile);\n return violations;\n}\n\n// webpieces-disable no-function-outside-class -- the rule engine is inherently functional; validators can't be class members\nfunction recordViolation(\n node: ts.Node,\n context: string,\n fileLines: string[],\n sourceFile: ts.SourceFile,\n violations: InjectViolationInfo[],\n disableAllowed: boolean,\n): void {\n const startPos = node.getStart(sourceFile);\n if (startPos < 0) return;\n const pos = sourceFile.getLineAndCharacterOfPosition(startPos);\n const line = pos.line + 1;\n const column = pos.character + 1;\n const disabled = hasDisableOnLine(fileLines, line);\n // When disableAllowed is false, a disable comment does NOT clear the violation.\n const effectiveDisabled = disableAllowed ? disabled : false;\n violations.push({ line, column, context, hasDisableComment: effectiveDisabled });\n}\n\n// webpieces-disable no-function-outside-class -- the rule engine is inherently functional; validators can't be class members\nfunction findRedundantInjectInFile(filePath: string, workspaceRoot: string, disableAllowed: boolean, allowedPaths: string[]): InjectViolationInfo[] {\n if (isTestFile(filePath)) return [];\n if (isPathExcluded(filePath, allowedPaths)) return [];\n const fullPath = path.join(workspaceRoot, filePath);\n if (!fs.existsSync(fullPath)) return [];\n const content = fs.readFileSync(fullPath, 'utf-8');\n return findRedundantInjectInSource(content, filePath, disableAllowed);\n}\n\n// webpieces-disable no-function-outside-class -- the rule engine is inherently functional; validators can't be class members\nfunction findViolationsForModifiedCode(workspaceRoot: string, changedFiles: string[], base: string, head: string | undefined, disableAllowed: boolean, allowedPaths: string[]): InjectViolation[] {\n const violations: InjectViolation[] = [];\n for (const file of changedFiles) {\n const changedLines = getChangedLineNumbers(getFileDiff(workspaceRoot, file, base, head));\n if (changedLines.size === 0) continue;\n for (const v of findRedundantInjectInFile(file, workspaceRoot, disableAllowed, allowedPaths)) {\n if (disableAllowed && v.hasDisableComment) continue;\n if (!changedLines.has(v.line)) continue;\n violations.push({ file, line: v.line, column: v.column, context: v.context });\n }\n }\n return violations;\n}\n\n// webpieces-disable no-function-outside-class -- the rule engine is inherently functional; validators can't be class members\nfunction findViolationsForModifiedFiles(workspaceRoot: string, changedFiles: string[], disableAllowed: boolean, allowedPaths: string[]): InjectViolation[] {\n const violations: InjectViolation[] = [];\n for (const file of changedFiles) {\n for (const v of findRedundantInjectInFile(file, workspaceRoot, disableAllowed, allowedPaths)) {\n if (disableAllowed && v.hasDisableComment) continue;\n violations.push({ file, line: v.line, column: v.column, context: v.context });\n }\n }\n return violations;\n}\n\n// webpieces-disable no-function-outside-class -- the rule engine is inherently functional; validators can't be class members\nfunction reportViolations(violations: InjectViolation[], mode: ModifiedCodeMode, disableAllowed: boolean): void {\n console.error('');\n console.error('❌ Redundant @inject — the parameter\\'s type already resolves it.');\n console.error('');\n console.error(SHARED_MESSAGE);\n console.error('');\n for (const v of violations) {\n console.error(` ❌ ${v.file}:${v.line}:${v.column}`);\n console.error(` ${v.context}`);\n }\n console.error('');\n console.error(disableAllowed\n ? ` Escape hatch (use sparingly): // webpieces-disable ${RULE_NAME} -- <reason>`\n : ' Escape hatch: DISABLED (disableAllowed: false)');\n console.error(` Whole-tree exemption: add a glob to ${RULE_NAME}.allowedPaths in webpieces.config.json`);\n console.error(`\\n Current mode: ${mode}\\n`);\n}\n\n// webpieces-disable no-function-outside-class -- the rule engine is inherently functional; validators can't be class members\nfunction resolveMode(normalMode: ModifiedCodeMode, epoch: number | undefined, branchPattern: string | undefined): ModifiedCodeMode {\n if (normalMode === 'OFF') return normalMode;\n const skip = shouldSkipRule(epoch, branchPattern);\n if (skip.skip) {\n console.log(`\\n⏭️ Skipping ${RULE_NAME} validation (${skip.reason})\\n`);\n return 'OFF';\n }\n return normalMode;\n}\n\n// webpieces-disable no-function-outside-class -- the rule engine is inherently functional; validators can't be class members\nasync function runValidatorImpl(options: InjectAnnotationNotNeededForConcreteClassConfig, workspaceRoot: string): Promise<ExecutorResult> {\n const mode: ModifiedCodeMode = resolveMode(options.mode ?? 'OFF', options.turnOffRuleUntilEpoch, (options.turnOffRuleWhileOnBranch ?? undefined));\n const disableAllowed = options.disableAllowed ?? true;\n const allowedPaths = options.allowedPaths ?? [];\n\n if (mode === 'OFF') {\n console.log(`\\n⏭️ Skipping ${RULE_NAME} validation (mode: OFF)\\n`);\n return { success: true };\n }\n\n console.log(`\\n📏 Validating ${RULE_NAME}\\n`);\n console.log(` Mode: ${mode}`);\n\n let base = process.env['NX_BASE'];\n const head = process.env['NX_HEAD'];\n if (!base) {\n base = detectBase(workspaceRoot) ?? undefined;\n if (!base) {\n console.log(`\\n⏭️ Skipping ${RULE_NAME} validation (could not detect base branch)\\n`);\n return { success: true };\n }\n }\n\n console.log(` Base: ${base}`);\n console.log(` Head: ${head ?? 'working tree (includes uncommitted changes)'}\\n`);\n\n const changedFiles = getChangedFiles(workspaceRoot, base, head);\n if (changedFiles.length === 0) {\n console.log('✅ No TypeScript files changed');\n return { success: true };\n }\n\n console.log(`📂 Checking ${changedFiles.length} changed file(s)...`);\n\n let violations: InjectViolation[] = [];\n if (mode === 'NEW_AND_MODIFIED_CODE') {\n violations = findViolationsForModifiedCode(workspaceRoot, changedFiles, base, head, disableAllowed, allowedPaths);\n } else if (mode === 'NEW_AND_MODIFIED_FILES') {\n violations = findViolationsForModifiedFiles(workspaceRoot, changedFiles, disableAllowed, allowedPaths);\n }\n\n if (violations.length === 0) {\n console.log('✅ No redundant-@inject violations found');\n return { success: true };\n }\n\n reportViolations(violations, mode, disableAllowed);\n return { success: false };\n}\n\n@injectable(bindingScopeValues.Singleton)\nexport class InjectAnnotationNotNeededForConcreteClassValidator extends CodeValidator<InjectAnnotationNotNeededForConcreteClassConfig> {\n constructor(config: InjectAnnotationNotNeededForConcreteClassConfig) {\n super(config, RULE_NAME);\n }\n\n async run(workspaceRoot: string): Promise<ExecutorResult> {\n return runValidatorImpl(this.config, workspaceRoot);\n }\n}\n"]}
1
+ {"version":3,"file":"validate-inject-annotation-not-needed-for-concrete-class.js","sourceRoot":"","sources":["../../../../../packages/tooling/code-rules/src/validate-inject-annotation-not-needed-for-concrete-class.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;;;AA+EH,kEA4BC;;AAzGD,+CAAyB;AACzB,mDAA6B;AAC7B,uDAAiC;AACjC,0DAAqN;AACrN,qDAAiE;AACjE,yCAA2D;AAC3D,iDAAgD;AAEhD,MAAM,SAAS,GAAG,yBAAU,CAAC,+CAA+C,CAAC;AAE7E,MAAM,cAAc,GAAG;;;;;;;;sFAQ+D,CAAC;AAgBvF,6HAA6H;AAC7H,SAAS,UAAU,CAAC,QAAgB;IAChC,OAAO,QAAQ,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,QAAQ,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,QAAQ,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC;AAC7G,CAAC;AAED,6HAA6H;AAC7H,SAAS,iBAAiB,CAAC,QAAgB;IACvC,OAAO,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;AACtC,CAAC;AAED,8EAA8E;AAC9E,6HAA6H;AAC7H,SAAS,gBAAgB,CAAC,SAAmB,EAAE,UAAkB;IAC7D,MAAM,OAAO,GAAG,SAAS,CAAC,UAAU,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;IAChD,MAAM,QAAQ,GAAG,UAAU,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,UAAU,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAC1E,OAAO,IAAA,yBAAU,EAAC,OAAO,EAAE,SAAS,CAAC,IAAI,IAAA,yBAAU,EAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;AAC7E,CAAC;AAED,mGAAmG;AACnG,mGAAmG;AACnG,qFAAqF;AACrF,6HAA6H;AAC7H,SAAS,mBAAmB,CAAC,SAAuB;IAChD,MAAM,IAAI,GAAG,SAAS,CAAC,UAAU,CAAC;IAClC,IAAI,CAAC,EAAE,CAAC,gBAAgB,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IAC5C,IAAI,CAAC,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC;IACxF,IAAI,IAAI,CAAC,SAAS,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAC7C,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;IAC9B,OAAO,GAAG,IAAI,EAAE,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;AACzD,CAAC;AAED,4FAA4F;AAC5F,6FAA6F;AAC7F,6HAA6H;AAC7H,SAAS,aAAa,CAAC,KAA8B;IACjD,MAAM,QAAQ,GAAG,KAAK,CAAC,IAAI,CAAC;IAC5B,IAAI,CAAC,QAAQ,IAAI,CAAC,EAAE,CAAC,mBAAmB,CAAC,QAAQ,CAAC;QAAE,OAAO,IAAI,CAAC;IAChE,OAAO,EAAE,CAAC,YAAY,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;AAC9E,CAAC;AAED,sGAAsG;AACtG,8FAA8F;AAC9F,6HAA6H;AAC7H,SAAgB,2BAA2B,CAAC,OAAe,EAAE,QAAgB,EAAE,cAAuB;IAClG,IAAI,iBAAiB,CAAC,QAAQ,CAAC;QAAE,OAAO,EAAE,CAAC;IAC3C,MAAM,SAAS,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACtC,MAAM,UAAU,GAAG,EAAE,CAAC,gBAAgB,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,CAAC,YAAY,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IACxF,MAAM,UAAU,GAA0B,EAAE,CAAC;IAE7C,SAAS,cAAc,CAAC,KAA8B;QAClD,MAAM,UAAU,GAAG,EAAE,CAAC,iBAAiB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QACrF,IAAI,CAAC,UAAU;YAAE,OAAO;QACxB,MAAM,QAAQ,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC;QACtC,IAAI,CAAC,QAAQ;YAAE,OAAO;QACtB,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;YACjC,IAAI,mBAAmB,CAAC,SAAS,CAAC,KAAK,QAAQ,EAAE,CAAC;gBAC9C,eAAe,CAAC,KAAK,EAAE,WAAW,QAAQ,+CAA+C,QAAQ,yBAAyB,EAAE,SAAS,EAAE,UAAU,EAAE,UAAU,EAAE,cAAc,CAAC,CAAC;gBAC/K,OAAO;YACX,CAAC;QACL,CAAC;IACL,CAAC;IAED,SAAS,KAAK,CAAC,IAAa;QACxB,IAAI,EAAE,CAAC,wBAAwB,CAAC,IAAI,CAAC,EAAE,CAAC;YACpC,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,UAAU;gBAAE,cAAc,CAAC,KAAK,CAAC,CAAC;QAC/D,CAAC;QACD,EAAE,CAAC,YAAY,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IACjC,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,CAAC;IAClB,OAAO,UAAU,CAAC;AACtB,CAAC;AAED,6HAA6H;AAC7H,SAAS,eAAe,CACpB,IAAa,EACb,OAAe,EACf,SAAmB,EACnB,UAAyB,EACzB,UAAiC,EACjC,cAAuB;IAEvB,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;IAC3C,IAAI,QAAQ,GAAG,CAAC;QAAE,OAAO;IACzB,MAAM,GAAG,GAAG,UAAU,CAAC,6BAA6B,CAAC,QAAQ,CAAC,CAAC;IAC/D,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,GAAG,CAAC,CAAC;IAC1B,MAAM,MAAM,GAAG,GAAG,CAAC,SAAS,GAAG,CAAC,CAAC;IACjC,MAAM,QAAQ,GAAG,gBAAgB,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;IACnD,gFAAgF;IAChF,MAAM,iBAAiB,GAAG,cAAc,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC;IAC5D,UAAU,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,CAAC,CAAC;AACrF,CAAC;AAED,6HAA6H;AAC7H,SAAS,yBAAyB,CAAC,QAAgB,EAAE,aAAqB,EAAE,cAAuB,EAAE,YAAsB;IACvH,IAAI,UAAU,CAAC,QAAQ,CAAC;QAAE,OAAO,EAAE,CAAC;IACpC,IAAI,IAAA,6BAAc,EAAC,QAAQ,EAAE,YAAY,CAAC;QAAE,OAAO,EAAE,CAAC;IACtD,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,QAAQ,CAAC,CAAC;IACpD,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC;QAAE,OAAO,EAAE,CAAC;IACxC,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IACnD,OAAO,2BAA2B,CAAC,OAAO,EAAE,QAAQ,EAAE,cAAc,CAAC,CAAC;AAC1E,CAAC;AAED,6HAA6H;AAC7H,SAAS,6BAA6B,CAAC,aAAqB,EAAE,YAAsB,EAAE,IAAY,EAAE,IAAwB,EAAE,cAAuB,EAAE,YAAsB;IACzK,MAAM,UAAU,GAAsB,EAAE,CAAC;IACzC,KAAK,MAAM,IAAI,IAAI,YAAY,EAAE,CAAC;QAC9B,MAAM,YAAY,GAAG,IAAA,oCAAqB,EAAC,IAAA,0BAAW,EAAC,aAAa,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC;QACzF,IAAI,YAAY,CAAC,IAAI,KAAK,CAAC;YAAE,SAAS;QACtC,KAAK,MAAM,CAAC,IAAI,yBAAyB,CAAC,IAAI,EAAE,aAAa,EAAE,cAAc,EAAE,YAAY,CAAC,EAAE,CAAC;YAC3F,IAAI,cAAc,IAAI,CAAC,CAAC,iBAAiB;gBAAE,SAAS;YACpD,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC;gBAAE,SAAS;YACxC,UAAU,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;QAClF,CAAC;IACL,CAAC;IACD,OAAO,UAAU,CAAC;AACtB,CAAC;AAED,6HAA6H;AAC7H,SAAS,8BAA8B,CAAC,aAAqB,EAAE,YAAsB,EAAE,cAAuB,EAAE,YAAsB;IAClI,MAAM,UAAU,GAAsB,EAAE,CAAC;IACzC,KAAK,MAAM,IAAI,IAAI,YAAY,EAAE,CAAC;QAC9B,KAAK,MAAM,CAAC,IAAI,yBAAyB,CAAC,IAAI,EAAE,aAAa,EAAE,cAAc,EAAE,YAAY,CAAC,EAAE,CAAC;YAC3F,IAAI,cAAc,IAAI,CAAC,CAAC,iBAAiB;gBAAE,SAAS;YACpD,UAAU,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;QAClF,CAAC;IACL,CAAC;IACD,OAAO,UAAU,CAAC;AACtB,CAAC;AAED,6HAA6H;AAC7H,SAAS,gBAAgB,CAAC,UAA6B,EAAE,IAAsB,EAAE,cAAuB;IACpG,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAClB,OAAO,CAAC,KAAK,CAAC,kEAAkE,CAAC,CAAC;IAClF,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAClB,OAAO,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;IAC9B,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAClB,KAAK,MAAM,CAAC,IAAI,UAAU,EAAE,CAAC;QACzB,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;QACrD,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;IACvC,CAAC;IACD,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAClB,OAAO,CAAC,KAAK,CAAC,cAAc;QACxB,CAAC,CAAC,yDAAyD,SAAS,cAAc;QAClF,CAAC,CAAC,mDAAmD,CAAC,CAAC;IAC3D,OAAO,CAAC,KAAK,CAAC,0CAA0C,SAAS,wCAAwC,CAAC,CAAC;IAC3G,OAAO,CAAC,KAAK,CAAC,sBAAsB,IAAI,IAAI,CAAC,CAAC;AAClD,CAAC;AAED,6HAA6H;AAC7H,SAAS,WAAW,CAAC,UAA4B,EAAE,KAAyB,EAAE,aAAiC;IAC3G,IAAI,UAAU,KAAK,KAAK;QAAE,OAAO,UAAU,CAAC;IAC5C,MAAM,IAAI,GAAG,IAAA,6BAAc,EAAC,KAAK,EAAE,aAAa,CAAC,CAAC;IAClD,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;QACZ,OAAO,CAAC,GAAG,CAAC,kBAAkB,SAAS,gBAAgB,IAAI,CAAC,MAAM,KAAK,CAAC,CAAC;QACzE,OAAO,KAAK,CAAC;IACjB,CAAC;IACD,OAAO,UAAU,CAAC;AACtB,CAAC;AAED,6HAA6H;AAC7H,KAAK,UAAU,gBAAgB,CAAC,OAAwD,EAAE,aAAqB;IAC3G,MAAM,IAAI,GAAqB,WAAW,CAAC,OAAO,CAAC,IAAI,IAAI,KAAK,EAAE,OAAO,CAAC,qBAAqB,EAAE,CAAC,OAAO,CAAC,wBAAwB,IAAI,SAAS,CAAC,CAAC,CAAC;IAClJ,MAAM,cAAc,GAAG,OAAO,CAAC,cAAc,IAAI,IAAI,CAAC;IACtD,MAAM,YAAY,GAAG,OAAO,CAAC,YAAY,IAAI,EAAE,CAAC;IAEhD,IAAI,IAAI,KAAK,KAAK,EAAE,CAAC;QACjB,OAAO,CAAC,GAAG,CAAC,kBAAkB,SAAS,2BAA2B,CAAC,CAAC;QACpE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IAC7B,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,mBAAmB,SAAS,IAAI,CAAC,CAAC;IAC9C,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,EAAE,CAAC,CAAC;IAEhC,IAAI,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IAClC,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IACpC,IAAI,CAAC,IAAI,EAAE,CAAC;QACR,IAAI,GAAG,IAAA,yBAAU,EAAC,aAAa,CAAC,IAAI,SAAS,CAAC;QAC9C,IAAI,CAAC,IAAI,EAAE,CAAC;YACR,OAAO,CAAC,GAAG,CAAC,kBAAkB,SAAS,8CAA8C,CAAC,CAAC;YACvF,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;QAC7B,CAAC;IACL,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,EAAE,CAAC,CAAC;IAChC,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,IAAI,6CAA6C,IAAI,CAAC,CAAC;IAEnF,MAAM,YAAY,GAAG,IAAA,8BAAe,EAAC,aAAa,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;IAChE,IAAI,YAAY,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC5B,OAAO,CAAC,GAAG,CAAC,+BAA+B,CAAC,CAAC;QAC7C,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IAC7B,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,eAAe,YAAY,CAAC,MAAM,qBAAqB,CAAC,CAAC;IAErE,IAAI,UAAU,GAAsB,EAAE,CAAC;IACvC,IAAI,IAAI,KAAK,uBAAuB,EAAE,CAAC;QACnC,UAAU,GAAG,6BAA6B,CAAC,aAAa,EAAE,YAAY,EAAE,IAAI,EAAE,IAAI,EAAE,cAAc,EAAE,YAAY,CAAC,CAAC;IACtH,CAAC;SAAM,IAAI,IAAI,KAAK,wBAAwB,EAAE,CAAC;QAC3C,UAAU,GAAG,8BAA8B,CAAC,aAAa,EAAE,YAAY,EAAE,cAAc,EAAE,YAAY,CAAC,CAAC;IAC3G,CAAC;IAED,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1B,OAAO,CAAC,GAAG,CAAC,yCAAyC,CAAC,CAAC;QACvD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IAC7B,CAAC;IAED,gBAAgB,CAAC,UAAU,EAAE,IAAI,EAAE,cAAc,CAAC,CAAC;IACnD,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;AAC9B,CAAC;AAGM,IAAM,kDAAkD,GAAxD,MAAM,kDAAmD,SAAQ,8BAA8D;IAClI,YAAY,MAAuD;QAC/D,KAAK,CAAC,MAAM,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC;IACxC,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,aAAqB;QAC3B,OAAO,gBAAgB,CAAC,IAAI,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IACxD,CAAC;CACJ,CAAA;AARY,gHAAkD;6DAAlD,kDAAkD;IAD9D,IAAA,sBAAU,EAAC,8BAAkB,CAAC,SAAS,CAAC;6CAEjB,8DAA+C;GAD1D,kDAAkD,CAQ9D","sourcesContent":["/**\n * Validate Inject Annotation Not Needed For Concrete Class\n *\n * Flags a REDUNDANT `@inject(X)` on a CONSTRUCTOR parameter whose token is textually identical to the\n * parameter's own declared type:\n *\n * BAD: constructor(@inject(RequestContextHeaders) private readonly h: RequestContextHeaders) {}\n * GOOD: constructor(private readonly h: RequestContextHeaders) {}\n *\n * WHY: in this inversify setup a constructor parameter is auto-resolved by its class TYPE via\n * reflect-metadata (`emitDecoratorMetadata` emits `design:paramtypes`). So `private readonly h: Foo`\n * already binds `Foo` — the `@inject(Foo)` adds nothing (see CLAUDE.md, and the sibling\n * no-symbol-di-tokens rule that pushes the same inject-by-type pattern). AI keeps carpet-bombing\n * `@inject`; this fails the build on the redundant form so it stops.\n *\n * Uses the TypeScript AST (not a regex) so \"token equals the parameter type\" is decided precisely.\n * That single rule is what makes every LEGITIMATE token pass untouched — a real token never equals the\n * type it resolves:\n * - `@inject(TASK_PROXY_CLIENT_PROVIDER) x: Provider<TaskProxyClient>` (Symbol token ≠ type)\n * - `@inject(WEBPIECES_CONFIG_TOKEN) c: WebpiecesConfig` (Symbol ≠ interface type)\n * - `@inject('some-string') x: Foo` (string token ≠ type)\n * - `@inject(Symbol.for('X')) x: Foo` (not a bare identifier)\n *\n * SCOPE: only CONSTRUCTOR parameters. Property injection (`@inject(Foo) private foo: Foo` on a class\n * field) genuinely REQUIRES `@inject` in inversify — there is no design:type auto-wiring for properties\n * — so it is left alone.\n *\n * ALLOWED (skip — NOT violations)\n * - Any `@inject(TOKEN)` whose token differs from the parameter's type (Symbols, string tokens,\n * provider tokens, interface tokens).\n * - Property/field injection, and any parameter without an `@inject` decorator.\n * - Test files (*.test.ts, *.spec.ts, __tests__/**).\n * - Files under a configured `allowedPaths` glob (shared isPathExcluded glob/prefix/segment semantics).\n * - Lines with `// webpieces-disable inject-annotation-not-needed-for-concrete-class -- <reason>`\n * (only when disableAllowed).\n *\n * MODES (AST + LINE-SCOPED)\n * - OFF: Skip.\n * - NEW_AND_MODIFIED_CODE: Flag only on changed lines (diff hunks).\n * - NEW_AND_MODIFIED_FILES: Flag every occurrence in any modified file.\n */\n\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport * as ts from 'typescript';\nimport { hasDisable, RULE_NAMES, InjectAnnotationNotNeededForConcreteClassConfig, ModifiedCodeMode, detectBase, getChangedFiles, getFileDiff, getChangedLineNumbers, isPathExcluded } from '@webpieces/rules-config';\nimport { CodeValidator, ExecutorResult } from './code-validator';\nimport { injectable, bindingScopeValues } from 'inversify';\nimport { shouldSkipRule } from './resolve-mode';\n\nconst RULE_NAME = RULE_NAMES.INJECT_ANNOTATION_NOT_NEEDED_FOR_CONCRETE_CLASS;\n\nconst SHARED_MESSAGE = `@inject(Foo) on a constructor parameter typed \\`: Foo\\` is noise — inversify resolves a constructor\nparameter by its class type via reflect-metadata, so \\`private readonly foo: Foo\\` already binds it\n(see CLAUDE.md). Pick one:\n Fix Option 1 (PREFERRED): delete the decorator — constructor(private readonly foo: Foo) {}\n Fix Option 2: if you actually need a DIFFERENT binding token (a Symbol for a generated\n http-client-node / cloud-tasks client, or an interface/config with multiple impls), inject that\n token so it DIFFERS from the type: @inject(FOO_TOKEN) foo: SomeInterface.\nProperty injection (@inject on a class field, not a constructor param) is NOT flagged — it genuinely\nneeds @inject. Only a constructor param whose token equals its own type is redundant.`;\n\ninterface InjectViolation {\n file: string;\n line: number;\n column: number;\n context: string;\n}\n\ninterface InjectViolationInfo {\n line: number;\n column: number;\n context: string;\n hasDisableComment: boolean;\n}\n\n// webpieces-disable no-function-outside-class -- the rule engine is inherently functional; validators can't be class members\nfunction isTestFile(filePath: string): boolean {\n return filePath.includes('.spec.ts') || filePath.includes('.test.ts') || filePath.includes('__tests__/');\n}\n\n// webpieces-disable no-function-outside-class -- the rule engine is inherently functional; validators can't be class members\nfunction isDeclarationFile(filePath: string): boolean {\n return filePath.endsWith('.d.ts');\n}\n\n// The violation line (or the line just above it) carries the disable comment.\n// webpieces-disable no-function-outside-class -- the rule engine is inherently functional; validators can't be class members\nfunction hasDisableOnLine(fileLines: string[], lineNumber: number): boolean {\n const current = fileLines[lineNumber - 1] ?? '';\n const previous = lineNumber >= 2 ? (fileLines[lineNumber - 2] ?? '') : '';\n return hasDisable(current, RULE_NAME) || hasDisable(previous, RULE_NAME);\n}\n\n// The `@inject(X)` decorator's single argument, when it is a BARE identifier (a class/token name).\n// Returns null for Symbol.for(...), property-access (`Symbol.x`), string literals, or a non-inject\n// decorator — those can never equal the parameter type, so they are never redundant.\n// webpieces-disable no-function-outside-class -- the rule engine is inherently functional; validators can't be class members\nfunction injectIdentifierArg(decorator: ts.Decorator): string | null {\n const expr = decorator.expression;\n if (!ts.isCallExpression(expr)) return null;\n if (!ts.isIdentifier(expr.expression) || expr.expression.text !== 'inject') return null;\n if (expr.arguments.length !== 1) return null;\n const arg = expr.arguments[0];\n return arg && ts.isIdentifier(arg) ? arg.text : null;\n}\n\n// The parameter's declared type when it is a simple `TypeReference` with an identifier name\n// (`Foo`, or `Foo<Bar>` → `Foo`). Qualified names (`ns.Foo`) and non-references return null.\n// webpieces-disable no-function-outside-class -- the rule engine is inherently functional; validators can't be class members\nfunction paramTypeName(param: ts.ParameterDeclaration): string | null {\n const typeNode = param.type;\n if (!typeNode || !ts.isTypeReferenceNode(typeNode)) return null;\n return ts.isIdentifier(typeNode.typeName) ? typeNode.typeName.text : null;\n}\n\n// AST scan: a CONSTRUCTOR parameter is a violation when it carries `@inject(X)` and its declared type\n// is exactly `X`. Property injection and method params are ignored (only constructor params).\n// webpieces-disable no-function-outside-class -- the rule engine is inherently functional; validators can't be class members\nexport function findRedundantInjectInSource(content: string, filePath: string, disableAllowed: boolean): InjectViolationInfo[] {\n if (isDeclarationFile(filePath)) return [];\n const fileLines = content.split('\\n');\n const sourceFile = ts.createSourceFile(filePath, content, ts.ScriptTarget.Latest, true);\n const violations: InjectViolationInfo[] = [];\n\n function checkParameter(param: ts.ParameterDeclaration): void {\n const decorators = ts.canHaveDecorators(param) ? ts.getDecorators(param) : undefined;\n if (!decorators) return;\n const typeName = paramTypeName(param);\n if (!typeName) return;\n for (const decorator of decorators) {\n if (injectIdentifierArg(decorator) === typeName) {\n recordViolation(param, `@inject(${typeName}) is redundant — the parameter is typed \\`: ${typeName}\\` and resolves by type`, fileLines, sourceFile, violations, disableAllowed);\n return;\n }\n }\n }\n\n function visit(node: ts.Node): void {\n if (ts.isConstructorDeclaration(node)) {\n for (const param of node.parameters) checkParameter(param);\n }\n ts.forEachChild(node, visit);\n }\n\n visit(sourceFile);\n return violations;\n}\n\n// webpieces-disable no-function-outside-class -- the rule engine is inherently functional; validators can't be class members\nfunction recordViolation(\n node: ts.Node,\n context: string,\n fileLines: string[],\n sourceFile: ts.SourceFile,\n violations: InjectViolationInfo[],\n disableAllowed: boolean,\n): void {\n const startPos = node.getStart(sourceFile);\n if (startPos < 0) return;\n const pos = sourceFile.getLineAndCharacterOfPosition(startPos);\n const line = pos.line + 1;\n const column = pos.character + 1;\n const disabled = hasDisableOnLine(fileLines, line);\n // When disableAllowed is false, a disable comment does NOT clear the violation.\n const effectiveDisabled = disableAllowed ? disabled : false;\n violations.push({ line, column, context, hasDisableComment: effectiveDisabled });\n}\n\n// webpieces-disable no-function-outside-class -- the rule engine is inherently functional; validators can't be class members\nfunction findRedundantInjectInFile(filePath: string, workspaceRoot: string, disableAllowed: boolean, allowedPaths: string[]): InjectViolationInfo[] {\n if (isTestFile(filePath)) return [];\n if (isPathExcluded(filePath, allowedPaths)) return [];\n const fullPath = path.join(workspaceRoot, filePath);\n if (!fs.existsSync(fullPath)) return [];\n const content = fs.readFileSync(fullPath, 'utf-8');\n return findRedundantInjectInSource(content, filePath, disableAllowed);\n}\n\n// webpieces-disable no-function-outside-class -- the rule engine is inherently functional; validators can't be class members\nfunction findViolationsForModifiedCode(workspaceRoot: string, changedFiles: string[], base: string, head: string | undefined, disableAllowed: boolean, allowedPaths: string[]): InjectViolation[] {\n const violations: InjectViolation[] = [];\n for (const file of changedFiles) {\n const changedLines = getChangedLineNumbers(getFileDiff(workspaceRoot, file, base, head));\n if (changedLines.size === 0) continue;\n for (const v of findRedundantInjectInFile(file, workspaceRoot, disableAllowed, allowedPaths)) {\n if (disableAllowed && v.hasDisableComment) continue;\n if (!changedLines.has(v.line)) continue;\n violations.push({ file, line: v.line, column: v.column, context: v.context });\n }\n }\n return violations;\n}\n\n// webpieces-disable no-function-outside-class -- the rule engine is inherently functional; validators can't be class members\nfunction findViolationsForModifiedFiles(workspaceRoot: string, changedFiles: string[], disableAllowed: boolean, allowedPaths: string[]): InjectViolation[] {\n const violations: InjectViolation[] = [];\n for (const file of changedFiles) {\n for (const v of findRedundantInjectInFile(file, workspaceRoot, disableAllowed, allowedPaths)) {\n if (disableAllowed && v.hasDisableComment) continue;\n violations.push({ file, line: v.line, column: v.column, context: v.context });\n }\n }\n return violations;\n}\n\n// webpieces-disable no-function-outside-class -- the rule engine is inherently functional; validators can't be class members\nfunction reportViolations(violations: InjectViolation[], mode: ModifiedCodeMode, disableAllowed: boolean): void {\n console.error('');\n console.error('❌ Redundant @inject — the parameter\\'s type already resolves it.');\n console.error('');\n console.error(SHARED_MESSAGE);\n console.error('');\n for (const v of violations) {\n console.error(` ❌ ${v.file}:${v.line}:${v.column}`);\n console.error(` ${v.context}`);\n }\n console.error('');\n console.error(disableAllowed\n ? ` Escape hatch (use sparingly): // webpieces-disable ${RULE_NAME} -- <reason>`\n : ' Escape hatch: DISABLED (disableAllowed: false)');\n console.error(` Whole-tree exemption: add a glob to ${RULE_NAME}.allowedPaths in webpieces.config.json`);\n console.error(`\\n Current mode: ${mode}\\n`);\n}\n\n// webpieces-disable no-function-outside-class -- the rule engine is inherently functional; validators can't be class members\nfunction resolveMode(normalMode: ModifiedCodeMode, epoch: number | undefined, branchPattern: string | undefined): ModifiedCodeMode {\n if (normalMode === 'OFF') return normalMode;\n const skip = shouldSkipRule(epoch, branchPattern);\n if (skip.skip) {\n console.log(`\\n⏭️ Skipping ${RULE_NAME} validation (${skip.reason})\\n`);\n return 'OFF';\n }\n return normalMode;\n}\n\n// webpieces-disable no-function-outside-class -- the rule engine is inherently functional; validators can't be class members\nasync function runValidatorImpl(options: InjectAnnotationNotNeededForConcreteClassConfig, workspaceRoot: string): Promise<ExecutorResult> {\n const mode: ModifiedCodeMode = resolveMode(options.mode ?? 'OFF', options.turnOffRuleUntilEpoch, (options.turnOffRuleWhileOnBranch ?? undefined));\n const disableAllowed = options.disableAllowed ?? true;\n const allowedPaths = options.allowedPaths ?? [];\n\n if (mode === 'OFF') {\n console.log(`\\n⏭️ Skipping ${RULE_NAME} validation (mode: OFF)\\n`);\n return { success: true };\n }\n\n console.log(`\\n📏 Validating ${RULE_NAME}\\n`);\n console.log(` Mode: ${mode}`);\n\n let base = process.env['NX_BASE'];\n const head = process.env['NX_HEAD'];\n if (!base) {\n base = detectBase(workspaceRoot) ?? undefined;\n if (!base) {\n console.log(`\\n⏭️ Skipping ${RULE_NAME} validation (could not detect base branch)\\n`);\n return { success: true };\n }\n }\n\n console.log(` Base: ${base}`);\n console.log(` Head: ${head ?? 'working tree (includes uncommitted changes)'}\\n`);\n\n const changedFiles = getChangedFiles(workspaceRoot, base, head);\n if (changedFiles.length === 0) {\n console.log('✅ No TypeScript files changed');\n return { success: true };\n }\n\n console.log(`📂 Checking ${changedFiles.length} changed file(s)...`);\n\n let violations: InjectViolation[] = [];\n if (mode === 'NEW_AND_MODIFIED_CODE') {\n violations = findViolationsForModifiedCode(workspaceRoot, changedFiles, base, head, disableAllowed, allowedPaths);\n } else if (mode === 'NEW_AND_MODIFIED_FILES') {\n violations = findViolationsForModifiedFiles(workspaceRoot, changedFiles, disableAllowed, allowedPaths);\n }\n\n if (violations.length === 0) {\n console.log('✅ No redundant-@inject violations found');\n return { success: true };\n }\n\n reportViolations(violations, mode, disableAllowed);\n return { success: false };\n}\n\n@injectable(bindingScopeValues.Singleton)\nexport class InjectAnnotationNotNeededForConcreteClassValidator extends CodeValidator<InjectAnnotationNotNeededForConcreteClassConfig> {\n constructor(config: InjectAnnotationNotNeededForConcreteClassConfig) {\n super(config, RULE_NAME, RULE_NAME);\n }\n\n async run(workspaceRoot: string): Promise<ExecutorResult> {\n return runValidatorImpl(this.config, workspaceRoot);\n }\n}\n"]}
@@ -260,7 +260,7 @@ async function runValidatorImpl(options, workspaceRoot) {
260
260
  }
261
261
  let MaxFileLinesValidator = class MaxFileLinesValidator extends code_validator_1.CodeValidator {
262
262
  constructor(config) {
263
- super(config, 'max-file-lines');
263
+ super(config, 'max-file-lines', 'max-file-lines');
264
264
  }
265
265
  async run(workspaceRoot) {
266
266
  return runValidatorImpl(this.config, workspaceRoot);