blume 2.0.3 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (455) hide show
  1. package/AGENTS.md +1 -0
  2. package/CHANGELOG.md +48 -0
  3. package/README.md +1 -1
  4. package/dist/cli/{chunk-1d7ve1dm.js → chunk-0gz36akr.js} +18 -2
  5. package/dist/cli/{chunk-1d7ve1dm.js.map → chunk-0gz36akr.js.map} +3 -3
  6. package/dist/cli/{chunk-2eytanqx.js → chunk-1n228xqb.js} +2 -2
  7. package/dist/cli/{chunk-yfyb25rh.js → chunk-2f3ndkpw.js} +24 -8
  8. package/dist/cli/chunk-2f3ndkpw.js.map +14 -0
  9. package/dist/cli/{chunk-r20tn01b.js → chunk-2f7n4qzt.js} +8 -2
  10. package/dist/cli/{chunk-r20tn01b.js.map → chunk-2f7n4qzt.js.map} +3 -3
  11. package/dist/cli/{chunk-35d4wj9f.js → chunk-2n4ps1b3.js} +7 -7
  12. package/dist/cli/{chunk-j85vccga.js → chunk-43zcf4gz.js} +97 -57
  13. package/dist/cli/{chunk-j85vccga.js.map → chunk-43zcf4gz.js.map} +6 -6
  14. package/dist/cli/{chunk-e04dxsz1.js → chunk-4ejxbzee.js} +1 -1
  15. package/dist/cli/{chunk-5m5nmvyq.js → chunk-4h8z9vv5.js} +233 -39
  16. package/dist/cli/chunk-4h8z9vv5.js.map +16 -0
  17. package/dist/cli/{chunk-5f86nr5m.js → chunk-5cg2rzgf.js} +18 -16
  18. package/dist/cli/{chunk-5f86nr5m.js.map → chunk-5cg2rzgf.js.map} +2 -2
  19. package/dist/cli/{chunk-tzmab476.js → chunk-5ffywsmb.js} +4 -4
  20. package/dist/cli/{chunk-2z928egk.js → chunk-5wj2qwn2.js} +5 -5
  21. package/dist/cli/chunk-6bm0xpgd.js +18 -0
  22. package/dist/cli/chunk-6bm0xpgd.js.map +10 -0
  23. package/dist/cli/{chunk-vg9r4eb9.js → chunk-713mngdq.js} +12 -5
  24. package/dist/cli/{chunk-vg9r4eb9.js.map → chunk-713mngdq.js.map} +3 -3
  25. package/dist/cli/{chunk-5xvm6tfj.js → chunk-9geymqns.js} +17 -15
  26. package/dist/cli/{chunk-5xvm6tfj.js.map → chunk-9geymqns.js.map} +2 -2
  27. package/dist/cli/{chunk-q58y5e6a.js → chunk-9xr4dgee.js} +26 -17
  28. package/dist/cli/chunk-9xr4dgee.js.map +10 -0
  29. package/dist/cli/{chunk-b07cmahc.js → chunk-amrb6hgh.js} +2 -2
  30. package/dist/cli/chunk-cm89scdv.js +443 -0
  31. package/dist/cli/chunk-cm89scdv.js.map +11 -0
  32. package/dist/cli/{chunk-akbpwfxc.js → chunk-cmtcnh9f.js} +2 -2
  33. package/dist/cli/chunk-cy5bm0j0.js +104 -0
  34. package/dist/cli/chunk-cy5bm0j0.js.map +11 -0
  35. package/dist/cli/{chunk-crgn1q09.js → chunk-e7vvk5ya.js} +4 -4
  36. package/dist/cli/{chunk-pehfxfta.js → chunk-g2z9x01v.js} +6 -98
  37. package/dist/cli/chunk-g2z9x01v.js.map +10 -0
  38. package/dist/cli/{chunk-tkacnehg.js → chunk-gp84za0h.js} +2 -2
  39. package/dist/cli/{chunk-wrr3j9w9.js → chunk-h2a48yhd.js} +186 -63
  40. package/dist/cli/chunk-h2a48yhd.js.map +36 -0
  41. package/dist/cli/{chunk-hm3vjy5s.js → chunk-jnwj5kjj.js} +14 -9
  42. package/dist/cli/{chunk-hm3vjy5s.js.map → chunk-jnwj5kjj.js.map} +4 -4
  43. package/dist/cli/chunk-kwrg63tm.js +31 -0
  44. package/dist/cli/chunk-kwrg63tm.js.map +10 -0
  45. package/dist/cli/{chunk-2hsdwb9n.js → chunk-nd1821sk.js} +18 -16
  46. package/dist/cli/{chunk-2hsdwb9n.js.map → chunk-nd1821sk.js.map} +2 -2
  47. package/dist/cli/{chunk-6dsbexzp.js → chunk-ntv4qrt7.js} +17 -15
  48. package/dist/cli/{chunk-6dsbexzp.js.map → chunk-ntv4qrt7.js.map} +2 -2
  49. package/dist/cli/{chunk-r9rcc4w7.js → chunk-p804f3pe.js} +7 -7
  50. package/dist/cli/{chunk-ey84smr6.js → chunk-py62fewh.js} +6 -6
  51. package/dist/cli/{chunk-ey84smr6.js.map → chunk-py62fewh.js.map} +1 -1
  52. package/dist/cli/chunk-q3wxxq39.js +126 -0
  53. package/dist/cli/chunk-q3wxxq39.js.map +11 -0
  54. package/dist/cli/{chunk-9t7a85s3.js → chunk-rekqz4qg.js} +23 -13
  55. package/dist/cli/chunk-rekqz4qg.js.map +10 -0
  56. package/dist/cli/{chunk-8ktnccpt.js → chunk-ta27feev.js} +1 -1
  57. package/dist/cli/{chunk-pv29h0wf.js → chunk-xkz5xbtv.js} +3476 -822
  58. package/dist/cli/chunk-xkz5xbtv.js.map +213 -0
  59. package/dist/cli/{chunk-a58773jm.js → chunk-y4ykbark.js} +2 -2
  60. package/dist/cli/{chunk-p3v96n38.js → chunk-y5h4r2y0.js} +4 -4
  61. package/dist/cli/{chunk-acanzt5p.js → chunk-yj17vs39.js} +6 -6
  62. package/dist/cli/{chunk-p73c0m7w.js → chunk-yxmk4pec.js} +16 -14
  63. package/dist/cli/{chunk-p73c0m7w.js.map → chunk-yxmk4pec.js.map} +2 -2
  64. package/dist/cli/{chunk-3em5wd2y.js → chunk-zccbjcj0.js} +4 -3
  65. package/dist/cli/{chunk-3em5wd2y.js.map → chunk-zccbjcj0.js.map} +2 -2
  66. package/dist/cli/{chunk-c8chx29p.js → chunk-zf748avv.js} +384 -207
  67. package/dist/cli/chunk-zf748avv.js.map +37 -0
  68. package/dist/cli/{chunk-g4hq16wv.js → chunk-zhvd6adm.js} +16 -14
  69. package/dist/cli/{chunk-g4hq16wv.js.map → chunk-zhvd6adm.js.map} +2 -2
  70. package/dist/cli/index.js +26 -20
  71. package/dist/cli/index.js.map +5 -5
  72. package/dist/types/ai/agent-surface.d.ts +8 -7
  73. package/dist/types/ai/ai-catalog.d.ts +7 -0
  74. package/dist/types/ai/ask-context.d.ts +22 -0
  75. package/dist/types/ai/ask.d.ts +271 -58
  76. package/dist/types/ai/index.d.ts +2 -2
  77. package/dist/types/ai/site-skill.d.ts +26 -0
  78. package/dist/types/ai/skills.d.ts +16 -0
  79. package/dist/types/astro/integration.d.ts +8 -0
  80. package/dist/types/captcha/hcaptcha.d.ts +27 -0
  81. package/dist/types/captcha/index.d.ts +28 -0
  82. package/dist/types/captcha/schema.d.ts +29 -0
  83. package/dist/types/captcha/turnstile.d.ts +28 -0
  84. package/dist/types/components/content/api-field.d.ts +59 -0
  85. package/dist/types/components/content/api-page.d.ts +95 -0
  86. package/dist/types/components/layout/nav-utils.d.ts +26 -0
  87. package/dist/types/components/openapi/helpers.d.ts +137 -0
  88. package/dist/types/components/openapi/security.d.ts +85 -0
  89. package/dist/types/consent/ethyca.d.ts +48 -0
  90. package/dist/types/consent/index.d.ts +37 -0
  91. package/dist/types/consent/native.d.ts +28 -0
  92. package/dist/types/consent/osano.d.ts +42 -0
  93. package/dist/types/consent/schema.d.ts +110 -0
  94. package/dist/types/core/config-input.d.ts +187 -20
  95. package/dist/types/core/data.d.ts +49 -4
  96. package/dist/types/core/footer.d.ts +8 -0
  97. package/dist/types/core/i18n-ui.d.ts +86 -0
  98. package/dist/types/core/includes.d.ts +8 -2
  99. package/dist/types/core/localizable.d.ts +7 -0
  100. package/dist/types/core/page-modes.d.ts +29 -0
  101. package/dist/types/core/redirect-patterns.d.ts +144 -0
  102. package/dist/types/core/related.d.ts +40 -0
  103. package/dist/types/core/schema.d.ts +551 -56
  104. package/dist/types/core/sources/read.d.ts +5 -0
  105. package/dist/types/core/types.d.ts +1 -1
  106. package/dist/types/core/variables.d.ts +42 -0
  107. package/dist/types/deploy/node-headers.d.ts +13 -2
  108. package/dist/types/deploy/platforms/cloudflare.d.ts +5 -0
  109. package/dist/types/deploy/platforms/netlify.d.ts +7 -0
  110. package/dist/types/deploy/platforms/vercel.d.ts +6 -0
  111. package/dist/types/deploy/redirects.d.ts +39 -11
  112. package/dist/types/deploy/vercel-negotiation.d.ts +9 -0
  113. package/dist/types/markdown/code-title.d.ts +17 -0
  114. package/dist/types/markdown/features.d.ts +3 -2
  115. package/dist/types/narration/build.d.ts +70 -0
  116. package/dist/types/narration/provider.d.ts +26 -0
  117. package/dist/types/narration/script.d.ts +154 -0
  118. package/dist/types/openapi/model.d.ts +12 -6
  119. package/dist/types/openapi/overlay.d.ts +54 -0
  120. package/dist/types/openapi/parse.d.ts +13 -0
  121. package/dist/types/openapi/references.d.ts +14 -4
  122. package/dist/types/ratelimit/cloudflare.d.ts +39 -0
  123. package/dist/types/ratelimit/index.d.ts +27 -0
  124. package/dist/types/ratelimit/memory.d.ts +36 -0
  125. package/dist/types/ratelimit/schema.d.ts +111 -0
  126. package/dist/types/ratelimit/upstash.d.ts +21 -0
  127. package/dist/types/ratelimit/wrangler.d.ts +23 -0
  128. package/dist/types/reference/asyncapi.d.ts +10 -10
  129. package/dist/types/reference/graphql.d.ts +13 -10
  130. package/dist/types/reference/openapi.d.ts +33 -12
  131. package/dist/types/reference/options.d.ts +45 -5
  132. package/dist/types/reference/scalar.d.ts +13 -0
  133. package/dist/types/reference/schema.d.ts +60 -36
  134. package/dist/types/search/documents.d.ts +12 -1
  135. package/dist/types/search/orama-index.d.ts +4 -0
  136. package/dist/types/seo/metatags.d.ts +20 -0
  137. package/docs/02-deployment.mdx +41 -5
  138. package/docs/03-upgrading.mdx +4 -4
  139. package/docs/04-migrating.mdx +1 -1
  140. package/docs/advanced/changelog.mdx +2 -2
  141. package/docs/advanced/skills.mdx +14 -0
  142. package/docs/cli/audit.mdx +21 -1
  143. package/docs/cli/index.mdx +1 -0
  144. package/docs/configuration/analytics.mdx +3 -1
  145. package/docs/configuration/assistant.mdx +188 -36
  146. package/docs/configuration/consent.mdx +100 -0
  147. package/docs/configuration/customization.mdx +4 -4
  148. package/docs/configuration/index.mdx +63 -5
  149. package/docs/configuration/meta.ts +3 -0
  150. package/docs/configuration/narration.mdx +119 -0
  151. package/docs/configuration/rate-limiting.mdx +69 -0
  152. package/docs/configuration/search.mdx +29 -1
  153. package/docs/configuration/theming.mdx +3 -1
  154. package/docs/content/components.mdx +106 -0
  155. package/docs/content/frontmatter.mdx +76 -0
  156. package/docs/content/i18n.mdx +38 -3
  157. package/docs/content/includes.mdx +16 -0
  158. package/docs/content/meta.mdx +1 -0
  159. package/docs/content/meta.ts +1 -0
  160. package/docs/content/navigation.mdx +28 -6
  161. package/docs/content/sources/contentful.mdx +32 -0
  162. package/docs/content/sources/custom.mdx +39 -0
  163. package/docs/content/sources/github-releases.mdx +31 -0
  164. package/docs/content/sources/index.mdx +91 -0
  165. package/docs/content/sources/meta.ts +16 -0
  166. package/docs/content/sources/notion.mdx +32 -0
  167. package/docs/content/sources/obsidian.mdx +37 -0
  168. package/docs/content/sources/payload.mdx +30 -0
  169. package/docs/content/sources/remote-mdx.mdx +40 -0
  170. package/docs/content/sources/sanity.mdx +29 -0
  171. package/docs/content/sources/strapi.mdx +31 -0
  172. package/docs/content/syntax.mdx +67 -2
  173. package/docs/content/variables.mdx +41 -0
  174. package/docs/discoverability/agent-discovery.mdx +29 -2
  175. package/docs/discoverability/index.mdx +1 -1
  176. package/docs/discoverability/llms-txt.mdx +1 -1
  177. package/docs/discoverability/metadata.mdx +17 -0
  178. package/docs/references/api-pages.mdx +74 -0
  179. package/docs/references/asyncapi.mdx +1 -1
  180. package/docs/references/graphql.mdx +2 -2
  181. package/docs/references/meta.ts +1 -1
  182. package/docs/references/openapi.mdx +102 -3
  183. package/docs/references/scalar.mdx +3 -1
  184. package/package.json +36 -1
  185. package/skills/blume/SKILL.md +3 -0
  186. package/skills/blume-migrate/SKILL.md +5 -5
  187. package/skills/blume-migrate/references/docusaurus.md +3 -3
  188. package/skills/blume-migrate/references/mintlify.md +37 -19
  189. package/skills/blume-migrate/references/nextra.md +2 -2
  190. package/skills/blume-migrate/references/starlight.md +2 -1
  191. package/skills/blume-migrate/scripts/mintlify-codemod.mjs +60 -14
  192. package/skills/blume-write-skill/SKILL.md +82 -0
  193. package/src/ai/agent-readability.ts +2 -1
  194. package/src/ai/agent-surface.ts +9 -7
  195. package/src/ai/ai-catalog.ts +6 -3
  196. package/src/ai/ask-context.ts +73 -20
  197. package/src/ai/ask-data.ts +6 -0
  198. package/src/ai/ask-tools.ts +142 -0
  199. package/src/ai/ask.ts +354 -76
  200. package/src/ai/component-markdown.ts +75 -0
  201. package/src/ai/cors.ts +2 -0
  202. package/src/ai/index.ts +12 -0
  203. package/src/ai/llms.ts +6 -2
  204. package/src/ai/markdown.ts +2 -1
  205. package/src/ai/mcp/data.ts +6 -0
  206. package/src/ai/openapi-components.ts +9 -3
  207. package/src/ai/site-skill.ts +274 -0
  208. package/src/ai/skills.ts +35 -2
  209. package/src/ai/write-skill.ts +97 -0
  210. package/src/astro/generate.ts +132 -18
  211. package/src/astro/index.ts +1 -0
  212. package/src/astro/integration.ts +35 -0
  213. package/src/astro/module-types.ts +6 -0
  214. package/src/astro/templates.ts +283 -30
  215. package/src/astro/variables.ts +31 -0
  216. package/src/audit/catalog.ts +19 -0
  217. package/src/audit/checks/contrast.ts +183 -0
  218. package/src/audit/checks/i18n.ts +2 -3
  219. package/src/audit/checks/indexability.ts +2 -3
  220. package/src/audit/checks/links.ts +5 -12
  221. package/src/audit/checks/sitemap.ts +2 -3
  222. package/src/audit/redirects.ts +46 -15
  223. package/src/audit/run.ts +2 -0
  224. package/src/audit/types.ts +2 -1
  225. package/src/blume-modules.d.ts +7 -0
  226. package/src/captcha/client.ts +152 -0
  227. package/src/captcha/hcaptcha.ts +36 -0
  228. package/src/captcha/index.ts +28 -0
  229. package/src/captcha/schema.ts +32 -0
  230. package/src/captcha/turnstile.ts +38 -0
  231. package/src/captcha/verify.ts +71 -0
  232. package/src/cli/command-meta.ts +5 -0
  233. package/src/cli/commands/doctor.ts +22 -16
  234. package/src/cli/commands/skill.ts +96 -0
  235. package/src/cli/index.ts +5 -0
  236. package/src/cli/required-secrets.ts +71 -29
  237. package/src/components/BlumePage.astro +2 -0
  238. package/src/components/content/ApiEndpoint.astro +18 -0
  239. package/src/components/content/ApiField.astro +79 -0
  240. package/src/components/content/ApiPlayground.astro +62 -0
  241. package/src/components/content/ApiRail.astro +19 -0
  242. package/src/components/content/Color.astro +1 -0
  243. package/src/components/content/FileTree.astro +1 -0
  244. package/src/components/content/GithubInfo.astro +1 -0
  245. package/src/components/content/Panel.astro +1 -0
  246. package/src/components/content/ParamField.astro +25 -0
  247. package/src/components/content/RequestExample.astro +17 -0
  248. package/src/components/content/ResponseExample.astro +17 -0
  249. package/src/components/content/ResponseField.astro +32 -0
  250. package/src/components/content/Step.astro +1 -0
  251. package/src/components/content/Tile.astro +1 -0
  252. package/src/components/content/Tooltip.astro +1 -0
  253. package/src/components/content/Tree.astro +1 -0
  254. package/src/components/content/TypeTable.astro +4 -1
  255. package/src/components/content/View.astro +21 -0
  256. package/src/components/content/ViewSwitcher.astro +168 -0
  257. package/src/components/content/api-field.ts +100 -0
  258. package/src/components/content/api-page.ts +224 -0
  259. package/src/components/content/view-switcher.ts +71 -0
  260. package/src/components/index.ts +2 -0
  261. package/src/components/islands/Assistant.astro +10 -1
  262. package/src/components/islands/assistant.tsx +104 -14
  263. package/src/components/islands/code-question.ts +62 -0
  264. package/src/components/islands/hooks.ts +110 -21
  265. package/src/components/islands/support-link.ts +68 -0
  266. package/src/components/layout/Analytics.astro +11 -2
  267. package/src/components/layout/Banner.astro +14 -10
  268. package/src/components/layout/Breadcrumbs.astro +6 -2
  269. package/src/components/layout/ConsentBanner.astro +62 -0
  270. package/src/components/layout/ConsentHead.astro +38 -0
  271. package/src/components/layout/Directory.astro +94 -0
  272. package/src/components/layout/DrawerSwitchers.astro +51 -0
  273. package/src/components/layout/Empty.astro +2 -2
  274. package/src/components/layout/Header.astro +122 -80
  275. package/src/components/layout/LanguageSwitcher.astro +48 -15
  276. package/src/components/layout/NarrationPlayer.astro +1085 -0
  277. package/src/components/layout/NavSelector.astro +33 -7
  278. package/src/components/layout/PageFeedback.astro +54 -49
  279. package/src/components/layout/PageLayout.astro +71 -3
  280. package/src/components/layout/ReferenceLayout.astro +17 -6
  281. package/src/components/layout/RelatedPages.astro +42 -0
  282. package/src/components/layout/RootLayout.astro +308 -45
  283. package/src/components/layout/Search.astro +31 -17
  284. package/src/components/layout/SiteFooter.astro +124 -0
  285. package/src/components/layout/SiteMetatags.astro +16 -0
  286. package/src/components/layout/consent/native.ts +79 -0
  287. package/src/components/layout/consent/types.ts +37 -0
  288. package/src/components/layout/footer-links.ts +53 -0
  289. package/src/components/layout/footer-socials.ts +87 -0
  290. package/src/components/layout/locale-redirect.ts +107 -0
  291. package/src/components/layout/nav-utils.ts +83 -0
  292. package/src/components/layout/page-feedback.ts +96 -0
  293. package/src/components/layout/search/analytics.ts +98 -0
  294. package/src/components/layout/search/flexsearch.ts +17 -5
  295. package/src/components/layout/search/orama-cloud.ts +26 -14
  296. package/src/components/layout/search/types.ts +20 -0
  297. package/src/components/layout/search/typesense.ts +5 -1
  298. package/src/components/openapi/Operation.astro +161 -13
  299. package/src/components/openapi/RequestBody.astro +6 -4
  300. package/src/components/openapi/RequestPanel.astro +59 -7
  301. package/src/components/openapi/Responses.astro +6 -4
  302. package/src/components/openapi/async-snippets.ts +4 -4
  303. package/src/components/openapi/code-samples.ts +97 -0
  304. package/src/components/openapi/security.ts +6 -3
  305. package/src/components/openapi/snippets.ts +869 -8
  306. package/src/components/props.ts +6 -0
  307. package/src/consent/client.ts +95 -0
  308. package/src/consent/clients.ts +19 -0
  309. package/src/consent/ethyca.ts +71 -0
  310. package/src/consent/head.ts +24 -0
  311. package/src/consent/index.ts +37 -0
  312. package/src/consent/init.ts +29 -0
  313. package/src/consent/native.ts +36 -0
  314. package/src/consent/osano.ts +59 -0
  315. package/src/consent/schema.ts +30 -0
  316. package/src/core/builtin-tags.ts +5 -0
  317. package/src/core/client-address.ts +19 -0
  318. package/src/core/config-input.ts +194 -20
  319. package/src/core/data.ts +44 -4
  320. package/src/core/diagnostics.ts +3 -2
  321. package/src/core/footer.ts +26 -0
  322. package/src/core/graph.ts +39 -36
  323. package/src/core/i18n-ui.ts +82 -2
  324. package/src/core/includes.ts +20 -3
  325. package/src/core/links.ts +16 -2
  326. package/src/core/localizable.ts +26 -0
  327. package/src/core/navigation.ts +43 -12
  328. package/src/core/page-modes.ts +56 -0
  329. package/src/core/project-graph.ts +111 -5
  330. package/src/core/redirect-patterns.ts +491 -0
  331. package/src/core/related.ts +131 -0
  332. package/src/core/schema.ts +318 -64
  333. package/src/core/sources/normalize.ts +2 -1
  334. package/src/core/sources/read.ts +8 -3
  335. package/src/core/types.ts +1 -1
  336. package/src/core/ui-packs/ar.ts +43 -0
  337. package/src/core/ui-packs/bg.ts +45 -0
  338. package/src/core/ui-packs/bn.ts +43 -0
  339. package/src/core/ui-packs/ca.ts +46 -0
  340. package/src/core/ui-packs/cs.ts +44 -0
  341. package/src/core/ui-packs/da.ts +45 -0
  342. package/src/core/ui-packs/de.ts +46 -0
  343. package/src/core/ui-packs/el.ts +45 -0
  344. package/src/core/ui-packs/es.ts +46 -0
  345. package/src/core/ui-packs/fa.ts +45 -0
  346. package/src/core/ui-packs/fi.ts +45 -0
  347. package/src/core/ui-packs/fr.ts +46 -0
  348. package/src/core/ui-packs/he.ts +43 -0
  349. package/src/core/ui-packs/hi.ts +44 -0
  350. package/src/core/ui-packs/hr.ts +45 -0
  351. package/src/core/ui-packs/hu.ts +44 -0
  352. package/src/core/ui-packs/id.ts +45 -0
  353. package/src/core/ui-packs/it.ts +45 -0
  354. package/src/core/ui-packs/ja.ts +45 -0
  355. package/src/core/ui-packs/ko.ts +44 -0
  356. package/src/core/ui-packs/nl.ts +46 -0
  357. package/src/core/ui-packs/no.ts +44 -0
  358. package/src/core/ui-packs/pl.ts +45 -0
  359. package/src/core/ui-packs/pt-br.ts +46 -0
  360. package/src/core/ui-packs/pt.ts +45 -0
  361. package/src/core/ui-packs/ro.ts +45 -0
  362. package/src/core/ui-packs/ru.ts +45 -0
  363. package/src/core/ui-packs/sk.ts +44 -0
  364. package/src/core/ui-packs/sr.ts +45 -0
  365. package/src/core/ui-packs/sv.ts +44 -0
  366. package/src/core/ui-packs/th.ts +43 -0
  367. package/src/core/ui-packs/tr.ts +45 -0
  368. package/src/core/ui-packs/uk.ts +45 -0
  369. package/src/core/ui-packs/vi.ts +45 -0
  370. package/src/core/ui-packs/zh-tw.ts +43 -0
  371. package/src/core/ui-packs/zh.ts +43 -0
  372. package/src/core/variables.ts +103 -0
  373. package/src/deploy/artifacts.ts +77 -8
  374. package/src/deploy/cloudflare-negotiation.ts +35 -5
  375. package/src/deploy/headers.ts +2 -1
  376. package/src/deploy/node-headers.ts +63 -9
  377. package/src/deploy/platforms/cloudflare.ts +32 -0
  378. package/src/deploy/platforms/netlify.ts +33 -1
  379. package/src/deploy/platforms/vercel.ts +37 -2
  380. package/src/deploy/redirects.ts +91 -24
  381. package/src/deploy/vercel-negotiation.ts +36 -0
  382. package/src/markdown/api-rail.ts +259 -0
  383. package/src/markdown/code-title.ts +35 -9
  384. package/src/markdown/features.ts +3 -2
  385. package/src/markdown/fence-meta.ts +2 -0
  386. package/src/markdown/include.ts +11 -1
  387. package/src/markdown/index.ts +28 -5
  388. package/src/markdown/math.ts +4 -4
  389. package/src/markdown/variables.ts +56 -0
  390. package/src/markdown/views.ts +82 -0
  391. package/src/narration/build.ts +412 -0
  392. package/src/narration/player.ts +249 -0
  393. package/src/narration/provider.ts +29 -0
  394. package/src/narration/script.ts +592 -0
  395. package/src/og/card.ts +7 -6
  396. package/src/openapi/model.ts +57 -24
  397. package/src/openapi/overlay.ts +256 -0
  398. package/src/openapi/parse.ts +55 -2
  399. package/src/openapi/references.ts +21 -5
  400. package/src/openapi/render-mdx.ts +5 -1
  401. package/src/openapi/scalar.ts +40 -6
  402. package/src/openapi/source.ts +1 -1
  403. package/src/ratelimit/cloudflare.ts +54 -0
  404. package/src/ratelimit/index.ts +30 -0
  405. package/src/ratelimit/memory.ts +45 -0
  406. package/src/ratelimit/runtime.ts +229 -0
  407. package/src/ratelimit/schema.ts +28 -0
  408. package/src/ratelimit/upstash.ts +30 -0
  409. package/src/ratelimit/wrangler.ts +70 -0
  410. package/src/reference/asyncapi.ts +2 -2
  411. package/src/reference/graphql.ts +5 -2
  412. package/src/reference/openapi.ts +21 -7
  413. package/src/reference/options.ts +51 -7
  414. package/src/reference/scalar.ts +33 -8
  415. package/src/registry/eject.ts +20 -4
  416. package/src/registry/registry.ts +7 -0
  417. package/src/search/documents.ts +26 -2
  418. package/src/search/orama-index.ts +28 -3
  419. package/src/search/pagefind-ranking.ts +39 -0
  420. package/src/search/sync/algolia.ts +15 -4
  421. package/src/search/sync/orama-cloud.ts +3 -0
  422. package/src/search/sync/typesense.ts +5 -0
  423. package/src/seo/metatags.ts +67 -0
  424. package/src/theme/chrome-icons.ts +1 -0
  425. package/src/theme/color.ts +500 -0
  426. package/src/theme/entry.ts +56 -3
  427. package/src/theme/palette.ts +121 -45
  428. package/src/translate/prompts.ts +1 -0
  429. package/src/translate/validate.ts +8 -2
  430. package/src/upgrade/upgrade.ts +4 -171
  431. package/dist/cli/chunk-364znk6q.js +0 -75
  432. package/dist/cli/chunk-364znk6q.js.map +0 -11
  433. package/dist/cli/chunk-5m5nmvyq.js.map +0 -13
  434. package/dist/cli/chunk-9t7a85s3.js.map +0 -10
  435. package/dist/cli/chunk-c8chx29p.js.map +0 -36
  436. package/dist/cli/chunk-pehfxfta.js.map +0 -10
  437. package/dist/cli/chunk-pv29h0wf.js.map +0 -190
  438. package/dist/cli/chunk-q58y5e6a.js.map +0 -10
  439. package/dist/cli/chunk-wrr3j9w9.js.map +0 -35
  440. package/dist/cli/chunk-yfyb25rh.js.map +0 -14
  441. package/docs/content/sources.mdx +0 -334
  442. /package/dist/cli/{chunk-2eytanqx.js.map → chunk-1n228xqb.js.map} +0 -0
  443. /package/dist/cli/{chunk-35d4wj9f.js.map → chunk-2n4ps1b3.js.map} +0 -0
  444. /package/dist/cli/{chunk-e04dxsz1.js.map → chunk-4ejxbzee.js.map} +0 -0
  445. /package/dist/cli/{chunk-tzmab476.js.map → chunk-5ffywsmb.js.map} +0 -0
  446. /package/dist/cli/{chunk-2z928egk.js.map → chunk-5wj2qwn2.js.map} +0 -0
  447. /package/dist/cli/{chunk-b07cmahc.js.map → chunk-amrb6hgh.js.map} +0 -0
  448. /package/dist/cli/{chunk-akbpwfxc.js.map → chunk-cmtcnh9f.js.map} +0 -0
  449. /package/dist/cli/{chunk-crgn1q09.js.map → chunk-e7vvk5ya.js.map} +0 -0
  450. /package/dist/cli/{chunk-tkacnehg.js.map → chunk-gp84za0h.js.map} +0 -0
  451. /package/dist/cli/{chunk-r9rcc4w7.js.map → chunk-p804f3pe.js.map} +0 -0
  452. /package/dist/cli/{chunk-8ktnccpt.js.map → chunk-ta27feev.js.map} +0 -0
  453. /package/dist/cli/{chunk-a58773jm.js.map → chunk-y4ykbark.js.map} +0 -0
  454. /package/dist/cli/{chunk-p3v96n38.js.map → chunk-y5h4r2y0.js.map} +0 -0
  455. /package/dist/cli/{chunk-acanzt5p.js.map → chunk-yj17vs39.js.map} +0 -0
