blume 2.0.1 → 2.0.3

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 (492) hide show
  1. package/CHANGELOG.md +147 -0
  2. package/dist/cli/{chunk-qwsrynx5.js → chunk-1d7ve1dm.js} +38 -19
  3. package/dist/cli/{chunk-qwsrynx5.js.map → chunk-1d7ve1dm.js.map} +4 -4
  4. package/dist/cli/{chunk-s6jhgk0q.js → chunk-2eytanqx.js} +2 -2
  5. package/dist/cli/{chunk-kdp5q7ke.js → chunk-2hsdwb9n.js} +18 -19
  6. package/dist/cli/{chunk-kdp5q7ke.js.map → chunk-2hsdwb9n.js.map} +2 -2
  7. package/dist/cli/{chunk-hdpx1tax.js → chunk-2z928egk.js} +5 -5
  8. package/dist/cli/{chunk-jwyddg7y.js → chunk-35d4wj9f.js} +30 -24
  9. package/dist/cli/chunk-35d4wj9f.js.map +15 -0
  10. package/dist/cli/{chunk-ah61y8py.js → chunk-364znk6q.js} +2 -2
  11. package/dist/cli/{chunk-jts8mvcz.js → chunk-3em5wd2y.js} +25 -6
  12. package/dist/cli/{chunk-jts8mvcz.js.map → chunk-3em5wd2y.js.map} +3 -3
  13. package/dist/cli/{chunk-s1p84fyh.js → chunk-5f86nr5m.js} +63 -22
  14. package/dist/cli/chunk-5f86nr5m.js.map +11 -0
  15. package/dist/cli/{chunk-2hn4b8z7.js → chunk-5m5nmvyq.js} +170 -76
  16. package/dist/cli/chunk-5m5nmvyq.js.map +13 -0
  17. package/dist/cli/{chunk-epjnccmv.js → chunk-5xvm6tfj.js} +18 -15
  18. package/dist/cli/chunk-5xvm6tfj.js.map +10 -0
  19. package/dist/cli/{chunk-fz5wtpmh.js → chunk-6dsbexzp.js} +18 -15
  20. package/dist/cli/chunk-6dsbexzp.js.map +10 -0
  21. package/dist/cli/{chunk-vtk4a6dg.js → chunk-8ktnccpt.js} +1 -1
  22. package/dist/cli/{chunk-6hsn950k.js → chunk-9t7a85s3.js} +178 -48
  23. package/dist/cli/chunk-9t7a85s3.js.map +10 -0
  24. package/dist/cli/{chunk-fxypxtvm.js → chunk-a58773jm.js} +2 -2
  25. package/dist/cli/{chunk-mb2919y2.js → chunk-acanzt5p.js} +17 -6
  26. package/dist/cli/chunk-acanzt5p.js.map +10 -0
  27. package/dist/cli/{chunk-27g6wdth.js → chunk-akbpwfxc.js} +90 -26
  28. package/dist/cli/chunk-akbpwfxc.js.map +10 -0
  29. package/dist/cli/{chunk-wm7js3j9.js → chunk-b07cmahc.js} +2 -2
  30. package/dist/cli/{chunk-wgm7m9qk.js → chunk-c8chx29p.js} +179 -51
  31. package/dist/cli/chunk-c8chx29p.js.map +36 -0
  32. package/dist/cli/{chunk-qs4q5p4e.js → chunk-crgn1q09.js} +32 -14
  33. package/dist/cli/chunk-crgn1q09.js.map +10 -0
  34. package/dist/cli/chunk-e04dxsz1.js +39 -0
  35. package/dist/cli/chunk-e04dxsz1.js.map +10 -0
  36. package/dist/cli/{chunk-yt5n7ppj.js → chunk-ey84smr6.js} +17 -7
  37. package/dist/cli/chunk-ey84smr6.js.map +10 -0
  38. package/dist/cli/{chunk-f2z5v128.js → chunk-g4hq16wv.js} +14 -15
  39. package/dist/cli/{chunk-f2z5v128.js.map → chunk-g4hq16wv.js.map} +2 -2
  40. package/dist/cli/{chunk-fa25z98p.js → chunk-ga0pf4aj.js} +9 -8
  41. package/dist/cli/chunk-ga0pf4aj.js.map +11 -0
  42. package/dist/cli/{chunk-kpf8rrjc.js → chunk-hm3vjy5s.js} +109 -58
  43. package/dist/cli/chunk-hm3vjy5s.js.map +19 -0
  44. package/dist/cli/{chunk-fs23ddbb.js → chunk-j85vccga.js} +625 -750
  45. package/dist/cli/chunk-j85vccga.js.map +36 -0
  46. package/dist/cli/{chunk-ch6g3ar0.js → chunk-p3v96n38.js} +6 -6
  47. package/dist/cli/{chunk-ch6g3ar0.js.map → chunk-p3v96n38.js.map} +3 -3
  48. package/dist/cli/{chunk-q5163e60.js → chunk-p73c0m7w.js} +21 -19
  49. package/dist/cli/chunk-p73c0m7w.js.map +11 -0
  50. package/dist/cli/{chunk-dh8cwk36.js → chunk-pehfxfta.js} +24 -9
  51. package/dist/cli/chunk-pehfxfta.js.map +10 -0
  52. package/dist/cli/{chunk-qkqwkpte.js → chunk-pv29h0wf.js} +3688 -1313
  53. package/dist/cli/chunk-pv29h0wf.js.map +190 -0
  54. package/dist/cli/{chunk-6vm74dry.js → chunk-q58y5e6a.js} +10 -10
  55. package/dist/cli/{chunk-6vm74dry.js.map → chunk-q58y5e6a.js.map} +3 -3
  56. package/dist/cli/{chunk-zxcczpyx.js → chunk-r20tn01b.js} +1 -1
  57. package/dist/cli/{chunk-m3vmjgmq.js → chunk-r9rcc4w7.js} +16 -8
  58. package/dist/cli/chunk-r9rcc4w7.js.map +10 -0
  59. package/dist/cli/{chunk-5shv93fd.js → chunk-tkacnehg.js} +2 -2
  60. package/dist/cli/{chunk-zxh4d9vy.js → chunk-tzmab476.js} +4 -4
  61. package/dist/cli/{chunk-yw7dm696.js → chunk-vg9r4eb9.js} +24 -11
  62. package/dist/cli/chunk-vg9r4eb9.js.map +14 -0
  63. package/dist/cli/{chunk-79jhk4py.js → chunk-wrr3j9w9.js} +260 -132
  64. package/dist/cli/chunk-wrr3j9w9.js.map +35 -0
  65. package/dist/cli/{chunk-6crbhc3x.js → chunk-yfyb25rh.js} +54 -27
  66. package/dist/cli/chunk-yfyb25rh.js.map +14 -0
  67. package/dist/cli/index.js +162 -35
  68. package/dist/cli/index.js.map +4 -4
  69. package/dist/types/ai/agent-surface.d.ts +32 -0
  70. package/dist/types/ai/api-catalog.d.ts +7 -1
  71. package/dist/types/ai/ask-context.d.ts +7 -0
  72. package/dist/types/ai/component-markdown.d.ts +4 -4
  73. package/dist/types/ai/link-headers.d.ts +8 -1
  74. package/dist/types/ai/openapi-components.d.ts +5 -2
  75. package/dist/types/ai/relative-links.d.ts +11 -4
  76. package/dist/types/ai/skills.d.ts +4 -1
  77. package/dist/types/ai/static-expression.d.ts +28 -0
  78. package/dist/types/ai/tar.d.ts +1 -3
  79. package/dist/types/analytics/databuddy.d.ts +43 -0
  80. package/dist/types/analytics/index.d.ts +4 -0
  81. package/dist/types/analytics/one-dollar-stats.d.ts +48 -0
  82. package/dist/types/analytics/schema.d.ts +28 -0
  83. package/dist/types/astro/integration.d.ts +3 -2
  84. package/dist/types/cli/env.d.ts +5 -0
  85. package/dist/types/cli/init/scaffold.d.ts +19 -3
  86. package/dist/types/cli/init/starter-spec.d.ts +11 -0
  87. package/dist/types/core/base-path.d.ts +24 -1
  88. package/dist/types/core/config-input.d.ts +13 -11
  89. package/dist/types/core/config.d.ts +2 -2
  90. package/dist/types/core/directive-diagnostics.d.ts +12 -0
  91. package/dist/types/core/graph.d.ts +2 -0
  92. package/dist/types/core/heading-markers.d.ts +5 -7
  93. package/dist/types/core/i18n-ui.d.ts +31 -0
  94. package/dist/types/core/i18n.d.ts +9 -1
  95. package/dist/types/core/last-modified.d.ts +10 -0
  96. package/dist/types/core/links.d.ts +3 -1
  97. package/dist/types/core/load-module.d.ts +10 -0
  98. package/dist/types/core/locale-links.d.ts +12 -2
  99. package/dist/types/core/meta.d.ts +13 -1
  100. package/dist/types/core/nav-diagnostics.d.ts +10 -0
  101. package/dist/types/core/navigation.d.ts +38 -0
  102. package/dist/types/core/ordering-prefix.d.ts +4 -0
  103. package/dist/types/core/safe-links.d.ts +3 -1
  104. package/dist/types/core/schema.d.ts +59 -13
  105. package/dist/types/core/sources/github-releases.d.ts +5 -0
  106. package/dist/types/core/sources/lower.d.ts +38 -13
  107. package/dist/types/core/sources/normalize.d.ts +23 -2
  108. package/dist/types/core/sources/remote.d.ts +11 -1
  109. package/dist/types/core/sources/resolve.d.ts +12 -0
  110. package/dist/types/core/sources/types.d.ts +31 -0
  111. package/dist/types/core/sources/watch.d.ts +12 -5
  112. package/dist/types/core/standard-schema.d.ts +5 -0
  113. package/dist/types/core/types.d.ts +9 -0
  114. package/dist/types/deploy/adapters/node.d.ts +5 -2
  115. package/dist/types/deploy/adapters/types.d.ts +7 -0
  116. package/dist/types/deploy/artifacts.d.ts +6 -4
  117. package/dist/types/deploy/cloudflare-negotiation.d.ts +3 -2
  118. package/dist/types/deploy/headers.d.ts +36 -7
  119. package/dist/types/deploy/node-headers.d.ts +43 -8
  120. package/dist/types/deploy/platforms/netlify.d.ts +27 -2
  121. package/dist/types/deploy/platforms/node.d.ts +6 -5
  122. package/dist/types/deploy/platforms/types.d.ts +15 -0
  123. package/dist/types/deploy/platforms/vercel.d.ts +3 -2
  124. package/dist/types/deploy/redirects.d.ts +31 -15
  125. package/dist/types/deploy/vercel-negotiation.d.ts +3 -2
  126. package/dist/types/markdown/directives.d.ts +62 -0
  127. package/dist/types/markdown/features.d.ts +21 -0
  128. package/dist/types/markdown/mdast.d.ts +63 -0
  129. package/dist/types/openapi/asyncapi.d.ts +4 -2
  130. package/dist/types/openapi/model.d.ts +20 -6
  131. package/dist/types/search/sync/algolia.d.ts +3 -1
  132. package/docs/01-quickstart.mdx +3 -2
  133. package/docs/02-deployment.mdx +20 -9
  134. package/docs/08-faq.mdx +10 -3
  135. package/docs/advanced/changelog.mdx +1 -1
  136. package/docs/advanced/custom-pages.mdx +7 -5
  137. package/docs/cli/audit.mdx +19 -3
  138. package/docs/cli/doctor.mdx +2 -2
  139. package/docs/cli/evals.mdx +4 -4
  140. package/docs/cli/index.mdx +4 -1
  141. package/docs/cli/translate.mdx +4 -4
  142. package/docs/cli/version.mdx +1 -1
  143. package/docs/configuration/analytics.mdx +42 -2
  144. package/docs/configuration/assistant.mdx +1 -1
  145. package/docs/configuration/customization.mdx +6 -3
  146. package/docs/configuration/index.mdx +5 -3
  147. package/docs/configuration/search.mdx +2 -2
  148. package/docs/content/components.mdx +2 -2
  149. package/docs/content/frontmatter.mdx +5 -1
  150. package/docs/content/i18n.mdx +3 -1
  151. package/docs/content/index.mdx +8 -4
  152. package/docs/content/islands.mdx +1 -1
  153. package/docs/content/meta.mdx +7 -3
  154. package/docs/content/navigation.mdx +29 -4
  155. package/docs/content/sources.mdx +18 -16
  156. package/docs/content/syntax.mdx +14 -0
  157. package/docs/content/versioning.mdx +2 -1
  158. package/docs/discoverability/agent-discovery.mdx +22 -8
  159. package/docs/discoverability/index.mdx +4 -3
  160. package/docs/discoverability/llms-txt.mdx +2 -5
  161. package/docs/discoverability/markdown.mdx +6 -4
  162. package/docs/discoverability/mcp.mdx +4 -0
  163. package/docs/discoverability/metadata.mdx +3 -2
  164. package/docs/discoverability/open-graph.mdx +8 -4
  165. package/docs/discoverability/rss.mdx +4 -2
  166. package/docs/references/asyncapi.mdx +2 -2
  167. package/docs/references/graphql.mdx +2 -2
  168. package/docs/references/openapi.mdx +6 -4
  169. package/package.json +1 -1
  170. package/skills/blume-migrate/SKILL.md +6 -6
  171. package/skills/blume-migrate/references/docusaurus.md +6 -6
  172. package/skills/blume-migrate/references/fumadocs.md +1 -1
  173. package/skills/blume-migrate/references/mintlify.md +3 -3
  174. package/skills/blume-migrate/references/monorepo.md +1 -1
  175. package/skills/blume-migrate/references/nextra.md +2 -2
  176. package/skills/blume-migrate/references/starlight.md +5 -5
  177. package/skills/blume-migrate/scripts/mintlify-codemod.mjs +9 -4
  178. package/skills/blume-update-docs/references/audit-checklist.md +1 -1
  179. package/src/ai/agent-readability.ts +2 -2
  180. package/src/ai/agent-surface.ts +56 -0
  181. package/src/ai/ai-catalog.ts +6 -2
  182. package/src/ai/api/handlers.ts +2 -2
  183. package/src/ai/api/spec.ts +17 -4
  184. package/src/ai/api-catalog.ts +13 -3
  185. package/src/ai/ask-context.ts +14 -2
  186. package/src/ai/ask-data.ts +26 -12
  187. package/src/ai/changelog-markdown.ts +2 -2
  188. package/src/ai/component-markdown.ts +43 -37
  189. package/src/ai/link-headers.ts +22 -8
  190. package/src/ai/llms.ts +22 -10
  191. package/src/ai/markdown.ts +23 -11
  192. package/src/ai/mcp/discovery.ts +2 -2
  193. package/src/ai/mcp/query.ts +2 -2
  194. package/src/ai/mcp/server.ts +80 -9
  195. package/src/ai/openapi-components.ts +22 -6
  196. package/src/ai/relative-links.ts +99 -15
  197. package/src/ai/serializers.ts +2 -1
  198. package/src/ai/skills.ts +14 -1
  199. package/src/ai/static-expression.ts +416 -0
  200. package/src/ai/tar.ts +139 -12
  201. package/src/ai/visibility.ts +45 -14
  202. package/src/analytics/databuddy.ts +67 -0
  203. package/src/analytics/head.ts +8 -0
  204. package/src/analytics/index.ts +7 -0
  205. package/src/analytics/one-dollar-stats.ts +86 -0
  206. package/src/analytics/posthog.ts +21 -3
  207. package/src/analytics/schema.ts +4 -0
  208. package/src/astro/generate.ts +72 -28
  209. package/src/astro/include-hmr.ts +31 -12
  210. package/src/astro/include-refresh.ts +19 -8
  211. package/src/astro/integration.ts +108 -14
  212. package/src/astro/runtime-modules.ts +28 -13
  213. package/src/astro/templates.ts +139 -57
  214. package/src/audit/catalog.ts +2 -2
  215. package/src/audit/checks/assets.ts +25 -5
  216. package/src/audit/checks/content.ts +20 -2
  217. package/src/audit/checks/i18n.ts +46 -8
  218. package/src/audit/checks/indexability.ts +39 -19
  219. package/src/audit/checks/links.ts +22 -1
  220. package/src/audit/checks/llms.ts +6 -3
  221. package/src/audit/checks/network.ts +3 -1
  222. package/src/audit/checks/og-image.ts +10 -0
  223. package/src/audit/checks/robots.ts +6 -1
  224. package/src/audit/checks/sitemap.ts +56 -31
  225. package/src/audit/checks/social.ts +21 -2
  226. package/src/audit/crawl.ts +88 -15
  227. package/src/audit/graph.ts +3 -1
  228. package/src/audit/report.ts +54 -17
  229. package/src/audit/run.ts +13 -9
  230. package/src/audit/snapshot.ts +5 -0
  231. package/src/audit/types.ts +18 -0
  232. package/src/audit/url.ts +37 -6
  233. package/src/cli/args.ts +32 -0
  234. package/src/cli/build-failure.ts +50 -0
  235. package/src/cli/commands/audit.ts +11 -1
  236. package/src/cli/commands/build.ts +19 -5
  237. package/src/cli/commands/check.ts +2 -0
  238. package/src/cli/commands/doctor.ts +3 -1
  239. package/src/cli/commands/eval.ts +20 -18
  240. package/src/cli/commands/init.ts +15 -5
  241. package/src/cli/commands/preview.ts +15 -0
  242. package/src/cli/commands/sync.ts +2 -0
  243. package/src/cli/commands/translate.ts +18 -18
  244. package/src/cli/commands/upgrade.ts +11 -0
  245. package/src/cli/commands/validate.ts +3 -1
  246. package/src/cli/dev-lock.ts +157 -37
  247. package/src/cli/eject-scripts.ts +32 -7
  248. package/src/cli/env.ts +12 -1
  249. package/src/cli/init/scaffold.ts +117 -11
  250. package/src/cli/init/starter-spec.ts +235 -0
  251. package/src/cli/report-format.ts +11 -6
  252. package/src/components/colors.ts +19 -0
  253. package/src/components/content/AccordionItem.astro +26 -22
  254. package/src/components/content/Badge.astro +7 -12
  255. package/src/components/content/Card.astro +2 -2
  256. package/src/components/content/Component.astro +11 -5
  257. package/src/components/content/Expandable.astro +5 -1
  258. package/src/components/content/Frame.astro +2 -7
  259. package/src/components/content/GithubInfo.astro +12 -2
  260. package/src/components/content/Prompt.astro +2 -7
  261. package/src/components/content/Tab.astro +0 -1
  262. package/src/components/content/Tabs.astro +58 -5
  263. package/src/components/content/Tile.astro +1 -1
  264. package/src/components/content/Tooltip.astro +69 -7
  265. package/src/components/content/Tree.astro +7 -2
  266. package/src/components/content/TypeTable.astro +10 -5
  267. package/src/components/content/Update.astro +8 -2
  268. package/src/components/content/auto-type-table.ts +4 -1
  269. package/src/components/content/badge-color.ts +20 -0
  270. package/src/components/content/base-href.ts +14 -22
  271. package/src/components/content/inline-markdown.ts +27 -7
  272. package/src/components/copy-feedback.ts +35 -8
  273. package/src/components/islands/assistant.tsx +37 -6
  274. package/src/components/islands/base-path.ts +47 -10
  275. package/src/components/islands/hooks.ts +42 -21
  276. package/src/components/islands/webmcp.ts +16 -10
  277. package/src/components/layout/Banner.astro +23 -4
  278. package/src/components/layout/Breadcrumbs.astro +5 -2
  279. package/src/components/layout/DiscoveryLinks.astro +9 -5
  280. package/src/components/layout/Header.astro +23 -10
  281. package/src/components/layout/LanguageSwitcher.astro +2 -2
  282. package/src/components/layout/Logo.astro +5 -0
  283. package/src/components/layout/NavSelector.astro +8 -3
  284. package/src/components/layout/NavTabMenu.astro +133 -0
  285. package/src/components/layout/NavTree.astro +31 -12
  286. package/src/components/layout/NavTreeCache.astro +5 -2
  287. package/src/components/layout/NavTreeScript.astro +45 -5
  288. package/src/components/layout/PageActions.astro +4 -3
  289. package/src/components/layout/PageLayout.astro +28 -13
  290. package/src/components/layout/Pagination.astro +3 -3
  291. package/src/components/layout/ReferenceLayout.astro +4 -1
  292. package/src/components/layout/RootLayout.astro +25 -12
  293. package/src/components/layout/Search.astro +38 -14
  294. package/src/components/layout/VersionBanner.astro +2 -2
  295. package/src/components/layout/analytics-client.ts +14 -0
  296. package/src/components/layout/toc-active.ts +41 -0
  297. package/src/components/layout/toc-element.ts +8 -14
  298. package/src/components/openapi/ApiTagOperations.astro +2 -2
  299. package/src/components/openapi/AsyncApiOperation.astro +7 -4
  300. package/src/components/openapi/GraphqlChip.astro +2 -2
  301. package/src/components/openapi/GraphqlType.astro +11 -3
  302. package/src/components/openapi/MessageComposer.astro +1 -1
  303. package/src/components/openapi/Operation.astro +23 -5
  304. package/src/components/openapi/PanelTabs.astro +4 -1
  305. package/src/components/openapi/Playground.astro +8 -2
  306. package/src/components/openapi/RequestPanel.astro +13 -6
  307. package/src/components/openapi/SchemaProperty.astro +11 -33
  308. package/src/components/openapi/SchemaTable.astro +34 -52
  309. package/src/components/openapi/async.ts +38 -6
  310. package/src/components/openapi/helpers.ts +100 -12
  311. package/src/components/openapi/message-composer.ts +14 -1
  312. package/src/components/openapi/message-model.ts +12 -2
  313. package/src/components/openapi/message.ts +21 -3
  314. package/src/components/openapi/operation-model.ts +119 -17
  315. package/src/components/openapi/panel.ts +31 -5
  316. package/src/components/openapi/param-style.ts +181 -0
  317. package/src/components/openapi/playground-client.ts +110 -23
  318. package/src/components/openapi/playground-schema.ts +25 -6
  319. package/src/components/openapi/request.ts +192 -26
  320. package/src/components/openapi/schema-tree.ts +209 -0
  321. package/src/components/openapi/snippets.ts +113 -19
  322. package/src/components/openapi/validate-json.ts +1 -1
  323. package/src/components/openapi/ws-client.ts +18 -2
  324. package/src/core/base-path.ts +69 -8
  325. package/src/core/config-input.ts +13 -11
  326. package/src/core/config.ts +18 -4
  327. package/src/core/diagnostics.ts +219 -30
  328. package/src/core/directive-diagnostics.ts +99 -0
  329. package/src/core/frontmatter.ts +21 -18
  330. package/src/core/graph.ts +120 -11
  331. package/src/core/heading-markers.ts +5 -18
  332. package/src/core/i18n-ui.ts +39 -2
  333. package/src/core/i18n.ts +44 -5
  334. package/src/core/last-modified.ts +25 -3
  335. package/src/core/links.ts +7 -4
  336. package/src/core/load-module.ts +20 -0
  337. package/src/core/locale-links.ts +22 -18
  338. package/src/core/manifest.ts +3 -2
  339. package/src/core/meta.ts +89 -12
  340. package/src/core/nav-diagnostics.ts +56 -1
  341. package/src/core/navigation.ts +272 -83
  342. package/src/core/ordering-prefix.ts +27 -0
  343. package/src/core/project-graph.ts +50 -6
  344. package/src/core/safe-href.ts +53 -1
  345. package/src/core/safe-links.ts +11 -2
  346. package/src/core/schema.ts +94 -18
  347. package/src/core/sources/assets.ts +83 -41
  348. package/src/core/sources/contentful-rich-text.ts +28 -20
  349. package/src/core/sources/contentful.ts +25 -12
  350. package/src/core/sources/filesystem.ts +25 -3
  351. package/src/core/sources/github-releases.ts +131 -11
  352. package/src/core/sources/lexical.ts +30 -20
  353. package/src/core/sources/lower.ts +276 -56
  354. package/src/core/sources/mdx-remote.ts +52 -16
  355. package/src/core/sources/normalize.ts +456 -119
  356. package/src/core/sources/notion.ts +77 -34
  357. package/src/core/sources/obsidian.ts +40 -9
  358. package/src/core/sources/payload.ts +1 -0
  359. package/src/core/sources/portable-text.ts +85 -49
  360. package/src/core/sources/remote.ts +18 -2
  361. package/src/core/sources/resolve.ts +52 -33
  362. package/src/core/sources/sanity.ts +1 -0
  363. package/src/core/sources/strapi-blocks.ts +28 -19
  364. package/src/core/sources/strapi.ts +1 -0
  365. package/src/core/sources/types.ts +31 -0
  366. package/src/core/sources/watch.ts +20 -7
  367. package/src/core/standard-schema.ts +10 -6
  368. package/src/core/types.ts +9 -0
  369. package/src/core/ui-packs/ar.ts +13 -0
  370. package/src/core/ui-packs/bg.ts +13 -0
  371. package/src/core/ui-packs/bn.ts +13 -0
  372. package/src/core/ui-packs/ca.ts +13 -0
  373. package/src/core/ui-packs/cs.ts +13 -0
  374. package/src/core/ui-packs/da.ts +13 -0
  375. package/src/core/ui-packs/de.ts +13 -0
  376. package/src/core/ui-packs/el.ts +13 -0
  377. package/src/core/ui-packs/es.ts +13 -0
  378. package/src/core/ui-packs/fa.ts +13 -0
  379. package/src/core/ui-packs/fi.ts +13 -0
  380. package/src/core/ui-packs/fr.ts +13 -0
  381. package/src/core/ui-packs/he.ts +13 -0
  382. package/src/core/ui-packs/hi.ts +13 -0
  383. package/src/core/ui-packs/hr.ts +13 -0
  384. package/src/core/ui-packs/hu.ts +13 -0
  385. package/src/core/ui-packs/id.ts +13 -0
  386. package/src/core/ui-packs/it.ts +13 -0
  387. package/src/core/ui-packs/ja.ts +13 -0
  388. package/src/core/ui-packs/ko.ts +13 -0
  389. package/src/core/ui-packs/nl.ts +13 -0
  390. package/src/core/ui-packs/no.ts +13 -0
  391. package/src/core/ui-packs/pl.ts +13 -0
  392. package/src/core/ui-packs/pt-br.ts +13 -0
  393. package/src/core/ui-packs/pt.ts +13 -0
  394. package/src/core/ui-packs/ro.ts +13 -0
  395. package/src/core/ui-packs/ru.ts +13 -0
  396. package/src/core/ui-packs/sk.ts +13 -0
  397. package/src/core/ui-packs/sr.ts +13 -0
  398. package/src/core/ui-packs/sv.ts +13 -0
  399. package/src/core/ui-packs/th.ts +13 -0
  400. package/src/core/ui-packs/tr.ts +13 -0
  401. package/src/core/ui-packs/uk.ts +13 -0
  402. package/src/core/ui-packs/vi.ts +13 -0
  403. package/src/core/ui-packs/zh-tw.ts +13 -0
  404. package/src/core/ui-packs/zh.ts +13 -0
  405. package/src/core/version-cut.ts +69 -17
  406. package/src/core/versions.ts +4 -1
  407. package/src/deploy/adapters/node.ts +5 -2
  408. package/src/deploy/adapters/registry.ts +2 -1
  409. package/src/deploy/adapters/types.ts +13 -1
  410. package/src/deploy/artifacts.ts +52 -11
  411. package/src/deploy/cloudflare-negotiation.ts +27 -16
  412. package/src/deploy/headers.ts +75 -55
  413. package/src/deploy/node-headers.ts +148 -27
  414. package/src/deploy/platforms/cloudflare.ts +13 -3
  415. package/src/deploy/platforms/netlify.ts +83 -5
  416. package/src/deploy/platforms/node.ts +8 -5
  417. package/src/deploy/platforms/static.ts +2 -0
  418. package/src/deploy/platforms/types.ts +15 -0
  419. package/src/deploy/platforms/vercel.ts +10 -3
  420. package/src/deploy/redirects.ts +68 -21
  421. package/src/deploy/robots.ts +2 -2
  422. package/src/deploy/rss.ts +4 -3
  423. package/src/deploy/sitemap.ts +7 -5
  424. package/src/deploy/vercel-negotiation.ts +35 -3
  425. package/src/eval/agents.ts +10 -2
  426. package/src/eval/run.ts +25 -0
  427. package/src/markdown/base-links.ts +74 -29
  428. package/src/markdown/directives.ts +242 -36
  429. package/src/markdown/features.ts +17 -0
  430. package/src/markdown/index.ts +13 -9
  431. package/src/markdown/mdast.ts +5 -2
  432. package/src/markdown/relative-links.ts +15 -27
  433. package/src/markdown/route-snapshot.ts +37 -0
  434. package/src/og/card.ts +149 -9
  435. package/src/og/derive.ts +156 -5
  436. package/src/og/index.ts +1 -0
  437. package/src/openapi/asyncapi.ts +4 -2
  438. package/src/openapi/graphql-build.ts +28 -2
  439. package/src/openapi/model.ts +99 -27
  440. package/src/openapi/proxy.ts +63 -10
  441. package/src/openapi/render-mdx.ts +51 -3
  442. package/src/registry/eject.ts +297 -43
  443. package/src/search/adapters/version-scope.ts +30 -0
  444. package/src/search/documents.ts +89 -27
  445. package/src/search/popular.ts +2 -1
  446. package/src/search/sync/algolia.ts +36 -2
  447. package/src/seo/jsonld.ts +7 -3
  448. package/src/sources/registry.ts +5 -0
  449. package/src/theme/entry.ts +11 -4
  450. package/src/translate/agents.ts +6 -1
  451. package/src/translate/ledger.ts +26 -3
  452. package/src/translate/meta.ts +76 -24
  453. package/src/translate/run.ts +14 -8
  454. package/src/translate/validate.ts +14 -2
  455. package/src/translate/work-list.ts +91 -19
  456. package/src/upgrade/upgrade.ts +36 -4
  457. package/dist/cli/chunk-27g6wdth.js.map +0 -10
  458. package/dist/cli/chunk-2hn4b8z7.js.map +0 -12
  459. package/dist/cli/chunk-6crbhc3x.js.map +0 -14
  460. package/dist/cli/chunk-6hsn950k.js.map +0 -10
  461. package/dist/cli/chunk-79jhk4py.js.map +0 -35
  462. package/dist/cli/chunk-82bbrxdn.js +0 -51
  463. package/dist/cli/chunk-82bbrxdn.js.map +0 -10
  464. package/dist/cli/chunk-abh8yjkn.js +0 -31
  465. package/dist/cli/chunk-abh8yjkn.js.map +0 -10
  466. package/dist/cli/chunk-ce574jw2.js +0 -23
  467. package/dist/cli/chunk-ce574jw2.js.map +0 -10
  468. package/dist/cli/chunk-dh8cwk36.js.map +0 -10
  469. package/dist/cli/chunk-epjnccmv.js.map +0 -10
  470. package/dist/cli/chunk-fa25z98p.js.map +0 -11
  471. package/dist/cli/chunk-fs23ddbb.js.map +0 -35
  472. package/dist/cli/chunk-fz5wtpmh.js.map +0 -10
  473. package/dist/cli/chunk-jwyddg7y.js.map +0 -15
  474. package/dist/cli/chunk-kpf8rrjc.js.map +0 -19
  475. package/dist/cli/chunk-m3vmjgmq.js.map +0 -10
  476. package/dist/cli/chunk-mb2919y2.js.map +0 -10
  477. package/dist/cli/chunk-q5163e60.js.map +0 -11
  478. package/dist/cli/chunk-qkqwkpte.js.map +0 -182
  479. package/dist/cli/chunk-qs4q5p4e.js.map +0 -10
  480. package/dist/cli/chunk-s1p84fyh.js.map +0 -10
  481. package/dist/cli/chunk-wgm7m9qk.js.map +0 -36
  482. package/dist/cli/chunk-yt5n7ppj.js.map +0 -10
  483. package/dist/cli/chunk-yw7dm696.js.map +0 -14
  484. /package/dist/cli/{chunk-s6jhgk0q.js.map → chunk-2eytanqx.js.map} +0 -0
  485. /package/dist/cli/{chunk-hdpx1tax.js.map → chunk-2z928egk.js.map} +0 -0
  486. /package/dist/cli/{chunk-ah61y8py.js.map → chunk-364znk6q.js.map} +0 -0
  487. /package/dist/cli/{chunk-vtk4a6dg.js.map → chunk-8ktnccpt.js.map} +0 -0
  488. /package/dist/cli/{chunk-fxypxtvm.js.map → chunk-a58773jm.js.map} +0 -0
  489. /package/dist/cli/{chunk-wm7js3j9.js.map → chunk-b07cmahc.js.map} +0 -0
  490. /package/dist/cli/{chunk-zxcczpyx.js.map → chunk-r20tn01b.js.map} +0 -0
  491. /package/dist/cli/{chunk-5shv93fd.js.map → chunk-tkacnehg.js.map} +0 -0
  492. /package/dist/cli/{chunk-zxh4d9vy.js.map → chunk-tzmab476.js.map} +0 -0
