blume 1.7.3 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (673) hide show
  1. package/AGENTS.md +19 -0
  2. package/CHANGELOG.md +217 -0
  3. package/README.md +34 -21
  4. package/dist/cli/chunk-11j0384y.js +148 -0
  5. package/dist/cli/chunk-11j0384y.js.map +10 -0
  6. package/dist/cli/{chunk-rqy0s5wh.js → chunk-1w8dp3qb.js} +17 -16
  7. package/dist/cli/{chunk-rqy0s5wh.js.map → chunk-1w8dp3qb.js.map} +3 -3
  8. package/dist/cli/chunk-2q1dwty4.js +75 -0
  9. package/dist/cli/chunk-2q1dwty4.js.map +11 -0
  10. package/dist/cli/chunk-41za066z.js +122 -0
  11. package/dist/cli/chunk-41za066z.js.map +11 -0
  12. package/dist/cli/chunk-5a2z0198.js +133 -0
  13. package/dist/cli/chunk-5a2z0198.js.map +10 -0
  14. package/dist/cli/{chunk-5g0w1e2c.js → chunk-6k8vp3ta.js} +25 -13
  15. package/dist/cli/{chunk-5g0w1e2c.js.map → chunk-6k8vp3ta.js.map} +4 -4
  16. package/dist/cli/{chunk-5qk08vmp.js → chunk-79njf86q.js} +133 -54
  17. package/dist/cli/chunk-79njf86q.js.map +11 -0
  18. package/dist/cli/{chunk-e7f42gdj.js → chunk-7ez8ny0t.js} +2 -2
  19. package/dist/cli/{chunk-nn13znc2.js → chunk-88cpgt6h.js} +1 -1
  20. package/dist/cli/chunk-a9kptbw5.js +361 -0
  21. package/dist/cli/chunk-a9kptbw5.js.map +14 -0
  22. package/dist/cli/chunk-abh8yjkn.js +31 -0
  23. package/dist/cli/chunk-abh8yjkn.js.map +10 -0
  24. package/dist/cli/chunk-b5aj94ah.js +91 -0
  25. package/dist/cli/chunk-b5aj94ah.js.map +10 -0
  26. package/dist/cli/{chunk-b27xqwn9.js → chunk-bctazmbk.js} +9 -5
  27. package/dist/cli/chunk-bctazmbk.js.map +10 -0
  28. package/dist/cli/chunk-beat36xx.js +279 -0
  29. package/dist/cli/chunk-beat36xx.js.map +10 -0
  30. package/dist/cli/chunk-bnbmcwfb.js +145 -0
  31. package/dist/cli/chunk-bnbmcwfb.js.map +11 -0
  32. package/dist/cli/{chunk-0xjyb285.js → chunk-bw22s759.js} +15 -5
  33. package/dist/cli/{chunk-0xjyb285.js.map → chunk-bw22s759.js.map} +4 -4
  34. package/dist/cli/chunk-by2290sx.js +39 -0
  35. package/dist/cli/chunk-by2290sx.js.map +10 -0
  36. package/dist/cli/chunk-d1tadaw7.js +79 -0
  37. package/dist/cli/chunk-d1tadaw7.js.map +10 -0
  38. package/dist/cli/{chunk-ahnw3kxw.js → chunk-d80hr03s.js} +24 -19
  39. package/dist/cli/chunk-d80hr03s.js.map +15 -0
  40. package/dist/cli/chunk-ernrthtr.js +97 -0
  41. package/dist/cli/chunk-ernrthtr.js.map +10 -0
  42. package/dist/cli/chunk-f2972sbt.js +374 -0
  43. package/dist/cli/chunk-f2972sbt.js.map +10 -0
  44. package/dist/cli/{chunk-vacwm2hv.js → chunk-f7t03s3g.js} +2 -2
  45. package/dist/cli/{chunk-2z47ypj8.js → chunk-fa25z98p.js} +16 -3
  46. package/dist/cli/chunk-fa25z98p.js.map +11 -0
  47. package/dist/cli/{chunk-cjtn640a.js → chunk-fh5hj5jt.js} +43 -20
  48. package/dist/cli/chunk-fh5hj5jt.js.map +10 -0
  49. package/dist/cli/{chunk-yg63d42r.js → chunk-j8mw0za6.js} +86 -57
  50. package/dist/cli/chunk-j8mw0za6.js.map +35 -0
  51. package/dist/cli/{chunk-ct47dqpx.js → chunk-jts8mvcz.js} +67 -7
  52. package/dist/cli/{chunk-2mzebbbz.js.map → chunk-jts8mvcz.js.map} +6 -4
  53. package/dist/cli/{chunk-ps4m1xh4.js → chunk-mnqj32sj.js} +505 -542
  54. package/dist/cli/chunk-mnqj32sj.js.map +12 -0
  55. package/dist/cli/{chunk-8cjtbafj.js → chunk-mwt1k8n7.js} +100 -374
  56. package/dist/cli/chunk-mwt1k8n7.js.map +10 -0
  57. package/dist/cli/chunk-nk3ts2xk.js +51 -0
  58. package/dist/cli/chunk-nk3ts2xk.js.map +10 -0
  59. package/dist/cli/{chunk-3r45185y.js → chunk-pat2zzwc.js} +9 -11
  60. package/dist/cli/{chunk-3r45185y.js.map → chunk-pat2zzwc.js.map} +2 -2
  61. package/dist/cli/chunk-pnnvybbk.js +176 -0
  62. package/dist/cli/chunk-pnnvybbk.js.map +11 -0
  63. package/dist/cli/{chunk-4x36ddpw.js → chunk-sqn5t4q0.js} +81 -87
  64. package/dist/cli/chunk-sqn5t4q0.js.map +10 -0
  65. package/dist/cli/{chunk-bvwwhd84.js → chunk-tzne8qfq.js} +15 -15
  66. package/dist/cli/{chunk-bvwwhd84.js.map → chunk-tzne8qfq.js.map} +1 -1
  67. package/dist/cli/chunk-xaz13gwg.js +12449 -0
  68. package/dist/cli/chunk-xaz13gwg.js.map +182 -0
  69. package/dist/cli/chunk-y3e45rc8.js +102 -0
  70. package/dist/cli/chunk-y3e45rc8.js.map +10 -0
  71. package/dist/cli/chunk-z01ze5c1.js +261 -0
  72. package/dist/cli/chunk-z01ze5c1.js.map +10 -0
  73. package/dist/cli/{chunk-k79xp7av.js → chunk-z1f5arsg.js} +219 -689
  74. package/dist/cli/chunk-z1f5arsg.js.map +36 -0
  75. package/dist/cli/{chunk-1jefwnfs.js → chunk-zg2gtj10.js} +1076 -2592
  76. package/dist/cli/chunk-zg2gtj10.js.map +35 -0
  77. package/dist/cli/{chunk-dwgcp5sm.js → chunk-zxccj738.js} +1 -1
  78. package/dist/cli/index.js +214 -57
  79. package/dist/cli/index.js.map +8 -7
  80. package/dist/types/ai/agent-readability.d.ts +52 -0
  81. package/dist/types/ai/ai-catalog.d.ts +42 -0
  82. package/dist/types/ai/api/paths.d.ts +17 -0
  83. package/dist/types/ai/api-catalog.d.ts +18 -0
  84. package/dist/types/ai/ask.d.ts +368 -0
  85. package/dist/types/ai/changelog-markdown.d.ts +2 -0
  86. package/dist/types/ai/component-markdown.d.ts +2 -2
  87. package/dist/types/ai/index.d.ts +24 -0
  88. package/dist/types/ai/link-headers.d.ts +24 -0
  89. package/dist/types/ai/llms.d.ts +25 -0
  90. package/dist/types/ai/markdown.d.ts +45 -0
  91. package/dist/types/ai/mcp/discovery.d.ts +68 -0
  92. package/dist/types/ai/mcp/tools.d.ts +16 -0
  93. package/dist/types/ai/openapi-components.d.ts +43 -0
  94. package/dist/types/ai/relative-links.d.ts +26 -0
  95. package/dist/types/ai/serializers.d.ts +15 -0
  96. package/dist/types/ai/skills.d.ts +42 -0
  97. package/dist/types/ai/tar.d.ts +25 -0
  98. package/dist/types/ai/visibility.d.ts +17 -0
  99. package/dist/types/ai/web-bot-auth.d.ts +16 -0
  100. package/dist/types/analytics/adobe.d.ts +35 -0
  101. package/dist/types/analytics/amplitude.d.ts +50 -0
  102. package/dist/types/analytics/clarity.d.ts +31 -0
  103. package/dist/types/analytics/clearbit.d.ts +29 -0
  104. package/dist/types/analytics/cloudflare.d.ts +41 -0
  105. package/dist/types/analytics/fathom.d.ts +41 -0
  106. package/dist/types/analytics/google-analytics.d.ts +44 -0
  107. package/dist/types/analytics/google-tag-manager.d.ts +40 -0
  108. package/dist/types/analytics/head.d.ts +30 -0
  109. package/dist/types/analytics/heap.d.ts +40 -0
  110. package/dist/types/analytics/hightouch.d.ts +44 -0
  111. package/dist/types/analytics/hotjar.d.ts +33 -0
  112. package/dist/types/analytics/index.d.ts +61 -0
  113. package/dist/types/analytics/inline.d.ts +17 -0
  114. package/dist/types/analytics/logrocket.d.ts +44 -0
  115. package/dist/types/analytics/mixpanel.d.ts +67 -0
  116. package/dist/types/analytics/pirsch.d.ts +42 -0
  117. package/dist/types/analytics/plausible.d.ts +56 -0
  118. package/dist/types/analytics/posthog.d.ts +45 -0
  119. package/dist/types/analytics/schema.d.ts +320 -0
  120. package/dist/types/analytics/script.d.ts +46 -0
  121. package/dist/types/analytics/segment.d.ts +50 -0
  122. package/dist/types/analytics/vercel.d.ts +48 -0
  123. package/dist/types/astro/integration.d.ts +76 -0
  124. package/dist/types/astro/markdown-negotiation.d.ts +23 -0
  125. package/dist/types/astro/module-types.d.ts +14 -0
  126. package/dist/types/astro/pages.d.ts +44 -0
  127. package/dist/types/cli/env.d.ts +12 -0
  128. package/dist/types/cli/init/scaffold.d.ts +154 -0
  129. package/dist/types/components/layout/nav-utils.d.ts +11 -0
  130. package/dist/types/core/adapter.d.ts +47 -0
  131. package/dist/types/core/api-name.d.ts +7 -0
  132. package/dist/types/core/changelog-index.d.ts +13 -0
  133. package/dist/types/core/config-input.d.ts +186 -515
  134. package/dist/types/core/config.d.ts +60 -34
  135. package/dist/types/core/content-assets.d.ts +76 -0
  136. package/dist/types/core/custom-pages.d.ts +33 -0
  137. package/dist/types/core/data.d.ts +27 -12
  138. package/dist/types/core/define-components.d.ts +12 -9
  139. package/dist/types/core/deployment-env.d.ts +6 -11
  140. package/dist/types/core/frontmatter.d.ts +10 -0
  141. package/dist/types/core/graph.d.ts +18 -0
  142. package/dist/types/core/heading-markers.d.ts +54 -0
  143. package/dist/types/core/i18n-ui.d.ts +6 -2
  144. package/dist/types/core/i18n.d.ts +87 -0
  145. package/dist/types/core/includes.d.ts +138 -0
  146. package/dist/types/core/last-modified.d.ts +47 -0
  147. package/dist/types/core/links.d.ts +95 -0
  148. package/dist/types/core/locale-links.d.ts +60 -0
  149. package/dist/types/core/manifest.d.ts +17 -0
  150. package/dist/types/core/meta.d.ts +38 -0
  151. package/dist/types/core/nav-diagnostics.d.ts +26 -0
  152. package/dist/types/core/navigation.d.ts +6 -0
  153. package/dist/types/core/node-require.d.ts +19 -0
  154. package/dist/types/core/package-json.d.ts +13 -0
  155. package/dist/types/core/probe.d.ts +42 -0
  156. package/dist/types/core/project-graph.d.ts +51 -0
  157. package/dist/types/core/project.d.ts +2 -0
  158. package/dist/types/core/safe-href.d.ts +2 -0
  159. package/dist/types/core/safe-links.d.ts +26 -0
  160. package/dist/types/core/schema.d.ts +2282 -452
  161. package/dist/types/core/site-url.d.ts +16 -0
  162. package/dist/types/core/sources/assets.d.ts +36 -0
  163. package/dist/types/core/sources/cache.d.ts +37 -0
  164. package/dist/types/core/sources/collection.d.ts +28 -0
  165. package/dist/types/core/sources/contentful-rich-text.d.ts +31 -0
  166. package/dist/types/core/sources/contentful.d.ts +40 -0
  167. package/dist/types/core/sources/filesystem.d.ts +24 -0
  168. package/dist/types/core/sources/github-releases.d.ts +31 -0
  169. package/dist/types/core/sources/json.d.ts +30 -0
  170. package/dist/types/core/sources/lexical.d.ts +19 -0
  171. package/dist/types/core/sources/lower.d.ts +75 -0
  172. package/dist/types/core/sources/mdx-remote.d.ts +28 -0
  173. package/dist/types/core/sources/normalize.d.ts +147 -0
  174. package/dist/types/core/sources/notion.d.ts +131 -0
  175. package/dist/types/core/sources/obsidian.d.ts +46 -0
  176. package/dist/types/core/sources/payload.d.ts +39 -0
  177. package/dist/types/core/sources/portable-text.d.ts +42 -0
  178. package/dist/types/core/sources/read.d.ts +23 -0
  179. package/dist/types/core/sources/remote.d.ts +74 -0
  180. package/dist/types/core/sources/resolve.d.ts +19 -0
  181. package/dist/types/core/sources/sanity.d.ts +43 -0
  182. package/dist/types/core/sources/strapi-blocks.d.ts +12 -0
  183. package/dist/types/core/sources/strapi.d.ts +33 -0
  184. package/dist/types/core/sources/types.d.ts +7 -0
  185. package/dist/types/core/sources/watch.d.ts +45 -0
  186. package/dist/types/core/text-width.d.ts +11 -0
  187. package/dist/types/core/types.d.ts +15 -1
  188. package/dist/types/core/unrecognized-keys.d.ts +7 -0
  189. package/dist/types/core/versions.d.ts +72 -0
  190. package/dist/types/core/yaml.d.ts +9 -0
  191. package/dist/types/deploy/adapter-output.d.ts +45 -0
  192. package/dist/types/deploy/adapters/cloudflare.d.ts +40 -0
  193. package/dist/types/deploy/adapters/index.d.ts +29 -0
  194. package/dist/types/deploy/adapters/netlify.d.ts +37 -0
  195. package/dist/types/deploy/adapters/node.d.ts +37 -0
  196. package/dist/types/deploy/adapters/registry.d.ts +133 -0
  197. package/dist/types/deploy/adapters/types.d.ts +71 -0
  198. package/dist/types/deploy/adapters/vercel.d.ts +38 -0
  199. package/dist/types/deploy/artifacts.d.ts +65 -0
  200. package/dist/types/deploy/cloudflare-negotiation.d.ts +196 -0
  201. package/dist/types/deploy/function-bundle.d.ts +80 -0
  202. package/dist/types/deploy/headers.d.ts +50 -0
  203. package/dist/types/deploy/node-headers.d.ts +42 -0
  204. package/dist/types/deploy/platforms/cloudflare.d.ts +40 -0
  205. package/dist/types/deploy/platforms/index.d.ts +18 -0
  206. package/dist/types/deploy/platforms/netlify.d.ts +13 -0
  207. package/dist/types/deploy/platforms/node.d.ts +11 -0
  208. package/dist/types/deploy/platforms/paths.d.ts +27 -0
  209. package/dist/types/deploy/platforms/static.d.ts +10 -0
  210. package/dist/types/deploy/platforms/types.d.ts +104 -0
  211. package/dist/types/deploy/platforms/vercel.d.ts +32 -0
  212. package/dist/types/deploy/redirects.d.ts +53 -0
  213. package/dist/types/deploy/robots.d.ts +8 -0
  214. package/dist/types/deploy/rss.d.ts +31 -0
  215. package/dist/types/deploy/sitemap.d.ts +21 -0
  216. package/dist/types/deploy/vercel-negotiation.d.ts +109 -0
  217. package/dist/types/markdown/code-title.d.ts +32 -0
  218. package/dist/types/markdown/fence-meta.d.ts +23 -0
  219. package/dist/types/markdown/themes.d.ts +3 -3
  220. package/dist/types/openapi/asyncapi.d.ts +129 -0
  221. package/dist/types/openapi/graphql-build.d.ts +8 -0
  222. package/dist/types/openapi/graphql.d.ts +122 -0
  223. package/dist/types/openapi/model.d.ts +158 -0
  224. package/dist/types/openapi/parse.d.ts +57 -0
  225. package/dist/types/openapi/references.d.ts +37 -25
  226. package/dist/types/openapi/render-mdx.d.ts +33 -0
  227. package/dist/types/openapi/sentence.d.ts +7 -0
  228. package/dist/types/openapi/signature.d.ts +10 -0
  229. package/dist/types/openapi/source.d.ts +22 -0
  230. package/dist/types/openapi/spec-dependency-error.d.ts +10 -0
  231. package/dist/types/reference/asyncapi.d.ts +166 -0
  232. package/dist/types/reference/graphql.d.ts +181 -0
  233. package/dist/types/reference/index.d.ts +32 -0
  234. package/dist/types/reference/openapi.d.ts +165 -0
  235. package/dist/types/reference/options.d.ts +157 -0
  236. package/dist/types/reference/scalar.d.ts +136 -0
  237. package/dist/types/reference/schema.d.ts +630 -0
  238. package/dist/types/search/adapters/algolia.d.ts +32 -0
  239. package/dist/types/search/adapters/flexsearch.d.ts +12 -0
  240. package/dist/types/search/adapters/index.d.ts +31 -0
  241. package/dist/types/search/adapters/mixedbread.d.ts +22 -0
  242. package/dist/types/search/adapters/orama-cloud.d.ts +33 -0
  243. package/dist/types/search/adapters/orama.d.ts +13 -0
  244. package/dist/types/search/adapters/pagefind.d.ts +12 -0
  245. package/dist/types/search/adapters/registry.d.ts +228 -0
  246. package/dist/types/search/adapters/types.d.ts +34 -0
  247. package/dist/types/search/adapters/typesense.d.ts +42 -0
  248. package/dist/types/search/build.d.ts +23 -0
  249. package/dist/types/search/documents.d.ts +90 -0
  250. package/dist/types/search/facets.d.ts +3 -0
  251. package/dist/types/search/sync/algolia.d.ts +14 -0
  252. package/dist/types/search/sync/index.d.ts +14 -0
  253. package/dist/types/search/sync/orama-cloud.d.ts +10 -0
  254. package/dist/types/search/sync/typesense.d.ts +14 -0
  255. package/dist/types/sources/contentful.d.ts +68 -0
  256. package/dist/types/sources/custom.d.ts +20 -0
  257. package/dist/types/sources/filesystem.d.ts +42 -0
  258. package/dist/types/sources/github-releases.d.ts +46 -0
  259. package/dist/types/sources/index.d.ts +48 -0
  260. package/dist/types/sources/mdx-remote.d.ts +63 -0
  261. package/dist/types/sources/notion.d.ts +65 -0
  262. package/dist/types/sources/obsidian.d.ts +34 -0
  263. package/dist/types/sources/payload.d.ts +68 -0
  264. package/dist/types/sources/registry.d.ts +1414 -0
  265. package/dist/types/sources/sanity.d.ts +69 -0
  266. package/dist/types/sources/shared.d.ts +46 -0
  267. package/dist/types/sources/strapi.d.ts +66 -0
  268. package/dist/types/theme/icon-kind.d.ts +11 -0
  269. package/dist/types/theme/icons.d.ts +20 -0
  270. package/docs/01-quickstart.mdx +18 -18
  271. package/docs/02-deployment.mdx +50 -26
  272. package/docs/03-upgrading.mdx +351 -0
  273. package/docs/04-migrating.mdx +58 -0
  274. package/docs/08-faq.mdx +3 -3
  275. package/docs/advanced/blog.mdx +13 -6
  276. package/docs/advanced/changelog.mdx +23 -35
  277. package/docs/advanced/custom-pages.mdx +20 -8
  278. package/docs/advanced/meta.ts +1 -8
  279. package/docs/advanced/skills.mdx +8 -0
  280. package/docs/cli/audit.mdx +646 -0
  281. package/docs/cli/doctor.mdx +29 -0
  282. package/docs/{reference/eval.mdx → cli/evals.mdx} +9 -8
  283. package/docs/cli/index.mdx +105 -0
  284. package/docs/cli/meta.ts +7 -0
  285. package/docs/{reference → cli}/translate.mdx +1 -1
  286. package/docs/cli/validate.mdx +41 -0
  287. package/docs/cli/version.mdx +40 -0
  288. package/docs/configuration/analytics.mdx +350 -59
  289. package/docs/configuration/ask-ai.mdx +162 -61
  290. package/docs/configuration/customization.mdx +15 -9
  291. package/docs/configuration/index.mdx +50 -31
  292. package/docs/configuration/search.mdx +75 -54
  293. package/docs/configuration/theming.mdx +24 -15
  294. package/docs/content/components.mdx +21 -5
  295. package/docs/{reference → content}/frontmatter.mdx +35 -1
  296. package/docs/content/i18n.mdx +8 -6
  297. package/docs/content/includes.mdx +2 -4
  298. package/docs/content/index.mdx +1 -1
  299. package/docs/content/islands.mdx +10 -5
  300. package/docs/content/meta.mdx +1 -1
  301. package/docs/content/meta.ts +1 -0
  302. package/docs/content/navigation.mdx +9 -7
  303. package/docs/content/sources.mdx +145 -50
  304. package/docs/content/syntax.mdx +16 -12
  305. package/docs/content/versioning.mdx +3 -3
  306. package/docs/discoverability/agent-discovery.mdx +11 -11
  307. package/docs/discoverability/index.mdx +4 -4
  308. package/docs/discoverability/json-api.mdx +4 -4
  309. package/docs/discoverability/llms-txt.mdx +6 -6
  310. package/docs/discoverability/markdown.mdx +4 -4
  311. package/docs/discoverability/mcp.mdx +11 -11
  312. package/docs/discoverability/sitemap-and-robots.mdx +3 -3
  313. package/docs/index.mdx +2 -2
  314. package/docs/references/asyncapi.mdx +59 -0
  315. package/docs/{advanced → references}/graphql.mdx +45 -32
  316. package/docs/{reference → references}/meta.ts +2 -2
  317. package/docs/references/openapi.mdx +171 -0
  318. package/docs/references/scalar.mdx +64 -0
  319. package/package.json +42 -8
  320. package/skills/blume/SKILL.md +21 -8
  321. package/skills/blume-migrate/SKILL.md +22 -21
  322. package/skills/blume-migrate/assets/oxfmt@0.67.0.patch +49 -0
  323. package/skills/blume-migrate/references/docusaurus.md +5 -4
  324. package/skills/blume-migrate/references/fumadocs.md +4 -4
  325. package/skills/blume-migrate/references/mintlify.md +23 -8
  326. package/skills/blume-migrate/references/monorepo.md +6 -6
  327. package/skills/blume-migrate/references/starlight.md +4 -4
  328. package/src/ai/agent-readability.ts +21 -22
  329. package/src/ai/ai-catalog.ts +50 -32
  330. package/src/ai/api/handlers.ts +46 -11
  331. package/src/ai/api-catalog.ts +8 -8
  332. package/src/ai/ask-data.ts +1 -1
  333. package/src/ai/ask.ts +624 -100
  334. package/src/ai/changelog-markdown.ts +91 -0
  335. package/src/ai/component-markdown.ts +328 -12
  336. package/src/ai/index.ts +45 -0
  337. package/src/ai/link-headers.ts +7 -6
  338. package/src/ai/llms.ts +20 -15
  339. package/src/ai/markdown.ts +35 -5
  340. package/src/ai/mcp/data.ts +9 -5
  341. package/src/ai/openapi-components.ts +4 -1
  342. package/src/ai/relative-links.ts +170 -0
  343. package/src/ai/serializers.ts +2 -2
  344. package/src/ai/skills.ts +1 -1
  345. package/src/ai/web-bot-auth.ts +2 -2
  346. package/src/analytics/adobe.ts +46 -0
  347. package/src/analytics/amplitude.ts +79 -0
  348. package/src/analytics/clarity.ts +46 -0
  349. package/src/analytics/clearbit.ts +47 -0
  350. package/src/analytics/cloudflare.ts +67 -0
  351. package/src/analytics/fathom.ts +64 -0
  352. package/src/analytics/google-analytics.ts +84 -0
  353. package/src/analytics/google-tag-manager.ts +61 -0
  354. package/src/analytics/head.ts +130 -0
  355. package/src/analytics/heap.ts +65 -0
  356. package/src/analytics/hightouch.ts +77 -0
  357. package/src/analytics/hotjar.ts +47 -0
  358. package/src/analytics/index.ts +71 -0
  359. package/src/analytics/inline.ts +21 -0
  360. package/src/analytics/logrocket.ts +71 -0
  361. package/src/analytics/mixpanel.ts +92 -0
  362. package/src/analytics/pirsch.ts +66 -0
  363. package/src/analytics/plausible.ts +83 -0
  364. package/src/analytics/posthog.ts +78 -0
  365. package/src/analytics/schema.ts +60 -0
  366. package/src/analytics/script.ts +60 -0
  367. package/src/analytics/segment.ts +85 -0
  368. package/src/analytics/vercel.ts +50 -0
  369. package/src/astro/adapter-root.ts +7 -9
  370. package/src/astro/component-slots.ts +131 -91
  371. package/src/astro/generate.ts +112 -345
  372. package/src/astro/integration.ts +2 -6
  373. package/src/astro/pages.ts +13 -101
  374. package/src/astro/render-deps.ts +379 -0
  375. package/src/astro/runtime-deps.ts +201 -0
  376. package/src/astro/templates.ts +554 -541
  377. package/src/audit/agent.ts +24 -0
  378. package/src/audit/catalog.ts +2 -2
  379. package/src/audit/checks/assets.ts +2 -2
  380. package/src/audit/checks/dns-aid.ts +1 -1
  381. package/src/audit/checks/duplicates.ts +3 -1
  382. package/src/audit/checks/i18n.ts +1 -1
  383. package/src/audit/checks/indexability.ts +7 -7
  384. package/src/audit/checks/links.ts +2 -2
  385. package/src/audit/checks/llms.ts +6 -6
  386. package/src/audit/checks/network.ts +3 -3
  387. package/src/audit/checks/og-image.ts +2 -2
  388. package/src/audit/checks/robots.ts +1 -1
  389. package/src/audit/checks/sitemap.ts +2 -2
  390. package/src/audit/checks/social.ts +1 -1
  391. package/src/audit/run.ts +4 -3
  392. package/src/audit/terms.ts +31 -0
  393. package/src/audit/url.ts +13 -13
  394. package/src/cli/command-meta.ts +10 -0
  395. package/src/cli/commands/audit.ts +39 -20
  396. package/src/cli/commands/build.ts +71 -316
  397. package/src/cli/commands/check.ts +1 -0
  398. package/src/cli/commands/dev.ts +40 -1
  399. package/src/cli/commands/doctor.ts +90 -14
  400. package/src/cli/commands/eject.ts +44 -7
  401. package/src/cli/commands/eval.ts +2 -2
  402. package/src/cli/commands/init.ts +161 -41
  403. package/src/cli/commands/migrate.ts +121 -0
  404. package/src/cli/commands/preview.ts +7 -1
  405. package/src/cli/commands/translate.ts +2 -2
  406. package/src/cli/commands/upgrade.ts +141 -0
  407. package/src/cli/commands/version.ts +57 -44
  408. package/src/cli/eject-scripts.ts +121 -6
  409. package/src/cli/index.ts +11 -1
  410. package/src/cli/init/install.ts +70 -0
  411. package/src/cli/init/questions.ts +7 -0
  412. package/src/cli/init/scaffold.ts +459 -75
  413. package/src/cli/lazy-command.ts +37 -1
  414. package/src/cli/prepare.ts +40 -6
  415. package/src/cli/required-secrets.ts +38 -11
  416. package/src/cli/unknown-flags.ts +266 -0
  417. package/src/cli/yarn-pnp.ts +52 -0
  418. package/src/components/content/AccordionItem.astro +7 -1
  419. package/src/components/content/Card.astro +4 -3
  420. package/src/components/content/ColorItem.astro +22 -4
  421. package/src/components/content/GithubInfo.astro +2 -2
  422. package/src/components/content/Prompt.astro +25 -25
  423. package/src/components/content/Tabs.astro +3 -1
  424. package/src/components/content/Tile.astro +2 -3
  425. package/src/components/content/Tooltip.astro +57 -9
  426. package/src/components/content/content-strings.ts +34 -0
  427. package/src/components/content/diff.ts +1 -1
  428. package/src/components/content/mermaid-element.ts +13 -2
  429. package/src/components/content/prompt-markdown.ts +292 -0
  430. package/src/components/content/tooltip-id.ts +41 -0
  431. package/src/components/islands/hooks.ts +25 -2
  432. package/src/components/layout/Analytics.astro +21 -79
  433. package/src/components/layout/Banner.astro +3 -1
  434. package/src/components/layout/DiscoveryLinks.astro +69 -0
  435. package/src/components/layout/Header.astro +83 -20
  436. package/src/components/layout/LanguageSwitcher.astro +4 -1
  437. package/src/components/layout/Logo.astro +23 -2
  438. package/src/components/layout/NavSelector.astro +13 -2
  439. package/src/components/layout/NavTree.astro +12 -3
  440. package/src/components/layout/NavTreeScript.astro +17 -3
  441. package/src/components/layout/PageActions.astro +3 -3
  442. package/src/components/layout/PageFeedback.astro +11 -1
  443. package/src/components/layout/PageLayout.astro +52 -5
  444. package/src/components/layout/ReferenceLayout.astro +21 -12
  445. package/src/components/layout/RootLayout.astro +69 -66
  446. package/src/components/layout/Search.astro +30 -6
  447. package/src/components/layout/WebMcp.astro +1 -1
  448. package/src/components/layout/analytics-client.ts +72 -15
  449. package/src/components/layout/drawer-inert.ts +113 -15
  450. package/src/components/layout/dropdown-clamp.ts +105 -0
  451. package/src/components/layout/head-scripts.ts +15 -6
  452. package/src/components/layout/nav-utils.ts +17 -0
  453. package/src/components/layout/search/algolia.ts +8 -8
  454. package/src/components/layout/search/orama-cloud.ts +9 -7
  455. package/src/components/layout/search/typesense.ts +11 -17
  456. package/src/components/openapi/MessageComposer.astro +2 -2
  457. package/src/components/openapi/Playground.astro +2 -2
  458. package/src/components/openapi/playground-client.ts +79 -10
  459. package/src/core/changelog-index.ts +24 -0
  460. package/src/core/component-overrides.ts +399 -154
  461. package/src/core/config-input.ts +188 -553
  462. package/src/core/config.ts +130 -41
  463. package/src/core/custom-pages.ts +105 -0
  464. package/src/core/data.ts +31 -12
  465. package/src/core/define-components.ts +12 -9
  466. package/src/core/deployment-env.ts +18 -74
  467. package/src/core/diagnostics.ts +14 -7
  468. package/src/core/graph.ts +69 -25
  469. package/src/core/i18n-ui.ts +6 -2
  470. package/src/core/i18n.ts +17 -0
  471. package/src/core/includes.ts +156 -38
  472. package/src/core/last-modified.ts +6 -11
  473. package/src/core/links.ts +166 -2
  474. package/src/core/manifest.ts +10 -3
  475. package/src/core/navigation.ts +115 -16
  476. package/src/core/new-tab.ts +35 -0
  477. package/src/core/node-require.ts +21 -0
  478. package/src/core/project-graph.ts +42 -26
  479. package/src/core/project.ts +9 -4
  480. package/src/core/request-body.ts +61 -0
  481. package/src/core/safe-href.ts +28 -0
  482. package/src/core/safe-links.ts +68 -0
  483. package/src/core/schema.ts +517 -739
  484. package/src/core/server-features.ts +8 -9
  485. package/src/core/sources/assets.ts +47 -11
  486. package/src/core/sources/collection.ts +67 -0
  487. package/src/core/sources/contentful-rich-text.ts +285 -0
  488. package/src/core/sources/contentful.ts +173 -0
  489. package/src/core/sources/github-releases.ts +51 -1
  490. package/src/core/sources/json.ts +71 -0
  491. package/src/core/sources/lexical.ts +195 -0
  492. package/src/core/sources/lower.ts +226 -0
  493. package/src/core/sources/normalize.ts +52 -2
  494. package/src/core/sources/notion.ts +39 -28
  495. package/src/core/sources/payload.ts +135 -0
  496. package/src/core/sources/portable-text.ts +11 -16
  497. package/src/core/sources/remote.ts +226 -0
  498. package/src/core/sources/resolve.ts +104 -166
  499. package/src/core/sources/sanity.ts +16 -49
  500. package/src/core/sources/strapi-blocks.ts +124 -0
  501. package/src/core/sources/strapi.ts +191 -0
  502. package/src/core/sources/types.ts +12 -1
  503. package/src/core/types.ts +15 -1
  504. package/src/core/ui-packs/ar.ts +6 -2
  505. package/src/core/ui-packs/bg.ts +6 -2
  506. package/src/core/ui-packs/bn.ts +6 -2
  507. package/src/core/ui-packs/ca.ts +3 -1
  508. package/src/core/ui-packs/cs.ts +6 -2
  509. package/src/core/ui-packs/da.ts +6 -2
  510. package/src/core/ui-packs/de.ts +6 -2
  511. package/src/core/ui-packs/el.ts +3 -1
  512. package/src/core/ui-packs/es.ts +3 -1
  513. package/src/core/ui-packs/fa.ts +6 -2
  514. package/src/core/ui-packs/fi.ts +6 -2
  515. package/src/core/ui-packs/fr.ts +3 -1
  516. package/src/core/ui-packs/he.ts +6 -2
  517. package/src/core/ui-packs/hi.ts +6 -2
  518. package/src/core/ui-packs/hr.ts +6 -2
  519. package/src/core/ui-packs/hu.ts +6 -2
  520. package/src/core/ui-packs/id.ts +6 -2
  521. package/src/core/ui-packs/it.ts +3 -1
  522. package/src/core/ui-packs/ja.ts +3 -1
  523. package/src/core/ui-packs/ko.ts +3 -1
  524. package/src/core/ui-packs/nl.ts +6 -2
  525. package/src/core/ui-packs/no.ts +6 -2
  526. package/src/core/ui-packs/pl.ts +6 -2
  527. package/src/core/ui-packs/pt-br.ts +3 -1
  528. package/src/core/ui-packs/pt.ts +3 -1
  529. package/src/core/ui-packs/ro.ts +6 -2
  530. package/src/core/ui-packs/ru.ts +6 -2
  531. package/src/core/ui-packs/sk.ts +6 -2
  532. package/src/core/ui-packs/sr.ts +6 -2
  533. package/src/core/ui-packs/sv.ts +6 -2
  534. package/src/core/ui-packs/th.ts +3 -1
  535. package/src/core/ui-packs/tr.ts +6 -2
  536. package/src/core/ui-packs/uk.ts +6 -2
  537. package/src/core/ui-packs/vi.ts +3 -1
  538. package/src/core/ui-packs/zh-tw.ts +3 -1
  539. package/src/core/ui-packs/zh.ts +3 -1
  540. package/src/core/unrecognized-keys.ts +10 -0
  541. package/src/core/version-cut.ts +116 -8
  542. package/src/deploy/adapter-output.ts +57 -97
  543. package/src/deploy/adapters/cloudflare.ts +39 -0
  544. package/src/deploy/adapters/index.ts +41 -0
  545. package/src/deploy/adapters/netlify.ts +34 -0
  546. package/src/deploy/adapters/node.ts +34 -0
  547. package/src/deploy/adapters/registry.ts +127 -0
  548. package/src/deploy/adapters/types.ts +92 -0
  549. package/src/deploy/adapters/vercel.ts +35 -0
  550. package/src/deploy/artifacts.ts +55 -27
  551. package/src/deploy/cloudflare-negotiation.ts +179 -100
  552. package/src/deploy/function-bundle.ts +18 -3
  553. package/src/deploy/headers.ts +124 -23
  554. package/src/deploy/node-headers.ts +198 -0
  555. package/src/deploy/platforms/cloudflare.ts +312 -0
  556. package/src/deploy/platforms/index.ts +67 -0
  557. package/src/deploy/platforms/netlify.ts +52 -0
  558. package/src/deploy/platforms/node.ts +40 -0
  559. package/src/deploy/platforms/paths.ts +42 -0
  560. package/src/deploy/platforms/static.ts +29 -0
  561. package/src/deploy/platforms/types.ts +112 -0
  562. package/src/deploy/platforms/vercel.ts +193 -0
  563. package/src/deploy/redirects.ts +30 -18
  564. package/src/deploy/robots.ts +3 -3
  565. package/src/deploy/rss.ts +2 -2
  566. package/src/deploy/sitemap.ts +2 -2
  567. package/src/deploy/vercel-negotiation.ts +2 -2
  568. package/src/eval/agents.ts +32 -1
  569. package/src/eval/findings.ts +19 -11
  570. package/src/eval/report.ts +10 -2
  571. package/src/markdown/external-links.ts +65 -0
  572. package/src/markdown/include.ts +45 -27
  573. package/src/markdown/index.ts +34 -9
  574. package/src/markdown/inline-code.ts +12 -6
  575. package/src/markdown/relative-links.ts +324 -0
  576. package/src/markdown/themes.ts +3 -3
  577. package/src/migrate/migrate.ts +149 -0
  578. package/src/openapi/parse.ts +64 -16
  579. package/src/openapi/proxy.ts +62 -10
  580. package/src/openapi/references.ts +147 -147
  581. package/src/openapi/render-mdx.ts +32 -10
  582. package/src/openapi/scalar.ts +15 -13
  583. package/src/openapi/sentence.ts +14 -0
  584. package/src/openapi/source.ts +37 -21
  585. package/src/openapi/spec-dependency-error.ts +15 -0
  586. package/src/reference/asyncapi.ts +83 -0
  587. package/src/reference/graphql.ts +89 -0
  588. package/src/reference/index.ts +40 -0
  589. package/src/reference/openapi.ts +83 -0
  590. package/src/reference/options.ts +201 -0
  591. package/src/reference/scalar.ts +136 -0
  592. package/src/reference/schema.ts +88 -0
  593. package/src/registry/eject.ts +97 -42
  594. package/src/search/adapters/algolia.ts +46 -0
  595. package/src/search/adapters/flexsearch.ts +29 -0
  596. package/src/search/adapters/index.ts +39 -0
  597. package/src/search/adapters/mixedbread.ts +39 -0
  598. package/src/search/adapters/orama-cloud.ts +51 -0
  599. package/src/search/adapters/orama.ts +24 -0
  600. package/src/search/adapters/pagefind.ts +27 -0
  601. package/src/search/adapters/registry.ts +131 -0
  602. package/src/search/adapters/types.ts +46 -0
  603. package/src/search/adapters/typesense.ts +57 -0
  604. package/src/search/build.ts +8 -4
  605. package/src/search/documents.ts +6 -0
  606. package/src/search/sync/algolia.ts +12 -11
  607. package/src/search/sync/index.ts +35 -20
  608. package/src/search/sync/orama-cloud.ts +12 -9
  609. package/src/search/sync/typesense.ts +15 -13
  610. package/src/sources/contentful.ts +63 -0
  611. package/src/sources/custom.ts +38 -0
  612. package/src/sources/filesystem.ts +51 -0
  613. package/src/sources/github-releases.ts +52 -0
  614. package/src/sources/index.ts +60 -0
  615. package/src/sources/mdx-remote.ts +76 -0
  616. package/src/sources/notion.ts +63 -0
  617. package/src/sources/obsidian.ts +38 -0
  618. package/src/sources/payload.ts +60 -0
  619. package/src/sources/registry.ts +182 -0
  620. package/src/sources/sanity.ts +66 -0
  621. package/src/sources/shared.ts +52 -0
  622. package/src/sources/strapi.ts +58 -0
  623. package/src/theme/entry.ts +24 -2
  624. package/src/translate/report.ts +40 -7
  625. package/src/upgrade/upgrade.ts +499 -0
  626. package/dist/cli/chunk-0qymqwzz.js +0 -164
  627. package/dist/cli/chunk-0qymqwzz.js.map +0 -15
  628. package/dist/cli/chunk-1jefwnfs.js.map +0 -48
  629. package/dist/cli/chunk-2mzebbbz.js +0 -69
  630. package/dist/cli/chunk-2z47ypj8.js.map +0 -11
  631. package/dist/cli/chunk-4x36ddpw.js.map +0 -11
  632. package/dist/cli/chunk-5093q3n7.js +0 -68
  633. package/dist/cli/chunk-5093q3n7.js.map +0 -10
  634. package/dist/cli/chunk-5qk08vmp.js.map +0 -11
  635. package/dist/cli/chunk-7s8hm3b6.js +0 -5347
  636. package/dist/cli/chunk-7s8hm3b6.js.map +0 -58
  637. package/dist/cli/chunk-8cjtbafj.js.map +0 -13
  638. package/dist/cli/chunk-97r59kpr.js +0 -381
  639. package/dist/cli/chunk-97r59kpr.js.map +0 -12
  640. package/dist/cli/chunk-ahnw3kxw.js.map +0 -15
  641. package/dist/cli/chunk-b27xqwn9.js.map +0 -10
  642. package/dist/cli/chunk-bf6bt1xt.js +0 -185
  643. package/dist/cli/chunk-bf6bt1xt.js.map +0 -11
  644. package/dist/cli/chunk-cjtn640a.js.map +0 -10
  645. package/dist/cli/chunk-ct47dqpx.js.map +0 -11
  646. package/dist/cli/chunk-esphfr8p.js +0 -107
  647. package/dist/cli/chunk-esphfr8p.js.map +0 -11
  648. package/dist/cli/chunk-ex56aa81.js +0 -1016
  649. package/dist/cli/chunk-ex56aa81.js.map +0 -13
  650. package/dist/cli/chunk-garjf5z9.js +0 -30
  651. package/dist/cli/chunk-garjf5z9.js.map +0 -10
  652. package/dist/cli/chunk-js7saxwm.js +0 -1045
  653. package/dist/cli/chunk-js7saxwm.js.map +0 -22
  654. package/dist/cli/chunk-k79xp7av.js.map +0 -39
  655. package/dist/cli/chunk-ps4m1xh4.js.map +0 -15
  656. package/dist/cli/chunk-q4rae3bg.js +0 -60
  657. package/dist/cli/chunk-q4rae3bg.js.map +0 -10
  658. package/dist/cli/chunk-rz9jmfhz.js +0 -108
  659. package/dist/cli/chunk-rz9jmfhz.js.map +0 -10
  660. package/dist/cli/chunk-vh9w1sgp.js +0 -73
  661. package/dist/cli/chunk-vh9w1sgp.js.map +0 -10
  662. package/dist/cli/chunk-vrfp10qk.js +0 -81
  663. package/dist/cli/chunk-vrfp10qk.js.map +0 -10
  664. package/dist/cli/chunk-yg63d42r.js.map +0 -34
  665. package/docs/advanced/api-reference.mdx +0 -240
  666. package/docs/reference/cli.mdx +0 -197
  667. package/skills/blume-migrate/assets/oxfmt@0.55.0.patch +0 -20
  668. package/src/components/content/changelog-element.ts +0 -69
  669. package/src/search/providers.ts +0 -91
  670. /package/dist/cli/{chunk-e7f42gdj.js.map → chunk-7ez8ny0t.js.map} +0 -0
  671. /package/dist/cli/{chunk-nn13znc2.js.map → chunk-88cpgt6h.js.map} +0 -0
  672. /package/dist/cli/{chunk-vacwm2hv.js.map → chunk-f7t03s3g.js.map} +0 -0
  673. /package/dist/cli/{chunk-dwgcp5sm.js.map → chunk-zxccj738.js.map} +0 -0
