@blaaiz/docs-core 0.5.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-ZWDLAW5M.js → chunk-2GUUVNTP.js} +222 -28
  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 +161 -18
  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 +140 -13
  10. package/dist/generator.js.map +1 -1
  11. package/dist/index.cjs +224 -25
  12. package/dist/index.cjs.map +1 -1
  13. package/dist/index.d.cts +249 -4
  14. package/dist/index.d.ts +249 -4
  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 +68 -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-ZKOOKLZ3.js.map +0 -1
  43. package/dist/chunk-ZWDLAW5M.js.map +0 -1
@@ -52,6 +52,21 @@ var GLYPHS = {
52
52
  /* @__PURE__ */ jsx("rect", { x: "3", y: "11", width: "18", height: "11", rx: "2" }),
53
53
  /* @__PURE__ */ jsx("path", { d: "M7 11V7a5 5 0 0 1 10 0v4" })
54
54
  ] }),
55
+ users: /* @__PURE__ */ jsxs(Fragment, { children: [
56
+ /* @__PURE__ */ jsx("circle", { cx: "9", cy: "7", r: "4" }),
57
+ /* @__PURE__ */ jsx("path", { d: "M2 21a7 7 0 0 1 14 0" }),
58
+ /* @__PURE__ */ jsx("path", { d: "M16 3.5a4 4 0 0 1 0 7" }),
59
+ /* @__PURE__ */ jsx("path", { d: "M17.5 14.5a7 7 0 0 1 4.5 6.5" })
60
+ ] }),
61
+ building: /* @__PURE__ */ jsxs(Fragment, { children: [
62
+ /* @__PURE__ */ jsx("rect", { x: "4", y: "2", width: "16", height: "20", rx: "2" }),
63
+ /* @__PURE__ */ jsx("path", { d: "M9 22v-4h6v4" }),
64
+ /* @__PURE__ */ jsx("path", { d: "M8 6h.01M12 6h.01M16 6h.01M8 10h.01M12 10h.01M16 10h.01M8 14h.01M12 14h.01M16 14h.01" })
65
+ ] }),
66
+ clock: /* @__PURE__ */ jsxs(Fragment, { children: [
67
+ /* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "9" }),
68
+ /* @__PURE__ */ jsx("path", { d: "M12 7v5l3 2" })
69
+ ] }),
55
70
  /** A circled `i` — an informational note, and the generic error state. */
