@webpieces/code-rules 0.0.1 → 0.2.113

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 (63) hide show
  1. package/package.json +4 -3
  2. package/src/cli.d.ts +1 -0
  3. package/src/cli.js +19 -0
  4. package/src/cli.js.map +1 -0
  5. package/src/diff-utils.d.ts +24 -0
  6. package/src/{diff-utils.ts → diff-utils.js} +30 -38
  7. package/src/diff-utils.js.map +1 -0
  8. package/src/from-shared-config.d.ts +28 -0
  9. package/src/from-shared-config.js +119 -0
  10. package/src/from-shared-config.js.map +1 -0
  11. package/src/index.js +33 -0
  12. package/src/index.js.map +1 -0
  13. package/src/validate-catch-error-pattern.d.ts +47 -0
  14. package/src/{validate-catch-error-pattern.ts → validate-catch-error-pattern.js} +74 -195
  15. package/src/validate-catch-error-pattern.js.map +1 -0
  16. package/src/validate-code.d.ts +98 -0
  17. package/src/{validate-code.ts → validate-code.js} +65 -259
  18. package/src/validate-code.js.map +1 -0
  19. package/src/validate-dtos.d.ts +41 -0
  20. package/src/{validate-dtos.ts → validate-dtos.js} +88 -215
  21. package/src/validate-dtos.js.map +1 -0
  22. package/src/validate-modified-files.d.ts +24 -0
  23. package/src/{validate-modified-files.ts → validate-modified-files.js} +46 -115
  24. package/src/validate-modified-files.js.map +1 -0
  25. package/src/validate-modified-methods.d.ts +30 -0
  26. package/src/{validate-modified-methods.ts → validate-modified-methods.js} +94 -196
  27. package/src/validate-modified-methods.js.map +1 -0
  28. package/src/validate-new-methods.d.ts +27 -0
  29. package/src/{validate-new-methods.ts → validate-new-methods.js} +63 -133
  30. package/src/validate-new-methods.js.map +1 -0
  31. package/src/validate-no-any-unknown.d.ts +41 -0
  32. package/src/{validate-no-any-unknown.ts → validate-no-any-unknown.js} +69 -146
  33. package/src/validate-no-any-unknown.js.map +1 -0
  34. package/src/validate-no-destructure.d.ts +51 -0
  35. package/src/{validate-no-destructure.ts → validate-no-destructure.js} +80 -166
  36. package/src/validate-no-destructure.js.map +1 -0
  37. package/src/validate-no-direct-api-resolver.d.ts +46 -0
  38. package/src/{validate-no-direct-api-resolver.ts → validate-no-direct-api-resolver.js} +112 -211
  39. package/src/validate-no-direct-api-resolver.js.map +1 -0
  40. package/src/validate-no-implicit-any.d.ts +36 -0
  41. package/src/{validate-no-implicit-any.ts → validate-no-implicit-any.js} +94 -141
  42. package/src/validate-no-implicit-any.js.map +1 -0
  43. package/src/validate-no-inline-types.d.ts +90 -0
  44. package/src/{validate-no-inline-types.ts → validate-no-inline-types.js} +93 -198
  45. package/src/validate-no-inline-types.js.map +1 -0
  46. package/src/validate-no-unmanaged-exceptions.d.ts +43 -0
  47. package/src/{validate-no-unmanaged-exceptions.ts → validate-no-unmanaged-exceptions.js} +71 -140
  48. package/src/validate-no-unmanaged-exceptions.js.map +1 -0
  49. package/src/validate-prisma-converters.d.ts +59 -0
  50. package/src/{validate-prisma-converters.ts → validate-prisma-converters.js} +120 -307
  51. package/src/validate-prisma-converters.js.map +1 -0
  52. package/src/validate-return-types.d.ts +28 -0
  53. package/src/{validate-return-types.ts → validate-return-types.js} +84 -168
  54. package/src/validate-return-types.js.map +1 -0
  55. package/LICENSE +0 -373
  56. package/jest.config.ts +0 -20
  57. package/project.json +0 -22
  58. package/src/cli.ts +0 -17
  59. package/src/from-shared-config.ts +0 -118
  60. package/tsconfig.json +0 -22
  61. package/tsconfig.lib.json +0 -10
  62. package/tsconfig.spec.json +0 -14
  63. /package/src/{index.ts → index.d.ts} +0 -0