@@ -0,0 +1,51 @@
1
+ import { z } from "zod";
2
+
3
+ import type { JsonValue } from "../../core/adapter.ts";
4
+ import type { SearchAdapter } from "./types.ts";
5
+
6
+ /**
7
+ * Public Orama Cloud credentials. The browser queries `endpoint` with the
8
+ * public `apiKey`; the build-time sync pushes records to `indexId` with
9
+ * `ORAMA_PRIVATE_API_KEY`, which never enters the config.
10
+ */
11
+ export interface OramaCloudNamedOptions {
12
+ /** The public API key (it ships to the browser). */
13
+ apiKey: string;
14
+ endpoint: string;
15
+ /** Index id used by the build-time sync; omit to skip syncing. */
16
+ indexId?: string;
17
+ }
18
+
19
+ /**
20
+ * Options for {@link oramaCloud}: the named options plus any other client
21
+ * option, forwarded to the browser verbatim. JSON values only.
22
+ */
23
+ export type OramaCloudOptions = OramaCloudNamedOptions & {
24
+ [option: string]: JsonValue;
25
+ };
26
+
27
+ export type OramaCloudAdapter = SearchAdapter<
28
+ "orama-cloud",
29
+ "hosted",
30
+ OramaCloudOptions
31
+ >;
32
+
33
+ export const oramaCloudOptionsSchema = z
34
+ .object({
35
+ apiKey: z.string(),
36
+ endpoint: z.string(),
37
+ indexId: z.string().optional(),
38
+ })
39
+ .catchall(z.json());
40
+
41
+ /**
42
+ * Hosted Orama. The browser queries your index endpoint directly; each
43
+ * `blume build` snapshots the records into the index and deploys it.
44
+ */
45
+ export const oramaCloud = (options: OramaCloudOptions): OramaCloudAdapter => ({
46
+ kind: "orama-cloud",
47
+ mode: "hosted",
48
+ options,
49
+ requiredSecrets: [],
50
+ runtimeDeps: ["@oramacloud/client"],
51
+ });
@@ -0,0 +1,24 @@
1
+ import { z } from "zod";
2
+
3
+ import type { KeylessSearchOptions, SearchAdapter } from "./types.ts";
4
+
5
+ /** Orama takes no options; unknown keys fail config validation. */
6
+ export type OramaOptions = KeylessSearchOptions;
7
+
8
+ export type OramaAdapter = SearchAdapter<"orama", "static", OramaOptions>;
9
+
10
+ export const oramaOptionsSchema = z.strictObject({});
11
+
12
+ /**
13
+ * Blume's default search: a JSON index built from the source files, served
14
+ * at `/blume-search.json` and queried in the browser. Keyless, and live in
15
+ * `blume dev`. The tokenizer follows `i18n.defaultLocale`, so non-Latin
16
+ * scripts are word-segmented.
17
+ */
18
+ export const orama = (options: OramaOptions = {}): OramaAdapter => ({
19
+ kind: "orama",
20
+ mode: "static",
21
+ options,
22
+ requiredSecrets: [],
23
+ runtimeDeps: ["@orama/orama"],
24
+ });
@@ -0,0 +1,27 @@
1
+ import { z } from "zod";
2
+
3
+ import type { KeylessSearchOptions, SearchAdapter } from "./types.ts";
4
+
5
+ /** Pagefind takes no options; unknown keys fail config validation. */
6
+ export type PagefindOptions = KeylessSearchOptions;
7
+
8
+ export type PagefindAdapter = SearchAdapter<
9
+ "pagefind",
10
+ "pagefind",
11
+ PagefindOptions
12
+ >;
13
+
14
+ export const pagefindOptionsSchema = z.strictObject({});
15
+
16
+ /**
17
+ * Pagefind indexes the built HTML after `blume build` and loads the index in
18
+ * shards on demand, so the initial payload stays small on very large sites.
19
+ * The index only exists in the production build, not in `blume dev`.
20
+ */
21
+ export const pagefind = (options: PagefindOptions = {}): PagefindAdapter => ({
22
+ kind: "pagefind",
23
+ mode: "pagefind",
24
+ options,
25
+ requiredSecrets: [],
26
+ runtimeDeps: [],
27
+ });
@@ -0,0 +1,131 @@
1
+ import { z } from "zod";
2
+
3
+ import { adapterDescriptorSchema } from "../../core/adapter.ts";
4
+ import { algolia, algoliaOptionsSchema } from "./algolia.ts";
5
+ import type { AlgoliaAdapter } from "./algolia.ts";
6
+ import { flexsearch, flexsearchOptionsSchema } from "./flexsearch.ts";
7
+ import type { FlexsearchAdapter } from "./flexsearch.ts";
8
+ import { mixedbread, mixedbreadOptionsSchema } from "./mixedbread.ts";
9
+ import type { MixedbreadAdapter } from "./mixedbread.ts";
10
+ import { oramaCloud, oramaCloudOptionsSchema } from "./orama-cloud.ts";
11
+ import type { OramaCloudAdapter } from "./orama-cloud.ts";
12
+ import { orama, oramaOptionsSchema } from "./orama.ts";
13
+ import type { OramaAdapter } from "./orama.ts";
14
+ import { pagefind, pagefindOptionsSchema } from "./pagefind.ts";
15
+ import type { PagefindAdapter } from "./pagefind.ts";
16
+ import type {
17
+ KeylessSearchOptions,
18
+ SearchAdapter,
19
+ SearchAdapterMode,
20
+ } from "./types.ts";
21
+ import { typesense, typesenseOptionsSchema } from "./typesense.ts";
22
+ import type { TypesenseAdapter } from "./typesense.ts";
23
+
24
+ /** Every descriptor a factory can return. */
25
+ export type AnySearchAdapter =
26
+ | AlgoliaAdapter
27
+ | FlexsearchAdapter
28
+ | MixedbreadAdapter
29
+ | OramaAdapter
30
+ | OramaCloudAdapter
31
+ | PagefindAdapter
32
+ | TypesenseAdapter;
33
+
34
+ /** The resolved form of `search: false`: search is disabled. */
35
+ export type NoneSearchAdapter = SearchAdapter<
36
+ "none",
37
+ "none",
38
+ KeylessSearchOptions
39
+ >;
40
+
41
+ /** What `config.search.provider` resolves to: an adapter, or `none`. */
42
+ export type ResolvedSearchAdapter = AnySearchAdapter | NoneSearchAdapter;
43
+
44
+ /** Every adapter identity, including the resolved `none`. */
45
+ export type SearchAdapterKind = ResolvedSearchAdapter["kind"];
46
+
47
+ export const NONE_SEARCH_ADAPTER: NoneSearchAdapter = {
48
+ kind: "none",
49
+ mode: "none",
50
+ options: {},
51
+ requiredSecrets: [],
52
+ runtimeDeps: [],
53
+ };
54
+
55
+ /**
56
+ * The descriptor shape a factory returns: the shared adapter contract plus
57
+ * the search-specific `mode`. Only `kind` and `options` carry information —
58
+ * the metadata lists are validated for shape, then re-derived from the
59
+ * factory below so a descriptor that went through JSON resolves to the same
60
+ * canonical metadata Blume ships.
61
+ */
62
+ const descriptor = <
63
+ Kind extends string,
64
+ Mode extends SearchAdapterMode,
65
+ Options extends z.ZodType,
66
+ >(
67
+ kind: Kind,
68
+ mode: Mode,
69
+ options: Options
70
+ ) => adapterDescriptorSchema(kind, options).extend({ mode: z.literal(mode) });
71
+
72
+ /** One variant per public adapter factory. */
73
+ const adapterVariants = [
74
+ descriptor("algolia", "hosted", algoliaOptionsSchema),
75
+ descriptor("flexsearch", "static", flexsearchOptionsSchema),
76
+ descriptor("mixedbread", "server", mixedbreadOptionsSchema),
77
+ descriptor("orama", "static", oramaOptionsSchema),
78
+ descriptor("orama-cloud", "hosted", oramaCloudOptionsSchema),
79
+ descriptor("pagefind", "pagefind", pagefindOptionsSchema),
80
+ descriptor("typesense", "hosted", typesenseOptionsSchema),
81
+ ] as const;
82
+
83
+ /** What a public factory returns, as the config schema accepts it. */
84
+ export type SearchAdapterInput = z.input<(typeof adapterVariants)[number]>;
85
+
86
+ /**
87
+ * Validates a descriptor — one a factory returned, or the `none` descriptor
88
+ * the config schema substitutes for `false` — and resolves it to the
89
+ * canonical form, so every consumer reads `mode`, `runtimeDeps`, and
90
+ * `requiredSecrets` straight off the descriptor. `none` is internal: it is
91
+ * not part of {@link SearchAdapterInput}, so `search: { kind: "none" }` is a
92
+ * type error even though the runtime schema admits it.
93
+ */
94
+ export const resolvedSearchAdapterSchema = z
95
+ .discriminatedUnion("kind", [
96
+ ...adapterVariants,
97
+ descriptor("none", "none", z.strictObject({})),
98
+ ])
99
+ .transform((value): ResolvedSearchAdapter => {
100
+ switch (value.kind) {
101
+ case "algolia": {
102
+ return algolia(value.options);
103
+ }
104
+ case "flexsearch": {
105
+ return flexsearch(value.options);
106
+ }
107
+ case "mixedbread": {
108
+ return mixedbread(value.options);
109
+ }
110
+ case "none": {
111
+ return NONE_SEARCH_ADAPTER;
112
+ }
113
+ case "orama": {
114
+ return orama(value.options);
115
+ }
116
+ case "orama-cloud": {
117
+ return oramaCloud(value.options);
118
+ }
119
+ case "pagefind": {
120
+ return pagefind(value.options);
121
+ }
122
+ default: {
123
+ // Only Typesense is left, and TypeScript has narrowed `value` to it.
124
+ // It returns after the switch rather than from a last case block:
125
+ // Bun 1.4.0's line coverage never credits the closing brace of a
126
+ // switch's final block, which would fail the 100% gate in CI.
127
+ break;
128
+ }
129
+ }
130
+ return typesense(value.options);
131
+ });
@@ -0,0 +1,46 @@
1
+ import type { AdapterDescriptor } from "../../core/adapter.ts";
2
+
3
+ /**
4
+ * How a search adapter integrates with the generated runtime.
5
+ *
6
+ * - `static` adapters ship a client-side index (`blume-search.json`) that the
7
+ * browser loads and queries — Orama, FlexSearch.
8
+ * - `pagefind` builds its own index from the rendered HTML after the build.
9
+ * - `hosted` adapters are queried directly from the browser against an
10
+ * external service, with a build-time sync uploading the index — Algolia,
11
+ * Orama Cloud, Typesense.
12
+ * - `server` adapters proxy queries through a generated `/api/search` endpoint
13
+ * that holds a secret key, so they require server output — Mixedbread.
14
+ * - `none` is the resolved form of `search: false`: search is disabled.
15
+ */
16
+ export type SearchAdapterMode =
17
+ | "static"
18
+ | "pagefind"
19
+ | "hosted"
20
+ | "server"
21
+ | "none";
22
+
23
+ /**
24
+ * Options for an adapter that takes none. The generated client never reads
25
+ * them — the static engines are configured from `i18n`, and Pagefind indexes
26
+ * the built HTML — so unknown keys fail config validation instead of passing
27
+ * silently. Adding a real option later is then additive, never a behavior
28
+ * change for a key that used to be ignored.
29
+ */
30
+ export type KeylessSearchOptions = Record<string, never>;
31
+
32
+ /**
33
+ * The descriptor a search adapter factory returns and `blume.config.ts`
34
+ * carries under `search`: the shared {@link AdapterDescriptor} contract plus
35
+ * the adapter's integration `mode`. It is plain data, never a live client —
36
+ * the runtime templates inline it as a literal into `.blume/` and ejected
37
+ * files, so every field must survive a JSON round-trip.
38
+ */
39
+ export interface SearchAdapter<
40
+ Kind extends string = string,
41
+ Mode extends SearchAdapterMode = SearchAdapterMode,
42
+ Options = object,
43
+ > extends AdapterDescriptor<Kind, Options> {
44
+ /** How the generated runtime queries this adapter. */
45
+ mode: Mode;
46
+ }
@@ -0,0 +1,57 @@
1
+ import { z } from "zod";
2
+
3
+ import type { JsonValue } from "../../core/adapter.ts";
4
+ import type { SearchAdapter } from "./types.ts";
5
+
6
+ /**
7
+ * Connection details for a self-hosted or cloud Typesense node. The browser
8
+ * queries the collection with the search-only `apiKey`; the build-time sync
9
+ * recreates the collection with `TYPESENSE_ADMIN_API_KEY`, which never enters
10
+ * the config.
11
+ */
12
+ export interface TypesenseNamedOptions {
13
+ /** The search-only API key (public — it ships to the browser). */
14
+ apiKey: string;
15
+ collection: string;
16
+ host: string;
17
+ /** Defaults to 443. */
18
+ port?: number;
19
+ /** Defaults to `https`. */
20
+ protocol?: "http" | "https";
21
+ }
22
+
23
+ /**
24
+ * Options for {@link typesense}: the named options plus any other client
25
+ * option, forwarded to the browser verbatim. JSON values only.
26
+ */
27
+ export type TypesenseOptions = TypesenseNamedOptions & {
28
+ [option: string]: JsonValue;
29
+ };
30
+
31
+ export type TypesenseAdapter = SearchAdapter<
32
+ "typesense",
33
+ "hosted",
34
+ TypesenseOptions
35
+ >;
36
+
37
+ export const typesenseOptionsSchema = z
38
+ .object({
39
+ apiKey: z.string(),
40
+ collection: z.string(),
41
+ host: z.string(),
42
+ port: z.number().int().positive().optional(),
43
+ protocol: z.enum(["http", "https"]).optional(),
44
+ })
45
+ .catchall(z.json());
46
+
47
+ /**
48
+ * Hosted search on Typesense. Each `blume build` drops and recreates the
49
+ * collection so deleted or renamed pages don't linger as stale hits.
50
+ */
51
+ export const typesense = (options: TypesenseOptions): TypesenseAdapter => ({
52
+ kind: "typesense",
53
+ mode: "hosted",
54
+ options,
55
+ requiredSecrets: [],
56
+ runtimeDeps: ["typesense"],
57
+ });
@@ -1,5 +1,6 @@
1
1
  import { mkdir, writeFile } from "node:fs/promises";
