blume 2.0.3 → 2.1.1
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 +142 -0
- package/README.md +1 -1
- package/dist/cli/{chunk-5f86nr5m.js → chunk-073rdvgb.js} +21 -48
- package/dist/cli/{chunk-5f86nr5m.js.map → chunk-073rdvgb.js.map} +4 -5
- package/dist/cli/{chunk-ga0pf4aj.js → chunk-0n9xkp3d.js} +12 -3
- package/dist/cli/{chunk-ga0pf4aj.js.map → chunk-0n9xkp3d.js.map} +3 -3
- package/dist/cli/chunk-150jk7km.js +52 -0
- package/dist/cli/chunk-150jk7km.js.map +10 -0
- package/dist/cli/{chunk-9t7a85s3.js → chunk-313vnn40.js} +30 -19
- package/dist/cli/chunk-313vnn40.js.map +10 -0
- package/dist/cli/{chunk-tkacnehg.js → chunk-3v3ffbrj.js} +2 -2
- package/dist/cli/{chunk-q58y5e6a.js → chunk-3x6x3pph.js} +46 -24
- package/dist/cli/chunk-3x6x3pph.js.map +10 -0
- package/dist/cli/{chunk-1d7ve1dm.js → chunk-42t4jxdx.js} +37 -5
- package/dist/cli/chunk-42t4jxdx.js.map +12 -0
- package/dist/cli/{chunk-8ktnccpt.js → chunk-54ztw1nj.js} +21 -2
- package/dist/cli/chunk-54ztw1nj.js.map +10 -0
- package/dist/cli/{chunk-hm3vjy5s.js → chunk-5vjtgs6e.js} +28 -10
- package/dist/cli/{chunk-hm3vjy5s.js.map → chunk-5vjtgs6e.js.map} +4 -4
- package/dist/cli/chunk-66w9j7p6.js +322 -0
- package/dist/cli/chunk-66w9j7p6.js.map +14 -0
- package/dist/cli/{chunk-2hsdwb9n.js → chunk-7ppf1rva.js} +34 -18
- package/dist/cli/chunk-7ppf1rva.js.map +10 -0
- package/dist/cli/{chunk-r9rcc4w7.js → chunk-8y2kmjv8.js} +7 -7
- package/dist/cli/{chunk-r20tn01b.js → chunk-c1y538kd.js} +8 -2
- package/dist/cli/{chunk-r20tn01b.js.map → chunk-c1y538kd.js.map} +3 -3
- package/dist/cli/{chunk-2eytanqx.js → chunk-c887fj0s.js} +2 -2
- package/dist/cli/{chunk-p3v96n38.js → chunk-cfyg47zg.js} +16 -6
- package/dist/cli/chunk-cfyg47zg.js.map +10 -0
- package/dist/cli/chunk-cm89scdv.js +443 -0
- package/dist/cli/chunk-cm89scdv.js.map +11 -0
- package/dist/cli/{chunk-akbpwfxc.js → chunk-dzwehpy7.js} +2 -2
- package/dist/cli/{chunk-wrr3j9w9.js → chunk-e6atmn4h.js} +299 -72
- package/dist/cli/chunk-e6atmn4h.js.map +36 -0
- package/dist/cli/{chunk-tzmab476.js → chunk-e8xw9qkh.js} +8 -6
- package/dist/cli/{chunk-tzmab476.js.map → chunk-e8xw9qkh.js.map} +3 -3
- package/dist/cli/{chunk-6dsbexzp.js → chunk-e9q7a2ak.js} +17 -15
- package/dist/cli/{chunk-6dsbexzp.js.map → chunk-e9q7a2ak.js.map} +2 -2
- package/dist/cli/{chunk-pv29h0wf.js → chunk-ehweg4fr.js} +5155 -1249
- package/dist/cli/chunk-ehweg4fr.js.map +218 -0
- package/dist/cli/{chunk-c8chx29p.js → chunk-ep6nd0rn.js} +390 -318
- package/dist/cli/chunk-ep6nd0rn.js.map +36 -0
- package/dist/cli/{chunk-p73c0m7w.js → chunk-fdrkhpjy.js} +18 -15
- package/dist/cli/{chunk-p73c0m7w.js.map → chunk-fdrkhpjy.js.map} +3 -3
- package/dist/cli/{chunk-2z928egk.js → chunk-ft9vfys6.js} +5 -5
- package/dist/cli/{chunk-5m5nmvyq.js → chunk-gb420vvz.js} +316 -79
- package/dist/cli/chunk-gb420vvz.js.map +17 -0
- package/dist/cli/{chunk-vg9r4eb9.js → chunk-hebn0tpx.js} +86 -13
- package/dist/cli/chunk-hebn0tpx.js.map +14 -0
- package/dist/cli/{chunk-35d4wj9f.js → chunk-htrwgabr.js} +41 -23
- package/dist/cli/chunk-htrwgabr.js.map +15 -0
- package/dist/cli/{chunk-g4hq16wv.js → chunk-hx3xqnk9.js} +16 -14
- package/dist/cli/{chunk-g4hq16wv.js.map → chunk-hx3xqnk9.js.map} +2 -2
- package/dist/cli/chunk-j134vrp2.js +65 -0
- package/dist/cli/chunk-j134vrp2.js.map +10 -0
- package/dist/cli/{chunk-a58773jm.js → chunk-kma9f6sf.js} +2 -2
- package/dist/cli/chunk-kwrg63tm.js +31 -0
- package/dist/cli/chunk-kwrg63tm.js.map +10 -0
- package/dist/cli/{chunk-ey84smr6.js → chunk-mrcccgnh.js} +6 -6
- package/dist/cli/{chunk-ey84smr6.js.map → chunk-mrcccgnh.js.map} +1 -1
- package/dist/cli/{chunk-yfyb25rh.js → chunk-n0v7m8ry.js} +24 -8
- package/dist/cli/chunk-n0v7m8ry.js.map +14 -0
- package/dist/cli/{chunk-j85vccga.js → chunk-ncj7w596.js} +576 -367
- package/dist/cli/chunk-ncj7w596.js.map +35 -0
- package/dist/cli/{chunk-5xvm6tfj.js → chunk-nq1d20w2.js} +17 -15
- package/dist/cli/{chunk-5xvm6tfj.js.map → chunk-nq1d20w2.js.map} +2 -2
- package/dist/cli/{chunk-pehfxfta.js → chunk-nrns10mj.js} +6 -98
- package/dist/cli/chunk-nrns10mj.js.map +10 -0
- package/dist/cli/{chunk-crgn1q09.js → chunk-sds923fa.js} +4 -4
- package/dist/cli/chunk-t2m5j4pr.js +104 -0
- package/dist/cli/chunk-t2m5j4pr.js.map +11 -0
- package/dist/cli/{chunk-acanzt5p.js → chunk-tdqhyxfz.js} +6 -6
- package/dist/cli/chunk-tphac74f.js +126 -0
- package/dist/cli/chunk-tphac74f.js.map +11 -0
- package/dist/cli/chunk-w1r4vase.js +18 -0
- package/dist/cli/chunk-w1r4vase.js.map +10 -0
- 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/index.js +31 -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 +26 -0
- package/dist/types/ai/ask.d.ts +271 -58
- package/dist/types/ai/component-markdown.d.ts +2 -0
- package/dist/types/ai/index.d.ts +2 -2
- package/dist/types/ai/openapi-components.d.ts +4 -1
- 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 +9 -0
- package/dist/types/astro/markdown-negotiation.d.ts +3 -0
- package/dist/types/astro/pages.d.ts +10 -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/cli/init/scaffold.d.ts +1 -1
- package/dist/types/components/content/api-field.d.ts +62 -0
- package/dist/types/components/content/api-page.d.ts +100 -0
- package/dist/types/components/layout/nav-utils.d.ts +26 -0
- package/dist/types/components/openapi/code-samples.d.ts +29 -0
- package/dist/types/components/openapi/helpers.d.ts +158 -0
- package/dist/types/components/openapi/security.d.ts +95 -0
- package/dist/types/components/openapi/snippets.d.ts +60 -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/changelog-index.d.ts +8 -0
- package/dist/types/core/config-input.d.ts +217 -23
- package/dist/types/core/data.d.ts +53 -4
- package/dist/types/core/footer.d.ts +8 -0
- package/dist/types/core/i18n-ui.d.ts +88 -0
- package/dist/types/core/includes.d.ts +8 -2
- package/dist/types/core/links.d.ts +8 -0
- package/dist/types/core/localizable.d.ts +7 -0
- package/dist/types/core/page-modes.d.ts +29 -0
- package/dist/types/core/probe.d.ts +2 -0
- package/dist/types/core/project-graph.d.ts +6 -0
- package/dist/types/core/redirect-patterns.d.ts +152 -0
- package/dist/types/core/related.d.ts +40 -0
- package/dist/types/core/schema.d.ts +670 -56
- package/dist/types/core/sources/cache.d.ts +3 -0
- package/dist/types/core/sources/contentful-rich-text.d.ts +11 -2
- package/dist/types/core/sources/contentful.d.ts +17 -1
- package/dist/types/core/sources/lexical.d.ts +5 -0
- package/dist/types/core/sources/normalize.d.ts +20 -1
- package/dist/types/core/sources/read.d.ts +5 -0
- package/dist/types/core/sources/remote.d.ts +37 -10
- package/dist/types/core/sources/sanity.d.ts +1 -1
- package/dist/types/core/types.d.ts +18 -1
- package/dist/types/core/variables.d.ts +42 -0
- package/dist/types/deploy/adapter-output.d.ts +2 -1
- package/dist/types/deploy/adapters/cloudflare.d.ts +7 -5
- package/dist/types/deploy/adapters/node.d.ts +58 -23
- package/dist/types/deploy/adapters/registry.d.ts +10 -0
- package/dist/types/deploy/adapters/types.d.ts +3 -2
- package/dist/types/deploy/node-headers.d.ts +13 -2
- package/dist/types/deploy/platforms/cloudflare.d.ts +15 -7
- package/dist/types/deploy/platforms/netlify.d.ts +7 -0
- package/dist/types/deploy/platforms/node.d.ts +3 -1
- package/dist/types/deploy/platforms/types.d.ts +18 -7
- package/dist/types/deploy/platforms/vercel.d.ts +26 -1
- package/dist/types/deploy/redirects.d.ts +55 -11
- package/dist/types/deploy/sitemap.d.ts +2 -1
- package/dist/types/deploy/vercel-negotiation.d.ts +51 -21
- 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/checks.d.ts +27 -0
- package/dist/types/openapi/graphql.d.ts +6 -0
- package/dist/types/openapi/model.d.ts +27 -10
- package/dist/types/openapi/overlay.d.ts +54 -0
- package/dist/types/openapi/parse.d.ts +16 -0
- package/dist/types/openapi/references.d.ts +30 -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 +119 -0
- package/dist/types/ratelimit/upstash.d.ts +46 -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 +89 -11
- package/dist/types/reference/index.d.ts +1 -1
- package/dist/types/reference/openapi.d.ts +33 -12
- package/dist/types/reference/options.d.ts +82 -6
- package/dist/types/reference/scalar.d.ts +13 -0
- package/dist/types/reference/schema.d.ts +144 -36
- package/dist/types/search/adapters/registry.d.ts +3 -0
- package/dist/types/search/adapters/typesense.d.ts +14 -4
- package/dist/types/search/build.d.ts +3 -1
- package/dist/types/search/documents.d.ts +12 -1
- package/dist/types/search/orama-index.d.ts +13 -9
- package/dist/types/search/sync/algolia.d.ts +5 -2
- package/dist/types/search/sync/index.d.ts +3 -1
- package/dist/types/search/sync/typesense.d.ts +11 -7
- package/dist/types/seo/metatags.d.ts +20 -0
- package/dist/types/sources/contentful.d.ts +16 -0
- package/dist/types/sources/github-releases.d.ts +8 -1
- package/dist/types/sources/payload.d.ts +2 -0
- package/dist/types/sources/registry.d.ts +54 -0
- package/dist/types/sources/shared.d.ts +3 -0
- package/dist/types/sources/strapi.d.ts +2 -0
- package/docs/01-quickstart.mdx +4 -2
- package/docs/02-deployment.mdx +71 -17
- package/docs/03-upgrading.mdx +4 -4
- package/docs/04-migrating.mdx +1 -1
- package/docs/advanced/changelog.mdx +13 -2
- package/docs/advanced/skills.mdx +15 -1
- package/docs/cli/audit.mdx +51 -8
- package/docs/cli/doctor.mdx +5 -1
- package/docs/cli/evals.mdx +4 -4
- package/docs/cli/index.mdx +1 -0
- package/docs/cli/translate.mdx +1 -0
- package/docs/cli/validate.mdx +4 -3
- package/docs/configuration/analytics.mdx +3 -1
- package/docs/configuration/assistant.mdx +194 -38
- package/docs/configuration/consent.mdx +100 -0
- package/docs/configuration/customization.mdx +8 -6
- package/docs/configuration/export.mdx +5 -3
- package/docs/configuration/index.mdx +64 -5
- package/docs/configuration/meta.ts +3 -0
- package/docs/configuration/narration.mdx +119 -0
- package/docs/configuration/rate-limiting.mdx +90 -0
- package/docs/configuration/search.mdx +63 -12
- package/docs/configuration/theming.mdx +3 -1
- package/docs/content/components.mdx +108 -2
- package/docs/content/frontmatter.mdx +80 -2
- package/docs/content/i18n.mdx +39 -4
- 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 +32 -10
- package/docs/content/sources/contentful.mdx +35 -0
- package/docs/content/sources/custom.mdx +43 -0
- package/docs/content/sources/github-releases.mdx +39 -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 +31 -0
- package/docs/content/sources/remote-mdx.mdx +44 -0
- package/docs/content/sources/sanity.mdx +29 -0
- package/docs/content/sources/strapi.mdx +32 -0
- package/docs/content/syntax.mdx +69 -4
- package/docs/content/variables.mdx +41 -0
- package/docs/discoverability/agent-discovery.mdx +29 -2
- package/docs/discoverability/index.mdx +2 -2
- package/docs/discoverability/json-api.mdx +2 -0
- package/docs/discoverability/llms-txt.mdx +2 -2
- package/docs/discoverability/markdown.mdx +3 -1
- package/docs/discoverability/mcp.mdx +4 -0
- package/docs/discoverability/metadata.mdx +17 -0
- package/docs/discoverability/sitemap-and-robots.mdx +1 -1
- package/docs/references/api-pages.mdx +74 -0
- package/docs/references/asyncapi.mdx +4 -2
- package/docs/references/graphql.mdx +14 -2
- package/docs/references/meta.ts +1 -1
- package/docs/references/openapi.mdx +148 -7
- package/docs/references/scalar.mdx +3 -1
- package/package.json +43 -8
- package/skills/blume/SKILL.md +3 -0
- package/skills/blume-migrate/SKILL.md +6 -6
- package/skills/blume-migrate/references/docusaurus.md +7 -7
- package/skills/blume-migrate/references/fumadocs.md +17 -13
- package/skills/blume-migrate/references/mintlify.md +37 -19
- package/skills/blume-migrate/references/nextra.md +10 -7
- package/skills/blume-migrate/references/starlight.md +11 -8
- 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 +103 -20
- package/src/ai/ask-data.ts +6 -0
- package/src/ai/ask-limits.ts +13 -0
- package/src/ai/ask-tools.ts +142 -0
- package/src/ai/ask.ts +354 -76
- package/src/ai/changelog-markdown.ts +11 -6
- package/src/ai/component-markdown.ts +76 -1
- package/src/ai/cors.ts +14 -3
- 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/mcp/query.ts +14 -6
- package/src/ai/openapi-components.ts +36 -6
- package/src/ai/relative-links.ts +4 -38
- 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 +210 -66
- package/src/astro/index.ts +1 -0
- package/src/astro/integration.ts +42 -4
- package/src/astro/markdown-negotiation.ts +3 -0
- package/src/astro/module-types.ts +9 -1
- package/src/astro/pages.ts +23 -0
- package/src/astro/templates.ts +406 -108
- package/src/astro/variables.ts +31 -0
- package/src/audit/catalog.ts +38 -3
- 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 +19 -13
- package/src/audit/checks/network.ts +110 -6
- package/src/audit/checks/redirects.ts +6 -4
- package/src/audit/checks/robots.ts +58 -2
- package/src/audit/checks/sitemap.ts +2 -3
- package/src/audit/redirects.ts +46 -15
- package/src/audit/run.ts +5 -0
- package/src/audit/types.ts +4 -1
- package/src/audit/url.ts +14 -5
- package/src/blume-modules.d.ts +12 -1
- 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/args.ts +51 -0
- package/src/cli/build-failure.ts +23 -0
- package/src/cli/command-meta.ts +5 -0
- package/src/cli/commands/audit.ts +10 -1
- package/src/cli/commands/dev.ts +18 -2
- package/src/cli/commands/doctor.ts +67 -28
- package/src/cli/commands/eval.ts +36 -4
- package/src/cli/commands/init.ts +6 -4
- package/src/cli/commands/skill.ts +96 -0
- package/src/cli/commands/validate.ts +10 -1
- package/src/cli/index.ts +5 -0
- package/src/cli/init/scaffold.ts +3 -3
- package/src/cli/prepare.ts +6 -3
- package/src/cli/required-secrets.ts +72 -30
- 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 +66 -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 +103 -0
- package/src/components/content/api-page.ts +248 -0
- package/src/components/content/mermaid-element.ts +15 -1
- 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 +136 -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/PageActions.astro +139 -24
- 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 +318 -47
- package/src/components/layout/Search.astro +47 -19
- package/src/components/layout/SiteFooter.astro +124 -0
- package/src/components/layout/SiteMetatags.astro +16 -0
- package/src/components/layout/TableOfContents.astro +24 -17
- 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/head-scripts.ts +6 -1
- 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/algolia.ts +10 -1
- package/src/components/layout/search/analytics.ts +126 -0
- package/src/components/layout/search/endpoint.ts +48 -5
- package/src/components/layout/search/flexsearch.ts +17 -5
- package/src/components/layout/search/orama-cloud.ts +26 -14
- package/src/components/layout/search/pagefind.ts +114 -5
- package/src/components/layout/search/types.ts +32 -0
- package/src/components/layout/search/typesense.ts +19 -3
- package/src/components/openapi/AsyncApiOperation.astro +14 -7
- package/src/components/openapi/Authorization.astro +10 -0
- package/src/components/openapi/GraphqlOperation.astro +5 -0
- package/src/components/openapi/Operation.astro +184 -13
- package/src/components/openapi/ParametersTable.astro +8 -4
- package/src/components/openapi/Playground.astro +7 -1
- package/src/components/openapi/RequestBody.astro +24 -5
- package/src/components/openapi/RequestPanel.astro +59 -7
- package/src/components/openapi/Responses.astro +7 -4
- package/src/components/openapi/SchemaTable.astro +15 -3
- package/src/components/openapi/async-snippets.ts +65 -9
- package/src/components/openapi/async.ts +123 -29
- package/src/components/openapi/code-samples.ts +97 -0
- package/src/components/openapi/graphql-helpers.ts +35 -12
- package/src/components/openapi/helpers.ts +36 -2
- package/src/components/openapi/message-model.ts +54 -11
- package/src/components/openapi/message.ts +14 -4
- package/src/components/openapi/operation-model.ts +16 -7
- package/src/components/openapi/playground-client.ts +24 -5
- package/src/components/openapi/playground-schema.ts +1 -1
- package/src/components/openapi/schema-tree.ts +44 -14
- package/src/components/openapi/security.ts +16 -3
- package/src/components/openapi/snippets.ts +873 -10
- package/src/components/openapi/validate-json.ts +4 -3
- 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/changelog-index.ts +31 -1
- package/src/core/client-address.ts +19 -0
- package/src/core/component-diagnostics.ts +53 -0
- package/src/core/component-overrides.ts +32 -0
- package/src/core/config-input.ts +225 -23
- package/src/core/data.ts +46 -4
- package/src/core/diagnostics.ts +8 -2
- package/src/core/footer.ts +26 -0
- package/src/core/graph.ts +39 -36
- package/src/core/i18n-ui.ts +84 -2
- package/src/core/includes.ts +21 -4
- package/src/core/links.ts +63 -19
- 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/probe.ts +26 -6
- package/src/core/project-graph.ts +163 -16
- package/src/core/redirect-patterns.ts +520 -0
- package/src/core/related.ts +131 -0
- package/src/core/schema.ts +339 -66
- package/src/core/sources/cache.ts +6 -0
- package/src/core/sources/contentful-rich-text.ts +29 -6
- package/src/core/sources/contentful.ts +135 -25
- package/src/core/sources/filesystem.ts +26 -4
- package/src/core/sources/github-releases.ts +12 -1
- package/src/core/sources/lexical.ts +15 -10
- package/src/core/sources/mdx-remote.ts +62 -10
- package/src/core/sources/normalize.ts +228 -41
- package/src/core/sources/notion.ts +7 -1
- package/src/core/sources/obsidian.ts +16 -3
- package/src/core/sources/payload.ts +38 -15
- package/src/core/sources/read.ts +8 -3
- package/src/core/sources/remote.ts +72 -15
- package/src/core/sources/resolve.ts +11 -1
- package/src/core/sources/sanity.ts +43 -25
- package/src/core/sources/strapi.ts +2 -2
- package/src/core/types.ts +19 -1
- package/src/core/ui-packs/ar.ts +44 -0
- package/src/core/ui-packs/bg.ts +46 -0
- package/src/core/ui-packs/bn.ts +44 -0
- package/src/core/ui-packs/ca.ts +47 -0
- package/src/core/ui-packs/cs.ts +45 -0
- package/src/core/ui-packs/da.ts +46 -0
- package/src/core/ui-packs/de.ts +47 -0
- package/src/core/ui-packs/el.ts +46 -0
- package/src/core/ui-packs/es.ts +47 -0
- package/src/core/ui-packs/fa.ts +46 -0
- package/src/core/ui-packs/fi.ts +46 -0
- package/src/core/ui-packs/fr.ts +47 -0
- package/src/core/ui-packs/he.ts +44 -0
- package/src/core/ui-packs/hi.ts +45 -0
- package/src/core/ui-packs/hr.ts +46 -0
- package/src/core/ui-packs/hu.ts +45 -0
- package/src/core/ui-packs/id.ts +46 -0
- package/src/core/ui-packs/it.ts +46 -0
- package/src/core/ui-packs/ja.ts +46 -0
- package/src/core/ui-packs/ko.ts +45 -0
- package/src/core/ui-packs/nl.ts +47 -0
- package/src/core/ui-packs/no.ts +45 -0
- package/src/core/ui-packs/pl.ts +46 -0
- package/src/core/ui-packs/pt-br.ts +47 -0
- package/src/core/ui-packs/pt.ts +46 -0
- package/src/core/ui-packs/ro.ts +46 -0
- package/src/core/ui-packs/ru.ts +46 -0
- package/src/core/ui-packs/sk.ts +45 -0
- package/src/core/ui-packs/sr.ts +46 -0
- package/src/core/ui-packs/sv.ts +45 -0
- package/src/core/ui-packs/th.ts +44 -0
- package/src/core/ui-packs/tr.ts +46 -0
- package/src/core/ui-packs/uk.ts +46 -0
- package/src/core/ui-packs/vi.ts +46 -0
- package/src/core/ui-packs/zh-tw.ts +44 -0
- package/src/core/ui-packs/zh.ts +44 -0
- package/src/core/variables.ts +103 -0
- package/src/deploy/adapter-output.ts +7 -2
- package/src/deploy/adapters/cloudflare.ts +7 -5
- package/src/deploy/adapters/node.ts +47 -9
- package/src/deploy/adapters/types.ts +7 -3
- package/src/deploy/artifacts.ts +79 -9
- 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 +45 -9
- package/src/deploy/platforms/netlify.ts +35 -2
- package/src/deploy/platforms/node.ts +12 -2
- package/src/deploy/platforms/types.ts +21 -7
- package/src/deploy/platforms/vercel.ts +149 -17
- package/src/deploy/redirects.ts +151 -24
- package/src/deploy/rss.ts +3 -1
- package/src/deploy/sitemap.ts +39 -5
- package/src/deploy/vercel-negotiation.ts +326 -102
- package/src/eval/agents.ts +18 -1
- package/src/eval/prompts.ts +6 -3
- package/src/eval/report.ts +34 -13
- package/src/eval/run.ts +5 -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/relative-links.ts +3 -2
- 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/checks.ts +273 -0
- package/src/openapi/graphql-build.ts +21 -0
- package/src/openapi/graphql.ts +11 -0
- package/src/openapi/model.ts +72 -27
- package/src/openapi/overlay.ts +256 -0
- package/src/openapi/parse.ts +182 -4
- package/src/openapi/references.ts +64 -8
- package/src/openapi/render-mdx.ts +5 -1
- package/src/openapi/scalar.ts +40 -6
- package/src/openapi/source.ts +40 -15
- 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 +247 -0
- package/src/ratelimit/schema.ts +28 -0
- package/src/ratelimit/upstash.ts +60 -0
- package/src/ratelimit/wrangler.ts +70 -0
- package/src/reference/asyncapi.ts +2 -2
- package/src/reference/graphql.ts +20 -3
- package/src/reference/index.ts +1 -0
- package/src/reference/openapi.ts +21 -7
- package/src/reference/options.ts +80 -8
- package/src/reference/scalar.ts +33 -8
- package/src/registry/eject.ts +23 -5
- package/src/registry/registry.ts +7 -0
- package/src/search/adapters/locale-scope.ts +30 -0
- package/src/search/adapters/typesense.ts +14 -4
- package/src/search/build.ts +21 -3
- package/src/search/documents.ts +26 -2
- package/src/search/orama-index.ts +191 -34
- package/src/search/pagefind-ranking.ts +39 -0
- package/src/search/source-pages.ts +29 -0
- package/src/search/sync/algolia.ts +111 -10
- package/src/search/sync/index.ts +52 -13
- package/src/search/sync/orama-cloud.ts +3 -0
- package/src/search/sync/typesense.ts +76 -26
- package/src/seo/metatags.ts +67 -0
- package/src/sources/contentful.ts +12 -0
- package/src/sources/github-releases.ts +7 -1
- package/src/sources/shared.ts +3 -0
- package/src/theme/chrome-icons.ts +1 -0
- package/src/theme/color.ts +500 -0
- package/src/theme/entry.ts +85 -6
- package/src/theme/palette.ts +121 -45
- package/src/translate/prompts.ts +1 -0
- package/src/translate/validate.ts +31 -3
- package/src/upgrade/upgrade.ts +4 -171
- package/dist/cli/chunk-1d7ve1dm.js.map +0 -12
- package/dist/cli/chunk-2hsdwb9n.js.map +0 -10
- package/dist/cli/chunk-35d4wj9f.js.map +0 -15
- 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-8ktnccpt.js.map +0 -10
- package/dist/cli/chunk-9t7a85s3.js.map +0 -10
- package/dist/cli/chunk-b07cmahc.js +0 -145
- package/dist/cli/chunk-b07cmahc.js.map +0 -11
- package/dist/cli/chunk-c8chx29p.js.map +0 -36
- package/dist/cli/chunk-e04dxsz1.js +0 -39
- package/dist/cli/chunk-e04dxsz1.js.map +0 -10
- package/dist/cli/chunk-j85vccga.js.map +0 -36
- package/dist/cli/chunk-p3v96n38.js.map +0 -10
- 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-vg9r4eb9.js.map +0 -14
- 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-tkacnehg.js.map → chunk-3v3ffbrj.js.map} +0 -0
- /package/dist/cli/{chunk-r9rcc4w7.js.map → chunk-8y2kmjv8.js.map} +0 -0
- /package/dist/cli/{chunk-2eytanqx.js.map → chunk-c887fj0s.js.map} +0 -0
- /package/dist/cli/{chunk-akbpwfxc.js.map → chunk-dzwehpy7.js.map} +0 -0
- /package/dist/cli/{chunk-2z928egk.js.map → chunk-ft9vfys6.js.map} +0 -0
- /package/dist/cli/{chunk-a58773jm.js.map → chunk-kma9f6sf.js.map} +0 -0
- /package/dist/cli/{chunk-crgn1q09.js.map → chunk-sds923fa.js.map} +0 -0
- /package/dist/cli/{chunk-acanzt5p.js.map → chunk-tdqhyxfz.js.map} +0 -0
package/src/core/graph.ts
CHANGED
|
@@ -4,6 +4,7 @@ import {
|
|
|
4
4
|
localizeRoute,
|
|
5
5
|
resolveFallbackLocale,
|
|
6
6
|
} from "./i18n.ts";
|
|
7
|
+
import { resolveLocalizable } from "./localizable.ts";
|
|
7
8
|
import {
|
|
8
9
|
validateNavIcons,
|
|
9
10
|
validateNavStructure,
|
|
@@ -97,31 +98,6 @@ const localePagesFor = (
|
|
|
97
98
|
return [...real, ...filled];
|
|
98
99
|
};
|
|
99
100
|
|
|
100
|
-
/**
|
|
101
|
-
* Resolve a possibly-per-locale header label to the string a locale renders:
|
|
102
|
-
* the active locale's entry, else the default locale's, else the map's first
|
|
103
|
-
* entry (which is also what a single-locale site gets).
|
|
104
|
-
*/
|
|
105
|
-
/** A label is either one string for every locale or a per-locale map. */
|
|
106
|
-
const isSingleLabel = (label: LocalizableLabel): label is string =>
|
|
107
|
-
typeof label === "string";
|
|
108
|
-
|
|
109
|
-
const resolveLabel = (
|
|
110
|
-
label: LocalizableLabel,
|
|
111
|
-
locale: string,
|
|
112
|
-
defaultLocale?: string
|
|
113
|
-
): string => {
|
|
114
|
-
if (isSingleLabel(label)) {
|
|
115
|
-
return label;
|
|
116
|
-
}
|
|
117
|
-
return (
|
|
118
|
-
label[locale] ??
|
|
119
|
-
(defaultLocale === undefined ? undefined : label[defaultLocale]) ??
|
|
120
|
-
Object.values(label)[0] ??
|
|
121
|
-
""
|
|
122
|
-
);
|
|
123
|
-
};
|
|
124
|
-
|
|
125
101
|
/**
|
|
126
102
|
* An explicit sidebar with every item's `href` passed through `localize` (page
|
|
127
103
|
* refs and `root`s resolve against each locale's own pages already).
|
|
@@ -154,11 +130,36 @@ const resolveTabLabels = (
|
|
|
154
130
|
...tab,
|
|
155
131
|
items: tab.items?.map((item) => ({
|
|
156
132
|
...item,
|
|
157
|
-
label:
|
|
133
|
+
label: resolveLocalizable(item.label, locale, defaultLocale),
|
|
158
134
|
})),
|
|
159
|
-
label:
|
|
135
|
+
label: resolveLocalizable(tab.label, locale, defaultLocale),
|
|
160
136
|
}));
|
|
161
137
|
|
|
138
|
+
/** A configured header or footer link with its label resolved for a locale. */
|
|
139
|
+
const withLabel = <T extends { label: LocalizableLabel }>(
|
|
140
|
+
link: T,
|
|
141
|
+
locale: string,
|
|
142
|
+
defaultLocale?: string
|
|
143
|
+
): Omit<T, "label"> & { label: string } => ({
|
|
144
|
+
...link,
|
|
145
|
+
label: resolveLocalizable(link.label, locale, defaultLocale),
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
/** The configured header links (plain, call to action, featured) in `locale`. */
|
|
149
|
+
const resolveHeaderLinks = (
|
|
150
|
+
navigation: BuildContentGraphOptions["navigation"],
|
|
151
|
+
locale: string,
|
|
152
|
+
defaultLocale?: string
|
|
153
|
+
) => ({
|
|
154
|
+
actions: navigation.actions.map((link) =>
|
|
155
|
+
withLabel(link, locale, defaultLocale)
|
|
156
|
+
),
|
|
157
|
+
cta: navigation.cta ? withLabel(navigation.cta, locale, defaultLocale) : null,
|
|
158
|
+
featured: navigation.featured.map((link) =>
|
|
159
|
+
withLabel(link, locale, defaultLocale)
|
|
160
|
+
),
|
|
161
|
+
});
|
|
162
|
+
|
|
162
163
|
/**
|
|
163
164
|
* Mount a configured link authored as if the site were served at root (the
|
|
164
165
|
* banner's): under `basePath`, except a route served outside the content tree
|
|
@@ -274,18 +275,22 @@ const buildLocaleNavigation = (
|
|
|
274
275
|
...item,
|
|
275
276
|
href: localizeServed(item.href, false),
|
|
276
277
|
});
|
|
277
|
-
const { actions, cta, featured } =
|
|
278
|
+
const { actions, cta, featured } = resolveHeaderLinks(
|
|
279
|
+
options.navigation,
|
|
280
|
+
code,
|
|
281
|
+
i18n.defaultLocale
|
|
282
|
+
);
|
|
278
283
|
const sidebarItems = options.navigation.sidebar.items;
|
|
279
284
|
|
|
280
285
|
const navigation = buildNavigation(localePages, {
|
|
281
|
-
actions: actions
|
|
286
|
+
actions: actions.map(localizeHref),
|
|
282
287
|
basePath,
|
|
283
288
|
cta: cta ? localizeHref(cta) : null,
|
|
284
289
|
diagnostics,
|
|
285
290
|
display: options.navigation.sidebar.display,
|
|
286
291
|
extraRoutes: options.extraRoutes,
|
|
287
292
|
fallbackMetaPrefix,
|
|
288
|
-
featured: featured
|
|
293
|
+
featured: featured.map(localizeHref),
|
|
289
294
|
folderMeta: options.folderMeta,
|
|
290
295
|
// The localized tree root ("/" for the hidden default, "/fr" otherwise;
|
|
291
296
|
// "/fr/v1.0" inside a snapshot): the tab pointing here spans the whole
|
|
@@ -415,13 +420,11 @@ const buildVersionNavigation = (
|
|
|
415
420
|
}
|
|
416
421
|
return {
|
|
417
422
|
"": buildNavigation(versionPages, {
|
|
418
|
-
|
|
423
|
+
...resolveHeaderLinks(options.navigation, ""),
|
|
419
424
|
basePath: options.basePath ?? "",
|
|
420
|
-
cta: options.navigation.cta,
|
|
421
425
|
diagnostics,
|
|
422
426
|
display: options.navigation.sidebar.display,
|
|
423
427
|
extraRoutes: options.extraRoutes,
|
|
424
|
-
featured: options.navigation.featured,
|
|
425
428
|
folderMeta: options.folderMeta,
|
|
426
429
|
localizedRoot: versionizeRoute("/", id),
|
|
427
430
|
metaPrefix: id,
|
|
@@ -465,13 +468,13 @@ export const buildContentGraph = (
|
|
|
465
468
|
));
|
|
466
469
|
} else {
|
|
467
470
|
navigation = buildNavigation(currentPages, {
|
|
468
|
-
|
|
471
|
+
// No locale to prefer: a per-locale label map resolves to its first
|
|
472
|
+
// entry on a single-locale site.
|
|
473
|
+
...resolveHeaderLinks(options.navigation, ""),
|
|
469
474
|
basePath: options.basePath ?? "",
|
|
470
|
-
cta: options.navigation.cta,
|
|
471
475
|
diagnostics,
|
|
472
476
|
display: options.navigation.sidebar.display,
|
|
473
477
|
extraRoutes: options.extraRoutes,
|
|
474
|
-
featured: options.navigation.featured,
|
|
475
478
|
folderMeta: options.folderMeta,
|
|
476
479
|
selectors: options.navigation.selectors,
|
|
477
480
|
sharedFolderMeta: options.sharedFolderMeta,
|
package/src/core/i18n-ui.ts
CHANGED
|
@@ -15,6 +15,8 @@ const uiStringsObject = z.object({
|
|
|
15
15
|
.object({
|
|
16
16
|
addToCursor: z.string().default("Add to Cursor"),
|
|
17
17
|
addToVscode: z.string().default("Add to VS Code"),
|
|
18
|
+
// A code block's button that opens the assistant with the code attached.
|
|
19
|
+
askAboutCode: z.string().default("Ask about this code"),
|
|
18
20
|
connectMcp: z.string().default("Connect to MCP"),
|
|
19
21
|
copied: z.string().default("Copied!"),
|
|
20
22
|
copyClaudeCode: z.string().default("Copy Claude Code command"),
|
|
@@ -47,11 +49,32 @@ const uiStringsObject = z.object({
|
|
|
47
49
|
copy: z.string().default("Copy conversation"),
|
|
48
50
|
empty: z.string().default("Ask a question about the docs."),
|
|
49
51
|
error: z.string().default("Sorry, something went wrong."),
|
|
52
|
+
// The question sent about an attached code block when the reader
|
|
53
|
+
// writes none.
|
|
54
|
+
explainCode: z.string().default("Explain this code."),
|
|
50
55
|
label: z.string().default("Ask a question"),
|
|
56
|
+
// The header trigger's tooltip.
|
|
57
|
+
open: z.string().default("Open assistant"),
|
|
51
58
|
placeholder: z.string().default("Ask a question…"),
|
|
59
|
+
// The answer when the rate limit (`rateLimit`) turns a question away.
|
|
60
|
+
rateLimited: z
|
|
61
|
+
.string()
|
|
62
|
+
.default(
|
|
63
|
+
"You've asked a lot of questions. Try again in a few minutes."
|
|
64
|
+
),
|
|
65
|
+
// The attached code block's dismiss button.
|
|
66
|
+
removeCode: z.string().default("Remove code"),
|
|
52
67
|
send: z.string().default("Send"),
|
|
68
|
+
// The link to your support channel (`ai.assistant.support`), and the
|
|
69
|
+
// subject of an email it starts.
|
|
70
|
+
support: z.string().default("Contact support"),
|
|
71
|
+
supportSubject: z.string().default("Question from the docs"),
|
|
53
72
|
tip: z.string().default("Tip: You can open and close chat with"),
|
|
54
73
|
title: z.string().default("Assistant"),
|
|
74
|
+
// The answer when the bot check (`ai.assistant.captcha`) fails.
|
|
75
|
+
verifyFailed: z
|
|
76
|
+
.string()
|
|
77
|
+
.default("We couldn't check that you're human. Try again."),
|
|
55
78
|
you: z.string().default("You"),
|
|
56
79
|
})
|
|
57
80
|
.prefault({}),
|
|
@@ -67,9 +90,28 @@ const uiStringsObject = z.object({
|
|
|
67
90
|
.default(
|
|
68
91
|
"Product updates, new features, and fixes from every release."
|
|
69
92
|
),
|
|
93
|
+
// What the index says when it has no entries to list.
|
|
94
|
+
empty: z.string().default("No changelog entries yet."),
|
|
70
95
|
title: z.string().default("Changelog"),
|
|
71
96
|
})
|
|
72
97
|
.prefault({}),
|
|
98
|
+
// The built-in cookie consent banner (`consent: native()`) and the footer
|
|
99
|
+
// link that reopens a consent manager's preferences.
|
|
100
|
+
consent: z
|
|
101
|
+
.object({
|
|
102
|
+
accept: z.string().default("Accept"),
|
|
103
|
+
decline: z.string().default("Decline"),
|
|
104
|
+
// The banner's accessible name.
|
|
105
|
+
label: z.string().default("Cookie consent"),
|
|
106
|
+
message: z
|
|
107
|
+
.string()
|
|
108
|
+
.default(
|
|
109
|
+
"We'd like to use cookies to understand how these docs are used."
|
|
110
|
+
),
|
|
111
|
+
policy: z.string().default("Privacy policy"),
|
|
112
|
+
settings: z.string().default("Cookie settings"),
|
|
113
|
+
})
|
|
114
|
+
.prefault({}),
|
|
73
115
|
content: z
|
|
74
116
|
.object({
|
|
75
117
|
// `<Component>`'s source tab.
|
|
@@ -89,7 +131,12 @@ const uiStringsObject = z.object({
|
|
|
89
131
|
prop: z.string().default("Prop"),
|
|
90
132
|
// `<Tabs dropdown>`: the accessible name of the tab picker.
|
|
91
133
|
selectTab: z.string().default("Select tab"),
|
|
92
|
-
// `<
|
|
134
|
+
// `<View>`: the accessible name of the page's view picker.
|
|
135
|
+
selectView: z.string().default("Select view"),
|
|
136
|
+
// An expanded `expandable` code block's toggle.
|
|
137
|
+
showLess: z.string().default("Show less"),
|
|
138
|
+
// `<Expandable>`'s toggle when it sets no `title`, and a collapsed
|
|
139
|
+
// `expandable` code block's.
|
|
93
140
|
showMore: z.string().default("Show more"),
|
|
94
141
|
stars: z.string().default("Stars"),
|
|
95
142
|
// An untitled tab's label; `{n}` is replaced with its position.
|
|
@@ -102,8 +149,11 @@ const uiStringsObject = z.object({
|
|
|
102
149
|
.prefault({}),
|
|
103
150
|
feedback: z
|
|
104
151
|
.object({
|
|
152
|
+
// The written comment box after the rating (`feedback.comments`).
|
|
153
|
+
comment: z.string().default("Tell us more (optional)"),
|
|
105
154
|
no: z.string().default("No"),
|
|
106
155
|
question: z.string().default("Was this page helpful?"),
|
|
156
|
+
send: z.string().default("Send"),
|
|
107
157
|
thanks: z.string().default("Thanks for your feedback!"),
|
|
108
158
|
yes: z.string().default("Yes"),
|
|
109
159
|
})
|
|
@@ -114,6 +164,36 @@ const uiStringsObject = z.object({
|
|
|
114
164
|
untranslated: z.string().default("Not translated"),
|
|
115
165
|
})
|
|
116
166
|
.prefault({}),
|
|
167
|
+
narration: z
|
|
168
|
+
.object({
|
|
169
|
+
// Spoken, not shown: the cues that introduce a callout of each type, a
|
|
170
|
+
// step (`{n}` is its number), a tab (`{title}` is its label), and a
|
|
171
|
+
// collapsible section. End each with a full stop so it reads as its own
|
|
172
|
+
// sentence.
|
|
173
|
+
cueDanger: z.string().default("Danger."),
|
|
174
|
+
cueInfo: z.string().default("Info."),
|
|
175
|
+
cueNote: z.string().default("Note."),
|
|
176
|
+
cueSection: z.string().default("Expandable section."),
|
|
177
|
+
cueStep: z.string().default("Step {n}."),
|
|
178
|
+
cueSuccess: z.string().default("Success."),
|
|
179
|
+
cueTab: z.string().default("{title} tab."),
|
|
180
|
+
cueTip: z.string().default("Tip."),
|
|
181
|
+
cueWarning: z.string().default("Warning."),
|
|
182
|
+
error: z.string().default("The narration couldn't load."),
|
|
183
|
+
// Resumes following the sentence being read after the reader scrolls away.
|
|
184
|
+
follow: z.string().default("Follow along"),
|
|
185
|
+
label: z.string().default("Listen to this page"),
|
|
186
|
+
// The estimated listening time; `{n}` is whole minutes.
|
|
187
|
+
minutes: z.string().default("{n} min"),
|
|
188
|
+
next: z.string().default("Next sentence"),
|
|
189
|
+
pause: z.string().default("Pause"),
|
|
190
|
+
play: z.string().default("Play"),
|
|
191
|
+
previous: z.string().default("Previous sentence"),
|
|
192
|
+
progress: z.string().default("Narration progress"),
|
|
193
|
+
speed: z.string().default("Playback speed"),
|
|
194
|
+
stop: z.string().default("Stop listening"),
|
|
195
|
+
})
|
|
196
|
+
.prefault({}),
|
|
117
197
|
nav: z
|
|
118
198
|
.object({
|
|
119
199
|
back: z.string().default("Back"),
|
|
@@ -128,7 +208,7 @@ const uiStringsObject = z.object({
|
|
|
128
208
|
primary: z.string().default("Primary"),
|
|
129
209
|
sections: z.string().default("Sections"),
|
|
130
210
|
toggleNavigation: z.string().default("Toggle navigation"),
|
|
131
|
-
toggleTheme: z.string().default("Toggle
|
|
211
|
+
toggleTheme: z.string().default("Toggle theme"),
|
|
132
212
|
})
|
|
133
213
|
.prefault({}),
|
|
134
214
|
notFound: z
|
|
@@ -154,6 +234,8 @@ const uiStringsObject = z.object({
|
|
|
154
234
|
next: z.string().default("Next"),
|
|
155
235
|
pagination: z.string().default("Pagination"),
|
|
156
236
|
previous: z.string().default("Previous"),
|
|
237
|
+
// The heading over a page's `related` links.
|
|
238
|
+
related: z.string().default("Related pages"),
|
|
157
239
|
skipToContent: z.string().default("Skip to content"),
|
|
158
240
|
})
|
|
159
241
|
.prefault({}),
|
package/src/core/includes.ts
CHANGED
|
@@ -7,6 +7,7 @@ import type { FenceState } from "./code-fences.ts";
|
|
|
7
7
|
import matter from "./frontmatter.ts";
|
|
8
8
|
import { INLINE_CODE, MD_IMAGE, targetOffsetIn } from "./sources/normalize.ts";
|
|
9
9
|
import type { Diagnostic } from "./types.ts";
|
|
10
|
+
import { substituteVariables } from "./variables.ts";
|
|
10
11
|
|
|
11
12
|
/**
|
|
12
13
|
* Content includes: `<include>./relative.mdx</include>` on a line of its own
|
|
@@ -98,6 +99,12 @@ export interface IncludeAttributes {
|
|
|
98
99
|
lang?: string;
|
|
99
100
|
/** Fence meta string in code-block mode (e.g. `title="lib.ts"`). */
|
|
100
101
|
meta?: string;
|
|
102
|
+
/**
|
|
103
|
+
* Every other attribute with a value: the snippet's own variables.
|
|
104
|
+
* `<include plan="Pro">` makes `{{plan}}` in the included file read `Pro`,
|
|
105
|
+
* ahead of any site-wide variable of the same name.
|
|
106
|
+
*/
|
|
107
|
+
props?: Record<string, string>;
|
|
101
108
|
}
|
|
102
109
|
|
|
103
110
|
/** A parsed include statement. */
|
|
@@ -108,8 +115,8 @@ export interface IncludeStatement {
|
|
|
108
115
|
|
|
109
116
|
/**
|
|
110
117
|
* Parse one trimmed line as an include statement, or `null` when it isn't
|
|
111
|
-
* one.
|
|
112
|
-
*
|
|
118
|
+
* one. `lang` and `meta` shape a code include; every other attribute with a
|
|
119
|
+
* value becomes a prop, a variable scoped to the included file.
|
|
113
120
|
*/
|
|
114
121
|
export const parseIncludeStatement = (
|
|
115
122
|
line: string
|
|
@@ -128,6 +135,9 @@ export const parseIncludeStatement = (
|
|
|
128
135
|
if (name === "meta" && value) {
|
|
129
136
|
attributes.meta = value;
|
|
130
137
|
}
|
|
138
|
+
if (name && name !== "lang" && name !== "meta" && value !== undefined) {
|
|
139
|
+
attributes.props = { ...attributes.props, [name]: value };
|
|
140
|
+
}
|
|
131
141
|
}
|
|
132
142
|
return { attributes, target: match.groups.target ?? "" };
|
|
133
143
|
};
|
|
@@ -232,7 +242,7 @@ export const malformedIncludeDiagnostic = (
|
|
|
232
242
|
"This <include> isn't a statement Blume can read, so the page shows it as written.",
|
|
233
243
|
severity: "warning",
|
|
234
244
|
suggestion:
|
|
235
|
-
|
|
245
|
+
'Write <include>./path.mdx</include> on a line of its own, or wrap it with the path on its own line and no blank lines. Attributes take lowercase names and quoted values (plan="Pro"): lang and meta shape a code include, and any other is a prop the included file reads as {{name}}.',
|
|
236
246
|
});
|
|
237
247
|
|
|
238
248
|
/**
|
|
@@ -519,8 +529,15 @@ const expandStatement = async (
|
|
|
519
529
|
lines.shift();
|
|
520
530
|
origins.shift();
|
|
521
531
|
}
|
|
532
|
+
// Props replace their `{{name}}` references line by line, so every line
|
|
533
|
+
// keeps its origin; they reach the file's own nested includes too.
|
|
534
|
+
const { props } = statement.attributes;
|
|
522
535
|
return {
|
|
523
|
-
lines: rebaseImages(
|
|
536
|
+
lines: rebaseImages(
|
|
537
|
+
props ? lines.map((text) => substituteVariables(text, props)) : lines,
|
|
538
|
+
dirname(path),
|
|
539
|
+
dirname(filePath)
|
|
540
|
+
),
|
|
524
541
|
origins,
|
|
525
542
|
};
|
|
526
543
|
};
|
package/src/core/links.ts
CHANGED
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
import type { LocaleRouting } from "./i18n.ts";
|
|
11
11
|
import { localizeLinkPath } from "./locale-links.ts";
|
|
12
12
|
import { gradeExternal, probeAll } from "./probe.ts";
|
|
13
|
+
import { isPatternPath, pathsUnderPattern } from "./redirect-patterns.ts";
|
|
13
14
|
import type {
|
|
14
15
|
ContentGraph,
|
|
15
16
|
Diagnostic,
|
|
@@ -87,6 +88,8 @@ interface LinkContext {
|
|
|
87
88
|
publicDir: string | null;
|
|
88
89
|
/** Normalized `redirect.from` paths — valid targets that resolve at runtime. */
|
|
89
90
|
redirects: Set<string>;
|
|
91
|
+
/** Pattern `redirect.from`s (`/beta/:slug*`), based like `redirects`. */
|
|
92
|
+
redirectPatterns: string[];
|
|
90
93
|
routes: Set<string>;
|
|
91
94
|
}
|
|
92
95
|
|
|
@@ -309,10 +312,13 @@ const checkPathLink = (
|
|
|
309
312
|
): LinkResult => {
|
|
310
313
|
// Page routes carry the site-wide base; an absolute author path is written
|
|
311
314
|
// as if mounted at root, so base it for the route lookup (idempotent — a
|
|
312
|
-
// relative link already resolved against the based `page.route`). A
|
|
313
|
-
//
|
|
314
|
-
//
|
|
315
|
-
|
|
315
|
+
// relative link already resolved against the based `page.route`). A raw
|
|
316
|
+
// `<a href>` ships unbased, so it's looked up as written. A real route
|
|
317
|
+
// always wins over the asset-extension heuristic, so a dotted route (e.g.
|
|
318
|
+
// `/releases/v1.0`) isn't misread as a missing asset.
|
|
319
|
+
const authoredRoute = toRoute(
|
|
320
|
+
link.raw ? resolved : withBasePath(ctx.basePath, resolved)
|
|
321
|
+
);
|
|
316
322
|
const route = servedRoute(authoredRoute, page, ctx);
|
|
317
323
|
if (ctx.routes.has(route)) {
|
|
318
324
|
return fragment ? checkAnchor(route, fragment, site, ctx, via) : null;
|
|
@@ -322,10 +328,16 @@ const checkPathLink = (
|
|
|
322
328
|
if (ctx.extraRoutes.has(route)) {
|
|
323
329
|
return null;
|
|
324
330
|
}
|
|
325
|
-
// A configured `redirect.from
|
|
331
|
+
// A configured `redirect.from`, or a path a pattern `from` covers, resolves
|
|
332
|
+
// at runtime, so it's a valid target.
|
|
326
333
|
// Its destination (and any anchor there) is validated on its own page, so we
|
|
327
334
|
// don't follow the redirect to check the fragment here.
|
|
328
|
-
if (
|
|
335
|
+
if (
|
|
336
|
+
ctx.redirects.has(route) ||
|
|
337
|
+
ctx.redirectPatterns.some(
|
|
338
|
+
(from) => pathsUnderPattern(from, [route]).length > 0
|
|
339
|
+
)
|
|
340
|
+
) {
|
|
329
341
|
return null;
|
|
330
342
|
}
|
|
331
343
|
|
|
@@ -427,6 +439,12 @@ export interface FileRouteIndex {
|
|
|
427
439
|
* into the reader's locale onto the fallback copy.
|
|
428
440
|
*/
|
|
429
441
|
byDefaultNavPath: Map<string, string>;
|
|
442
|
+
/**
|
|
443
|
+
* A staged page's entry id (`<source>/<ref>`) → its route. A remote
|
|
444
|
+
* source's files have no path on disk, so a file link between two of them
|
|
445
|
+
* (`./02-errors.mdx`) resolves by entry id, as the rendered link does.
|
|
446
|
+
*/
|
|
447
|
+
byEntryId: Map<string, string>;
|
|
430
448
|
}
|
|
431
449
|
|
|
432
450
|
/** The linking side of a file link: where the page's source lives. */
|
|
@@ -441,12 +459,19 @@ export const buildFileRouteIndex = (
|
|
|
441
459
|
): FileRouteIndex => {
|
|
442
460
|
const bySource = new Map<string, string>();
|
|
443
461
|
const byDefaultNavPath = new Map<string, string>();
|
|
462
|
+
const byEntryId = new Map<string, string>();
|
|
444
463
|
for (const page of pages) {
|
|
445
|
-
const { sourcePath } = page;
|
|
446
|
-
if (
|
|
464
|
+
const { entryId, sourcePath } = page;
|
|
465
|
+
if (page.fallback) {
|
|
447
466
|
continue;
|
|
448
467
|
}
|
|
449
468
|
const isDefault = page.locale === i18n?.defaultLocale;
|
|
469
|
+
if (entryId && (!byEntryId.has(entryId) || isDefault)) {
|
|
470
|
+
byEntryId.set(entryId, page.route);
|
|
471
|
+
}
|
|
472
|
+
if (!sourcePath) {
|
|
473
|
+
continue;
|
|
474
|
+
}
|
|
450
475
|
if (!bySource.has(sourcePath) || isDefault) {
|
|
451
476
|
bySource.set(sourcePath, page.route);
|
|
452
477
|
}
|
|
@@ -454,7 +479,7 @@ export const buildFileRouteIndex = (
|
|
|
454
479
|
byDefaultNavPath.set(normalize(page.navPath), page.route);
|
|
455
480
|
}
|
|
456
481
|
}
|
|
457
|
-
return { byDefaultNavPath, bySource };
|
|
482
|
+
return { byDefaultNavPath, byEntryId, bySource };
|
|
458
483
|
};
|
|
459
484
|
|
|
460
485
|
/**
|
|
@@ -483,11 +508,15 @@ const relativeTarget = (
|
|
|
483
508
|
ctx: LinkContext
|
|
484
509
|
): string => {
|
|
485
510
|
const base = { isIndex: isIndexPage(page), route: page.route };
|
|
486
|
-
const { navPath, sourcePath } = page;
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
511
|
+
const { entryId, navPath, sourcePath } = page;
|
|
512
|
+
let resolveFile: ((path: string) => string | undefined) | undefined;
|
|
513
|
+
if (sourcePath) {
|
|
514
|
+
resolveFile = (path) =>
|
|
515
|
+
routeOfLinkedFile(ctx.fileRoutes, { navPath, sourcePath }, path);
|
|
516
|
+
} else if (entryId) {
|
|
517
|
+
resolveFile = (path) =>
|
|
518
|
+
ctx.fileRoutes.byEntryId.get(normalize(join(dirname(entryId), path)));
|
|
519
|
+
}
|
|
491
520
|
return (
|
|
492
521
|
resolveRelativeHref(rawPath, base, resolveFile, (route) =>
|
|
493
522
|
ctx.routes.has(route)
|
|
@@ -546,9 +575,14 @@ const classifyLink = (
|
|
|
546
575
|
return fragment ? checkAnchor(page.route, fragment, site, ctx, via) : null;
|
|
547
576
|
}
|
|
548
577
|
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
578
|
+
let resolved = rawPath;
|
|
579
|
+
if (!rawPath.startsWith("/")) {
|
|
580
|
+
// A raw `<a href>` isn't rewritten, so the browser resolves it against
|
|
581
|
+
// the page's slashless URL: its parent directory, even on an index page.
|
|
582
|
+
resolved = link.raw
|
|
583
|
+
? resolveRelative(page.route, rawPath, false)
|
|
584
|
+
: relativeTarget(page, rawPath, ctx);
|
|
585
|
+
}
|
|
552
586
|
return checkPathLink(resolved, fragment, page, link, site, ctx, via);
|
|
553
587
|
};
|
|
554
588
|
|
|
@@ -573,6 +607,8 @@ export const validateLinks = async (
|
|
|
573
607
|
i18n?: LocaleRouting | null;
|
|
574
608
|
publicDir: string | null;
|
|
575
609
|
checkExternal?: boolean;
|
|
610
|
+
/** External URLs not to request (`--ignore`). Internal links are always checked. */
|
|
611
|
+
ignore?: (url: string) => boolean;
|
|
576
612
|
/** Configured redirects; their `from` paths count as valid link targets. */
|
|
577
613
|
redirects?: { from: string }[];
|
|
578
614
|
}
|
|
@@ -585,6 +621,11 @@ export const validateLinks = async (
|
|
|
585
621
|
fileRoutes: buildFileRouteIndex(graph.pages, options.i18n ?? null),
|
|
586
622
|
i18n: options.i18n ?? null,
|
|
587
623
|
publicDir: options.publicDir,
|
|
624
|
+
redirectPatterns: (options.redirects ?? []).flatMap((redirect) =>
|
|
625
|
+
isPatternPath(redirect.from)
|
|
626
|
+
? [withBasePath(basePath, redirect.from)]
|
|
627
|
+
: []
|
|
628
|
+
),
|
|
588
629
|
redirects: new Set(
|
|
589
630
|
(options.redirects ?? []).map((redirect) =>
|
|
590
631
|
toRoute(withBasePath(basePath, redirect.from))
|
|
@@ -615,8 +656,11 @@ export const validateLinks = async (
|
|
|
615
656
|
});
|
|
616
657
|
}
|
|
617
658
|
|
|
618
|
-
|
|
619
|
-
|
|
659
|
+
// `--ignore` names URLs that can't be checked from where this runs: a
|
|
660
|
+
// placeholder host, a local server, a site that turns bots away.
|
|
661
|
+
const probed = external.filter((ref) => !options.ignore?.(ref.url));
|
|
662
|
+
if (options.checkExternal && probed.length > 0) {
|
|
663
|
+
diagnostics.push(...(await checkExternalLinks(probed)));
|
|
620
664
|
}
|
|
621
665
|
|
|
622
666
|
// A partial spliced into several pages (or every locale of one) yields the
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { LocalizableLabel } from "./schema.ts";
|
|
2
|
+
|
|
3
|
+
/** A label is either one string for every locale or a per-locale map. */
|
|
4
|
+
const isSingleLabel = (label: LocalizableLabel): label is string =>
|
|
5
|
+
typeof label === "string";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Resolve a possibly-per-locale label to the string a locale renders: the
|
|
9
|
+
* active locale's entry, else the default locale's, else the map's first
|
|
10
|
+
* entry (which is also what a single-locale site gets).
|
|
11
|
+
*/
|
|
12
|
+
export const resolveLocalizable = (
|
|
13
|
+
label: LocalizableLabel,
|
|
14
|
+
locale?: string,
|
|
15
|
+
defaultLocale?: string
|
|
16
|
+
): string => {
|
|
17
|
+
if (isSingleLabel(label)) {
|
|
18
|
+
return label;
|
|
19
|
+
}
|
|
20
|
+
return (
|
|
21
|
+
(locale === undefined ? undefined : label[locale]) ??
|
|
22
|
+
(defaultLocale === undefined ? undefined : label[defaultLocale]) ??
|
|
23
|
+
Object.values(label)[0] ??
|
|
24
|
+
""
|
|
25
|
+
);
|
|
26
|
+
};
|
package/src/core/navigation.ts
CHANGED
|
@@ -3,6 +3,7 @@ import { extname } from "pathe";
|
|
|
3
3
|
import { stripBasePath, withBasePath } from "./base-path.ts";
|
|
4
4
|
import { orderingPrefix, stripOrderingPrefix } from "./ordering-prefix.ts";
|
|
5
5
|
import type {
|
|
6
|
+
DirectoryMode,
|
|
6
7
|
FolderMeta,
|
|
7
8
|
SidebarDisplay,
|
|
8
9
|
SidebarItemConfig,
|
|
@@ -202,6 +203,7 @@ interface MutableGroup {
|
|
|
202
203
|
label: string;
|
|
203
204
|
icon?: string;
|
|
204
205
|
collapsed?: boolean;
|
|
206
|
+
directory?: DirectoryMode;
|
|
205
207
|
display?: SidebarDisplay;
|
|
206
208
|
order: number;
|
|
207
209
|
/** Whether `order` is the node's position in its folder meta `pages` list. */
|
|
@@ -305,9 +307,19 @@ interface FallbackFolderMeta {
|
|
|
305
307
|
meta: (path: string) => FolderMeta | undefined;
|
|
306
308
|
}
|
|
307
309
|
|
|
310
|
+
/** A folder meta's own fields onto its group, over what the folder implied. */
|
|
311
|
+
const applyMetaFields = (group: MutableGroup, meta: FolderMeta): void => {
|
|
312
|
+
group.label = meta.title ?? group.label;
|
|
313
|
+
group.icon = meta.icon ?? group.icon;
|
|
314
|
+
group.order = meta.order ?? group.order;
|
|
315
|
+
group.collapsed = meta.collapsed ?? group.collapsed;
|
|
316
|
+
group.directory = meta.directory ?? group.directory;
|
|
317
|
+
};
|
|
318
|
+
|
|
308
319
|
/**
|
|
309
|
-
* Apply folder meta (title/order/icon/collapsed/display and
|
|
310
|
-
* order), plus the index-frontmatter display sugar collected
|
|
320
|
+
* Apply folder meta (title/order/icon/collapsed/display/directory and
|
|
321
|
+
* explicit page order), plus the index-frontmatter display sugar collected
|
|
322
|
+
* per folder path.
|
|
311
323
|
*/
|
|
312
324
|
const applyFolderMeta = (
|
|
313
325
|
group: MutableGroup,
|
|
@@ -346,10 +358,7 @@ const applyFolderMeta = (
|
|
|
346
358
|
(mirrored ? fallback.indexDisplay.get(group.path) : undefined) ??
|
|
347
359
|
meta?.display;
|
|
348
360
|
if (meta) {
|
|
349
|
-
group
|
|
350
|
-
group.icon = meta.icon ?? group.icon;
|
|
351
|
-
group.order = meta.order ?? group.order;
|
|
352
|
-
group.collapsed = meta.collapsed ?? group.collapsed;
|
|
361
|
+
applyMetaFields(group, meta);
|
|
353
362
|
}
|
|
354
363
|
|
|
355
364
|
for (const child of group.children) {
|
|
@@ -630,7 +639,15 @@ const hoistTabSections = (
|
|
|
630
639
|
}
|
|
631
640
|
};
|
|
632
641
|
|
|
633
|
-
|
|
642
|
+
/**
|
|
643
|
+
* A group's directory mode: its own, else the nearest one set above it (see
|
|
644
|
+
* `directory` in `schema.ts`).
|
|
645
|
+
*/
|
|
646
|
+
const toNavNode = (
|
|
647
|
+
node: MutableNode,
|
|
648
|
+
display: SidebarDisplay,
|
|
649
|
+
inheritedDirectory?: DirectoryMode
|
|
650
|
+
): NavNode => {
|
|
634
651
|
if (node.kind === "page") {
|
|
635
652
|
return {
|
|
636
653
|
badge: node.badge,
|
|
@@ -643,9 +660,13 @@ const toNavNode = (node: MutableNode, display: SidebarDisplay): NavNode => {
|
|
|
643
660
|
route: node.route,
|
|
644
661
|
};
|
|
645
662
|
}
|
|
663
|
+
const directory = node.directory ?? inheritedDirectory;
|
|
646
664
|
return {
|
|
647
|
-
children: node.children.map((child) =>
|
|
665
|
+
children: node.children.map((child) =>
|
|
666
|
+
toNavNode(child, display, directory)
|
|
667
|
+
),
|
|
648
668
|
collapsed: node.collapsed,
|
|
669
|
+
directory,
|
|
649
670
|
display: node.display ?? display,
|
|
650
671
|
icon: node.icon,
|
|
651
672
|
kind: "group",
|
|
@@ -805,7 +826,9 @@ const buildFileSystemSidebar = (
|
|
|
805
826
|
sortNodes(root.children, diagnostics);
|
|
806
827
|
hoistPages(root.children, display, true);
|
|
807
828
|
hoistTabSections(root.children, tabPaths, display);
|
|
808
|
-
return root.children.map((child) =>
|
|
829
|
+
return root.children.map((child) =>
|
|
830
|
+
toNavNode(child, display, root.directory)
|
|
831
|
+
);
|
|
809
832
|
};
|
|
810
833
|
|
|
811
834
|
/**
|
|
@@ -932,16 +955,24 @@ const buildConfigSidebar = (
|
|
|
932
955
|
items: SidebarItemConfig[],
|
|
933
956
|
byRoute: Map<string, PageRecord>,
|
|
934
957
|
display: SidebarDisplay,
|
|
935
|
-
basePath: string
|
|
958
|
+
basePath: string,
|
|
959
|
+
inheritedDirectory?: DirectoryMode
|
|
936
960
|
): NavNode[] => {
|
|
937
961
|
const nodes: NavNode[] = [];
|
|
938
962
|
for (const item of items) {
|
|
939
963
|
if (!isPageRef(item) && item.items) {
|
|
964
|
+
const directory = item.directory ?? inheritedDirectory;
|
|
940
965
|
nodes.push({
|
|
941
966
|
badge: item.badge,
|
|
942
|
-
children: buildConfigSidebar(
|
|
967
|
+
children: buildConfigSidebar(
|
|
968
|
+
item.items,
|
|
969
|
+
byRoute,
|
|
970
|
+
display,
|
|
971
|
+
basePath,
|
|
972
|
+
directory
|
|
973
|
+
),
|
|
943
974
|
collapsed: item.collapsed,
|
|
944
|
-
directory
|
|
975
|
+
directory,
|
|
945
976
|
display: item.display ?? display,
|
|
946
977
|
icon: item.icon,
|
|
947
978
|
kind: "group",
|