blume 2.0.3 → 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.
- package/AGENTS.md +1 -0
- package/CHANGELOG.md +48 -0
- package/README.md +1 -1
- package/dist/cli/{chunk-1d7ve1dm.js → chunk-0gz36akr.js} +18 -2
- package/dist/cli/{chunk-1d7ve1dm.js.map → chunk-0gz36akr.js.map} +3 -3
- package/dist/cli/{chunk-2eytanqx.js → chunk-1n228xqb.js} +2 -2
- package/dist/cli/{chunk-yfyb25rh.js → chunk-2f3ndkpw.js} +24 -8
- package/dist/cli/chunk-2f3ndkpw.js.map +14 -0
- package/dist/cli/{chunk-r20tn01b.js → chunk-2f7n4qzt.js} +8 -2
- package/dist/cli/{chunk-r20tn01b.js.map → chunk-2f7n4qzt.js.map} +3 -3
- package/dist/cli/{chunk-35d4wj9f.js → chunk-2n4ps1b3.js} +7 -7
- package/dist/cli/{chunk-j85vccga.js → chunk-43zcf4gz.js} +97 -57
- package/dist/cli/{chunk-j85vccga.js.map → chunk-43zcf4gz.js.map} +6 -6
- package/dist/cli/{chunk-e04dxsz1.js → chunk-4ejxbzee.js} +1 -1
- package/dist/cli/{chunk-5m5nmvyq.js → chunk-4h8z9vv5.js} +233 -39
- package/dist/cli/chunk-4h8z9vv5.js.map +16 -0
- package/dist/cli/{chunk-5f86nr5m.js → chunk-5cg2rzgf.js} +18 -16
- package/dist/cli/{chunk-5f86nr5m.js.map → chunk-5cg2rzgf.js.map} +2 -2
- package/dist/cli/{chunk-tzmab476.js → chunk-5ffywsmb.js} +4 -4
- package/dist/cli/{chunk-2z928egk.js → chunk-5wj2qwn2.js} +5 -5
- package/dist/cli/chunk-6bm0xpgd.js +18 -0
- package/dist/cli/chunk-6bm0xpgd.js.map +10 -0
- package/dist/cli/{chunk-vg9r4eb9.js → chunk-713mngdq.js} +12 -5
- package/dist/cli/{chunk-vg9r4eb9.js.map → chunk-713mngdq.js.map} +3 -3
- package/dist/cli/{chunk-5xvm6tfj.js → chunk-9geymqns.js} +17 -15
- package/dist/cli/{chunk-5xvm6tfj.js.map → chunk-9geymqns.js.map} +2 -2
- package/dist/cli/{chunk-q58y5e6a.js → chunk-9xr4dgee.js} +26 -17
- package/dist/cli/chunk-9xr4dgee.js.map +10 -0
- package/dist/cli/{chunk-b07cmahc.js → chunk-amrb6hgh.js} +2 -2
- package/dist/cli/chunk-cm89scdv.js +443 -0
- package/dist/cli/chunk-cm89scdv.js.map +11 -0
- package/dist/cli/{chunk-akbpwfxc.js → chunk-cmtcnh9f.js} +2 -2
- package/dist/cli/chunk-cy5bm0j0.js +104 -0
- package/dist/cli/chunk-cy5bm0j0.js.map +11 -0
- package/dist/cli/{chunk-crgn1q09.js → chunk-e7vvk5ya.js} +4 -4
- package/dist/cli/{chunk-pehfxfta.js → chunk-g2z9x01v.js} +6 -98
- package/dist/cli/chunk-g2z9x01v.js.map +10 -0
- package/dist/cli/{chunk-tkacnehg.js → chunk-gp84za0h.js} +2 -2
- package/dist/cli/{chunk-wrr3j9w9.js → chunk-h2a48yhd.js} +186 -63
- package/dist/cli/chunk-h2a48yhd.js.map +36 -0
- package/dist/cli/{chunk-hm3vjy5s.js → chunk-jnwj5kjj.js} +14 -9
- package/dist/cli/{chunk-hm3vjy5s.js.map → chunk-jnwj5kjj.js.map} +4 -4
- package/dist/cli/chunk-kwrg63tm.js +31 -0
- package/dist/cli/chunk-kwrg63tm.js.map +10 -0
- package/dist/cli/{chunk-2hsdwb9n.js → chunk-nd1821sk.js} +18 -16
- package/dist/cli/{chunk-2hsdwb9n.js.map → chunk-nd1821sk.js.map} +2 -2
- package/dist/cli/{chunk-6dsbexzp.js → chunk-ntv4qrt7.js} +17 -15
- package/dist/cli/{chunk-6dsbexzp.js.map → chunk-ntv4qrt7.js.map} +2 -2
- package/dist/cli/{chunk-r9rcc4w7.js → chunk-p804f3pe.js} +7 -7
- package/dist/cli/{chunk-ey84smr6.js → chunk-py62fewh.js} +6 -6
- package/dist/cli/{chunk-ey84smr6.js.map → chunk-py62fewh.js.map} +1 -1
- package/dist/cli/chunk-q3wxxq39.js +126 -0
- package/dist/cli/chunk-q3wxxq39.js.map +11 -0
- package/dist/cli/{chunk-9t7a85s3.js → chunk-rekqz4qg.js} +23 -13
- package/dist/cli/chunk-rekqz4qg.js.map +10 -0
- package/dist/cli/{chunk-8ktnccpt.js → chunk-ta27feev.js} +1 -1
- package/dist/cli/{chunk-pv29h0wf.js → chunk-xkz5xbtv.js} +3476 -822
- package/dist/cli/chunk-xkz5xbtv.js.map +213 -0
- package/dist/cli/{chunk-a58773jm.js → chunk-y4ykbark.js} +2 -2
- package/dist/cli/{chunk-p3v96n38.js → chunk-y5h4r2y0.js} +4 -4
- package/dist/cli/{chunk-acanzt5p.js → chunk-yj17vs39.js} +6 -6
- package/dist/cli/{chunk-p73c0m7w.js → chunk-yxmk4pec.js} +16 -14
- package/dist/cli/{chunk-p73c0m7w.js.map → chunk-yxmk4pec.js.map} +2 -2
- package/dist/cli/{chunk-3em5wd2y.js → chunk-zccbjcj0.js} +4 -3
- package/dist/cli/{chunk-3em5wd2y.js.map → chunk-zccbjcj0.js.map} +2 -2
- package/dist/cli/{chunk-c8chx29p.js → chunk-zf748avv.js} +384 -207
- package/dist/cli/chunk-zf748avv.js.map +37 -0
- package/dist/cli/{chunk-g4hq16wv.js → chunk-zhvd6adm.js} +16 -14
- package/dist/cli/{chunk-g4hq16wv.js.map → chunk-zhvd6adm.js.map} +2 -2
- package/dist/cli/index.js +26 -20
- package/dist/cli/index.js.map +5 -5
- package/dist/types/ai/agent-surface.d.ts +8 -7
- package/dist/types/ai/ai-catalog.d.ts +7 -0
- package/dist/types/ai/ask-context.d.ts +22 -0
- package/dist/types/ai/ask.d.ts +271 -58
- package/dist/types/ai/index.d.ts +2 -2
- package/dist/types/ai/site-skill.d.ts +26 -0
- package/dist/types/ai/skills.d.ts +16 -0
- package/dist/types/astro/integration.d.ts +8 -0
- package/dist/types/captcha/hcaptcha.d.ts +27 -0
- package/dist/types/captcha/index.d.ts +28 -0
- package/dist/types/captcha/schema.d.ts +29 -0
- package/dist/types/captcha/turnstile.d.ts +28 -0
- package/dist/types/components/content/api-field.d.ts +59 -0
- package/dist/types/components/content/api-page.d.ts +95 -0
- package/dist/types/components/layout/nav-utils.d.ts +26 -0
- package/dist/types/components/openapi/helpers.d.ts +137 -0
- package/dist/types/components/openapi/security.d.ts +85 -0
- package/dist/types/consent/ethyca.d.ts +48 -0
- package/dist/types/consent/index.d.ts +37 -0
- package/dist/types/consent/native.d.ts +28 -0
- package/dist/types/consent/osano.d.ts +42 -0
- package/dist/types/consent/schema.d.ts +110 -0
- package/dist/types/core/config-input.d.ts +187 -20
- package/dist/types/core/data.d.ts +49 -4
- package/dist/types/core/footer.d.ts +8 -0
- package/dist/types/core/i18n-ui.d.ts +86 -0
- package/dist/types/core/includes.d.ts +8 -2
- package/dist/types/core/localizable.d.ts +7 -0
- package/dist/types/core/page-modes.d.ts +29 -0
- package/dist/types/core/redirect-patterns.d.ts +144 -0
- package/dist/types/core/related.d.ts +40 -0
- package/dist/types/core/schema.d.ts +551 -56
- package/dist/types/core/sources/read.d.ts +5 -0
- package/dist/types/core/types.d.ts +1 -1
- package/dist/types/core/variables.d.ts +42 -0
- package/dist/types/deploy/node-headers.d.ts +13 -2
- package/dist/types/deploy/platforms/cloudflare.d.ts +5 -0
- package/dist/types/deploy/platforms/netlify.d.ts +7 -0
- package/dist/types/deploy/platforms/vercel.d.ts +6 -0
- package/dist/types/deploy/redirects.d.ts +39 -11
- package/dist/types/deploy/vercel-negotiation.d.ts +9 -0
- package/dist/types/markdown/code-title.d.ts +17 -0
- package/dist/types/markdown/features.d.ts +3 -2
- package/dist/types/narration/build.d.ts +70 -0
- package/dist/types/narration/provider.d.ts +26 -0
- package/dist/types/narration/script.d.ts +154 -0
- package/dist/types/openapi/model.d.ts +12 -6
- package/dist/types/openapi/overlay.d.ts +54 -0
- package/dist/types/openapi/parse.d.ts +13 -0
- package/dist/types/openapi/references.d.ts +14 -4
- package/dist/types/ratelimit/cloudflare.d.ts +39 -0
- package/dist/types/ratelimit/index.d.ts +27 -0
- package/dist/types/ratelimit/memory.d.ts +36 -0
- package/dist/types/ratelimit/schema.d.ts +111 -0
- package/dist/types/ratelimit/upstash.d.ts +21 -0
- package/dist/types/ratelimit/wrangler.d.ts +23 -0
- package/dist/types/reference/asyncapi.d.ts +10 -10
- package/dist/types/reference/graphql.d.ts +13 -10
- package/dist/types/reference/openapi.d.ts +33 -12
- package/dist/types/reference/options.d.ts +45 -5
- package/dist/types/reference/scalar.d.ts +13 -0
- package/dist/types/reference/schema.d.ts +60 -36
- package/dist/types/search/documents.d.ts +12 -1
- package/dist/types/search/orama-index.d.ts +4 -0
- package/dist/types/seo/metatags.d.ts +20 -0
- package/docs/02-deployment.mdx +41 -5
- package/docs/03-upgrading.mdx +4 -4
- package/docs/04-migrating.mdx +1 -1
- package/docs/advanced/changelog.mdx +2 -2
- package/docs/advanced/skills.mdx +14 -0
- package/docs/cli/audit.mdx +21 -1
- package/docs/cli/index.mdx +1 -0
- package/docs/configuration/analytics.mdx +3 -1
- package/docs/configuration/assistant.mdx +188 -36
- package/docs/configuration/consent.mdx +100 -0
- package/docs/configuration/customization.mdx +4 -4
- package/docs/configuration/index.mdx +63 -5
- package/docs/configuration/meta.ts +3 -0
- package/docs/configuration/narration.mdx +119 -0
- package/docs/configuration/rate-limiting.mdx +69 -0
- package/docs/configuration/search.mdx +29 -1
- package/docs/configuration/theming.mdx +3 -1
- package/docs/content/components.mdx +106 -0
- package/docs/content/frontmatter.mdx +76 -0
- package/docs/content/i18n.mdx +38 -3
- package/docs/content/includes.mdx +16 -0
- package/docs/content/meta.mdx +1 -0
- package/docs/content/meta.ts +1 -0
- package/docs/content/navigation.mdx +28 -6
- package/docs/content/sources/contentful.mdx +32 -0
- package/docs/content/sources/custom.mdx +39 -0
- package/docs/content/sources/github-releases.mdx +31 -0
- package/docs/content/sources/index.mdx +91 -0
- package/docs/content/sources/meta.ts +16 -0
- package/docs/content/sources/notion.mdx +32 -0
- package/docs/content/sources/obsidian.mdx +37 -0
- package/docs/content/sources/payload.mdx +30 -0
- package/docs/content/sources/remote-mdx.mdx +40 -0
- package/docs/content/sources/sanity.mdx +29 -0
- package/docs/content/sources/strapi.mdx +31 -0
- package/docs/content/syntax.mdx +67 -2
- package/docs/content/variables.mdx +41 -0
- package/docs/discoverability/agent-discovery.mdx +29 -2
- package/docs/discoverability/index.mdx +1 -1
- package/docs/discoverability/llms-txt.mdx +1 -1
- package/docs/discoverability/metadata.mdx +17 -0
- package/docs/references/api-pages.mdx +74 -0
- package/docs/references/asyncapi.mdx +1 -1
- package/docs/references/graphql.mdx +2 -2
- package/docs/references/meta.ts +1 -1
- package/docs/references/openapi.mdx +102 -3
- package/docs/references/scalar.mdx +3 -1
- package/package.json +36 -1
- package/skills/blume/SKILL.md +3 -0
- package/skills/blume-migrate/SKILL.md +5 -5
- package/skills/blume-migrate/references/docusaurus.md +3 -3
- package/skills/blume-migrate/references/mintlify.md +37 -19
- package/skills/blume-migrate/references/nextra.md +2 -2
- package/skills/blume-migrate/references/starlight.md +2 -1
- package/skills/blume-migrate/scripts/mintlify-codemod.mjs +60 -14
- package/skills/blume-write-skill/SKILL.md +82 -0
- package/src/ai/agent-readability.ts +2 -1
- package/src/ai/agent-surface.ts +9 -7
- package/src/ai/ai-catalog.ts +6 -3
- package/src/ai/ask-context.ts +73 -20
- package/src/ai/ask-data.ts +6 -0
- package/src/ai/ask-tools.ts +142 -0
- package/src/ai/ask.ts +354 -76
- package/src/ai/component-markdown.ts +75 -0
- package/src/ai/cors.ts +2 -0
- package/src/ai/index.ts +12 -0
- package/src/ai/llms.ts +6 -2
- package/src/ai/markdown.ts +2 -1
- package/src/ai/mcp/data.ts +6 -0
- package/src/ai/openapi-components.ts +9 -3
- package/src/ai/site-skill.ts +274 -0
- package/src/ai/skills.ts +35 -2
- package/src/ai/write-skill.ts +97 -0
- package/src/astro/generate.ts +132 -18
- package/src/astro/index.ts +1 -0
- package/src/astro/integration.ts +35 -0
- package/src/astro/module-types.ts +6 -0
- package/src/astro/templates.ts +283 -30
- package/src/astro/variables.ts +31 -0
- package/src/audit/catalog.ts +19 -0
- package/src/audit/checks/contrast.ts +183 -0
- package/src/audit/checks/i18n.ts +2 -3
- package/src/audit/checks/indexability.ts +2 -3
- package/src/audit/checks/links.ts +5 -12
- package/src/audit/checks/sitemap.ts +2 -3
- package/src/audit/redirects.ts +46 -15
- package/src/audit/run.ts +2 -0
- package/src/audit/types.ts +2 -1
- package/src/blume-modules.d.ts +7 -0
- package/src/captcha/client.ts +152 -0
- package/src/captcha/hcaptcha.ts +36 -0
- package/src/captcha/index.ts +28 -0
- package/src/captcha/schema.ts +32 -0
- package/src/captcha/turnstile.ts +38 -0
- package/src/captcha/verify.ts +71 -0
- package/src/cli/command-meta.ts +5 -0
- package/src/cli/commands/doctor.ts +22 -16
- package/src/cli/commands/skill.ts +96 -0
- package/src/cli/index.ts +5 -0
- package/src/cli/required-secrets.ts +71 -29
- package/src/components/BlumePage.astro +2 -0
- package/src/components/content/ApiEndpoint.astro +18 -0
- package/src/components/content/ApiField.astro +79 -0
- package/src/components/content/ApiPlayground.astro +62 -0
- package/src/components/content/ApiRail.astro +19 -0
- package/src/components/content/Color.astro +1 -0
- package/src/components/content/FileTree.astro +1 -0
- package/src/components/content/GithubInfo.astro +1 -0
- package/src/components/content/Panel.astro +1 -0
- package/src/components/content/ParamField.astro +25 -0
- package/src/components/content/RequestExample.astro +17 -0
- package/src/components/content/ResponseExample.astro +17 -0
- package/src/components/content/ResponseField.astro +32 -0
- package/src/components/content/Step.astro +1 -0
- package/src/components/content/Tile.astro +1 -0
- package/src/components/content/Tooltip.astro +1 -0
- package/src/components/content/Tree.astro +1 -0
- package/src/components/content/TypeTable.astro +4 -1
- package/src/components/content/View.astro +21 -0
- package/src/components/content/ViewSwitcher.astro +168 -0
- package/src/components/content/api-field.ts +100 -0
- package/src/components/content/api-page.ts +224 -0
- package/src/components/content/view-switcher.ts +71 -0
- package/src/components/index.ts +2 -0
- package/src/components/islands/Assistant.astro +10 -1
- package/src/components/islands/assistant.tsx +104 -14
- package/src/components/islands/code-question.ts +62 -0
- package/src/components/islands/hooks.ts +110 -21
- package/src/components/islands/support-link.ts +68 -0
- package/src/components/layout/Analytics.astro +11 -2
- package/src/components/layout/Banner.astro +14 -10
- package/src/components/layout/Breadcrumbs.astro +6 -2
- package/src/components/layout/ConsentBanner.astro +62 -0
- package/src/components/layout/ConsentHead.astro +38 -0
- package/src/components/layout/Directory.astro +94 -0
- package/src/components/layout/DrawerSwitchers.astro +51 -0
- package/src/components/layout/Empty.astro +2 -2
- package/src/components/layout/Header.astro +122 -80
- package/src/components/layout/LanguageSwitcher.astro +48 -15
- package/src/components/layout/NarrationPlayer.astro +1085 -0
- package/src/components/layout/NavSelector.astro +33 -7
- package/src/components/layout/PageFeedback.astro +54 -49
- package/src/components/layout/PageLayout.astro +71 -3
- package/src/components/layout/ReferenceLayout.astro +17 -6
- package/src/components/layout/RelatedPages.astro +42 -0
- package/src/components/layout/RootLayout.astro +308 -45
- package/src/components/layout/Search.astro +31 -17
- package/src/components/layout/SiteFooter.astro +124 -0
- package/src/components/layout/SiteMetatags.astro +16 -0
- package/src/components/layout/consent/native.ts +79 -0
- package/src/components/layout/consent/types.ts +37 -0
- package/src/components/layout/footer-links.ts +53 -0
- package/src/components/layout/footer-socials.ts +87 -0
- package/src/components/layout/locale-redirect.ts +107 -0
- package/src/components/layout/nav-utils.ts +83 -0
- package/src/components/layout/page-feedback.ts +96 -0
- package/src/components/layout/search/analytics.ts +98 -0
- package/src/components/layout/search/flexsearch.ts +17 -5
- package/src/components/layout/search/orama-cloud.ts +26 -14
- package/src/components/layout/search/types.ts +20 -0
- package/src/components/layout/search/typesense.ts +5 -1
- package/src/components/openapi/Operation.astro +161 -13
- package/src/components/openapi/RequestBody.astro +6 -4
- package/src/components/openapi/RequestPanel.astro +59 -7
- package/src/components/openapi/Responses.astro +6 -4
- package/src/components/openapi/async-snippets.ts +4 -4
- package/src/components/openapi/code-samples.ts +97 -0
- package/src/components/openapi/security.ts +6 -3
- package/src/components/openapi/snippets.ts +869 -8
- package/src/components/props.ts +6 -0
- package/src/consent/client.ts +95 -0
- package/src/consent/clients.ts +19 -0
- package/src/consent/ethyca.ts +71 -0
- package/src/consent/head.ts +24 -0
- package/src/consent/index.ts +37 -0
- package/src/consent/init.ts +29 -0
- package/src/consent/native.ts +36 -0
- package/src/consent/osano.ts +59 -0
- package/src/consent/schema.ts +30 -0
- package/src/core/builtin-tags.ts +5 -0
- package/src/core/client-address.ts +19 -0
- package/src/core/config-input.ts +194 -20
- package/src/core/data.ts +44 -4
- package/src/core/diagnostics.ts +3 -2
- package/src/core/footer.ts +26 -0
- package/src/core/graph.ts +39 -36
- package/src/core/i18n-ui.ts +82 -2
- package/src/core/includes.ts +20 -3
- package/src/core/links.ts +16 -2
- package/src/core/localizable.ts +26 -0
- package/src/core/navigation.ts +43 -12
- package/src/core/page-modes.ts +56 -0
- package/src/core/project-graph.ts +111 -5
- package/src/core/redirect-patterns.ts +491 -0
- package/src/core/related.ts +131 -0
- package/src/core/schema.ts +318 -64
- package/src/core/sources/normalize.ts +2 -1
- package/src/core/sources/read.ts +8 -3
- package/src/core/types.ts +1 -1
- package/src/core/ui-packs/ar.ts +43 -0
- package/src/core/ui-packs/bg.ts +45 -0
- package/src/core/ui-packs/bn.ts +43 -0
- package/src/core/ui-packs/ca.ts +46 -0
- package/src/core/ui-packs/cs.ts +44 -0
- package/src/core/ui-packs/da.ts +45 -0
- package/src/core/ui-packs/de.ts +46 -0
- package/src/core/ui-packs/el.ts +45 -0
- package/src/core/ui-packs/es.ts +46 -0
- package/src/core/ui-packs/fa.ts +45 -0
- package/src/core/ui-packs/fi.ts +45 -0
- package/src/core/ui-packs/fr.ts +46 -0
- package/src/core/ui-packs/he.ts +43 -0
- package/src/core/ui-packs/hi.ts +44 -0
- package/src/core/ui-packs/hr.ts +45 -0
- package/src/core/ui-packs/hu.ts +44 -0
- package/src/core/ui-packs/id.ts +45 -0
- package/src/core/ui-packs/it.ts +45 -0
- package/src/core/ui-packs/ja.ts +45 -0
- package/src/core/ui-packs/ko.ts +44 -0
- package/src/core/ui-packs/nl.ts +46 -0
- package/src/core/ui-packs/no.ts +44 -0
- package/src/core/ui-packs/pl.ts +45 -0
- package/src/core/ui-packs/pt-br.ts +46 -0
- package/src/core/ui-packs/pt.ts +45 -0
- package/src/core/ui-packs/ro.ts +45 -0
- package/src/core/ui-packs/ru.ts +45 -0
- package/src/core/ui-packs/sk.ts +44 -0
- package/src/core/ui-packs/sr.ts +45 -0
- package/src/core/ui-packs/sv.ts +44 -0
- package/src/core/ui-packs/th.ts +43 -0
- package/src/core/ui-packs/tr.ts +45 -0
- package/src/core/ui-packs/uk.ts +45 -0
- package/src/core/ui-packs/vi.ts +45 -0
- package/src/core/ui-packs/zh-tw.ts +43 -0
- package/src/core/ui-packs/zh.ts +43 -0
- package/src/core/variables.ts +103 -0
- package/src/deploy/artifacts.ts +77 -8
- package/src/deploy/cloudflare-negotiation.ts +35 -5
- package/src/deploy/headers.ts +2 -1
- package/src/deploy/node-headers.ts +63 -9
- package/src/deploy/platforms/cloudflare.ts +32 -0
- package/src/deploy/platforms/netlify.ts +33 -1
- package/src/deploy/platforms/vercel.ts +37 -2
- package/src/deploy/redirects.ts +91 -24
- package/src/deploy/vercel-negotiation.ts +36 -0
- package/src/markdown/api-rail.ts +259 -0
- package/src/markdown/code-title.ts +35 -9
- package/src/markdown/features.ts +3 -2
- package/src/markdown/fence-meta.ts +2 -0
- package/src/markdown/include.ts +11 -1
- package/src/markdown/index.ts +28 -5
- package/src/markdown/math.ts +4 -4
- package/src/markdown/variables.ts +56 -0
- package/src/markdown/views.ts +82 -0
- package/src/narration/build.ts +412 -0
- package/src/narration/player.ts +249 -0
- package/src/narration/provider.ts +29 -0
- package/src/narration/script.ts +592 -0
- package/src/og/card.ts +7 -6
- package/src/openapi/model.ts +57 -24
- package/src/openapi/overlay.ts +256 -0
- package/src/openapi/parse.ts +55 -2
- package/src/openapi/references.ts +21 -5
- package/src/openapi/render-mdx.ts +5 -1
- package/src/openapi/scalar.ts +40 -6
- package/src/openapi/source.ts +1 -1
- package/src/ratelimit/cloudflare.ts +54 -0
- package/src/ratelimit/index.ts +30 -0
- package/src/ratelimit/memory.ts +45 -0
- package/src/ratelimit/runtime.ts +229 -0
- package/src/ratelimit/schema.ts +28 -0
- package/src/ratelimit/upstash.ts +30 -0
- package/src/ratelimit/wrangler.ts +70 -0
- package/src/reference/asyncapi.ts +2 -2
- package/src/reference/graphql.ts +5 -2
- package/src/reference/openapi.ts +21 -7
- package/src/reference/options.ts +51 -7
- package/src/reference/scalar.ts +33 -8
- package/src/registry/eject.ts +20 -4
- package/src/registry/registry.ts +7 -0
- package/src/search/documents.ts +26 -2
- package/src/search/orama-index.ts +28 -3
- package/src/search/pagefind-ranking.ts +39 -0
- package/src/search/sync/algolia.ts +15 -4
- package/src/search/sync/orama-cloud.ts +3 -0
- package/src/search/sync/typesense.ts +5 -0
- package/src/seo/metatags.ts +67 -0
- package/src/theme/chrome-icons.ts +1 -0
- package/src/theme/color.ts +500 -0
- package/src/theme/entry.ts +56 -3
- package/src/theme/palette.ts +121 -45
- package/src/translate/prompts.ts +1 -0
- package/src/translate/validate.ts +8 -2
- package/src/upgrade/upgrade.ts +4 -171
- package/dist/cli/chunk-364znk6q.js +0 -75
- package/dist/cli/chunk-364znk6q.js.map +0 -11
- package/dist/cli/chunk-5m5nmvyq.js.map +0 -13
- package/dist/cli/chunk-9t7a85s3.js.map +0 -10
- package/dist/cli/chunk-c8chx29p.js.map +0 -36
- package/dist/cli/chunk-pehfxfta.js.map +0 -10
- package/dist/cli/chunk-pv29h0wf.js.map +0 -190
- package/dist/cli/chunk-q58y5e6a.js.map +0 -10
- package/dist/cli/chunk-wrr3j9w9.js.map +0 -35
- package/dist/cli/chunk-yfyb25rh.js.map +0 -14
- package/docs/content/sources.mdx +0 -334
- /package/dist/cli/{chunk-2eytanqx.js.map → chunk-1n228xqb.js.map} +0 -0
- /package/dist/cli/{chunk-35d4wj9f.js.map → chunk-2n4ps1b3.js.map} +0 -0
- /package/dist/cli/{chunk-e04dxsz1.js.map → chunk-4ejxbzee.js.map} +0 -0
- /package/dist/cli/{chunk-tzmab476.js.map → chunk-5ffywsmb.js.map} +0 -0
- /package/dist/cli/{chunk-2z928egk.js.map → chunk-5wj2qwn2.js.map} +0 -0
- /package/dist/cli/{chunk-b07cmahc.js.map → chunk-amrb6hgh.js.map} +0 -0
- /package/dist/cli/{chunk-akbpwfxc.js.map → chunk-cmtcnh9f.js.map} +0 -0
- /package/dist/cli/{chunk-crgn1q09.js.map → chunk-e7vvk5ya.js.map} +0 -0
- /package/dist/cli/{chunk-tkacnehg.js.map → chunk-gp84za0h.js.map} +0 -0
- /package/dist/cli/{chunk-r9rcc4w7.js.map → chunk-p804f3pe.js.map} +0 -0
- /package/dist/cli/{chunk-8ktnccpt.js.map → chunk-ta27feev.js.map} +0 -0
- /package/dist/cli/{chunk-a58773jm.js.map → chunk-y4ykbark.js.map} +0 -0
- /package/dist/cli/{chunk-p3v96n38.js.map → chunk-y5h4r2y0.js.map} +0 -0
- /package/dist/cli/{chunk-acanzt5p.js.map → chunk-yj17vs39.js.map} +0 -0
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
import type { PageRecord } from "../types.ts";
|
|
2
|
+
import type { ContentVariables } from "../variables.ts";
|
|
2
3
|
import type { ContentSource } from "./types.ts";
|
|
3
4
|
/** The subset of a scanned project the entry reader needs. */
|
|
4
5
|
export interface EntryReadContext {
|
|
6
|
+
/** The site's content variables, substituted into what's read. */
|
|
7
|
+
config?: {
|
|
8
|
+
variables?: ContentVariables;
|
|
9
|
+
};
|
|
5
10
|
/** The instantiated sources, keyed for `read()` lookups. */
|
|
6
11
|
sources?: ContentSource[];
|
|
7
12
|
}
|
|
@@ -297,7 +297,7 @@ export interface Navigation {
|
|
|
297
297
|
cta?: HeaderAction | null;
|
|
298
298
|
/** Pinned links shown above the sidebar sections, unscoped by tab. */
|
|
299
299
|
featured: FeaturedLink[];
|
|
300
|
-
/** Repo URL for the
|
|
300
|
+
/** Repo URL for the footer's GitHub link, or null when hidden (`navigation.repo`). */
|
|
301
301
|
repoUrl?: string | null;
|
|
302
302
|
/**
|
|
303
303
|
* Where the header's brand link points in this locale: `logo.href` moved
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Content variables: `variables: { version: "2.1.0" }` in `blume.config.ts`
|
|
3
|
+
* makes `{{version}}` in a page read `2.1.0` wherever it appears in the body,
|
|
4
|
+
* code and links included. The syntax is Mintlify's, so migrated pages keep
|
|
5
|
+
* working.
|
|
6
|
+
*
|
|
7
|
+
* Substitution is textual, before any parsing, so a page's HTML, its search
|
|
8
|
+
* entry, its `.md` mirror, and `llms-full.txt` all agree: the MDX pipeline
|
|
9
|
+
* substitutes in a Vite transform ahead of the compiler (an MDX parser would
|
|
10
|
+
* read `{{version}}` as a JavaScript expression), the Markdown pipeline in a
|
|
11
|
+
* plugin over the parsed text, includes as their files are read, and the raw
|
|
12
|
+
* readers through {@link substituteVariables}. Only defined names are
|
|
13
|
+
* replaced; an undefined one in prose is a build error
|
|
14
|
+
* (`BLUME_UNDEFINED_VARIABLE`), and inside code it is left alone, since
|
|
15
|
+
* templating examples (`{{name}}` in a Handlebars snippet) are common there.
|
|
16
|
+
*/
|
|
17
|
+
/** The variables a site defines, name to value. */
|
|
18
|
+
export type ContentVariables = Readonly<Record<string, string>>;
|
|
19
|
+
/** A variable name: letters, digits, `_`, and `-` (Mintlify's `api-url`). */
|
|
20
|
+
export declare const VARIABLE_NAME: RegExp;
|
|
21
|
+
/** Whether a site defines any variables, so the rest can be skipped. */
|
|
22
|
+
export declare const hasVariables: (variables?: ContentVariables) => variables is ContentVariables;
|
|
23
|
+
/** `text` with every reference to a defined variable replaced by its value. */
|
|
24
|
+
export declare const substituteVariables: (text: string, variables?: ContentVariables) => string;
|
|
25
|
+
/**
|
|
26
|
+
* {@link substituteVariables} over a page's raw source, leaving its front
|
|
27
|
+
* matter as written: the rendered page reads its title and description from
|
|
28
|
+
* the unsubstituted front matter, so the other surfaces must too.
|
|
29
|
+
*/
|
|
30
|
+
export declare const substituteVariablesInBody: (source: string, variables?: ContentVariables) => string;
|
|
31
|
+
/** An undefined variable referenced in prose, with its 1-based line. */
|
|
32
|
+
export interface UndefinedVariable {
|
|
33
|
+
line: number;
|
|
34
|
+
name: string;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* The undefined variables `text` references outside code: fenced blocks and
|
|
38
|
+
* inline code spans are skipped, so a templating example never fails a
|
|
39
|
+
* build. Empty when the site defines no variables at all, so a page that
|
|
40
|
+
* shows `{{…}}` literally keeps working until the site opts in.
|
|
41
|
+
*/
|
|
42
|
+
export declare const undefinedVariables: (text: string, variables?: ContentVariables) => UndefinedVariable[];
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { BlumeProject } from "../core/project-graph.ts";
|
|
2
|
+
import type { CompiledRedirect } from "../core/redirect-patterns.ts";
|
|
2
3
|
import type { ResolvedConfig } from "../core/schema.ts";
|
|
3
4
|
import type { BuildLog } from "./platforms/types.ts";
|
|
4
5
|
/**
|
|
@@ -34,19 +35,29 @@ export declare const nodeHeaderRules: (config: ResolvedConfig) => NodeHeaderRule
|
|
|
34
35
|
*/
|
|
35
36
|
export type NodeRedirects = Record<string, [string, number]>;
|
|
36
37
|
/**
|
|
37
|
-
* The configured redirects, based the way the host matches them (see
|
|
38
|
+
* The configured exact redirects, based the way the host matches them (see
|
|
38
39
|
* `platformRedirects`) and keyed for the wrapper's lookup, the `Location`
|
|
39
40
|
* percent-encoded as Astro sends it. A redirect at a content route's own path
|
|
40
41
|
* is left out: the prerendered page owns that URL, and the static handler
|
|
41
|
-
* serves it before Astro's redirect ever could.
|
|
42
|
+
* serves it before Astro's redirect ever could. Patterns are compiled apart
|
|
43
|
+
* ({@link nodePatternRedirects}).
|
|
42
44
|
*/
|
|
43
45
|
export declare const nodeRedirects: (project: BlumeProject) => NodeRedirects;
|
|
46
|
+
/**
|
|
47
|
+
* The configured pattern redirects (`/beta/:slug*`), based the way the host
|
|
48
|
+
* matches them and compiled for the wrapper, which tries them in order after
|
|
49
|
+
* the exact ones. None can match a page: the scan rejects a pattern that
|
|
50
|
+
* does (`BLUME_REDIRECT_MATCHES_PAGE`).
|
|
51
|
+
*/
|
|
52
|
+
export declare const nodePatternRedirects: (project: BlumeProject) => CompiledRedirect[];
|
|
44
53
|
/** What the wrapper needs beyond the header rules. */
|
|
45
54
|
export interface NodeEntryOptions {
|
|
46
55
|
/** `deployment.base`, normalized (`""` at the root). */
|
|
47
56
|
base?: string;
|
|
48
57
|
/** The configured redirects, from {@link nodeRedirects}. */
|
|
49
58
|
redirects?: NodeRedirects;
|
|
59
|
+
/** The configured pattern redirects, from {@link nodePatternRedirects}. */
|
|
60
|
+
patternRedirects?: CompiledRedirect[];
|
|
50
61
|
}
|
|
51
62
|
/**
|
|
52
63
|
* The entry that replaces Astro's: it answers a configured redirect with its
|
|
@@ -28,6 +28,11 @@ export declare const emitCloudflareDeployConfig: (context: ProjectContext) => Pr
|
|
|
28
28
|
* built config instead, and is left alone.
|
|
29
29
|
*/
|
|
30
30
|
export declare const nameCloudflareWorker: (project: BlumeProject, log: BuildLog) => Promise<void>;
|
|
31
|
+
/**
|
|
32
|
+
* Declare the Workers rate limiting binding `rateLimit: cloudflare()` counts
|
|
33
|
+
* with in the built Worker's config, which `wrangler deploy` reads.
|
|
34
|
+
*/
|
|
35
|
+
export declare const bindCloudflareRateLimit: (project: BlumeProject, log: BuildLog) => Promise<void>;
|
|
31
36
|
/**
|
|
32
37
|
* Cloudflare Workers and Pages. A server build emits the Worker into
|
|
33
38
|
* `dist/server` and serves `dist/client` through the ASSETS binding, which
|
|
@@ -26,6 +26,13 @@ export declare const NETLIFY_CONFIG_FILE: string;
|
|
|
26
26
|
* as static files, so the prerendered endpoint's own headers never ship.
|
|
27
27
|
*/
|
|
28
28
|
export declare const emitNetlifyHeaders: (project: BlumeProject, log: BuildLog) => Promise<void>;
|
|
29
|
+
/**
|
|
30
|
+
* Carry the pattern redirects (`/beta/:slug*`) into a server build, as
|
|
31
|
+
* `redirects` in the Frameworks API config: Astro's `redirects` carry only
|
|
32
|
+
* the exact ones, since it can't prerender a pattern's pages, so the adapter
|
|
33
|
+
* never writes these. Netlify appends them after any rules of the user's own.
|
|
34
|
+
*/
|
|
35
|
+
export declare const emitNetlifyPatternRedirects: (project: BlumeProject) => Promise<void>;
|
|
29
36
|
/**
|
|
30
37
|
* Netlify. A server build runs on Netlify Functions from the Frameworks API
|
|
31
38
|
* tree the adapter writes to `.netlify/v1`, relative to the Astro root —
|
|
@@ -20,6 +20,12 @@ export declare const checkVercelFunctionBundles: (outputDir: string, root: strin
|
|
|
20
20
|
* root it was shown.
|
|
21
21
|
*/
|
|
22
22
|
export declare const emitVercelNegotiation: (project: BlumeProject, log: BuildLog) => Promise<void>;
|
|
23
|
+
/**
|
|
24
|
+
* Route the pattern redirects (`/beta/:slug*`) in the adapter's Build Output
|
|
25
|
+
* config: Astro's `redirects` carry only the exact ones, since it can't
|
|
26
|
+
* prerender a pattern's pages, so the adapter never sees these.
|
|
27
|
+
*/
|
|
28
|
+
export declare const emitVercelPatternRedirects: (project: BlumeProject, log: BuildLog) => Promise<void>;
|
|
23
29
|
/**
|
|
24
30
|
* Vercel. A server build's Build Output tree lands at `.vercel/output` — at
|
|
25
31
|
* the project root, because the adapter is handed that root up front: its
|
|
@@ -2,12 +2,16 @@ import type { RouteSet } from "../core/locale-links.ts";
|
|
|
2
2
|
import type { BlumeProject } from "../core/project-graph.ts";
|
|
3
3
|
import type { ResolvedConfig } from "../core/schema.ts";
|
|
4
4
|
import type { VercelHeader } from "./headers.ts";
|
|
5
|
+
import type { VercelRoute } from "./vercel-negotiation.ts";
|
|
5
6
|
/**
|
|
6
7
|
* Platform redirect files for a static build. Astro already emits redirect HTML
|
|
7
8
|
* (meta-refresh) pages for static output, but that's a soft client redirect.
|
|
8
9
|
* These give the host a real HTTP 3xx: Netlify/Cloudflare read `_redirects`,
|
|
9
10
|
* Vercel reads `vercel.json`, and `blume-redirects.json` is a structured
|
|
10
|
-
* manifest for anything else (Apache/nginx rules, an edge worker).
|
|
11
|
+
* manifest for anything else (Apache/nginx rules, an edge worker). A pattern
|
|
12
|
+
* redirect (`/beta/:slug*`) gets no redirect page, since Astro can't
|
|
13
|
+
* prerender one for paths it doesn't know; each host file carries it in that
|
|
14
|
+
* host's syntax (see `core/redirect-patterns.ts`).
|
|
11
15
|
*/
|
|
12
16
|
type Redirect = ResolvedConfig["redirects"][number];
|
|
13
17
|
/**
|
|
@@ -39,19 +43,22 @@ export declare const applyBaseToAstroRedirects: (redirects: Redirect[], basePath
|
|
|
39
43
|
export declare const applyBaseToPlatformRedirects: (redirects: Redirect[], basePath: string, deployBase: string, routes: RouteSet) => Redirect[];
|
|
40
44
|
/**
|
|
41
45
|
* The configured redirects as the host platform matches them, via
|
|
42
|
-
* {@link applyBaseToPlatformRedirects}
|
|
43
|
-
*
|
|
44
|
-
*
|
|
46
|
+
* {@link applyBaseToPlatformRedirects}, exact paths ahead of patterns: hosts
|
|
47
|
+
* try rules in order, and an exact redirect wins over a pattern that also
|
|
48
|
+
* covers its path. The one basing every consumer must share: the emitted
|
|
49
|
+
* redirect files and the server wrappers all compare these paths against
|
|
50
|
+
* real served URLs.
|
|
45
51
|
*/
|
|
46
52
|
export declare const platformRedirects: (project: {
|
|
47
53
|
config: ResolvedConfig;
|
|
48
54
|
manifest: Pick<BlumeProject["manifest"], "routes">;
|
|
49
55
|
}) => Redirect[];
|
|
50
56
|
/**
|
|
51
|
-
* `_redirects` text (Netlify + Cloudflare Pages): `from to status` per line
|
|
52
|
-
*
|
|
53
|
-
*
|
|
54
|
-
*
|
|
57
|
+
* `_redirects` text (Netlify + Cloudflare Pages): `from to status` per line,
|
|
58
|
+
* a pattern as `:placeholder`s and a `*` splat the destination reads as
|
|
59
|
+
* `:splat`. `force` appends Netlify's `!` to each status (`301!`), so the rule
|
|
60
|
+
* wins over the redirect page Astro writes at `from`; Cloudflare, which always
|
|
61
|
+
* applies its rules first, rejects a line carrying it.
|
|
55
62
|
*/
|
|
56
63
|
export declare const buildNetlifyRedirects: (redirects: Redirect[], force?: boolean) => string;
|
|
57
64
|
/**
|
|
@@ -60,10 +67,31 @@ export declare const buildNetlifyRedirects: (redirects: Redirect[], force?: bool
|
|
|
60
67
|
* alternative to the boolean `permanent`) so the configured code ships exactly:
|
|
61
68
|
* `permanent` would silently coerce a 301 to 308 and a 302 to 307, diverging
|
|
62
69
|
* from the `_redirects` file, which preserves exact codes. A `source` is a
|
|
63
|
-
* `path-to-regexp` pattern, so each
|
|
64
|
-
* `/c++-guide` fails the whole config and `/faq(old)` never
|
|
70
|
+
* `path-to-regexp` pattern, so each literal run of a `from` path is escaped:
|
|
71
|
+
* unescaped, `/c++-guide` fails the whole config and `/faq(old)` never
|
|
72
|
+
* matches. A pattern's captures are `path-to-regexp` params.
|
|
65
73
|
*/
|
|
66
74
|
export declare const buildVercelConfig: (redirects: Redirect[], headers?: readonly VercelHeader[]) => string;
|
|
67
|
-
/**
|
|
75
|
+
/**
|
|
76
|
+
* The pattern redirects as `_redirects` entries, for the `redirects` of a
|
|
77
|
+
* Netlify server build's Frameworks API config (see
|
|
78
|
+
* {@link buildNetlifyRedirects} for the syntax).
|
|
79
|
+
*/
|
|
80
|
+
export declare const netlifyPatternRedirects: (redirects: Redirect[]) => {
|
|
81
|
+
from: string;
|
|
82
|
+
status: number;
|
|
83
|
+
to: string;
|
|
84
|
+
}[];
|
|
85
|
+
/**
|
|
86
|
+
* The pattern redirects as Build Output API routes, for a Vercel server
|
|
87
|
+
* build: the adapter routes only the exact redirects Astro's config carries.
|
|
88
|
+
* Each matches the served path, a trailing slash optional, and fills its
|
|
89
|
+
* `Location` from numbered captures, as the adapter's own redirect routes do.
|
|
90
|
+
*/
|
|
91
|
+
export declare const vercelPatternRoutes: (redirects: Redirect[]) => VercelRoute[];
|
|
92
|
+
/**
|
|
93
|
+
* Structured manifest for hosts that need manual wiring. A pattern stays as
|
|
94
|
+
* configured (`/beta/:slug*`), for the rule it becomes to be written by hand.
|
|
95
|
+
*/
|
|
68
96
|
export declare const buildRedirectManifest: (redirects: Redirect[]) => string;
|
|
69
97
|
export {};
|
|
@@ -108,3 +108,12 @@ export declare const buildNegotiationRoutes: (routePaths: readonly string[], hom
|
|
|
108
108
|
* `handle: "filesystem"` marker to anchor the splice.
|
|
109
109
|
*/
|
|
110
110
|
export declare const injectNegotiationRoutes: (configText: string, routePaths: readonly string[], homeLinkHeader?: string | null, contentTypeOverrides?: Record<string, string>, homeTokens?: number, notFound?: NotFoundVariants, corsPaths?: readonly string[], svgAssets?: boolean) => string | null;
|
|
111
|
+
/**
|
|
112
|
+
* Splice routes for the pattern redirects (see `vercelPatternRoutes`) into a
|
|
113
|
+
* Build Output `config.json`, in the main phase just ahead of
|
|
114
|
+
* `handle: "filesystem"`: after the exact redirects the adapter puts first,
|
|
115
|
+
* so an exact path still wins. A second pass replaces its own routes. Returns
|
|
116
|
+
* the updated JSON text, or `null` when there is nowhere safe to splice: an
|
|
117
|
+
* unparsable config, no `routes` array, or no `handle: "filesystem"` marker.
|
|
118
|
+
*/
|
|
119
|
+
export declare const injectRedirectRoutes: (configText: string, redirectRoutes: readonly VercelRoute[]) => string | null;
|
|
@@ -7,7 +7,20 @@
|
|
|
7
7
|
* language label.
|
|
8
8
|
* - the `lineNumbers` keyword (```ts file.ts lineNumbers) becomes
|
|
9
9
|
* `data-line-numbers`; the theme renders a counter-driven line-number gutter.
|
|
10
|
+
* - the `wrap` keyword becomes `data-wrap`: this block's long lines wrap
|
|
11
|
+
* instead of scrolling, as `markdown.code.wrap` does for every block.
|
|
12
|
+
* - the `expandable` keyword becomes `data-expandable` on a block of
|
|
13
|
+
* {@link EXPANDABLE_MIN_LINES} lines or more: the theme shows its first
|
|
14
|
+
* {@link EXPANDABLE_VISIBLE_LINES} lines, and the page script adds a toggle
|
|
15
|
+
* that shows the rest in full. A shorter block renders as it is.
|
|
10
16
|
*/
|
|
17
|
+
/** The lines a collapsed `expandable` block shows. */
|
|
18
|
+
export declare const EXPANDABLE_VISIBLE_LINES = 10;
|
|
19
|
+
/**
|
|
20
|
+
* The lines a block needs before `expandable` collapses it: a few more than it
|
|
21
|
+
* shows, so the toggle never hides a line or two behind a click.
|
|
22
|
+
*/
|
|
23
|
+
export declare const EXPANDABLE_MIN_LINES = 16;
|
|
11
24
|
/** The slice of Shiki's transformer `this` context Blume reads. */
|
|
12
25
|
interface CodeMetaContext {
|
|
13
26
|
options: {
|
|
@@ -15,6 +28,8 @@ interface CodeMetaContext {
|
|
|
15
28
|
__raw?: string;
|
|
16
29
|
};
|
|
17
30
|
};
|
|
31
|
+
/** The block's code, as highlighted. */
|
|
32
|
+
source?: string;
|
|
18
33
|
}
|
|
19
34
|
/** The `<pre>` hast node a Shiki `pre` hook receives. */
|
|
20
35
|
interface PreNode {
|
|
@@ -27,6 +42,8 @@ export interface CodeTitleTransformer {
|
|
|
27
42
|
}
|
|
28
43
|
/** The title a fence's meta string promotes to `data-title`, if any. */
|
|
29
44
|
export declare const parseCodeTitle: (raw: string | undefined) => string | undefined;
|
|
45
|
+
/** How many lines a block's code runs to, a trailing newline aside. */
|
|
46
|
+
export declare const lineCount: (source?: string) => number;
|
|
30
47
|
/** Build the transformer. Runs after Shiki's built-in `data-language` hook. */
|
|
31
48
|
export declare const codeTitleTransformer: () => CodeTitleTransformer;
|
|
32
49
|
export {};
|
|
@@ -8,8 +8,9 @@ export declare const MARKDOWN_FEATURES: {
|
|
|
8
8
|
};
|
|
9
9
|
/**
|
|
10
10
|
* The `.mdx` feature set: Markdown's plus `:::` directives (→ `<Callout>`) and
|
|
11
|
-
*
|
|
12
|
-
*
|
|
11
|
+
* math — `singleDollarTextMath: false` keeps a bare `$` (currency, shell,
|
|
12
|
+
* code) as literal text and only parses `$$…$$`, as a block on its own lines
|
|
13
|
+
* or inline within a sentence.
|
|
13
14
|
*/
|
|
14
15
|
export declare const MDX_FEATURES: {
|
|
15
16
|
directive: true;
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { HTMLElement } from "node-html-parser";
|
|
2
|
+
import type { Node } from "node-html-parser";
|
|
3
|
+
import type { BlumeProject } from "../core/project-graph.ts";
|
|
4
|
+
import type { ProjectContext } from "../core/types.ts";
|
|
5
|
+
import type { NarrationProvider } from "./provider.ts";
|
|
6
|
+
import type { NarrationCues, NarrationTree } from "./script.ts";
|
|
7
|
+
/**
|
|
8
|
+
* Generated narration: after Astro writes the HTML, read every page that
|
|
9
|
+
* carries the player exactly as the browser will (same walker, same blocks),
|
|
10
|
+
* split it into sentences, and give each sentence a clip from the configured
|
|
11
|
+
* speech model. Clips are cached by what decides their sound (text, language,
|
|
12
|
+
* model, voice, instructions, provider options), so a rebuild only pays for
|
|
13
|
+
* sentences that changed, and one sentence shared by many pages is generated
|
|
14
|
+
* once. Each page gets a manifest listing its clips; the player plays them in
|
|
15
|
+
* order and falls back to browser voices wherever a manifest is missing.
|
|
16
|
+
*/
|
|
17
|
+
/** How the build logs: the integration's Astro logger. */
|
|
18
|
+
export interface NarrationLogger {
|
|
19
|
+
info: (message: string) => void;
|
|
20
|
+
warn: (message: string) => void;
|
|
21
|
+
}
|
|
22
|
+
/** Speak `text` in `lang`, returning MP3 bytes. */
|
|
23
|
+
export type Speak = (text: string, lang: string) => Promise<Uint8Array>;
|
|
24
|
+
/** What a narration build did, for the log line and tests. */
|
|
25
|
+
export interface NarrationBuildResult {
|
|
26
|
+
/** Clips that failed to generate; their pages get no manifest. */
|
|
27
|
+
failed: number;
|
|
28
|
+
/** Clips generated by the speech model on this build. */
|
|
29
|
+
generated: number;
|
|
30
|
+
/** Pages that got a manifest. */
|
|
31
|
+
pages: number;
|
|
32
|
+
/** Clips read back from the cache. */
|
|
33
|
+
reused: number;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* The clip cache directory: `node_modules/.cache/blume/narration`, next to the
|
|
37
|
+
* OG card cache and restored by the same host build caches (see `ogCacheDir`).
|
|
38
|
+
*/
|
|
39
|
+
export declare const narrationCacheDir: (context: Pick<ProjectContext, "outDir" | "root">) => string;
|
|
40
|
+
/** The walker's view of a node-html-parser tree. */
|
|
41
|
+
export declare const htmlTree: NarrationTree<Node>;
|
|
42
|
+
/** The player's settings on a built page, and the article it reads. */
|
|
43
|
+
interface PlayerPage {
|
|
44
|
+
article: HTMLElement;
|
|
45
|
+
audioBase: string;
|
|
46
|
+
cues: NarrationCues;
|
|
47
|
+
lang: string;
|
|
48
|
+
manifest: string;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* The generated player on a built page, or `null` when the page has none (or
|
|
52
|
+
* a player without generated audio, which reads with browser voices).
|
|
53
|
+
*/
|
|
54
|
+
export declare const readPlayerPage: (html: string) => PlayerPage | null;
|
|
55
|
+
/**
|
|
56
|
+
* A clip's cache key: a digest of everything that decides how it sounds. The
|
|
57
|
+
* Blume version is deliberately left out, unlike the OG card's: an upgrade
|
|
58
|
+
* shouldn't pay to regenerate audio that would sound the same.
|
|
59
|
+
*/
|
|
60
|
+
export declare const clipKey: (provider: NarrationProvider, lang: string, text: string) => string;
|
|
61
|
+
/** Speak through the Vercel AI Gateway with the provider's model and voice. */
|
|
62
|
+
export declare const gatewaySpeaker: (provider: NarrationProvider) => Speak;
|
|
63
|
+
/**
|
|
64
|
+
* Generate the narration for a built site in `distDir`: a clip per sentence
|
|
65
|
+
* and a manifest per page. Does nothing unless `narration.provider` is set,
|
|
66
|
+
* and warns instead of generating when the provider's key is missing (the
|
|
67
|
+
* pages then read with browser voices). `speak` replaces the gateway call.
|
|
68
|
+
*/
|
|
69
|
+
export declare const buildNarration: (project: BlumeProject, distDir: string, logger: NarrationLogger, speak?: Speak) => Promise<NarrationBuildResult | null>;
|
|
70
|
+
export {};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
/** The speech model narration uses when `gateway()` names none. */
|
|
3
|
+
export declare const DEFAULT_NARRATION_MODEL = "openai/tts-1-hd";
|
|
4
|
+
/** The voice narration uses when `gateway()` names none. */
|
|
5
|
+
export declare const DEFAULT_NARRATION_VOICE = "alloy";
|
|
6
|
+
/**
|
|
7
|
+
* `narration.provider`: the `gateway()` descriptor from `blume/ai`, read with
|
|
8
|
+
* speech defaults. `reasoning` is an assistant option and is rejected here;
|
|
9
|
+
* `voice` and `instructions` are narration options and are rejected by the
|
|
10
|
+
* assistant.
|
|
11
|
+
*/
|
|
12
|
+
export declare const narrationProviderSchema: z.ZodObject<{
|
|
13
|
+
kind: z.ZodLiteral<"gateway">;
|
|
14
|
+
options: z.ZodObject<{
|
|
15
|
+
instructions: z.ZodOptional<z.ZodString>;
|
|
16
|
+
model: z.ZodDefault<z.ZodString>;
|
|
17
|
+
voice: z.ZodDefault<z.ZodString>;
|
|
18
|
+
apiKeyEnv: z.ZodDefault<z.ZodString>;
|
|
19
|
+
headers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
20
|
+
providerOptions: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodRecord<z.ZodString, z.ZodJSONSchema>>>;
|
|
21
|
+
}, z.core.$strict>;
|
|
22
|
+
requiredSecrets: z.ZodArray<z.ZodString>;
|
|
23
|
+
runtimeDeps: z.ZodArray<z.ZodString>;
|
|
24
|
+
}, z.core.$strict>;
|
|
25
|
+
/** A validated narration provider, defaults filled in. */
|
|
26
|
+
export type NarrationProvider = z.output<typeof narrationProviderSchema>;
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Narration's reading script: what "Listen to this page" says, in order, and
|
|
3
|
+
* where each spoken sentence sits in the page's text.
|
|
4
|
+
*
|
|
5
|
+
* One walker serves both sides. `blume build` runs it over the built HTML
|
|
6
|
+
* (parsed with node-html-parser) to generate a clip per sentence, and the
|
|
7
|
+
* player runs it over the live `<article>` to highlight the sentence being
|
|
8
|
+
* read. Both see the same markup and apply the same rules, so they agree on
|
|
9
|
+
* every block's text; the sentence split is only ever computed once per
|
|
10
|
+
* engine (by the build for generated audio, by the browser for its own
|
|
11
|
+
* voices), so an ICU difference between Node and the browser can't move a
|
|
12
|
+
* highlight.
|
|
13
|
+
*
|
|
14
|
+
* The rules follow what reads well aloud: the title, description, headings,
|
|
15
|
+
* and prose are read in order; callouts, steps, tabs, and collapsible
|
|
16
|
+
* sections are announced with a short spoken cue; code, tables, media,
|
|
17
|
+
* diagrams, math, API field tables, and anything marked
|
|
18
|
+
* `data-blume-narration="skip"` are left out.
|
|
19
|
+
*/
|
|
20
|
+
/**
|
|
21
|
+
* The slice of a DOM-like tree the walker reads. The browser DOM and
|
|
22
|
+
* node-html-parser both satisfy it through a small adapter, so the walker
|
|
23
|
+
* never touches either API directly.
|
|
24
|
+
*/
|
|
25
|
+
export interface NarrationTree<N> {
|
|
26
|
+
/** An element's attribute, or `null` when it is absent. */
|
|
27
|
+
attr: (node: N, name: string) => string | null;
|
|
28
|
+
children: (node: N) => readonly N[];
|
|
29
|
+
/** An element's lowercase tag name; `null` for text and other nodes. */
|
|
30
|
+
tag: (node: N) => string | null;
|
|
31
|
+
/** A text node's decoded text; `null` for elements and other nodes. */
|
|
32
|
+
text: (node: N) => string | null;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* The spoken cues, already localized for the page. `{n}` in `step` is the
|
|
36
|
+
* step's number and `{title}` in `tab` is the tab's label. An empty string
|
|
37
|
+
* silences that cue.
|
|
38
|
+
*/
|
|
39
|
+
export interface NarrationCues {
|
|
40
|
+
danger: string;
|
|
41
|
+
info: string;
|
|
42
|
+
note: string;
|
|
43
|
+
section: string;
|
|
44
|
+
step: string;
|
|
45
|
+
success: string;
|
|
46
|
+
tab: string;
|
|
47
|
+
tip: string;
|
|
48
|
+
warning: string;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* A run of text read as one unit: a paragraph, heading, list item, or any
|
|
52
|
+
* other block. `nodes` are the text nodes it was read from; `nodeOf[i]` and
|
|
53
|
+
* `offsetOf[i]` locate character `i` of `text` in them, so a sentence's
|
|
54
|
+
* `[start, end)` maps back to a DOM range for highlighting.
|
|
55
|
+
*/
|
|
56
|
+
export interface NarrationBlock<N> {
|
|
57
|
+
nodeOf: number[];
|
|
58
|
+
nodes: N[];
|
|
59
|
+
offsetOf: number[];
|
|
60
|
+
text: string;
|
|
61
|
+
}
|
|
62
|
+
/** One step of the reading order: a spoken cue, or a block of page text. */
|
|
63
|
+
export type NarrationItem = {
|
|
64
|
+
block: number;
|
|
65
|
+
kind: "block";
|
|
66
|
+
} | {
|
|
67
|
+
kind: "cue";
|
|
68
|
+
text: string;
|
|
69
|
+
};
|
|
70
|
+
/** What {@link extractNarration} reads from a page. */
|
|
71
|
+
export interface NarrationExtract<N> {
|
|
72
|
+
blocks: NarrationBlock<N>[];
|
|
73
|
+
items: NarrationItem[];
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* One spoken unit. A sentence carries its block and its `[start, end)` in
|
|
77
|
+
* that block's text; a cue carries `block: null`. `text` is what is spoken.
|
|
78
|
+
*/
|
|
79
|
+
export interface NarrationSegment {
|
|
80
|
+
block: number | null;
|
|
81
|
+
end: number;
|
|
82
|
+
start: number;
|
|
83
|
+
text: string;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* The per-page manifest `blume build` writes for generated narration. The
|
|
87
|
+
* player aligns `blocks` (the build's block texts) with the live page by
|
|
88
|
+
* text, then plays one clip per segment. A sentence names its block and range;
|
|
89
|
+
* a cue carries its spoken `text` instead.
|
|
90
|
+
*/
|
|
91
|
+
export interface NarrationManifest {
|
|
92
|
+
blocks: string[];
|
|
93
|
+
segments: NarrationManifestSegment[];
|
|
94
|
+
version: 1;
|
|
95
|
+
}
|
|
96
|
+
/** One clip of a {@link NarrationManifest}: a sentence or a cue. */
|
|
97
|
+
export type NarrationManifestSegment = {
|
|
98
|
+
audio: string;
|
|
99
|
+
block: number;
|
|
100
|
+
end: number;
|
|
101
|
+
start: number;
|
|
102
|
+
} | {
|
|
103
|
+
audio: string;
|
|
104
|
+
text: string;
|
|
105
|
+
};
|
|
106
|
+
/**
|
|
107
|
+
* A page needs at least this many spoken characters (title and description
|
|
108
|
+
* included) to offer narration: roughly 50 English words. Shorter pages, and
|
|
109
|
+
* pages that are mostly code, tables, or API fields, get no player.
|
|
110
|
+
*/
|
|
111
|
+
export declare const NARRATION_MIN_CHARS = 280;
|
|
112
|
+
/**
|
|
113
|
+
* Sentences longer than this are split at a clause, then a word boundary.
|
|
114
|
+
* Browser speech engines drop an utterance that runs past about 15 seconds,
|
|
115
|
+
* and shorter clips also keep the highlight moving.
|
|
116
|
+
*/
|
|
117
|
+
export declare const NARRATION_MAX_SEGMENT_CHARS = 220;
|
|
118
|
+
/** The attribute that keeps an element (and everything in it) out of narration. */
|
|
119
|
+
export declare const NARRATION_SKIP_ATTRIBUTE = "data-blume-narration";
|
|
120
|
+
/**
|
|
121
|
+
* Walk `root` and return its reading order: each block of text, with the
|
|
122
|
+
* cues that introduce callouts, steps, tabs, and collapsible sections.
|
|
123
|
+
* Whitespace collapses to single spaces, as it renders.
|
|
124
|
+
*/
|
|
125
|
+
export declare const extractNarration: <N>(root: N, tree: NarrationTree<N>, cues: NarrationCues) => NarrationExtract<N>;
|
|
126
|
+
/**
|
|
127
|
+
* Split an extract into spoken segments: a cue as it is, and each block into
|
|
128
|
+
* its sentences for `lang` (long ones broken further, see
|
|
129
|
+
* {@link NARRATION_MAX_SEGMENT_CHARS}).
|
|
130
|
+
*/
|
|
131
|
+
export declare const segmentNarration: <N>(extract: NarrationExtract<N>, lang: string, max?: number) => NarrationSegment[];
|
|
132
|
+
/** How many characters the page's blocks will speak, cues excluded. */
|
|
133
|
+
export declare const narrationLength: <N>(extract: NarrationExtract<N>) => number;
|
|
134
|
+
/** Whether a page has enough prose to offer narration. */
|
|
135
|
+
export declare const isNarratable: <N>(extract: NarrationExtract<N>) => boolean;
|
|
136
|
+
/**
|
|
137
|
+
* Characters read per second at 1x: about 170 words a minute for
|
|
138
|
+
* space-separated scripts, and a slower character rate where a character is a
|
|
139
|
+
* word or more. Estimates only; neither engine reports durations up front.
|
|
140
|
+
*/
|
|
141
|
+
export declare const narrationCharsPerSecond: (lang: string) => number;
|
|
142
|
+
/** The page's estimated listening time at 1x, in whole minutes (at least 1). */
|
|
143
|
+
export declare const narrationMinutes: (chars: number, lang: string) => number;
|
|
144
|
+
/**
|
|
145
|
+
* Map each manifest block onto the live page's blocks by exact text, in
|
|
146
|
+
* order, skipping page blocks the build didn't see (a script may have added
|
|
147
|
+
* some). A manifest block with no match maps to `-1`: its sentences still
|
|
148
|
+
* play, without a highlight.
|
|
149
|
+
*/
|
|
150
|
+
export declare const alignBlocks: (manifestBlocks: readonly string[], pageBlocks: readonly string[]) => number[];
|
|
151
|
+
/** Whether a value (the player's `data-cues` JSON) is a full set of cues. */
|
|
152
|
+
export declare const isNarrationCues: (value: unknown) => value is NarrationCues;
|
|
153
|
+
/** Whether a fetched manifest has the shape the player plays. */
|
|
154
|
+
export declare const isNarrationManifest: (value: unknown) => value is NarrationManifest;
|
|
@@ -45,6 +45,12 @@ export interface ApiOperationRef {
|
|
|
45
45
|
deprecated: boolean;
|
|
46
46
|
/** The channel the operation acts on (AsyncAPI only). */
|
|
47
47
|
channelId?: string;
|
|
48
|
+
/**
|
|
49
|
+
* An OpenAPI 3.1 webhook: a request the API sends to the reader's endpoint
|
|
50
|
+
* rather than one it serves. `path` then holds the webhook's name, the key
|
|
51
|
+
* it has under the document's `webhooks`.
|
|
52
|
+
*/
|
|
53
|
+
webhook?: true;
|
|
48
54
|
}
|
|
49
55
|
/**
|
|
50
56
|
* A tag/section: the spec's declared tags in their declared order, then any
|
|
@@ -76,8 +82,8 @@ export interface ApiSpecData {
|
|
|
76
82
|
/** Operations keyed by {@link ApiOperationRef.key}. */
|
|
77
83
|
operations: Record<string, ApiOperationRef>;
|
|
78
84
|
tags: ApiTagRef[];
|
|
79
|
-
/** Code-sample languages to render per operation. */
|
|
80
|
-
codeSamples: string[];
|
|
85
|
+
/** Code-sample languages to render per operation; `false` for none. */
|
|
86
|
+
codeSamples: string[] | false;
|
|
81
87
|
/** Whether nested schema rows start expanded. */
|
|
82
88
|
expandSchemas: boolean;
|
|
83
89
|
/**
|
|
@@ -162,10 +168,10 @@ export interface ExtractedOperations extends CollectedOperations {
|
|
|
162
168
|
export declare const operationCollector: (baseRoute: string, tagMeta: ReadonlyMap<string, string>) => OperationCollector;
|
|
163
169
|
/**
|
|
164
170
|
* Flatten a 3.1 document into a route-mapped operation list and its ordered
|
|
165
|
-
* tags. Operations inherit the first tag they declare; keys
|
|
166
|
-
* a repeated `operationId` still yields distinct routes.
|
|
167
|
-
* anything skipped (a `$ref` path item
|
|
168
|
-
* aren't silent.
|
|
171
|
+
* tags, webhooks included. Operations inherit the first tag they declare; keys
|
|
172
|
+
* are de-duplicated so a repeated `operationId` still yields distinct routes.
|
|
173
|
+
* `warnings` reports anything skipped (a `$ref` path item), so missing
|
|
174
|
+
* operations aren't silent.
|
|
169
175
|
*/
|
|
170
176
|
export declare const extractOperations: (document: ApiDocument, baseRoute: string) => ExtractedOperations;
|
|
171
177
|
/** Resolve the operation object for a ref out of its (OpenAPI) document. */
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import type { JsonValue } from "../core/adapter.ts";
|
|
3
|
+
/**
|
|
4
|
+
* OpenAPI Overlays: the OpenAPI Initiative's format for changing an API
|
|
5
|
+
* description without editing it — an ordered list of actions, each an RFC
|
|
6
|
+
* 9535 JSONPath `target` with an `update` to merge in, a `copy` of another
|
|
7
|
+
* node to merge in, or `remove`. A spec generated by another tool or owned by
|
|
8
|
+
* another team can then carry docs-only changes (better descriptions, hidden
|
|
9
|
+
* internal operations, a public server URL) in a file of its own.
|
|
10
|
+
*
|
|
11
|
+
* Implements Overlay Specification 1.0 and 1.1 over `jsonpath-rfc9535`, which
|
|
12
|
+
* passes the JSONPath compliance suite in full, as the spec requires. The
|
|
13
|
+
* documents here are already parsed; `parse.ts` reads the files.
|
|
14
|
+
*/
|
|
15
|
+
/** An overlay document or action that doesn't follow the spec. */
|
|
16
|
+
export declare class OverlayError extends Error {
|
|
17
|
+
constructor(message: string);
|
|
18
|
+
}
|
|
19
|
+
/** An object node, the only kind that holds named properties. */
|
|
20
|
+
interface JsonObject {
|
|
21
|
+
[key: string]: JsonValue;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* A parsed YAML or JSON mapping, as the document an overlay acts on: the
|
|
25
|
+
* parser's own types say nothing of JSON, but what it parses is JSON.
|
|
26
|
+
*/
|
|
27
|
+
export declare const isJsonObject: <Value>(value: Value) => value is Value & JsonObject;
|
|
28
|
+
declare const overlaySchema: z.ZodObject<{
|
|
29
|
+
actions: z.ZodArray<z.ZodObject<{
|
|
30
|
+
copy: z.ZodOptional<z.ZodString>;
|
|
31
|
+
description: z.ZodOptional<z.ZodString>;
|
|
32
|
+
remove: z.ZodDefault<z.ZodBoolean>;
|
|
33
|
+
target: z.ZodString;
|
|
34
|
+
update: z.ZodOptional<z.ZodJSONSchema>;
|
|
35
|
+
}, z.core.$loose>>;
|
|
36
|
+
extends: z.ZodOptional<z.ZodString>;
|
|
37
|
+
info: z.ZodObject<{
|
|
38
|
+
title: z.ZodString;
|
|
39
|
+
version: z.ZodString;
|
|
40
|
+
}, z.core.$loose>;
|
|
41
|
+
overlay: z.ZodString;
|
|
42
|
+
}, z.core.$loose>;
|
|
43
|
+
/** A validated overlay document. */
|
|
44
|
+
export type OverlayDocument = z.output<typeof overlaySchema>;
|
|
45
|
+
/** Validate a parsed overlay document, naming the file in any error. */
|
|
46
|
+
export declare const overlayDocument: <Value>(value: Value, name: string) => OverlayDocument;
|
|
47
|
+
/**
|
|
48
|
+
* Apply an overlay to a parsed document, in place and in action order: each
|
|
49
|
+
* action sees the result of the one before. A target that matches nothing
|
|
50
|
+
* changes nothing. Throws an {@link OverlayError} naming the overlay file and
|
|
51
|
+
* the action that failed.
|
|
52
|
+
*/
|
|
53
|
+
export declare const applyOverlay: (document: JsonValue, overlay: OverlayDocument, name: string) => void;
|
|
54
|
+
export {};
|