@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.
Files changed (43) hide show
  1. package/dist/{chunk-JHN5XQPU.js → chunk-2GUUVNTP.js} +226 -31
  2. package/dist/chunk-2GUUVNTP.js.map +1 -0
  3. package/dist/{chunk-ZKOOKLZ3.js → chunk-6H6OB7YP.js} +17 -2
  4. package/dist/chunk-6H6OB7YP.js.map +1 -0
  5. package/dist/generator.cjs +204 -30
  6. package/dist/generator.cjs.map +1 -1
  7. package/dist/generator.d.cts +24 -0
  8. package/dist/generator.d.ts +24 -0
  9. package/dist/generator.js +179 -22
  10. package/dist/generator.js.map +1 -1
  11. package/dist/index.cjs +228 -28
  12. package/dist/index.cjs.map +1 -1
  13. package/dist/index.d.cts +267 -8
  14. package/dist/index.d.ts +267 -8
  15. package/dist/index.js +1 -1
  16. package/dist/{navigation-CGqFIPlP.d.cts → navigation-DvgyWSZ4.d.cts} +22 -1
  17. package/dist/{navigation-CGqFIPlP.d.ts → navigation-DvgyWSZ4.d.ts} +22 -1
  18. package/dist/ui/api-try-it.cjs +15 -0
  19. package/dist/ui/api-try-it.cjs.map +1 -1
  20. package/dist/ui/api-try-it.js +1 -1
  21. package/dist/ui/ask-ai.cjs +26 -6
  22. package/dist/ui/ask-ai.cjs.map +1 -1
  23. package/dist/ui/ask-ai.d.cts +6 -1
  24. package/dist/ui/ask-ai.d.ts +6 -1
  25. package/dist/ui/ask-ai.js +26 -6
  26. package/dist/ui/ask-ai.js.map +1 -1
  27. package/dist/ui/copy-page.cjs +15 -0
  28. package/dist/ui/copy-page.cjs.map +1 -1
  29. package/dist/ui/copy-page.js +1 -1
  30. package/dist/ui.cjs +77 -6
  31. package/dist/ui.cjs.map +1 -1
  32. package/dist/ui.d.cts +99 -8
  33. package/dist/ui.d.ts +99 -8
  34. package/dist/ui.js +62 -8
  35. package/dist/ui.js.map +1 -1
  36. package/package.json +1 -1
  37. package/skills/SKILL.md +73 -27
  38. package/styles/api-reference.css +45 -2
  39. package/styles/ask-ai.css +28 -0
  40. package/styles/docs.css +96 -1
  41. package/styles/home.css +34 -1
  42. package/dist/chunk-JHN5XQPU.js.map +0 -1
  43. 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 apiTabDocPages = [];
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, apiTabDocPages };
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
- apiTabDocPages.push(item.file);
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
- entries.push(...planDocItems(item.items, dir));
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(groupDir.slice(dir.length + 1));
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: { title: group.title, pages: planDocItems(group.items, groupDir) }
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(_request, context) {
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 new Response(markdown, {
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 isRecord(value) {
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 (isRecord(entry) && typeof entry["group"] === "string") {
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 (!isRecord(tab) || typeof tab["tab"] !== "string") {
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 (!isRecord(group)) {
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 (!isRecord(docsJson)) {
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 (!isRecord(navigation)) {
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 isRecord2(value) {
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 (isRecord2(server) && typeof server["url"] === "string" && !byUrl.has(server["url"])) {
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 (isRecord2(tag) && typeof tag["name"] === "string" && !byName.has(tag["name"])) {
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 (!isRecord2(components)) {
3254
+ if (!isRecord3(components)) {
3060
3255
  continue;
3061
3256
  }
3062
3257
  for (const [section, value] of Object.entries(components)) {
3063
- if (!isRecord2(value)) {
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 (!isRecord2(docPaths)) {
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 (!isRecord2(pathItem)) {
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()) && isRecord2(operation) && !("security" in operation) && Array.isArray(docSecurity)) {
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 (!isRecord2(input)) {
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;