@emeryld/rrroutes-contract 2.7.10 → 2.7.12
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 +1 -1
- package/dist/export/defaultViewerTemplate.d.ts +1 -1
- package/dist/export/flattenSchema.d.ts +1 -0
- package/dist/index.cjs +35 -9
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +35 -9
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/tools/finalized-leaves-viewer.html +435 -141
package/README.md
CHANGED
|
@@ -459,7 +459,7 @@ How to use:
|
|
|
459
459
|
1. Generate an export JSON with `export:finalized-leaves`.
|
|
460
460
|
2. Open the HTML file in your browser.
|
|
461
461
|
3. Load the JSON file using the file picker.
|
|
462
|
-
4. Use the
|
|
462
|
+
4. Use the search box, quick filter toggles, grouped field chips, and advanced filter panel to filter routes.
|
|
463
463
|
|
|
464
464
|
Each result is rendered as a collapsible block with title `METHOD path`.
|
|
465
465
|
|
|
@@ -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 }\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 .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 || !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
|
|
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 }\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 .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 || !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";
|
|
@@ -5,6 +5,7 @@ export type FlatSchemaEntry = {
|
|
|
5
5
|
type: string;
|
|
6
6
|
nullable: boolean;
|
|
7
7
|
optional: boolean;
|
|
8
|
+
literal?: unknown;
|
|
8
9
|
};
|
|
9
10
|
export type FlatSchemaMap = Record<string, FlatSchemaEntry>;
|
|
10
11
|
export declare function flattenSerializableSchema(schema: SerializableSchema | undefined, path: string): FlatSchemaMap;
|
package/dist/index.cjs
CHANGED
|
@@ -657,6 +657,24 @@ function serializeLeavesContract(leaves, options = {}) {
|
|
|
657
657
|
}
|
|
658
658
|
|
|
659
659
|
// src/export/flattenSchema.ts
|
|
660
|
+
function formatLiteralType(literal) {
|
|
661
|
+
if (typeof literal === "string") return literal;
|
|
662
|
+
if (typeof literal === "number" || typeof literal === "boolean" || typeof literal === "bigint") {
|
|
663
|
+
return String(literal);
|
|
664
|
+
}
|
|
665
|
+
if (literal === null) return "null";
|
|
666
|
+
if (Array.isArray(literal)) {
|
|
667
|
+
return literal.map((item) => formatLiteralType(item)).join("|");
|
|
668
|
+
}
|
|
669
|
+
if (typeof literal === "object") {
|
|
670
|
+
try {
|
|
671
|
+
return JSON.stringify(literal);
|
|
672
|
+
} catch {
|
|
673
|
+
return "object";
|
|
674
|
+
}
|
|
675
|
+
}
|
|
676
|
+
return "unknown";
|
|
677
|
+
}
|
|
660
678
|
function normalizeType(schema) {
|
|
661
679
|
switch (schema.kind) {
|
|
662
680
|
case "string":
|
|
@@ -673,11 +691,7 @@ function normalizeType(schema) {
|
|
|
673
691
|
return "unknown";
|
|
674
692
|
}
|
|
675
693
|
case "literal": {
|
|
676
|
-
|
|
677
|
-
if (typeof lit === "string") return "string";
|
|
678
|
-
if (typeof lit === "number") return "number";
|
|
679
|
-
if (typeof lit === "boolean") return "boolean";
|
|
680
|
-
return "unknown";
|
|
694
|
+
return formatLiteralType(schema.literal);
|
|
681
695
|
}
|
|
682
696
|
default:
|
|
683
697
|
return "unknown";
|
|
@@ -691,7 +705,8 @@ function setNode(out, path4, schema, inherited) {
|
|
|
691
705
|
out[path4] = {
|
|
692
706
|
type: normalizeType(schema),
|
|
693
707
|
nullable: inherited.nullable || Boolean(schema.nullable),
|
|
694
|
-
optional: inherited.optional || Boolean(schema.optional)
|
|
708
|
+
optional: inherited.optional || Boolean(schema.optional),
|
|
709
|
+
literal: schema.kind === "literal" ? schema.literal : void 0
|
|
695
710
|
};
|
|
696
711
|
}
|
|
697
712
|
function flattenInto(out, schema, path4, inherited) {
|
|
@@ -800,8 +815,19 @@ var DEFAULT_VIEWER_TEMPLATE = `<!doctype html>
|
|
|
800
815
|
const toHref = (source) => {
|
|
801
816
|
if (!source || !source.file) return null
|
|
802
817
|
const normalizedPath = String(source.file).replace(/\\\\/g, '/')
|
|
803
|
-
const
|
|
804
|
-
|
|
818
|
+
const platform =
|
|
819
|
+
(navigator.userAgentData && navigator.userAgentData.platform) ||
|
|
820
|
+
navigator.platform ||
|
|
821
|
+
''
|
|
822
|
+
const isWindows = /win/i.test(platform)
|
|
823
|
+
const vscodePath = isWindows
|
|
824
|
+
? normalizedPath.replace(/^\\/+/, '')
|
|
825
|
+
: normalizedPath.startsWith('/')
|
|
826
|
+
? normalizedPath
|
|
827
|
+
: '/' + normalizedPath
|
|
828
|
+
const line = Number.isFinite(source.line) ? source.line : 1
|
|
829
|
+
const column = Number.isFinite(source.column) ? source.column : 1
|
|
830
|
+
return 'vscode://file/' + encodeURI(vscodePath) + ':' + line + ':' + column
|
|
805
831
|
}
|
|
806
832
|
|
|
807
833
|
const sourceDisplay = (source) => {
|
|
@@ -1450,7 +1476,7 @@ function buildMeta(sourceExtraction) {
|
|
|
1450
1476
|
"literal?",
|
|
1451
1477
|
"enumValues?"
|
|
1452
1478
|
],
|
|
1453
|
-
flatSchemaEntry: ["type", "nullable", "optional"]
|
|
1479
|
+
flatSchemaEntry: ["type", "nullable", "optional", "literal?"]
|
|
1454
1480
|
},
|
|
1455
1481
|
flattening: {
|
|
1456
1482
|
notation: "dot+[]",
|