blume 1.5.3 → 1.6.1

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 (209) hide show
  1. package/CHANGELOG.md +94 -0
  2. package/dist/cli/index.js +3949 -1403
  3. package/dist/cli/index.js.map +111 -96
  4. package/dist/types/ai/component-markdown.d.ts +79 -0
  5. package/dist/types/components/layout/nav-utils.d.ts +60 -0
  6. package/dist/types/core/base-path.d.ts +9 -0
  7. package/dist/types/core/config-input.d.ts +206 -4
  8. package/dist/types/core/config.d.ts +6 -4
  9. package/dist/types/core/data.d.ts +33 -2
  10. package/dist/types/core/github.d.ts +35 -0
  11. package/dist/types/core/i18n-ui.d.ts +10 -0
  12. package/dist/types/core/navigation.d.ts +69 -0
  13. package/dist/types/core/schema.d.ts +122 -1
  14. package/dist/types/core/sources/types.d.ts +31 -6
  15. package/dist/types/core/types.d.ts +29 -2
  16. package/dist/types/markdown/features.d.ts +21 -0
  17. package/dist/types/openapi/references.d.ts +26 -1
  18. package/dist/types/seo/jsonld.d.ts +105 -0
  19. package/dist/types/theme/fonts.d.ts +34 -4
  20. package/docs/07-faq.mdx +9 -9
  21. package/docs/_snippets/include-demo.mdx +7 -0
  22. package/docs/advanced/api-reference.mdx +13 -4
  23. package/docs/advanced/custom-pages.mdx +4 -2
  24. package/docs/advanced/graphql.mdx +84 -0
  25. package/docs/advanced/meta.ts +8 -1
  26. package/docs/configuration/ai.mdx +25 -3
  27. package/docs/configuration/index.mdx +24 -0
  28. package/docs/configuration/search.mdx +13 -1
  29. package/docs/configuration/seo.mdx +30 -3
  30. package/docs/configuration/theming.mdx +23 -0
  31. package/docs/content/components.mdx +15 -1
  32. package/docs/content/includes.mdx +68 -0
  33. package/docs/content/meta.ts +1 -0
  34. package/docs/content/navigation.mdx +25 -0
  35. package/docs/content/sources.mdx +42 -1
  36. package/docs/content/syntax.mdx +69 -1
  37. package/docs/content/versioning.mdx +15 -9
  38. package/docs/reference/cli.mdx +2 -1
  39. package/package.json +66 -57
  40. package/skills/blume-migrate/SKILL.md +16 -7
  41. package/skills/blume-migrate/references/docusaurus.md +5 -3
  42. package/skills/blume-migrate/references/fumadocs.md +10 -2
  43. package/skills/blume-migrate/references/mintlify.md +3 -2
  44. package/skills/blume-migrate/references/nextra.md +2 -2
  45. package/skills/blume-migrate/references/starlight.md +1 -1
  46. package/src/ai/agent-readability.ts +2 -1
  47. package/src/ai/ask-data.ts +2 -1
  48. package/src/ai/component-markdown.ts +199 -36
  49. package/src/ai/llms.ts +93 -6
  50. package/src/ai/markdown.ts +2 -2
  51. package/src/ai/mcp/discovery.ts +10 -2
  52. package/src/ai/mcp/server.ts +74 -2
  53. package/src/astro/examples.ts +29 -2
  54. package/src/astro/generate.ts +282 -177
  55. package/src/astro/include-hmr.ts +81 -0
  56. package/src/astro/include-refresh.ts +0 -0
  57. package/src/astro/index.ts +10 -5
  58. package/src/astro/markdown-negotiation.ts +1 -1
  59. package/src/astro/runtime-modules.ts +196 -0
  60. package/src/astro/templates.ts +365 -113
  61. package/src/cli/commands/build.ts +91 -16
  62. package/src/cli/commands/dev.ts +6 -3
  63. package/src/cli/host-args.ts +18 -0
  64. package/src/cli/index.ts +2 -1
  65. package/src/cli/init/questions.ts +1 -0
  66. package/src/cli/init/scaffold.ts +27 -4
  67. package/src/components/colors.ts +142 -0
  68. package/src/components/content/Badge.astro +5 -12
  69. package/src/components/content/Callout.astro +19 -36
  70. package/src/components/content/Card.astro +15 -21
  71. package/src/components/content/Component.astro +10 -1
  72. package/src/components/content/GithubInfo.astro +28 -9
  73. package/src/components/content/Tabs.astro +27 -5
  74. package/src/components/content/github-info.ts +20 -5
  75. package/src/components/copy-feedback.ts +93 -9
  76. package/src/components/dropdown-dismiss.ts +122 -0
  77. package/src/components/islands/ask-ai.tsx +4 -1
  78. package/src/components/islands/hooks.ts +3 -1
  79. package/src/components/layout/Fonts.astro +15 -8
  80. package/src/components/layout/Header.astro +44 -0
  81. package/src/components/layout/LanguageSwitcher.astro +9 -1
  82. package/src/components/layout/NavSelector.astro +12 -3
  83. package/src/components/layout/NavTree.astro +6 -18
  84. package/src/components/layout/PageActions.astro +54 -22
  85. package/src/components/layout/PageLayout.astro +2 -0
  86. package/src/components/layout/ReferenceLayout.astro +6 -1
  87. package/src/components/layout/RootLayout.astro +42 -15
  88. package/src/components/layout/Search.astro +36 -4
  89. package/src/components/layout/TableOfContents.astro +8 -2
  90. package/src/components/layout/head-scripts.ts +30 -1
  91. package/src/components/openapi/ApiOverview.astro +13 -3
  92. package/src/components/openapi/AsyncApiOperation.astro +7 -14
  93. package/src/components/openapi/GraphqlChip.astro +33 -0
  94. package/src/components/openapi/GraphqlFieldsTable.astro +111 -0
  95. package/src/components/openapi/GraphqlOperation.astro +186 -0
  96. package/src/components/openapi/GraphqlType.astro +154 -0
  97. package/src/components/openapi/MethodBadge.astro +3 -14
  98. package/src/components/openapi/Operation.astro +12 -5
  99. package/src/components/openapi/OperationPanel.astro +43 -0
  100. package/src/components/openapi/RequestPanel.astro +5 -10
  101. package/src/components/openapi/Responses.astro +1 -16
  102. package/src/components/openapi/graphql-helpers.ts +466 -0
  103. package/src/components/openapi/playground-client.ts +15 -0
  104. package/src/components/openapi/sample-panels.ts +45 -0
  105. package/src/components/openapi/snippets.ts +13 -35
  106. package/src/core/base-path.ts +11 -0
  107. package/src/core/config-input.ts +209 -2
  108. package/src/core/config.ts +6 -4
  109. package/src/core/content-assets.ts +15 -4
  110. package/src/core/data.ts +28 -3
  111. package/src/core/define-components.ts +2 -0
  112. package/src/core/diagnostics.ts +8 -0
  113. package/src/core/frontmatter.ts +20 -8
  114. package/src/core/github.ts +71 -0
  115. package/src/core/graph.ts +22 -8
  116. package/src/core/heading-markers.ts +96 -0
  117. package/src/core/i18n-ui.ts +12 -0
  118. package/src/core/includes.ts +633 -0
  119. package/src/core/last-modified.ts +36 -11
  120. package/src/core/links.ts +79 -13
  121. package/src/core/manifest.ts +10 -0
  122. package/src/core/meta.ts +2 -1
  123. package/src/core/nav-diagnostics.ts +11 -2
  124. package/src/core/navigation.ts +27 -6
  125. package/src/core/project-graph.ts +61 -9
  126. package/src/core/schema.ts +235 -36
  127. package/src/core/server-features.ts +5 -9
  128. package/src/core/sources/github-releases.ts +2 -2
  129. package/src/core/sources/normalize.ts +502 -115
  130. package/src/core/sources/notion.ts +43 -8
  131. package/src/core/sources/obsidian.ts +1038 -0
  132. package/src/core/sources/read.ts +36 -1
  133. package/src/core/sources/resolve.ts +34 -1
  134. package/src/core/sources/types.ts +28 -6
  135. package/src/core/sources/watch.ts +12 -8
  136. package/src/core/tsconfig-aliases.ts +48 -35
  137. package/src/core/types.ts +31 -2
  138. package/src/core/ui-packs/ar.ts +2 -0
  139. package/src/core/ui-packs/bg.ts +3 -0
  140. package/src/core/ui-packs/bn.ts +2 -0
  141. package/src/core/ui-packs/ca.ts +3 -0
  142. package/src/core/ui-packs/cs.ts +2 -0
  143. package/src/core/ui-packs/da.ts +2 -0
  144. package/src/core/ui-packs/de.ts +3 -0
  145. package/src/core/ui-packs/el.ts +3 -0
  146. package/src/core/ui-packs/es.ts +3 -0
  147. package/src/core/ui-packs/fa.ts +2 -0
  148. package/src/core/ui-packs/fi.ts +2 -0
  149. package/src/core/ui-packs/fr.ts +3 -0
  150. package/src/core/ui-packs/he.ts +2 -0
  151. package/src/core/ui-packs/hi.ts +2 -0
  152. package/src/core/ui-packs/hr.ts +3 -0
  153. package/src/core/ui-packs/hu.ts +3 -0
  154. package/src/core/ui-packs/id.ts +3 -0
  155. package/src/core/ui-packs/it.ts +2 -0
  156. package/src/core/ui-packs/ja.ts +3 -0
  157. package/src/core/ui-packs/ko.ts +3 -0
  158. package/src/core/ui-packs/nl.ts +3 -0
  159. package/src/core/ui-packs/no.ts +3 -0
  160. package/src/core/ui-packs/pl.ts +3 -0
  161. package/src/core/ui-packs/pt-br.ts +3 -0
  162. package/src/core/ui-packs/pt.ts +3 -0
  163. package/src/core/ui-packs/ro.ts +3 -0
  164. package/src/core/ui-packs/ru.ts +3 -0
  165. package/src/core/ui-packs/sk.ts +2 -0
  166. package/src/core/ui-packs/sr.ts +2 -0
  167. package/src/core/ui-packs/sv.ts +3 -0
  168. package/src/core/ui-packs/th.ts +2 -0
  169. package/src/core/ui-packs/tr.ts +3 -0
  170. package/src/core/ui-packs/uk.ts +3 -0
  171. package/src/core/ui-packs/vi.ts +2 -0
  172. package/src/core/ui-packs/zh-tw.ts +2 -0
  173. package/src/core/ui-packs/zh.ts +2 -0
  174. package/src/core/version-cut.ts +26 -6
  175. package/src/core/yaml.ts +26 -0
  176. package/src/deploy/function-bundle.ts +251 -0
  177. package/src/deploy/vercel-negotiation.ts +49 -6
  178. package/src/eval/schema.ts +3 -1
  179. package/src/markdown/code-title.ts +22 -16
  180. package/src/markdown/features.ts +21 -0
  181. package/src/markdown/fence-meta.ts +50 -0
  182. package/src/markdown/heading-anchors.ts +198 -37
  183. package/src/markdown/include.ts +247 -0
  184. package/src/markdown/index.ts +43 -34
  185. package/src/markdown/language-icon.ts +2 -2
  186. package/src/markdown/mdast.ts +7 -3
  187. package/src/markdown/ts2js.ts +264 -0
  188. package/src/og/card.ts +1 -1
  189. package/src/openapi/asyncapi.ts +4 -1
  190. package/src/openapi/graphql-build.ts +293 -0
  191. package/src/openapi/graphql.ts +212 -0
  192. package/src/openapi/model.ts +38 -5
  193. package/src/openapi/parse.ts +34 -0
  194. package/src/openapi/proxy.ts +30 -5
  195. package/src/openapi/references.ts +97 -13
  196. package/src/openapi/render-mdx.ts +66 -12
  197. package/src/openapi/scalar.ts +5 -16
  198. package/src/openapi/source.ts +91 -23
  199. package/src/registry/eject.ts +47 -17
  200. package/src/search/documents.ts +229 -37
  201. package/src/search/orama-index.ts +9 -5
  202. package/src/seo/jsonld.ts +293 -51
  203. package/src/theme/code-block-padding.ts +16 -0
  204. package/src/theme/entry.ts +67 -13
  205. package/src/theme/fonts.ts +189 -16
  206. package/src/theme/sources.ts +49 -0
  207. package/src/translate/prompts.ts +2 -0
  208. package/src/translate/run.ts +7 -0
  209. package/src/translate/work-list.ts +0 -0
