@tenphi/docs 0.15.0 → 0.16.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.
@@ -1,4 +1,4 @@
1
- import { A as NavigationConfig, B as SiteIconConfig, D as HeadConfig, E as EditLinkConfig, G as TypographyPreset, H as ThemePaletteConfig, K as TypographyPresets, M as NavigationPlacement, N as NavigationTab, O as LocaleConfig, P as NormalizedDocsConfig, R as SearchConfig, T as DocsSource, U as ThemeTokenValue, V as ThemeConfig, W as ThemeTokens, _ as DocsConfig, a as ComponentStyleConfig, c as ComponentsConfig, i as COOKBOOK_COMPONENT_SUB_ELEMENTS, j as NavigationItem, k as MarkdownConfig, l as ContentConfig, n as BuildConfig, o as ComponentStyles, r as COOKBOOK_COMPONENT_NAMES, s as ComponentStylesConfig, t as BrandConfig, u as CookbookComponentName, v as DocsDiagnostic, z as SiteConfig } from "../types-B-msp1dH.js";
1
+ import { A as MarkdownConfig, B as SiteConfig, D as HeadConfig, E as EditLinkConfig, F as NormalizedDocsConfig, G as ThemeTokens, H as ThemeConfig, K as TypographyPreset, M as NavigationItem, N as NavigationPlacement, O as HeaderLink, P as NavigationTab, T as DocsSource, U as ThemePaletteConfig, V as SiteIconConfig, W as ThemeTokenValue, _ as DocsConfig, a as ComponentStyleConfig, c as ComponentsConfig, i as COOKBOOK_COMPONENT_SUB_ELEMENTS, j as NavigationConfig, k as LocaleConfig, l as ContentConfig, n as BuildConfig, o as ComponentStyles, q as TypographyPresets, r as COOKBOOK_COMPONENT_NAMES, s as ComponentStylesConfig, t as BrandConfig, u as CookbookComponentName, v as DocsDiagnostic, z as SearchConfig } from "../types-CH6E2v-J.js";
2
2
  //#region src/config/index.d.ts
3
3
  declare class DocsConfigError extends Error {
4
4
  readonly diagnostics: DocsDiagnostic[];
@@ -10,5 +10,5 @@ declare function defineDocsConfig(config: DocsConfig): DocsConfig;
10
10
  /** Compose presets. Objects merge, arrays replace, and styles use Tasty semantics. */
11
11
  declare function mergeDocsConfig(...configs: DocsConfig[]): DocsConfig;
12
12
  //#endregion
13
- export { type BrandConfig, type BuildConfig, COOKBOOK_COMPONENT_NAMES, COOKBOOK_COMPONENT_SUB_ELEMENTS, type ComponentStyleConfig, type ComponentStyles, type ComponentStylesConfig, type ComponentsConfig, type ContentConfig, type CookbookComponentName, type DocsConfig, DocsConfigError, type DocsSource, type EditLinkConfig, type HeadConfig, type LocaleConfig, type MarkdownConfig, type NavigationConfig, type NavigationItem, type NavigationPlacement, type NavigationTab, type NormalizedDocsConfig, type SearchConfig, type SiteConfig, type SiteIconConfig, type ThemeConfig, type ThemePaletteConfig, type ThemeTokenValue, type ThemeTokens, type TypographyPreset, type TypographyPresets, defineDocsConfig, mergeDocsConfig, normalizeDocsConfig, validateConfig };
13
+ export { type BrandConfig, type BuildConfig, COOKBOOK_COMPONENT_NAMES, COOKBOOK_COMPONENT_SUB_ELEMENTS, type ComponentStyleConfig, type ComponentStyles, type ComponentStylesConfig, type ComponentsConfig, type ContentConfig, type CookbookComponentName, type DocsConfig, DocsConfigError, type DocsSource, type EditLinkConfig, type HeadConfig, type HeaderLink, type LocaleConfig, type MarkdownConfig, type NavigationConfig, type NavigationItem, type NavigationPlacement, type NavigationTab, type NormalizedDocsConfig, type SearchConfig, type SiteConfig, type SiteIconConfig, type ThemeConfig, type ThemePaletteConfig, type ThemeTokenValue, type ThemeTokens, type TypographyPreset, type TypographyPresets, defineDocsConfig, mergeDocsConfig, normalizeDocsConfig, validateConfig };
14
14
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../../src/config/index.ts"],"mappings":";;cAyEa,wBAAwB;WAC1B,aAAa;EAEtB,YAAY,aAAa;;iBAOX,eAAe,QAAQ,aAAa;iBA4iBpC,oBACd,SAAQ,aACP;iBA4Ca,iBAAiB,QAAQ,aAAa;;iBAOtC,mBAAmB,SAAS,eAAe"}
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../../src/config/index.ts"],"mappings":";;cA0Ea,wBAAwB;WAC1B,aAAa;EAEtB,YAAY,aAAa;;iBAOX,eAAe,QAAQ,aAAa;iBAmqBpC,oBACd,SAAQ,aACP;iBA4Ca,iBAAiB,QAAQ,aAAa;;iBAOtC,mBAAmB,SAAS,eAAe"}
@@ -1,2 +1,2 @@
1
- import { a as validateConfig, i as normalizeDocsConfig, n as defineDocsConfig, o as COOKBOOK_COMPONENT_NAMES, r as mergeDocsConfig, s as COOKBOOK_COMPONENT_SUB_ELEMENTS, t as DocsConfigError } from "../config-DoR8g9IM.js";
1
+ import { a as validateConfig, i as normalizeDocsConfig, n as defineDocsConfig, o as COOKBOOK_COMPONENT_NAMES, r as mergeDocsConfig, s as COOKBOOK_COMPONENT_SUB_ELEMENTS, t as DocsConfigError } from "../config-CmoSqvii.js";
2
2
  export { COOKBOOK_COMPONENT_NAMES, COOKBOOK_COMPONENT_SUB_ELEMENTS, DocsConfigError, defineDocsConfig, mergeDocsConfig, normalizeDocsConfig, validateConfig };
@@ -48,6 +48,32 @@
48
48
  }
49
49
  }
50
50
  ]
51
+ },
52
+ "headerLinks": {
53
+ "type": "array",
54
+ "items": {
55
+ "type": "object",
56
+ "additionalProperties": false,
57
+ "required": ["label", "link"],
58
+ "properties": {
59
+ "label": {
60
+ "type": "string",
61
+ "minLength": 1,
62
+ "pattern": "\\S"
63
+ },
64
+ "link": {
65
+ "type": "string",
66
+ "pattern": "^(?:https?://[^\\s\\\\]+|/(?!/)[^\\s\\\\]*|#[^\\s\\\\]*)$"
67
+ },
68
+ "variant": {
69
+ "enum": ["default", "primary"]
70
+ },
71
+ "newTab": {
72
+ "type": "boolean",
73
+ "default": false
74
+ }
75
+ }
76
+ }
51
77
  }
52
78
  }
53
79
  },
@@ -164,7 +190,9 @@
164
190
  "info": {},
165
191
  "success": {},
166
192
  "warning": {},
167
- "danger": {}
193
+ "danger": {},
194
+ "header": {},
195
+ "overlay": {}
168
196
  }
169
197
  },
170
198
  "states": {
@@ -407,6 +435,54 @@
407
435
  "const": "mode"
408
436
  }
409
437
  }
438
+ },
439
+ "HeaderFrame": {
440
+ "type": "object",
441
+ "propertyNames": {
442
+ "not": {
443
+ "const": "mode"
444
+ }
445
+ }
446
+ },
447
+ "HeaderLinks": {
448
+ "type": "object",
449
+ "propertyNames": {
450
+ "not": {
451
+ "const": "mode"
452
+ }
453
+ }
454
+ },
455
+ "Layout": {
456
+ "type": "object",
457
+ "propertyNames": {
458
+ "not": {
459
+ "const": "mode"
460
+ }
461
+ }
462
+ },
463
+ "SearchButton": {
464
+ "type": "object",
465
+ "propertyNames": {
466
+ "not": {
467
+ "const": "mode"
468
+ }
469
+ }
470
+ },
471
+ "TableOfContentsLayout": {
472
+ "type": "object",
473
+ "propertyNames": {
474
+ "not": {
475
+ "const": "mode"
476
+ }
477
+ }
478
+ },
479
+ "PageFrame": {
480
+ "type": "object",
481
+ "propertyNames": {
482
+ "not": {
483
+ "const": "mode"
484
+ }
485
+ }
410
486
  }
411
487
  }
412
488
  },
@@ -567,6 +643,14 @@
567
643
  "items": {
568
644
  "$ref": "#/$defs/navigationItem"
569
645
  }
646
+ },
647
+ "link": {
648
+ "type": "string",
649
+ "pattern": "^/(?!/)[^?#\\\\\\s]*$",
650
+ "description": "Optional parent page route, without a deployment base, query, or fragment.",
651
+ "not": {
652
+ "pattern": "//|(^|/)\\.{1,2}(/|$)"
653
+ }
570
654
  }
571
655
  }
572
656
  },
@@ -587,6 +671,14 @@
587
671
  "type": "string"
588
672
  }
589
673
  }
674
+ },
675
+ "link": {
676
+ "type": "string",
677
+ "pattern": "^/(?!/)[^?#\\\\\\s]*$",
678
+ "description": "Optional parent page route, without a deployment base, query, or fragment.",
679
+ "not": {
680
+ "pattern": "//|(^|/)\\.{1,2}(/|$)"
681
+ }
590
682
  }
591
683
  }
592
684
  },
