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
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The assistant's handoff to your support channel (`ai.assistant.support`).
|
|
3
|
+
* A `mailto:` link starts an email with the conversation as its body, so the
|
|
4
|
+
* reader doesn't have to repeat themselves; any other link gets the
|
|
5
|
+
* conversation's `thread` id in its query, the same id the assistant's
|
|
6
|
+
* analytics events carry, so a support team can find the conversation.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
/** One turn of the conversation. */
|
|
10
|
+
export interface SupportMessage {
|
|
11
|
+
content: string;
|
|
12
|
+
role: "assistant" | "user";
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/** What the link is built from. */
|
|
16
|
+
export interface SupportContext {
|
|
17
|
+
/** The label the transcript gives the assistant's turns. */
|
|
18
|
+
ai: string;
|
|
19
|
+
messages: readonly SupportMessage[];
|
|
20
|
+
/** The email's subject. */
|
|
21
|
+
subject: string;
|
|
22
|
+
thread: string;
|
|
23
|
+
/** The label the transcript gives the reader's turns. */
|
|
24
|
+
you: string;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* How much conversation an email carries: mail clients cut long `mailto:`
|
|
29
|
+
* links, so a long conversation is trimmed from the start, keeping the
|
|
30
|
+
* latest turns.
|
|
31
|
+
*/
|
|
32
|
+
export const MAX_TRANSCRIPT_CHARS = 1500;
|
|
33
|
+
|
|
34
|
+
const transcriptOf = (context: SupportContext): string => {
|
|
35
|
+
const full = context.messages
|
|
36
|
+
.map(
|
|
37
|
+
(message) =>
|
|
38
|
+
`${message.role === "user" ? context.you : context.ai}: ${message.content}`
|
|
39
|
+
)
|
|
40
|
+
.join("\n\n");
|
|
41
|
+
return full.length > MAX_TRANSCRIPT_CHARS
|
|
42
|
+
? `…${full.slice(-MAX_TRANSCRIPT_CHARS)}`
|
|
43
|
+
: full;
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
/** The support link for this conversation. */
|
|
47
|
+
export const supportHref = (
|
|
48
|
+
support: string,
|
|
49
|
+
context: SupportContext
|
|
50
|
+
): string => {
|
|
51
|
+
if (support.startsWith("mailto:")) {
|
|
52
|
+
// `mailto:` wants %20, not the `+` URLSearchParams writes for a space.
|
|
53
|
+
const body = `${transcriptOf(context)}\n\n(${context.thread})`;
|
|
54
|
+
const separator = support.includes("?") ? "&" : "?";
|
|
55
|
+
return `${support}${separator}subject=${encodeURIComponent(context.subject)}&body=${encodeURIComponent(body)}`;
|
|
56
|
+
}
|
|
57
|
+
const url = new URL(support, "https://blume.invalid");
|
|
58
|
+
url.searchParams.set("thread", context.thread);
|
|
59
|
+
return url.origin === "https://blume.invalid"
|
|
60
|
+
? `${url.pathname}${url.search}${url.hash}`
|
|
61
|
+
: url.href;
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
/** A fresh conversation id: 16 hex characters. */
|
|
65
|
+
export const newThreadId = (): string =>
|
|
66
|
+
Array.from(crypto.getRandomValues(new Uint8Array(8)), (byte) =>
|
|
67
|
+
byte.toString(16).padStart(2, "0")
|
|
68
|
+
).join("");
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
import VercelAnalytics from "@vercel/analytics/astro";
|
|
3
|
+
import data from "blume:data";
|
|
3
4
|
|
|
4
5
|
import { analyticsHead } from "../../analytics/head.ts";
|
|
5
6
|
import type { BlumeDataConfig } from "../../core/data.ts";
|
|
@@ -10,12 +11,20 @@ import type { BlumeDataConfig } from "../../core/data.ts";
|
|
|
10
11
|
// component for `vercel()`, one <script> for every other adapter. Loads ONLY
|
|
11
12
|
// in production builds so `blume dev` stays clean and local traffic never
|
|
12
13
|
// reaches your analytics.
|
|
14
|
+
//
|
|
15
|
+
// With `consent` configured, every tag is held as inert `text/plain` until
|
|
16
|
+
// the reader allows analytics, when the consent runtime runs it
|
|
17
|
+
// (`consent/client.ts`); Vercel's component sends nothing until then instead
|
|
18
|
+
// (`consent/init.ts`).
|
|
13
19
|
interface Props {
|
|
14
20
|
analytics?: BlumeDataConfig["analytics"] | null;
|
|
15
21
|
}
|
|
16
22
|
|
|
17
23
|
const { analytics } = Astro.props;
|
|
18
24
|
const nodes = analyticsHead(import.meta.env.PROD ? (analytics ?? []) : []);
|
|
25
|
+
const held = data.config.consent
|
|
26
|
+
? { "data-blume-consent": "analytics", type: "text/plain" }
|
|
27
|
+
: {};
|
|
19
28
|
---
|
|
20
29
|
|
|
21
30
|
{
|
|
@@ -24,9 +33,9 @@ const nodes = analyticsHead(import.meta.env.PROD ? (analytics ?? []) : []);
|
|
|
24
33
|
return <VercelAnalytics {...node.props} />;
|
|
25
34
|
}
|
|
26
35
|
return node.content === null ? (
|
|
27
|
-
<script is:inline {...node.attributes} />
|
|
36
|
+
<script is:inline {...node.attributes} {...held} />
|
|
28
37
|
) : (
|
|
29
|
-
<script is:inline set:html={node.content} {...node.attributes} />
|
|
38
|
+
<script is:inline set:html={node.content} {...node.attributes} {...held} />
|
|
30
39
|
);
|
|
31
40
|
})
|
|
32
41
|
}
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
---
|
|
2
2
|
import data from "blume:data";
|
|
3
|
+
import type { BlumeBanner } from "../../core/data.ts";
|
|
3
4
|
import { EN_UI } from "../../core/i18n-ui.ts";
|
|
4
5
|
import type { UIStrings } from "../../core/i18n-ui.ts";
|
|
6
|
+
import { resolveLocalizable } from "../../core/localizable.ts";
|
|
5
7
|
import { withBase } from "../islands/base-path.ts";
|
|
6
8
|
import Icon from "../Icon.astro";
|
|
7
9
|
|
|
@@ -9,14 +11,11 @@ import Icon from "../Icon.astro";
|
|
|
9
11
|
// every shell shows the same bar. The pre-paint hide for a dismissed banner and
|
|
10
12
|
// the dismiss click handler live in the layout/Header, not here.
|
|
11
13
|
interface Props {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
key: string;
|
|
18
|
-
}
|
|
19
|
-
| null;
|
|
14
|
+
/**
|
|
15
|
+
* The banner. Its `content` and link `text` may be per-locale maps, shown
|
|
16
|
+
* in `locale` (else the default locale, else the map's first entry).
|
|
17
|
+
*/
|
|
18
|
+
banner: BlumeBanner | null;
|
|
20
19
|
/** Localized banner labels. */
|
|
21
20
|
strings?: UIStrings["banner"];
|
|
22
21
|
/**
|
|
@@ -40,6 +39,11 @@ const b = { ...EN_UI.banner, ...strings };
|
|
|
40
39
|
const navigation =
|
|
41
40
|
(locale === undefined ? undefined : data.navigationByLocale[locale]) ??
|
|
42
41
|
data.navigation;
|
|
42
|
+
const defaultLocale = data.config.i18n?.defaultLocale;
|
|
43
|
+
const content =
|
|
44
|
+
banner && resolveLocalizable(banner.content, locale, defaultLocale);
|
|
45
|
+
const linkText =
|
|
46
|
+
banner?.link && resolveLocalizable(banner.link.text, locale, defaultLocale);
|
|
43
47
|
const linkHref =
|
|
44
48
|
banner?.link && banner.link.href === data.config.banner?.link?.href
|
|
45
49
|
? (navigation.bannerHref ?? banner.link.href)
|
|
@@ -55,13 +59,13 @@ const linkHref =
|
|
|
55
59
|
>
|
|
56
60
|
{/* The message is authored in one language, whatever the page's
|
|
57
61
|
direction: `dir="auto"` keeps its punctuation where it was typed. */}
|
|
58
|
-
<span dir="auto">{
|
|
62
|
+
<span dir="auto">{content}</span>
|
|
59
63
|
{banner.link && linkHref && (
|
|
60
64
|
<a
|
|
61
65
|
class="inline-flex items-center gap-1 font-medium underline underline-offset-2"
|
|
62
66
|
href={withBase(linkHref)}
|
|
63
67
|
>
|
|
64
|
-
{
|
|
68
|
+
{linkText}
|
|
65
69
|
<Icon class="rtl:-scale-x-100" name="arrow-right" size={14} />
|
|
66
70
|
</a>
|
|
67
71
|
)}
|
|
@@ -11,9 +11,11 @@ interface Props {
|
|
|
11
11
|
strings?: UIStrings["nav"];
|
|
12
12
|
/** Left-align full width (for the wide API layout) instead of the prose measure. */
|
|
13
13
|
wide?: boolean;
|
|
14
|
+
/** Match a `center` page's wider centered column instead of the prose measure. */
|
|
15
|
+
centered?: boolean;
|
|
14
16
|
}
|
|
15
17
|
|
|
16
|
-
const { crumbs, strings, wide = false } = Astro.props;
|
|
18
|
+
const { crumbs, strings, wide = false, centered = false } = Astro.props;
|
|
17
19
|
|
|
18
20
|
// Merge over the English defaults so a label missing from a translation (or
|
|
19
21
|
// from a not-yet-regenerated snapshot) still renders instead of coming out
|
|
@@ -31,7 +33,9 @@ const eyebrowCrumb = crumbs.length > 1 ? crumbs[crumbs.length - 2] : null;
|
|
|
31
33
|
aria-label={n.breadcrumb}
|
|
32
34
|
class:list={[
|
|
33
35
|
"mb-2 text-muted-foreground text-sm",
|
|
34
|
-
wide
|
|
36
|
+
wide
|
|
37
|
+
? "max-w-none"
|
|
38
|
+
: ["mx-auto", centered ? "max-w-[54rem]" : "max-w-content"],
|
|
35
39
|
]}
|
|
36
40
|
>
|
|
37
41
|
{eyebrowCrumb.route ? (
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
---
|
|
2
|
+
import { EN_UI } from "../../core/i18n-ui.ts";
|
|
3
|
+
import type { UIStrings } from "../../core/i18n-ui.ts";
|
|
4
|
+
import { newTabAttrs } from "../../core/new-tab.ts";
|
|
5
|
+
import { withBase } from "../islands/base-path.ts";
|
|
6
|
+
|
|
7
|
+
// The `native()` consent banner: a card at the foot of the viewport asking to
|
|
8
|
+
// use analytics cookies. It renders hidden, and the consent runtime
|
|
9
|
+
// (`consent/client.ts`) shows it until the reader answers, stores the answer,
|
|
10
|
+
// and shows it again from the footer's Cookie settings link. Accept and
|
|
11
|
+
// Decline carry the same weight, so declining is as easy as accepting.
|
|
12
|
+
interface Props {
|
|
13
|
+
/** The privacy policy link: a page route or a URL. */
|
|
14
|
+
policy?: string;
|
|
15
|
+
/** Localized banner labels. */
|
|
16
|
+
strings?: UIStrings["consent"];
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const { policy, strings } = Astro.props;
|
|
20
|
+
const c = { ...EN_UI.consent, ...strings };
|
|
21
|
+
const buttonClass =
|
|
22
|
+
"flex-1 rounded-blume border border-border px-4 py-2 text-foreground text-sm transition-colors hover:border-foreground";
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
<div
|
|
26
|
+
aria-label={c.label}
|
|
27
|
+
class="fixed inset-x-4 bottom-4 z-50 rounded-blume border border-border bg-background p-4 shadow-lg sm:start-auto sm:end-4 sm:w-96"
|
|
28
|
+
data-blume-consent-banner
|
|
29
|
+
hidden
|
|
30
|
+
role="region"
|
|
31
|
+
>
|
|
32
|
+
<p class="text-foreground text-sm">
|
|
33
|
+
{c.message}{" "}
|
|
34
|
+
{
|
|
35
|
+
policy && (
|
|
36
|
+
<a
|
|
37
|
+
class="text-muted-foreground underline underline-offset-2 transition-colors hover:text-foreground"
|
|
38
|
+
href={withBase(policy)}
|
|
39
|
+
{...newTabAttrs(policy)}
|
|
40
|
+
>
|
|
41
|
+
{c.policy}
|
|
42
|
+
</a>
|
|
43
|
+
)
|
|
44
|
+
}
|
|
45
|
+
</p>
|
|
46
|
+
<div class="mt-3 flex gap-2">
|
|
47
|
+
<button
|
|
48
|
+
class={buttonClass}
|
|
49
|
+
data-blume-consent-choice="decline"
|
|
50
|
+
type="button"
|
|
51
|
+
>
|
|
52
|
+
{c.decline}
|
|
53
|
+
</button>
|
|
54
|
+
<button
|
|
55
|
+
class={buttonClass}
|
|
56
|
+
data-blume-consent-choice="accept"
|
|
57
|
+
type="button"
|
|
58
|
+
>
|
|
59
|
+
{c.accept}
|
|
60
|
+
</button>
|
|
61
|
+
</div>
|
|
62
|
+
</div>
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
---
|
|
2
|
+
import { consentHead } from "../../consent/head.ts";
|
|
3
|
+
import { CONSENT_INIT_SCRIPT } from "../../consent/init.ts";
|
|
4
|
+
import type { BlumeDataConfig } from "../../core/data.ts";
|
|
5
|
+
|
|
6
|
+
// The consent layer's <head> output, rendered ahead of `Analytics.astro` by
|
|
7
|
+
// every layout when `consent` is configured: the inline script that creates
|
|
8
|
+
// `window.blumeConsent` (`consent/init.ts`), the adapter's own tags — a
|
|
9
|
+
// hosted consent manager's loader and the bridge that reports its answers —
|
|
10
|
+
// and the runtime that runs the held analytics (`consent/client.ts`), which
|
|
11
|
+
// starts the adapter's browser module, if it has one (`blume:consent-client`,
|
|
12
|
+
// see `consent/clients.ts`). Like analytics, a hosted manager loads in
|
|
13
|
+
// production builds only; a browser module (`native()`'s banner) works in
|
|
14
|
+
// `blume dev` too.
|
|
15
|
+
interface Props {
|
|
16
|
+
consent: NonNullable<BlumeDataConfig["consent"]>;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const { consent } = Astro.props;
|
|
20
|
+
const tags = import.meta.env.PROD ? consentHead(consent) : [];
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
<script data-kind={consent.kind} is:inline set:html={CONSENT_INIT_SCRIPT} />
|
|
24
|
+
{
|
|
25
|
+
tags.map((tag) =>
|
|
26
|
+
tag.content === null ? (
|
|
27
|
+
<script is:inline {...tag.attributes} />
|
|
28
|
+
) : (
|
|
29
|
+
<script is:inline set:html={tag.content} {...tag.attributes} />
|
|
30
|
+
)
|
|
31
|
+
)
|
|
32
|
+
}
|
|
33
|
+
<script>
|
|
34
|
+
import { startConsentClient } from "blume:consent-client";
|
|
35
|
+
import { startConsent } from "../../consent/client.ts";
|
|
36
|
+
|
|
37
|
+
startConsent(startConsentClient);
|
|
38
|
+
</script>
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
---
|
|
2
|
+
import AccordionItem from "../content/AccordionItem.astro";
|
|
3
|
+
import Card from "../content/Card.astro";
|
|
4
|
+
import CardGroup from "../content/CardGroup.astro";
|
|
5
|
+
import Icon from "../Icon.astro";
|
|
6
|
+
import { directoryEntries } from "./nav-utils.ts";
|
|
7
|
+
import type { NavGroup } from "./nav-utils.ts";
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* A group page's directory: the group's other pages listed below the page's
|
|
11
|
+
* content, as cards or as an accordion whose subgroups open to their pages
|
|
12
|
+
* (the group's `directory`, see `core/schema.ts`).
|
|
13
|
+
*/
|
|
14
|
+
interface Props {
|
|
15
|
+
group: NavGroup;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const { group } = Astro.props;
|
|
19
|
+
const entries = directoryEntries(group);
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
{
|
|
23
|
+
entries.length > 0 && (
|
|
24
|
+
<nav
|
|
25
|
+
aria-label={group.label}
|
|
26
|
+
class="mx-auto mt-6 max-w-content"
|
|
27
|
+
data-blume-directory={group.directory}
|
|
28
|
+
>
|
|
29
|
+
{group.directory === "card" ? (
|
|
30
|
+
<CardGroup>
|
|
31
|
+
{entries.map((entry) => (
|
|
32
|
+
<Card href={entry.href} icon={entry.icon} title={entry.label}>
|
|
33
|
+
{entry.description}
|
|
34
|
+
</Card>
|
|
35
|
+
))}
|
|
36
|
+
</CardGroup>
|
|
37
|
+
) : (
|
|
38
|
+
<div class="not-prose my-6 divide-y divide-border overflow-hidden rounded-blume border border-border">
|
|
39
|
+
{entries.map((entry, index) =>
|
|
40
|
+
entry.pages ? (
|
|
41
|
+
<AccordionItem
|
|
42
|
+
description={entry.description}
|
|
43
|
+
icon={entry.icon}
|
|
44
|
+
id={`blume-directory-${index + 1}`}
|
|
45
|
+
title={entry.label}
|
|
46
|
+
>
|
|
47
|
+
<ul class="grid gap-2 text-sm">
|
|
48
|
+
{entry.pages.map((page) => (
|
|
49
|
+
<li>
|
|
50
|
+
<a
|
|
51
|
+
class="text-muted-foreground no-underline transition-colors hover:text-foreground"
|
|
52
|
+
href={page.route}
|
|
53
|
+
>
|
|
54
|
+
{page.label}
|
|
55
|
+
</a>
|
|
56
|
+
</li>
|
|
57
|
+
))}
|
|
58
|
+
</ul>
|
|
59
|
+
</AccordionItem>
|
|
60
|
+
) : (
|
|
61
|
+
<a
|
|
62
|
+
class="flex items-center justify-between gap-4 p-4 font-medium text-foreground no-underline transition-colors hover:bg-muted/40"
|
|
63
|
+
href={entry.href}
|
|
64
|
+
>
|
|
65
|
+
<span class="flex items-start gap-2">
|
|
66
|
+
{entry.icon && (
|
|
67
|
+
<Icon
|
|
68
|
+
class="mt-0.5 shrink-0 text-muted-foreground"
|
|
69
|
+
name={entry.icon}
|
|
70
|
+
size={16}
|
|
71
|
+
/>
|
|
72
|
+
)}
|
|
73
|
+
<span>
|
|
74
|
+
<span class="block">{entry.label}</span>
|
|
75
|
+
{entry.description && (
|
|
76
|
+
<span class="block font-normal text-muted-foreground text-sm">
|
|
77
|
+
{entry.description}
|
|
78
|
+
</span>
|
|
79
|
+
)}
|
|
80
|
+
</span>
|
|
81
|
+
</span>
|
|
82
|
+
<Icon
|
|
83
|
+
class="shrink-0 text-muted-foreground rtl:-scale-x-100"
|
|
84
|
+
name="arrow-right"
|
|
85
|
+
size={16}
|
|
86
|
+
/>
|
|
87
|
+
</a>
|
|
88
|
+
)
|
|
89
|
+
)}
|
|
90
|
+
</div>
|
|
91
|
+
)}
|
|
92
|
+
</nav>
|
|
93
|
+
)
|
|
94
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
---
|
|
2
|
+
// The header's selectors, version selector, and language switcher, as a row
|
|
3
|
+
// at the top of the nav drawer. Below `lg` the sidebar is this drawer, and the
|
|
4
|
+
// header has no room for them beside the logo, tabs, search, and icon
|
|
5
|
+
// buttons, so it hides them whenever there's a drawer to open and this row
|
|
6
|
+
// takes over; from `lg` up the row hides and the header shows them again.
|
|
7
|
+
import type { UIStrings } from "../../core/i18n-ui.ts";
|
|
8
|
+
import type {
|
|
9
|
+
LocaleSwitchOption,
|
|
10
|
+
NavSelector as NavSelectorConfig,
|
|
11
|
+
} from "../../core/types.ts";
|
|
12
|
+
import LanguageSwitcher from "./LanguageSwitcher.astro";
|
|
13
|
+
import NavSelector from "./NavSelector.astro";
|
|
14
|
+
|
|
15
|
+
interface Props {
|
|
16
|
+
selectors: NavSelectorConfig[];
|
|
17
|
+
versionSelector?: NavSelectorConfig | null;
|
|
18
|
+
localeSwitch?: LocaleSwitchOption[];
|
|
19
|
+
route: string;
|
|
20
|
+
switcherStrings?: UIStrings["languageSwitcher"];
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const { selectors, versionSelector, localeSwitch, route, switcherStrings } =
|
|
24
|
+
Astro.props;
|
|
25
|
+
const hasLocales = (localeSwitch?.length ?? 0) > 1;
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
{
|
|
29
|
+
(selectors.length > 0 || versionSelector || hasLocales) && (
|
|
30
|
+
<div class="mb-4 flex flex-col gap-2 border-border border-b pb-4 lg:hidden">
|
|
31
|
+
{selectors.map((selector) => (
|
|
32
|
+
<NavSelector route={route} selector={selector} variant="drawer" />
|
|
33
|
+
))}
|
|
34
|
+
{versionSelector && (
|
|
35
|
+
<NavSelector
|
|
36
|
+
route={route}
|
|
37
|
+
selector={versionSelector}
|
|
38
|
+
variant="drawer"
|
|
39
|
+
/>
|
|
40
|
+
)}
|
|
41
|
+
{localeSwitch && hasLocales && (
|
|
42
|
+
<LanguageSwitcher
|
|
43
|
+
label={switcherStrings?.label ?? "Language"}
|
|
44
|
+
options={localeSwitch}
|
|
45
|
+
untranslatedLabel={switcherStrings?.untranslated ?? "Not translated"}
|
|
46
|
+
variant="drawer"
|
|
47
|
+
/>
|
|
48
|
+
)}
|
|
49
|
+
</div>
|
|
50
|
+
)
|
|
51
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
// A no-op layout slot: renders nothing regardless of props. Used as the built-in
|
|
3
|
-
// fallback for the content-injection slots (
|
|
4
|
-
//
|
|
3
|
+
// fallback for the content-injection slots (PageHeader, PageFooter) that have
|
|
4
|
+
// no default, so an unconfigured slot renders empty while `resolveSlot`
|
|
5
5
|
// still returns a valid component and the generated pages stay type-safe.
|
|
6
6
|
---
|