@webpieces/dev-config 0.2.94 → 0.2.95
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/architecture/executors/validate-no-any-unknown/executor.js +2 -2
- package/architecture/executors/validate-no-any-unknown/executor.js.map +1 -1
- package/architecture/executors/validate-no-any-unknown/executor.ts +2 -2
- package/architecture/executors/validate-no-skiplevel-deps/executor.js.map +1 -1
- package/architecture/executors/validate-no-skiplevel-deps/executor.ts +2 -2
- package/eslint-plugin/__tests__/catch-error-pattern.test.ts +41 -26
- package/eslint-plugin/__tests__/no-unmanaged-exceptions.test.ts +20 -20
- package/eslint-plugin/rules/catch-error-pattern.d.ts +3 -3
- package/eslint-plugin/rules/catch-error-pattern.js +84 -137
- package/eslint-plugin/rules/catch-error-pattern.js.map +1 -1
- package/eslint-plugin/rules/catch-error-pattern.ts +123 -158
- package/eslint-plugin/rules/enforce-architecture.js +3 -3
- package/eslint-plugin/rules/enforce-architecture.js.map +1 -1
- package/eslint-plugin/rules/enforce-architecture.ts +8 -8
- package/eslint-plugin/rules/max-file-lines.js +3 -3
- package/eslint-plugin/rules/max-file-lines.js.map +1 -1
- package/eslint-plugin/rules/max-file-lines.ts +5 -5
- package/eslint-plugin/rules/max-method-lines.js +3 -3
- package/eslint-plugin/rules/max-method-lines.js.map +1 -1
- package/eslint-plugin/rules/max-method-lines.ts +5 -5
- package/executors/validate-eslint-sync/executor.d.ts +3 -2
- package/executors/validate-eslint-sync/executor.js.map +1 -1
- package/executors/validate-eslint-sync/executor.ts +6 -2
- package/executors/validate-versions-locked/executor.js +3 -2
- package/executors/validate-versions-locked/executor.js.map +1 -1
- package/executors/validate-versions-locked/executor.ts +5 -4
- package/package.json +1 -1
- package/src/generators/init/generator.js.map +1 -1
- package/templates/webpieces.exceptions.md +15 -15
|
@@ -195,7 +195,7 @@ function getViolationContext(node, sourceFile) {
|
|
|
195
195
|
}
|
|
196
196
|
/**
|
|
197
197
|
* Check if a node is in a catch clause variable declaration.
|
|
198
|
-
* This allows `catch (err:
|
|
198
|
+
* This allows `catch (err: unknown)` and `catch (err: unknown)` patterns.
|
|
199
199
|
*/
|
|
200
200
|
function isInCatchClause(node) {
|
|
201
201
|
let current = node.parent;
|
|
@@ -235,7 +235,7 @@ function findAnyUnknownInFile(filePath, workspaceRoot) {
|
|
|
235
235
|
try {
|
|
236
236
|
// Detect `any` keyword
|
|
237
237
|
if (node.kind === ts.SyntaxKind.AnyKeyword) {
|
|
238
|
-
// Skip catch clause variable types: catch (err:
|
|
238
|
+
// Skip catch clause variable types: catch (err: unknown) is allowed
|
|
239
239
|
if (isInCatchClause(node)) {
|
|
240
240
|
ts.forEachChild(node, visit);
|
|
241
241
|
return;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"executor.js","sourceRoot":"","sources":["../../../../../../../packages/tooling/dev-config/architecture/executors/validate-no-any-unknown/executor.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Validate No Any Unknown Executor\n *\n * Validates that `any` and `unknown` TypeScript keywords are not used.\n * Uses LINE-BASED detection (not method-based) for git diff filtering.\n *\n * ============================================================================\n * VIOLATIONS (BAD) - These patterns are flagged:\n * ============================================================================\n *\n * - const x: any = ...\n * - function foo(arg: any): any { }\n * - const data = response as any;\n * - type T = any;\n * - const x: unknown = ...\n * - function foo(arg: unknown): unknown { }\n *\n * ============================================================================\n * MODES (LINE-BASED)\n * ============================================================================\n * - OFF: Skip validation entirely\n * - MODIFIED_CODE: Flag any/unknown on changed lines (lines in diff hunks)\n * - MODIFIED_FILES: Flag ALL any/unknown in files that were modified\n *\n * ============================================================================\n * ESCAPE HATCH\n * ============================================================================\n * Add comment above the violation:\n * // webpieces-disable no-any-unknown -- [your justification]\n * const x: any = ...;\n */\n\nimport type { ExecutorContext } from '@nx/devkit';\nimport { execSync } from 'child_process';\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport * as ts from 'typescript';\n\nexport type NoAnyUnknownMode = 'OFF' | 'MODIFIED_CODE' | 'MODIFIED_FILES';\n\nexport interface ValidateNoAnyUnknownOptions {\n mode?: NoAnyUnknownMode;\n disableAllowed?: boolean;\n ignoreModifiedUntilEpoch?: number;\n}\n\nexport interface ExecutorResult {\n success: boolean;\n}\n\ninterface AnyUnknownViolation {\n file: string;\n line: number;\n column: number;\n keyword: 'any' | 'unknown';\n context: string;\n}\n\n/**\n * Get changed TypeScript files between base and head (or working tree if head not specified).\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 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 && !f.includes('.spec.ts') && !f.includes('.test.ts'));\n\n if (!head) {\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 && !f.includes('.spec.ts') && !f.includes('.test.ts'));\n const allFiles = new Set([...changedFiles, ...untrackedFiles]);\n return Array.from(allFiles);\n } catch {\n return changedFiles;\n }\n }\n\n return changedFiles;\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 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 } catch {\n return '';\n }\n}\n\n/**\n * Parse diff to extract changed line numbers (additions only - lines starting with +).\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 webpieces-disable comment for no-any-unknown.\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('no-any-unknown')) {\n return true;\n }\n }\n return false;\n}\n\n/**\n * Get a description of the context where the any/unknown keyword appears.\n */\n// webpieces-disable max-lines-new-methods -- Context detection requires checking many AST node types\nfunction getViolationContext(node: ts.Node, sourceFile: ts.SourceFile): string {\n try {\n let current: ts.Node = node;\n while (current.parent) {\n const parent = current.parent;\n if (ts.isParameter(parent)) {\n return 'parameter type';\n }\n if (ts.isFunctionDeclaration(parent) || ts.isMethodDeclaration(parent) || ts.isArrowFunction(parent)) {\n if (parent.type === current) {\n return 'return type';\n }\n }\n if (ts.isVariableDeclaration(parent)) {\n return 'variable type';\n }\n if (ts.isPropertyDeclaration(parent) || ts.isPropertySignature(parent)) {\n return 'property type';\n }\n if (ts.isAsExpression(parent)) {\n return 'type assertion';\n }\n if (ts.isTypeAliasDeclaration(parent)) {\n return 'type alias';\n }\n if (ts.isTypeReferenceNode(parent)) {\n return 'generic argument';\n }\n if (ts.isArrayTypeNode(parent)) {\n return 'array element type';\n }\n if (ts.isUnionTypeNode(parent) || ts.isIntersectionTypeNode(parent)) {\n return 'union/intersection type';\n }\n current = parent;\n }\n return 'type position';\n } catch {\n return 'type position';\n }\n}\n\ninterface AnyUnknownInfo {\n line: number;\n column: number;\n keyword: 'any' | 'unknown';\n context: string;\n hasDisableComment: boolean;\n}\n\n/**\n * Check if a node is in a catch clause variable declaration.\n * This allows `catch (err: any)` and `catch (err: unknown)` patterns.\n */\nfunction isInCatchClause(node: ts.Node): boolean {\n let current: ts.Node | undefined = node.parent;\n while (current) {\n if (ts.isCatchClause(current)) {\n // We're somewhere in a catch clause - check if we're in the variable declaration\n const catchClause = current as ts.CatchClause;\n if (catchClause.variableDeclaration) {\n // Walk back up from the original node to see if we're part of the variable declaration\n let checkNode: ts.Node | undefined = node.parent;\n while (checkNode && checkNode !== current) {\n if (checkNode === catchClause.variableDeclaration) {\n return true;\n }\n checkNode = checkNode.parent;\n }\n }\n }\n current = current.parent;\n }\n return false;\n}\n\n/**\n * Find all `any` and `unknown` keywords in a file using AST.\n */\n// webpieces-disable max-lines-new-methods -- AST traversal with nested visitor function for keyword detection\nfunction findAnyUnknownInFile(filePath: string, workspaceRoot: string): AnyUnknownInfo[] {\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: AnyUnknownInfo[] = [];\n\n // webpieces-disable max-lines-new-methods -- AST visitor needs to handle both any and unknown keywords with full context detection\n function visit(node: ts.Node): void {\n try {\n // Detect `any` keyword\n if (node.kind === ts.SyntaxKind.AnyKeyword) {\n // Skip catch clause variable types: catch (err: any) is allowed\n if (isInCatchClause(node)) {\n ts.forEachChild(node, visit);\n return;\n }\n\n const startPos = node.getStart(sourceFile);\n if (startPos >= 0) {\n const pos = sourceFile.getLineAndCharacterOfPosition(startPos);\n const line = pos.line + 1;\n const column = pos.character + 1;\n const context = getViolationContext(node, sourceFile);\n const disabled = hasDisableComment(fileLines, line);\n\n violations.push({\n line,\n column,\n keyword: 'any',\n context,\n hasDisableComment: disabled,\n });\n }\n }\n\n // Detect `unknown` keyword\n if (node.kind === ts.SyntaxKind.UnknownKeyword) {\n // Skip catch clause variable types: catch (err: unknown) is allowed\n if (isInCatchClause(node)) {\n ts.forEachChild(node, visit);\n return;\n }\n\n const startPos = node.getStart(sourceFile);\n if (startPos >= 0) {\n const pos = sourceFile.getLineAndCharacterOfPosition(startPos);\n const line = pos.line + 1;\n const column = pos.character + 1;\n const context = getViolationContext(node, sourceFile);\n const disabled = hasDisableComment(fileLines, line);\n\n violations.push({\n line,\n column,\n keyword: 'unknown',\n context,\n hasDisableComment: disabled,\n });\n }\n }\n } catch {\n // Skip nodes that cause errors during analysis\n }\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 in diff hunks.\n * This is LINE-BASED detection.\n */\n// webpieces-disable max-lines-new-methods -- File iteration with diff parsing and line filtering\nfunction findViolationsForModifiedCode(\n workspaceRoot: string,\n changedFiles: string[],\n base: string,\n head: string | undefined,\n disableAllowed: boolean\n): AnyUnknownViolation[] {\n const violations: AnyUnknownViolation[] = [];\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 = findAnyUnknownInFile(file, workspaceRoot);\n\n for (const v of allViolations) {\n if (disableAllowed && v.hasDisableComment) continue;\n // LINE-BASED: Only include if the violation is on a changed line\n if (!changedLines.has(v.line)) continue;\n\n violations.push({\n file,\n line: v.line,\n column: v.column,\n keyword: v.keyword,\n context: v.context,\n });\n }\n }\n\n return violations;\n}\n\n/**\n * MODIFIED_FILES mode: Flag ALL violations in files that were modified.\n */\nfunction findViolationsForModifiedFiles(workspaceRoot: string, changedFiles: string[], disableAllowed: boolean): AnyUnknownViolation[] {\n const violations: AnyUnknownViolation[] = [];\n\n for (const file of changedFiles) {\n const allViolations = findAnyUnknownInFile(file, workspaceRoot);\n\n for (const v of allViolations) {\n if (disableAllowed && v.hasDisableComment) continue;\n\n violations.push({\n file,\n line: v.line,\n column: v.column,\n keyword: v.keyword,\n context: v.context,\n });\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 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 } catch {\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 } catch {\n // Ignore\n }\n }\n return null;\n}\n\n/**\n * Report violations to console.\n */\nfunction reportViolations(violations: AnyUnknownViolation[], mode: NoAnyUnknownMode): void {\n console.error('');\n console.error('❌ `any` and `unknown` keywords found! Use specific types instead.');\n console.error('');\n console.error('📚 Avoiding any/unknown improves type safety:');\n console.error('');\n console.error(' BAD: const data: any = fetchData();');\n console.error(' GOOD: const data: UserData = fetchData();');\n console.error('');\n console.error(' BAD: function process(input: unknown): unknown { }');\n console.error(' GOOD: function process(input: ValidInput): ValidOutput { }');\n console.error('');\n\n for (const v of violations) {\n console.error(` ❌ ${v.file}:${v.line}:${v.column}`);\n console.error(` \\`${v.keyword}\\` keyword in ${v.context}`);\n }\n console.error('');\n\n console.error(' To fix: Replace with specific types or interfaces');\n console.error('');\n console.error(' Escape hatch (use sparingly):');\n console.error(' // webpieces-disable no-any-unknown -- [your reason]');\n console.error('');\n console.error(` Current mode: ${mode}`);\n console.error('');\n}\n\n/**\n * Resolve mode considering ignoreModifiedUntilEpoch override.\n * When active, downgrades to OFF. When expired, logs a warning.\n */\nfunction resolveMode(normalMode: NoAnyUnknownMode, epoch: number | undefined): NoAnyUnknownMode {\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⏭️ Skipping no-any-unknown validation (ignoreModifiedUntilEpoch active, expires: ${expiresDate})`);\n console.log('');\n return 'OFF';\n }\n return normalMode;\n}\n\nexport default async function runExecutor(\n options: ValidateNoAnyUnknownOptions,\n context: ExecutorContext\n): Promise<ExecutorResult> {\n const workspaceRoot = context.root;\n const mode: NoAnyUnknownMode = resolveMode(options.mode ?? 'OFF', options.ignoreModifiedUntilEpoch);\n const disableAllowed = options.disableAllowed ?? true;\n\n if (mode === 'OFF') {\n console.log('\\n⏭️ Skipping no-any-unknown validation (mode: OFF)');\n console.log('');\n return { success: true };\n }\n\n console.log('\\n📏 Validating No Any/Unknown\\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⏭️ Skipping no-any-unknown 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('✅ No TypeScript files changed');\n return { success: true };\n }\n\n console.log(`📂 Checking ${changedFiles.length} changed file(s)...`);\n\n let violations: AnyUnknownViolation[] = [];\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('✅ No any/unknown keywords found');\n return { success: true };\n }\n\n reportViolations(violations, mode);\n\n return { success: false };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"executor.js","sourceRoot":"","sources":["../../../../../../../packages/tooling/dev-config/architecture/executors/validate-no-any-unknown/executor.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Validate No Any Unknown Executor\n *\n * Validates that `any` and `unknown` TypeScript keywords are not used.\n * Uses LINE-BASED detection (not method-based) for git diff filtering.\n *\n * ============================================================================\n * VIOLATIONS (BAD) - These patterns are flagged:\n * ============================================================================\n *\n * - const x: any = ...\n * - function foo(arg: any): any { }\n * - const data = response as any;\n * - type T = any;\n * - const x: unknown = ...\n * - function foo(arg: unknown): unknown { }\n *\n * ============================================================================\n * MODES (LINE-BASED)\n * ============================================================================\n * - OFF: Skip validation entirely\n * - MODIFIED_CODE: Flag any/unknown on changed lines (lines in diff hunks)\n * - MODIFIED_FILES: Flag ALL any/unknown in files that were modified\n *\n * ============================================================================\n * ESCAPE HATCH\n * ============================================================================\n * Add comment above the violation:\n * // webpieces-disable no-any-unknown -- [your justification]\n * const x: any = ...;\n */\n\nimport type { ExecutorContext } from '@nx/devkit';\nimport { execSync } from 'child_process';\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport * as ts from 'typescript';\n\nexport type NoAnyUnknownMode = 'OFF' | 'MODIFIED_CODE' | 'MODIFIED_FILES';\n\nexport interface ValidateNoAnyUnknownOptions {\n mode?: NoAnyUnknownMode;\n disableAllowed?: boolean;\n ignoreModifiedUntilEpoch?: number;\n}\n\nexport interface ExecutorResult {\n success: boolean;\n}\n\ninterface AnyUnknownViolation {\n file: string;\n line: number;\n column: number;\n keyword: 'any' | 'unknown';\n context: string;\n}\n\n/**\n * Get changed TypeScript files between base and head (or working tree if head not specified).\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 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 && !f.includes('.spec.ts') && !f.includes('.test.ts'));\n\n if (!head) {\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 && !f.includes('.spec.ts') && !f.includes('.test.ts'));\n const allFiles = new Set([...changedFiles, ...untrackedFiles]);\n return Array.from(allFiles);\n } catch {\n return changedFiles;\n }\n }\n\n return changedFiles;\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 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 } catch {\n return '';\n }\n}\n\n/**\n * Parse diff to extract changed line numbers (additions only - lines starting with +).\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 webpieces-disable comment for no-any-unknown.\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('no-any-unknown')) {\n return true;\n }\n }\n return false;\n}\n\n/**\n * Get a description of the context where the any/unknown keyword appears.\n */\n// webpieces-disable max-lines-new-methods -- Context detection requires checking many AST node types\nfunction getViolationContext(node: ts.Node, sourceFile: ts.SourceFile): string {\n try {\n let current: ts.Node = node;\n while (current.parent) {\n const parent = current.parent;\n if (ts.isParameter(parent)) {\n return 'parameter type';\n }\n if (ts.isFunctionDeclaration(parent) || ts.isMethodDeclaration(parent) || ts.isArrowFunction(parent)) {\n if (parent.type === current) {\n return 'return type';\n }\n }\n if (ts.isVariableDeclaration(parent)) {\n return 'variable type';\n }\n if (ts.isPropertyDeclaration(parent) || ts.isPropertySignature(parent)) {\n return 'property type';\n }\n if (ts.isAsExpression(parent)) {\n return 'type assertion';\n }\n if (ts.isTypeAliasDeclaration(parent)) {\n return 'type alias';\n }\n if (ts.isTypeReferenceNode(parent)) {\n return 'generic argument';\n }\n if (ts.isArrayTypeNode(parent)) {\n return 'array element type';\n }\n if (ts.isUnionTypeNode(parent) || ts.isIntersectionTypeNode(parent)) {\n return 'union/intersection type';\n }\n current = parent;\n }\n return 'type position';\n } catch {\n return 'type position';\n }\n}\n\ninterface AnyUnknownInfo {\n line: number;\n column: number;\n keyword: 'any' | 'unknown';\n context: string;\n hasDisableComment: boolean;\n}\n\n/**\n * Check if a node is in a catch clause variable declaration.\n * This allows `catch (err: unknown)` and `catch (err: unknown)` patterns.\n */\nfunction isInCatchClause(node: ts.Node): boolean {\n let current: ts.Node | undefined = node.parent;\n while (current) {\n if (ts.isCatchClause(current)) {\n // We're somewhere in a catch clause - check if we're in the variable declaration\n const catchClause = current as ts.CatchClause;\n if (catchClause.variableDeclaration) {\n // Walk back up from the original node to see if we're part of the variable declaration\n let checkNode: ts.Node | undefined = node.parent;\n while (checkNode && checkNode !== current) {\n if (checkNode === catchClause.variableDeclaration) {\n return true;\n }\n checkNode = checkNode.parent;\n }\n }\n }\n current = current.parent;\n }\n return false;\n}\n\n/**\n * Find all `any` and `unknown` keywords in a file using AST.\n */\n// webpieces-disable max-lines-new-methods -- AST traversal with nested visitor function for keyword detection\nfunction findAnyUnknownInFile(filePath: string, workspaceRoot: string): AnyUnknownInfo[] {\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: AnyUnknownInfo[] = [];\n\n // webpieces-disable max-lines-new-methods -- AST visitor needs to handle both any and unknown keywords with full context detection\n function visit(node: ts.Node): void {\n try {\n // Detect `any` keyword\n if (node.kind === ts.SyntaxKind.AnyKeyword) {\n // Skip catch clause variable types: catch (err: unknown) is allowed\n if (isInCatchClause(node)) {\n ts.forEachChild(node, visit);\n return;\n }\n\n const startPos = node.getStart(sourceFile);\n if (startPos >= 0) {\n const pos = sourceFile.getLineAndCharacterOfPosition(startPos);\n const line = pos.line + 1;\n const column = pos.character + 1;\n const context = getViolationContext(node, sourceFile);\n const disabled = hasDisableComment(fileLines, line);\n\n violations.push({\n line,\n column,\n keyword: 'any',\n context,\n hasDisableComment: disabled,\n });\n }\n }\n\n // Detect `unknown` keyword\n if (node.kind === ts.SyntaxKind.UnknownKeyword) {\n // Skip catch clause variable types: catch (err: unknown) is allowed\n if (isInCatchClause(node)) {\n ts.forEachChild(node, visit);\n return;\n }\n\n const startPos = node.getStart(sourceFile);\n if (startPos >= 0) {\n const pos = sourceFile.getLineAndCharacterOfPosition(startPos);\n const line = pos.line + 1;\n const column = pos.character + 1;\n const context = getViolationContext(node, sourceFile);\n const disabled = hasDisableComment(fileLines, line);\n\n violations.push({\n line,\n column,\n keyword: 'unknown',\n context,\n hasDisableComment: disabled,\n });\n }\n }\n } catch {\n // Skip nodes that cause errors during analysis\n }\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 in diff hunks.\n * This is LINE-BASED detection.\n */\n// webpieces-disable max-lines-new-methods -- File iteration with diff parsing and line filtering\nfunction findViolationsForModifiedCode(\n workspaceRoot: string,\n changedFiles: string[],\n base: string,\n head: string | undefined,\n disableAllowed: boolean\n): AnyUnknownViolation[] {\n const violations: AnyUnknownViolation[] = [];\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 = findAnyUnknownInFile(file, workspaceRoot);\n\n for (const v of allViolations) {\n if (disableAllowed && v.hasDisableComment) continue;\n // LINE-BASED: Only include if the violation is on a changed line\n if (!changedLines.has(v.line)) continue;\n\n violations.push({\n file,\n line: v.line,\n column: v.column,\n keyword: v.keyword,\n context: v.context,\n });\n }\n }\n\n return violations;\n}\n\n/**\n * MODIFIED_FILES mode: Flag ALL violations in files that were modified.\n */\nfunction findViolationsForModifiedFiles(workspaceRoot: string, changedFiles: string[], disableAllowed: boolean): AnyUnknownViolation[] {\n const violations: AnyUnknownViolation[] = [];\n\n for (const file of changedFiles) {\n const allViolations = findAnyUnknownInFile(file, workspaceRoot);\n\n for (const v of allViolations) {\n if (disableAllowed && v.hasDisableComment) continue;\n\n violations.push({\n file,\n line: v.line,\n column: v.column,\n keyword: v.keyword,\n context: v.context,\n });\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 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 } catch {\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 } catch {\n // Ignore\n }\n }\n return null;\n}\n\n/**\n * Report violations to console.\n */\nfunction reportViolations(violations: AnyUnknownViolation[], mode: NoAnyUnknownMode): void {\n console.error('');\n console.error('❌ `any` and `unknown` keywords found! Use specific types instead.');\n console.error('');\n console.error('📚 Avoiding any/unknown improves type safety:');\n console.error('');\n console.error(' BAD: const data: any = fetchData();');\n console.error(' GOOD: const data: UserData = fetchData();');\n console.error('');\n console.error(' BAD: function process(input: unknown): unknown { }');\n console.error(' GOOD: function process(input: ValidInput): ValidOutput { }');\n console.error('');\n\n for (const v of violations) {\n console.error(` ❌ ${v.file}:${v.line}:${v.column}`);\n console.error(` \\`${v.keyword}\\` keyword in ${v.context}`);\n }\n console.error('');\n\n console.error(' To fix: Replace with specific types or interfaces');\n console.error('');\n console.error(' Escape hatch (use sparingly):');\n console.error(' // webpieces-disable no-any-unknown -- [your reason]');\n console.error('');\n console.error(` Current mode: ${mode}`);\n console.error('');\n}\n\n/**\n * Resolve mode considering ignoreModifiedUntilEpoch override.\n * When active, downgrades to OFF. When expired, logs a warning.\n */\nfunction resolveMode(normalMode: NoAnyUnknownMode, epoch: number | undefined): NoAnyUnknownMode {\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⏭️ Skipping no-any-unknown validation (ignoreModifiedUntilEpoch active, expires: ${expiresDate})`);\n console.log('');\n return 'OFF';\n }\n return normalMode;\n}\n\nexport default async function runExecutor(\n options: ValidateNoAnyUnknownOptions,\n context: ExecutorContext\n): Promise<ExecutorResult> {\n const workspaceRoot = context.root;\n const mode: NoAnyUnknownMode = resolveMode(options.mode ?? 'OFF', options.ignoreModifiedUntilEpoch);\n const disableAllowed = options.disableAllowed ?? true;\n\n if (mode === 'OFF') {\n console.log('\\n⏭️ Skipping no-any-unknown validation (mode: OFF)');\n console.log('');\n return { success: true };\n }\n\n console.log('\\n📏 Validating No Any/Unknown\\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⏭️ Skipping no-any-unknown 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('✅ No TypeScript files changed');\n return { success: true };\n }\n\n console.log(`📂 Checking ${changedFiles.length} changed file(s)...`);\n\n let violations: AnyUnknownViolation[] = [];\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('✅ No any/unknown keywords found');\n return { success: true };\n }\n\n reportViolations(violations, mode);\n\n return { success: false };\n}\n"]}
|
|
@@ -229,7 +229,7 @@ interface AnyUnknownInfo {
|
|
|
229
229
|
|
|
230
230
|
/**
|
|
231
231
|
* Check if a node is in a catch clause variable declaration.
|
|
232
|
-
* This allows `catch (err:
|
|
232
|
+
* This allows `catch (err: unknown)` and `catch (err: unknown)` patterns.
|
|
233
233
|
*/
|
|
234
234
|
function isInCatchClause(node: ts.Node): boolean {
|
|
235
235
|
let current: ts.Node | undefined = node.parent;
|
|
@@ -272,7 +272,7 @@ function findAnyUnknownInFile(filePath: string, workspaceRoot: string): AnyUnkno
|
|
|
272
272
|
try {
|
|
273
273
|
// Detect `any` keyword
|
|
274
274
|
if (node.kind === ts.SyntaxKind.AnyKeyword) {
|
|
275
|
-
// Skip catch clause variable types: catch (err:
|
|
275
|
+
// Skip catch clause variable types: catch (err: unknown) is allowed
|
|
276
276
|
if (isInCatchClause(node)) {
|
|
277
277
|
ts.forEachChild(node, visit);
|
|
278
278
|
return;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"executor.js","sourceRoot":"","sources":["../../../../../../../packages/tooling/dev-config/architecture/executors/validate-no-skiplevel-deps/executor.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Validate No Skip-Level Dependencies Executor\n *\n * Validates that no project has redundant transitive dependencies.\n * If project A depends on B, and B transitively brings in C, then A should NOT\n * also directly depend on C (it's redundant and clutters the dependency graph).\n *\n * This keeps the architecture graph clean for visualization and human understanding.\n *\n * Usage:\n * nx run architecture:validate-no-skiplevel-deps\n */\n\nimport type { ExecutorContext } from '@nx/devkit';\nimport { generateGraph } from '../../lib/graph-generator';\nimport * as fs from 'fs';\nimport * as path from 'path';\n\nexport interface ValidateNoSkipLevelDepsOptions {\n // No options needed\n}\n\nexport interface ExecutorResult {\n success: boolean;\n}\n\ninterface RedundantDep {\n project: string;\n redundantDep: string;\n alreadyBroughtInBy: string;\n}\n\nconst TRANSITIVE_DEPS_DOC = `# AI Agent Instructions: Redundant Transitive Dependency Violation\n\n**READ THIS FILE FIRST before making any changes!**\n\n## Why This Rule Exists\n\nThis rule keeps the architecture dependency graph **CLEAN and SIMPLE**.\n\nWhen you run \\`npx nx run architecture:visualize\\`, it generates a visual diagram of all\npackage dependencies. Without this rule, you end up with a tangled mess of 100+ lines\nwhere everything depends on everything - making it impossible to understand.\n\n**Clean graphs = easier understanding for humans AND AI agents.**\n\n## Understanding the Error\n\nYou have a **redundant transitive dependency**. This means:\n\n1. Project A directly depends on Project C\n2. BUT Project A also depends on Project B\n3. AND Project B already brings in Project C (transitively)\n\nTherefore, Project A's direct dependency on C is **redundant** - it's already available\nthrough B. This extra line clutters the dependency graph.\n\n**Example:**\n\\`\\`\\`\nhttp-server depends on: [http-routing, http-filters, core-util]\n ^^^^^^^^^ ^^^^^^^^\n REDUNDANT! REDUNDANT!\n\nWhy? Because http-routing already brings in:\n - http-filters (direct)\n - core-util (via http-api)\n\\`\\`\\`\n\n## How to Fix\n\n### Step 1: Identify the Redundant Dependency\n\nLook at the error message. It tells you:\n- Which project has the problem\n- Which dependency is redundant\n- Which other dependency already brings it in\n\n### Step 2: Remove from project.json\n\nRemove the redundant dependency from \\`build.dependsOn\\`:\n\n\\`\\`\\`json\n{\n \"targets\": {\n \"build\": {\n \"dependsOn\": [\n \"^build\",\n \"http-routing:build\"\n // REMOVE: \"http-filters:build\" <-- redundant, http-routing brings it in\n // REMOVE: \"core-util:build\" <-- redundant, http-routing brings it in\n ]\n }\n }\n}\n\\`\\`\\`\n\n### Step 3: Remove from package.json\n\nRemove the redundant dependency from \\`dependencies\\`:\n\n\\`\\`\\`json\n{\n \"dependencies\": {\n \"@webpieces/http-routing\": \"*\"\n // REMOVE: \"@webpieces/http-filters\": \"*\" <-- redundant\n // REMOVE: \"@webpieces/core-util\": \"*\" <-- redundant\n }\n}\n\\`\\`\\`\n\n### Step 4: Regenerate Architecture\n\n\\`\\`\\`bash\nnpx nx run architecture:generate\n\\`\\`\\`\n\n### Step 5: Verify\n\n\\`\\`\\`bash\nnpm run build-all\n\\`\\`\\`\n\n## Important Notes\n\n- You DON'T lose access to the transitive dependency - it's still available through the parent\n- This is about keeping the DECLARED dependencies minimal and clean\n- The actual runtime/compile behavior is unchanged\n- TypeScript will still find the types through the transitive path\n\n## Remember\n\n- Fewer lines in the graph = easier to understand\n- Only declare what you DIRECTLY need that isn't already transitively available\n- When in doubt, check with \\`npx nx run architecture:visualize\\`\n`;\n\n/**\n * Compute all transitive dependencies for a project\n */\nfunction computeTransitiveDeps(\n project: string,\n graph: Record<string, string[]>,\n visited: Set<string> = new Set()\n): Set<string> {\n const result = new Set<string>();\n\n if (visited.has(project)) {\n return result;\n }\n visited.add(project);\n\n const directDeps = graph[project] || [];\n for (const dep of directDeps) {\n result.add(dep);\n // Recursively get transitive deps\n const transitive = computeTransitiveDeps(dep, graph, visited);\n for (const t of transitive) {\n result.add(t);\n }\n }\n\n return result;\n}\n\n/**\n * Find redundant dependencies for a project\n */\nfunction findRedundantDeps(\n project: string,\n graph: Record<string, string[]>\n): RedundantDep[] {\n const redundant: RedundantDep[] = [];\n const directDeps = graph[project] || [];\n\n // For each direct dependency, compute what it transitively brings in\n const transitiveByDep = new Map<string, Set<string>>();\n for (const dep of directDeps) {\n transitiveByDep.set(dep, computeTransitiveDeps(dep, graph));\n }\n\n // Check if any direct dependency is already brought in by another\n for (const dep of directDeps) {\n for (const [otherDep, otherTransitive] of transitiveByDep) {\n if (otherDep !== dep && otherTransitive.has(dep)) {\n redundant.push({\n project,\n redundantDep: dep,\n alreadyBroughtInBy: otherDep,\n });\n break; // Only report once per redundant dep\n }\n }\n }\n\n return redundant;\n}\n\n/**\n * Write documentation file when violations are found\n */\nfunction writeDocFile(workspaceRoot: string): void {\n const docPath = path.join(workspaceRoot, 'tmp', 'webpieces', 'webpieces.transitivedeps.md');\n const docDir = path.dirname(docPath);\n\n try {\n fs.mkdirSync(docDir, { recursive: true });\n fs.writeFileSync(docPath, TRANSITIVE_DEPS_DOC, 'utf-8');\n } catch (err: any) {\n void err;\n console.warn(`Could not write documentation file: ${docPath}`);\n }\n}\n\nexport default async function runExecutor(\n _options: ValidateNoSkipLevelDepsOptions,\n context: ExecutorContext\n): Promise<ExecutorResult> {\n console.log('\\n🔄 Validating No Skip-Level Dependencies\\n');\n\n try {\n // Step 1: Generate current graph from project.json files\n console.log('📊 Generating dependency graph from project.json files...');\n const graph = await generateGraph();\n\n // Step 2: Find all redundant dependencies\n console.log('🔍 Checking for redundant transitive dependencies...');\n const allRedundant: RedundantDep[] = [];\n\n for (const project of Object.keys(graph)) {\n const redundant = findRedundantDeps(project, graph);\n allRedundant.push(...redundant);\n }\n\n if (allRedundant.length === 0) {\n console.log('✅ No redundant transitive dependencies detected!');\n console.log('\\n📈 Graph is clean and minimal.');\n return { success: true };\n }\n\n // Write documentation file\n const workspaceRoot = context.root || process.cwd();\n writeDocFile(workspaceRoot);\n\n // Report violations\n console.error('\\n❌ Redundant transitive dependencies detected!\\n');\n console.error('⚠️ AI Agent: READ tmp/webpieces/webpieces.transitivedeps.md for fix instructions!\\n');\n\n for (const r of allRedundant) {\n console.error(` ${r.project}:`);\n console.error(` └─ \"${r.redundantDep}\" is REDUNDANT`);\n console.error(` (already brought in by \"${r.alreadyBroughtInBy}\")\\n`);\n }\n\n console.error('\\nTo fix:');\n console.error(' 1. READ tmp/webpieces/webpieces.transitivedeps.md');\n console.error(' 2. Remove redundant deps from project.json build.dependsOn');\n console.error(' 3. Remove redundant deps from package.json dependencies');\n console.error(' 4. Run: npx nx run architecture:generate');\n console.error(' 5. Run: npm run build-all');\n\n return { success: false };\n } catch (err: any) {\n const error = err instanceof Error ? err : new Error(String(err));\n console.error('❌ Skip-level validation failed:', error.message);\n return { success: false };\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"executor.js","sourceRoot":"","sources":["../../../../../../../packages/tooling/dev-config/architecture/executors/validate-no-skiplevel-deps/executor.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Validate No Skip-Level Dependencies Executor\n *\n * Validates that no project has redundant transitive dependencies.\n * If project A depends on B, and B transitively brings in C, then A should NOT\n * also directly depend on C (it's redundant and clutters the dependency graph).\n *\n * This keeps the architecture graph clean for visualization and human understanding.\n *\n * Usage:\n * nx run architecture:validate-no-skiplevel-deps\n */\n\nimport type { ExecutorContext } from '@nx/devkit';\nimport { generateGraph } from '../../lib/graph-generator';\nimport * as fs from 'fs';\nimport * as path from 'path';\n\nexport interface ValidateNoSkipLevelDepsOptions {\n // No options needed\n}\n\nexport interface ExecutorResult {\n success: boolean;\n}\n\ninterface RedundantDep {\n project: string;\n redundantDep: string;\n alreadyBroughtInBy: string;\n}\n\nconst TRANSITIVE_DEPS_DOC = `# AI Agent Instructions: Redundant Transitive Dependency Violation\n\n**READ THIS FILE FIRST before making any changes!**\n\n## Why This Rule Exists\n\nThis rule keeps the architecture dependency graph **CLEAN and SIMPLE**.\n\nWhen you run \\`npx nx run architecture:visualize\\`, it generates a visual diagram of all\npackage dependencies. Without this rule, you end up with a tangled mess of 100+ lines\nwhere everything depends on everything - making it impossible to understand.\n\n**Clean graphs = easier understanding for humans AND AI agents.**\n\n## Understanding the Error\n\nYou have a **redundant transitive dependency**. This means:\n\n1. Project A directly depends on Project C\n2. BUT Project A also depends on Project B\n3. AND Project B already brings in Project C (transitively)\n\nTherefore, Project A's direct dependency on C is **redundant** - it's already available\nthrough B. This extra line clutters the dependency graph.\n\n**Example:**\n\\`\\`\\`\nhttp-server depends on: [http-routing, http-filters, core-util]\n ^^^^^^^^^ ^^^^^^^^\n REDUNDANT! REDUNDANT!\n\nWhy? Because http-routing already brings in:\n - http-filters (direct)\n - core-util (via http-api)\n\\`\\`\\`\n\n## How to Fix\n\n### Step 1: Identify the Redundant Dependency\n\nLook at the error message. It tells you:\n- Which project has the problem\n- Which dependency is redundant\n- Which other dependency already brings it in\n\n### Step 2: Remove from project.json\n\nRemove the redundant dependency from \\`build.dependsOn\\`:\n\n\\`\\`\\`json\n{\n \"targets\": {\n \"build\": {\n \"dependsOn\": [\n \"^build\",\n \"http-routing:build\"\n // REMOVE: \"http-filters:build\" <-- redundant, http-routing brings it in\n // REMOVE: \"core-util:build\" <-- redundant, http-routing brings it in\n ]\n }\n }\n}\n\\`\\`\\`\n\n### Step 3: Remove from package.json\n\nRemove the redundant dependency from \\`dependencies\\`:\n\n\\`\\`\\`json\n{\n \"dependencies\": {\n \"@webpieces/http-routing\": \"*\"\n // REMOVE: \"@webpieces/http-filters\": \"*\" <-- redundant\n // REMOVE: \"@webpieces/core-util\": \"*\" <-- redundant\n }\n}\n\\`\\`\\`\n\n### Step 4: Regenerate Architecture\n\n\\`\\`\\`bash\nnpx nx run architecture:generate\n\\`\\`\\`\n\n### Step 5: Verify\n\n\\`\\`\\`bash\nnpm run build-all\n\\`\\`\\`\n\n## Important Notes\n\n- You DON'T lose access to the transitive dependency - it's still available through the parent\n- This is about keeping the DECLARED dependencies minimal and clean\n- The actual runtime/compile behavior is unchanged\n- TypeScript will still find the types through the transitive path\n\n## Remember\n\n- Fewer lines in the graph = easier to understand\n- Only declare what you DIRECTLY need that isn't already transitively available\n- When in doubt, check with \\`npx nx run architecture:visualize\\`\n`;\n\n/**\n * Compute all transitive dependencies for a project\n */\nfunction computeTransitiveDeps(\n project: string,\n graph: Record<string, string[]>,\n visited: Set<string> = new Set()\n): Set<string> {\n const result = new Set<string>();\n\n if (visited.has(project)) {\n return result;\n }\n visited.add(project);\n\n const directDeps = graph[project] || [];\n for (const dep of directDeps) {\n result.add(dep);\n // Recursively get transitive deps\n const transitive = computeTransitiveDeps(dep, graph, visited);\n for (const t of transitive) {\n result.add(t);\n }\n }\n\n return result;\n}\n\n/**\n * Find redundant dependencies for a project\n */\nfunction findRedundantDeps(\n project: string,\n graph: Record<string, string[]>\n): RedundantDep[] {\n const redundant: RedundantDep[] = [];\n const directDeps = graph[project] || [];\n\n // For each direct dependency, compute what it transitively brings in\n const transitiveByDep = new Map<string, Set<string>>();\n for (const dep of directDeps) {\n transitiveByDep.set(dep, computeTransitiveDeps(dep, graph));\n }\n\n // Check if any direct dependency is already brought in by another\n for (const dep of directDeps) {\n for (const [otherDep, otherTransitive] of transitiveByDep) {\n if (otherDep !== dep && otherTransitive.has(dep)) {\n redundant.push({\n project,\n redundantDep: dep,\n alreadyBroughtInBy: otherDep,\n });\n break; // Only report once per redundant dep\n }\n }\n }\n\n return redundant;\n}\n\n/**\n * Write documentation file when violations are found\n */\nfunction writeDocFile(workspaceRoot: string): void {\n const docPath = path.join(workspaceRoot, 'tmp', 'webpieces', 'webpieces.transitivedeps.md');\n const docDir = path.dirname(docPath);\n\n try {\n fs.mkdirSync(docDir, { recursive: true });\n fs.writeFileSync(docPath, TRANSITIVE_DEPS_DOC, 'utf-8');\n } catch (err: unknown) {\n void err;\n console.warn(`Could not write documentation file: ${docPath}`);\n }\n}\n\nexport default async function runExecutor(\n _options: ValidateNoSkipLevelDepsOptions,\n context: ExecutorContext\n): Promise<ExecutorResult> {\n console.log('\\n🔄 Validating No Skip-Level Dependencies\\n');\n\n try {\n // Step 1: Generate current graph from project.json files\n console.log('📊 Generating dependency graph from project.json files...');\n const graph = await generateGraph();\n\n // Step 2: Find all redundant dependencies\n console.log('🔍 Checking for redundant transitive dependencies...');\n const allRedundant: RedundantDep[] = [];\n\n for (const project of Object.keys(graph)) {\n const redundant = findRedundantDeps(project, graph);\n allRedundant.push(...redundant);\n }\n\n if (allRedundant.length === 0) {\n console.log('✅ No redundant transitive dependencies detected!');\n console.log('\\n📈 Graph is clean and minimal.');\n return { success: true };\n }\n\n // Write documentation file\n const workspaceRoot = context.root || process.cwd();\n writeDocFile(workspaceRoot);\n\n // Report violations\n console.error('\\n❌ Redundant transitive dependencies detected!\\n');\n console.error('⚠️ AI Agent: READ tmp/webpieces/webpieces.transitivedeps.md for fix instructions!\\n');\n\n for (const r of allRedundant) {\n console.error(` ${r.project}:`);\n console.error(` └─ \"${r.redundantDep}\" is REDUNDANT`);\n console.error(` (already brought in by \"${r.alreadyBroughtInBy}\")\\n`);\n }\n\n console.error('\\nTo fix:');\n console.error(' 1. READ tmp/webpieces/webpieces.transitivedeps.md');\n console.error(' 2. Remove redundant deps from project.json build.dependsOn');\n console.error(' 3. Remove redundant deps from package.json dependencies');\n console.error(' 4. Run: npx nx run architecture:generate');\n console.error(' 5. Run: npm run build-all');\n\n return { success: false };\n } catch (err: unknown) {\n const error = err instanceof Error ? err : new Error(String(err));\n console.error('❌ Skip-level validation failed:', error.message);\n return { success: false };\n }\n}\n"]}
|
|
@@ -205,7 +205,7 @@ function writeDocFile(workspaceRoot: string): void {
|
|
|
205
205
|
try {
|
|
206
206
|
fs.mkdirSync(docDir, { recursive: true });
|
|
207
207
|
fs.writeFileSync(docPath, TRANSITIVE_DEPS_DOC, 'utf-8');
|
|
208
|
-
} catch (err:
|
|
208
|
+
} catch (err: unknown) {
|
|
209
209
|
void err;
|
|
210
210
|
console.warn(`Could not write documentation file: ${docPath}`);
|
|
211
211
|
}
|
|
@@ -259,7 +259,7 @@ export default async function runExecutor(
|
|
|
259
259
|
console.error(' 5. Run: npm run build-all');
|
|
260
260
|
|
|
261
261
|
return { success: false };
|
|
262
|
-
} catch (err:
|
|
262
|
+
} catch (err: unknown) {
|
|
263
263
|
const error = err instanceof Error ? err : new Error(String(err));
|
|
264
264
|
console.error('❌ Skip-level validation failed:', error.message);
|
|
265
265
|
return { success: false };
|
|
@@ -24,7 +24,7 @@ ruleTester.run('catch-error-pattern', rule, {
|
|
|
24
24
|
{
|
|
25
25
|
code: `try {
|
|
26
26
|
doSomething();
|
|
27
|
-
} catch (err:
|
|
27
|
+
} catch (err: unknown) {
|
|
28
28
|
const error = toError(err);
|
|
29
29
|
}`,
|
|
30
30
|
},
|
|
@@ -32,7 +32,7 @@ ruleTester.run('catch-error-pattern', rule, {
|
|
|
32
32
|
{
|
|
33
33
|
code: `try {
|
|
34
34
|
doSomething();
|
|
35
|
-
} catch (err:
|
|
35
|
+
} catch (err: unknown) {
|
|
36
36
|
const error = toError(err);
|
|
37
37
|
console.log('Error occurred:', error);
|
|
38
38
|
throw error;
|
|
@@ -42,7 +42,7 @@ ruleTester.run('catch-error-pattern', rule, {
|
|
|
42
42
|
{
|
|
43
43
|
code: `try {
|
|
44
44
|
doSomething();
|
|
45
|
-
} catch (err:
|
|
45
|
+
} catch (err: unknown) {
|
|
46
46
|
//const error = toError(err);
|
|
47
47
|
}`,
|
|
48
48
|
},
|
|
@@ -50,7 +50,7 @@ ruleTester.run('catch-error-pattern', rule, {
|
|
|
50
50
|
{
|
|
51
51
|
code: `try {
|
|
52
52
|
doSomething();
|
|
53
|
-
} catch (err:
|
|
53
|
+
} catch (err: unknown) {
|
|
54
54
|
// const error = toError(err);
|
|
55
55
|
}`,
|
|
56
56
|
},
|
|
@@ -58,11 +58,11 @@ ruleTester.run('catch-error-pattern', rule, {
|
|
|
58
58
|
{
|
|
59
59
|
code: `try {
|
|
60
60
|
doSomething();
|
|
61
|
-
} catch (err:
|
|
61
|
+
} catch (err: unknown) {
|
|
62
62
|
const error = toError(err);
|
|
63
63
|
try {
|
|
64
64
|
cleanup();
|
|
65
|
-
} catch (err2:
|
|
65
|
+
} catch (err2: unknown) {
|
|
66
66
|
const error2 = toError(err2);
|
|
67
67
|
}
|
|
68
68
|
}`,
|
|
@@ -71,15 +71,15 @@ ruleTester.run('catch-error-pattern', rule, {
|
|
|
71
71
|
{
|
|
72
72
|
code: `try {
|
|
73
73
|
operation1();
|
|
74
|
-
} catch (err:
|
|
74
|
+
} catch (err: unknown) {
|
|
75
75
|
const error = toError(err);
|
|
76
76
|
try {
|
|
77
77
|
operation2();
|
|
78
|
-
} catch (err2:
|
|
78
|
+
} catch (err2: unknown) {
|
|
79
79
|
const error2 = toError(err2);
|
|
80
80
|
try {
|
|
81
81
|
operation3();
|
|
82
|
-
} catch (err3:
|
|
82
|
+
} catch (err3: unknown) {
|
|
83
83
|
const error3 = toError(err3);
|
|
84
84
|
}
|
|
85
85
|
}
|
|
@@ -89,7 +89,7 @@ ruleTester.run('catch-error-pattern', rule, {
|
|
|
89
89
|
{
|
|
90
90
|
code: `try {
|
|
91
91
|
doSomething();
|
|
92
|
-
} catch (err:
|
|
92
|
+
} catch (err: unknown) {
|
|
93
93
|
const error = toError(err);
|
|
94
94
|
} finally {
|
|
95
95
|
cleanup();
|
|
@@ -99,7 +99,7 @@ ruleTester.run('catch-error-pattern', rule, {
|
|
|
99
99
|
{
|
|
100
100
|
code: `try {
|
|
101
101
|
doSomething();
|
|
102
|
-
} catch (err:
|
|
102
|
+
} catch (err: unknown) {
|
|
103
103
|
const error = toError(err);
|
|
104
104
|
logger.error(error);
|
|
105
105
|
throw error;
|
|
@@ -113,7 +113,7 @@ ruleTester.run('catch-error-pattern', rule, {
|
|
|
113
113
|
code: `
|
|
114
114
|
try {
|
|
115
115
|
doSomething();
|
|
116
|
-
} catch (e:
|
|
116
|
+
} catch (e: unknown) {
|
|
117
117
|
const error = toError(e);
|
|
118
118
|
}
|
|
119
119
|
`,
|
|
@@ -129,7 +129,7 @@ ruleTester.run('catch-error-pattern', rule, {
|
|
|
129
129
|
code: `
|
|
130
130
|
try {
|
|
131
131
|
doSomething();
|
|
132
|
-
} catch (error:
|
|
132
|
+
} catch (error: unknown) {
|
|
133
133
|
const error2 = toError(error);
|
|
134
134
|
}
|
|
135
135
|
`,
|
|
@@ -159,7 +159,7 @@ ruleTester.run('catch-error-pattern', rule, {
|
|
|
159
159
|
},
|
|
160
160
|
],
|
|
161
161
|
},
|
|
162
|
-
// Wrong type annotation (Error instead of
|
|
162
|
+
// Wrong type annotation (Error instead of unknown)
|
|
163
163
|
{
|
|
164
164
|
code: `
|
|
165
165
|
try {
|
|
@@ -174,12 +174,27 @@ ruleTester.run('catch-error-pattern', rule, {
|
|
|
174
174
|
},
|
|
175
175
|
],
|
|
176
176
|
},
|
|
177
|
-
//
|
|
177
|
+
// Wrong type annotation (any instead of unknown)
|
|
178
178
|
{
|
|
179
179
|
code: `
|
|
180
180
|
try {
|
|
181
181
|
doSomething();
|
|
182
182
|
} catch (err: any) {
|
|
183
|
+
const error = toError(err);
|
|
184
|
+
}
|
|
185
|
+
`,
|
|
186
|
+
errors: [
|
|
187
|
+
{
|
|
188
|
+
messageId: 'missingTypeAnnotation',
|
|
189
|
+
},
|
|
190
|
+
],
|
|
191
|
+
},
|
|
192
|
+
// Empty catch block
|
|
193
|
+
{
|
|
194
|
+
code: `
|
|
195
|
+
try {
|
|
196
|
+
doSomething();
|
|
197
|
+
} catch (err: unknown) {
|
|
183
198
|
}
|
|
184
199
|
`,
|
|
185
200
|
errors: [
|
|
@@ -193,7 +208,7 @@ ruleTester.run('catch-error-pattern', rule, {
|
|
|
193
208
|
code: `
|
|
194
209
|
try {
|
|
195
210
|
doSomething();
|
|
196
|
-
} catch (err:
|
|
211
|
+
} catch (err: unknown) {
|
|
197
212
|
console.log(err);
|
|
198
213
|
}
|
|
199
214
|
`,
|
|
@@ -208,7 +223,7 @@ ruleTester.run('catch-error-pattern', rule, {
|
|
|
208
223
|
code: `
|
|
209
224
|
try {
|
|
210
225
|
doSomething();
|
|
211
|
-
} catch (err:
|
|
226
|
+
} catch (err: unknown) {
|
|
212
227
|
const e = toError(err);
|
|
213
228
|
}
|
|
214
229
|
`,
|
|
@@ -224,7 +239,7 @@ ruleTester.run('catch-error-pattern', rule, {
|
|
|
224
239
|
code: `
|
|
225
240
|
try {
|
|
226
241
|
doSomething();
|
|
227
|
-
} catch (err:
|
|
242
|
+
} catch (err: unknown) {
|
|
228
243
|
const myError = toError(err);
|
|
229
244
|
}
|
|
230
245
|
`,
|
|
@@ -240,7 +255,7 @@ ruleTester.run('catch-error-pattern', rule, {
|
|
|
240
255
|
code: `
|
|
241
256
|
try {
|
|
242
257
|
doSomething();
|
|
243
|
-
} catch (err:
|
|
258
|
+
} catch (err: unknown) {
|
|
244
259
|
console.log('caught error');
|
|
245
260
|
const error = toError(err);
|
|
246
261
|
}
|
|
@@ -256,7 +271,7 @@ ruleTester.run('catch-error-pattern', rule, {
|
|
|
256
271
|
code: `
|
|
257
272
|
try {
|
|
258
273
|
doSomething();
|
|
259
|
-
} catch (err:
|
|
274
|
+
} catch (err: unknown) {
|
|
260
275
|
const error = handleError(err);
|
|
261
276
|
}
|
|
262
277
|
`,
|
|
@@ -271,11 +286,11 @@ ruleTester.run('catch-error-pattern', rule, {
|
|
|
271
286
|
code: `
|
|
272
287
|
try {
|
|
273
288
|
operation1();
|
|
274
|
-
} catch (err:
|
|
289
|
+
} catch (err: unknown) {
|
|
275
290
|
const error = toError(err);
|
|
276
291
|
try {
|
|
277
292
|
operation2();
|
|
278
|
-
} catch (e:
|
|
293
|
+
} catch (e: unknown) {
|
|
279
294
|
const error2 = toError(e);
|
|
280
295
|
}
|
|
281
296
|
}
|
|
@@ -292,11 +307,11 @@ ruleTester.run('catch-error-pattern', rule, {
|
|
|
292
307
|
code: `
|
|
293
308
|
try {
|
|
294
309
|
operation1();
|
|
295
|
-
} catch (err:
|
|
310
|
+
} catch (err: unknown) {
|
|
296
311
|
const error = toError(err);
|
|
297
312
|
try {
|
|
298
313
|
operation2();
|
|
299
|
-
} catch (err2:
|
|
314
|
+
} catch (err2: unknown) {
|
|
300
315
|
const err = toError(err2);
|
|
301
316
|
}
|
|
302
317
|
}
|
|
@@ -328,7 +343,7 @@ ruleTester.run('catch-error-pattern', rule, {
|
|
|
328
343
|
code: `
|
|
329
344
|
try {
|
|
330
345
|
doSomething();
|
|
331
|
-
} catch (err:
|
|
346
|
+
} catch (err: unknown) {
|
|
332
347
|
const error;
|
|
333
348
|
}
|
|
334
349
|
`,
|
|
@@ -343,7 +358,7 @@ ruleTester.run('catch-error-pattern', rule, {
|
|
|
343
358
|
code: `
|
|
344
359
|
try {
|
|
345
360
|
doSomething();
|
|
346
|
-
} catch (err:
|
|
361
|
+
} catch (err: unknown) {
|
|
347
362
|
const error = new Error(err.message);
|
|
348
363
|
}
|
|
349
364
|
`,
|