@emeryld/rrroutes-export 1.0.14 → 1.0.16

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.
@@ -1 +1 @@
1
- export declare const DEFAULT_VIEWER_TEMPLATE = "<!doctype html>\n<html lang=\"en\">\n <head>\n <meta charset=\"UTF-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n <title>Finalized Leaves Viewer</title>\n <style>\n :root {\n --bg: #212121;\n --surface: #2a2a2a;\n --border: #4a4a4a;\n --text: #fffafa;\n --muted: #c8c2c2;\n --accent: #a764d3;\n --schema-accent: #fbbd23;\n }\n body {\n margin: 0;\n font-family: 'Iosevka Web', 'SFMono-Regular', Menlo, Consolas, monospace;\n color: var(--text);\n background: var(--bg);\n }\n a { color: var(--schema-accent); }\n .wrap { max-width: 1100px; margin: 0 auto; padding: 20px; }\n .card { background: var(--surface); border: 1px solid var(--border); border-radius: 12px; padding: 14px; }\n .meta { color: var(--muted); font-size: 12px; }\n #results { margin-top: 12px; display: grid; gap: 8px; }\n details { background: var(--surface); border: 1px solid var(--border); border-radius: 10px; padding: 8px 10px; }\n summary { cursor: pointer; font-weight: 700; color: var(--accent); }\n pre { margin: 10px 0 0; overflow: auto; border: 1px solid var(--border); border-radius: 8px; padding: 10px; background: #303030; color: var(--text); }\n </style>\n </head>\n <body>\n <div class=\"wrap\">\n <h1>Finalized Leaves Viewer (Baked)</h1>\n <div class=\"card\">\n <div id=\"status\" class=\"meta\">Waiting for baked payload...</div>\n </div>\n <div id=\"results\"></div>\n </div>\n\n <!--__FINALIZED_LEAVES_BAKED_PAYLOAD__-->\n\n <script>\n const statusEl = document.getElementById('status')\n const resultsEl = document.getElementById('results')\n const payload = window.__FINALIZED_LEAVES_PAYLOAD\n\n if (payload && payload.kind === 'finalized-leaves-changelog') {\n statusEl.textContent =\n 'Loaded changelog payload with ' + (payload.commits?.length || 0) + ' commits.'\n\n const wrapSection = (title, value) => {\n const card = document.createElement('details')\n const summary = document.createElement('summary')\n summary.textContent = title\n const pre = document.createElement('pre')\n pre.textContent = JSON.stringify(value, null, 2)\n card.appendChild(summary)\n card.appendChild(pre)\n return card\n }\n\n resultsEl.appendChild(wrapSection('Commits', payload.commits || []))\n resultsEl.appendChild(wrapSection('By Route', payload.byRoute || {}))\n resultsEl.appendChild(\n wrapSection('By Source Object', payload.bySourceObject || {}),\n )\n } else if (!payload || !Array.isArray(payload.leaves)) {\n statusEl.textContent = 'No baked payload found in this HTML file.'\n } else {\n statusEl.textContent = 'Loaded baked payload with ' + payload.leaves.length + ' routes.'\n\n const toHref = (source) => {\n if (!source || !source.file) return null\n const normalizedPath = String(source.file).replace(/\\\\/g, '/')\n const platform =\n (navigator.userAgentData && navigator.userAgentData.platform) ||\n navigator.platform ||\n ''\n const isWindows = /win/i.test(platform)\n const vscodePath = isWindows\n ? normalizedPath.replace(/^\\/+/, '')\n : normalizedPath.startsWith('/')\n ? normalizedPath\n : '/' + normalizedPath\n const line = Number.isFinite(source.line) ? source.line : 1\n const column = Number.isFinite(source.column) ? source.column : 1\n return 'vscode://file/' + encodeURI(vscodePath) + ':' + line + ':' + column\n }\n\n const sourceDisplay = (source) => {\n return ''\n }\n\n payload.leaves.forEach((leaf) => {\n const details = document.createElement('details')\n const summary = document.createElement('summary')\n summary.textContent = String(leaf.method || '').toUpperCase() + ' ' + (leaf.path || '')\n\n const pre = document.createElement('pre')\n pre.textContent = JSON.stringify(leaf, null, 2)\n\n const source = payload.sourceByLeaf && payload.sourceByLeaf[leaf.key]\n let sourceWrap = null\n if (source) {\n sourceWrap = document.createElement('div')\n sourceWrap.className = 'meta'\n\n const definitionHref = toHref(source.definition)\n if (definitionHref) {\n const label = document.createElement('div')\n const link = document.createElement('a')\n link.href = definitionHref\n link.target = '_blank'\n link.rel = 'noopener noreferrer'\n link.textContent = 'definition'\n label.appendChild(link)\n sourceWrap.appendChild(label)\n }\n\n if (source.schemas && typeof source.schemas === 'object') {\n Object.entries(source.schemas).forEach(([name, schema]) => {\n if (!schema) return\n const href = toHref(schema)\n const row = document.createElement('div')\n if (href) {\n const link = document.createElement('a')\n link.href = href\n link.target = '_blank'\n link.rel = 'noopener noreferrer'\n link.textContent =\n name + ': ' + (schema.sourceName || schema.tag || '<anonymous>')\n row.appendChild(link)\n } else {\n row.textContent = name + ': ' + (schema.sourceName || schema.tag || '<anonymous>')\n }\n sourceWrap.appendChild(row)\n })\n }\n\n }\n\n details.appendChild(summary)\n if (sourceWrap) details.appendChild(sourceWrap)\n details.appendChild(pre)\n resultsEl.appendChild(details)\n })\n }\n </script>\n </body>\n</html>\n";
1
+ export declare const DEFAULT_VIEWER_TEMPLATE = "<!doctype html>\n<html lang=\"en\">\n <head>\n <meta charset=\"UTF-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n <title>RRRoutes Export Viewer</title>\n <style>\n :root {\n --bg: #212121;\n --surface: #2a2a2a;\n --border: #4a4a4a;\n --text: #fffafa;\n --muted: #c8c2c2;\n --accent: #a764d3;\n --schema-accent: #fbbd23;\n }\n body {\n margin: 0;\n font-family: 'Iosevka Web', 'SFMono-Regular', Menlo, Consolas, monospace;\n color: var(--text);\n background: var(--bg);\n }\n a { color: var(--schema-accent); }\n .wrap { max-width: 1100px; margin: 0 auto; padding: 20px; }\n .card { background: var(--surface); border: 1px solid var(--border); border-radius: 12px; padding: 14px; }\n .meta { color: var(--muted); font-size: 12px; }\n #results { margin-top: 12px; display: grid; gap: 8px; }\n details { background: var(--surface); border: 1px solid var(--border); border-radius: 10px; padding: 8px 10px; }\n summary { cursor: pointer; font-weight: 700; color: var(--accent); }\n pre { margin: 10px 0 0; overflow: auto; border: 1px solid var(--border); border-radius: 8px; padding: 10px; background: #303030; color: var(--text); }\n </style>\n </head>\n <body>\n <div class=\"wrap\">\n <h1>RRRoutes Export Viewer (Baked)</h1>\n <div class=\"card\">\n <div id=\"status\" class=\"meta\">Waiting for baked payload...</div>\n </div>\n <div id=\"results\"></div>\n </div>\n\n <!--__FINALIZED_LEAVES_BAKED_PAYLOAD__-->\n\n <script>\n const statusEl = document.getElementById('status')\n const resultsEl = document.getElementById('results')\n const payload = window.__FINALIZED_LEAVES_PAYLOAD\n\n if (payload && payload.kind === 'finalized-leaves-changelog') {\n statusEl.textContent =\n 'Loaded changelog payload with ' + (payload.commits?.length || 0) + ' commits.'\n\n const wrapSection = (title, value) => {\n const card = document.createElement('details')\n const summary = document.createElement('summary')\n summary.textContent = title\n const pre = document.createElement('pre')\n pre.textContent = JSON.stringify(value, null, 2)\n card.appendChild(summary)\n card.appendChild(pre)\n return card\n }\n\n resultsEl.appendChild(wrapSection('Commits', payload.commits || []))\n resultsEl.appendChild(wrapSection('By Route', payload.byRoute || {}))\n resultsEl.appendChild(\n wrapSection('By Source Object', payload.bySourceObject || {}),\n )\n } else if (!payload || !Array.isArray(payload.leaves)) {\n statusEl.textContent = 'No baked leaves/changelog/bundle payload found in this HTML file.'\n } else {\n statusEl.textContent = 'Loaded baked payload with ' + payload.leaves.length + ' routes.'\n\n const toHref = (source) => {\n if (!source || !source.file) return null\n const normalizedPath = String(source.file).replace(/\\\\/g, '/')\n const platform =\n (navigator.userAgentData && navigator.userAgentData.platform) ||\n navigator.platform ||\n ''\n const isWindows = /win/i.test(platform)\n const vscodePath = isWindows\n ? normalizedPath.replace(/^\\/+/, '')\n : normalizedPath.startsWith('/')\n ? normalizedPath\n : '/' + normalizedPath\n const line = Number.isFinite(source.line) ? source.line : 1\n const column = Number.isFinite(source.column) ? source.column : 1\n return 'vscode://file/' + encodeURI(vscodePath) + ':' + line + ':' + column\n }\n\n const sourceDisplay = (source) => {\n return ''\n }\n\n payload.leaves.forEach((leaf) => {\n const details = document.createElement('details')\n const summary = document.createElement('summary')\n summary.textContent = String(leaf.method || '').toUpperCase() + ' ' + (leaf.path || '')\n\n const pre = document.createElement('pre')\n pre.textContent = JSON.stringify(leaf, null, 2)\n\n const source = payload.sourceByLeaf && payload.sourceByLeaf[leaf.key]\n let sourceWrap = null\n if (source) {\n sourceWrap = document.createElement('div')\n sourceWrap.className = 'meta'\n\n const definitionHref = toHref(source.definition)\n if (definitionHref) {\n const label = document.createElement('div')\n const link = document.createElement('a')\n link.href = definitionHref\n link.target = '_blank'\n link.rel = 'noopener noreferrer'\n link.textContent = 'definition'\n label.appendChild(link)\n sourceWrap.appendChild(label)\n }\n\n if (source.schemas && typeof source.schemas === 'object') {\n Object.entries(source.schemas).forEach(([name, schema]) => {\n if (!schema) return\n const href = toHref(schema)\n const row = document.createElement('div')\n if (href) {\n const link = document.createElement('a')\n link.href = href\n link.target = '_blank'\n link.rel = 'noopener noreferrer'\n link.textContent =\n name + ': ' + (schema.sourceName || schema.tag || '<anonymous>')\n row.appendChild(link)\n } else {\n row.textContent = name + ': ' + (schema.sourceName || schema.tag || '<anonymous>')\n }\n sourceWrap.appendChild(row)\n })\n }\n\n }\n\n details.appendChild(summary)\n if (sourceWrap) details.appendChild(sourceWrap)\n details.appendChild(pre)\n resultsEl.appendChild(details)\n })\n }\n </script>\n </body>\n</html>\n";
@@ -141,10 +141,7 @@ declare function toRouteSnapshots(payload: FinalizedLeavesExport): Record<string
141
141
  declare function toSourceObjectSnapshots(routesByKey: Record<string, RouteSnapshot>): Record<string, SourceObjectSnapshot>;