56
71
  info: /* @__PURE__ */ jsxs(Fragment, { children: [
57
72
  /* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "10" }),
@@ -120,5 +135,5 @@ function filledIcon(path, options = {}) {
120
135
  var PLAY_PATH = "M8 5v14l11-7z";
121
136
 
122
137
  export { PLAY_PATH, filledIcon, strokeIcon };
123
- //# sourceMappingURL=chunk-ZKOOKLZ3.js.map
124
- //# sourceMappingURL=chunk-ZKOOKLZ3.js.map
138
+ //# sourceMappingURL=chunk-6H6OB7YP.js.map
139
+ //# sourceMappingURL=chunk-6H6OB7YP.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/ui/icons.tsx"],"names":[],"mappings":"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","file":"chunk-6H6OB7YP.js","sourcesContent":["import type { ReactNode } from 'react';\n\n/**\n * The framework's inline-SVG glyph set — internal.\n *\n * Five UI modules drew their own icons, and four glyphs were drawn twice: the\n * house on the error screen and in the sidebar icon map, the padlock on the\n * sign-in and the `403` screen, the info circle on both of those, the key in\n * both places again, and the check mark in the copy-page button and the\n * playground. One drawing per glyph now lives here.\n *\n * Nothing is exported from the package: the modules below compose these paths,\n * and `docsIcon` remains the only public icon surface. Zero dependencies — the\n * paths are Lucide-shaped, on the same 24×24 grid, so any glyph works at any\n * size.\n *\n * @packageDocumentation\n */\n\n/**\n * The glyph paths, keyed by name. Each value is the *inside* of an `<svg>`, so\n * a caller decides the size, the stroke, and the class.\n */\nconst GLYPHS = {\n house: (\n <>\n <path d=\"m3 9 9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z\" />\n <path d=\"M9 22V12h6v10\" />\n </>\n ),\n book: <path d=\"M4 19.5v-15A2.5 2.5 0 0 1 6.5 2H20v20H6.5a2.5 2.5 0 0 1 0-5H20\" />,\n code: (\n <>\n <path d=\"m16 18 6-6-6-6\" />\n <path d=\"m8 6-6 6 6 6\" />\n </>\n ),\n rocket: (\n <>\n <path d=\"M4.5 16.5c-1.5 1.26-2 5-2 5s3.74-.5 5-2c.71-.84.7-2.13-.09-2.91a2.18 2.18 0 0 0-2.91 0z\" />\n <path d=\"m12 15-3-3a22 22 0 0 1 2-3.95A12.88 12.88 0 0 1 22 2c0 2.72-.78 7.5-6 11a22.35 22.35 0 0 1-4 2z\" />\n <path d=\"M9 12H4s.55-3.03 2-4c1.62-1.08 5 0 5 0\" />\n <path d=\"M12 15v5s3.03-.55 4-2c1.08-1.62 0-5 0-5\" />\n </>\n ),\n terminal: (\n <>\n <path d=\"m4 17 6-6-6-6\" />\n <path d=\"M12 19h8\" />\n </>\n ),\n wallet: (\n <>\n <path d=\"M19 7V4a1 1 0 0 0-1-1H5a2 2 0 0 0 0 4h15a1 1 0 0 1 1 1v4h-3a2 2 0 0 0 0 4h3a1 1 0 0 0 1-1v-2a1 1 0 0 0-1-1\" />\n <path d=\"M3 5v14a2 2 0 0 0 2 2h15a1 1 0 0 0 1-1v-4\" />\n </>\n ),\n key: (\n <>\n <path d=\"m15.5 7.5 2.3 2.3a1 1 0 0 0 1.4 0l2.1-2.1a1 1 0 0 0 0-1.4L19 4\" />\n <path d=\"m21 2-9.6 9.6\" />\n <circle cx=\"7.5\" cy=\"15.5\" r=\"5.5\" />\n </>\n ),\n webhook: (\n <>\n <path d=\"M18 16.98h-5.99c-1.1 0-1.95.94-2.48 1.9A4 4 0 0 1 2 17c.01-.7.2-1.4.57-2\" />\n <path d=\"m6 17 3.13-5.78c.53-.97.1-2.18-.5-3.1a4 4 0 1 1 6.89-4.06\" />\n <path d=\"m12 6 3.13 5.73C15.66 12.7 16.9 13 18 13a4 4 0 0 1 0 8\" />\n </>\n ),\n globe: (\n <>\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <path d=\"M12 2a14.5 14.5 0 0 0 0 20 14.5 14.5 0 0 0 0-20\" />\n <path d=\"M2 12h20\" />\n </>\n ),\n mail: (\n <>\n <rect x=\"2\" y=\"4\" width=\"20\" height=\"16\" rx=\"2\" />\n <path d=\"m22 7-8.97 5.7a1.94 1.94 0 0 1-2.06 0L2 7\" />\n </>\n ),\n user: (\n <>\n <circle cx=\"12\" cy=\"8\" r=\"4\" />\n <path d=\"M4 21a8 8 0 0 1 16 0\" />\n </>\n ),\n lock: (\n <>\n <rect x=\"3\" y=\"11\" width=\"18\" height=\"11\" rx=\"2\" />\n <path d=\"M7 11V7a5 5 0 0 1 10 0v4\" />\n </>\n ),\n users: (\n <>\n <circle cx=\"9\" cy=\"7\" r=\"4\" />\n <path d=\"M2 21a7 7 0 0 1 14 0\" />\n <path d=\"M16 3.5a4 4 0 0 1 0 7\" />\n <path d=\"M17.5 14.5a7 7 0 0 1 4.5 6.5\" />\n </>\n ),\n building: (\n <>\n <rect x=\"4\" y=\"2\" width=\"16\" height=\"20\" rx=\"2\" />\n <path d=\"M9 22v-4h6v4\" />\n <path d=\"M8 6h.01M12 6h.01M16 6h.01M8 10h.01M12 10h.01M16 10h.01M8 14h.01M12 14h.01M16 14h.01\" />\n </>\n ),\n clock: (\n <>\n <circle cx=\"12\" cy=\"12\" r=\"9\" />\n <path d=\"M12 7v5l3 2\" />\n </>\n ),\n /** A circled `i` — an informational note, and the generic error state. */\n info: (\n <>\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <path d=\"M12 8v4M12 16h.01\" strokeLinecap=\"round\" />\n </>\n ),\n /** A warning triangle — a caution, and the `500` screen. */\n alert: (\n <>\n <path d=\"M10.29 3.86 1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z\" />\n <path d=\"M12 9v4M12 17h.01\" strokeLinecap=\"round\" />\n </>\n ),\n /** A light bulb — a tip. */\n bulb: (\n <path d=\"M9 18h6M10 22h4M12 2a7 7 0 0 0-4 12.7c.6.5 1 1.3 1 2.1V17h6v-.2c0-.8.4-1.6 1-2.1A7 7 0 0 0 12 2Z\" />\n ),\n /** A circle with a cross — the `404` screen. */\n crossCircle: (\n <>\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <path d=\"m14.31 8-1.31 2.4M9.69 8l4.62 8M14.31 16 9.69 8\" strokeLinecap=\"round\" />\n </>\n ),\n /** Struck-through signal bars — the offline screen. */\n offline: (\n <>\n <path d=\"M5 12.55a11 11 0 0 1 14 0M8.5 16.11a6 6 0 0 1 7 0M12 20h.01\" strokeLinecap=\"round\" />\n <path d=\"m2 2 20 20\" strokeLinecap=\"round\" />\n </>\n ),\n copy: (\n <path d=\"M9 9h9a2 2 0 0 1 2 2v9a2 2 0 0 1-2 2H9a2 2 0 0 1-2-2v-9a2 2 0 0 1 2-2ZM5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1\" />\n ),\n check: <path d=\"M20 6 9 17l-5-5\" />,\n chevronDown: <path d=\"m6 9 6 6 6-6\" />,\n /** Stacked chevrons — a value this control switches between. */\n chevronUpDown: <path d=\"m7 15 5 5 5-5M7 9l5-5 5 5\" />,\n /** An open arc — one turn of a loading spinner. */\n spinner: <path d=\"M21 12a9 9 0 1 1-6.219-8.56\" strokeLinecap=\"round\" />,\n markdown: (\n <>\n <rect x=\"2\" y=\"5\" width=\"20\" height=\"14\" rx=\"2\" />\n <path d=\"M6 15V9l3 3 3-3v6M17 9v4m0 0 2-2m-2 2-2-2\" />\n </>\n ),\n} satisfies Record<string, ReactNode>;\n\n/** A glyph in {@link GLYPHS}. */\nexport type GlyphName = keyof typeof GLYPHS;\n\n/**\n * How one icon is drawn. Every field is optional, and the defaults match the\n * house style: 24×24 grid, current colour, hidden from assistive technology.\n */\nexport interface IconOptions {\n /**\n * React key for the `<svg>`. Set it when a host may place the icon in an\n * array of children — fumadocs renders a sidebar link as `[icon, text]`, and\n * an unkeyed element there raises React's \"unique key\" warning in the\n * consuming site's console.\n */\n readonly key?: string;\n /** Pixel size for `width` and `height`. Omit to let CSS size the icon. */\n readonly size?: number;\n /** Stroke width. Default 2. */\n readonly strokeWidth?: number;\n /** Round the stroke's ends and joins. Default `false`. */\n readonly rounded?: boolean;\n /** Class for the `<svg>`, e.g. a spin animation. */\n readonly className?: string;\n}\n\n/**\n * Draw a stroked glyph.\n *\n * @param name - the glyph\n * @param options - size, stroke, and class\n * @returns the `<svg>` element\n */\nexport function strokeIcon(name: GlyphName, options: IconOptions = {}): ReactNode {\n return (\n <svg\n key={options.key}\n {...(options.className === undefined ? {} : { className: options.className })}\n {...(options.size === undefined ? {} : { width: options.size, height: options.size })}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={options.strokeWidth ?? 2}\n {...(options.rounded ? { strokeLinecap: 'round', strokeLinejoin: 'round' } : {})}\n aria-hidden=\"true\"\n >\n {GLYPHS[name]}\n </svg>\n );\n}\n\n/**\n * Draw a filled glyph. Used by the solid play triangle, where a stroke would\n * read as an outline.\n *\n * @param path - the path data\n * @param options - size and class\n * @returns the `<svg>` element\n */\nexport function filledIcon(path: string, options: IconOptions = {}): ReactNode {\n return (\n <svg\n key={options.key}\n {...(options.className === undefined ? {} : { className: options.className })}\n {...(options.size === undefined ? {} : { width: options.size, height: options.size })}\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n aria-hidden=\"true\"\n >\n <path d={path} />\n </svg>\n );\n}\n\n/** A solid right-pointing triangle: run this request. */\nexport const PLAY_PATH = 'M8 5v14l11-7z';\n"]}
@@ -43,6 +43,7 @@ function firstDocFile(items) {
43
43
  }
44
44
  function planDocsTree(navigation, options = {}) {
45
45
  const apiDir = options.apiDir ?? "api";
46
+ const headings = (options.sidebar ?? "collapsible") === "headings";
46
47
  const specs = [];
47
48
  const apiPages = [];
48
49
  const apiGroups = [];
@@ -90,7 +91,7 @@ function planDocsTree(navigation, options = {}) {
90
91
  const at = apiGroups.length;
91
92
  const sub = planApiItems(item.items, childDir);
92
93
  apiGroups.splice(at, 0, { dir: childDir, title: item.title, children: sub });
93
- children.push({ order, folder });
94
+ children.push({ order, folder, title: item.title });
94
95
  order += 1;
95
96
  continue;
96
97
  }
@@ -128,11 +129,11 @@ function planDocsTree(navigation, options = {}) {
128
129
  title: tab.title,
129
130
  root: true,
130
131
  ...tab.icon ? { icon: tab.icon } : {},
131
- pages: planDocItems(tab.items, tabDir)
132
+ pages: planDocItems(tab.items, tabDir, true)
132
133
  }
133
134
  });
134
135
  }
135
- function planDocItems(items, dir) {
136
+ function planDocItems(items, dir, tabLevel) {
136
137
  const entries = [];
137
138
  for (const item of items) {
138
139
  if (item.kind === "doc") {
@@ -147,10 +148,18 @@ function planDocsTree(navigation, options = {}) {
147
148
  continue;
148
149
  }
149
150
  if (groupDir === dir) {
150
- entries.push(...planDocItems(item.items, dir));
151
+ if (headings) {
152
+ entries.push(`---${item.title}---`);
153
+ }
154
+ entries.push(...planDocItems(item.items, dir, false));
155
+ continue;
156
+ }
157
+ const folder = groupDir.slice(dir.length + 1);
158
+ if (headings && tabLevel) {
159
+ entries.push(`---${item.title}---`, `...${folder}`);
151
160
  continue;
152
161
  }
153
- entries.push(groupDir.slice(dir.length + 1));
162
+ entries.push(folder);
154
163
  }
155
164
  return entries;
156
165
  }
@@ -165,7 +174,14 @@ function planDocsTree(navigation, options = {}) {
165
174
  }
166
175
  metas.push({
167
176
  path: `${groupDir}/meta.json`,
168
- content: { title: group.title, pages: planDocItems(group.items, groupDir) }
177
+ content: {
178
+ title: group.title,
179
+ // A nested group starts closed in the headings style, whatever the
180
+ // site's defaultOpenLevel. On a tab-level group the flag is inert:
181
+ // that folder is extracted, so no folder node renders it.
182
+ ...headings ? { defaultOpen: false } : {},
183
+ pages: planDocItems(group.items, groupDir, false)
184
+ }
169
185
  });
170
186
  return groupDir;
171
187
  }
@@ -387,8 +403,19 @@ function mergeOpenApiDocuments(inputs, options) {
387
403
  }
388
404
 
389
405
  // src/generator/index.ts
390
- function slugify2(value) {
391
- return value.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
406
+ function kebabCase(value) {
407
+ return value.replace(/([a-z0-9])([A-Z])/g, "$1 $2").toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
408
+ }
409
+ function pageSlug(operation, method, apiPath) {
410
+ for (const candidate of [operation.summary, operation.operationId]) {
411
+ if (candidate !== void 0) {
412
+ const slug = kebabCase(candidate);
413
+ if (slug !== "") {
414
+ return slug;
415
+ }
416
+ }
417
+ }
418
+ return kebabCase(`${method} ${apiPath}`);
392
419
  }
393
420
  function frontmatterTitle(source) {
394
421
  const block = /^---\r?\n([\s\S]*?)\r?\n---/.exec(source);
@@ -415,6 +442,15 @@ function operationKeyOf(content) {
415
442
  }
416
443
  }
417
444
  var PROSE_ONLY_INFO = { title: "No API reference", version: "0.0.0" };
445
+ function sidebarStyleOf(docsJson) {
446
+ const value = docsJson["sidebar"] ?? "collapsible";
447
+ if (value !== "collapsible" && value !== "headings") {
448
+ throw new Error(
449
+ `[docs-core] docs.json has sidebar: ${JSON.stringify(value)}. Use 'headings' (flat group headings, nested groups closed) or 'collapsible' (every group a folder).`
450
+ );
451
+ }
452
+ return value;
453
+ }
418
454
  function requireFumadocs(value, apiPageCount) {
419
455
  const because = `docs.json publishes ${String(apiPageCount)} API page(s)`;
420
456
  if (typeof value !== "object" || value === null) {
@@ -436,8 +472,11 @@ async function generateDocsTree(options) {
436
472
  const docsJson = options.docsJson ?? path__default.default.join(options.contentDir, "docs.json");
437
473
  const outDir = options.outDir ?? path__default.default.join(options.contentDir, "docs");
438
474
  const apiDir = options.apiDir ?? "api";
439
- const navigation = parseNavigation(JSON.parse(await promises.readFile(docsJson, "utf8")));
440
- const plan = planDocsTree(navigation, { apiDir });
475
+ const parsed = JSON.parse(await promises.readFile(docsJson, "utf8"));
476
+ const navigation = parseNavigation(parsed);
477
+ const sidebar = sidebarStyleOf(parsed);
478
+ const headings = sidebar === "headings";
479
+ const plan = planDocsTree(navigation, { apiDir, sidebar });
441
480
  const placements = /* @__PURE__ */ new Map();
442
481
  const groupPages = /* @__PURE__ */ new Map();
443
482
  let pages = 0;
@@ -460,6 +499,7 @@ async function generateDocsTree(options) {
460
499
  info: options.info,
461
500
  ...options.servers ? { servers: options.servers } : {}
462
501
  });
502
+ const taken = /* @__PURE__ */ new Map();
463
503
  for (const page of plan.apiPages) {
464
504
  const operation = document.paths[page.apiPath]?.[page.method.toLowerCase()];
465
505
  if (!operation) {
@@ -467,7 +507,15 @@ async function generateDocsTree(options) {
467
507
  `[docs-core] docs.json references ${page.method} ${page.apiPath}, but ${page.file} defines no such operation.`
468
508
  );
469
509
  }
470
- const slug = operation.operationId ?? slugify2(`${page.method} ${page.apiPath}`);
510
+ const slug = pageSlug(operation, page.method, page.apiPath);
511
+ const key = `${page.dir}/${slug}`;
512
+ const holder = taken.get(key);
513
+ if (holder !== void 0) {
514
+ throw new Error(
515
+ `[docs-core] ${holder} and ${page.method.toUpperCase()} ${page.apiPath} both resolve to the page '${key}'. Give one of them a distinct summary.`
516
+ );
517
+ }
518
+ taken.set(key, `${page.method.toUpperCase()} ${page.apiPath}`);
471
519
  placements.set(`${page.method.toUpperCase()} ${page.apiPath}`, { ...page, slug });
472
520
  const group = groupPages.get(page.dir) ?? [];
473
521
  group.push({ order: page.order, slug });
@@ -543,13 +591,21 @@ async function generateDocsTree(options) {
543
591
  title: group.title,
544
592
  ...group.root ? { root: true } : {},
545
593
  ...group.icon ? { icon: group.icon } : {},
594
+ // A nested group starts closed in the headings style, whatever the
595
+ // site's defaultOpenLevel.
596
+ ...headings && !group.root ? { defaultOpen: false } : {},
546
597
  pages: [
547
598
  ...(groupPages.get(group.dir) ?? []).map((page) => ({
548
599
  order: page.order,
549
- name: page.slug
600
+ names: [page.slug]
550
601
  })),
551
- ...group.children.map((child) => ({ order: child.order, name: child.folder }))
552
- ].sort((a, b) => a.order - b.order).map((entry) => entry.name)
602
+ ...group.children.map((child) => ({
603
+ order: child.order,
604
+ // In the headings style a tab-level group is a flat heading with
605
+ // its pages extracted beneath it, not a collapsible folder.
606
+ names: headings && group.root ? [`---${child.title}---`, `...${child.folder}`] : [child.folder]
607
+ }))
608
+ ].sort((a, b) => a.order - b.order).flatMap((entry) => entry.names)
553
609
  }
554
610
  }))
555
611
  ];
@@ -577,12 +633,36 @@ async function generateDocsTree(options) {
577
633
  }
578
634
  return void 0;
579
635
  };
