@emeryld/rrroutes-contract 2.7.2 → 2.7.4

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 CHANGED
@@ -386,7 +386,8 @@ Use `viewerTemplateFile` when you want your own branded/layout HTML while still
386
386
 
387
387
  Behavior:
388
388
 
389
- - If omitted, RRRoutes uses `packages/contract/tools/finalized-leaves-viewer.html`.
389
+ - If omitted, RRRoutes uses the bundled `finalized-leaves-viewer.html` template.
390
+ - Resolution order: package-bundled viewer, then local repo paths (`tools/...`, `packages/contract/tools/...`), then built-in string fallback.
390
391
  - If provided, RRRoutes reads your template and injects a script like:
391
392
  - `window.__FINALIZED_LEAVES_PAYLOAD = {...}`
392
393
  - If your template contains this marker comment, payload is injected exactly there:
@@ -0,0 +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: #f5f7fb;\n --surface: #ffffff;\n --border: #d6ddea;\n --text: #172033;\n --muted: #5b6680;\n --accent: #1858c6;\n }\n body {\n margin: 0;\n font-family: 'Iosevka Web', 'SFMono-Regular', Menlo, Consolas, monospace;\n color: var(--text);\n background: linear-gradient(180deg, var(--bg), #eef2fa);\n }\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: #fafcff; }\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 || !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 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 details.appendChild(summary)\n details.appendChild(pre)\n resultsEl.appendChild(details)\n })\n }\n </script>\n </body>\n</html>\n";
@@ -3,3 +3,4 @@ export * from './serializeLeafContract';
3
3
  export * from './flattenSchema';
4
4
  export * from './exportFinalizedLeaves';
5
5
  export * from './exportFinalizedLeaves.cli';
6
+ export * from './defaultViewerTemplate';
package/dist/index.cjs CHANGED
@@ -30,6 +30,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
30
30
  // src/index.ts
31
31
  var index_exports = {};
