@living-architecture/riviere-cli 0.8.10 → 0.8.11
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 +327 -203
- package/dist/index.js +326 -202
- 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,
|
|
@@ -29298,7 +29306,7 @@ import { posix as posix2 } from "node:path";
|
|
|
29298
29306
|
function findMatchingModule2(filePath, modules, globMatcher, configDir) {
|
|
29299
29307
|
const normalized = filePath.replaceAll(/\\+/g, "/");
|
|
29300
29308
|
const pathToMatch = posix2.relative(configDir.replaceAll(/\\+/g, "/"), normalized);
|
|
29301
|
-
return modules.find((m) => globMatcher(pathToMatch, m.path));
|
|
29309
|
+
return modules.find((m) => globMatcher(pathToMatch, posix2.join(m.path, m.glob)));
|
|
29302
29310
|
}
|
|
29303
29311
|
function getBuiltInRule(module, componentType) {
|
|
29304
29312
|
const ruleMap = {
|
|
@@ -29520,7 +29528,8 @@ var NOT_USED = { notUsed: true };
|
|
|
29520
29528
|
function topLevelRulesToModule(parsed) {
|
|
29521
29529
|
return {
|
|
29522
29530
|
name: "extended",
|
|
29523
|
-
path: "
|
|
29531
|
+
path: ".",
|
|
29532
|
+
glob: "**",
|
|
29524
29533
|
api: parsed.api ?? NOT_USED,
|
|
29525
29534
|
useCase: parsed.useCase ?? NOT_USED,
|
|
29526
29535
|
domainOp: parsed.domainOp ?? NOT_USED,
|
|
@@ -29640,9 +29649,9 @@ function tryExpandModuleRefs(data, configDir) {
|
|
|
29640
29649
|
}
|
|
29641
29650
|
}
|
|
29642
29651
|
function resolveSourceFiles(resolvedConfig, configDir) {
|
|
29643
|
-
const sourceFilePaths = resolvedConfig.modules.flatMap((module) => globSync(module.path, { cwd: configDir })).map((filePath) => resolve2(configDir, filePath));
|
|
29652
|
+
const sourceFilePaths = resolvedConfig.modules.flatMap((module) => globSync(posix3.join(module.path, module.glob), { cwd: configDir })).map((filePath) => resolve2(configDir, filePath));
|
|
29644
29653
|
if (sourceFilePaths.length === 0) {
|
|
29645
|
-
const patterns = resolvedConfig.modules.map((m) => m.path).join(", ");
|
|
29654
|
+
const patterns = resolvedConfig.modules.map((m) => posix3.join(m.path, m.glob)).join(", ");
|
|
29646
29655
|
throw new ConfigValidationError(
|
|
29647
29656
|
"VALIDATION_ERROR" /* ValidationError */,
|
|
29648
29657
|
`No files matched extraction patterns: ${patterns}
|
|
@@ -29897,111 +29906,6 @@ function validateFlagCombinations(options) {
|
|
|
29897
29906
|
validateFormatOption(options);
|
|
29898
29907
|
}
|
|
29899
29908
|
|
|
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
29909
|
// src/platform/infra/extraction-config/draft-component-loader.ts
|
|
30006
29910
|
import {
|
|
30007
29911
|
existsSync as existsSync4,
|
|
@@ -30040,43 +29944,6 @@ function loadDraftComponentsFromFile(filePath) {
|
|
|
30040
29944
|
return parsed;
|
|
30041
29945
|
}
|
|
30042
29946
|
|
|
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
29947
|
// src/platform/infra/git/git-repository-info.ts
|
|
30081
29948
|
import { execFileSync as execFileSync2 } from "node:child_process";
|
|
30082
29949
|
var RepositoryUrlParseError = class extends Error {
|
|
@@ -30158,31 +30025,298 @@ function getRepositoryInfo(gitBinary = "git", cwd = process.cwd(), executor = de
|
|
|
30158
30025
|
}
|
|
30159
30026
|
}
|
|
30160
30027
|
|
|
30161
|
-
// src/features/extract/infra/
|
|
30028
|
+
// src/features/extract/infra/external-clients/create-module-contexts.ts
|
|
30029
|
+
import {
|
|
30030
|
+
posix as posix4,
|
|
30031
|
+
resolve as resolve7
|
|
30032
|
+
} from "node:path";
|
|
30033
|
+
import { globSync as globSync2 } from "glob";
|
|
30034
|
+
|
|
30035
|
+
// src/features/extract/infra/external-clients/find-module-tsconfig-dir.ts
|
|
30162
30036
|
import { existsSync as existsSync5 } from "node:fs";
|
|
30163
30037
|
import { resolve as resolve5 } from "node:path";
|
|
30164
|
-
|
|
30038
|
+
function findModuleTsConfigDir(configDir, modulePath) {
|
|
30039
|
+
const moduleTsConfigPath = resolve5(configDir, modulePath, "tsconfig.json");
|
|
30040
|
+
if (existsSync5(moduleTsConfigPath)) {
|
|
30041
|
+
return resolve5(configDir, modulePath);
|
|
30042
|
+
}
|
|
30043
|
+
return configDir;
|
|
30044
|
+
}
|
|
30045
|
+
|
|
30046
|
+
// src/features/extract/infra/external-clients/create-configured-project.ts
|
|
30047
|
+
import { existsSync as existsSync6 } from "node:fs";
|
|
30048
|
+
import { resolve as resolve6 } from "node:path";
|
|
30049
|
+
import { Project as Project2 } from "ts-morph";
|
|
30165
30050
|
function createConfiguredProject(configDir, skipTsConfig) {
|
|
30166
30051
|
if (skipTsConfig) {
|
|
30167
|
-
return new
|
|
30052
|
+
return new Project2();
|
|
30168
30053
|
}
|
|
30169
|
-
const tsConfigPath =
|
|
30170
|
-
if (!
|
|
30171
|
-
return new
|
|
30054
|
+
const tsConfigPath = resolve6(configDir, "tsconfig.json");
|
|
30055
|
+
if (!existsSync6(tsConfigPath)) {
|
|
30056
|
+
return new Project2();
|
|
30172
30057
|
}
|
|
30173
|
-
return new
|
|
30058
|
+
return new Project2({
|
|
30174
30059
|
tsConfigFilePath: tsConfigPath,
|
|
30175
30060
|
skipAddingFilesFromTsConfig: true
|
|
30176
30061
|
});
|
|
30177
30062
|
}
|
|
30178
30063
|
|
|
30179
|
-
// src/features/extract/infra/load-extraction-project.ts
|
|
30064
|
+
// src/features/extract/infra/external-clients/load-extraction-project.ts
|
|
30180
30065
|
function loadExtractionProject(configDir, sourceFilePaths, skipTsConfig) {
|
|
30181
30066
|
const project = createConfiguredProject(configDir, skipTsConfig);
|
|
30182
30067
|
project.addSourceFilesAtPaths(sourceFilePaths);
|
|
30183
30068
|
return project;
|
|
30184
30069
|
}
|
|
30185
30070
|
|
|
30071
|
+
// src/features/extract/infra/external-clients/create-module-contexts.ts
|
|
30072
|
+
function createModuleContexts(resolvedConfig, configDir, sourceFilePaths, skipTsConfig) {
|
|
30073
|
+
const sourceFileSet = new Set(sourceFilePaths);
|
|
30074
|
+
return resolvedConfig.modules.map((module) => {
|
|
30075
|
+
const allModuleFiles = globSync2(posix4.join(module.path, module.glob), { cwd: configDir }).map(
|
|
30076
|
+
(f) => resolve7(configDir, f)
|
|
30077
|
+
);
|
|
30078
|
+
const moduleFiles = allModuleFiles.filter((f) => sourceFileSet.has(f));
|
|
30079
|
+
const tsConfigDir = findModuleTsConfigDir(configDir, module.path);
|
|
30080
|
+
const project = loadExtractionProject(tsConfigDir, moduleFiles, skipTsConfig);
|
|
30081
|
+
return {
|
|
30082
|
+
module,
|
|
30083
|
+
files: moduleFiles,
|
|
30084
|
+
project
|
|
30085
|
+
};
|
|
30086
|
+
});
|
|
30087
|
+
}
|
|
30088
|
+
|
|
30089
|
+
// src/features/extract/domain/extract-draft-components.ts
|
|
30090
|
+
function extractDraftComponents(moduleContexts, resolvedConfig, configDir) {
|
|
30091
|
+
return moduleContexts.flatMap(
|
|
30092
|
+
(ctx) => extractComponents(ctx.project, ctx.files, resolvedConfig, matchesGlob, configDir)
|
|
30093
|
+
);
|
|
30094
|
+
}
|
|
30095
|
+
|
|
30096
|
+
// src/features/extract/domain/enrich-per-module.ts
|
|
30097
|
+
var OrphanedDraftComponentError = class extends Error {
|
|
30098
|
+
constructor(orphanedModules, knownModules) {
|
|
30099
|
+
super(
|
|
30100
|
+
`Draft components reference unknown modules: [${orphanedModules.join(", ")}]. Known modules: [${knownModules.join(", ")}]`
|
|
30101
|
+
);
|
|
30102
|
+
this.name = "OrphanedDraftComponentError";
|
|
30103
|
+
}
|
|
30104
|
+
};
|
|
30105
|
+
function enrichPerModule(moduleContexts, draftComponents, resolvedConfig, configDir) {
|
|
30106
|
+
const moduleNames = new Set(moduleContexts.map((ctx) => ctx.module.name));
|
|
30107
|
+
const draftsByModule = groupDraftsByModule(draftComponents);
|
|
30108
|
+
assertAllDraftsMatchModules(draftsByModule, moduleNames);
|
|
30109
|
+
const components = [];
|
|
30110
|
+
const failedFieldSet = /* @__PURE__ */ new Set();
|
|
30111
|
+
for (const ctx of moduleContexts) {
|
|
30112
|
+
const moduleDrafts = draftsByModule.get(ctx.module.name) ?? [];
|
|
30113
|
+
if (moduleDrafts.length === 0) {
|
|
30114
|
+
continue;
|
|
30115
|
+
}
|
|
30116
|
+
const result = enrichComponents(
|
|
30117
|
+
moduleDrafts,
|
|
30118
|
+
resolvedConfig,
|
|
30119
|
+
ctx.project,
|
|
30120
|
+
matchesGlob,
|
|
30121
|
+
configDir
|
|
30122
|
+
);
|
|
30123
|
+
components.push(...result.components);
|
|
30124
|
+
for (const f of result.failures) {
|
|
30125
|
+
failedFieldSet.add(f.field);
|
|
30126
|
+
}
|
|
30127
|
+
}
|
|
30128
|
+
return {
|
|
30129
|
+
components,
|
|
30130
|
+
failedFields: [...failedFieldSet]
|
|
30131
|
+
};
|
|
30132
|
+
}
|
|
30133
|
+
function assertAllDraftsMatchModules(draftsByModule, moduleNames) {
|
|
30134
|
+
const orphanedModules = [...draftsByModule.keys()].filter((name) => !moduleNames.has(name));
|
|
30135
|
+
if (orphanedModules.length > 0) {
|
|
30136
|
+
throw new OrphanedDraftComponentError(orphanedModules, [...moduleNames]);
|
|
30137
|
+
}
|
|
30138
|
+
}
|
|
30139
|
+
function groupDraftsByModule(drafts) {
|
|
30140
|
+
const grouped = /* @__PURE__ */ new Map();
|
|
30141
|
+
for (const draft of drafts) {
|
|
30142
|
+
const existing = grouped.get(draft.domain);
|
|
30143
|
+
if (existing) {
|
|
30144
|
+
existing.push(draft);
|
|
30145
|
+
} else {
|
|
30146
|
+
grouped.set(draft.domain, [draft]);
|
|
30147
|
+
}
|
|
30148
|
+
}
|
|
30149
|
+
return grouped;
|
|
30150
|
+
}
|
|
30151
|
+
|
|
30152
|
+
// src/features/extract/domain/detect-connections-per-module.ts
|
|
30153
|
+
import { posix as posix5 } from "node:path";
|
|
30154
|
+
function detectConnectionsPerModule(moduleContexts, enrichedComponents, repositoryName, allowIncomplete) {
|
|
30155
|
+
const links = [];
|
|
30156
|
+
const timings = [];
|
|
30157
|
+
for (const ctx of moduleContexts) {
|
|
30158
|
+
const moduleComponents = enrichedComponents.filter((c) => c.domain === ctx.module.name);
|
|
30159
|
+
if (moduleComponents.length === 0) {
|
|
30160
|
+
continue;
|
|
30161
|
+
}
|
|
30162
|
+
const result = detectConnections(
|
|
30163
|
+
ctx.project,
|
|
30164
|
+
moduleComponents,
|
|
30165
|
+
{
|
|
30166
|
+
allowIncomplete,
|
|
30167
|
+
moduleGlobs: [posix5.join(ctx.module.path, ctx.module.glob)],
|
|
30168
|
+
repository: repositoryName
|
|
30169
|
+
},
|
|
30170
|
+
matchesGlob
|
|
30171
|
+
);
|
|
30172
|
+
links.push(...result.links);
|
|
30173
|
+
timings.push(result.timings);
|
|
30174
|
+
}
|
|
30175
|
+
return {
|
|
30176
|
+
links,
|
|
30177
|
+
timings
|
|
30178
|
+
};
|
|
30179
|
+
}
|
|
30180
|
+
|
|
30181
|
+
// src/features/extract/commands/run-extraction.ts
|
|
30182
|
+
function runExtraction(options, resolvedConfig, configDir, sourceFilePaths) {
|
|
30183
|
+
const skipTsConfig = options.tsConfig === false;
|
|
30184
|
+
const moduleContexts = createModuleContexts(
|
|
30185
|
+
resolvedConfig,
|
|
30186
|
+
configDir,
|
|
30187
|
+
sourceFilePaths,
|
|
30188
|
+
skipTsConfig
|
|
30189
|
+
);
|
|
30190
|
+
const draftComponents = options.enrich === void 0 ? extractDraftComponents(moduleContexts, resolvedConfig, configDir) : loadDraftComponentsFromFile(options.enrich);
|
|
30191
|
+
if (options.dryRun || options.format === "markdown" || options.componentsOnly) {
|
|
30192
|
+
return {
|
|
30193
|
+
kind: "draftOnly",
|
|
30194
|
+
components: draftComponents
|
|
30195
|
+
};
|
|
30196
|
+
}
|
|
30197
|
+
const allowIncomplete = options.allowIncomplete === true;
|
|
30198
|
+
const enrichment = enrichPerModule(moduleContexts, draftComponents, resolvedConfig, configDir);
|
|
30199
|
+
if (enrichment.failedFields.length > 0 && !allowIncomplete) {
|
|
30200
|
+
throw new ExtractionFieldFailureError(enrichment.failedFields);
|
|
30201
|
+
}
|
|
30202
|
+
const repositoryInfo = getRepositoryInfo();
|
|
30203
|
+
const connectionResult = detectConnectionsPerModule(
|
|
30204
|
+
moduleContexts,
|
|
30205
|
+
enrichment.components,
|
|
30206
|
+
repositoryInfo.name,
|
|
30207
|
+
allowIncomplete
|
|
30208
|
+
);
|
|
30209
|
+
return {
|
|
30210
|
+
kind: "full",
|
|
30211
|
+
components: enrichment.components,
|
|
30212
|
+
links: connectionResult.links,
|
|
30213
|
+
timings: connectionResult.timings,
|
|
30214
|
+
failedFields: enrichment.failedFields
|
|
30215
|
+
};
|
|
30216
|
+
}
|
|
30217
|
+
|
|
30218
|
+
// src/platform/infra/cli-presentation/format-pr-markdown.ts
|
|
30219
|
+
function formatComponentLine(component) {
|
|
30220
|
+
return `- **${component.type}** \`${component.name}\` in \`${component.domain}\` domain`;
|
|
30221
|
+
}
|
|
30222
|
+
function formatSection(title, components) {
|
|
30223
|
+
const header = `### ${title} (${components.length})`;
|
|
30224
|
+
if (components.length === 0) {
|
|
30225
|
+
return `${header}
|
|
30226
|
+
None`;
|
|
30227
|
+
}
|
|
30228
|
+
return `${header}
|
|
30229
|
+
${components.map(formatComponentLine).join("\n")}`;
|
|
30230
|
+
}
|
|
30231
|
+
function formatPrMarkdown(categorized) {
|
|
30232
|
+
const sections = [
|
|
30233
|
+
formatSection("Added Components", categorized.added),
|
|
30234
|
+
formatSection("Modified Components", categorized.modified),
|
|
30235
|
+
formatSection("Removed Components", categorized.removed)
|
|
30236
|
+
];
|
|
30237
|
+
return `## Architecture Changes
|
|
30238
|
+
|
|
30239
|
+
${sections.join("\n\n")}`;
|
|
30240
|
+
}
|
|
30241
|
+
|
|
30242
|
+
// src/platform/infra/cli-presentation/extract-output-formatter.ts
|
|
30243
|
+
function compareByCodePoint2(a, b) {
|
|
30244
|
+
if (a < b) return -1;
|
|
30245
|
+
if (a > b) return 1;
|
|
30246
|
+
return 0;
|
|
30247
|
+
}
|
|
30248
|
+
function formatDryRunOutput(components) {
|
|
30249
|
+
const countsByDomain = /* @__PURE__ */ new Map();
|
|
30250
|
+
for (const component of components) {
|
|
30251
|
+
const existingTypeCounts = countsByDomain.get(component.domain);
|
|
30252
|
+
const typeCounts = existingTypeCounts ?? /* @__PURE__ */ new Map();
|
|
30253
|
+
if (existingTypeCounts === void 0) {
|
|
30254
|
+
countsByDomain.set(component.domain, typeCounts);
|
|
30255
|
+
}
|
|
30256
|
+
const currentCount = typeCounts.get(component.type) ?? 0;
|
|
30257
|
+
typeCounts.set(component.type, currentCount + 1);
|
|
30258
|
+
}
|
|
30259
|
+
const sortedDomains = [...countsByDomain.entries()].sort(([a], [b]) => compareByCodePoint2(a, b));
|
|
30260
|
+
const lines = [];
|
|
30261
|
+
for (const [domain2, typeCounts] of sortedDomains) {
|
|
30262
|
+
const typeStrings = [...typeCounts.entries()].sort(([a], [b]) => compareByCodePoint2(a, b)).map(([type, count]) => `${type}(${count})`);
|
|
30263
|
+
lines.push(`${domain2}: ${typeStrings.join(", ")}`);
|
|
30264
|
+
}
|
|
30265
|
+
return lines;
|
|
30266
|
+
}
|
|
30267
|
+
|
|
30268
|
+
// src/platform/infra/cli-presentation/output-writer.ts
|
|
30269
|
+
import { writeFileSync } from "node:fs";
|
|
30270
|
+
function outputResult(data, options) {
|
|
30271
|
+
if (options.output !== void 0) {
|
|
30272
|
+
try {
|
|
30273
|
+
writeFileSync(options.output, JSON.stringify(data));
|
|
30274
|
+
} catch {
|
|
30275
|
+
console.log(
|
|
30276
|
+
JSON.stringify(
|
|
30277
|
+
formatError2(
|
|
30278
|
+
"VALIDATION_ERROR" /* ValidationError */,
|
|
30279
|
+
"Failed to write output file: " + options.output
|
|
30280
|
+
)
|
|
30281
|
+
)
|
|
30282
|
+
);
|
|
30283
|
+
process.exit(3 /* RuntimeError */);
|
|
30284
|
+
}
|
|
30285
|
+
return;
|
|
30286
|
+
}
|
|
30287
|
+
console.log(JSON.stringify(data));
|
|
30288
|
+
}
|
|
30289
|
+
|
|
30290
|
+
// src/platform/infra/cli-presentation/format-extraction-stats.ts
|
|
30291
|
+
function countLinksByType(componentCount, links) {
|
|
30292
|
+
const syncLinkCount = links.filter((l) => l.type === "sync").length;
|
|
30293
|
+
const asyncLinkCount = links.filter((l) => l.type === "async").length;
|
|
30294
|
+
const uncertainLinkCount = links.filter((l) => l._uncertain !== void 0).length;
|
|
30295
|
+
return {
|
|
30296
|
+
componentCount,
|
|
30297
|
+
linkCount: links.length,
|
|
30298
|
+
syncLinkCount,
|
|
30299
|
+
asyncLinkCount,
|
|
30300
|
+
uncertainLinkCount
|
|
30301
|
+
};
|
|
30302
|
+
}
|
|
30303
|
+
function formatSeconds(ms) {
|
|
30304
|
+
return (ms / 1e3).toFixed(2) + "s";
|
|
30305
|
+
}
|
|
30306
|
+
function formatExtractionStats(stats) {
|
|
30307
|
+
const lines = [`Components: ${stats.componentCount}`];
|
|
30308
|
+
if (stats.linkCount !== void 0) {
|
|
30309
|
+
lines.push(
|
|
30310
|
+
`Links: ${stats.linkCount} (sync: ${stats.syncLinkCount}, async: ${stats.asyncLinkCount})`
|
|
30311
|
+
);
|
|
30312
|
+
lines.push(`Uncertain: ${stats.uncertainLinkCount}`);
|
|
30313
|
+
}
|
|
30314
|
+
return lines;
|
|
30315
|
+
}
|
|
30316
|
+
function formatTimingLine(timings) {
|
|
30317
|
+
return `Extraction completed in ${formatSeconds(timings.totalMs)} (call graph: ${formatSeconds(timings.callGraphMs)}, detection: ${formatSeconds(timings.asyncDetectionMs)}, setup: ${formatSeconds(timings.setupMs)})`;
|
|
30318
|
+
}
|
|
30319
|
+
|
|
30186
30320
|
// src/platform/infra/cli-presentation/categorize-components.ts
|
|
30187
30321
|
function componentKey(component) {
|
|
30188
30322
|
return `${component.domain}:${component.type}:${component.name}`;
|
|
@@ -30213,61 +30347,50 @@ function categorizeComponents(current, baseline) {
|
|
|
30213
30347
|
};
|
|
30214
30348
|
}
|
|
30215
30349
|
|
|
30216
|
-
// src/features/extract/
|
|
30217
|
-
function
|
|
30218
|
-
|
|
30219
|
-
|
|
30220
|
-
|
|
30221
|
-
|
|
30222
|
-
|
|
30223
|
-
|
|
30224
|
-
|
|
30225
|
-
);
|
|
30350
|
+
// src/features/extract/infra/mappers/present-extraction-result.ts
|
|
30351
|
+
function presentExtractionResult(result, options) {
|
|
30352
|
+
if (result.kind === "draftOnly") {
|
|
30353
|
+
presentDraftResult(result.components, options);
|
|
30354
|
+
return;
|
|
30355
|
+
}
|
|
30356
|
+
presentFullResult(result, options);
|
|
30357
|
+
}
|
|
30358
|
+
function presentDraftResult(components, options) {
|
|
30226
30359
|
if (options.dryRun) {
|
|
30227
|
-
for (const line of formatDryRunOutput(
|
|
30360
|
+
for (const line of formatDryRunOutput(components)) {
|
|
30228
30361
|
console.log(line);
|
|
30229
30362
|
}
|
|
30230
30363
|
return;
|
|
30231
30364
|
}
|
|
30232
30365
|
if (options.format === "markdown") {
|
|
30233
|
-
const categorized = categorizeComponents(
|
|
30366
|
+
const categorized = categorizeComponents(components, void 0);
|
|
30234
30367
|
const markdown = formatPrMarkdown(categorized);
|
|
30235
30368
|
console.log(markdown);
|
|
30236
30369
|
return;
|
|
30237
30370
|
}
|
|
30238
|
-
|
|
30239
|
-
|
|
30240
|
-
|
|
30371
|
+
outputResult(formatSuccess(components), { output: options.output });
|
|
30372
|
+
}
|
|
30373
|
+
function presentFullResult(result, options) {
|
|
30374
|
+
if (result.failedFields.length > 0) {
|
|
30375
|
+
console.error(
|
|
30376
|
+
`Warning: Enrichment failed for ${result.failedFields.length} field(s): ${result.failedFields.join(", ")}`
|
|
30377
|
+
);
|
|
30241
30378
|
}
|
|
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
30379
|
if (options.stats === true) {
|
|
30259
|
-
const
|
|
30380
|
+
for (const timing of result.timings) {
|
|
30381
|
+
console.error(formatTimingLine(timing));
|
|
30382
|
+
}
|
|
30383
|
+
const stats = countLinksByType(result.components.length, result.links);
|
|
30260
30384
|
for (const line of formatExtractionStats(stats)) {
|
|
30261
30385
|
console.error(line);
|
|
30262
30386
|
}
|
|
30263
30387
|
}
|
|
30264
|
-
const outputOptions = options.output === void 0 ? {} : { output: options.output };
|
|
30265
30388
|
outputResult(
|
|
30266
30389
|
formatSuccess({
|
|
30267
|
-
components:
|
|
30268
|
-
links
|
|
30390
|
+
components: result.components,
|
|
30391
|
+
links: result.links
|
|
30269
30392
|
}),
|
|
30270
|
-
|
|
30393
|
+
{ output: options.output }
|
|
30271
30394
|
);
|
|
30272
30395
|
}
|
|
30273
30396
|
|
|
@@ -30281,7 +30404,8 @@ function createExtractCommand() {
|
|
|
30281
30404
|
} = loadAndValidateConfig(options.config);
|
|
30282
30405
|
const allSourceFilePaths = resolveSourceFiles(resolvedConfig, configDir);
|
|
30283
30406
|
const sourceFilePaths = resolveFilteredSourceFiles(allSourceFilePaths, options);
|
|
30284
|
-
runExtraction(options, resolvedConfig, configDir, sourceFilePaths);
|
|
30407
|
+
const result = runExtraction(options, resolvedConfig, configDir, sourceFilePaths);
|
|
30408
|
+
presentExtractionResult(result, options);
|
|
30285
30409
|
});
|
|
30286
30410
|
}
|
|
30287
30411
|
|
|
@@ -30297,7 +30421,7 @@ function parsePackageJson(pkg) {
|
|
|
30297
30421
|
}
|
|
30298
30422
|
function loadPackageJson() {
|
|
30299
30423
|
if (true) {
|
|
30300
|
-
return { version: "0.8.
|
|
30424
|
+
return { version: "0.8.10" };
|
|
30301
30425
|
}
|
|
30302
30426
|
const require2 = createRequire2(import.meta.url);
|
|
30303
30427
|
return parsePackageJson(require2("../../package.json"));
|
|
@@ -30395,8 +30519,8 @@ program.parseAsync().catch(handleGlobalError);
|
|
|
30395
30519
|
/* v8 ignore next -- @preserve: error is always Error from yaml parser; defensive guard */
|
|
30396
30520
|
/* v8 ignore start -- @preserve: default executor delegates to execFileSync; tested via CLI integration */
|
|
30397
30521
|
/* 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
30522
|
/* v8 ignore start -- @preserve: git execution; mocked in all integration tests */
|
|
30401
30523
|
/* v8 ignore start -- @preserve: defensive check; regex ([^/]+) requires non-empty groups */
|
|
30524
|
+
/* v8 ignore start -- @preserve: trivial comparator, Map keys guarantee a !== b */
|
|
30525
|
+
/* v8 ignore start -- @preserve: dry-run output formatting; tested via CLI integration */
|
|
30402
30526
|
/* v8 ignore start -- @preserve: dry-run tested via CLI integration */
|