@emeryld/rrroutes-export 1.0.9 → 1.0.10
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/README.md +4 -0
- package/dist/exportFinalizedLeaves.changelog.d.ts +7 -1
- package/dist/index.cjs +120 -17
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +120 -17
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -72,11 +72,13 @@ Settings:
|
|
|
72
72
|
Behavior summary:
|
|
73
73
|
|
|
74
74
|
- Resolves commit path from `from..to` (chronological).
|
|
75
|
+
- Builds commit-aware module path candidates (current path + extension variants + rename history).
|
|
75
76
|
- Filters commits to those touching module tree/relevant config files.
|
|
76
77
|
- Ensures tip commit is always included.
|
|
77
78
|
- Creates a temp git worktree per selected commit.
|
|
78
79
|
- For TypeScript module entries, compiles the commit snapshot to JS and imports emitted output.
|
|
79
80
|
- For JavaScript module entries, imports directly from worktree.
|
|
81
|
+
- If module entrypoint cannot be resolved for a commit, changelog uses an empty snapshot for that commit (timeline continuity).
|
|
80
82
|
- Exports snapshots, then computes adjacent diffs:
|
|
81
83
|
- route events (`route_added`, `route_removed`, `schema_changed`, `cfg_changed`)
|
|
82
84
|
- source-object events (`source_object_added`, `source_object_removed`, `source_schema_changed`)
|
|
@@ -85,6 +87,7 @@ Runtime progress logs:
|
|
|
85
87
|
|
|
86
88
|
- `rrroutes-export-changelog` now prints step-by-step progress (window resolution, commit filtering, per-commit snapshot progress, diff totals, output writing, cleanup).
|
|
87
89
|
- Changelog logs include compile lifecycle details: selected tsconfig, cache hit/miss, emitted entry path.
|
|
90
|
+
- Changelog logs include per-commit module resolution and unresolved-entry fallback messages.
|
|
88
91
|
- Bundle script prints stage logs for snapshot export + changelog export.
|
|
89
92
|
|
|
90
93
|
Troubleshooting historical TS imports:
|
|
@@ -92,6 +95,7 @@ Troubleshooting historical TS imports:
|
|
|
92
95
|
- Changelog execution no longer relies on direct Node runtime loading of TS sources.
|
|
93
96
|
- Historical imports like `./x.js` pointing to `x.ts` are handled by snapshot compilation.
|
|
94
97
|
- If tsconfig auto-discovery fails, pass `--tsconfig`.
|
|
98
|
+
- If entrypoint path moved across history, changelog resolves rename history automatically.
|
|
95
99
|
|
|
96
100
|
## Recommended end-to-end script
|
|
97
101
|
|
|
@@ -32,6 +32,7 @@ type CommitSnapshot = {
|
|
|
32
32
|
commit: ChangelogCommit;
|
|
33
33
|
routesByKey: Record<string, RouteSnapshot>;
|
|
34
34
|
sourceObjectsById: Record<string, SourceObjectSnapshot>;
|
|
35
|
+
unresolvedModule?: boolean;
|
|
35
36
|
};
|
|
36
37
|
type DiffOp = 'added' | 'removed' | 'changed';
|
|
37
38
|
export type SchemaPathDelta = {
|
|
@@ -96,6 +97,7 @@ export type FinalizedLeavesChangelogExport = {
|
|
|
96
97
|
from: string;
|
|
97
98
|
to: string;
|
|
98
99
|
selectedCommitCount: number;
|
|
100
|
+
unresolvedModuleCommits?: string[];
|
|
99
101
|
};
|
|
100
102
|
commits: ChangelogCommit[];
|
|
101
103
|
byRoute: Record<string, RouteChangeEvent[]>;
|
|
@@ -123,7 +125,9 @@ declare function resolveCommitWindow(cwd: string, from?: string, to?: string): P
|
|
|
123
125
|
to: string;
|
|
124
126
|
}>;
|
|
125
127
|
declare function resolveCommitPath(cwd: string, fromCommit: string, toCommit: string): Promise<string[]>;
|
|
126
|
-
declare function
|
|
128
|
+
declare function buildModulePathCandidates(repoRoot: string, toCommit: string, requestedModuleRel: string): Promise<string[]>;
|
|
129
|
+
declare function resolveModulePathForCommit(repoRoot: string, commitSha: string, candidates: readonly string[]): Promise<string | undefined>;
|
|
130
|
+
declare function filterCommits(cwd: string, commits: string[], moduleCandidates: readonly string[], tsconfigRel?: string): Promise<string[]>;
|
|
127
131
|
declare function buildSourceIdentity(section: ChangelogSchemaSection, value: Record<string, unknown>): SourceIdentity;
|
|
128
132
|
declare function toRouteSnapshots(payload: FinalizedLeavesExport): Record<string, RouteSnapshot>;
|
|
129
133
|
declare function toSourceObjectSnapshots(routesByKey: Record<string, RouteSnapshot>): Record<string, SourceObjectSnapshot>;
|
|
@@ -160,6 +164,8 @@ export declare const __private: {
|
|
|
160
164
|
resolveCommitWindow: typeof resolveCommitWindow;
|
|
161
165
|
resolveCommitPath: typeof resolveCommitPath;
|
|
162
166
|
filterCommits: typeof filterCommits;
|
|
167
|
+
buildModulePathCandidates: typeof buildModulePathCandidates;
|
|
168
|
+
resolveModulePathForCommit: typeof resolveModulePathForCommit;
|
|
163
169
|
resolveSnapshotTsconfig: typeof resolveSnapshotTsconfig;
|
|
164
170
|
toEmittedModulePath: typeof toEmittedModulePath;
|
|
165
171
|
buildCompileCacheKey: typeof buildCompileCacheKey;
|
package/dist/index.cjs
CHANGED
|
@@ -1411,6 +1411,7 @@ var CHANGESET_CFG_FIELDS = [
|
|
|
1411
1411
|
"feed"
|
|
1412
1412
|
];
|
|
1413
1413
|
var SCHEMA_SECTIONS = ["params", "query", "body", "output"];
|
|
1414
|
+
var MODULE_EXTENSIONS = [".ts", ".tsx", ".mts", ".cts", ".js", ".mjs", ".cjs"];
|
|
1414
1415
|
var SOURCE_KEY_BY_SECTION = {
|
|
1415
1416
|
params: "paramsSchema",
|
|
1416
1417
|
query: "querySchema",
|
|
@@ -1525,6 +1526,65 @@ async function resolveCommitPath(cwd, fromCommit, toCommit) {
|
|
|
1525
1526
|
const commits = pathRaw.split("\n").map((item) => item.trim()).filter(Boolean);
|
|
1526
1527
|
return [fromCommit, ...commits];
|
|
1527
1528
|
}
|
|
1529
|
+
function modulePathStem(modulePath) {
|
|
1530
|
+
const normalized = normalizePath(modulePath).replace(/^\/+/, "");
|
|
1531
|
+
for (const ext of MODULE_EXTENSIONS) {
|
|
1532
|
+
if (normalized.endsWith(ext)) {
|
|
1533
|
+
return normalized.slice(0, -ext.length);
|
|
1534
|
+
}
|
|
1535
|
+
}
|
|
1536
|
+
return normalized;
|
|
1537
|
+
}
|
|
1538
|
+
function extensionVariants(pathLike) {
|
|
1539
|
+
const stem = modulePathStem(pathLike);
|
|
1540
|
+
return MODULE_EXTENSIONS.map((ext) => `${stem}${ext}`);
|
|
1541
|
+
}
|
|
1542
|
+
async function buildModulePathCandidates(repoRoot, toCommit, requestedModuleRel) {
|
|
1543
|
+
const requested = normalizePath(requestedModuleRel).replace(/^\/+/, "");
|
|
1544
|
+
const out = [];
|
|
1545
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1546
|
+
const pushCandidate = (value) => {
|
|
1547
|
+
const normalized = normalizePath(value).replace(/^\/+/, "");
|
|
1548
|
+
if (!normalized) return;
|
|
1549
|
+
if (seen.has(normalized)) return;
|
|
1550
|
+
seen.add(normalized);
|
|
1551
|
+
out.push(normalized);
|
|
1552
|
+
};
|
|
1553
|
+
pushCandidate(requested);
|
|
1554
|
+
extensionVariants(requested).forEach(pushCandidate);
|
|
1555
|
+
const history = await runGit(repoRoot, [
|
|
1556
|
+
"log",
|
|
1557
|
+
"--follow",
|
|
1558
|
+
"--name-only",
|
|
1559
|
+
"--format=",
|
|
1560
|
+
toCommit,
|
|
1561
|
+
"--",
|
|
1562
|
+
requested
|
|
1563
|
+
]);
|
|
1564
|
+
history.split("\n").map((item) => item.trim()).filter(Boolean).forEach((candidate) => {
|
|
1565
|
+
pushCandidate(candidate);
|
|
1566
|
+
extensionVariants(candidate).forEach(pushCandidate);
|
|
1567
|
+
});
|
|
1568
|
+
return out;
|
|
1569
|
+
}
|
|
1570
|
+
async function commitHasPath(repoRoot, commitSha, candidatePath) {
|
|
1571
|
+
try {
|
|
1572
|
+
await execFile("git", ["cat-file", "-e", `${commitSha}:${candidatePath}`], {
|
|
1573
|
+
cwd: repoRoot
|
|
1574
|
+
});
|
|
1575
|
+
return true;
|
|
1576
|
+
} catch {
|
|
1577
|
+
return false;
|
|
1578
|
+
}
|
|
1579
|
+
}
|
|
1580
|
+
async function resolveModulePathForCommit(repoRoot, commitSha, candidates) {
|
|
1581
|
+
for (const candidate of candidates) {
|
|
1582
|
+
if (await commitHasPath(repoRoot, commitSha, candidate)) {
|
|
1583
|
+
return candidate;
|
|
1584
|
+
}
|
|
1585
|
+
}
|
|
1586
|
+
return void 0;
|
|
1587
|
+
}
|
|
1528
1588
|
function parentDirectories(relativePath) {
|
|
1529
1589
|
const clean = normalizePath(relativePath).replace(/^\/+/, "");
|
|
1530
1590
|
const dir = import_node_path4.default.posix.dirname(clean);
|
|
@@ -1536,8 +1596,11 @@ function parentDirectories(relativePath) {
|
|
|
1536
1596
|
}
|
|
1537
1597
|
return out;
|
|
1538
1598
|
}
|
|
1539
|
-
function buildRelevantConfigFiles(
|
|
1540
|
-
const dirs = new Set(
|
|
1599
|
+
function buildRelevantConfigFiles(moduleCandidates, tsconfigRel) {
|
|
1600
|
+
const dirs = /* @__PURE__ */ new Set();
|
|
1601
|
+
for (const moduleRel of moduleCandidates) {
|
|
1602
|
+
parentDirectories(moduleRel).forEach((item) => dirs.add(item));
|
|
1603
|
+
}
|
|
1541
1604
|
if (tsconfigRel) {
|
|
1542
1605
|
parentDirectories(tsconfigRel).forEach((item) => dirs.add(item));
|
|
1543
1606
|
dirs.add(import_node_path4.default.posix.dirname(normalizePath(tsconfigRel)));
|
|
@@ -1550,7 +1613,7 @@ function buildRelevantConfigFiles(moduleRel, tsconfigRel) {
|
|
|
1550
1613
|
}
|
|
1551
1614
|
return files;
|
|
1552
1615
|
}
|
|
1553
|
-
async function commitTouchedRelevantPaths(cwd, commit,
|
|
1616
|
+
async function commitTouchedRelevantPaths(cwd, commit, moduleCandidates, tsconfigRel) {
|
|
1554
1617
|
const changed = await runGit(cwd, [
|
|
1555
1618
|
"show",
|
|
1556
1619
|
"--pretty=format:",
|
|
@@ -1559,27 +1622,35 @@ async function commitTouchedRelevantPaths(cwd, commit, moduleRel, tsconfigRel) {
|
|
|
1559
1622
|
commit
|
|
1560
1623
|
]);
|
|
1561
1624
|
const changedFiles = changed.split("\n").map((item) => normalizePath(item.trim()).replace(/^\/+/, "")).filter(Boolean);
|
|
1562
|
-
const
|
|
1563
|
-
|
|
1625
|
+
const moduleFiles = Array.from(
|
|
1626
|
+
new Set(moduleCandidates.map((item) => normalizePath(item).replace(/^\/+/, "")))
|
|
1627
|
+
);
|
|
1628
|
+
const moduleDirs = Array.from(
|
|
1629
|
+
new Set(
|
|
1630
|
+
moduleFiles.map((item) => normalizePath(import_node_path4.default.posix.dirname(item)).replace(/^\/+/, "")).filter((item) => item && item !== ".")
|
|
1631
|
+
)
|
|
1632
|
+
);
|
|
1564
1633
|
const tsconfigFile = tsconfigRel ? normalizePath(tsconfigRel).replace(/^\/+/, "") : void 0;
|
|
1565
|
-
const configFiles = buildRelevantConfigFiles(
|
|
1634
|
+
const configFiles = buildRelevantConfigFiles(moduleFiles, tsconfigFile);
|
|
1566
1635
|
return changedFiles.some((file) => {
|
|
1567
|
-
if (file
|
|
1568
|
-
|
|
1569
|
-
|
|
1636
|
+
if (moduleFiles.includes(file)) return true;
|
|
1637
|
+
for (const moduleDir of moduleDirs) {
|
|
1638
|
+
if (file === moduleDir || file.startsWith(`${moduleDir}/`)) {
|
|
1639
|
+
return true;
|
|
1640
|
+
}
|
|
1570
1641
|
}
|
|
1571
1642
|
if (tsconfigFile && file === tsconfigFile) return true;
|
|
1572
1643
|
return configFiles.has(file);
|
|
1573
1644
|
});
|
|
1574
1645
|
}
|
|
1575
|
-
async function filterCommits(cwd, commits,
|
|
1646
|
+
async function filterCommits(cwd, commits, moduleCandidates, tsconfigRel) {
|
|
1576
1647
|
if (commits.length <= 1) {
|
|
1577
1648
|
return commits;
|
|
1578
1649
|
}
|
|
1579
1650
|
const keep = [commits[0]];
|
|
1580
1651
|
for (let i = 1; i < commits.length; i += 1) {
|
|
1581
1652
|
const commit = commits[i];
|
|
1582
|
-
if (await commitTouchedRelevantPaths(cwd, commit,
|
|
1653
|
+
if (await commitTouchedRelevantPaths(cwd, commit, moduleCandidates, tsconfigRel)) {
|
|
1583
1654
|
keep.push(commit);
|
|
1584
1655
|
}
|
|
1585
1656
|
}
|
|
@@ -2045,12 +2116,31 @@ ${message}`
|
|
|
2045
2116
|
async function loadSnapshotExport(options) {
|
|
2046
2117
|
return loadChangelogInput(options.entryPath, options.exportName);
|
|
2047
2118
|
}
|
|
2048
|
-
async function createSnapshot(repoRoot,
|
|
2119
|
+
async function createSnapshot(repoRoot, moduleCandidates, exportName, commit, tempRoot, tsconfigRel, exportOptions, log) {
|
|
2049
2120
|
const worktreeDir = import_node_path4.default.join(tempRoot, `wt-${commit.sha.slice(0, 12)}`);
|
|
2050
2121
|
await runGit(repoRoot, ["worktree", "add", "--detach", worktreeDir, commit.sha]);
|
|
2051
2122
|
try {
|
|
2052
2123
|
await ensureWorktreeDependencies(repoRoot, worktreeDir);
|
|
2053
|
-
const
|
|
2124
|
+
const resolvedModuleRel = await resolveModulePathForCommit(
|
|
2125
|
+
repoRoot,
|
|
2126
|
+
commit.sha,
|
|
2127
|
+
moduleCandidates
|
|
2128
|
+
);
|
|
2129
|
+
if (!resolvedModuleRel) {
|
|
2130
|
+
log?.(
|
|
2131
|
+
`[changelog] unresolved module for commit ${commit.sha.slice(0, 12)}; using empty snapshot`
|
|
2132
|
+
);
|
|
2133
|
+
return {
|
|
2134
|
+
commit,
|
|
2135
|
+
routesByKey: {},
|
|
2136
|
+
sourceObjectsById: {},
|
|
2137
|
+
unresolvedModule: true
|
|
2138
|
+
};
|
|
2139
|
+
}
|
|
2140
|
+
log?.(
|
|
2141
|
+
`[changelog] resolved module for commit ${commit.sha.slice(0, 12)}: ${resolvedModuleRel}`
|
|
2142
|
+
);
|
|
2143
|
+
const modulePath = import_node_path4.default.resolve(worktreeDir, resolvedModuleRel);
|
|
2054
2144
|
let snapshotRuntimePath = modulePath;
|
|
2055
2145
|
let resolvedTsconfigPath;
|
|
2056
2146
|
if (isTypeScriptModule(modulePath)) {
|
|
@@ -2065,7 +2155,7 @@ async function createSnapshot(repoRoot, moduleRel, exportName, commit, tempRoot,
|
|
|
2065
2155
|
);
|
|
2066
2156
|
snapshotRuntimePath = await compileSnapshotEntry({
|
|
2067
2157
|
worktreeDir,
|
|
2068
|
-
moduleRel,
|
|
2158
|
+
moduleRel: resolvedModuleRel,
|
|
2069
2159
|
modulePath,
|
|
2070
2160
|
tsconfigPath: resolvedTsconfigPath,
|
|
2071
2161
|
commitSha: commit.sha,
|
|
@@ -2322,12 +2412,18 @@ async function exportFinalizedLeavesChangelog(options) {
|
|
|
2322
2412
|
log("[changelog] resolving commit window");
|
|
2323
2413
|
const window = await resolveCommitWindow(repoRoot, options.from, options.to);
|
|
2324
2414
|
log(`[changelog] window: ${window.from.slice(0, 12)}..${window.to.slice(0, 12)}`);
|
|
2415
|
+
const moduleCandidates = await buildModulePathCandidates(
|
|
2416
|
+
repoRoot,
|
|
2417
|
+
window.to,
|
|
2418
|
+
modulePathRelative
|
|
2419
|
+
);
|
|
2420
|
+
log(`[changelog] module candidates discovered: ${moduleCandidates.length}`);
|
|
2325
2421
|
const allCommits = await resolveCommitPath(repoRoot, window.from, window.to);
|
|
2326
2422
|
log(`[changelog] commits in ancestry path: ${allCommits.length}`);
|
|
2327
2423
|
const selectedCommitShas = await filterCommits(
|
|
2328
2424
|
repoRoot,
|
|
2329
2425
|
allCommits,
|
|
2330
|
-
|
|
2426
|
+
moduleCandidates,
|
|
2331
2427
|
tsconfigRelative
|
|
2332
2428
|
);
|
|
2333
2429
|
log(`[changelog] commits after path filter: ${selectedCommitShas.length}`);
|
|
@@ -2344,6 +2440,7 @@ async function exportFinalizedLeavesChangelog(options) {
|
|
|
2344
2440
|
log(`[changelog] temp workspace: ${tempRoot}`);
|
|
2345
2441
|
try {
|
|
2346
2442
|
const snapshots = [];
|
|
2443
|
+
const unresolvedModuleCommits = [];
|
|
2347
2444
|
for (let index = 0; index < commits.length; index += 1) {
|
|
2348
2445
|
const commit = commits[index];
|
|
2349
2446
|
log(
|
|
@@ -2352,7 +2449,7 @@ async function exportFinalizedLeavesChangelog(options) {
|
|
|
2352
2449
|
snapshots.push(
|
|
2353
2450
|
await createSnapshot(
|
|
2354
2451
|
repoRoot,
|
|
2355
|
-
|
|
2452
|
+
moduleCandidates,
|
|
2356
2453
|
exportName,
|
|
2357
2454
|
commit,
|
|
2358
2455
|
tempRoot,
|
|
@@ -2361,6 +2458,9 @@ async function exportFinalizedLeavesChangelog(options) {
|
|
|
2361
2458
|
log
|
|
2362
2459
|
)
|
|
2363
2460
|
);
|
|
2461
|
+
if (snapshots[snapshots.length - 1]?.unresolvedModule) {
|
|
2462
|
+
unresolvedModuleCommits.push(commit.sha);
|
|
2463
|
+
}
|
|
2364
2464
|
}
|
|
2365
2465
|
const routeEvents = [];
|
|
2366
2466
|
const sourceEvents = [];
|
|
@@ -2385,7 +2485,8 @@ async function exportFinalizedLeavesChangelog(options) {
|
|
|
2385
2485
|
exportName,
|
|
2386
2486
|
from: window.from,
|
|
2387
2487
|
to: window.to,
|
|
2388
|
-
selectedCommitCount: commits.length
|
|
2488
|
+
selectedCommitCount: commits.length,
|
|
2489
|
+
unresolvedModuleCommits: unresolvedModuleCommits.length > 0 ? unresolvedModuleCommits : void 0
|
|
2389
2490
|
},
|
|
2390
2491
|
commits,
|
|
2391
2492
|
byRoute: routeRecordByKey(routeEvents),
|
|
@@ -2412,6 +2513,8 @@ var __private = {
|
|
|
2412
2513
|
resolveCommitWindow,
|
|
2413
2514
|
resolveCommitPath,
|
|
2414
2515
|
filterCommits,
|
|
2516
|
+
buildModulePathCandidates,
|
|
2517
|
+
resolveModulePathForCommit,
|
|
2415
2518
|
resolveSnapshotTsconfig,
|
|
2416
2519
|
toEmittedModulePath,
|
|
2417
2520
|
buildCompileCacheKey,
|