32
32
  __export(index_exports, {
33
+ DEFAULT_VIEWER_TEMPLATE: () => DEFAULT_VIEWER_TEMPLATE,
33
34
  buildCacheKey: () => buildCacheKey,
34
35
  buildLowProfileLeaf: () => buildLowProfileLeaf,
35
36
  clearSchemaIntrospectionHandlers: () => clearSchemaIntrospectionHandlers,
@@ -742,6 +743,78 @@ function flattenLeafSchemas(leaf) {
742
743
  var import_promises = __toESM(require("fs/promises"), 1);
743
744
  var import_node_path = __toESM(require("path"), 1);
744
745
  var import_node_child_process = require("child_process");
746
+
747
+ // src/export/defaultViewerTemplate.ts
748
+ var DEFAULT_VIEWER_TEMPLATE = `<!doctype html>
749
+ <html lang="en">
750
+ <head>
751
+ <meta charset="UTF-8" />
752
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
753
+ <title>Finalized Leaves Viewer</title>
754
+ <style>
755
+ :root {
756
+ --bg: #f5f7fb;
757
+ --surface: #ffffff;
758
+ --border: #d6ddea;
759
+ --text: #172033;
760
+ --muted: #5b6680;
761
+ --accent: #1858c6;
762
+ }
763
+ body {
764
+ margin: 0;
765
+ font-family: 'Iosevka Web', 'SFMono-Regular', Menlo, Consolas, monospace;
766
+ color: var(--text);
767
+ background: linear-gradient(180deg, var(--bg), #eef2fa);
768
+ }
769
+ .wrap { max-width: 1100px; margin: 0 auto; padding: 20px; }
770
+ .card { background: var(--surface); border: 1px solid var(--border); border-radius: 12px; padding: 14px; }
771
+ .meta { color: var(--muted); font-size: 12px; }
772
+ #results { margin-top: 12px; display: grid; gap: 8px; }
773
+ details { background: var(--surface); border: 1px solid var(--border); border-radius: 10px; padding: 8px 10px; }
774
+ summary { cursor: pointer; font-weight: 700; color: var(--accent); }
775
+ pre { margin: 10px 0 0; overflow: auto; border: 1px solid var(--border); border-radius: 8px; padding: 10px; background: #fafcff; }
776
+ </style>
777
+ </head>
778
+ <body>
779
+ <div class="wrap">
780
+ <h1>Finalized Leaves Viewer (Baked)</h1>
781
+ <div class="card">
782
+ <div id="status" class="meta">Waiting for baked payload...</div>
783
+ </div>
784
+ <div id="results"></div>
785
+ </div>
786
+
787
+ <!--__FINALIZED_LEAVES_BAKED_PAYLOAD__-->
788
+
789
+ <script>
790
+ const statusEl = document.getElementById('status')
791
+ const resultsEl = document.getElementById('results')
792
+ const payload = window.__FINALIZED_LEAVES_PAYLOAD
793
+
794
+ if (!payload || !Array.isArray(payload.leaves)) {
795
+ statusEl.textContent = 'No baked payload found in this HTML file.'
796
+ } else {
797
+ statusEl.textContent = 'Loaded baked payload with ' + payload.leaves.length + ' routes.'
798
+
799
+ payload.leaves.forEach((leaf) => {
800
+ const details = document.createElement('details')
801
+ const summary = document.createElement('summary')
802
+ summary.textContent = String(leaf.method || '').toUpperCase() + ' ' + (leaf.path || '')
803
+
804
+ const pre = document.createElement('pre')
805
+ pre.textContent = JSON.stringify(leaf, null, 2)
806
+
807
+ details.appendChild(summary)
808
+ details.appendChild(pre)
809
+ resultsEl.appendChild(details)
810
+ })
811
+ }
812
+ </script>
813
+ </body>
814
+ </html>
815
+ `;
816
+
817
+ // src/export/exportFinalizedLeaves.ts
745
818
  function isRegistry(value) {
746
819
  return typeof value === "object" && value !== null && "all" in value && "byKey" in value;
747
820
  }
@@ -808,10 +881,19 @@ ${htmlTemplate}`;
808
881
  }
809
882
  async function resolveViewerTemplatePath(viewerTemplateFile) {
810
883
  if (viewerTemplateFile) {
811
- return import_node_path.default.resolve(viewerTemplateFile);
884
+ const resolved = import_node_path.default.resolve(viewerTemplateFile);
885
+ await import_promises.default.access(resolved);
886
+ return resolved;
812
887
  }
813
888
  const candidates = [
814
- import_node_path.default.resolve(process.cwd(), "tools/finalized-leaves-viewer.html"),
889
+ import_node_path.default.resolve(
890
+ process.cwd(),
891
+ "node_modules/@emeryld/rrroutes-contract/tools/finalized-leaves-viewer.html"
892
+ ),
893
+ import_node_path.default.resolve(
894
+ process.cwd(),
895
+ "tools/finalized-leaves-viewer.html"
896
+ ),
815
897
  import_node_path.default.resolve(
816
898
  process.cwd(),
817
899
  "packages/contract/tools/finalized-leaves-viewer.html"
@@ -824,11 +906,7 @@ async function resolveViewerTemplatePath(viewerTemplateFile) {
824
906
  } catch {
825
907
  }
826
908
  }
827
- throw new Error(
828
- `Could not locate finalized-leaves viewer template. Checked: ${candidates.join(
829
- ", "
830
- )}`
831
- );
909
+ return void 0;
832
910
  }
833
911
  async function writeJsonExport(payload, outFile) {
834
912
  const resolved = import_node_path.default.resolve(outFile);
@@ -839,7 +917,7 @@ async function writeJsonExport(payload, outFile) {
839
917
  }
840
918
  async function writeBakedHtmlExport(payload, htmlFile, viewerTemplateFile) {
841
919
  const templatePath = await resolveViewerTemplatePath(viewerTemplateFile);
842
- const template = await import_promises.default.readFile(templatePath, "utf8");
920
+ const template = templatePath ? await import_promises.default.readFile(templatePath, "utf8") : DEFAULT_VIEWER_TEMPLATE;
843
921
  const baked = injectPayloadIntoViewerHtml(template, payload);
844
922
  const resolved = import_node_path.default.resolve(htmlFile);
845
923
  await import_promises.default.mkdir(import_node_path.default.dirname(resolved), { recursive: true });
@@ -956,6 +1034,7 @@ async function runExportFinalizedLeavesCli(argv) {
956
1034
  }
957
1035
  // Annotate the CommonJS export names for ESM import in node:
958
1036
  0 && (module.exports = {
1037
+ DEFAULT_VIEWER_TEMPLATE,
959
1038
  buildCacheKey,
960
1039
  buildLowProfileLeaf,
961
1040
  clearSchemaIntrospectionHandlers,