@@ -36,4 +36,4 @@ var parseTimeoutSeconds = (value, fallback) => {
36
36
  export { parsePort, parseTimeoutSeconds };
37
37
 
38
38
  //# debugId=02AD79A562BBAEE664756E2164756E21
39
- //# sourceMappingURL=chunk-e04dxsz1.js.map
39
+ //# sourceMappingURL=chunk-4ejxbzee.js.map
@@ -4,19 +4,25 @@ import {
4
4
  resolveDocsCollection,
5
5
  TOC_HIDDEN_KEY,
6
6
  deployPassthrough,
7
+ RATE_LIMIT_BINDING,
7
8
  fontLocaleCodes,
8
9
  buildFontEntries,
10
+ isPatternPath,
11
+ compileRedirects,
12
+ hasVariables,
9
13
  SVG_ASSET_HEADERS,
10
14
  applyBaseToAstroRedirects,
11
15
  distDir,
12
16
  adapterRoot,
13
- deployPlatform,
14
- BLUME_IGNORE_DIRS
15
- } from "./chunk-pv29h0wf.js";
17
+ deployPlatform
18
+ } from "./chunk-xkz5xbtv.js";
16
19
  import {
17
20
  trimChar,
18
21
  normalizeBasePath
19
- } from "./chunk-3em5wd2y.js";
22
+ } from "./chunk-zccbjcj0.js";
23
+ import {
24
+ BLUME_IGNORE_DIRS
25
+ } from "./chunk-kwrg63tm.js";
20
26
 
