@living-architecture/riviere-cli 0.8.10 → 0.8.12
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/bin.js +412 -266
- package/dist/index.js +411 -265
- package/package.json +6 -6
package/dist/index.js
CHANGED
|
@@ -2979,7 +2979,7 @@ var require_compile = __commonJS({
|
|
|
2979
2979
|
const schOrFunc = root.refs[ref];
|
|
2980
2980
|
if (schOrFunc)
|
|
2981
2981
|
return schOrFunc;
|
|
2982
|
-
let _sch =
|
|
2982
|
+
let _sch = resolve8.call(this, root, ref);
|
|
2983
2983
|
if (_sch === void 0) {
|
|
2984
2984
|
const schema = (_a2 = root.localRefs) === null || _a2 === void 0 ? void 0 : _a2[ref];
|
|
2985
2985
|
const { schemaId } = this.opts;
|
|
@@ -3006,7 +3006,7 @@ var require_compile = __commonJS({
|
|
|
3006
3006
|
function sameSchemaEnv(s1, s2) {
|
|
3007
3007
|
return s1.schema === s2.schema && s1.root === s2.root && s1.baseId === s2.baseId;
|
|
3008
3008
|
}
|
|
3009
|
-
function
|
|
3009
|
+
function resolve8(root, ref) {
|
|
3010
3010
|
let sch;
|
|
3011
3011
|
while (typeof (sch = this.refs[ref]) == "string")
|
|
3012
3012
|
ref = sch;
|
|
@@ -3581,7 +3581,7 @@ var require_fast_uri = __commonJS({
|
|
|
3581
3581
|
}
|
|
3582
3582
|
return uri;
|
|
3583
3583
|
}
|
|
3584
|
-
function
|
|
3584
|
+
function resolve8(baseURI, relativeURI, options) {
|
|
3585
3585
|
const schemelessOptions = options ? Object.assign({ scheme: "null" }, options) : { scheme: "null" };
|
|
3586
3586
|
const resolved = resolveComponent(parse3(baseURI, schemelessOptions), parse3(relativeURI, schemelessOptions), schemelessOptions, true);
|
|
3587
3587
|
schemelessOptions.skipEscape = true;
|
|
@@ -3808,7 +3808,7 @@ var require_fast_uri = __commonJS({
|
|
|
3808
3808
|
var fastUri = {
|
|
3809
3809
|
SCHEMES,
|
|
3810
3810
|
normalize,
|
|
3811
|
-
resolve:
|
|
3811
|
+
resolve: resolve8,
|
|
3812
3812
|
resolveComponent,
|
|
3813
3813
|
equal,
|
|
3814
3814
|
serialize,
|
|
@@ -25204,7 +25204,8 @@ import { Command as Command21 } from "commander";
|
|
|
25204
25204
|
// src/platform/infra/extraction-config/config-loader.ts
|
|
25205
25205
|
import {
|
|
25206
25206
|
dirname as dirname2,
|
|
25207
|
-
resolve as resolve2
|
|
25207
|
+
resolve as resolve2,
|
|
25208
|
+
posix as posix3
|
|
25208
25209
|
} from "node:path";
|
|
25209
25210
|
import {
|
|
25210
25211
|
existsSync as existsSync2,
|
|
@@ -25265,7 +25266,7 @@ var extraction_config_schema_default = {
|
|
|
25265
25266
|
module: {
|
|
25266
25267
|
type: "object",
|
|
25267
25268
|
description: "A module defines extraction rules for a path pattern",
|
|
25268
|
-
required: ["name", "path"],
|
|
25269
|
+
required: ["name", "path", "glob"],
|
|
25269
25270
|
additionalProperties: false,
|
|
25270
25271
|
properties: {
|
|
25271
25272
|
name: {
|
|
@@ -25275,7 +25276,12 @@ var extraction_config_schema_default = {
|
|
|
25275
25276
|
},
|
|
25276
25277
|
path: {
|
|
25277
25278
|
type: "string",
|
|
25278
|
-
description: "
|
|
25279
|
+
description: "Module root directory relative to config file",
|
|
25280
|
+
minLength: 1
|
|
25281
|
+
},
|
|
25282
|
+
glob: {
|
|
25283
|
+
type: "string",
|
|
25284
|
+
description: "Glob pattern for source files within the module directory",
|
|
25279
25285
|
minLength: 1
|
|
25280
25286
|
},
|
|
25281
25287
|
extends: {
|
|
@@ -26342,11 +26348,11 @@ function createFunctionComponent(func, filePath, domain2, componentType) {
|
|
|
26342
26348
|
function findMatchingModule(filePath, modules, globMatcher, configDir) {
|
|
26343
26349
|
const normalized = filePath.replaceAll(/\\+/g, "/");
|
|
26344
26350
|
if (configDir === void 0) {
|
|
26345
|
-
return modules.find((m) => globMatcher(normalized, m.path));
|
|
26351
|
+
return modules.find((m) => globMatcher(normalized, posix.join(m.path, m.glob)));
|
|
26346
26352
|
}
|
|
26347
26353
|
const normalizedConfigDir = configDir.replaceAll(/\\+/g, "/");
|
|
26348
26354
|
const pathToMatch = posix.relative(normalizedConfigDir, normalized);
|
|
26349
|
-
return modules.find((m) => globMatcher(pathToMatch, m.path));
|
|
26355
|
+
return modules.find((m) => globMatcher(pathToMatch, posix.join(m.path, m.glob)));
|
|
26350
26356
|
}
|
|
26351
26357
|
|
|
26352
26358
|
// ../riviere-extract-ts/dist/features/extraction/domain/config-resolution/config-resolution-errors.js
|
|
@@ -26384,6 +26390,7 @@ function resolveModule(moduleConfig, loader) {
|
|
|
26384
26390
|
return {
|
|
26385
26391
|
name: moduleConfig.name,
|
|
26386
26392
|
path: moduleConfig.path,
|
|
26393
|
+
glob: moduleConfig.glob,
|
|
26387
26394
|
api: requireRule(moduleConfig.api, "api", moduleConfig.name),
|
|
26388
26395
|
useCase: requireRule(moduleConfig.useCase, "useCase", moduleConfig.name),
|
|
26389
26396
|
domainOp: requireRule(moduleConfig.domainOp, "domainOp", moduleConfig.name),
|
|
@@ -26403,6 +26410,7 @@ function resolveModuleWithExtends(moduleConfig, extendsSource, loader) {
|
|
|
26403
26410
|
return {
|
|
26404
26411
|
name: moduleConfig.name,
|
|
26405
26412
|
path: moduleConfig.path,
|
|
26413
|
+
glob: moduleConfig.glob,
|
|
26406
26414
|
api: moduleConfig.api ?? baseModule.api,
|
|
26407
26415
|
useCase: moduleConfig.useCase ?? baseModule.useCase,
|
|
26408
26416
|
domainOp: moduleConfig.domainOp ?? baseModule.domainOp,
|
|
@@ -28869,50 +28877,48 @@ function traceNonComponent(project, componentIndex, source, typeName, calledMeth
|
|
|
28869
28877
|
}
|
|
28870
28878
|
|
|
28871
28879
|
// ../riviere-extract-ts/dist/features/extraction/domain/connection-detection/async-detection/detect-publish-connections.js
|
|
28872
|
-
function detectPublishConnections(
|
|
28880
|
+
function detectPublishConnections(components, options) {
|
|
28873
28881
|
const publishers = components.filter((c) => c.type === "eventPublisher");
|
|
28874
28882
|
const events = components.filter((c) => c.type === "event");
|
|
28875
28883
|
const repository = options.repository;
|
|
28876
|
-
return publishers.flatMap((publisher) =>
|
|
28877
|
-
|
|
28878
|
-
function extractPublisherLinks(project, publisher, events, options, repository) {
|
|
28879
|
-
const publishedEventType = publisher.metadata["publishedEventType"];
|
|
28880
|
-
if (typeof publishedEventType === "string") {
|
|
28884
|
+
return publishers.flatMap((publisher) => {
|
|
28885
|
+
const publishedEventType = publisher.metadata["publishedEventType"];
|
|
28881
28886
|
const sourceLocation = {
|
|
28882
28887
|
repository,
|
|
28883
28888
|
filePath: publisher.location.file,
|
|
28884
28889
|
lineNumber: publisher.location.line
|
|
28885
28890
|
};
|
|
28886
|
-
|
|
28887
|
-
|
|
28888
|
-
const classDecl = findClassInProject(project, publisher);
|
|
28889
|
-
if (classDecl === void 0) {
|
|
28890
|
-
return [];
|
|
28891
|
-
}
|
|
28892
|
-
const methods = classDecl.getMethods();
|
|
28893
|
-
return methods.flatMap((method) => {
|
|
28894
|
-
const firstParam = method.getParameters()[0];
|
|
28895
|
-
if (firstParam === void 0) {
|
|
28896
|
-
return [];
|
|
28891
|
+
if (typeof publishedEventType !== "string") {
|
|
28892
|
+
return [handleMissingMetadata(publisher, options, sourceLocation)];
|
|
28897
28893
|
}
|
|
28898
|
-
|
|
28899
|
-
const paramTypeName = stripGenericArgs(paramType.getText(firstParam));
|
|
28900
|
-
const sourceLocation = {
|
|
28901
|
-
repository,
|
|
28902
|
-
filePath: publisher.location.file,
|
|
28903
|
-
lineNumber: method.getStartLineNumber()
|
|
28904
|
-
};
|
|
28905
|
-
return resolvePublishTarget(publisher, paramTypeName, events, options, sourceLocation);
|
|
28894
|
+
return resolvePublishTarget(publisher, publishedEventType, events, options, sourceLocation);
|
|
28906
28895
|
});
|
|
28907
28896
|
}
|
|
28908
|
-
function
|
|
28909
|
-
|
|
28897
|
+
function handleMissingMetadata(publisher, options, sourceLocation) {
|
|
28898
|
+
if (options.strict) {
|
|
28899
|
+
throw new ConnectionDetectionError({
|
|
28900
|
+
file: sourceLocation.filePath,
|
|
28901
|
+
line: sourceLocation.lineNumber,
|
|
28902
|
+
typeName: publisher.name,
|
|
28903
|
+
reason: 'eventPublisher is missing required "publishedEventType" metadata'
|
|
28904
|
+
});
|
|
28905
|
+
}
|
|
28906
|
+
return {
|
|
28907
|
+
source: componentIdentity(publisher),
|
|
28908
|
+
target: "_unresolved",
|
|
28909
|
+
type: "async",
|
|
28910
|
+
sourceLocation,
|
|
28911
|
+
_uncertain: `eventPublisher "${publisher.name}" is missing required "publishedEventType" metadata`
|
|
28912
|
+
};
|
|
28913
|
+
}
|
|
28914
|
+
function resolvePublishTarget(publisher, publishedEventType, events, options, sourceLocation) {
|
|
28915
|
+
const matchingEvents = events.filter((e) => e.metadata["eventName"] === publishedEventType);
|
|
28910
28916
|
if (matchingEvents.length === 0) {
|
|
28911
|
-
return [handleNoMatch(publisher,
|
|
28917
|
+
return [handleNoMatch(publisher, publishedEventType, options, sourceLocation)];
|
|
28912
28918
|
}
|
|
28913
28919
|
if (matchingEvents.length > 1) {
|
|
28914
28920
|
return [
|
|
28915
|
-
handleAmbiguousMatch(publisher,
|
|
28921
|
+
handleAmbiguousMatch(publisher, publishedEventType, matchingEvents.length, options, sourceLocation)
|
|
28916
28922
|
];
|
|
28917
28923
|
}
|
|
28918
28924
|
return matchingEvents.map((event) => ({
|
|
@@ -28922,13 +28928,13 @@ function resolvePublishTarget(publisher, paramTypeName, events, options, sourceL
|
|
|
28922
28928
|
sourceLocation
|
|
28923
28929
|
}));
|
|
28924
28930
|
}
|
|
28925
|
-
function handleAmbiguousMatch(publisher,
|
|
28931
|
+
function handleAmbiguousMatch(publisher, publishedEventType, matchCount, options, sourceLocation) {
|
|
28926
28932
|
if (options.strict) {
|
|
28927
28933
|
throw new ConnectionDetectionError({
|
|
28928
28934
|
file: sourceLocation.filePath,
|
|
28929
28935
|
line: sourceLocation.lineNumber,
|
|
28930
28936
|
typeName: publisher.name,
|
|
28931
|
-
reason: `
|
|
28937
|
+
reason: `publishedEventType "${publishedEventType}" matches ${matchCount} Event components (ambiguous)`
|
|
28932
28938
|
});
|
|
28933
28939
|
}
|
|
28934
28940
|
return {
|
|
@@ -28936,16 +28942,16 @@ function handleAmbiguousMatch(publisher, paramTypeName, matchCount, options, sou
|
|
|
28936
28942
|
target: "_unresolved",
|
|
28937
28943
|
type: "async",
|
|
28938
28944
|
sourceLocation,
|
|
28939
|
-
_uncertain: `ambiguous: ${matchCount} events match
|
|
28945
|
+
_uncertain: `ambiguous: ${matchCount} events match publishedEventType: ${publishedEventType}`
|
|
28940
28946
|
};
|
|
28941
28947
|
}
|
|
28942
|
-
function handleNoMatch(publisher,
|
|
28948
|
+
function handleNoMatch(publisher, publishedEventType, options, sourceLocation) {
|
|
28943
28949
|
if (options.strict) {
|
|
28944
28950
|
throw new ConnectionDetectionError({
|
|
28945
28951
|
file: sourceLocation.filePath,
|
|
28946
28952
|
line: sourceLocation.lineNumber,
|
|
28947
28953
|
typeName: publisher.name,
|
|
28948
|
-
reason: `
|
|
28954
|
+
reason: `publishedEventType "${publishedEventType}" does not match any Event component`
|
|
28949
28955
|
});
|
|
28950
28956
|
}
|
|
28951
28957
|
return {
|
|
@@ -28953,7 +28959,7 @@ function handleNoMatch(publisher, paramTypeName, options, sourceLocation) {
|
|
|
28953
28959
|
target: "_unresolved",
|
|
28954
28960
|
type: "async",
|
|
28955
28961
|
sourceLocation,
|
|
28956
|
-
_uncertain: `no event found for
|
|
28962
|
+
_uncertain: `no event found for publishedEventType: ${publishedEventType}`
|
|
28957
28963
|
};
|
|
28958
28964
|
}
|
|
28959
28965
|
|
|
@@ -29262,8 +29268,7 @@ function deduplicateCrossStrategy(links) {
|
|
|
29262
29268
|
}
|
|
29263
29269
|
return [...seen.values()];
|
|
29264
29270
|
}
|
|
29265
|
-
function
|
|
29266
|
-
const totalStart = performance.now();
|
|
29271
|
+
function detectPerModuleConnections(project, components, options, globMatcher) {
|
|
29267
29272
|
const setupStart = performance.now();
|
|
29268
29273
|
const componentIndex = new ComponentIndex(components);
|
|
29269
29274
|
const sourceFilePaths = computeFilteredFilePaths(project, options.moduleGlobs, globMatcher);
|
|
@@ -29277,43 +29282,50 @@ function detectConnections(project, components, options, globMatcher) {
|
|
|
29277
29282
|
repository
|
|
29278
29283
|
});
|
|
29279
29284
|
const callGraphMs = performance.now() - callGraphStart;
|
|
29285
|
+
const patterns = options.patterns ?? [];
|
|
29286
|
+
const { configurableLinks, configurableMs } = runConfigurableDetection(project, patterns, components, componentIndex, strict, repository);
|
|
29287
|
+
return {
|
|
29288
|
+
links: [...syncLinks, ...configurableLinks],
|
|
29289
|
+
timings: {
|
|
29290
|
+
callGraphMs,
|
|
29291
|
+
configurableMs,
|
|
29292
|
+
setupMs
|
|
29293
|
+
}
|
|
29294
|
+
};
|
|
29295
|
+
}
|
|
29296
|
+
function detectCrossModuleConnections(allComponents, options) {
|
|
29297
|
+
const strict = options.allowIncomplete !== true;
|
|
29298
|
+
const repository = options.repository;
|
|
29280
29299
|
const asyncStart = performance.now();
|
|
29281
|
-
const publishLinks = detectPublishConnections(
|
|
29300
|
+
const publishLinks = detectPublishConnections(allComponents, {
|
|
29282
29301
|
strict,
|
|
29283
29302
|
repository
|
|
29284
29303
|
});
|
|
29285
|
-
const subscribeLinks = detectSubscribeConnections(
|
|
29304
|
+
const subscribeLinks = detectSubscribeConnections(allComponents, {
|
|
29286
29305
|
strict,
|
|
29287
29306
|
repository
|
|
29288
29307
|
});
|
|
29289
29308
|
const asyncDetectionMs = performance.now() - asyncStart;
|
|
29290
|
-
|
|
29291
|
-
|
|
29292
|
-
|
|
29293
|
-
|
|
29294
|
-
|
|
29295
|
-
|
|
29296
|
-
|
|
29309
|
+
return {
|
|
29310
|
+
links: [...publishLinks, ...subscribeLinks],
|
|
29311
|
+
timings: { asyncDetectionMs }
|
|
29312
|
+
};
|
|
29313
|
+
}
|
|
29314
|
+
function runConfigurableDetection(project, patterns, components, componentIndex, strict, repository) {
|
|
29315
|
+
if (patterns.length === 0) {
|
|
29297
29316
|
return {
|
|
29298
|
-
configurableLinks:
|
|
29299
|
-
configurableMs:
|
|
29317
|
+
configurableLinks: [],
|
|
29318
|
+
configurableMs: 0
|
|
29300
29319
|
};
|
|
29301
|
-
}
|
|
29302
|
-
|
|
29303
|
-
|
|
29304
|
-
|
|
29305
|
-
|
|
29306
|
-
|
|
29307
|
-
const deduplicatedLinks = deduplicateCrossStrategy(allLinks);
|
|
29320
|
+
}
|
|
29321
|
+
const configurableStart = performance.now();
|
|
29322
|
+
const links = detectConfigurableConnections(project, patterns, components, componentIndex, {
|
|
29323
|
+
strict,
|
|
29324
|
+
repository
|
|
29325
|
+
});
|
|
29308
29326
|
return {
|
|
29309
|
-
|
|
29310
|
-
|
|
29311
|
-
callGraphMs,
|
|
29312
|
-
asyncDetectionMs,
|
|
29313
|
-
configurableMs,
|
|
29314
|
-
setupMs,
|
|
29315
|
-
totalMs
|
|
29316
|
-
}
|
|
29327
|
+
configurableLinks: links,
|
|
29328
|
+
configurableMs: performance.now() - configurableStart
|
|
29317
29329
|
};
|
|
29318
29330
|
}
|
|
29319
29331
|
|
|
@@ -29322,7 +29334,7 @@ import { posix as posix2 } from "node:path";
|
|
|
29322
29334
|
function findMatchingModule2(filePath, modules, globMatcher, configDir) {
|
|
29323
29335
|
const normalized = filePath.replaceAll(/\\+/g, "/");
|
|
29324
29336
|
const pathToMatch = posix2.relative(configDir.replaceAll(/\\+/g, "/"), normalized);
|
|
29325
|
-
return modules.find((m) => globMatcher(pathToMatch, m.path));
|
|
29337
|
+
return modules.find((m) => globMatcher(pathToMatch, posix2.join(m.path, m.glob)));
|
|
29326
29338
|
}
|
|
29327
29339
|
function getBuiltInRule(module, componentType) {
|
|
29328
29340
|
const ruleMap = {
|
|
@@ -29544,7 +29556,8 @@ var NOT_USED = { notUsed: true };
|
|
|
29544
29556
|
function topLevelRulesToModule(parsed) {
|
|
29545
29557
|
return {
|
|
29546
29558
|
name: "extended",
|
|
29547
|
-
path: "
|
|
29559
|
+
path: ".",
|
|
29560
|
+
glob: "**",
|
|
29548
29561
|
api: parsed.api ?? NOT_USED,
|
|
29549
29562
|
useCase: parsed.useCase ?? NOT_USED,
|
|
29550
29563
|
domainOp: parsed.domainOp ?? NOT_USED,
|
|
@@ -29664,9 +29677,9 @@ function tryExpandModuleRefs(data, configDir) {
|
|
|
29664
29677
|
}
|
|
29665
29678
|
}
|
|
29666
29679
|
function resolveSourceFiles(resolvedConfig, configDir) {
|
|
29667
|
-
const sourceFilePaths = resolvedConfig.modules.flatMap((module) => globSync(module.path, { cwd: configDir })).map((filePath) => resolve2(configDir, filePath));
|
|
29680
|
+
const sourceFilePaths = resolvedConfig.modules.flatMap((module) => globSync(posix3.join(module.path, module.glob), { cwd: configDir })).map((filePath) => resolve2(configDir, filePath));
|
|
29668
29681
|
if (sourceFilePaths.length === 0) {
|
|
29669
|
-
const patterns = resolvedConfig.modules.map((m) => m.path).join(", ");
|
|
29682
|
+
const patterns = resolvedConfig.modules.map((m) => posix3.join(m.path, m.glob)).join(", ");
|
|
29670
29683
|
throw new ConfigValidationError(
|
|
29671
29684
|
"VALIDATION_ERROR" /* ValidationError */,
|
|
29672
29685
|
`No files matched extraction patterns: ${patterns}
|
|
@@ -29921,111 +29934,6 @@ function validateFlagCombinations(options) {
|
|
|
29921
29934
|
validateFormatOption(options);
|
|
29922
29935
|
}
|
|
29923
29936
|
|
|
29924
|
-
// src/platform/infra/cli-presentation/format-pr-markdown.ts
|
|
29925
|
-
function formatComponentLine(component) {
|
|
29926
|
-
return `- **${component.type}** \`${component.name}\` in \`${component.domain}\` domain`;
|
|
29927
|
-
}
|
|
29928
|
-
function formatSection(title, components) {
|
|
29929
|
-
const header = `### ${title} (${components.length})`;
|
|
29930
|
-
if (components.length === 0) {
|
|
29931
|
-
return `${header}
|
|
29932
|
-
None`;
|
|
29933
|
-
}
|
|
29934
|
-
return `${header}
|
|
29935
|
-
${components.map(formatComponentLine).join("\n")}`;
|
|
29936
|
-
}
|
|
29937
|
-
function formatPrMarkdown(categorized) {
|
|
29938
|
-
const sections = [
|
|
29939
|
-
formatSection("Added Components", categorized.added),
|
|
29940
|
-
formatSection("Modified Components", categorized.modified),
|
|
29941
|
-
formatSection("Removed Components", categorized.removed)
|
|
29942
|
-
];
|
|
29943
|
-
return `## Architecture Changes
|
|
29944
|
-
|
|
29945
|
-
${sections.join("\n\n")}`;
|
|
29946
|
-
}
|
|
29947
|
-
|
|
29948
|
-
// src/platform/infra/cli-presentation/extract-output-formatter.ts
|
|
29949
|
-
function compareByCodePoint2(a, b) {
|
|
29950
|
-
if (a < b) return -1;
|
|
29951
|
-
if (a > b) return 1;
|
|
29952
|
-
return 0;
|
|
29953
|
-
}
|
|
29954
|
-
function formatDryRunOutput(components) {
|
|
29955
|
-
const countsByDomain = /* @__PURE__ */ new Map();
|
|
29956
|
-
for (const component of components) {
|
|
29957
|
-
const existingTypeCounts = countsByDomain.get(component.domain);
|
|
29958
|
-
const typeCounts = existingTypeCounts ?? /* @__PURE__ */ new Map();
|
|
29959
|
-
if (existingTypeCounts === void 0) {
|
|
29960
|
-
countsByDomain.set(component.domain, typeCounts);
|
|
29961
|
-
}
|
|
29962
|
-
const currentCount = typeCounts.get(component.type) ?? 0;
|
|
29963
|
-
typeCounts.set(component.type, currentCount + 1);
|
|
29964
|
-
}
|
|
29965
|
-
const sortedDomains = [...countsByDomain.entries()].sort(([a], [b]) => compareByCodePoint2(a, b));
|
|
29966
|
-
const lines = [];
|
|
29967
|
-
for (const [domain2, typeCounts] of sortedDomains) {
|
|
29968
|
-
const typeStrings = [...typeCounts.entries()].sort(([a], [b]) => compareByCodePoint2(a, b)).map(([type, count]) => `${type}(${count})`);
|
|
29969
|
-
lines.push(`${domain2}: ${typeStrings.join(", ")}`);
|
|
29970
|
-
}
|
|
29971
|
-
return lines;
|
|
29972
|
-
}
|
|
29973
|
-
|
|
29974
|
-
// src/platform/infra/cli-presentation/output-writer.ts
|
|
29975
|
-
import { writeFileSync } from "node:fs";
|
|
29976
|
-
function outputResult(data, options) {
|
|
29977
|
-
if (options.output !== void 0) {
|
|
29978
|
-
try {
|
|
29979
|
-
writeFileSync(options.output, JSON.stringify(data));
|
|
29980
|
-
} catch {
|
|
29981
|
-
console.log(
|
|
29982
|
-
JSON.stringify(
|
|
29983
|
-
formatError2(
|
|
29984
|
-
"VALIDATION_ERROR" /* ValidationError */,
|
|
29985
|
-
"Failed to write output file: " + options.output
|
|
29986
|
-
)
|
|
29987
|
-
)
|
|
29988
|
-
);
|
|
29989
|
-
process.exit(3 /* RuntimeError */);
|
|
29990
|
-
}
|
|
29991
|
-
return;
|
|
29992
|
-
}
|
|
29993
|
-
console.log(JSON.stringify(data));
|
|
29994
|
-
}
|
|
29995
|
-
|
|
29996
|
-
// src/platform/infra/cli-presentation/format-extraction-stats.ts
|
|
29997
|
-
function countLinksByType(componentCount, links) {
|
|
29998
|
-
const syncLinkCount = links.filter((l) => l.type === "sync").length;
|
|
29999
|
-
const asyncLinkCount = links.filter((l) => l.type === "async").length;
|
|
30000
|
-
const uncertainLinkCount = links.filter((l) => l._uncertain !== void 0).length;
|
|
30001
|
-
return {
|
|
30002
|
-
componentCount,
|
|
30003
|
-
linkCount: links.length,
|
|
30004
|
-
syncLinkCount,
|
|
30005
|
-
asyncLinkCount,
|
|
30006
|
-
uncertainLinkCount
|
|
30007
|
-
};
|
|
30008
|
-
}
|
|
30009
|
-
function formatSeconds(ms) {
|
|
30010
|
-
return (ms / 1e3).toFixed(2) + "s";
|
|
30011
|
-
}
|
|
30012
|
-
function formatExtractionStats(stats) {
|
|
30013
|
-
const lines = [`Components: ${stats.componentCount}`];
|
|
30014
|
-
if (stats.linkCount !== void 0) {
|
|
30015
|
-
lines.push(
|
|
30016
|
-
`Links: ${stats.linkCount} (sync: ${stats.syncLinkCount}, async: ${stats.asyncLinkCount})`
|
|
30017
|
-
);
|
|
30018
|
-
lines.push(`Uncertain: ${stats.uncertainLinkCount}`);
|
|
30019
|
-
}
|
|
30020
|
-
return lines;
|
|
30021
|
-
}
|
|
30022
|
-
function formatTimingLine(timings) {
|
|
30023
|
-
return `Extraction completed in ${formatSeconds(timings.totalMs)} (call graph: ${formatSeconds(timings.callGraphMs)}, detection: ${formatSeconds(timings.asyncDetectionMs)}, setup: ${formatSeconds(timings.setupMs)})`;
|
|
30024
|
-
}
|
|
30025
|
-
|
|
30026
|
-
// src/features/extract/infra/safe-extraction-operations.ts
|
|
30027
|
-
import "ts-morph";
|
|
30028
|
-
|
|
30029
29937
|
// src/platform/infra/extraction-config/draft-component-loader.ts
|
|
30030
29938
|
import {
|
|
30031
29939
|
existsSync as existsSync4,
|
|
@@ -30064,43 +29972,6 @@ function loadDraftComponentsFromFile(filePath) {
|
|
|
30064
29972
|
return parsed;
|
|
30065
29973
|
}
|
|
30066
29974
|
|
|
30067
|
-
// src/features/extract/infra/safe-extraction-operations.ts
|
|
30068
|
-
function loadOrExtractComponents(project, sourceFilePaths, resolvedConfig, configDir, enrichPath) {
|
|
30069
|
-
if (enrichPath === void 0) {
|
|
30070
|
-
return extractComponents(project, sourceFilePaths, resolvedConfig, matchesGlob, configDir);
|
|
30071
|
-
}
|
|
30072
|
-
return loadDraftComponentsFromFile(enrichPath);
|
|
30073
|
-
}
|
|
30074
|
-
function enrichComponentsSafe(draftComponents, resolvedConfig, project, configDir, allowIncomplete) {
|
|
30075
|
-
const result = enrichComponents(draftComponents, resolvedConfig, project, matchesGlob, configDir);
|
|
30076
|
-
if (result.failures.length > 0) {
|
|
30077
|
-
const failedFields = result.failures.map((f) => f.field);
|
|
30078
|
-
if (!allowIncomplete) {
|
|
30079
|
-
throw new ExtractionFieldFailureError(failedFields);
|
|
30080
|
-
}
|
|
30081
|
-
console.error(
|
|
30082
|
-
`Warning: Enrichment failed for ${failedFields.length} field(s): ${failedFields.join(", ")}`
|
|
30083
|
-
);
|
|
30084
|
-
}
|
|
30085
|
-
return result;
|
|
30086
|
-
}
|
|
30087
|
-
function detectConnectionsSafe(project, components, moduleGlobs, repository, allowIncomplete, showStats) {
|
|
30088
|
-
const result = detectConnections(
|
|
30089
|
-
project,
|
|
30090
|
-
components,
|
|
30091
|
-
{
|
|
30092
|
-
allowIncomplete,
|
|
30093
|
-
moduleGlobs,
|
|
30094
|
-
repository
|
|
30095
|
-
},
|
|
30096
|
-
matchesGlob
|
|
30097
|
-
);
|
|
30098
|
-
if (showStats) {
|
|
30099
|
-
console.error(formatTimingLine(result.timings));
|
|
30100
|
-
}
|
|
30101
|
-
return result;
|
|
30102
|
-
}
|
|
30103
|
-
|
|
30104
29975
|
// src/platform/infra/git/git-repository-info.ts
|
|
30105
29976
|
import { execFileSync as execFileSync2 } from "node:child_process";
|
|
30106
29977
|
var RepositoryUrlParseError = class extends Error {
|
|
@@ -30182,31 +30053,316 @@ function getRepositoryInfo(gitBinary = "git", cwd = process.cwd(), executor = de
|
|
|
30182
30053
|
}
|
|
30183
30054
|
}
|
|
30184
30055
|
|
|
30185
|
-
// src/features/extract/infra/
|
|
30056
|
+
// src/features/extract/infra/external-clients/create-module-contexts.ts
|
|
30057
|
+
import {
|
|
30058
|
+
posix as posix4,
|
|
30059
|
+
resolve as resolve7
|
|
30060
|
+
} from "node:path";
|
|
30061
|
+
import { globSync as globSync2 } from "glob";
|
|
30062
|
+
|
|
30063
|
+
// src/features/extract/infra/external-clients/find-module-tsconfig-dir.ts
|
|
30186
30064
|
import { existsSync as existsSync5 } from "node:fs";
|
|
30187
30065
|
import { resolve as resolve5 } from "node:path";
|
|
30188
|
-
|
|
30066
|
+
function findModuleTsConfigDir(configDir, modulePath) {
|
|
30067
|
+
const moduleTsConfigPath = resolve5(configDir, modulePath, "tsconfig.json");
|
|
30068
|
+
if (existsSync5(moduleTsConfigPath)) {
|
|
30069
|
+
return resolve5(configDir, modulePath);
|
|
30070
|
+
}
|
|
30071
|
+
return configDir;
|
|
30072
|
+
}
|
|
30073
|
+
|
|
30074
|
+
// src/features/extract/infra/external-clients/create-configured-project.ts
|
|
30075
|
+
import { existsSync as existsSync6 } from "node:fs";
|
|
30076
|
+
import { resolve as resolve6 } from "node:path";
|
|
30077
|
+
import { Project as Project2 } from "ts-morph";
|
|
30189
30078
|
function createConfiguredProject(configDir, skipTsConfig) {
|
|
30190
30079
|
if (skipTsConfig) {
|
|
30191
|
-
return new
|
|
30080
|
+
return new Project2();
|
|
30192
30081
|
}
|
|
30193
|
-
const tsConfigPath =
|
|
30194
|
-
if (!
|
|
30195
|
-
return new
|
|
30082
|
+
const tsConfigPath = resolve6(configDir, "tsconfig.json");
|
|
30083
|
+
if (!existsSync6(tsConfigPath)) {
|
|
30084
|
+
return new Project2();
|
|
30196
30085
|
}
|
|
30197
|
-
return new
|
|
30086
|
+
return new Project2({
|
|
30198
30087
|
tsConfigFilePath: tsConfigPath,
|
|
30199
30088
|
skipAddingFilesFromTsConfig: true
|
|
30200
30089
|
});
|
|
30201
30090
|
}
|
|
30202
30091
|
|
|
30203
|
-
// src/features/extract/infra/load-extraction-project.ts
|
|
30092
|
+
// src/features/extract/infra/external-clients/load-extraction-project.ts
|
|
30204
30093
|
function loadExtractionProject(configDir, sourceFilePaths, skipTsConfig) {
|
|
30205
30094
|
const project = createConfiguredProject(configDir, skipTsConfig);
|
|
30206
30095
|
project.addSourceFilesAtPaths(sourceFilePaths);
|
|
30207
30096
|
return project;
|
|
30208
30097
|
}
|
|
30209
30098
|
|
|
30099
|
+
// src/features/extract/infra/external-clients/create-module-contexts.ts
|
|
30100
|
+
function createModuleContexts(resolvedConfig, configDir, sourceFilePaths, skipTsConfig) {
|
|
30101
|
+
const sourceFileSet = new Set(sourceFilePaths);
|
|
30102
|
+
return resolvedConfig.modules.map((module) => {
|
|
30103
|
+
const allModuleFiles = globSync2(posix4.join(module.path, module.glob), { cwd: configDir }).map(
|
|
30104
|
+
(f) => resolve7(configDir, f)
|
|
30105
|
+
);
|
|
30106
|
+
const moduleFiles = allModuleFiles.filter((f) => sourceFileSet.has(f));
|
|
30107
|
+
const tsConfigDir = findModuleTsConfigDir(configDir, module.path);
|
|
30108
|
+
const project = loadExtractionProject(tsConfigDir, moduleFiles, skipTsConfig);
|
|
30109
|
+
return {
|
|
30110
|
+
module,
|
|
30111
|
+
files: moduleFiles,
|
|
30112
|
+
project
|
|
30113
|
+
};
|
|
30114
|
+
});
|
|
30115
|
+
}
|
|
30116
|
+
|
|
30117
|
+
// src/features/extract/domain/extract-draft-components.ts
|
|
30118
|
+
function extractDraftComponents(moduleContexts, resolvedConfig, configDir) {
|
|
30119
|
+
return moduleContexts.flatMap(
|
|
30120
|
+
(ctx) => extractComponents(ctx.project, ctx.files, resolvedConfig, matchesGlob, configDir)
|
|
30121
|
+
);
|
|
30122
|
+
}
|
|
30123
|
+
|
|
30124
|
+
// src/features/extract/domain/enrich-per-module.ts
|
|
30125
|
+
var OrphanedDraftComponentError = class extends Error {
|
|
30126
|
+
constructor(orphanedModules, knownModules) {
|
|
30127
|
+
super(
|
|
30128
|
+
`Draft components reference unknown modules: [${orphanedModules.join(", ")}]. Known modules: [${knownModules.join(", ")}]`
|
|
30129
|
+
);
|
|
30130
|
+
this.name = "OrphanedDraftComponentError";
|
|
30131
|
+
}
|
|
30132
|
+
};
|
|
30133
|
+
function enrichPerModule(moduleContexts, draftComponents, resolvedConfig, configDir) {
|
|
30134
|
+
const moduleNames = new Set(moduleContexts.map((ctx) => ctx.module.name));
|
|
30135
|
+
const draftsByModule = groupDraftsByModule(draftComponents);
|
|
30136
|
+
assertAllDraftsMatchModules(draftsByModule, moduleNames);
|
|
30137
|
+
const components = [];
|
|
30138
|
+
const failedFieldSet = /* @__PURE__ */ new Set();
|
|
30139
|
+
for (const ctx of moduleContexts) {
|
|
30140
|
+
const moduleDrafts = draftsByModule.get(ctx.module.name) ?? [];
|
|
30141
|
+
if (moduleDrafts.length === 0) {
|
|
30142
|
+
continue;
|
|
30143
|
+
}
|
|
30144
|
+
const result = enrichComponents(
|
|
30145
|
+
moduleDrafts,
|
|
30146
|
+
resolvedConfig,
|
|
30147
|
+
ctx.project,
|
|
30148
|
+
matchesGlob,
|
|
30149
|
+
configDir
|
|
30150
|
+
);
|
|
30151
|
+
components.push(...result.components);
|
|
30152
|
+
for (const f of result.failures) {
|
|
30153
|
+
failedFieldSet.add(f.field);
|
|
30154
|
+
}
|
|
30155
|
+
}
|
|
30156
|
+
return {
|
|
30157
|
+
components,
|
|
30158
|
+
failedFields: [...failedFieldSet]
|
|
30159
|
+
};
|
|
30160
|
+
}
|
|
30161
|
+
function assertAllDraftsMatchModules(draftsByModule, moduleNames) {
|
|
30162
|
+
const orphanedModules = [...draftsByModule.keys()].filter((name) => !moduleNames.has(name));
|
|
30163
|
+
if (orphanedModules.length > 0) {
|
|
30164
|
+
throw new OrphanedDraftComponentError(orphanedModules, [...moduleNames]);
|
|
30165
|
+
}
|
|
30166
|
+
}
|
|
30167
|
+
function groupDraftsByModule(drafts) {
|
|
30168
|
+
const grouped = /* @__PURE__ */ new Map();
|
|
30169
|
+
for (const draft of drafts) {
|
|
30170
|
+
const existing = grouped.get(draft.domain);
|
|
30171
|
+
if (existing) {
|
|
30172
|
+
existing.push(draft);
|
|
30173
|
+
} else {
|
|
30174
|
+
grouped.set(draft.domain, [draft]);
|
|
30175
|
+
}
|
|
30176
|
+
}
|
|
30177
|
+
return grouped;
|
|
30178
|
+
}
|
|
30179
|
+
|
|
30180
|
+
// src/features/extract/domain/detect-connections-per-module.ts
|
|
30181
|
+
import { posix as posix5 } from "node:path";
|
|
30182
|
+
function detectConnectionsPerModule(moduleContexts, enrichedComponents, repositoryName, allowIncomplete) {
|
|
30183
|
+
const links = [];
|
|
30184
|
+
const timings = [];
|
|
30185
|
+
for (const ctx of moduleContexts) {
|
|
30186
|
+
const moduleComponents = enrichedComponents.filter((c) => c.domain === ctx.module.name);
|
|
30187
|
+
if (moduleComponents.length === 0) {
|
|
30188
|
+
continue;
|
|
30189
|
+
}
|
|
30190
|
+
const result = detectPerModuleConnections(
|
|
30191
|
+
ctx.project,
|
|
30192
|
+
moduleComponents,
|
|
30193
|
+
{
|
|
30194
|
+
allowIncomplete,
|
|
30195
|
+
moduleGlobs: [posix5.join(ctx.module.path, ctx.module.glob)],
|
|
30196
|
+
repository: repositoryName
|
|
30197
|
+
},
|
|
30198
|
+
matchesGlob
|
|
30199
|
+
);
|
|
30200
|
+
links.push(...result.links);
|
|
30201
|
+
timings.push({
|
|
30202
|
+
callGraphMs: result.timings.callGraphMs,
|
|
30203
|
+
asyncDetectionMs: 0,
|
|
30204
|
+
configurableMs: result.timings.configurableMs,
|
|
30205
|
+
setupMs: result.timings.setupMs,
|
|
30206
|
+
totalMs: result.timings.callGraphMs + result.timings.configurableMs + result.timings.setupMs
|
|
30207
|
+
});
|
|
30208
|
+
}
|
|
30209
|
+
const crossResult = detectCrossModuleConnections(enrichedComponents, {
|
|
30210
|
+
allowIncomplete,
|
|
30211
|
+
repository: repositoryName
|
|
30212
|
+
});
|
|
30213
|
+
links.push(...crossResult.links);
|
|
30214
|
+
timings.push({
|
|
30215
|
+
callGraphMs: 0,
|
|
30216
|
+
asyncDetectionMs: crossResult.timings.asyncDetectionMs,
|
|
30217
|
+
configurableMs: 0,
|
|
30218
|
+
setupMs: 0,
|
|
30219
|
+
totalMs: crossResult.timings.asyncDetectionMs
|
|
30220
|
+
});
|
|
30221
|
+
return {
|
|
30222
|
+
links: deduplicateCrossStrategy(links),
|
|
30223
|
+
timings
|
|
30224
|
+
};
|
|
30225
|
+
}
|
|
30226
|
+
|
|
30227
|
+
// src/features/extract/commands/run-extraction.ts
|
|
30228
|
+
function runExtraction(options, resolvedConfig, configDir, sourceFilePaths) {
|
|
30229
|
+
const skipTsConfig = options.tsConfig === false;
|
|
30230
|
+
const moduleContexts = createModuleContexts(
|
|
30231
|
+
resolvedConfig,
|
|
30232
|
+
configDir,
|
|
30233
|
+
sourceFilePaths,
|
|
30234
|
+
skipTsConfig
|
|
30235
|
+
);
|
|
30236
|
+
const draftComponents = options.enrich === void 0 ? extractDraftComponents(moduleContexts, resolvedConfig, configDir) : loadDraftComponentsFromFile(options.enrich);
|
|
30237
|
+
if (options.dryRun || options.format === "markdown" || options.componentsOnly) {
|
|
30238
|
+
return {
|
|
30239
|
+
kind: "draftOnly",
|
|
30240
|
+
components: draftComponents
|
|
30241
|
+
};
|
|
30242
|
+
}
|
|
30243
|
+
const allowIncomplete = options.allowIncomplete === true;
|
|
30244
|
+
const enrichment = enrichPerModule(moduleContexts, draftComponents, resolvedConfig, configDir);
|
|
30245
|
+
if (enrichment.failedFields.length > 0 && !allowIncomplete) {
|
|
30246
|
+
throw new ExtractionFieldFailureError(enrichment.failedFields);
|
|
30247
|
+
}
|
|
30248
|
+
const repositoryInfo = getRepositoryInfo();
|
|
30249
|
+
const connectionResult = detectConnectionsPerModule(
|
|
30250
|
+
moduleContexts,
|
|
30251
|
+
enrichment.components,
|
|
30252
|
+
repositoryInfo.name,
|
|
30253
|
+
allowIncomplete
|
|
30254
|
+
);
|
|
30255
|
+
return {
|
|
30256
|
+
kind: "full",
|
|
30257
|
+
components: enrichment.components,
|
|
30258
|
+
links: connectionResult.links,
|
|
30259
|
+
timings: connectionResult.timings,
|
|
30260
|
+
failedFields: enrichment.failedFields
|
|
30261
|
+
};
|
|
30262
|
+
}
|
|
30263
|
+
|
|
30264
|
+
// src/platform/infra/cli-presentation/format-pr-markdown.ts
|
|
30265
|
+
function formatComponentLine(component) {
|
|
30266
|
+
return `- **${component.type}** \`${component.name}\` in \`${component.domain}\` domain`;
|
|
30267
|
+
}
|
|
30268
|
+
function formatSection(title, components) {
|
|
30269
|
+
const header = `### ${title} (${components.length})`;
|
|
30270
|
+
if (components.length === 0) {
|
|
30271
|
+
return `${header}
|
|
30272
|
+
None`;
|
|
30273
|
+
}
|
|
30274
|
+
return `${header}
|
|
30275
|
+
${components.map(formatComponentLine).join("\n")}`;
|
|
30276
|
+
}
|
|
30277
|
+
function formatPrMarkdown(categorized) {
|
|
30278
|
+
const sections = [
|
|
30279
|
+
formatSection("Added Components", categorized.added),
|
|
30280
|
+
formatSection("Modified Components", categorized.modified),
|
|
30281
|
+
formatSection("Removed Components", categorized.removed)
|
|
30282
|
+
];
|
|
30283
|
+
return `## Architecture Changes
|
|
30284
|
+
|
|
30285
|
+
${sections.join("\n\n")}`;
|
|
30286
|
+
}
|
|
30287
|
+
|
|
30288
|
+
// src/platform/infra/cli-presentation/extract-output-formatter.ts
|
|
30289
|
+
function compareByCodePoint2(a, b) {
|
|
30290
|
+
if (a < b) return -1;
|
|
30291
|
+
if (a > b) return 1;
|
|
30292
|
+
return 0;
|
|
30293
|
+
}
|
|
30294
|
+
function formatDryRunOutput(components) {
|
|
30295
|
+
const countsByDomain = /* @__PURE__ */ new Map();
|
|
30296
|
+
for (const component of components) {
|
|
30297
|
+
const existingTypeCounts = countsByDomain.get(component.domain);
|
|
30298
|
+
const typeCounts = existingTypeCounts ?? /* @__PURE__ */ new Map();
|
|
30299
|
+
if (existingTypeCounts === void 0) {
|
|
30300
|
+
countsByDomain.set(component.domain, typeCounts);
|
|
30301
|
+
}
|
|
30302
|
+
const currentCount = typeCounts.get(component.type) ?? 0;
|
|
30303
|
+
typeCounts.set(component.type, currentCount + 1);
|
|
30304
|
+
}
|
|
30305
|
+
const sortedDomains = [...countsByDomain.entries()].sort(([a], [b]) => compareByCodePoint2(a, b));
|
|
30306
|
+
const lines = [];
|
|
30307
|
+
for (const [domain2, typeCounts] of sortedDomains) {
|
|
30308
|
+
const typeStrings = [...typeCounts.entries()].sort(([a], [b]) => compareByCodePoint2(a, b)).map(([type, count]) => `${type}(${count})`);
|
|
30309
|
+
lines.push(`${domain2}: ${typeStrings.join(", ")}`);
|
|
30310
|
+
}
|
|
30311
|
+
return lines;
|
|
30312
|
+
}
|
|
30313
|
+
|
|
30314
|
+
// src/platform/infra/cli-presentation/output-writer.ts
|
|
30315
|
+
import { writeFileSync } from "node:fs";
|
|
30316
|
+
function outputResult(data, options) {
|
|
30317
|
+
if (options.output !== void 0) {
|
|
30318
|
+
try {
|
|
30319
|
+
writeFileSync(options.output, JSON.stringify(data));
|
|
30320
|
+
} catch {
|
|
30321
|
+
console.log(
|
|
30322
|
+
JSON.stringify(
|
|
30323
|
+
formatError2(
|
|
30324
|
+
"VALIDATION_ERROR" /* ValidationError */,
|
|
30325
|
+
"Failed to write output file: " + options.output
|
|
30326
|
+
)
|
|
30327
|
+
)
|
|
30328
|
+
);
|
|
30329
|
+
process.exit(3 /* RuntimeError */);
|
|
30330
|
+
}
|
|
30331
|
+
return;
|
|
30332
|
+
}
|
|
30333
|
+
console.log(JSON.stringify(data));
|
|
30334
|
+
}
|
|
30335
|
+
|
|
30336
|
+
// src/platform/infra/cli-presentation/format-extraction-stats.ts
|
|
30337
|
+
function countLinksByType(componentCount, links) {
|
|
30338
|
+
const syncLinkCount = links.filter((l) => l.type === "sync").length;
|
|
30339
|
+
const asyncLinkCount = links.filter((l) => l.type === "async").length;
|
|
30340
|
+
const uncertainLinkCount = links.filter((l) => l._uncertain !== void 0).length;
|
|
30341
|
+
return {
|
|
30342
|
+
componentCount,
|
|
30343
|
+
linkCount: links.length,
|
|
30344
|
+
syncLinkCount,
|
|
30345
|
+
asyncLinkCount,
|
|
30346
|
+
uncertainLinkCount
|
|
30347
|
+
};
|
|
30348
|
+
}
|
|
30349
|
+
function formatSeconds(ms) {
|
|
30350
|
+
return (ms / 1e3).toFixed(2) + "s";
|
|
30351
|
+
}
|
|
30352
|
+
function formatExtractionStats(stats) {
|
|
30353
|
+
const lines = [`Components: ${stats.componentCount}`];
|
|
30354
|
+
if (stats.linkCount !== void 0) {
|
|
30355
|
+
lines.push(
|
|
30356
|
+
`Links: ${stats.linkCount} (sync: ${stats.syncLinkCount}, async: ${stats.asyncLinkCount})`
|
|
30357
|
+
);
|
|
30358
|
+
lines.push(`Uncertain: ${stats.uncertainLinkCount}`);
|
|
30359
|
+
}
|
|
30360
|
+
return lines;
|
|
30361
|
+
}
|
|
30362
|
+
function formatTimingLine(timings) {
|
|
30363
|
+
return `Extraction completed in ${formatSeconds(timings.totalMs)} (call graph: ${formatSeconds(timings.callGraphMs)}, detection: ${formatSeconds(timings.asyncDetectionMs)}, setup: ${formatSeconds(timings.setupMs)})`;
|
|
30364
|
+
}
|
|
30365
|
+
|
|
30210
30366
|
// src/platform/infra/cli-presentation/categorize-components.ts
|
|
30211
30367
|
function componentKey(component) {
|
|
30212
30368
|
return `${component.domain}:${component.type}:${component.name}`;
|
|
@@ -30237,61 +30393,50 @@ function categorizeComponents(current, baseline) {
|
|
|
30237
30393
|
};
|
|
30238
30394
|
}
|
|
30239
30395
|
|
|
30240
|
-
// src/features/extract/
|
|
30241
|
-
function
|
|
30242
|
-
|
|
30243
|
-
|
|
30244
|
-
|
|
30245
|
-
|
|
30246
|
-
|
|
30247
|
-
|
|
30248
|
-
|
|
30249
|
-
);
|
|
30396
|
+
// src/features/extract/infra/mappers/present-extraction-result.ts
|
|
30397
|
+
function presentExtractionResult(result, options) {
|
|
30398
|
+
if (result.kind === "draftOnly") {
|
|
30399
|
+
presentDraftResult(result.components, options);
|
|
30400
|
+
return;
|
|
30401
|
+
}
|
|
30402
|
+
presentFullResult(result, options);
|
|
30403
|
+
}
|
|
30404
|
+
function presentDraftResult(components, options) {
|
|
30250
30405
|
if (options.dryRun) {
|
|
30251
|
-
for (const line of formatDryRunOutput(
|
|
30406
|
+
for (const line of formatDryRunOutput(components)) {
|
|
30252
30407
|
console.log(line);
|
|
30253
30408
|
}
|
|
30254
30409
|
return;
|
|
30255
30410
|
}
|
|
30256
30411
|
if (options.format === "markdown") {
|
|
30257
|
-
const categorized = categorizeComponents(
|
|
30412
|
+
const categorized = categorizeComponents(components, void 0);
|
|
30258
30413
|
const markdown = formatPrMarkdown(categorized);
|
|
30259
30414
|
console.log(markdown);
|
|
30260
30415
|
return;
|
|
30261
30416
|
}
|
|
30262
|
-
|
|
30263
|
-
|
|
30264
|
-
|
|
30417
|
+
outputResult(formatSuccess(components), { output: options.output });
|
|
30418
|
+
}
|
|
30419
|
+
function presentFullResult(result, options) {
|
|
30420
|
+
if (result.failedFields.length > 0) {
|
|
30421
|
+
console.error(
|
|
30422
|
+
`Warning: Enrichment failed for ${result.failedFields.length} field(s): ${result.failedFields.join(", ")}`
|
|
30423
|
+
);
|
|
30265
30424
|
}
|
|
30266
|
-
const enrichmentResult = enrichComponentsSafe(
|
|
30267
|
-
draftComponents,
|
|
30268
|
-
resolvedConfig,
|
|
30269
|
-
project,
|
|
30270
|
-
configDir,
|
|
30271
|
-
options.allowIncomplete === true
|
|
30272
|
-
);
|
|
30273
|
-
const repositoryInfo = getRepositoryInfo();
|
|
30274
|
-
const { links } = detectConnectionsSafe(
|
|
30275
|
-
project,
|
|
30276
|
-
enrichmentResult.components,
|
|
30277
|
-
resolvedConfig.modules.map((m) => m.path),
|
|
30278
|
-
repositoryInfo.name,
|
|
30279
|
-
options.allowIncomplete === true,
|
|
30280
|
-
options.stats === true
|
|
30281
|
-
);
|
|
30282
30425
|
if (options.stats === true) {
|
|
30283
|
-
const
|
|
30426
|
+
for (const timing of result.timings) {
|
|
30427
|
+
console.error(formatTimingLine(timing));
|
|
30428
|
+
}
|
|
30429
|
+
const stats = countLinksByType(result.components.length, result.links);
|
|
30284
30430
|
for (const line of formatExtractionStats(stats)) {
|
|
30285
30431
|
console.error(line);
|
|
30286
30432
|
}
|
|
30287
30433
|
}
|
|
30288
|
-
const outputOptions = options.output === void 0 ? {} : { output: options.output };
|
|
30289
30434
|
outputResult(
|
|
30290
30435
|
formatSuccess({
|
|
30291
|
-
components:
|
|
30292
|
-
links
|
|
30436
|
+
components: result.components,
|
|
30437
|
+
links: result.links
|
|
30293
30438
|
}),
|
|
30294
|
-
|
|
30439
|
+
{ output: options.output }
|
|
30295
30440
|
);
|
|
30296
30441
|
}
|
|
30297
30442
|
|
|
@@ -30305,7 +30450,8 @@ function createExtractCommand() {
|
|
|
30305
30450
|
} = loadAndValidateConfig(options.config);
|
|
30306
30451
|
const allSourceFilePaths = resolveSourceFiles(resolvedConfig, configDir);
|
|
30307
30452
|
const sourceFilePaths = resolveFilteredSourceFiles(allSourceFilePaths, options);
|
|
30308
|
-
runExtraction(options, resolvedConfig, configDir, sourceFilePaths);
|
|
30453
|
+
const result = runExtraction(options, resolvedConfig, configDir, sourceFilePaths);
|
|
30454
|
+
presentExtractionResult(result, options);
|
|
30309
30455
|
});
|
|
30310
30456
|
}
|
|
30311
30457
|
|
|
@@ -30383,8 +30529,8 @@ export {
|
|
|
30383
30529
|
/* v8 ignore next -- @preserve: error is always Error from yaml parser; defensive guard */
|
|
30384
30530
|
/* v8 ignore start -- @preserve: default executor delegates to execFileSync; tested via CLI integration */
|
|
30385
30531
|
/* v8 ignore start -- @preserve: detectChangedTypeScriptFiles only throws GitError; non-GitError path is unreachable */
|
|
30386
|
-
/* v8 ignore start -- @preserve: trivial comparator, Map keys guarantee a !== b */
|
|
30387
|
-
/* v8 ignore start -- @preserve: dry-run output formatting; tested via CLI integration */
|
|
30388
30532
|
/* v8 ignore start -- @preserve: git execution; mocked in all integration tests */
|
|
30389
30533
|
/* v8 ignore start -- @preserve: defensive check; regex ([^/]+) requires non-empty groups */
|
|
30534
|
+
/* v8 ignore start -- @preserve: trivial comparator, Map keys guarantee a !== b */
|
|
30535
|
+
/* v8 ignore start -- @preserve: dry-run output formatting; tested via CLI integration */
|
|
30390
30536
|
/* v8 ignore start -- @preserve: dry-run tested via CLI integration */
|