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
@@ -27,9 +27,10 @@ import {
27
27
  parseGraphqlSpec,
28
28
  parseSpec,
29
29
  } from "./parse.ts";
30
- import type { ReferenceSource } from "./references.ts";
30
+ import type { BlumeReferenceSource } from "./references.ts";
31
31
  import { operationMdx, overviewMdx } from "./render-mdx.ts";
32
32
  import type { RenderedPage } from "./render-mdx.ts";
33
+ import { SpecDependencyError } from "./spec-dependency-error.ts";
33
34
 
34
35
  /**
35
36
  * The staged content source behind Blume's own API reference renderer (OpenAPI
@@ -38,7 +39,7 @@ import type { RenderedPage } from "./render-mdx.ts";
38
39
  * first-class Blume pages (real routes, sidebar, search, i18n, OG) and the
39
40
  * parsed documents are handed to the generated `blume:openapi` module for the
40
41
  * UI components to render. The source keeps its historical `openapi` name for
41
- * both kinds — downstream consumers (`ai.llmsTxt.openapi`, the llms noindex
42
+ * both kinds — downstream consumers (`agents.llmsTxt.openapi`, the llms noindex
42
43
  * exemption) key on it as "the generated API reference source".
43
44
  */
44
45
 
@@ -63,14 +64,14 @@ const KIND_LABELS = {
63
64
  asyncapi: "AsyncAPI",
64
65
  graphql: "GraphQL",
65
66
  openapi: "OpenAPI",
66
- } satisfies Record<ReferenceSource["kind"], string>;
67
+ } satisfies Record<BlumeReferenceSource["kind"], string>;
67
68
 
68
69
  /** Diagnostic-code prefix per spec kind. */
69
70
  const CODE_PREFIXES = {
70
71
  asyncapi: "BLUME_ASYNCAPI",
71
72
  graphql: "BLUME_GRAPHQL",
72
73
  openapi: "BLUME_OPENAPI",
73
- } satisfies Record<ReferenceSource["kind"], string>;
74
+ } satisfies Record<BlumeReferenceSource["kind"], string>;
74
75
 
75
76
  /**
76
77
  * Parse-level warning code per kind: an offline cache fallback for any kind,
@@ -81,7 +82,7 @@ const SPEC_WARNING_CODES = {
81
82
  asyncapi: "BLUME_ASYNCAPI_SPEC_WARNING",
82
83
  graphql: "BLUME_GRAPHQL_SPEC_WARNING",
83
84
  openapi: "BLUME_OPENAPI_STALE",
84
- } satisfies Record<ReferenceSource["kind"], string>;
85
+ } satisfies Record<BlumeReferenceSource["kind"], string>;
85
86
 
86
87
  /**
87
88
  * Extract-level skip code per kind. OpenAPI keeps its historical code (the
@@ -92,7 +93,7 @@ const SKIPPED_CODES = {
92
93
  asyncapi: "BLUME_ASYNCAPI_SKIPPED_OPERATION",
93
94
  graphql: "BLUME_GRAPHQL_SKIPPED",
94
95
  openapi: "BLUME_OPENAPI_REF_PATH_ITEM",
95
- } satisfies Record<ReferenceSource["kind"], string>;
96
+ } satisfies Record<BlumeReferenceSource["kind"], string>;
96
97
 
97
98
  /** `_EMPTY` diagnostic suggestion per kind. */
98
99
  const EMPTY_SUGGESTIONS = {
@@ -102,7 +103,7 @@ const EMPTY_SUGGESTIONS = {
102
103
  "Check the spec points at a GraphQL schema (SDL or introspection JSON) whose root types declare fields.",
103
104
  openapi:
104
105
  "Check the spec points at an OpenAPI document with operations under `paths`.",
105
- } satisfies Record<ReferenceSource["kind"], string>;
106
+ } satisfies Record<BlumeReferenceSource["kind"], string>;
106
107
 
107
108
  /** `_UNAVAILABLE` suggestion for a readable-but-invalid spec, per kind. */
