@archpilotlabs/archpilot 0.2.5 → 0.2.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +30 -0
- package/dist/archpilot-cli.js +350 -61
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,35 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.2.6
|
|
4
|
+
|
|
5
|
+
### Improved
|
|
6
|
+
|
|
7
|
+
- Improved Smart Init component and repository topology classification across complex monorepos and multi-module repositories.
|
|
8
|
+
- Improved component classification accuracy across TypeScript/NestJS, Java/Spring, frontend, backend, library, multi-module, and mixed repository structures.
|
|
9
|
+
- Improved API-design analysis precision for terminal or unconditional collection endpoints.
|
|
10
|
+
- Improved event-architecture analysis for Spring listener declarations and inherited event types.
|
|
11
|
+
- Improved data-query-risk handling for real-world SQL, JPQL, Spring Data repository, and query-builder patterns.
|
|
12
|
+
- Bounded data-query-risk analysis for complex Java/Spring repository declarations to avoid pathological validation time.
|
|
13
|
+
- Expanded regression coverage from validation against multiple real public repository shapes.
|
|
14
|
+
|
|
15
|
+
### Fixed
|
|
16
|
+
|
|
17
|
+
- Fixed runtime Nx projects and shared libraries being missed or misclassified in package-layout workspaces.
|
|
18
|
+
- Fixed Maven runtime, library, support, distribution, and deploy-skipped modules being over- or under-promoted during Smart Init.
|
|
19
|
+
- Fixed file-like candidate paths aborting Smart Init traversal.
|
|
20
|
+
- Fixed terminal throw-only collection endpoints being reported as missing pagination.
|
|
21
|
+
- Fixed Spring event listeners using annotation attributes, `ApplicationListener<T>`, or parent event types being treated as unhandled.
|
|
22
|
+
- Fixed bounded Spring Data repository queries with `Pageable` or `Limit` parameters being reported as unbounded collection reads.
|
|
23
|
+
- Fixed SQL-looking comments, non-query files, and Spring configuration files contributing noisy data-query-risk findings.
|
|
24
|
+
|
|
25
|
+
### Notes
|
|
26
|
+
|
|
27
|
+
- This release focuses on public-repository model accuracy and analyzer correctness.
|
|
28
|
+
- These changes improve model and finding accuracy without changing rule IDs, severities, score weights, scoring caps, or normalization behavior.
|
|
29
|
+
- Existing architecture configurations remain backward compatible.
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
3
33
|
## 0.2.5
|
|
4
34
|
|
|
5
35
|
### Improved
|
package/dist/archpilot-cli.js
CHANGED
|
@@ -12907,7 +12907,7 @@ ${lanes.join("\n")}
|
|
|
12907
12907
|
return process.memoryUsage().heapUsed;
|
|
12908
12908
|
},
|
|
12909
12909
|
getFileSize(path74) {
|
|
12910
|
-
const stat =
|
|
12910
|
+
const stat = statSync2(path74);
|
|
12911
12911
|
if (stat == null ? void 0 : stat.isFile()) {
|
|
12912
12912
|
return stat.size;
|
|
12913
12913
|
}
|
|
@@ -12951,7 +12951,7 @@ ${lanes.join("\n")}
|
|
|
12951
12951
|
}
|
|
12952
12952
|
};
|
|
12953
12953
|
return nodeSystem;
|
|
12954
|
-
function
|
|
12954
|
+
function statSync2(path74) {
|
|
12955
12955
|
try {
|
|
12956
12956
|
return _fs.statSync(path74, statSyncOptions);
|
|
12957
12957
|
} catch {
|
|
@@ -13010,7 +13010,7 @@ ${lanes.join("\n")}
|
|
|
13010
13010
|
activeSession.post("Profiler.stop", (err, { profile }) => {
|
|
13011
13011
|
var _a;
|
|
13012
13012
|
if (!err) {
|
|
13013
|
-
if ((_a =
|
|
13013
|
+
if ((_a = statSync2(profilePath)) == null ? void 0 : _a.isDirectory()) {
|
|
13014
13014
|
profilePath = _path.join(profilePath, `${(/* @__PURE__ */ new Date()).toISOString().replace(/:/g, "-")}+P${process.pid}.cpuprofile`);
|
|
13015
13015
|
}
|
|
13016
13016
|
try {
|
|
@@ -13130,7 +13130,7 @@ ${lanes.join("\n")}
|
|
|
13130
13130
|
let stat;
|
|
13131
13131
|
if (typeof dirent === "string" || dirent.isSymbolicLink()) {
|
|
13132
13132
|
const name = combinePaths(path74, entry);
|
|
13133
|
-
stat =
|
|
13133
|
+
stat = statSync2(name);
|
|
13134
13134
|
if (!stat) {
|
|
13135
13135
|
continue;
|
|
13136
13136
|
}
|
|
@@ -13154,7 +13154,7 @@ ${lanes.join("\n")}
|
|
|
13154
13154
|
return matchFiles(path74, extensions, excludes, includes, useCaseSensitiveFileNames2, process.cwd(), depth, getAccessibleFileSystemEntries, realpath);
|
|
13155
13155
|
}
|
|
13156
13156
|
function fileSystemEntryExists(path74, entryKind) {
|
|
13157
|
-
const stat =
|
|
13157
|
+
const stat = statSync2(path74);
|
|
13158
13158
|
if (!stat) {
|
|
13159
13159
|
return false;
|
|
13160
13160
|
}
|
|
@@ -13196,7 +13196,7 @@ ${lanes.join("\n")}
|
|
|
13196
13196
|
}
|
|
13197
13197
|
function getModifiedTime3(path74) {
|
|
13198
13198
|
var _a;
|
|
13199
|
-
return (_a =
|
|
13199
|
+
return (_a = statSync2(path74)) == null ? void 0 : _a.mtime;
|
|
13200
13200
|
}
|
|
13201
13201
|
function setModifiedTime(path74, time) {
|
|
13202
13202
|
try {
|
|
@@ -225435,6 +225435,7 @@ init_sourceScopeClassification();
|
|
|
225435
225435
|
var maxFileSizeBytes = 256 * 1024;
|
|
225436
225436
|
var supplementalRiskScanExtensions = [".json", ".yaml", ".yml", ".sql"];
|
|
225437
225437
|
var backendCodeExtensions = [".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs", ".java", ".cs", ".py", ".php", ".go"];
|
|
225438
|
+
var methodBodyScanExtensions = new Set(backendCodeExtensions);
|
|
225438
225439
|
var supplementalIgnoredDirectoryNames = [".vscode-test", ".tmp"];
|
|
225439
225440
|
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;
|
|
225440
225441
|
var queryReadPattern = /\b((?:this\.)?(?:prisma\.(\w+)|([A-Za-z_$][\w$]*Repository|repository))\.(find\w*|count|aggregate|groupBy)\s*\()/giu;
|
|
@@ -225443,6 +225444,7 @@ var boundEvidencePattern = /\b(?:take|limit|page|cursor|skip|offset|PageRequest|
|
|
|
225443
225444
|
var repeatedQueryPattern = /\b((?:this\.)?(?:prisma\.(\w+)|(\w*Repository|repository))\.(find\w*|count|aggregate|groupBy)\s*\(\s*(?:\{[\s\S]{0,300}?\}|\w+)\s*\))/giu;
|
|
225444
225445
|
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;
|
|
225445
225446
|
var codePaginationEvidencePattern = /\b(?:take|skip|limit|offset|page|perPage|pageSize|cursor|Pageable|PageRequest|paginate|simplePaginate|Limit|Offset|Take|Skip|TOP\s+\d+)\b/iu;
|
|
225447
|
+
var sqlQueryInvocationHintPattern = /\b(?:query|execute|executeQuery|createNativeQuery|createQuery|FromSqlRaw|FromSqlInterpolated|Query|QueryContext|QueryRow|QueryRowContext|Exec|ExecContext|Raw|text|DB::select|DB::statement|DB::raw|DB::table)\s*\(|\$queryRaw\s*\(|\$executeRaw\s*\(|@Query\s*\(/u;
|
|
225446
225448
|
function getLineStarts(file) {
|
|
225447
225449
|
if (file.lineStarts) {
|
|
225448
225450
|
return file.lineStarts;
|
|
@@ -225666,10 +225668,15 @@ function hasPaginationEvidence(statement) {
|
|
|
225666
225668
|
);
|
|
225667
225669
|
}
|
|
225668
225670
|
function hasEqualityPredicate(statement, columnPattern) {
|
|
225671
|
+
const whereMatch = /\bwhere\b/iu.exec(statement);
|
|
225672
|
+
if (!whereMatch) {
|
|
225673
|
+
return false;
|
|
225674
|
+
}
|
|
225675
|
+
const predicateWindow = statement.slice(whereMatch.index, whereMatch.index + 1200);
|
|
225669
225676
|
return new RegExp(
|
|
225670
|
-
`\\
|
|
225677
|
+
`\\b(?:${columnPattern})\\b\\s*=\\s*(?:[\\w$:@?]+|'[^']+'|"[^"]+"|\\d+)`,
|
|
225671
225678
|
"iu"
|
|
225672
|
-
).test(
|
|
225679
|
+
).test(predicateWindow);
|
|
225673
225680
|
}
|
|
225674
225681
|
function isCatalogIdentifierPointLookup(statement) {
|
|
225675
225682
|
const metadataSourcePattern = /\bfrom\s+(?:information_schema\.(?:schemata|tables|columns|key_column_usage|table_constraints)|pg_catalog\.(?:pg_class|pg_namespace|pg_attribute|pg_constraint|pg_type|pg_enum|pg_tables|pg_indexes)|pg_(?:class|namespace|attribute|constraint|type|enum|tables|indexes))\b/iu;
|
|
@@ -226270,6 +226277,9 @@ function detectRepeatedQueryPattern(method) {
|
|
|
226270
226277
|
}
|
|
226271
226278
|
function extractSqlQueryLiterals(content) {
|
|
226272
226279
|
const queries = [];
|
|
226280
|
+
if (!sqlQueryInvocationHintPattern.test(content)) {
|
|
226281
|
+
return queries;
|
|
226282
|
+
}
|
|
226273
226283
|
const searchableContent = maskSourceComments(content);
|
|
226274
226284
|
const patterns = [
|
|
226275
226285
|
/(?:\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,
|
|
@@ -226291,7 +226301,7 @@ function extractSqlQueryLiterals(content) {
|
|
|
226291
226301
|
return queries;
|
|
226292
226302
|
}
|
|
226293
226303
|
function maskSourceComments(content) {
|
|
226294
|
-
|
|
226304
|
+
const masked = [];
|
|
226295
226305
|
let index = 0;
|
|
226296
226306
|
let state = "code";
|
|
226297
226307
|
let escaped = false;
|
|
@@ -226300,27 +226310,27 @@ function maskSourceComments(content) {
|
|
|
226300
226310
|
const next = content[index + 1] ?? "";
|
|
226301
226311
|
if (state === "line-comment") {
|
|
226302
226312
|
if (current === "\r" || current === "\n") {
|
|
226303
|
-
masked
|
|
226313
|
+
masked.push(current);
|
|
226304
226314
|
state = "code";
|
|
226305
226315
|
} else {
|
|
226306
|
-
masked
|
|
226316
|
+
masked.push(" ");
|
|
226307
226317
|
}
|
|
226308
226318
|
index += 1;
|
|
226309
226319
|
continue;
|
|
226310
226320
|
}
|
|
226311
226321
|
if (state === "block-comment") {
|
|
226312
226322
|
if (current === "*" && next === "/") {
|
|
226313
|
-
masked
|
|
226323
|
+
masked.push(" ");
|
|
226314
226324
|
index += 2;
|
|
226315
226325
|
state = "code";
|
|
226316
226326
|
continue;
|
|
226317
226327
|
}
|
|
226318
|
-
masked
|
|
226328
|
+
masked.push(current === "\r" || current === "\n" ? current : " ");
|
|
226319
226329
|
index += 1;
|
|
226320
226330
|
continue;
|
|
226321
226331
|
}
|
|
226322
226332
|
if (state === "single" || state === "double" || state === "template") {
|
|
226323
|
-
masked
|
|
226333
|
+
masked.push(current);
|
|
226324
226334
|
if (escaped) {
|
|
226325
226335
|
escaped = false;
|
|
226326
226336
|
} else if (current === "\\") {
|
|
@@ -226332,13 +226342,13 @@ function maskSourceComments(content) {
|
|
|
226332
226342
|
continue;
|
|
226333
226343
|
}
|
|
226334
226344
|
if (current === "/" && next === "/") {
|
|
226335
|
-
masked
|
|
226345
|
+
masked.push(" ");
|
|
226336
226346
|
index += 2;
|
|
226337
226347
|
state = "line-comment";
|
|
226338
226348
|
continue;
|
|
226339
226349
|
}
|
|
226340
226350
|
if (current === "/" && next === "*") {
|
|
226341
|
-
masked
|
|
226351
|
+
masked.push(" ");
|
|
226342
226352
|
index += 2;
|
|
226343
226353
|
state = "block-comment";
|
|
226344
226354
|
continue;
|
|
@@ -226350,10 +226360,10 @@ function maskSourceComments(content) {
|
|
|
226350
226360
|
} else if (current === "`") {
|
|
226351
226361
|
state = "template";
|
|
226352
226362
|
}
|
|
226353
|
-
masked
|
|
226363
|
+
masked.push(current);
|
|
226354
226364
|
index += 1;
|
|
226355
226365
|
}
|
|
226356
|
-
return masked;
|
|
226366
|
+
return masked.join("");
|
|
226357
226367
|
}
|
|
226358
226368
|
function detectCodeSqlQueryShapeFindings(file, config) {
|
|
226359
226369
|
const findings = [];
|
|
@@ -226383,7 +226393,7 @@ function detectCodeSqlQueryShapeFindings(file, config) {
|
|
|
226383
226393
|
target: firstTable ?? "sql-query"
|
|
226384
226394
|
}));
|
|
226385
226395
|
}
|
|
226386
|
-
if (statement.queryType === "select" && !isOperationalOrBatchQueryContext(file) && !hasPaginationEvidence(statement.statement) && !isObviousPointLookup(statement.statement) && !/\bcount\s*\(/i.test(statement.statement)) {
|
|
226396
|
+
if (statement.queryType === "select" && !isOperationalOrBatchQueryContext(file) && !hasPaginationEvidence(statement.statement) && !hasSpringDataRepositoryMethodBoundEvidence(file.content, query.offset) && !isObviousPointLookup(statement.statement) && !/\bcount\s*\(/i.test(statement.statement)) {
|
|
226387
226397
|
findings.push(createCodeFinding({
|
|
226388
226398
|
id: "AP-DQR-003",
|
|
226389
226399
|
message: `Potential unbounded query risk: SELECT query${firstTable ? ` on table '${firstTable}'` : ""} has no LIMIT/OFFSET/FETCH pagination evidence.`,
|
|
@@ -226397,6 +226407,18 @@ function detectCodeSqlQueryShapeFindings(file, config) {
|
|
|
226397
226407
|
}
|
|
226398
226408
|
return findings;
|
|
226399
226409
|
}
|
|
226410
|
+
function hasSpringDataRepositoryMethodBoundEvidence(content, queryOffset) {
|
|
226411
|
+
const annotationOffset = content.lastIndexOf("@Query", queryOffset);
|
|
226412
|
+
if (annotationOffset < 0 || queryOffset - annotationOffset > 2400) {
|
|
226413
|
+
return false;
|
|
226414
|
+
}
|
|
226415
|
+
const semicolonOffset = content.indexOf(";", queryOffset);
|
|
226416
|
+
if (semicolonOffset < queryOffset || semicolonOffset - annotationOffset > 3200) {
|
|
226417
|
+
return false;
|
|
226418
|
+
}
|
|
226419
|
+
const declarationWindow = content.slice(queryOffset, semicolonOffset + 1);
|
|
226420
|
+
return /\b(?:Page|Slice|Window)\s*</u.test(declarationWindow) && /\b(?:Pageable|Limit)\s+\w+\b/u.test(declarationWindow);
|
|
226421
|
+
}
|
|
226400
226422
|
function collectOrmReadEvidence(method) {
|
|
226401
226423
|
const patterns = [
|
|
226402
226424
|
[/\b(?:this\.)?prisma\.\w+\.findMany\s*\(/giu, "prisma.findMany"],
|
|
@@ -226514,7 +226536,11 @@ function detectCodeQueryRiskFindings(files, config, astCache) {
|
|
|
226514
226536
|
if (isProductionBackend) {
|
|
226515
226537
|
findings.push(...detectCodeSqlQueryShapeFindings(file, config));
|
|
226516
226538
|
}
|
|
226517
|
-
|
|
226539
|
+
if (!methodBodyScanExtensions.has(file.extension)) {
|
|
226540
|
+
continue;
|
|
226541
|
+
}
|
|
226542
|
+
const methods = extractMethodBodies(file, astCache);
|
|
226543
|
+
for (const method of methods) {
|
|
226518
226544
|
if (!isProductionBackend) {
|
|
226519
226545
|
continue;
|
|
226520
226546
|
}
|
|
@@ -229970,8 +229996,15 @@ function isStaticCollectionBackedEndpoint(endpoint) {
|
|
|
229970
229996
|
}
|
|
229971
229997
|
return isStaticCollectionExpression(stripStaticLiteralNoise(expression));
|
|
229972
229998
|
}
|
|
229999
|
+
function isUnconditionallyTerminalThrowEndpoint(endpoint) {
|
|
230000
|
+
const body = endpoint.body.trim().replace(/^\{\s*/u, "").replace(/\s*\}$/u, "").trim();
|
|
230001
|
+
if (!/^throw\s+new\s+[A-Z]\w*(?:Exception|Error)\s*\([^;{}]*\)\s*;?$/u.test(body)) {
|
|
230002
|
+
return false;
|
|
230003
|
+
}
|
|
230004
|
+
return !/\b(?:if|for|while|switch|try|catch|return|await|yield)\b/u.test(body);
|
|
230005
|
+
}
|
|
229973
230006
|
function detectPaginationFindings(endpoints, contractEndpoints) {
|
|
229974
|
-
return endpoints.filter((endpoint) => isCollectionGet(endpoint) && !hasPaginationEvidence2(endpoint, contractEndpoints) && !isStaticCollectionBackedEndpoint(endpoint)).map((endpoint) => createFinding4({
|
|
230007
|
+
return endpoints.filter((endpoint) => isCollectionGet(endpoint) && !hasPaginationEvidence2(endpoint, contractEndpoints) && !isStaticCollectionBackedEndpoint(endpoint) && !isUnconditionallyTerminalThrowEndpoint(endpoint)).map((endpoint) => createFinding4({
|
|
229975
230008
|
id: RuleIds3.MISSING_PAGINATION,
|
|
229976
230009
|
message: `Collection endpoint ${endpoint.httpMethod.toUpperCase()} ${endpoint.path} lacks visible pagination evidence.`,
|
|
229977
230010
|
endpoint
|
|
@@ -230731,12 +230764,14 @@ function extractTypeScriptSignals(file, astCache) {
|
|
|
230731
230764
|
ts6.forEachChild(node, visit);
|
|
230732
230765
|
};
|
|
230733
230766
|
visit(sourceFile);
|
|
230734
|
-
return { publishes, handlers: handlers2, publicEventNames: /* @__PURE__ */ new Set() };
|
|
230767
|
+
return { publishes, handlers: handlers2, publicEventNames: /* @__PURE__ */ new Set(), eventTypeParents: /* @__PURE__ */ new Map() };
|
|
230735
230768
|
}
|
|
230736
230769
|
function extractJavaSignals(file) {
|
|
230737
230770
|
const publishes = [];
|
|
230738
230771
|
const handlers2 = [];
|
|
230739
|
-
for (const match of file.content.matchAll(
|
|
230772
|
+
for (const match of file.content.matchAll(
|
|
230773
|
+
/@EventListener\s*(?:\(\s*(?:(?:classes|value)\s*=\s*)?(?:\{\s*)?([A-Za-z_]\w*)\.class\s*(?:\})?\s*\))?/gu
|
|
230774
|
+
)) {
|
|
230740
230775
|
const eventName = match[1] ?? "ApplicationEvent";
|
|
230741
230776
|
handlers2.push({
|
|
230742
230777
|
eventName,
|
|
@@ -230748,6 +230783,21 @@ function extractJavaSignals(file) {
|
|
|
230748
230783
|
publishes: []
|
|
230749
230784
|
});
|
|
230750
230785
|
}
|
|
230786
|
+
for (const match of file.content.matchAll(/\b(?:class|interface)\s+\w+[^{;]*\bApplicationListener\s*<\s*([A-Za-z_]\w*)\s*>/gu)) {
|
|
230787
|
+
const eventName = match[1];
|
|
230788
|
+
if (!eventName) {
|
|
230789
|
+
continue;
|
|
230790
|
+
}
|
|
230791
|
+
handlers2.push({
|
|
230792
|
+
eventName,
|
|
230793
|
+
normalizedName: normalizeEventName(eventName),
|
|
230794
|
+
file,
|
|
230795
|
+
line: lineNumberForOffset5(file, match.index ?? 0),
|
|
230796
|
+
module: file.module,
|
|
230797
|
+
style: classifyEventStyle(eventName),
|
|
230798
|
+
publishes: []
|
|
230799
|
+
});
|
|
230800
|
+
}
|
|
230751
230801
|
for (const match of file.content.matchAll(/(?:await\s+)?(?:\w+\.)?(?:publishEvent|publish|emit)\s*\(\s*(?:(new)\s+([A-Za-z_]\w*(?:\.[A-Za-z_]\w*)*)\s*\(|(["'])([A-Za-z][\w.]*Event?|[a-z][\w.]+)\3|([A-Z][A-Za-z0-9_]*Event)\b)/gu)) {
|
|
230752
230802
|
const constructedType = match[2]?.split(".").at(-1);
|
|
230753
230803
|
const eventName = constructedType ?? match[4] ?? match[5];
|
|
@@ -230765,7 +230815,23 @@ function extractJavaSignals(file) {
|
|
|
230765
230815
|
assignedOrReturned: false
|
|
230766
230816
|
});
|
|
230767
230817
|
}
|
|
230768
|
-
return { publishes, handlers: handlers2, publicEventNames: /* @__PURE__ */ new Set() };
|
|
230818
|
+
return { publishes, handlers: handlers2, publicEventNames: /* @__PURE__ */ new Set(), eventTypeParents: extractJavaEventTypeParents(file) };
|
|
230819
|
+
}
|
|
230820
|
+
function extractJavaEventTypeParents(file) {
|
|
230821
|
+
const parentsByType = /* @__PURE__ */ new Map();
|
|
230822
|
+
for (const match of file.content.matchAll(/\b(?:class|record)\s+([A-Za-z_]\w*)(?:\s*<[^>{}]+>)?\s+extends\s+([A-Za-z_]\w*)/gu)) {
|
|
230823
|
+
const child = match[1];
|
|
230824
|
+
const parent = match[2];
|
|
230825
|
+
if (!child || !parent || !child.endsWith("Event")) {
|
|
230826
|
+
continue;
|
|
230827
|
+
}
|
|
230828
|
+
const normalizedChild = normalizeEventName(child);
|
|
230829
|
+
const normalizedParent = normalizeEventName(parent);
|
|
230830
|
+
const parents = parentsByType.get(normalizedChild) ?? /* @__PURE__ */ new Set();
|
|
230831
|
+
parents.add(normalizedParent);
|
|
230832
|
+
parentsByType.set(normalizedChild, parents);
|
|
230833
|
+
}
|
|
230834
|
+
return parentsByType;
|
|
230769
230835
|
}
|
|
230770
230836
|
function extractPublishSignalsFromText(file, body, baseOffset, pattern) {
|
|
230771
230837
|
const publishes = [];
|
|
@@ -230811,7 +230877,7 @@ function extractCsharpSignals(file) {
|
|
|
230811
230877
|
publishes: extractPublishSignalsFromText(file, classBody, classOpenBrace >= 0 ? classOpenBrace : classStart, csharpPublishPattern)
|
|
230812
230878
|
});
|
|
230813
230879
|
}
|
|
230814
|
-
return { publishes, handlers: handlers2, publicEventNames: /* @__PURE__ */ new Set() };
|
|
230880
|
+
return { publishes, handlers: handlers2, publicEventNames: /* @__PURE__ */ new Set(), eventTypeParents: /* @__PURE__ */ new Map() };
|
|
230815
230881
|
}
|
|
230816
230882
|
function extractPythonSignals(file) {
|
|
230817
230883
|
const publishes = extractPublishSignalsFromText(file, file.content, 0, pythonPublishPattern);
|
|
@@ -230834,7 +230900,7 @@ function extractPythonSignals(file) {
|
|
|
230834
230900
|
publishes: extractPublishSignalsFromText(file, block, blockStart, pythonPublishPattern)
|
|
230835
230901
|
});
|
|
230836
230902
|
}
|
|
230837
|
-
return { publishes, handlers: handlers2, publicEventNames: /* @__PURE__ */ new Set() };
|
|
230903
|
+
return { publishes, handlers: handlers2, publicEventNames: /* @__PURE__ */ new Set(), eventTypeParents: /* @__PURE__ */ new Map() };
|
|
230838
230904
|
}
|
|
230839
230905
|
function extractPhpSignals(file) {
|
|
230840
230906
|
const publishes = extractPublishSignalsFromText(file, file.content, 0, phpEventPublishPattern);
|
|
@@ -230859,7 +230925,7 @@ function extractPhpSignals(file) {
|
|
|
230859
230925
|
publishes: extractPublishSignalsFromText(file, classBody, classOpenBrace >= 0 ? classOpenBrace : classStart, phpEventPublishPattern)
|
|
230860
230926
|
});
|
|
230861
230927
|
}
|
|
230862
|
-
return { publishes, handlers: handlers2, publicEventNames: /* @__PURE__ */ new Set() };
|
|
230928
|
+
return { publishes, handlers: handlers2, publicEventNames: /* @__PURE__ */ new Set(), eventTypeParents: /* @__PURE__ */ new Map() };
|
|
230863
230929
|
}
|
|
230864
230930
|
function extractGoSignals(file) {
|
|
230865
230931
|
const publishes = extractPublishSignalsFromText(file, file.content, 0, goPublishPattern);
|
|
@@ -230879,7 +230945,7 @@ function extractGoSignals(file) {
|
|
|
230879
230945
|
publishes: []
|
|
230880
230946
|
});
|
|
230881
230947
|
}
|
|
230882
|
-
return { publishes, handlers: handlers2, publicEventNames: /* @__PURE__ */ new Set() };
|
|
230948
|
+
return { publishes, handlers: handlers2, publicEventNames: /* @__PURE__ */ new Set(), eventTypeParents: /* @__PURE__ */ new Map() };
|
|
230883
230949
|
}
|
|
230884
230950
|
function isTypeScriptLikeExtension(extension) {
|
|
230885
230951
|
return [".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"].includes(extension);
|
|
@@ -230979,6 +231045,7 @@ function collectPublicTypeScriptEventNames(files, contract, astCache) {
|
|
|
230979
231045
|
function collectSignals(files, contract, astCache) {
|
|
230980
231046
|
const publishes = [];
|
|
230981
231047
|
const handlers2 = [];
|
|
231048
|
+
const eventTypeParents = /* @__PURE__ */ new Map();
|
|
230982
231049
|
const publicEventNames = collectPublicTypeScriptEventNames(files, contract, astCache);
|
|
230983
231050
|
for (const file of files) {
|
|
230984
231051
|
let signals;
|
|
@@ -231004,14 +231071,41 @@ function collectSignals(files, contract, astCache) {
|
|
|
231004
231071
|
}
|
|
231005
231072
|
publishes.push(...signals.publishes);
|
|
231006
231073
|
handlers2.push(...signals.handlers);
|
|
231074
|
+
for (const [eventName, parents] of signals.eventTypeParents) {
|
|
231075
|
+
const existing = eventTypeParents.get(eventName) ?? /* @__PURE__ */ new Set();
|
|
231076
|
+
for (const parent of parents) {
|
|
231077
|
+
existing.add(parent);
|
|
231078
|
+
}
|
|
231079
|
+
eventTypeParents.set(eventName, existing);
|
|
231080
|
+
}
|
|
231007
231081
|
}
|
|
231008
|
-
return { publishes, handlers: handlers2, publicEventNames };
|
|
231082
|
+
return { publishes, handlers: handlers2, publicEventNames, eventTypeParents };
|
|
231083
|
+
}
|
|
231084
|
+
function isHandledEventName(normalizedName, handledNames, eventTypeParents) {
|
|
231085
|
+
const queue = [normalizedName];
|
|
231086
|
+
const visited = /* @__PURE__ */ new Set();
|
|
231087
|
+
while (queue.length > 0) {
|
|
231088
|
+
const current = queue.shift();
|
|
231089
|
+
if (!current || visited.has(current)) {
|
|
231090
|
+
continue;
|
|
231091
|
+
}
|
|
231092
|
+
if (handledNames.has(current)) {
|
|
231093
|
+
return true;
|
|
231094
|
+
}
|
|
231095
|
+
visited.add(current);
|
|
231096
|
+
for (const parent of eventTypeParents.get(current) ?? []) {
|
|
231097
|
+
if (!visited.has(parent)) {
|
|
231098
|
+
queue.push(parent);
|
|
231099
|
+
}
|
|
231100
|
+
}
|
|
231101
|
+
}
|
|
231102
|
+
return false;
|
|
231009
231103
|
}
|
|
231010
231104
|
function buildEventFindings(signals) {
|
|
231011
231105
|
const findings = [];
|
|
231012
231106
|
const handledNames = new Set(signals.handlers.map((handler) => handler.normalizedName));
|
|
231013
231107
|
for (const publish of signals.publishes) {
|
|
231014
|
-
if (!
|
|
231108
|
+
if (!isHandledEventName(publish.normalizedName, handledNames, signals.eventTypeParents)) {
|
|
231015
231109
|
if (signals.publicEventNames.has(publish.normalizedName)) {
|
|
231016
231110
|
continue;
|
|
231017
231111
|
}
|
|
@@ -243013,8 +243107,6 @@ var ignoredRootPathPrefixes = [
|
|
|
243013
243107
|
"static",
|
|
243014
243108
|
"assets",
|
|
243015
243109
|
"vendor",
|
|
243016
|
-
"plugins",
|
|
243017
|
-
"plugin",
|
|
243018
243110
|
"themes",
|
|
243019
243111
|
"theme",
|
|
243020
243112
|
"generated",
|
|
@@ -243037,8 +243129,12 @@ function pushEvidence(evidence, message) {
|
|
|
243037
243129
|
function safeReadDirectoryEntries(directoryPath) {
|
|
243038
243130
|
try {
|
|
243039
243131
|
return fs52.readdirSync(directoryPath, { withFileTypes: true });
|
|
243040
|
-
} catch {
|
|
243041
|
-
|
|
243132
|
+
} catch (error) {
|
|
243133
|
+
const code = typeof error === "object" && error !== null && "code" in error ? String(error.code) : "";
|
|
243134
|
+
if (code === "ENOENT" || code === "ENOTDIR") {
|
|
243135
|
+
return [];
|
|
243136
|
+
}
|
|
243137
|
+
throw error;
|
|
243042
243138
|
}
|
|
243043
243139
|
}
|
|
243044
243140
|
function safeReadJsonFile(jsonPath) {
|
|
@@ -245612,8 +245708,6 @@ function isIgnoredComponentCandidatePath(componentPath) {
|
|
|
245612
245708
|
"static",
|
|
245613
245709
|
"assets",
|
|
245614
245710
|
"vendor",
|
|
245615
|
-
"plugins",
|
|
245616
|
-
"plugin",
|
|
245617
245711
|
"themes",
|
|
245618
245712
|
"theme",
|
|
245619
245713
|
"generated",
|
|
@@ -245634,6 +245728,36 @@ function pathExists19(pathValue) {
|
|
|
245634
245728
|
return false;
|
|
245635
245729
|
}
|
|
245636
245730
|
}
|
|
245731
|
+
function isSafeMissingPathError(error) {
|
|
245732
|
+
const code = typeof error === "object" && error !== null && "code" in error ? String(error.code) : "";
|
|
245733
|
+
return code === "ENOENT" || code === "ENOTDIR";
|
|
245734
|
+
}
|
|
245735
|
+
function isDirectoryPath(pathValue) {
|
|
245736
|
+
try {
|
|
245737
|
+
return fs58.statSync(pathValue).isDirectory();
|
|
245738
|
+
} catch (error) {
|
|
245739
|
+
if (isSafeMissingPathError(error)) {
|
|
245740
|
+
return false;
|
|
245741
|
+
}
|
|
245742
|
+
throw error;
|
|
245743
|
+
}
|
|
245744
|
+
}
|
|
245745
|
+
function readDirectoryEntriesForTraversal(directoryPath, options) {
|
|
245746
|
+
if (!isDirectoryPath(directoryPath)) {
|
|
245747
|
+
return [];
|
|
245748
|
+
}
|
|
245749
|
+
try {
|
|
245750
|
+
return fs58.readdirSync(directoryPath, {
|
|
245751
|
+
withFileTypes: true,
|
|
245752
|
+
...options?.recursive ? { recursive: true } : {}
|
|
245753
|
+
});
|
|
245754
|
+
} catch (error) {
|
|
245755
|
+
if (isSafeMissingPathError(error)) {
|
|
245756
|
+
return [];
|
|
245757
|
+
}
|
|
245758
|
+
throw error;
|
|
245759
|
+
}
|
|
245760
|
+
}
|
|
245637
245761
|
function hasManifest2(workspaceRoot, componentPath) {
|
|
245638
245762
|
const absoluteRoot = componentPath === "." ? workspaceRoot : path64.join(workspaceRoot, ...componentPath.split("/"));
|
|
245639
245763
|
return [
|
|
@@ -245641,7 +245765,8 @@ function hasManifest2(workspaceRoot, componentPath) {
|
|
|
245641
245765
|
"pom.xml",
|
|
245642
245766
|
"requirements.txt",
|
|
245643
245767
|
"go.mod",
|
|
245644
|
-
"composer.json"
|
|
245768
|
+
"composer.json",
|
|
245769
|
+
"project.json"
|
|
245645
245770
|
].some((fileName) => pathExists19(path64.join(absoluteRoot, fileName)));
|
|
245646
245771
|
}
|
|
245647
245772
|
function safeReadJson(filePath) {
|
|
@@ -245664,6 +245789,10 @@ function recordKeys(value) {
|
|
|
245664
245789
|
function hasObject(value) {
|
|
245665
245790
|
return Boolean(value && typeof value === "object" && !Array.isArray(value));
|
|
245666
245791
|
}
|
|
245792
|
+
function readStringProperty(value, key) {
|
|
245793
|
+
const field = value?.[key];
|
|
245794
|
+
return typeof field === "string" && field.trim().length > 0 ? field.trim() : void 0;
|
|
245795
|
+
}
|
|
245667
245796
|
function hasPackagePublishSurface(packageJson) {
|
|
245668
245797
|
return hasObject(packageJson?.exports) || typeof packageJson?.main === "string" || typeof packageJson?.module === "string" || typeof packageJson?.types === "string" || hasObject(packageJson?.publishConfig) || Array.isArray(packageJson?.files);
|
|
245669
245798
|
}
|
|
@@ -245686,6 +245815,132 @@ function readProjectJson(workspaceRoot, componentPath) {
|
|
|
245686
245815
|
const absoluteRoot = absoluteComponentRoot(workspaceRoot, componentPath);
|
|
245687
245816
|
return safeReadJson(path64.join(absoluteRoot, "project.json"));
|
|
245688
245817
|
}
|
|
245818
|
+
function readNxWorkspaceLayout(workspaceRoot) {
|
|
245819
|
+
const nxJson = safeReadJson(path64.join(workspaceRoot, "nx.json"));
|
|
245820
|
+
const workspaceLayout = nxJson?.workspaceLayout;
|
|
245821
|
+
if (!hasObject(workspaceLayout)) {
|
|
245822
|
+
return {};
|
|
245823
|
+
}
|
|
245824
|
+
const layout = workspaceLayout;
|
|
245825
|
+
return {
|
|
245826
|
+
...typeof layout.appsDir === "string" && layout.appsDir.trim().length > 0 ? { appsDir: normalizePath25(layout.appsDir.trim()) } : {},
|
|
245827
|
+
...typeof layout.libsDir === "string" && layout.libsDir.trim().length > 0 ? { libsDir: normalizePath25(layout.libsDir.trim()) } : {}
|
|
245828
|
+
};
|
|
245829
|
+
}
|
|
245830
|
+
function readTargetMap(projectJson) {
|
|
245831
|
+
const targets = projectJson?.targets ?? projectJson?.architect;
|
|
245832
|
+
return hasObject(targets) ? targets : {};
|
|
245833
|
+
}
|
|
245834
|
+
function targetExecutorText(target) {
|
|
245835
|
+
if (!hasObject(target)) {
|
|
245836
|
+
return "";
|
|
245837
|
+
}
|
|
245838
|
+
const typed = target;
|
|
245839
|
+
const executor = typeof typed.executor === "string" ? typed.executor : "";
|
|
245840
|
+
const builder = typeof typed.builder === "string" ? typed.builder : "";
|
|
245841
|
+
const options = hasObject(typed.options) ? typed.options : {};
|
|
245842
|
+
const main = typeof options.main === "string" ? options.main : "";
|
|
245843
|
+
const index = typeof options.index === "string" ? options.index : "";
|
|
245844
|
+
const outputPath = typeof options.outputPath === "string" ? options.outputPath : "";
|
|
245845
|
+
return `${executor} ${builder} ${main} ${index} ${outputPath}`.toLowerCase();
|
|
245846
|
+
}
|
|
245847
|
+
function hasNxRuntimeProjectEvidence(projectJson) {
|
|
245848
|
+
const projectType = readStringProperty(projectJson, "projectType");
|
|
245849
|
+
if (projectType === "library") {
|
|
245850
|
+
return false;
|
|
245851
|
+
}
|
|
245852
|
+
const targets = readTargetMap(projectJson);
|
|
245853
|
+
const targetNames = Object.keys(targets);
|
|
245854
|
+
const targetText = targetNames.map((targetName) => `${targetName} ${targetExecutorText(targets[targetName])}`).join(" ");
|
|
245855
|
+
const hasRuntimeTarget = /\b(?:serve|start|preview|worker|package:container|deploy:static)\b/u.test(targetText);
|
|
245856
|
+
const hasBuildEntrypoint = /\bbuild\b/u.test(targetNames.join(" ")) && /(?:\bmain\b|src\/main|src\/index|public\/index|webpack|vite|next|node|container|browser|dev-server)/u.test(targetText);
|
|
245857
|
+
return projectType === "application" || hasRuntimeTarget || hasBuildEntrypoint;
|
|
245858
|
+
}
|
|
245859
|
+
function hasNxSupportOnlyProjectEvidence(projectJson) {
|
|
245860
|
+
const projectType = readStringProperty(projectJson, "projectType");
|
|
245861
|
+
const targets = readTargetMap(projectJson);
|
|
245862
|
+
const targetNames = Object.keys(targets);
|
|
245863
|
+
if (targetNames.length === 0) {
|
|
245864
|
+
return false;
|
|
245865
|
+
}
|
|
245866
|
+
const targetText = targetNames.map((targetName) => `${targetName} ${targetExecutorText(targets[targetName])}`).join(" ");
|
|
245867
|
+
const hasOnlySupportTargets = targetNames.every(
|
|
245868
|
+
(targetName) => /^(?:e2e|test|unit-test|integration-test|lint|typecheck|format|smoke|bench|benchmark)$/u.test(targetName)
|
|
245869
|
+
);
|
|
245870
|
+
const hasTestExecutor = /(?:cypress|playwright|jest|vitest|mocha|karma|protractor)/u.test(targetText);
|
|
245871
|
+
return projectType !== "library" && (hasOnlySupportTargets || hasTestExecutor);
|
|
245872
|
+
}
|
|
245873
|
+
function classifyNxRuntimeKind(projectJson) {
|
|
245874
|
+
if (!hasNxRuntimeProjectEvidence(projectJson)) {
|
|
245875
|
+
return void 0;
|
|
245876
|
+
}
|
|
245877
|
+
const targets = readTargetMap(projectJson);
|
|
245878
|
+
const targetText = Object.entries(targets).map(([targetName, target]) => `${targetName} ${targetExecutorText(target)}`).join(" ");
|
|
245879
|
+
if (/(?:webpack:dev-server|webpack-dev-server|src\/index\.(?:tsx|jsx|ts|js)|public\/index\.html|browser|react|vite|next|angular|deploy:static)/u.test(targetText)) {
|
|
245880
|
+
return "frontend";
|
|
245881
|
+
}
|
|
245882
|
+
if (/(?:@nx\/js:node|@nrwl\/node|src\/main\.(?:ts|js)|target:\s*node|node\b|container|worker|queue)/u.test(targetText)) {
|
|
245883
|
+
return /\bworker\b/u.test(targetText) ? "worker" : "backend";
|
|
245884
|
+
}
|
|
245885
|
+
return void 0;
|
|
245886
|
+
}
|
|
245887
|
+
function collectNxProjectCandidates(workspaceRoot) {
|
|
245888
|
+
if (!pathExists19(path64.join(workspaceRoot, "nx.json"))) {
|
|
245889
|
+
return [];
|
|
245890
|
+
}
|
|
245891
|
+
const candidates = /* @__PURE__ */ new Map();
|
|
245892
|
+
const workspaceLayout = readNxWorkspaceLayout(workspaceRoot);
|
|
245893
|
+
const preferredRoots = new Set(
|
|
245894
|
+
["apps", "packages", "services", "libs", workspaceLayout.appsDir, workspaceLayout.libsDir].filter((entry) => typeof entry === "string" && entry.length > 0).map(normalizePath25)
|
|
245895
|
+
);
|
|
245896
|
+
const maxDepth = 5;
|
|
245897
|
+
const queue = [
|
|
245898
|
+
{ absolutePath: workspaceRoot, relativePath: "", depth: 0 }
|
|
245899
|
+
];
|
|
245900
|
+
const addCandidate = (candidatePath, evidence) => {
|
|
245901
|
+
const normalized = normalizePath25(candidatePath);
|
|
245902
|
+
const existing = candidates.get(normalized) ?? { path: normalized, evidence: [] };
|
|
245903
|
+
addEvidence6(existing.evidence, evidence);
|
|
245904
|
+
candidates.set(normalized, existing);
|
|
245905
|
+
};
|
|
245906
|
+
while (queue.length > 0) {
|
|
245907
|
+
const current = queue.shift();
|
|
245908
|
+
if (!current) {
|
|
245909
|
+
continue;
|
|
245910
|
+
}
|
|
245911
|
+
for (const entry of readDirectoryEntriesForTraversal(current.absolutePath)) {
|
|
245912
|
+
if (!entry.isDirectory()) {
|
|
245913
|
+
continue;
|
|
245914
|
+
}
|
|
245915
|
+
if ([".git", ".archpilot", "node_modules", "dist", "build", "out", "coverage"].includes(entry.name)) {
|
|
245916
|
+
continue;
|
|
245917
|
+
}
|
|
245918
|
+
const relativePath = normalizePath25(current.relativePath ? `${current.relativePath}/${entry.name}` : entry.name);
|
|
245919
|
+
if (current.depth >= maxDepth) {
|
|
245920
|
+
continue;
|
|
245921
|
+
}
|
|
245922
|
+
const projectJsonPath = path64.join(current.absolutePath, entry.name, "project.json");
|
|
245923
|
+
if (pathExists19(projectJsonPath)) {
|
|
245924
|
+
const projectJson = safeReadJson(projectJsonPath);
|
|
245925
|
+
const projectRoot = normalizePath25(readStringProperty(projectJson, "root") ?? relativePath);
|
|
245926
|
+
if (hasNxRuntimeProjectEvidence(projectJson)) {
|
|
245927
|
+
addCandidate(projectRoot, "Detected Nx runtime project metadata");
|
|
245928
|
+
} else if (readStringProperty(projectJson, "sourceRoot")) {
|
|
245929
|
+
addCandidate(projectRoot, "Detected Nx source-bearing project metadata");
|
|
245930
|
+
}
|
|
245931
|
+
}
|
|
245932
|
+
const firstSegment = relativePath.split("/")[0] ?? "";
|
|
245933
|
+
if (current.depth === 0 || preferredRoots.has(firstSegment) || preferredRoots.has(relativePath.split("/").slice(0, 2).join("/"))) {
|
|
245934
|
+
queue.push({
|
|
245935
|
+
absolutePath: path64.join(current.absolutePath, entry.name),
|
|
245936
|
+
relativePath,
|
|
245937
|
+
depth: current.depth + 1
|
|
245938
|
+
});
|
|
245939
|
+
}
|
|
245940
|
+
}
|
|
245941
|
+
}
|
|
245942
|
+
return [...candidates.values()].sort((left, right) => left.path.localeCompare(right.path));
|
|
245943
|
+
}
|
|
245689
245944
|
function readTextFileSafe(filePath) {
|
|
245690
245945
|
try {
|
|
245691
245946
|
return fs58.readFileSync(filePath, { encoding: "utf8" });
|
|
@@ -245732,6 +245987,8 @@ function readMavenMetadata(workspaceRoot, componentPath) {
|
|
|
245732
245987
|
testScopedDependencyCount: dependencyBlocks.filter((block) => /<scope>\s*test\s*<\/scope>/iu.test(block)).length,
|
|
245733
245988
|
totalDependencyCount: dependencyBlocks.length,
|
|
245734
245989
|
hasMavenPluginConfiguration: packaging === "maven-plugin" || /maven-plugin-plugin|<goalPrefix>|<mojo/iu.test(normalizedPom),
|
|
245990
|
+
hasAssemblyPackagingConfiguration: /maven-assembly-plugin|<goal>\s*single\s*<\/goal>|<descriptor>[^<]*(?:assembly|dist|distribution)[^<]*<\/descriptor>/iu.test(normalizedPom),
|
|
245991
|
+
hasDeploySkipConfiguration: /<maven\.deploy\.skip>\s*true\s*<\/maven\.deploy\.skip>|<artifactId>\s*maven-deploy-plugin\s*<\/artifactId>[\s\S]*?<skip>\s*true\s*<\/skip>/iu.test(normalizedPom),
|
|
245735
245992
|
hasTestLifecycleConfiguration: /maven-surefire-plugin|maven-failsafe-plugin|integration-test|failsafe|surefire/iu.test(normalizedPom),
|
|
245736
245993
|
hasArquillianEvidence: /arquillian/iu.test(normalizedPom),
|
|
245737
245994
|
hasMainJava: pathExists19(path64.join(absoluteRoot, "src", "main", "java")),
|
|
@@ -245864,6 +246121,12 @@ function buildRootCandidates(input2) {
|
|
|
245864
246121
|
addCandidate(root, `Detected project root ${root}`);
|
|
245865
246122
|
}
|
|
245866
246123
|
if (input2.workspaceRoot) {
|
|
246124
|
+
for (const candidate of collectNxProjectCandidates(input2.workspaceRoot)) {
|
|
246125
|
+
addCandidate(candidate.path, "Detected Nx project metadata");
|
|
246126
|
+
for (const evidence of candidate.evidence) {
|
|
246127
|
+
addCandidate(candidate.path, evidence);
|
|
246128
|
+
}
|
|
246129
|
+
}
|
|
245867
246130
|
const mavenRoots = [".", ...input2.topology.detectedRoots ?? []];
|
|
245868
246131
|
for (const candidate of collectMavenReactorCandidates(input2.workspaceRoot, mavenRoots)) {
|
|
245869
246132
|
addCandidate(
|
|
@@ -245947,10 +246210,7 @@ function isUnderJvmResourceRoot4(componentPath) {
|
|
|
245947
246210
|
return /(^|\/)src\/main\/resources(?:\/|$)/u.test(normalizePath25(componentPath).toLowerCase());
|
|
245948
246211
|
}
|
|
245949
246212
|
function hasFileUnderRoot(root, pattern) {
|
|
245950
|
-
|
|
245951
|
-
return false;
|
|
245952
|
-
}
|
|
245953
|
-
const entries = fs58.readdirSync(root, { recursive: true, withFileTypes: true });
|
|
246213
|
+
const entries = readDirectoryEntriesForTraversal(root, { recursive: true });
|
|
245954
246214
|
return entries.some((entry) => entry.isFile() && pattern.test(entry.name));
|
|
245955
246215
|
}
|
|
245956
246216
|
var javaMainMethodPattern = /\bpublic\s+static\s+void\s+main\s*\(\s*String\s*(?:(?:\[\s*\]\s*)|\.\.\.\s*)[A-Za-z_$][\w$]*\s*(?:\[\s*\])?\s*\)/u;
|
|
@@ -246068,10 +246328,7 @@ function readMavenProductionSourceFiles(workspaceRoot, componentPath) {
|
|
|
246068
246328
|
];
|
|
246069
246329
|
const files = [];
|
|
246070
246330
|
for (const sourceRoot of mainRoots) {
|
|
246071
|
-
|
|
246072
|
-
continue;
|
|
246073
|
-
}
|
|
246074
|
-
const entries = fs58.readdirSync(sourceRoot, { recursive: true, withFileTypes: true });
|
|
246331
|
+
const entries = readDirectoryEntriesForTraversal(sourceRoot, { recursive: true });
|
|
246075
246332
|
for (const entry of entries) {
|
|
246076
246333
|
if (!entry.isFile() || !/\.(?:java|kt|scala)$/iu.test(entry.name)) {
|
|
246077
246334
|
continue;
|
|
@@ -246243,10 +246500,7 @@ function hasRuntimeSourceFiles(workspaceRoot, componentPath) {
|
|
|
246243
246500
|
path64.join(absoluteRoot, "server")
|
|
246244
246501
|
];
|
|
246245
246502
|
for (const sourceRoot of sourceRoots) {
|
|
246246
|
-
|
|
246247
|
-
continue;
|
|
246248
|
-
}
|
|
246249
|
-
const entries = fs58.readdirSync(sourceRoot, { recursive: true, withFileTypes: true });
|
|
246503
|
+
const entries = readDirectoryEntriesForTraversal(sourceRoot, { recursive: true });
|
|
246250
246504
|
if (entries.some((entry) => entry.isFile() && /\.(?:ts|tsx|js|jsx|java|cs|py|php|go)$/iu.test(entry.name))) {
|
|
246251
246505
|
return true;
|
|
246252
246506
|
}
|
|
@@ -246254,10 +246508,7 @@ function hasRuntimeSourceFiles(workspaceRoot, componentPath) {
|
|
|
246254
246508
|
return false;
|
|
246255
246509
|
}
|
|
246256
246510
|
function hasFileMatchingUnderRoot(root, pattern) {
|
|
246257
|
-
|
|
246258
|
-
return false;
|
|
246259
|
-
}
|
|
246260
|
-
const entries = fs58.readdirSync(root, { recursive: true, withFileTypes: true });
|
|
246511
|
+
const entries = readDirectoryEntriesForTraversal(root, { recursive: true });
|
|
246261
246512
|
return entries.some((entry) => entry.isFile() && pattern.test(normalizePath25(path64.join(entry.parentPath, entry.name))));
|
|
246262
246513
|
}
|
|
246263
246514
|
function hasNestRuntimeApplicationEvidence(workspaceRoot, componentPath, packageJson = readPackageJson(workspaceRoot, componentPath)) {
|
|
@@ -246300,13 +246551,16 @@ function hasNestRuntimeApplicationEvidence(workspaceRoot, componentPath, package
|
|
|
246300
246551
|
function resolveKind(workspaceRoot, candidate, localProjectKinds) {
|
|
246301
246552
|
const lowerPath = candidate.path.toLowerCase();
|
|
246302
246553
|
const packageJson = readPackageJson(workspaceRoot, candidate.path);
|
|
246554
|
+
const projectJson = readProjectJson(workspaceRoot, candidate.path);
|
|
246555
|
+
const nxProjectType = readStringProperty(projectJson, "projectType");
|
|
246303
246556
|
const maven = readMavenMetadata(workspaceRoot, candidate.path);
|
|
246304
246557
|
const dependencies = new Set(packageDependencyNames(packageJson));
|
|
246305
246558
|
const hasRunnableFrontendEvidence = hasRunnableFrontendComponentEvidence(workspaceRoot, candidate.path);
|
|
246306
246559
|
const hasNestRuntimeEvidence = hasNestRuntimeApplicationEvidence(workspaceRoot, candidate.path, packageJson);
|
|
246560
|
+
const nxRuntimeKind = classifyNxRuntimeKind(projectJson);
|
|
246307
246561
|
const hasPublishSurface = hasPackagePublishSurface(packageJson);
|
|
246308
246562
|
const hasMavenRunnableEvidence = Boolean(
|
|
246309
|
-
maven && (hasMavenMainEntrypoint(workspaceRoot, candidate.path) || hasMavenConfiguredMainClassEntrypoint(workspaceRoot, candidate.path, maven.configuredMainClass) || maven.hasSpringBootPlugin && maven.hasSpringBootRepackageGoal && hasMavenMainEntrypoint(workspaceRoot, candidate.path) || maven.packaging === "war" && hasMavenMainEntrypoint(workspaceRoot, candidate.path))
|
|
246563
|
+
maven && (hasMavenMainEntrypoint(workspaceRoot, candidate.path) || hasMavenConfiguredMainClassEntrypoint(workspaceRoot, candidate.path, maven.configuredMainClass) || maven.configuredMainClass && maven.hasSpringBootStarterDependency || maven.hasSpringBootPlugin && maven.hasSpringBootRepackageGoal && hasMavenMainEntrypoint(workspaceRoot, candidate.path) || maven.packaging === "war" && hasMavenMainEntrypoint(workspaceRoot, candidate.path))
|
|
246310
246564
|
);
|
|
246311
246565
|
const hasMavenLibraryEvidence = Boolean(
|
|
246312
246566
|
maven && !hasMavenRunnableEvidence && (maven.packaging === "jar" || maven.packaging === "maven-plugin" || maven.packaging === "pom") && (hasMavenMainJvmSource(workspaceRoot, candidate.path) || maven.hasMainResources || maven.hasDependencyManagement || maven.hasSpringBootAutoconfigureDependency || maven.hasSpringBootAutoconfigureProcessor || hasMavenAutoConfigurationMetadata(workspaceRoot, candidate.path) || maven.hasDocumentationTooling || maven.hasTestJava || maven.hasTestResources)
|
|
@@ -246314,6 +246568,12 @@ function resolveKind(workspaceRoot, candidate, localProjectKinds) {
|
|
|
246314
246568
|
if (lowerPath.endsWith("/db") || lowerPath.endsWith("/database") || lowerPath.endsWith("/data")) {
|
|
246315
246569
|
return "data";
|
|
246316
246570
|
}
|
|
246571
|
+
if (nxRuntimeKind) {
|
|
246572
|
+
return nxRuntimeKind;
|
|
246573
|
+
}
|
|
246574
|
+
if (nxProjectType === "library") {
|
|
246575
|
+
return "library";
|
|
246576
|
+
}
|
|
246317
246577
|
if (hasMavenLibraryEvidence) {
|
|
246318
246578
|
return "library";
|
|
246319
246579
|
}
|
|
@@ -246413,7 +246673,10 @@ function classifyGovernanceRole(input2) {
|
|
|
246413
246673
|
const scriptText = scripts.join(" ").toLowerCase();
|
|
246414
246674
|
const projectMetadataText = `${projectTags.join(" ")} ${projectTargets.join(" ")}`.toLowerCase();
|
|
246415
246675
|
const dependencyText = [...dependencies, ...devDependencies].join(" ").toLowerCase();
|
|
246676
|
+
const hasRunnableFrontendEvidence = hasRunnableFrontendComponentEvidence(input2.workspaceRoot, input2.candidate.path);
|
|
246416
246677
|
const hasNestRuntimeEvidence = hasNestRuntimeApplicationEvidence(input2.workspaceRoot, input2.candidate.path, packageJson);
|
|
246678
|
+
const nxRuntimeKind = classifyNxRuntimeKind(projectJson);
|
|
246679
|
+
const hasNxSupportOnlyEvidence = hasNxSupportOnlyProjectEvidence(projectJson);
|
|
246417
246680
|
const hasStrongSupportPath = hasAnyToken(pathText, [
|
|
246418
246681
|
/(^|\/)(testing|e2e-testing|test-plugins|cypress-tests|fixtures?|benchmarks?|smoke)(\/|$)/u,
|
|
246419
246682
|
/(^|\/)(dev-server|scaffold|scaffolding|generators?|devkit|tooling|tools|templates?)(\/|$)/u
|
|
@@ -246428,9 +246691,11 @@ function classifyGovernanceRole(input2) {
|
|
|
246428
246691
|
const hasMavenMainEntrypointEvidence = Boolean(maven && hasMavenMainEntrypoint(input2.workspaceRoot, input2.candidate.path));
|
|
246429
246692
|
const hasMavenMainJvmSourceEvidence = Boolean(maven && hasMavenMainJvmSource(input2.workspaceRoot, input2.candidate.path));
|
|
246430
246693
|
const hasMavenAutoConfigurationEvidence = Boolean(maven && (hasMavenAutoConfigurationMetadata(input2.workspaceRoot, input2.candidate.path) || maven.hasSpringBootAutoconfigureDependency || maven.hasSpringBootAutoconfigureProcessor));
|
|
246431
|
-
const hasMavenExecutableConfiguration = Boolean(maven && (hasMavenConfiguredMainClassEntrypoint(input2.workspaceRoot, input2.candidate.path, maven.configuredMainClass) || maven.hasSpringBootPlugin && maven.hasSpringBootRepackageGoal && hasMavenMainEntrypointEvidence || maven.packaging === "war" && hasMavenMainEntrypointEvidence));
|
|
246694
|
+
const hasMavenExecutableConfiguration = Boolean(maven && (hasMavenConfiguredMainClassEntrypoint(input2.workspaceRoot, input2.candidate.path, maven.configuredMainClass) || maven.configuredMainClass && maven.hasSpringBootStarterDependency || maven.hasSpringBootPlugin && maven.hasSpringBootRepackageGoal && hasMavenMainEntrypointEvidence || maven.packaging === "war" && hasMavenMainEntrypointEvidence));
|
|
246432
246695
|
const hasMavenRunnableApplicationEvidence = Boolean(hasMavenMainEntrypointEvidence || hasMavenExecutableConfiguration);
|
|
246433
|
-
const isMavenPomOnly = Boolean(
|
|
246696
|
+
const isMavenPomOnly = Boolean(
|
|
246697
|
+
maven?.packaging === "pom" && !hasMavenRunnableApplicationEvidence && !hasMavenMainSource && !hasMavenTestSource
|
|
246698
|
+
);
|
|
246434
246699
|
const hasMavenTestContext = hasAnyToken(pathText, [
|
|
246435
246700
|
/(^|\/)(test-framework|testsuite|integration-tests?|test-apps)(\/|$)/u
|
|
246436
246701
|
]) && (hasAnyToken(mavenMetadataText, [/\b(test|testsuite|test framework|arquillian|integration test)\b/u]) || Boolean(maven?.hasTestLifecycleConfiguration || maven?.hasArquillianEvidence || hasMavenTestSource));
|
|
@@ -246438,7 +246703,7 @@ function classifyGovernanceRole(input2) {
|
|
|
246438
246703
|
maven?.packaging === "pom" && maven.hasDependencyManagement && !hasMavenMainSource && hasAnyToken(mavenMetadataText, [/\b(bom|bill of materials|dependency management|platform)\b/u])
|
|
246439
246704
|
);
|
|
246440
246705
|
const hasMavenDistributionPackagingEvidence = Boolean(
|
|
246441
|
-
maven
|
|
246706
|
+
maven && !hasMavenMainSource && (maven.hasAssemblyPackagingConfiguration || maven.hasDeploySkipConfiguration && maven.hasDocumentationTooling || hasAnyToken(mavenMetadataText, [/\b(distribution|assembly|release package|packaging bundle)\b/u]))
|
|
246442
246707
|
);
|
|
246443
246708
|
const hasMavenStarterPackagingEvidence = Boolean(
|
|
246444
246709
|
maven && !hasMavenMainJvmSourceEvidence && hasAnyToken(`${pathText} ${mavenMetadataText}`, [/\bstarters?\b|\bspring-boot-starter\b|\bstarter[-\s]/u])
|
|
@@ -246465,6 +246730,18 @@ function classifyGovernanceRole(input2) {
|
|
|
246465
246730
|
runtimeScore += 3;
|
|
246466
246731
|
addEvidence6(evidence, "NestJS runtime application evidence");
|
|
246467
246732
|
}
|
|
246733
|
+
if (input2.kind === "frontend" && hasRunnableFrontendEvidence) {
|
|
246734
|
+
runtimeScore += 3;
|
|
246735
|
+
addEvidence6(evidence, "Runnable frontend application evidence");
|
|
246736
|
+
}
|
|
246737
|
+
if (nxRuntimeKind) {
|
|
246738
|
+
runtimeScore += 3;
|
|
246739
|
+
addEvidence6(evidence, `Nx runtime project evidence: ${nxRuntimeKind}`);
|
|
246740
|
+
}
|
|
246741
|
+
if (hasNxSupportOnlyEvidence) {
|
|
246742
|
+
supportScore += 4;
|
|
246743
|
+
addEvidence6(evidence, "Nx project metadata indicates test/tooling-only workspace");
|
|
246744
|
+
}
|
|
246468
246745
|
if (hasPublishSurface && !isPrivate) {
|
|
246469
246746
|
runtimeScore += 1;
|
|
246470
246747
|
addEvidence6(evidence, "Published package surface signal");
|
|
@@ -246475,7 +246752,7 @@ function classifyGovernanceRole(input2) {
|
|
|
246475
246752
|
if (maven?.hasPom) {
|
|
246476
246753
|
addEvidence6(evidence, `Maven packaging ${maven.packaging ?? "jar"}`);
|
|
246477
246754
|
}
|
|
246478
|
-
if (maven &&
|
|
246755
|
+
if (maven && hasMavenRunnableApplicationEvidence) {
|
|
246479
246756
|
runtimeScore += 3;
|
|
246480
246757
|
addEvidence6(evidence, "Maven executable application evidence");
|
|
246481
246758
|
}
|
|
@@ -246512,6 +246789,10 @@ function classifyGovernanceRole(input2) {
|
|
|
246512
246789
|
supportScore += 1;
|
|
246513
246790
|
addEvidence6(evidence, "Path contains support/tooling role tokens");
|
|
246514
246791
|
}
|
|
246792
|
+
if (maven && hasStrongSupportPath && !hasMavenRunnableApplicationEvidence) {
|
|
246793
|
+
supportScore += 3;
|
|
246794
|
+
addEvidence6(evidence, "Maven module path and metadata indicate support/tooling role");
|
|
246795
|
+
}
|
|
246515
246796
|
if (hasAnyToken(pathText, [/(^|\/)(?:src\/constants\/)?templates?(\/|$)/u])) {
|
|
246516
246797
|
supportScore += 4;
|
|
246517
246798
|
addEvidence6(evidence, "Nested scaffold/template source surface");
|
|
@@ -246544,6 +246825,10 @@ function classifyGovernanceRole(input2) {
|
|
|
246544
246825
|
supportScore += 4;
|
|
246545
246826
|
addEvidence6(evidence, "Maven documentation tooling without JVM runtime source");
|
|
246546
246827
|
}
|
|
246828
|
+
if (maven?.hasDeploySkipConfiguration && !hasMavenMainJvmSourceEvidence && !hasMavenRunnableApplicationEvidence) {
|
|
246829
|
+
supportScore += 4;
|
|
246830
|
+
addEvidence6(evidence, "Maven deploy-skipped artifact without runtime source");
|
|
246831
|
+
}
|
|
246547
246832
|
if (hasMavenBomEvidence) {
|
|
246548
246833
|
supportScore += 5;
|
|
246549
246834
|
addEvidence6(evidence, "Maven BOM/dependency-management module without runtime source");
|
|
@@ -246572,6 +246857,10 @@ function classifyGovernanceRole(input2) {
|
|
|
246572
246857
|
supportScore += 4;
|
|
246573
246858
|
addEvidence6(evidence, "Maven starter/resource artifact without JVM runtime source");
|
|
246574
246859
|
}
|
|
246860
|
+
if (hasMavenDistributionPackagingEvidence) {
|
|
246861
|
+
supportScore += 4;
|
|
246862
|
+
addEvidence6(evidence, "Maven distribution/release packaging without runtime source");
|
|
246863
|
+
}
|
|
246575
246864
|
if (isPlainResourcesSurface) {
|
|
246576
246865
|
supportScore += 4;
|
|
246577
246866
|
addEvidence6(evidence, "Resources-only surface without runtime source or manifest evidence");
|
|
@@ -246594,7 +246883,7 @@ function classifyGovernanceRole(input2) {
|
|
|
246594
246883
|
supportScore += 3;
|
|
246595
246884
|
addEvidence6(evidence, "Maven documentation/build/distribution packaging evidence without runtime source");
|
|
246596
246885
|
}
|
|
246597
|
-
if (supportScore >= 3 && supportScore > runtimeScore || hasStrongSupportPath && supportScore >= 2 && runtimeScore <= 5 || maven?.packaging === "maven-plugin" && input2.candidate.path !== "." && supportScore >= 5 || maven && supportScore >= 5 && !
|
|
246886
|
+
if (supportScore >= 3 && supportScore > runtimeScore || hasStrongSupportPath && supportScore >= 2 && runtimeScore <= 5 || maven?.packaging === "maven-plugin" && input2.candidate.path !== "." && supportScore >= 5 || maven && supportScore >= 5 && !hasMavenMainJvmSourceEvidence && !hasMavenRunnableApplicationEvidence || maven && supportScore >= 4 && maven.hasDeploySkipConfiguration && !hasMavenMainJvmSourceEvidence && !hasMavenRunnableApplicationEvidence || maven && supportScore >= 4 && hasStrongSupportPath && !hasMavenMainJvmSourceEvidence && !hasMavenRunnableApplicationEvidence || maven && supportScore >= 4 && hasMavenTestContext || maven && supportScore >= 4 && hasMavenDistributionPackagingEvidence && hasAnyToken(mavenMetadataText, [/\b(docs?|documentation|metadata tests?|licenses?|maven plugins?|builds?)\b/u])) {
|
|
246598
246887
|
return {
|
|
246599
246888
|
governanceRole: "support",
|
|
246600
246889
|
governanceEvidence: uniqueSorted4(evidence),
|
|
@@ -250255,8 +250544,8 @@ function readFlagValue(args, flag) {
|
|
|
250255
250544
|
return value && value.length > 0 ? value : void 0;
|
|
250256
250545
|
}
|
|
250257
250546
|
async function readCliPackageVersion() {
|
|
250258
|
-
if ("0.2.
|
|
250259
|
-
return "0.2.
|
|
250547
|
+
if ("0.2.6".trim().length > 0) {
|
|
250548
|
+
return "0.2.6".trim();
|
|
250260
250549
|
}
|
|
250261
250550
|
const candidatePackageJsonPaths = [
|
|
250262
250551
|
path73.join(__dirname, "..", "package.json"),
|
package/package.json
CHANGED