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
|
@@ -2,12 +2,15 @@
|
|
|
2
2
|
import IconSprite from "./IconSprite.astro";
|
|
3
3
|
import { createIconSprite } from "../icon-sprite.ts";
|
|
4
4
|
import data from "blume:data";
|
|
5
|
+
import { relatedLinks } from "../../core/related.ts";
|
|
6
|
+
import type { RelatedEntry } from "../../core/related.ts";
|
|
5
7
|
import { EN_UI } from "../../core/i18n-ui.ts";
|
|
6
8
|
import type { UIStrings } from "../../core/i18n-ui.ts";
|
|
7
9
|
import { resolveDateFormatOptions } from "../../core/date-format.ts";
|
|
8
10
|
import type { ResolvedDateFormat } from "../../core/schema.ts";
|
|
9
11
|
import type { OpenInChatProvider } from "../../core/open-in-chat.ts";
|
|
10
12
|
import type {
|
|
13
|
+
BlumeBanner,
|
|
11
14
|
BlumeClientData,
|
|
12
15
|
BlumeDataConfig,
|
|
13
16
|
BlumeFavicon,
|
|
@@ -40,14 +43,28 @@ import {
|
|
|
40
43
|
import { buildStructuredData, toIso } from "../../seo/jsonld.ts";
|
|
41
44
|
import { normalizeXHandle } from "../../seo/x-handle.ts";
|
|
42
45
|
import { withBase, withMountedBase } from "../islands/base-path.ts";
|
|
46
|
+
import { routeSetFor } from "../../core/locale-links.ts";
|
|
47
|
+
import {
|
|
48
|
+
KEYWORDS_ATTRIBUTE,
|
|
49
|
+
pagefindRanking,
|
|
50
|
+
} from "../../search/pagefind-ranking.ts";
|
|
51
|
+
import {
|
|
52
|
+
browserLanguageTargets,
|
|
53
|
+
LOCALE_REDIRECT_SCRIPT,
|
|
54
|
+
} from "./locale-redirect.ts";
|
|
43
55
|
import { isExternalUrl } from "../../core/base-path.ts";
|
|
44
56
|
import { NEW_TAB_HINT_ID, newTabAttrs } from "../../core/new-tab.ts";
|
|
45
57
|
import Analytics from "./Analytics.astro";
|
|
58
|
+
import ConsentBanner from "./ConsentBanner.astro";
|
|
59
|
+
import ConsentHead from "./ConsentHead.astro";
|
|
46
60
|
import WebMcp from "./WebMcp.astro";
|
|
47
61
|
import Banner from "./Banner.astro";
|
|
48
62
|
import Breadcrumbs from "./Breadcrumbs.astro";
|
|
49
63
|
import Empty from "./Empty.astro";
|
|
64
|
+
import Directory from "./Directory.astro";
|
|
65
|
+
import RelatedPages from "./RelatedPages.astro";
|
|
50
66
|
import DiscoveryLinks from "./DiscoveryLinks.astro";
|
|
67
|
+
import DrawerSwitchers from "./DrawerSwitchers.astro";
|
|
51
68
|
import Favicon from "./Favicon.astro";
|
|
52
69
|
import Fonts from "./Fonts.astro";
|
|
53
70
|
import {
|
|
@@ -62,6 +79,7 @@ import {
|
|
|
62
79
|
currentTabForRoute,
|
|
63
80
|
findBreadcrumbs,
|
|
64
81
|
flattenPages,
|
|
82
|
+
directoryGroupForRoute,
|
|
65
83
|
getPagination,
|
|
66
84
|
navGroupIds,
|
|
67
85
|
sidebarForRoute,
|
|
@@ -69,10 +87,14 @@ import {
|
|
|
69
87
|
import NavTabMenu from "./NavTabMenu.astro";
|
|
70
88
|
import NavTree from "./NavTree.astro";
|
|
71
89
|
import { resolveSlot } from "./overrides.ts";
|
|
90
|
+
import { pageModeLayout } from "../../core/page-modes.ts";
|
|
91
|
+
import type { PageMode } from "../../core/page-modes.ts";
|
|
72
92
|
import { pageDirection, pageLocale } from "./page-locale.ts";
|
|
73
93
|
import { searchLocaleFor } from "./search-locale.ts";
|
|
74
94
|
import PageActions from "./PageActions.astro";
|
|
75
95
|
import PageFeedback from "./PageFeedback.astro";
|
|
96
|
+
import SiteFooter from "./SiteFooter.astro";
|
|
97
|
+
import SiteMetatags from "./SiteMetatags.astro";
|
|
76
98
|
import Pagination from "./Pagination.astro";
|
|
77
99
|
import TableOfContents from "./TableOfContents.astro";
|
|
78
100
|
import VersionBanner from "./VersionBanner.astro";
|
|
@@ -89,12 +111,7 @@ interface Props {
|
|
|
89
111
|
} | null;
|
|
90
112
|
favicon?: BlumeFavicon | null;
|
|
91
113
|
appleIcon?: BlumeFavicon | null;
|
|
92
|
-
banner?:
|
|
93
|
-
content: string;
|
|
94
|
-
link?: { text: string; href: string };
|
|
95
|
-
dismissible: boolean;
|
|
96
|
-
key: string;
|
|
97
|
-
} | null;
|
|
114
|
+
banner?: BlumeBanner | null;
|
|
98
115
|
analytics?: BlumeDataConfig["analytics"] | null;
|
|
99
116
|
navigation: Navigation;
|
|
100
117
|
mcp?: { name: string; route: string } | null;
|
|
@@ -129,6 +146,17 @@ interface Props {
|
|
|
129
146
|
assistantEnabled?: boolean;
|
|
130
147
|
/** Show the "Was this page helpful?" rating below the content. */
|
|
131
148
|
feedback?: boolean;
|
|
149
|
+
/** Ask for a written comment after the rating. */
|
|
150
|
+
feedbackComments?: boolean;
|
|
151
|
+
/** Show the previous/next links at the foot of the page. */
|
|
152
|
+
pagination?: boolean;
|
|
153
|
+
/** The page's `related` frontmatter: pages to suggest at its foot. */
|
|
154
|
+
related?: RelatedEntry[] | false;
|
|
155
|
+
/**
|
|
156
|
+
* The page's `search.boost` and `search.keywords`, for Pagefind, which
|
|
157
|
+
* reads them from the built page (see search/pagefind-ranking.ts).
|
|
158
|
+
*/
|
|
159
|
+
search?: { boost?: number; keywords?: string[] };
|
|
132
160
|
exportPdf?: boolean;
|
|
133
161
|
exportEpub?: boolean;
|
|
134
162
|
/**
|
|
@@ -149,6 +177,14 @@ interface Props {
|
|
|
149
177
|
discovery?: DiscoveryHeadLinks | null;
|
|
150
178
|
siteUrl?: string | null;
|
|
151
179
|
pageType?: string;
|
|
180
|
+
/**
|
|
181
|
+
* The page pins `<RequestExample>`/`<ResponseExample>` to a column beside
|
|
182
|
+
* its content (see `markdown/api-rail.ts`): it takes the API layout, with
|
|
183
|
+
* no table of contents, and the article makes room for the column.
|
|
184
|
+
*/
|
|
185
|
+
apiRail?: boolean;
|
|
186
|
+
/** The page's `mode` frontmatter: what it shows around its content (see `core/page-modes.ts`). */
|
|
187
|
+
pageMode?: PageMode;
|
|
152
188
|
published?: string | Date | null;
|
|
153
189
|
lastModified?: string | null;
|
|
154
190
|
noindex?: boolean;
|
|
@@ -201,9 +237,10 @@ interface Props {
|
|
|
201
237
|
* User layout-slot overrides from `components.ts` (`defineComponents`). Each
|
|
202
238
|
* key replaces the matching built-in; unknown keys are ignored. Wired slots:
|
|
203
239
|
* `Header`, `Logo`, `Search`, `Sidebar`, `MobileNav`, `Breadcrumbs`,
|
|
204
|
-
* `TableOfContents`, `Pagination`, `Feedback`,
|
|
205
|
-
*
|
|
206
|
-
*
|
|
240
|
+
* `TableOfContents`, `Pagination`, `Feedback`, `Footer` (the built-in renders
|
|
241
|
+
* only when `footer` is configured), plus the content-injection slots
|
|
242
|
+
* `PageHeader` and `PageFooter` (which have no built-in and render only when
|
|
243
|
+
* overridden). `Layout` (replacing this whole component) is wired in
|
|
207
244
|
* the generated page templates, not here.
|
|
208
245
|
*/
|
|
209
246
|
layout?: Record<string, ComponentOverride>;
|
|
@@ -251,6 +288,10 @@ const {
|
|
|
251
288
|
editUrl,
|
|
252
289
|
assistantEnabled,
|
|
253
290
|
feedback = false,
|
|
291
|
+
feedbackComments = false,
|
|
292
|
+
pagination = true,
|
|
293
|
+
related,
|
|
294
|
+
search,
|
|
254
295
|
exportPdf,
|
|
255
296
|
exportEpub,
|
|
256
297
|
openInChat,
|
|
@@ -258,6 +299,8 @@ const {
|
|
|
258
299
|
discovery = data.config.discovery,
|
|
259
300
|
siteUrl,
|
|
260
301
|
pageType,
|
|
302
|
+
apiRail = false,
|
|
303
|
+
pageMode,
|
|
261
304
|
published,
|
|
262
305
|
lastModified,
|
|
263
306
|
noindex,
|
|
@@ -304,15 +347,21 @@ const PaginationSlot = resolveSlot(layout.Pagination, Pagination);
|
|
|
304
347
|
const MobileNavSlot = layout.MobileNav
|
|
305
348
|
? resolveSlot(layout.MobileNav, NavTree)
|
|
306
349
|
: null;
|
|
350
|
+
// The site footer renders nothing when `footer` is unset.
|
|
351
|
+
const FooterSlot = resolveSlot(layout.Footer, SiteFooter);
|
|
307
352
|
// Content-injection slots with no built-in: the `Empty` fallback renders nothing
|
|
308
353
|
// when unconfigured, so these are safe to render unconditionally.
|
|
309
|
-
const FooterSlot = resolveSlot(layout.Footer, Empty);
|
|
310
354
|
const PageHeaderSlot = resolveSlot(layout.PageHeader, Empty);
|
|
311
355
|
const PageFooterSlot = resolveSlot(layout.PageFooter, Empty);
|
|
312
356
|
// The "Was this page helpful?" rating (rendered only when `feedback` is on).
|
|
313
357
|
const FeedbackSlot = resolveSlot(layout.Feedback, PageFeedback);
|
|
314
358
|
|
|
315
359
|
const strings = ui ?? EN_UI;
|
|
360
|
+
// The consent adapter (`consent`), site-wide: analytics waits for the reader.
|
|
361
|
+
const consent = data.config.consent;
|
|
362
|
+
// Code blocks get an Ask button when the assistant is on (same default as the
|
|
363
|
+
// header's trigger).
|
|
364
|
+
const assistantOn = assistantEnabled ?? Boolean(data.config.assistant);
|
|
316
365
|
// Merge the groups this layout reads directly over the English defaults so a
|
|
317
366
|
// key missing from a translation (or from a not-yet-regenerated snapshot)
|
|
318
367
|
// still renders instead of coming out blank — the PageActions pattern.
|
|
@@ -328,11 +377,19 @@ const searchLocale = searchLocaleFor(data.config.i18n, locale);
|
|
|
328
377
|
// API operation pages own a two-column body (docs + request panel) and their own
|
|
329
378
|
// right rail, so they drop the table of contents and widen the content column.
|
|
330
379
|
const isApiOperation = pageType === "openapi-operation";
|
|
380
|
+
// A hand-written API page lays out like one: its example column replaces the
|
|
381
|
+
// table of contents.
|
|
382
|
+
const isApiLayout = isApiOperation || apiRail;
|
|
331
383
|
// A "bare" page (the changelog index) is a standalone landing: no sidebar, no
|
|
332
384
|
// TOC, just a wider centered column of content.
|
|
333
385
|
const isBare = contentLayout === "bare";
|
|
334
|
-
|
|
335
|
-
const
|
|
386
|
+
// The page's `mode`: which of the sidebar, TOC, and its own chrome it keeps.
|
|
387
|
+
const modeLayout = pageModeLayout(pageMode);
|
|
388
|
+
const showSidebar = !isBare && modeLayout.sidebar;
|
|
389
|
+
const showToc = !(isApiLayout || isBare) && modeLayout.toc;
|
|
390
|
+
// Breadcrumbs, page-end links, and the site footer; `custom` and `frame`
|
|
391
|
+
// pages bring their own.
|
|
392
|
+
const showChrome = modeLayout.chrome;
|
|
336
393
|
const tocHeadings =
|
|
337
394
|
toc.enabled && showToc
|
|
338
395
|
? headings.filter((h) => h.depth >= toc.minLevel && h.depth <= toc.maxLevel)
|
|
@@ -342,15 +399,21 @@ const tocHeadings =
|
|
|
342
399
|
const hasToc = tocHeadings.length > 0;
|
|
343
400
|
let gridClass =
|
|
344
401
|
"lg:grid-cols-[17.5rem_minmax(0,1fr)] xl:grid-cols-[17.5rem_minmax(0,1fr)_17.5rem]";
|
|
345
|
-
if (
|
|
402
|
+
if (!showSidebar) {
|
|
346
403
|
gridClass = "";
|
|
347
|
-
} else if (
|
|
404
|
+
} else if (!showToc) {
|
|
348
405
|
gridClass = "lg:grid-cols-[17.5rem_minmax(0,1fr)]";
|
|
349
406
|
}
|
|
350
407
|
let articleClass = "prose mx-auto max-w-content";
|
|
351
|
-
if (isBare) {
|
|
408
|
+
if (isBare || modeLayout.width === "center") {
|
|
352
409
|
articleClass = "prose mx-auto max-w-[54rem]";
|
|
353
|
-
} else if (
|
|
410
|
+
} else if (apiRail) {
|
|
411
|
+
// Room at `xl` for the example column (28rem plus the 2.5rem gap an
|
|
412
|
+
// operation page keeps), which `ApiRail.astro` positions in it, and a
|
|
413
|
+
// viewport's height so the column's capped panel never overhangs the page.
|
|
414
|
+
articleClass =
|
|
415
|
+
"prose max-w-none xl:relative xl:min-h-[calc(100dvh-7.25rem)] xl:pe-[30.5rem]";
|
|
416
|
+
} else if (isApiOperation || modeLayout.width === "full") {
|
|
354
417
|
articleClass = "prose max-w-none";
|
|
355
418
|
}
|
|
356
419
|
// A page titled like the site (a home page often is) takes the bare site title
|
|
@@ -435,6 +498,17 @@ const activeTab = currentTabForRoute(
|
|
|
435
498
|
navigation.root
|
|
436
499
|
);
|
|
437
500
|
const crumbs = findBreadcrumbs(sidebar, page.route);
|
|
501
|
+
// A group's own page lists the group's pages below its content when the
|
|
502
|
+
// group asks for a directory. Looked up in the full tree: a tab's own page
|
|
503
|
+
// is not in its scoped sidebar.
|
|
504
|
+
const directoryGroup = directoryGroupForRoute(navigation.sidebar, page.route);
|
|
505
|
+
// The page's `related` links, resolved to served routes in this locale.
|
|
506
|
+
const relatedItems = relatedLinks(related, {
|
|
507
|
+
basePath: data.config.basePath,
|
|
508
|
+
i18n: data.config.i18n,
|
|
509
|
+
locale,
|
|
510
|
+
routes: data.routes,
|
|
511
|
+
});
|
|
438
512
|
const { prev, next } = getPagination(flattenPages(sidebar), page.route);
|
|
439
513
|
|
|
440
514
|
// Structured data is skipped when disabled or for pages we ask crawlers not to
|
|
@@ -466,6 +540,27 @@ const bannerKey = banner?.dismissible ? banner.key : null;
|
|
|
466
540
|
// Start the page's icon sprite before anything renders an icon (see
|
|
467
541
|
// icon-sprite.ts); <IconSprite /> at the end of the body emits it.
|
|
468
542
|
createIconSprite(Astro.locals);
|
|
543
|
+
|
|
544
|
+
const pagefind = pagefindRanking(search ?? {});
|
|
545
|
+
|
|
546
|
+
// A visitor landing on the default language's home page goes to their
|
|
547
|
+
// browser's language (`i18n.routeByBrowserLanguage`, see locale-redirect.ts).
|
|
548
|
+
const localeTargets = browserLanguageTargets({
|
|
549
|
+
basePath: data.config.basePath,
|
|
550
|
+
i18n: data.config.i18n,
|
|
551
|
+
route: page.route,
|
|
552
|
+
routes: routeSetFor(data.routes),
|
|
553
|
+
});
|
|
554
|
+
const localeRedirect = localeTargets
|
|
555
|
+
? JSON.stringify(
|
|
556
|
+
Object.fromEntries(
|
|
557
|
+
Object.entries(localeTargets).map(([code, path]) => [
|
|
558
|
+
code,
|
|
559
|
+
withMountedBase(path),
|
|
560
|
+
])
|
|
561
|
+
)
|
|
562
|
+
)
|
|
563
|
+
: null;
|
|
469
564
|
---
|
|
470
565
|
|
|
471
566
|
<!doctype html>
|
|
@@ -473,6 +568,16 @@ createIconSprite(Astro.locals);
|
|
|
473
568
|
<head>
|
|
474
569
|
<meta charset="utf-8" />
|
|
475
570
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
571
|
+
{
|
|
572
|
+
localeRedirect && (
|
|
573
|
+
<script
|
|
574
|
+
data-default={data.config.i18n?.defaultLocale}
|
|
575
|
+
data-targets={localeRedirect}
|
|
576
|
+
is:inline
|
|
577
|
+
set:html={LOCALE_REDIRECT_SCRIPT}
|
|
578
|
+
/>
|
|
579
|
+
)
|
|
580
|
+
}
|
|
476
581
|
{/* Client-side navigation: same-origin link clicks swap the DOM in place
|
|
477
582
|
instead of tearing the document down, so no browser ever paints a blank
|
|
478
583
|
frame between pages (Firefox has no cross-document paint holding and
|
|
@@ -537,6 +642,7 @@ createIconSprite(Astro.locals);
|
|
|
537
642
|
{description && <meta name="twitter:description" content={description} />}
|
|
538
643
|
{xSite && <meta name="twitter:site" content={xSite} />}
|
|
539
644
|
{xCreator && <meta name="twitter:creator" content={xCreator} />}
|
|
645
|
+
<SiteMetatags tags={data.config.metatags} />
|
|
540
646
|
{
|
|
541
647
|
feeds?.map((feed) => (
|
|
542
648
|
<link
|
|
@@ -563,16 +669,21 @@ createIconSprite(Astro.locals);
|
|
|
563
669
|
)
|
|
564
670
|
}
|
|
565
671
|
<script data-mode={themeMode} is:inline set:html={THEME_INIT_SCRIPT} />
|
|
672
|
+
{consent && <ConsentHead consent={consent} />}
|
|
566
673
|
<Analytics analytics={analytics} />
|
|
567
674
|
</head>
|
|
568
675
|
<body
|
|
569
676
|
class="bg-background font-sans text-foreground antialiased"
|
|
677
|
+
data-blume-code-ask={assistantOn ? "" : undefined}
|
|
570
678
|
data-blume-code-copy=""
|
|
571
679
|
data-blume-code-wrap={codeWrap ? "" : undefined}
|
|
572
680
|
data-blume-image-zoom={imageZoom ? "" : undefined}
|
|
681
|
+
data-i18n-ask-code={assistantOn ? actionStrings.askAboutCode : undefined}
|
|
573
682
|
data-i18n-copied={actionStrings.copied}
|
|
574
683
|
data-i18n-copy-code={actionStrings.copyCode}
|
|
575
684
|
data-i18n-diagram-error={contentStrings.diagramError}
|
|
685
|
+
data-i18n-show-less={contentStrings.showLess}
|
|
686
|
+
data-i18n-show-more={contentStrings.showMore}
|
|
576
687
|
>
|
|
577
688
|
<a
|
|
578
689
|
class="absolute start-[-999px] top-0 z-[100] bg-accent px-4 py-2 text-accent-foreground focus:start-0"
|
|
@@ -616,6 +727,13 @@ createIconSprite(Astro.locals);
|
|
|
616
727
|
!showSidebar && "lg:hidden",
|
|
617
728
|
]}
|
|
618
729
|
>
|
|
730
|
+
<DrawerSwitchers
|
|
731
|
+
localeSwitch={localeSwitch}
|
|
732
|
+
route={page.route}
|
|
733
|
+
selectors={navigation.selectors}
|
|
734
|
+
switcherStrings={strings.languageSwitcher}
|
|
735
|
+
versionSelector={versionSelector}
|
|
736
|
+
/>
|
|
619
737
|
{
|
|
620
738
|
// Pinned links (blog, changelog, contact…) sit above every section on
|
|
621
739
|
// all breakpoints, outside the tab-scoped sidebar so they never change
|
|
@@ -740,11 +858,16 @@ createIconSprite(Astro.locals);
|
|
|
740
858
|
</aside>
|
|
741
859
|
<script is:inline set:html={SIDEBAR_SCROLL_INIT_SCRIPT} />
|
|
742
860
|
<main class="px-6 pt-6 pb-10 lg:px-8 xl:px-10" id="blume-content">
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
861
|
+
{
|
|
862
|
+
showChrome && (
|
|
863
|
+
<BreadcrumbsSlot
|
|
864
|
+
crumbs={crumbs}
|
|
865
|
+
strings={navStrings}
|
|
866
|
+
centered={modeLayout.width === "center"}
|
|
867
|
+
wide={isApiLayout || modeLayout.width === "full"}
|
|
868
|
+
/>
|
|
869
|
+
)
|
|
870
|
+
}
|
|
748
871
|
{
|
|
749
872
|
hasToc && (
|
|
750
873
|
<TableOfContentsSlot
|
|
@@ -764,14 +887,33 @@ createIconSprite(Astro.locals);
|
|
|
764
887
|
<article
|
|
765
888
|
class:list={[articleClass]}
|
|
766
889
|
data-pagefind-body={indexable && !isBare ? "" : undefined}
|
|
890
|
+
data-pagefind-weight={pagefind.weight}
|
|
767
891
|
dir={contentDir}
|
|
768
892
|
lang={articleLang}
|
|
769
893
|
>
|
|
894
|
+
{pagefind.keywords && (
|
|
895
|
+
<span
|
|
896
|
+
data-pagefind-index-attrs={KEYWORDS_ATTRIBUTE}
|
|
897
|
+
{...{ [KEYWORDS_ATTRIBUTE]: pagefind.keywords }}
|
|
898
|
+
hidden
|
|
899
|
+
/>
|
|
900
|
+
)}
|
|
770
901
|
<slot />
|
|
771
902
|
</article>
|
|
772
903
|
{
|
|
773
|
-
!isApiOperation && (
|
|
774
|
-
|
|
904
|
+
!isApiOperation && showChrome && (
|
|
905
|
+
<div
|
|
906
|
+
class:list={[
|
|
907
|
+
// Aligned with the content column, not centered under the
|
|
908
|
+
// prose measure: a rail page's, a wide page's, or a center
|
|
909
|
+
// page's wider one.
|
|
910
|
+
apiRail && "xl:pe-[30.5rem]",
|
|
911
|
+
(apiRail || modeLayout.width === "full") && "[&>*]:max-w-none",
|
|
912
|
+
modeLayout.width === "center" && "[&>*]:max-w-[54rem]",
|
|
913
|
+
]}
|
|
914
|
+
>
|
|
915
|
+
{directoryGroup && <Directory group={directoryGroup} />}
|
|
916
|
+
<RelatedPages links={relatedItems} title={strings.page.related} />
|
|
775
917
|
<PageFooterSlot
|
|
776
918
|
headings={tocHeadings}
|
|
777
919
|
page={page}
|
|
@@ -782,9 +924,16 @@ createIconSprite(Astro.locals);
|
|
|
782
924
|
{strings.page.lastUpdated} {formattedLastModified}
|
|
783
925
|
</p>
|
|
784
926
|
)}
|
|
785
|
-
{feedback &&
|
|
786
|
-
|
|
787
|
-
|
|
927
|
+
{feedback && (
|
|
928
|
+
<FeedbackSlot
|
|
929
|
+
comments={feedbackComments}
|
|
930
|
+
strings={strings.feedback}
|
|
931
|
+
/>
|
|
932
|
+
)}
|
|
933
|
+
{pagination && (
|
|
934
|
+
<PaginationSlot next={next} prev={prev} strings={strings.page} />
|
|
935
|
+
)}
|
|
936
|
+
</div>
|
|
788
937
|
)
|
|
789
938
|
}
|
|
790
939
|
</main>
|
|
@@ -817,7 +966,17 @@ createIconSprite(Astro.locals);
|
|
|
817
966
|
)
|
|
818
967
|
}
|
|
819
968
|
</div>
|
|
820
|
-
|
|
969
|
+
{
|
|
970
|
+
showChrome && (
|
|
971
|
+
<FooterSlot
|
|
972
|
+
footer={data.config.footer}
|
|
973
|
+
locale={locale}
|
|
974
|
+
navigation={navigation}
|
|
975
|
+
site={site}
|
|
976
|
+
ui={strings}
|
|
977
|
+
/>
|
|
978
|
+
)
|
|
979
|
+
}
|
|
821
980
|
{
|
|
822
981
|
clientDataJson && (
|
|
823
982
|
<script
|
|
@@ -954,6 +1113,24 @@ createIconSprite(Astro.locals);
|
|
|
954
1113
|
const copiedLabel =
|
|
955
1114
|
document.body.getAttribute("data-i18n-copied") || "Copied!";
|
|
956
1115
|
|
|
1116
|
+
// A block's code as the reader sees it. Twoslash nests each hover
|
|
1117
|
+
// popup's type signature and docs inside the <code>; its textContent
|
|
1118
|
+
// verbatim would interleave them with the source, so the popups are
|
|
1119
|
+
// stripped from a clone first.
|
|
1120
|
+
const codeText = (pre: Element | null): string => {
|
|
1121
|
+
const code = pre?.querySelector("code");
|
|
1122
|
+
if (!code?.querySelector(".twoslash-popup-container")) {
|
|
1123
|
+
return code?.textContent ?? "";
|
|
1124
|
+
}
|
|
1125
|
+
const clone = code.cloneNode(true) as HTMLElement;
|
|
1126
|
+
for (const popup of clone.querySelectorAll(
|
|
1127
|
+
".twoslash-popup-container"
|
|
1128
|
+
)) {
|
|
1129
|
+
popup.remove();
|
|
1130
|
+
}
|
|
1131
|
+
return clone.textContent ?? "";
|
|
1132
|
+
};
|
|
1133
|
+
|
|
957
1134
|
// `placement` is the extra class set for an overlay button (empty for
|
|
958
1135
|
// one hosted by a tab strip); `readPre` resolves the block to copy at
|
|
959
1136
|
// click time, since a strip button follows the active panel.
|
|
@@ -989,27 +1166,91 @@ createIconSprite(Astro.locals);
|
|
|
989
1166
|
};
|
|
990
1167
|
const flash = createCopyFlash(setChecked, copiedLabel);
|
|
991
1168
|
button.addEventListener("click", async () => {
|
|
992
|
-
|
|
993
|
-
let text = code?.textContent ?? "";
|
|
994
|
-
// Twoslash nests each hover popup's type signature and docs inside
|
|
995
|
-
// the <code>; copying textContent verbatim would interleave them
|
|
996
|
-
// with the source. Strip the popups from a clone first.
|
|
997
|
-
if (code?.querySelector(".twoslash-popup-container")) {
|
|
998
|
-
const clone = code.cloneNode(true) as HTMLElement;
|
|
999
|
-
for (const popup of clone.querySelectorAll(
|
|
1000
|
-
".twoslash-popup-container"
|
|
1001
|
-
)) {
|
|
1002
|
-
popup.remove();
|
|
1003
|
-
}
|
|
1004
|
-
text = clone.textContent ?? "";
|
|
1005
|
-
}
|
|
1006
|
-
if (await copyText(text)) {
|
|
1169
|
+
if (await copyText(codeText(readPre()))) {
|
|
1007
1170
|
flash();
|
|
1008
1171
|
}
|
|
1009
1172
|
});
|
|
1010
1173
|
return button;
|
|
1011
1174
|
};
|
|
1012
1175
|
|
|
1176
|
+
// A code block's Ask button, when the assistant is on: it opens the
|
|
1177
|
+
// panel with the block attached (see islands/code-question.ts).
|
|
1178
|
+
const askEnabled = document.body.hasAttribute("data-blume-code-ask");
|
|
1179
|
+
const askLabel =
|
|
1180
|
+
document.body.getAttribute("data-i18n-ask-code") ||
|
|
1181
|
+
"Ask about this code";
|
|
1182
|
+
const createAskButton = (
|
|
1183
|
+
placement: string,
|
|
1184
|
+
readPre: () => Element | null
|
|
1185
|
+
) => {
|
|
1186
|
+
const button = document.createElement("button");
|
|
1187
|
+
button.type = "button";
|
|
1188
|
+
button.className = `${buttonClass} ${idleClasses.join(" ")} ${placement}`;
|
|
1189
|
+
button.setAttribute("data-blume-ask", "");
|
|
1190
|
+
button.setAttribute("aria-label", askLabel);
|
|
1191
|
+
button.title = askLabel;
|
|
1192
|
+
button.innerHTML = svg("sparkles");
|
|
1193
|
+
button.addEventListener("click", () => {
|
|
1194
|
+
const pre = readPre();
|
|
1195
|
+
if (!(pre instanceof HTMLElement)) {
|
|
1196
|
+
return;
|
|
1197
|
+
}
|
|
1198
|
+
window.dispatchEvent(
|
|
1199
|
+
new CustomEvent("blume:open-assistant", {
|
|
1200
|
+
detail: {
|
|
1201
|
+
code: {
|
|
1202
|
+
language: pre.dataset.blumeLanguage ?? "",
|
|
1203
|
+
source: codeText(pre),
|
|
1204
|
+
title: pre.dataset.title,
|
|
1205
|
+
},
|
|
1206
|
+
},
|
|
1207
|
+
})
|
|
1208
|
+
);
|
|
1209
|
+
});
|
|
1210
|
+
return button;
|
|
1211
|
+
};
|
|
1212
|
+
|
|
1213
|
+
// An `expandable` block (```ts expandable) opens and closes from a
|
|
1214
|
+
// toggle under its code. The theme only collapses the block where
|
|
1215
|
+
// scripting runs, so the toggle is added on the same terms.
|
|
1216
|
+
const showMoreLabel =
|
|
1217
|
+
document.body.getAttribute("data-i18n-show-more") || "Show more";
|
|
1218
|
+
const showLessLabel =
|
|
1219
|
+
document.body.getAttribute("data-i18n-show-less") || "Show less";
|
|
1220
|
+
const expandToggle = (pre: HTMLElement) => {
|
|
1221
|
+
const button = document.createElement("button");
|
|
1222
|
+
button.type = "button";
|
|
1223
|
+
button.setAttribute("data-blume-code-expand", "");
|
|
1224
|
+
button.innerHTML = svg("chevron-down");
|
|
1225
|
+
const label = document.createElement("span");
|
|
1226
|
+
button.prepend(label);
|
|
1227
|
+
const setExpanded = (expanded: boolean) => {
|
|
1228
|
+
pre.toggleAttribute("data-expanded", expanded);
|
|
1229
|
+
button.setAttribute("aria-expanded", String(expanded));
|
|
1230
|
+
label.textContent = expanded ? showLessLabel : showMoreLabel;
|
|
1231
|
+
};
|
|
1232
|
+
setExpanded(false);
|
|
1233
|
+
button.addEventListener("click", () => {
|
|
1234
|
+
const expanded = !pre.hasAttribute("data-expanded");
|
|
1235
|
+
setExpanded(expanded);
|
|
1236
|
+
// Collapsing a long block can leave the reader below it; bring
|
|
1237
|
+
// its top back into view.
|
|
1238
|
+
if (!expanded && pre.getBoundingClientRect().top < 0) {
|
|
1239
|
+
pre.scrollIntoView({ block: "start" });
|
|
1240
|
+
}
|
|
1241
|
+
});
|
|
1242
|
+
return button;
|
|
1243
|
+
};
|
|
1244
|
+
if (matchMedia("(scripting: enabled)").matches) {
|
|
1245
|
+
for (const pre of document.querySelectorAll<HTMLElement>(
|
|
1246
|
+
".prose pre[data-expandable]"
|
|
1247
|
+
)) {
|
|
1248
|
+
if (!pre.querySelector(":scope > [data-blume-code-expand]")) {
|
|
1249
|
+
pre.appendChild(expandToggle(pre));
|
|
1250
|
+
}
|
|
1251
|
+
}
|
|
1252
|
+
}
|
|
1253
|
+
|
|
1013
1254
|
for (const pre of document.querySelectorAll(".prose pre")) {
|
|
1014
1255
|
if (pre.querySelector("[data-blume-copy]")) {
|
|
1015
1256
|
continue;
|
|
@@ -1021,6 +1262,11 @@ createIconSprite(Astro.locals);
|
|
|
1021
1262
|
}
|
|
1022
1263
|
const language = pre.getAttribute("data-language");
|
|
1023
1264
|
if (language) {
|
|
1265
|
+
// The fence's own language id, for a question about the code; the
|
|
1266
|
+
// attribute itself becomes the header's display label.
|
|
1267
|
+
if (pre instanceof HTMLElement) {
|
|
1268
|
+
pre.dataset.blumeLanguage = language;
|
|
1269
|
+
}
|
|
1024
1270
|
pre.setAttribute(
|
|
1025
1271
|
"data-language",
|
|
1026
1272
|
languageLabels[language.toLowerCase()] ?? language
|
|
@@ -1042,9 +1288,11 @@ createIconSprite(Astro.locals);
|
|
|
1042
1288
|
// One button per code switcher, reading whichever panel shows.
|
|
1043
1289
|
if (!actions.querySelector("[data-blume-copy]")) {
|
|
1044
1290
|
const tabs = actions.closest("blume-tabs");
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1291
|
+
const readActive = () => (tabs ? activeCodePre(tabs) : null);
|
|
1292
|
+
if (askEnabled) {
|
|
1293
|
+
actions.appendChild(createAskButton("", readActive));
|
|
1294
|
+
}
|
|
1295
|
+
actions.appendChild(createCopyButton("", readActive));
|
|
1048
1296
|
}
|
|
1049
1297
|
continue;
|
|
1050
1298
|
}
|
|
@@ -1053,6 +1301,13 @@ createIconSprite(Astro.locals);
|
|
|
1053
1301
|
const topClass = pre.closest("blume-tabs, .not-prose")
|
|
1054
1302
|
? "top-2.5"
|
|
1055
1303
|
: "top-2";
|
|
1304
|
+
if (askEnabled) {
|
|
1305
|
+
// Beside the copy button: its 0.75rem inset, its 1.875rem width,
|
|
1306
|
+
// and a quarter-rem gap.
|
|
1307
|
+
pre.appendChild(
|
|
1308
|
+
createAskButton(`absolute right-[2.875rem] z-[2] ${topClass}`, () => pre)
|
|
1309
|
+
);
|
|
1310
|
+
}
|
|
1056
1311
|
pre.appendChild(
|
|
1057
1312
|
createCopyButton(`${overlayClass} ${topClass}`, () => pre)
|
|
1058
1313
|
);
|
|
@@ -1123,6 +1378,14 @@ createIconSprite(Astro.locals);
|
|
|
1123
1378
|
}
|
|
1124
1379
|
</style>
|
|
1125
1380
|
<WebMcp />
|
|
1381
|
+
{
|
|
1382
|
+
consent?.kind === "native" && (
|
|
1383
|
+
<ConsentBanner
|
|
1384
|
+
policy={consent.options.policy}
|
|
1385
|
+
strings={strings.consent}
|
|
1386
|
+
/>
|
|
1387
|
+
)
|
|
1388
|
+
}
|
|
1126
1389
|
<IconSprite />
|
|
1127
1390
|
</body>
|
|
1128
1391
|
</html>
|