108
109
  const INVALID_SUGGESTIONS = {
@@ -112,7 +113,26 @@ const INVALID_SUGGESTIONS = {
112
113
  "Point the spec at a GraphQL schema — SDL text or an introspection JSON result.",
113
114
  openapi:
114
115
  "Point the spec at an OpenAPI document (a YAML or JSON file with an object at the top level).",
115
- } satisfies Record<ReferenceSource["kind"], string>;
116
+ } satisfies Record<BlumeReferenceSource["kind"], string>;
117
+
118
+ /**
119
+ * What to suggest for a spec that failed to load: the install command when
120
+ * reading it needs a package the project lacks, a fix to the file when it
121
+ * isn't a spec of its kind, and reachability for everything else (a fetch or
122
+ * read failure).
123
+ */
124
+ const failureSuggestion = (
125
+ error: Error,
126
+ kind: BlumeReferenceSource["kind"]
127
+ ): string => {
128
+ if (error instanceof SpecDependencyError) {
129
+ return error.suggestion;
130
+ }
131
+ if (error instanceof InvalidSpecError) {
132
+ return INVALID_SUGGESTIONS[kind];
133
+ }
134
+ return "Check the spec URL/path is reachable from the build environment; behind a proxy, set HTTP(S)_PROXY.";
135
+ };
116
136
 
