blume 2.0.2 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (601) hide show
  1. package/AGENTS.md +1 -0
  2. package/CHANGELOG.md +113 -0
  3. package/README.md +1 -1
  4. package/dist/cli/{chunk-6k4ftwze.js → chunk-0gz36akr.js} +18 -2
  5. package/dist/cli/{chunk-6k4ftwze.js.map → chunk-0gz36akr.js.map} +3 -3
  6. package/dist/cli/{chunk-zp79m0ts.js → chunk-1n228xqb.js} +2 -2
  7. package/dist/cli/{chunk-ddndchfr.js → chunk-2f3ndkpw.js} +57 -29
  8. package/dist/cli/chunk-2f3ndkpw.js.map +14 -0
  9. package/dist/cli/{chunk-fsmrqk8a.js → chunk-2f7n4qzt.js} +8 -2
  10. package/dist/cli/{chunk-fsmrqk8a.js.map → chunk-2f7n4qzt.js.map} +3 -3
  11. package/dist/cli/{chunk-ppzjqwx2.js → chunk-2n4ps1b3.js} +17 -18
  12. package/dist/cli/{chunk-ppzjqwx2.js.map → chunk-2n4ps1b3.js.map} +3 -3
  13. package/dist/cli/{chunk-5r8g91qn.js → chunk-43zcf4gz.js} +398 -159
  14. package/dist/cli/chunk-43zcf4gz.js.map +36 -0
  15. package/dist/cli/chunk-4ejxbzee.js +39 -0
  16. package/dist/cli/chunk-4ejxbzee.js.map +10 -0
  17. package/dist/cli/{chunk-hr8ne106.js → chunk-4h8z9vv5.js} +296 -77
  18. package/dist/cli/chunk-4h8z9vv5.js.map +16 -0
  19. package/dist/cli/{chunk-k7pj68a8.js → chunk-5cg2rzgf.js} +18 -16
  20. package/dist/cli/{chunk-k7pj68a8.js.map → chunk-5cg2rzgf.js.map} +2 -2
  21. package/dist/cli/{chunk-h2ez8dzb.js → chunk-5ffywsmb.js} +4 -4
  22. package/dist/cli/{chunk-g698a744.js → chunk-5wj2qwn2.js} +5 -5
  23. package/dist/cli/chunk-6bm0xpgd.js +18 -0
  24. package/dist/cli/chunk-6bm0xpgd.js.map +10 -0
  25. package/dist/cli/{chunk-3yce002v.js → chunk-713mngdq.js} +15 -8
  26. package/dist/cli/chunk-713mngdq.js.map +14 -0
  27. package/dist/cli/{chunk-91ws1n6j.js → chunk-9geymqns.js} +17 -15
  28. package/dist/cli/{chunk-91ws1n6j.js.map → chunk-9geymqns.js.map} +2 -2
  29. package/dist/cli/{chunk-6dtt0zfn.js → chunk-9xr4dgee.js} +27 -18
  30. package/dist/cli/chunk-9xr4dgee.js.map +10 -0
  31. package/dist/cli/{chunk-sqw4ekg1.js → chunk-amrb6hgh.js} +2 -2
  32. package/dist/cli/chunk-cm89scdv.js +443 -0
  33. package/dist/cli/chunk-cm89scdv.js.map +11 -0
  34. package/dist/cli/{chunk-wdrt2k2v.js → chunk-cmtcnh9f.js} +90 -26
  35. package/dist/cli/chunk-cmtcnh9f.js.map +10 -0
  36. package/dist/cli/chunk-cy5bm0j0.js +104 -0
  37. package/dist/cli/chunk-cy5bm0j0.js.map +11 -0
  38. package/dist/cli/{chunk-7mbqtmgb.js → chunk-e7vvk5ya.js} +21 -12
  39. package/dist/cli/chunk-e7vvk5ya.js.map +10 -0
  40. package/dist/cli/{chunk-qkb5a8sa.js → chunk-g2z9x01v.js} +6 -98
  41. package/dist/cli/chunk-g2z9x01v.js.map +10 -0
  42. package/dist/cli/{chunk-273ygyr4.js → chunk-ga0pf4aj.js} +7 -7
  43. package/dist/cli/{chunk-273ygyr4.js.map → chunk-ga0pf4aj.js.map} +3 -3
  44. package/dist/cli/{chunk-h7k3nq3v.js → chunk-gp84za0h.js} +2 -2
  45. package/dist/cli/{chunk-hqp2ajnh.js → chunk-h2a48yhd.js} +195 -73
  46. package/dist/cli/chunk-h2a48yhd.js.map +36 -0
  47. package/dist/cli/{chunk-pbg5a4s3.js → chunk-jnwj5kjj.js} +71 -47
  48. package/dist/cli/chunk-jnwj5kjj.js.map +19 -0
  49. package/dist/cli/chunk-kwrg63tm.js +31 -0
  50. package/dist/cli/chunk-kwrg63tm.js.map +10 -0
  51. package/dist/cli/{chunk-8g8ytmgx.js → chunk-nd1821sk.js} +21 -19
  52. package/dist/cli/{chunk-8g8ytmgx.js.map → chunk-nd1821sk.js.map} +2 -2
  53. package/dist/cli/{chunk-w4bxdvsa.js → chunk-ntv4qrt7.js} +17 -15
  54. package/dist/cli/{chunk-w4bxdvsa.js.map → chunk-ntv4qrt7.js.map} +2 -2
  55. package/dist/cli/{chunk-bfwp9vp6.js → chunk-p804f3pe.js} +7 -7
  56. package/dist/cli/{chunk-4e9b9ra6.js → chunk-py62fewh.js} +6 -6
  57. package/dist/cli/{chunk-4e9b9ra6.js.map → chunk-py62fewh.js.map} +1 -1
  58. package/dist/cli/chunk-q3wxxq39.js +126 -0
  59. package/dist/cli/chunk-q3wxxq39.js.map +11 -0
  60. package/dist/cli/{chunk-j85scx15.js → chunk-rekqz4qg.js} +142 -46
  61. package/dist/cli/chunk-rekqz4qg.js.map +10 -0
  62. package/dist/cli/{chunk-00gs3wqs.js → chunk-ta27feev.js} +1 -1
  63. package/dist/cli/{chunk-v6ya5kcb.js → chunk-xkz5xbtv.js} +4031 -1132
  64. package/dist/cli/chunk-xkz5xbtv.js.map +213 -0
  65. package/dist/cli/{chunk-bbnwccaz.js → chunk-y4ykbark.js} +2 -2
  66. package/dist/cli/{chunk-n1yg3tj3.js → chunk-y5h4r2y0.js} +6 -6
  67. package/dist/cli/{chunk-n1yg3tj3.js.map → chunk-y5h4r2y0.js.map} +3 -3
  68. package/dist/cli/{chunk-nfcyttvj.js → chunk-yj17vs39.js} +9 -9
  69. package/dist/cli/{chunk-nfcyttvj.js.map → chunk-yj17vs39.js.map} +1 -1
  70. package/dist/cli/{chunk-7vtckvaw.js → chunk-yxmk4pec.js} +16 -14
  71. package/dist/cli/{chunk-7vtckvaw.js.map → chunk-yxmk4pec.js.map} +2 -2
  72. package/dist/cli/{chunk-gs7r695n.js → chunk-zccbjcj0.js} +22 -8
  73. package/dist/cli/{chunk-gs7r695n.js.map → chunk-zccbjcj0.js.map} +3 -3
  74. package/dist/cli/{chunk-xh43dwgw.js → chunk-zf748avv.js} +415 -225
  75. package/dist/cli/chunk-zf748avv.js.map +37 -0
  76. package/dist/cli/{chunk-d1v5rhy0.js → chunk-zhvd6adm.js} +16 -14
  77. package/dist/cli/{chunk-d1v5rhy0.js.map → chunk-zhvd6adm.js.map} +2 -2
  78. package/dist/cli/index.js +28 -20
  79. package/dist/cli/index.js.map +5 -5
  80. package/dist/types/ai/agent-surface.d.ts +8 -7
  81. package/dist/types/ai/ai-catalog.d.ts +7 -0
  82. package/dist/types/ai/ask-context.d.ts +22 -0
  83. package/dist/types/ai/ask.d.ts +271 -58
  84. package/dist/types/ai/index.d.ts +2 -2
  85. package/dist/types/ai/link-headers.d.ts +8 -1
  86. package/dist/types/ai/openapi-components.d.ts +5 -2
  87. package/dist/types/ai/relative-links.d.ts +9 -7
  88. package/dist/types/ai/site-skill.d.ts +26 -0
  89. package/dist/types/ai/skills.d.ts +20 -1
  90. package/dist/types/ai/tar.d.ts +1 -3
  91. package/dist/types/analytics/index.d.ts +2 -0
  92. package/dist/types/analytics/one-dollar-stats.d.ts +48 -0
  93. package/dist/types/analytics/schema.d.ts +14 -0
  94. package/dist/types/astro/integration.d.ts +11 -2
  95. package/dist/types/captcha/hcaptcha.d.ts +27 -0
  96. package/dist/types/captcha/index.d.ts +28 -0
  97. package/dist/types/captcha/schema.d.ts +29 -0
  98. package/dist/types/captcha/turnstile.d.ts +28 -0
  99. package/dist/types/components/content/api-field.d.ts +59 -0
  100. package/dist/types/components/content/api-page.d.ts +95 -0
  101. package/dist/types/components/layout/nav-utils.d.ts +26 -0
  102. package/dist/types/components/openapi/helpers.d.ts +137 -0
  103. package/dist/types/components/openapi/security.d.ts +85 -0
  104. package/dist/types/consent/ethyca.d.ts +48 -0
  105. package/dist/types/consent/index.d.ts +37 -0
  106. package/dist/types/consent/native.d.ts +28 -0
  107. package/dist/types/consent/osano.d.ts +42 -0
  108. package/dist/types/consent/schema.d.ts +110 -0
  109. package/dist/types/core/base-path.d.ts +21 -7
  110. package/dist/types/core/config-input.d.ts +196 -27
  111. package/dist/types/core/data.d.ts +49 -4
  112. package/dist/types/core/directive-diagnostics.d.ts +12 -0
  113. package/dist/types/core/footer.d.ts +8 -0
  114. package/dist/types/core/heading-markers.d.ts +5 -7
  115. package/dist/types/core/i18n-ui.d.ts +86 -0
  116. package/dist/types/core/i18n.d.ts +2 -0
  117. package/dist/types/core/includes.d.ts +8 -2
  118. package/dist/types/core/last-modified.d.ts +10 -0
  119. package/dist/types/core/localizable.d.ts +7 -0
  120. package/dist/types/core/meta.d.ts +8 -0
  121. package/dist/types/core/page-modes.d.ts +29 -0
  122. package/dist/types/core/redirect-patterns.d.ts +144 -0
  123. package/dist/types/core/related.d.ts +40 -0
  124. package/dist/types/core/schema.d.ts +558 -56
  125. package/dist/types/core/sources/lower.d.ts +29 -16
  126. package/dist/types/core/sources/normalize.d.ts +13 -1
  127. package/dist/types/core/sources/read.d.ts +5 -0
  128. package/dist/types/core/sources/watch.d.ts +12 -5
  129. package/dist/types/core/standard-schema.d.ts +5 -0
  130. package/dist/types/core/types.d.ts +1 -1
  131. package/dist/types/core/variables.d.ts +42 -0
  132. package/dist/types/deploy/artifacts.d.ts +6 -4
  133. package/dist/types/deploy/headers.d.ts +5 -0
  134. package/dist/types/deploy/node-headers.d.ts +13 -2
  135. package/dist/types/deploy/platforms/cloudflare.d.ts +5 -0
  136. package/dist/types/deploy/platforms/netlify.d.ts +7 -0
  137. package/dist/types/deploy/platforms/types.d.ts +8 -0
  138. package/dist/types/deploy/platforms/vercel.d.ts +6 -0
  139. package/dist/types/deploy/redirects.d.ts +61 -22
  140. package/dist/types/deploy/vercel-negotiation.d.ts +9 -0
  141. package/dist/types/markdown/code-title.d.ts +17 -0
  142. package/dist/types/markdown/directives.d.ts +62 -0
  143. package/dist/types/markdown/features.d.ts +24 -2
  144. package/dist/types/markdown/mdast.d.ts +63 -0
  145. package/dist/types/narration/build.d.ts +70 -0
  146. package/dist/types/narration/provider.d.ts +26 -0
  147. package/dist/types/narration/script.d.ts +154 -0
  148. package/dist/types/openapi/asyncapi.d.ts +4 -2
  149. package/dist/types/openapi/model.d.ts +12 -6
  150. package/dist/types/openapi/overlay.d.ts +54 -0
  151. package/dist/types/openapi/parse.d.ts +13 -0
  152. package/dist/types/openapi/references.d.ts +14 -4
  153. package/dist/types/ratelimit/cloudflare.d.ts +39 -0
  154. package/dist/types/ratelimit/index.d.ts +27 -0
  155. package/dist/types/ratelimit/memory.d.ts +36 -0
  156. package/dist/types/ratelimit/schema.d.ts +111 -0
  157. package/dist/types/ratelimit/upstash.d.ts +21 -0
  158. package/dist/types/ratelimit/wrangler.d.ts +23 -0
  159. package/dist/types/reference/asyncapi.d.ts +10 -10
  160. package/dist/types/reference/graphql.d.ts +13 -10
  161. package/dist/types/reference/openapi.d.ts +33 -12
  162. package/dist/types/reference/options.d.ts +45 -5
  163. package/dist/types/reference/scalar.d.ts +13 -0
  164. package/dist/types/reference/schema.d.ts +60 -36
  165. package/dist/types/search/documents.d.ts +12 -1
  166. package/dist/types/search/orama-index.d.ts +4 -0
  167. package/dist/types/seo/metatags.d.ts +20 -0
  168. package/docs/02-deployment.mdx +44 -6
  169. package/docs/03-upgrading.mdx +4 -4
  170. package/docs/04-migrating.mdx +1 -1
  171. package/docs/08-faq.mdx +1 -1
  172. package/docs/advanced/changelog.mdx +2 -2
  173. package/docs/advanced/custom-pages.mdx +3 -3
  174. package/docs/advanced/skills.mdx +14 -0
  175. package/docs/cli/audit.mdx +38 -2
  176. package/docs/cli/evals.mdx +3 -3
  177. package/docs/cli/index.mdx +1 -0
  178. package/docs/cli/translate.mdx +3 -3
  179. package/docs/cli/version.mdx +1 -1
  180. package/docs/configuration/analytics.mdx +22 -1
  181. package/docs/configuration/assistant.mdx +188 -36
  182. package/docs/configuration/consent.mdx +100 -0
  183. package/docs/configuration/customization.mdx +6 -4
  184. package/docs/configuration/index.mdx +63 -5
  185. package/docs/configuration/meta.ts +3 -0
  186. package/docs/configuration/narration.mdx +119 -0
  187. package/docs/configuration/rate-limiting.mdx +69 -0
  188. package/docs/configuration/search.mdx +30 -2
  189. package/docs/configuration/theming.mdx +3 -1
  190. package/docs/content/components.mdx +107 -1
  191. package/docs/content/frontmatter.mdx +77 -1
  192. package/docs/content/i18n.mdx +40 -3
  193. package/docs/content/includes.mdx +16 -0
  194. package/docs/content/index.mdx +4 -2
  195. package/docs/content/islands.mdx +1 -1
  196. package/docs/content/meta.mdx +4 -1
  197. package/docs/content/meta.ts +1 -0
  198. package/docs/content/navigation.mdx +28 -6
  199. package/docs/content/sources/contentful.mdx +32 -0
  200. package/docs/content/sources/custom.mdx +39 -0
  201. package/docs/content/sources/github-releases.mdx +31 -0
  202. package/docs/content/sources/index.mdx +91 -0
  203. package/docs/content/sources/meta.ts +16 -0
  204. package/docs/content/sources/notion.mdx +32 -0
  205. package/docs/content/sources/obsidian.mdx +37 -0
  206. package/docs/content/sources/payload.mdx +30 -0
  207. package/docs/content/sources/remote-mdx.mdx +40 -0
  208. package/docs/content/sources/sanity.mdx +29 -0
  209. package/docs/content/sources/strapi.mdx +31 -0
  210. package/docs/content/syntax.mdx +81 -2
  211. package/docs/content/variables.mdx +41 -0
  212. package/docs/content/versioning.mdx +1 -1
  213. package/docs/discoverability/agent-discovery.mdx +30 -3
  214. package/docs/discoverability/index.mdx +3 -2
  215. package/docs/discoverability/llms-txt.mdx +1 -1
  216. package/docs/discoverability/markdown.mdx +2 -2
  217. package/docs/discoverability/metadata.mdx +17 -0
  218. package/docs/discoverability/open-graph.mdx +5 -3
  219. package/docs/discoverability/rss.mdx +1 -1
  220. package/docs/references/api-pages.mdx +74 -0
  221. package/docs/references/asyncapi.mdx +2 -2
  222. package/docs/references/graphql.mdx +3 -3
  223. package/docs/references/meta.ts +1 -1
  224. package/docs/references/openapi.mdx +106 -5
  225. package/docs/references/scalar.mdx +3 -1
  226. package/package.json +36 -1
  227. package/skills/blume/SKILL.md +3 -0
  228. package/skills/blume-migrate/SKILL.md +5 -5
  229. package/skills/blume-migrate/references/docusaurus.md +3 -3
  230. package/skills/blume-migrate/references/fumadocs.md +1 -1
  231. package/skills/blume-migrate/references/mintlify.md +37 -19
  232. package/skills/blume-migrate/references/nextra.md +3 -3
  233. package/skills/blume-migrate/references/starlight.md +2 -1
  234. package/skills/blume-migrate/scripts/mintlify-codemod.mjs +67 -16
  235. package/skills/blume-write-skill/SKILL.md +82 -0
  236. package/src/ai/agent-readability.ts +4 -3
  237. package/src/ai/agent-surface.ts +9 -7
  238. package/src/ai/ai-catalog.ts +12 -5
  239. package/src/ai/api/handlers.ts +2 -2
  240. package/src/ai/api/spec.ts +2 -2
  241. package/src/ai/api-catalog.ts +6 -2
  242. package/src/ai/ask-context.ts +73 -20
  243. package/src/ai/ask-data.ts +6 -0
  244. package/src/ai/ask-tools.ts +142 -0
  245. package/src/ai/ask.ts +354 -76
  246. package/src/ai/changelog-markdown.ts +2 -2
  247. package/src/ai/component-markdown.ts +75 -0
  248. package/src/ai/cors.ts +2 -0
  249. package/src/ai/index.ts +12 -0
  250. package/src/ai/link-headers.ts +14 -5
  251. package/src/ai/llms.ts +24 -9
  252. package/src/ai/markdown.ts +2 -1
  253. package/src/ai/mcp/data.ts +6 -0
  254. package/src/ai/mcp/discovery.ts +2 -2
  255. package/src/ai/mcp/query.ts +2 -2
  256. package/src/ai/mcp/server.ts +2 -2
  257. package/src/ai/openapi-components.ts +31 -9
  258. package/src/ai/relative-links.ts +42 -26
  259. package/src/ai/serializers.ts +2 -1
  260. package/src/ai/site-skill.ts +274 -0
  261. package/src/ai/skills.ts +49 -3
  262. package/src/ai/tar.ts +139 -12
  263. package/src/ai/write-skill.ts +97 -0
  264. package/src/analytics/head.ts +4 -0
  265. package/src/analytics/index.ts +5 -0
  266. package/src/analytics/one-dollar-stats.ts +86 -0
  267. package/src/analytics/schema.ts +2 -0
  268. package/src/astro/generate.ts +133 -19
  269. package/src/astro/include-hmr.ts +31 -12
  270. package/src/astro/include-refresh.ts +19 -8
  271. package/src/astro/index.ts +1 -0
  272. package/src/astro/integration.ts +143 -14
  273. package/src/astro/module-types.ts +6 -0
  274. package/src/astro/runtime-modules.ts +28 -13
  275. package/src/astro/templates.ts +364 -67
  276. package/src/astro/variables.ts +31 -0
  277. package/src/audit/catalog.ts +19 -0
  278. package/src/audit/checks/contrast.ts +183 -0
  279. package/src/audit/checks/i18n.ts +2 -3
  280. package/src/audit/checks/indexability.ts +2 -3
  281. package/src/audit/checks/links.ts +13 -13
  282. package/src/audit/checks/sitemap.ts +2 -3
  283. package/src/audit/graph.ts +3 -1
  284. package/src/audit/redirects.ts +46 -15
  285. package/src/audit/run.ts +14 -9
  286. package/src/audit/snapshot.ts +5 -0
  287. package/src/audit/types.ts +2 -1
  288. package/src/blume-modules.d.ts +7 -0
  289. package/src/captcha/client.ts +152 -0
  290. package/src/captcha/hcaptcha.ts +36 -0
  291. package/src/captcha/index.ts +28 -0
  292. package/src/captcha/schema.ts +32 -0
  293. package/src/captcha/turnstile.ts +38 -0
  294. package/src/captcha/verify.ts +71 -0
  295. package/src/cli/args.ts +32 -0
  296. package/src/cli/command-meta.ts +5 -0
  297. package/src/cli/commands/audit.ts +4 -1
  298. package/src/cli/commands/doctor.ts +25 -17
  299. package/src/cli/commands/eval.ts +19 -11
  300. package/src/cli/commands/skill.ts +96 -0
  301. package/src/cli/commands/translate.ts +9 -12
  302. package/src/cli/commands/validate.ts +3 -1
  303. package/src/cli/dev-lock.ts +157 -37
  304. package/src/cli/index.ts +5 -0
  305. package/src/cli/report-format.ts +11 -6
  306. package/src/cli/required-secrets.ts +71 -29
  307. package/src/components/BlumePage.astro +2 -0
  308. package/src/components/colors.ts +19 -0
  309. package/src/components/content/ApiEndpoint.astro +18 -0
  310. package/src/components/content/ApiField.astro +79 -0
  311. package/src/components/content/ApiPlayground.astro +62 -0
  312. package/src/components/content/ApiRail.astro +19 -0
  313. package/src/components/content/Badge.astro +5 -3
  314. package/src/components/content/Color.astro +1 -0
  315. package/src/components/content/Component.astro +2 -2
  316. package/src/components/content/FileTree.astro +1 -0
  317. package/src/components/content/GithubInfo.astro +1 -0
  318. package/src/components/content/Panel.astro +1 -0
  319. package/src/components/content/ParamField.astro +25 -0
  320. package/src/components/content/RequestExample.astro +17 -0
  321. package/src/components/content/ResponseExample.astro +17 -0
  322. package/src/components/content/ResponseField.astro +32 -0
  323. package/src/components/content/Step.astro +1 -0
  324. package/src/components/content/Tab.astro +0 -1
  325. package/src/components/content/Tabs.astro +4 -0
  326. package/src/components/content/Tile.astro +1 -0
  327. package/src/components/content/Tooltip.astro +1 -0
  328. package/src/components/content/Tree.astro +1 -0
  329. package/src/components/content/TypeTable.astro +4 -1
  330. package/src/components/content/View.astro +21 -0
  331. package/src/components/content/ViewSwitcher.astro +168 -0
  332. package/src/components/content/api-field.ts +100 -0
  333. package/src/components/content/api-page.ts +224 -0
  334. package/src/components/content/badge-color.ts +5 -2
  335. package/src/components/content/base-href.ts +13 -36
  336. package/src/components/content/view-switcher.ts +71 -0
  337. package/src/components/index.ts +2 -0
  338. package/src/components/islands/Assistant.astro +10 -1
  339. package/src/components/islands/assistant.tsx +125 -18
  340. package/src/components/islands/base-path.ts +47 -10
  341. package/src/components/islands/code-question.ts +62 -0
  342. package/src/components/islands/hooks.ts +145 -40
  343. package/src/components/islands/support-link.ts +68 -0
  344. package/src/components/islands/webmcp.ts +4 -2
  345. package/src/components/layout/Analytics.astro +11 -2
  346. package/src/components/layout/Banner.astro +14 -10
  347. package/src/components/layout/Breadcrumbs.astro +11 -4
  348. package/src/components/layout/ConsentBanner.astro +62 -0
  349. package/src/components/layout/ConsentHead.astro +38 -0
  350. package/src/components/layout/Directory.astro +94 -0
  351. package/src/components/layout/DiscoveryLinks.astro +9 -5
  352. package/src/components/layout/DrawerSwitchers.astro +51 -0
  353. package/src/components/layout/Empty.astro +2 -2
  354. package/src/components/layout/Header.astro +124 -82
  355. package/src/components/layout/LanguageSwitcher.astro +50 -17
  356. package/src/components/layout/NarrationPlayer.astro +1085 -0
  357. package/src/components/layout/NavSelector.astro +35 -9
  358. package/src/components/layout/NavTabMenu.astro +3 -3
  359. package/src/components/layout/NavTree.astro +16 -6
  360. package/src/components/layout/PageActions.astro +4 -3
  361. package/src/components/layout/PageFeedback.astro +54 -49
  362. package/src/components/layout/PageLayout.astro +78 -9
  363. package/src/components/layout/Pagination.astro +3 -3
  364. package/src/components/layout/ReferenceLayout.astro +17 -6
  365. package/src/components/layout/RelatedPages.astro +42 -0
  366. package/src/components/layout/RootLayout.astro +313 -50
  367. package/src/components/layout/Search.astro +64 -30
  368. package/src/components/layout/SiteFooter.astro +124 -0
  369. package/src/components/layout/SiteMetatags.astro +16 -0
  370. package/src/components/layout/VersionBanner.astro +2 -2
  371. package/src/components/layout/analytics-client.ts +12 -0
  372. package/src/components/layout/consent/native.ts +79 -0
  373. package/src/components/layout/consent/types.ts +37 -0
  374. package/src/components/layout/footer-links.ts +53 -0
  375. package/src/components/layout/footer-socials.ts +87 -0
  376. package/src/components/layout/locale-redirect.ts +107 -0
  377. package/src/components/layout/nav-utils.ts +83 -0
  378. package/src/components/layout/page-feedback.ts +96 -0
  379. package/src/components/layout/search/analytics.ts +98 -0
  380. package/src/components/layout/search/flexsearch.ts +17 -5
  381. package/src/components/layout/search/orama-cloud.ts +26 -14
  382. package/src/components/layout/search/types.ts +20 -0
  383. package/src/components/layout/search/typesense.ts +5 -1
  384. package/src/components/layout/toc-active.ts +41 -0
  385. package/src/components/layout/toc-element.ts +8 -14
  386. package/src/components/openapi/ApiTagOperations.astro +2 -2
  387. package/src/components/openapi/AsyncApiOperation.astro +7 -4
  388. package/src/components/openapi/GraphqlChip.astro +2 -2
  389. package/src/components/openapi/Operation.astro +163 -13
  390. package/src/components/openapi/Playground.astro +4 -4
  391. package/src/components/openapi/RequestBody.astro +6 -4
  392. package/src/components/openapi/RequestPanel.astro +63 -8
  393. package/src/components/openapi/Responses.astro +6 -4
  394. package/src/components/openapi/SchemaTable.astro +7 -0
  395. package/src/components/openapi/async-snippets.ts +4 -4
  396. package/src/components/openapi/async.ts +38 -6
  397. package/src/components/openapi/code-samples.ts +97 -0
  398. package/src/components/openapi/helpers.ts +19 -9
  399. package/src/components/openapi/message-composer.ts +6 -1
  400. package/src/components/openapi/message.ts +17 -2
  401. package/src/components/openapi/operation-model.ts +81 -11
  402. package/src/components/openapi/panel.ts +4 -2
  403. package/src/components/openapi/param-style.ts +181 -0
  404. package/src/components/openapi/playground-client.ts +73 -16
  405. package/src/components/openapi/request.ts +190 -26
  406. package/src/components/openapi/schema-tree.ts +30 -24
  407. package/src/components/openapi/security.ts +6 -3
  408. package/src/components/openapi/snippets.ts +953 -13
  409. package/src/components/openapi/ws-client.ts +18 -2
  410. package/src/components/props.ts +6 -0
  411. package/src/consent/client.ts +95 -0
  412. package/src/consent/clients.ts +19 -0
  413. package/src/consent/ethyca.ts +71 -0
  414. package/src/consent/head.ts +24 -0
  415. package/src/consent/index.ts +37 -0
  416. package/src/consent/init.ts +29 -0
  417. package/src/consent/native.ts +36 -0
  418. package/src/consent/osano.ts +59 -0
  419. package/src/consent/schema.ts +30 -0
  420. package/src/core/base-path.ts +62 -16
  421. package/src/core/builtin-tags.ts +5 -0
  422. package/src/core/client-address.ts +19 -0
  423. package/src/core/config-input.ts +203 -27
  424. package/src/core/data.ts +44 -4
  425. package/src/core/diagnostics.ts +5 -2
  426. package/src/core/directive-diagnostics.ts +99 -0
  427. package/src/core/footer.ts +26 -0
  428. package/src/core/frontmatter.ts +21 -18
  429. package/src/core/graph.ts +39 -36
  430. package/src/core/heading-markers.ts +5 -18
  431. package/src/core/i18n-ui.ts +82 -2
  432. package/src/core/i18n.ts +31 -3
  433. package/src/core/includes.ts +20 -3
  434. package/src/core/last-modified.ts +25 -3
  435. package/src/core/links.ts +16 -2
  436. package/src/core/locale-links.ts +5 -1
  437. package/src/core/localizable.ts +26 -0
  438. package/src/core/meta.ts +33 -19
  439. package/src/core/navigation.ts +71 -20
  440. package/src/core/page-modes.ts +56 -0
  441. package/src/core/project-graph.ts +138 -10
  442. package/src/core/redirect-patterns.ts +491 -0
  443. package/src/core/related.ts +131 -0
  444. package/src/core/schema.ts +342 -68
  445. package/src/core/sources/contentful-rich-text.ts +27 -20
  446. package/src/core/sources/filesystem.ts +20 -2
  447. package/src/core/sources/github-releases.ts +25 -6
  448. package/src/core/sources/lexical.ts +23 -18
  449. package/src/core/sources/lower.ts +201 -34
  450. package/src/core/sources/mdx-remote.ts +51 -16
  451. package/src/core/sources/normalize.ts +327 -91
  452. package/src/core/sources/notion.ts +52 -25
  453. package/src/core/sources/obsidian.ts +23 -6
  454. package/src/core/sources/portable-text.ts +38 -21
  455. package/src/core/sources/read.ts +8 -3
  456. package/src/core/sources/strapi-blocks.ts +20 -16
  457. package/src/core/sources/watch.ts +20 -7
  458. package/src/core/standard-schema.ts +10 -6
  459. package/src/core/types.ts +1 -1
  460. package/src/core/ui-packs/ar.ts +43 -0
  461. package/src/core/ui-packs/bg.ts +45 -0
  462. package/src/core/ui-packs/bn.ts +43 -0
  463. package/src/core/ui-packs/ca.ts +46 -0
  464. package/src/core/ui-packs/cs.ts +44 -0
  465. package/src/core/ui-packs/da.ts +45 -0
  466. package/src/core/ui-packs/de.ts +46 -0
  467. package/src/core/ui-packs/el.ts +45 -0
  468. package/src/core/ui-packs/es.ts +46 -0
  469. package/src/core/ui-packs/fa.ts +45 -0
  470. package/src/core/ui-packs/fi.ts +45 -0
  471. package/src/core/ui-packs/fr.ts +46 -0
  472. package/src/core/ui-packs/he.ts +43 -0
  473. package/src/core/ui-packs/hi.ts +44 -0
  474. package/src/core/ui-packs/hr.ts +45 -0
  475. package/src/core/ui-packs/hu.ts +44 -0
  476. package/src/core/ui-packs/id.ts +45 -0
  477. package/src/core/ui-packs/it.ts +45 -0
  478. package/src/core/ui-packs/ja.ts +45 -0
  479. package/src/core/ui-packs/ko.ts +44 -0
  480. package/src/core/ui-packs/nl.ts +46 -0
  481. package/src/core/ui-packs/no.ts +44 -0
  482. package/src/core/ui-packs/pl.ts +45 -0
  483. package/src/core/ui-packs/pt-br.ts +46 -0
  484. package/src/core/ui-packs/pt.ts +45 -0
  485. package/src/core/ui-packs/ro.ts +45 -0
  486. package/src/core/ui-packs/ru.ts +45 -0
  487. package/src/core/ui-packs/sk.ts +44 -0
  488. package/src/core/ui-packs/sr.ts +45 -0
  489. package/src/core/ui-packs/sv.ts +44 -0
  490. package/src/core/ui-packs/th.ts +43 -0
  491. package/src/core/ui-packs/tr.ts +45 -0
  492. package/src/core/ui-packs/uk.ts +45 -0
  493. package/src/core/ui-packs/vi.ts +45 -0
  494. package/src/core/ui-packs/zh-tw.ts +43 -0
  495. package/src/core/ui-packs/zh.ts +43 -0
  496. package/src/core/variables.ts +103 -0
  497. package/src/core/version-cut.ts +52 -15
  498. package/src/deploy/artifacts.ts +104 -14
  499. package/src/deploy/cloudflare-negotiation.ts +39 -17
  500. package/src/deploy/headers.ts +10 -5
  501. package/src/deploy/node-headers.ts +64 -10
  502. package/src/deploy/platforms/cloudflare.ts +44 -3
  503. package/src/deploy/platforms/netlify.ts +34 -1
  504. package/src/deploy/platforms/node.ts +1 -0
  505. package/src/deploy/platforms/static.ts +1 -0
  506. package/src/deploy/platforms/types.ts +8 -0
  507. package/src/deploy/platforms/vercel.ts +38 -2
  508. package/src/deploy/redirects.ts +139 -36
  509. package/src/deploy/robots.ts +2 -2
  510. package/src/deploy/rss.ts +4 -3
  511. package/src/deploy/sitemap.ts +7 -5
  512. package/src/deploy/vercel-negotiation.ts +36 -0
  513. package/src/markdown/api-rail.ts +259 -0
  514. package/src/markdown/base-links.ts +34 -36
  515. package/src/markdown/code-title.ts +35 -9
  516. package/src/markdown/directives.ts +242 -36
  517. package/src/markdown/features.ts +20 -2
  518. package/src/markdown/fence-meta.ts +2 -0
  519. package/src/markdown/include.ts +11 -1
  520. package/src/markdown/index.ts +35 -11
  521. package/src/markdown/math.ts +4 -4
  522. package/src/markdown/mdast.ts +5 -2
  523. package/src/markdown/relative-links.ts +12 -4
  524. package/src/markdown/variables.ts +56 -0
  525. package/src/markdown/views.ts +82 -0
  526. package/src/narration/build.ts +412 -0
  527. package/src/narration/player.ts +249 -0
  528. package/src/narration/provider.ts +29 -0
  529. package/src/narration/script.ts +592 -0
  530. package/src/og/card.ts +136 -11
  531. package/src/og/derive.ts +41 -31
  532. package/src/og/index.ts +1 -0
  533. package/src/openapi/asyncapi.ts +4 -2
  534. package/src/openapi/model.ts +77 -36
  535. package/src/openapi/overlay.ts +256 -0
  536. package/src/openapi/parse.ts +55 -2
  537. package/src/openapi/proxy.ts +63 -10
  538. package/src/openapi/references.ts +21 -5
  539. package/src/openapi/render-mdx.ts +46 -3
  540. package/src/openapi/scalar.ts +40 -6
  541. package/src/openapi/source.ts +1 -1
  542. package/src/ratelimit/cloudflare.ts +54 -0
  543. package/src/ratelimit/index.ts +30 -0
  544. package/src/ratelimit/memory.ts +45 -0
  545. package/src/ratelimit/runtime.ts +229 -0
  546. package/src/ratelimit/schema.ts +28 -0
  547. package/src/ratelimit/upstash.ts +30 -0
  548. package/src/ratelimit/wrangler.ts +70 -0
  549. package/src/reference/asyncapi.ts +2 -2
  550. package/src/reference/graphql.ts +5 -2
  551. package/src/reference/openapi.ts +21 -7
  552. package/src/reference/options.ts +51 -7
  553. package/src/reference/scalar.ts +33 -8
  554. package/src/registry/eject.ts +201 -28
  555. package/src/registry/registry.ts +7 -0
  556. package/src/search/adapters/version-scope.ts +30 -0
  557. package/src/search/documents.ts +93 -28
  558. package/src/search/orama-index.ts +28 -3
  559. package/src/search/pagefind-ranking.ts +39 -0
  560. package/src/search/popular.ts +2 -1
  561. package/src/search/sync/algolia.ts +15 -4
  562. package/src/search/sync/orama-cloud.ts +3 -0
  563. package/src/search/sync/typesense.ts +5 -0
  564. package/src/seo/jsonld.ts +7 -3
  565. package/src/seo/metatags.ts +67 -0
  566. package/src/theme/chrome-icons.ts +1 -0
  567. package/src/theme/color.ts +500 -0
  568. package/src/theme/entry.ts +56 -3
  569. package/src/theme/palette.ts +121 -45
  570. package/src/translate/meta.ts +68 -24
  571. package/src/translate/prompts.ts +1 -0
  572. package/src/translate/run.ts +3 -3
  573. package/src/translate/validate.ts +12 -3
  574. package/src/translate/work-list.ts +56 -17
  575. package/src/upgrade/upgrade.ts +4 -171
  576. package/dist/cli/chunk-3yce002v.js.map +0 -14
  577. package/dist/cli/chunk-5r8g91qn.js.map +0 -34
  578. package/dist/cli/chunk-6dtt0zfn.js.map +0 -10
  579. package/dist/cli/chunk-7mbqtmgb.js.map +0 -10
  580. package/dist/cli/chunk-ddndchfr.js.map +0 -14
  581. package/dist/cli/chunk-esh98wmb.js +0 -23
  582. package/dist/cli/chunk-esh98wmb.js.map +0 -10
  583. package/dist/cli/chunk-hqp2ajnh.js.map +0 -35
  584. package/dist/cli/chunk-hr8ne106.js.map +0 -13
  585. package/dist/cli/chunk-j85scx15.js.map +0 -10
  586. package/dist/cli/chunk-mqc662a6.js +0 -75
  587. package/dist/cli/chunk-mqc662a6.js.map +0 -11
  588. package/dist/cli/chunk-pbg5a4s3.js.map +0 -19
  589. package/dist/cli/chunk-qkb5a8sa.js.map +0 -10
  590. package/dist/cli/chunk-v6ya5kcb.js.map +0 -189
  591. package/dist/cli/chunk-wdrt2k2v.js.map +0 -10
  592. package/dist/cli/chunk-xh43dwgw.js.map +0 -36
  593. package/docs/content/sources.mdx +0 -338
  594. /package/dist/cli/{chunk-zp79m0ts.js.map → chunk-1n228xqb.js.map} +0 -0
  595. /package/dist/cli/{chunk-h2ez8dzb.js.map → chunk-5ffywsmb.js.map} +0 -0
  596. /package/dist/cli/{chunk-g698a744.js.map → chunk-5wj2qwn2.js.map} +0 -0
  597. /package/dist/cli/{chunk-sqw4ekg1.js.map → chunk-amrb6hgh.js.map} +0 -0
  598. /package/dist/cli/{chunk-h7k3nq3v.js.map → chunk-gp84za0h.js.map} +0 -0
  599. /package/dist/cli/{chunk-bfwp9vp6.js.map → chunk-p804f3pe.js.map} +0 -0
  600. /package/dist/cli/{chunk-00gs3wqs.js.map → chunk-ta27feev.js.map} +0 -0
  601. /package/dist/cli/{chunk-bbnwccaz.js.map → chunk-y4ykbark.js.map} +0 -0
