@webpieces/code-rules 0.3.139 → 0.3.140

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 (52) hide show
  1. package/package.json +2 -2
  2. package/src/from-shared-config.js +20 -59
  3. package/src/from-shared-config.js.map +1 -1
  4. package/src/resolve-mode.d.ts +6 -0
  5. package/src/resolve-mode.js +40 -0
  6. package/src/resolve-mode.js.map +1 -0
  7. package/src/validate-catch-error-pattern.d.ts +1 -0
  8. package/src/validate-catch-error-pattern.js +7 -7
  9. package/src/validate-catch-error-pattern.js.map +1 -1
  10. package/src/validate-code-options.d.ts +13 -0
  11. package/src/validate-code-options.js.map +1 -1
  12. package/src/validate-code.js +49 -83
  13. package/src/validate-code.js.map +1 -1
  14. package/src/validate-dtos.d.ts +1 -0
  15. package/src/validate-dtos.js +7 -7
  16. package/src/validate-dtos.js.map +1 -1
  17. package/src/validate-modified-files.d.ts +2 -0
  18. package/src/validate-modified-files.js +6 -2
  19. package/src/validate-modified-files.js.map +1 -1
  20. package/src/validate-modified-methods.d.ts +2 -0
  21. package/src/validate-modified-methods.js +6 -2
  22. package/src/validate-modified-methods.js.map +1 -1
  23. package/src/validate-new-methods.d.ts +2 -0
  24. package/src/validate-new-methods.js +6 -2
  25. package/src/validate-new-methods.js.map +1 -1
  26. package/src/validate-no-any-unknown.d.ts +1 -0
  27. package/src/validate-no-any-unknown.js +7 -7
  28. package/src/validate-no-any-unknown.js.map +1 -1
  29. package/src/validate-no-destructure.d.ts +1 -0
  30. package/src/validate-no-destructure.js +7 -7
  31. package/src/validate-no-destructure.js.map +1 -1
  32. package/src/validate-no-direct-api-resolver.d.ts +1 -0
  33. package/src/validate-no-direct-api-resolver.js +7 -7
  34. package/src/validate-no-direct-api-resolver.js.map +1 -1
  35. package/src/validate-no-implicit-any.d.ts +1 -0
  36. package/src/validate-no-implicit-any.js +7 -7
  37. package/src/validate-no-implicit-any.js.map +1 -1
  38. package/src/validate-no-inline-types.d.ts +1 -0
  39. package/src/validate-no-inline-types.js +7 -7
  40. package/src/validate-no-inline-types.js.map +1 -1
  41. package/src/validate-no-symbol-di-tokens.d.ts +1 -0
  42. package/src/validate-no-symbol-di-tokens.js +7 -7
  43. package/src/validate-no-symbol-di-tokens.js.map +1 -1
  44. package/src/validate-no-unmanaged-exceptions.d.ts +1 -0
  45. package/src/validate-no-unmanaged-exceptions.js +7 -7
  46. package/src/validate-no-unmanaged-exceptions.js.map +1 -1
  47. package/src/validate-prisma-converters.d.ts +1 -0
  48. package/src/validate-prisma-converters.js +7 -7
  49. package/src/validate-prisma-converters.js.map +1 -1
  50. package/src/validate-return-types.d.ts +1 -0
  51. package/src/validate-return-types.js +7 -7
  52. package/src/validate-return-types.js.map +1 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@webpieces/code-rules",
3
- "version": "0.3.139",
3
+ "version": "0.3.140",
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,7 +20,7 @@
20
20
  "directory": "packages/tooling/code-rules"
21
21
  },
22
22
  "dependencies": {
23
- "@webpieces/rules-config": "0.3.139"
23
+ "@webpieces/rules-config": "0.3.140"
24
24
  },