636
+ const tabDocFiles = (items) => items.flatMap((item) => {
637
+ if (item.kind === "group") {
638
+ return tabDocFiles(item.items);
639
+ }
640
+ return item.kind === "doc" ? [item.file] : [];
641
+ });
642
+ const apiTabRoots = plan.apiGroups.filter((group) => group.root).map((group) => group.dir);
643
+ let apiTabIndex = 0;
580
644
  const navLinks = [];
581
645
  for (const tab of navigation) {
646
+ let match;
647
+ if (hasOpenApi(tab.items)) {
648
+ const root = apiTabRoots[apiTabIndex];
649
+ apiTabIndex += 1;
650
+ if (root !== void 0) {
651
+ match = [
652
+ .../* @__PURE__ */ new Set([`${baseUrl}/${root}`, ...tabDocFiles(tab.items).map((file) => docUrl(file))])
653
+ ];
654
+ }
655
+ }
582
656
  const url = firstUrl(tab.items);
583
- if (url) {
584
- navLinks.push({ text: tab.title, url, ...tab.icon ? { icon: tab.icon } : {} });
657
+ if (!url) {
658
+ continue;
585
659
  }
660
+ navLinks.push({
661
+ text: tab.title,
662
+ url,
663
+ ...tab.icon ? { icon: tab.icon } : {},
664
+ ...match ? { match } : {}
665
+ });
586
666
  }
587
667
  await promises.writeFile(
588
668
  path__default.default.join(options.contentDir, "nav.json"),
@@ -590,10 +670,54 @@ async function generateDocsTree(options) {
590
670
  `
591
671
  );
592
672
  const methodsByUrl = {};
673
+ const sourcesByUrl = {};
593
674
  for (const page of plan.apiPages) {
594
675
  const placement = placements.get(`${page.method.toUpperCase()} ${page.apiPath}`);
595
676
  if (placement) {
596
- methodsByUrl[`${baseUrl}/${placement.dir}/${placement.slug}`] = page.method.toUpperCase();
677
+ const url = `${baseUrl}/${placement.dir}/${placement.slug}`;
678
+ methodsByUrl[url] = page.method.toUpperCase();
679
+ sourcesByUrl[url] = {
680
+ file: page.file,
681
+ method: page.method.toUpperCase(),
682
+ route: page.apiPath
683
+ };
684
+ }
685
+ }
686
+ const sourcesPath = path__default.default.join(options.contentDir, "api-sources.json");
687
+ const redirectsPath = path__default.default.join(options.contentDir, "redirects.json");
688
+ const previousSources = await readJson(sourcesPath);
689
+ const redirects = await readJson(redirectsPath) ?? {};
690
+ if (previousSources) {
691
+ const urlByOperation = new Map(
692
+ Object.entries(sourcesByUrl).map(([url, s]) => [`${s.method} ${s.route}`, url])
693
+ );
694
+ for (const [oldUrl, source] of Object.entries(previousSources)) {
695
+ const newUrl = urlByOperation.get(`${source.method} ${source.route}`);
696
+ if (newUrl !== void 0 && newUrl !== oldUrl) {
697
+ redirects[oldUrl] = newUrl;
698
+ }
699
+ }
700
+ }
701
+ const finalDestination = (from) => {
702
+ const seen = /* @__PURE__ */ new Set([from]);
703
+ let current = redirects[from];
704
+ while (current !== void 0 && !(current in sourcesByUrl)) {
705
+ if (seen.has(current)) {
706
+ return null;
707
+ }
708
+ seen.add(current);
709
+ current = redirects[current];
710
+ }
711
+ return current ?? null;
712
+ };
713
+ const liveRedirects = {};
714
+ for (const oldUrl of Object.keys(redirects)) {
715
+ if (oldUrl in sourcesByUrl) {
716
+ continue;
717
+ }
718
+ const destination = finalDestination(oldUrl);
719
+ if (destination !== null && destination !== oldUrl) {
720
+ liveRedirects[oldUrl] = destination;
597
721
  }
598
722
  }
599
723
  await promises.writeFile(
@@ -601,7 +725,26 @@ async function generateDocsTree(options) {
601
725
  `${JSON.stringify(methodsByUrl, null, 2)}
602
726
  `
603
727
  );
604
- return { pages, metas: metas.length, navLinks, methodsByUrl, document };
728
+ await promises.writeFile(sourcesPath, `${JSON.stringify(sourcesByUrl, null, 2)}
729
+ `);
730
+ await promises.writeFile(redirectsPath, `${JSON.stringify(liveRedirects, null, 2)}
731
+ `);
732
+ return {
733
+ pages,
734
+ metas: metas.length,
735
+ navLinks,
736
+ methodsByUrl,
737
+ sourcesByUrl,
738
+ redirects: liveRedirects,
739
+ document
740
+ };
741
+ }
742
+ async function readJson(file) {
743
+ try {
744
+ return JSON.parse(await promises.readFile(file, "utf8"));
745
+ } catch {
746
+ return null;
747
+ }
605
748
  }
606
749
 
607
750
  exports.generateDocsTree = generateDocsTree;