@@ -9,6 +9,12 @@ const COOKBOOK_COMPONENT_NAMES = [
9
9
  "Tab",
10
10
  "Footer",
11
11
  "Hero",
12
+ "PageFrame",
13
+ "HeaderFrame",
14
+ "HeaderLinks",
15
+ "Layout",
16
+ "SearchButton",
17
+ "TableOfContentsLayout",
12
18
  "LanguageSelect",
13
19
  "Logo",
14
20
  "MarkdownCodeBlock",
@@ -33,6 +39,37 @@ const COOKBOOK_COMPONENT_NAMES = [
33
39
  ];
34
40
  /** Named Tasty sub-elements available on each configurable Cookbook surface. */
35
41
  const COOKBOOK_COMPONENT_SUB_ELEMENTS = {
42
+ PageFrame: [
43
+ "MainFrame",
44
+ "SidebarFrame",
45
+ "Columns"
46
+ ],
47
+ HeaderFrame: [],
48
+ HeaderLinks: [
49
+ "Desktop",
50
+ "Link",
51
+ "HoverLink",
52
+ "PrimaryLink",
53
+ "HoverPrimaryLink",
54
+ "Trigger",
55
+ "HoverTrigger",
56
+ "Panel",
57
+ "PanelNavigation",
58
+ "PanelLink",
59
+ "FirstPanelLink",
60
+ "Close",
61
+ "HoverClose"
62
+ ],
63
+ Layout: ["LockedPage"],
64
+ SearchButton: [
65
+ "Label",
66
+ "Shortcut",
67
+ "Hover",
68
+ "Active",
69
+ "NativeIcon",
70
+ "Icon"
71
+ ],
72
+ TableOfContentsLayout: ["Content"],
36
73
  Card: [
37
74
  "Heading2",
38
75
  "Heading3",
@@ -104,8 +141,12 @@ const COOKBOOK_COMPONENT_SUB_ELEMENTS = {
104
141
  "Heading5",
105
142
  "Heading6",
106
143
  "Link",
144
+ "RevealedLink",
107
145
  "HoverLink",
108
- "LinkIcon"
146
+ "LinkIcon",
147
+ "CopiedLink",
148
+ "CopiedLinkIcon",
149
+ "CopiedIcon"
109
150
  ],
110
151
  MarkdownTable: [
111
152
  "Table",
@@ -123,10 +164,16 @@ const COOKBOOK_COMPONENT_SUB_ELEMENTS = {
123
164
  MobileMenuToggle: [
124
165
  "Control",
125
166
  "Icon",
167
+ "Section",
168
+ "Page",
126
169
  "HoverControl",
127
170
  "ActiveControl"
128
171
  ],
129
172
  MobileNavigationTabs: [
173
+ "Trigger",
174
+ "Marker",
175
+ "Caret",
176
+ "ExpandedCaret",
130
177
  "Label",
131
178
  "List",
132
179
  "Item",
@@ -152,14 +199,25 @@ const COOKBOOK_COMPONENT_SUB_ELEMENTS = {
152
199
  "Pre"
153
200
  ],
154
201
  Sidebar: [
202
+ "Backdrop",
203
+ "OpenBackdrop",
204
+ "MobileHeading",
205
+ "HomeLink",
206
+ "HomeLogo",
207
+ "HomeLabel",
208
+ "Close",
209
+ "HoverClose",
210
+ "CloseIcon",
155
211
  "CurrentLink",
156
212
  "OpenPane",
157
213
  "Content",
214
+ "Tree",
158
215
  "List",
159
216
  "Item",
160
217
  "TopLevelSpacing",
161
218
  "GroupSpacing",
162
219
  "NestedItem",
220
+ "SectionHeading",
163
221
  "Control",
164
222
  "Summary",
165
223
  "GroupLabel",
@@ -168,6 +226,13 @@ const COOKBOOK_COMPONENT_SUB_ELEMENTS = {
168
226
  "LinkLabel",
169
227
  "InteractiveControl",
170
228
  "SummaryMarker",
229
+ "Caret",
230
+ "ExpandedCaret",
231
+ "LinkedSummary",
232
+ "GroupLink",
233
+ "LinkedSectionHeading",
234
+ "SectionLink",
235
+ "Badge",
171
236
  "TopLevelLink"
172
237
  ],
173
238
  Steps: ["Item", "Marker"],
@@ -194,8 +259,10 @@ const COOKBOOK_COMPONENT_SUB_ELEMENTS = {
194
259
  ThemeSelect: [
195
260
  "Trigger",
196
261
  "HoverTrigger",
262
+ "ActiveTrigger",
197
263
  "Icon",
198
264
  "Panel",
265
+ "OpenPanel",
199
266
  "Section",
200
267
  "SectionSpacing",
201
268
  "SectionLabel",
@@ -219,6 +286,7 @@ const COOKBOOK_COMPONENT_SUB_ELEMENTS = {
219
286
  "Primary",
220
287
  "TitleAndSearch",
221
288
  "Title",
289
+ "LogoLink",
222
290
  "Logo",
223
291
  "SiteTitle",
224
292
  "Search",
@@ -231,7 +299,7 @@ const COOKBOOK_COMPONENT_SUB_ELEMENTS = {
231
299
  };
232
300
  //#endregion
233
301
  //#region src/config/index.ts
234
- const DEFAULT_BRAND = "#315efb";
302
+ const DEFAULT_BRAND = "okhsl(266 68% 48%)";
235
303
  const HEAD_KEYS = /* @__PURE__ */ new Set([
236
304
  "tag",
237
305
  "attrs",
@@ -262,7 +330,8 @@ const OBJECT_KEYS = {
262
330
  "description",
263
331
  "url",
264
332
  "repository",
265
- "favicon"
333
+ "favicon",
334
+ "headerLinks"
266
335
  ]),
267
336
  content: /* @__PURE__ */ new Set([
268
337
  "sources",
@@ -319,6 +388,26 @@ function validateConfig(config) {
319
388
  }
320
389
  for (const key of Object.keys(value)) if (!keys.has(key)) unknown(diagnostics, `${section}.${key}`);
321
390
  }
391
+ if (isRecord(config.site) && config.site.headerLinks !== void 0) {
392
+ if (!Array.isArray(config.site.headerLinks)) invalid(diagnostics, "site.headerLinks must be an array.");
393
+ else config.site.headerLinks.forEach((item, index) => {
394
+ const path = `site.headerLinks[${index}]`;
395
+ if (!isRecord(item)) {
396
+ invalid(diagnostics, `${path} must be an object.`);
397
+ return;
398
+ }
399
+ for (const key of Object.keys(item)) if (![
400
+ "label",
401
+ "link",
402
+ "variant",
403
+ "newTab"
404
+ ].includes(key)) unknown(diagnostics, `${path}.${key}`);
405
+ if (typeof item.label !== "string" || !item.label.trim()) invalid(diagnostics, `${path}.label must be a non-empty string.`);
406
+ if (typeof item.link !== "string" || /[\\\s]/.test(item.link) || !(/^(?:\/(?!\/)|#)/.test(item.link) || isHttpUrl(item.link))) invalid(diagnostics, `${path}.link must be an HTTP(S) URL, root-relative route, or fragment.`);
407
+ if (item.variant !== void 0 && !["default", "primary"].includes(item.variant)) invalid(diagnostics, `${path}.variant must be "default" or "primary".`);
408
+ if (item.newTab !== void 0 && typeof item.newTab !== "boolean") invalid(diagnostics, `${path}.newTab must be a boolean.`);
409
+ });
410
+ }
322
411
  if (config.navigation !== void 0 && !Array.isArray(config.navigation)) {
323
412
  if (!isRecord(config.navigation)) invalid(diagnostics, "navigation must be an array or object.");
324
413
  else {
@@ -327,6 +416,15 @@ function validateConfig(config) {
327
416
  if (config.navigation.tabs !== void 0 && !Array.isArray(config.navigation.tabs)) invalid(diagnostics, "navigation.tabs must be an array.");
328
417
  }
329
418
  }
419
+ if (Array.isArray(config.navigation)) validateNavigationItems(config.navigation, "navigation", diagnostics);
420
+ else if (isRecord(config.navigation)) {
421
+ if (Array.isArray(config.navigation.items)) validateNavigationItems(config.navigation.items, "navigation.items", diagnostics);
422
+ if (Array.isArray(config.navigation.tabs)) for (const [index, tab] of config.navigation.tabs.entries()) {
423
+ const path = `navigation.tabs[${index}]`;
424
+ if (!isRecord(tab) || typeof tab.label !== "string" || typeof tab.link !== "string") invalid(diagnostics, `${path} must have a label and link.`);
425
+ else if (tab.items !== void 0) validateNavigationItems(tab.items, `${path}.items`, diagnostics);
426
+ }
427
+ }
330
428
  if (config.redirects !== void 0 && (!isRecord(config.redirects) || Object.values(config.redirects).some((value) => typeof value !== "string"))) invalid(diagnostics, "redirects must map old routes to document routes.");
331
429
  const head = config.head;
332
430
  if (head !== void 0 && !Array.isArray(head)) invalid(diagnostics, "head must be an array.");
@@ -522,6 +620,8 @@ function validateConfig(config) {
522
620
  for (const [name, value] of Object.entries(config.theme?.palette ?? {})) {
523
621
  if (![
524
622
  "surface",
623
+ "header",
624
+ "overlay",
525
625
  "text",
526
626
  "textSoft",
527
627
  "info",
@@ -575,6 +675,25 @@ function isHttpUrl(value) {
575
675
  return false;
576
676
  }
577
677
  }
678
+ function validateNavigationItems(items, path, diagnostics) {
679
+ if (!Array.isArray(items)) {
680
+ invalid(diagnostics, `${path} must be an array.`);
681
+ return;
682
+ }
683
+ for (const [index, item] of items.entries()) {
684
+ const itemPath = `${path}[${index}]`;
685
+ if (typeof item === "string") continue;
686
+ if (!isRecord(item) || typeof item.label !== "string") {
687
+ invalid(diagnostics, `${itemPath} must be a route or a labeled navigation item.`);
688
+ continue;
689
+ }
690
+ if (("items" in item || "autogenerate" in item) && item.link !== void 0 && (typeof item.link !== "string" || !/^\/(?!\/)[^?#\\\s]*$/.test(item.link) || item.link.includes("//") || item.link.split("/").some((segment) => segment === "." || segment === ".."))) invalid(diagnostics, `${itemPath}.link must be a root-relative page route without a query or fragment.`);
691
+ if ("items" in item) validateNavigationItems(item.items, `${itemPath}.items`, diagnostics);
692
+ else if ("autogenerate" in item) {
693
+ if (!isRecord(item.autogenerate) || typeof item.autogenerate.directory !== "string") invalid(diagnostics, `${itemPath}.autogenerate.directory must be a directory path.`);
694
+ } else if (typeof item.link !== "string") invalid(diagnostics, `${itemPath}.link must be a URL or route.`);
695
+ }
696
+ }
578
697
  function normalizeDocsConfig(config = {}) {
579
698
  const diagnostics = validateConfig(config);
580
699
  if (diagnostics.length > 0) throw new DocsConfigError(diagnostics);
@@ -652,4 +771,4 @@ function mergeDocsConfig(...configs) {
652
771
  //#endregion
653
772
  export { validateConfig as a, normalizeDocsConfig as i, defineDocsConfig as n, COOKBOOK_COMPONENT_NAMES as o, mergeDocsConfig as r, COOKBOOK_COMPONENT_SUB_ELEMENTS as s, DocsConfigError as t };
654
773
 
655
- //# sourceMappingURL=config-DoR8g9IM.js.map
774
+ //# sourceMappingURL=config-CmoSqvii.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-CmoSqvii.js","names":[],"sources":["../src/types.ts","../src/config/index.ts"],"sourcesContent":["import type { Styles, StylesWithoutSelectors } from \"@tenphi/tasty/core\";\nimport type { GlazeColorValue } from \"@tenphi/glaze\";\nimport type { Root } from \"mdast\";\n\nexport type DiagnosticSeverity = \"warning\" | \"error\";\n\nexport interface DocsDiagnostic {\n code: string;\n severity: DiagnosticSeverity;\n message: string;\n file?: string;\n line?: number;\n column?: number;\n hint?: string;\n related?: Array<{ file: string; line?: number; message: string }>;\n}\n\nexport interface SiteConfig {\n title?: string;\n /** Version of the documented package, rendered beside the site title. */\n version?: string;\n description?: string;\n url?: string;\n repository?: string;\n /** Header buttons, collapsed into a More menu on mobile. */\n headerLinks?: HeaderLink[];\n /** Source artwork used to generate browser, touch, and installable-app icons. */\n favicon?: string | SiteIconConfig;\n}\n\nexport interface HeaderLink {\n label: string;\n /** HTTP(S) URL, root-relative route (prefixed with the site base), or fragment. */\n link: string;\n /** Desktop button variant; mobile More menus use uniform navigation links. */\n variant?: \"default\" | \"primary\";\n newTab?: boolean;\n}\n\nexport interface SiteIconConfig {\n /** Local SVG, PNG, JPEG, WebP, AVIF, or GIF path, relative to the project root. */\n source: string;\n /** Opaque background for touch and maskable icons. */\n background?: string;\n}\n\n/** A language exposed by Starlight's locale picker and routing. */\nexport interface LocaleConfig {\n label: string;\n /** BCP-47 language tag. Defaults to the locale key. */\n lang?: string;\n dir?: \"ltr\" | \"rtl\";\n}\n\nexport interface EditLinkConfig {\n /** Base URL joined with each page's repository-relative source path. */\n baseUrl: string;\n}\n\n/** A custom HTML element rendered in the document head. */\nexport interface HeadConfig {\n tag: string;\n attrs?: Record<string, string | boolean | undefined>;\n content?: string;\n}\n\nexport interface NavigationPlacement {\n label?: string;\n order?: number;\n group?: string;\n}\n\nexport type DocsSource = {\n /** Stable name for cross-source links and repeated mounts. */\n id?: string;\n routeBase?: string;\n} & (\n | {\n file: string;\n root?: string;\n route?: string;\n title?: string;\n description?: string;\n navigation?: false | NavigationPlacement;\n }\n | {\n glob: string | string[];\n root?: string;\n base?: string;\n routeBase?: string;\n exclude?: string[];\n navigation?: \"auto\" | false;\n }\n | {\n package: string;\n registry?: string;\n include?: string[];\n exclude?: string[];\n index?: string;\n routeBase?: string;\n trust?: \"markdown\" | \"mdx\";\n }\n);\n\nexport interface ContentConfig {\n sources?: DocsSource[];\n allowOutsideRoot?: boolean;\n /** Rewrite absolute links into the current repository to matching Cookbook routes. */\n localizeRepositoryLinks?: boolean;\n /** Keep unrelated metadata without exposing it as renderer frontmatter. */\n frontmatter?: \"preserve\" | \"reject\";\n}\n\nexport type NavigationItem =\n | string\n | { label: string; link?: string; items: NavigationItem[] }\n | { label: string; link?: string; autogenerate: { directory: string } }\n | { label: string; link: string };\n\nexport interface NavigationTab {\n label: string;\n link: string;\n /** Sidebar tree shown while this tab is active. */\n items?: NavigationItem[];\n}\n\nexport interface NavigationConfig {\n items?: NavigationItem[];\n /** Optional primary navigation rendered as a compact row below the header. */\n tabs?: NavigationTab[];\n}\n\nexport type BrandConfig =\n | GlazeColorValue\n | {\n from: GlazeColorValue;\n contrast?: { apca: number | [number, number] };\n unsafeContrast?: boolean;\n };\n\nexport type ThemeTokenValue = string | number;\n\n/**\n * Tasty design tokens. `$name` is emitted as `--name`; existing `--name`\n * custom-property keys remain supported for compatibility.\n */\nexport interface ThemeTokens {\n $gap?: ThemeTokenValue;\n $radius?: ThemeTokenValue;\n \"$card-radius\"?: ThemeTokenValue;\n \"$border-width\"?: ThemeTokenValue;\n \"$outline-width\"?: ThemeTokenValue;\n \"$outline-offset\"?: ThemeTokenValue;\n \"$layout-width\"?: ThemeTokenValue;\n \"$content-width\"?: ThemeTokenValue;\n \"$sidebar-width\"?: ThemeTokenValue;\n \"$control-height\"?: ThemeTokenValue;\n [name: `$${string}`]: ThemeTokenValue | undefined;\n [customProperty: `--${string}`]: ThemeTokenValue | undefined;\n}\n\nexport interface TypographyPreset {\n fontFamily?: string;\n fontSize?: ThemeTokenValue;\n lineHeight?: ThemeTokenValue;\n letterSpacing?: ThemeTokenValue;\n fontWeight?: ThemeTokenValue;\n boldFontWeight?: ThemeTokenValue;\n iconSize?: ThemeTokenValue;\n textTransform?: ThemeTokenValue;\n fontStyle?: ThemeTokenValue;\n}\n\n/** Built-in presets can be overridden and additional Tasty presets may be added. */\nexport interface TypographyPresets {\n body?: TypographyPreset;\n heading?: TypographyPreset;\n h1?: TypographyPreset;\n h2?: TypographyPreset;\n h3?: TypographyPreset;\n h4?: TypographyPreset;\n h5?: TypographyPreset;\n h6?: TypographyPreset;\n navigation?: TypographyPreset;\n small?: TypographyPreset;\n code?: TypographyPreset;\n [name: string]: TypographyPreset | undefined;\n}\n\n/** Semantic palette inputs. Glaze resolves every value for all appearance modes. */\nexport interface ThemePaletteConfig {\n info?: GlazeColorValue;\n success?: GlazeColorValue;\n warning?: GlazeColorValue;\n danger?: GlazeColorValue;\n /** Light-scheme page surface; dark and high-contrast values adapt. */\n surface?: GlazeColorValue;\n /** Translucent header surface seed; defaults to the page surface. */\n header?: GlazeColorValue;\n /** Fixed underlay seed; defaults to black at 50% opacity in every scheme. */\n overlay?: GlazeColorValue;\n /** Primary reading text seed, resolved against `surface`. */\n text?: GlazeColorValue;\n /** Secondary text seed, resolved against `surface`. */\n textSoft?: GlazeColorValue;\n}\n\n/** Cookbook UI surfaces whose default Tasty styles can be customized. */\nexport const COOKBOOK_COMPONENT_NAMES = [\n \"Card\",\n \"Callout\",\n \"CodeGroup\",\n \"Tab\",\n \"Footer\",\n \"Hero\",\n \"PageFrame\",\n \"HeaderFrame\",\n \"HeaderLinks\",\n \"Layout\",\n \"SearchButton\",\n \"TableOfContentsLayout\",\n \"LanguageSelect\",\n \"Logo\",\n \"MarkdownCodeBlock\",\n \"MarkdownHeading\",\n \"MarkdownInlineCode\",\n \"MarkdownTable\",\n \"Mermaid\",\n \"MobileMenuFooter\",\n \"MobileMenuToggle\",\n \"MobileNavigationTabs\",\n \"MobileTableOfContents\",\n \"PackageVersion\",\n \"Preview\",\n \"Sidebar\",\n \"SocialIcons\",\n \"Steps\",\n \"Tabs\",\n \"TableOfContents\",\n \"ThemeSelect\",\n \"TopNavigation\",\n \"StarlightHeader\",\n] as const;\n\nexport type CookbookComponentName = (typeof COOKBOOK_COMPONENT_NAMES)[number];\n\n/** Named Tasty sub-elements available on each configurable Cookbook surface. */\nexport const COOKBOOK_COMPONENT_SUB_ELEMENTS = {\n PageFrame: [\"MainFrame\", \"SidebarFrame\", \"Columns\"],\n HeaderFrame: [],\n HeaderLinks: [\n \"Desktop\",\n \"Link\",\n \"HoverLink\",\n \"PrimaryLink\",\n \"HoverPrimaryLink\",\n \"Trigger\",\n \"HoverTrigger\",\n \"Panel\",\n \"PanelNavigation\",\n \"PanelLink\",\n \"FirstPanelLink\",\n \"Close\",\n \"HoverClose\",\n ],\n Layout: [\"LockedPage\"],\n SearchButton: [\"Label\", \"Shortcut\", \"Hover\", \"Active\", \"NativeIcon\", \"Icon\"],\n TableOfContentsLayout: [\"Content\"],\n Card: [\"Heading2\", \"Heading3\", \"Paragraph\"],\n Callout: [\"Title\", \"Body\", \"Tip\", \"Caution\", \"Danger\"],\n CodeGroup: [\"Caption\", \"Pre\", \"Code\"],\n Tab: [\"Heading\", \"Hidden\", \"HiddenHeading\"],\n Footer: [\n \"Meta\",\n \"LoneMetaItem\",\n \"MetaLink\",\n \"HoverMetaLink\",\n \"Credit\",\n \"CreditLink\",\n \"HoverCreditLink\",\n ],\n Hero: [\n \"Visual\",\n \"Stack\",\n \"Copy\",\n \"Title\",\n \"Tagline\",\n \"Actions\",\n \"Action\",\n \"HoverAction\",\n \"PrimaryAction\",\n \"SecondaryAction\",\n \"MinimalAction\",\n \"ActionIcon\",\n ],\n LanguageSelect: [\n \"Label\",\n \"HoverLabel\",\n \"LabelIcon\",\n \"Select\",\n \"Caret\",\n \"Option\",\n ],\n Logo: [\"Svg\", \"Mark\"],\n MarkdownCodeBlock: [\n \"Pre\",\n \"CopyButton\",\n \"HoverCopyButton\",\n \"CopiedButton\",\n \"CopyIcon\",\n \"CopiedIcon\",\n ],\n MarkdownHeading: [\n \"Heading\",\n \"Heading1\",\n \"Heading2\",\n \"Heading3\",\n \"Heading4\",\n \"Heading5\",\n \"Heading6\",\n \"Link\",\n \"RevealedLink\",\n \"HoverLink\",\n \"LinkIcon\",\n \"CopiedLink\",\n \"CopiedLinkIcon\",\n \"CopiedIcon\",\n ],\n MarkdownTable: [\"Table\", \"Cell\", \"LastBodyRowCell\", \"HeaderCell\"],\n MarkdownInlineCode: [],\n Mermaid: [\"Diagram\", \"Text\", \"MonoText\"],\n MobileMenuFooter: [\"Social\"],\n MobileMenuToggle: [\n \"Control\",\n \"Icon\",\n \"Section\",\n \"Page\",\n \"HoverControl\",\n \"ActiveControl\",\n ],\n MobileNavigationTabs: [\n \"Trigger\",\n \"Marker\",\n \"Caret\",\n \"ExpandedCaret\",\n \"Label\",\n \"List\",\n \"Item\",\n \"Link\",\n \"HoverLink\",\n \"CurrentLink\",\n ],\n MobileTableOfContents: [\n \"Item\",\n \"Link\",\n \"LinkLabel\",\n \"HoverLink\",\n \"CurrentLink\",\n \"CurrentIndicator\",\n ],\n PackageVersion: [],\n Preview: [\"Caption\", \"Stage\", \"Frame\", \"Code\", \"Summary\", \"Pre\"],\n Sidebar: [\n \"Backdrop\",\n \"OpenBackdrop\",\n \"MobileHeading\",\n \"HomeLink\",\n \"HomeLogo\",\n \"HomeLabel\",\n \"Close\",\n \"HoverClose\",\n \"CloseIcon\",\n \"CurrentLink\",\n \"OpenPane\",\n \"Content\",\n \"Tree\",\n \"List\",\n \"Item\",\n \"TopLevelSpacing\",\n \"GroupSpacing\",\n \"NestedItem\",\n \"SectionHeading\",\n \"Control\",\n \"Summary\",\n \"GroupLabel\",\n \"GroupLabelText\",\n \"Link\",\n \"LinkLabel\",\n \"InteractiveControl\",\n \"SummaryMarker\",\n \"Caret\",\n \"ExpandedCaret\",\n \"LinkedSummary\",\n \"GroupLink\",\n \"LinkedSectionHeading\",\n \"SectionLink\",\n \"Badge\",\n \"TopLevelLink\",\n ],\n Steps: [\"Item\", \"Marker\"],\n SocialIcons: [\"Link\", \"HoverLink\", \"Icon\"],\n Tabs: [\"List\", \"Button\", \"SelectedButton\", \"FocusedButton\"],\n TableOfContents: [\n \"Heading\",\n \"List\",\n \"Item\",\n \"Link\",\n \"LinkLabel\",\n \"HoverLink\",\n \"CurrentLink\",\n ],\n ThemeSelect: [\n \"Trigger\",\n \"HoverTrigger\",\n \"ActiveTrigger\",\n \"Icon\",\n \"Panel\",\n \"OpenPanel\",\n \"Section\",\n \"SectionSpacing\",\n \"SectionLabel\",\n \"Option\",\n \"HoverOption\",\n \"CheckedOption\",\n \"FocusedOption\",\n \"Input\",\n \"OptionIcon\",\n \"Checkmark\",\n \"SelectedCheckmark\",\n ],\n TopNavigation: [\n \"Scrollbar\",\n \"Link\",\n \"HoverLink\",\n \"CurrentLink\",\n \"ActiveIndicator\",\n ],\n StarlightHeader: [\n \"Primary\",\n \"TitleAndSearch\",\n \"Title\",\n \"LogoLink\",\n \"Logo\",\n \"SiteTitle\",\n \"Search\",\n \"SearchElement\",\n \"Tools\",\n \"ToolItem\",\n \"Social\",\n \"MobileTheme\",\n ],\n} as const satisfies Record<CookbookComponentName, readonly string[]>;\n\nexport type CookbookComponentSubElementName<\n Name extends CookbookComponentName,\n> = (typeof COOKBOOK_COMPONENT_SUB_ELEMENTS)[Name][number];\n\n/** A serializable partial Tasty style object, merged into the base internally. */\nexport type ComponentStyles = StylesWithoutSelectors & {\n $?: string;\n mode?: never;\n recipe?: string;\n [token: `$${string}`]: Styles[string];\n [color: `#${string}`]: Styles[string];\n [state: `@${string}`]: Styles[string];\n};\n\n/** Style properties supplied by the user to override Cookbook defaults. */\nexport type ComponentStyleConfig = ComponentStyles;\n\n/** A component override with typed suggestions for its named sub-elements. */\nexport type CookbookComponentStyles<Name extends CookbookComponentName> =\n ComponentStyles &\n Partial<Record<CookbookComponentSubElementName<Name>, ComponentStyles>>;\n\nexport type ComponentStylesConfig = {\n [Name in CookbookComponentName]?: CookbookComponentStyles<Name>;\n};\n\nexport interface ThemeConfig {\n brand?: BrandConfig;\n palette?: ThemePaletteConfig;\n states?: Record<string, string>;\n tokens?: ThemeTokens;\n presets?: TypographyPresets;\n /** Tasty UI styles, keyed by Cookbook component or bridge name. */\n styles?: ComponentStylesConfig;\n /** Explicit registration and overrides for user-authored components. */\n customStyles?: Record<string, Styles>;\n contrastLevel?: number | \"auto\";\n}\n\nexport interface MarkdownConfig {\n stripLeadingBadges?: boolean;\n /** Raw HTML policy for trusted Markdown. Untrusted package Markdown is always sanitized. */\n rawHtml?: \"allow\" | \"sanitize\" | \"strip\" | \"reject\";\n}\n\nexport interface SearchConfig {\n enabled?: boolean;\n}\n\nexport interface ComponentsConfig {\n /** Astro component paths keyed by Starlight component name. `Footer` also accepts `false`. */\n overrides?: Record<string, string | false>;\n}\n\nexport interface BuildConfig {\n strict?: boolean;\n ci?: boolean;\n cacheDir?: string;\n maxArtifactBytes?: number;\n maxUnpackedBytes?: number;\n maxFiles?: number;\n maxPathDepth?: number;\n maxAssetBytes?: number;\n}\n\nexport interface DocsConfig {\n /** Content and lock directory, relative to docs.config.ts (or the inline root). */\n root?: string;\n /** Old public routes mapped to current document routes. */\n redirects?: Record<string, string>;\n site?: SiteConfig;\n head?: HeadConfig[];\n /** Enable source-aware “Edit page” links. */\n editLink?: EditLinkConfig;\n /** Show the most recent Git commit date for each local page. */\n lastUpdated?: boolean;\n /** Languages keyed by their URL segment, or `root` for `/`. */\n locales?: Record<string, LocaleConfig>;\n /** Locale key used for fallback content. */\n defaultLocale?: string;\n content?: ContentConfig;\n navigation?: NavigationConfig | NavigationItem[];\n theme?: ThemeConfig;\n markdown?: MarkdownConfig;\n search?: SearchConfig;\n components?: ComponentsConfig;\n build?: BuildConfig;\n}\n\nexport interface NormalizedDocsConfig {\n redirects: Record<string, string>;\n site: SiteConfig;\n head: HeadConfig[];\n editLink?: EditLinkConfig;\n lastUpdated: boolean;\n locales?: Record<string, LocaleConfig>;\n defaultLocale?: string;\n content: Required<\n Pick<ContentConfig, \"allowOutsideRoot\" | \"localizeRepositoryLinks\">\n > &\n ContentConfig;\n navigation: NavigationConfig;\n theme: ThemeConfig & { brand: BrandConfig };\n markdown: Required<Pick<MarkdownConfig, \"stripLeadingBadges\" | \"rawHtml\">> &\n MarkdownConfig;\n search: Required<SearchConfig>;\n components: ComponentsConfig;\n build: Required<BuildConfig> & { base: string };\n}\n\nexport interface DocsFrontmatter {\n aliases?: string[];\n title?: string;\n description?: string;\n slug?: string;\n draft?: boolean;\n sidebar?: false | { label?: string; order?: number; group?: string };\n tableOfContents?:\n false | { minHeadingLevel?: number; maxHeadingLevel?: number };\n editUrl?: false | string;\n /** Starlight page layout. */\n template?: \"doc\" | \"splash\";\n hero?: {\n title?: string;\n tagline?: string;\n image?:\n | { html: string }\n | { file: string; alt?: string }\n | { dark: string; light: string; alt?: string };\n actions?: Array<{\n text: string;\n link: string;\n variant?: \"primary\" | \"secondary\" | \"minimal\";\n }>;\n };\n lastUpdated?: boolean | Date;\n prev?: false | string | { link?: string; label?: string };\n next?: false | string | { link?: string; label?: string };\n banner?: { content: string };\n pagefind?: boolean;\n head?: Array<Record<string, unknown>>;\n}\n\nexport interface DocsHeading {\n depth: number;\n text: string;\n slug: string;\n line?: number;\n}\n\nexport interface DocsReference {\n original: string;\n resolved?: string;\n targetSource?: string;\n fragment?: string;\n line?: number;\n}\n\nexport interface DocsAsset extends DocsReference {\n sourcePath?: string;\n publicPath?: string;\n hash?: string;\n bytes?: number;\n}\n\nexport interface DocsEntry {\n id: string;\n sourceId: string;\n routeBase: string;\n metadata: Record<string, unknown>;\n sourcePath: string;\n absolutePath: string;\n sourceRoot: string;\n route: string;\n title: string;\n description?: string;\n frontmatter: DocsFrontmatter;\n headings: DocsHeading[];\n body: string;\n transformedBody: string;\n ast: Root;\n links: DocsReference[];\n assets: DocsAsset[];\n trust: \"markdown\" | \"mdx\";\n package?: { requested: string; resolved: string };\n}\n\nexport interface DocsRoute {\n route: string;\n entryId: string;\n sourcePath: string;\n title: string;\n sidebar?: false | NavigationPlacement;\n}\n\nexport interface DocsGraph {\n redirects: Record<string, string>;\n root: string;\n config: NormalizedDocsConfig;\n entries: DocsEntry[];\n routes: DocsRoute[];\n assets: DocsAsset[];\n diagnostics: DocsDiagnostic[];\n entryByRoute(route: string): DocsEntry | undefined;\n entryBySource(sourcePath: string, sourceId?: string): DocsEntry | undefined;\n}\n\nexport interface PackageLockSource {\n requested: string;\n resolved: string;\n registry: string;\n integrity: string;\n vendored?: string;\n}\n\nexport interface CookbookLock {\n schemaVersion: 1;\n sources: PackageLockSource[];\n}\n\nexport interface PackageManifest {\n name: string;\n version: string;\n description?: string;\n homepage?: string;\n repository?: string | { type?: string; url?: string; directory?: string };\n cookbook?: {\n index?: string;\n include?: string[];\n exclude?: string[];\n theme?: { brand?: BrandConfig };\n };\n _integrity?: string;\n _resolved?: string;\n}\n\nexport interface PackageDiscovery {\n root: string;\n manifest: PackageManifest;\n home?: string;\n pages: string[];\n assets: string[];\n}\n\nexport interface CreateDocsGraphOptions {\n root?: string;\n config?: DocsConfig;\n lock?: CookbookLock;\n /** Public URL base used when rewriting routes and assets. */\n base?: string;\n}\n","import { glaze } from \"@tenphi/glaze\";\nimport { mergeStyles, type Styles } from \"@tenphi/tasty/core\";\nimport {\n COOKBOOK_COMPONENT_NAMES,\n COOKBOOK_COMPONENT_SUB_ELEMENTS,\n} from \"../types.js\";\nimport type {\n DocsConfig,\n DocsDiagnostic,\n NormalizedDocsConfig,\n} from \"../types.js\";\n\nconst DEFAULT_BRAND = \"okhsl(266 68% 48%)\";\nconst HEAD_KEYS = new Set([\"tag\", \"attrs\", \"content\"]);\nconst SITE_ICON_KEYS = new Set([\"source\", \"background\"]);\nconst ROOT_KEYS = new Set([\n \"root\",\n \"redirects\",\n \"site\",\n \"head\",\n \"editLink\",\n \"lastUpdated\",\n \"locales\",\n \"defaultLocale\",\n \"content\",\n \"navigation\",\n \"theme\",\n \"markdown\",\n \"search\",\n \"components\",\n \"build\",\n]);\n\nconst OBJECT_KEYS: Record<string, Set<string>> = {\n site: new Set([\n \"title\",\n \"version\",\n \"description\",\n \"url\",\n \"repository\",\n \"favicon\",\n \"headerLinks\",\n ]),\n content: new Set([\n \"sources\",\n \"allowOutsideRoot\",\n \"localizeRepositoryLinks\",\n \"frontmatter\",\n ]),\n markdown: new Set([\"stripLeadingBadges\", \"rawHtml\"]),\n search: new Set([\"enabled\"]),\n components: new Set([\"overrides\"]),\n theme: new Set([\n \"brand\",\n \"palette\",\n \"states\",\n \"tokens\",\n \"presets\",\n \"styles\",\n \"customStyles\",\n \"contrastLevel\",\n ]),\n build: new Set([\n \"strict\",\n \"ci\",\n \"cacheDir\",\n \"maxArtifactBytes\",\n \"maxUnpackedBytes\",\n \"maxFiles\",\n \"maxPathDepth\",\n \"maxAssetBytes\",\n ]),\n};\n\nexport class DocsConfigError extends Error {\n readonly diagnostics: DocsDiagnostic[];\n\n constructor(diagnostics: DocsDiagnostic[]) {\n super(diagnostics.map((diagnostic) => diagnostic.message).join(\"\\n\"));\n this.name = \"DocsConfigError\";\n this.diagnostics = diagnostics;\n }\n}\n\nexport function validateConfig(config: DocsConfig): DocsDiagnostic[] {\n const diagnostics: DocsDiagnostic[] = [];\n if (config === null || typeof config !== \"object\" || Array.isArray(config)) {\n invalid(diagnostics, \"Documentation configuration must be an object.\");\n return diagnostics;\n }\n if (config.root !== undefined && typeof config.root !== \"string\") {\n invalid(diagnostics, \"root must be a directory path.\");\n }\n for (const key of Object.keys(config)) {\n if (!ROOT_KEYS.has(key)) unknown(diagnostics, key);\n }\n for (const [section, keys] of Object.entries(OBJECT_KEYS)) {\n const value = config[section as keyof DocsConfig];\n if (value === undefined) continue;\n if (!isRecord(value)) {\n invalid(diagnostics, `${section} must be an object.`);\n continue;\n }\n for (const key of Object.keys(value)) {\n if (!keys.has(key)) unknown(diagnostics, `${section}.${key}`);\n }\n }\n\n if (isRecord(config.site) && config.site.headerLinks !== undefined) {\n if (!Array.isArray(config.site.headerLinks)) {\n invalid(diagnostics, \"site.headerLinks must be an array.\");\n } else {\n config.site.headerLinks.forEach((item, index) => {\n const path = `site.headerLinks[${index}]`;\n if (!isRecord(item)) {\n invalid(diagnostics, `${path} must be an object.`);\n return;\n }\n for (const key of Object.keys(item)) {\n if (![\"label\", \"link\", \"variant\", \"newTab\"].includes(key))\n unknown(diagnostics, `${path}.${key}`);\n }\n if (typeof item.label !== \"string\" || !item.label.trim())\n invalid(diagnostics, `${path}.label must be a non-empty string.`);\n if (\n typeof item.link !== \"string\" ||\n /[\\\\\\s]/.test(item.link) ||\n !(/^(?:\\/(?!\\/)|#)/.test(item.link) || isHttpUrl(item.link))\n )\n invalid(\n diagnostics,\n `${path}.link must be an HTTP(S) URL, root-relative route, or fragment.`,\n );\n if (\n item.variant !== undefined &&\n ![\"default\", \"primary\"].includes(item.variant as string)\n )\n invalid(\n diagnostics,\n `${path}.variant must be \"default\" or \"primary\".`,\n );\n if (item.newTab !== undefined && typeof item.newTab !== \"boolean\")\n invalid(diagnostics, `${path}.newTab must be a boolean.`);\n });\n }\n }\n\n if (config.navigation !== undefined && !Array.isArray(config.navigation)) {\n if (!isRecord(config.navigation)) {\n invalid(diagnostics, \"navigation must be an array or object.\");\n } else {\n for (const key of Object.keys(config.navigation)) {\n if (!new Set([\"items\", \"tabs\"]).has(key)) {\n unknown(diagnostics, `navigation.${key}`);\n }\n }\n if (\n config.navigation.items !== undefined &&\n !Array.isArray(config.navigation.items)\n ) {\n invalid(diagnostics, \"navigation.items must be an array.\");\n }\n if (\n config.navigation.tabs !== undefined &&\n !Array.isArray(config.navigation.tabs)\n ) {\n invalid(diagnostics, \"navigation.tabs must be an array.\");\n }\n }\n }\n if (Array.isArray(config.navigation)) {\n validateNavigationItems(config.navigation, \"navigation\", diagnostics);\n } else if (isRecord(config.navigation)) {\n if (Array.isArray(config.navigation.items)) {\n validateNavigationItems(\n config.navigation.items,\n \"navigation.items\",\n diagnostics,\n );\n }\n if (Array.isArray(config.navigation.tabs)) {\n for (const [index, tab] of config.navigation.tabs.entries()) {\n const path = `navigation.tabs[${index}]`;\n if (\n !isRecord(tab) ||\n typeof tab.label !== \"string\" ||\n typeof tab.link !== \"string\"\n ) {\n invalid(diagnostics, `${path} must have a label and link.`);\n } else if (tab.items !== undefined) {\n validateNavigationItems(tab.items, `${path}.items`, diagnostics);\n }\n }\n }\n }\n\n if (\n config.redirects !== undefined &&\n (!isRecord(config.redirects) ||\n Object.values(config.redirects).some(\n (value) => typeof value !== \"string\",\n ))\n )\n invalid(diagnostics, \"redirects must map old routes to document routes.\");\n const head = config.head;\n if (head !== undefined && !Array.isArray(head)) {\n invalid(diagnostics, \"head must be an array.\");\n } else {\n for (const [index, entry] of (head ?? []).entries()) {\n if (!isRecord(entry)) {\n invalid(diagnostics, `head[${index}] must be an object.`);\n continue;\n }\n for (const key of Object.keys(entry)) {\n if (!HEAD_KEYS.has(key)) {\n unknown(diagnostics, `head[${index}].${key}`);\n }\n }\n if (typeof entry.tag !== \"string\") {\n invalid(diagnostics, `head[${index}].tag must be a string.`);\n }\n if (entry.attrs !== undefined && !isRecord(entry.attrs)) {\n invalid(diagnostics, `head[${index}].attrs must be an object.`);\n } else {\n for (const [name, value] of Object.entries(entry.attrs ?? {})) {\n if (\n value !== undefined &&\n typeof value !== \"string\" &&\n typeof value !== \"boolean\"\n ) {\n invalid(\n diagnostics,\n `head[${index}].attrs.${name} must be a string or boolean.`,\n );\n }\n }\n }\n if (entry.content !== undefined && typeof entry.content !== \"string\") {\n invalid(diagnostics, `head[${index}].content must be a string.`);\n }\n }\n }\n\n const favicon = config.site?.favicon;\n if (favicon !== undefined) {\n if (typeof favicon === \"string\") {\n if (favicon.trim() === \"\") {\n invalid(diagnostics, \"site.favicon must be a non-empty local path.\");\n }\n } else if (!isRecord(favicon)) {\n invalid(\n diagnostics,\n \"site.favicon must be a local path or an object with a source path.\",\n );\n } else {\n for (const key of Object.keys(favicon)) {\n if (!SITE_ICON_KEYS.has(key)) {\n unknown(diagnostics, `site.favicon.${key}`);\n }\n }\n if (typeof favicon.source !== \"string\" || favicon.source.trim() === \"\") {\n invalid(diagnostics, \"site.favicon.source must be a non-empty string.\");\n }\n if (\n favicon.background !== undefined &&\n (typeof favicon.background !== \"string\" ||\n favicon.background.trim() === \"\")\n ) {\n invalid(\n diagnostics,\n \"site.favicon.background must be a non-empty color string.\",\n );\n }\n }\n }\n for (const field of [\"url\", \"repository\"] as const) {\n const value = config.site?.[field];\n if (value === undefined) continue;\n if (typeof value !== \"string\" || !isHttpUrl(value)) {\n invalid(diagnostics, `site.${field} must be an absolute HTTP(S) URL.`);\n }\n }\n\n if (\n config.editLink !== undefined &&\n (!isRecord(config.editLink) || typeof config.editLink.baseUrl !== \"string\")\n ) {\n invalid(diagnostics, \"editLink must contain a string baseUrl.\");\n } else if (config.editLink !== undefined) {\n for (const key of Object.keys(config.editLink)) {\n if (key !== \"baseUrl\") unknown(diagnostics, `editLink.${key}`);\n }\n try {\n new URL(config.editLink.baseUrl);\n } catch {\n invalid(diagnostics, \"editLink.baseUrl must be an absolute URL.\");\n }\n }\n if (\n config.lastUpdated !== undefined &&\n typeof config.lastUpdated !== \"boolean\"\n ) {\n invalid(diagnostics, \"lastUpdated must be a boolean.\");\n }\n if (config.locales !== undefined && !isRecord(config.locales)) {\n invalid(diagnostics, \"locales must be an object.\");\n } else {\n for (const [key, locale] of Object.entries(config.locales ?? {})) {\n if (!isRecord(locale) || typeof locale.label !== \"string\") {\n invalid(diagnostics, `locales.${key} must contain a string label.`);\n continue;\n }\n for (const property of Object.keys(locale)) {\n if (![\"label\", \"lang\", \"dir\"].includes(property)) {\n unknown(diagnostics, `locales.${key}.${property}`);\n }\n }\n if (locale.lang !== undefined && typeof locale.lang !== \"string\") {\n invalid(diagnostics, `locales.${key}.lang must be a string.`);\n }\n if (\n locale.dir !== undefined &&\n locale.dir !== \"ltr\" &&\n locale.dir !== \"rtl\"\n ) {\n invalid(diagnostics, `locales.${key}.dir must be \"ltr\" or \"rtl\".`);\n }\n }\n }\n if (\n config.defaultLocale !== undefined &&\n typeof config.defaultLocale !== \"string\"\n ) {\n invalid(diagnostics, \"defaultLocale must be a string.\");\n } else if (\n config.defaultLocale !== undefined &&\n (config.locales === undefined || !(config.defaultLocale in config.locales))\n ) {\n invalid(\n diagnostics,\n `defaultLocale must match a key in locales; received \"${config.defaultLocale}\".`,\n );\n }\n\n if (\n config.content?.allowOutsideRoot !== undefined &&\n typeof config.content.allowOutsideRoot !== \"boolean\"\n ) {\n invalid(diagnostics, \"content.allowOutsideRoot must be a boolean.\");\n }\n if (\n config.content?.localizeRepositoryLinks !== undefined &&\n typeof config.content.localizeRepositoryLinks !== \"boolean\"\n ) {\n invalid(diagnostics, \"content.localizeRepositoryLinks must be a boolean.\");\n }\n const configuredSources = config.content?.sources;\n if (configuredSources !== undefined && !Array.isArray(configuredSources)) {\n invalid(diagnostics, \"content.sources must be an array.\");\n }\n const sources = Array.isArray(configuredSources) ? configuredSources : [];\n for (const [index, source] of sources.entries()) {\n if (!isRecord(source)) {\n invalid(diagnostics, `content.sources[${index}] must be an object.`);\n continue;\n }\n const sourceRecord = source as unknown as Record<string, unknown>;\n const variants = [\"file\", \"glob\", \"package\"].filter((key) => key in source);\n if (variants.length !== 1) {\n diagnostics.push({\n code: \"DOCS_CONFIG_INVALID\",\n severity: \"error\",\n message: `content.sources[${index}] must select exactly one of file, glob, or package.`,\n });\n continue;\n }\n const variant = variants[0] as \"file\" | \"glob\" | \"package\";\n const allowed = {\n file: new Set([\n \"id\",\n \"root\",\n \"routeBase\",\n \"file\",\n \"route\",\n \"title\",\n \"description\",\n \"navigation\",\n ]),\n glob: new Set([\n \"id\",\n \"root\",\n \"glob\",\n \"base\",\n \"routeBase\",\n \"exclude\",\n \"navigation\",\n ]),\n package: new Set([\n \"id\",\n \"package\",\n \"registry\",\n \"include\",\n \"exclude\",\n \"index\",\n \"routeBase\",\n \"trust\",\n ]),\n }[variant];\n for (const key of Object.keys(source)) {\n if (!allowed.has(key))\n unknown(diagnostics, `content.sources[${index}].${key}`);\n }\n for (const field of [\n \"id\",\n \"root\",\n \"route\",\n \"routeBase\",\n \"base\",\n \"index\",\n \"title\",\n \"description\",\n \"registry\",\n ]) {\n if (\n sourceRecord[field] !== undefined &&\n typeof sourceRecord[field] !== \"string\"\n )\n invalid(\n diagnostics,\n `content.sources[${index}].${field} must be a string.`,\n );\n }\n if (\n typeof sourceRecord.id === \"string\" &&\n !/^[a-zA-Z0-9_-]+$/.test(sourceRecord.id)\n )\n invalid(\n diagnostics,\n `content.sources[${index}].id must contain only letters, numbers, underscores, and hyphens.`,\n );\n if (\n sourceRecord.trust !== undefined &&\n ![\"markdown\", \"mdx\"].includes(String(sourceRecord.trust))\n )\n invalid(\n diagnostics,\n `content.sources[${index}].trust must be \"markdown\" or \"mdx\".`,\n );\n if (\n typeof sourceRecord.registry === \"string\" &&\n !isHttpUrl(sourceRecord.registry)\n )\n invalid(\n diagnostics,\n `content.sources[${index}].registry must be an absolute HTTP(S) URL.`,\n );\n const selector = sourceRecord[variant];\n if (\n variant === \"glob\"\n ? typeof selector !== \"string\" &&\n (!Array.isArray(selector) ||\n selector.some((value) => typeof value !== \"string\"))\n : typeof selector !== \"string\" || selector.trim() === \"\"\n ) {\n invalid(\n diagnostics,\n `content.sources[${index}].${variant} must be ${variant === \"glob\" ? \"a string or string array\" : \"a non-empty string\"}.`,\n );\n }\n for (const list of [\"include\", \"exclude\"] as const) {\n const value = sourceRecord[list];\n if (\n value !== undefined &&\n (!Array.isArray(value) ||\n value.some((entry) => typeof entry !== \"string\"))\n ) {\n invalid(\n diagnostics,\n `content.sources[${index}].${list} must be a string array.`,\n );\n }\n }\n }\n\n if (\n config.markdown?.stripLeadingBadges !== undefined &&\n typeof config.markdown.stripLeadingBadges !== \"boolean\"\n ) {\n invalid(diagnostics, \"markdown.stripLeadingBadges must be a boolean.\");\n }\n if (\n config.markdown?.rawHtml !== undefined &&\n ![\"allow\", \"sanitize\", \"strip\", \"reject\"].includes(config.markdown.rawHtml)\n ) {\n invalid(\n diagnostics,\n 'markdown.rawHtml must be \"allow\", \"sanitize\", \"strip\", or \"reject\".',\n );\n }\n if (\n config.search?.enabled !== undefined &&\n typeof config.search.enabled !== \"boolean\"\n ) {\n invalid(diagnostics, \"search.enabled must be a boolean.\");\n }\n for (const key of [\"strict\", \"ci\"] as const) {\n const value = config.build?.[key];\n if (value !== undefined && typeof value !== \"boolean\") {\n invalid(diagnostics, `build.${key} must be a boolean.`);\n }\n }\n for (const key of [\n \"maxArtifactBytes\",\n \"maxUnpackedBytes\",\n \"maxFiles\",\n \"maxPathDepth\",\n \"maxAssetBytes\",\n ] as const) {\n const value = config.build?.[key];\n if (value !== undefined && (!Number.isSafeInteger(value) || value <= 0)) {\n invalid(diagnostics, `build.${key} must be a positive integer.`);\n }\n }\n\n const brand = config.theme?.brand;\n if (\n typeof brand === \"object\" &&\n brand !== null &&\n \"contrast\" in brand &&\n !brand.unsafeContrast\n ) {\n const target = brand.contrast?.apca;\n const normal = Array.isArray(target) ? target[0] : target;\n if (typeof normal === \"number\" && normal < 45) {\n diagnostics.push({\n code: \"DOCS_CONFIG_INVALID\",\n severity: \"error\",\n message:\n \"theme.brand.contrast.apca cannot be below 45 without unsafeContrast.\",\n hint: \"Remove the override, use 45 or higher, or explicitly set unsafeContrast: true.\",\n });\n }\n }\n\n if (\n config.content?.frontmatter !== undefined &&\n ![\"preserve\", \"reject\"].includes(config.content.frontmatter)\n )\n invalid(diagnostics, 'content.frontmatter must be \"preserve\" or \"reject\".');\n for (const field of [\n \"styles\",\n \"customStyles\",\n \"palette\",\n \"tokens\",\n \"states\",\n \"presets\",\n ] as const) {\n if (config.theme?.[field] !== undefined && !isRecord(config.theme[field]))\n invalid(diagnostics, `theme.${field} must be an object.`);\n }\n for (const [name, entry] of Object.entries(config.theme?.styles ?? {})) {\n if (!(COOKBOOK_COMPONENT_NAMES as readonly string[]).includes(name)) {\n unknown(\n diagnostics,\n `theme.styles.${name}; register custom components under theme.customStyles`,\n );\n continue;\n }\n if (!isRecord(entry))\n invalid(\n diagnostics,\n `theme.styles.${name} must be a Tasty style object.`,\n );\n else {\n if (\"mode\" in entry)\n invalid(\n diagnostics,\n `theme.styles.${name} must contain only Tasty properties, without a mode wrapper.`,\n );\n const elements: readonly string[] =\n COOKBOOK_COMPONENT_SUB_ELEMENTS[\n name as keyof typeof COOKBOOK_COMPONENT_SUB_ELEMENTS\n ];\n for (const key of Object.keys(entry)) {\n if (/^[A-Z]/.test(key) && !elements.includes(key))\n unknown(diagnostics, `theme.styles.${name}.${key}`);\n }\n }\n }\n for (const [name, entry] of Object.entries(\n config.theme?.customStyles ?? {},\n )) {\n if ((COOKBOOK_COMPONENT_NAMES as readonly string[]).includes(name))\n invalid(\n diagnostics,\n `Use theme.styles.${name} for a built-in component.`,\n );\n if (\n !/^[A-Za-z][A-Za-z0-9_-]*$/.test(name) ||\n !isRecord(entry) ||\n \"mode\" in entry\n )\n invalid(\n diagnostics,\n `theme.customStyles.${name} must be a named partial Tasty style object.`,\n );\n }\n for (const [name, value] of Object.entries(config.theme?.palette ?? {})) {\n if (\n ![\n \"surface\",\n \"header\",\n \"overlay\",\n \"text\",\n \"textSoft\",\n \"info\",\n \"success\",\n \"warning\",\n \"danger\",\n ].includes(name)\n )\n unknown(diagnostics, `theme.palette.${name}`);\n try {\n glaze.color({ from: value }).resolve();\n } catch (error) {\n invalid(\n diagnostics,\n `theme.palette.${name}: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n }\n if (brand !== undefined) {\n try {\n glaze\n .color({\n from:\n typeof brand === \"object\" && brand !== null && \"from\" in brand\n ? brand.from\n : brand,\n })\n .resolve();\n } catch (error) {\n invalid(\n diagnostics,\n `theme.brand: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n }\n const contrast = config.theme?.contrastLevel;\n if (\n contrast !== undefined &&\n contrast !== \"auto\" &&\n (typeof contrast !== \"number\" ||\n !Number.isFinite(contrast) ||\n contrast < 0 ||\n contrast > 100)\n )\n invalid(\n diagnostics,\n 'theme.contrastLevel must be \"auto\" or a number from 0 to 100.',\n );\n\n const componentOverrides = config.components?.overrides;\n if (componentOverrides !== undefined && !isRecord(componentOverrides)) {\n invalid(diagnostics, \"components.overrides must be an object.\");\n } else {\n for (const [name, override] of Object.entries(componentOverrides ?? {})) {\n if (typeof override === \"string\") continue;\n if (name === \"Footer\" && override === false) continue;\n invalid(\n diagnostics,\n `components.overrides.${name} must be an Astro component path${name === \"Footer\" ? \" or false\" : \"\"}.`,\n );\n }\n }\n return diagnostics;\n}\n\nfunction unknown(diagnostics: DocsDiagnostic[], path: string): void {\n diagnostics.push({\n code: \"DOCS_CONFIG_UNKNOWN_KEY\",\n severity: \"error\",\n message: `Unknown configuration key \"${path}\".`,\n });\n}\n\nfunction invalid(diagnostics: DocsDiagnostic[], message: string): void {\n diagnostics.push({\n code: \"DOCS_CONFIG_INVALID\",\n severity: \"error\",\n message,\n });\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction isHttpUrl(value: string): boolean {\n try {\n return [\"http:\", \"https:\"].includes(new URL(value).protocol);\n } catch {\n return false;\n }\n}\n\nfunction validateNavigationItems(\n items: unknown,\n path: string,\n diagnostics: DocsDiagnostic[],\n): void {\n if (!Array.isArray(items)) {\n invalid(diagnostics, `${path} must be an array.`);\n return;\n }\n for (const [index, item] of items.entries()) {\n const itemPath = `${path}[${index}]`;\n if (typeof item === \"string\") continue;\n if (!isRecord(item) || typeof item.label !== \"string\") {\n invalid(\n diagnostics,\n `${itemPath} must be a route or a labeled navigation item.`,\n );\n continue;\n }\n const group = \"items\" in item || \"autogenerate\" in item;\n if (\n group &&\n item.link !== undefined &&\n (typeof item.link !== \"string\" ||\n !/^\\/(?!\\/)[^?#\\\\\\s]*$/.test(item.link) ||\n item.link.includes(\"//\") ||\n item.link\n .split(\"/\")\n .some((segment) => segment === \".\" || segment === \"..\"))\n ) {\n invalid(\n diagnostics,\n `${itemPath}.link must be a root-relative page route without a query or fragment.`,\n );\n }\n if (\"items\" in item) {\n validateNavigationItems(item.items, `${itemPath}.items`, diagnostics);\n } else if (\"autogenerate\" in item) {\n if (\n !isRecord(item.autogenerate) ||\n typeof item.autogenerate.directory !== \"string\"\n ) {\n invalid(\n diagnostics,\n `${itemPath}.autogenerate.directory must be a directory path.`,\n );\n }\n } else if (typeof item.link !== \"string\") {\n invalid(diagnostics, `${itemPath}.link must be a URL or route.`);\n }\n }\n}\n\nexport function normalizeDocsConfig(\n config: DocsConfig = {},\n): NormalizedDocsConfig {\n const diagnostics = validateConfig(config);\n if (diagnostics.length > 0) throw new DocsConfigError(diagnostics);\n const navigation = Array.isArray(config.navigation)\n ? { items: config.navigation }\n : (config.navigation ?? {});\n\n return {\n redirects: { ...config.redirects },\n site: { ...config.site },\n head: [...(config.head ?? [])],\n ...(config.editLink ? { editLink: { ...config.editLink } } : {}),\n lastUpdated: config.lastUpdated ?? false,\n ...(config.locales ? { locales: { ...config.locales } } : {}),\n ...(config.defaultLocale ? { defaultLocale: config.defaultLocale } : {}),\n content: {\n allowOutsideRoot: false,\n localizeRepositoryLinks: false,\n ...config.content,\n },\n navigation,\n theme: { ...config.theme, brand: config.theme?.brand ?? DEFAULT_BRAND },\n markdown: {\n stripLeadingBadges: true,\n rawHtml: \"sanitize\",\n ...config.markdown,\n },\n search: { enabled: true, ...config.search },\n components: { ...config.components },\n build: {\n strict: true,\n ci: process.env.CI === \"true\",\n base: \"/\",\n cacheDir: \"\",\n maxArtifactBytes: 25 * 1024 * 1024,\n maxUnpackedBytes: 100 * 1024 * 1024,\n maxFiles: 10_000,\n maxPathDepth: 24,\n maxAssetBytes: 20 * 1024 * 1024,\n ...config.build,\n },\n };\n}\n\nexport function defineDocsConfig(config: DocsConfig): DocsConfig {\n const diagnostics = validateConfig(config);\n if (diagnostics.length > 0) throw new DocsConfigError(diagnostics);\n return config;\n}\n\n/** Compose presets. Objects merge, arrays replace, and styles use Tasty semantics. */\nexport function mergeDocsConfig(...configs: DocsConfig[]): DocsConfig {\n const merge = (\n base: Record<string, unknown>,\n next: Record<string, unknown>,\n ) => {\n const result = { ...base };\n for (const [key, value] of Object.entries(next)) {\n if (value === undefined) continue;\n result[key] = isRecord(value)\n ? merge(isRecord(result[key]) ? result[key] : {}, value)\n : Array.isArray(value)\n ? [...value]\n : value;\n }\n return result;\n };\n return defineDocsConfig(\n configs.reduce<DocsConfig>((base, next) => {\n const diagnostics = validateConfig(next);\n if (diagnostics.length) throw new DocsConfigError(diagnostics);\n const result = merge(\n base as Record<string, unknown>,\n next as Record<string, unknown>,\n ) as DocsConfig;\n for (const field of [\"styles\", \"customStyles\"] as const) {\n if (!next.theme?.[field]) continue;\n const styles = { ...base.theme?.[field] } as Record<string, Styles>;\n for (const [name, configured] of Object.entries(next.theme[field])) {\n styles[name] = mergeStyles(styles[name] ?? {}, configured);\n }\n result.theme![field] = styles;\n }\n return result;\n }, {}),\n );\n}\n\nexport { COOKBOOK_COMPONENT_NAMES, COOKBOOK_COMPONENT_SUB_ELEMENTS };\n\nexport type {\n BrandConfig,\n BuildConfig,\n ComponentStyleConfig,\n ComponentStyles,\n ComponentStylesConfig,\n CookbookComponentName,\n ComponentsConfig,\n ContentConfig,\n DocsConfig,\n DocsSource,\n EditLinkConfig,\n HeadConfig,\n LocaleConfig,\n MarkdownConfig,\n NavigationConfig,\n NavigationItem,\n NavigationPlacement,\n NavigationTab,\n NormalizedDocsConfig,\n SearchConfig,\n SiteConfig,\n HeaderLink,\n SiteIconConfig,\n ThemeConfig,\n ThemePaletteConfig,\n ThemeTokens,\n ThemeTokenValue,\n TypographyPreset,\n TypographyPresets,\n} from \"../types.js\";\n"],"mappings":";;;;AAgNA,MAAa,2BAA2B;CACtC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF;;AAKA,MAAa,kCAAkC;CAC7C,WAAW;EAAC;EAAa;EAAgB;CAAS;CAClD,aAAa,CAAC;CACd,aAAa;EACX;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF;CACA,QAAQ,CAAC,YAAY;CACrB,cAAc;EAAC;EAAS;EAAY;EAAS;EAAU;EAAc;CAAM;CAC3E,uBAAuB,CAAC,SAAS;CACjC,MAAM;EAAC;EAAY;EAAY;CAAW;CAC1C,SAAS;EAAC;EAAS;EAAQ;EAAO;EAAW;CAAQ;CACrD,WAAW;EAAC;EAAW;EAAO;CAAM;CACpC,KAAK;EAAC;EAAW;EAAU;CAAe;CAC1C,QAAQ;EACN;EACA;EACA;EACA;EACA;EACA;EACA;CACF;CACA,MAAM;EACJ;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF;CACA,gBAAgB;EACd;EACA;EACA;EACA;EACA;EACA;CACF;CACA,MAAM,CAAC,OAAO,MAAM;CACpB,mBAAmB;EACjB;EACA;EACA;EACA;EACA;EACA;CACF;CACA,iBAAiB;EACf;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF;CACA,eAAe;EAAC;EAAS;EAAQ;EAAmB;CAAY;CAChE,oBAAoB,CAAC;CACrB,SAAS;EAAC;EAAW;EAAQ;CAAU;CACvC,kBAAkB,CAAC,QAAQ;CAC3B,kBAAkB;EAChB;EACA;EACA;EACA;EACA;EACA;CACF;CACA,sBAAsB;EACpB;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF;CACA,uBAAuB;EACrB;EACA;EACA;EACA;EACA;EACA;CACF;CACA,gBAAgB,CAAC;CACjB,SAAS;EAAC;EAAW;EAAS;EAAS;EAAQ;EAAW;CAAK;CAC/D,SAAS;EACP;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF;CACA,OAAO,CAAC,QAAQ,QAAQ;CACxB,aAAa;EAAC;EAAQ;EAAa;CAAM;CACzC,MAAM;EAAC;EAAQ;EAAU;EAAkB;CAAe;CAC1D,iBAAiB;EACf;EACA;EACA;EACA;EACA;EACA;EACA;CACF;CACA,aAAa;EACX;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF;CACA,eAAe;EACb;EACA;EACA;EACA;EACA;CACF;CACA,iBAAiB;EACf;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF;AACF;;;ACvbA,MAAM,gBAAgB;AACtB,MAAM,4BAAY,IAAI,IAAI;CAAC;CAAO;CAAS;AAAS,CAAC;AACrD,MAAM,iCAAiB,IAAI,IAAI,CAAC,UAAU,YAAY,CAAC;AACvD,MAAM,4BAAY,IAAI,IAAI;CACxB;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF,CAAC;AAED,MAAM,cAA2C;CAC/C,sBAAM,IAAI,IAAI;EACZ;EACA;EACA;EACA;EACA;EACA;EACA;CACF,CAAC;CACD,yBAAS,IAAI,IAAI;EACf;EACA;EACA;EACA;CACF,CAAC;CACD,0BAAU,IAAI,IAAI,CAAC,sBAAsB,SAAS,CAAC;CACnD,wBAAQ,IAAI,IAAI,CAAC,SAAS,CAAC;CAC3B,4BAAY,IAAI,IAAI,CAAC,WAAW,CAAC;CACjC,uBAAO,IAAI,IAAI;EACb;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF,CAAC;CACD,uBAAO,IAAI,IAAI;EACb;EACA;EACA;EACA;EACA;EACA;EA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"}
@@ -1,4 +1,4 @@
1
- import { _ as DocsConfig, g as DocsAsset, m as CreateDocsGraphOptions, w as DocsRoute, x as DocsGraph, y as DocsEntry } from "../types-B-msp1dH.js";
1
+ import { _ as DocsConfig, g as DocsAsset, m as CreateDocsGraphOptions, w as DocsRoute, x as DocsGraph, y as DocsEntry } from "../types-CH6E2v-J.js";
2
2
  //#region src/content/index.d.ts
3
3
  interface DocsLoaderContext {
4
4
  store: {
@@ -1,2 +1,2 @@
1
- import { t as createDocsLoader } from "../content-BIpXueW7.js";
1
+ import { t as createDocsLoader } from "../content-Btz1o52C.js";
2
2
  export { createDocsLoader };
@@ -1,4 +1,4 @@
1
- import { i as normalizeDocsConfig } from "./config-DoR8g9IM.js";
1
+ import { i as normalizeDocsConfig } from "./config-CmoSqvii.js";
2
2
  import { cloneAst, parseMarkdown, removeRenderedTitle, serializeMarkdown, stripLeadingBadgeBlock } from "./markdown/index.js";
3
3
  import { lstat, mkdir, mkdtemp, readFile, readdir, rename, rm, stat, writeFile } from "node:fs/promises";
4
4
  import { basename, dirname, extname, isAbsolute, join, relative, resolve, sep } from "node:path";
@@ -970,18 +970,20 @@ function missingLink(diagnostics, entry, node, url, config) {
970
970
  });
971
971
  }
972
972
  function validateNavigation(items, routes, diagnostics) {
973
- for (const item of items) if (typeof item === "string") {
974
- if (!routes.has(normalizeRoute(item))) diagnostics.push({
973
+ for (const item of items) {
974
+ if (typeof item === "string") {
975
+ if (!routes.has(normalizeRoute(item))) diagnostics.push({
976
+ code: "DOCS_NAV_TARGET_NOT_FOUND",
977
+ severity: "error",
978
+ message: `Navigation target does not exist: ${item}.`
979
+ });
980
+ } else if (item.link?.startsWith("/") && !routes.has(normalizeRoute(item.link))) diagnostics.push({
975
981
  code: "DOCS_NAV_TARGET_NOT_FOUND",
976
982
  severity: "error",
977
- message: `Navigation target does not exist: ${item}.`
983
+ message: `Navigation target does not exist: ${item.link}.`
978
984
  });
979
- } else if ("items" in item) validateNavigation(item.items, routes, diagnostics);
980
- else if ("link" in item && item.link.startsWith("/") && !routes.has(normalizeRoute(item.link))) diagnostics.push({
981
- code: "DOCS_NAV_TARGET_NOT_FOUND",
982
- severity: "error",
983
- message: `Navigation target does not exist: ${item.link}.`
984
- });
985
+ if (typeof item !== "string" && "items" in item) validateNavigation(item.items, routes, diagnostics);
986
+ }
985
987
  }
986
988
  function normalizeRoute(route) {
987
989
  const segments = (route.split(/[?#]/, 1)[0]?.replace(/\\/g, "/").replace(/\/{2,}/g, "/") ?? "/").split("/").filter(Boolean);
@@ -1335,4 +1337,4 @@ function toLoaderEntry(entry) {
1335
1337
  //#endregion
1336
1338
  export { resolvePackageLock as _, validateDocs as a, routeForPath as c, discoverPackage as d, lockForSource as f, reconcileDocsLock as g, readDocsLock as h, formatDiagnostics as i, assertSafePackagePath as l, packageNameFromSpecifier as m, DocsValidationError as n, createDocsGraph as o, materializePackage as p, assertValidDocs as r, normalizeRoute as s, createDocsLoader as t, defaultLock as u, validateLock as v, writeDocsLock as y };
1337
1339
 
1338
- //# sourceMappingURL=content-BIpXueW7.js.map
1340
+ //# sourceMappingURL=content-Btz1o52C.js.map