@webpieces/code-rules 0.3.360 → 0.3.362

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 (45) hide show
  1. package/package.json +2 -4
  2. package/src/code-rules-app.js +4 -4
  3. package/src/code-rules-app.js.map +1 -1
  4. package/src/code-rules-engine.js +2 -2
  5. package/src/code-rules-engine.js.map +1 -1
  6. package/src/rule-reporter.js +2 -2
  7. package/src/rule-reporter.js.map +1 -1
  8. package/src/validate-catch-error-pattern.js +2 -2
  9. package/src/validate-catch-error-pattern.js.map +1 -1
  10. package/src/validate-dtos.js +2 -2
  11. package/src/validate-dtos.js.map +1 -1
  12. package/src/validate-framework-tag.js +2 -2
  13. package/src/validate-framework-tag.js.map +1 -1
  14. package/src/validate-inject-annotation-not-needed-for-concrete-class.js +2 -2
  15. package/src/validate-inject-annotation-not-needed-for-concrete-class.js.map +1 -1
  16. package/src/validate-match-rules.js +2 -2
  17. package/src/validate-match-rules.js.map +1 -1
  18. package/src/validate-modified-files.js +2 -2
  19. package/src/validate-modified-files.js.map +1 -1
  20. package/src/validate-modified-methods.js +2 -2
  21. package/src/validate-modified-methods.js.map +1 -1
  22. package/src/validate-no-any-unknown.js +2 -2
  23. package/src/validate-no-any-unknown.js.map +1 -1
  24. package/src/validate-no-destructure.js +2 -2
  25. package/src/validate-no-destructure.js.map +1 -1
  26. package/src/validate-no-direct-api-resolver.js +2 -2
  27. package/src/validate-no-direct-api-resolver.js.map +1 -1
  28. package/src/validate-no-function-outside-class.js +2 -2
  29. package/src/validate-no-function-outside-class.js.map +1 -1
  30. package/src/validate-no-implicit-any.js +2 -2
  31. package/src/validate-no-implicit-any.js.map +1 -1
  32. package/src/validate-no-inline-types.js +2 -2
  33. package/src/validate-no-inline-types.js.map +1 -1
  34. package/src/validate-no-process-exit-outside-main.js +2 -2
  35. package/src/validate-no-process-exit-outside-main.js.map +1 -1
  36. package/src/validate-no-symbol-di-tokens.js +2 -2
  37. package/src/validate-no-symbol-di-tokens.js.map +1 -1
  38. package/src/validate-no-unmanaged-exceptions.js +2 -2
  39. package/src/validate-no-unmanaged-exceptions.js.map +1 -1
  40. package/src/validate-prisma-converters.js +2 -2
  41. package/src/validate-prisma-converters.js.map +1 -1
  42. package/src/validate-return-types.js +2 -2
  43. package/src/validate-return-types.js.map +1 -1
  44. package/src/validate-role-tag.js +2 -2
  45. 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.3.360",
3
+ "version": "0.3.362",
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",
@@ -20,9 +20,7 @@
20
20
  "directory": "packages/tooling/code-rules"
21
21
  },