21
27
  // src/deploy/adapter-output.ts
22
28
  import { existsSync } from "node:fs";
@@ -212,6 +218,19 @@ var publishRuntimeModules = (modules) => {
212
218
  import { existsSync as existsSync2, readFileSync } from "node:fs";
213
219
  import { pathToFileURL } from "node:url";
214
220
  import { dirname as dirname2, isAbsolute as isAbsolute2, join as join3, relative as relative2 } from "pathe";
221
+
222
+ // src/consent/clients.ts
223
+ var CONSENT_CLIENT_MODULES = new Map([
224
+ ["native", "blume/components/layout/consent/native.ts"]
225
+ ]);
226
+
227
+ // src/markdown/api-rail.ts
228
+ var API_RAIL_KEY = "blumeApiRail";
229
+
230
+ // src/markdown/views.ts
231
+ var VIEWS_KEY = "blumeViews";
232
+
233
+ // src/astro/templates.ts
215
234
  var WORKSPACE_MARKERS = [
216
235
  ".git",
217
236
  "bun.lock",
@@ -288,7 +307,7 @@ var runtimeDependencies = (options) => {
288
307
  if (needsSvelte) {
289
308
  deps.push("@astrojs/svelte");
290
309
  }
291
- deps.push(...new Set(config.reference.flatMap((adapter) => adapter.runtimeDeps)), ...config.search.provider.runtimeDeps, ...config.analytics.flatMap((adapter) => adapter.runtimeDeps));
310
+ deps.push(...new Set(config.reference.flatMap((adapter) => adapter.runtimeDeps)), ...config.search.provider.runtimeDeps, ...config.analytics.flatMap((adapter) => adapter.runtimeDeps), ...config.consent?.runtimeDeps ?? []);
292
311
  for (const source of config.content.sources) {
293
312
  for (const dep of source.runtimeDeps) {
294
313
  if (!deps.includes(dep)) {
@@ -404,17 +423,24 @@ var renderRuntimeModuleWiring = (generatedModulesDir) => {
404
423
  ${JSON.stringify(id)}: ${configPath(`${generatedModulesDir}/${file}`, true)},`).join("");
405
424
  return { aliasLines, imports: [], pluginEntry: "" };
406
425
  };
407
- var blumeIntegrationOptions = (options) => options.ejected ? {
408
- buildArtifactsRoot: ".",
409
- contentRoutes: options.contentRoutes,
410
- homeLinkHeader: buildHomeLinkHeader(options.config, options.contentRoutes, "dev") ?? undefined,
411
- pages: options.pages
412
- } : { pages: options.pages };
426
+ var blumeIntegrationOptions = (options) => {
427
+ const shared = { pages: options.pages };
428
+ if (options.redirects.length > 0) {
429
+ shared.redirects = options.redirects;
430
+ }
431
+ return options.ejected ? {
432
+ ...shared,
433
+ buildArtifactsRoot: ".",
434
+ contentRoutes: options.contentRoutes,
435
+ homeLinkHeader: buildHomeLinkHeader(options.config, options.contentRoutes, "dev") ?? undefined
436
+ } : shared;
437
+ };
413
438
  var astroConfigTemplate = (options) => {
414
439
  const { context, config, needsReact, pages, themePath } = options;
415
440
  const { astro: cacheOptions, vite: viteCacheOption } = runtimeCacheOptions(context, options.generatedModulesDir);
416
441
  const {
417
442
  askPath,
443
+ consentClientPath,
418
444
  contentRoutes,
419
445
  examplesPath,
420
446
  examplesThemePath,
@@ -461,8 +487,9 @@ var astroConfigTemplate = (options) => {
461
487
  }
462
488
  })},` : "";
463
489
  const basedRedirects = applyBaseToAstroRedirects(config.redirects, config.basePath, deployment.options.base ?? "", new Set(contentRoutes));
464
- const redirectsOption = basedRedirects.length > 0 ? `
465
- redirects: ${JSON.stringify(Object.fromEntries(basedRedirects.map((redirect) => [
490
+ const exactRedirects = basedRedirects.filter((redirect) => !isPatternPath(redirect.from));
491
+ const redirectsOption = exactRedirects.length > 0 ? `
492
+ redirects: ${JSON.stringify(Object.fromEntries(exactRedirects.map((redirect) => [
466
493
  redirect.from,
467
494
  { destination: redirect.to, status: redirect.status }
468
495
  ])))},` : "";
@@ -492,12 +519,15 @@ var astroConfigTemplate = (options) => {
492
519
  ` : "";
493
520
  const svelteImport = needsSvelte ? `import svelte from "@astrojs/svelte";
494
521
  ` : "";
522
+ const substitutesVariables = hasVariables(config.variables);
523
+ const variablesPluginEntry = substitutesVariables ? `variablesVitePlugin(${JSON.stringify(config.variables)}), ` : "";
495
524
  const blumeImports = [
496
525
  "blumeIntegration",
497
526
  "includeHmrPlugin",
498
527
  "prerenderDepsPlugin",
499
528
  ...runtimeModuleImports,
500
- ...adapterOption.includes("withAdapterRoot") ? ["withAdapterRoot"] : []
529
+ ...adapterOption.includes("withAdapterRoot") ? ["withAdapterRoot"] : [],
530
+ ...substitutesVariables ? ["variablesVitePlugin"] : []
501
531
  ];
502
532
  const blumeImport = `import { ${blumeImports.join(", ")} } from "blume/astro";
503
533
  `;
@@ -509,7 +539,8 @@ var astroConfigTemplate = (options) => {
509
539
  contentRoot: options.contentRoot,
510
540
  deployBase,
511
541
  externalLinks: config.markdown.externalLinks,
512
- headingAnchors: config.markdown.headingAnchors
542
+ headingAnchors: config.markdown.headingAnchors,
543
+ variables: config.variables
513
544
  });
514
545
  const processorOptions = options.generatedModulesDir === undefined ? processorLiteral : `{ ...${processorLiteral}, dataFile: ${configPath(`${options.generatedModulesDir}/data.json`, true)} }`;
515
546
  const integrations = [
@@ -528,7 +559,8 @@ var astroConfigTemplate = (options) => {
528
559
  config,
529
560
  contentRoutes,
530
561
  ejected,
531
- pages
562
+ pages,
563
+ redirects: compileRedirects(basedRedirects)
532
564
  }))})`);
533
565
  const {
534
566
  configSourceMarker,
@@ -584,7 +616,7 @@ ${userConfigSetup}export default defineConfig({
584
616
  // the overlap only adds memory.
585
617
  build: { concurrency: Math.min(8, availableParallelism()) },
586
618
  vite: {${viteCacheOption}
587
- plugins: [${runtimeModulesPluginEntry}tailwindcss(), includeHmrPlugin(${configPath(`${context.outDir}/src/generated/includes.json`, ejected)}), prerenderDepsPlugin()],
619
+ plugins: [${runtimeModulesPluginEntry}${variablesPluginEntry}tailwindcss(), includeHmrPlugin(${configPath(`${context.outDir}/src/generated/includes.json`, ejected)}), prerenderDepsPlugin()],
588
620
  build: {${features.mermaid ? MERMAID_CHUNK_LIMIT : ""}
589
621
  rolldownOptions: {
590
622
  ${ROLLDOWN_ON_LOG},
@@ -640,6 +672,7 @@ ${userConfigSetup}export default defineConfig({
640
672
  resolve: {
641
673
  alias: {
642
674
  "blume:ask": ${configPath(askPath, ejected)},
675
+ "blume:consent-client": ${configPath(consentClientPath, ejected)},
643
676
  "blume:examples": ${configPath(examplesPath, ejected)},
644
677
  "blume:examples-theme": ${configPath(examplesThemePath, ejected)},
645
678
  "blume:features": ${configPath(featuresPath, ejected)},
@@ -719,18 +752,73 @@ var askCorsTemplate = (cors = []) => cors.length > 0 ? {
719
752
  imports: [
720
753
  'import { preflightResponse, withCors } from "blume/ai/cors.ts";'
721
754
  ],
722
- open: "withCors(ALLOWED_ORIGINS, async ({ request }) => {",
755
+ open: "withCors(ALLOWED_ORIGINS, async (context) => {",
723
756
  setup: `
724
757
  const ALLOWED_ORIGINS = ${JSON.stringify(cors)};
725
758
 
726
759
  export const OPTIONS: APIRoute = ({ request }) =>
727
760
  preflightResponse(request, ALLOWED_ORIGINS);
728
761
  `
729
- } : { close: "};", imports: [], open: "async ({ request }) => {", setup: "" };
762
+ } : { close: "};", imports: [], open: "async (context) => {", setup: "" };
763
+ var rateLimitTemplate = (adapter, scope) => {
764
+ if (!adapter) {
765
+ return { check: "", imports: [], setup: "" };
766
+ }
767
+ const imports = [
768
+ 'import { createLimiter, rateLimited } from "blume/ratelimit/runtime.ts";'
769
+ ];
770
+ let runtime = "";
771
+ if (adapter.kind === "upstash") {
772
+ imports.push('import { getSecret } from "astro:env/server";');
773
+ runtime = ", { secret: getSecret }";
774
+ } else if (adapter.kind === "cloudflare") {
775
+ imports.push("// @ts-ignore `cloudflare:workers` is typed once `wrangler types` has run.", 'import { env } from "cloudflare:workers";');
776
+ runtime = `, { binding: Reflect.get(env, ${JSON.stringify(RATE_LIMIT_BINDING)}) }`;
777
+ }
778
+ return {
779
+ check: ` const limited = await rateLimited(limiter, context, ${JSON.stringify(scope)});
780
+ if (limited) {
781
+ return limited;
782
+ }
783
+ `,
784
+ imports,
785
+ setup: `
786
+ const limiter = createLimiter(${JSON.stringify(adapter)}${runtime});
787
+ `
788
+ };
789
+ };
790
+ var askCaptchaTemplate = (adapter) => {
791
+ if (!adapter) {
792
+ return { check: "", imports: [], setup: "" };
793
+ }
794
+ const [secret = ""] = adapter.requiredSecrets;
795
+ return {
796
+ check: ` const captchaSecret = getSecret(${JSON.stringify(secret)});
797
+ if (!captchaSecret) {
798
+ return new Response(
799
+ ${JSON.stringify(`The assistant is not configured: set ${secret}.`)},
800
+ { status: 503 }
801
+ );
802
+ }
803
+ const captchaToken =
804
+ typeof body.captcha === "string" ? body.captcha : undefined;
805
+ if (!(await verifyCaptcha(CAPTCHA, captchaToken, context, { secret: captchaSecret }))) {
806
+ return new Response("Verification failed: the bot check didn't pass.", {
807
+ status: 403,
808
+ });
809
+ }
810
+ `,
811
+ imports: ['import { verifyCaptcha } from "blume/captcha/verify.ts";'],
812
+ setup: `
813
+ const CAPTCHA = ${JSON.stringify(adapter)};
814
+ `
815
+ };
816
+ };
730
817
  var ASK_BODY_LIMIT_BYTES = 65536;
731
818
  var askEndpointTemplate = (backend, options) => {
732
819
  const { instructions, retrieval } = options ?? {};
733
820
  const { grounded } = backend;
821
+ const tools = grounded && Boolean(options?.tools);
734
822
  const fallbackPrompt = instructions ? `${ASK_FALLBACK_PROMPT}
735
823
 
736
824
  ${instructions}` : ASK_FALLBACK_PROMPT;
@@ -750,14 +838,33 @@ ${instructions}` : ASK_FALLBACK_PROMPT;
750
838
  if (retrieval) {
751
839
  groundFields.push(`retrieval: ${JSON.stringify(retrieval)}`);
752
840
  }
841
+ if (tools) {
842
+ groundFields.push("tools: true");
843
+ }
753
844
  const groundOptions = groundFields.length > 0 ? `, { ${groundFields.join(", ")} }` : "";
754
845
  setup += `
755
846
  const ground = createAskContext(askData${groundOptions});
756
847
  `;
848
+ if (tools) {
849
+ imports.push('import { stepCountIs } from "ai";', 'import { ASK_MAX_STEPS, createAskTools } from "blume/ai/ask-tools.ts";');
850
+ setup += `const askTools = createAskTools(askData);
851
+ `;
852
+ }
757
853
  }
758
854
  const cors = askCorsTemplate(options?.cors);
759
855
  imports.push(...cors.imports);
760
- const validate = ` const text = await readCappedText(request, ${ASK_BODY_LIMIT_BYTES});
856
+ const limit = rateLimitTemplate(options?.rateLimit, "ask");
857
+ for (const line of limit.imports) {
858
+ if (!imports.includes(line)) {
859
+ imports.push(line);
860
+ }
861
+ }
862
+ setup += limit.setup;
863
+ const captcha = askCaptchaTemplate(options?.captcha);
864
+ imports.push(...captcha.imports);
865
+ setup += captcha.setup;
866
+ const validate = ` const { request } = context;
867
+ ${limit.check} const text = await readCappedText(request, ${ASK_BODY_LIMIT_BYTES});
761
868
  if (text === undefined) {
762
869
  return new Response("Request too large: the body must be at most 64 KB.", {
763
870
  status: 413,
@@ -802,6 +909,7 @@ const ground = createAskContext(askData${groundOptions});
802
909
  grounded ? "instructions" : `instructions:
803
910
  ${JSON.stringify(fallbackPrompt)}`,
804
911
  "messages",
912
+ ...tools ? ["tools: askTools(body.page)", "stopWhen: stepCountIs(ASK_MAX_STEPS)"] : [],
805
913
  ...backend.template.fields
806
914
  ];
807
915
  const call = ` const result = streamText({
@@ -817,7 +925,7 @@ ${call}` : call;
817
925
  const handler = `export const POST: APIRoute = ${cors.open}
818
926
  ${validate}
819
927
  ${keyCheck}
820
- try {
928
+ ${captcha.check} try {
821
929
  ${stream}
822
930
  return createTextStreamResponse({
823
931
  stream: toTextStream({ stream: result.stream }),
@@ -844,9 +952,11 @@ const { strings } = Astro.props;
844
952
  ---
845
953
 
846
954
  <Assistant
955
+ captcha={data.config.assistant?.captcha ?? undefined}
847
956
  endpoint={data.config.assistant?.endpoint ?? undefined}
848
957
  strings={strings ?? data.ui.assistant}
849
958
  suggestions={data.config.assistant?.suggestions ?? []}
959
+ support={data.config.assistant?.support ?? undefined}
850
960
  />
851
961
  ` : `---
852
962
  // Generated by Blume. Do not edit.
@@ -894,6 +1004,25 @@ ${features.epub ? `export const loadEpub:
894
1004
  | (() => Promise<typeof import("epub-gen-memory/bundle")>)
895
1005
  | null = () => import("epub-gen-memory/bundle");` : "export const loadEpub: (() => Promise<unknown>) | null = null;"}
896
1006
  `;
1007
+ var consentClientTemplate = (consent) => {
1008
+ const module = consent ? CONSENT_CLIENT_MODULES.get(consent.kind) : undefined;
1009
+ if (!(consent && module)) {
1010
+ return `// Generated by Blume. Do not edit.
1011
+ // The consent adapter has no browser module, or consent is off.
1012
+ export const startConsentClient = (): void => {};
1013
+ `;
1014
+ }
1015
+ return `// Generated by Blume. Do not edit.
1016
+ // The \`${consent.kind}\` consent adapter's browser module, with its options.
1017
+ import { start } from ${JSON.stringify(module)};
1018
+
1019
+ export const startConsentClient = (
1020
+ consent: Parameters<typeof start>[0]
1021
+ ): void => {
1022
+ start(consent, ${JSON.stringify(consent.options)});
1023
+ };
1024
+ `;
1025
+ };
897
1026
  var searchClientTemplate = (config) => {
898
1027
  const { provider } = config.search;
899
1028
  switch (provider.mode) {
@@ -925,11 +1054,18 @@ export const createSearch = () => create({ url });
925
1054
  }
926
1055
  }
927
1056
  };
928
- var mixedbreadSearchEndpointTemplate = (options) => `// Generated by Blume. Do not edit.
929
- import type { APIRoute } from "astro";
930
- import { getSecret } from "astro:env/server";
931
- import Mixedbread from "@mixedbread/sdk";
932
- import { readCappedText } from "blume/core/request-body.ts";
1057
+ var mixedbreadSearchEndpointTemplate = (options, rateLimit) => {
1058
+ const limit = rateLimitTemplate(rateLimit, "search");
1059
+ const imports = [
1060
+ 'import type { APIRoute } from "astro";',
1061
+ 'import { getSecret } from "astro:env/server";',
1062
+ 'import Mixedbread from "@mixedbread/sdk";',
1063
+ 'import { readCappedText } from "blume/core/request-body.ts";',
1064
+ ...limit.imports.filter((line) => !line.includes('"astro:env/server"'))
1065
+ ];
1066
+ return `// Generated by Blume. Do not edit.
1067
+ ${imports.join(`
1068
+ `)}
933
1069
 
934
1070
  export const prerender = false;
935
1071
 
@@ -937,9 +1073,10 @@ const client = new Mixedbread({ apiKey: getSecret("MIXEDBREAD_API_KEY") ?? "" })
937
1073
  const OPTIONS = ${JSON.stringify(options)};
938
1074
  // Every option besides the store reaches the search call verbatim.
939
1075
  const { storeId: STORE_ID, ...SEARCH_OPTIONS } = OPTIONS;
940
-
941
- export const POST: APIRoute = async ({ request }) => {
942
- // A search body is one short query: read it under a 16 KB cap, so a
1076
+ ${limit.setup}
1077
+ export const POST: APIRoute = async (context) => {
1078
+ const { request } = context;
1079
+ ${limit.check} // A search body is one short query: read it under a 16 KB cap, so a
943
1080
  // self-hosted server never buffers an arbitrarily large POST first.
944
1081
  const text = await readCappedText(request, 16_384);
945
1082
  if (text === undefined) {
@@ -984,6 +1121,7 @@ export const POST: APIRoute = async ({ request }) => {
984
1121
  });
985
1122
  };
986
1123
  `;
1124
+ };
987
1125
  var rawMarkdownEndpointTemplate = (kind) => `// Generated by Blume. Do not edit.
988
1126
  import raw from "blume:raw-markdown";
989
1127
 
@@ -1128,16 +1266,22 @@ const handler = createMcpFetchHandler(data);
1128
1266
 
1129
1267
  export const ALL: APIRoute = ({ request }) => handler(request);
1130
1268
  `;
1131
- var playgroundProxyTemplate = (origins) => `// Generated by Blume. Do not edit.
1132
- import type { APIRoute } from "astro";
1133
- import { createPlaygroundProxyHandler } from "blume/openapi/proxy.ts";
1269
+ var playgroundProxyTemplate = (origins, rateLimit) => {
1270
+ const limit = rateLimitTemplate(rateLimit, "api-proxy");
1271
+ const route = limit.check ? `export const ALL: APIRoute = async (context) => {
1272
+ ${limit.check} return handler(context.request);
1273
+ };` : "export const ALL: APIRoute = ({ request }) => handler(request);";
1274
+ return `// Generated by Blume. Do not edit.
1275
+ ${['import type { APIRoute } from "astro";', 'import { createPlaygroundProxyHandler } from "blume/openapi/proxy.ts";', ...limit.imports].join(`
1276
+ `)}
1134
1277
 
1135
1278
  export const prerender = false;
1136
1279
 
1137
1280
  const handler = createPlaygroundProxyHandler(${JSON.stringify(origins)});
1138
-
1139
- export const ALL: APIRoute = ({ request }) => handler(request);
1281
+ ${limit.setup}
1282
+ ${route}
1140
1283
  `;
1284
+ };
1141
1285
  var staticJsonEndpointTemplate = (payload) => `// Generated by Blume. Do not edit.
1142
1286
  export const prerender = true;
1143
1287
 
@@ -1378,6 +1522,9 @@ var contentComponentsSource = (mathEnabled) => {
1378
1522
  return {
1379
1523
  imports: `import Accordion from "blume/components/content/Accordion.astro";
1380
1524
  import AccordionItem from "blume/components/content/AccordionItem.astro";
1525
+ import ApiEndpoint from "blume/components/content/ApiEndpoint.astro";
1526
+ import ApiPlayground from "blume/components/content/ApiPlayground.astro";
1527
+ import ApiRail from "blume/components/content/ApiRail.astro";
1381
1528
  import AutoTypeTable from "blume/components/content/AutoTypeTable.astro";
1382
1529
  import Badge from "blume/components/content/Badge.astro";
1383
1530
  import Callout from "blume/components/content/Callout.astro";
@@ -1397,7 +1544,11 @@ import FileTree from "blume/components/content/FileTree.astro";
1397
1544
  import Frame from "blume/components/content/Frame.astro";
1398
1545
  import GithubInfo from "blume/components/content/GithubInfo.astro";
1399
1546
  import Panel from "blume/components/content/Panel.astro";
1547
+ import ParamField from "blume/components/content/ParamField.astro";
1400
1548
  import Prompt from "blume/components/content/Prompt.astro";
1549
+ import RequestExample from "blume/components/content/RequestExample.astro";
1550
+ import ResponseExample from "blume/components/content/ResponseExample.astro";
1551
+ import ResponseField from "blume/components/content/ResponseField.astro";
1401
1552
  import Step from "blume/components/content/Step.astro";
1402
1553
  import Steps from "blume/components/content/Steps.astro";
1403
1554
  import Tab from "blume/components/content/Tab.astro";
@@ -1408,10 +1559,13 @@ import TreeRoot from "blume/components/content/Tree.astro";
1408
1559
  import TreeFile from "blume/components/content/TreeFile.astro";
1409
1560
  import TreeFolder from "blume/components/content/TreeFolder.astro";
1410
1561
  import TypeTable from "blume/components/content/TypeTable.astro";
1562
+ import View from "blume/components/content/View.astro";
1411
1563
  import Visibility from "blume/components/content/Visibility.astro";
1412
1564
  import YouTube from "blume/components/content/YouTube.astro";
1413
1565
  import Icon from "blume/components/Icon.astro";
1414
1566
  import LocaleLinks from "blume/components/layout/LocaleLinks.astro";
1567
+ import NarrationPlayer from "blume/components/layout/NarrationPlayer.astro";
1568
+ import ViewSwitcher from "blume/components/content/ViewSwitcher.astro";
1415
1569
  import ApiOverview from "blume/components/openapi/ApiOverview.astro";
1416
1570
  import ApiTagOperations from "blume/components/openapi/ApiTagOperations.astro";
1417
1571
  import Operation from "blume/components/openapi/Operation.astro";
@@ -1419,7 +1573,10 @@ ${mathImport}import { mdxComponents as userMdx, layoutOverrides } from "../gener
1419
1573
  map: `{
1420
1574
  Accordion,
1421
1575
  AccordionItem,
1576
+ ApiEndpoint,
1422
1577
  ApiOverview,
1578
+ ApiPlayground,
1579
+ ApiRail,
1423
1580
  ApiTagOperations,
1424
1581
  AutoTypeTable,
1425
1582
  Badge,
@@ -1440,7 +1597,11 @@ ${mathImport}import { mdxComponents as userMdx, layoutOverrides } from "../gener
1440
1597
  Icon,
1441
1598
  Operation,
1442
1599
  Panel,
1600
+ ParamField,
1443
1601
  Prompt,
1602
+ RequestExample,
1603
+ ResponseExample,
1604
+ ResponseField,
1444
1605
  Step,
1445
1606
  Steps,
1446
1607
  Tab,
@@ -1449,6 +1610,7 @@ ${mathImport}import { mdxComponents as userMdx, layoutOverrides } from "../gener
1449
1610
  Tooltip,
1450
1611
  Tree,
1451
1612
  TypeTable,
1613
+ View,
1452
1614
  Visibility,
1453
1615
  YouTube,
1454
1616
  ${mathEntry}...userMdx,
@@ -1462,6 +1624,7 @@ var catchAllPageTemplate = (options) => {
1462
1624
  return `---
1463
1625
  // Generated by Blume. Do not edit.
1464
1626
  import { getEntry, render } from "astro:content";
1627
+ import { pageModeLayout } from "blume/core/page-modes.ts";
1465
1628
  import type { CollectionKey } from "astro:content";
1466
1629
  import RootLayout from "blume/components/layout/RootLayout.astro";
1467
1630
  import { withBase, withMountedBase } from "blume/components/islands/base-path.ts";
@@ -1513,6 +1676,13 @@ const { Content, headings: allHeadings, remarkPluginFrontmatter } = await render
1513
1676
  // frontmatter (see markdown/heading-anchors.ts). Only the plugin's array
1514
1677
  // counts: \`frontmatter.extend\` can declare the same key, and on a page with
1515
1678
  // no headings that user-supplied value would pass straight through.
1679
+ // A page written in \`<View>\` blocks gets their picker above the content;
1680
+ // the views plugin lists them through the render's frontmatter (see
1681
+ // markdown/views.ts), and only a list of titled entries counts.
1682
+ const viewsRaw = remarkPluginFrontmatter?.${VIEWS_KEY};
1683
+ const views = Array.isArray(viewsRaw)
1684
+ ? viewsRaw.filter((view) => typeof view?.title === "string")
1685
+ : [];
1516
1686
  const tocHiddenRaw = remarkPluginFrontmatter?.${TOC_HIDDEN_KEY};
1517
1687
  const tocHidden = new Set(Array.isArray(tocHiddenRaw) ? tocHiddenRaw : []);
1518
1688
  const headings =
@@ -1591,6 +1761,14 @@ const htmlLang = i18n ? locale : "en";
1591
1761
  // follows that language — not the (mirrored) page locale.
1592
1762
  const contentLocale =
1593
1763
  fallback && i18n?.fallbackLocale ? i18n.fallbackLocale : locale;
1764
+ // "Listen to this page", unless the page opts out. The spoken cues are read
1765
+ // between the content's own sentences, so they come from the content's
1766
+ // language (a fallback page's), while the player's labels follow the page.
1767
+ // A \`custom\` or \`frame\` page brings its own heading: no title, description,
1768
+ // or narration player above its content.
1769
+ const pageChrome = pageModeLayout(frontmatter.mode).chrome;
1770
+ const narration = pageChrome && frontmatter.narration ? data.config.narration : null;
1771
+ const narrationCues = (i18n ? (data.uiByLocale[contentLocale] ?? data.ui) : data.ui).narration;
1594
1772
  const contentDir = i18n
1595
1773
  ? (i18n.locales.find((l) => l.code === contentLocale)?.dir ?? "ltr")
1596
1774
  : "ltr";
@@ -1774,6 +1952,10 @@ const LayoutComponent = resolveSlot(layoutOverrides.Layout, RootLayout);
1774
1952
  canonical={canonical}
1775
1953
  editUrl={editUrl}
1776
1954
  feedback={data.config.feedback}
1955
+ feedbackComments={data.config.feedbackComments}
1956
+ pagination={frontmatter.pagination}
1957
+ related={frontmatter.related}
1958
+ search={frontmatter.search}
1777
1959
  exportPdf={${options.exportPdf}}
1778
1960
  exportEpub={${options.exportEpub}}${options.navFragments ? `
1779
1961
  navFragmentBase={withMountedBase(\`/blume-nav/\${version || "current"}/\${i18n && localePrefix(locale) ? locale : "default"}\`)}` : ""}
@@ -1782,13 +1964,25 @@ const LayoutComponent = resolveSlot(layoutOverrides.Layout, RootLayout);
1782
1964
  discovery={data.config.discovery}
1783
1965
  siteUrl={data.config.site}
1784
1966
  pageType={frontmatter.type}
1967
+ apiRail={remarkPluginFrontmatter?.${API_RAIL_KEY} === true}
1968
+ pageMode={frontmatter.mode}
1785
1969
  published={frontmatter.date ?? frontmatter.changelog?.date ?? null}
1786
1970
  lastModified={lastModified}
1787
1971
  noindex={effectiveNoindex}
1788
1972
  structuredDataEnabled={data.config.structuredData}
1789
1973
  >
1790
- <h1>{title}</h1>
1791
- {frontmatter.description && <p class="text-lg text-muted-foreground">{frontmatter.description}</p>}
1974
+ {pageChrome && <h1>{title}</h1>}
1975
+ {pageChrome && frontmatter.description && <p class="text-lg text-muted-foreground">{frontmatter.description}</p>}
1976
+ {narration && (
1977
+ <NarrationPlayer
1978
+ audioBase={narration.generated ? withMountedBase("/blume-narration/audio/") : undefined}
1979
+ cues={narrationCues}
1980
+ lang={i18n ? contentLocale : htmlLang}
1981
+ manifest={narration.generated ? withMountedBase(encodeURI(\`/blume-narration/\${route === "/" ? "index" : route.slice(1)}.json\`)) : undefined}
1982
+ strings={ui.narration}
1983
+ />
1984
+ )}
1985
+ {views.length > 1 && <ViewSwitcher label={ui.content.selectView} views={views} />}
1792
1986
  <LocaleLinks locale={locale}>
1793
1987
  <Content components={components} />
1794
1988
  </LocaleLinks>
@@ -2559,7 +2753,7 @@ var runtimeTsconfigTemplate = () => `${JSON.stringify({
2559
2753
  }, null, 2)}
2560
2754
  `;
2561
2755
 
2562
- export { deployOutputDir, deployStaticDir, surfaceAdapterOutput, planComponentSlots, publishRuntimeModules, runtimeDependencies, EJECTED_CONFIG_HEADER, astroConfigTemplate, stagedContentDir, contentConfigTemplate, askEndpointTemplate, askComponentTemplate, searchEndpointTemplate, featuresTemplate, searchClientTemplate, mixedbreadSearchEndpointTemplate, rawMarkdownEndpointTemplate, contentAssetsEndpointTemplate, mcpPageFile, mcpEndpointTemplate, playgroundProxyTemplate, staticJsonEndpointTemplate, rssEndpointTemplate, navFragmentTemplate, ogEndpointTemplate, scalarReferenceTemplate, catchAllPageTemplate, changelogIndexTemplate, notFoundPageTemplate, notFoundMarkdownTemplate, notFoundJsonTemplate, apiPagesIndexTemplate, apiPageTemplate, apiNavigationTemplate, apiSearchTemplate, apiNotFoundTemplate, exampleSlug, exampleWrapperTemplate, examplesRouteBase, exampleMapTemplate, examplesPageTemplate, runtimePackageTemplate, runtimeTsconfigTemplate };
2756
+ export { deployOutputDir, deployStaticDir, surfaceAdapterOutput, planComponentSlots, publishRuntimeModules, runtimeDependencies, EJECTED_CONFIG_HEADER, astroConfigTemplate, stagedContentDir, contentConfigTemplate, askEndpointTemplate, askComponentTemplate, searchEndpointTemplate, featuresTemplate, consentClientTemplate, searchClientTemplate, mixedbreadSearchEndpointTemplate, rawMarkdownEndpointTemplate, contentAssetsEndpointTemplate, mcpPageFile, mcpEndpointTemplate, playgroundProxyTemplate, staticJsonEndpointTemplate, rssEndpointTemplate, navFragmentTemplate, ogEndpointTemplate, scalarReferenceTemplate, catchAllPageTemplate, changelogIndexTemplate, notFoundPageTemplate, notFoundMarkdownTemplate, notFoundJsonTemplate, apiPagesIndexTemplate, apiPageTemplate, apiNavigationTemplate, apiSearchTemplate, apiNotFoundTemplate, exampleSlug, exampleWrapperTemplate, examplesRouteBase, exampleMapTemplate, examplesPageTemplate, runtimePackageTemplate, runtimeTsconfigTemplate };
2563
2757
 
2564
- //# debugId=D53DB1B1EA2E6A3764756E2164756E21
2565
- //# sourceMappingURL=chunk-5m5nmvyq.js.map
2758
+ //# debugId=F21B5F971981289464756E2164756E21
2759
+ //# sourceMappingURL=chunk-4h8z9vv5.js.map