25
25
  "publishConfig": {
26
26
  "access": "public"
@@ -41,81 +41,42 @@ function modeOrOff(rule) {
41
41
  const mode = rule.options['mode'];
42
42
  return mode ?? undefined;
43
43
  }
44
+ function skipOpts(rule) {
45
+ return {
46
+ disableAllowed: opt(rule, 'disableAllowed'),
47
+ ignoreModifiedUntilEpoch: opt(rule, 'ignoreModifiedUntilEpoch'),
48
+ ignoreRuleWhileOnBranch: opt(rule, 'ignoreRuleWhileOnBranch'),
49
+ };
50
+ }
44
51
  function toValidateCodeOptions(shared) {
45
52
  const r = (name) => shared.rules.get(name);
46
53
  return {
47
- methodMaxLimit: {
48
- limit: opt(r('max-method-lines'), 'limit'),
49
- mode: modeOrOff(r('max-method-lines')),
50
- disableAllowed: opt(r('max-method-lines'), 'disableAllowed'),
51
- ignoreModifiedUntilEpoch: opt(r('max-method-lines'), 'ignoreModifiedUntilEpoch'),
52
- },
53
- fileMaxLimit: {
54
- limit: opt(r('max-file-lines'), 'limit'),
55
- mode: modeOrOff(r('max-file-lines')),
56
- disableAllowed: opt(r('max-file-lines'), 'disableAllowed'),
57
- ignoreModifiedUntilEpoch: opt(r('max-file-lines'), 'ignoreModifiedUntilEpoch'),
58
- },
59
- requireReturnType: {
60
- mode: modeOrOff(r('require-return-type')),
61
- disableAllowed: opt(r('require-return-type'), 'disableAllowed'),
62
- ignoreModifiedUntilEpoch: opt(r('require-return-type'), 'ignoreModifiedUntilEpoch'),
63
- },
64
- noInlineTypeLiterals: {
65
- mode: modeOrOff(r('no-inline-type-literals')),
66
- disableAllowed: opt(r('no-inline-type-literals'), 'disableAllowed'),
67
- ignoreModifiedUntilEpoch: opt(r('no-inline-type-literals'), 'ignoreModifiedUntilEpoch'),
68
- },
69
- noAnyUnknown: {
70
- mode: modeOrOff(r('no-any-unknown')),
71
- disableAllowed: opt(r('no-any-unknown'), 'disableAllowed'),
72
- ignoreModifiedUntilEpoch: opt(r('no-any-unknown'), 'ignoreModifiedUntilEpoch'),
73
- },
74
- noImplicitAny: {
75
- mode: modeOrOff(r('no-implicit-any')),
76
- disableAllowed: opt(r('no-implicit-any'), 'disableAllowed'),
77
- ignoreModifiedUntilEpoch: opt(r('no-implicit-any'), 'ignoreModifiedUntilEpoch'),
78
- },
54
+ methodMaxLimit: { mode: modeOrOff(r('max-method-lines')), ...skipOpts(r('max-method-lines')), limit: opt(r('max-method-lines'), 'limit') },
55
+ fileMaxLimit: { mode: modeOrOff(r('max-file-lines')), ...skipOpts(r('max-file-lines')), limit: opt(r('max-file-lines'), 'limit') },
56
+ requireReturnType: { mode: modeOrOff(r('require-return-type')), ...skipOpts(r('require-return-type')) },
57
+ noInlineTypeLiterals: { mode: modeOrOff(r('no-inline-type-literals')), ...skipOpts(r('no-inline-type-literals')) },
58
+ noAnyUnknown: { mode: modeOrOff(r('no-any-unknown')), ...skipOpts(r('no-any-unknown')) },
59
+ noImplicitAny: { mode: modeOrOff(r('no-implicit-any')), ...skipOpts(r('no-implicit-any')) },
79
60
  validateDtos: {
80
- mode: modeOrOff(r('prisma-validate-dtos')),
81
- disableAllowed: opt(r('prisma-validate-dtos'), 'disableAllowed'),
61
+ mode: modeOrOff(r('prisma-validate-dtos')), ...skipOpts(r('prisma-validate-dtos')),
82
62
  prismaSchemaPath: opt(r('prisma-validate-dtos'), 'prismaSchemaPath'),
83
63
  dtoSourcePaths: opt(r('prisma-validate-dtos'), 'dtoSourcePaths'),
84
- ignoreModifiedUntilEpoch: opt(r('prisma-validate-dtos'), 'ignoreModifiedUntilEpoch'),
85
64
  },
86
65
  prismaConverter: {
87
- mode: modeOrOff(r('prisma-converter')),
88
- disableAllowed: opt(r('prisma-converter'), 'disableAllowed'),
66
+ mode: modeOrOff(r('prisma-converter')), ...skipOpts(r('prisma-converter')),
89
67
  schemaPath: opt(r('prisma-converter'), 'schemaPath'),
90
68
  convertersPaths: opt(r('prisma-converter'), 'convertersPaths'),
91
69
  enforcePaths: opt(r('prisma-converter'), 'enforcePaths'),
92
- ignoreModifiedUntilEpoch: opt(r('prisma-converter'), 'ignoreModifiedUntilEpoch'),
93
- },
94
- noDestructure: {
95
- mode: modeOrOff(r('no-destructure')),
96
- disableAllowed: opt(r('no-destructure'), 'disableAllowed'),
97
- ignoreModifiedUntilEpoch: opt(r('no-destructure'), 'ignoreModifiedUntilEpoch'),
98
- },
99
- catchErrorPattern: {
100
- mode: modeOrOff(r('catch-error-pattern')),
101
- disableAllowed: opt(r('catch-error-pattern'), 'disableAllowed'),
102
- ignoreModifiedUntilEpoch: opt(r('catch-error-pattern'), 'ignoreModifiedUntilEpoch'),
103
- },
104
- noUnmanagedExceptions: {
105
- mode: modeOrOff(r('no-unmanaged-exceptions')),
106
- disableAllowed: opt(r('no-unmanaged-exceptions'), 'disableAllowed'),
107
- ignoreModifiedUntilEpoch: opt(r('no-unmanaged-exceptions'), 'ignoreModifiedUntilEpoch'),
108
70
  },
71
+ noDestructure: { mode: modeOrOff(r('no-destructure')), ...skipOpts(r('no-destructure')) },
72
+ catchErrorPattern: { mode: modeOrOff(r('catch-error-pattern')), ...skipOpts(r('catch-error-pattern')) },
73
+ noUnmanagedExceptions: { mode: modeOrOff(r('no-unmanaged-exceptions')), ...skipOpts(r('no-unmanaged-exceptions')) },
109
74
  noDirectApiInResolver: {
110
- mode: modeOrOff(r('angular-no-direct-api-in-resolver')),
111
- disableAllowed: opt(r('angular-no-direct-api-in-resolver'), 'disableAllowed'),
112
- ignoreModifiedUntilEpoch: opt(r('angular-no-direct-api-in-resolver'), 'ignoreModifiedUntilEpoch'),
75
+ mode: modeOrOff(r('angular-no-direct-api-in-resolver')), ...skipOpts(r('angular-no-direct-api-in-resolver')),
113
76
  enforcePaths: opt(r('angular-no-direct-api-in-resolver'), 'enforcePaths'),
114
77
  },
115
78
  noSymbolDiTokens: {
116
- mode: modeOrOff(r('no-symbol-di-tokens')),
117
- disableAllowed: opt(r('no-symbol-di-tokens'), 'disableAllowed'),
118
- ignoreModifiedUntilEpoch: opt(r('no-symbol-di-tokens'), 'ignoreModifiedUntilEpoch'),
79
+ mode: modeOrOff(r('no-symbol-di-tokens')), ...skipOpts(r('no-symbol-di-tokens')),
119
80
  allowedPaths: opt(r('no-symbol-di-tokens'), 'allowedPaths'),
120
81
  },
121
82
  };
@@ -1 +1 @@
1
- {"version":3,"file":"from-shared-config.js","sourceRoot":"","sources":["../../../../../packages/tooling/code-rules/src/from-shared-config.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Adapter: map @webpieces/rules-config ResolvedConfig -> legacy ValidateCodeOptions.\n *\n * We don't want to rewrite the 11 sub-executors in this PR, so this file\n * takes the shared webpieces.config.json entries (kebab-case rule names)\n * and reconstructs the camelCase ValidateCodeOptions shape the executor\n * already understands.\n *\n * Mapping of canonical kebab-case rule name -> ValidateCodeOptions field:\n * max-method-lines -> methodMaxLimit\n * max-file-lines -> fileMaxLimit\n * require-return-type -> requireReturnType\n * no-inline-type-literals -> noInlineTypeLiterals\n * no-any-unknown -> noAnyUnknown\n * no-implicit-any -> noImplicitAny\n * prisma-validate-dtos -> validateDtos\n * prisma-converter -> prismaConverter\n * no-destructure -> noDestructure\n * catch-error-pattern -> catchErrorPattern\n * no-unmanaged-exceptions -> noUnmanagedExceptions\n * angular-no-direct-api-in-resolver -> noDirectApiInResolver\n *\n * On/off is driven entirely by `mode`: a `mode:'OFF'` entry flows straight\n * through to the downstream executor, which short-circuits on it.\n */\n\nimport type { ResolvedConfig, ResolvedRuleConfig } from '@webpieces/rules-config';\nimport type { ValidateCodeOptions } from './validate-code-options';\n\n// webpieces-disable no-any-unknown -- coerces opaque option values pulled from JSON\nfunction opt<T>(rule: ResolvedRuleConfig | undefined, key: string): T | undefined {\n if (!rule) return undefined;\n const value = rule.options[key];\n if (value === undefined) return undefined;\n return value as T;\n}\n\nfunction modeOrOff<T extends string>(rule: ResolvedRuleConfig | undefined): T | undefined {\n if (!rule) return undefined;\n const mode = rule.options['mode'];\n return (mode as T) ?? undefined;\n}\n\nexport function toValidateCodeOptions(shared: ResolvedConfig): ValidateCodeOptions {\n const r = (name: string): ResolvedRuleConfig | undefined => shared.rules.get(name);\n\n return {\n methodMaxLimit: {\n limit: opt<number>(r('max-method-lines'), 'limit'),\n mode: modeOrOff(r('max-method-lines')),\n disableAllowed: opt<boolean>(r('max-method-lines'), 'disableAllowed'),\n ignoreModifiedUntilEpoch: opt<number>(r('max-method-lines'), 'ignoreModifiedUntilEpoch'),\n },\n fileMaxLimit: {\n limit: opt<number>(r('max-file-lines'), 'limit'),\n mode: modeOrOff(r('max-file-lines')),\n disableAllowed: opt<boolean>(r('max-file-lines'), 'disableAllowed'),\n ignoreModifiedUntilEpoch: opt<number>(r('max-file-lines'), 'ignoreModifiedUntilEpoch'),\n },\n requireReturnType: {\n mode: modeOrOff(r('require-return-type')),\n disableAllowed: opt<boolean>(r('require-return-type'), 'disableAllowed'),\n ignoreModifiedUntilEpoch: opt<number>(r('require-return-type'), 'ignoreModifiedUntilEpoch'),\n },\n noInlineTypeLiterals: {\n mode: modeOrOff(r('no-inline-type-literals')),\n disableAllowed: opt<boolean>(r('no-inline-type-literals'), 'disableAllowed'),\n ignoreModifiedUntilEpoch: opt<number>(r('no-inline-type-literals'), 'ignoreModifiedUntilEpoch'),\n },\n noAnyUnknown: {\n mode: modeOrOff(r('no-any-unknown')),\n disableAllowed: opt<boolean>(r('no-any-unknown'), 'disableAllowed'),\n ignoreModifiedUntilEpoch: opt<number>(r('no-any-unknown'), 'ignoreModifiedUntilEpoch'),\n },\n noImplicitAny: {\n mode: modeOrOff(r('no-implicit-any')),\n disableAllowed: opt<boolean>(r('no-implicit-any'), 'disableAllowed'),\n ignoreModifiedUntilEpoch: opt<number>(r('no-implicit-any'), 'ignoreModifiedUntilEpoch'),\n },\n validateDtos: {\n mode: modeOrOff(r('prisma-validate-dtos')),\n disableAllowed: opt<boolean>(r('prisma-validate-dtos'), 'disableAllowed'),\n prismaSchemaPath: opt<string>(r('prisma-validate-dtos'), 'prismaSchemaPath'),\n dtoSourcePaths: opt<string[]>(r('prisma-validate-dtos'), 'dtoSourcePaths'),\n ignoreModifiedUntilEpoch: opt<number>(r('prisma-validate-dtos'), 'ignoreModifiedUntilEpoch'),\n },\n prismaConverter: {\n mode: modeOrOff(r('prisma-converter')),\n disableAllowed: opt<boolean>(r('prisma-converter'), 'disableAllowed'),\n schemaPath: opt<string>(r('prisma-converter'), 'schemaPath'),\n convertersPaths: opt<string[]>(r('prisma-converter'), 'convertersPaths'),\n enforcePaths: opt<string[]>(r('prisma-converter'), 'enforcePaths'),\n ignoreModifiedUntilEpoch: opt<number>(r('prisma-converter'), 'ignoreModifiedUntilEpoch'),\n },\n noDestructure: {\n mode: modeOrOff(r('no-destructure')),\n disableAllowed: opt<boolean>(r('no-destructure'), 'disableAllowed'),\n ignoreModifiedUntilEpoch: opt<number>(r('no-destructure'), 'ignoreModifiedUntilEpoch'),\n },\n catchErrorPattern: {\n mode: modeOrOff(r('catch-error-pattern')),\n disableAllowed: opt<boolean>(r('catch-error-pattern'), 'disableAllowed'),\n ignoreModifiedUntilEpoch: opt<number>(r('catch-error-pattern'), 'ignoreModifiedUntilEpoch'),\n },\n noUnmanagedExceptions: {\n mode: modeOrOff(r('no-unmanaged-exceptions')),\n disableAllowed: opt<boolean>(r('no-unmanaged-exceptions'), 'disableAllowed'),\n ignoreModifiedUntilEpoch: opt<number>(r('no-unmanaged-exceptions'), 'ignoreModifiedUntilEpoch'),\n },\n noDirectApiInResolver: {\n mode: modeOrOff(r('angular-no-direct-api-in-resolver')),\n disableAllowed: opt<boolean>(r('angular-no-direct-api-in-resolver'), 'disableAllowed'),\n ignoreModifiedUntilEpoch: opt<number>(r('angular-no-direct-api-in-resolver'), 'ignoreModifiedUntilEpoch'),\n enforcePaths: opt<string[]>(r('angular-no-direct-api-in-resolver'), 'enforcePaths'),\n },\n noSymbolDiTokens: {\n mode: modeOrOff(r('no-symbol-di-tokens')),\n disableAllowed: opt<boolean>(r('no-symbol-di-tokens'), 'disableAllowed'),\n ignoreModifiedUntilEpoch: opt<number>(r('no-symbol-di-tokens'), 'ignoreModifiedUntilEpoch'),\n allowedPaths: opt<string[]>(r('no-symbol-di-tokens'), 'allowedPaths'),\n },\n };\n}\n"]}
1
+ {"version":3,"file":"from-shared-config.js","sourceRoot":"","sources":["../../../../../packages/tooling/code-rules/src/from-shared-config.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Adapter: map @webpieces/rules-config ResolvedConfig -> legacy ValidateCodeOptions.\n *\n * We don't want to rewrite the 11 sub-executors in this PR, so this file\n * takes the shared webpieces.config.json entries (kebab-case rule names)\n * and reconstructs the camelCase ValidateCodeOptions shape the executor\n * already understands.\n *\n * Mapping of canonical kebab-case rule name -> ValidateCodeOptions field:\n * max-method-lines -> methodMaxLimit\n * max-file-lines -> fileMaxLimit\n * require-return-type -> requireReturnType\n * no-inline-type-literals -> noInlineTypeLiterals\n * no-any-unknown -> noAnyUnknown\n * no-implicit-any -> noImplicitAny\n * prisma-validate-dtos -> validateDtos\n * prisma-converter -> prismaConverter\n * no-destructure -> noDestructure\n * catch-error-pattern -> catchErrorPattern\n * no-unmanaged-exceptions -> noUnmanagedExceptions\n * angular-no-direct-api-in-resolver -> noDirectApiInResolver\n *\n * On/off is driven entirely by `mode`: a `mode:'OFF'` entry flows straight\n * through to the downstream executor, which short-circuits on it.\n */\n\nimport type { ResolvedConfig, ResolvedRuleConfig } from '@webpieces/rules-config';\nimport type { ValidateCodeOptions } from './validate-code-options';\n\n// webpieces-disable no-any-unknown -- coerces opaque option values pulled from JSON\nfunction opt<T>(rule: ResolvedRuleConfig | undefined, key: string): T | undefined {\n if (!rule) return undefined;\n const value = rule.options[key];\n if (value === undefined) return undefined;\n return value as T;\n}\n\nfunction modeOrOff<T extends string>(rule: ResolvedRuleConfig | undefined): T | undefined {\n if (!rule) return undefined;\n const mode = rule.options['mode'];\n return (mode as T) ?? undefined;\n}\n\ninterface SkipOpts {\n disableAllowed: boolean | undefined;\n ignoreModifiedUntilEpoch: number | undefined;\n ignoreRuleWhileOnBranch: string | undefined;\n}\n\nfunction skipOpts(rule: ResolvedRuleConfig | undefined): SkipOpts {\n return {\n disableAllowed: opt<boolean>(rule, 'disableAllowed'),\n ignoreModifiedUntilEpoch: opt<number>(rule, 'ignoreModifiedUntilEpoch'),\n ignoreRuleWhileOnBranch: opt<string>(rule, 'ignoreRuleWhileOnBranch'),\n };\n}\n\nexport function toValidateCodeOptions(shared: ResolvedConfig): ValidateCodeOptions {\n const r = (name: string): ResolvedRuleConfig | undefined => shared.rules.get(name);\n\n return {\n methodMaxLimit: { mode: modeOrOff(r('max-method-lines')), ...skipOpts(r('max-method-lines')), limit: opt<number>(r('max-method-lines'), 'limit') },\n fileMaxLimit: { mode: modeOrOff(r('max-file-lines')), ...skipOpts(r('max-file-lines')), limit: opt<number>(r('max-file-lines'), 'limit') },\n requireReturnType: { mode: modeOrOff(r('require-return-type')), ...skipOpts(r('require-return-type')) },\n noInlineTypeLiterals: { mode: modeOrOff(r('no-inline-type-literals')), ...skipOpts(r('no-inline-type-literals')) },\n noAnyUnknown: { mode: modeOrOff(r('no-any-unknown')), ...skipOpts(r('no-any-unknown')) },\n noImplicitAny: { mode: modeOrOff(r('no-implicit-any')), ...skipOpts(r('no-implicit-any')) },\n validateDtos: {\n mode: modeOrOff(r('prisma-validate-dtos')), ...skipOpts(r('prisma-validate-dtos')),\n prismaSchemaPath: opt<string>(r('prisma-validate-dtos'), 'prismaSchemaPath'),\n dtoSourcePaths: opt<string[]>(r('prisma-validate-dtos'), 'dtoSourcePaths'),\n },\n prismaConverter: {\n mode: modeOrOff(r('prisma-converter')), ...skipOpts(r('prisma-converter')),\n schemaPath: opt<string>(r('prisma-converter'), 'schemaPath'),\n convertersPaths: opt<string[]>(r('prisma-converter'), 'convertersPaths'),\n enforcePaths: opt<string[]>(r('prisma-converter'), 'enforcePaths'),\n },\n noDestructure: { mode: modeOrOff(r('no-destructure')), ...skipOpts(r('no-destructure')) },\n catchErrorPattern: { mode: modeOrOff(r('catch-error-pattern')), ...skipOpts(r('catch-error-pattern')) },\n noUnmanagedExceptions: { mode: modeOrOff(r('no-unmanaged-exceptions')), ...skipOpts(r('no-unmanaged-exceptions')) },\n noDirectApiInResolver: {\n mode: modeOrOff(r('angular-no-direct-api-in-resolver')), ...skipOpts(r('angular-no-direct-api-in-resolver')),\n enforcePaths: opt<string[]>(r('angular-no-direct-api-in-resolver'), 'enforcePaths'),\n },\n noSymbolDiTokens: {\n mode: modeOrOff(r('no-symbol-di-tokens')), ...skipOpts(r('no-symbol-di-tokens')),\n allowedPaths: opt<string[]>(r('no-symbol-di-tokens'), 'allowedPaths'),\n },\n };\n}\n"]}
@@ -0,0 +1,6 @@
1
+ export interface SkipRuleResult {
2
+ skip: boolean;
3
+ reason?: string;
4
+ }
5
+ export declare function getCurrentBranch(): string;
6
+ export declare function shouldSkipRule(epoch: number | undefined, branchPattern: string | undefined): SkipRuleResult;
@@ -0,0 +1,40 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getCurrentBranch = getCurrentBranch;
4
+ exports.shouldSkipRule = shouldSkipRule;
5
+ const child_process_1 = require("child_process");
6
+ function getCurrentBranch() {
7
+ const envBranch = process.env['BRANCH_NAME'] ||
8
+ process.env['GIT_BRANCH'] ||
9
+ process.env['GITHUB_HEAD_REF'] ||
10
+ process.env['GITHUB_REF_NAME'] ||
11
+ process.env['CI_COMMIT_BRANCH'] ||
12
+ process.env['CIRCLE_BRANCH'];
13
+ if (envBranch)
14
+ return envBranch;
15
+ // eslint-disable-next-line @webpieces/no-unmanaged-exceptions
16
+ try {
17
+ return (0, child_process_1.execSync)('git rev-parse --abbrev-ref HEAD', { encoding: 'utf8' }).trim();
18
+ // webpieces-disable catch-error-pattern -- intentional swallow of git command failure; no useful error to surface
19
+ }
20
+ catch {
21
+ return '';
22
+ }
23
+ }
24
+ function shouldSkipRule(epoch, branchPattern) {
25
+ if (branchPattern) {
26
+ const current = getCurrentBranch();
27
+ if (current === branchPattern) {
28
+ return { skip: true, reason: `on branch "${branchPattern}"` };
29
+ }
30
+ }
31
+ if (epoch !== undefined) {
32
+ const nowSeconds = Date.now() / 1000;
33
+ if (nowSeconds < epoch) {
34
+ const expiresDate = new Date(epoch * 1000).toISOString().split('T')[0];
35
+ return { skip: true, reason: `ignoreModifiedUntilEpoch active, expires: ${expiresDate}` };
36
+ }
37
+ }
38
+ return { skip: false };
39
+ }
40
+ //# sourceMappingURL=resolve-mode.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolve-mode.js","sourceRoot":"","sources":["../../../../../packages/tooling/code-rules/src/resolve-mode.ts"],"names":[],"mappings":";;AAOA,4CAgBC;AAED,wCAkBC;AA3CD,iDAAyC;AAOzC,SAAgB,gBAAgB;IAC5B,MAAM,SAAS,GACX,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC;QAC1B,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC;QACzB,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC;QAC9B,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC;QAC9B,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC;QAC/B,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;IACjC,IAAI,SAAS;QAAE,OAAO,SAAS,CAAC;IAChC,8DAA8D;IAC9D,IAAI,CAAC;QACD,OAAO,IAAA,wBAAQ,EAAC,iCAAiC,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;QACpF,kHAAkH;IAClH,CAAC;IAAC,MAAM,CAAC;QACL,OAAO,EAAE,CAAC;IACd,CAAC;AACL,CAAC;AAED,SAAgB,cAAc,CAC1B,KAAyB,EACzB,aAAiC;IAEjC,IAAI,aAAa,EAAE,CAAC;QAChB,MAAM,OAAO,GAAG,gBAAgB,EAAE,CAAC;QACnC,IAAI,OAAO,KAAK,aAAa,EAAE,CAAC;YAC5B,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,cAAc,aAAa,GAAG,EAAE,CAAC;QAClE,CAAC;IACL,CAAC;IACD,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACtB,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC;QACrC,IAAI,UAAU,GAAG,KAAK,EAAE,CAAC;YACrB,MAAM,WAAW,GAAG,IAAI,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;YACvE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,6CAA6C,WAAW,EAAE,EAAE,CAAC;QAC9F,CAAC;IACL,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;AAC3B,CAAC","sourcesContent":["import { execSync } from 'child_process';\n\nexport interface SkipRuleResult {\n skip: boolean;\n reason?: string;\n}\n\nexport function getCurrentBranch(): string {\n const envBranch =\n process.env['BRANCH_NAME'] ||\n process.env['GIT_BRANCH'] ||\n process.env['GITHUB_HEAD_REF'] ||\n process.env['GITHUB_REF_NAME'] ||\n process.env['CI_COMMIT_BRANCH'] ||\n process.env['CIRCLE_BRANCH'];\n if (envBranch) return envBranch;\n // eslint-disable-next-line @webpieces/no-unmanaged-exceptions\n try {\n return execSync('git rev-parse --abbrev-ref HEAD', { encoding: 'utf8' }).trim();\n // webpieces-disable catch-error-pattern -- intentional swallow of git command failure; no useful error to surface\n } catch {\n return '';\n }\n}\n\nexport function shouldSkipRule(\n epoch: number | undefined,\n branchPattern: string | undefined\n): SkipRuleResult {\n if (branchPattern) {\n const current = getCurrentBranch();\n if (current === branchPattern) {\n return { skip: true, reason: `on branch \"${branchPattern}\"` };\n }\n }\n if (epoch !== undefined) {\n const nowSeconds = Date.now() / 1000;\n if (nowSeconds < epoch) {\n const expiresDate = new Date(epoch * 1000).toISOString().split('T')[0];\n return { skip: true, reason: `ignoreModifiedUntilEpoch active, expires: ${expiresDate}` };\n }\n }\n return { skip: false };\n}\n"]}
@@ -40,6 +40,7 @@ export interface ValidateCatchErrorPatternOptions {
40
40
  mode?: CatchErrorPatternMode;
41
41
  disableAllowed?: boolean;
42
42
  ignoreModifiedUntilEpoch?: number;
43
+ ignoreRuleWhileOnBranch?: string;
43
44
  }
44
45
  export interface ExecutorResult {
45
46
  success: boolean;
@@ -43,6 +43,7 @@ const child_process_1 = require("child_process");
43
43
  const fs = tslib_1.__importStar(require("fs"));
44
44
  const path = tslib_1.__importStar(require("path"));
45
45
  const ts = tslib_1.__importStar(require("typescript"));
46
+ const resolve_mode_1 = require("./resolve-mode");
46
47
  /**
47
48
  * Check if a file is a test file that should be skipped.
48
49
  */
@@ -459,21 +460,20 @@ function reportViolations(violations, mode, disableAllowed) {
459
460
  /**
460
461
  * Resolve mode considering ignoreModifiedUntilEpoch override.
461
462
  */
462
- function resolveMode(normalMode, epoch) {
463
- if (epoch === undefined || normalMode === 'OFF') {
463
+ function resolveMode(normalMode, epoch, branchPattern) {
464
+ if (normalMode === 'OFF') {
464
465
  return normalMode;
465
466
  }
466
- const nowSeconds = Date.now() / 1000;
467
- if (nowSeconds < epoch) {
468
- const expiresDate = new Date(epoch * 1000).toISOString().split('T')[0];
469
- console.log(`\n\u23ed\ufe0f Skipping catch-error-pattern validation (ignoreModifiedUntilEpoch active, expires: ${expiresDate})`);
467
+ const skip = (0, resolve_mode_1.shouldSkipRule)(epoch, branchPattern);
468
+ if (skip.skip) {
469
+ console.log(`\n\u23ed\ufe0f Skipping catch-error-pattern validation (${skip.reason})`);
470
470
  console.log('');
471
471
  return 'OFF';
472
472
  }
473
473
  return normalMode;
474
474
  }
475
475
  async function runValidator(options, workspaceRoot) {
476
- const mode = resolveMode(options.mode ?? 'OFF', options.ignoreModifiedUntilEpoch);
476
+ const mode = resolveMode(options.mode ?? 'OFF', options.ignoreModifiedUntilEpoch, options.ignoreRuleWhileOnBranch);
477
477
  const disableAllowed = options.disableAllowed ?? true;
478
478
  if (mode === 'OFF') {
479
479
  console.log('\n\u23ed\ufe0f Skipping catch-error-pattern validation (mode: OFF)');
@@ -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 * - MODIFIED_CODE: Flag catch violations on changed lines (lines in diff hunks)\n * - 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 { execSync } from 'child_process';\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport * as ts from 'typescript';\n\nexport type CatchErrorPatternMode = 'OFF' | 'MODIFIED_CODE' | 'MODIFIED_FILES';\n\nexport interface ValidateCatchErrorPatternOptions {\n mode?: CatchErrorPatternMode;\n disableAllowed?: boolean;\n ignoreModifiedUntilEpoch?: number;\n}\n\nexport interface ExecutorResult {\n success: boolean;\n}\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 file is a test file that should be skipped.\n */\nfunction isTestFile(filePath: string): boolean {\n return filePath.includes('.spec.ts') ||\n filePath.includes('.test.ts') ||\n filePath.includes('__tests__/');\n}\n\n/**\n * Get changed TypeScript files between base and head.\n * Excludes test files.\n */\n// webpieces-disable max-lines-new-methods -- Git command handling with untracked files requires multiple code paths\nfunction getChangedTypeScriptFiles(workspaceRoot: string, base: string, head?: string): string[] {\n // eslint-disable-next-line @webpieces/no-unmanaged-exceptions\n try {\n const diffTarget = head ? `${base} ${head}` : base;\n const output = execSync(`git diff --name-only ${diffTarget} -- '*.ts' '*.tsx'`, {\n cwd: workspaceRoot,\n encoding: 'utf-8',\n });\n const changedFiles = output\n .trim()\n .split('\\n')\n .filter((f) => f && !isTestFile(f));\n\n if (!head) {\n // eslint-disable-next-line @webpieces/no-unmanaged-exceptions\n try {\n const untrackedOutput = execSync(`git ls-files --others --exclude-standard '*.ts' '*.tsx'`, {\n cwd: workspaceRoot,\n encoding: 'utf-8',\n });\n const untrackedFiles = untrackedOutput\n .trim()\n .split('\\n')\n .filter((f) => f && !isTestFile(f));\n const allFiles = new Set([...changedFiles, ...untrackedFiles]);\n return Array.from(allFiles);\n // webpieces-disable catch-error-pattern -- intentional swallow of git command failure\n } catch {\n return changedFiles;\n }\n }\n\n return changedFiles;\n // webpieces-disable catch-error-pattern -- intentional swallow of git command failure\n } catch {\n return [];\n }\n}\n\n/**\n * Get the diff content for a specific file.\n */\nfunction getFileDiff(workspaceRoot: string, file: string, base: string, head?: string): string {\n // eslint-disable-next-line @webpieces/no-unmanaged-exceptions\n try {\n const diffTarget = head ? `${base} ${head}` : base;\n const diff = execSync(`git diff ${diffTarget} -- \"${file}\"`, {\n cwd: workspaceRoot,\n encoding: 'utf-8',\n });\n\n if (!diff && !head) {\n const fullPath = path.join(workspaceRoot, file);\n if (fs.existsSync(fullPath)) {\n const isUntracked = execSync(`git ls-files --others --exclude-standard \"${file}\"`, {\n cwd: workspaceRoot,\n encoding: 'utf-8',\n }).trim();\n\n if (isUntracked) {\n const content = fs.readFileSync(fullPath, 'utf-8');\n const lines = content.split('\\n');\n return lines.map((line) => `+${line}`).join('\\n');\n }\n }\n }\n\n return diff;\n // webpieces-disable catch-error-pattern -- intentional swallow of git command failure\n } catch {\n return '';\n }\n}\n\n/**\n * Parse diff to extract changed line numbers (additions only).\n */\nfunction getChangedLineNumbers(diffContent: string): Set<number> {\n const changedLines = new Set<number>();\n const lines = diffContent.split('\\n');\n let currentLine = 0;\n\n for (const line of lines) {\n const hunkMatch = line.match(/^@@ -\\d+(?:,\\d+)? \\+(\\d+)(?:,\\d+)? @@/);\n if (hunkMatch) {\n currentLine = parseInt(hunkMatch[1], 10);\n continue;\n }\n\n if (line.startsWith('+') && !line.startsWith('+++')) {\n changedLines.add(currentLine);\n currentLine++;\n } else if (line.startsWith('-') && !line.startsWith('---')) {\n // Deletions don't increment line number\n } else {\n currentLine++;\n }\n }\n\n return changedLines;\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 (line.includes('webpieces-disable') && line.includes('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 blockText.includes('webpieces-disable') && blockText.includes('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 * 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 * 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 * Auto-detect the base branch by finding the merge-base with origin/main.\n */\nfunction detectBase(workspaceRoot: string): string | null {\n // eslint-disable-next-line @webpieces/no-unmanaged-exceptions\n try {\n const mergeBase = execSync('git merge-base HEAD origin/main', {\n cwd: workspaceRoot,\n encoding: 'utf-8',\n stdio: ['pipe', 'pipe', 'pipe'],\n }).trim();\n\n if (mergeBase) {\n return mergeBase;\n }\n // webpieces-disable catch-error-pattern -- intentional swallow of git command failure\n } catch {\n // eslint-disable-next-line @webpieces/no-unmanaged-exceptions\n try {\n const mergeBase = execSync('git merge-base HEAD main', {\n cwd: workspaceRoot,\n encoding: 'utf-8',\n stdio: ['pipe', 'pipe', 'pipe'],\n }).trim();\n\n if (mergeBase) {\n return mergeBase;\n }\n // webpieces-disable catch-error-pattern -- intentional swallow of git command failure\n } catch {\n // Ignore\n }\n }\n return null;\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: CatchErrorPatternMode, 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: CatchErrorPatternMode, epoch: number | undefined): CatchErrorPatternMode {\n if (epoch === undefined || normalMode === 'OFF') {\n return normalMode;\n }\n const nowSeconds = Date.now() / 1000;\n if (nowSeconds < epoch) {\n const expiresDate = new Date(epoch * 1000).toISOString().split('T')[0];\n console.log(`\\n\\u23ed\\ufe0f Skipping catch-error-pattern validation (ignoreModifiedUntilEpoch active, expires: ${expiresDate})`);\n console.log('');\n return 'OFF';\n }\n return normalMode;\n}\n\nexport default async function runValidator(\n options: ValidateCatchErrorPatternOptions,\n workspaceRoot: string\n): Promise<ExecutorResult> {\n const mode: CatchErrorPatternMode = resolveMode(options.mode ?? 'OFF', options.ignoreModifiedUntilEpoch);\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 = getChangedTypeScriptFiles(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 === 'MODIFIED_CODE') {\n violations = findViolationsForModifiedCode(workspaceRoot, changedFiles, base, head, disableAllowed);\n } else if (mode === '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"]}
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 * - MODIFIED_CODE: Flag catch violations on changed lines (lines in diff hunks)\n * - 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 { execSync } from 'child_process';\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport * as ts from 'typescript';\nimport { shouldSkipRule } from './resolve-mode';\n\nexport type CatchErrorPatternMode = 'OFF' | 'MODIFIED_CODE' | 'MODIFIED_FILES';\n\nexport interface ValidateCatchErrorPatternOptions {\n mode?: CatchErrorPatternMode;\n disableAllowed?: boolean;\n ignoreModifiedUntilEpoch?: number;\n ignoreRuleWhileOnBranch?: string;\n}\n\nexport interface ExecutorResult {\n success: boolean;\n}\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 file is a test file that should be skipped.\n */\nfunction isTestFile(filePath: string): boolean {\n return filePath.includes('.spec.ts') ||\n filePath.includes('.test.ts') ||\n filePath.includes('__tests__/');\n}\n\n/**\n * Get changed TypeScript files between base and head.\n * Excludes test files.\n */\n// webpieces-disable max-lines-new-methods -- Git command handling with untracked files requires multiple code paths\nfunction getChangedTypeScriptFiles(workspaceRoot: string, base: string, head?: string): string[] {\n // eslint-disable-next-line @webpieces/no-unmanaged-exceptions\n try {\n const diffTarget = head ? `${base} ${head}` : base;\n const output = execSync(`git diff --name-only ${diffTarget} -- '*.ts' '*.tsx'`, {\n cwd: workspaceRoot,\n encoding: 'utf-8',\n });\n const changedFiles = output\n .trim()\n .split('\\n')\n .filter((f) => f && !isTestFile(f));\n\n if (!head) {\n // eslint-disable-next-line @webpieces/no-unmanaged-exceptions\n try {\n const untrackedOutput = execSync(`git ls-files --others --exclude-standard '*.ts' '*.tsx'`, {\n cwd: workspaceRoot,\n encoding: 'utf-8',\n });\n const untrackedFiles = untrackedOutput\n .trim()\n .split('\\n')\n .filter((f) => f && !isTestFile(f));\n const allFiles = new Set([...changedFiles, ...untrackedFiles]);\n return Array.from(allFiles);\n // webpieces-disable catch-error-pattern -- intentional swallow of git command failure\n } catch {\n return changedFiles;\n }\n }\n\n return changedFiles;\n // webpieces-disable catch-error-pattern -- intentional swallow of git command failure\n } catch {\n return [];\n }\n}\n\n/**\n * Get the diff content for a specific file.\n */\nfunction getFileDiff(workspaceRoot: string, file: string, base: string, head?: string): string {\n // eslint-disable-next-line @webpieces/no-unmanaged-exceptions\n try {\n const diffTarget = head ? `${base} ${head}` : base;\n const diff = execSync(`git diff ${diffTarget} -- \"${file}\"`, {\n cwd: workspaceRoot,\n encoding: 'utf-8',\n });\n\n if (!diff && !head) {\n const fullPath = path.join(workspaceRoot, file);\n if (fs.existsSync(fullPath)) {\n const isUntracked = execSync(`git ls-files --others --exclude-standard \"${file}\"`, {\n cwd: workspaceRoot,\n encoding: 'utf-8',\n }).trim();\n\n if (isUntracked) {\n const content = fs.readFileSync(fullPath, 'utf-8');\n const lines = content.split('\\n');\n return lines.map((line) => `+${line}`).join('\\n');\n }\n }\n }\n\n return diff;\n // webpieces-disable catch-error-pattern -- intentional swallow of git command failure\n } catch {\n return '';\n }\n}\n\n/**\n * Parse diff to extract changed line numbers (additions only).\n */\nfunction getChangedLineNumbers(diffContent: string): Set<number> {\n const changedLines = new Set<number>();\n const lines = diffContent.split('\\n');\n let currentLine = 0;\n\n for (const line of lines) {\n const hunkMatch = line.match(/^@@ -\\d+(?:,\\d+)? \\+(\\d+)(?:,\\d+)? @@/);\n if (hunkMatch) {\n currentLine = parseInt(hunkMatch[1], 10);\n continue;\n }\n\n if (line.startsWith('+') && !line.startsWith('+++')) {\n changedLines.add(currentLine);\n currentLine++;\n } else if (line.startsWith('-') && !line.startsWith('---')) {\n // Deletions don't increment line number\n } else {\n currentLine++;\n }\n }\n\n return changedLines;\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 (line.includes('webpieces-disable') && line.includes('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 blockText.includes('webpieces-disable') && blockText.includes('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 * 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 * 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 * Auto-detect the base branch by finding the merge-base with origin/main.\n */\nfunction detectBase(workspaceRoot: string): string | null {\n // eslint-disable-next-line @webpieces/no-unmanaged-exceptions\n try {\n const mergeBase = execSync('git merge-base HEAD origin/main', {\n cwd: workspaceRoot,\n encoding: 'utf-8',\n stdio: ['pipe', 'pipe', 'pipe'],\n }).trim();\n\n if (mergeBase) {\n return mergeBase;\n }\n // webpieces-disable catch-error-pattern -- intentional swallow of git command failure\n } catch {\n // eslint-disable-next-line @webpieces/no-unmanaged-exceptions\n try {\n const mergeBase = execSync('git merge-base HEAD main', {\n cwd: workspaceRoot,\n encoding: 'utf-8',\n stdio: ['pipe', 'pipe', 'pipe'],\n }).trim();\n\n if (mergeBase) {\n return mergeBase;\n }\n // webpieces-disable catch-error-pattern -- intentional swallow of git command failure\n } catch {\n // Ignore\n }\n }\n return null;\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: CatchErrorPatternMode, 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: CatchErrorPatternMode, epoch: number | undefined, branchPattern: string | undefined): CatchErrorPatternMode {\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\nexport default async function runValidator(\n options: ValidateCatchErrorPatternOptions,\n workspaceRoot: string\n): Promise<ExecutorResult> {\n const mode: CatchErrorPatternMode = 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 = getChangedTypeScriptFiles(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 === 'MODIFIED_CODE') {\n violations = findViolationsForModifiedCode(workspaceRoot, changedFiles, base, head, disableAllowed);\n } else if (mode === '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"]}
@@ -28,32 +28,38 @@ export interface MethodMaxLimitConfig {
28
28
  mode?: MethodMaxLimitMode;
29
29
  disableAllowed?: boolean;
30
30
  ignoreModifiedUntilEpoch?: number;
31
+ ignoreRuleWhileOnBranch?: string;
31
32
  }
32
33
  export interface FileMaxLimitConfig {
33
34
  limit?: number;
34
35
  mode?: FileMaxLimitMode;
35
36
  disableAllowed?: boolean;
36
37
  ignoreModifiedUntilEpoch?: number;
38
+ ignoreRuleWhileOnBranch?: string;
37
39
  }
38
40
  export interface RequireReturnTypeConfig {
39
41
  mode?: ReturnTypeMode;
40
42
  disableAllowed?: boolean;
41
43
  ignoreModifiedUntilEpoch?: number;
44
+ ignoreRuleWhileOnBranch?: string;
42
45
  }
43
46
  export interface NoInlineTypeLiteralsConfig {
44
47
  mode?: NoInlineTypesMode;
45
48
  disableAllowed?: boolean;
46
49
  ignoreModifiedUntilEpoch?: number;
50
+ ignoreRuleWhileOnBranch?: string;
47
51
  }
48
52
  export interface NoAnyUnknownConfig {
49
53
  mode?: NoAnyUnknownMode;
50
54
  disableAllowed?: boolean;
51
55
  ignoreModifiedUntilEpoch?: number;
56
+ ignoreRuleWhileOnBranch?: string;
52
57
  }
53
58
  export interface NoImplicitAnyConfig {
54
59
  mode?: NoImplicitAnyMode;
55
60
  disableAllowed?: boolean;
56
61
  ignoreModifiedUntilEpoch?: number;
62
+ ignoreRuleWhileOnBranch?: string;
57
63
  }
58
64
  export interface ValidateDtosConfig {
59
65
  mode?: ValidateDtosMode;
@@ -61,6 +67,7 @@ export interface ValidateDtosConfig {
61
67
  prismaSchemaPath?: string;
62
68
  dtoSourcePaths?: string[];
63
69
  ignoreModifiedUntilEpoch?: number;
70
+ ignoreRuleWhileOnBranch?: string;
64
71
  }
65
72
  export interface PrismaConverterConfig {
66
73
  mode?: PrismaConverterMode;
@@ -69,32 +76,38 @@ export interface PrismaConverterConfig {
69
76
  convertersPaths?: string[];
70
77
  enforcePaths?: string[];
71
78
  ignoreModifiedUntilEpoch?: number;
79
+ ignoreRuleWhileOnBranch?: string;
72
80
  }
73
81
  export interface NoDestructureConfig {
74
82
  mode?: NoDestructureMode;
75
83
  disableAllowed?: boolean;
76
84
  ignoreModifiedUntilEpoch?: number;
85
+ ignoreRuleWhileOnBranch?: string;
77
86
  }
78
87
  export interface CatchErrorPatternConfig {
79
88
  mode?: CatchErrorPatternMode;
80
89
  disableAllowed?: boolean;
81
90
  ignoreModifiedUntilEpoch?: number;
91
+ ignoreRuleWhileOnBranch?: string;
82
92
  }
83
93
  export interface NoUnmanagedExceptionsConfig {
84
94
  mode?: NoUnmanagedExceptionsMode;
85
95
  disableAllowed?: boolean;
86
96
  ignoreModifiedUntilEpoch?: number;
97
+ ignoreRuleWhileOnBranch?: string;
87
98
  }
88
99
  export interface NoDirectApiResolverConfig {
89
100
  mode?: NoDirectApiResolverMode;
90
101
  disableAllowed?: boolean;
91
102
  ignoreModifiedUntilEpoch?: number;
103
+ ignoreRuleWhileOnBranch?: string;
92
104
  enforcePaths?: string[];
93
105
  }
94
106
  export interface NoSymbolDiTokensConfig {
95
107
  mode?: NoSymbolDiTokensMode;
96
108
  disableAllowed?: boolean;
97
109
  ignoreModifiedUntilEpoch?: number;
110
+ ignoreRuleWhileOnBranch?: string;
98
111
  allowedPaths?: string[];
99
112
  }
100
113
  export interface ValidateCodeOptions {
@@ -1 +1 @@
1
- {"version":3,"file":"validate-code-options.js","sourceRoot":"","sources":["../../../../../packages/tooling/code-rules/src/validate-code-options.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;GAUG","sourcesContent":["/**\n * ValidateCodeOptions and its sub-config types.\n *\n * This is a leaf module: it owns the option/config shape shared by `validate-code.ts`\n * (which consumes the options) and `from-shared-config.ts` (which produces them). Keeping\n * the type here breaks the otherwise-circular import between those two files — a type that\n * two modules share must not live inside one of them.\n *\n * It imports only the per-rule `*Mode` unions from the individual rule executors (leaves),\n * and re-exports them so consumers have a single import site.\n */\n\nimport type { ReturnTypeMode } from './validate-return-types';\nimport type { NoInlineTypesMode } from './validate-no-inline-types';\nimport type { NoAnyUnknownMode } from './validate-no-any-unknown';\nimport type { NoImplicitAnyMode } from './validate-no-implicit-any';\nimport type { ValidateDtosMode } from './validate-dtos';\nimport type { PrismaConverterMode } from './validate-prisma-converters';\nimport type { NoDestructureMode } from './validate-no-destructure';\nimport type { CatchErrorPatternMode } from './validate-catch-error-pattern';\nimport type { NoUnmanagedExceptionsMode } from './validate-no-unmanaged-exceptions';\nimport type { NoDirectApiResolverMode } from './validate-no-direct-api-resolver';\nimport type { NoSymbolDiTokensMode } from './validate-no-symbol-di-tokens';\n\nexport type {\n ReturnTypeMode,\n NoInlineTypesMode,\n NoAnyUnknownMode,\n NoImplicitAnyMode,\n ValidateDtosMode,\n PrismaConverterMode,\n NoDestructureMode,\n CatchErrorPatternMode,\n NoUnmanagedExceptionsMode,\n NoDirectApiResolverMode,\n NoSymbolDiTokensMode,\n};\n\nexport type MethodMaxLimitMode = 'OFF' | 'NEW_METHODS' | 'NEW_AND_MODIFIED_METHODS' | 'MODIFIED_FILES';\nexport type FileMaxLimitMode = 'OFF' | 'MODIFIED_FILES';\n\nexport interface MethodMaxLimitConfig {\n limit?: number;\n mode?: MethodMaxLimitMode;\n disableAllowed?: boolean;\n ignoreModifiedUntilEpoch?: number;\n}\n\nexport interface FileMaxLimitConfig {\n limit?: number;\n mode?: FileMaxLimitMode;\n disableAllowed?: boolean;\n ignoreModifiedUntilEpoch?: number;\n}\n\nexport interface RequireReturnTypeConfig {\n mode?: ReturnTypeMode;\n disableAllowed?: boolean;\n ignoreModifiedUntilEpoch?: number;\n}\n\nexport interface NoInlineTypeLiteralsConfig {\n mode?: NoInlineTypesMode;\n disableAllowed?: boolean;\n ignoreModifiedUntilEpoch?: number;\n}\n\nexport interface NoAnyUnknownConfig {\n mode?: NoAnyUnknownMode;\n disableAllowed?: boolean;\n ignoreModifiedUntilEpoch?: number;\n}\n\nexport interface NoImplicitAnyConfig {\n mode?: NoImplicitAnyMode;\n disableAllowed?: boolean;\n ignoreModifiedUntilEpoch?: number;\n}\n\nexport interface ValidateDtosConfig {\n mode?: ValidateDtosMode;\n disableAllowed?: boolean;\n prismaSchemaPath?: string;\n dtoSourcePaths?: string[];\n ignoreModifiedUntilEpoch?: number;\n}\n\nexport interface PrismaConverterConfig {\n mode?: PrismaConverterMode;\n disableAllowed?: boolean;\n schemaPath?: string;\n convertersPaths?: string[];\n enforcePaths?: string[];\n ignoreModifiedUntilEpoch?: number;\n}\n\nexport interface NoDestructureConfig {\n mode?: NoDestructureMode;\n disableAllowed?: boolean;\n ignoreModifiedUntilEpoch?: number;\n}\n\nexport interface CatchErrorPatternConfig {\n mode?: CatchErrorPatternMode;\n disableAllowed?: boolean;\n ignoreModifiedUntilEpoch?: number;\n}\n\nexport interface NoUnmanagedExceptionsConfig {\n mode?: NoUnmanagedExceptionsMode;\n disableAllowed?: boolean;\n ignoreModifiedUntilEpoch?: number;\n}\n\nexport interface NoDirectApiResolverConfig {\n mode?: NoDirectApiResolverMode;\n disableAllowed?: boolean;\n ignoreModifiedUntilEpoch?: number;\n enforcePaths?: string[];\n}\n\nexport interface NoSymbolDiTokensConfig {\n mode?: NoSymbolDiTokensMode;\n disableAllowed?: boolean;\n ignoreModifiedUntilEpoch?: number;\n allowedPaths?: string[];\n}\n\nexport interface ValidateCodeOptions {\n methodMaxLimit?: MethodMaxLimitConfig;\n fileMaxLimit?: FileMaxLimitConfig;\n requireReturnType?: RequireReturnTypeConfig;\n noInlineTypeLiterals?: NoInlineTypeLiteralsConfig;\n noAnyUnknown?: NoAnyUnknownConfig;\n noImplicitAny?: NoImplicitAnyConfig;\n validateDtos?: ValidateDtosConfig;\n prismaConverter?: PrismaConverterConfig;\n noDestructure?: NoDestructureConfig;\n catchErrorPattern?: CatchErrorPatternConfig;\n noUnmanagedExceptions?: NoUnmanagedExceptionsConfig;\n noDirectApiInResolver?: NoDirectApiResolverConfig;\n noSymbolDiTokens?: NoSymbolDiTokensConfig;\n}\n"]}
1
+ {"version":3,"file":"validate-code-options.js","sourceRoot":"","sources":["../../../../../packages/tooling/code-rules/src/validate-code-options.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;GAUG","sourcesContent":["/**\n * ValidateCodeOptions and its sub-config types.\n *\n * This is a leaf module: it owns the option/config shape shared by `validate-code.ts`\n * (which consumes the options) and `from-shared-config.ts` (which produces them). Keeping\n * the type here breaks the otherwise-circular import between those two files — a type that\n * two modules share must not live inside one of them.\n *\n * It imports only the per-rule `*Mode` unions from the individual rule executors (leaves),\n * and re-exports them so consumers have a single import site.\n */\n\nimport type { ReturnTypeMode } from './validate-return-types';\nimport type { NoInlineTypesMode } from './validate-no-inline-types';\nimport type { NoAnyUnknownMode } from './validate-no-any-unknown';\nimport type { NoImplicitAnyMode } from './validate-no-implicit-any';\nimport type { ValidateDtosMode } from './validate-dtos';\nimport type { PrismaConverterMode } from './validate-prisma-converters';\nimport type { NoDestructureMode } from './validate-no-destructure';\nimport type { CatchErrorPatternMode } from './validate-catch-error-pattern';\nimport type { NoUnmanagedExceptionsMode } from './validate-no-unmanaged-exceptions';\nimport type { NoDirectApiResolverMode } from './validate-no-direct-api-resolver';\nimport type { NoSymbolDiTokensMode } from './validate-no-symbol-di-tokens';\n\nexport type {\n ReturnTypeMode,\n NoInlineTypesMode,\n NoAnyUnknownMode,\n NoImplicitAnyMode,\n ValidateDtosMode,\n PrismaConverterMode,\n NoDestructureMode,\n CatchErrorPatternMode,\n NoUnmanagedExceptionsMode,\n NoDirectApiResolverMode,\n NoSymbolDiTokensMode,\n};\n\nexport type MethodMaxLimitMode = 'OFF' | 'NEW_METHODS' | 'NEW_AND_MODIFIED_METHODS' | 'MODIFIED_FILES';\nexport type FileMaxLimitMode = 'OFF' | 'MODIFIED_FILES';\n\nexport interface MethodMaxLimitConfig {\n limit?: number;\n mode?: MethodMaxLimitMode;\n disableAllowed?: boolean;\n ignoreModifiedUntilEpoch?: number;\n ignoreRuleWhileOnBranch?: string;\n}\n\nexport interface FileMaxLimitConfig {\n limit?: number;\n mode?: FileMaxLimitMode;\n disableAllowed?: boolean;\n ignoreModifiedUntilEpoch?: number;\n ignoreRuleWhileOnBranch?: string;\n}\n\nexport interface RequireReturnTypeConfig {\n mode?: ReturnTypeMode;\n disableAllowed?: boolean;\n ignoreModifiedUntilEpoch?: number;\n ignoreRuleWhileOnBranch?: string;\n}\n\nexport interface NoInlineTypeLiteralsConfig {\n mode?: NoInlineTypesMode;\n disableAllowed?: boolean;\n ignoreModifiedUntilEpoch?: number;\n ignoreRuleWhileOnBranch?: string;\n}\n\nexport interface NoAnyUnknownConfig {\n mode?: NoAnyUnknownMode;\n disableAllowed?: boolean;\n ignoreModifiedUntilEpoch?: number;\n ignoreRuleWhileOnBranch?: string;\n}\n\nexport interface NoImplicitAnyConfig {\n mode?: NoImplicitAnyMode;\n disableAllowed?: boolean;\n ignoreModifiedUntilEpoch?: number;\n ignoreRuleWhileOnBranch?: string;\n}\n\nexport interface ValidateDtosConfig {\n mode?: ValidateDtosMode;\n disableAllowed?: boolean;\n prismaSchemaPath?: string;\n dtoSourcePaths?: string[];\n ignoreModifiedUntilEpoch?: number;\n ignoreRuleWhileOnBranch?: string;\n}\n\nexport interface PrismaConverterConfig {\n mode?: PrismaConverterMode;\n disableAllowed?: boolean;\n schemaPath?: string;\n convertersPaths?: string[];\n enforcePaths?: string[];\n ignoreModifiedUntilEpoch?: number;\n ignoreRuleWhileOnBranch?: string;\n}\n\nexport interface NoDestructureConfig {\n mode?: NoDestructureMode;\n disableAllowed?: boolean;\n ignoreModifiedUntilEpoch?: number;\n ignoreRuleWhileOnBranch?: string;\n}\n\nexport interface CatchErrorPatternConfig {\n mode?: CatchErrorPatternMode;\n disableAllowed?: boolean;\n ignoreModifiedUntilEpoch?: number;\n ignoreRuleWhileOnBranch?: string;\n}\n\nexport interface NoUnmanagedExceptionsConfig {\n mode?: NoUnmanagedExceptionsMode;\n disableAllowed?: boolean;\n ignoreModifiedUntilEpoch?: number;\n ignoreRuleWhileOnBranch?: string;\n}\n\nexport interface NoDirectApiResolverConfig {\n mode?: NoDirectApiResolverMode;\n disableAllowed?: boolean;\n ignoreModifiedUntilEpoch?: number;\n ignoreRuleWhileOnBranch?: string;\n enforcePaths?: string[];\n}\n\nexport interface NoSymbolDiTokensConfig {\n mode?: NoSymbolDiTokensMode;\n disableAllowed?: boolean;\n ignoreModifiedUntilEpoch?: number;\n ignoreRuleWhileOnBranch?: string;\n allowedPaths?: string[];\n}\n\nexport interface ValidateCodeOptions {\n methodMaxLimit?: MethodMaxLimitConfig;\n fileMaxLimit?: FileMaxLimitConfig;\n requireReturnType?: RequireReturnTypeConfig;\n noInlineTypeLiterals?: NoInlineTypeLiteralsConfig;\n noAnyUnknown?: NoAnyUnknownConfig;\n noImplicitAny?: NoImplicitAnyConfig;\n validateDtos?: ValidateDtosConfig;\n prismaConverter?: PrismaConverterConfig;\n noDestructure?: NoDestructureConfig;\n catchErrorPattern?: CatchErrorPatternConfig;\n noUnmanagedExceptions?: NoUnmanagedExceptionsConfig;\n noDirectApiInResolver?: NoDirectApiResolverConfig;\n noSymbolDiTokens?: NoSymbolDiTokensConfig;\n}\n"]}