@@ -1,3 +1,4 @@
1
+ "use strict";
1
2
  /**
2
3
  * Validate Catch Error Pattern Executor
3
4
  *
@@ -35,57 +36,31 @@
35
36
  * // webpieces-disable catch-error-pattern -- [your justification]
36
37
  * } catch (err: unknown) {
37
38
  */
38
-
39
- import { execSync } from 'child_process';
40
- import * as fs from 'fs';
41
- import * as path from 'path';
42
- import * as ts from 'typescript';
43
-
44
- export type CatchErrorPatternMode = 'OFF' | 'MODIFIED_CODE' | 'MODIFIED_FILES';
45
-
46
- export interface ValidateCatchErrorPatternOptions {
47
- mode?: CatchErrorPatternMode;
48
- disableAllowed?: boolean;
49
- ignoreModifiedUntilEpoch?: number;
50
- }
51
-
52
- export interface ExecutorResult {
53
- success: boolean;
54
- }
55
-
56
- interface CatchViolation {
57
- file: string;
58
- line: number;
59
- message: string;
60
- context: string;
61
- }
62
-
63
- interface CatchViolationInfo {
64
- line: number;
65
- message: string;
66
- context: string;
67
- hasDisableComment: boolean;
68
- }
69
-
39
+ Object.defineProperty(exports, "__esModule", { value: true });
40
+ exports.default = runValidator;
41
+ const tslib_1 = require("tslib");
42
+ const child_process_1 = require("child_process");
43
+ const fs = tslib_1.__importStar(require("fs"));
44
+ const path = tslib_1.__importStar(require("path"));
45
+ const ts = tslib_1.__importStar(require("typescript"));
70
46
  /**
71
47
  * Check if a file is a test file that should be skipped.
72
48
  */