@@ -1,8 +1,4 @@
1
1
  #!/usr/bin/env node
2
- import {
3
- trimChar,
4
- normalizeBasePath
5
- } from "./chunk-jts8mvcz.js";
6
2
  import {
7
3
  buildHomeLinkHeader,
8
4
  resolveDocsCollection,
@@ -10,18 +6,61 @@ import {
10
6
  deployPassthrough,
11
7
  fontLocaleCodes,
12
8
  buildFontEntries,
9
+ SVG_ASSET_HEADERS,
13
10
  applyBaseToAstroRedirects,
14
11
  distDir,
15
12
  adapterRoot,
16
- SVG_ASSET_POLICY,
17
- deployPlatform
18
- } from "./chunk-qkqwkpte.js";
19
- import {
13
+ deployPlatform,
20
14
  BLUME_IGNORE_DIRS
21
- } from "./chunk-abh8yjkn.js";
15
+ } from "./chunk-pv29h0wf.js";
16
+ import {
17
+ trimChar,
18
+ normalizeBasePath
19
+ } from "./chunk-3em5wd2y.js";
20
+
21
+ // src/deploy/adapter-output.ts
22
+ import { existsSync } from "node:fs";
23
+ import { cp, mkdir, rm } from "node:fs/promises";
24
+ import { dirname, join } from "pathe";
25
+ var deployOutputDir = (config, context) => {
26
+ const { deployment } = config;
27
+ return deployment.options.output === "server" ? deployPlatform(deployment).serverOutputDir(context) : distDir(context);
28
+ };
29
+ var deployStaticDir = (config, context) => {
30
+ const { deployment } = config;
31
+ return deployment.options.output === "server" ? deployPlatform(deployment).serverStaticDir(context) : distDir(context);
32
+ };
33
+ var surfaceAdapterOutput = async (config, context) => {
34
+ const { deployment } = config;
35
+ if (deployment.options.output !== "server") {
36
+ return { moved: false };
37
+ }
38
+ const rel = deployPlatform(deployment).hiddenRuntime.surfacePath;
39
+ if (!rel) {
40
+ return { moved: false };
41
+ }
42
+ const from = join(context.outDir, rel);
43
+ const to = join(context.root, rel);
44
+ if (!existsSync(from)) {
45
+ return { moved: false };
46
+ }
47
+ await mkdir(dirname(to), { recursive: true });
48
+ await rm(to, { force: true, recursive: true });
49
+ try {
50
+ await cp(from, to, { recursive: true, verbatimSymlinks: true });
51
+ } catch (error) {
52
+ if (error.code !== "EPERM") {
53
+ throw error;
54
+ }
55
+ await rm(to, { force: true, recursive: true });
56
+ await cp(from, to, { dereference: true, recursive: true });
57
+ }
58
+ await rm(from, { force: true, recursive: true });
59
+ return { from, moved: true, to };
60
+ };
22
61
 