@@ -0,0 +1,62 @@
1
+ ---
2
+ // A hand-written endpoint's Try it panel and request samples, at the head of
3
+ // its rail: the page's `<ParamField>`s become the parameters and body of an
4
+ // operation model like a spec'd operation's (see `api-page.ts`), so the
5
+ // playground and the samples are the OpenAPI reference's own. A page's own
6
+ // `<RequestExample>` stands in for the generated samples, and its
7
+ // `playground` frontmatter can drop the Try it panel (`simple`).
8
+ import data from "blume:data";
9
+
10
+ import { operationModel } from "../openapi/operation-model.ts";
11
+ import Playground from "../openapi/Playground.astro";
12
+ import { buildRequest, defaultValues } from "../openapi/request.ts";
13
+ import RequestPanel from "../openapi/RequestPanel.astro";
14
+ import { sampleLanguages } from "../openapi/snippets.ts";
15
+ import {
16
+ endpointBody,
17
+ endpointParameters,
18
+ endpointSecurity,
19
+ endpointTarget,
20
+ readEndpointSpec,
21
+ } from "./api-page.ts";
22
+
23
+ interface Props {
24
+ /** The endpoint, as the page's plugin wrote it. */
25
+ spec: string;
26
+ }
27
+
28
+ const spec = readEndpointSpec(Astro.props.spec);
29
+ const { api } = data.config;
30
+ const { path, servers } = endpointTarget(spec.target, api.server);
31
+ const model = operationModel({
32
+ method: spec.method,
33
+ parameters: endpointParameters(spec.fields),
34
+ path,
35
+ requestBody: endpointBody(spec.fields),
36
+ schemas: {},
37
+ security: endpointSecurity(spec.authMethod, api.auth),
38
+ servers,
39
+ });
40
+ const tryIt = spec.playground !== "simple" && api.playground.enabled;
41
+ ---
42
+
43
+ {
44
+ tryIt && (
45
+ <Playground
46
+ model={model}
47
+ operation={`${spec.method} ${spec.target}`}
48
+ proxy={api.playground.proxy}
49
+ slug="api-pages"
50
+ />
51
+ )
52
+ }
53
+ {
54
+ !spec.requestExample && (
55
+ <RequestPanel
56
+ languages={sampleLanguages([])}
57
+ responses={{}}
58
+ sample={buildRequest(model, defaultValues(model))}
59
+ schemas={{}}
60
+ />
61
+ )
62
+ }
@@ -0,0 +1,19 @@
1
+ ---
2
+ // The column `<RequestExample>` and `<ResponseExample>` pin to, which
3
+ // `markdown/api-rail.ts` gathers at the end of the page. At `xl` it sits
4
+ // beside the page's content, which the layout pads to make room, and sticks
5
+ // under the header like an OpenAPI operation's sample panel; below `xl` it
6
+ // follows the content.
7
+ import OperationPanel from "../openapi/OperationPanel.astro";
8
+ ---
9
+
10
+ <div
11
+ class="not-prose mt-10 xl:absolute xl:inset-y-0 xl:end-0 xl:mt-0 xl:w-[28rem]"
12
+ data-blume-api-rail
13
+ >
14
+ <OperationPanel>
15
+ <div class="flex flex-col gap-4 [&>*]:my-0">
16
+ <slot />
17
+ </div>
18
+ </OperationPanel>
19
+ </div>
@@ -1,5 +1,5 @@
1
1
  ---
