@webpieces/code-rules 0.0.1 → 0.2.114
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.
- package/package.json +4 -3
- package/src/cli.d.ts +1 -0
- package/src/cli.js +19 -0
- package/src/cli.js.map +1 -0
- package/src/diff-utils.d.ts +24 -0
- package/src/{diff-utils.ts → diff-utils.js} +30 -38
- package/src/diff-utils.js.map +1 -0
- package/src/from-shared-config.d.ts +28 -0
- package/src/from-shared-config.js +119 -0
- package/src/from-shared-config.js.map +1 -0
- package/src/index.js +33 -0
- package/src/index.js.map +1 -0
- package/src/validate-catch-error-pattern.d.ts +47 -0
- package/src/{validate-catch-error-pattern.ts → validate-catch-error-pattern.js} +74 -195
- package/src/validate-catch-error-pattern.js.map +1 -0
- package/src/validate-code.d.ts +98 -0
- package/src/{validate-code.ts → validate-code.js} +65 -259
- package/src/validate-code.js.map +1 -0
- package/src/validate-dtos.d.ts +41 -0
- package/src/{validate-dtos.ts → validate-dtos.js} +88 -215
- package/src/validate-dtos.js.map +1 -0
- package/src/validate-modified-files.d.ts +24 -0
- package/src/{validate-modified-files.ts → validate-modified-files.js} +46 -115
- package/src/validate-modified-files.js.map +1 -0
- package/src/validate-modified-methods.d.ts +30 -0
- package/src/{validate-modified-methods.ts → validate-modified-methods.js} +94 -196
- package/src/validate-modified-methods.js.map +1 -0
- package/src/validate-new-methods.d.ts +27 -0
- package/src/{validate-new-methods.ts → validate-new-methods.js} +63 -133
- package/src/validate-new-methods.js.map +1 -0
- package/src/validate-no-any-unknown.d.ts +41 -0
- package/src/{validate-no-any-unknown.ts → validate-no-any-unknown.js} +69 -146
- package/src/validate-no-any-unknown.js.map +1 -0
- package/src/validate-no-destructure.d.ts +51 -0
- package/src/{validate-no-destructure.ts → validate-no-destructure.js} +80 -166
- package/src/validate-no-destructure.js.map +1 -0
- package/src/validate-no-direct-api-resolver.d.ts +46 -0
- package/src/{validate-no-direct-api-resolver.ts → validate-no-direct-api-resolver.js} +112 -211
- package/src/validate-no-direct-api-resolver.js.map +1 -0
- package/src/validate-no-implicit-any.d.ts +36 -0
- package/src/{validate-no-implicit-any.ts → validate-no-implicit-any.js} +94 -141
- package/src/validate-no-implicit-any.js.map +1 -0
- package/src/validate-no-inline-types.d.ts +90 -0
- package/src/{validate-no-inline-types.ts → validate-no-inline-types.js} +93 -198
- package/src/validate-no-inline-types.js.map +1 -0
- package/src/validate-no-unmanaged-exceptions.d.ts +43 -0
- package/src/{validate-no-unmanaged-exceptions.ts → validate-no-unmanaged-exceptions.js} +71 -140
- package/src/validate-no-unmanaged-exceptions.js.map +1 -0
- package/src/validate-prisma-converters.d.ts +59 -0
- package/src/{validate-prisma-converters.ts → validate-prisma-converters.js} +120 -307
- package/src/validate-prisma-converters.js.map +1 -0
- package/src/validate-return-types.d.ts +28 -0
- package/src/{validate-return-types.ts → validate-return-types.js} +84 -168
- package/src/validate-return-types.js.map +1 -0
- package/LICENSE +0 -373
- package/jest.config.ts +0 -20
- package/project.json +0 -22
- package/src/cli.ts +0 -17
- package/src/from-shared-config.ts +0 -118
- package/tsconfig.json +0 -22
- package/tsconfig.lib.json +0 -10
- package/tsconfig.spec.json +0 -14
- /package/src/{index.ts → index.d.ts} +0 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@webpieces/code-rules",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.114",
|
|
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",
|
|
@@ -15,9 +15,10 @@
|
|
|
15
15
|
"directory": "packages/tooling/code-rules"
|
|
16
16
|
},
|
|
17
17
|
"dependencies": {
|
|
18
|
-
"@webpieces/rules-config": "0.
|
|
18
|
+
"@webpieces/rules-config": "0.2.114"
|
|
19
19
|
},
|
|
20
20
|
"publishConfig": {
|
|
21
21
|
"access": "public"
|
|
22
|
-
}
|
|
22
|
+
},
|
|
23
|
+
"types": "./src/index.d.ts"
|
|
23
24
|
}
|
package/src/cli.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/src/cli.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const tslib_1 = require("tslib");
|
|
4
|
+
const rules_config_1 = require("@webpieces/rules-config");
|
|
5
|
+
const from_shared_config_1 = require("./from-shared-config");
|
|
6
|
+
const validate_code_1 = tslib_1.__importDefault(require("./validate-code"));
|
|
7
|
+
async function main() {
|
|
8
|
+
const workspaceRoot = process.cwd();
|
|
9
|
+
const shared = (0, rules_config_1.loadConfig)(workspaceRoot);
|
|
10
|
+
if (!shared.configPath) {
|
|
11
|
+
console.error('No webpieces.config.json found');
|
|
12
|
+
process.exit(1);
|
|
13
|
+
}
|
|
14
|
+
const options = (0, from_shared_config_1.toValidateCodeOptions)(shared);
|
|
15
|
+
const result = await (0, validate_code_1.default)(options, workspaceRoot);
|
|
16
|
+
process.exit(result.success ? 0 : 1);
|
|
17
|
+
}
|
|
18
|
+
main();
|
|
19
|
+
//# sourceMappingURL=cli.js.map
|
package/src/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../../../../../packages/tooling/code-rules/src/cli.ts"],"names":[],"mappings":";;;AAAA,0DAAqD;AACrD,6DAA6D;AAC7D,4EAA8C;AAE9C,KAAK,UAAU,IAAI;IACf,MAAM,aAAa,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IACpC,MAAM,MAAM,GAAG,IAAA,yBAAU,EAAC,aAAa,CAAC,CAAC;IACzC,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC;QACrB,OAAO,CAAC,KAAK,CAAC,gCAAgC,CAAC,CAAC;QAChD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACpB,CAAC;IACD,MAAM,OAAO,GAAG,IAAA,0CAAqB,EAAC,MAAM,CAAC,CAAC;IAC9C,MAAM,MAAM,GAAG,MAAM,IAAA,uBAAe,EAAC,OAAO,EAAE,aAAa,CAAC,CAAC;IAC7D,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACzC,CAAC;AAED,IAAI,EAAE,CAAC","sourcesContent":["import { loadConfig } from '@webpieces/rules-config';\nimport { toValidateCodeOptions } from './from-shared-config';\nimport runValidateCode from './validate-code';\n\nasync function main(): Promise<void> {\n const workspaceRoot = process.cwd();\n const shared = loadConfig(workspaceRoot);\n if (!shared.configPath) {\n console.error('No webpieces.config.json found');\n process.exit(1);\n }\n const options = toValidateCodeOptions(shared);\n const result = await runValidateCode(options, workspaceRoot);\n process.exit(result.success ? 0 : 1);\n}\n\nmain();\n"]}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared diff utility functions for code-rules validators.
|
|
3
|
+
* These are used by multiple validators for git diff parsing and line-level detection.
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Get the diff content for a specific file.
|
|
7
|
+
*/
|
|
8
|
+
export declare function getFileDiff(workspaceRoot: string, file: string, base: string, head?: string): string;
|
|
9
|
+
/**
|
|
10
|
+
* Parse diff to extract changed line numbers (additions only - lines starting with +).
|
|
11
|
+
*/
|
|
12
|
+
export declare function getChangedLineNumbers(diffContent: string): Set<number>;
|
|
13
|
+
/**
|
|
14
|
+
* Parse diff to find newly added method signatures.
|
|
15
|
+
*/
|
|
16
|
+
export declare function findNewMethodSignaturesInDiff(diffContent: string): Set<string>;
|
|
17
|
+
/**
|
|
18
|
+
* Check if any line in [startLine, endLine] is in the changedLines set.
|
|
19
|
+
*/
|
|
20
|
+
export declare function hasChangesInRange(startLine: number, endLine: number, changedLines: Set<number>): boolean;
|
|
21
|
+
/**
|
|
22
|
+
* Check if a node (method or function) is new or has changed lines in its range.
|
|
23
|
+
*/
|
|
24
|
+
export declare function isNewOrModified(name: string, startLine: number, endLine: number, changedLines: Set<number>, newMethodNames: Set<string>): boolean;
|
|
@@ -1,89 +1,88 @@
|
|
|
1
|
+
"use strict";
|
|
1
2
|
/**
|
|
2
3
|
* Shared diff utility functions for code-rules validators.
|
|
3
4
|
* These are used by multiple validators for git diff parsing and line-level detection.
|
|
4
5
|
*/
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.getFileDiff = getFileDiff;
|
|
8
|
+
exports.getChangedLineNumbers = getChangedLineNumbers;
|
|
9
|
+
exports.findNewMethodSignaturesInDiff = findNewMethodSignaturesInDiff;
|
|
10
|
+
exports.hasChangesInRange = hasChangesInRange;
|
|
11
|
+
exports.isNewOrModified = isNewOrModified;
|
|
12
|
+
const tslib_1 = require("tslib");
|
|
13
|
+
const child_process_1 = require("child_process");
|
|
14
|
+
const fs = tslib_1.__importStar(require("fs"));
|
|
15
|
+
const path = tslib_1.__importStar(require("path"));
|
|
10
16
|
/**
|
|
11
17
|
* Get the diff content for a specific file.
|
|
12
18
|
*/
|
|
13
|
-
|
|
19
|
+
function getFileDiff(workspaceRoot, file, base, head) {
|
|
14
20
|
// eslint-disable-next-line @webpieces/no-unmanaged-exceptions
|
|
15
21
|
try {
|
|
16
22
|
const diffTarget = head ? `${base} ${head}` : base;
|
|
17
|
-
const diff = execSync(`git diff ${diffTarget} -- "${file}"`, {
|
|
23
|
+
const diff = (0, child_process_1.execSync)(`git diff ${diffTarget} -- "${file}"`, {
|
|
18
24
|
cwd: workspaceRoot,
|
|
19
25
|
encoding: 'utf-8',
|
|
20
26
|
});
|
|
21
|
-
|
|
22
27
|
if (!diff && !head) {
|
|
23
28
|
const fullPath = path.join(workspaceRoot, file);
|
|
24
29
|
if (fs.existsSync(fullPath)) {
|
|
25
|
-
const isUntracked = execSync(`git ls-files --others --exclude-standard "${file}"`, {
|
|
30
|
+
const isUntracked = (0, child_process_1.execSync)(`git ls-files --others --exclude-standard "${file}"`, {
|
|
26
31
|
cwd: workspaceRoot,
|
|
27
32
|
encoding: 'utf-8',
|
|
28
33
|
}).trim();
|
|
29
|
-
|
|
30
34
|
if (isUntracked) {
|
|
31
35
|
const content = fs.readFileSync(fullPath, 'utf-8');
|
|
32
36
|
const lines = content.split('\n');
|
|
33
|
-
return lines.map((l
|
|
37
|
+
return lines.map((l) => `+${l}`).join('\n');
|
|
34
38
|
}
|
|
35
39
|
}
|
|
36
40
|
}
|
|
37
|
-
|
|
38
41
|
return diff;
|
|
39
|
-
}
|
|
42
|
+
}
|
|
43
|
+
catch (err) {
|
|
40
44
|
//const error = toError(err);
|
|
41
45
|
return '';
|
|
42
46
|
}
|
|
43
47
|
}
|
|
44
|
-
|
|
45
48
|
/**
|
|
46
49
|
* Parse diff to extract changed line numbers (additions only - lines starting with +).
|
|
47
50
|
*/
|
|
48
|
-
|
|
49
|
-
const changedLines = new Set
|
|
51
|
+
function getChangedLineNumbers(diffContent) {
|
|
52
|
+
const changedLines = new Set();
|
|
50
53
|
const lines = diffContent.split('\n');
|
|
51
54
|
let currentLine = 0;
|
|
52
|
-
|
|
53
55
|
for (const line of lines) {
|
|
54
56
|
const hunkMatch = line.match(/^@@ -\d+(?:,\d+)? \+(\d+)(?:,\d+)? @@/);
|
|
55
57
|
if (hunkMatch) {
|
|
56
58
|
currentLine = parseInt(hunkMatch[1], 10);
|
|
57
59
|
continue;
|
|
58
60
|
}
|
|
59
|
-
|
|
60
61
|
if (line.startsWith('+') && !line.startsWith('+++')) {
|
|
61
62
|
changedLines.add(currentLine);
|
|
62
63
|
currentLine++;
|
|
63
|
-
}
|
|
64
|
+
}
|
|
65
|
+
else if (line.startsWith('-') && !line.startsWith('---')) {
|
|
64
66
|
// Deletions don't increment line number
|
|
65
|
-
}
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
66
69
|
currentLine++;
|
|
67
70
|
}
|
|
68
71
|
}
|
|
69
|
-
|
|
70
72
|
return changedLines;
|
|
71
73
|
}
|
|
72
|
-
|
|
73
74
|
/**
|
|
74
75
|
* Parse diff to find newly added method signatures.
|
|
75
76
|
*/
|
|
76
|
-
|
|
77
|
-
const newMethods = new Set
|
|
77
|
+
function findNewMethodSignaturesInDiff(diffContent) {
|
|
78
|
+
const newMethods = new Set();
|
|
78
79
|
const lines = diffContent.split('\n');
|
|
79
|
-
|
|
80
80
|
const patterns = [
|
|
81
81
|
/^\+\s*(?:export\s+)?(?:async\s+)?function\s+(\w+)\s*\(/,
|
|
82
82
|
/^\+\s*(?:export\s+)?(?:const|let)\s+(\w+)\s*=\s*(?:async\s*)?\(/,
|
|
83
83
|
/^\+\s*(?:export\s+)?(?:const|let)\s+(\w+)\s*=\s*(?:async\s+)?function/,
|
|
84
84
|
/^\+\s*(?:(?:public|private|protected)\s+)?(?:static\s+)?(?:async\s+)?(\w+)\s*\(/,
|
|
85
85
|
];
|
|
86
|
-
|
|
87
86
|
for (const line of lines) {
|
|
88
87
|
if (line.startsWith('+') && !line.startsWith('+++')) {
|
|
89
88
|
for (const pattern of patterns) {
|
|
@@ -98,14 +97,12 @@ export function findNewMethodSignaturesInDiff(diffContent: string): Set<string>
|
|
|
98
97
|
}
|
|
99
98
|
}
|
|
100
99
|
}
|
|
101
|
-
|
|
102
100
|
return newMethods;
|
|
103
101
|
}
|
|
104
|
-
|
|
105
102
|
/**
|
|
106
103
|
* Check if any line in [startLine, endLine] is in the changedLines set.
|
|
107
104
|
*/
|
|
108
|
-
|
|
105
|
+
function hasChangesInRange(startLine, endLine, changedLines) {
|
|
109
106
|
for (let line = startLine; line <= endLine; line++) {
|
|
110
107
|
if (changedLines.has(line)) {
|
|
111
108
|
return true;
|
|
@@ -113,17 +110,12 @@ export function hasChangesInRange(startLine: number, endLine: number, changedLin
|
|
|
113
110
|
}
|
|
114
111
|
return false;
|
|
115
112
|
}
|
|
116
|
-
|
|
117
113
|
/**
|
|
118
114
|
* Check if a node (method or function) is new or has changed lines in its range.
|
|
119
115
|
*/
|
|
120
|
-
|
|
121
|
-
name
|
|
122
|
-
|
|
123
|
-
endLine: number,
|
|
124
|
-
changedLines: Set<number>,
|
|
125
|
-
newMethodNames: Set<string>
|
|
126
|
-
): boolean {
|
|
127
|
-
if (newMethodNames.has(name)) return true;
|
|
116
|
+
function isNewOrModified(name, startLine, endLine, changedLines, newMethodNames) {
|
|
117
|
+
if (newMethodNames.has(name))
|
|
118
|
+
return true;
|
|
128
119
|
return hasChangesInRange(startLine, endLine, changedLines);
|
|
129
120
|
}
|
|
121
|
+
//# sourceMappingURL=diff-utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diff-utils.js","sourceRoot":"","sources":["../../../../../packages/tooling/code-rules/src/diff-utils.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Shared diff utility functions for code-rules validators.\n * These are used by multiple validators for git diff parsing and line-level detection.\n */\n\nimport { execSync } from 'child_process';\nimport * as fs from 'fs';\nimport * as path from 'path';\n\n/**\n * Get the diff content for a specific file.\n */\nexport function 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((l: string) => `+${l}`).join('\\n');\n }\n }\n }\n\n return diff;\n } catch (err: unknown) {\n //const error = toError(err);\n return '';\n }\n}\n\n/**\n * Parse diff to extract changed line numbers (additions only - lines starting with +).\n */\nexport function 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 * Parse diff to find newly added method signatures.\n */\nexport function findNewMethodSignaturesInDiff(diffContent: string): Set<string> {\n const newMethods = new Set<string>();\n const lines = diffContent.split('\\n');\n\n const patterns = [\n /^\\+\\s*(?:export\\s+)?(?:async\\s+)?function\\s+(\\w+)\\s*\\(/,\n /^\\+\\s*(?:export\\s+)?(?:const|let)\\s+(\\w+)\\s*=\\s*(?:async\\s*)?\\(/,\n /^\\+\\s*(?:export\\s+)?(?:const|let)\\s+(\\w+)\\s*=\\s*(?:async\\s+)?function/,\n /^\\+\\s*(?:(?:public|private|protected)\\s+)?(?:static\\s+)?(?:async\\s+)?(\\w+)\\s*\\(/,\n ];\n\n for (const line of lines) {\n if (line.startsWith('+') && !line.startsWith('+++')) {\n for (const pattern of patterns) {\n const match = line.match(pattern);\n if (match) {\n const methodName = match[1];\n if (methodName && !['if', 'for', 'while', 'switch', 'catch', 'constructor'].includes(methodName)) {\n newMethods.add(methodName);\n }\n break;\n }\n }\n }\n }\n\n return newMethods;\n}\n\n/**\n * Check if any line in [startLine, endLine] is in the changedLines set.\n */\nexport function hasChangesInRange(startLine: number, endLine: number, changedLines: Set<number>): boolean {\n for (let line = startLine; line <= endLine; line++) {\n if (changedLines.has(line)) {\n return true;\n }\n }\n return false;\n}\n\n/**\n * Check if a node (method or function) is new or has changed lines in its range.\n */\nexport function isNewOrModified(\n name: string,\n startLine: number,\n endLine: number,\n changedLines: Set<number>,\n newMethodNames: Set<string>\n): boolean {\n if (newMethodNames.has(name)) return true;\n return hasChangesInRange(startLine, endLine, changedLines);\n}\n"]}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Adapter: map @webpieces/rules-config ResolvedConfig -> legacy ValidateCodeOptions.
|
|
3
|
+
*
|
|
4
|
+
* We don't want to rewrite the 11 sub-executors in this PR, so this file
|
|
5
|
+
* takes the shared webpieces.config.json entries (kebab-case rule names)
|
|
6
|
+
* and reconstructs the camelCase ValidateCodeOptions shape the executor
|
|
7
|
+
* already understands.
|
|
8
|
+
*
|
|
9
|
+
* Mapping of canonical kebab-case rule name -> ValidateCodeOptions field:
|
|
10
|
+
* max-method-lines -> methodMaxLimit
|
|
11
|
+
* max-file-lines -> fileMaxLimit
|
|
12
|
+
* require-return-type -> requireReturnType
|
|
13
|
+
* no-inline-type-literals -> noInlineTypeLiterals
|
|
14
|
+
* no-any-unknown -> noAnyUnknown
|
|
15
|
+
* no-implicit-any -> noImplicitAny
|
|
16
|
+
* validate-dtos -> validateDtos
|
|
17
|
+
* prisma-converter -> prismaConverter
|
|
18
|
+
* no-destructure -> noDestructure
|
|
19
|
+
* catch-error-pattern -> catchErrorPattern
|
|
20
|
+
* no-unmanaged-exceptions -> noUnmanagedExceptions
|
|
21
|
+
* no-direct-api-in-resolver -> noDirectApiInResolver
|
|
22
|
+
*
|
|
23
|
+
* A rule entry with enabled:false is surfaced as mode:'OFF' so the
|
|
24
|
+
* downstream executor short-circuits the same way it did before.
|
|
25
|
+
*/
|
|
26
|
+
import type { ResolvedConfig } from '@webpieces/rules-config';
|
|
27
|
+
import type { ValidateCodeOptions } from './validate-code';
|
|
28
|
+
export declare function toValidateCodeOptions(shared: ResolvedConfig): ValidateCodeOptions;
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Adapter: map @webpieces/rules-config ResolvedConfig -> legacy ValidateCodeOptions.
|
|
4
|
+
*
|
|
5
|
+
* We don't want to rewrite the 11 sub-executors in this PR, so this file
|
|
6
|
+
* takes the shared webpieces.config.json entries (kebab-case rule names)
|
|
7
|
+
* and reconstructs the camelCase ValidateCodeOptions shape the executor
|
|
8
|
+
* already understands.
|
|
9
|
+
*
|
|
10
|
+
* Mapping of canonical kebab-case rule name -> ValidateCodeOptions field:
|
|
11
|
+
* max-method-lines -> methodMaxLimit
|
|
12
|
+
* max-file-lines -> fileMaxLimit
|
|
13
|
+
* require-return-type -> requireReturnType
|
|
14
|
+
* no-inline-type-literals -> noInlineTypeLiterals
|
|
15
|
+
* no-any-unknown -> noAnyUnknown
|
|
16
|
+
* no-implicit-any -> noImplicitAny
|
|
17
|
+
* validate-dtos -> validateDtos
|
|
18
|
+
* prisma-converter -> prismaConverter
|
|
19
|
+
* no-destructure -> noDestructure
|
|
20
|
+
* catch-error-pattern -> catchErrorPattern
|
|
21
|
+
* no-unmanaged-exceptions -> noUnmanagedExceptions
|
|
22
|
+
* no-direct-api-in-resolver -> noDirectApiInResolver
|
|
23
|
+
*
|
|
24
|
+
* A rule entry with enabled:false is surfaced as mode:'OFF' so the
|
|
25
|
+
* downstream executor short-circuits the same way it did before.
|
|
26
|
+
*/
|
|
27
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
28
|
+
exports.toValidateCodeOptions = toValidateCodeOptions;
|
|
29
|
+
// webpieces-disable no-any-unknown -- coerces opaque option values pulled from JSON
|
|
30
|
+
function opt(rule, key) {
|
|
31
|
+
if (!rule)
|
|
32
|
+
return undefined;
|
|
33
|
+
const value = rule.options[key];
|
|
34
|
+
if (value === undefined)
|
|
35
|
+
return undefined;
|
|
36
|
+
return value;
|
|
37
|
+
}
|
|
38
|
+
function modeOrOff(rule) {
|
|
39
|
+
if (!rule)
|
|
40
|
+
return undefined;
|
|
41
|
+
if (rule.enabled === false)
|
|
42
|
+
return 'OFF';
|
|
43
|
+
const mode = rule.options['mode'];
|
|
44
|
+
return mode ?? undefined;
|
|
45
|
+
}
|
|
46
|
+
function toValidateCodeOptions(shared) {
|
|
47
|
+
const r = (name) => shared.rules.get(name);
|
|
48
|
+
return {
|
|
49
|
+
methodMaxLimit: {
|
|
50
|
+
limit: opt(r('max-method-lines'), 'limit'),
|
|
51
|
+
mode: modeOrOff(r('max-method-lines')),
|
|
52
|
+
disableAllowed: opt(r('max-method-lines'), 'disableAllowed'),
|
|
53
|
+
ignoreModifiedUntilEpoch: opt(r('max-method-lines'), 'ignoreModifiedUntilEpoch'),
|
|
54
|
+
},
|
|
55
|
+
fileMaxLimit: {
|
|
56
|
+
limit: opt(r('max-file-lines'), 'limit'),
|
|
57
|
+
mode: modeOrOff(r('max-file-lines')),
|
|
58
|
+
disableAllowed: opt(r('max-file-lines'), 'disableAllowed'),
|
|
59
|
+
ignoreModifiedUntilEpoch: opt(r('max-file-lines'), 'ignoreModifiedUntilEpoch'),
|
|
60
|
+
},
|
|
61
|
+
requireReturnType: {
|
|
62
|
+
mode: modeOrOff(r('require-return-type')),
|
|
63
|
+
disableAllowed: opt(r('require-return-type'), 'disableAllowed'),
|
|
64
|
+
ignoreModifiedUntilEpoch: opt(r('require-return-type'), 'ignoreModifiedUntilEpoch'),
|
|
65
|
+
},
|
|
66
|
+
noInlineTypeLiterals: {
|
|
67
|
+
mode: modeOrOff(r('no-inline-type-literals')),
|
|
68
|
+
disableAllowed: opt(r('no-inline-type-literals'), 'disableAllowed'),
|
|
69
|
+
ignoreModifiedUntilEpoch: opt(r('no-inline-type-literals'), 'ignoreModifiedUntilEpoch'),
|
|
70
|
+
},
|
|
71
|
+
noAnyUnknown: {
|
|
72
|
+
mode: modeOrOff(r('no-any-unknown')),
|
|
73
|
+
disableAllowed: opt(r('no-any-unknown'), 'disableAllowed'),
|
|
74
|
+
ignoreModifiedUntilEpoch: opt(r('no-any-unknown'), 'ignoreModifiedUntilEpoch'),
|
|
75
|
+
},
|
|
76
|
+
noImplicitAny: {
|
|
77
|
+
mode: modeOrOff(r('no-implicit-any')),
|
|
78
|
+
disableAllowed: opt(r('no-implicit-any'), 'disableAllowed'),
|
|
79
|
+
ignoreModifiedUntilEpoch: opt(r('no-implicit-any'), 'ignoreModifiedUntilEpoch'),
|
|
80
|
+
},
|
|
81
|
+
validateDtos: {
|
|
82
|
+
mode: modeOrOff(r('validate-dtos')),
|
|
83
|
+
disableAllowed: opt(r('validate-dtos'), 'disableAllowed'),
|
|
84
|
+
prismaSchemaPath: opt(r('validate-dtos'), 'prismaSchemaPath'),
|
|
85
|
+
dtoSourcePaths: opt(r('validate-dtos'), 'dtoSourcePaths'),
|
|
86
|
+
ignoreModifiedUntilEpoch: opt(r('validate-dtos'), 'ignoreModifiedUntilEpoch'),
|
|
87
|
+
},
|
|
88
|
+
prismaConverter: {
|
|
89
|
+
mode: modeOrOff(r('prisma-converter')),
|
|
90
|
+
disableAllowed: opt(r('prisma-converter'), 'disableAllowed'),
|
|
91
|
+
schemaPath: opt(r('prisma-converter'), 'schemaPath'),
|
|
92
|
+
convertersPaths: opt(r('prisma-converter'), 'convertersPaths'),
|
|
93
|
+
enforcePaths: opt(r('prisma-converter'), 'enforcePaths'),
|
|
94
|
+
ignoreModifiedUntilEpoch: opt(r('prisma-converter'), 'ignoreModifiedUntilEpoch'),
|
|
95
|
+
},
|
|
96
|
+
noDestructure: {
|
|
97
|
+
mode: modeOrOff(r('no-destructure')),
|
|
98
|
+
disableAllowed: opt(r('no-destructure'), 'disableAllowed'),
|
|
99
|
+
ignoreModifiedUntilEpoch: opt(r('no-destructure'), 'ignoreModifiedUntilEpoch'),
|
|
100
|
+
},
|
|
101
|
+
catchErrorPattern: {
|
|
102
|
+
mode: modeOrOff(r('catch-error-pattern')),
|
|
103
|
+
disableAllowed: opt(r('catch-error-pattern'), 'disableAllowed'),
|
|
104
|
+
ignoreModifiedUntilEpoch: opt(r('catch-error-pattern'), 'ignoreModifiedUntilEpoch'),
|
|
105
|
+
},
|
|
106
|
+
noUnmanagedExceptions: {
|
|
107
|
+
mode: modeOrOff(r('no-unmanaged-exceptions')),
|
|
108
|
+
disableAllowed: opt(r('no-unmanaged-exceptions'), 'disableAllowed'),
|
|
109
|
+
ignoreModifiedUntilEpoch: opt(r('no-unmanaged-exceptions'), 'ignoreModifiedUntilEpoch'),
|
|
110
|
+
},
|
|
111
|
+
noDirectApiInResolver: {
|
|
112
|
+
mode: modeOrOff(r('no-direct-api-in-resolver')),
|
|
113
|
+
disableAllowed: opt(r('no-direct-api-in-resolver'), 'disableAllowed'),
|
|
114
|
+
ignoreModifiedUntilEpoch: opt(r('no-direct-api-in-resolver'), 'ignoreModifiedUntilEpoch'),
|
|
115
|
+
enforcePaths: opt(r('no-direct-api-in-resolver'), 'enforcePaths'),
|
|
116
|
+
},
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
//# sourceMappingURL=from-shared-config.js.map
|
|
@@ -0,0 +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 * validate-dtos -> validateDtos\n * prisma-converter -> prismaConverter\n * no-destructure -> noDestructure\n * catch-error-pattern -> catchErrorPattern\n * no-unmanaged-exceptions -> noUnmanagedExceptions\n * no-direct-api-in-resolver -> noDirectApiInResolver\n *\n * A rule entry with enabled:false is surfaced as mode:'OFF' so the\n * downstream executor short-circuits the same way it did before.\n */\n\nimport type { ResolvedConfig, ResolvedRuleConfig } from '@webpieces/rules-config';\nimport type { ValidateCodeOptions } from './validate-code';\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 if (rule.enabled === false) return 'OFF' as T;\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('validate-dtos')),\n disableAllowed: opt<boolean>(r('validate-dtos'), 'disableAllowed'),\n prismaSchemaPath: opt<string>(r('validate-dtos'), 'prismaSchemaPath'),\n dtoSourcePaths: opt<string[]>(r('validate-dtos'), 'dtoSourcePaths'),\n ignoreModifiedUntilEpoch: opt<number>(r('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('no-direct-api-in-resolver')),\n disableAllowed: opt<boolean>(r('no-direct-api-in-resolver'), 'disableAllowed'),\n ignoreModifiedUntilEpoch: opt<number>(r('no-direct-api-in-resolver'), 'ignoreModifiedUntilEpoch'),\n enforcePaths: opt<string[]>(r('no-direct-api-in-resolver'), 'enforcePaths'),\n },\n };\n}\n"]}
|
package/src/index.js
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.validateCode = exports.validatePrismaConverters = exports.validateDtos = exports.validateNoDirectApiResolver = exports.validateNoDestructure = exports.validateNoUnmanagedExceptions = exports.validateCatchErrorPattern = exports.validateNoImplicitAny = exports.validateNoInlineTypes = exports.validateReturnTypes = exports.validateModifiedFiles = exports.validateModifiedMethods = exports.validateNewMethods = exports.validateNoAnyUnknown = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
var validate_no_any_unknown_1 = require("./validate-no-any-unknown");
|
|
6
|
+
Object.defineProperty(exports, "validateNoAnyUnknown", { enumerable: true, get: function () { return tslib_1.__importDefault(validate_no_any_unknown_1).default; } });
|
|
7
|
+
var validate_new_methods_1 = require("./validate-new-methods");
|
|
8
|
+
Object.defineProperty(exports, "validateNewMethods", { enumerable: true, get: function () { return tslib_1.__importDefault(validate_new_methods_1).default; } });
|
|
9
|
+
var validate_modified_methods_1 = require("./validate-modified-methods");
|
|
10
|
+
Object.defineProperty(exports, "validateModifiedMethods", { enumerable: true, get: function () { return tslib_1.__importDefault(validate_modified_methods_1).default; } });
|
|
11
|
+
var validate_modified_files_1 = require("./validate-modified-files");
|
|
12
|
+
Object.defineProperty(exports, "validateModifiedFiles", { enumerable: true, get: function () { return tslib_1.__importDefault(validate_modified_files_1).default; } });
|
|
13
|
+
var validate_return_types_1 = require("./validate-return-types");
|
|
14
|
+
Object.defineProperty(exports, "validateReturnTypes", { enumerable: true, get: function () { return tslib_1.__importDefault(validate_return_types_1).default; } });
|
|
15
|
+
var validate_no_inline_types_1 = require("./validate-no-inline-types");
|
|
16
|
+
Object.defineProperty(exports, "validateNoInlineTypes", { enumerable: true, get: function () { return tslib_1.__importDefault(validate_no_inline_types_1).default; } });
|
|
17
|
+
var validate_no_implicit_any_1 = require("./validate-no-implicit-any");
|
|
18
|
+
Object.defineProperty(exports, "validateNoImplicitAny", { enumerable: true, get: function () { return tslib_1.__importDefault(validate_no_implicit_any_1).default; } });
|
|
19
|
+
var validate_catch_error_pattern_1 = require("./validate-catch-error-pattern");
|
|
20
|
+
Object.defineProperty(exports, "validateCatchErrorPattern", { enumerable: true, get: function () { return tslib_1.__importDefault(validate_catch_error_pattern_1).default; } });
|
|
21
|
+
var validate_no_unmanaged_exceptions_1 = require("./validate-no-unmanaged-exceptions");
|
|
22
|
+
Object.defineProperty(exports, "validateNoUnmanagedExceptions", { enumerable: true, get: function () { return tslib_1.__importDefault(validate_no_unmanaged_exceptions_1).default; } });
|
|
23
|
+
var validate_no_destructure_1 = require("./validate-no-destructure");
|
|
24
|
+
Object.defineProperty(exports, "validateNoDestructure", { enumerable: true, get: function () { return tslib_1.__importDefault(validate_no_destructure_1).default; } });
|
|
25
|
+
var validate_no_direct_api_resolver_1 = require("./validate-no-direct-api-resolver");
|
|
26
|
+
Object.defineProperty(exports, "validateNoDirectApiResolver", { enumerable: true, get: function () { return tslib_1.__importDefault(validate_no_direct_api_resolver_1).default; } });
|
|
27
|
+
var validate_dtos_1 = require("./validate-dtos");
|
|
28
|
+
Object.defineProperty(exports, "validateDtos", { enumerable: true, get: function () { return tslib_1.__importDefault(validate_dtos_1).default; } });
|
|
29
|
+
var validate_prisma_converters_1 = require("./validate-prisma-converters");
|
|
30
|
+
Object.defineProperty(exports, "validatePrismaConverters", { enumerable: true, get: function () { return tslib_1.__importDefault(validate_prisma_converters_1).default; } });
|
|
31
|
+
var validate_code_1 = require("./validate-code");
|
|
32
|
+
Object.defineProperty(exports, "validateCode", { enumerable: true, get: function () { return tslib_1.__importDefault(validate_code_1).default; } });
|
|
33
|
+
//# sourceMappingURL=index.js.map
|
package/src/index.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../packages/tooling/code-rules/src/index.ts"],"names":[],"mappings":";;;;AAAA,qEAA4E;AAAnE,wJAAA,OAAO,OAAwB;AACxC,+DAAuE;AAA9D,mJAAA,OAAO,OAAsB;AACtC,yEAAiF;AAAxE,6JAAA,OAAO,OAA2B;AAC3C,qEAA6E;AAApE,yJAAA,OAAO,OAAyB;AACzC,iEAAyE;AAAhE,qJAAA,OAAO,OAAuB;AACvC,uEAA8E;AAArE,0JAAA,OAAO,OAAyB;AACzC,uEAA8E;AAArE,0JAAA,OAAO,OAAyB;AACzC,+EAAsF;AAA7E,kKAAA,OAAO,OAA6B;AAC7C,uFAA8F;AAArF,0KAAA,OAAO,OAAiC;AACjD,qEAA6E;AAApE,yJAAA,OAAO,OAAyB;AACzC,qFAA2F;AAAlF,uKAAA,OAAO,OAA+B;AAC/C,iDAA0D;AAAjD,sIAAA,OAAO,OAAgB;AAChC,2EAAmF;AAA1E,+JAAA,OAAO,OAA4B;AAC5C,iDAA0D;AAAjD,sIAAA,OAAO,OAAgB","sourcesContent":["export { default as validateNoAnyUnknown } from './validate-no-any-unknown';\nexport { default as validateNewMethods } from './validate-new-methods';\nexport { default as validateModifiedMethods } from './validate-modified-methods';\nexport { default as validateModifiedFiles } from './validate-modified-files';\nexport { default as validateReturnTypes } from './validate-return-types';\nexport { default as validateNoInlineTypes } from './validate-no-inline-types';\nexport { default as validateNoImplicitAny } from './validate-no-implicit-any';\nexport { default as validateCatchErrorPattern } from './validate-catch-error-pattern';\nexport { default as validateNoUnmanagedExceptions } from './validate-no-unmanaged-exceptions';\nexport { default as validateNoDestructure } from './validate-no-destructure';\nexport { default as validateNoDirectApiResolver } from './validate-no-direct-api-resolver';\nexport { default as validateDtos } from './validate-dtos';\nexport { default as validatePrismaConverters } from './validate-prisma-converters';\nexport { default as validateCode } from './validate-code';\n"]}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Validate Catch Error Pattern Executor
|
|
3
|
+
*
|
|
4
|
+
* Validates that catch blocks follow the standardized error handling pattern.
|
|
5
|
+
* Uses TypeScript AST for detection and LINE-BASED git diff filtering.
|
|
6
|
+
*
|
|
7
|
+
* ============================================================================
|
|
8
|
+
* REQUIRED PATTERN
|
|
9
|
+
* ============================================================================
|
|
10
|
+
*
|
|
11
|
+
* Standard: catch (err: unknown) { const error = toError(err); ... }
|
|
12
|
+
* Ignored: catch (err: unknown) { //const error = toError(err); ... }
|
|
13
|
+
* Nested: catch (err2: unknown) { const error2 = toError(err2); ... }
|
|
14
|
+
*
|
|
15
|
+
* ============================================================================
|
|
16
|
+
* VIOLATIONS (BAD) - These patterns are flagged:
|
|
17
|
+
* ============================================================================
|
|
18
|
+
*
|
|
19
|
+
* - catch (e) { ... } — wrong parameter name
|
|
20
|
+
* - catch (err) { ... } — missing : unknown type annotation
|
|
21
|
+
* - catch (err: unknown) { ... } — missing toError() as first statement
|
|
22
|
+
* - catch (err: unknown) { const x = toError(err); } — wrong variable name
|
|
23
|
+
*
|
|
24
|
+
* ============================================================================
|
|
25
|
+
* MODES (LINE-BASED)
|
|
26
|
+
* ============================================================================
|
|
27
|
+
* - OFF: Skip validation entirely
|
|
28
|
+
* - MODIFIED_CODE: Flag catch violations on changed lines (lines in diff hunks)
|
|
29
|
+
* - MODIFIED_FILES: Flag ALL catch violations in files that were modified
|
|
30
|
+
*
|
|
31
|
+
* ============================================================================
|
|
32
|
+
* ESCAPE HATCH
|
|
33
|
+
* ============================================================================
|
|
34
|
+
* Add comment above the violation:
|
|
35
|
+
* // webpieces-disable catch-error-pattern -- [your justification]
|
|
36
|
+
* } catch (err: unknown) {
|
|
37
|
+
*/
|
|
38
|
+
export type CatchErrorPatternMode = 'OFF' | 'MODIFIED_CODE' | 'MODIFIED_FILES';
|
|
39
|
+
export interface ValidateCatchErrorPatternOptions {
|
|
40
|
+
mode?: CatchErrorPatternMode;
|
|
41
|
+
disableAllowed?: boolean;
|
|
42
|
+
ignoreModifiedUntilEpoch?: number;
|
|
43
|
+
}
|
|
44
|
+
export interface ExecutorResult {
|
|
45
|
+
success: boolean;
|
|
46
|
+
}
|
|
47
|
+
export default function runValidator(options: ValidateCatchErrorPatternOptions, workspaceRoot: string): Promise<ExecutorResult>;
|