117
137
  const toEntry = (rendered: RenderedPage, ref: string): SourceEntry => {
118
138
  const raw = matter.stringify(`${rendered.body}\n`, rendered.data);
@@ -131,7 +151,7 @@ const toEntry = (rendered: RenderedPage, ref: string): SourceEntry => {
131
151
  const specEntries = (
132
152
  spec: ApiSpecData,
133
153
  operations: ApiOperationRef[],
134
- reference: ReferenceSource
154
+ reference: BlumeReferenceSource
135
155
  ): SourceEntry[] => {
136
156
  const entries = operations.map((operation) =>
137
157
  toEntry(
@@ -193,7 +213,7 @@ interface ParsedReference {
193
213
  }
194
214
 
195
215
  const parseReference = async (
196
- reference: ReferenceSource,
216
+ reference: BlumeReferenceSource,
197
217
  ctx: SourceContext
198
218
  ): Promise<ParsedReference> => {
199
219
  const options = { cacheDir: ctx.cacheDir, refresh: ctx.refresh };
@@ -243,13 +263,13 @@ const parseReference = async (
243
263
  };
244
264
 
245
265
  export const openApiSource = (
246
- references: ReferenceSource[],
266
+ references: BlumeReferenceSource[],
247
267
  ctx: SourceContext
248
268
  ): OpenApiContentSource => {
249
269
  let parsed: OpenApiData = {};
250
270
 
251
271
  const loadReference = async (
252
- reference: ReferenceSource
272
+ reference: BlumeReferenceSource
253
273
  ): Promise<LoadedSpec | Diagnostic> => {
254
274
  // Human label and diagnostic-code prefix for the spec's kind, so an
255
275
  // AsyncAPI failure never reads as an OpenAPI one.
@@ -335,21 +355,17 @@ export const openApiSource = (
335
355
  spec,
336
356
  };
337
357
  } catch (error) {
358
+ // SAFETY: spec loading fails with Error instances (fetch, read, parse,
359
+ // and missing-package errors alike).
360
+ const failure = error as Error;
338
361
  return {
339
362
  code: `${codePrefix}_UNAVAILABLE`,
340
- // SAFETY: spec loading fails with Error instances (fetch, read, and
341
- // parse errors alike); only the message is read for the diagnostic.
342
- message: `Could not load ${kindLabel} spec "${reference.spec}" for ${reference.route} (${(error as Error).message}); its reference pages were skipped.`,
363
+ message: `Could not load ${kindLabel} spec "${reference.spec}" for ${reference.route} (${failure.message}); its reference pages were skipped.`,
343
364
  // A configured-but-unloadable spec ships a dead nav tab (a 404 route),
344
365
  // so fail loudly in build (blocks under --strict) while staying a warning
345
366
  // in dev so offline work still runs.
346
367
  severity: ctx.mode === "build" ? "error" : "warning",
347
- // A readable-but-invalid file is a content problem, not a network one;
348
- // only point at reachability for actual fetch/read failures.
349
- suggestion:
350
- error instanceof InvalidSpecError
351
- ? INVALID_SUGGESTIONS[reference.kind]
352
- : "Check the spec URL/path is reachable from the build environment; behind a proxy, set HTTP(S)_PROXY.",
368
+ suggestion: failureSuggestion(failure, reference.kind),
353
369
  };
354
370
  }
355
371
  };
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Reading a spec needs an optional package the project hasn't installed (the
3
+ * AsyncAPI converter, for a pre-3.0 document). Carries its own suggestion —
4
+ * the install command — because neither of the other spec failures fits: the
5
+ * file is fine and so is the network.
6
+ */
7
+ export class SpecDependencyError extends Error {
8
+ readonly suggestion: string;
9
+
10
+ constructor(message: string, suggestion: string) {
11
+ super(message);
12
+ this.name = "SpecDependencyError";
13
+ this.suggestion = suggestion;
14
+ }
15
+ }
@@ -0,0 +1,83 @@
1
+ import { z } from "zod";
2
+
3
+ import type { AdapterDescriptor } from "../core/adapter.ts";
4
+ import { adapterDescriptorSchema } from "../core/adapter.ts";
5
+ import {
6
+ liftSpec,
7
+ referenceSourceSchema,
8
+ hasSources,
9
+ missingSourcesIssue,
10
+ rendererRemovedHint,
11
+ sharedOptions,
12
+ } from "./options.ts";
13
+ import type { PlaygroundOptions, ReferenceSourceOptions } from "./options.ts";
14
+
15
+ /** Options for {@link asyncapi}. */
16
+ export interface AsyncApiOptions {
17
+ /**
18
+ * Code-sample tools shown per operation (Blume renderer). Defaults to every
19
+ * tool appropriate to the operation's protocol binding.
20
+ */
21
+ codeSamples?: string[];
22
+ /** Start nested schema rows expanded rather than collapsed (Blume renderer). Defaults to `false`. */
23
+ expandSchemas?: boolean;
24
+ /**
25
+ * The "Try it" message composer (Blume renderer). On by default; `false`
26
+ * hides it. `proxy` is accepted for parity but doesn't apply to event
27
+ * operations — a WebSocket connect goes straight from the browser.
28
+ */
29
+ playground?: PlaygroundOptions;
30
+ /** Where the reference mounts. Defaults to `/events`. */
31
+ route?: string;
32
+ /** One or more specs; each renders on its own route by default. */
33
+ sources?: ReferenceSourceOptions[];
34
+ /** Shorthand for a single source: `sources: [{ spec }]`. */
35
+ spec?: string;
36
+ }
37
+
38
+ export const asyncapiOptionsSchema = z
39
+ .strictObject(
40
+ {
41
+ // Empty `codeSamples` means every tool the operation's protocol binding
42
+ // suggests.
43
+ ...sharedOptions({ codeSamples: [], route: "/events" }),
44
+ /** Start nested schema rows expanded rather than collapsed (Blume renderer). */
45
+ expandSchemas: z.boolean().default(false),
46
+ /** One or more specs; each renders on its own route by default. */
47
+ sources: z.array(referenceSourceSchema).default([]),
48
+ },
49
+ rendererRemovedHint
50
+ )
51
+ .transform(liftSpec(referenceSourceSchema))
52
+ .refine(hasSources, missingSourcesIssue("asyncapi"));
53
+
54
+ /** `asyncapi()` options with every default applied and `spec` folded into `sources`. */
55
+ export type ResolvedAsyncApiOptions = z.output<typeof asyncapiOptionsSchema>;
56
+
57
+ export type AsyncApiAdapter = AdapterDescriptor<"asyncapi", AsyncApiOptions>;
58
+
59
+ /** An `asyncapi()` descriptor as the config schema resolves it. */
60
+ export type ResolvedAsyncApiAdapter = AdapterDescriptor<
61
+ "asyncapi",
62
+ ResolvedAsyncApiOptions
63
+ >;
64
+
65
+ export const asyncapiAdapterSchema = adapterDescriptorSchema(
66
+ "asyncapi",
67
+ asyncapiOptionsSchema
68
+ );
69
+
70
+ /**
71
+ * An AsyncAPI reference. Blume normalizes the spec to AsyncAPI 3.x and renders
72
+ * its own UI — one real page per operation, in the sidebar, search, llms.txt,
73
+ * and OG; a `scalar()` adapter is the embedded-SPA alternative. Only the
74
+ * defaults differ from `openapi()`: the reference mounts at `/events`, and
75
+ * empty `codeSamples` means every tool the operation's protocol binding
76
+ * suggests.
77
+ */
78
+ export const asyncapi = (options: AsyncApiOptions): AsyncApiAdapter => ({
79
+ kind: "asyncapi",
80
+ options,
81
+ requiredSecrets: [],
82
+ runtimeDeps: [],
83
+ });
@@ -0,0 +1,89 @@
1
+ import { z } from "zod";
2
+
3
+ import type { AdapterDescriptor } from "../core/adapter.ts";
4
+ import { adapterDescriptorSchema } from "../core/adapter.ts";
5
+ import {
6
+ graphqlSourceSchema,
7
+ liftSpec,
8
+ hasSources,
9
+ missingSourcesIssue,
10
+ sharedOptions,
11
+ } from "./options.ts";
12
+ import type { GraphqlSourceOptions, PlaygroundOptions } from "./options.ts";
13
+
14
+ /** Options for {@link graphql}. */
15
+ export interface GraphqlOptions {
16
+ /** Code-sample languages shown per operation. Defaults to `["curl", "js", "python"]`. */
17
+ codeSamples?: string[];
18
+ /**
19
+ * URL of the live GraphQL endpoint the playground and code samples target —
20
+ * a schema, unlike an OpenAPI document, names no server. Applies to every
21
+ * source; a per-source `endpoint` wins.
22
+ */
23
+ endpoint?: string;
24
+ /**
25
+ * The interactive "Try it" panel. On by default; `false` hides it. The
26
+ * object form sets `proxy`, the CORS escape hatch the Send button routes
27
+ * requests through: a proxy URL, or `true` for the built-in `/_api-proxy`
28
+ * endpoint (which needs server output: a host adapter such as `vercel()` in
29
+ * `deployment`).
30
+ */
31
+ playground?: PlaygroundOptions;
32
+ /** Where the reference mounts. Defaults to `/graphql`. */
33
+ route?: string;
34
+ /** One or more schemas; each renders on its own route by default. */
35
+ sources?: GraphqlSourceOptions[];
36
+ /** Shorthand for a single source: `sources: [{ spec }]`. */
37
+ spec?: string;
38
+ }
39
+
40
+ /**
41
+ * No `expandSchemas` (GraphQL field tables have no nesting) — everything
42
+ * else, the playground normalization included, is the shared reference
43
+ * shape. There is no Scalar counterpart: the Scalar embed reads OpenAPI and
44
+ * AsyncAPI documents only.
45
+ */
46
+ export const graphqlOptionsSchema = z
47
+ .strictObject({
48
+ ...sharedOptions({
49
+ codeSamples: ["curl", "js", "python"],
50
+ route: "/graphql",
51
+ }),
52
+ /** Default live endpoint URL for every source (per-source `endpoint` wins). */
53
+ endpoint: z.string().optional(),
54
+ /** One or more schemas; each renders on its own route by default. */
55
+ sources: z.array(graphqlSourceSchema).default([]),
56
+ })
57
+ .transform(liftSpec(graphqlSourceSchema))
58
+ .refine(hasSources, missingSourcesIssue("graphql"));
59
+
60
+ /** `graphql()` options with every default applied and `spec` folded into `sources`. */
61
+ export type ResolvedGraphqlOptions = z.output<typeof graphqlOptionsSchema>;
62
+
63
+ export type GraphqlAdapter = AdapterDescriptor<"graphql", GraphqlOptions>;
64
+
65
+ /** A `graphql()` descriptor as the config schema resolves it. */
66
+ export type ResolvedGraphqlAdapter = AdapterDescriptor<
67
+ "graphql",
68
+ ResolvedGraphqlOptions
69
+ >;
70
+
71
+ export const graphqlAdapterSchema = adapterDescriptorSchema(
72
+ "graphql",
73
+ graphqlOptionsSchema
74
+ );
75
+
76
+ /**
77
+ * A GraphQL reference. Blume lowers the schema (SDL or introspection JSON) to
78
+ * one real page per root field — grouped as Queries/Mutations/Subscriptions —
79
+ * plus one page per named type (Objects, Input Objects, Enums, Interfaces,
80
+ * Unions, Scalars), all included in the sidebar, search, llms.txt, and OG.
81
+ * Always Blume-rendered: the Scalar embed reads OpenAPI and AsyncAPI
82
+ * documents only, so there is no `scalar()` counterpart.
83
+ */
84
+ export const graphql = (options: GraphqlOptions): GraphqlAdapter => ({
85
+ kind: "graphql",
86
+ options,
87
+ requiredSecrets: [],
88
+ runtimeDeps: [],
89
+ });
@@ -0,0 +1,40 @@
1
+ /**
2
+ * API reference adapters for `blume.config.ts`:
3
+ *
4
+ * ```ts
5
+ * import { defineConfig } from "blume";
6
+ * import { asyncapi, graphql, openapi, scalar } from "blume/reference";
7
+ *
8
+ * export default defineConfig({
9
+ * reference: [
10
+ * openapi({ spec: "./openapi.yaml" }),
11
+ * asyncapi({ spec: "./asyncapi.yaml" }),
12
+ * graphql({ spec: "./schema.graphql", endpoint: "https://api.example.com/graphql" }),
13
+ * scalar({ spec: "./legacy.yaml", route: "/legacy", theme: "purple" }),
14
+ * ],
15
+ * });
16
+ * ```
17
+ *
18
+ * Each factory returns a plain descriptor (see `core/adapter.ts`) that the
19
+ * schema validates and the generated site reads as a literal; nothing here
20
+ * runs in the browser.
21
+ */
22
+ export type { AdapterDescriptor, JsonValue } from "../core/adapter.ts";
23
+ export { asyncapi } from "./asyncapi.ts";
24
+ export type { AsyncApiAdapter, AsyncApiOptions } from "./asyncapi.ts";
25
+ export { graphql } from "./graphql.ts";
26
+ export type { GraphqlAdapter, GraphqlOptions } from "./graphql.ts";
27
+ export { openapi } from "./openapi.ts";
28
+ export type { OpenApiAdapter, OpenApiOptions } from "./openapi.ts";
29
+ export type {
30
+ GraphqlSourceOptions,
31
+ PlaygroundOptions,
32
+ ReferenceSourceOptions,
33
+ } from "./options.ts";
34
+ export { scalar } from "./scalar.ts";
35
+ export type {
36
+ ScalarAdapter,
37
+ ScalarOptions,
38
+ ScalarSourceOptions,
39
+ } from "./scalar.ts";
40
+ export type { ReferenceAdapter, ResolvedReferenceAdapter } from "./schema.ts";
@@ -0,0 +1,83 @@
1
+ import { z } from "zod";
2
+
3
+ import type { AdapterDescriptor } from "../core/adapter.ts";
4
+ import { adapterDescriptorSchema } from "../core/adapter.ts";
5
+ import {
6
+ liftSpec,
7
+ referenceSourceSchema,
8
+ hasSources,
9
+ missingSourcesIssue,
10
+ rendererRemovedHint,
11
+ sharedOptions,
12
+ } from "./options.ts";
13
+ import type { PlaygroundOptions, ReferenceSourceOptions } from "./options.ts";
14
+
15
+ /** Options for {@link openapi}. */
16
+ export interface OpenApiOptions {
17
+ /** Code-sample languages shown per operation (Blume renderer). Defaults to `["curl", "js", "python"]`. */
18
+ codeSamples?: string[];
19
+ /** Start nested schema rows expanded rather than collapsed (Blume renderer). Defaults to `false`. */
20
+ expandSchemas?: boolean;
21
+ /**
22
+ * The interactive "Try it" panel (Blume renderer). On by default; `false`
23
+ * hides it. The object form sets `proxy`, the CORS escape hatch the Send
24
+ * button routes requests through: a proxy URL, or `true` for the built-in
25
+ * `/_api-proxy` endpoint (which needs server output: a host adapter such as
26
+ * `vercel()` in `deployment`).
27
+ */
28
+ playground?: PlaygroundOptions;
29
+ /** Where the reference mounts. Defaults to `/reference`. */
30
+ route?: string;
31
+ /** One or more specs; each renders on its own route by default. */
32
+ sources?: ReferenceSourceOptions[];
33
+ /** Shorthand for a single source: `sources: [{ spec }]`. */
34
+ spec?: string;
35
+ }
36
+
37
+ export const openapiOptionsSchema = z
38
+ .strictObject(
39
+ {
40
+ ...sharedOptions({
41
+ codeSamples: ["curl", "js", "python"],
42
+ route: "/reference",
43
+ }),
44
+ /** Start nested schema rows expanded rather than collapsed (Blume renderer). */
45
+ expandSchemas: z.boolean().default(false),
46
+ /** One or more specs; each renders on its own route by default. */
47
+ sources: z.array(referenceSourceSchema).default([]),
48
+ },
49
+ rendererRemovedHint
50
+ )
51
+ .transform(liftSpec(referenceSourceSchema))
52
+ .refine(hasSources, missingSourcesIssue("openapi"));
53
+
54
+ /** `openapi()` options with every default applied and `spec` folded into `sources`. */
55
+ export type ResolvedOpenApiOptions = z.output<typeof openapiOptionsSchema>;
56
+
57
+ export type OpenApiAdapter = AdapterDescriptor<"openapi", OpenApiOptions>;
58
+
59
+ /** An `openapi()` descriptor as the config schema resolves it. */
60
+ export type ResolvedOpenApiAdapter = AdapterDescriptor<
61
+ "openapi",
62
+ ResolvedOpenApiOptions
63
+ >;
64
+
65
+ export const openapiAdapterSchema = adapterDescriptorSchema(
66
+ "openapi",
67
+ openapiOptionsSchema
68
+ );
69
+
70
+ /**
71
+ * An OpenAPI reference. Blume parses the spec with Scalar's parser and renders
72
+ * its own UI: one real page per operation, grouped by tag in the sidebar and
73
+ * included in site search, llms.txt, and OG. To embed the Scalar SPA instead
74
+ * (a single self-contained route that doesn't weave into the sidebar or
75
+ * search), list a `scalar()` adapter. Blume's renderer parses at generate
76
+ * time and needs no runtime dependency.
77
+ */
78
+ export const openapi = (options: OpenApiOptions): OpenApiAdapter => ({
79
+ kind: "openapi",
80
+ options,
81
+ requiredSecrets: [],
82
+ runtimeDeps: [],
83
+ });
@@ -0,0 +1,201 @@
1
+ import { z } from "zod";
2
+
3
+ import { unrecognizedKeysMessage } from "../core/unrecognized-keys.ts";
4
+
5
+ /**
6
+ * The option pieces every reference adapter shares: a spec source, the "Try
7
+ * it" playground normalization, and the `spec` shorthand that folds into
8
+ * `sources` at parse. Kept apart from the kind modules so `openapi()`,
9
+ * `asyncapi()`, and `graphql()` validate one definition of each.
10
+ */
11
+
12
+ const isBoolean = <Value>(value: Value): value is Value & boolean =>
13
+ typeof value === "boolean";
14
+
15
+ /**
16
+ * A single spec rendered by a reference. `spec` is a local path or an
17
+ * `http(s)` URL (an OpenAPI document for `openapi()`, an AsyncAPI document
18
+ * for `asyncapi()`, SDL or introspection JSON for `graphql()`).
19
+ */
20
+ export const referenceSourceSchema = z.strictObject({
21
+ /** Include generated pages from this spec in llms.txt/llms-full.txt. */
22
+ includeInLlms: z.boolean().default(true),
23
+ /** Include generated pages from this spec in site search. */
24
+ includeInSearch: z.boolean().default(true),
25
+ /** Nav/section label for this source. */
26
+ label: z.string().optional(),
27
+ /** Emit noindex metadata and omit generated pages from the sitemap. */
28
+ noindex: z.boolean().default(false),
29
+ /** Per-source route; defaults to the adapter's `route` (or a derived path). */
30
+ route: z.string().optional(),
31
+ /**
32
+ * Append the English "Reference for the … endpoint in the … API." sentence
33
+ * to every generated operation page's meta description. On by default, so
34
+ * terse specs still ship distinct, snippet-length descriptions; set to
35
+ * `false` on a non-English site to describe pages with the spec's own prose
36
+ * alone (falling back to the page title when an operation has none).
37
+ */
38
+ seoDescriptionSuffix: z.boolean().default(true),
39
+ /** Local path or `http(s)` URL to the spec. */
40
+ spec: z.string(),
41
+ });
42
+
43
+ /** One spec source, as `openapi()` and `asyncapi()` accept it. */
44
+ export interface ReferenceSourceOptions {
45
+ /** Include generated pages from this spec in llms.txt/llms-full.txt. Defaults to `true`. */
46
+ includeInLlms?: boolean;
47
+ /** Include generated pages from this spec in site search. Defaults to `true`. */
48
+ includeInSearch?: boolean;
49
+ /** Nav/section label for this source. */
50
+ label?: string;
51
+ /** Emit noindex metadata and omit generated pages from the sitemap. Defaults to `false`. */
52
+ noindex?: boolean;
53
+ /** Per-source route; defaults to the adapter's `route` (or a derived path). */
54
+ route?: string;
55
+ /**
56
+ * Append the generated English "Reference for …" sentence to every
57
+ * operation page's meta description. Defaults to `true`; set `false` on a
58
+ * non-English site to keep the spec's own prose alone.
59
+ */
60
+ seoDescriptionSuffix?: boolean;
61
+ /** Local path or `http(s)` URL to the spec. */
62
+ spec: string;
63
+ }
64
+
65
+ /** A spec source with every default applied. */
66
+ export type ResolvedReferenceSource = z.output<typeof referenceSourceSchema>;
67
+
68
+ /**
69
+ * A single GraphQL schema: the shared source shape plus `endpoint`, the live
70
+ * GraphQL API URL the playground and code samples target (a schema, unlike an
71
+ * OpenAPI document, names no server).
72
+ */
73
+ export const graphqlSourceSchema = referenceSourceSchema.extend({
74
+ /** URL of the live GraphQL endpoint (playground + code samples). */
75
+ endpoint: z.string().optional(),
76
+ });
77
+
78
+ /** One schema source, as `graphql()` accepts it. */
79
+ export interface GraphqlSourceOptions extends ReferenceSourceOptions {
80
+ /** URL of the live GraphQL endpoint (playground + code samples); wins over the adapter's `endpoint`. */
81
+ endpoint?: string;
82
+ }
83
+
84
+ /** A GraphQL schema source with every default applied. */
85
+ export type ResolvedGraphqlSource = z.output<typeof graphqlSourceSchema>;
86
+
87
+ /**
88
+ * The interactive "Try it" panel on operation pages (Blume renderer). On by
89
+ * default; `false` hides it. The object form keeps it on and sets `proxy`,
90
+ * the CORS escape hatch the Send button routes requests through: a proxy URL,
91
+ * or `true` for the built-in `/_api-proxy` endpoint (which needs server
92
+ * output: a host adapter such as `vercel()` in `deployment`). Booleans
93
+ * normalize to the object shape so consumers read `{ enabled, proxy }`
94
+ * directly. `proxy` applies to the HTTP-posting playgrounds (OpenAPI, GraphQL)
95
+ * — an event composer's WebSocket connect is direct. One schema for every
96
+ * reference kind, so the normalization can never drift between them.
97
+ */
98
+ export const playgroundSchema = z
99
+ .union([
100
+ z.boolean(),
101
+ z.strictObject({
102
+ enabled: z.boolean().default(true),
103
+ proxy: z.union([z.boolean(), z.string()]).default(false),
104
+ }),
105
+ ])
106
+ .default(true)
107
+ .transform((value) =>
108
+ isBoolean(value) ? { enabled: value, proxy: false } : value
109
+ );
110
+
111
+ /** The `playground` option as a factory accepts it. */
112
+ export type PlaygroundOptions =
113
+ | boolean
114
+ | {
115
+ /** Render the panel. Defaults to `true`. */
116
+ enabled?: boolean;
117
+ /** CORS proxy: a URL, or `true` for the built-in `/_api-proxy` route. Defaults to `false`. */
118
+ proxy?: boolean | string;
119
+ };
120
+
121
+ /** The playground with its booleans normalized: `{ enabled, proxy }`. */
122
+ export type ResolvedPlayground = z.output<typeof playgroundSchema>;
123
+
124
+ /**
125
+ * The message a config still passing `renderer` to `openapi()`/`asyncapi()`
126
+ * gets: Scalar is its own adapter now, so the option has no home.
127
+ */
128
+ export const RENDERER_REMOVED_HINT =
129
+ '`renderer` was removed: the Scalar embed is its own adapter. Replace `openapi({ spec, renderer: "scalar", theme })` with a separate `scalar({ spec, theme })` entry in `reference`, imported from "blume/reference" — `route`, `sources`, `label`, and `noindex` carry over, and the native display options (`codeSamples`, `expandSchemas`, `playground`) don\'t apply to the embed.';
130
+
131
+ /**
132
+ * Error params for the `openapi()`/`asyncapi()` option objects: a leftover
133
+ * `renderer` key names its replacement instead of Zod's bare "Unrecognized
134
+ * key"; any other unknown key keeps the default message, beside the hint.
135
+ */
136
+ export const rendererRemovedHint = {
137
+ error: (issue: z.core.$ZodRawIssue): string | undefined => {
138
+ if (
139
+ issue.code !== "unrecognized_keys" ||
140
+ !issue.keys.includes("renderer")
141
+ ) {
142
+ return;
143
+ }
144
+ const others = issue.keys.filter((key) => key !== "renderer");
145
+ return others.length > 0
146
+ ? `${RENDERER_REMOVED_HINT} ${unrecognizedKeysMessage(others)}`
147
+ : RENDERER_REMOVED_HINT;
148
+ },
149
+ };
150
+
151
+ /**
152
+ * The options every kind shares, with that kind's defaults for the mount
153
+ * route and code-sample set. `spec` is the single-source shorthand; the kind
154
+ * schema folds it into `sources` with {@link liftSpec}.
155
+ */
156
+ export const sharedOptions = (defaults: {
157
+ codeSamples: string[];
158
+ route: string;
159
+ }) => ({
160
+ /** Code-sample languages/tools shown per operation (Blume renderer). */
161
+ codeSamples: z.array(z.string()).default(defaults.codeSamples),
162
+ /** The "Try it" panel; see {@link playgroundSchema}. */
163
+ playground: playgroundSchema,
164
+ /** Where the reference mounts. */
165
+ route: z.string().default(defaults.route),
166
+ /** Shorthand for a single source: `sources: [{ spec }]`. */
167
+ spec: z.string().optional(),
168
+ });
169
+
170
+ /**
171
+ * Resolve the `spec` shorthand into `sources` so downstream code reads one
172
+ * field: the shorthand becomes the first source (with the source defaults
173
+ * applied through the source schema itself, so the two can never drift) and
174
+ * the `spec` key is dropped. An adapter with neither renders nothing, which
175
+ * is a config mistake rather than a choice — `refine` it away with
176
+ * {@link hasSources}.
177
+ */
178
+ export const liftSpec =
179
+ <Source extends { spec: string }>(
180
+ sourceSchema: z.ZodType<Source, { spec: string }>
181
+ ) =>
182
+ <Options extends { sources: Source[]; spec?: string }>({
183
+ spec,
184
+ ...options
185
+ }: Options): Omit<Options, "spec"> => ({
186
+ ...options,
187
+ sources:
188
+ spec === undefined
189
+ ? options.sources
190
+ : [sourceSchema.parse({ spec }), ...options.sources],
191
+ });
192
+
193
+ /** Whether an adapter has anything to render; pairs with {@link missingSourcesIssue}. */
194
+ export const hasSources = (options: { sources: { spec: string }[] }): boolean =>
195
+ options.sources.length > 0;
196
+
197
+ /** The refinement issue for a source-less adapter, naming its factory. */
198
+ export const missingSourcesIssue = (factory: string) => ({
199
+ message: `${factory}() renders nothing without a spec — set \`spec\` or at least one \`sources\` entry.`,
200
+ path: ["sources"],
201
+ });