@kevinrabun/judges 3.55.0 → 3.56.0
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/CHANGELOG.md +12 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +56 -0
- package/dist/cli.js.map +1 -1
- package/dist/commands/api-versioning-audit.d.ts +6 -0
- package/dist/commands/api-versioning-audit.d.ts.map +1 -0
- package/dist/commands/api-versioning-audit.js +234 -0
- package/dist/commands/api-versioning-audit.js.map +1 -0
- package/dist/commands/boundary-enforce.d.ts +6 -0
- package/dist/commands/boundary-enforce.d.ts.map +1 -0
- package/dist/commands/boundary-enforce.js +256 -0
- package/dist/commands/boundary-enforce.js.map +1 -0
- package/dist/commands/error-taxonomy.d.ts +6 -0
- package/dist/commands/error-taxonomy.d.ts.map +1 -0
- package/dist/commands/error-taxonomy.js +227 -0
- package/dist/commands/error-taxonomy.js.map +1 -0
- package/dist/commands/log-quality.d.ts +6 -0
- package/dist/commands/log-quality.d.ts.map +1 -0
- package/dist/commands/log-quality.js +212 -0
- package/dist/commands/log-quality.js.map +1 -0
- package/dist/commands/null-safety-audit.d.ts +6 -0
- package/dist/commands/null-safety-audit.d.ts.map +1 -0
- package/dist/commands/null-safety-audit.js +222 -0
- package/dist/commands/null-safety-audit.js.map +1 -0
- package/dist/commands/ownership-map.d.ts +6 -0
- package/dist/commands/ownership-map.d.ts.map +1 -0
- package/dist/commands/ownership-map.js +229 -0
- package/dist/commands/ownership-map.js.map +1 -0
- package/dist/commands/retry-pattern-audit.d.ts +6 -0
- package/dist/commands/retry-pattern-audit.d.ts.map +1 -0
- package/dist/commands/retry-pattern-audit.js +216 -0
- package/dist/commands/retry-pattern-audit.js.map +1 -0
- package/dist/commands/test-isolation.d.ts +6 -0
- package/dist/commands/test-isolation.d.ts.map +1 -0
- package/dist/commands/test-isolation.js +235 -0
- package/dist/commands/test-isolation.js.map +1 -0
- package/package.json +1 -1
- package/server.json +2 -2
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* API versioning audit — detect breaking changes and versioning policy
|
|
3
|
+
* violations across API surface evolution.
|
|
4
|
+
*/
|
|
5
|
+
import { readFileSync, readdirSync, statSync, existsSync } from "fs";
|
|
6
|
+
import { join, extname } from "path";
|
|
7
|
+
// ─── File Collection ────────────────────────────────────────────────────────
|
|
8
|
+
const SCAN_EXTS = new Set([
|
|
9
|
+
".ts",
|
|
10
|
+
".tsx",
|
|
11
|
+
".js",
|
|
12
|
+
".jsx",
|
|
13
|
+
".py",
|
|
14
|
+
".java",
|
|
15
|
+
".go",
|
|
16
|
+
".rs",
|
|
17
|
+
".yaml",
|
|
18
|
+
".yml",
|
|
19
|
+
".json",
|
|
20
|
+
".graphql",
|
|
21
|
+
".gql",
|
|
22
|
+
".proto",
|
|
23
|
+
]);
|
|
24
|
+
function collectFiles(dir, max = 300) {
|
|
25
|
+
const files = [];
|
|
26
|
+
function walk(d) {
|
|
27
|
+
if (files.length >= max)
|
|
28
|
+
return;
|
|
29
|
+
let entries;
|
|
30
|
+
try {
|
|
31
|
+
entries = readdirSync(d);
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
for (const e of entries) {
|
|
37
|
+
if (files.length >= max)
|
|
38
|
+
return;
|
|
39
|
+
if (e.startsWith(".") || e === "node_modules" || e === "dist" || e === "build")
|
|
40
|
+
continue;
|
|
41
|
+
const full = join(d, e);
|
|
42
|
+
try {
|
|
43
|
+
if (statSync(full).isDirectory())
|
|
44
|
+
walk(full);
|
|
45
|
+
else if (SCAN_EXTS.has(extname(full)))
|
|
46
|
+
files.push(full);
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
/* skip */
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
walk(dir);
|
|
54
|
+
return files;
|
|
55
|
+
}
|
|
56
|
+
// ─── Analysis ───────────────────────────────────────────────────────────────
|
|
57
|
+
const BREAKING_PATTERNS = [
|
|
58
|
+
{
|
|
59
|
+
pattern: /(?:DELETE|REMOVE).*(?:endpoint|route|path)/i,
|
|
60
|
+
issue: "Endpoint removal",
|
|
61
|
+
severity: "critical",
|
|
62
|
+
detail: "Removing an endpoint breaks existing consumers — deprecate first",
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
pattern: /(?:removed|deleted)\s+(?:field|property|attribute)/i,
|
|
66
|
+
issue: "Response field removal",
|
|
67
|
+
severity: "critical",
|
|
68
|
+
detail: "Removing response fields breaks parsers — add deprecation notice",
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
pattern: /(?:required|mandatory).*(?:added|new)/i,
|
|
72
|
+
issue: "New required field",
|
|
73
|
+
severity: "high",
|
|
74
|
+
detail: "Adding required request fields breaks existing callers",
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
pattern: /(?:type|format)\s*(?:changed|modified|updated)/i,
|
|
78
|
+
issue: "Type change",
|
|
79
|
+
severity: "high",
|
|
80
|
+
detail: "Changing field types breaks serialization/deserialization",
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
pattern: /(?:rename|renamed)\s+(?:field|property|endpoint)/i,
|
|
84
|
+
issue: "Field/endpoint rename",
|
|
85
|
+
severity: "high",
|
|
86
|
+
detail: "Renaming breaks existing integrations — keep both during transition",
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
pattern: /(?:status\s+code|response\s+code).*(?:changed|updated)/i,
|
|
90
|
+
issue: "Status code change",
|
|
91
|
+
severity: "high",
|
|
92
|
+
detail: "Changing status codes breaks error handling in consumers",
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
pattern: /\/v\d+\/.*\/v\d+\//i,
|
|
96
|
+
issue: "Multiple version prefixes",
|
|
97
|
+
severity: "medium",
|
|
98
|
+
detail: "Inconsistent version path segments — standardize versioning scheme",
|
|
99
|
+
},
|
|
100
|
+
];
|
|
101
|
+
const VERSION_PATTERNS = [
|
|
102
|
+
{
|
|
103
|
+
pattern: /['"]\/api\/[^v]/i,
|
|
104
|
+
issue: "Unversioned API path",
|
|
105
|
+
severity: "high",
|
|
106
|
+
detail: "API paths without version prefix prevent safe evolution",
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
pattern: /(?:deprecated|sunset).*(?:no\s+date|without\s+date|missing\s+date)/i,
|
|
110
|
+
issue: "Deprecation without sunset date",
|
|
111
|
+
severity: "medium",
|
|
112
|
+
detail: "Deprecated APIs need a concrete sunset date for consumer planning",
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
pattern: /(?:Accept|Content-Type).*(?:version|v=)/i,
|
|
116
|
+
issue: "Header-based versioning detected",
|
|
117
|
+
severity: "medium",
|
|
118
|
+
detail: "Header versioning is harder to discover — ensure docs are explicit",
|
|
119
|
+
},
|
|
120
|
+
];
|
|
121
|
+
function analyzeFile(filepath) {
|
|
122
|
+
const issues = [];
|
|
123
|
+
let content;
|
|
124
|
+
try {
|
|
125
|
+
content = readFileSync(filepath, "utf-8");
|
|
126
|
+
}
|
|
127
|
+
catch {
|
|
128
|
+
return issues;
|
|
129
|
+
}
|
|
130
|
+
const lines = content.split("\n");
|
|
131
|
+
for (let i = 0; i < lines.length; i++) {
|
|
132
|
+
const line = lines[i];
|
|
133
|
+
for (const bp of [...BREAKING_PATTERNS, ...VERSION_PATTERNS]) {
|
|
134
|
+
if (bp.pattern.test(line)) {
|
|
135
|
+
issues.push({ file: filepath, line: i + 1, issue: bp.issue, severity: bp.severity, detail: bp.detail });
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
// Check for OpenAPI spec versioning
|
|
140
|
+
if (/openapi|swagger/i.test(content)) {
|
|
141
|
+
if (!/version\s*:\s*['"]?\d+\.\d+/i.test(content)) {
|
|
142
|
+
issues.push({
|
|
143
|
+
file: filepath,
|
|
144
|
+
line: 1,
|
|
145
|
+
issue: "OpenAPI spec missing version",
|
|
146
|
+
severity: "high",
|
|
147
|
+
detail: "API spec should declare a semantic version",
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
// Check for GraphQL deprecation
|
|
152
|
+
if (/type\s+\w+\s*\{/i.test(content) && extname(filepath) === ".graphql") {
|
|
153
|
+
const deprecated = (content.match(/@deprecated/g) || []).length;
|
|
154
|
+
const fields = (content.match(/\w+\s*(?:\([^)]*\))?\s*:\s*\w/g) || []).length;
|
|
155
|
+
if (fields > 20 && deprecated === 0) {
|
|
156
|
+
issues.push({
|
|
157
|
+
file: filepath,
|
|
158
|
+
line: 1,
|
|
159
|
+
issue: "Large schema without deprecation markers",
|
|
160
|
+
severity: "medium",
|
|
161
|
+
detail: "Use @deprecated directive to signal field lifecycle",
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
return issues;
|
|
166
|
+
}
|
|
167
|
+
function checkBaselineFile(dir) {
|
|
168
|
+
const candidates = ["api-baseline.json", "openapi.yaml", "openapi.json", "swagger.json", "swagger.yaml"];
|
|
169
|
+
for (const c of candidates) {
|
|
170
|
+
if (existsSync(join(dir, c)))
|
|
171
|
+
return c;
|
|
172
|
+
}
|
|
173
|
+
return null;
|
|
174
|
+
}
|
|
175
|
+
// ─── CLI ────────────────────────────────────────────────────────────────────
|
|
176
|
+
export function runApiVersioningAudit(argv) {
|
|
177
|
+
if (argv.includes("--help") || argv.includes("-h")) {
|
|
178
|
+
console.log(`
|
|
179
|
+
judges api-versioning-audit — Detect breaking changes and versioning policy violations
|
|
180
|
+
|
|
181
|
+
Usage:
|
|
182
|
+
judges api-versioning-audit [dir]
|
|
183
|
+
judges api-versioning-audit src/ --format json
|
|
184
|
+
|
|
185
|
+
Options:
|
|
186
|
+
[dir] Directory to scan (default: .)
|
|
187
|
+
--format json JSON output
|
|
188
|
+
--help, -h Show this help
|
|
189
|
+
|
|
190
|
+
Detects: endpoint removals, field deletions, type changes, unversioned paths,
|
|
191
|
+
missing deprecation dates, OpenAPI version gaps, GraphQL schema lifecycle.
|
|
192
|
+
`);
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
195
|
+
const format = argv.find((_a, i) => argv[i - 1] === "--format") || "text";
|
|
196
|
+
const dir = argv.find((a) => !a.startsWith("-") && argv.indexOf(a) > 0) || ".";
|
|
197
|
+
const files = collectFiles(dir);
|
|
198
|
+
const allIssues = [];
|
|
199
|
+
for (const f of files)
|
|
200
|
+
allIssues.push(...analyzeFile(f));
|
|
201
|
+
const baseline = checkBaselineFile(dir);
|
|
202
|
+
const critCount = allIssues.filter((i) => i.severity === "critical").length;
|
|
203
|
+
const highCount = allIssues.filter((i) => i.severity === "high").length;
|
|
204
|
+
const score = allIssues.length === 0 ? 100 : Math.max(0, 100 - critCount * 20 - highCount * 8);
|
|
205
|
+
if (format === "json") {
|
|
206
|
+
console.log(JSON.stringify({
|
|
207
|
+
issues: allIssues,
|
|
208
|
+
baseline,
|
|
209
|
+
score,
|
|
210
|
+
summary: { critical: critCount, high: highCount, total: allIssues.length },
|
|
211
|
+
timestamp: new Date().toISOString(),
|
|
212
|
+
}, null, 2));
|
|
213
|
+
}
|
|
214
|
+
else {
|
|
215
|
+
const badge = critCount > 0 ? "🚫 BREAKING" : highCount > 0 ? "⚠️ REVIEW" : "✅ COMPATIBLE";
|
|
216
|
+
console.log(`\n API Versioning: ${badge} (${score}/100)\n ───────────────────────────`);
|
|
217
|
+
if (baseline)
|
|
218
|
+
console.log(` 📋 Baseline detected: ${baseline}`);
|
|
219
|
+
else
|
|
220
|
+
console.log(" ⚠️ No API baseline file — consider adding openapi.yaml or api-baseline.json");
|
|
221
|
+
if (allIssues.length === 0) {
|
|
222
|
+
console.log("\n No versioning issues detected.\n");
|
|
223
|
+
return;
|
|
224
|
+
}
|
|
225
|
+
for (const issue of allIssues) {
|
|
226
|
+
const icon = issue.severity === "critical" ? "🚫" : issue.severity === "high" ? "🔴" : "🟡";
|
|
227
|
+
console.log(` ${icon} [${issue.severity.toUpperCase()}] ${issue.issue}`);
|
|
228
|
+
console.log(` ${issue.file}:${issue.line}`);
|
|
229
|
+
console.log(` ${issue.detail}`);
|
|
230
|
+
}
|
|
231
|
+
console.log(`\n Total: ${allIssues.length} | Critical: ${critCount} | High: ${highCount} | Score: ${score}/100\n`);
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
//# sourceMappingURL=api-versioning-audit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api-versioning-audit.js","sourceRoot":"","sources":["../../src/commands/api-versioning-audit.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"boundary-enforce.d.ts","sourceRoot":"","sources":["../../src/commands/boundary-enforce.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAqNH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CAqFvD"}
|
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Boundary enforce — validate architectural module boundaries and enforce
|
|
3
|
+
* import/dependency rules.
|
|
4
|
+
*/
|
|
5
|
+
import { readFileSync, readdirSync, statSync, existsSync } from "fs";
|
|
6
|
+
import { join, extname, relative, dirname } from "path";
|
|
7
|
+
// ─── File Collection ────────────────────────────────────────────────────────
|
|
8
|
+
const CODE_EXTS = new Set([".ts", ".tsx", ".js", ".jsx", ".py", ".java", ".go", ".rs"]);
|
|
9
|
+
function collectFiles(dir, max = 400) {
|
|
10
|
+
const files = [];
|
|
11
|
+
function walk(d) {
|
|
12
|
+
if (files.length >= max)
|
|
13
|
+
return;
|
|
14
|
+
let entries;
|
|
15
|
+
try {
|
|
16
|
+
entries = readdirSync(d);
|
|
17
|
+
}
|
|
18
|
+
catch {
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
for (const e of entries) {
|
|
22
|
+
if (files.length >= max)
|
|
23
|
+
return;
|
|
24
|
+
if (e.startsWith(".") || e === "node_modules" || e === "dist" || e === "build")
|
|
25
|
+
continue;
|
|
26
|
+
const full = join(d, e);
|
|
27
|
+
try {
|
|
28
|
+
if (statSync(full).isDirectory())
|
|
29
|
+
walk(full);
|
|
30
|
+
else if (CODE_EXTS.has(extname(full)))
|
|
31
|
+
files.push(full);
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
/* skip */
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
walk(dir);
|
|
39
|
+
return files;
|
|
40
|
+
}
|
|
41
|
+
// ─── Boundary Definition ────────────────────────────────────────────────────
|
|
42
|
+
function loadBoundaryConfig(dir) {
|
|
43
|
+
const configPath = join(dir, ".boundaries.json");
|
|
44
|
+
if (existsSync(configPath)) {
|
|
45
|
+
try {
|
|
46
|
+
const content = readFileSync(configPath, "utf-8");
|
|
47
|
+
return JSON.parse(content);
|
|
48
|
+
}
|
|
49
|
+
catch {
|
|
50
|
+
/* fall through */
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
55
|
+
function inferLayers(dir) {
|
|
56
|
+
const rules = [];
|
|
57
|
+
// Common architectural layers
|
|
58
|
+
const layerHierarchy = [
|
|
59
|
+
{ dirs: ["domain", "core", "model", "entities"], level: 0 },
|
|
60
|
+
{ dirs: ["application", "services", "use-cases", "usecases"], level: 1 },
|
|
61
|
+
{ dirs: ["infrastructure", "infra", "adapters", "repositories"], level: 2 },
|
|
62
|
+
{ dirs: ["presentation", "ui", "views", "pages", "components"], level: 3 },
|
|
63
|
+
{ dirs: ["api", "controllers", "routes", "handlers"], level: 3 },
|
|
64
|
+
];
|
|
65
|
+
const foundLayers = [];
|
|
66
|
+
let entries;
|
|
67
|
+
try {
|
|
68
|
+
entries = readdirSync(dir);
|
|
69
|
+
}
|
|
70
|
+
catch {
|
|
71
|
+
return rules;
|
|
72
|
+
}
|
|
73
|
+
for (const e of entries) {
|
|
74
|
+
const full = join(dir, e);
|
|
75
|
+
try {
|
|
76
|
+
if (!statSync(full).isDirectory())
|
|
77
|
+
continue;
|
|
78
|
+
}
|
|
79
|
+
catch {
|
|
80
|
+
continue;
|
|
81
|
+
}
|
|
82
|
+
for (const lh of layerHierarchy) {
|
|
83
|
+
if (lh.dirs.includes(e.toLowerCase())) {
|
|
84
|
+
foundLayers.push({ name: e, level: lh.level });
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
// Inner layers should not depend on outer layers
|
|
89
|
+
for (const layer of foundLayers) {
|
|
90
|
+
const allowed = foundLayers.filter((l) => l.level <= layer.level).map((l) => l.name);
|
|
91
|
+
rules.push({ layer: layer.name, allowedDeps: allowed });
|
|
92
|
+
}
|
|
93
|
+
return rules;
|
|
94
|
+
}
|
|
95
|
+
// ─── Analysis ───────────────────────────────────────────────────────────────
|
|
96
|
+
function getLayer(filepath, dir) {
|
|
97
|
+
const rel = relative(dir, filepath).replace(/\\/g, "/");
|
|
98
|
+
const parts = rel.split("/");
|
|
99
|
+
return parts.length > 1 ? parts[0] : null;
|
|
100
|
+
}
|
|
101
|
+
function analyzeImports(filepath, dir, rules) {
|
|
102
|
+
const violations = [];
|
|
103
|
+
const fromLayer = getLayer(filepath, dir);
|
|
104
|
+
if (!fromLayer)
|
|
105
|
+
return violations;
|
|
106
|
+
const rule = rules.find((r) => r.layer === fromLayer);
|
|
107
|
+
if (!rule)
|
|
108
|
+
return violations;
|
|
109
|
+
let content;
|
|
110
|
+
try {
|
|
111
|
+
content = readFileSync(filepath, "utf-8");
|
|
112
|
+
}
|
|
113
|
+
catch {
|
|
114
|
+
return violations;
|
|
115
|
+
}
|
|
116
|
+
const lines = content.split("\n");
|
|
117
|
+
const importRegex = /(?:import|from)\s+['"]([^'"]+)['"]/g;
|
|
118
|
+
for (let i = 0; i < lines.length; i++) {
|
|
119
|
+
let match;
|
|
120
|
+
importRegex.lastIndex = 0;
|
|
121
|
+
while ((match = importRegex.exec(lines[i])) !== null) {
|
|
122
|
+
const importPath = match[1];
|
|
123
|
+
if (!importPath.startsWith("."))
|
|
124
|
+
continue; // Skip external modules
|
|
125
|
+
const resolved = join(dirname(filepath), importPath).replace(/\\/g, "/");
|
|
126
|
+
const importedRel = relative(dir, resolved).replace(/\\/g, "/");
|
|
127
|
+
const toLayer = importedRel.split("/")[0];
|
|
128
|
+
if (toLayer && toLayer !== fromLayer && !rule.allowedDeps.includes(toLayer)) {
|
|
129
|
+
violations.push({
|
|
130
|
+
file: relative(dir, filepath).replace(/\\/g, "/"),
|
|
131
|
+
line: i + 1,
|
|
132
|
+
from: fromLayer,
|
|
133
|
+
to: toLayer,
|
|
134
|
+
severity: "high",
|
|
135
|
+
detail: `${fromLayer} → ${toLayer} violates boundary (allowed: ${rule.allowedDeps.join(", ")})`,
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
return violations;
|
|
141
|
+
}
|
|
142
|
+
// Additional heuristic checks
|
|
143
|
+
function checkCommonViolations(filepath, dir) {
|
|
144
|
+
const violations = [];
|
|
145
|
+
const rel = relative(dir, filepath).replace(/\\/g, "/");
|
|
146
|
+
let content;
|
|
147
|
+
try {
|
|
148
|
+
content = readFileSync(filepath, "utf-8");
|
|
149
|
+
}
|
|
150
|
+
catch {
|
|
151
|
+
return violations;
|
|
152
|
+
}
|
|
153
|
+
const lines = content.split("\n");
|
|
154
|
+
for (let i = 0; i < lines.length; i++) {
|
|
155
|
+
const line = lines[i];
|
|
156
|
+
// UI importing DB/ORM directly
|
|
157
|
+
if (/\b(?:components?|pages?|views?|ui)\//i.test(rel)) {
|
|
158
|
+
if (/(?:prisma|sequelize|typeorm|mongoose|knex|pg\b|mysql|sqlite)/i.test(line) && /import|require/.test(line)) {
|
|
159
|
+
violations.push({
|
|
160
|
+
file: rel,
|
|
161
|
+
line: i + 1,
|
|
162
|
+
from: "UI",
|
|
163
|
+
to: "Database",
|
|
164
|
+
severity: "high",
|
|
165
|
+
detail: "UI layer importing database library directly — use a service/repository layer",
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
// Test code importing test internals from src
|
|
170
|
+
if (/\b(?:src|lib)\//i.test(rel) && !/__test__|\.test\.|\.spec\./i.test(rel)) {
|
|
171
|
+
if (/import.*(?:jest|vitest|mocha|chai|sinon)/.test(line) && !/devDependencies/.test(line)) {
|
|
172
|
+
violations.push({
|
|
173
|
+
file: rel,
|
|
174
|
+
line: i + 1,
|
|
175
|
+
from: "source",
|
|
176
|
+
to: "test-framework",
|
|
177
|
+
severity: "medium",
|
|
178
|
+
detail: "Production code importing test framework",
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
return violations;
|
|
184
|
+
}
|
|
185
|
+
// ─── CLI ────────────────────────────────────────────────────────────────────
|
|
186
|
+
export function runBoundaryEnforce(argv) {
|
|
187
|
+
if (argv.includes("--help") || argv.includes("-h")) {
|
|
188
|
+
console.log(`
|
|
189
|
+
judges boundary-enforce — Validate architectural module boundaries
|
|
190
|
+
|
|
191
|
+
Usage:
|
|
192
|
+
judges boundary-enforce [dir]
|
|
193
|
+
judges boundary-enforce src/ --format json
|
|
194
|
+
|
|
195
|
+
Options:
|
|
196
|
+
[dir] Directory to scan (default: .)
|
|
197
|
+
--format json JSON output
|
|
198
|
+
--help, -h Show this help
|
|
199
|
+
|
|
200
|
+
Config: Create .boundaries.json with rules:
|
|
201
|
+
[{"layer": "domain", "allowedDeps": ["domain"]},
|
|
202
|
+
{"layer": "services", "allowedDeps": ["domain", "services"]}]
|
|
203
|
+
|
|
204
|
+
Without config, layers are inferred from directory structure.
|
|
205
|
+
`);
|
|
206
|
+
return;
|
|
207
|
+
}
|
|
208
|
+
const format = argv.find((_a, i) => argv[i - 1] === "--format") || "text";
|
|
209
|
+
const dir = argv.find((a) => !a.startsWith("-") && argv.indexOf(a) > 0) || ".";
|
|
210
|
+
const configRules = loadBoundaryConfig(dir);
|
|
211
|
+
const rules = configRules || inferLayers(dir);
|
|
212
|
+
const usingConfig = configRules !== null;
|
|
213
|
+
const files = collectFiles(dir);
|
|
214
|
+
const violations = [];
|
|
215
|
+
for (const f of files) {
|
|
216
|
+
violations.push(...analyzeImports(f, dir, rules));
|
|
217
|
+
violations.push(...checkCommonViolations(f, dir));
|
|
218
|
+
}
|
|
219
|
+
const score = Math.max(0, 100 - violations.length * 5);
|
|
220
|
+
if (format === "json") {
|
|
221
|
+
console.log(JSON.stringify({
|
|
222
|
+
violations,
|
|
223
|
+
rules,
|
|
224
|
+
usingConfig,
|
|
225
|
+
score,
|
|
226
|
+
summary: { files: files.length, violations: violations.length, layers: rules.length },
|
|
227
|
+
timestamp: new Date().toISOString(),
|
|
228
|
+
}, null, 2));
|
|
229
|
+
}
|
|
230
|
+
else {
|
|
231
|
+
const badge = violations.length === 0 ? "✅ CLEAN" : violations.length <= 3 ? "⚠️ MINOR" : "❌ ERODED";
|
|
232
|
+
console.log(`\n Boundary Enforcement: ${badge} (${score}/100)\n ──────────────────────────────`);
|
|
233
|
+
console.log(` Config: ${usingConfig ? ".boundaries.json" : "inferred from directories"} | Layers: ${rules.length} | Files: ${files.length}\n`);
|
|
234
|
+
if (rules.length > 0) {
|
|
235
|
+
console.log(" Layers:");
|
|
236
|
+
for (const r of rules) {
|
|
237
|
+
console.log(` 📦 ${r.layer} → can depend on: ${r.allowedDeps.join(", ")}`);
|
|
238
|
+
}
|
|
239
|
+
console.log();
|
|
240
|
+
}
|
|
241
|
+
if (violations.length === 0) {
|
|
242
|
+
console.log(" No boundary violations detected.\n");
|
|
243
|
+
return;
|
|
244
|
+
}
|
|
245
|
+
for (const v of violations.slice(0, 20)) {
|
|
246
|
+
const icon = v.severity === "high" ? "🔴" : v.severity === "medium" ? "🟡" : "🔵";
|
|
247
|
+
console.log(` ${icon} ${v.from} → ${v.to}`);
|
|
248
|
+
console.log(` ${v.file}:${v.line}`);
|
|
249
|
+
console.log(` ${v.detail}`);
|
|
250
|
+
}
|
|
251
|
+
if (violations.length > 20)
|
|
252
|
+
console.log(` ... and ${violations.length - 20} more`);
|
|
253
|
+
console.log(`\n Violations: ${violations.length} | Score: ${score}/100\n`);
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
//# sourceMappingURL=boundary-enforce.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"boundary-enforce.js","sourceRoot":"","sources":["../../src/commands/boundary-enforce.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error-taxonomy.d.ts","sourceRoot":"","sources":["../../src/commands/error-taxonomy.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAqMH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CAyErD"}
|