@webpieces/eslint-plugin 0.0.0-dev
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/README.md +11 -0
- package/package.json +21 -0
- package/src/index.d.ts +23 -0
- package/src/index.js +30 -0
- package/src/index.js.map +1 -0
- package/src/rules/catch-error-pattern.d.ts +11 -0
- package/src/rules/catch-error-pattern.js +144 -0
- package/src/rules/catch-error-pattern.js.map +1 -0
- package/src/rules/enforce-architecture.d.ts +15 -0
- package/src/rules/enforce-architecture.js +473 -0
- package/src/rules/enforce-architecture.js.map +1 -0
- package/src/rules/max-file-lines.d.ts +12 -0
- package/src/rules/max-file-lines.js +258 -0
- package/src/rules/max-file-lines.js.map +1 -0
- package/src/rules/max-method-lines.d.ts +12 -0
- package/src/rules/max-method-lines.js +243 -0
- package/src/rules/max-method-lines.js.map +1 -0
- package/src/rules/no-unmanaged-exceptions.d.ts +22 -0
- package/src/rules/no-unmanaged-exceptions.js +162 -0
- package/src/rules/no-unmanaged-exceptions.js.map +1 -0
- package/src/toError.d.ts +5 -0
- package/src/toError.js +37 -0
- package/src/toError.js.map +1 -0
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* ESLint rule to discourage try-catch blocks outside test files
|
|
4
|
+
*
|
|
5
|
+
* Works alongside catch-error-pattern rule:
|
|
6
|
+
* - catch-error-pattern: Enforces HOW to handle exceptions (with toError())
|
|
7
|
+
* - no-unmanaged-exceptions: Enforces WHERE try-catch is allowed (tests only by default)
|
|
8
|
+
*
|
|
9
|
+
* Philosophy: Exceptions should bubble to global error handlers where they are logged
|
|
10
|
+
* with traceId and stored for debugging via /debugLocal and /debugCloud endpoints.
|
|
11
|
+
* Local try-catch blocks break this architecture and create blind spots in production.
|
|
12
|
+
*
|
|
13
|
+
* Auto-allowed in:
|
|
14
|
+
* - Test files (.test.ts, .spec.ts, __tests__/)
|
|
15
|
+
*
|
|
16
|
+
* Requires eslint-disable comment in:
|
|
17
|
+
* - Retry loops with exponential backoff
|
|
18
|
+
* - Batch processing where partial failure is expected
|
|
19
|
+
* - Resource cleanup (with approval)
|
|
20
|
+
*/
|
|
21
|
+
const tslib_1 = require("tslib");
|
|
22
|
+
const fs = tslib_1.__importStar(require("fs"));
|
|
23
|
+
const path = tslib_1.__importStar(require("path"));
|
|
24
|
+
/**
|
|
25
|
+
* Determines if a file is a test file based on naming conventions
|
|
26
|
+
* Test files are auto-allowed to use try-catch blocks
|
|
27
|
+
*/
|
|
28
|
+
function isTestFile(filename) {
|
|
29
|
+
const normalizedPath = filename.toLowerCase();
|
|
30
|
+
// Check file extensions
|
|
31
|
+
if (normalizedPath.endsWith('.test.ts') || normalizedPath.endsWith('.spec.ts')) {
|
|
32
|
+
return true;
|
|
33
|
+
}
|
|
34
|
+
// Check directory names (cross-platform)
|
|
35
|
+
if (normalizedPath.includes('/__tests__/') || normalizedPath.includes('\\__tests__\\')) {
|
|
36
|
+
return true;
|
|
37
|
+
}
|
|
38
|
+
return false;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Finds the workspace root by walking up the directory tree
|
|
42
|
+
* Looks for package.json with workspaces or name === 'webpieces-ts'
|
|
43
|
+
*/
|
|
44
|
+
function getWorkspaceRoot(context) {
|
|
45
|
+
const filename = context.filename || context.getFilename();
|
|
46
|
+
let dir = path.dirname(filename);
|
|
47
|
+
// Walk up directory tree
|
|
48
|
+
for (let i = 0; i < 10; i++) {
|
|
49
|
+
const pkgPath = path.join(dir, 'package.json');
|
|
50
|
+
if (fs.existsSync(pkgPath)) {
|
|
51
|
+
try {
|
|
52
|
+
const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'));
|
|
53
|
+
// Check if this is the root workspace
|
|
54
|
+
if (pkg.workspaces || pkg.name === 'webpieces-ts') {
|
|
55
|
+
return dir;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
// Invalid JSON, keep searching
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
const parentDir = path.dirname(dir);
|
|
63
|
+
if (parentDir === dir)
|
|
64
|
+
break; // Reached filesystem root
|
|
65
|
+
dir = parentDir;
|
|
66
|
+
}
|
|
67
|
+
// Fallback: return current directory
|
|
68
|
+
return process.cwd();
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Ensures a documentation file exists at the given path
|
|
72
|
+
* Creates parent directories if needed
|
|
73
|
+
*/
|
|
74
|
+
function ensureDocFile(docPath, content) {
|
|
75
|
+
try {
|
|
76
|
+
const dir = path.dirname(docPath);
|
|
77
|
+
if (!fs.existsSync(dir)) {
|
|
78
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
79
|
+
}
|
|
80
|
+
// Only write if file doesn't exist or is empty
|
|
81
|
+
if (!fs.existsSync(docPath) || fs.readFileSync(docPath, 'utf-8').trim() === '') {
|
|
82
|
+
fs.writeFileSync(docPath, content, 'utf-8');
|
|
83
|
+
}
|
|
84
|
+
return true;
|
|
85
|
+
}
|
|
86
|
+
catch (error) {
|
|
87
|
+
// Silently fail - don't break linting if file creation fails
|
|
88
|
+
return false;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Ensures the exception documentation markdown file exists
|
|
93
|
+
* Only creates file once per lint run using module-level flag
|
|
94
|
+
*
|
|
95
|
+
* Reads from the template file packaged with @webpieces/dev-config
|
|
96
|
+
* and copies it to tmp/webpieces/ for AI agents to read.
|
|
97
|
+
*/
|
|
98
|
+
function ensureExceptionDoc(context) {
|
|
99
|
+
if (exceptionDocCreated)
|
|
100
|
+
return;
|
|
101
|
+
const workspaceRoot = getWorkspaceRoot(context);
|
|
102
|
+
const docPath = path.join(workspaceRoot, 'tmp', 'webpieces', 'webpieces.exceptions.md');
|
|
103
|
+
// Read from the template file packaged with the npm module
|
|
104
|
+
// Path: from eslint-plugin/rules/ -> ../../templates/
|
|
105
|
+
const templatePath = path.join(__dirname, '..', '..', 'templates', 'webpieces.exceptions.md');
|
|
106
|
+
let content;
|
|
107
|
+
try {
|
|
108
|
+
content = fs.readFileSync(templatePath, 'utf-8');
|
|
109
|
+
}
|
|
110
|
+
catch {
|
|
111
|
+
// Fallback message if template not found (shouldn't happen in published package)
|
|
112
|
+
content = `# Exception Documentation Not Found\n\nTemplate file not found at: ${templatePath}\n\nPlease ensure @webpieces/dev-config is properly installed.`;
|
|
113
|
+
}
|
|
114
|
+
if (ensureDocFile(docPath, content)) {
|
|
115
|
+
exceptionDocCreated = true;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
// Module-level flag to prevent redundant markdown file creation
|
|
119
|
+
let exceptionDocCreated = false;
|
|
120
|
+
// NOTE: Documentation content moved to templates/webpieces.exceptions.md
|
|
121
|
+
// The ensureExceptionDoc function reads from that file at runtime.
|
|
122
|
+
const rule = {
|
|
123
|
+
meta: {
|
|
124
|
+
type: 'problem',
|
|
125
|
+
docs: {
|
|
126
|
+
description: 'Discourage try-catch blocks outside test files - use global error handlers',
|
|
127
|
+
category: 'Best Practices',
|
|
128
|
+
recommended: true,
|
|
129
|
+
url: 'https://github.com/deanhiller/webpieces-ts/blob/main/CLAUDE.md#exception-handling-philosophy',
|
|
130
|
+
},
|
|
131
|
+
messages: {
|
|
132
|
+
noUnmanagedExceptions: 'AI Agent: READ tmp/webpieces/webpieces.exceptions.md for context. Try-catch blocks are discouraged - use global error handlers instead. Only allowed in test files or with eslint-disable comment.',
|
|
133
|
+
},
|
|
134
|
+
fixable: undefined,
|
|
135
|
+
schema: [],
|
|
136
|
+
},
|
|
137
|
+
create(context) {
|
|
138
|
+
return {
|
|
139
|
+
// webpieces-disable no-any-unknown -- ESLint visitor callback parameter type
|
|
140
|
+
TryStatement(node) {
|
|
141
|
+
// Skip try..finally blocks (no catch handler, no exception handling)
|
|
142
|
+
// webpieces-disable no-any-unknown -- ESTree AST node type assertion
|
|
143
|
+
if (!node.handler) {
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
// Auto-allow in test files
|
|
147
|
+
const filename = context.filename || context.getFilename();
|
|
148
|
+
if (isTestFile(filename)) {
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
// Has catch block outside test file - report violation
|
|
152
|
+
ensureExceptionDoc(context);
|
|
153
|
+
context.report({
|
|
154
|
+
node: node,
|
|
155
|
+
messageId: 'noUnmanagedExceptions',
|
|
156
|
+
});
|
|
157
|
+
},
|
|
158
|
+
};
|
|
159
|
+
},
|
|
160
|
+
};
|
|
161
|
+
module.exports = rule;
|
|
162
|
+
//# sourceMappingURL=no-unmanaged-exceptions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"no-unmanaged-exceptions.js","sourceRoot":"","sources":["../../../../../../packages/tooling/eslint-plugin/src/rules/no-unmanaged-exceptions.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * ESLint rule to discourage try-catch blocks outside test files\n *\n * Works alongside catch-error-pattern rule:\n * - catch-error-pattern: Enforces HOW to handle exceptions (with toError())\n * - no-unmanaged-exceptions: Enforces WHERE try-catch is allowed (tests only by default)\n *\n * Philosophy: Exceptions should bubble to global error handlers where they are logged\n * with traceId and stored for debugging via /debugLocal and /debugCloud endpoints.\n * Local try-catch blocks break this architecture and create blind spots in production.\n *\n * Auto-allowed in:\n * - Test files (.test.ts, .spec.ts, __tests__/)\n *\n * Requires eslint-disable comment in:\n * - Retry loops with exponential backoff\n * - Batch processing where partial failure is expected\n * - Resource cleanup (with approval)\n */\n\nimport type { Rule } from 'eslint';\nimport * as fs from 'fs';\nimport * as path from 'path';\n\n// webpieces-disable no-any-unknown -- ESTree AST node interface\ninterface TryStatementNode {\n handler?: unknown;\n}\n\n/**\n * Determines if a file is a test file based on naming conventions\n * Test files are auto-allowed to use try-catch blocks\n */\nfunction isTestFile(filename: string): boolean {\n const normalizedPath = filename.toLowerCase();\n\n // Check file extensions\n if (normalizedPath.endsWith('.test.ts') || normalizedPath.endsWith('.spec.ts')) {\n return true;\n }\n\n // Check directory names (cross-platform)\n if (normalizedPath.includes('/__tests__/') || normalizedPath.includes('\\\\__tests__\\\\')) {\n return true;\n }\n\n return false;\n}\n\n/**\n * Finds the workspace root by walking up the directory tree\n * Looks for package.json with workspaces or name === 'webpieces-ts'\n */\nfunction getWorkspaceRoot(context: Rule.RuleContext): string {\n const filename = context.filename || context.getFilename();\n let dir = path.dirname(filename);\n\n // Walk up directory tree\n for (let i = 0; i < 10; i++) {\n const pkgPath = path.join(dir, 'package.json');\n if (fs.existsSync(pkgPath)) {\n try {\n const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'));\n // Check if this is the root workspace\n if (pkg.workspaces || pkg.name === 'webpieces-ts') {\n return dir;\n }\n } catch {\n // Invalid JSON, keep searching\n }\n }\n\n const parentDir = path.dirname(dir);\n if (parentDir === dir) break; // Reached filesystem root\n dir = parentDir;\n }\n\n // Fallback: return current directory\n return process.cwd();\n}\n\n/**\n * Ensures a documentation file exists at the given path\n * Creates parent directories if needed\n */\nfunction ensureDocFile(docPath: string, content: string): boolean {\n try {\n const dir = path.dirname(docPath);\n if (!fs.existsSync(dir)) {\n fs.mkdirSync(dir, { recursive: true });\n }\n\n // Only write if file doesn't exist or is empty\n if (!fs.existsSync(docPath) || fs.readFileSync(docPath, 'utf-8').trim() === '') {\n fs.writeFileSync(docPath, content, 'utf-8');\n }\n\n return true;\n } catch (error) {\n // Silently fail - don't break linting if file creation fails\n return false;\n }\n}\n\n/**\n * Ensures the exception documentation markdown file exists\n * Only creates file once per lint run using module-level flag\n *\n * Reads from the template file packaged with @webpieces/dev-config\n * and copies it to tmp/webpieces/ for AI agents to read.\n */\nfunction ensureExceptionDoc(context: Rule.RuleContext): void {\n if (exceptionDocCreated) return;\n\n const workspaceRoot = getWorkspaceRoot(context);\n const docPath = path.join(workspaceRoot, 'tmp', 'webpieces', 'webpieces.exceptions.md');\n\n // Read from the template file packaged with the npm module\n // Path: from eslint-plugin/rules/ -> ../../templates/\n const templatePath = path.join(__dirname, '..', '..', 'templates', 'webpieces.exceptions.md');\n\n let content: string;\n try {\n content = fs.readFileSync(templatePath, 'utf-8');\n } catch {\n // Fallback message if template not found (shouldn't happen in published package)\n content = `# Exception Documentation Not Found\\n\\nTemplate file not found at: ${templatePath}\\n\\nPlease ensure @webpieces/dev-config is properly installed.`;\n }\n\n if (ensureDocFile(docPath, content)) {\n exceptionDocCreated = true;\n }\n}\n\n// Module-level flag to prevent redundant markdown file creation\nlet exceptionDocCreated = false;\n\n// NOTE: Documentation content moved to templates/webpieces.exceptions.md\n// The ensureExceptionDoc function reads from that file at runtime.\n\nconst rule: Rule.RuleModule = {\n meta: {\n type: 'problem',\n docs: {\n description: 'Discourage try-catch blocks outside test files - use global error handlers',\n category: 'Best Practices',\n recommended: true,\n url: 'https://github.com/deanhiller/webpieces-ts/blob/main/CLAUDE.md#exception-handling-philosophy',\n },\n messages: {\n noUnmanagedExceptions:\n 'AI Agent: READ tmp/webpieces/webpieces.exceptions.md for context. Try-catch blocks are discouraged - use global error handlers instead. Only allowed in test files or with eslint-disable comment.',\n },\n fixable: undefined,\n schema: [],\n },\n\n create(context: Rule.RuleContext): Rule.RuleListener {\n return {\n // webpieces-disable no-any-unknown -- ESLint visitor callback parameter type\n TryStatement(node: unknown): void {\n // Skip try..finally blocks (no catch handler, no exception handling)\n // webpieces-disable no-any-unknown -- ESTree AST node type assertion\n if (!(node as TryStatementNode).handler) {\n return;\n }\n\n // Auto-allow in test files\n const filename = context.filename || context.getFilename();\n if (isTestFile(filename)) {\n return;\n }\n\n // Has catch block outside test file - report violation\n ensureExceptionDoc(context);\n context.report({\n node: node as Rule.Node,\n messageId: 'noUnmanagedExceptions',\n });\n },\n };\n },\n};\n\nexport = rule;\n\n"]}
|
package/src/toError.d.ts
ADDED
package/src/toError.js
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.toError = toError;
|
|
4
|
+
/**
|
|
5
|
+
* Lightweight duplicate of @webpieces/core-util toError for use in eslint-plugin.
|
|
6
|
+
* eslint-plugin is Level 0 and cannot depend on core-util (also Level 0).
|
|
7
|
+
*/
|
|
8
|
+
// webpieces-disable no-any-unknown -- toError intentionally accepts unknown to safely convert any thrown value to Error
|
|
9
|
+
function toError(err) {
|
|
10
|
+
if (err instanceof Error) {
|
|
11
|
+
return err;
|
|
12
|
+
}
|
|
13
|
+
if (err && typeof err === 'object') {
|
|
14
|
+
if ('message' in err) {
|
|
15
|
+
const error = new Error(String(err.message));
|
|
16
|
+
if ('stack' in err && typeof err.stack === 'string') {
|
|
17
|
+
error.stack = err.stack;
|
|
18
|
+
}
|
|
19
|
+
if ('name' in err && typeof err.name === 'string') {
|
|
20
|
+
error.name = err.name;
|
|
21
|
+
}
|
|
22
|
+
return error;
|
|
23
|
+
}
|
|
24
|
+
// eslint-disable-next-line @webpieces/no-unmanaged-exceptions -- must handle circular references without recursion
|
|
25
|
+
try {
|
|
26
|
+
return new Error(`Non-Error object thrown: ${JSON.stringify(err)}`);
|
|
27
|
+
}
|
|
28
|
+
catch (err) {
|
|
29
|
+
//const error = toError(err);
|
|
30
|
+
void err;
|
|
31
|
+
return new Error('Non-Error object thrown (unable to stringify)');
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
const message = err == null ? 'Null or undefined thrown' : String(err);
|
|
35
|
+
return new Error(message);
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=toError.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"toError.js","sourceRoot":"","sources":["../../../../../packages/tooling/eslint-plugin/src/toError.ts"],"names":[],"mappings":";;AAKA,0BA8BC;AAnCD;;;GAGG;AACH,wHAAwH;AACxH,SAAgB,OAAO,CAAC,GAAY;IAChC,IAAI,GAAG,YAAY,KAAK,EAAE,CAAC;QACvB,OAAO,GAAG,CAAC;IACf,CAAC;IAED,IAAI,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;QACjC,IAAI,SAAS,IAAI,GAAG,EAAE,CAAC;YACnB,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;YAE7C,IAAI,OAAO,IAAI,GAAG,IAAI,OAAO,GAAG,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;gBAClD,KAAK,CAAC,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC;YAC5B,CAAC;YACD,IAAI,MAAM,IAAI,GAAG,IAAI,OAAO,GAAG,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBAChD,KAAK,CAAC,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC;YAC1B,CAAC;YACD,OAAO,KAAK,CAAC;QACjB,CAAC;QAED,mHAAmH;QACnH,IAAI,CAAC;YACD,OAAO,IAAI,KAAK,CAAC,4BAA4B,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACxE,CAAC;QAAC,OAAO,GAAY,EAAE,CAAC;YACpB,6BAA6B;YAC7B,KAAK,GAAG,CAAC;YACT,OAAO,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAC;QACtE,CAAC;IACL,CAAC;IAED,MAAM,OAAO,GAAG,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,0BAA0B,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IACvE,OAAO,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC;AAC9B,CAAC","sourcesContent":["/**\n * Lightweight duplicate of @webpieces/core-util toError for use in eslint-plugin.\n * eslint-plugin is Level 0 and cannot depend on core-util (also Level 0).\n */\n// webpieces-disable no-any-unknown -- toError intentionally accepts unknown to safely convert any thrown value to Error\nexport function toError(err: unknown): Error {\n if (err instanceof Error) {\n return err;\n }\n\n if (err && typeof err === 'object') {\n if ('message' in err) {\n const error = new Error(String(err.message));\n\n if ('stack' in err && typeof err.stack === 'string') {\n error.stack = err.stack;\n }\n if ('name' in err && typeof err.name === 'string') {\n error.name = err.name;\n }\n return error;\n }\n\n // eslint-disable-next-line @webpieces/no-unmanaged-exceptions -- must handle circular references without recursion\n try {\n return new Error(`Non-Error object thrown: ${JSON.stringify(err)}`);\n } catch (err: unknown) {\n //const error = toError(err);\n void err;\n return new Error('Non-Error object thrown (unable to stringify)');\n }\n }\n\n const message = err == null ? 'Null or undefined thrown' : String(err);\n return new Error(message);\n}\n"]}
|