142
142
  declare function resolveSnapshotTsconfig(worktreeDir: string, modulePath: string, tsconfigOverride?: string): Promise<string>;
143
143
  declare function toEmittedModulePath(moduleRel: string): string;
144
- declare function buildCompileCacheKey(commitSha: string, moduleRel: string, tsconfigPath: string, tsconfigStat: {
145
- mtimeMs: number;
146
- size: number;
147
- }): string;
144
+ declare function buildCompileCacheKey(commitSha: string, moduleRel: string, tsconfigKeyPath: string): string;
148
145
  declare function compileSnapshotEntry(options: {
149
146
  worktreeDir: string;
150
147
  moduleRel: string;
package/dist/index.cjs CHANGED
@@ -421,7 +421,7 @@ var DEFAULT_VIEWER_TEMPLATE = `<!doctype html>
421
421
  <head>
422
422
  <meta charset="UTF-8" />
423
423
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
424
- <title>Finalized Leaves Viewer</title>
424
+ <title>RRRoutes Export Viewer</title>
425
425
  <style>
426
426
  :root {
427
427
  --bg: #212121;
@@ -450,7 +450,7 @@ var DEFAULT_VIEWER_TEMPLATE = `<!doctype html>
450
450
  </head>
451
451
  <body>
452
452
  <div class="wrap">
453
- <h1>Finalized Leaves Viewer (Baked)</h1>
453
+ <h1>RRRoutes Export Viewer (Baked)</h1>
454
454
  <div class="card">
455
455
  <div id="status" class="meta">Waiting for baked payload...</div>
456
456
  </div>
@@ -485,7 +485,7 @@ var DEFAULT_VIEWER_TEMPLATE = `<!doctype html>
485
485
  wrapSection('By Source Object', payload.bySourceObject || {}),
486
486
  )
487
487
  } else if (!payload || !Array.isArray(payload.leaves)) {
488
- statusEl.textContent = 'No baked payload found in this HTML file.'
488
+ statusEl.textContent = 'No baked leaves/changelog/bundle payload found in this HTML file.'
489
489
  } else {
490
490
  statusEl.textContent = 'Loaded baked payload with ' + payload.leaves.length + ' routes.'
491
491
 
@@ -1414,6 +1414,7 @@ var CHANGESET_CFG_FIELDS = [
1414
1414
  ];
1415
1415
  var SCHEMA_SECTIONS = ["params", "query", "body", "output"];
1416
1416
  var MODULE_EXTENSIONS = [".ts", ".tsx", ".mts", ".cts", ".js", ".mjs", ".cjs"];
1417
+ var COMPILE_CACHE_VERSION = "v2";
1417
1418
  var SOURCE_KEY_BY_SECTION = {
1418
1419
  params: "paramsSchema",
1419
1420
  query: "querySchema",
@@ -1995,8 +1996,8 @@ function toEmittedModulePath(moduleRel) {
1995
1996
  if (normalized.endsWith(".ts")) return normalized.slice(0, -3) + ".js";
1996
1997
  return normalized;
1997
1998
  }
1998
- function buildCompileCacheKey(commitSha, moduleRel, tsconfigPath, tsconfigStat) {
1999
- return import_node_crypto.default.createHash("sha1").update(commitSha).update("\n").update(normalizePath(moduleRel)).update("\n").update(normalizePath(tsconfigPath)).update("\n").update(String(tsconfigStat.mtimeMs)).update("\n").update(String(tsconfigStat.size)).digest("hex");
1999
+ function buildCompileCacheKey(commitSha, moduleRel, tsconfigKeyPath) {
2000
+ return import_node_crypto.default.createHash("sha1").update(COMPILE_CACHE_VERSION).update("\n").update(commitSha).update("\n").update(normalizePath(moduleRel)).update("\n").update(normalizePath(tsconfigKeyPath)).digest("hex");
2000
2001
  }
2001
2002
  async function collectFilesRecursive(rootDir) {
2002
2003
  const files = [];
@@ -2051,16 +2052,18 @@ async function resolveEmittedEntryPath(emitRoot, moduleRel) {
2051
2052
  }
2052
2053
  async function compileSnapshotEntry(options) {
2053
2054
  const log = options.log ?? (() => void 0);
2054
- const tsconfigStat = await import_promises2.default.stat(options.tsconfigPath);
2055
+ const relativeTsconfigPath = normalizePath(
2056
+ import_node_path4.default.relative(options.worktreeDir, options.tsconfigPath)
2057
+ );
2058
+ const tsconfigKeyPath = relativeTsconfigPath.startsWith("..") || import_node_path4.default.isAbsolute(relativeTsconfigPath) ? normalizePath(options.tsconfigPath) : relativeTsconfigPath;
2055
2059
  const cacheKey = buildCompileCacheKey(
2056
2060
  options.commitSha,
2057
2061
  options.moduleRel,
2058
- options.tsconfigPath,
2059
- { mtimeMs: tsconfigStat.mtimeMs, size: tsconfigStat.size }
2062
+ tsconfigKeyPath
2060
2063
  );
2061
2064
  const emitRoot = import_node_path4.default.join(options.cacheRoot, cacheKey, "dist");
2062
- let emittedEntry = import_node_path4.default.resolve(emitRoot, toEmittedModulePath(options.moduleRel));
2063
- if (!options.noCache && await pathExists(emittedEntry)) {
2065
+ let emittedEntry = await resolveEmittedEntryPath(emitRoot, options.moduleRel);
2066
+ if (!options.noCache && emittedEntry && await pathExists(emittedEntry)) {
2064
2067
  log(`[changelog] compile cache hit: ${options.commitSha.slice(0, 12)}`);
2065
2068
  return emittedEntry;
2066
2069
  }
@@ -2108,10 +2111,10 @@ async function compileSnapshotEntry(options) {
2108
2111
  ${message}`
2109
2112
  );
2110
2113
  }
2111
- emittedEntry = await resolveEmittedEntryPath(emitRoot, options.moduleRel) ?? emittedEntry;
2112
- if (!await pathExists(emittedEntry)) {
2114
+ emittedEntry = await resolveEmittedEntryPath(emitRoot, options.moduleRel);
2115
+ if (!emittedEntry || !await pathExists(emittedEntry)) {
2113
2116
  throw new Error(
2114
- `Compiled snapshot entry was not emitted: ${emittedEntry}. Check module/tsconfig compatibility.`
2117
+ `Compiled snapshot entry was not emitted for ${options.moduleRel} under ${emitRoot}. Check module/tsconfig compatibility.`
2115
2118
  );
2116
2119
  }
2117
2120
  log(`[changelog] compiled snapshot entry: ${emittedEntry}`);