@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/bin.js
CHANGED
|
@@ -2980,7 +2980,7 @@ var require_compile = __commonJS({
|
|
|
2980
2980
|
const schOrFunc = root.refs[ref];
|
|
2981
2981
|
if (schOrFunc)
|
|
2982
2982
|
return schOrFunc;
|
|
2983
|
-
let _sch =
|
|
2983
|
+
let _sch = resolve8.call(this, root, ref);
|
|
2984
2984
|
if (_sch === void 0) {
|
|
2985
2985
|
const schema = (_a2 = root.localRefs) === null || _a2 === void 0 ? void 0 : _a2[ref];
|
|
2986
2986
|
const { schemaId } = this.opts;
|
|
@@ -3007,7 +3007,7 @@ var require_compile = __commonJS({
|
|
|
3007
3007
|
function sameSchemaEnv(s1, s2) {
|
|
3008
3008
|
return s1.schema === s2.schema && s1.root === s2.root && s1.baseId === s2.baseId;
|
|
3009
3009
|
}
|
|
3010
|
-
function
|
|
3010
|
+
function resolve8(root, ref) {
|
|
3011
3011
|
let sch;
|
|
3012
3012
|
while (typeof (sch = this.refs[ref]) == "string")
|
|
3013
3013
|
ref = sch;
|
|
@@ -3582,7 +3582,7 @@ var require_fast_uri = __commonJS({
|
|
|
3582
3582
|
}
|
|
3583
3583
|
return uri;
|
|
3584
3584
|
}
|
|
3585
|
-
function
|
|
3585
|
+
function resolve8(baseURI, relativeURI, options) {
|
|
3586
3586
|
const schemelessOptions = options ? Object.assign({ scheme: "null" }, options) : { scheme: "null" };
|
|
3587
3587
|
const resolved = resolveComponent(parse3(baseURI, schemelessOptions), parse3(relativeURI, schemelessOptions), schemelessOptions, true);
|
|
3588
3588
|
schemelessOptions.skipEscape = true;
|
|
@@ -3809,7 +3809,7 @@ var require_fast_uri = __commonJS({
|
|
|
3809
3809
|
var fastUri = {
|
|
3810
3810
|
SCHEMES,
|
|
3811
3811
|
normalize,
|
|
3812
|
-
resolve:
|
|
3812
|
+
resolve: resolve8,
|
|
3813
3813
|
resolveComponent,
|
|
3814
3814
|
equal,
|
|
3815
3815
|
serialize,
|
|
@@ -25180,7 +25180,8 @@ import { Command as Command21 } from "commander";
|
|
|
25180
25180
|
// src/platform/infra/extraction-config/config-loader.ts
|
|
25181
25181
|
import {
|
|
25182
25182
|
dirname as dirname2,
|
|
25183
|
-
resolve as resolve2
|
|
25183
|
+
resolve as resolve2,
|
|
25184
|
+
posix as posix3
|
|
25184
25185
|
} from "node:path";
|
|
25185
25186
|
import {
|
|
25186
25187
|
existsSync as existsSync2,
|
|
@@ -25241,7 +25242,7 @@ var extraction_config_schema_default = {
|
|
|
25241
25242
|
module: {
|
|
25242
25243
|
type: "object",
|
|
25243
25244
|
description: "A module defines extraction rules for a path pattern",
|
|
25244
|
-
required: ["name", "path"],
|
|
25245
|
+
required: ["name", "path", "glob"],
|
|
25245
25246
|
additionalProperties: false,
|
|
25246
25247
|
properties: {
|
|
25247
25248
|
name: {
|
|
@@ -25251,7 +25252,12 @@ var extraction_config_schema_default = {
|
|
|
25251
25252
|
},
|
|
25252
25253
|
path: {
|
|
25253
25254
|
type: "string",
|
|
25254
|
-
description: "
|
|
25255
|
+
description: "Module root directory relative to config file",
|
|
25256
|
+
minLength: 1
|
|
25257
|
+
},
|
|
25258
|
+
glob: {
|
|
25259
|
+
type: "string",
|
|
25260
|
+
description: "Glob pattern for source files within the module directory",
|
|
25255
25261
|
minLength: 1
|
|
25256
25262
|
},
|
|
25257
25263
|
extends: {
|
|
@@ -26318,11 +26324,11 @@ function createFunctionComponent(func, filePath, domain2, componentType) {
|
|
|
26318
26324
|
function findMatchingModule(filePath, modules, globMatcher, configDir) {
|
|
26319
26325
|
const normalized = filePath.replaceAll(/\\+/g, "/");
|
|
26320
26326
|
if (configDir === void 0) {
|
|
26321
|
-
return modules.find((m) => globMatcher(normalized, m.path));
|
|
26327
|
+
return modules.find((m) => globMatcher(normalized, posix.join(m.path, m.glob)));
|
|
26322
26328
|
}
|
|
26323
26329
|
const normalizedConfigDir = configDir.replaceAll(/\\+/g, "/");
|
|
26324
26330
|
const pathToMatch = posix.relative(normalizedConfigDir, normalized);
|
|
26325
|
-
return modules.find((m) => globMatcher(pathToMatch, m.path));
|
|
26331
|
+
return modules.find((m) => globMatcher(pathToMatch, posix.join(m.path, m.glob)));
|
|
26326
26332
|
}
|
|
26327
26333
|
|
|
26328
26334
|
// ../riviere-extract-ts/dist/features/extraction/domain/config-resolution/config-resolution-errors.js
|
|
@@ -26360,6 +26366,7 @@ function resolveModule(moduleConfig, loader) {
|
|
|
26360
26366
|
return {
|
|
26361
26367
|
name: moduleConfig.name,
|
|
26362
26368
|
path: moduleConfig.path,
|
|
26369
|
+
glob: moduleConfig.glob,
|
|
26363
26370
|
api: requireRule(moduleConfig.api, "api", moduleConfig.name),
|
|
26364
26371
|
useCase: requireRule(moduleConfig.useCase, "useCase", moduleConfig.name),
|
|
26365
26372
|
domainOp: requireRule(moduleConfig.domainOp, "domainOp", moduleConfig.name),
|
|
@@ -26379,6 +26386,7 @@ function resolveModuleWithExtends(moduleConfig, extendsSource, loader) {
|
|
|
26379
26386
|
return {
|
|
26380
26387
|
name: moduleConfig.name,
|
|
26381
26388
|
path: moduleConfig.path,
|
|
26389
|
+
glob: moduleConfig.glob,
|
|
26382
26390
|
api: moduleConfig.api ?? baseModule.api,
|
|
26383
26391
|
useCase: moduleConfig.useCase ?? baseModule.useCase,
|
|
26384
26392
|
domainOp: moduleConfig.domainOp ?? baseModule.domainOp,
|
|
@@ -28845,50 +28853,48 @@ function traceNonComponent(project, componentIndex, source, typeName, calledMeth
|
|
|
28845
28853
|
}
|
|
28846
28854
|
|
|
28847
28855
|
// ../riviere-extract-ts/dist/features/extraction/domain/connection-detection/async-detection/detect-publish-connections.js
|
|
28848
|
-
function detectPublishConnections(
|
|
28856
|
+
function detectPublishConnections(components, options) {
|
|
28849
28857
|
const publishers = components.filter((c) => c.type === "eventPublisher");
|
|
28850
28858
|
const events = components.filter((c) => c.type === "event");
|
|
28851
28859
|
const repository = options.repository;
|
|
28852
|
-
return publishers.flatMap((publisher) =>
|
|
28853
|
-
|
|
28854
|
-
function extractPublisherLinks(project, publisher, events, options, repository) {
|
|
28855
|
-
const publishedEventType = publisher.metadata["publishedEventType"];
|
|
28856
|
-
if (typeof publishedEventType === "string") {
|
|
28860
|
+
return publishers.flatMap((publisher) => {
|
|
28861
|
+
const publishedEventType = publisher.metadata["publishedEventType"];
|
|
28857
28862
|
const sourceLocation = {
|
|
28858
28863
|
repository,
|
|
28859
28864
|
filePath: publisher.location.file,
|
|
28860
28865
|
lineNumber: publisher.location.line
|
|
28861
28866
|
};
|
|
28862
|
-
|
|
28863
|
-
|
|
28864
|
-
const classDecl = findClassInProject(project, publisher);
|
|
28865
|
-
if (classDecl === void 0) {
|
|
28866
|
-
return [];
|
|
28867
|
-
}
|
|
28868
|
-
const methods = classDecl.getMethods();
|
|
28869
|
-
return methods.flatMap((method) => {
|
|
28870
|
-
const firstParam = method.getParameters()[0];
|
|
28871
|
-
if (firstParam === void 0) {
|
|
28872
|
-
return [];
|
|
28867
|
+
if (typeof publishedEventType !== "string") {
|
|
28868
|
+
return [handleMissingMetadata(publisher, options, sourceLocation)];
|
|
28873
28869
|
}
|
|
28874
|
-
|
|
28875
|
-
const paramTypeName = stripGenericArgs(paramType.getText(firstParam));
|
|
28876
|
-
const sourceLocation = {
|
|
28877
|
-
repository,
|
|
28878
|
-
filePath: publisher.location.file,
|
|
28879
|
-
lineNumber: method.getStartLineNumber()
|
|
28880
|
-
};
|
|
28881
|
-
return resolvePublishTarget(publisher, paramTypeName, events, options, sourceLocation);
|
|
28870
|
+
return resolvePublishTarget(publisher, publishedEventType, events, options, sourceLocation);
|
|
28882
28871
|
});
|
|
28883
28872
|
}
|
|
28884
|
-
function
|
|
28885
|
-
|
|
28873
|
+
function handleMissingMetadata(publisher, options, sourceLocation) {
|
|
28874
|
+
if (options.strict) {
|
|
28875
|
+
throw new ConnectionDetectionError({
|
|
28876
|
+
file: sourceLocation.filePath,
|
|
28877
|
+
line: sourceLocation.lineNumber,
|
|
28878
|
+
typeName: publisher.name,
|
|
28879
|
+
reason: 'eventPublisher is missing required "publishedEventType" metadata'
|
|
28880
|
+
});
|
|
28881
|
+
}
|
|
28882
|
+
return {
|
|
28883
|
+
source: componentIdentity(publisher),
|
|
28884
|
+
target: "_unresolved",
|
|
28885
|
+
type: "async",
|
|
28886
|
+
sourceLocation,
|
|
28887
|
+
_uncertain: `eventPublisher "${publisher.name}" is missing required "publishedEventType" metadata`
|
|
28888
|
+
};
|
|
28889
|
+
}
|
|
28890
|
+
function resolvePublishTarget(publisher, publishedEventType, events, options, sourceLocation) {
|
|
28891
|
+
const matchingEvents = events.filter((e) => e.metadata["eventName"] === publishedEventType);
|
|
28886
28892
|
if (matchingEvents.length === 0) {
|
|
28887
|
-
return [handleNoMatch(publisher,
|
|
28893
|
+
return [handleNoMatch(publisher, publishedEventType, options, sourceLocation)];
|
|
28888
28894
|
}
|
|
28889
28895
|
if (matchingEvents.length > 1) {
|
|
28890
28896
|
return [
|
|
28891
|
-
handleAmbiguousMatch(publisher,
|
|
28897
|
+
handleAmbiguousMatch(publisher, publishedEventType, matchingEvents.length, options, sourceLocation)
|
|
28892
28898
|
];
|
|
28893
28899
|
}
|
|
28894
28900
|
return matchingEvents.map((event) => ({
|
|
@@ -28898,13 +28904,13 @@ function resolvePublishTarget(publisher, paramTypeName, events, options, sourceL
|
|
|
28898
28904
|
sourceLocation
|
|
28899
28905
|
}));
|
|
28900
28906
|
}
|
|
28901
|
-
function handleAmbiguousMatch(publisher,
|
|
28907
|
+
function handleAmbiguousMatch(publisher, publishedEventType, matchCount, options, sourceLocation) {
|
|
28902
28908
|
if (options.strict) {
|
|
28903
28909
|
throw new ConnectionDetectionError({
|
|
28904
28910
|
file: sourceLocation.filePath,
|
|
28905
28911
|
line: sourceLocation.lineNumber,
|
|
28906
28912
|
typeName: publisher.name,
|
|
28907
|
-
reason: `
|
|
28913
|
+
reason: `publishedEventType "${publishedEventType}" matches ${matchCount} Event components (ambiguous)`
|
|
28908
28914
|
});
|
|
28909
28915
|
}
|
|
28910
28916
|
return {
|
|
@@ -28912,16 +28918,16 @@ function handleAmbiguousMatch(publisher, paramTypeName, matchCount, options, sou
|
|
|
28912
28918
|
target: "_unresolved",
|
|
28913
28919
|
type: "async",
|
|
28914
28920
|
sourceLocation,
|
|
28915
|
-
_uncertain: `ambiguous: ${matchCount} events match
|
|
28921
|
+
_uncertain: `ambiguous: ${matchCount} events match publishedEventType: ${publishedEventType}`
|
|
28916
28922
|
};
|
|
28917
28923
|
}
|
|
28918
|
-
function handleNoMatch(publisher,
|
|
28924
|
+
function handleNoMatch(publisher, publishedEventType, options, sourceLocation) {
|
|
28919
28925
|
if (options.strict) {
|
|
28920
28926
|
throw new ConnectionDetectionError({
|
|
28921
28927
|
file: sourceLocation.filePath,
|
|
28922
28928
|
line: sourceLocation.lineNumber,
|
|
28923
28929
|
typeName: publisher.name,
|
|
28924
|
-
reason: `
|
|
28930
|
+
reason: `publishedEventType "${publishedEventType}" does not match any Event component`
|
|
28925
28931
|
});
|
|
28926
28932
|
}
|
|
28927
28933
|
return {
|
|
@@ -28929,7 +28935,7 @@ function handleNoMatch(publisher, paramTypeName, options, sourceLocation) {
|
|
|
28929
28935
|
target: "_unresolved",
|
|
28930
28936
|
type: "async",
|
|
28931
28937
|
sourceLocation,
|
|
28932
|
-
_uncertain: `no event found for
|
|
28938
|
+
_uncertain: `no event found for publishedEventType: ${publishedEventType}`
|
|
28933
28939
|
};
|
|
28934
28940
|
}
|
|
28935
28941
|
|
|
@@ -29238,8 +29244,7 @@ function deduplicateCrossStrategy(links) {
|
|
|
29238
29244
|
}
|
|
29239
29245
|
return [...seen.values()];
|
|
29240
29246
|
}
|
|
29241
|
-
function
|
|
29242
|
-
const totalStart = performance.now();
|
|
29247
|
+
function detectPerModuleConnections(project, components, options, globMatcher) {
|
|
29243
29248
|
const setupStart = performance.now();
|
|
29244
29249
|
const componentIndex = new ComponentIndex(components);
|
|
29245
29250
|
const sourceFilePaths = computeFilteredFilePaths(project, options.moduleGlobs, globMatcher);
|
|
@@ -29253,43 +29258,50 @@ function detectConnections(project, components, options, globMatcher) {
|
|
|
29253
29258
|
repository
|
|
29254
29259
|
});
|
|
29255
29260
|
const callGraphMs = performance.now() - callGraphStart;
|
|
29261
|
+
const patterns = options.patterns ?? [];
|
|
29262
|
+
const { configurableLinks, configurableMs } = runConfigurableDetection(project, patterns, components, componentIndex, strict, repository);
|
|
29263
|
+
return {
|
|
29264
|
+
links: [...syncLinks, ...configurableLinks],
|
|
29265
|
+
timings: {
|
|
29266
|
+
callGraphMs,
|
|
29267
|
+
configurableMs,
|
|
29268
|
+
setupMs
|
|
29269
|
+
}
|
|
29270
|
+
};
|
|
29271
|
+
}
|
|
29272
|
+
function detectCrossModuleConnections(allComponents, options) {
|
|
29273
|
+
const strict = options.allowIncomplete !== true;
|
|
29274
|
+
const repository = options.repository;
|
|
29256
29275
|
const asyncStart = performance.now();
|
|
29257
|
-
const publishLinks = detectPublishConnections(
|
|
29276
|
+
const publishLinks = detectPublishConnections(allComponents, {
|
|
29258
29277
|
strict,
|
|
29259
29278
|
repository
|
|
29260
29279
|
});
|
|
29261
|
-
const subscribeLinks = detectSubscribeConnections(
|
|
29280
|
+
const subscribeLinks = detectSubscribeConnections(allComponents, {
|
|
29262
29281
|
strict,
|
|
29263
29282
|
repository
|
|
29264
29283
|
});
|
|
29265
29284
|
const asyncDetectionMs = performance.now() - asyncStart;
|
|
29266
|
-
|
|
29267
|
-
|
|
29268
|
-
|
|
29269
|
-
|
|
29270
|
-
|
|
29271
|
-
|
|
29272
|
-
|
|
29285
|
+
return {
|
|
29286
|
+
links: [...publishLinks, ...subscribeLinks],
|
|
29287
|
+
timings: { asyncDetectionMs }
|
|
29288
|
+
};
|
|
29289
|
+
}
|
|
29290
|
+
function runConfigurableDetection(project, patterns, components, componentIndex, strict, repository) {
|
|
29291
|
+
if (patterns.length === 0) {
|
|
29273
29292
|
return {
|
|
29274
|
-
configurableLinks:
|
|
29275
|
-
configurableMs:
|
|
29293
|
+
configurableLinks: [],
|
|
29294
|
+
configurableMs: 0
|
|
29276
29295
|
};
|
|
29277
|
-
}
|
|
29278
|
-
|
|
29279
|
-
|
|
29280
|
-
|
|
29281
|
-
|
|
29282
|
-
|
|
29283
|
-
const deduplicatedLinks = deduplicateCrossStrategy(allLinks);
|
|
29296
|
+
}
|
|
29297
|
+
const configurableStart = performance.now();
|
|
29298
|
+
const links = detectConfigurableConnections(project, patterns, components, componentIndex, {
|
|
29299
|
+
strict,
|
|
29300
|
+
repository
|
|
29301
|
+
});
|
|
29284
29302
|
return {
|
|
29285
|
-
|
|
29286
|
-
|
|
29287
|
-
callGraphMs,
|
|
29288
|
-
asyncDetectionMs,
|
|
29289
|
-
configurableMs,
|
|
29290
|
-
setupMs,
|
|
29291
|
-
totalMs
|
|
29292
|
-
}
|
|
29303
|
+
configurableLinks: links,
|
|
29304
|
+
configurableMs: performance.now() - configurableStart
|
|
29293
29305
|
};
|
|
29294
29306
|
}
|
|
29295
29307
|
|
|
@@ -29298,7 +29310,7 @@ import { posix as posix2 } from "node:path";
|
|
|
29298
29310
|
function findMatchingModule2(filePath, modules, globMatcher, configDir) {
|
|
29299
29311
|
const normalized = filePath.replaceAll(/\\+/g, "/");
|
|
29300
29312
|
const pathToMatch = posix2.relative(configDir.replaceAll(/\\+/g, "/"), normalized);
|
|
29301
|
-
return modules.find((m) => globMatcher(pathToMatch, m.path));
|
|
29313
|
+
return modules.find((m) => globMatcher(pathToMatch, posix2.join(m.path, m.glob)));
|
|
29302
29314
|
}
|
|
29303
29315
|
function getBuiltInRule(module, componentType) {
|
|
29304
29316
|
const ruleMap = {
|
|
@@ -29520,7 +29532,8 @@ var NOT_USED = { notUsed: true };
|
|
|
29520
29532
|
function topLevelRulesToModule(parsed) {
|
|
29521
29533
|
return {
|
|
29522
29534
|
name: "extended",
|
|
29523
|
-
path: "
|
|
29535
|
+
path: ".",
|
|
29536
|
+
glob: "**",
|
|
29524
29537
|
api: parsed.api ?? NOT_USED,
|
|
29525
29538
|
useCase: parsed.useCase ?? NOT_USED,
|
|
29526
29539
|
domainOp: parsed.domainOp ?? NOT_USED,
|
|
@@ -29640,9 +29653,9 @@ function tryExpandModuleRefs(data, configDir) {
|
|
|
29640
29653
|
}
|
|
29641
29654
|
}
|
|
29642
29655
|
function resolveSourceFiles(resolvedConfig, configDir) {
|
|
29643
|
-
const sourceFilePaths = resolvedConfig.modules.flatMap((module) => globSync(module.path, { cwd: configDir })).map((filePath) => resolve2(configDir, filePath));
|
|
29656
|
+
const sourceFilePaths = resolvedConfig.modules.flatMap((module) => globSync(posix3.join(module.path, module.glob), { cwd: configDir })).map((filePath) => resolve2(configDir, filePath));
|
|
29644
29657
|
if (sourceFilePaths.length === 0) {
|
|
29645
|
-
const patterns = resolvedConfig.modules.map((m) => m.path).join(", ");
|
|
29658
|
+
const patterns = resolvedConfig.modules.map((m) => posix3.join(m.path, m.glob)).join(", ");
|
|
29646
29659
|
throw new ConfigValidationError(
|
|
29647
29660
|
"VALIDATION_ERROR" /* ValidationError */,
|
|
29648
29661
|
`No files matched extraction patterns: ${patterns}
|
|
@@ -29897,111 +29910,6 @@ function validateFlagCombinations(options) {
|
|
|
29897
29910
|
validateFormatOption(options);
|
|
29898
29911
|
}
|
|
29899
29912
|
|
|
29900
|
-
// src/platform/infra/cli-presentation/format-pr-markdown.ts
|
|
29901
|
-
function formatComponentLine(component) {
|
|
29902
|
-
return `- **${component.type}** \`${component.name}\` in \`${component.domain}\` domain`;
|
|
29903
|
-
}
|
|
29904
|
-
function formatSection(title, components) {
|
|
29905
|
-
const header = `### ${title} (${components.length})`;
|
|
29906
|
-
if (components.length === 0) {
|
|
29907
|
-
return `${header}
|
|
29908
|
-
None`;
|
|
29909
|
-
}
|
|
29910
|
-
return `${header}
|
|
29911
|
-
${components.map(formatComponentLine).join("\n")}`;
|
|
29912
|
-
}
|
|
29913
|
-
function formatPrMarkdown(categorized) {
|
|
29914
|
-
const sections = [
|
|
29915
|
-
formatSection("Added Components", categorized.added),
|
|
29916
|
-
formatSection("Modified Components", categorized.modified),
|
|
29917
|
-
formatSection("Removed Components", categorized.removed)
|
|
29918
|
-
];
|
|
29919
|
-
return `## Architecture Changes
|
|
29920
|
-
|
|
29921
|
-
${sections.join("\n\n")}`;
|
|
29922
|
-
}
|
|
29923
|
-
|
|
29924
|
-
// src/platform/infra/cli-presentation/extract-output-formatter.ts
|
|
29925
|
-
function compareByCodePoint2(a, b) {
|
|
29926
|
-
if (a < b) return -1;
|
|
29927
|
-
if (a > b) return 1;
|
|
29928
|
-
return 0;
|
|
29929
|
-
}
|
|
29930
|
-
function formatDryRunOutput(components) {
|
|
29931
|
-
const countsByDomain = /* @__PURE__ */ new Map();
|
|
29932
|
-
for (const component of components) {
|
|
29933
|
-
const existingTypeCounts = countsByDomain.get(component.domain);
|
|
29934
|
-
const typeCounts = existingTypeCounts ?? /* @__PURE__ */ new Map();
|
|
29935
|
-
if (existingTypeCounts === void 0) {
|
|
29936
|
-
countsByDomain.set(component.domain, typeCounts);
|
|
29937
|
-
}
|
|
29938
|
-
const currentCount = typeCounts.get(component.type) ?? 0;
|
|
29939
|
-
typeCounts.set(component.type, currentCount + 1);
|
|
29940
|
-
}
|
|
29941
|
-
const sortedDomains = [...countsByDomain.entries()].sort(([a], [b]) => compareByCodePoint2(a, b));
|
|
29942
|
-
const lines = [];
|
|
29943
|
-
for (const [domain2, typeCounts] of sortedDomains) {
|
|
29944
|
-
const typeStrings = [...typeCounts.entries()].sort(([a], [b]) => compareByCodePoint2(a, b)).map(([type, count]) => `${type}(${count})`);
|
|
29945
|
-
lines.push(`${domain2}: ${typeStrings.join(", ")}`);
|
|
29946
|
-
}
|
|
29947
|
-
return lines;
|
|
29948
|
-
}
|
|
29949
|
-
|
|
29950
|
-
// src/platform/infra/cli-presentation/output-writer.ts
|
|
29951
|
-
import { writeFileSync } from "node:fs";
|
|
29952
|
-
function outputResult(data, options) {
|
|
29953
|
-
if (options.output !== void 0) {
|
|
29954
|
-
try {
|
|
29955
|
-
writeFileSync(options.output, JSON.stringify(data));
|
|
29956
|
-
} catch {
|
|
29957
|
-
console.log(
|
|
29958
|
-
JSON.stringify(
|
|
29959
|
-
formatError2(
|
|
29960
|
-
"VALIDATION_ERROR" /* ValidationError */,
|
|
29961
|
-
"Failed to write output file: " + options.output
|
|
29962
|
-
)
|
|
29963
|
-
)
|
|
29964
|
-
);
|
|
29965
|
-
process.exit(3 /* RuntimeError */);
|
|
29966
|
-
}
|
|
29967
|
-
return;
|
|
29968
|
-
}
|
|
29969
|
-
console.log(JSON.stringify(data));
|
|
29970
|
-
}
|
|
29971
|
-
|
|
29972
|
-
// src/platform/infra/cli-presentation/format-extraction-stats.ts
|
|
29973
|
-
function countLinksByType(componentCount, links) {
|
|
29974
|
-
const syncLinkCount = links.filter((l) => l.type === "sync").length;
|
|
29975
|
-
const asyncLinkCount = links.filter((l) => l.type === "async").length;
|
|
29976
|
-
const uncertainLinkCount = links.filter((l) => l._uncertain !== void 0).length;
|
|
29977
|
-
return {
|
|
29978
|
-
componentCount,
|
|
29979
|
-
linkCount: links.length,
|
|
29980
|
-
syncLinkCount,
|
|
29981
|
-
asyncLinkCount,
|
|
29982
|
-
uncertainLinkCount
|
|
29983
|
-
};
|
|
29984
|
-
}
|
|
29985
|
-
function formatSeconds(ms) {
|
|
29986
|
-
return (ms / 1e3).toFixed(2) + "s";
|
|
29987
|
-
}
|
|
29988
|
-
function formatExtractionStats(stats) {
|
|
29989
|
-
const lines = [`Components: ${stats.componentCount}`];
|
|
29990
|
-
if (stats.linkCount !== void 0) {
|
|
29991
|
-
lines.push(
|
|
29992
|
-
`Links: ${stats.linkCount} (sync: ${stats.syncLinkCount}, async: ${stats.asyncLinkCount})`
|
|
29993
|
-
);
|
|
29994
|
-
lines.push(`Uncertain: ${stats.uncertainLinkCount}`);
|
|
29995
|
-
}
|
|
29996
|
-
return lines;
|
|
29997
|
-
}
|
|
29998
|
-
function formatTimingLine(timings) {
|
|
29999
|
-
return `Extraction completed in ${formatSeconds(timings.totalMs)} (call graph: ${formatSeconds(timings.callGraphMs)}, detection: ${formatSeconds(timings.asyncDetectionMs)}, setup: ${formatSeconds(timings.setupMs)})`;
|
|
30000
|
-
}
|
|
30001
|
-
|
|
30002
|
-
// src/features/extract/infra/safe-extraction-operations.ts
|
|
30003
|
-
import "ts-morph";
|
|
30004
|
-
|
|
30005
29913
|
// src/platform/infra/extraction-config/draft-component-loader.ts
|
|
30006
29914
|
import {
|
|
30007
29915
|
existsSync as existsSync4,
|
|
@@ -30040,43 +29948,6 @@ function loadDraftComponentsFromFile(filePath) {
|
|
|
30040
29948
|
return parsed;
|
|
30041
29949
|
}
|
|
30042
29950
|
|
|
30043
|
-
// src/features/extract/infra/safe-extraction-operations.ts
|
|
30044
|
-
function loadOrExtractComponents(project, sourceFilePaths, resolvedConfig, configDir, enrichPath) {
|
|
30045
|
-
if (enrichPath === void 0) {
|
|
30046
|
-
return extractComponents(project, sourceFilePaths, resolvedConfig, matchesGlob, configDir);
|
|
30047
|
-
}
|
|
30048
|
-
return loadDraftComponentsFromFile(enrichPath);
|
|
30049
|
-
}
|
|
30050
|
-
function enrichComponentsSafe(draftComponents, resolvedConfig, project, configDir, allowIncomplete) {
|
|
30051
|
-
const result = enrichComponents(draftComponents, resolvedConfig, project, matchesGlob, configDir);
|
|
30052
|
-
if (result.failures.length > 0) {
|
|
30053
|
-
const failedFields = result.failures.map((f) => f.field);
|
|
30054
|
-
if (!allowIncomplete) {
|
|
30055
|
-
throw new ExtractionFieldFailureError(failedFields);
|
|
30056
|
-
}
|
|
30057
|
-
console.error(
|
|
30058
|
-
`Warning: Enrichment failed for ${failedFields.length} field(s): ${failedFields.join(", ")}`
|
|
30059
|
-
);
|
|
30060
|
-
}
|
|
30061
|
-
return result;
|
|
30062
|
-
}
|
|
30063
|
-
function detectConnectionsSafe(project, components, moduleGlobs, repository, allowIncomplete, showStats) {
|
|
30064
|
-
const result = detectConnections(
|
|
30065
|
-
project,
|
|
30066
|
-
components,
|
|
30067
|
-
{
|
|
30068
|
-
allowIncomplete,
|
|
30069
|
-
moduleGlobs,
|
|
30070
|
-
repository
|
|
30071
|
-
},
|
|
30072
|
-
matchesGlob
|
|
30073
|
-
);
|
|
30074
|
-
if (showStats) {
|
|
30075
|
-
console.error(formatTimingLine(result.timings));
|
|
30076
|
-
}
|
|
30077
|
-
return result;
|
|
30078
|
-
}
|
|
30079
|
-
|
|
30080
29951
|
// src/platform/infra/git/git-repository-info.ts
|
|
30081
29952
|
import { execFileSync as execFileSync2 } from "node:child_process";
|
|
30082
29953
|
var RepositoryUrlParseError = class extends Error {
|
|
@@ -30158,31 +30029,316 @@ function getRepositoryInfo(gitBinary = "git", cwd = process.cwd(), executor = de
|
|
|
30158
30029
|
}
|
|
30159
30030
|
}
|
|
30160
30031
|
|
|
30161
|
-
// src/features/extract/infra/
|
|
30032
|
+
// src/features/extract/infra/external-clients/create-module-contexts.ts
|
|
30033
|
+
import {
|
|
30034
|
+
posix as posix4,
|
|
30035
|
+
resolve as resolve7
|
|
30036
|
+
} from "node:path";
|
|
30037
|
+
import { globSync as globSync2 } from "glob";
|
|
30038
|
+
|
|
30039
|
+
// src/features/extract/infra/external-clients/find-module-tsconfig-dir.ts
|
|
30162
30040
|
import { existsSync as existsSync5 } from "node:fs";
|
|
30163
30041
|
import { resolve as resolve5 } from "node:path";
|
|
30164
|
-
|
|
30042
|
+
function findModuleTsConfigDir(configDir, modulePath) {
|
|
30043
|
+
const moduleTsConfigPath = resolve5(configDir, modulePath, "tsconfig.json");
|
|
30044
|
+
if (existsSync5(moduleTsConfigPath)) {
|
|
30045
|
+
return resolve5(configDir, modulePath);
|
|
30046
|
+
}
|
|
30047
|
+
return configDir;
|
|
30048
|
+
}
|
|
30049
|
+
|
|
30050
|
+
// src/features/extract/infra/external-clients/create-configured-project.ts
|
|
30051
|
+
import { existsSync as existsSync6 } from "node:fs";
|
|
30052
|
+
import { resolve as resolve6 } from "node:path";
|
|
30053
|
+
import { Project as Project2 } from "ts-morph";
|
|
30165
30054
|
function createConfiguredProject(configDir, skipTsConfig) {
|
|
30166
30055
|
if (skipTsConfig) {
|
|
30167
|
-
return new
|
|
30056
|
+
return new Project2();
|
|
30168
30057
|
}
|
|
30169
|
-
const tsConfigPath =
|
|
30170
|
-
if (!
|
|
30171
|
-
return new
|
|
30058
|
+
const tsConfigPath = resolve6(configDir, "tsconfig.json");
|
|
30059
|
+
if (!existsSync6(tsConfigPath)) {
|
|
30060
|
+
return new Project2();
|
|
30172
30061
|
}
|
|
30173
|
-
return new
|
|
30062
|
+
return new Project2({
|
|
30174
30063
|
tsConfigFilePath: tsConfigPath,
|
|
30175
30064
|
skipAddingFilesFromTsConfig: true
|
|
30176
30065
|
});
|
|
30177
30066
|
}
|
|
30178
30067
|
|
|
30179
|
-
// src/features/extract/infra/load-extraction-project.ts
|
|
30068
|
+
// src/features/extract/infra/external-clients/load-extraction-project.ts
|
|
30180
30069
|
function loadExtractionProject(configDir, sourceFilePaths, skipTsConfig) {
|
|
30181
30070
|
const project = createConfiguredProject(configDir, skipTsConfig);
|
|
30182
30071
|
project.addSourceFilesAtPaths(sourceFilePaths);
|
|
30183
30072
|
return project;
|
|
30184
30073
|
}
|
|
30185
30074
|
|
|
30075
|
+
// src/features/extract/infra/external-clients/create-module-contexts.ts
|
|
30076
|
+
function createModuleContexts(resolvedConfig, configDir, sourceFilePaths, skipTsConfig) {
|
|
30077
|
+
const sourceFileSet = new Set(sourceFilePaths);
|
|
30078
|
+
return resolvedConfig.modules.map((module) => {
|
|
30079
|
+
const allModuleFiles = globSync2(posix4.join(module.path, module.glob), { cwd: configDir }).map(
|
|
30080
|
+
(f) => resolve7(configDir, f)
|
|
30081
|
+
);
|
|
30082
|
+
const moduleFiles = allModuleFiles.filter((f) => sourceFileSet.has(f));
|
|
30083
|
+
const tsConfigDir = findModuleTsConfigDir(configDir, module.path);
|
|
30084
|
+
const project = loadExtractionProject(tsConfigDir, moduleFiles, skipTsConfig);
|
|
30085
|
+
return {
|
|
30086
|
+
module,
|
|
30087
|
+
files: moduleFiles,
|
|
30088
|
+
project
|
|
30089
|
+
};
|
|
30090
|
+
});
|
|
30091
|
+
}
|
|
30092
|
+
|
|
30093
|
+
// src/features/extract/domain/extract-draft-components.ts
|
|
30094
|
+
function extractDraftComponents(moduleContexts, resolvedConfig, configDir) {
|
|
30095
|
+
return moduleContexts.flatMap(
|
|
30096
|
+
(ctx) => extractComponents(ctx.project, ctx.files, resolvedConfig, matchesGlob, configDir)
|
|
30097
|
+
);
|
|
30098
|
+
}
|
|
30099
|
+
|
|
30100
|
+
// src/features/extract/domain/enrich-per-module.ts
|
|
30101
|
+
var OrphanedDraftComponentError = class extends Error {
|
|
30102
|
+
constructor(orphanedModules, knownModules) {
|
|
30103
|
+
super(
|
|
30104
|
+
`Draft components reference unknown modules: [${orphanedModules.join(", ")}]. Known modules: [${knownModules.join(", ")}]`
|
|
30105
|
+
);
|
|
30106
|
+
this.name = "OrphanedDraftComponentError";
|
|
30107
|
+
}
|
|
30108
|
+
};
|
|
30109
|
+
function enrichPerModule(moduleContexts, draftComponents, resolvedConfig, configDir) {
|
|
30110
|
+
const moduleNames = new Set(moduleContexts.map((ctx) => ctx.module.name));
|
|
30111
|
+
const draftsByModule = groupDraftsByModule(draftComponents);
|
|
30112
|
+
assertAllDraftsMatchModules(draftsByModule, moduleNames);
|
|
30113
|
+
const components = [];
|
|
30114
|
+
const failedFieldSet = /* @__PURE__ */ new Set();
|
|
30115
|
+
for (const ctx of moduleContexts) {
|
|
30116
|
+
const moduleDrafts = draftsByModule.get(ctx.module.name) ?? [];
|
|
30117
|
+
if (moduleDrafts.length === 0) {
|
|
30118
|
+
continue;
|
|
30119
|
+
}
|
|
30120
|
+
const result = enrichComponents(
|
|
30121
|
+
moduleDrafts,
|
|
30122
|
+
resolvedConfig,
|
|
30123
|
+
ctx.project,
|
|
30124
|
+
matchesGlob,
|
|
30125
|
+
configDir
|
|
30126
|
+
);
|
|
30127
|
+
components.push(...result.components);
|
|
30128
|
+
for (const f of result.failures) {
|
|
30129
|
+
failedFieldSet.add(f.field);
|
|
30130
|
+
}
|
|
30131
|
+
}
|
|
30132
|
+
return {
|
|
30133
|
+
components,
|
|
30134
|
+
failedFields: [...failedFieldSet]
|
|
30135
|
+
};
|
|
30136
|
+
}
|
|
30137
|
+
function assertAllDraftsMatchModules(draftsByModule, moduleNames) {
|
|
30138
|
+
const orphanedModules = [...draftsByModule.keys()].filter((name) => !moduleNames.has(name));
|
|
30139
|
+
if (orphanedModules.length > 0) {
|
|
30140
|
+
throw new OrphanedDraftComponentError(orphanedModules, [...moduleNames]);
|
|
30141
|
+
}
|
|
30142
|
+
}
|
|
30143
|
+
function groupDraftsByModule(drafts) {
|
|
30144
|
+
const grouped = /* @__PURE__ */ new Map();
|
|
30145
|
+
for (const draft of drafts) {
|
|
30146
|
+
const existing = grouped.get(draft.domain);
|
|
30147
|
+
if (existing) {
|
|
30148
|
+
existing.push(draft);
|
|
30149
|
+
} else {
|
|
30150
|
+
grouped.set(draft.domain, [draft]);
|
|
30151
|
+
}
|
|
30152
|
+
}
|
|
30153
|
+
return grouped;
|
|
30154
|
+
}
|
|
30155
|
+
|
|
30156
|
+
// src/features/extract/domain/detect-connections-per-module.ts
|
|
30157
|
+
import { posix as posix5 } from "node:path";
|
|
30158
|
+
function detectConnectionsPerModule(moduleContexts, enrichedComponents, repositoryName, allowIncomplete) {
|
|
30159
|
+
const links = [];
|
|
30160
|
+
const timings = [];
|
|
30161
|
+
for (const ctx of moduleContexts) {
|
|
30162
|
+
const moduleComponents = enrichedComponents.filter((c) => c.domain === ctx.module.name);
|
|
30163
|
+
if (moduleComponents.length === 0) {
|
|
30164
|
+
continue;
|
|
30165
|
+
}
|
|
30166
|
+
const result = detectPerModuleConnections(
|
|
30167
|
+
ctx.project,
|
|
30168
|
+
moduleComponents,
|
|
30169
|
+
{
|
|
30170
|
+
allowIncomplete,
|
|
30171
|
+
moduleGlobs: [posix5.join(ctx.module.path, ctx.module.glob)],
|
|
30172
|
+
repository: repositoryName
|
|
30173
|
+
},
|
|
30174
|
+
matchesGlob
|
|
30175
|
+
);
|
|
30176
|
+
links.push(...result.links);
|
|
30177
|
+
timings.push({
|
|
30178
|
+
callGraphMs: result.timings.callGraphMs,
|
|
30179
|
+
asyncDetectionMs: 0,
|
|
30180
|
+
configurableMs: result.timings.configurableMs,
|
|
30181
|
+
setupMs: result.timings.setupMs,
|
|
30182
|
+
totalMs: result.timings.callGraphMs + result.timings.configurableMs + result.timings.setupMs
|
|
30183
|
+
});
|
|
30184
|
+
}
|
|
30185
|
+
const crossResult = detectCrossModuleConnections(enrichedComponents, {
|
|
30186
|
+
allowIncomplete,
|
|
30187
|
+
repository: repositoryName
|
|
30188
|
+
});
|
|
30189
|
+
links.push(...crossResult.links);
|
|
30190
|
+
timings.push({
|
|
30191
|
+
callGraphMs: 0,
|
|
30192
|
+
asyncDetectionMs: crossResult.timings.asyncDetectionMs,
|
|
30193
|
+
configurableMs: 0,
|
|
30194
|
+
setupMs: 0,
|
|
30195
|
+
totalMs: crossResult.timings.asyncDetectionMs
|
|
30196
|
+
});
|
|
30197
|
+
return {
|
|
30198
|
+
links: deduplicateCrossStrategy(links),
|
|
30199
|
+
timings
|
|
30200
|
+
};
|
|
30201
|
+
}
|
|
30202
|
+
|
|
30203
|
+
// src/features/extract/commands/run-extraction.ts
|
|
30204
|
+
function runExtraction(options, resolvedConfig, configDir, sourceFilePaths) {
|
|
30205
|
+
const skipTsConfig = options.tsConfig === false;
|
|
30206
|
+
const moduleContexts = createModuleContexts(
|
|
30207
|
+
resolvedConfig,
|
|
30208
|
+
configDir,
|
|
30209
|
+
sourceFilePaths,
|
|
30210
|
+
skipTsConfig
|
|
30211
|
+
);
|
|
30212
|
+
const draftComponents = options.enrich === void 0 ? extractDraftComponents(moduleContexts, resolvedConfig, configDir) : loadDraftComponentsFromFile(options.enrich);
|
|
30213
|
+
if (options.dryRun || options.format === "markdown" || options.componentsOnly) {
|
|
30214
|
+
return {
|
|
30215
|
+
kind: "draftOnly",
|
|
30216
|
+
components: draftComponents
|
|
30217
|
+
};
|
|
30218
|
+
}
|
|
30219
|
+
const allowIncomplete = options.allowIncomplete === true;
|
|
30220
|
+
const enrichment = enrichPerModule(moduleContexts, draftComponents, resolvedConfig, configDir);
|
|
30221
|
+
if (enrichment.failedFields.length > 0 && !allowIncomplete) {
|
|
30222
|
+
throw new ExtractionFieldFailureError(enrichment.failedFields);
|
|
30223
|
+
}
|
|
30224
|
+
const repositoryInfo = getRepositoryInfo();
|
|
30225
|
+
const connectionResult = detectConnectionsPerModule(
|
|
30226
|
+
moduleContexts,
|
|
30227
|
+
enrichment.components,
|
|
30228
|
+
repositoryInfo.name,
|
|
30229
|
+
allowIncomplete
|
|
30230
|
+
);
|
|
30231
|
+
return {
|
|
30232
|
+
kind: "full",
|
|
30233
|
+
components: enrichment.components,
|
|
30234
|
+
links: connectionResult.links,
|
|
30235
|
+
timings: connectionResult.timings,
|
|
30236
|
+
failedFields: enrichment.failedFields
|
|
30237
|
+
};
|
|
30238
|
+
}
|
|
30239
|
+
|
|
30240
|
+
// src/platform/infra/cli-presentation/format-pr-markdown.ts
|
|
30241
|
+
function formatComponentLine(component) {
|
|
30242
|
+
return `- **${component.type}** \`${component.name}\` in \`${component.domain}\` domain`;
|
|
30243
|
+
}
|
|
30244
|
+
function formatSection(title, components) {
|
|
30245
|
+
const header = `### ${title} (${components.length})`;
|
|
30246
|
+
if (components.length === 0) {
|
|
30247
|
+
return `${header}
|
|
30248
|
+
None`;
|
|
30249
|
+
}
|
|
30250
|
+
return `${header}
|
|
30251
|
+
${components.map(formatComponentLine).join("\n")}`;
|
|
30252
|
+
}
|
|
30253
|
+
function formatPrMarkdown(categorized) {
|
|
30254
|
+
const sections = [
|
|
30255
|
+
formatSection("Added Components", categorized.added),
|
|
30256
|
+
formatSection("Modified Components", categorized.modified),
|
|
30257
|
+
formatSection("Removed Components", categorized.removed)
|
|
30258
|
+
];
|
|
30259
|
+
return `## Architecture Changes
|
|
30260
|
+
|
|
30261
|
+
${sections.join("\n\n")}`;
|
|
30262
|
+
}
|
|
30263
|
+
|
|
30264
|
+
// src/platform/infra/cli-presentation/extract-output-formatter.ts
|
|
30265
|
+
function compareByCodePoint2(a, b) {
|
|
30266
|
+
if (a < b) return -1;
|
|
30267
|
+
if (a > b) return 1;
|
|
30268
|
+
return 0;
|
|
30269
|
+
}
|
|
30270
|
+
function formatDryRunOutput(components) {
|
|
30271
|
+
const countsByDomain = /* @__PURE__ */ new Map();
|
|
30272
|
+
for (const component of components) {
|
|
30273
|
+
const existingTypeCounts = countsByDomain.get(component.domain);
|
|
30274
|
+
const typeCounts = existingTypeCounts ?? /* @__PURE__ */ new Map();
|
|
30275
|
+
if (existingTypeCounts === void 0) {
|
|
30276
|
+
countsByDomain.set(component.domain, typeCounts);
|
|
30277
|
+
}
|
|
30278
|
+
const currentCount = typeCounts.get(component.type) ?? 0;
|
|
30279
|
+
typeCounts.set(component.type, currentCount + 1);
|
|
30280
|
+
}
|
|
30281
|
+
const sortedDomains = [...countsByDomain.entries()].sort(([a], [b]) => compareByCodePoint2(a, b));
|
|
30282
|
+
const lines = [];
|
|
30283
|
+
for (const [domain2, typeCounts] of sortedDomains) {
|
|
30284
|
+
const typeStrings = [...typeCounts.entries()].sort(([a], [b]) => compareByCodePoint2(a, b)).map(([type, count]) => `${type}(${count})`);
|
|
30285
|
+
lines.push(`${domain2}: ${typeStrings.join(", ")}`);
|
|
30286
|
+
}
|
|
30287
|
+
return lines;
|
|
30288
|
+
}
|
|
30289
|
+
|
|
30290
|
+
// src/platform/infra/cli-presentation/output-writer.ts
|
|
30291
|
+
import { writeFileSync } from "node:fs";
|
|
30292
|
+
function outputResult(data, options) {
|
|
30293
|
+
if (options.output !== void 0) {
|
|
30294
|
+
try {
|
|
30295
|
+
writeFileSync(options.output, JSON.stringify(data));
|
|
30296
|
+
} catch {
|
|
30297
|
+
console.log(
|
|
30298
|
+
JSON.stringify(
|
|
30299
|
+
formatError2(
|
|
30300
|
+
"VALIDATION_ERROR" /* ValidationError */,
|
|
30301
|
+
"Failed to write output file: " + options.output
|
|
30302
|
+
)
|
|
30303
|
+
)
|
|
30304
|
+
);
|
|
30305
|
+
process.exit(3 /* RuntimeError */);
|
|
30306
|
+
}
|
|
30307
|
+
return;
|
|
30308
|
+
}
|
|
30309
|
+
console.log(JSON.stringify(data));
|
|
30310
|
+
}
|
|
30311
|
+
|
|
30312
|
+
// src/platform/infra/cli-presentation/format-extraction-stats.ts
|
|
30313
|
+
function countLinksByType(componentCount, links) {
|
|
30314
|
+
const syncLinkCount = links.filter((l) => l.type === "sync").length;
|
|
30315
|
+
const asyncLinkCount = links.filter((l) => l.type === "async").length;
|
|
30316
|
+
const uncertainLinkCount = links.filter((l) => l._uncertain !== void 0).length;
|
|
30317
|
+
return {
|
|
30318
|
+
componentCount,
|
|
30319
|
+
linkCount: links.length,
|
|
30320
|
+
syncLinkCount,
|
|
30321
|
+
asyncLinkCount,
|
|
30322
|
+
uncertainLinkCount
|
|
30323
|
+
};
|
|
30324
|
+
}
|
|
30325
|
+
function formatSeconds(ms) {
|
|
30326
|
+
return (ms / 1e3).toFixed(2) + "s";
|
|
30327
|
+
}
|
|
30328
|
+
function formatExtractionStats(stats) {
|
|
30329
|
+
const lines = [`Components: ${stats.componentCount}`];
|
|
30330
|
+
if (stats.linkCount !== void 0) {
|
|
30331
|
+
lines.push(
|
|
30332
|
+
`Links: ${stats.linkCount} (sync: ${stats.syncLinkCount}, async: ${stats.asyncLinkCount})`
|
|
30333
|
+
);
|
|
30334
|
+
lines.push(`Uncertain: ${stats.uncertainLinkCount}`);
|
|
30335
|
+
}
|
|
30336
|
+
return lines;
|
|
30337
|
+
}
|
|
30338
|
+
function formatTimingLine(timings) {
|
|
30339
|
+
return `Extraction completed in ${formatSeconds(timings.totalMs)} (call graph: ${formatSeconds(timings.callGraphMs)}, detection: ${formatSeconds(timings.asyncDetectionMs)}, setup: ${formatSeconds(timings.setupMs)})`;
|
|
30340
|
+
}
|
|
30341
|
+
|
|
30186
30342
|
// src/platform/infra/cli-presentation/categorize-components.ts
|
|
30187
30343
|
function componentKey(component) {
|
|
30188
30344
|
return `${component.domain}:${component.type}:${component.name}`;
|
|
@@ -30213,61 +30369,50 @@ function categorizeComponents(current, baseline) {
|
|
|
30213
30369
|
};
|
|
30214
30370
|
}
|
|
30215
30371
|
|
|
30216
|
-
// src/features/extract/
|
|
30217
|
-
function
|
|
30218
|
-
|
|
30219
|
-
|
|
30220
|
-
|
|
30221
|
-
|
|
30222
|
-
|
|
30223
|
-
|
|
30224
|
-
|
|
30225
|
-
);
|
|
30372
|
+
// src/features/extract/infra/mappers/present-extraction-result.ts
|
|
30373
|
+
function presentExtractionResult(result, options) {
|
|
30374
|
+
if (result.kind === "draftOnly") {
|
|
30375
|
+
presentDraftResult(result.components, options);
|
|
30376
|
+
return;
|
|
30377
|
+
}
|
|
30378
|
+
presentFullResult(result, options);
|
|
30379
|
+
}
|
|
30380
|
+
function presentDraftResult(components, options) {
|
|
30226
30381
|
if (options.dryRun) {
|
|
30227
|
-
for (const line of formatDryRunOutput(
|
|
30382
|
+
for (const line of formatDryRunOutput(components)) {
|
|
30228
30383
|
console.log(line);
|
|
30229
30384
|
}
|
|
30230
30385
|
return;
|
|
30231
30386
|
}
|
|
30232
30387
|
if (options.format === "markdown") {
|
|
30233
|
-
const categorized = categorizeComponents(
|
|
30388
|
+
const categorized = categorizeComponents(components, void 0);
|
|
30234
30389
|
const markdown = formatPrMarkdown(categorized);
|
|
30235
30390
|
console.log(markdown);
|
|
30236
30391
|
return;
|
|
30237
30392
|
}
|
|
30238
|
-
|
|
30239
|
-
|
|
30240
|
-
|
|
30393
|
+
outputResult(formatSuccess(components), { output: options.output });
|
|
30394
|
+
}
|
|
30395
|
+
function presentFullResult(result, options) {
|
|
30396
|
+
if (result.failedFields.length > 0) {
|
|
30397
|
+
console.error(
|
|
30398
|
+
`Warning: Enrichment failed for ${result.failedFields.length} field(s): ${result.failedFields.join(", ")}`
|
|
30399
|
+
);
|
|
30241
30400
|
}
|
|
30242
|
-
const enrichmentResult = enrichComponentsSafe(
|
|
30243
|
-
draftComponents,
|
|
30244
|
-
resolvedConfig,
|
|
30245
|
-
project,
|
|
30246
|
-
configDir,
|
|
30247
|
-
options.allowIncomplete === true
|
|
30248
|
-
);
|
|
30249
|
-
const repositoryInfo = getRepositoryInfo();
|
|
30250
|
-
const { links } = detectConnectionsSafe(
|
|
30251
|
-
project,
|
|
30252
|
-
enrichmentResult.components,
|
|
30253
|
-
resolvedConfig.modules.map((m) => m.path),
|
|
30254
|
-
repositoryInfo.name,
|
|
30255
|
-
options.allowIncomplete === true,
|
|
30256
|
-
options.stats === true
|
|
30257
|
-
);
|
|
30258
30401
|
if (options.stats === true) {
|
|
30259
|
-
const
|
|
30402
|
+
for (const timing of result.timings) {
|
|
30403
|
+
console.error(formatTimingLine(timing));
|
|
30404
|
+
}
|
|
30405
|
+
const stats = countLinksByType(result.components.length, result.links);
|
|
30260
30406
|
for (const line of formatExtractionStats(stats)) {
|
|
30261
30407
|
console.error(line);
|
|
30262
30408
|
}
|
|
30263
30409
|
}
|
|
30264
|
-
const outputOptions = options.output === void 0 ? {} : { output: options.output };
|
|
30265
30410
|
outputResult(
|
|
30266
30411
|
formatSuccess({
|
|
30267
|
-
components:
|
|
30268
|
-
links
|
|
30412
|
+
components: result.components,
|
|
30413
|
+
links: result.links
|
|
30269
30414
|
}),
|
|
30270
|
-
|
|
30415
|
+
{ output: options.output }
|
|
30271
30416
|
);
|
|
30272
30417
|
}
|
|
30273
30418
|
|
|
@@ -30281,7 +30426,8 @@ function createExtractCommand() {
|
|
|
30281
30426
|
} = loadAndValidateConfig(options.config);
|
|
30282
30427
|
const allSourceFilePaths = resolveSourceFiles(resolvedConfig, configDir);
|
|
30283
30428
|
const sourceFilePaths = resolveFilteredSourceFiles(allSourceFilePaths, options);
|
|
30284
|
-
runExtraction(options, resolvedConfig, configDir, sourceFilePaths);
|
|
30429
|
+
const result = runExtraction(options, resolvedConfig, configDir, sourceFilePaths);
|
|
30430
|
+
presentExtractionResult(result, options);
|
|
30285
30431
|
});
|
|
30286
30432
|
}
|
|
30287
30433
|
|
|
@@ -30297,7 +30443,7 @@ function parsePackageJson(pkg) {
|
|
|
30297
30443
|
}
|
|
30298
30444
|
function loadPackageJson() {
|
|
30299
30445
|
if (true) {
|
|
30300
|
-
return { version: "0.8.
|
|
30446
|
+
return { version: "0.8.11" };
|
|
30301
30447
|
}
|
|
30302
30448
|
const require2 = createRequire2(import.meta.url);
|
|
30303
30449
|
return parsePackageJson(require2("../../package.json"));
|
|
@@ -30395,8 +30541,8 @@ program.parseAsync().catch(handleGlobalError);
|
|
|
30395
30541
|
/* v8 ignore next -- @preserve: error is always Error from yaml parser; defensive guard */
|
|
30396
30542
|
/* v8 ignore start -- @preserve: default executor delegates to execFileSync; tested via CLI integration */
|
|
30397
30543
|
/* v8 ignore start -- @preserve: detectChangedTypeScriptFiles only throws GitError; non-GitError path is unreachable */
|
|
30398
|
-
/* v8 ignore start -- @preserve: trivial comparator, Map keys guarantee a !== b */
|
|
30399
|
-
/* v8 ignore start -- @preserve: dry-run output formatting; tested via CLI integration */
|
|
30400
30544
|
/* v8 ignore start -- @preserve: git execution; mocked in all integration tests */
|
|
30401
30545
|
/* v8 ignore start -- @preserve: defensive check; regex ([^/]+) requires non-empty groups */
|
|
30546
|
+
/* v8 ignore start -- @preserve: trivial comparator, Map keys guarantee a !== b */
|
|
30547
|
+
/* v8 ignore start -- @preserve: dry-run output formatting; tested via CLI integration */
|
|
30402
30548
|
/* v8 ignore start -- @preserve: dry-run tested via CLI integration */
|