@@ -0,0 +1,69 @@
1
+ import type { FolderMeta, SidebarDisplay, SidebarItemConfig } from "./schema.ts";
2
+ import type { Diagnostic, FeaturedLink, HeaderAction, Navigation, NavSelector, NavTab, PageRecord } from "./types.ts";
3
+ /**
4
+ * Whether `route` is the section root `base` or nested beneath it. Requires a
5
+ * path boundary, so `/api-reference` is not under `/api`. The root `/` spans
6
+ * every route.
7
+ */
8
+ export declare const isUnderPath: (route: string, base: string) => boolean;
9
+ /**
10
+ * Whether `tab` is the root tab of the tree rooted at `root` — the tab that
11
+ * spans the whole sidebar rather than one section. Tab paths and the root
12
+ * normally share one path space, so the root tab sits at `root` exactly (`/`,
13
+ * `/en`, `/docs`); in an archived version tree the root is versionized
14
+ * (`/v1.0`, `/docs/v1.0`) while tab paths stay in current-docs space, so the
15
+ * root tab is any tab the whole root sits under. The one definition shared by
16
+ * sidebar scoping, tab-section hoisting, and the header's current-tab state —
17
+ * consumers that disagree on which tab is the root tab prune an archived
18
+ * sidebar or highlight the wrong tab over it.
19
+ */
20
+ export declare const isRootTab: (tab: NavTab, root: string) => boolean;
21
+ /** Build the complete navigation model from pages, meta, and config. */
22
+ export declare const buildNavigation: (pages: PageRecord[], options: {
23
+ /** Plain links in the header, left of the icon buttons. */
24
+ actions?: HeaderAction[];
25
+ /** Site-wide route mount point (`""` or `/seg`); applied to config paths. */
26
+ basePath?: string;
27
+ /** The single primary call to action in the header. */
28
+ cta?: HeaderAction | null;
29
+ folderMeta: Map<string, FolderMeta>;
30
+ /** Global display mode for every sidebar group (default `flat`). */
31
+ display?: SidebarDisplay;
32
+ featured?: FeaturedLink[];
33
+ selectors?: NavSelector[];
34
+ tabs?: NavTab[];
35
+ sidebar?: SidebarItemConfig[];
36
+ /**
37
+ * Folder-meta lookup prefix (`""` for the default locale of the current
38
+ * version): the version dir and/or locale dir hoisted in front of the
39
+ * group path, e.g. `fr`, `v1.0`, or `v1.0/fr`.
40
+ */
41
+ metaPrefix?: string;
42
+ /**
43
+ * Prefix for shared `meta.$.*` lookups — the version dir inside a
44
+ * snapshot (`v1.0`), since shared meta is locale-agnostic but still
45
+ * version-specific. `""` for the current version.
46
+ */
47
+ sharedMetaPrefix?: string;
48
+ /**
49
+ * Resolve explicit-sidebar references against each page's locale-agnostic
50
+ * `translationKey` instead of its localized `route`. Used under i18n so a
51
+ * single authored sidebar maps onto every locale's pages.
52
+ */
53
+ refByLogical?: boolean;
54
+ /** Shared `meta.$.*` meta, keyed by locale-stripped dir path. */
55
+ sharedFolderMeta?: Map<string, FolderMeta>;
56
+ /**
57
+ * The tree's root route before `basePath` (`"/"`, or the locale prefix
58
+ * under i18n, e.g. `/fr` — tab paths arrive already localized). The tab
59
+ * pointing here spans the whole tree, so it is excluded from tab-section
60
+ * scoping.
61
+ */
62
+ localizedRoot?: string;
63
+ /**
64
+ * Sink for diagnostics produced while building the tree (duplicate sidebar
65
+ * `order` values, index-page title/folder-meta-title mismatches). Pushed
66
+ * into in place; omit to discard.
67
+ */
68
+ diagnostics?: Diagnostic[];
69
+ }) => Navigation;
@@ -218,6 +218,11 @@ declare const contentSourceSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
218
218
  publishedValue: z.ZodOptional<z.ZodString>;