2
- import { STROKE, TINT } from "../colors.ts";
2
+ import { ACCENT_STROKE, ACCENT_TINT, STROKE, TINT } from "../colors.ts";
3
3
  import Icon from "../Icon.astro";
4
4
  import { badgeColorName } from "./badge-color.ts";
5
5
 
@@ -38,10 +38,11 @@ const isDisabled = disabled === true || disabled === "true";
38
38
  const colorName = badgeColorName(variant, color);
39
39
  const customColor = colorName.startsWith("#") ? colorName : null;
40
40
 
41
- // The hue rows come from the shared table (see colors.ts for the contrast
42
- // rule); the neutral and surface rows are Badge's own.
41
+ // The hue and theme-accent rows come from the shared table (see colors.ts for
42
+ // the contrast rule); the neutral and surface rows are Badge's own.
43
43
  const filledColorClass: Record<string, string> = {
44
44
  ...TINT,
45
+ accent: ACCENT_TINT,
45
46
  gray: "bg-muted text-muted-foreground",
46
47
  surface: "bg-background text-muted-foreground ring-1 ring-border",
47
48
  "surface-destructive":
@@ -53,6 +54,7 @@ const filledColorClass: Record<string, string> = {
53
54
 
54
55
  const strokeColorClass: Record<string, string> = {
55
56
  ...STROKE,
57
+ accent: ACCENT_STROKE,
56
58
  gray: "border-border text-muted-foreground",
57
59
  surface: "border-border text-muted-foreground",
58
60
  "surface-destructive": "border-red-500/40 text-red-700 dark:text-red-300",
@@ -10,6 +10,7 @@ const { variant = "compact" } = Astro.props;
10
10
  : "grid grid-cols-2 gap-x-5 gap-y-4 sm:grid-cols-4",
11
11
  ]}
12
12
  data-blume-color={variant}
13
+ data-blume-narration="skip"
13
14
  >
14
15
  <slot />
15
16
  </div>
@@ -13,7 +13,7 @@ import data from "blume:data";
13
13
  import { CODE_PADDING_BLOCK_REM } from "../../theme/code-block-padding.ts";
14
14
 
15
15
  import { highlightCode } from "../../markdown/index.ts";
16
- import { withBase } from "../islands/base-path.ts";
16
+ import { withMountedBase } from "../islands/base-path.ts";
17
17
  import { contentStrings } from "./content-strings.ts";
18
18
  import { EXAMPLE_PANE_MIN_PX } from "./example-pane.ts";
19
19
  import Tab from "./Tab.astro";
@@ -35,7 +35,7 @@ const { content: strings } = contentStrings(data, Astro.currentLocale);
35
35
  // by their own design system (e.g. shadcn, via the configured `examples.css`).
36
36
  // The frame syncs its theme with this document before first paint.
37
37
  const previewSrc = entry
38
- ? withBase(
38
+ ? withMountedBase(
39
39
  `${examplesBase}/${path.split("/").map(encodeURIComponent).join("/")}`
40
40
  )
41
41
  : undefined;
@@ -3,6 +3,7 @@
3
3
 
4
4
  <div
5
5
  class="not-prose my-6 rounded-blume border border-border p-5 text-sm [&_ul]:m-0! [&_ul]:list-none [&_ul]:ps-4 [&>ul]:ps-0"
6
+ data-blume-narration="skip"
6
7
  >
7
8
  <slot />
8
9
  </div>
@@ -73,6 +73,7 @@ const { content: strings } = contentStrings(data, Astro.currentLocale);
73
73
  owner && repo && (
74
74
  <a
75
75
  class="not-prose my-6 flex flex-col gap-2 rounded-blume border border-border p-4 no-underline! transition-colors hover:border-foreground/30 hover:bg-muted/40"
76
+ data-blume-narration="skip"
76
77
  href={`${host}/${owner}/${repo}`}
77
78
  {...NEW_TAB_ATTRS}
78
79
  >
@@ -4,6 +4,7 @@ const { title } = Astro.props;
4
4
 
5
5
  <aside
6
6
  class="not-prose my-6 overflow-hidden rounded-blume border border-border/80 bg-background shadow-sm shadow-border/30"
7
+ data-blume-narration="skip"
7
8
  data-blume-panel
8
9
  data-blume-right-rail-item
9
10
  >
@@ -0,0 +1,25 @@
1
+ ---
2
+ // `<ParamField query="limit" type="integer" required>`: a request parameter,
3
+ // named by the attribute that says where it goes (`path`, `query`, `header`,
4
+ // or `body`), with its description in the slot. On a page with `api`
5
+ // frontmatter the fields also build that page's playground.
6
+ import ApiField from "./ApiField.astro";
7
+ import { paramField } from "./api-field.ts";
8
+ import type { ParamFieldProps } from "./api-field.ts";
9
+
10
+ type Props = ParamFieldProps;
11
+
12
+ const { location, name } = paramField(Astro.props);
13
+ const { default: value, deprecated, required, type } = Astro.props;
14
+ ---
15
+
16
+ <ApiField
17
+ default={value}
18
+ deprecated={deprecated}
19
+ location={location}
20
+ name={name}
21
+ required={required}
22
+ type={type}
23
+ >
24
+ <slot />
25
+ </ApiField>
@@ -0,0 +1,17 @@
1
+ ---
2
+ // `<RequestExample>`: code blocks showing a request, one tab per titled
3
+ // fence (or a language menu with `dropdown`). On a wide screen it pins to the
4
+ // column beside the page (see `ApiRail.astro`), above any `<ResponseExample>`.
5
+ import CodeGroup from "./CodeGroup.astro";
6
+
7
+ interface Props {
8
+ /** A language menu in place of tabs. */
9
+ dropdown?: boolean;
10
+ }
11
+
12
+ const { dropdown = false } = Astro.props;
13
+ ---
14
+
15
+ <CodeGroup dropdown={dropdown}>
16
+ <slot />
17
+ </CodeGroup>
@@ -0,0 +1,17 @@
1
+ ---
2
+ // `<ResponseExample>`: code blocks showing a response, one tab per titled
3
+ // fence (or a language menu with `dropdown`). On a wide screen it pins to the
4
+ // column beside the page (see `ApiRail.astro`), below any `<RequestExample>`.
5
+ import CodeGroup from "./CodeGroup.astro";
6
+
7
+ interface Props {
8
+ /** A language menu in place of tabs. */
9
+ dropdown?: boolean;
10
+ }
11
+
12
+ const { dropdown = false } = Astro.props;
13
+ ---
14
+
15
+ <CodeGroup dropdown={dropdown}>
16
+ <slot />
17
+ </CodeGroup>
@@ -0,0 +1,32 @@
1
+ ---
2
+ // `<ResponseField name="id" type="string" required>`: a field of the
3
+ // response, with optional `pre` and `post` labels around its name and its
4
+ // description in the slot.
5
+ import ApiField from "./ApiField.astro";
6
+ import { fieldLabels } from "./api-field.ts";
7
+ import type { ResponseFieldProps } from "./api-field.ts";
8
+
9
+ type Props = ResponseFieldProps;
10
+
11
+ const {
12
+ default: value,
13
+ deprecated,
14
+ name,
15
+ post,
16
+ pre,
17
+ required,
18
+ type,
19
+ } = Astro.props;
20
+ ---
21
+
22
+ <ApiField
23
+ default={value}
24
+ deprecated={deprecated}
25
+ name={name}
26
+ post={fieldLabels(post)}
27
+ pre={fieldLabels(pre)}
28
+ required={required}
29
+ type={type}
30
+ >
31
+ <slot />
32
+ </ApiField>
@@ -17,6 +17,7 @@ const canRenderIcon =
17
17
 
18
18
  <div
19
19
  class="relative [counter-increment:blume-step]"
20
+ data-blume-step
20
21
  >
21
22
  <span class:list={[markerClass, !canRenderIcon && "before:[content:counter(blume-step)]"]}>
22
23
  {canRenderIcon && <Icon name={icon} size={14} />}
@@ -44,7 +44,6 @@ const tabId = id ?? componentSlug(title);
44
44
  data-tab-id={tabId}
45
45
  data-title={title}
46
46
  id={id}
47
- role="tabpanel"
48
47
  >
49
48
  <slot />
50
49
  {
@@ -237,6 +237,10 @@ const { content: strings } = contentStrings(data, Astro.currentLocale);
237
237
  }
238
238
  trigger.id = `blume-tab-${slug}-${instance}`;
239
239
  trigger.setAttribute("aria-controls", panel.id);
240
+ // The role rides with the labelling tab: adopted panels (CodeGroup
241
+ // fences, ts2js pairs, nested groups) have none of their own, and
242
+ // dropdown mode renders no tabs, so its panels take no role.
243
+ panel.setAttribute("role", "tabpanel");
240
244
  panel.setAttribute("aria-labelledby", trigger.id);
241
245
  trigger.setAttribute(
242
246
  "aria-selected",
@@ -17,6 +17,7 @@ const previewPattern =
17
17
  >
18
18
  <div
19
19
  class="flex aspect-[16/9] min-h-32 items-center justify-center bg-muted/40 p-4 text-muted-foreground [&_img]:max-h-full [&_img]:max-w-full [&_svg]:max-h-full [&_svg]:max-w-full"
20
+ data-blume-narration="skip"
20
21
  data-blume-tile-preview
21
22
  style={previewPattern}
22
23
  >
@@ -39,6 +39,7 @@ const tooltipId = tooltipIdFor(Astro.locals, [
39
39
  />
40
40
  <span
41
41
  class="absolute bottom-full left-1/2 z-20 mb-2 w-max max-w-[min(20rem,calc(100vw-1rem))] -translate-x-1/2 rounded-blume border border-border bg-background p-3 text-start font-sans text-foreground text-sm shadow-lg"
42
+ data-blume-narration="skip"
42
43
  data-blume-tooltip-panel
43
44
  id={tooltipId}
44
45
  role="tooltip"
@@ -3,6 +3,7 @@
3
3
 
4
4
  <blume-tree
5
5
  class="not-prose my-6 block rounded-blume border border-border bg-background p-3 text-sm"
6
+ data-blume-narration="skip"
6
7
  data-blume-tree
7
8
  role="tree"
8
9
  >
@@ -37,7 +37,10 @@ const columns = "grid grid-cols-[1fr_2fr_auto] items-center gap-4";
37
37
 
38
38
  {
39
39
  entries.length > 0 && (
40
- <div class="not-prose my-6 rounded-blume border border-border bg-muted/30 p-1.5">
40
+ <div
41
+ class="not-prose my-6 rounded-blume border border-border bg-muted/30 p-1.5"
42
+ data-blume-narration="skip"
43
+ >
41
44
  <div class={`${columns} px-3 py-2 font-medium text-muted-foreground text-xs`}>
42
45
  <span>{strings.prop}</span>
43
46
  <span>{strings.type}</span>
@@ -0,0 +1,21 @@
1
+ ---
2
+ /**
3
+ * One view of a page written for several (`<View title="Python">`), as
4
+ * Mintlify writes them. Each distinct title is an option of the page's view
5
+ * picker, and blocks sharing a title show and hide together, so a page can
6
+ * alternate between prose everyone reads and view-specific sections. The
7
+ * picker and the hiding live in `ViewSwitcher.astro`; `icon` shows beside
8
+ * the view's name there.
9
+ */
10
+ interface Props {
11
+ class?: string;
12
+ icon?: string;
13
+ title: string;
14
+ }
15
+
16
+ const { class: className, title } = Astro.props;
17
+ ---
18
+
19
+ <div class={className} data-blume-view={title}>
20
+ <slot />
21
+ </div>
@@ -0,0 +1,168 @@
1
+ ---
2
+ import type { PageView } from "../../markdown/views.ts";
3
+ import Icon from "../Icon.astro";
4
+ import { VIEW_INIT_SCRIPT, viewStyle } from "./view-switcher.ts";
5
+
6
+ /**
7
+ * The picker for a page written in `<View>` blocks, rendered above the
8
+ * content with the page's views (collected by `markdown/views.ts`). The
9
+ * style hides every other view's blocks and table of contents entries, and
10
+ * the inline script applies a linked or remembered choice before the views
11
+ * paint (see `view-switcher.ts`).
12
+ */
13
+ interface Props {
14
+ /** The select's accessible name (`content.selectView`). */
15
+ label: string;
16
+ views: PageView[];
17
+ }
18
+
19
+ const { label, views } = Astro.props;
20
+ const titles = views.map((view) => view.title);
21
+ ---
22
+
23
+ <blume-view-switcher
24
+ class="not-prose mt-4 mb-8 flex items-center gap-2"
25
+ data-views={JSON.stringify(titles)}
26
+ >
27
+ <style is:inline set:html={viewStyle(titles)} />
28
+ {
29
+ views.map(
30
+ (view) =>
31
+ view.icon && (
32
+ <span
33
+ class="inline-flex shrink-0 text-muted-foreground"
34
+ data-blume-view={view.title}
35
+ >
36
+ <Icon name={view.icon} size={16} />
37
+ </span>
38
+ )
39
+ )
40
+ }
41
+ <select
42
+ aria-label={label}
43
+ class="cursor-pointer rounded-blume border border-border bg-background px-3 py-1.5 font-medium text-foreground text-sm"
44
+ >
45
+ {views.map((view) => <option value={view.title}>{view.title}</option>)}
46
+ </select>
47
+ <script is:inline set:html={VIEW_INIT_SCRIPT} />
48
+ </blume-view-switcher>
49
+
50
+ <script>
51
+ import {
52
+ chooseView,
53
+ VIEW_PARAM,
54
+ VIEW_STORAGE_KEY,
55
+ } from "./view-switcher.ts";
56
+
57
+ const HEADINGS = "h2[id], h3[id], h4[id], h5[id], h6[id]";
58
+
59
+ const stored = (): string | null => {
60
+ try {
61
+ return localStorage.getItem(VIEW_STORAGE_KEY);
62
+ } catch {
63
+ return null;
64
+ }
65
+ };
66
+
67
+ /** The view holding the element a `#hash` link points at, if any. */
68
+ const linkedView = (): string | undefined => {
69
+ const id = decodeURIComponent(location.hash.slice(1));
70
+ const target = id ? document.getElementById(id) : null;
71
+ return (
72
+ target?.closest<HTMLElement>("article [data-blume-view]")?.dataset
73
+ .blumeView ?? undefined
74
+ );
75
+ };
76
+
77
+ /**
78
+ * Tag each table of contents entry with the view its heading is in, so the
79
+ * page's view style hides it with the view.
80
+ */
81
+ const tagTableOfContents = () => {
82
+ const views = new Map<string, string>();
83
+ for (const view of document.querySelectorAll<HTMLElement>(
84
+ "article [data-blume-view]"
85
+ )) {
86
+ for (const heading of view.querySelectorAll(HEADINGS)) {
87
+ views.set(heading.id, view.dataset.blumeView ?? "");
88
+ }
89
+ }
90
+ for (const link of document.querySelectorAll<HTMLAnchorElement>(
91
+ 'blume-toc a[href^="#"]'
92
+ )) {
93
+ const id = decodeURIComponent(link.getAttribute("href")?.slice(1) ?? "");
94
+ const item = link.closest("li");
95
+ const title = views.get(id);
96
+ if (item && title) {
97
+ item.dataset.blumeView = title;
98
+ }
99
+ }
100
+ };
101
+
102
+ class BlumeViewSwitcher extends HTMLElement {
103
+ #titles: string[] = [];
104
+
105
+ connectedCallback() {
106
+ try {
107
+ this.#titles = JSON.parse(this.dataset.views ?? "[]");
108
+ } catch {
109
+ this.#titles = [];
110
+ }
111
+ tagTableOfContents();
112
+ this.#show(
113
+ chooseView(this.#titles, [
114
+ linkedView(),
115
+ new URL(location.href).searchParams.get(VIEW_PARAM),
116
+ stored(),
117
+ ])
118
+ );
119
+ this.querySelector("select")?.addEventListener("change", this.#onPick);
120
+ window.addEventListener("hashchange", this.#onHash);
121
+ }
122
+
123
+ disconnectedCallback() {
124
+ this.querySelector("select")?.removeEventListener("change", this.#onPick);
125
+ window.removeEventListener("hashchange", this.#onHash);
126
+ }
127
+
128
+ #show(title: string | undefined) {
129
+ if (title === undefined) {
130
+ return;
131
+ }
132
+ document.body.dataset.blumeView = title;
133
+ const select = this.querySelector("select");
134
+ if (select) {
135
+ select.value = title;
136
+ }
137
+ }
138
+
139
+ #onPick = (event: Event) => {
140
+ // SAFETY: the listener is only added to this picker's <select>.
141
+ const { value } = event.currentTarget as HTMLSelectElement;
142
+ this.#show(value);
143
+ try {
144
+ localStorage.setItem(VIEW_STORAGE_KEY, value);
145
+ } catch {
146
+ // Storage can be off; the choice still holds for this page.
147
+ }
148
+ // replaceState: the link stays shareable without a history entry per
149
+ // pick, and the client router needs the entry's state kept.
150
+ const url = new URL(location.href);
151
+ url.searchParams.set(VIEW_PARAM, value);
152
+ history.replaceState(history.state, "", url);
153
+ };
154
+
155
+ // An in-page link to a heading in another view switches to that view.
156
+ #onHash = () => {
157
+ const view = linkedView();
158
+ if (view && view !== document.body.dataset.blumeView) {
159
+ this.#show(view);
160
+ document.getElementById(decodeURIComponent(location.hash.slice(1)))?.scrollIntoView();
161
+ }
162
+ };
163
+ }
164
+
165
+ if (!customElements.get("blume-view-switcher")) {
166
+ customElements.define("blume-view-switcher", BlumeViewSwitcher);
167
+ }
168
+ </script>
@@ -0,0 +1,100 @@
1
+ /**
2
+ * The props `<ParamField>` and `<ResponseField>` take, in Mintlify's shape: a
3
+ * parameter names its location with the attribute that carries its name
4
+ * (`<ParamField query="limit">`), and both take `type`, `required`,
5
+ * `deprecated`, and `default`; a response field adds `pre` and `post` labels
6
+ * around its name. Pure, so the Markdown downlevel and the playground can
7
+ * read fields the way the components render them.
8
+ */
9
+
10
+ /** Where a `<ParamField>` parameter goes, in the order the attributes are checked. */
11
+ export const PARAM_LOCATIONS = ["path", "query", "header", "body"] as const;
12
+
13
+ /** A parameter's location. */
14
+ export type ParamLocation = (typeof PARAM_LOCATIONS)[number];
15
+
16
+ /** A literal value as MDX passes it: a string attribute, or an expression's data. */
17
+ export type FieldValue =
18
+ | string
19
+ | number
20
+ | boolean
21
+ | null
22
+ | undefined
23
+ | FieldValue[]
24
+ | { [key: string]: FieldValue };
25
+
26
+ /** A boolean prop: MDX shorthand (`required`) is `true`, `required="true"` a string. */
27
+ export type FlagProp = boolean | string;
28
+
29
+ /** What both field components take. */
30
+ export interface FieldProps {
31
+ /** The value used when none is given. */
32
+ default?: FieldValue;
33
+ deprecated?: FlagProp;
34
+ required?: FlagProp;
35
+ /** Free text: `string`, `integer`, `string[]`, `object`. */
36
+ type?: string;
37
+ }
38
+
39
+ /** `<ParamField>`: a request parameter, named by its location attribute. */
40
+ export interface ParamFieldProps extends FieldProps {
41
+ body?: string;
42
+ header?: string;
43
+ /** The name, for a field with no location attribute. */
44
+ name?: string;
45
+ path?: string;
46
+ /** Placeholder text for the parameter's playground input. */
47
+ placeholder?: string;
48
+ query?: string;
49
+ }
50
+
51
+ /** `<ResponseField>`: a field of the response. */
52
+ export interface ResponseFieldProps extends FieldProps {
53
+ name: string;
54
+ /** Labels after the name. */
55
+ post?: string | string[];
56
+ /** Labels before the name. */
57
+ pre?: string | string[];
58
+ }
59
+
60
+ /** Whether a flag prop is on. */
61
+ export const isOn = (value?: FlagProp): boolean =>
62
+ value === true || value === "true";
63
+
64
+ /** Where a parameter goes, and what it's called. */
65
+ export interface ParamFieldName {
66
+ location?: ParamLocation;
67
+ name?: string;
68
+ }
69
+
70
+ /** A parameter's location and name: the first location attribute set, else `name`. */
71
+ export const paramField = (props: ParamFieldProps): ParamFieldName => {
72
+ for (const location of PARAM_LOCATIONS) {
73
+ const name = props[location];
74
+ if (name !== undefined) {
75
+ return { location, name };
76
+ }
77
+ }
78
+ return { name: props.name };
79
+ };
80
+
81
+ const isText = (value: FieldValue): value is string =>
82
+ typeof value === "string";
83
+
84
+ /** A default value as shown: text as written, anything else as JSON; `null` when there is none. */
85
+ export const defaultLabel = (value?: FieldValue): string | null => {
86
+ if (value === undefined || value === null || value === "") {
87
+ return null;
88
+ }
89
+ return isText(value) ? value : JSON.stringify(value);
90
+ };
91
+
92
+ /** `pre`/`post` labels as a list, whether one was written or several. */
93
+ export const fieldLabels = (value?: string | string[]): string[] => {
94
+ if (value === undefined) {
95
+ return [];
96
+ }
97
+ return (Array.isArray(value) ? value : [value]).filter(
98
+ (label) => label !== ""
99
+ );
100
+ };