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
|
@@ -19,9 +19,15 @@ interface Props {
|
|
|
19
19
|
* overflow the viewport — pass `end` there.
|
|
20
20
|
*/
|
|
21
21
|
align?: "start" | "end";
|
|
22
|
+
/**
|
|
23
|
+
* `bar` (the default) for the header; `drawer` for the top of the nav
|
|
24
|
+
* drawer, where the trigger spans the drawer, always shows its label, and
|
|
25
|
+
* opens a panel as wide as itself, so nothing reaches past the drawer edge.
|
|
26
|
+
*/
|
|
27
|
+
variant?: "bar" | "drawer";
|
|
22
28
|
}
|
|
23
29
|
|
|
24
|
-
const { selector, route, align = "start" } = Astro.props;
|
|
30
|
+
const { selector, route, align = "start", variant = "bar" } = Astro.props;
|
|
25
31
|
|
|
26
32
|
// The active item is the deepest path the current route sits under (on a path
|
|
27
33
|
// boundary, so `/api` never claims `/api-reference` routes), falling back to
|
|
@@ -37,25 +43,37 @@ const active =
|
|
|
37
43
|
// version like "v2" or "Latest"): on a phone a bare chevron doesn't say what
|
|
38
44
|
// it switches. Longer product names still collapse to the icon there.
|
|
39
45
|
const label = active?.label ?? selector.label;
|
|
40
|
-
|
|
46
|
+
let labelClass: string | undefined;
|
|
47
|
+
if (variant === "drawer") {
|
|
48
|
+
labelClass = "flex-1 text-start";
|
|
49
|
+
} else if (label.length > 6) {
|
|
50
|
+
labelClass = "max-sm:hidden";
|
|
51
|
+
}
|
|
41
52
|
// The accessible name carries the visible active label too (WCAG 2.5.3,
|
|
42
53
|
// label in name), so a voice-control user can say "v2" to open it — the
|
|
43
54
|
// language switcher's pattern.
|
|
44
55
|
const summaryLabel =
|
|
45
56
|
label === selector.label ? selector.label : `${selector.label}: ${label}`;
|
|
46
57
|
|
|
47
|
-
|
|
48
|
-
|
|
58
|
+
// Borderless in the header, like the icon buttons and the language switcher;
|
|
59
|
+
// bordered in the drawer, where the trigger spans it.
|
|
60
|
+
const triggerClass =
|
|
61
|
+
variant === "bar"
|
|
62
|
+
? "inline-flex h-9 cursor-pointer items-center gap-1.5 rounded-full px-3 text-muted-foreground text-sm transition-colors hover:bg-muted hover:text-foreground group-open:bg-muted group-open:text-foreground"
|
|
63
|
+
: "inline-flex h-9 w-full cursor-pointer items-center gap-1.5 rounded-full border border-border bg-background px-3 text-muted-foreground text-sm transition-colors hover:border-foreground hover:text-foreground";
|
|
49
64
|
const menuRowClass =
|
|
50
65
|
"flex w-full items-start gap-2.5 rounded-md px-2 py-1.5 text-start text-muted-foreground text-sm transition-colors hover:bg-muted hover:text-foreground aria-[current=true]:text-foreground";
|
|
51
66
|
---
|
|
52
67
|
|
|
53
68
|
{
|
|
54
69
|
selector.items.length > 0 && (
|
|
55
|
-
<details
|
|
70
|
+
<details
|
|
71
|
+
class:list={["group relative", variant === "drawer" && "w-full"]}
|
|
72
|
+
data-blume-dropdown
|
|
73
|
+
>
|
|
56
74
|
<summary
|
|
57
75
|
aria-label={summaryLabel}
|
|
58
|
-
class={
|
|
76
|
+
class:list={[triggerClass, "list-none [&::-webkit-details-marker]:hidden"]}
|
|
59
77
|
>
|
|
60
78
|
{active?.icon && <Icon name={active.icon} size={16} />}
|
|
61
79
|
<span class={labelClass}>{label}</span>
|
|
@@ -66,7 +84,15 @@ const menuRowClass =
|
|
|
66
84
|
/>
|
|
67
85
|
</summary>
|
|
68
86
|
<div
|
|
69
|
-
class={
|
|
87
|
+
class:list={[
|
|
88
|
+
"absolute z-50 mt-2 rounded-blume border border-border bg-background p-1 shadow-xl",
|
|
89
|
+
variant === "drawer"
|
|
90
|
+
? "inset-x-0"
|
|
91
|
+
: [
|
|
92
|
+
"min-w-56 max-w-[calc(100vw-1rem)]",
|
|
93
|
+
align === "end" ? "end-0" : "start-0",
|
|
94
|
+
],
|
|
95
|
+
]}
|
|
70
96
|
data-blume-dropdown-panel
|
|
71
97
|
>
|
|
72
98
|
{selector.items.map((item) => (
|
|
@@ -1,14 +1,22 @@
|
|
|
1
1
|
---
|
|
2
|
+
import data from "blume:data";
|
|
3
|
+
|
|
2
4
|
import { EN_UI } from "../../core/i18n-ui.ts";
|
|
3
5
|
import type { UIStrings } from "../../core/i18n-ui.ts";
|
|
4
6
|
import Icon from "../Icon.astro";
|
|
7
|
+
import { COMMENT_MAX_LENGTH } from "./page-feedback.ts";
|
|
5
8
|
|
|
6
9
|
interface Props {
|
|
10
|
+
/** Ask for a written comment after the rating (`feedback.comments`). */
|
|
11
|
+
comments?: boolean;
|
|
7
12
|
/** Localized feedback labels. */
|
|
8
13
|
strings?: UIStrings["feedback"];
|
|
9
14
|
}
|
|
10
15
|
|
|
11
|
-
const { strings } = Astro.props;
|
|
16
|
+
const { comments = false, strings } = Astro.props;
|
|
17
|
+
// Answers go through analytics, so under a consent layer the rating waits,
|
|
18
|
+
// hidden, until the reader allows analytics (`page-feedback.ts` shows it).
|
|
19
|
+
const waitsForConsent = data.config.consent !== null;
|
|
12
20
|
// Merge over the English baseline per key (rather than `strings ?? …`) so a
|
|
13
21
|
// partial — or empty `{}` — strings object still resolves every label to a
|
|
14
22
|
// default, matching the pattern PageActions and Search use.
|
|
@@ -20,61 +28,58 @@ const buttonClass =
|
|
|
20
28
|
|
|
21
29
|
<section
|
|
22
30
|
aria-label={f.question}
|
|
23
|
-
class="mx-auto mt-12
|
|
31
|
+
class="mx-auto mt-12 max-w-content border-border border-t pt-6"
|
|
24
32
|
data-blume-page-feedback
|
|
33
|
+
hidden={waitsForConsent}
|
|
25
34
|
>
|
|
26
|
-
<
|
|
27
|
-
|
|
28
|
-
<
|
|
29
|
-
<
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
<
|
|
34
|
-
|
|
35
|
-
|
|
35
|
+
<div class="flex items-center justify-between gap-4">
|
|
36
|
+
<p class="text-muted-foreground text-sm">{f.question}</p>
|
|
37
|
+
<div class="flex items-center gap-2" data-feedback-actions>
|
|
38
|
+
<button class={buttonClass} data-feedback-value="yes" type="button">
|
|
39
|
+
<Icon name="thumbs-up" size={16} />
|
|
40
|
+
{f.yes}
|
|
41
|
+
</button>
|
|
42
|
+
<button class={buttonClass} data-feedback-value="no" type="button">
|
|
43
|
+
<Icon name="thumbs-down" size={16} />
|
|
44
|
+
{f.no}
|
|
45
|
+
</button>
|
|
46
|
+
</div>
|
|
47
|
+
<p
|
|
48
|
+
class="hidden text-muted-foreground text-sm focus:outline-none"
|
|
49
|
+
data-feedback-thanks
|
|
50
|
+
role="status"
|
|
51
|
+
tabindex="-1"
|
|
52
|
+
>
|
|
53
|
+
{f.thanks}
|
|
54
|
+
</p>
|
|
36
55
|
</div>
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
56
|
+
{
|
|
57
|
+
comments && (
|
|
58
|
+
<form class="mt-4 grid gap-2" data-feedback-form hidden>
|
|
59
|
+
<label class="text-muted-foreground text-sm" for="blume-feedback-comment">
|
|
60
|
+
{f.comment}
|
|
61
|
+
</label>
|
|
62
|
+
<textarea
|
|
63
|
+
class="w-full resize-y rounded-blume border border-border bg-background px-3 py-2 text-foreground text-sm outline-none transition-colors focus:border-foreground"
|
|
64
|
+
id="blume-feedback-comment"
|
|
65
|
+
maxlength={COMMENT_MAX_LENGTH}
|
|
66
|
+
name="comment"
|
|
67
|
+
rows="3"
|
|
68
|
+
></textarea>
|
|
69
|
+
<div>
|
|
70
|
+
<button class={buttonClass} type="submit">
|
|
71
|
+
{f.send}
|
|
72
|
+
</button>
|
|
73
|
+
</div>
|
|
74
|
+
</form>
|
|
75
|
+
)
|
|
76
|
+
}
|
|
45
77
|
</section>
|
|
46
78
|
|
|
47
79
|
<script>
|
|
48
|
-
import {
|
|
49
|
-
|
|
50
|
-
// Run on the initial load and again after every client-router swap, which
|
|
51
|
-
// rebuilds the rating widget from server-rendered markup — the handlers
|
|
52
|
-
// below always bind to the freshly swapped-in elements.
|
|
53
|
-
const initFeedback = () => {
|
|
54
|
-
const root = document.querySelector("[data-blume-page-feedback]");
|
|
55
|
-
if (!root) {
|
|
56
|
-
return;
|
|
57
|
-
}
|
|
58
|
-
const actions = root.querySelector("[data-feedback-actions]");
|
|
59
|
-
const thanks = root.querySelector("[data-feedback-thanks]");
|
|
60
|
-
for (const button of root.querySelectorAll("[data-feedback-value]")) {
|
|
61
|
-
button.addEventListener("click", () => {
|
|
62
|
-
track("feedback", {
|
|
63
|
-
helpful: button.getAttribute("data-feedback-value") ?? "",
|
|
64
|
-
path: location.pathname,
|
|
65
|
-
title: document.title,
|
|
66
|
-
});
|
|
67
|
-
actions?.classList.add("hidden");
|
|
68
|
-
thanks?.classList.remove("hidden");
|
|
69
|
-
// The clicked button just disappeared under focus; hand focus to the
|
|
70
|
-
// (live) thanks line so the reader isn't dropped at the top of the page.
|
|
71
|
-
if (thanks instanceof HTMLElement) {
|
|
72
|
-
thanks.focus();
|
|
73
|
-
}
|
|
74
|
-
});
|
|
75
|
-
}
|
|
76
|
-
};
|
|
80
|
+
import { initFeedback, syncFeedbackVisibility } from "./page-feedback.ts";
|
|
77
81
|
|
|
78
82
|
initFeedback();
|
|
79
83
|
document.addEventListener("astro:after-swap", initFeedback);
|
|
84
|
+
addEventListener("blume:consent", syncFeedbackVisibility);
|
|
80
85
|
</script>
|
|
@@ -5,8 +5,8 @@ import { createIconSprite } from "../icon-sprite.ts";
|
|
|
5
5
|
// page that wants Blume's chrome (document shell, header, theme, fonts) without
|
|
6
6
|
// the docs sidebar + prose + TOC grid that RootLayout hard-codes. It renders the
|
|
7
7
|
// `<head>`, theme/banner pre-paint scripts, banner, and header, then a single
|
|
8
|
-
// full-width `<slot />` for the body
|
|
9
|
-
//
|
|
8
|
+
// full-width `<slot />` for the body, then an optional `footer` slot, or the
|
|
9
|
+
// site footer `footer` configures when the page fills no slot. Import it into a custom page and pull props from `blume:data`:
|
|
10
10
|
//
|
|
11
11
|
// import PageLayout from "blume/components/layout/PageLayout.astro";
|
|
12
12
|
// import data from "blume:data";
|
|
@@ -40,11 +40,18 @@ import { buildStructuredData } from "../../seo/jsonld.ts";
|
|
|
40
40
|
import { normalizeXHandle } from "../../seo/x-handle.ts";
|
|
41
41
|
import Icon from "../Icon.astro";
|
|
42
42
|
import { stripBase, withBase, withMountedBase } from "../islands/base-path.ts";
|
|
43
|
+
import { routeSetFor } from "../../core/locale-links.ts";
|
|
44
|
+
import {
|
|
45
|
+
browserLanguageTargets,
|
|
46
|
+
LOCALE_REDIRECT_SCRIPT,
|
|
47
|
+
} from "./locale-redirect.ts";
|
|
43
48
|
import { pageDirection, pageLocale } from "./page-locale.ts";
|
|
44
49
|
import { searchLocaleFor } from "./search-locale.ts";
|
|
45
50
|
import "blume:theme";
|
|
46
51
|
import { ClientRouter } from "astro:transitions";
|
|
47
52
|
import Analytics from "./Analytics.astro";
|
|
53
|
+
import ConsentBanner from "./ConsentBanner.astro";
|
|
54
|
+
import ConsentHead from "./ConsentHead.astro";
|
|
48
55
|
import Banner from "./Banner.astro";
|
|
49
56
|
import DiscoveryLinks from "./DiscoveryLinks.astro";
|
|
50
57
|
import Favicon from "./Favicon.astro";
|
|
@@ -57,6 +64,9 @@ import {
|
|
|
57
64
|
import Header from "./Header.astro";
|
|
58
65
|
import { currentTabForRoute } from "./nav-utils.ts";
|
|
59
66
|
import NavTabMenu from "./NavTabMenu.astro";
|
|
67
|
+
import DrawerSwitchers from "./DrawerSwitchers.astro";
|
|
68
|
+
import SiteFooter from "./SiteFooter.astro";
|
|
69
|
+
import SiteMetatags from "./SiteMetatags.astro";
|
|
60
70
|
import WebMcp from "./WebMcp.astro";
|
|
61
71
|
|
|
62
72
|
interface Props {
|
|
@@ -195,6 +205,8 @@ const clientDataJson = clientData
|
|
|
195
205
|
: null;
|
|
196
206
|
|
|
197
207
|
const strings = ui ?? EN_UI;
|
|
208
|
+
// The consent adapter (`consent`), site-wide: analytics waits for the reader.
|
|
209
|
+
const consent = data.config.consent;
|
|
198
210
|
// Merge over the English defaults so a label missing from a translation (or
|
|
199
211
|
// from a not-yet-regenerated snapshot) still renders instead of coming out
|
|
200
212
|
// blank — the PageActions pattern.
|
|
@@ -291,6 +303,25 @@ const bannerKey = banner?.dismissible ? banner.key : null;
|
|
|
291
303
|
// Start the page's icon sprite before anything renders an icon (see
|
|
292
304
|
// icon-sprite.ts); <IconSprite /> at the end of the body emits it.
|
|
293
305
|
createIconSprite(Astro.locals);
|
|
306
|
+
|
|
307
|
+
// A visitor landing on the default language's home page goes to their
|
|
308
|
+
// browser's language (`i18n.routeByBrowserLanguage`, see locale-redirect.ts).
|
|
309
|
+
const localeTargets = browserLanguageTargets({
|
|
310
|
+
basePath: data.config.basePath,
|
|
311
|
+
i18n: data.config.i18n,
|
|
312
|
+
route,
|
|
313
|
+
routes: routeSetFor(data.routes),
|
|
314
|
+
});
|
|
315
|
+
const localeRedirect = localeTargets
|
|
316
|
+
? JSON.stringify(
|
|
317
|
+
Object.fromEntries(
|
|
318
|
+
Object.entries(localeTargets).map(([code, path]) => [
|
|
319
|
+
code,
|
|
320
|
+
withMountedBase(path),
|
|
321
|
+
])
|
|
322
|
+
)
|
|
323
|
+
)
|
|
324
|
+
: null;
|
|
294
325
|
---
|
|
295
326
|
|
|
296
327
|
<!doctype html>
|
|
@@ -298,6 +329,16 @@ createIconSprite(Astro.locals);
|
|
|
298
329
|
<head>
|
|
299
330
|
<meta charset="utf-8" />
|
|
300
331
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
332
|
+
{
|
|
333
|
+
localeRedirect && (
|
|
334
|
+
<script
|
|
335
|
+
data-default={data.config.i18n?.defaultLocale}
|
|
336
|
+
data-targets={localeRedirect}
|
|
337
|
+
is:inline
|
|
338
|
+
set:html={LOCALE_REDIRECT_SCRIPT}
|
|
339
|
+
/>
|
|
340
|
+
)
|
|
341
|
+
}
|
|
301
342
|
{/* Client-side navigation, matching RootLayout: same-origin link clicks
|
|
302
343
|
swap the DOM in place instead of tearing the document down, so no
|
|
303
344
|
browser paints a blank frame between pages. */}
|
|
@@ -363,6 +404,7 @@ createIconSprite(Astro.locals);
|
|
|
363
404
|
{description && <meta content={description} name="twitter:description" />}
|
|
364
405
|
{xSite && <meta content={xSite} name="twitter:site" />}
|
|
365
406
|
{xCreator && <meta content={xCreator} name="twitter:creator" />}
|
|
407
|
+
<SiteMetatags tags={data.config.metatags} />
|
|
366
408
|
{/* Agent discovery on every page, so a custom page built on PageLayout is
|
|
367
409
|
covered without passing a prop, the same way the docs pages are. */}
|
|
368
410
|
<DiscoveryLinks discovery={discovery} markdownMirror={markdownMirror} />
|
|
@@ -381,6 +423,7 @@ createIconSprite(Astro.locals);
|
|
|
381
423
|
)
|
|
382
424
|
}
|
|
383
425
|
<script data-mode={themeMode} is:inline set:html={THEME_INIT_SCRIPT} />
|
|
426
|
+
{consent && <ConsentHead consent={consent} />}
|
|
384
427
|
<Analytics analytics={analytics} />
|
|
385
428
|
</head>
|
|
386
429
|
<body class="bg-background font-sans text-foreground antialiased">
|
|
@@ -409,8 +452,27 @@ createIconSprite(Astro.locals);
|
|
|
409
452
|
transparent={transparentHeader}
|
|
410
453
|
/>
|
|
411
454
|
<main id="blume-content"><slot /></main>
|
|
412
|
-
|
|
455
|
+
{
|
|
456
|
+
Astro.slots.has("footer") ? (
|
|
457
|
+
<slot name="footer" />
|
|
458
|
+
) : (
|
|
459
|
+
<SiteFooter
|
|
460
|
+
footer={data.config.footer}
|
|
461
|
+
locale={locale}
|
|
462
|
+
navigation={navigation}
|
|
463
|
+
ui={strings}
|
|
464
|
+
/>
|
|
465
|
+
)
|
|
466
|
+
}
|
|
413
467
|
<WebMcp />
|
|
468
|
+
{
|
|
469
|
+
consent?.kind === "native" && (
|
|
470
|
+
<ConsentBanner
|
|
471
|
+
policy={consent.options.policy}
|
|
472
|
+
strings={strings.consent}
|
|
473
|
+
/>
|
|
474
|
+
)
|
|
475
|
+
}
|
|
414
476
|
{
|
|
415
477
|
// Mobile nav for chrome-only pages: the header's inline tab bar is hidden
|
|
416
478
|
// below `lg` and there's no sidebar drawer, so surface the tabs in a
|
|
@@ -425,6 +487,12 @@ createIconSprite(Astro.locals);
|
|
|
425
487
|
data-blume-nav-drawer
|
|
426
488
|
id="blume-nav-drawer"
|
|
427
489
|
>
|
|
490
|
+
<DrawerSwitchers
|
|
491
|
+
localeSwitch={localeSwitch}
|
|
492
|
+
route={route}
|
|
493
|
+
selectors={navigation.selectors}
|
|
494
|
+
switcherStrings={strings.languageSwitcher}
|
|
495
|
+
/>
|
|
428
496
|
<nav aria-label={navStrings.sections}>
|
|
429
497
|
<ul class="m-0 list-none p-0">
|
|
430
498
|
{navigation.tabs.map((tab) => (
|
|
@@ -4,6 +4,7 @@ import { createIconSprite } from "../icon-sprite.ts";
|
|
|
4
4
|
import "blume:theme";
|
|
5
5
|
import data from "blume:data";
|
|
6
6
|
import type {
|
|
7
|
+
BlumeBanner,
|
|
7
8
|
BlumeDataConfig,
|
|
8
9
|
BlumeFavicon,
|
|
9
10
|
DiscoveryHeadLinks,
|
|
@@ -14,6 +15,8 @@ import { NEW_TAB_HINT_ID } from "../../core/new-tab.ts";
|
|
|
14
15
|
import type { FontHead } from "../../theme/fonts.ts";
|
|
15
16
|
import type { Navigation } from "../../core/types.ts";
|
|
16
17
|
import Analytics from "./Analytics.astro";
|
|
18
|
+
import ConsentBanner from "./ConsentBanner.astro";
|
|
19
|
+
import ConsentHead from "./ConsentHead.astro";
|
|
17
20
|
import WebMcp from "./WebMcp.astro";
|
|
18
21
|
import Banner from "./Banner.astro";
|
|
19
22
|
import DiscoveryLinks from "./DiscoveryLinks.astro";
|
|
@@ -27,6 +30,7 @@ import {
|
|
|
27
30
|
import Header from "./Header.astro";
|
|
28
31
|
import { pageDirection, pageLocale } from "./page-locale.ts";
|
|
29
32
|
import { searchLocaleFor } from "./search-locale.ts";
|
|
33
|
+
import SiteMetatags from "./SiteMetatags.astro";
|
|
30
34
|
|
|
31
35
|
// A minimal shell for the Scalar API/AsyncAPI reference: Blume's banner + navbar
|
|
32
36
|
// on top, then a full-height region the reference mounts into. Unlike RootLayout
|
|
@@ -50,12 +54,7 @@ interface Props {
|
|
|
50
54
|
} | null;
|
|
51
55
|
favicon?: BlumeFavicon | null;
|
|
52
56
|
appleIcon?: BlumeFavicon | null;
|
|
53
|
-
banner?:
|
|
54
|
-
content: string;
|
|
55
|
-
link?: { text: string; href: string };
|
|
56
|
-
dismissible: boolean;
|
|
57
|
-
key: string;
|
|
58
|
-
} | null;
|
|
57
|
+
banner?: BlumeBanner | null;
|
|
59
58
|
analytics?: BlumeDataConfig["analytics"] | null;
|
|
60
59
|
navigation: Navigation;
|
|
61
60
|
route: string;
|
|
@@ -110,6 +109,8 @@ const locale = pageLocale(data.config.i18n, localeProp, Astro.currentLocale);
|
|
|
110
109
|
const dir = dirProp ?? pageDirection(data.config.i18n, locale);
|
|
111
110
|
|
|
112
111
|
const strings = ui ?? EN_UI;
|
|
112
|
+
// The consent adapter (`consent`), site-wide: analytics waits for the reader.
|
|
113
|
+
const consent = data.config.consent;
|
|
113
114
|
const navStrings = { ...EN_UI.nav, ...strings.nav };
|
|
114
115
|
// Scope search to the reference page's language on a multi-locale site.
|
|
115
116
|
const searchLocale = searchLocaleFor(data.config.i18n, locale);
|
|
@@ -128,6 +129,7 @@ createIconSprite(Astro.locals);
|
|
|
128
129
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
129
130
|
{noindex && <meta name="robots" content="noindex" />}
|
|
130
131
|
<title>{pageTitle}</title>
|
|
132
|
+
<SiteMetatags tags={data.config.metatags} />
|
|
131
133
|
<Favicon favicon={favicon} appleIcon={appleIcon} />
|
|
132
134
|
<Fonts cssVars={fontCssVars ?? []} />
|
|
133
135
|
<DiscoveryLinks discovery={discovery} />
|
|
@@ -137,6 +139,7 @@ createIconSprite(Astro.locals);
|
|
|
137
139
|
)
|
|
138
140
|
}
|
|
139
141
|
<script data-mode={themeMode} is:inline set:html={THEME_INIT_SCRIPT} />
|
|
142
|
+
{consent && <ConsentHead consent={consent} />}
|
|
140
143
|
<Analytics analytics={analytics} />
|
|
141
144
|
</head>
|
|
142
145
|
<body class="bg-background font-sans text-foreground antialiased">
|
|
@@ -170,6 +173,14 @@ createIconSprite(Astro.locals);
|
|
|
170
173
|
<script is:inline set:html={SCALAR_THEME_INIT_SCRIPT} />
|
|
171
174
|
</div>
|
|
172
175
|
<WebMcp />
|
|
176
|
+
{
|
|
177
|
+
consent?.kind === "native" && (
|
|
178
|
+
<ConsentBanner
|
|
179
|
+
policy={consent.options.policy}
|
|
180
|
+
strings={strings.consent}
|
|
181
|
+
/>
|
|
182
|
+
)
|
|
183
|
+
}
|
|
173
184
|
<IconSprite />
|
|
174
185
|
</body>
|
|
175
186
|
</html>
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
---
|
|
2
|
+
import type { RelatedLink } from "../../core/related.ts";
|
|
3
|
+
import Card from "../content/Card.astro";
|
|
4
|
+
import CardGroup from "../content/CardGroup.astro";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* A page's `related` links, as cards at its foot: each linked page's title
|
|
8
|
+
* and description, or a URL's host for a link off the site (see
|
|
9
|
+
* `core/related.ts`).
|
|
10
|
+
*/
|
|
11
|
+
interface Props {
|
|
12
|
+
links: RelatedLink[];
|
|
13
|
+
/** The heading, from the `page.related` UI string. */
|
|
14
|
+
title: string;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const { links, title } = Astro.props;
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
{
|
|
21
|
+
links.length > 0 && (
|
|
22
|
+
<nav
|
|
23
|
+
aria-labelledby="blume-related-pages"
|
|
24
|
+
class="mx-auto mt-10 max-w-content"
|
|
25
|
+
data-blume-related
|
|
26
|
+
>
|
|
27
|
+
<h2
|
|
28
|
+
class="font-medium text-foreground text-sm"
|
|
29
|
+
id="blume-related-pages"
|
|
30
|
+
>
|
|
31
|
+
{title}
|
|
32
|
+
</h2>
|
|
33
|
+
<CardGroup>
|
|
34
|
+
{links.map((link) => (
|
|
35
|
+
<Card href={link.href} title={link.title}>
|
|
36
|
+
{link.description}
|
|
37
|
+
</Card>
|
|
38
|
+
))}
|
|
39
|
+
</CardGroup>
|
|
40
|
+
</nav>
|
|
41
|
+
)
|
|
42
|
+
}
|