@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/dist/index.mjs CHANGED
@@ -1357,6 +1357,7 @@ var CHANGESET_CFG_FIELDS = [
1357
1357
  "feed"
1358
1358
  ];
1359
1359
  var SCHEMA_SECTIONS = ["params", "query", "body", "output"];
1360
+ var MODULE_EXTENSIONS = [".ts", ".tsx", ".mts", ".cts", ".js", ".mjs", ".cjs"];
1360
1361
  var SOURCE_KEY_BY_SECTION = {
1361
1362
  params: "paramsSchema",
1362
1363
  query: "querySchema",
@@ -1471,6 +1472,65 @@ async function resolveCommitPath(cwd, fromCommit, toCommit) {
1471
1472
  const commits = pathRaw.split("\n").map((item) => item.trim()).filter(Boolean);
1472
1473
  return [fromCommit, ...commits];
1473
1474
  }
1475
+ function modulePathStem(modulePath) {
1476
+ const normalized = normalizePath(modulePath).replace(/^\/+/, "");
1477
+ for (const ext of MODULE_EXTENSIONS) {
1478
+ if (normalized.endsWith(ext)) {
1479
+ return normalized.slice(0, -ext.length);
1480
+ }
1481
+ }
1482
+ return normalized;
1483
+ }
1484
+ function extensionVariants(pathLike) {
1485
+ const stem = modulePathStem(pathLike);
1486
+ return MODULE_EXTENSIONS.map((ext) => `${stem}${ext}`);
1487
+ }
1488
+ async function buildModulePathCandidates(repoRoot, toCommit, requestedModuleRel) {
1489
+ const requested = normalizePath(requestedModuleRel).replace(/^\/+/, "");
1490
+ const out = [];
1491
+ const seen = /* @__PURE__ */ new Set();
1492
+ const pushCandidate = (value) => {
1493
+ const normalized = normalizePath(value).replace(/^\/+/, "");
1494
+ if (!normalized) return;
1495
+ if (seen.has(normalized)) return;
1496
+ seen.add(normalized);
1497
+ out.push(normalized);
1498
+ };
1499
+ pushCandidate(requested);
1500
+ extensionVariants(requested).forEach(pushCandidate);
1501
+ const history = await runGit(repoRoot, [
1502
+ "log",
1503
+ "--follow",
1504
+ "--name-only",
1505
+ "--format=",
1506
+ toCommit,
1507
+ "--",
1508
+ requested
1509
+ ]);
1510
+ history.split("\n").map((item) => item.trim()).filter(Boolean).forEach((candidate) => {
1511
+ pushCandidate(candidate);
1512
+ extensionVariants(candidate).forEach(pushCandidate);
1513
+ });
1514
+ return out;
1515
+ }
1516
+ async function commitHasPath(repoRoot, commitSha, candidatePath) {
1517
+ try {
1518
+ await execFile("git", ["cat-file", "-e", `${commitSha}:${candidatePath}`], {
1519
+ cwd: repoRoot
1520
+ });
1521
+ return true;
1522
+ } catch {
1523
+ return false;
1524
+ }
1525
+ }
1526
+ async function resolveModulePathForCommit(repoRoot, commitSha, candidates) {
1527
+ for (const candidate of candidates) {
1528
+ if (await commitHasPath(repoRoot, commitSha, candidate)) {
1529
+ return candidate;
1530
+ }
1531
+ }
1532
+ return void 0;
1533
+ }
1474
1534
  function parentDirectories(relativePath) {
1475
1535
  const clean = normalizePath(relativePath).replace(/^\/+/, "");
1476
1536
  const dir = path4.posix.dirname(clean);
@@ -1482,8 +1542,11 @@ function parentDirectories(relativePath) {
1482
1542
  }
1483
1543
  return out;
1484
1544
  }
1485
- function buildRelevantConfigFiles(moduleRel, tsconfigRel) {
1486
- const dirs = new Set(parentDirectories(moduleRel));
1545
+ function buildRelevantConfigFiles(moduleCandidates, tsconfigRel) {
1546
+ const dirs = /* @__PURE__ */ new Set();
1547
+ for (const moduleRel of moduleCandidates) {
1548
+ parentDirectories(moduleRel).forEach((item) => dirs.add(item));
1549
+ }
1487
1550
  if (tsconfigRel) {
1488
1551
  parentDirectories(tsconfigRel).forEach((item) => dirs.add(item));
1489
1552
  dirs.add(path4.posix.dirname(normalizePath(tsconfigRel)));
@@ -1496,7 +1559,7 @@ function buildRelevantConfigFiles(moduleRel, tsconfigRel) {
1496
1559
  }
1497
1560
  return files;
1498
1561
  }
1499
- async function commitTouchedRelevantPaths(cwd, commit, moduleRel, tsconfigRel) {
1562
+ async function commitTouchedRelevantPaths(cwd, commit, moduleCandidates, tsconfigRel) {
1500
1563
  const changed = await runGit(cwd, [
1501
1564
  "show",
1502
1565
  "--pretty=format:",
@@ -1505,27 +1568,35 @@ async function commitTouchedRelevantPaths(cwd, commit, moduleRel, tsconfigRel) {
1505
1568
  commit
1506
1569
  ]);
1507
1570
  const changedFiles = changed.split("\n").map((item) => normalizePath(item.trim()).replace(/^\/+/, "")).filter(Boolean);
1508
- const moduleFile = normalizePath(moduleRel).replace(/^\/+/, "");
1509
- const moduleDir = normalizePath(path4.posix.dirname(moduleFile)).replace(/^\/+/, "");
1571
+ const moduleFiles = Array.from(
1572
+ new Set(moduleCandidates.map((item) => normalizePath(item).replace(/^\/+/, "")))
1573
+ );
1574
+ const moduleDirs = Array.from(
1575
+ new Set(
1576
+ moduleFiles.map((item) => normalizePath(path4.posix.dirname(item)).replace(/^\/+/, "")).filter((item) => item && item !== ".")
1577
+ )
1578
+ );
1510
1579
  const tsconfigFile = tsconfigRel ? normalizePath(tsconfigRel).replace(/^\/+/, "") : void 0;
1511
- const configFiles = buildRelevantConfigFiles(moduleFile, tsconfigFile);
1580
+ const configFiles = buildRelevantConfigFiles(moduleFiles, tsconfigFile);
1512
1581
  return changedFiles.some((file) => {
1513
- if (file === moduleFile) return true;
1514
- if (moduleDir && moduleDir !== "." && (file === moduleDir || file.startsWith(`${moduleDir}/`))) {
1515
- return true;
1582
+ if (moduleFiles.includes(file)) return true;
1583
+ for (const moduleDir of moduleDirs) {
1584
+ if (file === moduleDir || file.startsWith(`${moduleDir}/`)) {
1585
+ return true;
1586
+ }
1516
1587
  }
1517
1588
  if (tsconfigFile && file === tsconfigFile) return true;
1518
1589
  return configFiles.has(file);
1519
1590
  });
1520
1591
  }
1521
- async function filterCommits(cwd, commits, moduleRel, tsconfigRel) {
1592
+ async function filterCommits(cwd, commits, moduleCandidates, tsconfigRel) {
1522
1593
  if (commits.length <= 1) {
1523
1594
  return commits;
1524
1595
  }
1525
1596
  const keep = [commits[0]];
1526
1597
  for (let i = 1; i < commits.length; i += 1) {
1527
1598
  const commit = commits[i];
1528
- if (await commitTouchedRelevantPaths(cwd, commit, moduleRel, tsconfigRel)) {
1599
+ if (await commitTouchedRelevantPaths(cwd, commit, moduleCandidates, tsconfigRel)) {
1529
1600
  keep.push(commit);
1530
1601
  }
1531
1602
  }
@@ -1991,12 +2062,31 @@ ${message}`
1991
2062
  async function loadSnapshotExport(options) {
1992
2063
  return loadChangelogInput(options.entryPath, options.exportName);
1993
2064
  }
1994
- async function createSnapshot(repoRoot, moduleRel, exportName, commit, tempRoot, tsconfigRel, exportOptions, log) {
2065
+ async function createSnapshot(repoRoot, moduleCandidates, exportName, commit, tempRoot, tsconfigRel, exportOptions, log) {
1995
2066
  const worktreeDir = path4.join(tempRoot, `wt-${commit.sha.slice(0, 12)}`);
1996
2067
  await runGit(repoRoot, ["worktree", "add", "--detach", worktreeDir, commit.sha]);
1997
2068
  try {
1998
2069
  await ensureWorktreeDependencies(repoRoot, worktreeDir);
1999
- const modulePath = path4.resolve(worktreeDir, moduleRel);
2070
+ const resolvedModuleRel = await resolveModulePathForCommit(
2071
+ repoRoot,
2072
+ commit.sha,
2073
+ moduleCandidates
2074
+ );
2075
+ if (!resolvedModuleRel) {
2076
+ log?.(
2077
+ `[changelog] unresolved module for commit ${commit.sha.slice(0, 12)}; using empty snapshot`
2078
+ );
2079
+ return {
2080
+ commit,
2081
+ routesByKey: {},
2082
+ sourceObjectsById: {},
2083
+ unresolvedModule: true
2084
+ };
2085
+ }
2086
+ log?.(
2087
+ `[changelog] resolved module for commit ${commit.sha.slice(0, 12)}: ${resolvedModuleRel}`
2088
+ );
2089
+ const modulePath = path4.resolve(worktreeDir, resolvedModuleRel);
2000
2090
  let snapshotRuntimePath = modulePath;
2001
2091
  let resolvedTsconfigPath;
2002
2092
  if (isTypeScriptModule(modulePath)) {
@@ -2011,7 +2101,7 @@ async function createSnapshot(repoRoot, moduleRel, exportName, commit, tempRoot,
2011
2101
  );
2012
2102
  snapshotRuntimePath = await compileSnapshotEntry({
2013
2103
  worktreeDir,
2014
- moduleRel,
2104
+ moduleRel: resolvedModuleRel,
2015
2105
  modulePath,
2016
2106
  tsconfigPath: resolvedTsconfigPath,
2017
2107
  commitSha: commit.sha,
@@ -2268,12 +2358,18 @@ async function exportFinalizedLeavesChangelog(options) {
2268
2358
  log("[changelog] resolving commit window");
2269
2359
  const window = await resolveCommitWindow(repoRoot, options.from, options.to);
2270
2360
  log(`[changelog] window: ${window.from.slice(0, 12)}..${window.to.slice(0, 12)}`);
2361
+ const moduleCandidates = await buildModulePathCandidates(
2362
+ repoRoot,
2363
+ window.to,
2364
+ modulePathRelative
2365
+ );
2366
+ log(`[changelog] module candidates discovered: ${moduleCandidates.length}`);
2271
2367
  const allCommits = await resolveCommitPath(repoRoot, window.from, window.to);
2272
2368
  log(`[changelog] commits in ancestry path: ${allCommits.length}`);
2273
2369
  const selectedCommitShas = await filterCommits(
2274
2370
  repoRoot,
2275
2371
  allCommits,
2276
- modulePathRelative,
2372
+ moduleCandidates,
2277
2373
  tsconfigRelative
2278
2374
  );
2279
2375
  log(`[changelog] commits after path filter: ${selectedCommitShas.length}`);
@@ -2290,6 +2386,7 @@ async function exportFinalizedLeavesChangelog(options) {
2290
2386
  log(`[changelog] temp workspace: ${tempRoot}`);
2291
2387
  try {
2292
2388
  const snapshots = [];
2389
+ const unresolvedModuleCommits = [];
2293
2390
  for (let index = 0; index < commits.length; index += 1) {
2294
2391
  const commit = commits[index];
2295
2392
  log(
@@ -2298,7 +2395,7 @@ async function exportFinalizedLeavesChangelog(options) {
2298
2395
  snapshots.push(
2299
2396
  await createSnapshot(
2300
2397
  repoRoot,
2301
- modulePathRelative,
2398
+ moduleCandidates,
2302
2399
  exportName,
2303
2400
  commit,
2304
2401
  tempRoot,
@@ -2307,6 +2404,9 @@ async function exportFinalizedLeavesChangelog(options) {
2307
2404
  log
2308
2405
  )
2309
2406
  );
2407
+ if (snapshots[snapshots.length - 1]?.unresolvedModule) {
2408
+ unresolvedModuleCommits.push(commit.sha);
2409
+ }
2310
2410
  }
2311
2411
  const routeEvents = [];
2312
2412
  const sourceEvents = [];
@@ -2331,7 +2431,8 @@ async function exportFinalizedLeavesChangelog(options) {
2331
2431
  exportName,
2332
2432
  from: window.from,
2333
2433
  to: window.to,
2334
- selectedCommitCount: commits.length
2434
+ selectedCommitCount: commits.length,
2435
+ unresolvedModuleCommits: unresolvedModuleCommits.length > 0 ? unresolvedModuleCommits : void 0
2335
2436
  },
2336
2437
  commits,
2337
2438
  byRoute: routeRecordByKey(routeEvents),
@@ -2358,6 +2459,8 @@ var __private = {
2358
2459
  resolveCommitWindow,
2359
2460
  resolveCommitPath,
2360
2461
  filterCommits,
2462
+ buildModulePathCandidates,
2463
+ resolveModulePathForCommit,
2361
2464
  resolveSnapshotTsconfig,
2362
2465
  toEmittedModulePath,
2363
2466
  buildCompileCacheKey,