73
- function isTestFile(filePath: string): boolean {
49
+ function isTestFile(filePath) {
74
50
  return filePath.includes('.spec.ts') ||
75
51
  filePath.includes('.test.ts') ||
76
52
  filePath.includes('__tests__/');
77
53
  }
78
-
79
54
  /**
80
55
  * Get changed TypeScript files between base and head.
81
56
  * Excludes test files.
82
57
  */
83
58
  // webpieces-disable max-lines-new-methods -- Git command handling with untracked files requires multiple code paths
84
- function getChangedTypeScriptFiles(workspaceRoot: string, base: string, head?: string): string[] {
59
+ function getChangedTypeScriptFiles(workspaceRoot, base, head) {
85
60
  // eslint-disable-next-line @webpieces/no-unmanaged-exceptions
86
61
  try {
87
62
  const diffTarget = head ? `${base} ${head}` : base;
88
- const output = execSync(`git diff --name-only ${diffTarget} -- '*.ts' '*.tsx'`, {
63
+ const output = (0, child_process_1.execSync)(`git diff --name-only ${diffTarget} -- '*.ts' '*.tsx'`, {
89
64
  cwd: workspaceRoot,
90
65
  encoding: 'utf-8',
91
66
  });
@@ -93,11 +68,10 @@ function getChangedTypeScriptFiles(workspaceRoot: string, base: string, head?: s
93
68
  .trim()
94
69
  .split('\n')
95
70
  .filter((f) => f && !isTestFile(f));
96
-
97
71
  if (!head) {
98
72
  // eslint-disable-next-line @webpieces/no-unmanaged-exceptions
99
73
  try {
100
- const untrackedOutput = execSync(`git ls-files --others --exclude-standard '*.ts' '*.tsx'`, {
74
+ const untrackedOutput = (0, child_process_1.execSync)(`git ls-files --others --exclude-standard '*.ts' '*.tsx'`, {
101
75
  cwd: workspaceRoot,
102
76
  encoding: 'utf-8',
103
77
  });
@@ -107,39 +81,37 @@ function getChangedTypeScriptFiles(workspaceRoot: string, base: string, head?: s
107
81
  .filter((f) => f && !isTestFile(f));
108
82
  const allFiles = new Set([...changedFiles, ...untrackedFiles]);
109
83
  return Array.from(allFiles);
110
- // webpieces-disable catch-error-pattern -- intentional swallow of git command failure
111
- } catch {
84
+ // webpieces-disable catch-error-pattern -- intentional swallow of git command failure
85
+ }
86
+ catch {
112
87
  return changedFiles;
113
88
  }
114
89
  }
115
-
116
90
  return changedFiles;
117
- // webpieces-disable catch-error-pattern -- intentional swallow of git command failure
118
- } catch {
91
+ // webpieces-disable catch-error-pattern -- intentional swallow of git command failure
92
+ }
93
+ catch {
119
94
  return [];
120
95
  }
121
96
  }
122
-
123
97
  /**
124
98
  * Get the diff content for a specific file.
125
99
  */
126
- function getFileDiff(workspaceRoot: string, file: string, base: string, head?: string): string {
100
+ function getFileDiff(workspaceRoot, file, base, head) {
127
101
  // eslint-disable-next-line @webpieces/no-unmanaged-exceptions
128
102
  try {
129
103
  const diffTarget = head ? `${base} ${head}` : base;
130
- const diff = execSync(`git diff ${diffTarget} -- "${file}"`, {
104
+ const diff = (0, child_process_1.execSync)(`git diff ${diffTarget} -- "${file}"`, {
131
105
  cwd: workspaceRoot,
132
106
  encoding: 'utf-8',
133
107
  });
134
-
135
108
  if (!diff && !head) {
136
109
  const fullPath = path.join(workspaceRoot, file);
137
110
  if (fs.existsSync(fullPath)) {
138
- const isUntracked = execSync(`git ls-files --others --exclude-standard "${file}"`, {
111
+ const isUntracked = (0, child_process_1.execSync)(`git ls-files --others --exclude-standard "${file}"`, {
139
112
  cwd: workspaceRoot,
140
113
  encoding: 'utf-8',
141
114
  }).trim();
142
-
143
115
  if (isUntracked) {
144
116
  const content = fs.readFileSync(fullPath, 'utf-8');
145
117
  const lines = content.split('\n');
@@ -147,47 +119,44 @@ function getFileDiff(workspaceRoot: string, file: string, base: string, head?: s
147
119
  }
148
120
  }
149
121
  }
150
-
151
122
  return diff;
152
- // webpieces-disable catch-error-pattern -- intentional swallow of git command failure
153
- } catch {
123
+ // webpieces-disable catch-error-pattern -- intentional swallow of git command failure
124
+ }
125
+ catch {
154
126
  return '';
155
127
  }
156
128
  }
157
-
158
129
  /**
159
130
  * Parse diff to extract changed line numbers (additions only).
160
131
  */
161
- function getChangedLineNumbers(diffContent: string): Set<number> {
162
- const changedLines = new Set<number>();
132
+ function getChangedLineNumbers(diffContent) {
133
+ const changedLines = new Set();
163
134
  const lines = diffContent.split('\n');
164
135
  let currentLine = 0;
165
-
166
136
  for (const line of lines) {
167
137
  const hunkMatch = line.match(/^@@ -\d+(?:,\d+)? \+(\d+)(?:,\d+)? @@/);
168
138
  if (hunkMatch) {
169
139
  currentLine = parseInt(hunkMatch[1], 10);
170
140
  continue;
171
141
  }
172
-
173
142
  if (line.startsWith('+') && !line.startsWith('+++')) {
174
143
  changedLines.add(currentLine);
175
144
  currentLine++;
176
- } else if (line.startsWith('-') && !line.startsWith('---')) {
145
+ }
146
+ else if (line.startsWith('-') && !line.startsWith('---')) {
177
147
  // Deletions don't increment line number
178
- } else {
148
+ }
149
+ else {
179
150
  currentLine++;
180
151
  }
181
152
  }
182
-
183
153
  return changedLines;
184
154
  }
185
-
186
155
  /**
187
156
  * Check if a line contains a disable comment for catch-error-pattern.
188
157
  * Recognizes both webpieces-disable and eslint-disable-next-line @webpieces/ formats.
189
158
  */
190
- function hasDisableComment(lines: string[], lineNumber: number): boolean {
159
+ function hasDisableComment(lines, lineNumber) {
191
160
  const startCheck = Math.max(0, lineNumber - 5);
192
161
  for (let i = lineNumber - 2; i >= startCheck; i--) {
193
162
  const line = lines[i]?.trim() ?? '';
@@ -203,56 +172,37 @@ function hasDisableComment(lines: string[], lineNumber: number): boolean {
203
172
  }
204
173
  return false;
205
174
  }
206
-
207
175
  /**
208
176
  * Check if the catch block contains a disable comment for catch-error-pattern.
209
177
  */
210
- function hasBlockLevelDisable(sourceText: string, blockStart: number, blockEnd: number): boolean {
178
+ function hasBlockLevelDisable(sourceText, blockStart, blockEnd) {
211
179
  const blockText = sourceText.substring(blockStart, blockEnd);
212
180
  return blockText.includes('webpieces-disable') && blockText.includes('catch-error-pattern') ||
213
181
  blockText.includes('@webpieces/catch-error-pattern');
214
182
  }
215
-
216
183
  /**
217
184
  * Check if the catch block body text contains the commented-out ignore pattern.
218
185
  */
219
- function hasIgnoreComment(
220
- sourceText: string,
221
- blockStart: number,
222
- blockEnd: number,
223
- expectedVarName: string,
224
- actualParamName: string,
225
- ): boolean {
186
+ function hasIgnoreComment(sourceText, blockStart, blockEnd, expectedVarName, actualParamName) {
226
187
  const blockText = sourceText.substring(blockStart, blockEnd);
227
- const ignorePattern = new RegExp(
228
- `//\\s*const\\s+${expectedVarName}\\s*=\\s*toError\\(${actualParamName}\\)`,
229
- );
188
+ const ignorePattern = new RegExp(`//\\s*const\\s+${expectedVarName}\\s*=\\s*toError\\(${actualParamName}\\)`);
230
189
  return ignorePattern.test(blockText);
231
190
  }
232
-
233
191
  /**
234
192
  * Validate a single CatchClause node.
235
193
  */
236
194
  // webpieces-disable max-lines-new-methods -- AST validation with multiple check paths for param name, type, and toError
237
- function validateCatchClause(
238
- node: ts.CatchClause,
239
- sourceFile: ts.SourceFile,
240
- fileLines: string[],
241
- depth: number,
242
- disableAllowed: boolean,
243
- ): CatchViolationInfo[] {
244
- const violations: CatchViolationInfo[] = [];
195
+ function validateCatchClause(node, sourceFile, fileLines, depth, disableAllowed) {
196
+ const violations = [];
245
197
  const suffix = depth === 1 ? '' : String(depth);
246
198
  const expectedParam = 'err' + suffix;
247
199
  const expectedVar = 'error' + suffix;
248
-
249
200
  const catchLine = sourceFile.getLineAndCharacterOfPosition(node.getStart(sourceFile)).line + 1;
250
201
  const catchContext = fileLines[catchLine - 1]?.trim() ?? '';
251
202
  const blockStart = node.block.getStart(sourceFile);
252
203
  const blockEnd = node.block.getEnd();
253
204
  const disabled = hasDisableComment(fileLines, catchLine) ||
254
205
  hasBlockLevelDisable(sourceFile.text, blockStart, blockEnd);
255
-
256
206
  const varDecl = node.variableDeclaration;
257
207
  if (!varDecl) {
258
208
  violations.push({
@@ -262,9 +212,7 @@ function validateCatchClause(
262
212
  });
263
213
  return violations;
264
214
  }
265
-
266
215
  const actualParam = ts.isIdentifier(varDecl.name) ? varDecl.name.text : expectedParam;
267
-
268
216
  // Check parameter name
269
217
  if (ts.isIdentifier(varDecl.name) && varDecl.name.text !== expectedParam) {
270
218
  violations.push({
@@ -273,7 +221,6 @@ function validateCatchClause(
273
221
  hasDisableComment: resolveDisable(disabled, disableAllowed),
274
222
  });
275
223
  }
276
-
277
224
  // Check type annotation is : unknown
278
225
  if (!varDecl.type || varDecl.type.kind !== ts.SyntaxKind.UnknownKeyword) {
279
226
  violations.push({
@@ -282,12 +229,10 @@ function validateCatchClause(
282
229
  hasDisableComment: resolveDisable(disabled, disableAllowed),
283
230
  });
284
231
  }
285
-
286
232
  // Check for commented-out ignore pattern
287
233
  if (hasIgnoreComment(sourceFile.text, blockStart, blockEnd, expectedVar, actualParam)) {
288
234
  return violations;
289
235
  }
290
-
291
236
  // Check first statement is const error = toError(err)
292
237
  if (node.block.statements.length === 0) {
293
238
  violations.push({
@@ -297,40 +242,26 @@ function validateCatchClause(
297
242
  });
298
243
  return violations;
299
244
  }
300
-
301
245
  const firstStmt = node.block.statements[0];
302
246
  const toErrorViolation = validateToErrorStatement(firstStmt, sourceFile, fileLines, expectedParam, expectedVar, actualParam, disabled, disableAllowed);
303
247
  if (toErrorViolation) {
304
248
  violations.push(toErrorViolation);
305
249
  }
306
-
307
250
  return violations;
308
251
  }
309
-
310
- function resolveDisable(disabled: boolean, disableAllowed: boolean): boolean {
252
+ function resolveDisable(disabled, disableAllowed) {
311
253
  if (!disableAllowed && disabled) {
312
254
  return false;
313
255
  }
314
256
  return disabled;
315
257
  }
316
-
317
258
  /**
318
259
  * Validate that the first statement is `const error = toError(err);`
319
260
  */
320
261
  // webpieces-disable max-lines-new-methods -- Deep AST check for variable declaration with toError call expression
321
- function validateToErrorStatement(
322
- stmt: ts.Statement,
323
- sourceFile: ts.SourceFile,
324
- fileLines: string[],
325
- expectedParam: string,
326
- expectedVar: string,
327
- actualParam: string,
328
- disabled: boolean,
329
- disableAllowed: boolean,
330
- ): CatchViolationInfo | null {
262
+ function validateToErrorStatement(stmt, sourceFile, fileLines, expectedParam, expectedVar, actualParam, disabled, disableAllowed) {
331
263
  const stmtLine = sourceFile.getLineAndCharacterOfPosition(stmt.getStart(sourceFile)).line + 1;
332
264
  const stmtContext = fileLines[stmtLine - 1]?.trim() ?? '';
333
-
334
265
  if (!ts.isVariableStatement(stmt)) {
335
266
  return {
336
267
  line: stmtLine,
@@ -339,7 +270,6 @@ function validateToErrorStatement(
339
270
  hasDisableComment: resolveDisable(disabled, disableAllowed),
340
271
  };
341
272
  }
342
-
343
273
  const declarations = stmt.declarationList.declarations;
344
274
  if (declarations.length === 0) {
345
275
  return {
@@ -349,9 +279,7 @@ function validateToErrorStatement(
349
279
  hasDisableComment: resolveDisable(disabled, disableAllowed),
350
280
  };
351
281
  }
352
-
353
282
  const decl = declarations[0];
354
-
355
283
  // Check variable name
356
284
  if (ts.isIdentifier(decl.name) && decl.name.text !== expectedVar) {
357
285
  return {
@@ -361,7 +289,6 @@ function validateToErrorStatement(
361
289
  hasDisableComment: resolveDisable(disabled, disableAllowed),
362
290
  };
363
291
  }
364
-
365
292
  // Check initializer is toError(actualParam)
366
293
  const init = decl.initializer;
367
294
  if (!init || !ts.isCallExpression(init)) {
@@ -372,7 +299,6 @@ function validateToErrorStatement(
372
299
  hasDisableComment: resolveDisable(disabled, disableAllowed),
373
300
  };
374
301
  }
375
-
376
302
  if (!ts.isIdentifier(init.expression) || init.expression.text !== 'toError') {
377
303
  return {
378
304
  line: stmtLine,
@@ -381,7 +307,6 @@ function validateToErrorStatement(
381
307
  hasDisableComment: resolveDisable(disabled, disableAllowed),
382
308
  };
383
309
  }
384
-
385
310
  // Check argument
386
311
  const args = init.arguments;
387
312
  if (args.length !== 1 || !ts.isIdentifier(args[0]) || args[0].text !== actualParam) {
@@ -392,29 +317,21 @@ function validateToErrorStatement(
392
317
  hasDisableComment: resolveDisable(disabled, disableAllowed),
393
318
  };
394
319
  }
395
-
396
320
  return null;
397
321
  }
398
-
399
322
  /**
400
323
  * Find all catch pattern violations in a file using AST.
401
324
  */
402
- function findCatchViolationsInFile(
403
- filePath: string,
404
- workspaceRoot: string,
405
- disableAllowed: boolean,
406
- ): CatchViolationInfo[] {
325
+ function findCatchViolationsInFile(filePath, workspaceRoot, disableAllowed) {
407
326
  const fullPath = path.join(workspaceRoot, filePath);
408
- if (!fs.existsSync(fullPath)) return [];
409
-
327
+ if (!fs.existsSync(fullPath))
328
+ return [];
410
329
  const content = fs.readFileSync(fullPath, 'utf-8');
411
330
  const fileLines = content.split('\n');
412
331
  const sourceFile = ts.createSourceFile(filePath, content, ts.ScriptTarget.Latest, true);
413
-
414
- const violations: CatchViolationInfo[] = [];
332
+ const violations = [];
415
333
  let catchDepth = 0;
416
-
417
- function visit(node: ts.Node): void {
334
+ function visit(node) {
418
335
  if (ts.isCatchClause(node)) {
419
336
  catchDepth++;
420
337
  const clauseViolations = validateCatchClause(node, sourceFile, fileLines, catchDepth, disableAllowed);
@@ -425,105 +342,85 @@ function findCatchViolationsInFile(
425
342
  }
426
343
  ts.forEachChild(node, visit);
427
344
  }
428
-
429
345
  visit(sourceFile);
430
346
  return violations;
431
347
  }
432
-
433
348
  /**
434
349
  * MODIFIED_CODE mode: Flag violations on changed lines.
435
350
  */
436
- function findViolationsForModifiedCode(
437
- workspaceRoot: string,
438
- changedFiles: string[],
439
- base: string,
440
- head: string | undefined,
441
- disableAllowed: boolean,
442
- ): CatchViolation[] {
443
- const violations: CatchViolation[] = [];
444
-
351
+ function findViolationsForModifiedCode(workspaceRoot, changedFiles, base, head, disableAllowed) {
352
+ const violations = [];
445
353
  for (const file of changedFiles) {
446
354
  const diff = getFileDiff(workspaceRoot, file, base, head);
447
355
  const changedLines = getChangedLineNumbers(diff);
448
-
449
- if (changedLines.size === 0) continue;
450
-
356
+ if (changedLines.size === 0)
357
+ continue;
451
358
  const allViolations = findCatchViolationsInFile(file, workspaceRoot, disableAllowed);
452
-
453
359
  for (const v of allViolations) {
454
- if (disableAllowed && v.hasDisableComment) continue;
455
- if (!changedLines.has(v.line)) continue;
456
-
360
+ if (disableAllowed && v.hasDisableComment)
361
+ continue;
362
+ if (!changedLines.has(v.line))
363
+ continue;
457
364
  violations.push({ file, line: v.line, message: v.message, context: v.context });
458
365
  }
459
366
  }
460
-
461
367
  return violations;
462
368
  }
463
-
464
369
  /**
465
370
  * MODIFIED_FILES mode: Flag ALL violations in modified files.
466
371
  */
467
- function findViolationsForModifiedFiles(
468
- workspaceRoot: string,
469
- changedFiles: string[],
470
- disableAllowed: boolean,
471
- ): CatchViolation[] {
472
- const violations: CatchViolation[] = [];
473
-
372
+ function findViolationsForModifiedFiles(workspaceRoot, changedFiles, disableAllowed) {
373
+ const violations = [];
474
374
  for (const file of changedFiles) {
475
375
  const allViolations = findCatchViolationsInFile(file, workspaceRoot, disableAllowed);
476
-
477
376
  for (const v of allViolations) {
478
- if (disableAllowed && v.hasDisableComment) continue;
377
+ if (disableAllowed && v.hasDisableComment)
378
+ continue;
479
379
  violations.push({ file, line: v.line, message: v.message, context: v.context });
480
380
  }
481
381
  }
482
-
483
382
  return violations;
484
383
  }
485
-
486
384
  /**
487
385
  * Auto-detect the base branch by finding the merge-base with origin/main.
488
386
  */
489
- function detectBase(workspaceRoot: string): string | null {
387
+ function detectBase(workspaceRoot) {
490
388
  // eslint-disable-next-line @webpieces/no-unmanaged-exceptions
491
389
  try {
492
- const mergeBase = execSync('git merge-base HEAD origin/main', {
390
+ const mergeBase = (0, child_process_1.execSync)('git merge-base HEAD origin/main', {
493
391
  cwd: workspaceRoot,
494
392
  encoding: 'utf-8',
495
393
  stdio: ['pipe', 'pipe', 'pipe'],
496
394
  }).trim();
497
-
498
395
  if (mergeBase) {
499
396
  return mergeBase;
500
397
  }
501
- // webpieces-disable catch-error-pattern -- intentional swallow of git command failure
502
- } catch {
398
+ // webpieces-disable catch-error-pattern -- intentional swallow of git command failure
399
+ }
400
+ catch {
503
401
  // eslint-disable-next-line @webpieces/no-unmanaged-exceptions
504
402
  try {
505
- const mergeBase = execSync('git merge-base HEAD main', {
403
+ const mergeBase = (0, child_process_1.execSync)('git merge-base HEAD main', {
506
404
  cwd: workspaceRoot,
507
405
  encoding: 'utf-8',
508
406
  stdio: ['pipe', 'pipe', 'pipe'],
509
407
  }).trim();
510
-
511
408
  if (mergeBase) {
512
409
  return mergeBase;
513
410
  }
514
- // webpieces-disable catch-error-pattern -- intentional swallow of git command failure
515
- } catch {
411
+ // webpieces-disable catch-error-pattern -- intentional swallow of git command failure
412
+ }
413
+ catch {
516
414
  // Ignore
517
415
  }
518
416
  }
519
417
  return null;
520
418
  }
521
-
522
419
  /**
523
420
  * Report violations to console.
524
421
  */
525
422
  // webpieces-disable max-lines-new-methods -- Console output with pattern examples and escape hatch
526
- function reportViolations(violations: CatchViolation[], mode: CatchErrorPatternMode, disableAllowed: boolean): void {
423
+ function reportViolations(violations, mode, disableAllowed) {
527
424
  console.error('');
528
425
  console.error('\u274c Catch blocks must follow the standardized error handling pattern!');
529
426
  console.error('');
@@ -541,18 +438,17 @@ function reportViolations(violations: CatchViolation[], mode: CatchErrorPatternM
541
438
  console.error('');
542
439
  console.error(' For nested catches: err2/error2, err3/error3, etc.');
543
440
  console.error('');
544
-
545
441
  for (const v of violations) {
546
442
  console.error(` \u274c ${v.file}:${v.line}`);
547
443
  console.error(` ${v.message}`);
548
444
  console.error(` ${v.context}`);
549
445
  }
550
446
  console.error('');
551
-
552
447
  if (disableAllowed) {
553
448
  console.error(' Escape hatch (use sparingly):');
554
449
  console.error(' // webpieces-disable catch-error-pattern -- [your reason]');
555
- } else {
450
+ }
451
+ else {
556
452
  console.error(' Escape hatch: DISABLED (disableAllowed: false)');
557
453
  console.error(' Disable comments are ignored. Fix the catch block directly.');
558
454
  }
@@ -560,11 +456,10 @@ function reportViolations(violations: CatchViolation[], mode: CatchErrorPatternM
560
456
  console.error(` Current mode: ${mode}`);
561
457
  console.error('');
562
458
  }
563
-
564
459
  /**
565
460
  * Resolve mode considering ignoreModifiedUntilEpoch override.
566
461
  */
567
- function resolveMode(normalMode: CatchErrorPatternMode, epoch: number | undefined): CatchErrorPatternMode {
462
+ function resolveMode(normalMode, epoch) {
568
463
  if (epoch === undefined || normalMode === 'OFF') {
569
464
  return normalMode;
570
465
  }
@@ -577,63 +472,47 @@ function resolveMode(normalMode: CatchErrorPatternMode, epoch: number | undefine
577
472
  }
578
473
  return normalMode;
579
474
  }
580
-
581
- export default async function runValidator(
582
- options: ValidateCatchErrorPatternOptions,
583
- workspaceRoot: string
584
- ): Promise<ExecutorResult> {
585
- const mode: CatchErrorPatternMode = resolveMode(options.mode ?? 'OFF', options.ignoreModifiedUntilEpoch);
475
+ async function runValidator(options, workspaceRoot) {
476
+ const mode = resolveMode(options.mode ?? 'OFF', options.ignoreModifiedUntilEpoch);
586
477
  const disableAllowed = options.disableAllowed ?? true;
587
-
588
478
  if (mode === 'OFF') {
589
479
  console.log('\n\u23ed\ufe0f Skipping catch-error-pattern validation (mode: OFF)');
590
480
  console.log('');
591
481
  return { success: true };
592
482
  }
593
-
594
483
  console.log('\n\ud83d\udccf Validating Catch Error Pattern\n');
595
484
  console.log(` Mode: ${mode}`);
596
-
597
485
  let base = process.env['NX_BASE'];
598
486
  const head = process.env['NX_HEAD'];
599
-
600
487
  if (!base) {
601
488
  base = detectBase(workspaceRoot) ?? undefined;
602
-
603
489
  if (!base) {
604
490
  console.log('\n\u23ed\ufe0f Skipping catch-error-pattern validation (could not detect base branch)');
605
491
  console.log('');
606
492
  return { success: true };
607
493
  }
608
494
  }
609
-
610
495
  console.log(` Base: ${base}`);
611
496
  console.log(` Head: ${head ?? 'working tree (includes uncommitted changes)'}`);
612
497
  console.log('');
613
-
614
498
  const changedFiles = getChangedTypeScriptFiles(workspaceRoot, base, head);
615
-
616
499
  if (changedFiles.length === 0) {
617
500
  console.log('\u2705 No TypeScript files changed');
618
501
  return { success: true };
619
502
  }
620
-
621
503
  console.log(`\ud83d\udcc2 Checking ${changedFiles.length} changed file(s)...`);
622
-
623
- let violations: CatchViolation[] = [];
624
-
504
+ let violations = [];
625
505
  if (mode === 'MODIFIED_CODE') {
626
506
  violations = findViolationsForModifiedCode(workspaceRoot, changedFiles, base, head, disableAllowed);
627
- } else if (mode === 'MODIFIED_FILES') {
507
+ }
508
+ else if (mode === 'MODIFIED_FILES') {
628
509
  violations = findViolationsForModifiedFiles(workspaceRoot, changedFiles, disableAllowed);
629
510
  }
630
-
631
511
  if (violations.length === 0) {
632
512
  console.log('\u2705 No catch error pattern violations found');
633
513
  return { success: true };
634
514
  }
635
-
636
515
  reportViolations(violations, mode, disableAllowed);
637
-
638
516
  return { success: false };
639
517
  }
518
+ //# sourceMappingURL=validate-catch-error-pattern.js.map