raffel 1.1.59-next.46223d0 → 1.1.59
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/docs/ui/assets/raffel-docs.css +0 -108
- package/dist/docs/ui/assets/raffel-docs.js +9 -89
- package/dist/docs/ui/runtime/index.js +9 -89
- package/dist/docs/ui/runtime/index.js.map +1 -1
- package/dist/docs/ui/style-sections/content.d.ts +1 -1
- package/dist/docs/ui/style-sections/content.d.ts.map +1 -1
- package/dist/docs/ui/style-sections/content.js +0 -108
- package/dist/docs/ui/style-sections/content.js.map +1 -1
- package/dist/middleware/policy/bootstrap.d.ts +0 -32
- package/dist/middleware/policy/bootstrap.d.ts.map +1 -1
- package/dist/middleware/policy/bootstrap.js +0 -11
- package/dist/middleware/policy/bootstrap.js.map +1 -1
- package/dist/server/builder.d.ts.map +1 -1
- package/dist/server/builder.js +306 -47
- package/dist/server/builder.js.map +1 -1
- package/dist/server/discovery-utils.d.ts +0 -11
- package/dist/server/discovery-utils.d.ts.map +1 -1
- package/dist/server/discovery-utils.js +50 -41
- package/dist/server/discovery-utils.js.map +1 -1
- package/dist/server/fs-routes/loader.d.ts.map +1 -1
- package/dist/server/fs-routes/loader.js +232 -2
- package/dist/server/fs-routes/loader.js.map +1 -1
- package/dist/ui/docs/ui/style-sections/content.d.ts +1 -1
- package/dist/ui/docs/ui/style-sections/content.d.ts.map +1 -1
- package/dist/ui/server/fs-routes/loader.d.ts.map +1 -1
- package/package.json +1 -1
- package/dist/middleware/policy/co-located-accumulator.d.ts +0 -63
- package/dist/middleware/policy/co-located-accumulator.d.ts.map +0 -1
- package/dist/middleware/policy/co-located-accumulator.js +0 -148
- package/dist/middleware/policy/co-located-accumulator.js.map +0 -1
- package/dist/server/builder/policy-bridges.d.ts +0 -41
- package/dist/server/builder/policy-bridges.d.ts.map +0 -1
- package/dist/server/builder/policy-bridges.js +0 -96
- package/dist/server/builder/policy-bridges.js.map +0 -1
- package/dist/server/builder/programmatic-registration.d.ts +0 -43
- package/dist/server/builder/programmatic-registration.d.ts.map +0 -1
- package/dist/server/builder/programmatic-registration.js +0 -261
- package/dist/server/builder/programmatic-registration.js.map +0 -1
- package/dist/server/fs-routes/co-located-attach.d.ts +0 -32
- package/dist/server/fs-routes/co-located-attach.d.ts.map +0 -1
- package/dist/server/fs-routes/co-located-attach.js +0 -69
- package/dist/server/fs-routes/co-located-attach.js.map +0 -1
- package/dist/server/fs-routes/route-naming.d.ts +0 -61
- package/dist/server/fs-routes/route-naming.d.ts.map +0 -1
- package/dist/server/fs-routes/route-naming.js +0 -191
- package/dist/server/fs-routes/route-naming.js.map +0 -1
- package/dist/ui/server/fs-routes/co-located-attach.d.ts +0 -32
- package/dist/ui/server/fs-routes/co-located-attach.d.ts.map +0 -1
- package/dist/ui/server/fs-routes/route-naming.d.ts +0 -61
- package/dist/ui/server/fs-routes/route-naming.d.ts.map +0 -1
|
@@ -1483,114 +1483,6 @@
|
|
|
1483
1483
|
color: var(--text-color);
|
|
1484
1484
|
}
|
|
1485
1485
|
|
|
1486
|
-
/* ========== ROOT OVERVIEW (OpenAPI landing) ========== */
|
|
1487
|
-
.docs-overview {
|
|
1488
|
-
max-width: 820px;
|
|
1489
|
-
margin-bottom: 8px;
|
|
1490
|
-
}
|
|
1491
|
-
|
|
1492
|
-
.docs-overview-header {
|
|
1493
|
-
margin: 0 0 12px 0;
|
|
1494
|
-
}
|
|
1495
|
-
|
|
1496
|
-
.docs-overview-title {
|
|
1497
|
-
display: flex;
|
|
1498
|
-
align-items: baseline;
|
|
1499
|
-
flex-wrap: wrap;
|
|
1500
|
-
gap: 12px;
|
|
1501
|
-
font-size: 32px;
|
|
1502
|
-
font-weight: 700;
|
|
1503
|
-
line-height: 1.2;
|
|
1504
|
-
margin: 0;
|
|
1505
|
-
color: var(--text-color);
|
|
1506
|
-
}
|
|
1507
|
-
|
|
1508
|
-
.docs-overview-version {
|
|
1509
|
-
font-size: 13px;
|
|
1510
|
-
font-weight: 600;
|
|
1511
|
-
letter-spacing: 0.02em;
|
|
1512
|
-
padding: 3px 10px;
|
|
1513
|
-
border-radius: 999px;
|
|
1514
|
-
color: var(--accent, var(--primary-color));
|
|
1515
|
-
background: color-mix(in srgb, var(--accent, var(--primary-color)) 14%, transparent);
|
|
1516
|
-
border: 1px solid color-mix(in srgb, var(--accent, var(--primary-color)) 35%, transparent);
|
|
1517
|
-
}
|
|
1518
|
-
|
|
1519
|
-
.docs-overview-meta {
|
|
1520
|
-
display: flex;
|
|
1521
|
-
flex-wrap: wrap;
|
|
1522
|
-
align-items: center;
|
|
1523
|
-
gap: 10px;
|
|
1524
|
-
font-size: 14px;
|
|
1525
|
-
color: var(--text-muted);
|
|
1526
|
-
margin: 0 0 24px 0;
|
|
1527
|
-
}
|
|
1528
|
-
|
|
1529
|
-
.docs-overview-meta a {
|
|
1530
|
-
color: var(--accent, var(--primary-color));
|
|
1531
|
-
text-decoration: none;
|
|
1532
|
-
}
|
|
1533
|
-
|
|
1534
|
-
.docs-overview-meta a:hover {
|
|
1535
|
-
text-decoration: underline;
|
|
1536
|
-
}
|
|
1537
|
-
|
|
1538
|
-
.docs-overview-meta-sep {
|
|
1539
|
-
color: var(--border-color);
|
|
1540
|
-
}
|
|
1541
|
-
|
|
1542
|
-
.docs-overview-servers {
|
|
1543
|
-
margin: 0 0 28px 0;
|
|
1544
|
-
}
|
|
1545
|
-
|
|
1546
|
-
.docs-overview-subtitle {
|
|
1547
|
-
font-size: 13px;
|
|
1548
|
-
font-weight: 700;
|
|
1549
|
-
text-transform: uppercase;
|
|
1550
|
-
letter-spacing: 0.06em;
|
|
1551
|
-
color: var(--text-muted);
|
|
1552
|
-
margin: 0 0 12px 0;
|
|
1553
|
-
}
|
|
1554
|
-
|
|
1555
|
-
.docs-overview-server-list {
|
|
1556
|
-
list-style: none;
|
|
1557
|
-
margin: 0;
|
|
1558
|
-
padding: 0;
|
|
1559
|
-
display: flex;
|
|
1560
|
-
flex-direction: column;
|
|
1561
|
-
gap: 8px;
|
|
1562
|
-
}
|
|
1563
|
-
|
|
1564
|
-
.docs-overview-server {
|
|
1565
|
-
display: flex;
|
|
1566
|
-
align-items: center;
|
|
1567
|
-
flex-wrap: wrap;
|
|
1568
|
-
gap: 12px;
|
|
1569
|
-
padding: 12px 16px;
|
|
1570
|
-
border: 1px solid var(--border-color);
|
|
1571
|
-
border-radius: 10px;
|
|
1572
|
-
background: var(--surface-color);
|
|
1573
|
-
}
|
|
1574
|
-
|
|
1575
|
-
.docs-overview-server-url {
|
|
1576
|
-
font-family: 'SF Mono', Monaco, Consolas, monospace;
|
|
1577
|
-
font-size: 14px;
|
|
1578
|
-
color: var(--text-color);
|
|
1579
|
-
background: var(--code-bg);
|
|
1580
|
-
padding: 4px 10px;
|
|
1581
|
-
border-radius: 6px;
|
|
1582
|
-
word-break: break-all;
|
|
1583
|
-
}
|
|
1584
|
-
|
|
1585
|
-
.docs-overview-server-desc {
|
|
1586
|
-
font-size: 14px;
|
|
1587
|
-
color: var(--text-muted);
|
|
1588
|
-
}
|
|
1589
|
-
|
|
1590
|
-
.docs-overview-description {
|
|
1591
|
-
max-width: 820px;
|
|
1592
|
-
}
|
|
1593
|
-
|
|
1594
1486
|
/* ========== ENDPOINT SECTIONS (Redoc-style) ========== */
|
|
1595
1487
|
.endpoint-section {
|
|
1596
1488
|
padding: 32px 0;
|
|
@@ -42,15 +42,7 @@ const xUsd = spec['x-usd'] ?? {};
|
|
|
42
42
|
const { websocket: wsSpec = {}, graphql: graphqlSpec = {}, streams: streamsSpec = {}, jsonrpc: jsonrpcSpec = {}, grpc: grpcSpec = {}, tcp: tcpSpec = {}, udp: udpSpec = {} } = xUsd;
|
|
43
43
|
const docsRouteBase = String(xUsd.documentation?.routeBase ?? '').replace(/^#/, '').replace(/\/+$/, '');
|
|
44
44
|
const protocolData = detectProtocols();
|
|
45
|
-
|
|
46
|
-
// what a consumer of *this* API most likely came to read first. HTTP wins
|
|
47
|
-
// when present, then GraphQL, then realtime/RPC, then raw sockets.
|
|
48
|
-
const PROTOCOL_PRIORITY = ['http', 'graphql', 'websocket', 'jsonrpc', 'grpc', 'streams', 'tcp', 'udp'];
|
|
49
|
-
const protocolRank = (name) => {
|
|
50
|
-
const i = PROTOCOL_PRIORITY.indexOf(name);
|
|
51
|
-
return i === -1 ? PROTOCOL_PRIORITY.length : i;
|
|
52
|
-
};
|
|
53
|
-
const protocols = Object.keys(protocolData).sort((a, b) => protocolRank(a) - protocolRank(b));
|
|
45
|
+
const protocols = Object.keys(protocolData);
|
|
54
46
|
let activeProtocol = protocols[0] ?? 'http';
|
|
55
47
|
let searchQuery = '';
|
|
56
48
|
let routeState = parseRouteHash();
|
|
@@ -930,10 +922,9 @@ function renderProtocolTabs() {
|
|
|
930
922
|
if (!container)
|
|
931
923
|
return;
|
|
932
924
|
container.textContent = '';
|
|
933
|
-
const isRoot = !activePagePath || activePagePath === '/';
|
|
934
925
|
for (const protocol of protocols) {
|
|
935
926
|
const button = doc.createElement('button');
|
|
936
|
-
button.className = `protocol-tab${
|
|
927
|
+
button.className = `protocol-tab${!activePagePath && protocol === activeProtocol ? ' active' : ''}`;
|
|
937
928
|
button.innerHTML = `${esc(protocol.charAt(0).toUpperCase() + protocol.slice(1))}${sidebarConfig.showCounts !== false ? `<span class="count">${protocolData[protocol]}</span>` : ''}`;
|
|
938
929
|
button.onclick = () => {
|
|
939
930
|
activeProtocol = protocol;
|
|
@@ -1053,14 +1044,7 @@ function renderSidebar() {
|
|
|
1053
1044
|
return;
|
|
1054
1045
|
nav.textContent = '';
|
|
1055
1046
|
renderDocsPagesNav(nav);
|
|
1056
|
-
|
|
1057
|
-
// The docs root (`/`) is NOT a page — it's the overview, so it must list
|
|
1058
|
-
// the active protocol's endpoints, expanded, like the old empty-path state.
|
|
1059
|
-
const matchedPage = activePagePath
|
|
1060
|
-
? getDocsPageViews().some((p) => p.path === activePagePath)
|
|
1061
|
-
: false;
|
|
1062
|
-
const isRoot = !activePagePath || activePagePath === '/';
|
|
1063
|
-
if (matchedPage || !isRoot)
|
|
1047
|
+
if (activePagePath)
|
|
1064
1048
|
return;
|
|
1065
1049
|
const endpoints = getEndpointsForProtocol(activeProtocol).filter(endpoint => !searchQuery ||
|
|
1066
1050
|
endpoint.path.toLowerCase().includes(searchQuery) ||
|
|
@@ -1819,19 +1803,16 @@ function renderContent() {
|
|
|
1819
1803
|
scrollToActiveHeading();
|
|
1820
1804
|
return;
|
|
1821
1805
|
}
|
|
1822
|
-
|
|
1823
|
-
// non-root path with no matching page is a genuine 404.
|
|
1824
|
-
const isRoot = !activePagePath || activePagePath === '/';
|
|
1825
|
-
if (activePagePath && !isRoot) {
|
|
1806
|
+
if (activePagePath) {
|
|
1826
1807
|
renderMissingDocsPage(main);
|
|
1827
1808
|
renderToc(main);
|
|
1828
1809
|
return;
|
|
1829
1810
|
}
|
|
1830
|
-
|
|
1831
|
-
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
main.appendChild(
|
|
1811
|
+
if (!searchQuery && spec.info?.description) {
|
|
1812
|
+
const intro = doc.createElement('div');
|
|
1813
|
+
intro.className = 'intro-section';
|
|
1814
|
+
intro.innerHTML = `<div class="markdown-content">${parseMarkdown(spec.info.description)}</div>`;
|
|
1815
|
+
main.appendChild(intro);
|
|
1835
1816
|
}
|
|
1836
1817
|
if (searchQuery)
|
|
1837
1818
|
renderDocsSearch(main);
|
|
@@ -1848,67 +1829,6 @@ function renderContent() {
|
|
|
1848
1829
|
}
|
|
1849
1830
|
renderToc(main);
|
|
1850
1831
|
}
|
|
1851
|
-
function renderDocsOverview() {
|
|
1852
|
-
const info = (spec.info ?? {});
|
|
1853
|
-
const container = doc.createElement('div');
|
|
1854
|
-
container.className = 'docs-overview';
|
|
1855
|
-
const title = String(info.title ?? 'API');
|
|
1856
|
-
const versionBadge = info.version
|
|
1857
|
-
? `<span class="docs-overview-version">${esc(String(info.version))}</span>`
|
|
1858
|
-
: '';
|
|
1859
|
-
const header = doc.createElement('header');
|
|
1860
|
-
header.className = 'docs-overview-header';
|
|
1861
|
-
header.innerHTML = `<h1 class="docs-overview-title" id="overview">${esc(title)}${versionBadge}</h1>`;
|
|
1862
|
-
container.appendChild(header);
|
|
1863
|
-
// Contact / license line (ReDoc-style).
|
|
1864
|
-
const contact = (info.contact ?? {});
|
|
1865
|
-
const license = (info.license ?? {});
|
|
1866
|
-
const metaBits = [];
|
|
1867
|
-
if (contact.email) {
|
|
1868
|
-
const label = esc(String(contact.name ?? contact.email));
|
|
1869
|
-
metaBits.push(`E-mail: <a href="mailto:${esc(String(contact.email))}">${label}</a>`);
|
|
1870
|
-
}
|
|
1871
|
-
if (contact.url) {
|
|
1872
|
-
metaBits.push(`URL: <a href="${esc(String(contact.url))}" target="_blank" rel="noopener">${esc(String(contact.url))}</a>`);
|
|
1873
|
-
}
|
|
1874
|
-
if (license.name) {
|
|
1875
|
-
const lic = license.url
|
|
1876
|
-
? `<a href="${esc(String(license.url))}" target="_blank" rel="noopener">${esc(String(license.name))}</a>`
|
|
1877
|
-
: esc(String(license.name));
|
|
1878
|
-
metaBits.push(`License: ${lic}`);
|
|
1879
|
-
}
|
|
1880
|
-
if (metaBits.length) {
|
|
1881
|
-
const meta = doc.createElement('div');
|
|
1882
|
-
meta.className = 'docs-overview-meta';
|
|
1883
|
-
meta.innerHTML = metaBits.join('<span class="docs-overview-meta-sep">·</span>');
|
|
1884
|
-
container.appendChild(meta);
|
|
1885
|
-
}
|
|
1886
|
-
// Servers — straight from `spec.servers`.
|
|
1887
|
-
const servers = Array.isArray(spec.servers) ? spec.servers : [];
|
|
1888
|
-
if (servers.length) {
|
|
1889
|
-
const section = doc.createElement('section');
|
|
1890
|
-
section.className = 'docs-overview-servers';
|
|
1891
|
-
const rows = servers
|
|
1892
|
-
.map((s) => {
|
|
1893
|
-
const url = esc(String(s?.url ?? ''));
|
|
1894
|
-
const desc = s?.description
|
|
1895
|
-
? `<span class="docs-overview-server-desc">${esc(String(s.description))}</span>`
|
|
1896
|
-
: '';
|
|
1897
|
-
return `<li class="docs-overview-server"><code class="docs-overview-server-url">${url}</code>${desc}</li>`;
|
|
1898
|
-
})
|
|
1899
|
-
.join('');
|
|
1900
|
-
section.innerHTML = `<h2 class="docs-overview-subtitle">${servers.length > 1 ? 'Servers' : 'Server'}</h2><ul class="docs-overview-server-list">${rows}</ul>`;
|
|
1901
|
-
container.appendChild(section);
|
|
1902
|
-
}
|
|
1903
|
-
// Description (markdown).
|
|
1904
|
-
if (info.description) {
|
|
1905
|
-
const description = doc.createElement('div');
|
|
1906
|
-
description.className = 'docs-overview-description markdown-content';
|
|
1907
|
-
description.innerHTML = parseMarkdown(String(info.description));
|
|
1908
|
-
container.appendChild(description);
|
|
1909
|
-
}
|
|
1910
|
-
return container;
|
|
1911
|
-
}
|
|
1912
1832
|
function renderMissingDocsPage(main) {
|
|
1913
1833
|
const notFound = getDocsPageViews().find(page => page.path === '/404' || page.path.endsWith('/404'));
|
|
1914
1834
|
const article = doc.createElement('article');
|
|
@@ -42,15 +42,7 @@ const xUsd = spec['x-usd'] ?? {};
|
|
|
42
42
|
const { websocket: wsSpec = {}, graphql: graphqlSpec = {}, streams: streamsSpec = {}, jsonrpc: jsonrpcSpec = {}, grpc: grpcSpec = {}, tcp: tcpSpec = {}, udp: udpSpec = {} } = xUsd;
|
|
43
43
|
const docsRouteBase = String(xUsd.documentation?.routeBase ?? '').replace(/^#/, '').replace(/\/+$/, '');
|
|
44
44
|
const protocolData = detectProtocols();
|
|
45
|
-
|
|
46
|
-
// what a consumer of *this* API most likely came to read first. HTTP wins
|
|
47
|
-
// when present, then GraphQL, then realtime/RPC, then raw sockets.
|
|
48
|
-
const PROTOCOL_PRIORITY = ['http', 'graphql', 'websocket', 'jsonrpc', 'grpc', 'streams', 'tcp', 'udp'];
|
|
49
|
-
const protocolRank = (name) => {
|
|
50
|
-
const i = PROTOCOL_PRIORITY.indexOf(name);
|
|
51
|
-
return i === -1 ? PROTOCOL_PRIORITY.length : i;
|
|
52
|
-
};
|
|
53
|
-
const protocols = Object.keys(protocolData).sort((a, b) => protocolRank(a) - protocolRank(b));
|
|
45
|
+
const protocols = Object.keys(protocolData);
|
|
54
46
|
let activeProtocol = protocols[0] ?? 'http';
|
|
55
47
|
let searchQuery = '';
|
|
56
48
|
let routeState = parseRouteHash();
|
|
@@ -930,10 +922,9 @@ function renderProtocolTabs() {
|
|
|
930
922
|
if (!container)
|
|
931
923
|
return;
|
|
932
924
|
container.textContent = '';
|
|
933
|
-
const isRoot = !activePagePath || activePagePath === '/';
|
|
934
925
|
for (const protocol of protocols) {
|
|
935
926
|
const button = doc.createElement('button');
|
|
936
|
-
button.className = `protocol-tab${
|
|
927
|
+
button.className = `protocol-tab${!activePagePath && protocol === activeProtocol ? ' active' : ''}`;
|
|
937
928
|
button.innerHTML = `${esc(protocol.charAt(0).toUpperCase() + protocol.slice(1))}${sidebarConfig.showCounts !== false ? `<span class="count">${protocolData[protocol]}</span>` : ''}`;
|
|
938
929
|
button.onclick = () => {
|
|
939
930
|
activeProtocol = protocol;
|
|
@@ -1053,14 +1044,7 @@ function renderSidebar() {
|
|
|
1053
1044
|
return;
|
|
1054
1045
|
nav.textContent = '';
|
|
1055
1046
|
renderDocsPagesNav(nav);
|
|
1056
|
-
|
|
1057
|
-
// The docs root (`/`) is NOT a page — it's the overview, so it must list
|
|
1058
|
-
// the active protocol's endpoints, expanded, like the old empty-path state.
|
|
1059
|
-
const matchedPage = activePagePath
|
|
1060
|
-
? getDocsPageViews().some((p) => p.path === activePagePath)
|
|
1061
|
-
: false;
|
|
1062
|
-
const isRoot = !activePagePath || activePagePath === '/';
|
|
1063
|
-
if (matchedPage || !isRoot)
|
|
1047
|
+
if (activePagePath)
|
|
1064
1048
|
return;
|
|
1065
1049
|
const endpoints = getEndpointsForProtocol(activeProtocol).filter(endpoint => !searchQuery ||
|
|
1066
1050
|
endpoint.path.toLowerCase().includes(searchQuery) ||
|
|
@@ -1819,19 +1803,16 @@ function renderContent() {
|
|
|
1819
1803
|
scrollToActiveHeading();
|
|
1820
1804
|
return;
|
|
1821
1805
|
}
|
|
1822
|
-
|
|
1823
|
-
// non-root path with no matching page is a genuine 404.
|
|
1824
|
-
const isRoot = !activePagePath || activePagePath === '/';
|
|
1825
|
-
if (activePagePath && !isRoot) {
|
|
1806
|
+
if (activePagePath) {
|
|
1826
1807
|
renderMissingDocsPage(main);
|
|
1827
1808
|
renderToc(main);
|
|
1828
1809
|
return;
|
|
1829
1810
|
}
|
|
1830
|
-
|
|
1831
|
-
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
main.appendChild(
|
|
1811
|
+
if (!searchQuery && spec.info?.description) {
|
|
1812
|
+
const intro = doc.createElement('div');
|
|
1813
|
+
intro.className = 'intro-section';
|
|
1814
|
+
intro.innerHTML = `<div class="markdown-content">${parseMarkdown(spec.info.description)}</div>`;
|
|
1815
|
+
main.appendChild(intro);
|
|
1835
1816
|
}
|
|
1836
1817
|
if (searchQuery)
|
|
1837
1818
|
renderDocsSearch(main);
|
|
@@ -1848,67 +1829,6 @@ function renderContent() {
|
|
|
1848
1829
|
}
|
|
1849
1830
|
renderToc(main);
|
|
1850
1831
|
}
|
|
1851
|
-
function renderDocsOverview() {
|
|
1852
|
-
const info = (spec.info ?? {});
|
|
1853
|
-
const container = doc.createElement('div');
|
|
1854
|
-
container.className = 'docs-overview';
|
|
1855
|
-
const title = String(info.title ?? 'API');
|
|
1856
|
-
const versionBadge = info.version
|
|
1857
|
-
? `<span class="docs-overview-version">${esc(String(info.version))}</span>`
|
|
1858
|
-
: '';
|
|
1859
|
-
const header = doc.createElement('header');
|
|
1860
|
-
header.className = 'docs-overview-header';
|
|
1861
|
-
header.innerHTML = `<h1 class="docs-overview-title" id="overview">${esc(title)}${versionBadge}</h1>`;
|
|
1862
|
-
container.appendChild(header);
|
|
1863
|
-
// Contact / license line (ReDoc-style).
|
|
1864
|
-
const contact = (info.contact ?? {});
|
|
1865
|
-
const license = (info.license ?? {});
|
|
1866
|
-
const metaBits = [];
|
|
1867
|
-
if (contact.email) {
|
|
1868
|
-
const label = esc(String(contact.name ?? contact.email));
|
|
1869
|
-
metaBits.push(`E-mail: <a href="mailto:${esc(String(contact.email))}">${label}</a>`);
|
|
1870
|
-
}
|
|
1871
|
-
if (contact.url) {
|
|
1872
|
-
metaBits.push(`URL: <a href="${esc(String(contact.url))}" target="_blank" rel="noopener">${esc(String(contact.url))}</a>`);
|
|
1873
|
-
}
|
|
1874
|
-
if (license.name) {
|
|
1875
|
-
const lic = license.url
|
|
1876
|
-
? `<a href="${esc(String(license.url))}" target="_blank" rel="noopener">${esc(String(license.name))}</a>`
|
|
1877
|
-
: esc(String(license.name));
|
|
1878
|
-
metaBits.push(`License: ${lic}`);
|
|
1879
|
-
}
|
|
1880
|
-
if (metaBits.length) {
|
|
1881
|
-
const meta = doc.createElement('div');
|
|
1882
|
-
meta.className = 'docs-overview-meta';
|
|
1883
|
-
meta.innerHTML = metaBits.join('<span class="docs-overview-meta-sep">·</span>');
|
|
1884
|
-
container.appendChild(meta);
|
|
1885
|
-
}
|
|
1886
|
-
// Servers — straight from `spec.servers`.
|
|
1887
|
-
const servers = Array.isArray(spec.servers) ? spec.servers : [];
|
|
1888
|
-
if (servers.length) {
|
|
1889
|
-
const section = doc.createElement('section');
|
|
1890
|
-
section.className = 'docs-overview-servers';
|
|
1891
|
-
const rows = servers
|
|
1892
|
-
.map((s) => {
|
|
1893
|
-
const url = esc(String(s?.url ?? ''));
|
|
1894
|
-
const desc = s?.description
|
|
1895
|
-
? `<span class="docs-overview-server-desc">${esc(String(s.description))}</span>`
|
|
1896
|
-
: '';
|
|
1897
|
-
return `<li class="docs-overview-server"><code class="docs-overview-server-url">${url}</code>${desc}</li>`;
|
|
1898
|
-
})
|
|
1899
|
-
.join('');
|
|
1900
|
-
section.innerHTML = `<h2 class="docs-overview-subtitle">${servers.length > 1 ? 'Servers' : 'Server'}</h2><ul class="docs-overview-server-list">${rows}</ul>`;
|
|
1901
|
-
container.appendChild(section);
|
|
1902
|
-
}
|
|
1903
|
-
// Description (markdown).
|
|
1904
|
-
if (info.description) {
|
|
1905
|
-
const description = doc.createElement('div');
|
|
1906
|
-
description.className = 'docs-overview-description markdown-content';
|
|
1907
|
-
description.innerHTML = parseMarkdown(String(info.description));
|
|
1908
|
-
container.appendChild(description);
|
|
1909
|
-
}
|
|
1910
|
-
return container;
|
|
1911
|
-
}
|
|
1912
1832
|
function renderMissingDocsPage(main) {
|
|
1913
1833
|
const notFound = getDocsPageViews().find(page => page.path === '/404' || page.path.endsWith('/404'));
|
|
1914
1834
|
const article = doc.createElement('article');
|