219
219
  type: z.ZodLiteral<"notion">;
220
220
  }, z.core.$strip>, z.ZodObject<{
221
+ exclude: z.ZodOptional<z.ZodArray<z.ZodString>>;
222
+ prefix: z.ZodOptional<z.ZodString>;
223
+ type: z.ZodLiteral<"obsidian">;
224
+ vault: z.ZodString;
225
+ }, z.core.$strict>, z.ZodObject<{
221
226
  source: z.ZodCustom<ContentSource, ContentSource>;
222
227
  type: z.ZodLiteral<"custom">;
223
228
  }, z.core.$strip>], "type">;
@@ -280,14 +285,17 @@ declare const aiConfigSchema: z.ZodObject<{
280
285
  }, z.core.$strict>>>;
281
286
  }, z.core.$strict>>;
282
287
  llmsTxt: z.ZodPipe<z.ZodDefault<z.ZodUnion<readonly [z.ZodBoolean, z.ZodObject<{
288
+ details: z.ZodOptional<z.ZodString>;
283
289
  enabled: z.ZodDefault<z.ZodBoolean>;
284
290
  openapi: z.ZodDefault<z.ZodBoolean>;
285
291
  }, z.core.$strict>]>>, z.ZodTransform<{
286
292
  enabled: boolean;
287
293
  openapi: boolean;
294
+ details?: string | undefined;
288
295
  }, boolean | {
289
296
  enabled: boolean;
290
297
  openapi: boolean;
298
+ details?: string | undefined;
291
299
  }>>;
292
300
  markdownComponents: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodCustom<ComponentMarkdown, ComponentMarkdown>>>;
