blume 2.0.1 → 2.0.2

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 (410) hide show
  1. package/CHANGELOG.md +82 -0
  2. package/dist/cli/{chunk-vtk4a6dg.js → chunk-00gs3wqs.js} +1 -1
  3. package/dist/cli/{chunk-fa25z98p.js → chunk-273ygyr4.js} +4 -3
  4. package/dist/cli/chunk-273ygyr4.js.map +11 -0
  5. package/dist/cli/{chunk-yw7dm696.js → chunk-3yce002v.js} +21 -8
  6. package/dist/cli/{chunk-yw7dm696.js.map → chunk-3yce002v.js.map} +3 -3
  7. package/dist/cli/{chunk-yt5n7ppj.js → chunk-4e9b9ra6.js} +17 -7
  8. package/dist/cli/chunk-4e9b9ra6.js.map +10 -0
  9. package/dist/cli/{chunk-fs23ddbb.js → chunk-5r8g91qn.js} +352 -676
  10. package/dist/cli/chunk-5r8g91qn.js.map +34 -0
  11. package/dist/cli/{chunk-6vm74dry.js → chunk-6dtt0zfn.js} +8 -8
  12. package/dist/cli/{chunk-qwsrynx5.js → chunk-6k4ftwze.js} +38 -19
  13. package/dist/cli/{chunk-qwsrynx5.js.map → chunk-6k4ftwze.js.map} +4 -4
  14. package/dist/cli/{chunk-qs4q5p4e.js → chunk-7mbqtmgb.js} +16 -7
  15. package/dist/cli/chunk-7mbqtmgb.js.map +10 -0
  16. package/dist/cli/{chunk-q5163e60.js → chunk-7vtckvaw.js} +21 -19
  17. package/dist/cli/chunk-7vtckvaw.js.map +11 -0
  18. package/dist/cli/{chunk-kdp5q7ke.js → chunk-8g8ytmgx.js} +17 -18
  19. package/dist/cli/{chunk-kdp5q7ke.js.map → chunk-8g8ytmgx.js.map} +2 -2
  20. package/dist/cli/{chunk-epjnccmv.js → chunk-91ws1n6j.js} +18 -15
  21. package/dist/cli/chunk-91ws1n6j.js.map +10 -0
  22. package/dist/cli/{chunk-fxypxtvm.js → chunk-bbnwccaz.js} +2 -2
  23. package/dist/cli/{chunk-m3vmjgmq.js → chunk-bfwp9vp6.js} +16 -8
  24. package/dist/cli/chunk-bfwp9vp6.js.map +10 -0
  25. package/dist/cli/{chunk-f2z5v128.js → chunk-d1v5rhy0.js} +14 -15
  26. package/dist/cli/{chunk-f2z5v128.js.map → chunk-d1v5rhy0.js.map} +2 -2
  27. package/dist/cli/{chunk-6crbhc3x.js → chunk-ddndchfr.js} +21 -6
  28. package/dist/cli/chunk-ddndchfr.js.map +14 -0
  29. package/dist/cli/{chunk-ce574jw2.js → chunk-esh98wmb.js} +1 -1
  30. package/dist/cli/{chunk-zxcczpyx.js → chunk-fsmrqk8a.js} +1 -1
  31. package/dist/cli/{chunk-hdpx1tax.js → chunk-g698a744.js} +5 -5
  32. package/dist/cli/{chunk-jts8mvcz.js → chunk-gs7r695n.js} +9 -3
  33. package/dist/cli/{chunk-jts8mvcz.js.map → chunk-gs7r695n.js.map} +3 -3
  34. package/dist/cli/{chunk-zxh4d9vy.js → chunk-h2ez8dzb.js} +4 -4
  35. package/dist/cli/{chunk-5shv93fd.js → chunk-h7k3nq3v.js} +2 -2
  36. package/dist/cli/{chunk-79jhk4py.js → chunk-hqp2ajnh.js} +251 -122
  37. package/dist/cli/chunk-hqp2ajnh.js.map +35 -0
  38. package/dist/cli/{chunk-2hn4b8z7.js → chunk-hr8ne106.js} +109 -40
  39. package/dist/cli/chunk-hr8ne106.js.map +13 -0
  40. package/dist/cli/{chunk-6hsn950k.js → chunk-j85scx15.js} +62 -18
  41. package/dist/cli/chunk-j85scx15.js.map +10 -0
  42. package/dist/cli/{chunk-s1p84fyh.js → chunk-k7pj68a8.js} +63 -22
  43. package/dist/cli/chunk-k7pj68a8.js.map +11 -0
  44. package/dist/cli/{chunk-ah61y8py.js → chunk-mqc662a6.js} +2 -2
  45. package/dist/cli/{chunk-ch6g3ar0.js → chunk-n1yg3tj3.js} +4 -4
  46. package/dist/cli/{chunk-mb2919y2.js → chunk-nfcyttvj.js} +17 -6
  47. package/dist/cli/chunk-nfcyttvj.js.map +10 -0
  48. package/dist/cli/{chunk-kpf8rrjc.js → chunk-pbg5a4s3.js} +56 -24
  49. package/dist/cli/chunk-pbg5a4s3.js.map +19 -0
  50. package/dist/cli/{chunk-jwyddg7y.js → chunk-ppzjqwx2.js} +21 -14
  51. package/dist/cli/{chunk-jwyddg7y.js.map → chunk-ppzjqwx2.js.map} +4 -4
  52. package/dist/cli/{chunk-dh8cwk36.js → chunk-qkb5a8sa.js} +24 -9
  53. package/dist/cli/chunk-qkb5a8sa.js.map +10 -0
  54. package/dist/cli/{chunk-wm7js3j9.js → chunk-sqw4ekg1.js} +2 -2
  55. package/dist/cli/{chunk-qkqwkpte.js → chunk-v6ya5kcb.js} +3083 -953
  56. package/dist/cli/chunk-v6ya5kcb.js.map +189 -0
  57. package/dist/cli/{chunk-fz5wtpmh.js → chunk-w4bxdvsa.js} +18 -15
  58. package/dist/cli/chunk-w4bxdvsa.js.map +10 -0
  59. package/dist/cli/{chunk-27g6wdth.js → chunk-wdrt2k2v.js} +2 -2
  60. package/dist/cli/{chunk-wgm7m9qk.js → chunk-xh43dwgw.js} +158 -43
  61. package/dist/cli/chunk-xh43dwgw.js.map +36 -0
  62. package/dist/cli/{chunk-s6jhgk0q.js → chunk-zp79m0ts.js} +2 -2
  63. package/dist/cli/index.js +160 -35
  64. package/dist/cli/index.js.map +4 -4
  65. package/dist/types/ai/agent-surface.d.ts +32 -0
  66. package/dist/types/ai/api-catalog.d.ts +7 -1
  67. package/dist/types/ai/ask-context.d.ts +7 -0
  68. package/dist/types/ai/component-markdown.d.ts +4 -4
  69. package/dist/types/ai/relative-links.d.ts +9 -4
  70. package/dist/types/ai/static-expression.d.ts +28 -0
  71. package/dist/types/analytics/databuddy.d.ts +43 -0
  72. package/dist/types/analytics/index.d.ts +2 -0
  73. package/dist/types/analytics/schema.d.ts +14 -0
  74. package/dist/types/cli/env.d.ts +5 -0
  75. package/dist/types/cli/init/scaffold.d.ts +19 -3
  76. package/dist/types/cli/init/starter-spec.d.ts +11 -0
  77. package/dist/types/core/base-path.d.ts +9 -0
  78. package/dist/types/core/config-input.d.ts +4 -4
  79. package/dist/types/core/config.d.ts +2 -2
  80. package/dist/types/core/graph.d.ts +2 -0
  81. package/dist/types/core/i18n-ui.d.ts +31 -0
  82. package/dist/types/core/i18n.d.ts +7 -1
  83. package/dist/types/core/links.d.ts +3 -1
  84. package/dist/types/core/load-module.d.ts +10 -0
  85. package/dist/types/core/locale-links.d.ts +12 -2
  86. package/dist/types/core/meta.d.ts +5 -1
  87. package/dist/types/core/nav-diagnostics.d.ts +10 -0
  88. package/dist/types/core/navigation.d.ts +38 -0
  89. package/dist/types/core/ordering-prefix.d.ts +4 -0
  90. package/dist/types/core/safe-links.d.ts +3 -1
  91. package/dist/types/core/schema.d.ts +52 -13
  92. package/dist/types/core/sources/github-releases.d.ts +5 -0
  93. package/dist/types/core/sources/lower.d.ts +14 -2
  94. package/dist/types/core/sources/normalize.d.ts +10 -1
  95. package/dist/types/core/sources/remote.d.ts +11 -1
  96. package/dist/types/core/sources/resolve.d.ts +12 -0
  97. package/dist/types/core/sources/types.d.ts +31 -0
  98. package/dist/types/core/types.d.ts +9 -0
  99. package/dist/types/deploy/adapters/node.d.ts +5 -2
  100. package/dist/types/deploy/adapters/types.d.ts +7 -0
  101. package/dist/types/deploy/cloudflare-negotiation.d.ts +3 -2
  102. package/dist/types/deploy/headers.d.ts +31 -7
  103. package/dist/types/deploy/node-headers.d.ts +43 -8
  104. package/dist/types/deploy/platforms/netlify.d.ts +27 -2
  105. package/dist/types/deploy/platforms/node.d.ts +6 -5
  106. package/dist/types/deploy/platforms/types.d.ts +7 -0
  107. package/dist/types/deploy/platforms/vercel.d.ts +3 -2
  108. package/dist/types/deploy/redirects.d.ts +7 -2
  109. package/dist/types/deploy/vercel-negotiation.d.ts +3 -2
  110. package/dist/types/openapi/model.d.ts +20 -6
  111. package/dist/types/search/sync/algolia.d.ts +3 -1
  112. package/docs/01-quickstart.mdx +3 -2
  113. package/docs/02-deployment.mdx +17 -8
  114. package/docs/08-faq.mdx +9 -2
  115. package/docs/advanced/changelog.mdx +1 -1
  116. package/docs/advanced/custom-pages.mdx +4 -2
  117. package/docs/cli/audit.mdx +2 -2
  118. package/docs/cli/doctor.mdx +2 -2
  119. package/docs/cli/evals.mdx +2 -2
  120. package/docs/cli/index.mdx +4 -1
  121. package/docs/cli/translate.mdx +1 -1
  122. package/docs/configuration/analytics.mdx +23 -2
  123. package/docs/configuration/assistant.mdx +1 -1
  124. package/docs/configuration/customization.mdx +4 -3
  125. package/docs/configuration/index.mdx +5 -3
  126. package/docs/configuration/search.mdx +1 -1
  127. package/docs/content/components.mdx +1 -1
  128. package/docs/content/frontmatter.mdx +5 -1
  129. package/docs/content/i18n.mdx +1 -1
  130. package/docs/content/index.mdx +4 -2
  131. package/docs/content/meta.mdx +5 -3
  132. package/docs/content/navigation.mdx +29 -4
  133. package/docs/content/sources.mdx +18 -12
  134. package/docs/content/versioning.mdx +1 -0
  135. package/docs/discoverability/agent-discovery.mdx +21 -7
  136. package/docs/discoverability/index.mdx +2 -2
  137. package/docs/discoverability/llms-txt.mdx +2 -5
  138. package/docs/discoverability/markdown.mdx +5 -3
  139. package/docs/discoverability/mcp.mdx +4 -0
  140. package/docs/discoverability/metadata.mdx +3 -2
  141. package/docs/discoverability/open-graph.mdx +6 -4
  142. package/docs/discoverability/rss.mdx +3 -1
  143. package/docs/references/asyncapi.mdx +1 -1
  144. package/docs/references/graphql.mdx +2 -2
  145. package/docs/references/openapi.mdx +3 -3
  146. package/package.json +1 -1
  147. package/skills/blume-migrate/SKILL.md +6 -6
  148. package/skills/blume-migrate/references/docusaurus.md +6 -6
  149. package/skills/blume-migrate/references/mintlify.md +3 -3
  150. package/skills/blume-migrate/references/monorepo.md +1 -1
  151. package/skills/blume-migrate/references/nextra.md +1 -1
  152. package/skills/blume-migrate/references/starlight.md +5 -5
  153. package/skills/blume-migrate/scripts/mintlify-codemod.mjs +2 -2
  154. package/skills/blume-update-docs/references/audit-checklist.md +1 -1
  155. package/src/ai/agent-surface.ts +56 -0
  156. package/src/ai/api/spec.ts +15 -2
  157. package/src/ai/api-catalog.ts +7 -1
  158. package/src/ai/ask-context.ts +14 -2
  159. package/src/ai/ask-data.ts +26 -12
  160. package/src/ai/component-markdown.ts +43 -37
  161. package/src/ai/link-headers.ts +8 -3
  162. package/src/ai/llms.ts +4 -3
  163. package/src/ai/markdown.ts +23 -11
  164. package/src/ai/mcp/server.ts +78 -7
  165. package/src/ai/relative-links.ts +78 -10
  166. package/src/ai/static-expression.ts +416 -0
  167. package/src/ai/visibility.ts +45 -14
  168. package/src/analytics/databuddy.ts +67 -0
  169. package/src/analytics/head.ts +4 -0
  170. package/src/analytics/index.ts +2 -0
  171. package/src/analytics/posthog.ts +21 -3
  172. package/src/analytics/schema.ts +2 -0
  173. package/src/astro/generate.ts +71 -27
  174. package/src/astro/templates.ts +61 -23
  175. package/src/audit/catalog.ts +2 -2
  176. package/src/audit/checks/assets.ts +25 -5
  177. package/src/audit/checks/content.ts +20 -2
  178. package/src/audit/checks/i18n.ts +46 -8
  179. package/src/audit/checks/indexability.ts +39 -19
  180. package/src/audit/checks/links.ts +14 -0
  181. package/src/audit/checks/llms.ts +6 -3
  182. package/src/audit/checks/network.ts +3 -1
  183. package/src/audit/checks/og-image.ts +10 -0
  184. package/src/audit/checks/robots.ts +6 -1
  185. package/src/audit/checks/sitemap.ts +56 -31
  186. package/src/audit/checks/social.ts +21 -2
  187. package/src/audit/crawl.ts +88 -15
  188. package/src/audit/report.ts +54 -17
  189. package/src/audit/run.ts +1 -0
  190. package/src/audit/types.ts +18 -0
  191. package/src/audit/url.ts +37 -6
  192. package/src/cli/build-failure.ts +50 -0
  193. package/src/cli/commands/audit.ts +7 -0
  194. package/src/cli/commands/build.ts +19 -5
  195. package/src/cli/commands/check.ts +2 -0
  196. package/src/cli/commands/eval.ts +1 -7
  197. package/src/cli/commands/init.ts +15 -5
  198. package/src/cli/commands/preview.ts +15 -0
  199. package/src/cli/commands/sync.ts +2 -0
  200. package/src/cli/commands/translate.ts +9 -6
  201. package/src/cli/commands/upgrade.ts +11 -0
  202. package/src/cli/eject-scripts.ts +32 -7
  203. package/src/cli/env.ts +12 -1
  204. package/src/cli/init/scaffold.ts +117 -11
  205. package/src/cli/init/starter-spec.ts +235 -0
  206. package/src/components/content/AccordionItem.astro +26 -22
  207. package/src/components/content/Badge.astro +2 -9
  208. package/src/components/content/Card.astro +2 -2
  209. package/src/components/content/Component.astro +9 -3
  210. package/src/components/content/Expandable.astro +5 -1
  211. package/src/components/content/Frame.astro +2 -7
  212. package/src/components/content/GithubInfo.astro +12 -2
  213. package/src/components/content/Prompt.astro +2 -7
  214. package/src/components/content/Tabs.astro +54 -5
  215. package/src/components/content/Tile.astro +1 -1
  216. package/src/components/content/Tooltip.astro +69 -7
  217. package/src/components/content/Tree.astro +7 -2
  218. package/src/components/content/TypeTable.astro +10 -5
  219. package/src/components/content/Update.astro +8 -2
  220. package/src/components/content/auto-type-table.ts +4 -1
  221. package/src/components/content/badge-color.ts +17 -0
  222. package/src/components/content/base-href.ts +18 -3
  223. package/src/components/content/inline-markdown.ts +27 -7
  224. package/src/components/copy-feedback.ts +35 -8
  225. package/src/components/islands/assistant.tsx +16 -2
  226. package/src/components/islands/hooks.ts +7 -2
  227. package/src/components/islands/webmcp.ts +12 -8
  228. package/src/components/layout/Banner.astro +23 -4
  229. package/src/components/layout/Header.astro +22 -9
  230. package/src/components/layout/Logo.astro +5 -0
  231. package/src/components/layout/NavSelector.astro +6 -1
  232. package/src/components/layout/NavTabMenu.astro +133 -0
  233. package/src/components/layout/NavTree.astro +15 -6
  234. package/src/components/layout/NavTreeCache.astro +5 -2
  235. package/src/components/layout/NavTreeScript.astro +45 -5
  236. package/src/components/layout/PageLayout.astro +22 -8
  237. package/src/components/layout/ReferenceLayout.astro +4 -1
  238. package/src/components/layout/RootLayout.astro +21 -8
  239. package/src/components/layout/Search.astro +5 -1
  240. package/src/components/layout/analytics-client.ts +2 -0
  241. package/src/components/openapi/GraphqlType.astro +11 -3
  242. package/src/components/openapi/MessageComposer.astro +1 -1
  243. package/src/components/openapi/Operation.astro +21 -5
  244. package/src/components/openapi/PanelTabs.astro +4 -1
  245. package/src/components/openapi/Playground.astro +8 -2
  246. package/src/components/openapi/RequestPanel.astro +9 -5
  247. package/src/components/openapi/SchemaProperty.astro +11 -33
  248. package/src/components/openapi/SchemaTable.astro +27 -52
  249. package/src/components/openapi/helpers.ts +90 -12
  250. package/src/components/openapi/message-composer.ts +8 -0
  251. package/src/components/openapi/message-model.ts +12 -2
  252. package/src/components/openapi/message.ts +4 -1
  253. package/src/components/openapi/operation-model.ts +40 -8
  254. package/src/components/openapi/panel.ts +29 -5
  255. package/src/components/openapi/playground-client.ts +37 -7
  256. package/src/components/openapi/playground-schema.ts +25 -6
  257. package/src/components/openapi/request.ts +2 -0
  258. package/src/components/openapi/schema-tree.ts +203 -0
  259. package/src/components/openapi/snippets.ts +30 -15
  260. package/src/components/openapi/validate-json.ts +1 -1
  261. package/src/core/base-path.ts +15 -0
  262. package/src/core/config-input.ts +4 -4
  263. package/src/core/config.ts +18 -4
  264. package/src/core/diagnostics.ts +217 -30
  265. package/src/core/graph.ts +120 -11
  266. package/src/core/i18n-ui.ts +39 -2
  267. package/src/core/i18n.ts +13 -2
  268. package/src/core/links.ts +7 -4
  269. package/src/core/load-module.ts +20 -0
  270. package/src/core/locale-links.ts +17 -17
  271. package/src/core/manifest.ts +3 -2
  272. package/src/core/meta.ts +69 -6
  273. package/src/core/nav-diagnostics.ts +56 -1
  274. package/src/core/navigation.ts +245 -76
  275. package/src/core/ordering-prefix.ts +27 -0
  276. package/src/core/project-graph.ts +23 -1
  277. package/src/core/safe-href.ts +53 -1
  278. package/src/core/safe-links.ts +11 -2
  279. package/src/core/schema.ts +70 -14
  280. package/src/core/sources/assets.ts +83 -41
  281. package/src/core/sources/contentful-rich-text.ts +3 -2
  282. package/src/core/sources/contentful.ts +25 -12
  283. package/src/core/sources/filesystem.ts +5 -1
  284. package/src/core/sources/github-releases.ts +106 -5
  285. package/src/core/sources/lexical.ts +9 -4
  286. package/src/core/sources/lower.ts +79 -26
  287. package/src/core/sources/mdx-remote.ts +1 -0
  288. package/src/core/sources/normalize.ts +132 -30
  289. package/src/core/sources/notion.ts +26 -10
  290. package/src/core/sources/obsidian.ts +17 -3
  291. package/src/core/sources/payload.ts +1 -0
  292. package/src/core/sources/portable-text.ts +63 -44
  293. package/src/core/sources/remote.ts +18 -2
  294. package/src/core/sources/resolve.ts +52 -33
  295. package/src/core/sources/sanity.ts +1 -0
  296. package/src/core/sources/strapi-blocks.ts +9 -4
  297. package/src/core/sources/strapi.ts +1 -0
  298. package/src/core/sources/types.ts +31 -0
  299. package/src/core/types.ts +9 -0
  300. package/src/core/ui-packs/ar.ts +13 -0
  301. package/src/core/ui-packs/bg.ts +13 -0
  302. package/src/core/ui-packs/bn.ts +13 -0
  303. package/src/core/ui-packs/ca.ts +13 -0
  304. package/src/core/ui-packs/cs.ts +13 -0
  305. package/src/core/ui-packs/da.ts +13 -0
  306. package/src/core/ui-packs/de.ts +13 -0
  307. package/src/core/ui-packs/el.ts +13 -0
  308. package/src/core/ui-packs/es.ts +13 -0
  309. package/src/core/ui-packs/fa.ts +13 -0
  310. package/src/core/ui-packs/fi.ts +13 -0
  311. package/src/core/ui-packs/fr.ts +13 -0
  312. package/src/core/ui-packs/he.ts +13 -0
  313. package/src/core/ui-packs/hi.ts +13 -0
  314. package/src/core/ui-packs/hr.ts +13 -0
  315. package/src/core/ui-packs/hu.ts +13 -0
  316. package/src/core/ui-packs/id.ts +13 -0
  317. package/src/core/ui-packs/it.ts +13 -0
  318. package/src/core/ui-packs/ja.ts +13 -0
  319. package/src/core/ui-packs/ko.ts +13 -0
  320. package/src/core/ui-packs/nl.ts +13 -0
  321. package/src/core/ui-packs/no.ts +13 -0
  322. package/src/core/ui-packs/pl.ts +13 -0
  323. package/src/core/ui-packs/pt-br.ts +13 -0
  324. package/src/core/ui-packs/pt.ts +13 -0
  325. package/src/core/ui-packs/ro.ts +13 -0
  326. package/src/core/ui-packs/ru.ts +13 -0
  327. package/src/core/ui-packs/sk.ts +13 -0
  328. package/src/core/ui-packs/sr.ts +13 -0
  329. package/src/core/ui-packs/sv.ts +13 -0
  330. package/src/core/ui-packs/th.ts +13 -0
  331. package/src/core/ui-packs/tr.ts +13 -0
  332. package/src/core/ui-packs/uk.ts +13 -0
  333. package/src/core/ui-packs/vi.ts +13 -0
  334. package/src/core/ui-packs/zh-tw.ts +13 -0
  335. package/src/core/ui-packs/zh.ts +13 -0
  336. package/src/core/version-cut.ts +17 -2
  337. package/src/core/versions.ts +4 -1
  338. package/src/deploy/adapters/node.ts +5 -2
  339. package/src/deploy/adapters/registry.ts +2 -1
  340. package/src/deploy/adapters/types.ts +13 -1
  341. package/src/deploy/artifacts.ts +25 -5
  342. package/src/deploy/cloudflare-negotiation.ts +23 -4
  343. package/src/deploy/headers.ts +67 -51
  344. package/src/deploy/node-headers.ts +148 -27
  345. package/src/deploy/platforms/cloudflare.ts +1 -0
  346. package/src/deploy/platforms/netlify.ts +82 -5
  347. package/src/deploy/platforms/node.ts +7 -5
  348. package/src/deploy/platforms/static.ts +1 -0
  349. package/src/deploy/platforms/types.ts +7 -0
  350. package/src/deploy/platforms/vercel.ts +9 -3
  351. package/src/deploy/redirects.ts +14 -3
  352. package/src/deploy/vercel-negotiation.ts +35 -3
  353. package/src/eval/agents.ts +10 -2
  354. package/src/eval/run.ts +25 -0
  355. package/src/markdown/base-links.ts +55 -8
  356. package/src/markdown/index.ts +6 -3
  357. package/src/markdown/relative-links.ts +3 -23
  358. package/src/markdown/route-snapshot.ts +37 -0
  359. package/src/og/card.ts +20 -4
  360. package/src/og/derive.ts +145 -4
  361. package/src/openapi/graphql-build.ts +28 -2
  362. package/src/openapi/model.ts +77 -13
  363. package/src/openapi/render-mdx.ts +10 -1
  364. package/src/registry/eject.ts +119 -22
  365. package/src/search/documents.ts +22 -1
  366. package/src/search/sync/algolia.ts +36 -2
  367. package/src/sources/registry.ts +5 -0
  368. package/src/theme/entry.ts +11 -4
  369. package/src/translate/agents.ts +6 -1
  370. package/src/translate/ledger.ts +26 -3
  371. package/src/translate/meta.ts +11 -3
  372. package/src/translate/run.ts +11 -5
  373. package/src/translate/validate.ts +10 -1
  374. package/src/translate/work-list.ts +36 -3
  375. package/src/upgrade/upgrade.ts +36 -4
  376. package/dist/cli/chunk-2hn4b8z7.js.map +0 -12
  377. package/dist/cli/chunk-6crbhc3x.js.map +0 -14
  378. package/dist/cli/chunk-6hsn950k.js.map +0 -10
  379. package/dist/cli/chunk-79jhk4py.js.map +0 -35
  380. package/dist/cli/chunk-82bbrxdn.js +0 -51
  381. package/dist/cli/chunk-82bbrxdn.js.map +0 -10
  382. package/dist/cli/chunk-abh8yjkn.js +0 -31
  383. package/dist/cli/chunk-abh8yjkn.js.map +0 -10
  384. package/dist/cli/chunk-dh8cwk36.js.map +0 -10
  385. package/dist/cli/chunk-epjnccmv.js.map +0 -10
  386. package/dist/cli/chunk-fa25z98p.js.map +0 -11
  387. package/dist/cli/chunk-fs23ddbb.js.map +0 -35
  388. package/dist/cli/chunk-fz5wtpmh.js.map +0 -10
  389. package/dist/cli/chunk-kpf8rrjc.js.map +0 -19
  390. package/dist/cli/chunk-m3vmjgmq.js.map +0 -10
  391. package/dist/cli/chunk-mb2919y2.js.map +0 -10
  392. package/dist/cli/chunk-q5163e60.js.map +0 -11
  393. package/dist/cli/chunk-qkqwkpte.js.map +0 -182
  394. package/dist/cli/chunk-qs4q5p4e.js.map +0 -10
  395. package/dist/cli/chunk-s1p84fyh.js.map +0 -10
  396. package/dist/cli/chunk-wgm7m9qk.js.map +0 -36
  397. package/dist/cli/chunk-yt5n7ppj.js.map +0 -10
  398. /package/dist/cli/{chunk-vtk4a6dg.js.map → chunk-00gs3wqs.js.map} +0 -0
  399. /package/dist/cli/{chunk-6vm74dry.js.map → chunk-6dtt0zfn.js.map} +0 -0
  400. /package/dist/cli/{chunk-fxypxtvm.js.map → chunk-bbnwccaz.js.map} +0 -0
  401. /package/dist/cli/{chunk-ce574jw2.js.map → chunk-esh98wmb.js.map} +0 -0
  402. /package/dist/cli/{chunk-zxcczpyx.js.map → chunk-fsmrqk8a.js.map} +0 -0
  403. /package/dist/cli/{chunk-hdpx1tax.js.map → chunk-g698a744.js.map} +0 -0
  404. /package/dist/cli/{chunk-zxh4d9vy.js.map → chunk-h2ez8dzb.js.map} +0 -0
  405. /package/dist/cli/{chunk-5shv93fd.js.map → chunk-h7k3nq3v.js.map} +0 -0
  406. /package/dist/cli/{chunk-ah61y8py.js.map → chunk-mqc662a6.js.map} +0 -0
  407. /package/dist/cli/{chunk-ch6g3ar0.js.map → chunk-n1yg3tj3.js.map} +0 -0
  408. /package/dist/cli/{chunk-wm7js3j9.js.map → chunk-sqw4ekg1.js.map} +0 -0
  409. /package/dist/cli/{chunk-27g6wdth.js.map → chunk-wdrt2k2v.js.map} +0 -0
  410. /package/dist/cli/{chunk-s6jhgk0q.js.map → chunk-zp79m0ts.js.map} +0 -0
