@archpilotlabs/archpilot 0.2.1 → 0.2.2
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/dist/archpilot-cli.js +521 -237
- package/package.json +1 -1
package/dist/archpilot-cli.js
CHANGED
|
@@ -140818,9 +140818,9 @@ ${lanes.join("\n")}
|
|
|
140818
140818
|
/*ignoreCase*/
|
|
140819
140819
|
false
|
|
140820
140820
|
)) {
|
|
140821
|
-
const
|
|
140822
|
-
if (
|
|
140823
|
-
const name = removeSuffix(removePrefix(
|
|
140821
|
+
const basename9 = getBaseFileName(a.fileName);
|
|
140822
|
+
if (basename9 === "lib.d.ts" || basename9 === "lib.es6.d.ts") return 0;
|
|
140823
|
+
const name = removeSuffix(removePrefix(basename9, "lib."), ".d.ts");
|
|
140824
140824
|
const index = libs.indexOf(name);
|
|
140825
140825
|
if (index !== -1) return index + 1;
|
|
140826
140826
|
}
|
|
@@ -204566,8 +204566,8 @@ ${options.prefix}` : "\n" : options.prefix
|
|
|
204566
204566
|
}
|
|
204567
204567
|
};
|
|
204568
204568
|
for (const file of files) {
|
|
204569
|
-
const
|
|
204570
|
-
if (
|
|
204569
|
+
const basename9 = getBaseFileName(file);
|
|
204570
|
+
if (basename9 === "package.json" || basename9 === "bower.json") {
|
|
204571
204571
|
createProjectWatcher(
|
|
204572
204572
|
file,
|
|
204573
204573
|
"FileWatcher"
|
|
@@ -208239,8 +208239,8 @@ All files are: ${JSON.stringify(names)}`,
|
|
|
208239
208239
|
var _a;
|
|
208240
208240
|
const fileOrDirectoryPath = removeIgnoredPath(this.toPath(fileOrDirectory));
|
|
208241
208241
|
if (!fileOrDirectoryPath) return;
|
|
208242
|
-
const
|
|
208243
|
-
if (((_a = result.affectedModuleSpecifierCacheProjects) == null ? void 0 : _a.size) && (
|
|
208242
|
+
const basename9 = getBaseFileName(fileOrDirectoryPath);
|
|
208243
|
+
if (((_a = result.affectedModuleSpecifierCacheProjects) == null ? void 0 : _a.size) && (basename9 === "package.json" || basename9 === "node_modules")) {
|
|
208244
208244
|
result.affectedModuleSpecifierCacheProjects.forEach((project) => {
|
|
208245
208245
|
var _a2;
|
|
208246
208246
|
(_a2 = project.getModuleSpecifierCache()) == null ? void 0 : _a2.clear();
|
|
@@ -215396,15 +215396,83 @@ var init_architectureDependencyContext = __esm({
|
|
|
215396
215396
|
}
|
|
215397
215397
|
});
|
|
215398
215398
|
|
|
215399
|
+
// ../core/src/sourceScopeClassification.ts
|
|
215400
|
+
function normalizePath3(value) {
|
|
215401
|
+
return value.replace(/\\/g, "/").toLowerCase();
|
|
215402
|
+
}
|
|
215403
|
+
function hasPathSegment(pathValue, pattern) {
|
|
215404
|
+
return pathValue.split("/").some((segment) => pattern.test(segment));
|
|
215405
|
+
}
|
|
215406
|
+
function hasTopLevelPathSegment(pathValue, pattern) {
|
|
215407
|
+
const [firstSegment] = pathValue.split("/");
|
|
215408
|
+
return !!firstSegment && pattern.test(firstSegment);
|
|
215409
|
+
}
|
|
215410
|
+
function classifyValidationSourceScope(relativePath) {
|
|
215411
|
+
const normalized = normalizePath3(relativePath);
|
|
215412
|
+
const fileName = normalized.split("/").at(-1) ?? normalized;
|
|
215413
|
+
const extension = fileName.includes(".") ? fileName.slice(fileName.lastIndexOf(".")) : "";
|
|
215414
|
+
const isTestFile = /\.(?:spec|test|e2e-spec|integration-test)\.(?:ts|tsx|js|jsx|mjs|cjs|java|cs|py|php|go)$/u.test(fileName);
|
|
215415
|
+
const isE2e = isTestFile && /(?:^|[./_-])e2e(?:[./_-]|$)/u.test(fileName) || hasPathSegment(normalized, /^e2e$/u);
|
|
215416
|
+
const isFixture = hasPathSegment(normalized, /^(?:fixtures?|__fixtures__)$/u);
|
|
215417
|
+
const isTestPlugin = hasPathSegment(normalized, /^(?:test-plugins?|testing-plugins?)$/u);
|
|
215418
|
+
const isExamplePlugin = hasPathSegment(normalized, /^example-plugins?$/u) || hasTopLevelPathSegment(normalized, /^examples?$/u);
|
|
215419
|
+
const isGenerated = hasPathSegment(normalized, /^(?:generated|__generated__|gen|templates?)$/u) || /\.(?:generated|gen|g)\.(?:ts|tsx|js|jsx|java|cs|py|php|go)$/u.test(fileName) || /\.d\.ts$/u.test(fileName);
|
|
215420
|
+
const isMigration = hasPathSegment(normalized, /^(?:migrations?|schema-migrations?|data-migrations|migration-utils?)$/u);
|
|
215421
|
+
const isCliTooling = hasPathSegment(normalized, /^(?:cli|bin|scripts?|tools?|scaffold|scaffolding|generators?)$/u) || /(?:^|[./_-])(?:cli|script|tool|generator|scaffold)(?:[./_-]|$)/u.test(fileName);
|
|
215422
|
+
const isFrontend = extension === ".tsx" || extension === ".jsx" || hasPathSegment(normalized, /^(?:frontend|client|browser|ui|admin-ui|dashboard|web-app)$/u) || /\b(?:react|angular|vue|svelte)\b/u.test(normalized);
|
|
215423
|
+
const isInfrastructure = hasPathSegment(normalized, /^(?:infrastructure|infra|framework|adapters?|persistence|providers?)$/u) || /(?:transactional-connection|transaction-wrapper|transaction-subscriber|transaction-manager|query-runner|query-builder|event-bus|telemetry|interceptor)\.(?:ts|js|java|cs|py|php|go)$/u.test(fileName);
|
|
215424
|
+
let category = "production-backend";
|
|
215425
|
+
if (isGenerated) {
|
|
215426
|
+
category = "generated";
|
|
215427
|
+
} else if (isE2e) {
|
|
215428
|
+
category = "e2e";
|
|
215429
|
+
} else if (isTestFile || hasPathSegment(normalized, /^(?:test|tests|__tests__|spec|specs|__mocks__|cypress|cypress-tests)$/u)) {
|
|
215430
|
+
category = "test";
|
|
215431
|
+
} else if (isTestPlugin) {
|
|
215432
|
+
category = "test-plugin";
|
|
215433
|
+
} else if (isExamplePlugin) {
|
|
215434
|
+
category = "example-plugin";
|
|
215435
|
+
} else if (isFixture) {
|
|
215436
|
+
category = "fixture";
|
|
215437
|
+
} else if (isMigration) {
|
|
215438
|
+
category = "migration";
|
|
215439
|
+
} else if (isCliTooling) {
|
|
215440
|
+
category = "cli-tooling";
|
|
215441
|
+
} else if (isFrontend) {
|
|
215442
|
+
category = "production-frontend";
|
|
215443
|
+
} else if (isInfrastructure) {
|
|
215444
|
+
category = "infrastructure";
|
|
215445
|
+
}
|
|
215446
|
+
const isTestLike = category === "test" || category === "e2e" || category === "fixture" || category === "test-plugin" || category === "example-plugin";
|
|
215447
|
+
return {
|
|
215448
|
+
category,
|
|
215449
|
+
isProduction: category === "production-backend" || category === "production-frontend" || category === "infrastructure",
|
|
215450
|
+
isFrontend: category === "production-frontend",
|
|
215451
|
+
isTestLike,
|
|
215452
|
+
isGenerated: category === "generated",
|
|
215453
|
+
isMigration: category === "migration",
|
|
215454
|
+
isCliTooling: category === "cli-tooling",
|
|
215455
|
+
isInfrastructure: category === "infrastructure"
|
|
215456
|
+
};
|
|
215457
|
+
}
|
|
215458
|
+
function isProductionBackendGovernanceScope(scope) {
|
|
215459
|
+
return scope.category === "production-backend";
|
|
215460
|
+
}
|
|
215461
|
+
var init_sourceScopeClassification = __esm({
|
|
215462
|
+
"../core/src/sourceScopeClassification.ts"() {
|
|
215463
|
+
"use strict";
|
|
215464
|
+
}
|
|
215465
|
+
});
|
|
215466
|
+
|
|
215399
215467
|
// ../core/src/dependencyValidation.ts
|
|
215400
|
-
function
|
|
215468
|
+
function normalizePath4(filePath) {
|
|
215401
215469
|
return filePath.replace(/\\/g, "/");
|
|
215402
215470
|
}
|
|
215403
215471
|
function toSafeContractModuleFileStem(moduleName) {
|
|
215404
|
-
return
|
|
215472
|
+
return normalizePath4(moduleName).split("/").map((segment) => segment.trim()).filter((segment) => segment.length > 0).join(".");
|
|
215405
215473
|
}
|
|
215406
215474
|
function normalizeAbsolutePath(filePath) {
|
|
215407
|
-
return
|
|
215475
|
+
return normalizePath4(path7.resolve(filePath)).toLowerCase();
|
|
215408
215476
|
}
|
|
215409
215477
|
function isPathInsideOrEqual2(childPath, parentPath) {
|
|
215410
215478
|
const child = normalizeAbsolutePath(childPath);
|
|
@@ -215442,7 +215510,7 @@ function getComponentModuleRoots(workspaceRoot, architectureContract) {
|
|
|
215442
215510
|
}
|
|
215443
215511
|
const typed = value;
|
|
215444
215512
|
const componentId = typeof typed.id === "string" && typed.id.trim().length > 0 ? typed.id.trim() : typeof key === "string" && key.trim().length > 0 ? key.trim() : void 0;
|
|
215445
|
-
const componentPath = typeof typed.path === "string" && typed.path.trim().length > 0 ?
|
|
215513
|
+
const componentPath = typeof typed.path === "string" && typed.path.trim().length > 0 ? normalizePath4(typed.path.trim()) : void 0;
|
|
215446
215514
|
if (!componentId || !componentPath || componentPath === ".") {
|
|
215447
215515
|
continue;
|
|
215448
215516
|
}
|
|
@@ -215642,7 +215710,7 @@ async function buildTsConfigPathAliasMap(workspaceRoot, moduleRoots) {
|
|
|
215642
215710
|
continue;
|
|
215643
215711
|
}
|
|
215644
215712
|
const isWildcard = /\/\*$/u.test(aliasPattern) && /\/\*$/u.test(targetPattern);
|
|
215645
|
-
const normalizedTarget =
|
|
215713
|
+
const normalizedTarget = normalizePath4(targetPattern).replace(/\/\*$/u, "");
|
|
215646
215714
|
const absoluteTarget = path7.join(workspaceRoot, ...normalizedTarget.split("/"));
|
|
215647
215715
|
const moduleEntry = [...moduleRoots.entries()].filter(([, moduleRoot2]) => isPathInsideOrEqual2(absoluteTarget, moduleRoot2)).sort((left, right) => right[1].length - left[1].length || left[0].localeCompare(right[0]))[0];
|
|
215648
215716
|
if (!moduleEntry) {
|
|
@@ -215745,7 +215813,7 @@ async function findModuleRoots(workspaceRoot, modulesRootRelativePath = "src/mod
|
|
|
215745
215813
|
if (!configuredPath || typeof configuredPath !== "string") {
|
|
215746
215814
|
continue;
|
|
215747
215815
|
}
|
|
215748
|
-
const normalizedConfiguredPath =
|
|
215816
|
+
const normalizedConfiguredPath = normalizePath4(configuredPath);
|
|
215749
215817
|
if (/\.[a-z0-9]+$/iu.test(normalizedConfiguredPath)) {
|
|
215750
215818
|
continue;
|
|
215751
215819
|
}
|
|
@@ -215853,7 +215921,7 @@ async function buildExplicitStandaloneModulePathMap(workspaceRoot, architectureC
|
|
|
215853
215921
|
if (!configuredPath || typeof configuredPath !== "string") {
|
|
215854
215922
|
continue;
|
|
215855
215923
|
}
|
|
215856
|
-
const normalizedConfiguredPath =
|
|
215924
|
+
const normalizedConfiguredPath = normalizePath4(configuredPath);
|
|
215857
215925
|
if (!/\.[a-z0-9]+$/iu.test(normalizedConfiguredPath)) {
|
|
215858
215926
|
continue;
|
|
215859
215927
|
}
|
|
@@ -215869,11 +215937,7 @@ async function buildExplicitStandaloneModulePathMap(workspaceRoot, architectureC
|
|
|
215869
215937
|
return map;
|
|
215870
215938
|
}
|
|
215871
215939
|
function isTestSourcePath(relativePath) {
|
|
215872
|
-
|
|
215873
|
-
if (normalized.includes("/__tests__/") || normalized.includes("/test/") || normalized.includes("/tests/") || normalized.includes("/__mocks__/")) {
|
|
215874
|
-
return true;
|
|
215875
|
-
}
|
|
215876
|
-
return /(^|\/)[^/]+\.(test|spec)\.[cm]?[jt]sx?$/u.test(normalized);
|
|
215940
|
+
return classifyValidationSourceScope(relativePath).isTestLike;
|
|
215877
215941
|
}
|
|
215878
215942
|
async function collectSourceFiles(directoryPath, adapter, scanRootPath = directoryPath, excludedDirectoryRoots = []) {
|
|
215879
215943
|
const entries = await import_node_fs6.promises.readdir(directoryPath, { withFileTypes: true });
|
|
@@ -215887,7 +215951,7 @@ async function collectSourceFiles(directoryPath, adapter, scanRootPath = directo
|
|
|
215887
215951
|
)) {
|
|
215888
215952
|
continue;
|
|
215889
215953
|
}
|
|
215890
|
-
const normalizedRelativeDirectory =
|
|
215954
|
+
const normalizedRelativeDirectory = normalizePath4(
|
|
215891
215955
|
path7.relative(scanRootPath, fullPath)
|
|
215892
215956
|
);
|
|
215893
215957
|
if (adapter.ignoreDirectoryNames.includes(entry.name) || adapter.ignoreDirectoryNames.includes(normalizedRelativeDirectory)) {
|
|
@@ -216098,6 +216162,80 @@ function extractGoImportSpecifiers(sourceText) {
|
|
|
216098
216162
|
return left.specifier.localeCompare(right.specifier);
|
|
216099
216163
|
});
|
|
216100
216164
|
}
|
|
216165
|
+
function extractJavaPackageName(sourceText) {
|
|
216166
|
+
const match = /^\s*package\s+([a-zA-Z_][\w.]*)\s*;/mu.exec(sourceText);
|
|
216167
|
+
return match?.[1];
|
|
216168
|
+
}
|
|
216169
|
+
async function buildJavaImportIndex(workspaceRoot, moduleRoots, adapter) {
|
|
216170
|
+
const classes = /* @__PURE__ */ new Map();
|
|
216171
|
+
const packageCandidates = /* @__PURE__ */ new Map();
|
|
216172
|
+
for (const [moduleId, moduleRoot] of [...moduleRoots.entries()].sort(
|
|
216173
|
+
([left], [right]) => left.localeCompare(right)
|
|
216174
|
+
)) {
|
|
216175
|
+
const childModuleRoots = [...moduleRoots.entries()].filter(([childModuleName, childModuleRoot]) => childModuleName !== moduleId && isPathInsideOrEqual2(childModuleRoot, moduleRoot)).map(([, childModuleRoot]) => childModuleRoot);
|
|
216176
|
+
const sourceFiles = await collectSourceFiles(moduleRoot, adapter, moduleRoot, childModuleRoots);
|
|
216177
|
+
for (const sourceFilePath of sourceFiles) {
|
|
216178
|
+
const relativePath = normalizePath4(path7.relative(workspaceRoot, sourceFilePath));
|
|
216179
|
+
if (isTestSourcePath(relativePath)) {
|
|
216180
|
+
continue;
|
|
216181
|
+
}
|
|
216182
|
+
const sourceText = await readTextFileIfExists2(sourceFilePath);
|
|
216183
|
+
if (!sourceText) {
|
|
216184
|
+
continue;
|
|
216185
|
+
}
|
|
216186
|
+
const packageName = extractJavaPackageName(sourceText);
|
|
216187
|
+
if (!packageName) {
|
|
216188
|
+
continue;
|
|
216189
|
+
}
|
|
216190
|
+
const className = path7.basename(sourceFilePath, path7.extname(sourceFilePath));
|
|
216191
|
+
const entry = { moduleId, resolvedPath: sourceFilePath };
|
|
216192
|
+
classes.set(`${packageName}.${className}`, entry);
|
|
216193
|
+
const existing = packageCandidates.get(packageName) ?? [];
|
|
216194
|
+
existing.push(entry);
|
|
216195
|
+
packageCandidates.set(packageName, existing);
|
|
216196
|
+
}
|
|
216197
|
+
}
|
|
216198
|
+
const packages = /* @__PURE__ */ new Map();
|
|
216199
|
+
for (const [packageName, entries] of packageCandidates) {
|
|
216200
|
+
const moduleIds = new Set(entries.map((entry) => entry.moduleId));
|
|
216201
|
+
packages.set(packageName, moduleIds.size === 1 ? entries[0] : "ambiguous");
|
|
216202
|
+
}
|
|
216203
|
+
return { classes, packages };
|
|
216204
|
+
}
|
|
216205
|
+
function resolveJavaImportFromIndex(importSpecifier, index, workspaceRoot) {
|
|
216206
|
+
if (!index) {
|
|
216207
|
+
return void 0;
|
|
216208
|
+
}
|
|
216209
|
+
if (importSpecifier.endsWith(".*")) {
|
|
216210
|
+
const packageName = importSpecifier.slice(0, -2);
|
|
216211
|
+
const entry = index.packages.get(packageName);
|
|
216212
|
+
if (!entry || entry === "ambiguous") {
|
|
216213
|
+
return void 0;
|
|
216214
|
+
}
|
|
216215
|
+
return {
|
|
216216
|
+
targetModule: entry.moduleId,
|
|
216217
|
+
resolvedRelativePath: normalizePath4(path7.relative(workspaceRoot, entry.resolvedPath)),
|
|
216218
|
+
isPublicImport: false
|
|
216219
|
+
};
|
|
216220
|
+
}
|
|
216221
|
+
const exactEntry = index.classes.get(importSpecifier);
|
|
216222
|
+
if (exactEntry) {
|
|
216223
|
+
return {
|
|
216224
|
+
targetModule: exactEntry.moduleId,
|
|
216225
|
+
resolvedRelativePath: normalizePath4(path7.relative(workspaceRoot, exactEntry.resolvedPath)),
|
|
216226
|
+
isPublicImport: false
|
|
216227
|
+
};
|
|
216228
|
+
}
|
|
216229
|
+
const ownerCandidate = [...index.classes.entries()].filter(([classImport]) => importSpecifier.startsWith(`${classImport}.`)).sort((left, right) => right[0].length - left[0].length || left[0].localeCompare(right[0]))[0];
|
|
216230
|
+
if (!ownerCandidate) {
|
|
216231
|
+
return void 0;
|
|
216232
|
+
}
|
|
216233
|
+
return {
|
|
216234
|
+
targetModule: ownerCandidate[1].moduleId,
|
|
216235
|
+
resolvedRelativePath: normalizePath4(path7.relative(workspaceRoot, ownerCandidate[1].resolvedPath)),
|
|
216236
|
+
isPublicImport: false
|
|
216237
|
+
};
|
|
216238
|
+
}
|
|
216101
216239
|
function extractPythonImportSpecifiers(sourceText) {
|
|
216102
216240
|
const imports = [];
|
|
216103
216241
|
const lines = sourceText.split(/\r?\n/u);
|
|
@@ -216200,7 +216338,7 @@ function resolveJavaModuleImport(modulesRootRelativePath, moduleRoots, importSpe
|
|
|
216200
216338
|
const lastSegment = segments[segments.length - 1];
|
|
216201
216339
|
const defaultEntrypointFileName = adapter.scaffoldingDefaults?.moduleIndexFileName ?? "Application.java";
|
|
216202
216340
|
const resolvedFileName = lastSegment === "*" ? defaultEntrypointFileName : lastSegment.endsWith(".java") ? lastSegment : `${lastSegment}.java`;
|
|
216203
|
-
const resolvedRelativePath =
|
|
216341
|
+
const resolvedRelativePath = normalizePath4(
|
|
216204
216342
|
`${modulesRootRelativePath}/${targetModule}/${resolvedFileName}`
|
|
216205
216343
|
);
|
|
216206
216344
|
return {
|
|
@@ -216538,13 +216676,17 @@ async function resolveWorkspacePackageImportTarget(importSpecifier, workspacePac
|
|
|
216538
216676
|
}
|
|
216539
216677
|
return void 0;
|
|
216540
216678
|
}
|
|
216541
|
-
async function resolveCrossModuleImport(workspaceRoot, modulesRootRelativePath, moduleRoots, explicitStandaloneModuleByPath, workspacePackageAliases, sourceFilePath, importSpecifier, adapter, resolutionContext) {
|
|
216679
|
+
async function resolveCrossModuleImport(workspaceRoot, modulesRootRelativePath, moduleRoots, explicitStandaloneModuleByPath, workspacePackageAliases, sourceFilePath, importSpecifier, adapter, javaImportIndex, resolutionContext) {
|
|
216542
216680
|
const candidateBasePaths = [];
|
|
216543
216681
|
let packageAliasTargetModule;
|
|
216544
216682
|
let packageAliasTargetModuleRoot;
|
|
216545
216683
|
let isPublicPackageAliasImport = false;
|
|
216546
|
-
const normalizedModulesRoot =
|
|
216684
|
+
const normalizedModulesRoot = normalizePath4(modulesRootRelativePath).replace(/^\/+/, "");
|
|
216547
216685
|
if (usesJavaImportParser(adapter) && !importSpecifier.startsWith(".")) {
|
|
216686
|
+
const indexedJava = resolveJavaImportFromIndex(importSpecifier, javaImportIndex, workspaceRoot);
|
|
216687
|
+
if (indexedJava) {
|
|
216688
|
+
return indexedJava;
|
|
216689
|
+
}
|
|
216548
216690
|
const resolvedJava = resolveJavaModuleImport(
|
|
216549
216691
|
normalizedModulesRoot,
|
|
216550
216692
|
moduleRoots,
|
|
@@ -216641,19 +216783,19 @@ async function resolveCrossModuleImport(workspaceRoot, modulesRootRelativePath,
|
|
|
216641
216783
|
const targetModuleEntry = packageAliasTargetModule && packageAliasTargetModuleRoot ? [packageAliasTargetModule, packageAliasTargetModuleRoot] : [...moduleRoots.entries()].filter(([, moduleRoot]) => isPathInsideOrEqual2(resolvedPath, moduleRoot)).sort((left, right) => right[1].length - left[1].length || left[0].localeCompare(right[0]))[0];
|
|
216642
216784
|
if (!targetModuleEntry) {
|
|
216643
216785
|
const standaloneTargetModule = explicitStandaloneModuleByPath.get(
|
|
216644
|
-
|
|
216786
|
+
normalizePath4(path7.relative(workspaceRoot, resolvedPath))
|
|
216645
216787
|
);
|
|
216646
216788
|
if (!standaloneTargetModule) {
|
|
216647
216789
|
return void 0;
|
|
216648
216790
|
}
|
|
216649
216791
|
return {
|
|
216650
216792
|
targetModule: standaloneTargetModule,
|
|
216651
|
-
resolvedRelativePath:
|
|
216793
|
+
resolvedRelativePath: normalizePath4(path7.relative(workspaceRoot, resolvedPath)),
|
|
216652
216794
|
isPublicImport: true
|
|
216653
216795
|
};
|
|
216654
216796
|
}
|
|
216655
216797
|
const [targetModule, targetModuleRoot] = targetModuleEntry;
|
|
216656
|
-
const targetSubPath =
|
|
216798
|
+
const targetSubPath = normalizePath4(path7.relative(targetModuleRoot, resolvedPath));
|
|
216657
216799
|
if (targetSubPath === "" || targetSubPath.startsWith("../") || targetSubPath.startsWith("..\\")) {
|
|
216658
216800
|
return void 0;
|
|
216659
216801
|
}
|
|
@@ -216669,7 +216811,7 @@ async function resolveCrossModuleImport(workspaceRoot, modulesRootRelativePath,
|
|
|
216669
216811
|
);
|
|
216670
216812
|
return {
|
|
216671
216813
|
targetModule,
|
|
216672
|
-
resolvedRelativePath:
|
|
216814
|
+
resolvedRelativePath: normalizePath4(path7.relative(workspaceRoot, resolvedPath)),
|
|
216673
216815
|
isPublicImport,
|
|
216674
216816
|
...isPublicPackageAliasImport ? { isPackagePublicImport: true } : {}
|
|
216675
216817
|
};
|
|
@@ -216680,6 +216822,7 @@ async function collectCrossModuleImports(workspaceRoot, modulesRootRelativePath,
|
|
|
216680
216822
|
if (!supportsDependencyImportParsing(adapter)) {
|
|
216681
216823
|
return imports;
|
|
216682
216824
|
}
|
|
216825
|
+
const javaImportIndex = usesJavaImportParser(adapter) ? await buildJavaImportIndex(workspaceRoot, moduleRoots, adapter) : void 0;
|
|
216683
216826
|
for (const [moduleName, moduleRoot] of [...moduleRoots.entries()].sort(
|
|
216684
216827
|
([left], [right]) => left.localeCompare(right)
|
|
216685
216828
|
)) {
|
|
@@ -216691,7 +216834,7 @@ async function collectCrossModuleImports(workspaceRoot, modulesRootRelativePath,
|
|
|
216691
216834
|
childModuleRoots
|
|
216692
216835
|
);
|
|
216693
216836
|
for (const sourceFilePath of sourceFiles) {
|
|
216694
|
-
const sourceFileRelativePath =
|
|
216837
|
+
const sourceFileRelativePath = normalizePath4(
|
|
216695
216838
|
path7.relative(workspaceRoot, sourceFilePath)
|
|
216696
216839
|
);
|
|
216697
216840
|
if (!includeTestFiles && isTestSourcePath(sourceFileRelativePath)) {
|
|
@@ -216716,6 +216859,7 @@ async function collectCrossModuleImports(workspaceRoot, modulesRootRelativePath,
|
|
|
216716
216859
|
sourceFilePath,
|
|
216717
216860
|
importReference.specifier,
|
|
216718
216861
|
adapter,
|
|
216862
|
+
javaImportIndex,
|
|
216719
216863
|
options?.resolutionContext
|
|
216720
216864
|
);
|
|
216721
216865
|
if (!resolved || resolved.targetModule === moduleName) {
|
|
@@ -216956,7 +217100,7 @@ function buildDependencyConfigSkippedFindings(reason, options) {
|
|
|
216956
217100
|
return findings;
|
|
216957
217101
|
}
|
|
216958
217102
|
function normalizePathList(values) {
|
|
216959
|
-
return values.map((value) =>
|
|
217103
|
+
return values.map((value) => normalizePath4(value)).sort((left, right) => left.localeCompare(right));
|
|
216960
217104
|
}
|
|
216961
217105
|
function normalizeModuleContract(contractLike) {
|
|
216962
217106
|
if (typeof contractLike.module !== "string") {
|
|
@@ -217059,7 +217203,7 @@ function buildContractSkipMessage(ruleId, sourceModule, targetModule, sourceCont
|
|
|
217059
217203
|
)}.`;
|
|
217060
217204
|
}
|
|
217061
217205
|
function isImportWithinPublicEntrypoints(resolvedTargetRelativePath, publicEntrypoints) {
|
|
217062
|
-
const normalizedTargetPath =
|
|
217206
|
+
const normalizedTargetPath = normalizePath4(resolvedTargetRelativePath);
|
|
217063
217207
|
for (const publicEntrypoint of normalizePathList(publicEntrypoints)) {
|
|
217064
217208
|
const isFileEntrypoint = /\.[a-z0-9]+$/iu.test(publicEntrypoint);
|
|
217065
217209
|
if (isFileEntrypoint && normalizedTargetPath === publicEntrypoint) {
|
|
@@ -217106,17 +217250,18 @@ async function inferExistingPublicEntrypointsFromModuleRoot(workspaceRoot, modul
|
|
|
217106
217250
|
const candidatePath = path7.join(moduleRoot, ...candidateSubpath.split("/"));
|
|
217107
217251
|
if (await pathExists4(candidatePath)) {
|
|
217108
217252
|
existingEntrypoints.push(
|
|
217109
|
-
|
|
217253
|
+
normalizePath4(path7.relative(workspaceRoot, candidatePath))
|
|
217110
217254
|
);
|
|
217111
217255
|
}
|
|
217112
217256
|
}
|
|
217113
217257
|
return existingEntrypoints.sort((left, right) => left.localeCompare(right));
|
|
217114
217258
|
}
|
|
217115
|
-
async function
|
|
217116
|
-
const registryPublicEntrypoints = architectureContract
|
|
217259
|
+
async function resolveKnownModulePublicEntrypoints(workspaceRoot, architectureContract, moduleName, targetContract, moduleRoots, adapter) {
|
|
217260
|
+
const registryPublicEntrypoints = architectureContract?.modules[moduleName]?.publicEntrypoints ?? [];
|
|
217261
|
+
const contractPublicEntrypoints = targetContract?.publicEntrypoints ?? [];
|
|
217117
217262
|
const explicitPublicEntrypoints = sortUnique2([
|
|
217118
217263
|
...registryPublicEntrypoints,
|
|
217119
|
-
...
|
|
217264
|
+
...contractPublicEntrypoints
|
|
217120
217265
|
]);
|
|
217121
217266
|
const existingExplicitEntrypoints = await filterExistingPublicEntrypoints(
|
|
217122
217267
|
workspaceRoot,
|
|
@@ -217125,13 +217270,16 @@ async function resolveModulePublicEntrypoints(workspaceRoot, architectureContrac
|
|
|
217125
217270
|
if (existingExplicitEntrypoints.length > 0) {
|
|
217126
217271
|
return existingExplicitEntrypoints;
|
|
217127
217272
|
}
|
|
217273
|
+
if (usesJavaImportParser(adapter)) {
|
|
217274
|
+
return [];
|
|
217275
|
+
}
|
|
217128
217276
|
return inferExistingPublicEntrypointsFromModuleRoot(
|
|
217129
217277
|
workspaceRoot,
|
|
217130
217278
|
moduleRoots.get(moduleName)
|
|
217131
217279
|
);
|
|
217132
217280
|
}
|
|
217133
217281
|
function labelPublicEntrypoint(publicEntrypoint) {
|
|
217134
|
-
const normalizedEntrypoint =
|
|
217282
|
+
const normalizedEntrypoint = normalizePath4(publicEntrypoint);
|
|
217135
217283
|
const fileName = normalizedEntrypoint.split("/").at(-1) ?? "";
|
|
217136
217284
|
return /^index\.[cm]?[jt]sx?$/iu.test(fileName) ? `${fileName} public entrypoint` : "public entrypoint";
|
|
217137
217285
|
}
|
|
@@ -217151,7 +217299,7 @@ async function describeModulePublicImportGuidance(workspaceRoot, moduleName, mod
|
|
|
217151
217299
|
return `Use the public entrypoint at ${describePublicEntrypointTargets(inferredEntrypoints)} instead.`;
|
|
217152
217300
|
}
|
|
217153
217301
|
if (moduleRoot) {
|
|
217154
|
-
return `Use an existing public entrypoint under ${
|
|
217302
|
+
return `Use an existing public entrypoint under ${normalizePath4(path7.relative(workspaceRoot, moduleRoot))} instead.`;
|
|
217155
217303
|
}
|
|
217156
217304
|
return "Use an existing target module public entrypoint instead.";
|
|
217157
217305
|
}
|
|
@@ -217548,12 +217696,13 @@ async function validateDependencyContractBoundaries(workspaceRoot, architectureC
|
|
|
217548
217696
|
}
|
|
217549
217697
|
continue;
|
|
217550
217698
|
}
|
|
217551
|
-
const publicEntrypoints = await
|
|
217699
|
+
const publicEntrypoints = await resolveKnownModulePublicEntrypoints(
|
|
217552
217700
|
workspaceRoot,
|
|
217553
217701
|
architectureContract,
|
|
217554
217702
|
dependencyImport.targetModule,
|
|
217555
217703
|
targetContract.contract,
|
|
217556
|
-
moduleRoots
|
|
217704
|
+
moduleRoots,
|
|
217705
|
+
adapter
|
|
217557
217706
|
);
|
|
217558
217707
|
if (publicEntrypoints.length === 0) {
|
|
217559
217708
|
continue;
|
|
@@ -217737,6 +217886,7 @@ async function validateDependencyBoundaries(workspaceRoot, options) {
|
|
|
217737
217886
|
(dependencyImport) => isModuleScopedDependencyImport(parsedArchitectureContract, dependencyImport)
|
|
217738
217887
|
);
|
|
217739
217888
|
const findings = [];
|
|
217889
|
+
const moduleContractCache = /* @__PURE__ */ new Map();
|
|
217740
217890
|
let dependencyRules;
|
|
217741
217891
|
let dependencyRulesSkipReason;
|
|
217742
217892
|
if (options.dependencyRulesConfigOverride) {
|
|
@@ -217853,19 +218003,49 @@ async function validateDependencyBoundaries(workspaceRoot, options) {
|
|
|
217853
218003
|
})
|
|
217854
218004
|
);
|
|
217855
218005
|
} else {
|
|
217856
|
-
const violations =
|
|
218006
|
+
const violations = [];
|
|
218007
|
+
for (const dependencyImport of moduleScopedPeerImports) {
|
|
217857
218008
|
if (parsedArchitectureContract) {
|
|
217858
218009
|
const dependencyMetadata = resolveImportDependencyContextMetadata(
|
|
217859
218010
|
parsedArchitectureContract,
|
|
217860
218011
|
dependencyImport
|
|
217861
218012
|
);
|
|
217862
218013
|
if (dependencyMetadata.isExternal) {
|
|
217863
|
-
|
|
218014
|
+
continue;
|
|
217864
218015
|
}
|
|
217865
218016
|
}
|
|
217866
218017
|
const moduleRules = dependencyRules.modules[dependencyImport.sourceModule];
|
|
217867
|
-
|
|
217868
|
-
|
|
218018
|
+
if (moduleRules?.publicEntrypointsOnly !== true || dependencyImport.isPublicImport) {
|
|
218019
|
+
continue;
|
|
218020
|
+
}
|
|
218021
|
+
if (dependencyImport.isPackagePublicImport === true) {
|
|
218022
|
+
continue;
|
|
218023
|
+
}
|
|
218024
|
+
const targetContract = parsedArchitectureContract ? await loadModuleArchitectureContract(
|
|
218025
|
+
workspaceRoot,
|
|
218026
|
+
parsedArchitectureContract,
|
|
218027
|
+
dependencyImport.targetModule,
|
|
218028
|
+
moduleContractCache
|
|
218029
|
+
) : void 0;
|
|
218030
|
+
const publicEntrypoints = await resolveKnownModulePublicEntrypoints(
|
|
218031
|
+
workspaceRoot,
|
|
218032
|
+
parsedArchitectureContract,
|
|
218033
|
+
dependencyImport.targetModule,
|
|
218034
|
+
targetContract?.contract,
|
|
218035
|
+
moduleRoots,
|
|
218036
|
+
adapter
|
|
218037
|
+
);
|
|
218038
|
+
if (publicEntrypoints.length === 0) {
|
|
218039
|
+
continue;
|
|
218040
|
+
}
|
|
218041
|
+
if (isImportWithinPublicEntrypoints(
|
|
218042
|
+
dependencyImport.resolvedTargetRelativePath,
|
|
218043
|
+
publicEntrypoints
|
|
218044
|
+
)) {
|
|
218045
|
+
continue;
|
|
218046
|
+
}
|
|
218047
|
+
violations.push(dependencyImport);
|
|
218048
|
+
}
|
|
217869
218049
|
if (violations.length === 0) {
|
|
217870
218050
|
findings.push({
|
|
217871
218051
|
result: makeValidationResult(
|
|
@@ -218014,6 +218194,7 @@ var init_dependencyValidation = __esm({
|
|
|
218014
218194
|
init_architectureDependencyContext();
|
|
218015
218195
|
init_moduleDiscovery();
|
|
218016
218196
|
init_stackAdapters();
|
|
218197
|
+
init_sourceScopeClassification();
|
|
218017
218198
|
dependencyRulesConfigFile = ".archpilot/dependency-rules.json";
|
|
218018
218199
|
DependencyRulesConfigError = class extends Error {
|
|
218019
218200
|
};
|
|
@@ -218021,7 +218202,7 @@ var init_dependencyValidation = __esm({
|
|
|
218021
218202
|
});
|
|
218022
218203
|
|
|
218023
218204
|
// ../core/src/moduleScope.ts
|
|
218024
|
-
function
|
|
218205
|
+
function normalizePath5(value) {
|
|
218025
218206
|
return value.replace(/\\/g, "/").replace(/^\.\/+/u, "").replace(/\/+$/u, "").toLowerCase();
|
|
218026
218207
|
}
|
|
218027
218208
|
function pathExists5(targetPath) {
|
|
@@ -218074,7 +218255,7 @@ function hasJsxEnabled(configPath) {
|
|
|
218074
218255
|
return typeof jsx === "string" && jsx.trim().length > 0;
|
|
218075
218256
|
}
|
|
218076
218257
|
function listPathSegments(modulePath) {
|
|
218077
|
-
return
|
|
218258
|
+
return normalizePath5(modulePath).split("/").filter((entry) => entry.length > 0);
|
|
218078
218259
|
}
|
|
218079
218260
|
function getCandidateRoots(workspaceRoot, modulePath) {
|
|
218080
218261
|
const resolvedWorkspaceRoot = path8.resolve(workspaceRoot);
|
|
@@ -218406,9 +218587,12 @@ var init_moduleScope = __esm({
|
|
|
218406
218587
|
});
|
|
218407
218588
|
|
|
218408
218589
|
// ../core/src/smartInit/moduleDetection.ts
|
|
218409
|
-
function
|
|
218590
|
+
function normalizePath6(value) {
|
|
218410
218591
|
return value.replaceAll("\\", "/");
|
|
218411
218592
|
}
|
|
218593
|
+
function isUnderJvmResourceRoot(relativePath) {
|
|
218594
|
+
return /(^|\/)src\/main\/resources(?:\/|$)/u.test(normalizePath6(relativePath).toLowerCase());
|
|
218595
|
+
}
|
|
218412
218596
|
function safeReadDirEntries(directoryPath) {
|
|
218413
218597
|
try {
|
|
218414
218598
|
return fs8.readdirSync(directoryPath, { withFileTypes: true });
|
|
@@ -218425,7 +218609,7 @@ function pathExists6(pathValue) {
|
|
|
218425
218609
|
}
|
|
218426
218610
|
}
|
|
218427
218611
|
function isIgnoredPath(context, relativePath) {
|
|
218428
|
-
return context?.ignoreMatcher?.isIgnored(
|
|
218612
|
+
return context?.ignoreMatcher?.isIgnored(normalizePath6(relativePath)) ?? false;
|
|
218429
218613
|
}
|
|
218430
218614
|
function uniqueSorted(values) {
|
|
218431
218615
|
return [...new Set(values)].sort((left, right) => left.localeCompare(right));
|
|
@@ -218440,15 +218624,15 @@ function normalizeIdentity(value) {
|
|
|
218440
218624
|
return value.toLowerCase().replace(/[^a-z0-9]+/gu, "");
|
|
218441
218625
|
}
|
|
218442
218626
|
function pathLeafIdentity(value) {
|
|
218443
|
-
const normalized =
|
|
218627
|
+
const normalized = normalizePath6(value).replace(/\/+$/gu, "");
|
|
218444
218628
|
const leaf = normalized.split("/").filter((segment) => segment.length > 0).at(-1) ?? normalized;
|
|
218445
218629
|
return normalizeIdentity(leaf);
|
|
218446
218630
|
}
|
|
218447
218631
|
function getComponentAlignedEvidence(input2) {
|
|
218448
|
-
const modulePath =
|
|
218632
|
+
const modulePath = normalizePath6(input2.modulePath).replace(/\/+$/gu, "");
|
|
218449
218633
|
const moduleNameIdentity = normalizeIdentity(input2.moduleName);
|
|
218450
218634
|
const modulePathLeaf = pathLeafIdentity(modulePath);
|
|
218451
|
-
const matchingPath = input2.context?.componentPaths?.map((entry) =>
|
|
218635
|
+
const matchingPath = input2.context?.componentPaths?.map((entry) => normalizePath6(entry).replace(/\/+$/gu, "")).find(
|
|
218452
218636
|
(componentPath) => componentPath.length > 0 && componentPath !== "." && (componentPath === modulePath || componentPath.startsWith(`${modulePath}/`))
|
|
218453
218637
|
);
|
|
218454
218638
|
if (matchingPath) {
|
|
@@ -218458,7 +218642,7 @@ function getComponentAlignedEvidence(input2) {
|
|
|
218458
218642
|
if (matchingName) {
|
|
218459
218643
|
return `Matches detected component/service/app identity ${input2.moduleName}`;
|
|
218460
218644
|
}
|
|
218461
|
-
const matchingResourcePath = input2.context?.resourcePaths?.map((entry) =>
|
|
218645
|
+
const matchingResourcePath = input2.context?.resourcePaths?.map((entry) => normalizePath6(entry).replace(/\/+$/gu, "")).find(
|
|
218462
218646
|
(resourcePath) => resourcePath.length > 0 && resourcePath !== "." && (resourcePath === modulePath || resourcePath.startsWith(`${modulePath}/`))
|
|
218463
218647
|
);
|
|
218464
218648
|
if (matchingResourcePath) {
|
|
@@ -218638,6 +218822,9 @@ function containsAppRouteFiles(absolutePath) {
|
|
|
218638
218822
|
return false;
|
|
218639
218823
|
}
|
|
218640
218824
|
function makeDetectedModule(workspaceRoot, moduleName, modulePath, rootPath, hasSourceFiles, hasRoleFiles, sourceFileCount, context) {
|
|
218825
|
+
if (isUnderJvmResourceRoot(modulePath)) {
|
|
218826
|
+
return void 0;
|
|
218827
|
+
}
|
|
218641
218828
|
const evidence = [];
|
|
218642
218829
|
if (hasSourceFiles) {
|
|
218643
218830
|
evidence.push("Contains source files");
|
|
@@ -218696,11 +218883,14 @@ function collectModuleCandidatesFromRoot(workspaceRoot, modulesRootRelative, def
|
|
|
218696
218883
|
const rootLower = modulesRootRelative.toLowerCase();
|
|
218697
218884
|
const skipFrontendUtilities = rootLower === "src/features" || rootLower.endsWith("/src/features") || rootLower === "app" || rootLower === "src/app" || rootLower.endsWith("/app") || rootLower.endsWith("/src/app");
|
|
218698
218885
|
const entries = safeReadDirEntries(absoluteRoot).filter(
|
|
218699
|
-
(entry) => entry.isDirectory() && !ignoredDirectoryNames.has(entry.name) && !isIgnoredPath(context,
|
|
218886
|
+
(entry) => entry.isDirectory() && !ignoredDirectoryNames.has(entry.name) && !isIgnoredPath(context, normalizePath6(`${modulesRootRelative}/${entry.name}`))
|
|
218700
218887
|
).sort((left, right) => left.name.localeCompare(right.name));
|
|
218701
218888
|
const modules = [];
|
|
218702
218889
|
for (const entry of entries) {
|
|
218703
|
-
const candidateProjectRoot =
|
|
218890
|
+
const candidateProjectRoot = normalizePath6(`${modulesRootRelative}/${entry.name}`);
|
|
218891
|
+
if (isUnderJvmResourceRoot(candidateProjectRoot)) {
|
|
218892
|
+
continue;
|
|
218893
|
+
}
|
|
218704
218894
|
if (["apps", "packages", "services", "libs"].includes(rootLower) && (context?.projectRoots?.length ?? 0) > 0 && !context?.projectRoots?.includes(candidateProjectRoot)) {
|
|
218705
218895
|
continue;
|
|
218706
218896
|
}
|
|
@@ -218717,7 +218907,7 @@ function collectModuleCandidatesFromRoot(workspaceRoot, modulesRootRelative, def
|
|
|
218717
218907
|
const detected = makeDetectedModule(
|
|
218718
218908
|
workspaceRoot,
|
|
218719
218909
|
moduleName,
|
|
218720
|
-
|
|
218910
|
+
normalizePath6(`${modulesRootRelative}/${entry.name}`),
|
|
218721
218911
|
modulesRootRelative,
|
|
218722
218912
|
inspected.hasSourceFiles,
|
|
218723
218913
|
inspected.hasRoleFiles,
|
|
@@ -218740,7 +218930,7 @@ function collectAppRouteModules(workspaceRoot, appRootRelative, context) {
|
|
|
218740
218930
|
return [];
|
|
218741
218931
|
}
|
|
218742
218932
|
const entries = safeReadDirEntries(absoluteRoot).filter(
|
|
218743
|
-
(entry) => entry.isDirectory() && !ignoredDirectoryNames.has(entry.name) && !isIgnoredPath(context,
|
|
218933
|
+
(entry) => entry.isDirectory() && !ignoredDirectoryNames.has(entry.name) && !isIgnoredPath(context, normalizePath6(`${appRootRelative}/${entry.name}`))
|
|
218744
218934
|
).sort((left, right) => left.name.localeCompare(right.name));
|
|
218745
218935
|
const modules = [];
|
|
218746
218936
|
for (const entry of entries) {
|
|
@@ -218754,7 +218944,7 @@ function collectAppRouteModules(workspaceRoot, appRootRelative, context) {
|
|
|
218754
218944
|
if (!moduleName || frontendUtilityDirectoryNames.has(moduleName.toLowerCase())) {
|
|
218755
218945
|
continue;
|
|
218756
218946
|
}
|
|
218757
|
-
const moduleRelativePath =
|
|
218947
|
+
const moduleRelativePath = normalizePath6(`${appRootRelative}/${rawName}`);
|
|
218758
218948
|
const moduleAbsolutePath = path9.join(absoluteRoot, rawName);
|
|
218759
218949
|
if (!containsAppRouteFiles(moduleAbsolutePath)) {
|
|
218760
218950
|
continue;
|
|
@@ -218881,14 +219071,14 @@ function collectJavaPackageRoots(workspaceRoot, context) {
|
|
|
218881
219071
|
continue;
|
|
218882
219072
|
}
|
|
218883
219073
|
for (const entry of safeReadDirEntries(current.absolutePath)) {
|
|
218884
|
-
const childRelativePath =
|
|
219074
|
+
const childRelativePath = normalizePath6(`${current.relativePath}/${entry.name}`);
|
|
218885
219075
|
if (!entry.isDirectory() || ignoredDirectoryNames.has(entry.name) || isIgnoredPath(context, childRelativePath)) {
|
|
218886
219076
|
continue;
|
|
218887
219077
|
}
|
|
218888
219078
|
const lowerName = entry.name.toLowerCase();
|
|
218889
219079
|
if (lowerName === "modules" || lowerName === "features") {
|
|
218890
219080
|
const childCount = safeReadDirEntries(path9.join(current.absolutePath, entry.name)).filter(
|
|
218891
|
-
(child) => child.isDirectory() && !ignoredDirectoryNames.has(child.name) && !isIgnoredPath(context,
|
|
219081
|
+
(child) => child.isDirectory() && !ignoredDirectoryNames.has(child.name) && !isIgnoredPath(context, normalizePath6(`${childRelativePath}/${child.name}`))
|
|
218892
219082
|
).length;
|
|
218893
219083
|
if (childCount >= 2) {
|
|
218894
219084
|
roots.push(childRelativePath);
|
|
@@ -218947,10 +219137,10 @@ function detectModules(workspaceRoot, options) {
|
|
|
218947
219137
|
projectKinds: options?.projectKinds,
|
|
218948
219138
|
stacks: options?.stacks,
|
|
218949
219139
|
ignoreMatcher: options?.ignoreMatcher,
|
|
218950
|
-
projectRoots: options?.projectRoots?.map(
|
|
218951
|
-
componentPaths: options?.componentPaths?.map(
|
|
219140
|
+
projectRoots: options?.projectRoots?.map(normalizePath6),
|
|
219141
|
+
componentPaths: options?.componentPaths?.map(normalizePath6),
|
|
218952
219142
|
componentNames: options?.componentNames,
|
|
218953
|
-
resourcePaths: options?.resourcePaths?.map(
|
|
219143
|
+
resourcePaths: options?.resourcePaths?.map(normalizePath6),
|
|
218954
219144
|
resourceNames: options?.resourceNames
|
|
218955
219145
|
};
|
|
218956
219146
|
const explicitRoots = collectExplicitRoots(workspaceRoot, context);
|
|
@@ -219028,7 +219218,7 @@ function detectModules(workspaceRoot, options) {
|
|
|
219028
219218
|
};
|
|
219029
219219
|
}
|
|
219030
219220
|
function detectModuleCandidatesForRoot(workspaceRoot, modulesRootRelative, options) {
|
|
219031
|
-
const normalizedRoot =
|
|
219221
|
+
const normalizedRoot = normalizePath6(modulesRootRelative.trim()).replace(/^\/+|\/+$/gu, "");
|
|
219032
219222
|
if (normalizedRoot.length === 0) {
|
|
219033
219223
|
return [];
|
|
219034
219224
|
}
|
|
@@ -219040,10 +219230,10 @@ function detectModuleCandidatesForRoot(workspaceRoot, modulesRootRelative, optio
|
|
|
219040
219230
|
projectKinds: options?.projectKinds,
|
|
219041
219231
|
stacks: options?.stacks,
|
|
219042
219232
|
ignoreMatcher: options?.ignoreMatcher,
|
|
219043
|
-
projectRoots: options?.projectRoots?.map(
|
|
219044
|
-
componentPaths: options?.componentPaths?.map(
|
|
219233
|
+
projectRoots: options?.projectRoots?.map(normalizePath6),
|
|
219234
|
+
componentPaths: options?.componentPaths?.map(normalizePath6),
|
|
219045
219235
|
componentNames: options?.componentNames,
|
|
219046
|
-
resourcePaths: options?.resourcePaths?.map(
|
|
219236
|
+
resourcePaths: options?.resourcePaths?.map(normalizePath6),
|
|
219047
219237
|
resourceNames: options?.resourceNames
|
|
219048
219238
|
}
|
|
219049
219239
|
);
|
|
@@ -219084,6 +219274,7 @@ var init_moduleDetection = __esm({
|
|
|
219084
219274
|
"scripts",
|
|
219085
219275
|
"test",
|
|
219086
219276
|
"tests",
|
|
219277
|
+
"cypress-tests",
|
|
219087
219278
|
"__tests__",
|
|
219088
219279
|
"fixtures",
|
|
219089
219280
|
"docs",
|
|
@@ -219307,7 +219498,7 @@ var init_moduleDetection = __esm({
|
|
|
219307
219498
|
});
|
|
219308
219499
|
|
|
219309
219500
|
// ../core/src/architectureMap.ts
|
|
219310
|
-
function
|
|
219501
|
+
function normalizePath7(value) {
|
|
219311
219502
|
return value.replace(/\\/g, "/");
|
|
219312
219503
|
}
|
|
219313
219504
|
async function pathExists7(targetPath) {
|
|
@@ -219329,7 +219520,7 @@ function sortUnique3(values) {
|
|
|
219329
219520
|
return [...new Set(values)].sort((left, right) => left.localeCompare(right));
|
|
219330
219521
|
}
|
|
219331
219522
|
function toSafeContractModuleFileStem2(moduleName) {
|
|
219332
|
-
return
|
|
219523
|
+
return normalizePath7(moduleName).split("/").map((segment) => segment.trim()).filter((segment) => segment.length > 0).join(".");
|
|
219333
219524
|
}
|
|
219334
219525
|
function getModuleRegistry(contract) {
|
|
219335
219526
|
const modules = contract?.modules;
|
|
@@ -219374,7 +219565,7 @@ function hasExplicitModuleRegistry(config) {
|
|
|
219374
219565
|
);
|
|
219375
219566
|
}
|
|
219376
219567
|
function normalizePublicEntrypointList(entries) {
|
|
219377
|
-
return sortUnique3(entries.map((entry) =>
|
|
219568
|
+
return sortUnique3(entries.map((entry) => normalizePath7(entry.trim())).filter((entry) => entry.length > 0));
|
|
219378
219569
|
}
|
|
219379
219570
|
function hasConfiguredPublicEntrypoint(registryEntry) {
|
|
219380
219571
|
return Array.isArray(registryEntry?.publicEntrypoints) && registryEntry.publicEntrypoints.some(
|
|
@@ -219484,10 +219675,10 @@ function parseCycleString(cycle) {
|
|
|
219484
219675
|
}
|
|
219485
219676
|
async function discoverModulesFromArchitectureContract(workspaceRoot, contract, modulesRoot) {
|
|
219486
219677
|
const moduleRegistry = getModuleRegistry(contract);
|
|
219487
|
-
const normalizedModulesRoot =
|
|
219488
|
-
const contractsRoot =
|
|
219678
|
+
const normalizedModulesRoot = normalizePath7(modulesRoot);
|
|
219679
|
+
const contractsRoot = normalizePath7(contract.structure.contractsRoot ?? ".archpilot/contracts");
|
|
219489
219680
|
const discovered = [];
|
|
219490
|
-
const toContractPath = (moduleName, registryEntry) =>
|
|
219681
|
+
const toContractPath = (moduleName, registryEntry) => normalizePath7(
|
|
219491
219682
|
typeof registryEntry?.contract === "string" ? registryEntry.contract : `${contractsRoot}/${toSafeContractModuleFileStem2(moduleName)}.contract.json`
|
|
219492
219683
|
);
|
|
219493
219684
|
const resolveMissingPublicEntrypointAlignment = async (registryEntry, contractPath) => {
|
|
@@ -219515,7 +219706,7 @@ async function discoverModulesFromArchitectureContract(workspaceRoot, contract,
|
|
|
219515
219706
|
if (!registryEntry.path || typeof registryEntry.path !== "string") {
|
|
219516
219707
|
continue;
|
|
219517
219708
|
}
|
|
219518
|
-
const normalizedSourcePath =
|
|
219709
|
+
const normalizedSourcePath = normalizePath7(registryEntry.path);
|
|
219519
219710
|
const absoluteSourcePath = path10.join(workspaceRoot, ...normalizedSourcePath.split("/"));
|
|
219520
219711
|
let sourcePathExists = false;
|
|
219521
219712
|
let sourceIsDirectory = false;
|
|
@@ -219531,7 +219722,7 @@ async function discoverModulesFromArchitectureContract(workspaceRoot, contract,
|
|
|
219531
219722
|
if (!sourceIsDirectory && !sourceIsFile) {
|
|
219532
219723
|
continue;
|
|
219533
219724
|
}
|
|
219534
|
-
const contractPath =
|
|
219725
|
+
const contractPath = normalizePath7(
|
|
219535
219726
|
typeof registryEntry.contract === "string" ? registryEntry.contract : `${contractsRoot}/${toSafeContractModuleFileStem2(moduleName)}.contract.json`
|
|
219536
219727
|
);
|
|
219537
219728
|
const contractExists = await pathExists7(path10.join(workspaceRoot, ...contractPath.split("/")));
|
|
@@ -219615,7 +219806,7 @@ function getComponentEntries(contract) {
|
|
|
219615
219806
|
}
|
|
219616
219807
|
const typed = value;
|
|
219617
219808
|
const componentId = typeof typed.id === "string" && typed.id.trim().length > 0 ? typed.id.trim() : typeof key === "string" && key.trim().length > 0 ? key.trim() : void 0;
|
|
219618
|
-
const sourcePath = typeof typed.path === "string" && typed.path.trim().length > 0 ?
|
|
219809
|
+
const sourcePath = typeof typed.path === "string" && typed.path.trim().length > 0 ? normalizePath7(typed.path.trim()) : void 0;
|
|
219619
219810
|
if (!componentId || !sourcePath || sourcePath === ".") {
|
|
219620
219811
|
continue;
|
|
219621
219812
|
}
|
|
@@ -219740,7 +219931,7 @@ async function generateArchitectureMap(workspaceRoot, options) {
|
|
|
219740
219931
|
const shouldUseConfiguredRootInference = hasArchitectureJson && !contractHasConfiguredModules && !hasExplicitEmptyModuleRegistry && hasExplicitModuleRootConfig(rawArchitectureConfig);
|
|
219741
219932
|
const shouldUseTopLevelWorkspaceInference = hasArchitectureJson && !contractHasConfiguredModules && !hasExplicitEmptyModuleRegistry && !shouldUseConfiguredRootInference;
|
|
219742
219933
|
const discoveryMode = hasArchitectureJson ? "architecture-json" : "inferred-src-modules";
|
|
219743
|
-
const modulesRoot =
|
|
219934
|
+
const modulesRoot = normalizePath7(
|
|
219744
219935
|
await resolveConfiguredModulesRoot(
|
|
219745
219936
|
workspaceRoot,
|
|
219746
219937
|
resolveModulesRootFromContract(contract)
|
|
@@ -220638,7 +220829,7 @@ var init_archpilotIgnore = __esm({
|
|
|
220638
220829
|
});
|
|
220639
220830
|
|
|
220640
220831
|
// ../core/src/moduleContractsGenerator.ts
|
|
220641
|
-
function
|
|
220832
|
+
function normalizePath8(value) {
|
|
220642
220833
|
return value.replace(/\\/g, "/");
|
|
220643
220834
|
}
|
|
220644
220835
|
function toAbsolutePath(workspaceRoot, relativePath) {
|
|
@@ -220656,7 +220847,7 @@ function sortUnique4(values) {
|
|
|
220656
220847
|
return [...new Set(values)].sort((left, right) => left.localeCompare(right));
|
|
220657
220848
|
}
|
|
220658
220849
|
function toSafeContractModuleFileStem3(moduleName) {
|
|
220659
|
-
return
|
|
220850
|
+
return normalizePath8(moduleName).split("/").map((segment) => segment.trim()).filter((segment) => segment.length > 0).join(".");
|
|
220660
220851
|
}
|
|
220661
220852
|
function wildcardToRegex(pattern) {
|
|
220662
220853
|
const escaped = pattern.replace(/[.+?^${}()|[\]\\]/g, "\\$&");
|
|
@@ -220670,14 +220861,14 @@ function getModuleRegistry2(contract) {
|
|
|
220670
220861
|
return modules;
|
|
220671
220862
|
}
|
|
220672
220863
|
async function inferModulePublicEntrypoints(workspaceRoot, moduleSourcePath, adapter) {
|
|
220673
|
-
const normalizedSourcePath =
|
|
220864
|
+
const normalizedSourcePath = normalizePath8(moduleSourcePath);
|
|
220674
220865
|
if (/\.[a-z0-9]+$/iu.test(normalizedSourcePath)) {
|
|
220675
220866
|
const absoluteSourcePath = toAbsolutePath(workspaceRoot, normalizedSourcePath);
|
|
220676
220867
|
if (await pathExists8(absoluteSourcePath)) {
|
|
220677
220868
|
return [normalizedSourcePath];
|
|
220678
220869
|
}
|
|
220679
220870
|
}
|
|
220680
|
-
const candidateFiles = adapter.defaultEntrypointHints.map((hint) =>
|
|
220871
|
+
const candidateFiles = adapter.defaultEntrypointHints.map((hint) => normalizePath8(hint)).filter((hint) => !hint.includes("/"));
|
|
220681
220872
|
const exactCandidates = candidateFiles.filter((hint) => !hint.includes("*"));
|
|
220682
220873
|
const wildcardCandidates = candidateFiles.filter((hint) => hint.includes("*"));
|
|
220683
220874
|
const resolvedWildcardCandidates = [];
|
|
@@ -220712,10 +220903,6 @@ async function inferModulePublicEntrypoints(workspaceRoot, moduleSourcePath, ada
|
|
|
220712
220903
|
break;
|
|
220713
220904
|
}
|
|
220714
220905
|
}
|
|
220715
|
-
if (inferred.length === 0) {
|
|
220716
|
-
const fallbackName = adapter.scaffoldingDefaults?.moduleIndexFileName ?? orderedCandidates.find((entry) => entry.startsWith("index.")) ?? "index.ts";
|
|
220717
|
-
inferred.push(`${normalizedSourcePath}/${fallbackName}`);
|
|
220718
|
-
}
|
|
220719
220906
|
return sortUnique4(inferred);
|
|
220720
220907
|
}
|
|
220721
220908
|
function buildDependsOnBySource(edges) {
|
|
@@ -220736,9 +220923,9 @@ function resolveContractPath(contract, moduleName) {
|
|
|
220736
220923
|
const moduleRegistry = getModuleRegistry2(contract);
|
|
220737
220924
|
const configured = moduleRegistry[moduleName]?.contract;
|
|
220738
220925
|
if (configured && configured.trim().length > 0) {
|
|
220739
|
-
return
|
|
220926
|
+
return normalizePath8(configured);
|
|
220740
220927
|
}
|
|
220741
|
-
return
|
|
220928
|
+
return normalizePath8(
|
|
220742
220929
|
path15.posix.join(
|
|
220743
220930
|
resolveContractsRootFromContract(contract),
|
|
220744
220931
|
`${toSafeContractModuleFileStem3(moduleName)}.contract.json`
|
|
@@ -220769,7 +220956,7 @@ async function readExistingModuleContractPublicEntrypoints(workspaceRoot, contra
|
|
|
220769
220956
|
if (parsed.publicEntrypoints.some((entry) => typeof entry !== "string")) {
|
|
220770
220957
|
return void 0;
|
|
220771
220958
|
}
|
|
220772
|
-
return sortUnique4(parsed.publicEntrypoints.map((entry) =>
|
|
220959
|
+
return sortUnique4(parsed.publicEntrypoints.map((entry) => normalizePath8(entry)));
|
|
220773
220960
|
} catch {
|
|
220774
220961
|
return void 0;
|
|
220775
220962
|
}
|
|
@@ -220832,14 +221019,14 @@ async function generateMissingModuleContracts(workspaceRoot) {
|
|
|
220832
221019
|
(left, right) => left.moduleName.localeCompare(right.moduleName)
|
|
220833
221020
|
)) {
|
|
220834
221021
|
const contractPath = resolveContractPath(contract, moduleEntry.moduleName);
|
|
220835
|
-
const sourcePath =
|
|
221022
|
+
const sourcePath = normalizePath8(moduleEntry.sourcePath);
|
|
220836
221023
|
const absoluteContractPath = toAbsolutePath(workspaceRoot, contractPath);
|
|
220837
221024
|
const contractExists = await pathExists8(absoluteContractPath);
|
|
220838
221025
|
const existingContract = contractExists ? await readExistingModuleContract(workspaceRoot, contractPath) : void 0;
|
|
220839
221026
|
const existingContractPublicEntrypoints = contractExists ? await readExistingModuleContractPublicEntrypoints(workspaceRoot, contractPath) : void 0;
|
|
220840
221027
|
const configuredPublicEntrypoints = !contractExists && Array.isArray(getModuleRegistry2(contract)[moduleEntry.moduleName]?.publicEntrypoints) ? sortUnique4(
|
|
220841
221028
|
getModuleRegistry2(contract)[moduleEntry.moduleName]?.publicEntrypoints?.map(
|
|
220842
|
-
(entry) =>
|
|
221029
|
+
(entry) => normalizePath8(entry)
|
|
220843
221030
|
) ?? []
|
|
220844
221031
|
) : void 0;
|
|
220845
221032
|
const publicEntrypoints = existingContractPublicEntrypoints ?? configuredPublicEntrypoints ?? await inferModulePublicEntrypoints(
|
|
@@ -220941,7 +221128,7 @@ var bootstrapArchitectureConfig_exports = {};
|
|
|
220941
221128
|
__export(bootstrapArchitectureConfig_exports, {
|
|
220942
221129
|
bootstrapArchitectureConfig: () => bootstrapArchitectureConfig
|
|
220943
221130
|
});
|
|
220944
|
-
function
|
|
221131
|
+
function normalizePath9(value) {
|
|
220945
221132
|
return value.replace(/\\/g, "/");
|
|
220946
221133
|
}
|
|
220947
221134
|
function toAbsolutePath2(workspaceRoot, relativePath) {
|
|
@@ -221044,9 +221231,9 @@ async function bootstrapArchitectureConfig(workspaceRoot, options) {
|
|
|
221044
221231
|
}
|
|
221045
221232
|
}
|
|
221046
221233
|
return {
|
|
221047
|
-
createdFiles: sortUnique5(createdFiles.map((entry) =>
|
|
221048
|
-
ensuredDirectories: sortUnique5(ensuredDirectories.map((entry) =>
|
|
221049
|
-
skippedExistingFiles: sortUnique5(skippedExistingFiles.map((entry) =>
|
|
221234
|
+
createdFiles: sortUnique5(createdFiles.map((entry) => normalizePath9(entry))),
|
|
221235
|
+
ensuredDirectories: sortUnique5(ensuredDirectories.map((entry) => normalizePath9(entry))),
|
|
221236
|
+
skippedExistingFiles: sortUnique5(skippedExistingFiles.map((entry) => normalizePath9(entry))),
|
|
221050
221237
|
moduleCount: modules.length,
|
|
221051
221238
|
...contractGeneration ? { contractGeneration } : {},
|
|
221052
221239
|
...contractGenerationSkippedReason ? { contractGenerationSkippedReason } : {}
|
|
@@ -221871,7 +222058,15 @@ function formatArchitectureDriftSummaryMessage(areas) {
|
|
|
221871
222058
|
}
|
|
221872
222059
|
return `Architecture drift detected in ${labels.slice(0, -1).join(", ")}, and ${labels.at(-1)}.`;
|
|
221873
222060
|
}
|
|
221874
|
-
function buildArchitectureDriftSummary(results, _suppressedResults = []) {
|
|
222061
|
+
function buildArchitectureDriftSummary(results, _suppressedResults = [], options = {}) {
|
|
222062
|
+
if (options.baselineAvailable !== true) {
|
|
222063
|
+
return {
|
|
222064
|
+
detected: false,
|
|
222065
|
+
areas: [],
|
|
222066
|
+
message: "No comparison baseline available; architecture drift was not evaluated.",
|
|
222067
|
+
baselineAvailable: false
|
|
222068
|
+
};
|
|
222069
|
+
}
|
|
221875
222070
|
const activeFailedResults = results.filter(
|
|
221876
222071
|
(result) => !result.passed && result.severity !== "info"
|
|
221877
222072
|
);
|
|
@@ -221879,7 +222074,8 @@ function buildArchitectureDriftSummary(results, _suppressedResults = []) {
|
|
|
221879
222074
|
return {
|
|
221880
222075
|
detected: areas.length > 0,
|
|
221881
222076
|
areas,
|
|
221882
|
-
message: formatArchitectureDriftSummaryMessage(areas)
|
|
222077
|
+
message: formatArchitectureDriftSummaryMessage(areas),
|
|
222078
|
+
baselineAvailable: true
|
|
221883
222079
|
};
|
|
221884
222080
|
}
|
|
221885
222081
|
|
|
@@ -222179,7 +222375,7 @@ async function validateModuleContractIntegrity(workspaceRoot, contract, options)
|
|
|
222179
222375
|
var path19 = __toESM(require("node:path"));
|
|
222180
222376
|
var import_node_fs15 = require("node:fs");
|
|
222181
222377
|
var suppressionsRelativePath = ".archpilot/suppressions.json";
|
|
222182
|
-
function
|
|
222378
|
+
function normalizePath10(value) {
|
|
222183
222379
|
let normalized = value.replace(/\\/g, "/").trim();
|
|
222184
222380
|
while (normalized.startsWith("./")) {
|
|
222185
222381
|
normalized = normalized.slice(2);
|
|
@@ -222217,8 +222413,8 @@ function globToRegex(pattern) {
|
|
|
222217
222413
|
return new RegExp(expression, "u");
|
|
222218
222414
|
}
|
|
222219
222415
|
function isSuppressionPathMatch(pattern, findingPath) {
|
|
222220
|
-
const normalizedPattern =
|
|
222221
|
-
const normalizedFindingPath =
|
|
222416
|
+
const normalizedPattern = normalizePath10(pattern);
|
|
222417
|
+
const normalizedFindingPath = normalizePath10(findingPath);
|
|
222222
222418
|
if (!normalizedPattern || !normalizedFindingPath) {
|
|
222223
222419
|
return false;
|
|
222224
222420
|
}
|
|
@@ -222321,7 +222517,7 @@ async function readValidationSuppressions(workspaceRoot, knownRuleIds) {
|
|
|
222321
222517
|
ignored.push({
|
|
222322
222518
|
index,
|
|
222323
222519
|
ruleId,
|
|
222324
|
-
...entryScopeValue ? { scope:
|
|
222520
|
+
...entryScopeValue ? { scope: normalizePath10(entryScopeValue) } : {},
|
|
222325
222521
|
reason: "Unknown rule ID. Entry was ignored.",
|
|
222326
222522
|
...expiresOn ? { expiresOn } : {}
|
|
222327
222523
|
});
|
|
@@ -222330,7 +222526,7 @@ async function readValidationSuppressions(workspaceRoot, knownRuleIds) {
|
|
|
222330
222526
|
suppressions.push({
|
|
222331
222527
|
index,
|
|
222332
222528
|
ruleId,
|
|
222333
|
-
...entryScopeValue ? { scope:
|
|
222529
|
+
...entryScopeValue ? { scope: normalizePath10(entryScopeValue) } : {},
|
|
222334
222530
|
...reason ? { reason } : {},
|
|
222335
222531
|
...expiresOn ? { expiresOn } : {}
|
|
222336
222532
|
});
|
|
@@ -225107,66 +225303,8 @@ async function profileValidationPhase(label, run, details) {
|
|
|
225107
225303
|
}
|
|
225108
225304
|
}
|
|
225109
225305
|
|
|
225110
|
-
// ../core/src/sourceScopeClassification.ts
|
|
225111
|
-
function normalizePath10(value) {
|
|
225112
|
-
return value.replace(/\\/g, "/").toLowerCase();
|
|
225113
|
-
}
|
|
225114
|
-
function hasPathSegment(pathValue, pattern) {
|
|
225115
|
-
return pathValue.split("/").some((segment) => pattern.test(segment));
|
|
225116
|
-
}
|
|
225117
|
-
function classifyValidationSourceScope(relativePath) {
|
|
225118
|
-
const normalized = normalizePath10(relativePath);
|
|
225119
|
-
const fileName = normalized.split("/").at(-1) ?? normalized;
|
|
225120
|
-
const extension = fileName.includes(".") ? fileName.slice(fileName.lastIndexOf(".")) : "";
|
|
225121
|
-
const isTestFile = /\.(?:spec|test|e2e-spec)\.(?:ts|tsx|js|jsx|mjs|cjs|java|cs|py|php|go)$/u.test(fileName);
|
|
225122
|
-
const isE2e = isTestFile && /(?:^|[./_-])e2e(?:[./_-]|$)/u.test(fileName) || hasPathSegment(normalized, /^e2e$/u);
|
|
225123
|
-
const isFixture = hasPathSegment(normalized, /^(?:fixtures?|__fixtures__)$/u);
|
|
225124
|
-
const isTestPlugin = hasPathSegment(normalized, /^(?:test-plugins?|testing-plugins?)$/u);
|
|
225125
|
-
const isExamplePlugin = hasPathSegment(normalized, /^(?:example-plugins?|examples?)$/u);
|
|
225126
|
-
const isGenerated = hasPathSegment(normalized, /^(?:generated|__generated__|gen|templates?)$/u) || /\.(?:generated|gen|g)\.(?:ts|tsx|js|jsx|java|cs|py|php|go)$/u.test(fileName) || /\.d\.ts$/u.test(fileName);
|
|
225127
|
-
const isMigration = hasPathSegment(normalized, /^(?:migrations?|schema-migrations?|migration-utils?)$/u) || /(?:^|[./_-])migration(?:[./_-]|$)/u.test(fileName);
|
|
225128
|
-
const isCliTooling = hasPathSegment(normalized, /^(?:cli|bin|scripts?|tools?|scaffold|scaffolding|generators?)$/u) || /(?:^|[./_-])(?:cli|script|tool|generator|scaffold)(?:[./_-]|$)/u.test(fileName);
|
|
225129
|
-
const isFrontend = extension === ".tsx" || extension === ".jsx" || hasPathSegment(normalized, /^(?:frontend|client|browser|ui|admin-ui|dashboard|web-app)$/u) || /\b(?:react|angular|vue|svelte)\b/u.test(normalized);
|
|
225130
|
-
const isInfrastructure = hasPathSegment(normalized, /^(?:infrastructure|infra|framework|adapters?|persistence|providers?)$/u) || /(?:transactional-connection|transaction-wrapper|transaction-subscriber|transaction-manager|query-runner|query-builder|event-bus|telemetry|interceptor)\.(?:ts|js|java|cs|py|php|go)$/u.test(fileName);
|
|
225131
|
-
let category = "production-backend";
|
|
225132
|
-
if (isGenerated) {
|
|
225133
|
-
category = "generated";
|
|
225134
|
-
} else if (isE2e) {
|
|
225135
|
-
category = "e2e";
|
|
225136
|
-
} else if (isTestFile || hasPathSegment(normalized, /^(?:test|tests|__tests__|spec|specs)$/u)) {
|
|
225137
|
-
category = "test";
|
|
225138
|
-
} else if (isTestPlugin) {
|
|
225139
|
-
category = "test-plugin";
|
|
225140
|
-
} else if (isExamplePlugin) {
|
|
225141
|
-
category = "example-plugin";
|
|
225142
|
-
} else if (isFixture) {
|
|
225143
|
-
category = "fixture";
|
|
225144
|
-
} else if (isMigration) {
|
|
225145
|
-
category = "migration";
|
|
225146
|
-
} else if (isCliTooling) {
|
|
225147
|
-
category = "cli-tooling";
|
|
225148
|
-
} else if (isFrontend) {
|
|
225149
|
-
category = "production-frontend";
|
|
225150
|
-
} else if (isInfrastructure) {
|
|
225151
|
-
category = "infrastructure";
|
|
225152
|
-
}
|
|
225153
|
-
const isTestLike = category === "test" || category === "e2e" || category === "fixture" || category === "test-plugin" || category === "example-plugin";
|
|
225154
|
-
return {
|
|
225155
|
-
category,
|
|
225156
|
-
isProduction: category === "production-backend" || category === "production-frontend" || category === "infrastructure",
|
|
225157
|
-
isFrontend: category === "production-frontend",
|
|
225158
|
-
isTestLike,
|
|
225159
|
-
isGenerated: category === "generated",
|
|
225160
|
-
isMigration: category === "migration",
|
|
225161
|
-
isCliTooling: category === "cli-tooling",
|
|
225162
|
-
isInfrastructure: category === "infrastructure"
|
|
225163
|
-
};
|
|
225164
|
-
}
|
|
225165
|
-
function isProductionBackendGovernanceScope(scope) {
|
|
225166
|
-
return scope.category === "production-backend";
|
|
225167
|
-
}
|
|
225168
|
-
|
|
225169
225306
|
// ../core/src/dataQueryRiskDetection.ts
|
|
225307
|
+
init_sourceScopeClassification();
|
|
225170
225308
|
var maxFileSizeBytes = 256 * 1024;
|
|
225171
225309
|
var supplementalRiskScanExtensions = [".json", ".yaml", ".yml", ".sql"];
|
|
225172
225310
|
var backendCodeExtensions = [".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs", ".java", ".cs", ".py", ".php", ".go"];
|
|
@@ -225174,7 +225312,7 @@ var supplementalIgnoredDirectoryNames = [".vscode-test", ".tmp"];
|
|
|
225174
225312
|
var batchingEvidencePattern = /\b(?:DataLoader|Promise\.all|findMany\s*\([\s\S]{0,300}\bin\b|where\s*:\s*\{[\s\S]{0,300}\bin\s*:|include\s*:|join\s*\(|leftJoin|innerJoin|JOIN\b)\b/iu;
|
|
225175
225313
|
var queryReadPattern = /\b((?:this\.)?(?:prisma\.(\w+)|([A-Za-z_$][\w$]*Repository|repository))\.(find\w*|count|aggregate|groupBy)\s*\()/giu;
|
|
225176
225314
|
var unboundedLoadPattern = /\b(?:const|let|var)\s+(\w+)\s*=\s*await\s+((?:this\.)?(?:prisma\.\w+|\w*Repository|repository)\.(?:findMany|findAll|find))\s*\(([\s\S]{0,700}?)\)\s*;?[\s\S]{0,1000}\b\1\.(?:filter|map|reduce)\s*\(/iu;
|
|
225177
|
-
var boundEvidencePattern = /\b(?:take|limit|page|cursor|skip|offset|PageRequest|Pageable)\b/iu;
|
|
225315
|
+
var boundEvidencePattern = /\b(?:take|limit|page|cursor|skip|offset|PageRequest|Pageable|findOne|findOneOrFail|findOneBy|findOneByOrFail|findUnique|findFirst|getOne|getRawOne|first)\b/iu;
|
|
225178
225316
|
var repeatedQueryPattern = /\b((?:this\.)?(?:prisma\.(\w+)|(\w*Repository|repository))\.(find\w*|count|aggregate|groupBy)\s*\(\s*(?:\{[\s\S]{0,300}?\}|\w+)\s*\))/giu;
|
|
225179
225317
|
var tenantPredicatePattern = /\b(?:tenantId|tenant_id|organizationId|organization_id|orgId|org_id|accountId|account_id|workspaceId|workspace_id|companyId|company_id|customerId|customer_id)\b/u;
|
|
225180
225318
|
var codePaginationEvidencePattern = /\b(?:take|skip|limit|offset|page|perPage|pageSize|cursor|Pageable|PageRequest|paginate|simplePaginate|Limit|Offset|Take|Skip|TOP\s+\d+)\b/iu;
|
|
@@ -225985,7 +226123,7 @@ function detectRepeatedQueryPattern(method) {
|
|
|
225985
226123
|
function extractSqlQueryLiterals(content) {
|
|
225986
226124
|
const queries = [];
|
|
225987
226125
|
const patterns = [
|
|
225988
|
-
/(?:\b(?:query|execute|executeQuery|createNativeQuery|createQuery|FromSqlRaw|FromSqlInterpolated|Query|QueryContext|QueryRow|QueryRowContext|Exec|ExecContext|Raw|text)|\$queryRaw|\$executeRaw)\s*\([^'"`)]{0,180}?(['"`])([\s\S]{0,900}?)\1/giu,
|
|
226126
|
+
/(?:\b(?:[\w$]+\.)?(?:query|execute|executeQuery|createNativeQuery|createQuery|FromSqlRaw|FromSqlInterpolated|Query|QueryContext|QueryRow|QueryRowContext|Exec|ExecContext|Raw|text)|\$queryRaw|\$executeRaw)\s*\([^'"`)]{0,180}?(['"`])([\s\S]{0,900}?)\1/giu,
|
|
225989
226127
|
/\b(?:DB::select|DB::statement|DB::raw|DB::table)\s*\([^'"`)]{0,180}?(['"`])([\s\S]{0,900}?)\1/gu,
|
|
225990
226128
|
/@Query\s*\(\s*(['"`])([\s\S]{0,900}?)\1/gu
|
|
225991
226129
|
];
|
|
@@ -226072,7 +226210,7 @@ function collectOrmReadEvidence(method) {
|
|
|
226072
226210
|
return evidence;
|
|
226073
226211
|
}
|
|
226074
226212
|
function getOrmTerminalOperation(snippet) {
|
|
226075
|
-
const match = /\.(getMany|getRawMany|getOne|getRawOne|getCount|getExists|execute|findOne|findOneBy|findUnique|findFirst|count|exists|update|delete|remove|save|insert)\s*\(/iu.exec(snippet);
|
|
226213
|
+
const match = /\.(getMany|getRawMany|loadMany|getOne|getRawOne|loadOne|getCount|getExists|execute|findOne|findOneOrFail|findOneBy|findOneByOrFail|findUnique|findFirst|count|exists|update|delete|remove|save|insert)\s*\(/iu.exec(snippet);
|
|
226076
226214
|
return match?.[1];
|
|
226077
226215
|
}
|
|
226078
226216
|
function isOperationalOrBatchQueryContext(file, methodName) {
|
|
@@ -226081,12 +226219,20 @@ function isOperationalOrBatchQueryContext(file, methodName) {
|
|
|
226081
226219
|
const method = methodName?.toLowerCase() ?? "";
|
|
226082
226220
|
return segments.some((segment) => /\b(?:health|cache|job|queue|scheduler|indexer|telemetry|metrics)\b/u.test(segment.replace(/-/g, " "))) || /(^|\/)(?:health-check|healthchecks?|cache|job-queue|scheduler|search|indexer|telemetry|metrics)(?:\/|-)/u.test(pathValue) || /(?:health-check|healthcheck|cache|job-queue|scheduler|search|indexer|telemetry|metrics)\.(?:ts|tsx|js|jsx|java|cs|py|php|go)$/u.test(pathValue) || /\b(?:health|cache|job|queue|schedule|scheduler|index|telemetry|metrics|buffer|worker|batch)\b/u.test(method) || method.includes("batch") || /^on(?:moduleinit|applicationbootstrap|applicationstart|init)$/u.test(method);
|
|
226083
226221
|
}
|
|
226084
|
-
function
|
|
226085
|
-
return
|
|
226222
|
+
function isScopedRelationLoad(snippet) {
|
|
226223
|
+
return /\.relation\s*\(/iu.test(snippet) && /\.of\s*\(\s*[^)]{1,180}\)\s*\.loadMany\s*\(/iu.test(snippet);
|
|
226224
|
+
}
|
|
226225
|
+
function hasAssignedBuilderBoundedTerminal(methodBody, snippet) {
|
|
226226
|
+
const variableMatch = /\b(?:const|let|var)\s+([A-Za-z_$][\w$]*)\s*=\s*(?:[\s\S]{0,240}?)createQueryBuilder\s*\(/iu.exec(snippet);
|
|
226227
|
+
const variableName = variableMatch?.[1];
|
|
226228
|
+
if (!variableName) {
|
|
226229
|
+
return false;
|
|
226230
|
+
}
|
|
226231
|
+
return new RegExp(`\\b${variableName}\\s*\\.\\s*(?:getOne|getRawOne|loadOne|getCount|getExists)\\s*\\(`, "iu").test(methodBody);
|
|
226086
226232
|
}
|
|
226087
|
-
function isNonCollectionOrmRead(label, snippet) {
|
|
226233
|
+
function isNonCollectionOrmRead(label, snippet, methodBody = snippet) {
|
|
226088
226234
|
const terminal = getOrmTerminalOperation(snippet);
|
|
226089
|
-
return /\b(?:findOne|findOneBy|findUnique|findFirst|count|exists|aggregate)\b/iu.test(label) || !!terminal && /^(?:getOne|getRawOne|getCount|getExists|findOne|findOneBy|findUnique|findFirst|count|exists|update|delete|remove|save|insert|execute)$/iu.test(terminal);
|
|
226235
|
+
return /\b(?:findOne|findOneOrFail|findOneBy|findOneByOrFail|findUnique|findFirst|count|exists|aggregate)\b/iu.test(label) || !!terminal && /^(?:getOne|getRawOne|loadOne|getCount|getExists|findOne|findOneOrFail|findOneBy|findOneByOrFail|findUnique|findFirst|count|exists|update|delete|remove|save|insert|execute)$/iu.test(terminal) || isScopedRelationLoad(snippet) || hasAssignedBuilderBoundedTerminal(methodBody, snippet);
|
|
226090
226236
|
}
|
|
226091
226237
|
function hasOrmBoundEvidence(snippet) {
|
|
226092
226238
|
return codePaginationEvidencePattern.test(snippet) || /\.(?:take|limit|offset|skip)\s*\(/iu.test(snippet) || /\b(?:maxResults|setMaxResults|firstResult|setFirstResult)\s*\(/iu.test(snippet) || /\b(?:pageSize|perPage|limit|take)\s*[:=]\s*\d+\b/iu.test(snippet);
|
|
@@ -226121,7 +226267,7 @@ function detectOrmQueryShapeFindings(method, config) {
|
|
|
226121
226267
|
target: evidence.label
|
|
226122
226268
|
}));
|
|
226123
226269
|
}
|
|
226124
|
-
if (!isOperationalOrBatchQueryContext(method.file, method.name) && !
|
|
226270
|
+
if (!isOperationalOrBatchQueryContext(method.file, method.name) && !isNonCollectionOrmRead(evidence.label, evidence.snippet, method.body) && !hasOrmBoundEvidence(evidence.snippet)) {
|
|
226125
226271
|
const target = getOrmQueryTarget(method, evidence.label, evidence.snippet);
|
|
226126
226272
|
const label = getOrmQueryLabel(method, evidence.label, evidence.snippet);
|
|
226127
226273
|
findings.push(createCodeFinding({
|
|
@@ -226146,9 +226292,12 @@ function detectCodeQueryRiskFindings(files, config, astCache) {
|
|
|
226146
226292
|
findings.push(...detectCodeSqlQueryShapeFindings(file, config));
|
|
226147
226293
|
}
|
|
226148
226294
|
for (const method of extractMethodBodies(file, astCache)) {
|
|
226295
|
+
if (!isProductionBackend) {
|
|
226296
|
+
continue;
|
|
226297
|
+
}
|
|
226149
226298
|
nPlusOneEvidence.push(...detectNPlusOneQueryRisk(method));
|
|
226150
226299
|
findings.push(
|
|
226151
|
-
...
|
|
226300
|
+
...detectOrmQueryShapeFindings(method, config),
|
|
226152
226301
|
...detectLargeCollectionLoading(method),
|
|
226153
226302
|
...detectMissingProjection(method),
|
|
226154
226303
|
...detectRepeatedQueryPattern(method)
|
|
@@ -226241,6 +226390,7 @@ var import_node_fs25 = require("node:fs");
|
|
|
226241
226390
|
var ts3 = __toESM(require_typescript());
|
|
226242
226391
|
init_moduleDiscovery();
|
|
226243
226392
|
init_archpilotIgnore();
|
|
226393
|
+
init_sourceScopeClassification();
|
|
226244
226394
|
var ApplicationLayeringRuleIds = {
|
|
226245
226395
|
CONTROLLER_BUSINESS_LOGIC: "AP-APP-001",
|
|
226246
226396
|
REPOSITORY_BUSINESS_LOGIC: "AP-APP-002",
|
|
@@ -226912,35 +227062,30 @@ function isDbModelEvidenceToken(value) {
|
|
|
226912
227062
|
const lower = normalized.toLowerCase();
|
|
226913
227063
|
const excluded = /* @__PURE__ */ new Set([
|
|
226914
227064
|
"a",
|
|
227065
|
+
"all",
|
|
226915
227066
|
"an",
|
|
226916
|
-
"
|
|
226917
|
-
"
|
|
226918
|
-
"
|
|
226919
|
-
"
|
|
226920
|
-
"into",
|
|
226921
|
-
"join",
|
|
226922
|
-
"openapi",
|
|
226923
|
-
"or",
|
|
226924
|
-
"paddle",
|
|
226925
|
-
"provider",
|
|
227067
|
+
"doing",
|
|
227068
|
+
"first",
|
|
227069
|
+
"is",
|
|
227070
|
+
"outside",
|
|
226926
227071
|
"resend",
|
|
226927
|
-
"
|
|
226928
|
-
"select",
|
|
226929
|
-
"stripe",
|
|
227072
|
+
"scratch",
|
|
226930
227073
|
"swagger",
|
|
226931
|
-
"
|
|
226932
|
-
"the",
|
|
226933
|
-
"this",
|
|
226934
|
-
"to",
|
|
226935
|
-
"update",
|
|
226936
|
-
"where",
|
|
226937
|
-
"with"
|
|
227074
|
+
"the"
|
|
226938
227075
|
]);
|
|
226939
227076
|
if (excluded.has(lower)) {
|
|
226940
227077
|
return false;
|
|
226941
227078
|
}
|
|
226942
227079
|
return !/(?:client|provider|service|controller|guard|swagger|openapi)$/iu.test(normalized);
|
|
226943
227080
|
}
|
|
227081
|
+
function isStructuredSqlTableEvidence(value, keyword, quote, following = "") {
|
|
227082
|
+
const normalized = value.trim();
|
|
227083
|
+
const hasStructuralEvidence = /^(?:from|update|into)$/iu.test(keyword) || quote !== void 0 && quote.length > 0 || /[_.]/u.test(normalized) || /^join$/iu.test(keyword) && /\bon\b/iu.test(following);
|
|
227084
|
+
return hasStructuralEvidence && isDbModelEvidenceToken(normalized);
|
|
227085
|
+
}
|
|
227086
|
+
function extractSqlLikeLiterals(content) {
|
|
227087
|
+
return [...content.matchAll(/(['"`])([\s\S]{0,1200}?)\1/gu)].map((match) => match[2] ?? "").filter((literal) => /\b(?:select|update|delete|insert)\b[\s\S]{0,400}\b(?:from|join|into|update)\b/iu.test(literal));
|
|
227088
|
+
}
|
|
226944
227089
|
function extractDbModelsTouched(content) {
|
|
226945
227090
|
const models = /* @__PURE__ */ new Set();
|
|
226946
227091
|
for (const match of content.matchAll(/\b(?:this\.)?prisma\.([a-z]\w*)\./giu)) {
|
|
@@ -226948,9 +227093,13 @@ function extractDbModelsTouched(content) {
|
|
|
226948
227093
|
models.add(match[1]);
|
|
226949
227094
|
}
|
|
226950
227095
|
}
|
|
226951
|
-
for (const
|
|
226952
|
-
|
|
226953
|
-
|
|
227096
|
+
for (const sqlLiteral of extractSqlLikeLiterals(content)) {
|
|
227097
|
+
for (const match of sqlLiteral.matchAll(/\b(?:from|join|update|into)\s+(["`]?)([A-Za-z_][\w]*(?:\.[A-Za-z_][\w]*)?)\1/giu)) {
|
|
227098
|
+
const keyword = /\b(from|join|update|into)\b/iu.exec(match[0])?.[1] ?? "";
|
|
227099
|
+
const following = sqlLiteral.slice((match.index ?? 0) + match[0].length, (match.index ?? 0) + match[0].length + 120);
|
|
227100
|
+
if (match[2] && isStructuredSqlTableEvidence(match[2], keyword, match[1], following)) {
|
|
227101
|
+
models.add(match[2]);
|
|
227102
|
+
}
|
|
226954
227103
|
}
|
|
226955
227104
|
}
|
|
226956
227105
|
return sortUnique6(models).slice(0, 6);
|
|
@@ -227694,6 +227843,7 @@ var import_node_fs27 = require("node:fs");
|
|
|
227694
227843
|
var ts5 = __toESM(require_typescript());
|
|
227695
227844
|
init_moduleDiscovery();
|
|
227696
227845
|
init_archpilotIgnore();
|
|
227846
|
+
init_sourceScopeClassification();
|
|
227697
227847
|
var RuleIds2 = {
|
|
227698
227848
|
TXN_BOUNDARY_TOO_BROAD: "AP-TXN-001",
|
|
227699
227849
|
TXN_IN_CONTROLLER: "AP-TXN-002",
|
|
@@ -228737,35 +228887,30 @@ function isDbModelEvidenceToken2(value) {
|
|
|
228737
228887
|
const lower = normalized.toLowerCase();
|
|
228738
228888
|
const excluded = /* @__PURE__ */ new Set([
|
|
228739
228889
|
"a",
|
|
228890
|
+
"all",
|
|
228740
228891
|
"an",
|
|
228741
|
-
"
|
|
228742
|
-
"
|
|
228743
|
-
"
|
|
228744
|
-
"
|
|
228745
|
-
"into",
|
|
228746
|
-
"join",
|
|
228747
|
-
"openapi",
|
|
228748
|
-
"or",
|
|
228749
|
-
"paddle",
|
|
228750
|
-
"provider",
|
|
228892
|
+
"doing",
|
|
228893
|
+
"first",
|
|
228894
|
+
"is",
|
|
228895
|
+
"outside",
|
|
228751
228896
|
"resend",
|
|
228752
|
-
"
|
|
228753
|
-
"select",
|
|
228754
|
-
"stripe",
|
|
228897
|
+
"scratch",
|
|
228755
228898
|
"swagger",
|
|
228756
|
-
"
|
|
228757
|
-
"the",
|
|
228758
|
-
"this",
|
|
228759
|
-
"to",
|
|
228760
|
-
"update",
|
|
228761
|
-
"where",
|
|
228762
|
-
"with"
|
|
228899
|
+
"the"
|
|
228763
228900
|
]);
|
|
228764
228901
|
if (excluded.has(lower)) {
|
|
228765
228902
|
return false;
|
|
228766
228903
|
}
|
|
228767
228904
|
return !/(?:client|provider|service|controller|guard|swagger|openapi)$/iu.test(normalized);
|
|
228768
228905
|
}
|
|
228906
|
+
function isStructuredSqlTableEvidence2(value, keyword, quote, following = "") {
|
|
228907
|
+
const normalized = value.trim();
|
|
228908
|
+
const hasStructuralEvidence = /^(?:from|update|into)$/iu.test(keyword) || quote !== void 0 && quote.length > 0 || /[_.]/u.test(normalized) || /^join$/iu.test(keyword) && /\bon\b/iu.test(following);
|
|
228909
|
+
return hasStructuralEvidence && isDbModelEvidenceToken2(normalized);
|
|
228910
|
+
}
|
|
228911
|
+
function extractSqlLikeLiterals2(content) {
|
|
228912
|
+
return [...content.matchAll(/(['"`])([\s\S]{0,1200}?)\1/gu)].map((match) => match[2] ?? "").filter((literal) => /\b(?:select|update|delete|insert)\b[\s\S]{0,400}\b(?:from|join|into|update)\b/iu.test(literal));
|
|
228913
|
+
}
|
|
228769
228914
|
function extractDbModelsTouched2(content) {
|
|
228770
228915
|
const models = /* @__PURE__ */ new Set();
|
|
228771
228916
|
for (const match of content.matchAll(/\b(?:this\.)?prisma\.([a-z]\w*)\./giu)) {
|
|
@@ -228773,9 +228918,13 @@ function extractDbModelsTouched2(content) {
|
|
|
228773
228918
|
models.add(match[1]);
|
|
228774
228919
|
}
|
|
228775
228920
|
}
|
|
228776
|
-
for (const
|
|
228777
|
-
|
|
228778
|
-
|
|
228921
|
+
for (const sqlLiteral of extractSqlLikeLiterals2(content)) {
|
|
228922
|
+
for (const match of sqlLiteral.matchAll(/\b(?:from|join|update|into)\s+(["`]?)([A-Za-z_][\w]*(?:\.[A-Za-z_][\w]*)?)\1/giu)) {
|
|
228923
|
+
const keyword = /\b(from|join|update|into)\b/iu.exec(match[0])?.[1] ?? "";
|
|
228924
|
+
const following = sqlLiteral.slice((match.index ?? 0) + match[0].length, (match.index ?? 0) + match[0].length + 120);
|
|
228925
|
+
if (match[2] && isStructuredSqlTableEvidence2(match[2], keyword, match[1], following)) {
|
|
228926
|
+
models.add(match[2]);
|
|
228927
|
+
}
|
|
228779
228928
|
}
|
|
228780
228929
|
}
|
|
228781
228930
|
return sortUnique7(models).slice(0, 6);
|
|
@@ -229025,6 +229174,7 @@ var path33 = __toESM(require("node:path"));
|
|
|
229025
229174
|
var import_node_fs28 = require("node:fs");
|
|
229026
229175
|
init_moduleDiscovery();
|
|
229027
229176
|
init_archpilotIgnore();
|
|
229177
|
+
init_sourceScopeClassification();
|
|
229028
229178
|
var RuleIds3 = {
|
|
229029
229179
|
MISSING_PAGINATION: "AP-API-010",
|
|
229030
229180
|
BULK_OPERATION_RISK: "AP-API-011",
|
|
@@ -229541,8 +229691,34 @@ function hasPaginationEvidence2(endpoint, contractEndpoints) {
|
|
|
229541
229691
|
${endpoint.signature}
|
|
229542
229692
|
${endpoint.body}`);
|
|
229543
229693
|
}
|
|
229694
|
+
function stripStaticLiteralNoise(value) {
|
|
229695
|
+
return value.replace(/\/\*[\s\S]*?\*\//gu, " ").replace(/\/\/.*$/gmu, " ").replace(/(['"`])(?:\\.|(?!\1)[\s\S])*\1/gu, '""');
|
|
229696
|
+
}
|
|
229697
|
+
function isStaticCollectionExpression(expression) {
|
|
229698
|
+
const normalized = expression.trim().replace(/;$/u, "").trim();
|
|
229699
|
+
return /^(?:Object\.)?(?:freeze|values|entries|keys)\s*\(/u.test(normalized) || /^(?:\[[\s\S]*\]|\{[\s\S]*\})$/u.test(normalized) || /^(?:[A-Z][A-Za-z0-9_]*|[a-z][A-Za-z0-9_]*(?:Config|Configs|Catalog|Catalogs|Metadata|Definitions|Types|Widgets|Constants))$/u.test(normalized);
|
|
229700
|
+
}
|
|
229701
|
+
function hasStaticDeclarationEvidence(fileContent, identifier) {
|
|
229702
|
+
const escaped = identifier.replace(/[.*+?^${}()|[\]\\]/gu, "\\$&");
|
|
229703
|
+
return new RegExp(`\\bimport\\s+(?:\\{[^}]*\\b${escaped}\\b[^}]*\\}|${escaped}\\b)`, "u").test(fileContent) || new RegExp(`\\b(?:const|readonly)\\s+${escaped}\\s*=\\s*(?:Object\\.freeze\\s*\\(|\\[|\\{)`, "u").test(fileContent) || new RegExp(`\\benum\\s+${escaped}\\b`, "u").test(fileContent);
|
|
229704
|
+
}
|
|
229705
|
+
function isStaticCollectionBackedEndpoint(endpoint) {
|
|
229706
|
+
const body = endpoint.body.trim();
|
|
229707
|
+
if (/\b(?:await|repository|Repository|createQueryBuilder|findMany|findAll|find\s*\(|query\s*\(|execute\s*\(|service\.)\b/iu.test(body)) {
|
|
229708
|
+
return false;
|
|
229709
|
+
}
|
|
229710
|
+
const returnMatch = /\breturn\s+([\s\S]{0,500}?);/u.exec(body) ?? /\bres\.(?:json|send)\s*\(\s*([\s\S]{0,500}?)\s*\)\s*;?/u.exec(body) ?? /\bOk\s*\(\s*([\s\S]{0,500}?)\s*\)\s*;?/u.exec(body);
|
|
229711
|
+
if (!returnMatch?.[1]) {
|
|
229712
|
+
return false;
|
|
229713
|
+
}
|
|
229714
|
+
const expression = returnMatch[1].trim();
|
|
229715
|
+
if (/^[A-Za-z_$][\w$]*$/u.test(expression)) {
|
|
229716
|
+
return hasStaticDeclarationEvidence(endpoint.file.content, expression);
|
|
229717
|
+
}
|
|
229718
|
+
return isStaticCollectionExpression(stripStaticLiteralNoise(expression));
|
|
229719
|
+
}
|
|
229544
229720
|
function detectPaginationFindings(endpoints, contractEndpoints) {
|
|
229545
|
-
return endpoints.filter((endpoint) => isCollectionGet(endpoint) && !hasPaginationEvidence2(endpoint, contractEndpoints)).map((endpoint) => createFinding4({
|
|
229721
|
+
return endpoints.filter((endpoint) => isCollectionGet(endpoint) && !hasPaginationEvidence2(endpoint, contractEndpoints) && !isStaticCollectionBackedEndpoint(endpoint)).map((endpoint) => createFinding4({
|
|
229546
229722
|
id: RuleIds3.MISSING_PAGINATION,
|
|
229547
229723
|
message: `Collection endpoint ${endpoint.httpMethod.toUpperCase()} ${endpoint.path} lacks visible pagination evidence.`,
|
|
229548
229724
|
endpoint
|
|
@@ -231200,7 +231376,7 @@ src/
|
|
|
231200
231376
|
architectureScope: "module",
|
|
231201
231377
|
applicability: { requiresArchitectureModules: true },
|
|
231202
231378
|
description: "Checks whether cross-module imports target another module through its public entrypoints rather than internal implementation files.",
|
|
231203
|
-
recommendedFix: "Import
|
|
231379
|
+
recommendedFix: "Import through the target module or package public entrypoint declared in its contract rather than reaching into internal implementation files."
|
|
231204
231380
|
},
|
|
231205
231381
|
DEP_CROSS_MODULE_DEPENDENCY_DECLARED_IN_CONTRACT: {
|
|
231206
231382
|
id: ValidationRuleIds.DEP_CROSS_MODULE_DEPENDENCY_DECLARED_IN_CONTRACT,
|
|
@@ -242593,6 +242769,9 @@ var ignoredRootPathPrefixes = [
|
|
|
242593
242769
|
function normalizeRelativePath5(value) {
|
|
242594
242770
|
return value.replaceAll("\\", "/");
|
|
242595
242771
|
}
|
|
242772
|
+
function isUnderJvmResourceRoot2(relativePath) {
|
|
242773
|
+
return /(^|\/)src\/main\/resources(?:\/|$)/u.test(normalizeRelativePath5(relativePath).toLowerCase());
|
|
242774
|
+
}
|
|
242596
242775
|
function sortUnique16(values) {
|
|
242597
242776
|
return [...new Set(values)].sort((left, right) => left.localeCompare(right));
|
|
242598
242777
|
}
|
|
@@ -242730,7 +242909,7 @@ function collectDetectedRoots(scan) {
|
|
|
242730
242909
|
const roots = /* @__PURE__ */ new Set();
|
|
242731
242910
|
for (const manifestName of manifestFileNames) {
|
|
242732
242911
|
for (const manifestPath of scan.manifestPathsByName[manifestName]) {
|
|
242733
|
-
if (isIgnoredRelativePath(manifestPath)) {
|
|
242912
|
+
if (isIgnoredRelativePath(manifestPath) || isUnderJvmResourceRoot2(manifestPath)) {
|
|
242734
242913
|
continue;
|
|
242735
242914
|
}
|
|
242736
242915
|
const containingDirectory = normalizeRelativePath5(path58.dirname(manifestPath));
|
|
@@ -242745,11 +242924,11 @@ function buildResultFromScan(scan) {
|
|
|
242745
242924
|
const evidence = [];
|
|
242746
242925
|
const detectedRoots = collectDetectedRoots(scan);
|
|
242747
242926
|
const filteredManifestPathsByName = {
|
|
242748
|
-
"package.json": scan.manifestPathsByName["package.json"].filter((entry) => !isIgnoredRelativePath(entry)),
|
|
242749
|
-
"pom.xml": scan.manifestPathsByName["pom.xml"].filter((entry) => !isIgnoredRelativePath(entry)),
|
|
242750
|
-
"requirements.txt": scan.manifestPathsByName["requirements.txt"].filter((entry) => !isIgnoredRelativePath(entry)),
|
|
242751
|
-
"go.mod": scan.manifestPathsByName["go.mod"].filter((entry) => !isIgnoredRelativePath(entry)),
|
|
242752
|
-
"composer.json": scan.manifestPathsByName["composer.json"].filter((entry) => !isIgnoredRelativePath(entry))
|
|
242927
|
+
"package.json": scan.manifestPathsByName["package.json"].filter((entry) => !isIgnoredRelativePath(entry) && !isUnderJvmResourceRoot2(entry)),
|
|
242928
|
+
"pom.xml": scan.manifestPathsByName["pom.xml"].filter((entry) => !isIgnoredRelativePath(entry) && !isUnderJvmResourceRoot2(entry)),
|
|
242929
|
+
"requirements.txt": scan.manifestPathsByName["requirements.txt"].filter((entry) => !isIgnoredRelativePath(entry) && !isUnderJvmResourceRoot2(entry)),
|
|
242930
|
+
"go.mod": scan.manifestPathsByName["go.mod"].filter((entry) => !isIgnoredRelativePath(entry) && !isUnderJvmResourceRoot2(entry)),
|
|
242931
|
+
"composer.json": scan.manifestPathsByName["composer.json"].filter((entry) => !isIgnoredRelativePath(entry) && !isUnderJvmResourceRoot2(entry))
|
|
242753
242932
|
};
|
|
242754
242933
|
let monorepoStrongSignals = 0;
|
|
242755
242934
|
let monorepoWeakSignals = 0;
|
|
@@ -243049,6 +243228,12 @@ function confidenceWeight(confidence) {
|
|
|
243049
243228
|
return 1;
|
|
243050
243229
|
}
|
|
243051
243230
|
function compareCandidates2(left, right) {
|
|
243231
|
+
if (left.result.confidence === "high" && right.result.confidence === "high" && left.adapter.category === "framework" && right.adapter.category === "generic-language" && left.adapter.ecosystem === right.adapter.ecosystem) {
|
|
243232
|
+
return -1;
|
|
243233
|
+
}
|
|
243234
|
+
if (left.result.confidence === "high" && right.result.confidence === "high" && left.adapter.category === "generic-language" && right.adapter.category === "framework" && left.adapter.ecosystem === right.adapter.ecosystem) {
|
|
243235
|
+
return 1;
|
|
243236
|
+
}
|
|
243052
243237
|
const confidenceDiff = confidenceWeight(right.result.confidence) - confidenceWeight(left.result.confidence);
|
|
243053
243238
|
if (confidenceDiff !== 0) {
|
|
243054
243239
|
return confidenceDiff;
|
|
@@ -244794,6 +244979,9 @@ var ignoredDirectoryNames12 = /* @__PURE__ */ new Set([
|
|
|
244794
244979
|
function normalizePath24(value) {
|
|
244795
244980
|
return value.replaceAll("\\", "/");
|
|
244796
244981
|
}
|
|
244982
|
+
function isUnderJvmResourceRoot3(relativePath) {
|
|
244983
|
+
return /(^|\/)src\/main\/resources(?:\/|$)/u.test(normalizePath24(relativePath).toLowerCase());
|
|
244984
|
+
}
|
|
244797
244985
|
function unique(values) {
|
|
244798
244986
|
return [...new Set(values)];
|
|
244799
244987
|
}
|
|
@@ -244942,7 +245130,7 @@ function hasAnyDependency2(summary, dependencyNames) {
|
|
|
244942
245130
|
function collectCandidateRoots(workspaceRoot, topology, ignoreMatcher) {
|
|
244943
245131
|
const roots = /* @__PURE__ */ new Set();
|
|
244944
245132
|
for (const root of topology.detectedRoots ?? []) {
|
|
244945
|
-
if (root && root !== "." && !isIgnoredPath6(ignoreMatcher, root) && !isSupportingAssetRoot(root)) {
|
|
245133
|
+
if (root && root !== "." && !isIgnoredPath6(ignoreMatcher, root) && !isSupportingAssetRoot(root) && !isUnderJvmResourceRoot3(root)) {
|
|
244946
245134
|
roots.add(normalizePath24(root));
|
|
244947
245135
|
}
|
|
244948
245136
|
}
|
|
@@ -244950,7 +245138,7 @@ function collectCandidateRoots(workspaceRoot, topology, ignoreMatcher) {
|
|
|
244950
245138
|
const absoluteBase = path63.join(workspaceRoot, base);
|
|
244951
245139
|
for (const entry of safeReadDirEntries4(absoluteBase)) {
|
|
244952
245140
|
const relativePath = `${base}/${entry.name}`;
|
|
244953
|
-
if (!entry.isDirectory() || ignoredDirectoryNames12.has(entry.name) || isIgnoredPath6(ignoreMatcher, relativePath) || isSupportingAssetRoot(relativePath) || (topology.detectedRoots?.length ?? 0) > 0 && !topology.detectedRoots?.includes(relativePath) && !hasManifest(workspaceRoot, relativePath)) {
|
|
245141
|
+
if (!entry.isDirectory() || ignoredDirectoryNames12.has(entry.name) || isIgnoredPath6(ignoreMatcher, relativePath) || isSupportingAssetRoot(relativePath) || isUnderJvmResourceRoot3(relativePath) || (topology.detectedRoots?.length ?? 0) > 0 && !topology.detectedRoots?.includes(relativePath) && !hasManifest(workspaceRoot, relativePath)) {
|
|
244954
245142
|
continue;
|
|
244955
245143
|
}
|
|
244956
245144
|
roots.add(relativePath);
|
|
@@ -245034,9 +245222,10 @@ function inspectRoot(workspaceRoot, root, ignoreMatcher) {
|
|
|
245034
245222
|
addEvidence5(evidence, "Detected modules root");
|
|
245035
245223
|
}
|
|
245036
245224
|
const hasFrontendSignals = fileExists5(scan.files, "next.config.js") || fileExists5(scan.files, "next.config.ts") || fileExists5(scan.files, "angular.json") || fileExists5(scan.files, "vite.config.ts") || fileExists5(scan.files, "vite.config.js") || hasDirectory(scan.directories, "pages") || hasDirectory(scan.directories, "public") || hasAnyDependency2(packageJson, ["next", "react", "vue", "@angular/core"]);
|
|
245225
|
+
const hasRunnableFrontendSignals = fileExists5(scan.files, "next.config.js") || fileExists5(scan.files, "next.config.ts") || fileExists5(scan.files, "angular.json") || fileExists5(scan.files, "vite.config.ts") || fileExists5(scan.files, "vite.config.js") || fileExists5(scan.files, "index.html") || hasDirectory(scan.directories, "pages") || hasDirectory(scan.directories, "src/app");
|
|
245037
245226
|
const hasBackendSignals = hasApiBoundary || hasDatabaseAccess || fileExists5(scan.files, "pom.xml") || fileExists5(scan.files, "requirements.txt") || fileExists5(scan.files, "go.mod") || hasDirectory(scan.directories, "src/main/java");
|
|
245038
245227
|
let classification = "unknown";
|
|
245039
|
-
if ((root.startsWith("packages/") || root.startsWith("libs/")) && !hasApiBoundary) {
|
|
245228
|
+
if ((root.startsWith("packages/") || root.startsWith("libs/")) && !hasRunnableFrontendSignals && !hasApiBoundary) {
|
|
245040
245229
|
classification = "shared_package";
|
|
245041
245230
|
} else if (hasBackendSignals && !hasFrontendSignals) {
|
|
245042
245231
|
classification = "backend_app";
|
|
@@ -245147,6 +245336,8 @@ function isIgnoredComponentCandidatePath(componentPath) {
|
|
|
245147
245336
|
const ignoredRootSegments = [
|
|
245148
245337
|
"tests",
|
|
245149
245338
|
"test",
|
|
245339
|
+
"cypress",
|
|
245340
|
+
"cypress-tests",
|
|
245150
245341
|
"__tests__",
|
|
245151
245342
|
"fixtures",
|
|
245152
245343
|
"smoke",
|
|
@@ -245214,8 +245405,14 @@ function recordKeys(value) {
|
|
|
245214
245405
|
function hasObject(value) {
|
|
245215
245406
|
return Boolean(value && typeof value === "object" && !Array.isArray(value));
|
|
245216
245407
|
}
|
|
245408
|
+
function hasPackagePublishSurface(packageJson) {
|
|
245409
|
+
return hasObject(packageJson?.exports) || typeof packageJson?.main === "string" || typeof packageJson?.module === "string" || typeof packageJson?.types === "string" || hasObject(packageJson?.publishConfig) || Array.isArray(packageJson?.files);
|
|
245410
|
+
}
|
|
245411
|
+
function absoluteComponentRoot(workspaceRoot, componentPath) {
|
|
245412
|
+
return componentPath === "." ? workspaceRoot : path64.join(workspaceRoot, ...componentPath.split("/"));
|
|
245413
|
+
}
|
|
245217
245414
|
function readPackageJson(workspaceRoot, componentPath) {
|
|
245218
|
-
const absoluteRoot =
|
|
245415
|
+
const absoluteRoot = absoluteComponentRoot(workspaceRoot, componentPath);
|
|
245219
245416
|
return safeReadJson(path64.join(absoluteRoot, "package.json"));
|
|
245220
245417
|
}
|
|
245221
245418
|
function readTextFileSafe(filePath) {
|
|
@@ -245233,7 +245430,10 @@ function readFirstXmlTag(value, tagName) {
|
|
|
245233
245430
|
return match?.[1]?.trim().replace(/\s+/gu, " ");
|
|
245234
245431
|
}
|
|
245235
245432
|
function readMavenMetadata(workspaceRoot, componentPath) {
|
|
245236
|
-
|
|
245433
|
+
if (isUnderJvmResourceRoot4(componentPath)) {
|
|
245434
|
+
return void 0;
|
|
245435
|
+
}
|
|
245436
|
+
const absoluteRoot = absoluteComponentRoot(workspaceRoot, componentPath);
|
|
245237
245437
|
const pomXml = readTextFileSafe(path64.join(absoluteRoot, "pom.xml"));
|
|
245238
245438
|
if (!pomXml) {
|
|
245239
245439
|
return void 0;
|
|
@@ -245329,21 +245529,86 @@ function resolveId(componentPath, usedIds) {
|
|
|
245329
245529
|
usedIds.add(id);
|
|
245330
245530
|
return id;
|
|
245331
245531
|
}
|
|
245332
|
-
function
|
|
245532
|
+
function hasRunnableFrontendComponentEvidence(workspaceRoot, componentPath) {
|
|
245533
|
+
const absoluteRoot = componentPath === "." ? workspaceRoot : path64.join(workspaceRoot, ...componentPath.split("/"));
|
|
245534
|
+
const packageJson = readPackageJson(workspaceRoot, componentPath);
|
|
245535
|
+
const dependencies = [
|
|
245536
|
+
...recordKeys(packageJson?.dependencies),
|
|
245537
|
+
...recordKeys(packageJson?.devDependencies)
|
|
245538
|
+
];
|
|
245539
|
+
const scripts = recordKeys(packageJson?.scripts);
|
|
245540
|
+
const hasFrontendFramework = dependencies.some(
|
|
245541
|
+
(dependency) => /^(?:react|next|vue|@angular\/core|@sveltejs\/kit)$/u.test(dependency)
|
|
245542
|
+
);
|
|
245543
|
+
const hasInteractiveRunnableScript = scripts.some(
|
|
245544
|
+
(script) => /^(?:dev|start|serve|preview)(?::|$)/u.test(script)
|
|
245545
|
+
);
|
|
245546
|
+
const hasBundlerConfig = [
|
|
245547
|
+
"next.config.js",
|
|
245548
|
+
"next.config.ts",
|
|
245549
|
+
"vite.config.js",
|
|
245550
|
+
"vite.config.ts",
|
|
245551
|
+
"angular.json"
|
|
245552
|
+
].some((relativePath) => pathExists19(path64.join(absoluteRoot, ...relativePath.split("/"))));
|
|
245553
|
+
const hasApplicationEntry = [
|
|
245554
|
+
"index.html",
|
|
245555
|
+
"src/main.tsx",
|
|
245556
|
+
"src/main.ts",
|
|
245557
|
+
"src/App.tsx",
|
|
245558
|
+
"src/app",
|
|
245559
|
+
"pages"
|
|
245560
|
+
].some((relativePath) => pathExists19(path64.join(absoluteRoot, ...relativePath.split("/"))));
|
|
245561
|
+
return hasFrontendFramework && (hasApplicationEntry || hasInteractiveRunnableScript && hasBundlerConfig);
|
|
245562
|
+
}
|
|
245563
|
+
function isUnderJvmResourceRoot4(componentPath) {
|
|
245564
|
+
return /(^|\/)src\/main\/resources(?:\/|$)/u.test(normalizePath25(componentPath).toLowerCase());
|
|
245565
|
+
}
|
|
245566
|
+
function hasRuntimeSourceFiles(workspaceRoot, componentPath) {
|
|
245567
|
+
if (isUnderJvmResourceRoot4(componentPath)) {
|
|
245568
|
+
return false;
|
|
245569
|
+
}
|
|
245570
|
+
const absoluteRoot = absoluteComponentRoot(workspaceRoot, componentPath);
|
|
245571
|
+
const sourceRoots = [
|
|
245572
|
+
path64.join(absoluteRoot, "src", "main", "java"),
|
|
245573
|
+
path64.join(absoluteRoot, "src"),
|
|
245574
|
+
path64.join(absoluteRoot, "app"),
|
|
245575
|
+
path64.join(absoluteRoot, "server")
|
|
245576
|
+
];
|
|
245577
|
+
for (const sourceRoot of sourceRoots) {
|
|
245578
|
+
if (!pathExists19(sourceRoot)) {
|
|
245579
|
+
continue;
|
|
245580
|
+
}
|
|
245581
|
+
const entries = fs58.readdirSync(sourceRoot, { recursive: true, withFileTypes: true });
|
|
245582
|
+
if (entries.some((entry) => entry.isFile() && /\.(?:ts|tsx|js|jsx|java|cs|py|php|go)$/iu.test(entry.name))) {
|
|
245583
|
+
return true;
|
|
245584
|
+
}
|
|
245585
|
+
}
|
|
245586
|
+
return false;
|
|
245587
|
+
}
|
|
245588
|
+
function resolveKind(workspaceRoot, candidate, localProjectKinds) {
|
|
245333
245589
|
const lowerPath = candidate.path.toLowerCase();
|
|
245590
|
+
const packageJson = readPackageJson(workspaceRoot, candidate.path);
|
|
245591
|
+
const hasRunnableFrontendEvidence = hasRunnableFrontendComponentEvidence(workspaceRoot, candidate.path);
|
|
245592
|
+
const hasPublishSurface = hasPackagePublishSurface(packageJson);
|
|
245334
245593
|
if (lowerPath.endsWith("/db") || lowerPath.endsWith("/database") || lowerPath.endsWith("/data")) {
|
|
245335
245594
|
return "data";
|
|
245336
245595
|
}
|
|
245337
245596
|
const classification = candidate.architectureRoot?.classification;
|
|
245338
245597
|
if (classification === "frontend_app") {
|
|
245339
|
-
return "frontend";
|
|
245598
|
+
return hasPublishSurface && !hasRunnableFrontendEvidence ? "library" : "frontend";
|
|
245340
245599
|
}
|
|
245341
245600
|
if (classification === "backend_app") {
|
|
245342
245601
|
return "backend";
|
|
245343
245602
|
}
|
|
245603
|
+
if (hasRunnableFrontendEvidence && localProjectKinds.primaryKind !== "backend" && localProjectKinds.primaryKind !== "service" && localProjectKinds.primaryKind !== "cli") {
|
|
245604
|
+
return "frontend";
|
|
245605
|
+
}
|
|
245344
245606
|
if (classification === "shared_package") {
|
|
245345
245607
|
return "library";
|
|
245346
245608
|
}
|
|
245609
|
+
if (hasPublishSurface && !hasRunnableFrontendEvidence) {
|
|
245610
|
+
return "library";
|
|
245611
|
+
}
|
|
245347
245612
|
if (localProjectKinds.primaryKind === "service") {
|
|
245348
245613
|
return "worker";
|
|
245349
245614
|
}
|
|
@@ -245412,10 +245677,11 @@ function classifyGovernanceRole(input2) {
|
|
|
245412
245677
|
const scriptText = scripts.join(" ").toLowerCase();
|
|
245413
245678
|
const dependencyText = [...dependencies, ...devDependencies].join(" ").toLowerCase();
|
|
245414
245679
|
const hasStrongSupportPath = hasAnyToken(pathText, [
|
|
245415
|
-
/(^|\/)(testing|test-plugins|fixtures?|examples?|benchmarks?|smoke)(\/|$)/u,
|
|
245680
|
+
/(^|\/)(testing|test-plugins|cypress-tests|fixtures?|examples?|benchmarks?|smoke)(\/|$)/u,
|
|
245416
245681
|
/(^|\/)(dev-server|scaffold|scaffolding|generators?|devkit|tooling|tools)(\/|$)/u
|
|
245417
245682
|
]);
|
|
245418
|
-
const
|
|
245683
|
+
const isPlainResourcesSurface = isUnderJvmResourceRoot4(pathText) && !hasRuntimeSourceFiles(input2.workspaceRoot, input2.candidate.path) && !packageJson && !maven;
|
|
245684
|
+
const hasPublishSurface = hasPackagePublishSurface(packageJson);
|
|
245419
245685
|
const isPrivate = packageJson?.private === true;
|
|
245420
245686
|
const hasBin = hasObject(packageJson?.bin) || typeof packageJson?.bin === "string";
|
|
245421
245687
|
const mavenMetadataText = `${maven?.artifactId ?? ""} ${maven?.name ?? ""}`.toLowerCase();
|
|
@@ -245484,7 +245750,7 @@ function classifyGovernanceRole(input2) {
|
|
|
245484
245750
|
addEvidence6(evidence, "Package metadata describes development/tooling usage");
|
|
245485
245751
|
}
|
|
245486
245752
|
if (hasAnyToken(pathText, [
|
|
245487
|
-
/(^|\/)(test|tests|testing|__tests__|fixtures?|examples?|benchmarks?|smoke)(\/|$)/u,
|
|
245753
|
+
/(^|\/)(test|tests|testing|__tests__|cypress|cypress-tests|fixtures?|examples?|benchmarks?|smoke)(\/|$)/u,
|
|
245488
245754
|
/(^|\/)(dev-server|test-plugins|scaffold|scaffolding|generators?|devkit|tooling|tools)(\/|$)/u
|
|
245489
245755
|
])) {
|
|
245490
245756
|
supportScore += 1;
|
|
@@ -245534,6 +245800,17 @@ function classifyGovernanceRole(input2) {
|
|
|
245534
245800
|
supportScore += 1;
|
|
245535
245801
|
addEvidence6(evidence, "Maven POM-only aggregator/packaging module");
|
|
245536
245802
|
}
|
|
245803
|
+
if (isPlainResourcesSurface) {
|
|
245804
|
+
supportScore += 4;
|
|
245805
|
+
addEvidence6(evidence, "Resources-only surface without runtime source or manifest evidence");
|
|
245806
|
+
}
|
|
245807
|
+
if (isPlainResourcesSurface && input2.kind !== "infrastructure" && input2.stack !== "terraform" && input2.stack !== "ansible") {
|
|
245808
|
+
return {
|
|
245809
|
+
governanceRole: "support",
|
|
245810
|
+
governanceEvidence: uniqueSorted4(evidence),
|
|
245811
|
+
selectedByDefault: false
|
|
245812
|
+
};
|
|
245813
|
+
}
|
|
245537
245814
|
if (hasMavenDistributionPackagingEvidence && hasAnyToken(mavenMetadataText, [/\b(docs?|documentation|metadata tests?|licenses?|maven plugins?|builds?)\b/u])) {
|
|
245538
245815
|
supportScore += 3;
|
|
245539
245816
|
addEvidence6(evidence, "Maven documentation/build/distribution packaging evidence without runtime source");
|
|
@@ -245547,9 +245824,9 @@ function classifyGovernanceRole(input2) {
|
|
|
245547
245824
|
}
|
|
245548
245825
|
if (maven && (isMavenPomOnly || hasMavenDistributionPackagingEvidence) && supportScore >= 1) {
|
|
245549
245826
|
return {
|
|
245550
|
-
governanceRole: "
|
|
245827
|
+
governanceRole: "support",
|
|
245551
245828
|
governanceEvidence: uniqueSorted4(evidence),
|
|
245552
|
-
selectedByDefault:
|
|
245829
|
+
selectedByDefault: false
|
|
245553
245830
|
};
|
|
245554
245831
|
}
|
|
245555
245832
|
if (runtimeScore >= 2) {
|
|
@@ -245590,8 +245867,10 @@ function maybeAddAttributedApiAndDb(component, workspaceRoot, componentPath, arc
|
|
|
245590
245867
|
}
|
|
245591
245868
|
function detectComponents(input2) {
|
|
245592
245869
|
const ignoreMatcher = input2.ignoreMatcher ?? loadArchpilotIgnoreMatcher(input2.workspaceRoot);
|
|
245593
|
-
const manifestBackedRoots = new Set(
|
|
245594
|
-
|
|
245870
|
+
const manifestBackedRoots = new Set(
|
|
245871
|
+
(input2.topology.detectedRoots ?? []).filter((root) => !isUnderJvmResourceRoot4(root))
|
|
245872
|
+
);
|
|
245873
|
+
const rootCandidates = buildRootCandidates(input2).filter((candidate) => !ignoreMatcher.isIgnored(candidate.path)).filter((candidate) => !isIgnoredComponentCandidatePath(candidate.path)).filter((candidate) => !(isUnderJvmResourceRoot4(candidate.path) && !hasRuntimeSourceFiles(input2.workspaceRoot, candidate.path))).filter((candidate) => {
|
|
245595
245874
|
if (input2.topology.topology !== "monorepo" || manifestBackedRoots.size === 0) {
|
|
245596
245875
|
return true;
|
|
245597
245876
|
}
|
|
@@ -245614,7 +245893,7 @@ function detectComponents(input2) {
|
|
|
245614
245893
|
}
|
|
245615
245894
|
const localProjectKinds = input2.runContext?.detectProjectKinds(absoluteRoot) ?? detectProjectKinds(absoluteRoot);
|
|
245616
245895
|
const stackDetection = input2.runContext?.detectStacks(absoluteRoot) ?? detectStacks(absoluteRoot);
|
|
245617
|
-
const kind = resolveKind(candidate, localProjectKinds);
|
|
245896
|
+
const kind = resolveKind(input2.workspaceRoot, candidate, localProjectKinds);
|
|
245618
245897
|
const stack = resolveStack(kind, stackDetection);
|
|
245619
245898
|
const evidence = [...candidate.evidence];
|
|
245620
245899
|
if (candidate.architectureRoot?.classification && candidate.architectureRoot.classification !== "unknown") {
|
|
@@ -245851,6 +246130,10 @@ function getSelectedCandidate(detection) {
|
|
|
245851
246130
|
function getBackendComponents(detection) {
|
|
245852
246131
|
return (detection.detectedComponents ?? []).filter((component) => component.kind === "backend" || component.kind === "worker");
|
|
245853
246132
|
}
|
|
246133
|
+
function getDefaultGovernedBackendComponents(detection) {
|
|
246134
|
+
const components = detection.detectedComponents ?? [];
|
|
246135
|
+
return components.filter((component) => component.kind === "backend" || component.kind === "worker").filter((component) => isDefaultGovernedComponent(component, components));
|
|
246136
|
+
}
|
|
245854
246137
|
function getFrontendComponents(detection) {
|
|
245855
246138
|
return (detection.detectedComponents ?? []).filter((component) => component.kind === "frontend");
|
|
245856
246139
|
}
|
|
@@ -245990,7 +246273,8 @@ function resolveProposalComponents(detection) {
|
|
|
245990
246273
|
return components.length > 0 ? components : void 0;
|
|
245991
246274
|
}
|
|
245992
246275
|
function resolveResourceOwnerComponent(detection) {
|
|
245993
|
-
|
|
246276
|
+
const backendComponents = getDefaultGovernedBackendComponents(detection);
|
|
246277
|
+
return backendComponents.find((component) => component.kind === "backend") ?? backendComponents[0];
|
|
245994
246278
|
}
|
|
245995
246279
|
function resourceIdFor(ownerId, suffix) {
|
|
245996
246280
|
if (suffix === "api" && /(^|-)api$/u.test(ownerId)) {
|
|
@@ -246025,7 +246309,7 @@ function resolveProposalResources(input2) {
|
|
|
246025
246309
|
usedIds.add(resource.id);
|
|
246026
246310
|
resources.push(resource);
|
|
246027
246311
|
};
|
|
246028
|
-
for (const component of
|
|
246312
|
+
for (const component of getDefaultGovernedBackendComponents(input2.detection)) {
|
|
246029
246313
|
if (component.apiStyle && component.apiStyle !== "unknown" && component.apiStyle !== "none") {
|
|
246030
246314
|
addResource({
|
|
246031
246315
|
id: resourceIdFor(component.id, "api"),
|