293
301
  mcp: z.ZodPrefault<z.ZodObject<{
@@ -469,9 +477,27 @@ declare const openapiSourceSchema: z.ZodObject<{
469
477
  label: z.ZodOptional<z.ZodString>;
470
478
  noindex: z.ZodDefault<z.ZodBoolean>;
471
479
  route: z.ZodOptional<z.ZodString>;
480
+ seoDescriptionSuffix: z.ZodDefault<z.ZodBoolean>;
472
481
  spec: z.ZodString;
473
482
  }, z.core.$strict>;
474
483
  export type OpenApiSource = z.input<typeof openapiSourceSchema>;
484
+ /**
485
+ * A single GraphQL schema rendered by the reference. `spec` is a local path or
486
+ * an `http(s)` URL to SDL text or an introspection JSON result; `endpoint` is
487
+ * the live GraphQL API URL the playground and code samples target (a schema,
488
+ * unlike an OpenAPI document, names no server).
489
+ */
490
+ declare const graphqlSourceSchema: z.ZodObject<{
491
+ includeInLlms: z.ZodDefault<z.ZodBoolean>;
492
+ includeInSearch: z.ZodDefault<z.ZodBoolean>;
493
+ label: z.ZodOptional<z.ZodString>;
494
+ noindex: z.ZodDefault<z.ZodBoolean>;
495
+ route: z.ZodOptional<z.ZodString>;
496
+ seoDescriptionSuffix: z.ZodDefault<z.ZodBoolean>;
497
+ spec: z.ZodString;
498
+ endpoint: z.ZodOptional<z.ZodString>;
499
+ }, z.core.$strict>;
500
+ export type GraphqlSource = z.input<typeof graphqlSourceSchema>;
475
501
  export declare const blumeConfigSchema: z.ZodObject<{
476
502
  ai: z.ZodPrefault<z.ZodObject<{
477
503
  ask: z.ZodOptional<z.ZodObject<{
@@ -499,14 +525,17 @@ export declare const blumeConfigSchema: z.ZodObject<{
499
525
  }, z.core.$strict>>>;
500
526
  }, z.core.$strict>>;
501
527
  llmsTxt: z.ZodPipe<z.ZodDefault<z.ZodUnion<readonly [z.ZodBoolean, z.ZodObject<{
528
+ details: z.ZodOptional<z.ZodString>;
502
529
  enabled: z.ZodDefault<z.ZodBoolean>;
503
530
  openapi: z.ZodDefault<z.ZodBoolean>;
504
531
  }, z.core.$strict>]>>, z.ZodTransform<{
505
532
  enabled: boolean;
506
533
  openapi: boolean;
534
+ details?: string | undefined;
507
535
  }, boolean | {
508
536
  enabled: boolean;
509
537
  openapi: boolean;
538
+ details?: string | undefined;
510
539
  }>>;
511
540
  markdownComponents: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodCustom<ComponentMarkdown, ComponentMarkdown>>>;
512
541
  mcp: z.ZodPrefault<z.ZodObject<{
@@ -571,6 +600,7 @@ export declare const blumeConfigSchema: z.ZodObject<{
571
600
  label: z.ZodOptional<z.ZodString>;
572
601
  noindex: z.ZodDefault<z.ZodBoolean>;
573
602
  route: z.ZodOptional<z.ZodString>;
603
+ seoDescriptionSuffix: z.ZodDefault<z.ZodBoolean>;
574
604
  spec: z.ZodString;
575
605
  }, z.core.$strict>>>;
576
606
  spec: z.ZodOptional<z.ZodString>;
@@ -650,6 +680,11 @@ export declare const blumeConfigSchema: z.ZodObject<{
650
680
  publishedValue: z.ZodOptional<z.ZodString>;
651
681
  type: z.ZodLiteral<"notion">;
652
682
  }, z.core.$strip>, z.ZodObject<{
683
+ exclude: z.ZodOptional<z.ZodArray<z.ZodString>>;
684
+ prefix: z.ZodOptional<z.ZodString>;
685
+ type: z.ZodLiteral<"obsidian">;
686
+ vault: z.ZodString;
687
+ }, z.core.$strict>, z.ZodObject<{
653
688
  source: z.ZodCustom<ContentSource, ContentSource>;
654
689
  type: z.ZodLiteral<"custom">;
655
690
  }, z.core.$strip>], "type">>>;
@@ -734,11 +769,40 @@ export declare const blumeConfigSchema: z.ZodObject<{
734
769
  extend: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodCustom<StandardSchema<unknown, unknown>, StandardSchema<unknown, unknown>>>>;
735
770
  }, z.core.$strict>>;
736
771
  github: z.ZodOptional<z.ZodObject<{
772
+ api: z.ZodOptional<z.ZodPipe<z.ZodURL, z.ZodTransform<string, string>>>;
737
773
  branch: z.ZodDefault<z.ZodString>;
738
774
  dir: z.ZodOptional<z.ZodString>;
775
+ host: z.ZodDefault<z.ZodPipe<z.ZodURL, z.ZodTransform<string, string>>>;
739
776
  owner: z.ZodString;
740
777
  repo: z.ZodString;
741
778
  }, z.core.$strict>>;
779
+ graphql: z.ZodPrefault<z.ZodObject<{
780
+ enabled: z.ZodDefault<z.ZodBoolean>;
781
+ route: z.ZodDefault<z.ZodString>;
782
+ codeSamples: z.ZodDefault<z.ZodArray<z.ZodString>>;
783
+ playground: z.ZodPipe<z.ZodDefault<z.ZodUnion<readonly [z.ZodBoolean, z.ZodObject<{
784
+ enabled: z.ZodDefault<z.ZodBoolean>;
785
+ proxy: z.ZodDefault<z.ZodUnion<readonly [z.ZodBoolean, z.ZodString]>>;
786
+ }, z.core.$strict>]>>, z.ZodTransform<{
787
+ enabled: boolean;
788
+ proxy: string | boolean;
789
+ }, boolean | {
790
+ enabled: boolean;
791
+ proxy: string | boolean;
792
+ }>>;
793
+ spec: z.ZodOptional<z.ZodString>;
794
+ endpoint: z.ZodOptional<z.ZodString>;
795
+ sources: z.ZodDefault<z.ZodArray<z.ZodObject<{
796
+ includeInLlms: z.ZodDefault<z.ZodBoolean>;
797
+ includeInSearch: z.ZodDefault<z.ZodBoolean>;
798
+ label: z.ZodOptional<z.ZodString>;
799
+ noindex: z.ZodDefault<z.ZodBoolean>;
800
+ route: z.ZodOptional<z.ZodString>;
801
+ seoDescriptionSuffix: z.ZodDefault<z.ZodBoolean>;
802
+ spec: z.ZodString;
803
+ endpoint: z.ZodOptional<z.ZodString>;
804
+ }, z.core.$strict>>>;
805
+ }, z.core.$strict>>;
742
806
  i18n: z.ZodOptional<z.ZodObject<{
743
807
  defaultLocale: z.ZodDefault<z.ZodString>;
744
808
  fallbackLocale: z.ZodOptional<z.ZodNullable<z.ZodString>>;
@@ -798,12 +862,20 @@ export declare const blumeConfigSchema: z.ZodObject<{
798
862
  imageZoom: z.ZodDefault<z.ZodBoolean>;
799
863
  }, z.core.$strict>>;
800
864
  navigation: z.ZodPrefault<z.ZodObject<{
865
+ actions: z.ZodDefault<z.ZodArray<z.ZodObject<{
866
+ href: z.ZodString;
867
+ label: z.ZodString;
868
+ }, z.core.$strict>>>;
869
+ cta: z.ZodOptional<z.ZodObject<{
870
+ href: z.ZodString;
871
+ label: z.ZodString;
872
+ }, z.core.$strict>>;
801
873
  featured: z.ZodDefault<z.ZodArray<z.ZodObject<{
802
874
  href: z.ZodString;
803
875
  icon: z.ZodOptional<z.ZodString>;
804
876
  label: z.ZodString;
805
877
  }, z.core.$strict>>>;
806
- repo: z.ZodDefault<z.ZodBoolean>;
878
+ repo: z.ZodDefault<z.ZodUnion<readonly [z.ZodBoolean, z.ZodURL]>>;
807
879
  selectors: z.ZodDefault<z.ZodArray<z.ZodObject<{
808
880
  items: z.ZodDefault<z.ZodArray<z.ZodObject<{
809
881
  description: z.ZodOptional<z.ZodString>;
@@ -874,6 +946,7 @@ export declare const blumeConfigSchema: z.ZodObject<{
874
946
  label: z.ZodOptional<z.ZodString>;
875
947
  noindex: z.ZodDefault<z.ZodBoolean>;
876
948
  route: z.ZodOptional<z.ZodString>;
949
+ seoDescriptionSuffix: z.ZodDefault<z.ZodBoolean>;
877
950
  spec: z.ZodString;
878
951
  }, z.core.$strict>>>;
879
952
  spec: z.ZodOptional<z.ZodString>;
@@ -894,6 +967,7 @@ export declare const blumeConfigSchema: z.ZodObject<{
894
967
  searchApiKey: z.ZodString;
895
968
  }, z.core.$strict>>;
896
969
  indexing: z.ZodPrefault<z.ZodObject<{
970
+ includeCodeBlocks: z.ZodDefault<z.ZodBoolean>;
897
971
  includeHiddenPages: z.ZodDefault<z.ZodBoolean>;
898
972
  }, z.core.$strict>>;
899
973
  mixedbread: z.ZodOptional<z.ZodObject<{
@@ -978,6 +1052,22 @@ export declare const blumeConfigSchema: z.ZodObject<{
978
1052
  site: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodLiteral<false>]>>;
979
1053
  titles: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
980
1054
  }, z.core.$strict>>;
1055
+ organization: z.ZodOptional<z.ZodObject<{
1056
+ address: z.ZodOptional<z.ZodObject<{
1057
+ addressCountry: z.ZodOptional<z.ZodString>;
1058
+ addressLocality: z.ZodOptional<z.ZodString>;
1059
+ addressRegion: z.ZodOptional<z.ZodString>;
1060
+ postalCode: z.ZodOptional<z.ZodString>;
1061
+ streetAddress: z.ZodOptional<z.ZodString>;
1062
+ }, z.core.$strict>>;
1063
+ contactType: z.ZodDefault<z.ZodString>;
1064
+ email: z.ZodOptional<z.ZodEmail>;
1065
+ logo: z.ZodOptional<z.ZodString>;
1066
+ name: z.ZodOptional<z.ZodString>;
1067
+ sameAs: z.ZodDefault<z.ZodArray<z.ZodURL>>;
1068
+ telephone: z.ZodOptional<z.ZodString>;
1069
+ url: z.ZodOptional<z.ZodURL>;
1070
+ }, z.core.$strict>>;
981
1071
  robots: z.ZodDefault<z.ZodBoolean>;
982
1072
  rss: z.ZodPrefault<z.ZodObject<{
983
1073
  enabled: z.ZodDefault<z.ZodBoolean>;
@@ -985,6 +1075,34 @@ export declare const blumeConfigSchema: z.ZodObject<{
985
1075
  types: z.ZodDefault<z.ZodArray<z.ZodString>>;
986
1076
  }, z.core.$strict>>;
987
1077
  sitemap: z.ZodDefault<z.ZodBoolean>;
1078
+ software: z.ZodPipe<z.ZodOptional<z.ZodUnion<readonly [z.ZodBoolean, z.ZodObject<{
1079
+ applicationCategory: z.ZodDefault<z.ZodString>;
1080
+ description: z.ZodOptional<z.ZodString>;
1081
+ license: z.ZodOptional<z.ZodString>;
1082
+ name: z.ZodOptional<z.ZodString>;
1083
+ operatingSystem: z.ZodOptional<z.ZodString>;
1084
+ price: z.ZodOptional<z.ZodUnion<readonly [z.ZodNumber, z.ZodString]>>;
1085
+ priceCurrency: z.ZodDefault<z.ZodString>;
1086
+ sameAs: z.ZodDefault<z.ZodArray<z.ZodURL>>;
1087
+ }, z.core.$strict>]>>, z.ZodTransform<{
1088
+ applicationCategory: string;
1089
+ priceCurrency: string;
1090
+ sameAs: string[];
1091
+ description?: string | undefined;
1092
+ license?: string | undefined;
1093
+ name?: string | undefined;
1094
+ operatingSystem?: string | undefined;
1095
+ price?: string | number | undefined;
1096
+ } | undefined, boolean | {
1097
+ applicationCategory: string;
1098
+ priceCurrency: string;
1099
+ sameAs: string[];
1100
+ description?: string | undefined;
1101
+ license?: string | undefined;
1102
+ name?: string | undefined;
1103
+ operatingSystem?: string | undefined;
1104
+ price?: string | number | undefined;
1105
+ } | undefined>>;
988
1106
  structuredData: z.ZodDefault<z.ZodBoolean>;
989
1107
  x: z.ZodDefault<z.ZodObject<{
990
1108
  creator: z.ZodOptional<z.ZodPipe<z.ZodString, z.ZodTransform<string | undefined, string>>>;
@@ -1037,6 +1155,7 @@ export declare const blumeConfigSchema: z.ZodObject<{
1037
1155
  bunny: "bunny";
1038
1156
  fontshare: "fontshare";
1039
1157
  }>>;
1158
+ subsets: z.ZodOptional<z.ZodArray<z.ZodString>>;
1040
1159
  weights: z.ZodOptional<z.ZodArray<z.ZodUnion<readonly [z.ZodNumber, z.ZodString]>>>;
1041
1160
  }, z.core.$strict>, z.ZodObject<{
1042
1161
  fallback: z.ZodOptional<z.ZodEnum<{
@@ -1068,6 +1187,7 @@ export declare const blumeConfigSchema: z.ZodObject<{
1068
1187
  bunny: "bunny";
1069
1188
  fontshare: "fontshare";
1070
1189
  }>>;
1190
+ subsets: z.ZodOptional<z.ZodArray<z.ZodString>>;
1071
1191
  weights: z.ZodOptional<z.ZodArray<z.ZodUnion<readonly [z.ZodNumber, z.ZodString]>>>;
1072
1192
  }, z.core.$strict>, z.ZodObject<{
1073
1193
  fallback: z.ZodOptional<z.ZodEnum<{
@@ -1099,6 +1219,7 @@ export declare const blumeConfigSchema: z.ZodObject<{
1099
1219
  bunny: "bunny";
1100
1220
  fontshare: "fontshare";
1101
1221
  }>>;
1222
+ subsets: z.ZodOptional<z.ZodArray<z.ZodString>>;
1102
1223
  weights: z.ZodOptional<z.ZodArray<z.ZodUnion<readonly [z.ZodNumber, z.ZodString]>>>;
1103
1224
  }, z.core.$strict>, z.ZodObject<{
1104
1225
  fallback: z.ZodOptional<z.ZodEnum<{
@@ -24,9 +24,15 @@ export interface SourceEntry {
24
24
  */
25
25
  raw?: string;
26
26
  /**
27
- * Absolute filesystem path when the entry originates from disk. Populated by
28
- * the filesystem adapter only; powers git last-modified and edit URLs and the
29
- * `sourcePath` back-compat window. Omitted by remote/CMS adapters.
27
+ * Absolute filesystem path when the entry originates from disk. Set by any
28
+ * local-file adapter — the filesystem source, and staged local sources such
29
+ * as Obsidian, whose bodies are rewritten but whose notes are still real
30
+ * files. It gives diagnostics a path the author recognizes and lets relative
31
+ * image checks resolve next to the file. Omitted by remote/CMS adapters.
32
+ *
33
+ * It does *not* imply the entry renders through the docs glob collection —
34
+ * read `source.staged` for that — and git last-modified additionally needs
35
+ * the owning source to expose a `contentRoot` to bound the log's pathspec.
30
36
  */
31
37
  sourcePath?: string;
32
38
  /** Optional provenance for "edit this page". */
@@ -35,6 +41,22 @@ export interface SourceEntry {
35
41
  lastModified?: string;
36
42
  /** Content hash for cache invalidation / HMR; adapter-computed when cheap. */
37
43
  hash?: string;
44
+ /**
45
+ * The body with `<include>` statements expanded, set by the scan's expansion
46
+ * pass (filesystem entries whose body contains a statement). `normalizeEntry`
47
+ * extracts headings/links/components from this text so a partial's content
48
+ * counts toward the including page, with `origins` mapping each expanded
49
+ * line back to the file and raw line it came from for diagnostics.
50
+ */
51
+ expanded?: {
52
+ text: string;
53
+ origins: {
54
+ file: string;
55
+ line: number;
56
+ }[];
57
+ /** Absolute paths of every file included, transitively. */
58
+ includes: string[];
59
+ };
38
60
  }
39
61
  /** The result of a single `ContentSource.load()` call. */
40
62
  export interface SourceLoadResult {
@@ -92,9 +114,12 @@ export interface ContentSource {
92
114
  /** Optional route prefix; the source's routes namespace under `/<prefix>/`. */
93
115
  readonly prefix?: string;
94
116
  /**
95
- * Resolved on-disk root, set by filesystem-backed sources only. Drives
96
- * folder-meta discovery (scan under this root) and the docs-collection base;
97
- * omitted by remote/CMS/staged sources that have no local tree.
117
+ * Resolved on-disk root, set by sources whose entries live on disk. For
118
+ * filesystem sources it drives folder-meta discovery (scan under this root)
119
+ * and the docs-collection base; for staged local sources (an Obsidian
120
+ * vault) it only bounds the git last-modified pathspec — folder-meta
121
+ * discovery is guarded on `staged`. Omitted by remote/CMS sources that have
122
+ * no local tree.
98
123
  */
99
124
  readonly contentRoot?: string;
100
125
  /** Pull every entry. Called once per scan. */
@@ -55,6 +55,10 @@ export interface PageLink {
55
55
  line: number;
56
56
  /** 1-based column of the target within the line. */
57
57
  column: number;
58
+ /** Absolute path of the file the link was written in, when that isn't the
59
+ * page's own source — a link inside an included partial. Diagnostics point
60
+ * here so authors fix the partial, not the page that spliced it. */
61
+ file?: string;
58
62
  }
59
63
  /**
60
64
  * Resolved project paths. Computed once per CLI invocation and threaded
@@ -95,7 +99,7 @@ export interface PageRecord {
95
99
  name: string;
96
100
  ref: string;
97
101
  };
98
- /** Absolute source path. Populated by the filesystem adapter only (back-compat). */
102
+ /** Absolute source path. Populated by any local-file adapter (back-compat). */
99
103
  sourcePath?: string;
100
104
  /**
101
105
  * Renderable body captured at scan time. Set for staged (non-filesystem)
@@ -165,6 +169,11 @@ export interface PageRecord {
165
169
  */
166
170
  custom?: Record<string, unknown>;
167
171
  headings: Heading[];
172
+ /**
173
+ * Raw HTML element ids (`<a id="…">`) outside headings, deduplicated —
174
+ * fragment-link targets `blume validate` accepts alongside heading slugs.
175
+ */
176
+ anchors: string[];
168
177
  /** Whether the file is `.md`/`.mdx`. */
169
178
  format: "md" | "mdx";
170
179
  /** Internal/asset links discovered in the page (for validation). */
@@ -173,6 +182,9 @@ export interface PageRecord {
173
182
  componentsUsed?: string[];
174
183
  /** Resolved "last updated" ISO date, when the feature is enabled. */
175
184
  lastModified?: string;
185
+ /** Absolute paths of files this page `<include>`s, transitively. Drives the
186
+ * dev-server invalidation edge from a partial to the pages that splice it. */
187
+ includes?: string[];
176
188
  }
177
189
  /** A node in the generated navigation tree. */
178
190
  export type NavNode = {
@@ -249,6 +261,11 @@ export interface FeaturedLink {
249
261
  href: string;
250
262
  icon?: string;
251
263
  }
264
+ /** A plain header link, or the header's single call to action. */
265
+ export interface HeaderAction {
266
+ href: string;
267
+ label: string;
268
+ }
252
269
  /** The complete navigation model derived from the content graph. */
253
270
  export interface Navigation {
254
271
  tabs: NavTab[];
@@ -264,6 +281,10 @@ export interface Navigation {
264
281
  * graphs; treat as `/`.
265
282
  */
266
283
  root?: string;
284
+ /** Plain links in the header, left of the icon buttons. */
285
+ actions?: HeaderAction[];
286
+ /** The single primary call to action in the header. */
287
+ cta?: HeaderAction | null;
267
288
  /** Pinned links shown above the sidebar sections, unscoped by tab. */
268
289
  featured: FeaturedLink[];
269
290
  /** Repo URL for the header link, or null when hidden (`navigation.repo`). */
@@ -321,11 +342,17 @@ export interface RouteManifestEntry {
321
342
  /** Astro collection-relative entry id, passed to `getEntry`. */
322
343
  entryId: string;
323
344
  path: string;
324
- /** Absolute source path; populated for filesystem entries only (back-compat). */
345
+ /** Absolute source path; populated for local-file entries only (back-compat). */
325
346
  sourcePath?: string;
326
347
  /** Adapter-supplied "edit this page" URL (non-filesystem sources). */
327
348
  editUrl?: string;
328
349
  title: string;
350
+ /**
351
+ * The page's meta description as the head renders it: `seo.description`
352
+ * over the front matter `description`. Feeds the generated OG card's
353
+ * subtitle, so a shared link's image and its `og:description` agree.
354
+ */
355
+ description?: string;
329
356
  contentType: string;
330
357
  hidden: boolean;
331
358
  draft: boolean;
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Sätteri's feature set for plain `.md` pages. Shared by the renderer and the
3
+ * search extractor so the index reads the same grammar the page renders.
4
+ */
5
+ export declare const MARKDOWN_FEATURES: {
6
+ subscript: true;
7
+ superscript: true;
8
+ };
9
+ /**
10
+ * The `.mdx` feature set: Markdown's plus `:::` directives (→ `<Callout>`) and
11
+ * block-only math — `singleDollarTextMath: false` keeps a bare `$` (currency,
12
+ * shell, code) as literal text and only parses `$$…$$`.
13
+ */
14
+ export declare const MDX_FEATURES: {
15
+ directive: true;
16
+ math: {
17
+ singleDollarTextMath: false;
18
+ };
19
+ subscript: true;
20
+ superscript: true;
21
+ };
@@ -7,7 +7,7 @@ export { normalizeRoute } from "../core/base-path.ts";
7
7
  * data module all share one source of truth. Kept free of any Astro/template
8
8
  * imports so `core` can depend on it without a cycle.
9
9
  */
10
- export type ReferenceKind = "openapi" | "asyncapi";
10
+ export type ReferenceKind = "openapi" | "asyncapi" | "graphql";
11
11
  /** Who renders a reference: Blume's own UI, or the embedded Scalar SPA. */
12
12
  export type ReferenceRenderer = "blume" | "scalar";
13
13
  /** Per-block display options for the Blume renderer. */
@@ -47,8 +47,18 @@ export interface ReferenceSource {
47
47
  includeInSearch: boolean;
48
48
  /** Whether generated pages emit noindex metadata and stay out of the sitemap. */
49
49
  noindex: boolean;
50
+ /**
51
+ * Whether operation meta descriptions end with the generated English
52
+ * "Reference for …" sentence, or carry the spec's own prose alone.
53
+ */
54
+ seoDescriptionSuffix: boolean;
50
55
  /** Local path or `http(s)` URL, verbatim from config. */
51
56
  spec: string;
57
+ /**
58
+ * URL of the live GraphQL endpoint the playground and code samples target
59
+ * (GraphQL only — a schema, unlike an OpenAPI document, names no server).
60
+ */
61
+ endpoint?: string;
52
62
  /** Per-block Scalar theme name override, if any (Scalar renderer only). */
53
63
  theme?: string;
54
64
  /**
@@ -90,3 +100,18 @@ export declare const referenceRoutes: (config: ResolvedConfig) => string[];
90
100
  export declare const blumeReferences: (config: ResolvedConfig) => ReferenceSource[];
91
101
  /** Whether any reference is Scalar-rendered (gates the `@scalar/astro` dep + pages). */
92
102
  export declare const hasScalarReferences: (config: ResolvedConfig) => boolean;
103
+ /**
104
+ * The reference kinds whose enabled, Blume-rendered playground opted into the
105
+ * built-in CORS proxy with `proxy: true`. A proxy URL string points at an
106
+ * external service, and `false` sends requests directly — neither routes
107
+ * through the endpoint. The generator's per-spec allowlist diagnostics key on
108
+ * this, so it shares one definition with {@link needsPlaygroundProxy}.
109
+ */
110
+ export declare const builtinProxyKinds: (config: ResolvedConfig) => ReferenceKind[];
111
+ /**
112
+ * Whether the built-in playground CORS proxy endpoint (`/_api-proxy`) must be
113
+ * generated: some enabled Blume-rendered block's playground opted into it with
114
+ * `proxy: true`. Shared by the server feature gate and the generator so the
115
+ * two can never disagree.
116
+ */
117
+ export declare const needsPlaygroundProxy: (config: ResolvedConfig) => boolean;
@@ -0,0 +1,105 @@
1
+ import type { Crumb } from "../components/layout/nav-utils.ts";
2
+ /** A date-ish value carried through frontmatter (string, YAML Date, or unset). */
3
+ type DateInput = string | Date | null;
4
+ /** A schema.org `PostalAddress`; every part optional. */
5
+ export interface PostalAddressIdentity {
6
+ addressCountry?: string;
7
+ addressLocality?: string;
8
+ addressRegion?: string;
9
+ postalCode?: string;
10
+ streetAddress?: string;
11
+ }
12
+ /**
13
+ * `seo.organization`: the organization behind the site, emitted on every page
14
+ * as an `Organization` node the WebSite and article nodes cite as publisher.
15
+ */
16
+ export interface OrganizationIdentity {
17
+ address?: PostalAddressIdentity;
18
+ /** `ContactPoint.contactType`; only emitted with an email or telephone. */
19
+ contactType: string;
20
+ email?: string;
21
+ /** Absolute URL or root-relative path (absolutized like page URLs). */
22
+ logo?: string;
23
+ /** Defaults to the site title. */
24
+ name?: string;
25
+ /** Profile URLs (GitHub, X, LinkedIn, …) that identify the organization. */
26
+ sameAs: string[];
27
+ telephone?: string;
28
+ /** Defaults to the site origin. */
29
+ url?: string;
30
+ }
31
+ /**
32
+ * `seo.software`: the product the site documents, emitted on the homepage as
33
+ * a `SoftwareApplication` node — the identity type agents use to tell what a
34
+ * docs site is about.
35
+ */
36
+ export interface SoftwareIdentity {
37
+ applicationCategory: string;
38
+ /** Defaults to the site description. */
39
+ description?: string;
40
+ /** License URL or SPDX identifier. */
41
+ license?: string;
42
+ /** Defaults to the site title. */
43
+ name?: string;
44
+ operatingSystem?: string;
45
+ /** Emitted as an `Offer` when set; `0` marks the software free. */
46
+ price?: number | string;
47
+ priceCurrency: string;
48
+ /** Package registry, repository, and profile URLs for the product. */
49
+ sameAs: string[];
50
+ }
51
+ /** The site-level identity nodes, from `seo.organization`/`seo.software`. */
52
+ export interface StructuredDataIdentity {
53
+ organization?: OrganizationIdentity;
54
+ software?: SoftwareIdentity;
55
+ }
56
+ /** Inputs for a page's JSON-LD, all known at render time in RootLayout. */
57
+ export interface StructuredDataInput {
58
+ siteName: string;
59
+ /** Absolute site origin, or null when `deployment.site` is unset. */
60
+ siteUrl: string | null;
61
+ title: string;
62
+ description?: string;
63
+ /** Page route, e.g. `/blog/post`. */
64
+ route: string;
65
+ /** Deployment base (`import.meta.env.BASE_URL`); prefixed onto absolute URLs. */
66
+ base?: string;
67
+ /** Content type — `blog` and `changelog` map to richer article types. */
68
+ pageType?: string;
69
+ /** Publish date (string or YAML Date); emitted as ISO `datePublished`. */
70
+ published?: DateInput;
71
+ /** Last-modified date; emitted as ISO `dateModified`. */
72
+ modified?: DateInput;
73
+ /** BCP-47 language tag for `inLanguage`; defaults to `en`. */
74
+ locale?: string;
75
+ breadcrumbs: Crumb[];
76
+ /**
77
+ * Site identity (`seo.organization`, `seo.software`). Both nodes need an
78
+ * absolute `@id`, so they are emitted only when `siteUrl` is set — like the
79
+ * WebSite node.
80
+ */
81
+ identity?: StructuredDataIdentity | null;
82
+ }
83
+ /** A value a schema.org node property can hold. */
84
+ type JsonLdValue = string | number | JsonLdValue[] | JsonLdNode;
85
+ /** A schema.org node: JSON-LD keys to concrete JSON values. */
86
+ export interface JsonLdNode {
87
+ [key: string]: JsonLdValue;
88
+ }
89
+ /**
90
+ * Frontmatter date → ISO 8601, or undefined when absent/unparseable. Shared with
91
+ * the layout's `article:published_time`/`article:modified_time` so both date
92
+ * surfaces treat a malformed date the same way: omit it rather than emit
93
+ * "Invalid Date".
94
+ */
95
+ export declare const toIso: (value: DateInput | undefined) => string | undefined;
96
+ /**
97
+ * Build a schema.org JSON-LD `@graph` for a page: site identity (the WebSite,
98
+ * plus the configured Organization everywhere and the SoftwareApplication on
99
+ * the homepage), the page as an article, and its breadcrumb trail. Returns
100
+ * null when there is nothing useful to emit (e.g. the homepage without a
101
+ * configured site). URLs are absolute when `siteUrl` is set, otherwise
102
+ * route-relative.
103
+ */
104
+ export declare const buildStructuredData: (input: StructuredDataInput) => JsonLdNode | null;
105
+ export {};