2
2
 
3
+ import { close, createIndex } from "pagefind";
3
4
  import { dirname, join } from "pathe";
4
5
 
5
6
  /**
@@ -8,6 +9,11 @@ import { dirname, join } from "pathe";
8
9
  * `data-pagefind-ignore`, which Blume stamps on non-indexable pages
9
10
  * (search-excluded, or hidden without the opt-in), so those stay out.
10
11
  *
12
+ * Pagefind is imported statically, not with `import()`: this runs in the
13
+ * `astro:build:done` hook, after Astro has closed the module runner an
14
+ * installed Blume's config was evaluated in (see `core/node-require.ts`), and
15
+ * Pagefind ships only an `import` export, so `require` can't load it either.
16
+ *
11
17
  * The index files are fetched with `getFiles()` and written here rather than
12
18
  * with Pagefind's `writeFiles()`: in service mode Pagefind acknowledges
13
19
  * `writeFiles()` once tokio has buffered the writes, not once they are on
@@ -20,9 +26,7 @@ import { dirname, join } from "pathe";
20
26
  * Returns the number of pages indexed.
21
27
  */
22
28
  export const buildSearchIndex = async (outDir: string): Promise<number> => {
23
- const pagefind = await import("pagefind");
24
-
25
- const { index } = await pagefind.createIndex({});
29
+ const { index } = await createIndex({});
26
30
  if (!index) {
27
31
  throw new Error("Failed to create Pagefind index.");
28
32
  }
@@ -32,7 +36,7 @@ export const buildSearchIndex = async (outDir: string): Promise<number> => {
32
36
  // oxlint-disable-next-line react-doctor/async-parallel
33
37
  const result = await index.addDirectory({ path: outDir });
34
38
  const { files } = await index.getFiles();
35
- await pagefind.close();
39
+ await close();
36
40
 
37
41
  const searchDir = join(outDir, "pagefind");
38
42
  const directories = new Set(
@@ -433,6 +433,12 @@ export const buildSearchDocuments = async (
433
433
  if (!options?.includeWhenDisabled) {
434
434
  return route.indexable;
435
435
  }
436
+ // A fallback route renders the fallback locale's page at another locale's
437
+ // URL, so indexing it would only repeat that page as a second hit — the
438
+ // reason site search leaves it out too.
439
+ if (route.fallback) {
440
+ return false;
441
+ }
436
442
  const page = pageById.get(route.id);
437
443
  return page ? contentIndexable(page, project.config) : false;
438
444
  });
@@ -1,14 +1,16 @@
1
+ import type * as AlgoliaSdk from "algoliasearch";
2
+
3
+ import { nodeRequire } from "../../core/node-require.ts";
4
+ import type { AlgoliaOptions } from "../adapters/algolia.ts";
1
5
  import type { SearchRecord } from "../documents.ts";
2
6
 
3
- export interface AlgoliaSyncConfig {
4
- appId: string;
5
- indexName: string;
6
- }
7
+ /** The adapter options the sync reads (the public `apiKey` is never used). */
8
+ export type AlgoliaSyncConfig = Pick<AlgoliaOptions, "appId" | "indexName">;
7
9
 
8
10
  /**
9
11
  * Upload the search records to Algolia. Uses the admin key from
10
- * `ALGOLIA_ADMIN_API_KEY` (never the config, which holds only the public,
11
- * search-only key). Throws on a missing key/config so the caller can warn.
12
+ * `ALGOLIA_ADMIN_API_KEY` (never the adapter options, which hold only the
13
+ * public, search-only key). Throws on a missing key so the caller can warn.
12
14
  *
13
15
  * Uses `replaceAllObjects`, which atomically replaces the index contents, so
14
16
  * pages deleted or renamed since the last sync don't linger as stale search
@@ -16,16 +18,15 @@ export interface AlgoliaSyncConfig {
16
18
  */
17
19
  export const syncAlgolia = async (
18
20
  records: SearchRecord[],
19
- config: AlgoliaSyncConfig | undefined
21
+ config: AlgoliaSyncConfig
20
22
  ): Promise<void> => {
21
- if (!config) {
22
- throw new Error("search.algolia config is missing.");
23
- }
24
23
  const adminKey = process.env.ALGOLIA_ADMIN_API_KEY;
25
24
  if (!adminKey) {
26
25
  throw new Error("ALGOLIA_ADMIN_API_KEY is not set.");
27
26
  }
28
- const { algoliasearch } = await import("algoliasearch");
27
+ // `require`, not `import()`: this runs in `astro:build:done` (see
28
+ // `core/node-require.ts`).
29
+ const { algoliasearch }: typeof AlgoliaSdk = nodeRequire("algoliasearch");
29
30
  const client = algoliasearch(config.appId, adminKey);
30
31
  await client.replaceAllObjects({
31
32
  indexName: config.indexName,
@@ -1,6 +1,7 @@
1
1
  import type { BlumeProject } from "../../core/project-graph.ts";
2
+ import type { ResolvedSearchAdapter } from "../adapters/registry.ts";
2
3
  import { buildSearchDocuments, toSearchRecords } from "../documents.ts";
3
- import { searchProviderMeta } from "../providers.ts";
4
+ import type { SearchRecord } from "../documents.ts";
4
5
  import { syncAlgolia } from "./algolia.ts";
5
6
  import { syncOramaCloud } from "./orama-cloud.ts";
6
7
  import { syncTypesense } from "./typesense.ts";
@@ -13,37 +14,51 @@ export interface SyncReporter {
13
14
  }
14
15
 
15
16
  /**
16
- * After a build, upload the per-page records to the configured hosted provider.
17
- * Reads secret admin keys from the environment; if a key (or config) is
17
+ * The sync a hosted adapter runs after a build, closed over its options, or
18
+ * `null` for adapters with no in-process sync (static and Pagefind indexes are
19
+ * built locally; Mixedbread syncs out-of-band via the `mxbai` CLI).
20
+ */
21
+ const searchSync = (
22
+ provider: ResolvedSearchAdapter
23
+ ): ((records: SearchRecord[]) => Promise<void>) | null => {
24
+ switch (provider.kind) {
25
+ case "algolia": {
26
+ return (records) => syncAlgolia(records, provider.options);
27
+ }
28
+ case "orama-cloud": {
29
+ return (records) => syncOramaCloud(records, provider.options);
30
+ }
31
+ case "typesense": {
32
+ return (records) => syncTypesense(records, provider.options);
33
+ }
34
+ default: {
35
+ return null;
36
+ }
37
+ }
38
+ };
39
+
40
+ /**
41
+ * After a build, upload the per-page records to the configured hosted adapter.
42
+ * Reads secret admin keys from the environment; if a key (or option) is
18
43
  * missing the sync is skipped with a warning rather than failing the build —
19
- * CI may sync in a separate step. Providers without an in-process sync
20
- * (Mixedbread, which uses the `mxbai` CLI) are no-ops here.
44
+ * CI may sync in a separate step.
21
45
  */
22
46
  export const syncSearchProvider = async (
23
47
  project: BlumeProject,
24
48
  reporter: SyncReporter
25
49
  ): Promise<void> => {
26
- const { search } = project.config;
27
- if (!searchProviderMeta(search.provider).syncs) {
50
+ const { provider } = project.config.search;
51
+ const sync = searchSync(provider);
52
+ if (!sync) {
28
53
  return;
29
54
  }
30
55
 
31
56
  const records = toSearchRecords(await buildSearchDocuments(project));
32
- reporter.start(`Syncing ${records.length} record(s) to ${search.provider}`);
57
+ reporter.start(`Syncing ${records.length} record(s) to ${provider.kind}`);
33
58
 
34
59
  try {
35
- // The `syncs` guard above admits only these three hosted providers, so an
36
- // if-chain stays exhaustive without a dead `default` branch.
37
- if (search.provider === "algolia") {
38
- await syncAlgolia(records, search.algolia);
39
- } else if (search.provider === "orama-cloud") {
40
- await syncOramaCloud(records, search.oramaCloud);
41
- } else if (search.provider === "typesense") {
42
- await syncTypesense(records, search.typesense);
43
- }
44
- reporter.success(
45
- `Synced ${records.length} record(s) to ${search.provider}`
46
- );
60
+ await sync(records);
61
+ reporter.success(`Synced ${records.length} record(s) to ${provider.kind}`);
47
62
  } catch (error) {
48
63
  // SAFETY: the three sync clients surface network/auth failures as Error
49
64
  // instances; the message is read only to annotate the skip warning.
@@ -1,8 +1,11 @@
1
+ import type * as OramaCloudSdk from "@oramacloud/client";
2
+
3
+ import { nodeRequire } from "../../core/node-require.ts";
4
+ import type { OramaCloudOptions } from "../adapters/orama-cloud.ts";
1
5
  import type { SearchRecord } from "../documents.ts";
2
6
 
3
- export interface OramaCloudSyncConfig {
4
- indexId?: string;
5
- }
7
+ /** The adapter options the sync reads (the public credentials are never used). */
8
+ export type OramaCloudSyncConfig = Pick<OramaCloudOptions, "indexId">;
6
9
 
7
10
  /**
8
11
  * Push the search records to an Orama Cloud index via `CloudManager`, using the
@@ -11,19 +14,19 @@ export interface OramaCloudSyncConfig {
11
14
  */
12
15
  export const syncOramaCloud = async (
13
16
  records: SearchRecord[],
14
- config: OramaCloudSyncConfig | undefined
17
+ config: OramaCloudSyncConfig
15
18
  ): Promise<void> => {
16
- if (!config) {
17
- throw new Error("search.oramaCloud config is missing.");
18
- }
19
19
  if (!config.indexId) {
20
- throw new Error("search.oramaCloud.indexId is required to sync.");
20
+ throw new Error("oramaCloud({ indexId }) is required to sync.");
21
21
  }
22
22
  const privateKey = process.env.ORAMA_PRIVATE_API_KEY;
23
23
  if (!privateKey) {
24
24
  throw new Error("ORAMA_PRIVATE_API_KEY is not set.");
25
25
  }
26
- const { CloudManager } = await import("@oramacloud/client");
26
+ // `require`, not `import()`: this runs in `astro:build:done` (see
27
+ // `core/node-require.ts`).
28
+ const { CloudManager }: typeof OramaCloudSdk =
29
+ nodeRequire("@oramacloud/client");
27
30
  const manager = new CloudManager({ api_key: privateKey });
28
31
  const index = manager.index(config.indexId);
29
32
  await index.snapshot(
@@ -1,16 +1,19 @@
1
+ import type * as TypesenseSdk from "typesense";
2
+
3
+ import { nodeRequire } from "../../core/node-require.ts";
4
+ import type { TypesenseOptions } from "../adapters/typesense.ts";
1
5
  import type { SearchRecord } from "../documents.ts";
2
6
 
3
- export interface TypesenseSyncConfig {
4
- collection: string;
5
- host: string;
6
- port?: number;
7
- protocol?: string;
8
- }
7
+ /** The adapter options the sync reads (the public `apiKey` is never used). */
8
+ export type TypesenseSyncConfig = Pick<
9
+ TypesenseOptions,
10
+ "collection" | "host" | "port" | "protocol"
11
+ >;
9
12
 
10
13
  /**
11
14
  * Import the search records into a Typesense collection. Uses the admin key
12
- * from `TYPESENSE_ADMIN_API_KEY`. Throws on a missing key/config so the caller
13
- * can warn.
15
+ * from `TYPESENSE_ADMIN_API_KEY`. Throws on a missing key so the caller can
16
+ * warn.
14
17
  *
15
18
  * The collection is dropped and recreated on each sync so that pages deleted or
16
19
  * renamed since the last sync don't linger as stale search hits that 404 when
@@ -18,16 +21,15 @@ export interface TypesenseSyncConfig {
18
21
  */
19
22
  export const syncTypesense = async (
20
23
  records: SearchRecord[],
21
- config: TypesenseSyncConfig | undefined
24
+ config: TypesenseSyncConfig
22
25
  ): Promise<void> => {
23
- if (!config) {
24
- throw new Error("search.typesense config is missing.");
25
- }
26
26
  const adminKey = process.env.TYPESENSE_ADMIN_API_KEY;
27
27
  if (!adminKey) {
28
28
  throw new Error("TYPESENSE_ADMIN_API_KEY is not set.");
29
29
  }
30
- const { Client } = await import("typesense");
30
+ // `require`, not `import()`: this runs in `astro:build:done` (see
31
+ // `core/node-require.ts`).
32
+ const { Client }: typeof TypesenseSdk = nodeRequire("typesense");
31
33
  const client = new Client({
32
34
  apiKey: adminKey,
33
35
  nodes: [
@@ -0,0 +1,63 @@
1
+ import { z } from "zod";
2
+
3
+ import type { AdapterDescriptor } from "../core/adapter.ts";
4
+ import { adapterDescriptorSchema } from "../core/adapter.ts";
5
+ import type { SharedSourceOptions, SourceFieldMap } from "./shared.ts";
6
+ import {
7
+ queryParamsSchema,
8
+ sharedSourceOptionsSchema,
9
+ sourceFieldMapSchema,
10
+ } from "./shared.ts";
11
+
12
+ /** Options for {@link contentful}. */
13
+ export interface ContentfulOptions extends SharedSourceOptions {
14
+ /** The content type id whose entries become pages. */
15
+ contentType: string;
16
+ /** Environment id. Defaults to `master`. */
17
+ environment?: string;
18
+ /**
19
+ * Field ids mapping an entry onto Blume meta + body; `sys.<key>` reaches
20
+ * the entry's `sys`. Defaults to `title` / `description` / `slug` / `body`
21
+ * / `sys.updatedAt`.
22
+ */
23
+ fields?: SourceFieldMap;
24
+ /** Locale code to fetch; omit for the space's default locale. */
25
+ locale?: string;
26
+ /** Extra query parameters for the entries request (`"fields.section": "sdk"`). */
27
+ params?: Record<string, string>;
28
+ /** Space id. */
29
+ space: string;
30
+ }
31
+
32
+ export const contentfulOptionsSchema = sharedSourceOptionsSchema.extend({
33
+ contentType: z.string(),
34
+ environment: z.string().optional(),
35
+ fields: sourceFieldMapSchema.optional(),
36
+ locale: z.string().optional(),
37
+ params: queryParamsSchema.optional(),
38
+ space: z.string(),
39
+ });
40
+
41
+ export type ContentfulAdapter = AdapterDescriptor<
42
+ "contentful",
43
+ ContentfulOptions
44
+ >;
45
+
46
+ export const contentfulAdapterSchema = adapterDescriptorSchema(
47
+ "contentful",
48
+ contentfulOptionsSchema
49
+ );
50
+
51
+ /**
52
+ * A Contentful content type read through the Delivery API; rich text bodies
53
+ * become Markdown. The Delivery token comes from `CONTENTFUL_ACCESS_TOKEN`,
54
+ * and `--preview` reads drafts through the Preview API with
55
+ * `CONTENTFUL_PREVIEW_TOKEN`. Nothing to install: the adapter speaks the
56
+ * REST API directly.
57
+ */
58
+ export const contentful = (options: ContentfulOptions): ContentfulAdapter => ({
59
+ kind: "contentful",
60
+ options,
61
+ requiredSecrets: ["CONTENTFUL_ACCESS_TOKEN"],
62
+ runtimeDeps: [],
63
+ });