22
22
  "dependencies": {
23
- "@webpieces/rules-config": "0.3.360",
24
- "@webpieces/core-context": "0.3.360",
25
- "@webpieces/core-util": "0.3.360",
23
+ "@webpieces/rules-config": "0.3.362",
26
24
  "@inversifyjs/binding-decorators": "1.1.5",
27
25
  "inversify": "7.10.4",
28
26
  "reflect-metadata": "0.2.2"
@@ -2,8 +2,8 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.CodeRulesApp = void 0;
4
4
  const tslib_1 = require("tslib");
5
- const core_util_1 = require("@webpieces/core-util");
6
- const core_context_1 = require("@webpieces/core-context");
5
+ const rules_config_1 = require("@webpieces/rules-config");
6
+ const rules_config_2 = require("@webpieces/rules-config");
7
7
  const inversify_1 = require("inversify");
8
8
  const code_rules_engine_1 = require("./code-rules-engine");
9
9
  /**
@@ -23,8 +23,8 @@ let CodeRulesApp = class CodeRulesApp {
23
23
  };
24
24
  exports.CodeRulesApp = CodeRulesApp;
25
25
  exports.CodeRulesApp = CodeRulesApp = tslib_1.__decorate([
26
- (0, core_util_1.DocumentDesign)(),
27
- (0, core_context_1.provideSingleton)(),
26
+ (0, rules_config_1.DocumentDesign)(),
27
+ (0, rules_config_2.provideSingleton)(),
28
28
  (0, inversify_1.injectable)(),
29
29
  tslib_1.__metadata("design:paramtypes", [code_rules_engine_1.CodeRulesEngine])
30
30
  ], CodeRulesApp);
@@ -1 +1 @@
1
- {"version":3,"file":"code-rules-app.js","sourceRoot":"","sources":["../../../../../packages/tooling/code-rules/src/code-rules-app.ts"],"names":[],"mappings":";;;;AAAA,oDAAsD;AACtD,0DAA2D;AAC3D,yCAAuC;AAEvC,2DAAsD;AAGtD;;;;GAIG;AAII,IAAM,YAAY,GAAlB,MAAM,YAAY;IACQ;IAA7B,YAA6B,MAAuB;QAAvB,WAAM,GAAN,MAAM,CAAiB;IAAG,CAAC;IAExD,yFAAyF;IACzF,GAAG;QACC,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC;IAC7B,CAAC;CACJ,CAAA;AAPY,oCAAY;uBAAZ,YAAY;IAHxB,IAAA,0BAAc,GAAE;IAChB,IAAA,+BAAgB,GAAE;IAClB,IAAA,sBAAU,GAAE;6CAE4B,mCAAe;GAD3C,YAAY,CAOxB","sourcesContent":["import { DocumentDesign } from '@webpieces/core-util';\nimport { provideSingleton } from '@webpieces/core-context';\nimport { injectable } from 'inversify';\n\nimport { CodeRulesEngine } from './code-rules-engine';\nimport { ExecutorResult } from './code-validator';\n\n/**\n * The code-rules application root. `container.get(CodeRulesApp)` resolves the entire validator DAG\n * (engine → 18 injected validators → their bound configs + shared helpers). `@DocumentDesign` marks\n * it the top-of-DAG the DI-design analyzer roots on, so `role:app` code-rules draws its design.\n */\n@DocumentDesign()\n@provideSingleton()\n@injectable()\nexport class CodeRulesApp {\n constructor(private readonly engine: CodeRulesEngine) {}\n\n /** Run every configured code validator against the workspace root bound at bootstrap. */\n run(): Promise<ExecutorResult> {\n return this.engine.run();\n }\n}\n"]}
1
+ {"version":3,"file":"code-rules-app.js","sourceRoot":"","sources":["../../../../../packages/tooling/code-rules/src/code-rules-app.ts"],"names":[],"mappings":";;;;AAAA,0DAAyD;AACzD,0DAA2D;AAC3D,yCAAuC;AAEvC,2DAAsD;AAGtD;;;;GAIG;AAII,IAAM,YAAY,GAAlB,MAAM,YAAY;IACQ;IAA7B,YAA6B,MAAuB;QAAvB,WAAM,GAAN,MAAM,CAAiB;IAAG,CAAC;IAExD,yFAAyF;IACzF,GAAG;QACC,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC;IAC7B,CAAC;CACJ,CAAA;AAPY,oCAAY;uBAAZ,YAAY;IAHxB,IAAA,6BAAc,GAAE;IAChB,IAAA,+BAAgB,GAAE;IAClB,IAAA,sBAAU,GAAE;6CAE4B,mCAAe;GAD3C,YAAY,CAOxB","sourcesContent":["import { DocumentDesign } from '@webpieces/rules-config';\nimport { provideSingleton } from '@webpieces/rules-config';\nimport { injectable } from 'inversify';\n\nimport { CodeRulesEngine } from './code-rules-engine';\nimport { ExecutorResult } from './code-validator';\n\n/**\n * The code-rules application root. `container.get(CodeRulesApp)` resolves the entire validator DAG\n * (engine → 18 injected validators → their bound configs + shared helpers). `@DocumentDesign` marks\n * it the top-of-DAG the DI-design analyzer roots on, so `role:app` code-rules draws its design.\n */\n@DocumentDesign()\n@provideSingleton()\n@injectable()\nexport class CodeRulesApp {\n constructor(private readonly engine: CodeRulesEngine) {}\n\n /** Run every configured code validator against the workspace root bound at bootstrap. */\n run(): Promise<ExecutorResult> {\n return this.engine.run();\n }\n}\n"]}
@@ -2,7 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.CodeRulesEngine = void 0;
4
4
  const tslib_1 = require("tslib");
5
- const core_context_1 = require("@webpieces/core-context");
5
+ const rules_config_1 = require("@webpieces/rules-config");
6
6
  const inversify_1 = require("inversify");
7
7
  const code_validator_1 = require("./code-validator");
8
8
  const rule_reporter_1 = require("./rule-reporter");
@@ -128,7 +128,7 @@ let CodeRulesEngine = class CodeRulesEngine {
128
128
  };
129
129
  exports.CodeRulesEngine = CodeRulesEngine;
130
130
  exports.CodeRulesEngine = CodeRulesEngine = tslib_1.__decorate([
131
- (0, core_context_1.provideSingleton)(),
131
+ (0, rules_config_1.provideSingleton)(),
132
132
  (0, inversify_1.injectable)(),
133
133
  tslib_1.__metadata("design:paramtypes", [code_rules_context_1.WorkspaceRoot,
134
134
  rule_reporter_1.RuleReporter,
@@ -1 +1 @@
1
- {"version":3,"file":"code-rules-engine.js","sourceRoot":"","sources":["../../../../../packages/tooling/code-rules/src/code-rules-engine.ts"],"names":[],"mappings":"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","sourcesContent":["import { BaseRuleConfig } from '@webpieces/rules-config';\nimport { provideSingleton } from '@webpieces/core-context';\nimport { injectable } from 'inversify';\n\nimport { CodeValidator, ExecutorResult, RuleRun } from './code-validator';\nimport { RuleReporter } from './rule-reporter';\nimport { WorkspaceRoot, MatchRulesHolder } from './code-rules-context';\nimport { MatchRulesChecker } from './validate-match-rules';\nimport { MaxMethodLinesValidator } from './validate-modified-methods';\nimport { MaxFileLinesValidator } from './validate-modified-files';\nimport { RequireReturnTypeValidator } from './validate-return-types';\nimport { NoInlineTypeLiteralsValidator } from './validate-no-inline-types';\nimport { NoAnyUnknownValidator } from './validate-no-any-unknown';\nimport { NoImplicitAnyValidator } from './validate-no-implicit-any';\nimport { PrismaValidateDtosValidator } from './validate-dtos';\nimport { PrismaConverterValidator } from './validate-prisma-converters';\nimport { NoDestructureValidator } from './validate-no-destructure';\nimport { CatchErrorPatternValidator } from './validate-catch-error-pattern';\nimport { NoUnmanagedExceptionsValidator } from './validate-no-unmanaged-exceptions';\nimport { NoDirectApiResolverValidator } from './validate-no-direct-api-resolver';\nimport { NoSymbolDiTokensValidator } from './validate-no-symbol-di-tokens';\nimport { NoProcessExitOutsideMainValidator } from './validate-no-process-exit-outside-main';\nimport { NoFunctionOutsideClassValidator } from './validate-no-function-outside-class';\nimport { InjectAnnotationNotNeededForConcreteClassValidator } from './validate-inject-annotation-not-needed-for-concrete-class';\nimport { FrameworkTagValidator } from './validate-framework-tag';\nimport { RoleTagValidator } from './validate-role-tag';\n\n/**\n * Owns running the code-rules suite. Every built-in validator is injected as a singleton (its config\n * is bound in the container at bootstrap), so this class IS the code-rules DI DAG the design graph\n * draws. The per-entry match-rules validators are the one exception — they are config-per-instance,\n * so they are built from the injected {@link MatchRulesHolder}.\n */\n@provideSingleton()\n@injectable()\nexport class CodeRulesEngine {\n // webpieces-disable max-lines-new-methods -- the built-in validator set is flat; each is one injected field\n constructor(\n private readonly workspace: WorkspaceRoot,\n private readonly reporter: RuleReporter,\n private readonly matchRules: MatchRulesHolder,\n private readonly matchChecker: MatchRulesChecker,\n private readonly maxMethodLines: MaxMethodLinesValidator,\n private readonly maxFileLines: MaxFileLinesValidator,\n private readonly requireReturnType: RequireReturnTypeValidator,\n private readonly noInlineTypeLiterals: NoInlineTypeLiteralsValidator,\n private readonly noAnyUnknown: NoAnyUnknownValidator,\n private readonly noImplicitAny: NoImplicitAnyValidator,\n private readonly prismaValidateDtos: PrismaValidateDtosValidator,\n private readonly prismaConverter: PrismaConverterValidator,\n private readonly noDestructure: NoDestructureValidator,\n private readonly catchErrorPattern: CatchErrorPatternValidator,\n private readonly noUnmanagedExceptions: NoUnmanagedExceptionsValidator,\n private readonly noDirectApiResolver: NoDirectApiResolverValidator,\n private readonly noSymbolDiTokens: NoSymbolDiTokensValidator,\n private readonly noProcessExitOutsideMain: NoProcessExitOutsideMainValidator,\n private readonly noFunctionOutsideClass: NoFunctionOutsideClassValidator,\n private readonly injectAnnotationNotNeeded: InjectAnnotationNotNeededForConcreteClassValidator,\n private readonly frameworkTag: FrameworkTagValidator,\n private readonly roleTag: RoleTagValidator,\n ) {}\n\n /** The 18 injected built-in validators, in run order. */\n private builtIns(): CodeValidator<BaseRuleConfig>[] {\n return [\n this.maxMethodLines, this.maxFileLines, this.requireReturnType, this.noInlineTypeLiterals,\n this.noAnyUnknown, this.noImplicitAny, this.prismaValidateDtos, this.prismaConverter,\n this.noDestructure, this.catchErrorPattern, this.noUnmanagedExceptions, this.noDirectApiResolver,\n this.noSymbolDiTokens, this.noProcessExitOutsideMain, this.noFunctionOutsideClass,\n this.injectAnnotationNotNeeded, this.frameworkTag, this.roleTag,\n ];\n }\n\n /**\n * Every ACTIVE run: an injected built-in validator whose `shouldRun()` is true, or an injected\n * match-rule check per configured entry that is active. Built as {@link RuleRun} value objects\n * (name + thunk) so NO DAG member is `new`-ed — the validators and the checker are injected.\n */\n private activeRuns(root: string): RuleRun[] {\n const runs: RuleRun[] = [];\n for (const v of this.builtIns()) {\n if (v.shouldRun()) runs.push(new RuleRun(v.name, () => v.run(root)));\n }\n for (const mr of this.matchRules.rules) {\n if (this.matchChecker.shouldRun(mr)) runs.push(new RuleRun(mr.name, () => this.matchChecker.runForConfig(mr, root)));\n }\n return runs;\n }\n\n /**\n * Run all configured code validators against the workspace. A validator runs only when\n * `shouldRun()` is true (mode not OFF and no branch/epoch escape hatch). Per-run isolation lives\n * in {@link RuleReporter} so one validator can never abort the rest.\n */\n async run(): Promise<ExecutorResult> {\n const runs = this.activeRuns(this.workspace.path);\n if (runs.length === 0) {\n console.log('\\n⏭️ Skipping all code validations (all modes: OFF)\\n');\n return { success: true };\n }\n\n console.log('\\n📏 Running Code Validations\\n');\n console.log(` Active rules: ${runs.map((r: RuleRun) => r.name).join(', ')}`);\n console.log('');\n\n const result = await this.reporter.runValidators(runs);\n console.log(result.success ? '\\n✅ All code validations passed\\n' : '\\n❌ Some code validations failed\\n');\n return result;\n }\n}\n"]}
1
+ {"version":3,"file":"code-rules-engine.js","sourceRoot":"","sources":["../../../../../packages/tooling/code-rules/src/code-rules-engine.ts"],"names":[],"mappings":";;;;AACA,0DAA2D;AAC3D,yCAAuC;AAEvC,qDAA0E;AAC1E,mDAA+C;AAC/C,6DAAuE;AACvE,iEAA2D;AAC3D,2EAAsE;AACtE,uEAAkE;AAClE,mEAAqE;AACrE,yEAA2E;AAC3E,uEAAkE;AAClE,yEAAoE;AACpE,mDAA8D;AAC9D,6EAAwE;AACxE,uEAAmE;AACnE,iFAA4E;AAC5E,yFAAoF;AACpF,uFAAiF;AACjF,iFAA2E;AAC3E,mGAA4F;AAC5F,6FAAuF;AACvF,yIAAgI;AAChI,qEAAiE;AACjE,2DAAuD;AAEvD;;;;;GAKG;AAGI,IAAM,eAAe,GAArB,MAAM,eAAe;IAGH;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IAvBrB,4GAA4G;IAC5G,YACqB,SAAwB,EACxB,QAAsB,EACtB,UAA4B,EAC5B,YAA+B,EAC/B,cAAuC,EACvC,YAAmC,EACnC,iBAA6C,EAC7C,oBAAmD,EACnD,YAAmC,EACnC,aAAqC,EACrC,kBAA+C,EAC/C,eAAyC,EACzC,aAAqC,EACrC,iBAA6C,EAC7C,qBAAqD,EACrD,mBAAiD,EACjD,gBAA2C,EAC3C,wBAA2D,EAC3D,sBAAuD,EACvD,yBAA6E,EAC7E,YAAmC,EACnC,OAAyB;QArBzB,cAAS,GAAT,SAAS,CAAe;QACxB,aAAQ,GAAR,QAAQ,CAAc;QACtB,eAAU,GAAV,UAAU,CAAkB;QAC5B,iBAAY,GAAZ,YAAY,CAAmB;QAC/B,mBAAc,GAAd,cAAc,CAAyB;QACvC,iBAAY,GAAZ,YAAY,CAAuB;QACnC,sBAAiB,GAAjB,iBAAiB,CAA4B;QAC7C,yBAAoB,GAApB,oBAAoB,CAA+B;QACnD,iBAAY,GAAZ,YAAY,CAAuB;QACnC,kBAAa,GAAb,aAAa,CAAwB;QACrC,uBAAkB,GAAlB,kBAAkB,CAA6B;QAC/C,oBAAe,GAAf,eAAe,CAA0B;QACzC,kBAAa,GAAb,aAAa,CAAwB;QACrC,sBAAiB,GAAjB,iBAAiB,CAA4B;QAC7C,0BAAqB,GAArB,qBAAqB,CAAgC;QACrD,wBAAmB,GAAnB,mBAAmB,CAA8B;QACjD,qBAAgB,GAAhB,gBAAgB,CAA2B;QAC3C,6BAAwB,GAAxB,wBAAwB,CAAmC;QAC3D,2BAAsB,GAAtB,sBAAsB,CAAiC;QACvD,8BAAyB,GAAzB,yBAAyB,CAAoD;QAC7E,iBAAY,GAAZ,YAAY,CAAuB;QACnC,YAAO,GAAP,OAAO,CAAkB;IAC3C,CAAC;IAEJ,yDAAyD;IACjD,QAAQ;QACZ,OAAO;YACH,IAAI,CAAC,cAAc,EAAE,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,iBAAiB,EAAE,IAAI,CAAC,oBAAoB;YACzF,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,aAAa,EAAE,IAAI,CAAC,kBAAkB,EAAE,IAAI,CAAC,eAAe;YACpF,IAAI,CAAC,aAAa,EAAE,IAAI,CAAC,iBAAiB,EAAE,IAAI,CAAC,qBAAqB,EAAE,IAAI,CAAC,mBAAmB;YAChG,IAAI,CAAC,gBAAgB,EAAE,IAAI,CAAC,wBAAwB,EAAE,IAAI,CAAC,sBAAsB;YACjF,IAAI,CAAC,yBAAyB,EAAE,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,OAAO;SAClE,CAAC;IACN,CAAC;IAED;;;;OAIG;IACK,UAAU,CAAC,IAAY;QAC3B,MAAM,IAAI,GAAc,EAAE,CAAC;QAC3B,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,QAAQ,EAAE,EAAE,CAAC;YAC9B,IAAI,CAAC,CAAC,SAAS,EAAE;gBAAE,IAAI,CAAC,IAAI,CAAC,IAAI,wBAAO,CAAC,CAAC,CAAC,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACzE,CAAC;QACD,KAAK,MAAM,EAAE,IAAI,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC;YACrC,IAAI,IAAI,CAAC,YAAY,CAAC,SAAS,CAAC,EAAE,CAAC;gBAAE,IAAI,CAAC,IAAI,CAAC,IAAI,wBAAO,CAAC,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,YAAY,CAAC,YAAY,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;QACzH,CAAC;QACD,OAAO,IAAI,CAAC;IAChB,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,GAAG;QACL,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;QAClD,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACpB,OAAO,CAAC,GAAG,CAAC,wDAAwD,CAAC,CAAC;YACtE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;QAC7B,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,iCAAiC,CAAC,CAAC;QAC/C,OAAO,CAAC,GAAG,CAAC,oBAAoB,IAAI,CAAC,GAAG,CAAC,CAAC,CAAU,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAC/E,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAEhB,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;QACvD,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,mCAAmC,CAAC,CAAC,CAAC,oCAAoC,CAAC,CAAC;QACzG,OAAO,MAAM,CAAC;IAClB,CAAC;CACJ,CAAA;AA1EY,0CAAe;0BAAf,eAAe;IAF3B,IAAA,+BAAgB,GAAE;IAClB,IAAA,sBAAU,GAAE;6CAIuB,kCAAa;QACd,4BAAY;QACV,qCAAgB;QACd,wCAAiB;QACf,mDAAuB;QACzB,+CAAqB;QAChB,kDAA0B;QACvB,wDAA6B;QACrC,+CAAqB;QACpB,iDAAsB;QACjB,2CAA2B;QAC9B,qDAAwB;QAC1B,gDAAsB;QAClB,yDAA0B;QACtB,iEAA8B;QAChC,8DAA4B;QAC/B,wDAAyB;QACjB,yEAAiC;QACnC,oEAA+B;QAC5B,6GAAkD;QAC/D,8CAAqB;QAC1B,oCAAgB;GAxBrC,eAAe,CA0E3B","sourcesContent":["import { BaseRuleConfig } from '@webpieces/rules-config';\nimport { provideSingleton } from '@webpieces/rules-config';\nimport { injectable } from 'inversify';\n\nimport { CodeValidator, ExecutorResult, RuleRun } from './code-validator';\nimport { RuleReporter } from './rule-reporter';\nimport { WorkspaceRoot, MatchRulesHolder } from './code-rules-context';\nimport { MatchRulesChecker } from './validate-match-rules';\nimport { MaxMethodLinesValidator } from './validate-modified-methods';\nimport { MaxFileLinesValidator } from './validate-modified-files';\nimport { RequireReturnTypeValidator } from './validate-return-types';\nimport { NoInlineTypeLiteralsValidator } from './validate-no-inline-types';\nimport { NoAnyUnknownValidator } from './validate-no-any-unknown';\nimport { NoImplicitAnyValidator } from './validate-no-implicit-any';\nimport { PrismaValidateDtosValidator } from './validate-dtos';\nimport { PrismaConverterValidator } from './validate-prisma-converters';\nimport { NoDestructureValidator } from './validate-no-destructure';\nimport { CatchErrorPatternValidator } from './validate-catch-error-pattern';\nimport { NoUnmanagedExceptionsValidator } from './validate-no-unmanaged-exceptions';\nimport { NoDirectApiResolverValidator } from './validate-no-direct-api-resolver';\nimport { NoSymbolDiTokensValidator } from './validate-no-symbol-di-tokens';\nimport { NoProcessExitOutsideMainValidator } from './validate-no-process-exit-outside-main';\nimport { NoFunctionOutsideClassValidator } from './validate-no-function-outside-class';\nimport { InjectAnnotationNotNeededForConcreteClassValidator } from './validate-inject-annotation-not-needed-for-concrete-class';\nimport { FrameworkTagValidator } from './validate-framework-tag';\nimport { RoleTagValidator } from './validate-role-tag';\n\n/**\n * Owns running the code-rules suite. Every built-in validator is injected as a singleton (its config\n * is bound in the container at bootstrap), so this class IS the code-rules DI DAG the design graph\n * draws. The per-entry match-rules validators are the one exception — they are config-per-instance,\n * so they are built from the injected {@link MatchRulesHolder}.\n */\n@provideSingleton()\n@injectable()\nexport class CodeRulesEngine {\n // webpieces-disable max-lines-new-methods -- the built-in validator set is flat; each is one injected field\n constructor(\n private readonly workspace: WorkspaceRoot,\n private readonly reporter: RuleReporter,\n private readonly matchRules: MatchRulesHolder,\n private readonly matchChecker: MatchRulesChecker,\n private readonly maxMethodLines: MaxMethodLinesValidator,\n private readonly maxFileLines: MaxFileLinesValidator,\n private readonly requireReturnType: RequireReturnTypeValidator,\n private readonly noInlineTypeLiterals: NoInlineTypeLiteralsValidator,\n private readonly noAnyUnknown: NoAnyUnknownValidator,\n private readonly noImplicitAny: NoImplicitAnyValidator,\n private readonly prismaValidateDtos: PrismaValidateDtosValidator,\n private readonly prismaConverter: PrismaConverterValidator,\n private readonly noDestructure: NoDestructureValidator,\n private readonly catchErrorPattern: CatchErrorPatternValidator,\n private readonly noUnmanagedExceptions: NoUnmanagedExceptionsValidator,\n private readonly noDirectApiResolver: NoDirectApiResolverValidator,\n private readonly noSymbolDiTokens: NoSymbolDiTokensValidator,\n private readonly noProcessExitOutsideMain: NoProcessExitOutsideMainValidator,\n private readonly noFunctionOutsideClass: NoFunctionOutsideClassValidator,\n private readonly injectAnnotationNotNeeded: InjectAnnotationNotNeededForConcreteClassValidator,\n private readonly frameworkTag: FrameworkTagValidator,\n private readonly roleTag: RoleTagValidator,\n ) {}\n\n /** The 18 injected built-in validators, in run order. */\n private builtIns(): CodeValidator<BaseRuleConfig>[] {\n return [\n this.maxMethodLines, this.maxFileLines, this.requireReturnType, this.noInlineTypeLiterals,\n this.noAnyUnknown, this.noImplicitAny, this.prismaValidateDtos, this.prismaConverter,\n this.noDestructure, this.catchErrorPattern, this.noUnmanagedExceptions, this.noDirectApiResolver,\n this.noSymbolDiTokens, this.noProcessExitOutsideMain, this.noFunctionOutsideClass,\n this.injectAnnotationNotNeeded, this.frameworkTag, this.roleTag,\n ];\n }\n\n /**\n * Every ACTIVE run: an injected built-in validator whose `shouldRun()` is true, or an injected\n * match-rule check per configured entry that is active. Built as {@link RuleRun} value objects\n * (name + thunk) so NO DAG member is `new`-ed — the validators and the checker are injected.\n */\n private activeRuns(root: string): RuleRun[] {\n const runs: RuleRun[] = [];\n for (const v of this.builtIns()) {\n if (v.shouldRun()) runs.push(new RuleRun(v.name, () => v.run(root)));\n }\n for (const mr of this.matchRules.rules) {\n if (this.matchChecker.shouldRun(mr)) runs.push(new RuleRun(mr.name, () => this.matchChecker.runForConfig(mr, root)));\n }\n return runs;\n }\n\n /**\n * Run all configured code validators against the workspace. A validator runs only when\n * `shouldRun()` is true (mode not OFF and no branch/epoch escape hatch). Per-run isolation lives\n * in {@link RuleReporter} so one validator can never abort the rest.\n */\n async run(): Promise<ExecutorResult> {\n const runs = this.activeRuns(this.workspace.path);\n if (runs.length === 0) {\n console.log('\\n⏭️ Skipping all code validations (all modes: OFF)\\n');\n return { success: true };\n }\n\n console.log('\\n📏 Running Code Validations\\n');\n console.log(` Active rules: ${runs.map((r: RuleRun) => r.name).join(', ')}`);\n console.log('');\n\n const result = await this.reporter.runValidators(runs);\n console.log(result.success ? '\\n✅ All code validations passed\\n' : '\\n❌ Some code validations failed\\n');\n return result;\n }\n}\n"]}
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.RuleReporter = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  const rules_config_1 = require("@webpieces/rules-config");
6
- const core_context_1 = require("@webpieces/core-context");
6
+ const rules_config_2 = require("@webpieces/rules-config");
7
7
  const inversify_1 = require("inversify");
8
8
  /**
9
9
  * Runs the active validators with per-validator isolation and prints failures for humans/CI.
@@ -63,7 +63,7 @@ let RuleReporter = class RuleReporter {
63
63
  };
64
64
  exports.RuleReporter = RuleReporter;
65
65
  exports.RuleReporter = RuleReporter = tslib_1.__decorate([
66
- (0, core_context_1.provideSingleton)(),
66
+ (0, rules_config_2.provideSingleton)(),
67
67
  (0, inversify_1.injectable)()
68
68
  ], RuleReporter);
69
69
  //# sourceMappingURL=rule-reporter.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"rule-reporter.js","sourceRoot":"","sources":["../../../../../packages/tooling/code-rules/src/rule-reporter.ts"],"names":[],"mappings":";;;;AAAA,0DAAiE;AACjE,0DAA2D;AAC3D,yCAAuC;AAIvC;;GAEG;AAGI,IAAM,YAAY,GAAlB,MAAM,YAAY;IACrB;;;;;;;OAOG;IACH,KAAK,CAAC,aAAa,CAAC,IAAwB;QACxC,IAAI,SAAS,GAAG,KAAK,CAAC;QACtB,KAAK,MAAM,IAAI,IAAI,IAAI,EAAE,CAAC;YACtB,qHAAqH;YACrH,IAAI,CAAC;gBACD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,GAAG,EAAE,CAAC;gBAChC,IAAI,CAAC,MAAM,CAAC,OAAO;oBAAE,SAAS,GAAG,IAAI,CAAC;YAC1C,CAAC;YAAC,OAAO,GAAY,EAAE,CAAC;gBACpB,MAAM,KAAK,GAAG,IAAA,sBAAO,EAAC,GAAG,CAAC,CAAC;gBAC3B,IAAI,KAAK,YAAY,4BAAa,EAAE,CAAC;oBACjC,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;gBAC/B,CAAC;qBAAM,CAAC;oBACJ,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;gBACvC,CAAC;gBACD,SAAS,GAAG,IAAI,CAAC;YACrB,CAAC;QACL,CAAC;QACD,OAAO,EAAE,OAAO,EAAE,CAAC,SAAS,EAAE,CAAC;IACnC,CAAC;IAED,8FAA8F;IAC9F,iGAAiG;IACzF,cAAc,CAAC,GAAkB;QACrC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAClB,OAAO,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,QAAQ,KAAK,GAAG,CAAC,YAAY,EAAE,CAAC,CAAC;QACzD,IAAI,GAAG,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;YACzB,OAAO,CAAC,KAAK,CAAC,OAAO,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,GAAG,CAAC,OAAO,IAAI,EAAE,EAAE,CAAC,CAAC;QACnE,CAAC;QACD,KAAK,MAAM,IAAI,IAAI,GAAG,CAAC,QAAQ,EAAE,CAAC;YAC9B,OAAO,CAAC,KAAK,CAAC,WAAW,IAAI,EAAE,CAAC,CAAC;QACrC,CAAC;QACD,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IACtB,CAAC;IAED,kGAAkG;IAClG,+DAA+D;IACvD,WAAW,CAAC,IAAY,EAAE,KAAY;QAC1C,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAClB,OAAO,CAAC,KAAK,CAAC,gBAAgB,IAAI,cAAc,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;QACjE,OAAO,CAAC,KAAK,CAAC,8DAA8D,CAAC,CAAC;QAC9E,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IACtB,CAAC;CACJ,CAAA;AAnDY,oCAAY;uBAAZ,YAAY;IAFxB,IAAA,+BAAgB,GAAE;IAClB,IAAA,sBAAU,GAAE;GACA,YAAY,CAmDxB","sourcesContent":["import { RuleFailError, toError } from '@webpieces/rules-config';\nimport { provideSingleton } from '@webpieces/core-context';\nimport { injectable } from 'inversify';\n\nimport { RuleRun, ExecutorResult } from './code-validator';\n\n/**\n * Runs the active validators with per-validator isolation and prints failures for humans/CI.\n */\n@provideSingleton()\n@injectable()\nexport class RuleReporter {\n /**\n * Run every {@link RuleRun} with per-run isolation: a run that throws — a `RuleFailError` (an\n * expected failure) OR a plain `Error` (a bug) — is caught, reported, and marks the whole run\n * failed, but the remaining runs STILL execute. One validator can no longer abort the CI run.\n *\n * Back-compatible: runs that still `console.error(...)` + `return { success: false }` keep\n * working; their `false` result flips the aggregate exactly as before.\n */\n async runValidators(runs: readonly RuleRun[]): Promise<ExecutorResult> {\n let anyFailed = false;\n for (const item of runs) {\n // webpieces-disable no-unmanaged-exceptions -- per-run isolation chokepoint: one validator must never abort the rest\n try {\n const result = await item.run();\n if (!result.success) anyFailed = true;\n } catch (err: unknown) {\n const error = toError(err);\n if (error instanceof RuleFailError) {\n this.reportRuleFail(error);\n } else {\n this.reportCrash(item.name, error);\n }\n anyFailed = true;\n }\n }\n return { success: !anyFailed };\n }\n\n // Human/CI console block for a validator that threw a RuleFailError. code-rules is developer-\n // facing, so it prints humanMessage (falls back to aiMessage inside RuleFailError when not set).\n private reportRuleFail(err: RuleFailError): void {\n console.error('');\n console.error(`❌ [${err.ruleName}] ${err.humanMessage}`);\n if (err.line !== undefined) {\n console.error(` L${String(err.line)}: ${err.snippet ?? ''}`);\n }\n for (const hint of err.fixHints) {\n console.error(` Fix: ${hint}`);\n }\n console.error('');\n }\n\n // A validator that threw a plain Error is a BUG in the validator — surface it (don't swallow) and\n // keep going so it doesn't hide the other validators' results.\n private reportCrash(name: string, error: Error): void {\n console.error('');\n console.error(`❌ Validator '${name}' crashed: ${error.message}`);\n console.error(' (a bug in the validator — the other validators still ran)');\n console.error('');\n }\n}\n"]}
1
+ {"version":3,"file":"rule-reporter.js","sourceRoot":"","sources":["../../../../../packages/tooling/code-rules/src/rule-reporter.ts"],"names":[],"mappings":";;;;AAAA,0DAAiE;AACjE,0DAA2D;AAC3D,yCAAuC;AAIvC;;GAEG;AAGI,IAAM,YAAY,GAAlB,MAAM,YAAY;IACrB;;;;;;;OAOG;IACH,KAAK,CAAC,aAAa,CAAC,IAAwB;QACxC,IAAI,SAAS,GAAG,KAAK,CAAC;QACtB,KAAK,MAAM,IAAI,IAAI,IAAI,EAAE,CAAC;YACtB,qHAAqH;YACrH,IAAI,CAAC;gBACD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,GAAG,EAAE,CAAC;gBAChC,IAAI,CAAC,MAAM,CAAC,OAAO;oBAAE,SAAS,GAAG,IAAI,CAAC;YAC1C,CAAC;YAAC,OAAO,GAAY,EAAE,CAAC;gBACpB,MAAM,KAAK,GAAG,IAAA,sBAAO,EAAC,GAAG,CAAC,CAAC;gBAC3B,IAAI,KAAK,YAAY,4BAAa,EAAE,CAAC;oBACjC,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;gBAC/B,CAAC;qBAAM,CAAC;oBACJ,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;gBACvC,CAAC;gBACD,SAAS,GAAG,IAAI,CAAC;YACrB,CAAC;QACL,CAAC;QACD,OAAO,EAAE,OAAO,EAAE,CAAC,SAAS,EAAE,CAAC;IACnC,CAAC;IAED,8FAA8F;IAC9F,iGAAiG;IACzF,cAAc,CAAC,GAAkB;QACrC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAClB,OAAO,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,QAAQ,KAAK,GAAG,CAAC,YAAY,EAAE,CAAC,CAAC;QACzD,IAAI,GAAG,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;YACzB,OAAO,CAAC,KAAK,CAAC,OAAO,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,GAAG,CAAC,OAAO,IAAI,EAAE,EAAE,CAAC,CAAC;QACnE,CAAC;QACD,KAAK,MAAM,IAAI,IAAI,GAAG,CAAC,QAAQ,EAAE,CAAC;YAC9B,OAAO,CAAC,KAAK,CAAC,WAAW,IAAI,EAAE,CAAC,CAAC;QACrC,CAAC;QACD,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IACtB,CAAC;IAED,kGAAkG;IAClG,+DAA+D;IACvD,WAAW,CAAC,IAAY,EAAE,KAAY;QAC1C,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAClB,OAAO,CAAC,KAAK,CAAC,gBAAgB,IAAI,cAAc,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;QACjE,OAAO,CAAC,KAAK,CAAC,8DAA8D,CAAC,CAAC;QAC9E,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IACtB,CAAC;CACJ,CAAA;AAnDY,oCAAY;uBAAZ,YAAY;IAFxB,IAAA,+BAAgB,GAAE;IAClB,IAAA,sBAAU,GAAE;GACA,YAAY,CAmDxB","sourcesContent":["import { RuleFailError, toError } from '@webpieces/rules-config';\nimport { provideSingleton } from '@webpieces/rules-config';\nimport { injectable } from 'inversify';\n\nimport { RuleRun, ExecutorResult } from './code-validator';\n\n/**\n * Runs the active validators with per-validator isolation and prints failures for humans/CI.\n */\n@provideSingleton()\n@injectable()\nexport class RuleReporter {\n /**\n * Run every {@link RuleRun} with per-run isolation: a run that throws — a `RuleFailError` (an\n * expected failure) OR a plain `Error` (a bug) — is caught, reported, and marks the whole run\n * failed, but the remaining runs STILL execute. One validator can no longer abort the CI run.\n *\n * Back-compatible: runs that still `console.error(...)` + `return { success: false }` keep\n * working; their `false` result flips the aggregate exactly as before.\n */\n async runValidators(runs: readonly RuleRun[]): Promise<ExecutorResult> {\n let anyFailed = false;\n for (const item of runs) {\n // webpieces-disable no-unmanaged-exceptions -- per-run isolation chokepoint: one validator must never abort the rest\n try {\n const result = await item.run();\n if (!result.success) anyFailed = true;\n } catch (err: unknown) {\n const error = toError(err);\n if (error instanceof RuleFailError) {\n this.reportRuleFail(error);\n } else {\n this.reportCrash(item.name, error);\n }\n anyFailed = true;\n }\n }\n return { success: !anyFailed };\n }\n\n // Human/CI console block for a validator that threw a RuleFailError. code-rules is developer-\n // facing, so it prints humanMessage (falls back to aiMessage inside RuleFailError when not set).\n private reportRuleFail(err: RuleFailError): void {\n console.error('');\n console.error(`❌ [${err.ruleName}] ${err.humanMessage}`);\n if (err.line !== undefined) {\n console.error(` L${String(err.line)}: ${err.snippet ?? ''}`);\n }\n for (const hint of err.fixHints) {\n console.error(` Fix: ${hint}`);\n }\n console.error('');\n }\n\n // A validator that threw a plain Error is a BUG in the validator — surface it (don't swallow) and\n // keep going so it doesn't hide the other validators' results.\n private reportCrash(name: string, error: Error): void {\n console.error('');\n console.error(`❌ Validator '${name}' crashed: ${error.message}`);\n console.error(' (a bug in the validator — the other validators still ran)');\n console.error('');\n }\n}\n"]}
@@ -44,7 +44,7 @@ const path = tslib_1.__importStar(require("path"));
44
44
  const ts = tslib_1.__importStar(require("typescript"));
45
45
  const rules_config_1 = require("@webpieces/rules-config");
46
46
  const code_validator_1 = require("./code-validator");
47
- const core_context_1 = require("@webpieces/core-context");
47
+ const rules_config_2 = require("@webpieces/rules-config");
48
48
  const inversify_1 = require("inversify");
49
49
  const resolve_mode_1 = require("./resolve-mode");
50
50
  /**
@@ -384,7 +384,7 @@ let CatchErrorPatternValidator = class CatchErrorPatternValidator extends code_v
384
384
  };
385
385
  exports.CatchErrorPatternValidator = CatchErrorPatternValidator;
386
386
  exports.CatchErrorPatternValidator = CatchErrorPatternValidator = tslib_1.__decorate([
387
- (0, core_context_1.provideSingleton)(),
387
+ (0, rules_config_2.provideSingleton)(),
388
388
  (0, inversify_1.injectable)(),
389
389
  tslib_1.__metadata("design:paramtypes", [rules_config_1.CatchErrorPatternConfig])
390
390
  ], CatchErrorPatternValidator);
@@ -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 { provideSingleton } from '@webpieces/core-context';\nimport { injectable } 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 ignoreModifiedUntilEpoch 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.ignoreModifiedUntilEpoch, options.ignoreRuleWhileOnBranch);\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@provideSingleton()\n@injectable()\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 { provideSingleton } from '@webpieces/rules-config';\nimport { injectable } 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 ignoreModifiedUntilEpoch 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.ignoreModifiedUntilEpoch, options.ignoreRuleWhileOnBranch);\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@provideSingleton()\n@injectable()\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"]}
@@ -36,7 +36,7 @@ const path = tslib_1.__importStar(require("path"));
36
36
  const ts = tslib_1.__importStar(require("typescript"));
37
37
  const rules_config_1 = require("@webpieces/rules-config");
38
38
  const code_validator_1 = require("./code-validator");
39
- const core_context_1 = require("@webpieces/core-context");
39
+ const rules_config_2 = require("@webpieces/rules-config");
40
40
  const inversify_1 = require("inversify");
41
41
  const resolve_mode_1 = require("./resolve-mode");
42
42
  /**
@@ -445,7 +445,7 @@ let PrismaValidateDtosValidator = class PrismaValidateDtosValidator extends code
445
445
  };
446
446
  exports.PrismaValidateDtosValidator = PrismaValidateDtosValidator;
447
447
  exports.PrismaValidateDtosValidator = PrismaValidateDtosValidator = tslib_1.__decorate([
448
- (0, core_context_1.provideSingleton)(),
448
+ (0, rules_config_2.provideSingleton)(),
449
449
  (0, inversify_1.injectable)(),
450
450
  tslib_1.__metadata("design:paramtypes", [rules_config_1.PrismaValidateDtosConfig])
451
451
  ], PrismaValidateDtosValidator);
@@ -1 +1 @@
1
- {"version":3,"file":"validate-dtos.js","sourceRoot":"","sources":["../../../../../packages/tooling/code-rules/src/validate-dtos.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;;;;AAEH,+CAAyB;AACzB,mDAA6B;AAC7B,uDAAiC;AACjC,0DAA4J;AAC5J,qDAAiE;AACjE,0DAA2D;AAC3D,yCAAuC;AACvC,iDAAgD;AA8BhD;;;GAGG;AACH,SAAS,YAAY,CAAC,CAAS;IAC3B,OAAO,CAAC,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC,EAAE,MAAc,EAAE,EAAE,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC;AAC/E,CAAC;AAED;;;;GAIG;AACH,SAAS,iBAAiB,CAAC,UAAkB;IACzC,MAAM,MAAM,GAAG,IAAI,GAAG,EAAuB,CAAC;IAE9C,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC7B,OAAO,MAAM,CAAC;IAClB,CAAC;IAED,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;IACrD,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAElC,IAAI,YAAY,GAAkB,IAAI,CAAC;IACvC,IAAI,aAAa,GAAuB,IAAI,CAAC;IAE7C,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACvB,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;QAE5B,0CAA0C;QAC1C,MAAM,UAAU,GAAG,OAAO,CAAC,KAAK,CAAC,wBAAwB,CAAC,CAAC;QAC3D,IAAI,UAAU,EAAE,CAAC;YACb,YAAY,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC;YAC7B,aAAa,GAAG,IAAI,GAAG,EAAU,CAAC;YAClC,SAAS;QACb,CAAC;QAED,qBAAqB;QACrB,IAAI,YAAY,IAAI,OAAO,KAAK,GAAG,EAAE,CAAC;YAClC,MAAM,CAAC,GAAG,CAAC,YAAY,EAAE,aAAc,CAAC,CAAC;YACzC,YAAY,GAAG,IAAI,CAAC;YACpB,aAAa,GAAG,IAAI,CAAC;YACrB,SAAS;QACb,CAAC;QAED,6CAA6C;QAC7C,IAAI,YAAY,IAAI,aAAa,EAAE,CAAC;YAChC,8DAA8D;YAC9D,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;gBACnE,SAAS;YACb,CAAC;YAED,mEAAmE;YACnE,MAAM,UAAU,GAAG,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;YAC7C,IAAI,UAAU,EAAE,CAAC;gBACb,aAAa,CAAC,GAAG,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YACnD,CAAC;QACL,CAAC;IACL,CAAC;IAED,OAAO,MAAM,CAAC;AAClB,CAAC;AAED;;GAEG;AACH,SAAS,iBAAiB,CAAC,SAAmB,EAAE,SAAiB;IAC7D,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,SAAS,GAAG,CAAC,CAAC,CAAC;IACzC,KAAK,IAAI,CAAC,GAAG,KAAK,EAAE,CAAC,IAAI,SAAS,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC1C,MAAM,IAAI,GAAG,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;QACxC,IAAI,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC;YAAE,OAAO,IAAI,CAAC;IAClD,CAAC;IACD,OAAO,KAAK,CAAC;AACjB,CAAC;AAED;;;GAGG;AACH,4HAA4H;AAC5H,SAAS,cAAc,CAAC,QAAgB,EAAE,aAAqB;IAC3D,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;IAExC,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IACnD,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;IAExF,MAAM,IAAI,GAAc,EAAE,CAAC;IAE3B,SAAS,KAAK,CAAC,IAAa;QACxB,MAAM,OAAO,GAAG,EAAE,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC;QAC5C,MAAM,WAAW,GAAG,EAAE,CAAC,sBAAsB,CAAC,IAAI,CAAC,CAAC;QAEpD,IAAI,CAAC,OAAO,IAAI,WAAW,CAAC,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YACxC,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;YAE5B,yCAAyC;YACzC,IAAI,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;gBACpD,MAAM,MAAM,GAAmB,EAAE,CAAC;gBAClC,MAAM,SAAS,GAAG,UAAU,CAAC,6BAA6B,CAAC,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC;gBACtF,MAAM,OAAO,GAAG,UAAU,CAAC,6BAA6B,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;gBAExE,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;oBAChC,IAAI,EAAE,CAAC,qBAAqB,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,mBAAmB,CAAC,MAAM,CAAC,EAAE,CAAC;wBACrE,IAAI,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;4BAC9C,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC;4BACnC,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;4BAC7C,MAAM,GAAG,GAAG,UAAU,CAAC,6BAA6B,CAAC,QAAQ,CAAC,CAAC;4BAC/D,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,GAAG,CAAC,CAAC;4BAC1B,MAAM,UAAU,GAAG,iBAAiB,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;4BAEtD,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,CAAC;wBACvD,CAAC;oBACL,CAAC;gBACL,CAAC;gBAED,IAAI,CAAC,IAAI,CAAC;oBACN,IAAI;oBACJ,IAAI,EAAE,QAAQ;oBACd,SAAS,EAAE,SAAS,CAAC,IAAI,GAAG,CAAC;oBAC7B,OAAO,EAAE,OAAO,CAAC,IAAI,GAAG,CAAC;oBACzB,MAAM;iBACT,CAAC,CAAC;YACP,CAAC;QACL,CAAC;QAED,EAAE,CAAC,YAAY,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IACjC,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,CAAC;IAClB,OAAO,IAAI,CAAC;AAChB,CAAC;AAED;;;GAGG;AACH,SAAS,aAAa,CAAC,IAAY,EAAE,MAAc;IAC/C,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,WAAW,EAAE,CAAC;AACvD,CAAC;AAED;;GAEG;AACH,SAAS,cAAc,CACnB,IAAe,EACf,SAAmC;IAEnC,MAAM,UAAU,GAAmB,EAAE,CAAC;IAEtC,2CAA2C;IAC3C,MAAM,WAAW,GAAG,IAAI,GAAG,EAAoB,CAAC;IAChD,SAAS,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,OAAO,EAAE,EAAE;QAClC,MAAM,MAAM,GAAG,aAAa,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;QAC7C,WAAW,CAAC,GAAG,CAAC,MAAM,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;IACvD,CAAC,CAAC,CAAC;IAEH,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACrB,MAAM,MAAM,GAAG,aAAa,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QAC9C,MAAM,GAAG,GAAG,WAAW,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QAEpC,IAAI,CAAC,GAAG,EAAE,CAAC;YACP,mEAAmE;YACnE,SAAS;QACb,CAAC;QAED,KAAK,MAAM,KAAK,IAAI,GAAG,CAAC,MAAM,EAAE,CAAC;YAC7B,IAAI,KAAK,CAAC,UAAU;gBAAE,SAAS;YAE/B,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC9B,UAAU,CAAC,IAAI,CAAC;oBACZ,IAAI,EAAE,GAAG,CAAC,IAAI;oBACd,IAAI,EAAE,KAAK,CAAC,IAAI;oBAChB,OAAO,EAAE,GAAG,CAAC,IAAI;oBACjB,SAAS,EAAE,KAAK,CAAC,IAAI;oBACrB,OAAO,EAAE,GAAG,CAAC,IAAI;oBACjB,eAAe,EAAE,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE;iBACjD,CAAC,CAAC;YACP,CAAC;QACL,CAAC;IACL,CAAC;IAED,OAAO,UAAU,CAAC;AACtB,CAAC;AAED;;;GAGG;AACH,SAAS,UAAU,CAAC,CAAS,EAAE,CAAS;IACpC,MAAM,EAAE,GAAG,CAAC,CAAC,WAAW,EAAE,CAAC;IAC3B,MAAM,EAAE,GAAG,CAAC,CAAC,WAAW,EAAE,CAAC;IAC3B,IAAI,EAAE,KAAK,EAAE;QAAE,OAAO,CAAC,CAAC;IAExB,MAAM,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC;IACpB,MAAM,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC;IACpB,MAAM,IAAI,GAAG,IAAI,KAAK,CAAS,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC9C,MAAM,IAAI,GAAG,IAAI,KAAK,CAAS,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAE9C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC1B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;YAC1B,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;gBAC1B,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;YAC9B,CAAC;iBAAM,CAAC;gBACJ,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;YAC7C,CAAC;QACL,CAAC;QACD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;YAC1B,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;YAClB,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;QAChB,CAAC;IACL,CAAC;IAED,MAAM,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;IACvB,OAAO,CAAC,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;AAClC,CAAC;AAED;;;GAGG;AACH,SAAS,mBAAmB,CAAC,SAAiB,EAAE,eAAyB;IACrE,IAAI,SAAS,GAAkB,IAAI,CAAC;IACpC,IAAI,SAAS,GAAG,GAAG,CAAC,CAAC,oBAAoB;IAEzC,KAAK,MAAM,SAAS,IAAI,eAAe,EAAE,CAAC;QACtC,MAAM,KAAK,GAAG,UAAU,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;QAC/C,IAAI,KAAK,GAAG,SAAS,EAAE,CAAC;YACpB,SAAS,GAAG,KAAK,CAAC;YAClB,SAAS,GAAG,SAAS,CAAC;QAC1B,CAAC;IACL,CAAC;IAED,OAAO,SAAS,CAAC;AACrB,CAAC;AAED;;GAEG;AACH,SAAS,gBAAgB,CAAC,UAA0B;IAChD,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAClB,OAAO,CAAC,KAAK,CAAC,4DAA4D,CAAC,CAAC;IAC5E,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAClB,OAAO,CAAC,KAAK,CAAC,6DAA6D,CAAC,CAAC;IAC7E,OAAO,CAAC,KAAK,CAAC,iFAAiF,CAAC,CAAC;IACjG,OAAO,CAAC,KAAK,CAAC,0DAA0D,CAAC,CAAC;IAC1E,OAAO,CAAC,KAAK,CAAC,sFAAsF,CAAC,CAAC;IACtG,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAClB,OAAO,CAAC,KAAK,CAAC,6EAA6E,CAAC,CAAC;IAC7F,OAAO,CAAC,KAAK,CAAC,gFAAgF,CAAC,CAAC;IAChG,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAClB,OAAO,CAAC,KAAK,CAAC,mFAAmF,CAAC,CAAC;IACnG,OAAO,CAAC,KAAK,CAAC,iFAAiF,CAAC,CAAC;IACjG,OAAO,CAAC,KAAK,CAAC,qEAAqE,CAAC,CAAC;IACrF,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAElB,KAAK,MAAM,CAAC,IAAI,UAAU,EAAE,CAAC;QACzB,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;QACzC,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,SAAS,sBAAsB,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;QAEjF,MAAM,UAAU,GAAG,mBAAmB,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,eAAe,CAAC,CAAC;QACvE,IAAI,UAAU,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,6BAA6B,CAAC,CAAC,SAAS,MAAM,UAAU,yBAAyB,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,SAAS,GAAG,CAAC,CAAC;QAChI,CAAC;aAAM,CAAC;YACJ,MAAM,OAAO,GAAG,CAAC,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACzD,MAAM,QAAQ,GAAG,CAAC,CAAC,eAAe,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;YAC7D,OAAO,CAAC,KAAK,CAAC,4CAA4C,OAAO,GAAG,QAAQ,EAAE,CAAC,CAAC;QACpF,CAAC;IACL,CAAC;IACD,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAElB,OAAO,CAAC,KAAK,CAAC,+FAA+F,CAAC,CAAC;IAC/G,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;AACtB,CAAC;AAED;;GAEG;AACH,SAAS,cAAc,CAAC,YAAsB,EAAE,cAAwB;IACpE,OAAO,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE;QAC7B,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC;YAAE,OAAO,KAAK,CAAC;QAC5D,IAAI,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC;YAAE,OAAO,KAAK,CAAC;QACnE,OAAO,cAAc,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC;IACnE,CAAC,CAAC,CAAC;AACP,CAAC;AAED;;GAEG;AACH,SAAS,WAAW,CAAC,QAAkB,EAAE,aAAqB;IAC1D,MAAM,OAAO,GAAc,EAAE,CAAC;IAC9B,KAAK,MAAM,IAAI,IAAI,QAAQ,EAAE,CAAC;QAC1B,MAAM,IAAI,GAAG,cAAc,CAAC,IAAI,EAAE,aAAa,CAAC,CAAC;QACjD,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC;IAC1B,CAAC;IACD,OAAO,OAAO,CAAC;AACnB,CAAC;AAED;;GAEG;AACH,SAAS,YAAY,CAAC,GAAY,EAAE,YAAyB;IACzD,KAAK,IAAI,IAAI,GAAG,GAAG,CAAC,SAAS,EAAE,IAAI,IAAI,GAAG,CAAC,OAAO,EAAE,IAAI,EAAE,EAAE,CAAC;QACzD,IAAI,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC;YAAE,OAAO,IAAI,CAAC;IAC5C,CAAC;IACD,OAAO,KAAK,CAAC;AACjB,CAAC;AAED;;GAEG;AACH,SAAS,iBAAiB,CACtB,IAAe,EACf,aAAqB,EACrB,IAAY,EACZ,IAAa;IAEb,gDAAgD;IAChD,MAAM,MAAM,GAAG,IAAI,GAAG,EAAqB,CAAC;IAC5C,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACrB,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;QACxC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACf,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IAC/B,CAAC;IAED,MAAM,OAAO,GAAc,EAAE,CAAC;IAC9B,MAAM,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,IAAI,EAAE,EAAE;QAC9B,MAAM,IAAI,GAAG,IAAA,0BAAW,EAAC,aAAa,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;QAC1D,MAAM,YAAY,GAAG,IAAA,oCAAqB,EAAC,IAAI,CAAC,CAAC;QACjD,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;YACzB,IAAI,YAAY,CAAC,GAAG,EAAE,YAAY,CAAC,EAAE,CAAC;gBAClC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACtB,CAAC;QACL,CAAC;IACL,CAAC,CAAC,CAAC;IACH,OAAO,OAAO,CAAC;AACnB,CAAC;AAED;;GAEG;AACH,SAAS,WAAW,CAAC,aAAqB;IACtC,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IACvC,IAAI,OAAO;QAAE,OAAO,OAAO,CAAC;IAC5B,OAAO,IAAA,yBAAU,EAAC,aAAa,CAAC,IAAI,SAAS,CAAC;AAClD,CAAC;AAED;;GAEG;AACH,2GAA2G;AAC3G,SAAS,gBAAgB,CACrB,aAAqB,EACrB,gBAAwB,EACxB,YAAsB,EACtB,cAAwB,EACxB,IAA4B,EAC5B,IAAY,EACZ,IAAa;IAEb,IAAI,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,gBAAgB,CAAC,CAAC,EAAE,CAAC;QACzD,OAAO,CAAC,GAAG,CAAC,yEAAyE,CAAC,CAAC;QACvF,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAChB,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IAC7B,CAAC;IAED,MAAM,QAAQ,GAAG,cAAc,CAAC,YAAY,EAAE,cAAc,CAAC,CAAC;IAE9D,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxB,OAAO,CAAC,GAAG,CAAC,wBAAwB,CAAC,CAAC;QACtC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IAC7B,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,eAAe,QAAQ,CAAC,MAAM,yCAAyC,CAAC,CAAC;IAErF,MAAM,cAAc,GAAG,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,gBAAgB,CAAC,CAAC;IAClE,MAAM,SAAS,GAAG,iBAAiB,CAAC,cAAc,CAAC,CAAC;IAEpD,IAAI,SAAS,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;QACvB,OAAO,CAAC,GAAG,CAAC,0CAA0C,CAAC,CAAC;QACxD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAChB,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IAC7B,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,YAAY,SAAS,CAAC,IAAI,gCAAgC,CAAC,CAAC;IAExE,IAAI,OAAO,GAAG,WAAW,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC;IAEnD,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,OAAO,CAAC,GAAG,CAAC,6CAA6C,CAAC,CAAC;QAC3D,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IAC7B,CAAC;IAED,iEAAiE;IACjE,IAAI,IAAI,KAAK,gBAAgB,EAAE,CAAC;QAC5B,OAAO,GAAG,iBAAiB,CAAC,OAAO,EAAE,aAAa,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;QAChE,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACvB,OAAO,CAAC,GAAG,CAAC,gCAAgC,CAAC,CAAC;YAC9C,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;QAC7B,CAAC;IACL,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,iBAAiB,OAAO,CAAC,MAAM,oBAAoB,CAAC,CAAC;IAEjE,MAAM,UAAU,GAAG,cAAc,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;IAEtD,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,CAAC,CAAC;IAC7B,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;AAC9B,CAAC;AAED;;;GAGG;AACH,SAAS,WAAW,CAAC,UAAkC,EAAE,KAAyB,EAAE,aAAiC;IACjH,IAAI,UAAU,KAAK,KAAK,EAAE,CAAC;QACvB,OAAO,UAAU,CAAC;IACtB,CAAC;IACD,MAAM,IAAI,GAAG,IAAA,6BAAc,EAAC,KAAK,EAAE,aAAa,CAAC,CAAC;IAClD,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;QACZ,OAAO,CAAC,GAAG,CAAC,iCAAiC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC;QAC7D,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAChB,OAAO,KAAK,CAAC;IACjB,CAAC;IACD,OAAO,UAAU,CAAC;AACtB,CAAC;AAED,KAAK,UAAU,gBAAgB,CAC3B,OAAiC,EACjC,aAAqB;IAErB,MAAM,IAAI,GAAG,WAAW,CAAC,OAAO,CAAC,IAAI,IAAI,KAAK,EAAE,OAAO,CAAC,wBAAwB,EAAE,OAAO,CAAC,uBAAuB,CAAC,CAAC;IAEnH,IAAI,IAAI,KAAK,KAAK,EAAE,CAAC;QACjB,OAAO,CAAC,GAAG,CAAC,0CAA0C,CAAC,CAAC;QACxD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAChB,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IAC7B,CAAC;IAED,MAAM,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAClD,MAAM,cAAc,GAAG,OAAO,CAAC,cAAc,IAAI,EAAE,CAAC;IAEpD,IAAI,CAAC,gBAAgB,IAAI,cAAc,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACnD,MAAM,MAAM,GAAG,CAAC,gBAAgB,CAAC,CAAC,CAAC,gCAAgC,CAAC,CAAC,CAAC,8BAA8B,CAAC;QACrG,OAAO,CAAC,GAAG,CAAC,iCAAiC,MAAM,GAAG,CAAC,CAAC;QACxD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAChB,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IAC7B,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,gDAAgD,CAAC,CAAC;IAC9D,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,EAAE,CAAC,CAAC;IAChC,OAAO,CAAC,GAAG,CAAC,cAAc,gBAAgB,EAAE,CAAC,CAAC;IAC9C,OAAO,CAAC,GAAG,CAAC,iBAAiB,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAE1D,MAAM,IAAI,GAAG,WAAW,CAAC,aAAa,CAAC,CAAC;IACxC,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IAEpC,IAAI,CAAC,IAAI,EAAE,CAAC;QACR,OAAO,CAAC,GAAG,CAAC,6DAA6D,CAAC,CAAC;QAC3E,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAChB,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IAC7B,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,EAAE,CAAC,CAAC;IAChC,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,IAAI,6CAA6C,EAAE,CAAC,CAAC;IACjF,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAEhB,MAAM,YAAY,GAAG,IAAA,8BAAe,EAAC,aAAa,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;IAEnF,OAAO,gBAAgB,CAAC,aAAa,EAAE,gBAAgB,EAAE,YAAY,EAAE,cAAc,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;AAC7G,CAAC;AAIM,IAAM,2BAA2B,GAAjC,MAAM,2BAA4B,SAAQ,8BAAuC;IACpF,YAAY,MAAgC;QACxC,KAAK,CAAC,MAAM,EAAE,sBAAsB,CAAC,CAAC;IAC1C,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,aAAqB;QAC3B,OAAO,gBAAgB,CAAC,IAAI,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IACxD,CAAC;CACJ,CAAA;AARY,kEAA2B;sCAA3B,2BAA2B;IAFvC,IAAA,+BAAgB,GAAE;IAClB,IAAA,sBAAU,GAAE;6CAEW,uCAAwB;GADnC,2BAA2B,CAQvC","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 { provideSingleton } from '@webpieces/core-context';\nimport { injectable } 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 ignoreModifiedUntilEpoch 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.ignoreModifiedUntilEpoch, options.ignoreRuleWhileOnBranch);\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@provideSingleton()\n@injectable()\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 { provideSingleton } from '@webpieces/rules-config';\nimport { injectable } 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 ignoreModifiedUntilEpoch 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.ignoreModifiedUntilEpoch, options.ignoreRuleWhileOnBranch);\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@provideSingleton()\n@injectable()\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"]}
@@ -38,7 +38,7 @@ exports.findUntaggedProjects = findUntaggedProjects;
38
38
  const tslib_1 = require("tslib");
39
39
  const rules_config_1 = require("@webpieces/rules-config");
40
40
  const code_validator_1 = require("./code-validator");
41
- const core_context_1 = require("@webpieces/core-context");
41
+ const rules_config_2 = require("@webpieces/rules-config");
42
42
  const inversify_1 = require("inversify");
43
43
  const tag_rule_1 = require("./tag-rule");
44
44
  const FRAMEWORK_TAG_PREFIX = 'framework:';
@@ -104,7 +104,7 @@ let FrameworkTagValidator = class FrameworkTagValidator extends code_validator_1
104
104
  };
105
105
  exports.FrameworkTagValidator = FrameworkTagValidator;
106
106
  exports.FrameworkTagValidator = FrameworkTagValidator = tslib_1.__decorate([
107
- (0, core_context_1.provideSingleton)(),
107
+ (0, rules_config_2.provideSingleton)(),
108
108
  (0, inversify_1.injectable)(),
109
109
  tslib_1.__metadata("design:paramtypes", [rules_config_1.FrameworkTagConfig])
110
110
  ], FrameworkTagValidator);
@@ -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 { provideSingleton } from '@webpieces/core-context';\nimport { injectable } 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@provideSingleton()\n@injectable()\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 { provideSingleton } from '@webpieces/rules-config';\nimport { injectable } 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@provideSingleton()\n@injectable()\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"]}