@blaaiz/docs-core 0.4.0 → 0.6.0
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/{chunk-JHN5XQPU.js → chunk-2GUUVNTP.js} +226 -31
- package/dist/chunk-2GUUVNTP.js.map +1 -0
- package/dist/{chunk-ZKOOKLZ3.js → chunk-6H6OB7YP.js} +17 -2
- package/dist/chunk-6H6OB7YP.js.map +1 -0
- package/dist/generator.cjs +204 -30
- package/dist/generator.cjs.map +1 -1
- package/dist/generator.d.cts +24 -0
- package/dist/generator.d.ts +24 -0
- package/dist/generator.js +179 -22
- package/dist/generator.js.map +1 -1
- package/dist/index.cjs +228 -28
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +267 -8
- package/dist/index.d.ts +267 -8
- package/dist/index.js +1 -1
- package/dist/{navigation-CGqFIPlP.d.cts → navigation-DvgyWSZ4.d.cts} +22 -1
- package/dist/{navigation-CGqFIPlP.d.ts → navigation-DvgyWSZ4.d.ts} +22 -1
- package/dist/ui/api-try-it.cjs +15 -0
- package/dist/ui/api-try-it.cjs.map +1 -1
- package/dist/ui/api-try-it.js +1 -1
- package/dist/ui/ask-ai.cjs +26 -6
- package/dist/ui/ask-ai.cjs.map +1 -1
- package/dist/ui/ask-ai.d.cts +6 -1
- package/dist/ui/ask-ai.d.ts +6 -1
- package/dist/ui/ask-ai.js +26 -6
- package/dist/ui/ask-ai.js.map +1 -1
- package/dist/ui/copy-page.cjs +15 -0
- package/dist/ui/copy-page.cjs.map +1 -1
- package/dist/ui/copy-page.js +1 -1
- package/dist/ui.cjs +77 -6
- package/dist/ui.cjs.map +1 -1
- package/dist/ui.d.cts +99 -8
- package/dist/ui.d.ts +99 -8
- package/dist/ui.js +62 -8
- package/dist/ui.js.map +1 -1
- package/package.json +1 -1
- package/skills/SKILL.md +73 -27
- package/styles/api-reference.css +45 -2
- package/styles/ask-ai.css +28 -0
- package/styles/docs.css +96 -1
- package/styles/home.css +34 -1
- package/dist/chunk-JHN5XQPU.js.map +0 -1
- package/dist/chunk-ZKOOKLZ3.js.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -1363,6 +1363,22 @@ function validateFeatures(value) {
|
|
|
1363
1363
|
}
|
|
1364
1364
|
optionalBoolean(features["copyPage"], "features.copyPage");
|
|
1365
1365
|
}
|
|
1366
|
+
function validateNavbarAction(value, field) {
|
|
1367
|
+
const action = optionalObject(value, field);
|
|
1368
|
+
if (action === void 0) {
|
|
1369
|
+
return;
|
|
1370
|
+
}
|
|
1371
|
+
requireString(action["text"], `${field}.text`, "Example: 'Dashboard'.");
|
|
1372
|
+
requireString(action["href"], `${field}.href`, "Example: 'https://app.example.com'.");
|
|
1373
|
+
}
|
|
1374
|
+
function validateNavbar(value) {
|
|
1375
|
+
const navbar = optionalObject(value, "navbar");
|
|
1376
|
+
if (navbar === void 0) {
|
|
1377
|
+
return;
|
|
1378
|
+
}
|
|
1379
|
+
validateNavbarAction(navbar["primary"], "navbar.primary");
|
|
1380
|
+
validateNavbarAction(navbar["secondary"], "navbar.secondary");
|
|
1381
|
+
}
|
|
1366
1382
|
function validateSeo(value) {
|
|
1367
1383
|
const seo = optionalObject(value, "seo");
|
|
1368
1384
|
if (seo === void 0) {
|
|
@@ -1413,6 +1429,7 @@ function validateDocsConfig(config) {
|
|
|
1413
1429
|
validateTheme(config["theme"]);
|
|
1414
1430
|
validateAuth(config["auth"]);
|
|
1415
1431
|
validateProxy(config["proxy"]);
|
|
1432
|
+
validateNavbar(config["navbar"]);
|
|
1416
1433
|
validateFeatures(config["features"]);
|
|
1417
1434
|
validateSeo(config["seo"]);
|
|
1418
1435
|
if (config["ai"] !== void 0) {
|
|
@@ -1460,6 +1477,90 @@ function buildThemeCss(theme) {
|
|
|
1460
1477
|
return blocks.join("\n");
|
|
1461
1478
|
}
|
|
1462
1479
|
|
|
1480
|
+
// src/core/redirects.ts
|
|
1481
|
+
function redirectTarget(url, redirects) {
|
|
1482
|
+
const { pathname } = url;
|
|
1483
|
+
const markdown = pathname.endsWith(".md");
|
|
1484
|
+
const page = markdown ? pathname.slice(0, -3) : pathname;
|
|
1485
|
+
const destination = redirects[page];
|
|
1486
|
+
if (destination === void 0) {
|
|
1487
|
+
return null;
|
|
1488
|
+
}
|
|
1489
|
+
const target = new URL(url);
|
|
1490
|
+
target.pathname = markdown ? `${destination}.md` : destination;
|
|
1491
|
+
return target;
|
|
1492
|
+
}
|
|
1493
|
+
|
|
1494
|
+
// src/core/llms-txt.ts
|
|
1495
|
+
function buildLlmsTxt(pages, options) {
|
|
1496
|
+
const origin = options.origin?.replace(/\/$/, "") ?? "";
|
|
1497
|
+
const lines = [`# ${options.name}`];
|
|
1498
|
+
if (options.description !== void 0 && options.description !== "") {
|
|
1499
|
+
lines.push("", `> ${options.description}`);
|
|
1500
|
+
}
|
|
1501
|
+
lines.push("", "## Docs", "");
|
|
1502
|
+
for (const page of pages) {
|
|
1503
|
+
const link = `[${page.title}](${origin}${page.url}.md)`;
|
|
1504
|
+
lines.push(
|
|
1505
|
+
page.description === void 0 || page.description === "" ? `- ${link}` : `- ${link}: ${page.description}`
|
|
1506
|
+
);
|
|
1507
|
+
}
|
|
1508
|
+
lines.push("");
|
|
1509
|
+
return lines.join("\n");
|
|
1510
|
+
}
|
|
1511
|
+
|
|
1512
|
+
// src/core/code-samples.ts
|
|
1513
|
+
function singleQuote(value) {
|
|
1514
|
+
return `'${value.replaceAll("'", "'\\''")}'`;
|
|
1515
|
+
}
|
|
1516
|
+
function isRecord(value) {
|
|
1517
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
1518
|
+
}
|
|
1519
|
+
function bodyToString(body, mediaType) {
|
|
1520
|
+
if (typeof body === "string") {
|
|
1521
|
+
return body;
|
|
1522
|
+
}
|
|
1523
|
+
if (mediaType === "application/x-www-form-urlencoded" && isRecord(body)) {
|
|
1524
|
+
const params = new URLSearchParams();
|
|
1525
|
+
for (const [key, value] of Object.entries(body)) {
|
|
1526
|
+
if (value === void 0 || value === null) {
|
|
1527
|
+
continue;
|
|
1528
|
+
}
|
|
1529
|
+
const encoded = typeof value === "string" || typeof value === "number" || typeof value === "boolean" ? String(value) : JSON.stringify(value);
|
|
1530
|
+
params.set(key, encoded);
|
|
1531
|
+
}
|
|
1532
|
+
return params.toString();
|
|
1533
|
+
}
|
|
1534
|
+
if (mediaType === "application/x-ndjson" && Array.isArray(body)) {
|
|
1535
|
+
return body.map((entry) => JSON.stringify(entry)).join("\n");
|
|
1536
|
+
}
|
|
1537
|
+
return JSON.stringify(body, null, 2);
|
|
1538
|
+
}
|
|
1539
|
+
var curlCodeUsage = {
|
|
1540
|
+
label: "cURL",
|
|
1541
|
+
lang: "bash",
|
|
1542
|
+
generate(data) {
|
|
1543
|
+
const lines = [`curl --request ${data.method.toUpperCase()}`, `--url ${singleQuote(data.url)}`];
|
|
1544
|
+
for (const [name, param] of Object.entries(data.header ?? {})) {
|
|
1545
|
+
lines.push(`--header ${singleQuote(`${name}: ${param.value}`)}`);
|
|
1546
|
+
}
|
|
1547
|
+
for (const [name, param] of Object.entries(data.cookie ?? {})) {
|
|
1548
|
+
lines.push(`--cookie ${singleQuote(`${name}=${param.value}`)}`);
|
|
1549
|
+
}
|
|
1550
|
+
if (isRecord(data.body) && data.bodyMediaType === "multipart/form-data") {
|
|
1551
|
+
for (const [key, value] of Object.entries(data.body)) {
|
|
1552
|
+
lines.push(
|
|
1553
|
+
`--form ${singleQuote(`${key}=${typeof value === "string" ? value : JSON.stringify(value)}`)}`
|
|
1554
|
+
);
|
|
1555
|
+
}
|
|
1556
|
+
} else if (data.body !== void 0 && data.body !== null && data.bodyMediaType !== void 0) {
|
|
1557
|
+
lines.push(`--header ${singleQuote(`Content-Type: ${data.bodyMediaType}`)}`);
|
|
1558
|
+
lines.push(`--data ${singleQuote(bodyToString(data.body, data.bodyMediaType))}`);
|
|
1559
|
+
}
|
|
1560
|
+
return lines.map((line, i) => i === 0 ? line : ` ${line}`).join(" \\\n");
|
|
1561
|
+
}
|
|
1562
|
+
};
|
|
1563
|
+
|
|
1463
1564
|
// src/core/seo.ts
|
|
1464
1565
|
function trimTrailingSlash(value) {
|
|
1465
1566
|
return value.replace(/\/+$/, "");
|
|
@@ -1562,12 +1663,13 @@ function firstDocFile(items) {
|
|
|
1562
1663
|
}
|
|
1563
1664
|
function planDocsTree(navigation, options = {}) {
|
|
1564
1665
|
const apiDir = options.apiDir ?? "api";
|
|
1666
|
+
const headings = (options.sidebar ?? "collapsible") === "headings";
|
|
1565
1667
|
const specs = [];
|
|
1566
1668
|
const apiPages = [];
|
|
1567
1669
|
const apiGroups = [];
|
|
1568
1670
|
const metas = [];
|
|
1569
1671
|
const rootPages = [];
|
|
1570
|
-
const
|
|
1672
|
+
const apiDocLinks = [];
|
|
1571
1673
|
const apiTabs = navigation.filter((tab) => hasOpenApi(tab.items));
|
|
1572
1674
|
const soleApiTab = apiTabs.length === 1;
|
|
1573
1675
|
for (const tab of navigation) {
|
|
@@ -1578,7 +1680,7 @@ function planDocsTree(navigation, options = {}) {
|
|
|
1578
1680
|
planDocTab(tab);
|
|
1579
1681
|
}
|
|
1580
1682
|
metas.unshift({ path: "meta.json", content: { pages: rootPages } });
|
|
1581
|
-
return { specs, apiPages, apiGroups, metas,
|
|
1683
|
+
return { specs, apiPages, apiGroups, metas, apiDocLinks };
|
|
1582
1684
|
function planApiTab(tab) {
|
|
1583
1685
|
const tabDir = soleApiTab ? apiDir : slugify(tab.title);
|
|
1584
1686
|
rootPages.push(tabDir);
|
|
@@ -1609,7 +1711,7 @@ function planDocsTree(navigation, options = {}) {
|
|
|
1609
1711
|
const at = apiGroups.length;
|
|
1610
1712
|
const sub = planApiItems(item.items, childDir);
|
|
1611
1713
|
apiGroups.splice(at, 0, { dir: childDir, title: item.title, children: sub });
|
|
1612
|
-
children.push({ order, folder });
|
|
1714
|
+
children.push({ order, folder, title: item.title });
|
|
1613
1715
|
order += 1;
|
|
1614
1716
|
continue;
|
|
1615
1717
|
}
|
|
@@ -1621,7 +1723,8 @@ function planDocsTree(navigation, options = {}) {
|
|
|
1621
1723
|
order += 1;
|
|
1622
1724
|
continue;
|
|
1623
1725
|
}
|
|
1624
|
-
|
|
1726
|
+
apiDocLinks.push({ file: item.file, dir, order });
|
|
1727
|
+
order += 1;
|
|
1625
1728
|
}
|
|
1626
1729
|
return children;
|
|
1627
1730
|
}
|
|
@@ -1646,11 +1749,11 @@ function planDocsTree(navigation, options = {}) {
|
|
|
1646
1749
|
title: tab.title,
|
|
1647
1750
|
root: true,
|
|
1648
1751
|
...tab.icon ? { icon: tab.icon } : {},
|
|
1649
|
-
pages: planDocItems(tab.items, tabDir)
|
|
1752
|
+
pages: planDocItems(tab.items, tabDir, true)
|
|
1650
1753
|
}
|
|
1651
1754
|
});
|
|
1652
1755
|
}
|
|
1653
|
-
function planDocItems(items, dir) {
|
|
1756
|
+
function planDocItems(items, dir, tabLevel) {
|
|
1654
1757
|
const entries = [];
|
|
1655
1758
|
for (const item of items) {
|
|
1656
1759
|
if (item.kind === "doc") {
|
|
@@ -1665,10 +1768,18 @@ function planDocsTree(navigation, options = {}) {
|
|
|
1665
1768
|
continue;
|
|
1666
1769
|
}
|
|
1667
1770
|
if (groupDir === dir) {
|
|
1668
|
-
|
|
1771
|
+
if (headings) {
|
|
1772
|
+
entries.push(`---${item.title}---`);
|
|
1773
|
+
}
|
|
1774
|
+
entries.push(...planDocItems(item.items, dir, false));
|
|
1775
|
+
continue;
|
|
1776
|
+
}
|
|
1777
|
+
const folder = groupDir.slice(dir.length + 1);
|
|
1778
|
+
if (headings && tabLevel) {
|
|
1779
|
+
entries.push(`---${item.title}---`, `...${folder}`);
|
|
1669
1780
|
continue;
|
|
1670
1781
|
}
|
|
1671
|
-
entries.push(
|
|
1782
|
+
entries.push(folder);
|
|
1672
1783
|
}
|
|
1673
1784
|
return entries;
|
|
1674
1785
|
}
|
|
@@ -1683,7 +1794,14 @@ function planDocsTree(navigation, options = {}) {
|
|
|
1683
1794
|
}
|
|
1684
1795
|
metas.push({
|
|
1685
1796
|
path: `${groupDir}/meta.json`,
|
|
1686
|
-
content: {
|
|
1797
|
+
content: {
|
|
1798
|
+
title: group.title,
|
|
1799
|
+
// A nested group starts closed in the headings style, whatever the
|
|
1800
|
+
// site's defaultOpenLevel. On a tab-level group the flag is inert:
|
|
1801
|
+
// that folder is extracted, so no folder node renders it.
|
|
1802
|
+
...headings ? { defaultOpen: false } : {},
|
|
1803
|
+
pages: planDocItems(group.items, groupDir, false)
|
|
1804
|
+
}
|
|
1687
1805
|
});
|
|
1688
1806
|
return groupDir;
|
|
1689
1807
|
}
|
|
@@ -2116,10 +2234,67 @@ ${description ? `${description}
|
|
|
2116
2234
|
` : ""}${cleanBody(trimmedBody)}
|
|
2117
2235
|
`;
|
|
2118
2236
|
}
|
|
2237
|
+
function operationHead(operation) {
|
|
2238
|
+
let title;
|
|
2239
|
+
let description;
|
|
2240
|
+
try {
|
|
2241
|
+
const parsed = JSON.parse(operation.source);
|
|
2242
|
+
const exact = parsed.paths?.[operation.route]?.[operation.method.toLowerCase()];
|
|
2243
|
+
const first = Object.values(parsed.paths ?? {}).flatMap((item) => Object.values(item))[0];
|
|
2244
|
+
const named = exact ?? first;
|
|
2245
|
+
title = named?.summary ?? parsed.info?.title;
|
|
2246
|
+
description = named?.description ?? parsed.info?.description;
|
|
2247
|
+
} catch {
|
|
2248
|
+
}
|
|
2249
|
+
const head = [`# ${title ?? "API operation"}`];
|
|
2250
|
+
if (description !== void 0 && description !== "") {
|
|
2251
|
+
head.push("", `> ${description.replace(/\n/g, "\n> ")}`);
|
|
2252
|
+
}
|
|
2253
|
+
return head.join("\n");
|
|
2254
|
+
}
|
|
2255
|
+
function fenceFor(source) {
|
|
2256
|
+
const longest = source.match(/`+/g)?.reduce((max, run) => Math.max(max, run.length), 0) ?? 0;
|
|
2257
|
+
return "`".repeat(Math.max(4, longest + 1));
|
|
2258
|
+
}
|
|
2119
2259
|
function createMarkdownRoute(options) {
|
|
2260
|
+
const requestOrigin = (request) => {
|
|
2261
|
+
const url = new URL(request.url);
|
|
2262
|
+
const proto = request.headers.get("x-forwarded-proto") ?? url.protocol.replace(/:$/, "");
|
|
2263
|
+
const host = request.headers.get("x-forwarded-host") ?? request.headers.get("host") ?? url.host;
|
|
2264
|
+
return `${proto}://${host}`;
|
|
2265
|
+
};
|
|
2266
|
+
const respond = (request, markdown) => {
|
|
2267
|
+
const preamble = options.llmsTxtPath === void 0 ? "" : [
|
|
2268
|
+
"> ## Documentation Index",
|
|
2269
|
+
`> Fetch the complete documentation index at: ${requestOrigin(request)}${options.llmsTxtPath}`,
|
|
2270
|
+
"> Use this file to discover all available pages before exploring further.",
|
|
2271
|
+
"",
|
|
2272
|
+
""
|
|
2273
|
+
].join("\n");
|
|
2274
|
+
return new Response(`${preamble}${markdown}`, {
|
|
2275
|
+
headers: { "content-type": "text/plain; charset=utf-8" }
|
|
2276
|
+
});
|
|
2277
|
+
};
|
|
2120
2278
|
return {
|
|
2121
|
-
async GET(
|
|
2279
|
+
async GET(request, context) {
|
|
2122
2280
|
const { slug } = await context.params;
|
|
2281
|
+
const operation = await options.loadOperationSource?.(slug);
|
|
2282
|
+
if (operation) {
|
|
2283
|
+
const fence = fenceFor(operation.source);
|
|
2284
|
+
return respond(
|
|
2285
|
+
request,
|
|
2286
|
+
[
|
|
2287
|
+
operationHead(operation),
|
|
2288
|
+
"",
|
|
2289
|
+
"## OpenAPI",
|
|
2290
|
+
"",
|
|
2291
|
+
`${fence}json ${operation.file} ${operation.method.toLowerCase()} ${operation.route}`,
|
|
2292
|
+
operation.source.trimEnd(),
|
|
2293
|
+
fence,
|
|
2294
|
+
""
|
|
2295
|
+
].join("\n")
|
|
2296
|
+
);
|
|
2297
|
+
}
|
|
2123
2298
|
const raw = await options.read(slug);
|
|
2124
2299
|
if (raw === null) {
|
|
2125
2300
|
return new Response("Not found", { status: 404 });
|
|
@@ -2133,12 +2308,32 @@ function createMarkdownRoute(options) {
|
|
|
2133
2308
|
if (markdown === null) {
|
|
2134
2309
|
return new Response("Not found", { status: 404 });
|
|
2135
2310
|
}
|
|
2136
|
-
return
|
|
2137
|
-
headers: { "content-type": "text/plain; charset=utf-8" }
|
|
2138
|
-
});
|
|
2311
|
+
return respond(request, markdown);
|
|
2139
2312
|
}
|
|
2140
2313
|
};
|
|
2141
2314
|
}
|
|
2315
|
+
function markdownRewriteTarget(url, options = {}) {
|
|
2316
|
+
const baseUrl = (options.baseUrl ?? "/docs").replace(/\/+$/, "");
|
|
2317
|
+
const markdownBase = (options.markdownBase ?? "/md").replace(/\/+$/, "");
|
|
2318
|
+
const { pathname } = url;
|
|
2319
|
+
if (!pathname.endsWith(".md") || pathname.includes("%")) {
|
|
2320
|
+
return null;
|
|
2321
|
+
}
|
|
2322
|
+
const page = pathname.slice(0, -3);
|
|
2323
|
+
if (page !== baseUrl && !page.startsWith(`${baseUrl}/`)) {
|
|
2324
|
+
return null;
|
|
2325
|
+
}
|
|
2326
|
+
if (page.endsWith("/") || page.includes("//")) {
|
|
2327
|
+
return null;
|
|
2328
|
+
}
|
|
2329
|
+
const target = new URL(url);
|
|
2330
|
+
target.pathname = `${markdownBase}${page.slice(baseUrl.length)}`;
|
|
2331
|
+
return target;
|
|
2332
|
+
}
|
|
2333
|
+
function isMarkdownRouteRequest(url, options = {}) {
|
|
2334
|
+
const markdownBase = options.markdownBase ?? "/md";
|
|
2335
|
+
return url.pathname === markdownBase || url.pathname.startsWith(`${markdownBase}/`);
|
|
2336
|
+
}
|
|
2142
2337
|
|
|
2143
2338
|
// src/core/auth/domains.ts
|
|
2144
2339
|
function isAllowedEmail(email, allowedDomains) {
|
|
@@ -2922,7 +3117,7 @@ var InvalidNavigationError = class extends Error {
|
|
|
2922
3117
|
this.name = "InvalidNavigationError";
|
|
2923
3118
|
}
|
|
2924
3119
|
};
|
|
2925
|
-
function
|
|
3120
|
+
function isRecord2(value) {
|
|
2926
3121
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
2927
3122
|
}
|
|
2928
3123
|
function parsePageString(entry) {
|
|
@@ -2945,7 +3140,7 @@ function parseItem(entry, path) {
|
|
|
2945
3140
|
if (typeof entry === "string") {
|
|
2946
3141
|
return parsePageString(entry);
|
|
2947
3142
|
}
|
|
2948
|
-
if (
|
|
3143
|
+
if (isRecord2(entry) && typeof entry["group"] === "string") {
|
|
2949
3144
|
return parseGroup(entry, path);
|
|
2950
3145
|
}
|
|
2951
3146
|
throw new InvalidNavigationError(
|
|
@@ -2970,7 +3165,7 @@ function parseGroup(group, path) {
|
|
|
2970
3165
|
};
|
|
2971
3166
|
}
|
|
2972
3167
|
function parseTab(tab, path) {
|
|
2973
|
-
if (!
|
|
3168
|
+
if (!isRecord2(tab) || typeof tab["tab"] !== "string") {
|
|
2974
3169
|
throw new InvalidNavigationError(`Tab at ${path} is missing a string "tab" title.`);
|
|
2975
3170
|
}
|
|
2976
3171
|
const items = tab["groups"] !== void 0 ? parseGroups(tab["groups"], `${path}.groups`) : parseItems(tab["pages"], `${path}.pages`);
|
|
@@ -2988,18 +3183,18 @@ function parseGroups(groups, path) {
|
|
|
2988
3183
|
}
|
|
2989
3184
|
return groups.map((group, index) => {
|
|
2990
3185
|
const groupPath = `${path}[${String(index)}]`;
|
|
2991
|
-
if (!
|
|
3186
|
+
if (!isRecord2(group)) {
|
|
2992
3187
|
throw new InvalidNavigationError(`Group at ${groupPath} must be an object.`);
|
|
2993
3188
|
}
|
|
2994
3189
|
return parseGroup(group, groupPath);
|
|
2995
3190
|
});
|
|
2996
3191
|
}
|
|
2997
3192
|
function parseNavigation(docsJson) {
|
|
2998
|
-
if (!
|
|
3193
|
+
if (!isRecord2(docsJson)) {
|
|
2999
3194
|
throw new InvalidNavigationError("docs.json must be an object.");
|
|
3000
3195
|
}
|
|
3001
3196
|
const navigation = docsJson["navigation"];
|
|
3002
|
-
if (!
|
|
3197
|
+
if (!isRecord2(navigation)) {
|
|
3003
3198
|
throw new InvalidNavigationError('docs.json must have a "navigation" object.');
|
|
3004
3199
|
}
|
|
3005
3200
|
const tabs = navigation["tabs"];
|
|
@@ -3016,7 +3211,7 @@ var OpenApiMergeError = class extends Error {
|
|
|
3016
3211
|
this.name = "OpenApiMergeError";
|
|
3017
3212
|
}
|
|
3018
3213
|
};
|
|
3019
|
-
function
|
|
3214
|
+
function isRecord3(value) {
|
|
3020
3215
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
3021
3216
|
}
|
|
3022
3217
|
function collectServers(inputs, override) {
|
|
@@ -3030,7 +3225,7 @@ function collectServers(inputs, override) {
|
|
|
3030
3225
|
continue;
|
|
3031
3226
|
}
|
|
3032
3227
|
for (const server of servers) {
|
|
3033
|
-
if (
|
|
3228
|
+
if (isRecord3(server) && typeof server["url"] === "string" && !byUrl.has(server["url"])) {
|
|
3034
3229
|
byUrl.set(server["url"], server);
|
|
3035
3230
|
}
|
|
3036
3231
|
}
|
|
@@ -3045,7 +3240,7 @@ function collectTags(inputs) {
|
|
|
3045
3240
|
continue;
|
|
3046
3241
|
}
|
|
3047
3242
|
for (const tag of tags) {
|
|
3048
|
-
if (
|
|
3243
|
+
if (isRecord3(tag) && typeof tag["name"] === "string" && !byName.has(tag["name"])) {
|
|
3049
3244
|
byName.set(tag["name"], tag);
|
|
3050
3245
|
}
|
|
3051
3246
|
}
|
|
@@ -3056,11 +3251,11 @@ function mergeComponents(inputs) {
|
|
|
3056
3251
|
const merged = {};
|
|
3057
3252
|
for (const doc of inputs) {
|
|
3058
3253
|
const components = doc["components"];
|
|
3059
|
-
if (!
|
|
3254
|
+
if (!isRecord3(components)) {
|
|
3060
3255
|
continue;
|
|
3061
3256
|
}
|
|
3062
3257
|
for (const [section, value] of Object.entries(components)) {
|
|
3063
|
-
if (!
|
|
3258
|
+
if (!isRecord3(value)) {
|
|
3064
3259
|
continue;
|
|
3065
3260
|
}
|
|
3066
3261
|
const target = merged[section] ?? (merged[section] = {});
|
|
@@ -3078,12 +3273,12 @@ function assemblePaths(inputs) {
|
|
|
3078
3273
|
const paths = {};
|
|
3079
3274
|
for (const doc of inputs) {
|
|
3080
3275
|
const docPaths = doc["paths"];
|
|
3081
|
-
if (!
|
|
3276
|
+
if (!isRecord3(docPaths)) {
|
|
3082
3277
|
throw new OpenApiMergeError('Each OpenAPI input must have a "paths" object.');
|
|
3083
3278
|
}
|
|
3084
3279
|
const docSecurity = doc["security"];
|
|
3085
3280
|
for (const [route, pathItem] of Object.entries(docPaths)) {
|
|
3086
|
-
if (!
|
|
3281
|
+
if (!isRecord3(pathItem)) {
|
|
3087
3282
|
throw new OpenApiMergeError(`Path item for "${route}" must be an object.`);
|
|
3088
3283
|
}
|
|
3089
3284
|
const target = paths[route] ?? (paths[route] = {});
|
|
@@ -3094,7 +3289,7 @@ function assemblePaths(inputs) {
|
|
|
3094
3289
|
);
|
|
3095
3290
|
}
|
|
3096
3291
|
let resolved = operation;
|
|
3097
|
-
if (HTTP_METHODS2.has(method.toLowerCase()) &&
|
|
3292
|
+
if (HTTP_METHODS2.has(method.toLowerCase()) && isRecord3(operation) && !("security" in operation) && Array.isArray(docSecurity)) {
|
|
3098
3293
|
resolved = { ...operation, security: docSecurity };
|
|
3099
3294
|
}
|
|
3100
3295
|
target[method] = resolved;
|
|
@@ -3105,7 +3300,7 @@ function assemblePaths(inputs) {
|
|
|
3105
3300
|
}
|
|
3106
3301
|
function mergeOpenApiDocuments(inputs, options) {
|
|
3107
3302
|
const records = inputs.map((input, index) => {
|
|
3108
|
-
if (!
|
|
3303
|
+
if (!isRecord3(input)) {
|
|
3109
3304
|
throw new OpenApiMergeError(`OpenAPI input at index ${String(index)} must be an object.`);
|
|
3110
3305
|
}
|
|
3111
3306
|
return input;
|
|
@@ -3129,6 +3324,7 @@ exports.OpenApiMergeError = OpenApiMergeError;
|
|
|
3129
3324
|
exports.ProxyTargetError = ProxyTargetError;
|
|
3130
3325
|
exports.SESSION_COOKIE = SESSION_COOKIE;
|
|
3131
3326
|
exports.assertAllowedTarget = assertAllowedTarget;
|
|
3327
|
+
exports.buildLlmsTxt = buildLlmsTxt;
|
|
3132
3328
|
exports.buildMetadata = buildMetadata;
|
|
3133
3329
|
exports.buildRobots = buildRobots;
|
|
3134
3330
|
exports.buildSearchIndex = buildSearchIndex;
|
|
@@ -3146,14 +3342,18 @@ exports.createSignOut = createSignOut;
|
|
|
3146
3342
|
exports.createSiteAuth = createSiteAuth;
|
|
3147
3343
|
exports.createTryItProxy = createTryItProxy;
|
|
3148
3344
|
exports.createTryItProxyRoute = createTryItProxyRoute;
|
|
3345
|
+
exports.curlCodeUsage = curlCodeUsage;
|
|
3149
3346
|
exports.defineDocsConfig = defineDocsConfig;
|
|
3150
3347
|
exports.isAllowedEmail = isAllowedEmail;
|
|
3348
|
+
exports.isMarkdownRouteRequest = isMarkdownRouteRequest;
|
|
3349
|
+
exports.markdownRewriteTarget = markdownRewriteTarget;
|
|
3151
3350
|
exports.mdxToMarkdown = mdxToMarkdown;
|
|
3152
3351
|
exports.mergeOpenApiDocuments = mergeOpenApiDocuments;
|
|
3153
3352
|
exports.openApiOperationToMarkdown = openApiOperationToMarkdown;
|
|
3154
3353
|
exports.parseNavigation = parseNavigation;
|
|
3155
3354
|
exports.planDocsTree = planDocsTree;
|
|
3156
3355
|
exports.readCookie = readCookie;
|
|
3356
|
+
exports.redirectTarget = redirectTarget;
|
|
3157
3357
|
exports.resolveAiConfig = resolveAiConfig;
|
|
3158
3358
|
exports.searchIndex = searchIndex;
|
|
3159
3359
|
exports.signSession = signSession;
|