@@ -74,6 +74,13 @@ export declare const strippedLineOffset: (raw: string | undefined, body: string)
74
74
  export declare const isStringValue: (value: SourceEntry["data"][string]) => value is string;
75
75
  /** What a route resolution needs from the owning source and the config. */
76
76
  export type RouteContext = Pick<NormalizeContext, "i18n" | "versions"> & {
77
+ /**
78
+ * Whether the entry's ref is a path of file and folder names whose ordering
79
+ * prefixes (`01-intro`) sort the sidebar and drop from the route: true for
80
+ * filesystem sources. A staged source's ref is a slug, a release tag, or a
81
+ * note name, and keeps its leading numbers.
82
+ */
83
+ orderingPrefixes?: boolean;
77
84
  /** The source's route prefix (`NormalizeContext["source"]["prefix"]`). */
78
85
  prefix?: string;
79
86
  };
@@ -123,7 +130,9 @@ export interface EntryRoute extends Pick<EntryPlacement, "locales" | "version">
123
130
  * A frontmatter `slug` wins, then the adapter-supplied `entry.slug` (the typed
124
131
  * SPI's "logical route input; defaults to ref if omitted"), then the ref. The
125
132
  * extension is re-appended so `mapRoute`'s extname strip can't eat a dotted
126
- * slug segment (`v1.2`). A slug that trims to nothing falls back. The version
133
+ * slug segment (`v1.2`). A slug that trims to nothing falls back. Only a
134
+ * filesystem ref (`ctx.orderingPrefixes`) loses its ordering prefixes; a slug
135
+ * is a route spelled out, so `2024-year-in-review` stays whole. The version
127
136
  * prefixes the mapped route *after* `mapRoute` runs: the mapped route is the
128
137
  * version-agnostic key, the config id is prepended verbatim (never
129
138
  * numeric-prefix-stripped), a frontmatter `slug` gets versionized so snapshots
@@ -2,12 +2,21 @@ import type { JsonObject, JsonValue } from "./json.ts";
2
2
  import type { ContentSource, SourceContext, SourceEntry } from "./types.ts";
3
3
  /** What every REST-backed CMS source needs to be a staged, cached source. */
4
4
  export interface RemoteSourceOptions {
5
+ /**
6
+ * Throw a `BlumeError` when the source cannot load as configured. Runs
7
+ * before the cache is consulted: thrown from `fetchEntries` instead, a
8
+ * misconfiguration would be served over by a stale snapshot with only an
9
+ * offline warning.
10
+ */
11
+ assertConfigured?: () => void;
5
12
  /** Pull every entry from the API; called on refresh and on each poll. */
6
13
  fetchEntries: () => Promise<SourceEntry[]>;
7
14
  name: string;
8
15
  /** Opt-in dev polling interval (seconds); omit to freeze for the session. */
9
16
  pollInterval?: number;
10
17
  prefix?: string;
18
+ /** The adapter rebuilt on another context (`ContentSource.withContext`). */
19
+ withContext?: (ctx: SourceContext) => ContentSource;
11
20
  }
12
21
  /**
13
22
  * The staged-source scaffolding a CMS adapter shares: a snapshot cache under
@@ -68,7 +77,8 @@ export interface RemoteFieldMap {
68
77
  * when the slug field is missing or slugifies to nothing (pure punctuation),
69
78
  * so distinct documents never collapse onto one `untitled.md`; a slashed
70
79
  * slug keeps its segments. A string body is Markdown and passes through as
71
- * `.md`; any other shape goes to the CMS's lowerer, and is written as `.mdx`
80
+ * `.md`, its unsafe links reduced to their labels; any other shape goes to
81
+ * the CMS's lowerer, and is written as `.mdx`
72
82
  * when `lowersToMdx` (the source has serializers, see `writesMdx`).
73
83
  */
74
84
  export declare const documentEntry: (doc: JsonObject, fields: Required<RemoteFieldMap>, id: string, lower: (body: JsonValue) => string, draft?: boolean, lowersToMdx?: boolean) => SourceEntry;
@@ -1,3 +1,4 @@
1
+ import type { ContentSourceAdapter } from "../../sources/registry.ts";
1
2
  import type { ResolvedConfig } from "../schema.ts";
2
3
  import type { ProjectContext } from "../types.ts";
3
4
  import type { ContentSource } from "./types.ts";
@@ -9,6 +10,17 @@ export interface SourceRuntime {
9
10
  preview?: boolean;
10
11
  refresh?: boolean;
11
12
  }
13
+ /**
14
+ * The directory under `.blume/cache/<source>/` a source keeps its snapshot in:
15
+ * one per preview mode and set of adapter options. A preview snapshot holds
16
+ * drafts, so a published load must never read it, neither as dev's cache-first
17
+ * snapshot nor as a build's offline fallback; and a snapshot fetched with
18
+ * another `query` or `fields` is another result, not a cached copy of this
19
+ * one. `pollInterval` only paces dev re-fetches, so it is left out. A
20
+ * `custom()` source is a live instance rather than options, so its snapshot
21
+ * is keyed by preview mode alone.
22
+ */
23
+ export declare const snapshotKey: (adapter: ContentSourceAdapter, runtime: SourceRuntime) => string;
12
24
  /**
13
25
  * Build the ordered list of content sources for a project. The config schema
14
26
  * already desugared the zero-config shorthand into a single `filesystem()`
@@ -35,6 +35,13 @@ export interface SourceEntry {
35
35
  * the owning source to expose a `contentRoot` to bound the log's pathspec.
36
36
  */
37
37
  sourcePath?: string;
38
+ /**
39
+ * How many lines of the file at `sourcePath` sit above `body.text`, when
40
+ * `raw` is not that file's text: a source that rewrites a local file's
41
+ * front matter (an Obsidian note) sets it, so a diagnostic points at the
42
+ * line the author wrote. Otherwise the height of `raw`'s front matter.
43
+ */
44
+ bodyLineOffset?: number;
38
45
  /** Optional provenance for "edit this page". */
39
46
  editUrl?: string;
40
47
  /** Optional last-modified ISO date supplied by the adapter (non-filesystem). */
@@ -119,6 +126,14 @@ export interface ContentSource {
119
126
  * switcher, since every other locale would only repeat the same text.
120
127
  */
121
128
  readonly monolingual?: boolean;
129
+ /**
130
+ * True for a staged source whose entry refs are file and folder names (an
131
+ * Obsidian vault), so their ordering prefixes (`01 Intro`) sort the sidebar
132
+ * and drop from the route the way a filesystem source's do. Filesystem
133
+ * sources always do; other staged refs are slugs and release tags, kept
134
+ * whole.
135
+ */
136
+ readonly orderedNames?: boolean;
122
137
  /**
123
138
  * Resolved on-disk root, set by sources whose entries live on disk. For
124
139
  * filesystem sources it drives folder-meta discovery (scan under this root)
@@ -128,6 +143,13 @@ export interface ContentSource {
128
143
  * no local tree.
129
144
  */
130
145
  readonly contentRoot?: string;
146
+ /**
147
+ * The globs a filesystem source reads under `contentRoot`, and the ones it
148
+ * skips. Folder-meta discovery honors them, so a `meta.ts` outside the
149
+ * content the source reads is never imported.
150
+ */
151
+ readonly include?: readonly string[];
152
+ readonly exclude?: readonly string[];
131
153
  /** Pull every entry. Called once per scan. */
132
154
  load: () => Promise<SourceLoadResult>;
133
155
  /** Validate the source is usable; throws a BlumeError when not. */
@@ -139,12 +161,21 @@ export interface ContentSource {
139
161
  * remote/static sources omit it (content is frozen for the session).
140
162
  */
141
163
  watch?: (onChange: () => void) => () => void;
164
+ /**
165
+ * This source rebuilt on another runtime context. A source passed to
166
+ * `custom()` is constructed before Blume knows the scan's preview flag,
167
+ * refresh policy, or runtime directory; Blume rebuilds it on them through
168
+ * this, so it previews and caches the way the built-in adapter does. The
169
+ * engine factories (`sanitySource`, `contentfulSource`, …) all set it.
170
+ */
171
+ withContext?: (ctx: SourceContext) => ContentSource;
142
172
  }
143
173
  /** Context passed to `normalizeEntry`, describing the owning source. */
144
174
  export interface NormalizeContext {
145
175
  source: {
146
176
  monolingual?: boolean;
147
177
  name: string;
178
+ orderedNames?: boolean;
148
179
  prefix?: string;
149
180
  staged: boolean;
150
181
  };
@@ -306,6 +306,13 @@ export interface Navigation {
306
306
  * locale trees.
307
307
  */
308
308
  brandHref?: string;
309
+ /**
310
+ * Where the banner's link points in this locale: `banner.link.href`
311
+ * localized like a featured link, then mounted under `basePath` (a route
312
+ * served outside the content tree keeps its own path). Set when the banner
313
+ * has a link.
314
+ */
315
+ bannerHref?: string;
309
316
  }
310
317
  /** The full content graph: the source of truth for generated modules. */
311
318
  export interface ContentGraph {
@@ -392,6 +399,8 @@ export interface RouteManifestEntry {
392
399
  fallback?: boolean;
393
400
  /** True when the page's source publishes one language only (no switcher). */
394
401
  monolingual?: boolean;
402
+ /** True when front matter `ai.exclude` keeps the page out of llms.txt. */
403
+ aiExclude?: boolean;
395
404
  /** Resolved "last updated" ISO date, when the feature is enabled. */
396
405
  lastModified?: string;
397
406
  }
@@ -3,8 +3,11 @@ import type { DeployAdapter, DeployOptions } from "./types.ts";
3
3
  export declare const NODE_ADAPTER_PACKAGE = "@astrojs/node";
4
4
  /**
5
5
  * Options for {@link node}: `output`, `site`, and `base`, plus any option of
6
- * `@astrojs/node` forwarded verbatim (`mode`, `host`, `port`, …). Blume
7
- * defaults `mode` to `"standalone"`; an option you pass wins.
6
+ * `@astrojs/node` forwarded verbatim (`mode`, `staticHeaders`, …). Blume
7
+ * defaults `mode` to `"standalone"`; an option you pass wins. `host` and
8
+ * `port` are forwarded too, but `@astrojs/node` replaces both with Astro's
9
+ * own server settings, so the standalone server listens on `localhost:4321`
10
+ * unless the `HOST` and `PORT` environment variables are set when it starts.
8
11
  */
9
12
  export type NodeOptions = DeployOptions;
10
13
  export type NodeAdapter = DeployAdapter<"node">;
@@ -49,6 +49,13 @@ export interface StaticDeployment {
49
49
  */
50
50
  site?: string;
51
51
  }
52
+ /**
53
+ * `deployment.site`: an absolute http(s) URL, which always has a host. A bare
54
+ * `z.url()` takes any scheme, so `localhost:4321` (scheme `localhost:`),
55
+ * `mailto:`, and `javascript:` all passed and became the prefix of every
56
+ * sitemap entry and canonical link.
57
+ */
58
+ export declare const siteUrlSchema: z.ZodURL;
52
59
  /** The named options' schema; every host adapter extends it with `z.json()` passthrough. */
53
60
  export declare const deployOptionsSchema: z.ZodObject<{
54
61
  base: z.ZodOptional<z.ZodString>;
@@ -39,8 +39,9 @@
39
39
  *
40
40
  * Cloudflare does not apply `_headers` to worker-first routes, so the wrapper
41
41
  * also re-stamps what the static layer would otherwise add on the routes it
42
- * takes over: the homepage agent-discovery `Link` header and the Markdown
43
- * `charset=utf-8` (see `deploy/headers.ts`). The raw `.md`/`.mdx` URLs are
42
+ * takes over: the homepage agent-discovery `Link` header, the Markdown
43
+ * `charset=utf-8`, and the sandbox on the SVGs a content source downloaded
44
+ * (see `deploy/headers.ts`). The raw `.md`/`.mdx` URLs are
44
45
  * exempted from worker-first routing with negative rules, keeping their
45
46
  * `_headers` treatment and their zero-Worker serving path.
46
47
  *
@@ -1,11 +1,24 @@
1
1
  import type { ResolvedConfig } from "../core/schema.ts";
2
+ /** Where the generated endpoint serves content-source images from. */
3
+ export declare const CONTENT_ASSETS_ROOT = "/blume-assets";
2
4
  /**
3
5
  * The policy a content-source SVG is served with: an opaque origin with
4
6
  * scripts off, so an uploaded SVG that carries a `<script>` stays inert when
5
- * opened directly. The endpoint sends it from the server and dev runtimes;
6
- * {@link headerRules} carries it to static hosts.
7
+ * opened directly.
7
8
  */
8
9
  export declare const SVG_ASSET_POLICY = "sandbox";
10
+ /**
11
+ * The headers a content-source SVG is served with: the sandbox policy, and no
12
+ * MIME sniffing. The endpoint sends them from the dev runtime; every host
13
+ * gets them for the built files — static hosts through {@link headerRules},
14
+ * server builds through each platform's own mechanism (`deploy/platforms`).
15
+ */
16
+ export declare const SVG_ASSET_HEADERS: {
17
+ "Content-Security-Policy": string;
18
+ "X-Content-Type-Options": string;
19
+ };
20
+ /** The served glob of content-source SVGs, under the deployment base. */
21
+ export declare const svgAssetPath: (config: ResolvedConfig) => string;
9
22
  /**
10
23
  * One static-host header rule: a served path (a `*` glob spanning path
11
24
  * segments, or an exact path) and the header it sets there.
@@ -17,11 +30,9 @@ export interface HeaderRule {
17
30
  }
18
31
  /**
19
32
  * The header rules every static host should apply, in `_headers` glob syntax.
20
- * The glob carries the served prefix (`{deployment.base}{basePath}` for the
21
- * Markdown mirrors, `{deployment.base}` for the root `.txt` files) so the rules
22
- * still match once the site is mounted under a subpath (`/docs/*.md`); the
23
- * wildcard spans path segments, so a nested route like `/docs/ja/intro.md`
24
- * matches too.
33
+ * The glob carries the deployment base so the rules still match once the site
34
+ * is mounted under a subpath (`/docs/*.md`); the wildcard spans path
35
+ * segments, so a nested route like `/docs/ja/intro.md` matches too.
25
36
  *
26
37
  * When a homepage `Link` header is provided (see `ai/link-headers.ts`), an
27
38
  * exact-path rule for the root page advertises the agent-discovery resources —
@@ -33,6 +44,19 @@ export declare const headerRules: (config: ResolvedConfig, homeLinkHeader?: stri
33
44
  * indented header line, in the two-space format Netlify and Cloudflare read.
34
45
  */
35
46
  export declare const buildNetlifyHeaders: (config: ResolvedConfig, homeLinkHeader?: string | null) => string;
47
+ /** One entry of Netlify's Frameworks API config `headers` array. */
48
+ export interface NetlifyConfigHeaders {
49
+ for: string;
50
+ values: Record<string, string>;
51
+ }
52
+ /**
53
+ * The {@link headerRules} as Netlify Frameworks API `headers` entries
54
+ * (`.netlify/v1/config.json`), one per path with every header it sets. A
55
+ * `netlify()` server build reads no `_headers` file, so it carries the same
56
+ * rules here, in the `for`/`values` form that follows `netlify.toml`'s
57
+ * `[[headers]]` and the same path syntax as `_headers`.
58
+ */
59
+ export declare const buildNetlifyConfigHeaders: (config: ResolvedConfig, homeLinkHeader?: string | null) => NetlifyConfigHeaders[];
36
60
  /** One entry of `vercel.json`'s `headers` array. */
37
61
  export interface VercelHeader {
38
62
  headers: {
@@ -10,6 +10,12 @@ import type { BuildLog } from "./platforms/types.ts";
10
10
  * (`deploy/headers.ts`) that a Node server has no file to read from. The Markdown
11
11
  * and text charsets need no rule here: `send` already adds `charset=UTF-8` to
12
12
  * `text/*` types.
13
+ *
14
+ * The same wrapper answers the configured redirects. Astro's own handler
15
+ * honors a redirect's configured status only when its destination resolves
16
+ * to a discrete route, and Blume serves every page from `[...slug]`, so a
17
+ * `302` or `307` would go out as a `301` or `308` — permanent redirects that
18
+ * browsers cache.
13
19
  */
14
20
  /** The headers one exact served path (deployment base included) gets. */
15
21
  export interface NodeHeaderRule {
@@ -23,20 +29,49 @@ export declare const NODE_ASTRO_ENTRY_FILE = "astro-entry.mjs";
23
29
  /** The header rules for this config, merged per path. */
24
30
  export declare const nodeHeaderRules: (config: ResolvedConfig) => NodeHeaderRule[];
25
31
  /**
26
- * The entry that replaces Astro's: it stamps the rules' headers on the
27
- * response, then hands the request to Astro's handler. `send` leaves a
28
- * Content-Type that is already set alone, so the registered media type wins.
32
+ * The configured redirects the wrapper answers, keyed by served path (the
33
+ * trailing slash trimmed), each to its `Location` and exact status.
34
+ */
35
+ export type NodeRedirects = Record<string, [string, number]>;
36
+ /**
37
+ * The configured redirects, based the way the host matches them (see
38
+ * `platformRedirects`) and keyed for the wrapper's lookup, the `Location`
39
+ * percent-encoded as Astro sends it. A redirect at a content route's own path
40
+ * is left out: the prerendered page owns that URL, and the static handler
41
+ * serves it before Astro's redirect ever could.
42
+ */
43
+ export declare const nodeRedirects: (project: BlumeProject) => NodeRedirects;
44
+ /** What the wrapper needs beyond the header rules. */
45
+ export interface NodeEntryOptions {
46
+ /** `deployment.base`, normalized (`""` at the root). */
47
+ base?: string;
48
+ /** The configured redirects, from {@link nodeRedirects}. */
49
+ redirects?: NodeRedirects;
50
+ }
51
+ /**
52
+ * The entry that replaces Astro's: it answers a configured redirect with its
53
+ * exact status, and otherwise stamps the rules' headers on the response and
54
+ * hands the request to Astro's handler. `send` leaves a Content-Type that is
55
+ * already set alone, so the registered media type wins.
56
+ *
57
+ * A rule matches the file the static handler will serve, not the raw URL:
58
+ * Astro strips the base when it leads the path and serves the rest from the
59
+ * client directory either way, and `send` decodes and normalizes the path —
60
+ * so `/docs/blume-assets/a.sv%67`, `/blume-assets/a.svg`, and
61
+ * `/docs//x/../blume-assets/a.svg` are all the same SVG. The comparison
62
+ * ignores case, as a case-insensitive disk and `send`'s MIME lookup do.
29
63
  *
30
64
  * It keeps Astro's contract — the `handler`, `options`, and `startServer`
31
65
  * exports `astro preview` and a middleware-mode host import — and its
32
66
  * autostart: Astro's entry is imported with autostart off (the env var is read
33
67
  * when that module evaluates, so the import has to be dynamic), and the
34
- * wrapper starts the server itself with its listener in front of Astro's.
68
+ * wrapper starts the server itself, taking over its request listener so a
69
+ * redirect is answered before Astro sees the request.
35
70
  */
36
- export declare const nodeEntryWrapper: (rules: readonly NodeHeaderRule[]) => string;
71
+ export declare const nodeEntryWrapper: (rules: readonly NodeHeaderRule[], options?: NodeEntryOptions) => string;
37
72
  /**
38
- * Put the header wrapper in front of a Node server build's entry. A build
39
- * with no rule (no API catalog, AI catalog, MCP server, signatures directory,
40
- * or downloaded content assets) leaves Astro's entry alone.
73
+ * Put the wrapper in front of a Node server build's entry. A build with no
74
+ * rule (no API catalog, AI catalog, MCP server, signatures directory, or
75
+ * downloaded content assets) and no redirect leaves Astro's entry alone.
41
76
  */
42
77
  export declare const wrapNodeEntry: (project: BlumeProject, log: BuildLog) => Promise<void>;
@@ -1,6 +1,31 @@
1
- import type { DeployPlatform, RedirectFile } from "./types.ts";
2
- /** `_redirects`, the format Netlify and Cloudflare Pages/Workers read. */
1
+ import type { BlumeProject } from "../../core/project-graph.ts";
2
+ import type { BuildLog, DeployPlatform, RedirectFile } from "./types.ts";
3
+ /**
4
+ * `_redirects`, the format Netlify and Cloudflare Pages/Workers read, in the
5
+ * form both accept: a static build for Cloudflare, or for no named host.
6
+ */
3
7
  export declare const REDIRECTS_FILE: RedirectFile;
8
+ /**
9
+ * `_redirects` for a `netlify()` static build, every rule forced (`301!`).
10
+ * Astro writes a redirect page at each `from` (`dist/old/index.html`), and
11
+ * Netlify serves a file that exists ahead of an unforced rule, so without the
12
+ * flag that page would answer with a 200 instead of the redirect.
13
+ */
14
+ export declare const NETLIFY_REDIRECTS_FILE: RedirectFile;
15
+ /** The Frameworks API config, once the build surfaced it to the project root. */
16
+ export declare const NETLIFY_CONFIG_FILE: string;
17
+ /**
18
+ * Carry the static header rules into a server build. A static `netlify()`
19
+ * build gets them from `_headers` (see `deploy/artifacts.ts`), but a server
20
+ * build's header rules go in the Frameworks API config the adapter writes
21
+ * (`.netlify/v1/config.json`, beside its own `Cache-Control` rule for
22
+ * `/_astro/*`), which follows the same rules as `netlify.toml`'s
23
+ * `[[headers]]`: the charset on the raw Markdown and text files, the homepage
24
+ * `Link` header, the discovery files' media types and CORS header, and the
25
+ * sandbox on downloaded SVGs, which Netlify serves from the publish directory
26
+ * as static files, so the prerendered endpoint's own headers never ship.
27
+ */
28
+ export declare const emitNetlifyHeaders: (project: BlumeProject, log: BuildLog) => Promise<void>;
4
29
  /**
5
30
  * Netlify. A server build runs on Netlify Functions from the Frameworks API
6
31
  * tree the adapter writes to `.netlify/v1`, relative to the Astro root —
@@ -2,10 +2,11 @@ import type { DeployPlatform } from "./types.ts";
2
2
  /**
3
3
  * A self-hosted Node server. The standalone server in `dist/server` serves
4
4
  * `dist/client` through its own static handler, which has no `_headers` or
5
- * `_redirects` support — redirects are answered at request time from the
6
- * Astro config, and a header file written there would be inert. The headers
7
- * the discovery files need come from a wrapper around the server entry
8
- * instead (`deploy/node-headers.ts`). No platform env to detect: the site URL
9
- * has to be configured.
5
+ * `_redirects` support, so a file written there would be inert. A wrapper
6
+ * around the server entry (`deploy/node-headers.ts`) sets the headers the
7
+ * discovery files and downloaded SVGs need instead, and answers the
8
+ * configured redirects with their exact status, which Astro's own handler
9
+ * would default to 301 or 308. No platform env to detect: the site URL has to
10
+ * be configured.
10
11
  */
11
12
  export declare const nodePlatform: DeployPlatform;
@@ -89,6 +89,13 @@ export interface DeployPlatform {
89
89
  kind: DeployAdapterKind;
90
90
  /** Whether a server build honors `Accept: text/markdown` at the content URLs. */
91
91
  negotiatesMarkdown: boolean;
92
+ /**
93
+ * The host CLI command that deploys a preview, for a platform whose
94
+ * `@astrojs/*` adapter has no local preview server: Astro's `preview`
95
+ * throws for its server build, so `blume preview` points here instead. Null
96
+ * when the adapter can preview a server build locally, or there is none.
97
+ */
98
+ previewDeploy: string | null;
92
99
  /**
93
100
  * Whether the platform applies a `_headers` file to the static assets it
94
101
  * serves, per output mode.
@@ -26,7 +26,8 @@ export declare const emitVercelNegotiation: (project: BlumeProject, log: BuildLo
26
26
  * `@vercel/nft` dependency trace is rooted there too, and tracing from the
27
27
  * hidden runtime silently drops the function's chunks and `node_modules`.
28
28
  * Static assets are served from the tree's `static/` half, so the deploy
29
- * artifacts are written there; headers arrive through the routing config
30
- * rather than a `_headers` file, which Vercel never reads.
29
+ * artifacts are written there; headers (the discovery files', the sandbox on
30
+ * downloaded SVGs) arrive through the routing config rather than a
31
+ * `_headers` file, which Vercel never reads.
31
32
  */
32
33
  export declare const vercelPlatform: DeployPlatform;
@@ -38,8 +38,13 @@ export declare const applyBaseToPlatformRedirects: (redirects: Redirect[], baseP
38
38
  * exemptions both compare these paths against real served URLs.
39
39
  */
40
40
  export declare const platformRedirects: (config: ResolvedConfig) => Redirect[];
41
- /** `_redirects` text (Netlify + Cloudflare Pages): `from to status` per line. */
42
- export declare const buildNetlifyRedirects: (redirects: Redirect[]) => string;
41
+ /**
42
+ * `_redirects` text (Netlify + Cloudflare Pages): `from to status` per line.
43
+ * `force` appends Netlify's `!` to each status (`301!`), so the rule wins over
44
+ * the redirect page Astro writes at `from`; Cloudflare, which always applies
45
+ * its rules first, rejects a line carrying it.
46
+ */
47
+ export declare const buildNetlifyRedirects: (redirects: Redirect[], force?: boolean) => string;
43
48
  /**
44
49
  * `vercel.json` contents with a `redirects` array, and a `headers` array when
45
50
  * header rules are given (see `buildVercelHeaders`). Uses `statusCode` (Vercel's
@@ -101,9 +101,10 @@ export declare const buildNegotiationRoutes: (routePaths: readonly string[], hom
101
101
  * `404.md`, `notFound.json` for `404.json`), its routes go into the miss
102
102
  * phase right before the adapter's `/404.html` fallback — and nowhere when
103
103
  * that fallback is absent, since a `dest` with no file behind it would serve
104
- * nothing. Returns the updated JSON
104
+ * nothing. With `svgAssets`, a main-phase route also sandboxes the SVGs a
105
+ * content source downloaded (see {@link svgAssetRoute}). Returns the updated JSON
105
106
  * text (tab-indented, like the adapter's own output), or `null` when there is
106
107
  * nowhere safe to splice: an unparsable config, no `routes` array, or no
107
108
  * `handle: "filesystem"` marker to anchor the splice.
108
109
  */
109
- export declare const injectNegotiationRoutes: (configText: string, routePaths: readonly string[], homeLinkHeader?: string | null, contentTypeOverrides?: Record<string, string>, homeTokens?: number, notFound?: NotFoundVariants, corsPaths?: readonly string[]) => string | null;
110
+ export declare const injectNegotiationRoutes: (configText: string, routePaths: readonly string[], homeLinkHeader?: string | null, contentTypeOverrides?: Record<string, string>, homeTokens?: number, notFound?: NotFoundVariants, corsPaths?: readonly string[], svgAssets?: boolean) => string | null;
@@ -1,5 +1,5 @@
1
1
  import type { Document, OperationObject } from "@scalar/openapi-types/3.1";
2
- import type { AsyncApiAction, AsyncApiDocument } from "./asyncapi.ts";
2
+ import type { AsyncApiAction, AsyncApiDocument, AsyncApiSpecValue } from "./asyncapi.ts";
3
3
  import type { GraphqlDocument, GraphqlMember } from "./graphql.ts";
4
4
  import type { ReferenceKind } from "./references.ts";
5
5
  export { slugify } from "./references.ts";
@@ -46,7 +46,10 @@ export interface ApiOperationRef {
46
46
  /** The channel the operation acts on (AsyncAPI only). */
47
47
  channelId?: string;
48
48
  }
49
- /** A tag/section, in first-seen order. */
49
+ /**
50
+ * A tag/section: the spec's declared tags in their declared order, then any
51
+ * undeclared tag an operation uses, in first-seen order.
52
+ */
50
53
  export interface ApiTagRef {
51
54
  slug: string;
52
55
  name: string;
@@ -114,6 +117,15 @@ export interface SpecAddresses {
114
117
  * live endpoint stands in.
115
118
  */
116
119
  export declare const specAddresses: (spec: ApiSpecData) => SpecAddresses;
120
+ /**
121
+ * A server URL template — an OpenAPI `servers[].url`, an AsyncAPI server's
122
+ * `host` or `pathname` — with each `{variable}` replaced by the `default` its
123
+ * `variables` map declares. Code samples, the playground's Send, and the
124
+ * proxy allowlist all need a real address, and
125
+ * `https://{region}.api.example.com` is not one. A variable the map doesn't
126
+ * define with a default (invalid per both specs) stays templated.
127
+ */
128
+ export declare const withServerDefaults: (template: string, variables: AsyncApiSpecValue) => string;
117
129
  /**
118
130
  * Assign each distinct tag name a unique slug. `slugify` can collapse
119
131
  * different names onto one value — any two punctuation-only tags (`!!!`,
@@ -142,16 +154,18 @@ export interface ExtractedOperations extends CollectedOperations {
142
154
  }
143
155
  /**
144
156
  * The collector behind both extractors (OpenAPI here, AsyncAPI in
145
- * `asyncapi.ts`): first-seen tag ordering, key de-duplication (a repeated key
146
- * gains its method/action as a suffix), and the shared route template — so
147
- * URL shape and slug rules can never drift between the two spec kinds.
157
+ * `asyncapi.ts`): declared-then-first-seen tag ordering, key de-duplication
158
+ * (a repeated key gains its method/action as a suffix), and the shared route
159
+ * template — so URL shape and slug rules can never drift between the two spec
160
+ * kinds.
148
161
  */
149
162
  export declare const operationCollector: (baseRoute: string, tagMeta: ReadonlyMap<string, string>) => OperationCollector;
150
163
  /**
151
164
  * Flatten a 3.1 document into a route-mapped operation list and its ordered
152
165
  * tags. Operations inherit the first tag they declare; keys are de-duplicated so
153
166
  * a repeated `operationId` still yields distinct routes. `warnings` reports
154
- * anything skipped (a `$ref` path item), so missing operations aren't silent.
167
+ * anything skipped (a `$ref` path item, webhooks), so missing operations
168
+ * aren't silent.
155
169
  */
156
170
  export declare const extractOperations: (document: ApiDocument, baseRoute: string) => ExtractedOperations;
157
171
  /** Resolve the operation object for a ref out of its (OpenAPI) document. */
@@ -9,6 +9,8 @@ export type AlgoliaSyncConfig = Pick<AlgoliaOptions, "appId" | "indexName">;
9
9
  *
10
10
  * Uses `replaceAllObjects`, which atomically replaces the index contents, so
11
11
  * pages deleted or renamed since the last sync don't linger as stale search
12
- * hits that 404 when clicked.
12
+ * hits that 404 when clicked. Then adds `filterOnly(locale)` and
13
+ * `filterOnly(version)` to the index's `attributesForFaceting`, keeping any
14
+ * the site declared itself, so the dialog's locale and version filters match.
13
15
  */
14
16
  export declare const syncAlgolia: (records: SearchRecord[], config: AlgoliaSyncConfig) => Promise<void>;
@@ -23,11 +23,12 @@ Go from an empty folder to a running docs site in a few commands. Blume needs **
23
23
  npx blume init
24
24
  ```
25
25
 
26
- On pnpm 12, add `--allow-build=esbuild` after `pnpm dlx` (`pnpm dlx --allow-build=esbuild blume init`): pnpm 12 refuses to run the install script of esbuild, which Astro depends on, unless you approve it. Inside an existing pnpm workspace, add `allowBuilds: { esbuild: true }` to the workspace's `pnpm-workspace.yaml`; `init` reminds you. With Yarn 2 or later, `init` writes a `.yarnrc.yml` that switches Yarn to a `node_modules` install, which Blume needs; on Yarn 1, run `npx blume init`.
26
+ On pnpm 12, add `--allow-build=esbuild` after `pnpm dlx` (`pnpm dlx --allow-build=esbuild blume init`): pnpm 12 refuses to run the install script of esbuild, which Astro depends on, unless you approve it. Inside an existing pnpm workspace, the new folder must be listed under the workspace's `packages` (pnpm installs nothing else, so `init` skips the install until it is), and esbuild needs `allowBuilds: { esbuild: true }` in the workspace's `pnpm-workspace.yaml`; `init` reminds you of both. With Yarn 2 or later, `init` writes a `.yarnrc.yml` that switches Yarn to a `node_modules` install, which Blume needs; on Yarn 1, run `npx blume init`.
27
27
 
28
28
  ```txt
29
29
  docs/
30
30
  index.mdx
31
+ .gitignore
31
32
  blume.config.ts
32
33
  package.json
33
34
  ```
@@ -52,7 +53,7 @@ Go from an empty folder to a running docs site in a few commands. Blume needs **
52
53
  </Step>
53
54
  </Steps>
54
55
 
55
- Adding Blume to a project that already has a `package.json`? `blume init` leaves existing files alone, so add `"dev": "blume dev"` and `"build": "blume build"` to its scripts, or run `npx blume dev` directly.
56
+ Adding Blume to a project that already has a `package.json`? `blume init` leaves existing files alone and skips the install, so install Blume yourself (`npm install blume`), then add `"dev": "blume dev"` and `"build": "blume build"` to its scripts, or run `npx blume dev` directly. The next steps `init` prints include both commands for your package manager.
56
57
 
57
58
  :::tip
58
59
  Blume works with any package manager and never requires you to set up Astro or Tailwind yourself.