23
62
  // src/astro/component-slots.ts
24
- import { isAbsolute, join, relative } from "pathe";
63
+ import { isAbsolute, join as join2, relative } from "pathe";
25
64
  var attributeValue = (value) => value.replaceAll(/["\n\r]/gu, " ").trim();
26
65
  var CLIENT_LOAD = "client:load";
27
66
  var directiveFor = (override) => {
@@ -77,7 +116,7 @@ var islandOverride = (island) => ({
77
116
  var record = (entries) => entries.length ? `{ ${entries.join(", ")} }` : "{}";
78
117
  var planComponentSlots = (islands, analysis, options = {}) => {
79
118
  const { relativeTo } = options;
80
- const wrapperDir = relativeTo === undefined ? undefined : join(relativeTo, "component-slots");
119
+ const wrapperDir = relativeTo === undefined ? undefined : join2(relativeTo, "component-slots");
81
120
  const frameworks = new Set;
82
121
  const wrappers = [];
83
122
  const importLines = [];
@@ -156,10 +195,12 @@ var publishRuntimeModules = (modules) => {
156
195
  return changed;
157
196
  }
158
197
  for (const server of servers) {
159
- for (const id of changed) {
160
- const mod = server.moduleGraph.getModuleById(`${RESOLVED_PREFIX}${id}`);
161
- if (mod) {
162
- server.moduleGraph.invalidateModule(mod);
198
+ for (const { moduleGraph } of Object.values(server.environments)) {
199
+ for (const id of changed) {
200
+ const mod = moduleGraph.getModuleById(`${RESOLVED_PREFIX}${id}`);
201
+ if (mod) {
202
+ moduleGraph.invalidateModule(mod);
203
+ }
163
204
  }
164
205
  }
165
206
  server.ws.send({ type: "full-reload" });
@@ -168,9 +209,9 @@ var publishRuntimeModules = (modules) => {
168
209
  };
169
210
 
170
211
  // src/astro/templates.ts
171
- import { existsSync, readFileSync } from "node:fs";
212
+ import { existsSync as existsSync2, readFileSync } from "node:fs";
172
213
  import { pathToFileURL } from "node:url";
173
- import { dirname, isAbsolute as isAbsolute2, join as join2, relative as relative2 } from "pathe";
214
+ import { dirname as dirname2, isAbsolute as isAbsolute2, join as join3, relative as relative2 } from "pathe";
174
215
  var WORKSPACE_MARKERS = [
175
216
  ".git",
176
217
  "bun.lock",
@@ -181,7 +222,7 @@ var WORKSPACE_MARKERS = [
181
222
  "yarn.lock"
182
223
  ];
183
224
  var hasWorkspacesField = (pkgPath) => {
184
- if (!existsSync(pkgPath)) {
225
+ if (!existsSync2(pkgPath)) {
185
226
  return false;
186
227
  }
187
228
  try {
@@ -191,14 +232,14 @@ var hasWorkspacesField = (pkgPath) => {
191
232
  return false;
192
233
  }
193
234
  };
194
- var hasWorkspaceMarker = (dir) => hasWorkspacesField(join2(dir, "package.json")) || WORKSPACE_MARKERS.some((marker) => existsSync(join2(dir, marker)));
235
+ var hasWorkspaceMarker = (dir) => hasWorkspacesField(join3(dir, "package.json")) || WORKSPACE_MARKERS.some((marker) => existsSync2(join3(dir, marker)));
195
236
  var findWorkspaceRoot = (start) => {
196
237
  let dir = start;
197
238
  for (;; ) {
198
239
  if (hasWorkspaceMarker(dir)) {
199
240
  return dir;
200
241
  }
201
- const parent = dirname(dir);
242
+ const parent = dirname2(dir);
202
243
  if (parent === dir) {
203
244
  return start;
204
245
  }
@@ -317,8 +358,16 @@ const blumeConfig = await loadBlumeConfig(resolve(dirname(fileURLToPath(import.m
317
358
  var renderImageOption = (config) => config.image.domains.length > 0 || config.image.remotePatterns.length > 0 ? `
318
359
  image: ${JSON.stringify(config.image)},` : "";
319
360
  var ALL_CLIENT_FEATURES = { epub: true, mermaid: true };
361
+ var SEARCH_CLIENT_DEPS = {
362
+ algolia: "algoliasearch/lite",
363
+ flexsearch: "flexsearch",
364
+ orama: "@orama/orama",
365
+ "orama-cloud": "@oramacloud/client",
366
+ typesense: "typesense"
367
+ };
320
368
  var resolveOptimizeDeps = (options) => {
321
369
  const { context, features } = options;
370
+ const searchDep = SEARCH_CLIENT_DEPS[options.searchKind];
322
371
  const optimizeDepsEntries = [
323
372
  ...context.pagesRoot ? [`${context.pagesRoot}/**/*.astro`] : [],
324
373
  `${context.root}/islands/**/*.{jsx,svelte,tsx,vue}`,
@@ -327,6 +376,7 @@ var resolveOptimizeDeps = (options) => {
327
376
  const optimizeDepsInclude = [
328
377
  ...features.mermaid ? ["blume > mermaid"] : [],
329
378
  ...features.epub ? ["blume > epub-gen-memory/bundle"] : [],
379
+ ...searchDep ? [`blume > ${searchDep}`] : [],
330
380
  ...options.needsReact && options.reactCompilerPath ? ["react/compiler-runtime"] : []
331
381
  ];
332
382
  return { optimizeDepsEntries, optimizeDepsInclude };
@@ -357,7 +407,7 @@ var renderRuntimeModuleWiring = (generatedModulesDir) => {
357
407
  var blumeIntegrationOptions = (options) => options.ejected ? {
358
408
  buildArtifactsRoot: ".",
359
409
  contentRoutes: options.contentRoutes,
360
- homeLinkHeader: buildHomeLinkHeader(options.config, options.contentRoutes) ?? undefined,
410
+ homeLinkHeader: buildHomeLinkHeader(options.config, options.contentRoutes, "dev") ?? undefined,
361
411
  pages: options.pages
362
412
  } : { pages: options.pages };
363
413
  var astroConfigTemplate = (options) => {
@@ -389,7 +439,8 @@ var astroConfigTemplate = (options) => {
389
439
  context,
390
440
  features,
391
441
  needsReact,
392
- reactCompilerPath: options.reactCompilerPath
442
+ reactCompilerPath: options.reactCompilerPath,
443
+ searchKind: config.search.provider.kind
393
444
  });
394
445
  const {
395
446
  configEntries: adapterConfigEntries,
@@ -409,7 +460,7 @@ var astroConfigTemplate = (options) => {
409
460
  prefixDefaultLocale: !config.i18n.hideDefaultLocalePrefix
410
461
  }
411
462
  })},` : "";
412
- const basedRedirects = applyBaseToAstroRedirects(config.redirects, config.basePath, deployment.options.base ?? "");
463
+ const basedRedirects = applyBaseToAstroRedirects(config.redirects, config.basePath, deployment.options.base ?? "", new Set(contentRoutes));
413
464
  const redirectsOption = basedRedirects.length > 0 ? `
414
465
  redirects: ${JSON.stringify(Object.fromEntries(basedRedirects.map((redirect) => [
415
466
  redirect.from,
@@ -428,7 +479,7 @@ var astroConfigTemplate = (options) => {
428
479
  return {
429
480
  ...face,
430
481
  src: [
431
- isAbsolute2(variant.src) ? variant.src : join2(context.root, variant.src)
482
+ isAbsolute2(variant.src) ? variant.src : join3(context.root, variant.src)
432
483
  ]
433
484
  };
434
485
  }))} } }` : `{ provider: fontProviders.${font.provider}(), name: ${JSON.stringify(font.name)}, cssVariable: ${JSON.stringify(font.cssVariable)}, weights: ${astroFontWeights(font.weights)}, subsets: ${JSON.stringify(font.subsets)}, fallbacks: ${JSON.stringify(font.fallbacks)} }`).join(", ")}],` : "";
@@ -562,6 +613,10 @@ ${userConfigSetup}export default defineConfig({
562
613
  // \`/bundle\` subpath that is actually imported: optimizing the package
563
614
  // root leaves that entry out. Production (Rollup) already handles the
564
615
  // interop, so all of this only affects dev.
616
+ //
617
+ // The search adapter's client library rides the list for the same reason
618
+ // as the compiler runtime: the search dialog lazy-imports it on first
619
+ // open, and discovering it then re-optimizes and reloads the page.
565
620
  optimizeDeps: {
566
621
  entries: ${JSON.stringify(optimizeDepsEntries)},
567
622
  include: ${JSON.stringify(optimizeDepsInclude)},
@@ -601,7 +656,7 @@ ${userConfigSetup}export default defineConfig({
601
656
  });
602
657
  `;
603
658
  };
604
- var stagedContentDir = (outDir) => join2(outDir, "content");
659
+ var stagedContentDir = (outDir) => join3(outDir, "content");
605
660
  var runtimeDirWithin = (base, outDir) => {
606
661
  const rel = relative2(base, outDir);
607
662
  return rel && !rel.startsWith("..") && !isAbsolute2(rel) ? rel : null;
@@ -753,6 +808,7 @@ const ground = createAskContext(askData${groundOptions});
753
808
  ${streamFields.join(`,
754
809
  `)},
755
810
  ${onError}
811
+ abortSignal: request.signal,
756
812
  });`;
757
813
  const stream = grounded ? ` const instructions =
758
814
  (await ground(messages, body.page)) ??
@@ -834,9 +890,9 @@ var featuresTemplate = (features) => `// Generated by Blume. Do not edit.
834
890
  export const loadMermaid: (() => Promise<unknown>) | null = ${features.mermaid ? '() => import("blume/components/content/mermaid-element.ts")' : "null"};
835
891
 
836
892
  /** The EPUB generator's browser bundle; null when export.epub is off. */
837
- export const loadEpub:
893
+ ${features.epub ? `export const loadEpub:
838
894
  | (() => Promise<typeof import("epub-gen-memory/bundle")>)
839
- | null = ${features.epub ? '() => import("epub-gen-memory/bundle")' : "null"};
895
+ | null = () => import("epub-gen-memory/bundle");` : "export const loadEpub: (() => Promise<unknown>) | null = null;"}
840
896
  `;
841
897
  var searchClientTemplate = (config) => {
842
898
  const { provider } = config.search;
@@ -973,18 +1029,29 @@ const TYPES: Record<string, string> = {
973
1029
  ".ico": "image/x-icon",
974
1030
  ".jpeg": "image/jpeg",
975
1031
  ".jpg": "image/jpeg",
1032
+ ".mov": "video/quicktime",
1033
+ ".mp4": "video/mp4",
1034
+ ".ogv": "video/ogg",
976
1035
  ".png": "image/png",
977
1036
  ".svg": "image/svg+xml",
978
1037
  ".tiff": "image/tiff",
1038
+ ".webm": "video/webm",
979
1039
  ".webp": "image/webp",
980
1040
  };
981
1041
 
1042
+ const extensionOf = (path: string): string =>
1043
+ path.slice(path.lastIndexOf(".")).toLowerCase();
1044
+
982
1045
  const contentType = (path: string): string =>
983
- TYPES[path.slice(path.lastIndexOf(".")).toLowerCase()] ??
984
- "application/octet-stream";
1046
+ TYPES[extensionOf(path)] ?? "application/octet-stream";
1047
+
1048
+ // A source downloads only images and videos; anything else in the staged
1049
+ // directory (a page an older build saved under its URL's extension) is never
1050
+ // published from the docs origin.
1051
+ const isMedia = (path: string): boolean => Object.hasOwn(TYPES, extensionOf(path));
985
1052
 
986
1053
  const stagedParams = async (): Promise<string[]> => {
987
- if (!existsSync(STAGED_DIR)) {
1054
+ if (STAGED_DIR === null || !existsSync(STAGED_DIR)) {
988
1055
  return [];
989
1056
  }
990
1057
  const entries = await readdir(STAGED_DIR, {
@@ -992,7 +1059,7 @@ const stagedParams = async (): Promise<string[]> => {
992
1059
  withFileTypes: true,
993
1060
  });
994
1061
  return entries
995
- .filter((entry) => entry.isFile())
1062
+ .filter((entry) => entry.isFile() && isMedia(entry.name))
996
1063
  .map((entry) =>
997
1064
  relative(STAGED_DIR, join(entry.parentPath, entry.name)).replaceAll(
998
1065
  "\\\\",
@@ -1013,6 +1080,9 @@ const resolveAsset = (asset: string): string | null => {
1013
1080
  if (asset.startsWith("content/")) {
1014
1081
  return files[asset.slice("content/".length)] ?? null;
1015
1082
  }
1083
+ if (STAGED_DIR === null) {
1084
+ return null;
1085
+ }
1016
1086
  const abs = resolve(STAGED_DIR, asset);
1017
1087
  // Traversal guard: the dev server renders on demand, so the param is
1018
1088
  // attacker-controlled there — never step outside the staged directory.
@@ -1022,7 +1092,7 @@ const resolveAsset = (asset: string): string | null => {
1022
1092
  // asset — and a bare prefix also admits a sibling directory that merely
1023
1093
  // shares the name.
1024
1094
  const rel = relative(STAGED_DIR, abs);
1025
- if (rel === "" || rel.startsWith("..") || isAbsolute(rel)) {
1095
+ if (rel === "" || rel.startsWith("..") || isAbsolute(rel) || !isMedia(rel)) {
1026
1096
  return null;
1027
1097
  }
1028
1098
  return existsSync(abs) ? abs : null;
@@ -1036,11 +1106,12 @@ export const GET: APIRoute = async ({ params }) => {
1036
1106
  const body = await readFile(path);
1037
1107
  const type = contentType(path);
1038
1108
  // An SVG opened directly is a document that can run script; the sandbox
1039
- // keeps an uploaded one inert on the docs origin. Static hosts get the same
1040
- // header from the build's header rules.
1109
+ // keeps an uploaded one inert on the docs origin. This endpoint
1110
+ // prerenders, so these headers reach dev only: a build serves the files
1111
+ // with the same headers from its host's rules (see deploy/headers.ts).
1041
1112
  const headers: Record<string, string> =
1042
1113
  type === "image/svg+xml"
1043
- ? { "Content-Security-Policy": ${JSON.stringify(SVG_ASSET_POLICY)}, "Content-Type": type }
1114
+ ? { ...${JSON.stringify(SVG_ASSET_HEADERS)}, "Content-Type": type }
1044
1115
  : { "Content-Type": type };
1045
1116
  return new Response(new Uint8Array(body), { headers });
1046
1117
  };
@@ -1100,7 +1171,7 @@ export function GET({ props }: { props: { section: string } }) {
1100
1171
  var navFragmentTemplate = () => `---
1101
1172
  // Generated by Blume. Do not edit.
1102
1173
  import NavTree from "blume/components/layout/NavTree.astro";
1103
- import { withBase } from "blume/components/islands/base-path.ts";
1174
+ import { withMountedBase } from "blume/components/islands/base-path.ts";
1104
1175
  import {
1105
1176
  hiddenDefaultLocale,
1106
1177
  navGroupIds,
@@ -1139,7 +1210,7 @@ if (!(variant && node && node.kind === "group")) {
1139
1210
  }
1140
1211
  const strings =
1141
1212
  locale === "default" ? data.ui.nav : (data.uiByLocale[locale] ?? data.ui).nav;
1142
- const fragmentBase = withBase(\`/blume-nav/\${version}/\${locale}\`);
1213
+ const fragmentBase = withMountedBase(\`/blume-nav/\${version}/\${locale}\`);
1143
1214
  ---
1144
1215
 
1145
1216
  <NavTree
@@ -1155,7 +1226,7 @@ const fragmentBase = withBase(\`/blume-nav/\${version}/\${locale}\`);
1155
1226
  `;
1156
1227
  var ogEndpointTemplate = (customRoutes = [], og = {}, includeChangelog = false) => `// Generated by Blume. Do not edit.
1157
1228
  import { cachedOgImage } from "blume/og";
1158
- import type { OgCache, OgFont, OgFontFamilies } from "blume/og";
1229
+ import type { OgCache, OgFont, OgFontFamilies, OgGoogleFont } from "blume/og";
1159
1230
  import data from "blume:data";
1160
1231
 
1161
1232
  export const prerender = true;
@@ -1171,6 +1242,9 @@ const customRoutes: { slug: string; title: string }[] = ${JSON.stringify(customR
1171
1242
  // data that pages serialize into HTML.
1172
1243
  const fonts: OgFont[] = ${JSON.stringify(og.fonts ?? [])};
1173
1244
  const families: OgFontFamilies | undefined = ${og.families ? JSON.stringify(og.families) : "undefined"};
1245
+ // Script fallbacks (Noto families, the configured locales' first). A card
1246
+ // fetches them only when its text has a glyph Takumi's built-in font lacks.
1247
+ const fallbacks: OgGoogleFont[] = ${JSON.stringify(og.fallbacks ?? [])};
1174
1248
 
1175
1249
  // Rendered cards are kept on disk between builds, keyed by everything that
1176
1250
  // decides their pixels, so a rebuild renders only the cards whose title,
@@ -1237,6 +1311,7 @@ export async function GET({ props }: { props: CardProps }) {
1237
1311
  accent: data.config.og.palette?.accent ?? data.config.theme.accent.light,
1238
1312
  brand: data.config.title,
1239
1313
  description: props.description ?? data.config.og.description,
1314
+ fallbacks,
1240
1315
  families,
1241
1316
  fonts,
1242
1317
  logo: data.config.og.logo,
@@ -1389,8 +1464,8 @@ var catchAllPageTemplate = (options) => {
1389
1464
  import { getEntry, render } from "astro:content";
1390
1465
  import type { CollectionKey } from "astro:content";
1391
1466
  import RootLayout from "blume/components/layout/RootLayout.astro";
1392
- import { withBase } from "blume/components/islands/base-path.ts";
1393
- import { stripBasePath, withBasePath } from "blume/core/base-path.ts";
1467
+ import { withBase, withMountedBase } from "blume/components/islands/base-path.ts";
1468
+ import { mountBasePath, stripBasePath } from "blume/core/base-path.ts";
1394
1469
  import { resolveSlot } from "blume/components/layout/overrides.ts";
1395
1470
  ${componentImports}
1396
1471
  import data from "blume:data";
@@ -1455,12 +1530,16 @@ const base = data.config.site ? data.config.site.replace(/\\/$/, "") : null;
1455
1530
  const ogPath = data.config.og.enabled
1456
1531
  ? encodeURI(\`/og/\${route === "/" ? "index" : route.slice(1)}.png\`)
1457
1532
  : null;
1458
- const ogRel = seo.image ?? ogPath;
1459
1533
  // Absolute URLs also carry the deployment base (the page is served under it):
1460
1534
  // \`site + base + path\`. Only absolutize root-relative paths: \`seo.image\` may be
1461
- // an external URL, which passes through verbatim (mirrors PageLayout).
1462
- const ogImage =
1463
- ogRel && base && ogRel.startsWith("/") ? \`\${base}\${withBase(ogRel)}\` : ogRel;
1535
+ // an external URL, which passes through verbatim (mirrors PageLayout). An
1536
+ // authored \`seo.image\` keeps a base written by hand; the generated card is
1537
+ // always mounted under it.
1538
+ const absoluteOg = (path: string, based: (path: string) => string) =>
1539
+ base && path.startsWith("/") ? \`\${base}\${based(path)}\` : path;
1540
+ const ogImage = seo.image
1541
+ ? absoluteOg(seo.image, withBase)
1542
+ : ogPath && absoluteOg(ogPath, withMountedBase);
1464
1543
  // Blume's generated card has known dimensions the layout can declare; a user's
1465
1544
  // \`seo.image\` could be any size or format, so it gets none.
1466
1545
  const ogGenerated = !seo.image && Boolean(ogPath);
@@ -1469,7 +1548,7 @@ const ogGenerated = !seo.image && Boolean(ogPath);
1469
1548
  // itself (a guest post crediting its own author) over the configured default.
1470
1549
  const x = { ...data.config.x, ...(seo.x?.creator ? { creator: seo.x.creator } : {}) };
1471
1550
 
1472
- const basedRoute = withBase(route);
1551
+ const basedRoute = withMountedBase(route);
1473
1552
 
1474
1553
  // Locale resolution. With i18n on, pick the active locale's nav + dictionary,
1475
1554
  // build hreflang alternates, and derive the language-switcher targets.
@@ -1517,7 +1596,7 @@ const contentDir = i18n
1517
1596
  : "ltr";
1518
1597
  // The root route keeps its trailing slash (\`https://site/\`) so canonical and
1519
1598
  // hreflang URLs byte-match the sitemap's <loc> for the home page.
1520
- const absolute = (path: string) => base + withBase(path);
1599
+ const absolute = (path: string) => base + withMountedBase(path);
1521
1600
 
1522
1601
  // A fallback page renders the fallback locale's page at this locale's URL, so
1523
1602
  // its canonical names the page it copies, and search engines never rank the
@@ -1562,7 +1641,7 @@ const xDefault = defaultAlt && base ? absolute(defaultAlt.path) : null;
1562
1641
  // carries sits *after* the base (\`/docs/ja/guide\`), while \`localePrefix\` is
1563
1642
  // base-less (\`/ja\`). Stripping and re-adding a locale therefore happen in
1564
1643
  // base-less space, with the base re-applied at the end — the same
1565
- // \`withBasePath(basePath, localizeRoute(...))\` composition the manifest uses to
1644
+ // \`mountBasePath(basePath, localizeRoute(...))\` composition the manifest uses to
1566
1645
  // build every real route. Done in based space, \`stripLocale\` matches nothing
1567
1646
  // and \`localizeRoute\` prepends a second prefix (\`/ja/docs/ja/guide\`). Only a
1568
1647
  // switcher entry for a locale with no real translation reaches this fallback:
@@ -1570,7 +1649,7 @@ const xDefault = defaultAlt && base ? absolute(defaultAlt.path) : null;
1570
1649
  // generated reference (which has no \`alternates\` at all) for every locale
1571
1650
  // but its own.
1572
1651
  const mountLocalized = (logical: string, codeArg: string) =>
1573
- withBasePath(data.config.basePath, localizeRoute(logical, codeArg));
1652
+ mountBasePath(data.config.basePath, localizeRoute(logical, codeArg));
1574
1653
  const logicalRoute = i18n
1575
1654
  ? stripLocale(stripBasePath(data.config.basePath, route), locale)
1576
1655
  : route;
@@ -1599,7 +1678,7 @@ const versionRootFor = (id: string) => {
1599
1678
  const logical = id ? \`/\${id}\` : "/";
1600
1679
  return i18n
1601
1680
  ? mountLocalized(logical, locale)
1602
- : withBasePath(data.config.basePath, logical);
1681
+ : mountBasePath(data.config.basePath, logical);
1603
1682
  };
1604
1683
  const samePageSwitch = versionsConfig
1605
1684
  ? versionsConfig.switcher.redirect === "same-page"
@@ -1697,7 +1776,7 @@ const LayoutComponent = resolveSlot(layoutOverrides.Layout, RootLayout);
1697
1776
  feedback={data.config.feedback}
1698
1777
  exportPdf={${options.exportPdf}}
1699
1778
  exportEpub={${options.exportEpub}}${options.navFragments ? `
1700
- navFragmentBase={withBase(\`/blume-nav/\${version || "current"}/\${i18n && localePrefix(locale) ? locale : "default"}\`)}` : ""}
1779
+ navFragmentBase={withMountedBase(\`/blume-nav/\${version || "current"}/\${i18n && localePrefix(locale) ? locale : "default"}\`)}` : ""}
1701
1780
  openInChat={data.config.openInChat}
1702
1781
  feeds={data.feeds}
1703
1782
  discovery={data.config.discovery}
@@ -1725,7 +1804,7 @@ var changelogIndexTemplate = (options) => {
1725
1804
  // Generated by Blume. Do not edit.
1726
1805
  import { getCollection } from "astro:content";
1727
1806
  import RootLayout from "blume/components/layout/RootLayout.astro";
1728
- import { withBase } from "blume/components/islands/base-path.ts";
1807
+ import { withMountedBase } from "blume/components/islands/base-path.ts";
1729
1808
  import { resolveSlot } from "blume/components/layout/overrides.ts";
1730
1809
  import { resolveDateFormatOptions } from "blume/core/date-format.ts";
1731
1810
  import { layoutOverrides } from "../generated/components.ts";
@@ -1824,7 +1903,7 @@ const items = changelogEntries.map((entry) => {
1824
1903
  return {
1825
1904
  date: date ? formatRowDate(date) : null,
1826
1905
  dateTime: date ? date.toISOString().slice(0, 10) : null,
1827
- href: route ? withBase(route) : null,
1906
+ href: route ? withMountedBase(route) : null,
1828
1907
  id: slugify(label),
1829
1908
  label,
1830
1909
  tag: entry.data.changelog?.category ?? null,
@@ -1860,14 +1939,14 @@ for (const item of items) {
1860
1939
 
1861
1940
  const base = data.config.site ? data.config.site.replace(/\\/$/, "") : null;
1862
1941
  // The canonical URL carries the deployment base (the page is served under it),
1863
- // matching how the catch-all canonicalizes via \`withBase(route)\`.
1864
- const basedRoute = withBase("/changelog");
1942
+ // matching how the catch-all canonicalizes via \`withMountedBase(route)\`.
1943
+ const basedRoute = withMountedBase("/changelog");
1865
1944
  const canonical = base ? base + basedRoute : null;
1866
1945
 
1867
1946
  // The generated OG card for this route (the /og endpoint emits it alongside
1868
1947
  // the content-route cards), absolutized like the catch-all's so crawlers get
1869
1948
  // a full URL when the site is known.
1870
- const ogPath = data.config.og.enabled ? withBase("/og/changelog.png") : null;
1949
+ const ogPath = data.config.og.enabled ? withMountedBase("/og/changelog.png") : null;
1871
1950
  const ogImage = ogPath && base ? base + ogPath : ogPath;
1872
1951
 
1873
1952
  // The page chrome (h1, title, description) comes from the translatable
@@ -1979,7 +2058,8 @@ var notFoundPageTemplate = () => `---
1979
2058
  // Generated by Blume. Do not edit. Override by adding \`pages/404.astro\`.
1980
2059
  import Icon from "blume/components/Icon.astro";
1981
2060
  import PageLayout from "blume/components/layout/PageLayout.astro";
1982
- import { withBase } from "blume/components/islands/base-path.ts";
2061
+ import { withMountedBase } from "blume/components/islands/base-path.ts";
2062
+ import { mountBasePath } from "blume/core/base-path.ts";
1983
2063
  import data from "blume:data";
1984
2064
 
1985
2065
  export const prerender = true;
@@ -2003,22 +2083,27 @@ const htmlLang = i18n ? i18n.defaultLocale : "en";
2003
2083
  // their resolved target when the section has no index page of its own.
2004
2084
  const suggestions = [
2005
2085
  ...data.navigation.tabs.map((tab) => ({
2006
- href: withBase(tab.href ?? tab.path),
2086
+ href: withMountedBase(tab.href ?? tab.path),
2007
2087
  label: tab.label,
2008
2088
  })),
2009
2089
  ...(data.config.discovery.sitemap
2010
- ? [{ href: withBase("/sitemap.xml"), label: nf.sitemap }]
2090
+ ? [{ href: withMountedBase("/sitemap.xml"), label: nf.sitemap }]
2011
2091
  : []),
2012
2092
  ...(data.config.discovery.llmsTxt
2013
- ? [{ href: withBase("/llms.txt"), label: nf.llms }]
2093
+ ? [{ href: withMountedBase("/llms.txt"), label: nf.llms }]
2014
2094
  : []),
2015
2095
  ];
2016
2096
 
2017
2097
  // Every host serves this one page for any missing URL, so a reader who
2018
2098
  // mistyped \`/ar/…\` would get the default locale's message. The other locales'
2019
2099
  // copy rides along, and the script below swaps it in when the URL's first
2020
- // segment names one of them — the message, its language and direction, the
2021
- // tab title, and the home link (to that locale's root).
2100
+ // segment past the site's base names one of them — the message, its language
2101
+ // and direction, the tab title, and the home link (to that locale's root).
2102
+ // Localized routes sit under both bases (\`{deployment.base}/{basePath}/ar/…\`),
2103
+ // so the script strips the two together, trailing slash included.
2104
+ const { basePath } = data.config;
2105
+ const siteRoot = withMountedBase(mountBasePath(basePath, "/"));
2106
+ const localeBase = siteRoot.endsWith("/") ? siteRoot : siteRoot + "/";
2022
2107
  const localized = Object.fromEntries(
2023
2108
  (i18n?.locales ?? [])
2024
2109
  .filter((l) => l.code !== i18n?.defaultLocale && data.uiByLocale[l.code])
@@ -2030,7 +2115,7 @@ const localized = Object.fromEntries(
2030
2115
  description: strings.description,
2031
2116
  dir: l.dir ?? "ltr",
2032
2117
  home: strings.home,
2033
- homeHref: withBase("/" + l.code),
2118
+ homeHref: withMountedBase(mountBasePath(basePath, "/" + l.code)),
2034
2119
  suggestions: strings.suggestions,
2035
2120
  title: strings.title,
2036
2121
  },
@@ -2059,7 +2144,7 @@ const localizedJson = JSON.stringify(localized).replaceAll("<", "\\\\u003c");
2059
2144
  >
2060
2145
  <div
2061
2146
  class="mx-auto grid w-full max-w-5xl gap-12 px-6 py-20 sm:py-28 md:grid-cols-[3fr_2fr] md:gap-16 lg:gap-24 lg:py-36"
2062
- data-base={withBase("/")}
2147
+ data-base={localeBase}
2063
2148
  data-blume-not-found
2064
2149
  >
2065
2150
  <div class="flex flex-col items-start">
@@ -2080,7 +2165,7 @@ const localizedJson = JSON.stringify(localized).replaceAll("<", "\\\\u003c");
2080
2165
  <a
2081
2166
  class="mt-8 inline-flex items-center gap-1.5 rounded-full bg-accent py-2 pe-4 ps-3.5 text-sm font-medium text-accent-foreground transition-opacity hover:opacity-90"
2082
2167
  data-nf-home
2083
- href={withBase("/")}
2168
+ href={withMountedBase("/")}
2084
2169
  >
2085
2170
  <Icon class="rtl:-scale-x-100" name="arrow-left" size={14} />
2086
2171
  <span data-nf="home">{nf.home}</span>
@@ -2147,7 +2232,7 @@ const localizedJson = JSON.stringify(localized).replaceAll("<", "\\\\u003c");
2147
2232
  </PageLayout>
2148
2233
  `;
2149
2234
  var notFoundMarkdownTemplate = () => `// Generated by Blume. Do not edit. Override by adding \`pages/404.astro\`.
2150
- import { withBase } from "blume/components/islands/base-path.ts";
2235
+ import { withMountedBase } from "blume/components/islands/base-path.ts";
2151
2236
  import { absoluteUrl } from "blume/core/site-url.ts";
2152
2237
  import data from "blume:data";
2153
2238
 
@@ -2158,7 +2243,7 @@ const nf = data.ui.notFound;
2158
2243
  // Absolute for internal routes when the site is known; an external tab href
2159
2244
  // passes through untouched.
2160
2245
  const href = (path: string): string => {
2161
- const based = withBase(path);
2246
+ const based = withMountedBase(path);
2162
2247
  return data.config.site && based.startsWith("/") && !based.startsWith("//")
2163
2248
  ? absoluteUrl(data.config.site, based)
2164
2249
  : based;
@@ -2206,7 +2291,7 @@ export function GET() {
2206
2291
  `;
2207
2292
  var notFoundJsonTemplate = () => `// Generated by Blume. Do not edit. Override by adding \`pages/404.astro\`.
2208
2293
  import { problem } from "blume/ai/api/problem.ts";
2209
- import { withBase } from "blume/components/islands/base-path.ts";
2294
+ import { withMountedBase } from "blume/components/islands/base-path.ts";
2210
2295
  import { absoluteUrl } from "blume/core/site-url.ts";
2211
2296
  import data from "blume:data";
2212
2297
 
@@ -2217,7 +2302,7 @@ const nf = data.ui.notFound;
2217
2302
  // Absolute for internal routes when the site is known; an external tab href
2218
2303
  // passes through untouched.
2219
2304
  const href = (path: string): string => {
2220
- const based = withBase(path);
2305
+ const based = withMountedBase(path);
2221
2306
  return data.config.site && based.startsWith("/") && !based.startsWith("//")
2222
2307
  ? absoluteUrl(data.config.site, based)
2223
2308
  : based;
@@ -2379,11 +2464,20 @@ const Example = entry.Component;
2379
2464
  root.dataset.theme = theme;
2380
2465
  root.classList.toggle("dark", theme === "dark");
2381
2466
  };
2382
- const stored = () =>
2383
- localStorage.getItem("blume-theme") ??
2384
- (matchMedia("(prefers-color-scheme: dark)").matches
2385
- ? "dark"
2386
- : "light");
2467
+ // Blocked storage (a sandboxed or privacy-locked frame) throws on
2468
+ // access; it falls through to the OS setting like an unset preference.
2469
+ const stored = () => {
2470
+ let theme = null;
2471
+ try {
2472
+ theme = localStorage.getItem("blume-theme");
2473
+ } catch {}
2474
+ return (
2475
+ theme ??
2476
+ (matchMedia("(prefers-color-scheme: dark)").matches
2477
+ ? "dark"
2478
+ : "light")
2479
+ );
2480
+ };
2387
2481
  try {
2388
2482
  const host = window.parent.document.documentElement;
2389
2483
  apply(host.dataset.theme ?? stored());
@@ -2465,7 +2559,7 @@ var runtimeTsconfigTemplate = () => `${JSON.stringify({
2465
2559
  }, null, 2)}
2466
2560
  `;
2467
2561
 
2468
- export { 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 };
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 };
2469
2563
 
2470
- //# debugId=4C36F12BB67C30E764756E2164756E21
2471
- //# sourceMappingURL=chunk-2hn4b8z7.js.map
2564
+ //# debugId=D53DB1B1EA2E6A3764756E2164756E21
2565
+ //# sourceMappingURL=chunk-5m5nmvyq.js.map