blume 2.0.1 → 2.0.3
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/CHANGELOG.md +147 -0
- package/dist/cli/{chunk-qwsrynx5.js → chunk-1d7ve1dm.js} +38 -19
- package/dist/cli/{chunk-qwsrynx5.js.map → chunk-1d7ve1dm.js.map} +4 -4
- package/dist/cli/{chunk-s6jhgk0q.js → chunk-2eytanqx.js} +2 -2
- package/dist/cli/{chunk-kdp5q7ke.js → chunk-2hsdwb9n.js} +18 -19
- package/dist/cli/{chunk-kdp5q7ke.js.map → chunk-2hsdwb9n.js.map} +2 -2
- package/dist/cli/{chunk-hdpx1tax.js → chunk-2z928egk.js} +5 -5
- package/dist/cli/{chunk-jwyddg7y.js → chunk-35d4wj9f.js} +30 -24
- package/dist/cli/chunk-35d4wj9f.js.map +15 -0
- package/dist/cli/{chunk-ah61y8py.js → chunk-364znk6q.js} +2 -2
- package/dist/cli/{chunk-jts8mvcz.js → chunk-3em5wd2y.js} +25 -6
- package/dist/cli/{chunk-jts8mvcz.js.map → chunk-3em5wd2y.js.map} +3 -3
- package/dist/cli/{chunk-s1p84fyh.js → chunk-5f86nr5m.js} +63 -22
- package/dist/cli/chunk-5f86nr5m.js.map +11 -0
- package/dist/cli/{chunk-2hn4b8z7.js → chunk-5m5nmvyq.js} +170 -76
- package/dist/cli/chunk-5m5nmvyq.js.map +13 -0
- package/dist/cli/{chunk-epjnccmv.js → chunk-5xvm6tfj.js} +18 -15
- package/dist/cli/chunk-5xvm6tfj.js.map +10 -0
- package/dist/cli/{chunk-fz5wtpmh.js → chunk-6dsbexzp.js} +18 -15
- package/dist/cli/chunk-6dsbexzp.js.map +10 -0
- package/dist/cli/{chunk-vtk4a6dg.js → chunk-8ktnccpt.js} +1 -1
- package/dist/cli/{chunk-6hsn950k.js → chunk-9t7a85s3.js} +178 -48
- package/dist/cli/chunk-9t7a85s3.js.map +10 -0
- package/dist/cli/{chunk-fxypxtvm.js → chunk-a58773jm.js} +2 -2
- package/dist/cli/{chunk-mb2919y2.js → chunk-acanzt5p.js} +17 -6
- package/dist/cli/chunk-acanzt5p.js.map +10 -0
- package/dist/cli/{chunk-27g6wdth.js → chunk-akbpwfxc.js} +90 -26
- package/dist/cli/chunk-akbpwfxc.js.map +10 -0
- package/dist/cli/{chunk-wm7js3j9.js → chunk-b07cmahc.js} +2 -2
- package/dist/cli/{chunk-wgm7m9qk.js → chunk-c8chx29p.js} +179 -51
- package/dist/cli/chunk-c8chx29p.js.map +36 -0
- package/dist/cli/{chunk-qs4q5p4e.js → chunk-crgn1q09.js} +32 -14
- package/dist/cli/chunk-crgn1q09.js.map +10 -0
- package/dist/cli/chunk-e04dxsz1.js +39 -0
- package/dist/cli/chunk-e04dxsz1.js.map +10 -0
- package/dist/cli/{chunk-yt5n7ppj.js → chunk-ey84smr6.js} +17 -7
- package/dist/cli/chunk-ey84smr6.js.map +10 -0
- package/dist/cli/{chunk-f2z5v128.js → chunk-g4hq16wv.js} +14 -15
- package/dist/cli/{chunk-f2z5v128.js.map → chunk-g4hq16wv.js.map} +2 -2
- package/dist/cli/{chunk-fa25z98p.js → chunk-ga0pf4aj.js} +9 -8
- package/dist/cli/chunk-ga0pf4aj.js.map +11 -0
- package/dist/cli/{chunk-kpf8rrjc.js → chunk-hm3vjy5s.js} +109 -58
- package/dist/cli/chunk-hm3vjy5s.js.map +19 -0
- package/dist/cli/{chunk-fs23ddbb.js → chunk-j85vccga.js} +625 -750
- package/dist/cli/chunk-j85vccga.js.map +36 -0
- package/dist/cli/{chunk-ch6g3ar0.js → chunk-p3v96n38.js} +6 -6
- package/dist/cli/{chunk-ch6g3ar0.js.map → chunk-p3v96n38.js.map} +3 -3
- package/dist/cli/{chunk-q5163e60.js → chunk-p73c0m7w.js} +21 -19
- package/dist/cli/chunk-p73c0m7w.js.map +11 -0
- package/dist/cli/{chunk-dh8cwk36.js → chunk-pehfxfta.js} +24 -9
- package/dist/cli/chunk-pehfxfta.js.map +10 -0
- package/dist/cli/{chunk-qkqwkpte.js → chunk-pv29h0wf.js} +3688 -1313
- package/dist/cli/chunk-pv29h0wf.js.map +190 -0
- package/dist/cli/{chunk-6vm74dry.js → chunk-q58y5e6a.js} +10 -10
- package/dist/cli/{chunk-6vm74dry.js.map → chunk-q58y5e6a.js.map} +3 -3
- package/dist/cli/{chunk-zxcczpyx.js → chunk-r20tn01b.js} +1 -1
- package/dist/cli/{chunk-m3vmjgmq.js → chunk-r9rcc4w7.js} +16 -8
- package/dist/cli/chunk-r9rcc4w7.js.map +10 -0
- package/dist/cli/{chunk-5shv93fd.js → chunk-tkacnehg.js} +2 -2
- package/dist/cli/{chunk-zxh4d9vy.js → chunk-tzmab476.js} +4 -4
- package/dist/cli/{chunk-yw7dm696.js → chunk-vg9r4eb9.js} +24 -11
- package/dist/cli/chunk-vg9r4eb9.js.map +14 -0
- package/dist/cli/{chunk-79jhk4py.js → chunk-wrr3j9w9.js} +260 -132
- package/dist/cli/chunk-wrr3j9w9.js.map +35 -0
- package/dist/cli/{chunk-6crbhc3x.js → chunk-yfyb25rh.js} +54 -27
- package/dist/cli/chunk-yfyb25rh.js.map +14 -0
- package/dist/cli/index.js +162 -35
- package/dist/cli/index.js.map +4 -4
- package/dist/types/ai/agent-surface.d.ts +32 -0
- package/dist/types/ai/api-catalog.d.ts +7 -1
- package/dist/types/ai/ask-context.d.ts +7 -0
- package/dist/types/ai/component-markdown.d.ts +4 -4
- package/dist/types/ai/link-headers.d.ts +8 -1
- package/dist/types/ai/openapi-components.d.ts +5 -2
- package/dist/types/ai/relative-links.d.ts +11 -4
- package/dist/types/ai/skills.d.ts +4 -1
- package/dist/types/ai/static-expression.d.ts +28 -0
- package/dist/types/ai/tar.d.ts +1 -3
- package/dist/types/analytics/databuddy.d.ts +43 -0
- package/dist/types/analytics/index.d.ts +4 -0
- package/dist/types/analytics/one-dollar-stats.d.ts +48 -0
- package/dist/types/analytics/schema.d.ts +28 -0
- package/dist/types/astro/integration.d.ts +3 -2
- package/dist/types/cli/env.d.ts +5 -0
- package/dist/types/cli/init/scaffold.d.ts +19 -3
- package/dist/types/cli/init/starter-spec.d.ts +11 -0
- package/dist/types/core/base-path.d.ts +24 -1
- package/dist/types/core/config-input.d.ts +13 -11
- package/dist/types/core/config.d.ts +2 -2
- package/dist/types/core/directive-diagnostics.d.ts +12 -0
- package/dist/types/core/graph.d.ts +2 -0
- package/dist/types/core/heading-markers.d.ts +5 -7
- package/dist/types/core/i18n-ui.d.ts +31 -0
- package/dist/types/core/i18n.d.ts +9 -1
- package/dist/types/core/last-modified.d.ts +10 -0
- package/dist/types/core/links.d.ts +3 -1
- package/dist/types/core/load-module.d.ts +10 -0
- package/dist/types/core/locale-links.d.ts +12 -2
- package/dist/types/core/meta.d.ts +13 -1
- package/dist/types/core/nav-diagnostics.d.ts +10 -0
- package/dist/types/core/navigation.d.ts +38 -0
- package/dist/types/core/ordering-prefix.d.ts +4 -0
- package/dist/types/core/safe-links.d.ts +3 -1
- package/dist/types/core/schema.d.ts +59 -13
- package/dist/types/core/sources/github-releases.d.ts +5 -0
- package/dist/types/core/sources/lower.d.ts +38 -13
- package/dist/types/core/sources/normalize.d.ts +23 -2
- package/dist/types/core/sources/remote.d.ts +11 -1
- package/dist/types/core/sources/resolve.d.ts +12 -0
- package/dist/types/core/sources/types.d.ts +31 -0
- package/dist/types/core/sources/watch.d.ts +12 -5
- package/dist/types/core/standard-schema.d.ts +5 -0
- package/dist/types/core/types.d.ts +9 -0
- package/dist/types/deploy/adapters/node.d.ts +5 -2
- package/dist/types/deploy/adapters/types.d.ts +7 -0
- package/dist/types/deploy/artifacts.d.ts +6 -4
- package/dist/types/deploy/cloudflare-negotiation.d.ts +3 -2
- package/dist/types/deploy/headers.d.ts +36 -7
- package/dist/types/deploy/node-headers.d.ts +43 -8
- package/dist/types/deploy/platforms/netlify.d.ts +27 -2
- package/dist/types/deploy/platforms/node.d.ts +6 -5
- package/dist/types/deploy/platforms/types.d.ts +15 -0
- package/dist/types/deploy/platforms/vercel.d.ts +3 -2
- package/dist/types/deploy/redirects.d.ts +31 -15
- package/dist/types/deploy/vercel-negotiation.d.ts +3 -2
- package/dist/types/markdown/directives.d.ts +62 -0
- package/dist/types/markdown/features.d.ts +21 -0
- package/dist/types/markdown/mdast.d.ts +63 -0
- package/dist/types/openapi/asyncapi.d.ts +4 -2
- package/dist/types/openapi/model.d.ts +20 -6
- package/dist/types/search/sync/algolia.d.ts +3 -1
- package/docs/01-quickstart.mdx +3 -2
- package/docs/02-deployment.mdx +20 -9
- package/docs/08-faq.mdx +10 -3
- package/docs/advanced/changelog.mdx +1 -1
- package/docs/advanced/custom-pages.mdx +7 -5
- package/docs/cli/audit.mdx +19 -3
- package/docs/cli/doctor.mdx +2 -2
- package/docs/cli/evals.mdx +4 -4
- package/docs/cli/index.mdx +4 -1
- package/docs/cli/translate.mdx +4 -4
- package/docs/cli/version.mdx +1 -1
- package/docs/configuration/analytics.mdx +42 -2
- package/docs/configuration/assistant.mdx +1 -1
- package/docs/configuration/customization.mdx +6 -3
- package/docs/configuration/index.mdx +5 -3
- package/docs/configuration/search.mdx +2 -2
- package/docs/content/components.mdx +2 -2
- package/docs/content/frontmatter.mdx +5 -1
- package/docs/content/i18n.mdx +3 -1
- package/docs/content/index.mdx +8 -4
- package/docs/content/islands.mdx +1 -1
- package/docs/content/meta.mdx +7 -3
- package/docs/content/navigation.mdx +29 -4
- package/docs/content/sources.mdx +18 -16
- package/docs/content/syntax.mdx +14 -0
- package/docs/content/versioning.mdx +2 -1
- package/docs/discoverability/agent-discovery.mdx +22 -8
- package/docs/discoverability/index.mdx +4 -3
- package/docs/discoverability/llms-txt.mdx +2 -5
- package/docs/discoverability/markdown.mdx +6 -4
- package/docs/discoverability/mcp.mdx +4 -0
- package/docs/discoverability/metadata.mdx +3 -2
- package/docs/discoverability/open-graph.mdx +8 -4
- package/docs/discoverability/rss.mdx +4 -2
- package/docs/references/asyncapi.mdx +2 -2
- package/docs/references/graphql.mdx +2 -2
- package/docs/references/openapi.mdx +6 -4
- package/package.json +1 -1
- package/skills/blume-migrate/SKILL.md +6 -6
- package/skills/blume-migrate/references/docusaurus.md +6 -6
- package/skills/blume-migrate/references/fumadocs.md +1 -1
- package/skills/blume-migrate/references/mintlify.md +3 -3
- package/skills/blume-migrate/references/monorepo.md +1 -1
- package/skills/blume-migrate/references/nextra.md +2 -2
- package/skills/blume-migrate/references/starlight.md +5 -5
- package/skills/blume-migrate/scripts/mintlify-codemod.mjs +9 -4
- package/skills/blume-update-docs/references/audit-checklist.md +1 -1
- package/src/ai/agent-readability.ts +2 -2
- package/src/ai/agent-surface.ts +56 -0
- package/src/ai/ai-catalog.ts +6 -2
- package/src/ai/api/handlers.ts +2 -2
- package/src/ai/api/spec.ts +17 -4
- package/src/ai/api-catalog.ts +13 -3
- package/src/ai/ask-context.ts +14 -2
- package/src/ai/ask-data.ts +26 -12
- package/src/ai/changelog-markdown.ts +2 -2
- package/src/ai/component-markdown.ts +43 -37
- package/src/ai/link-headers.ts +22 -8
- package/src/ai/llms.ts +22 -10
- package/src/ai/markdown.ts +23 -11
- package/src/ai/mcp/discovery.ts +2 -2
- package/src/ai/mcp/query.ts +2 -2
- package/src/ai/mcp/server.ts +80 -9
- package/src/ai/openapi-components.ts +22 -6
- package/src/ai/relative-links.ts +99 -15
- package/src/ai/serializers.ts +2 -1
- package/src/ai/skills.ts +14 -1
- package/src/ai/static-expression.ts +416 -0
- package/src/ai/tar.ts +139 -12
- package/src/ai/visibility.ts +45 -14
- package/src/analytics/databuddy.ts +67 -0
- package/src/analytics/head.ts +8 -0
- package/src/analytics/index.ts +7 -0
- package/src/analytics/one-dollar-stats.ts +86 -0
- package/src/analytics/posthog.ts +21 -3
- package/src/analytics/schema.ts +4 -0
- package/src/astro/generate.ts +72 -28
- package/src/astro/include-hmr.ts +31 -12
- package/src/astro/include-refresh.ts +19 -8
- package/src/astro/integration.ts +108 -14
- package/src/astro/runtime-modules.ts +28 -13
- package/src/astro/templates.ts +139 -57
- package/src/audit/catalog.ts +2 -2
- package/src/audit/checks/assets.ts +25 -5
- package/src/audit/checks/content.ts +20 -2
- package/src/audit/checks/i18n.ts +46 -8
- package/src/audit/checks/indexability.ts +39 -19
- package/src/audit/checks/links.ts +22 -1
- package/src/audit/checks/llms.ts +6 -3
- package/src/audit/checks/network.ts +3 -1
- package/src/audit/checks/og-image.ts +10 -0
- package/src/audit/checks/robots.ts +6 -1
- package/src/audit/checks/sitemap.ts +56 -31
- package/src/audit/checks/social.ts +21 -2
- package/src/audit/crawl.ts +88 -15
- package/src/audit/graph.ts +3 -1
- package/src/audit/report.ts +54 -17
- package/src/audit/run.ts +13 -9
- package/src/audit/snapshot.ts +5 -0
- package/src/audit/types.ts +18 -0
- package/src/audit/url.ts +37 -6
- package/src/cli/args.ts +32 -0
- package/src/cli/build-failure.ts +50 -0
- package/src/cli/commands/audit.ts +11 -1
- package/src/cli/commands/build.ts +19 -5
- package/src/cli/commands/check.ts +2 -0
- package/src/cli/commands/doctor.ts +3 -1
- package/src/cli/commands/eval.ts +20 -18
- package/src/cli/commands/init.ts +15 -5
- package/src/cli/commands/preview.ts +15 -0
- package/src/cli/commands/sync.ts +2 -0
- package/src/cli/commands/translate.ts +18 -18
- package/src/cli/commands/upgrade.ts +11 -0
- package/src/cli/commands/validate.ts +3 -1
- package/src/cli/dev-lock.ts +157 -37
- package/src/cli/eject-scripts.ts +32 -7
- package/src/cli/env.ts +12 -1
- package/src/cli/init/scaffold.ts +117 -11
- package/src/cli/init/starter-spec.ts +235 -0
- package/src/cli/report-format.ts +11 -6
- package/src/components/colors.ts +19 -0
- package/src/components/content/AccordionItem.astro +26 -22
- package/src/components/content/Badge.astro +7 -12
- package/src/components/content/Card.astro +2 -2
- package/src/components/content/Component.astro +11 -5
- package/src/components/content/Expandable.astro +5 -1
- package/src/components/content/Frame.astro +2 -7
- package/src/components/content/GithubInfo.astro +12 -2
- package/src/components/content/Prompt.astro +2 -7
- package/src/components/content/Tab.astro +0 -1
- package/src/components/content/Tabs.astro +58 -5
- package/src/components/content/Tile.astro +1 -1
- package/src/components/content/Tooltip.astro +69 -7
- package/src/components/content/Tree.astro +7 -2
- package/src/components/content/TypeTable.astro +10 -5
- package/src/components/content/Update.astro +8 -2
- package/src/components/content/auto-type-table.ts +4 -1
- package/src/components/content/badge-color.ts +20 -0
- package/src/components/content/base-href.ts +14 -22
- package/src/components/content/inline-markdown.ts +27 -7
- package/src/components/copy-feedback.ts +35 -8
- package/src/components/islands/assistant.tsx +37 -6
- package/src/components/islands/base-path.ts +47 -10
- package/src/components/islands/hooks.ts +42 -21
- package/src/components/islands/webmcp.ts +16 -10
- package/src/components/layout/Banner.astro +23 -4
- package/src/components/layout/Breadcrumbs.astro +5 -2
- package/src/components/layout/DiscoveryLinks.astro +9 -5
- package/src/components/layout/Header.astro +23 -10
- package/src/components/layout/LanguageSwitcher.astro +2 -2
- package/src/components/layout/Logo.astro +5 -0
- package/src/components/layout/NavSelector.astro +8 -3
- package/src/components/layout/NavTabMenu.astro +133 -0
- package/src/components/layout/NavTree.astro +31 -12
- package/src/components/layout/NavTreeCache.astro +5 -2
- package/src/components/layout/NavTreeScript.astro +45 -5
- package/src/components/layout/PageActions.astro +4 -3
- package/src/components/layout/PageLayout.astro +28 -13
- package/src/components/layout/Pagination.astro +3 -3
- package/src/components/layout/ReferenceLayout.astro +4 -1
- package/src/components/layout/RootLayout.astro +25 -12
- package/src/components/layout/Search.astro +38 -14
- package/src/components/layout/VersionBanner.astro +2 -2
- package/src/components/layout/analytics-client.ts +14 -0
- package/src/components/layout/toc-active.ts +41 -0
- package/src/components/layout/toc-element.ts +8 -14
- package/src/components/openapi/ApiTagOperations.astro +2 -2
- package/src/components/openapi/AsyncApiOperation.astro +7 -4
- package/src/components/openapi/GraphqlChip.astro +2 -2
- package/src/components/openapi/GraphqlType.astro +11 -3
- package/src/components/openapi/MessageComposer.astro +1 -1
- package/src/components/openapi/Operation.astro +23 -5
- package/src/components/openapi/PanelTabs.astro +4 -1
- package/src/components/openapi/Playground.astro +8 -2
- package/src/components/openapi/RequestPanel.astro +13 -6
- package/src/components/openapi/SchemaProperty.astro +11 -33
- package/src/components/openapi/SchemaTable.astro +34 -52
- package/src/components/openapi/async.ts +38 -6
- package/src/components/openapi/helpers.ts +100 -12
- package/src/components/openapi/message-composer.ts +14 -1
- package/src/components/openapi/message-model.ts +12 -2
- package/src/components/openapi/message.ts +21 -3
- package/src/components/openapi/operation-model.ts +119 -17
- package/src/components/openapi/panel.ts +31 -5
- package/src/components/openapi/param-style.ts +181 -0
- package/src/components/openapi/playground-client.ts +110 -23
- package/src/components/openapi/playground-schema.ts +25 -6
- package/src/components/openapi/request.ts +192 -26
- package/src/components/openapi/schema-tree.ts +209 -0
- package/src/components/openapi/snippets.ts +113 -19
- package/src/components/openapi/validate-json.ts +1 -1
- package/src/components/openapi/ws-client.ts +18 -2
- package/src/core/base-path.ts +69 -8
- package/src/core/config-input.ts +13 -11
- package/src/core/config.ts +18 -4
- package/src/core/diagnostics.ts +219 -30
- package/src/core/directive-diagnostics.ts +99 -0
- package/src/core/frontmatter.ts +21 -18
- package/src/core/graph.ts +120 -11
- package/src/core/heading-markers.ts +5 -18
- package/src/core/i18n-ui.ts +39 -2
- package/src/core/i18n.ts +44 -5
- package/src/core/last-modified.ts +25 -3
- package/src/core/links.ts +7 -4
- package/src/core/load-module.ts +20 -0
- package/src/core/locale-links.ts +22 -18
- package/src/core/manifest.ts +3 -2
- package/src/core/meta.ts +89 -12
- package/src/core/nav-diagnostics.ts +56 -1
- package/src/core/navigation.ts +272 -83
- package/src/core/ordering-prefix.ts +27 -0
- package/src/core/project-graph.ts +50 -6
- package/src/core/safe-href.ts +53 -1
- package/src/core/safe-links.ts +11 -2
- package/src/core/schema.ts +94 -18
- package/src/core/sources/assets.ts +83 -41
- package/src/core/sources/contentful-rich-text.ts +28 -20
- package/src/core/sources/contentful.ts +25 -12
- package/src/core/sources/filesystem.ts +25 -3
- package/src/core/sources/github-releases.ts +131 -11
- package/src/core/sources/lexical.ts +30 -20
- package/src/core/sources/lower.ts +276 -56
- package/src/core/sources/mdx-remote.ts +52 -16
- package/src/core/sources/normalize.ts +456 -119
- package/src/core/sources/notion.ts +77 -34
- package/src/core/sources/obsidian.ts +40 -9
- package/src/core/sources/payload.ts +1 -0
- package/src/core/sources/portable-text.ts +85 -49
- package/src/core/sources/remote.ts +18 -2
- package/src/core/sources/resolve.ts +52 -33
- package/src/core/sources/sanity.ts +1 -0
- package/src/core/sources/strapi-blocks.ts +28 -19
- package/src/core/sources/strapi.ts +1 -0
- package/src/core/sources/types.ts +31 -0
- package/src/core/sources/watch.ts +20 -7
- package/src/core/standard-schema.ts +10 -6
- package/src/core/types.ts +9 -0
- package/src/core/ui-packs/ar.ts +13 -0
- package/src/core/ui-packs/bg.ts +13 -0
- package/src/core/ui-packs/bn.ts +13 -0
- package/src/core/ui-packs/ca.ts +13 -0
- package/src/core/ui-packs/cs.ts +13 -0
- package/src/core/ui-packs/da.ts +13 -0
- package/src/core/ui-packs/de.ts +13 -0
- package/src/core/ui-packs/el.ts +13 -0
- package/src/core/ui-packs/es.ts +13 -0
- package/src/core/ui-packs/fa.ts +13 -0
- package/src/core/ui-packs/fi.ts +13 -0
- package/src/core/ui-packs/fr.ts +13 -0
- package/src/core/ui-packs/he.ts +13 -0
- package/src/core/ui-packs/hi.ts +13 -0
- package/src/core/ui-packs/hr.ts +13 -0
- package/src/core/ui-packs/hu.ts +13 -0
- package/src/core/ui-packs/id.ts +13 -0
- package/src/core/ui-packs/it.ts +13 -0
- package/src/core/ui-packs/ja.ts +13 -0
- package/src/core/ui-packs/ko.ts +13 -0
- package/src/core/ui-packs/nl.ts +13 -0
- package/src/core/ui-packs/no.ts +13 -0
- package/src/core/ui-packs/pl.ts +13 -0
- package/src/core/ui-packs/pt-br.ts +13 -0
- package/src/core/ui-packs/pt.ts +13 -0
- package/src/core/ui-packs/ro.ts +13 -0
- package/src/core/ui-packs/ru.ts +13 -0
- package/src/core/ui-packs/sk.ts +13 -0
- package/src/core/ui-packs/sr.ts +13 -0
- package/src/core/ui-packs/sv.ts +13 -0
- package/src/core/ui-packs/th.ts +13 -0
- package/src/core/ui-packs/tr.ts +13 -0
- package/src/core/ui-packs/uk.ts +13 -0
- package/src/core/ui-packs/vi.ts +13 -0
- package/src/core/ui-packs/zh-tw.ts +13 -0
- package/src/core/ui-packs/zh.ts +13 -0
- package/src/core/version-cut.ts +69 -17
- package/src/core/versions.ts +4 -1
- package/src/deploy/adapters/node.ts +5 -2
- package/src/deploy/adapters/registry.ts +2 -1
- package/src/deploy/adapters/types.ts +13 -1
- package/src/deploy/artifacts.ts +52 -11
- package/src/deploy/cloudflare-negotiation.ts +27 -16
- package/src/deploy/headers.ts +75 -55
- package/src/deploy/node-headers.ts +148 -27
- package/src/deploy/platforms/cloudflare.ts +13 -3
- package/src/deploy/platforms/netlify.ts +83 -5
- package/src/deploy/platforms/node.ts +8 -5
- package/src/deploy/platforms/static.ts +2 -0
- package/src/deploy/platforms/types.ts +15 -0
- package/src/deploy/platforms/vercel.ts +10 -3
- package/src/deploy/redirects.ts +68 -21
- package/src/deploy/robots.ts +2 -2
- package/src/deploy/rss.ts +4 -3
- package/src/deploy/sitemap.ts +7 -5
- package/src/deploy/vercel-negotiation.ts +35 -3
- package/src/eval/agents.ts +10 -2
- package/src/eval/run.ts +25 -0
- package/src/markdown/base-links.ts +74 -29
- package/src/markdown/directives.ts +242 -36
- package/src/markdown/features.ts +17 -0
- package/src/markdown/index.ts +13 -9
- package/src/markdown/mdast.ts +5 -2
- package/src/markdown/relative-links.ts +15 -27
- package/src/markdown/route-snapshot.ts +37 -0
- package/src/og/card.ts +149 -9
- package/src/og/derive.ts +156 -5
- package/src/og/index.ts +1 -0
- package/src/openapi/asyncapi.ts +4 -2
- package/src/openapi/graphql-build.ts +28 -2
- package/src/openapi/model.ts +99 -27
- package/src/openapi/proxy.ts +63 -10
- package/src/openapi/render-mdx.ts +51 -3
- package/src/registry/eject.ts +297 -43
- package/src/search/adapters/version-scope.ts +30 -0
- package/src/search/documents.ts +89 -27
- package/src/search/popular.ts +2 -1
- package/src/search/sync/algolia.ts +36 -2
- package/src/seo/jsonld.ts +7 -3
- package/src/sources/registry.ts +5 -0
- package/src/theme/entry.ts +11 -4
- package/src/translate/agents.ts +6 -1
- package/src/translate/ledger.ts +26 -3
- package/src/translate/meta.ts +76 -24
- package/src/translate/run.ts +14 -8
- package/src/translate/validate.ts +14 -2
- package/src/translate/work-list.ts +91 -19
- package/src/upgrade/upgrade.ts +36 -4
- package/dist/cli/chunk-27g6wdth.js.map +0 -10
- package/dist/cli/chunk-2hn4b8z7.js.map +0 -12
- package/dist/cli/chunk-6crbhc3x.js.map +0 -14
- package/dist/cli/chunk-6hsn950k.js.map +0 -10
- package/dist/cli/chunk-79jhk4py.js.map +0 -35
- package/dist/cli/chunk-82bbrxdn.js +0 -51
- package/dist/cli/chunk-82bbrxdn.js.map +0 -10
- package/dist/cli/chunk-abh8yjkn.js +0 -31
- package/dist/cli/chunk-abh8yjkn.js.map +0 -10
- package/dist/cli/chunk-ce574jw2.js +0 -23
- package/dist/cli/chunk-ce574jw2.js.map +0 -10
- package/dist/cli/chunk-dh8cwk36.js.map +0 -10
- package/dist/cli/chunk-epjnccmv.js.map +0 -10
- package/dist/cli/chunk-fa25z98p.js.map +0 -11
- package/dist/cli/chunk-fs23ddbb.js.map +0 -35
- package/dist/cli/chunk-fz5wtpmh.js.map +0 -10
- package/dist/cli/chunk-jwyddg7y.js.map +0 -15
- package/dist/cli/chunk-kpf8rrjc.js.map +0 -19
- package/dist/cli/chunk-m3vmjgmq.js.map +0 -10
- package/dist/cli/chunk-mb2919y2.js.map +0 -10
- package/dist/cli/chunk-q5163e60.js.map +0 -11
- package/dist/cli/chunk-qkqwkpte.js.map +0 -182
- package/dist/cli/chunk-qs4q5p4e.js.map +0 -10
- package/dist/cli/chunk-s1p84fyh.js.map +0 -10
- package/dist/cli/chunk-wgm7m9qk.js.map +0 -36
- package/dist/cli/chunk-yt5n7ppj.js.map +0 -10
- package/dist/cli/chunk-yw7dm696.js.map +0 -14
- /package/dist/cli/{chunk-s6jhgk0q.js.map → chunk-2eytanqx.js.map} +0 -0
- /package/dist/cli/{chunk-hdpx1tax.js.map → chunk-2z928egk.js.map} +0 -0
- /package/dist/cli/{chunk-ah61y8py.js.map → chunk-364znk6q.js.map} +0 -0
- /package/dist/cli/{chunk-vtk4a6dg.js.map → chunk-8ktnccpt.js.map} +0 -0
- /package/dist/cli/{chunk-fxypxtvm.js.map → chunk-a58773jm.js.map} +0 -0
- /package/dist/cli/{chunk-wm7js3j9.js.map → chunk-b07cmahc.js.map} +0 -0
- /package/dist/cli/{chunk-zxcczpyx.js.map → chunk-r20tn01b.js.map} +0 -0
- /package/dist/cli/{chunk-5shv93fd.js.map → chunk-tkacnehg.js.map} +0 -0
- /package/dist/cli/{chunk-zxh4d9vy.js.map → chunk-tzmab476.js.map} +0 -0
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
---
|
|
2
|
+
import data from "blume:data";
|
|
3
|
+
|
|
2
4
|
import { EN_UI } from "../../core/i18n-ui.ts";
|
|
3
5
|
import type { UIStrings } from "../../core/i18n-ui.ts";
|
|
4
6
|
import type { Navigation } from "../../core/types.ts";
|
|
7
|
+
import { scopesVersions } from "../../search/adapters/version-scope.ts";
|
|
5
8
|
import { resolvePopularIconMarkup } from "../../search/popular-icon.ts";
|
|
6
9
|
import Icon from "../Icon.astro";
|
|
10
|
+
import { withBase, withMountedBase } from "../islands/base-path.ts";
|
|
7
11
|
import { flattenPages } from "./nav-utils.ts";
|
|
8
12
|
|
|
9
13
|
// The provider-specific loader is generated per project into `blume:search-client`
|
|
@@ -21,7 +25,8 @@ interface Props {
|
|
|
21
25
|
locale?: string;
|
|
22
26
|
/**
|
|
23
27
|
* Docs version to filter results to (`""` = the current docs — a meaningful
|
|
24
|
-
* value, so `null`/omitted is what disables version filtering).
|
|
28
|
+
* value, so `null`/omitted is what disables version filtering). Ignored when
|
|
29
|
+
* the configured provider can't scope by version.
|
|
25
30
|
*/
|
|
26
31
|
version?: string | null;
|
|
27
32
|
}
|
|
@@ -32,27 +37,41 @@ const {
|
|
|
32
37
|
popularPages,
|
|
33
38
|
strings,
|
|
34
39
|
locale,
|
|
35
|
-
version = null,
|
|
40
|
+
version: viewedVersion = null,
|
|
36
41
|
} = Astro.props;
|
|
42
|
+
// Pagefind, Orama Cloud, and Mixedbread search every version whatever the
|
|
43
|
+
// dialog asks, so on those an "All versions" toggle would change nothing:
|
|
44
|
+
// treat the site as unversioned for search instead.
|
|
45
|
+
const version = scopesVersions(data.config.search.provider)
|
|
46
|
+
? viewedVersion
|
|
47
|
+
: null;
|
|
37
48
|
// Merge over the English baseline per key (rather than `strings ?? …`) so a
|
|
38
49
|
// partial — or empty `{}` — strings object still resolves every label to a
|
|
39
50
|
// default, matching the pattern PageActions uses for its own dictionary.
|
|
40
51
|
const s = { ...EN_UI.search, ...strings };
|
|
41
52
|
|
|
42
53
|
// Resolve popular icons to markup here (icon set is server-only). Unknown
|
|
43
|
-
// names fall through to the island's file glyph.
|
|
54
|
+
// names fall through to the island's file glyph. Each entry's served href is
|
|
55
|
+
// resolved here too: a configured entry is authored, so a base written by hand
|
|
56
|
+
// is kept (`withBase`); the sidebar fallback links generated routes, which
|
|
57
|
+
// always go under the base (`withMountedBase`).
|
|
44
58
|
const popular =
|
|
45
59
|
popularPages && popularPages.length > 0
|
|
46
60
|
? popularPages.map((page) => ({
|
|
61
|
+
href: withBase(page.route),
|
|
47
62
|
icon: resolvePopularIconMarkup(
|
|
48
63
|
page.icon,
|
|
49
64
|
import.meta.env.BASE_URL ?? "/"
|
|
50
65
|
),
|
|
51
66
|
label: page.label,
|
|
52
|
-
route: page.route,
|
|
53
67
|
}))
|
|
54
68
|
: navigation
|
|
55
|
-
? flattenPages(navigation.sidebar)
|
|
69
|
+
? flattenPages(navigation.sidebar)
|
|
70
|
+
.slice(0, 6)
|
|
71
|
+
.map((page) => ({
|
|
72
|
+
href: withMountedBase(page.route),
|
|
73
|
+
label: page.label,
|
|
74
|
+
}))
|
|
56
75
|
: [];
|
|
57
76
|
|
|
58
77
|
const kbd = "rounded border border-border bg-muted px-1 py-0.5 font-mono";
|
|
@@ -67,6 +86,7 @@ const kbd = "rounded border border-border bg-muted px-1 py-0.5 font-mono";
|
|
|
67
86
|
data-i18n-dev={s.devOnly}
|
|
68
87
|
data-i18n-empty={s.noResults}
|
|
69
88
|
data-i18n-error={s.error}
|
|
89
|
+
data-i18n-latest={s.latest}
|
|
70
90
|
data-i18n-popular={s.popular}
|
|
71
91
|
data-i18n-results={s.results}
|
|
72
92
|
data-locale={locale || undefined}
|
|
@@ -219,7 +239,7 @@ const kbd = "rounded border border-border bg-muted px-1 py-0.5 font-mono";
|
|
|
219
239
|
<script>
|
|
220
240
|
import { navigate } from "astro:transitions/client";
|
|
221
241
|
import { chromeIcons as icons } from "../../theme/chrome-icons.ts";
|
|
222
|
-
import {
|
|
242
|
+
import { mountBase } from "../islands/base-path.ts";
|
|
223
243
|
import { escape as escapeHtml } from "html-escaper";
|
|
224
244
|
|
|
225
245
|
import { highlight, matchSnippet } from "./search/types.ts";
|
|
@@ -233,10 +253,11 @@ const kbd = "rounded border border-border bg-muted px-1 py-0.5 font-mono";
|
|
|
233
253
|
}
|
|
234
254
|
|
|
235
255
|
interface PopularPage {
|
|
256
|
+
/** The served URL, base included (resolved server-side). */
|
|
257
|
+
href: string;
|
|
236
258
|
/** Pre-resolved inline SVG from the server; absent falls back to `file`. */
|
|
237
259
|
icon?: string;
|
|
238
260
|
label: string;
|
|
239
|
-
route: string;
|
|
240
261
|
}
|
|
241
262
|
|
|
242
263
|
const GRID_COLS = "md:grid-cols-[22rem_minmax(0,1fr)]";
|
|
@@ -328,6 +349,7 @@ const kbd = "rounded border border-border bg-muted px-1 py-0.5 font-mono";
|
|
|
328
349
|
allMsg = "All";
|
|
329
350
|
popularMsg = "Popular";
|
|
330
351
|
resultsMsg = "Results";
|
|
352
|
+
latestMsg = "latest";
|
|
331
353
|
// The active locale to filter to (null when i18n is off), and whether the
|
|
332
354
|
// reader has opted to search across every language instead.
|
|
333
355
|
locale: string | null = null;
|
|
@@ -382,6 +404,8 @@ const kbd = "rounded border border-border bg-muted px-1 py-0.5 font-mono";
|
|
|
382
404
|
this.getAttribute("data-i18n-popular") || this.popularMsg;
|
|
383
405
|
this.resultsMsg =
|
|
384
406
|
this.getAttribute("data-i18n-results") || this.resultsMsg;
|
|
407
|
+
this.latestMsg =
|
|
408
|
+
this.getAttribute("data-i18n-latest") || this.latestMsg;
|
|
385
409
|
this.locale = this.getAttribute("data-locale");
|
|
386
410
|
// "" (the current docs) is a real version value, so a presence flag —
|
|
387
411
|
// not the attribute's truthiness — decides whether filtering is on.
|
|
@@ -667,7 +691,7 @@ const kbd = "rounded border border-border bg-muted px-1 py-0.5 font-mono";
|
|
|
667
691
|
if (this.popular.length > 0) {
|
|
668
692
|
const group = this.addGroup(this.popularMsg);
|
|
669
693
|
for (const page of this.popular) {
|
|
670
|
-
const item = this.createLinkRow(page.
|
|
694
|
+
const item = this.createLinkRow(page.href, page.label, page.icon);
|
|
671
695
|
group.appendChild(item.el);
|
|
672
696
|
this.selectables.push(item);
|
|
673
697
|
}
|
|
@@ -751,9 +775,10 @@ const kbd = "rounded border border-border bg-muted px-1 py-0.5 font-mono";
|
|
|
751
775
|
|
|
752
776
|
createHitRow(hit: SearchHit, query: string): Selectable {
|
|
753
777
|
const el = document.createElement("a");
|
|
754
|
-
// Index URLs are base-less logical routes;
|
|
755
|
-
// clicking a result lands on the page's real served
|
|
756
|
-
|
|
778
|
+
// Index URLs are base-less logical routes; mount them under the
|
|
779
|
+
// deployment base so clicking a result lands on the page's real served
|
|
780
|
+
// URL, even when the route starts with the base's own name.
|
|
781
|
+
const href = mountBase(import.meta.env.BASE_URL, hit.url);
|
|
757
782
|
el.href = href;
|
|
758
783
|
el.className = `${ROW_CLASS} ${MARK}`;
|
|
759
784
|
// `line-clamp-2` already sets `display`, so no `block` here (it would
|
|
@@ -765,7 +790,7 @@ const kbd = "rounded border border-border bg-muted px-1 py-0.5 font-mono";
|
|
|
765
790
|
// reader knows they're about to leave the docs they're viewing.
|
|
766
791
|
const versionTag =
|
|
767
792
|
this.versioned && hit.version !== undefined && hit.version !== this.version
|
|
768
|
-
? `<span class="ms-2 inline-block rounded-full bg-muted px-1.5 py-0.5 align-middle text-[0.65rem] text-muted-foreground">${escapeHtml(hit.version ||
|
|
793
|
+
? `<span class="ms-2 inline-block rounded-full bg-muted px-1.5 py-0.5 align-middle text-[0.65rem] text-muted-foreground">${escapeHtml(hit.version || this.latestMsg)}</span>`
|
|
769
794
|
: "";
|
|
770
795
|
el.innerHTML = `
|
|
771
796
|
<span class="mt-0.5 shrink-0 text-muted-foreground">${svg("file")}</span>
|
|
@@ -778,9 +803,8 @@ const kbd = "rounded border border-border bg-muted px-1 py-0.5 font-mono";
|
|
|
778
803
|
return item;
|
|
779
804
|
}
|
|
780
805
|
|
|
781
|
-
createLinkRow(
|
|
806
|
+
createLinkRow(href: string, label: string, icon?: string): Selectable {
|
|
782
807
|
const el = document.createElement("a");
|
|
783
|
-
const href = prefixBase(import.meta.env.BASE_URL, url);
|
|
784
808
|
el.href = href;
|
|
785
809
|
el.className = ROW_CLASS;
|
|
786
810
|
// `icon` is server-resolved markup (built-in Lucide, `<img>`, or
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
import {
|
|
2
|
+
import { withMountedBase } from "../islands/base-path.ts";
|
|
3
3
|
import Icon from "../Icon.astro";
|
|
4
4
|
|
|
5
5
|
// The "you're viewing an old version" notice, shared by RootLayout and
|
|
@@ -29,7 +29,7 @@ const { notice } = Astro.props;
|
|
|
29
29
|
<span>{notice.message}</span>
|
|
30
30
|
<a
|
|
31
31
|
class="inline-flex items-center gap-1 font-medium underline underline-offset-2"
|
|
32
|
-
href={
|
|
32
|
+
href={withMountedBase(notice.latestHref)}
|
|
33
33
|
>
|
|
34
34
|
{notice.latestLabel}
|
|
35
35
|
<Icon name="arrow-right" size={14} />
|
|
@@ -29,6 +29,7 @@ interface AnalyticsWindow {
|
|
|
29
29
|
analytics?: { track?: (event: string, props?: TrackProps) => void };
|
|
30
30
|
clarity?: (command: "event", event: string) => void;
|
|
31
31
|
dataLayer?: DataLayer;
|
|
32
|
+
databuddy?: { track?: (event: string, props?: TrackProps) => void };
|
|
32
33
|
fathom?: { trackEvent?: (event: string) => void };
|
|
33
34
|
gtag?: (command: "event", event: string, props?: TrackProps) => void;
|
|
34
35
|
heap?: { track?: (event: string, props?: TrackProps) => void };
|
|
@@ -39,6 +40,9 @@ interface AnalyticsWindow {
|
|
|
39
40
|
pirsch?: (event: string, options?: { meta?: TrackProps }) => void;
|
|
40
41
|
plausible?: (event: string, options?: { props?: TrackProps }) => void;
|
|
41
42
|
posthog?: { capture?: (event: string, props?: TrackProps) => void };
|
|
43
|
+
stonks?: {
|
|
44
|
+
event?: (event: string, props?: Record<string, string>) => void;
|
|
45
|
+
};
|
|
42
46
|
}
|
|
43
47
|
|
|
44
48
|
/** Run one provider call; its failure must not reach the others or the caller. */
|
|
@@ -82,7 +86,17 @@ const trackGlobals = (
|
|
|
82
86
|
attempt(() => (w.__blumeGtmLayer ?? w.dataLayer)?.push({ ...props, event }));
|
|
83
87
|
// Privacy-first counters take a name, some with properties.
|
|
84
88
|
attempt(() => w.plausible?.(event, { props }));
|
|
89
|
+
attempt(() => w.databuddy?.track?.(event, props));
|
|
85
90
|
attempt(() => w.fathom?.trackEvent?.(event));
|
|
91
|
+
// OneDollarStats only takes string property values.
|
|
92
|
+
attempt(() =>
|
|
93
|
+
w.stonks?.event?.(
|
|
94
|
+
event,
|
|
95
|
+
Object.fromEntries(
|
|
96
|
+
Object.entries(props).map(([key, value]) => [key, String(value)])
|
|
97
|
+
)
|
|
98
|
+
)
|
|
99
|
+
);
|
|
86
100
|
// Pirsch stringifies `meta` values in place, so it gets its own copy and
|
|
87
101
|
// the `blume:track` listeners still see the original types.
|
|
88
102
|
attempt(() => w.pirsch?.(event, { meta: { ...props } }));
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The scrollspy's choice of the active "On this page" entry, kept apart from
|
|
3
|
+
* the `<blume-toc>` element (toc-element.ts) so it runs without a DOM.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/** The two measurements the scrollspy takes of a heading. */
|
|
7
|
+
export interface MeasuredHeading {
|
|
8
|
+
getBoundingClientRect: () => { top: number };
|
|
9
|
+
getClientRects: () => { length: number };
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* The entry for the section being read: the last heading at or above the
|
|
14
|
+
* trigger line (the first heading before any has reached it), or the last
|
|
15
|
+
* heading once the page is scrolled to the bottom.
|
|
16
|
+
*
|
|
17
|
+
* Only rendered headings compete. A heading inside a hidden tab panel
|
|
18
|
+
* (`display: none`) has no boxes and measures `top: 0`, so it would always
|
|
19
|
+
* read as scrolled past and hold the highlight from the top of the page.
|
|
20
|
+
*/
|
|
21
|
+
export const activeTocEntry = <Entry extends { heading: MeasuredHeading }>(
|
|
22
|
+
entries: readonly Entry[],
|
|
23
|
+
triggerOffset: number,
|
|
24
|
+
scrolledToBottom: boolean
|
|
25
|
+
): Entry | null => {
|
|
26
|
+
const rendered = entries.filter(
|
|
27
|
+
({ heading }) => heading.getClientRects().length > 0
|
|
28
|
+
);
|
|
29
|
+
if (scrolledToBottom) {
|
|
30
|
+
return rendered.at(-1) ?? null;
|
|
31
|
+
}
|
|
32
|
+
// Headings are in document order, so the last one whose top has reached the
|
|
33
|
+
// trigger line is the section currently being read; default to the first.
|
|
34
|
+
let active = rendered[0] ?? null;
|
|
35
|
+
for (const entry of rendered) {
|
|
36
|
+
if (entry.heading.getBoundingClientRect().top <= triggerOffset) {
|
|
37
|
+
active = entry;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
return active;
|
|
41
|
+
};
|
|
@@ -6,7 +6,8 @@
|
|
|
6
6
|
*
|
|
7
7
|
* The active heading is chosen by rect (the last heading at or above a trigger
|
|
8
8
|
* line just below the sticky header), so it stays correct for sections taller
|
|
9
|
-
* than the viewport and at the bottom of the page
|
|
9
|
+
* than the viewport and at the bottom of the page; headings that aren't rendered
|
|
10
|
+
* (inside a hidden tab panel) are skipped (see toc-active.ts). An IntersectionObserver is the
|
|
10
11
|
* cheap primary trigger — it only fires as headings cross the band near the top —
|
|
11
12
|
* and a passive, rAF-throttled scroll listener covers the one case it can't: a
|
|
12
13
|
* final section too short to push its heading past the trigger line.
|
|
@@ -14,6 +15,8 @@
|
|
|
14
15
|
* Imported for its side effect (registers the element) from RootLayout's script.
|
|
15
16
|
*/
|
|
16
17
|
|
|
18
|
+
import { activeTocEntry } from "./toc-active.ts";
|
|
19
|
+
|
|
17
20
|
interface TocEntry {
|
|
18
21
|
heading: HTMLElement;
|
|
19
22
|
link: HTMLAnchorElement;
|
|
@@ -93,19 +96,10 @@ class BlumeToc extends HTMLElement {
|
|
|
93
96
|
const scrolledToBottom =
|
|
94
97
|
window.innerHeight + window.scrollY >=
|
|
95
98
|
document.documentElement.scrollHeight - 2;
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
// Headings are in document order, so the last one whose top has reached the
|
|
101
|
-
// trigger line is the section currently being read; default to the first.
|
|
102
|
-
let active = this.#entries[0]?.link ?? null;
|
|
103
|
-
for (const { heading, link } of this.#entries) {
|
|
104
|
-
if (heading.getBoundingClientRect().top <= TRIGGER_OFFSET) {
|
|
105
|
-
active = link;
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
return active;
|
|
99
|
+
return (
|
|
100
|
+
activeTocEntry(this.#entries, TRIGGER_OFFSET, scrolledToBottom)?.link ??
|
|
101
|
+
null
|
|
102
|
+
);
|
|
109
103
|
}
|
|
110
104
|
}
|
|
111
105
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
import specs from "blume:openapi";
|
|
3
3
|
import { specOf } from "../../openapi/model.ts";
|
|
4
|
-
import {
|
|
4
|
+
import { withMountedBase } from "../islands/base-path.ts";
|
|
5
5
|
import MethodBadge from "./MethodBadge.astro";
|
|
6
6
|
|
|
7
7
|
// The operation-link list for one tag section of an API overview page. The
|
|
@@ -27,7 +27,7 @@ const operations = Object.values(specOf(specs, source)?.operations ?? {}).filter
|
|
|
27
27
|
<li>
|
|
28
28
|
<a
|
|
29
29
|
class="flex items-start gap-3 rounded-blume border border-border p-3 text-inherit no-underline! transition-colors hover:border-accent hover:bg-muted hover:no-underline!"
|
|
30
|
-
href={
|
|
30
|
+
href={withMountedBase(operation.route)}
|
|
31
31
|
>
|
|
32
32
|
<MethodBadge class="mt-0.5 shrink-0" method={operation.method} />
|
|
33
33
|
{/* Title over path, stacked, so a long summary and a long route each
|
|
@@ -70,7 +70,7 @@ const security = resolveAsyncApiSecurity(
|
|
|
70
70
|
);
|
|
71
71
|
const parameters = channelParameters(channel, document);
|
|
72
72
|
const messages = operation ? operationMessages(operation, channel, document) : [];
|
|
73
|
-
const protocol = protocolOf(operation, channel, servers);
|
|
73
|
+
const protocol = protocolOf(operation, channel, servers, document.components);
|
|
74
74
|
|
|
75
75
|
/** Declared example first, else a sampled value from the payload schema. */
|
|
76
76
|
const exampleOf = (message: (typeof messages)[number]["message"]): unknown =>
|
|
@@ -115,8 +115,8 @@ const samplePanels = sample
|
|
|
115
115
|
? await languageSamplePanels(languages, sample, data.config.codeThemes)
|
|
116
116
|
: [];
|
|
117
117
|
|
|
118
|
-
const operationBindings = bindingGroups(operation?.bindings);
|
|
119
|
-
const channelBindings = bindingGroups(channel?.bindings);
|
|
118
|
+
const operationBindings = bindingGroups(operation?.bindings, document.components);
|
|
119
|
+
const channelBindings = bindingGroups(channel?.bindings, document.components);
|
|
120
120
|
---
|
|
121
121
|
|
|
122
122
|
{
|
|
@@ -144,7 +144,10 @@ const channelBindings = bindingGroups(channel?.bindings);
|
|
|
144
144
|
// Headers may be multi-format too; undefined with `headers`
|
|
145
145
|
// present means an inline-unrenderable schema format.
|
|
146
146
|
const headers = schemaOf(named.message.headers);
|
|
147
|
-
const messageBindings = bindingGroups(
|
|
147
|
+
const messageBindings = bindingGroups(
|
|
148
|
+
named.message.bindings,
|
|
149
|
+
document.components
|
|
150
|
+
);
|
|
148
151
|
return (
|
|
149
152
|
<section class="mt-6">
|
|
150
153
|
<div
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
import {
|
|
2
|
+
import { withMountedBase } from "../islands/base-path.ts";
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* A schema name (or full type display like `[Pet!]!`) rendered as a link when
|
|
@@ -21,7 +21,7 @@ const { name, route, class: className } = Astro.props;
|
|
|
21
21
|
route ? (
|
|
22
22
|
<a
|
|
23
23
|
class:list={["font-mono text-accent hover:underline", className]}
|
|
24
|
-
href={
|
|
24
|
+
href={withMountedBase(route)}
|
|
25
25
|
>
|
|
26
26
|
{name}
|
|
27
27
|
</a>
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
+
import { isSafeHref } from "../../core/safe-href.ts";
|
|
2
3
|
import type { GraphqlDocument } from "../../openapi/graphql.ts";
|
|
3
4
|
import { graphqlTypeDef } from "../../openapi/graphql.ts";
|
|
4
5
|
import type { ApiOperationRef, ApiSpecData } from "../../openapi/model.ts";
|
|
@@ -65,9 +66,16 @@ const SECTION_HEADING = "mb-2 font-semibold text-foreground text-sm";
|
|
|
65
66
|
{type.specifiedByUrl && (
|
|
66
67
|
<div class="mb-4 text-muted-foreground text-sm">
|
|
67
68
|
Specified by{" "}
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
69
|
+
{/* The URL comes from the schema, someone else's content: a
|
|
70
|
+
`javascript:` one would run on the docs origin when clicked, so
|
|
71
|
+
only a safe destination becomes a link. */}
|
|
72
|
+
{isSafeHref(type.specifiedByUrl) ? (
|
|
73
|
+
<a class="text-accent hover:underline" href={type.specifiedByUrl}>
|
|
74
|
+
{type.specifiedByUrl}
|
|
75
|
+
</a>
|
|
76
|
+
) : (
|
|
77
|
+
<code class="break-all">{type.specifiedByUrl}</code>
|
|
78
|
+
)}
|
|
71
79
|
</div>
|
|
72
80
|
)}
|
|
73
81
|
<GraphqlFieldsTable
|
|
@@ -6,8 +6,13 @@ import {
|
|
|
6
6
|
type ParameterLike,
|
|
7
7
|
resolveComponentRef,
|
|
8
8
|
type SchemaLike,
|
|
9
|
+
type SpecValue,
|
|
9
10
|
} from "./helpers.ts";
|
|
10
|
-
import {
|
|
11
|
+
import {
|
|
12
|
+
effectiveServers,
|
|
13
|
+
operationModel,
|
|
14
|
+
type ServerLike,
|
|
15
|
+
} from "./operation-model.ts";
|
|
11
16
|
import { buildRequest, defaultValues } from "./request.ts";
|
|
12
17
|
import {
|
|
13
18
|
effectiveSecurity,
|
|
@@ -35,7 +40,8 @@ interface Props {
|
|
|
35
40
|
|
|
36
41
|
interface MediaTypeLike {
|
|
37
42
|
schema?: SchemaLike;
|
|
38
|
-
example?:
|
|
43
|
+
example?: SpecValue;
|
|
44
|
+
examples?: SpecValue;
|
|
39
45
|
}
|
|
40
46
|
|
|
41
47
|
interface RequestBodyLike {
|
|
@@ -59,6 +65,7 @@ interface FullOperation {
|
|
|
59
65
|
requestBody?: RequestBodyLike;
|
|
60
66
|
responses?: Record<string, ResponseLike>;
|
|
61
67
|
security?: SecurityRequirementLike[];
|
|
68
|
+
servers?: ServerLike[];
|
|
62
69
|
}
|
|
63
70
|
|
|
64
71
|
const { source, id } = Astro.props;
|
|
@@ -73,7 +80,10 @@ const isGraphql = spec?.kind === "graphql";
|
|
|
73
80
|
const doc = (spec?.document ?? {}) as {
|
|
74
81
|
paths?: Record<
|
|
75
82
|
string,
|
|
76
|
-
Record<string, unknown> & {
|
|
83
|
+
Record<string, unknown> & {
|
|
84
|
+
parameters?: ParameterLike[];
|
|
85
|
+
servers?: ServerLike[];
|
|
86
|
+
}
|
|
77
87
|
>;
|
|
78
88
|
components?: {
|
|
79
89
|
schemas?: Record<string, SchemaLike>;
|
|
@@ -83,7 +93,7 @@ const doc = (spec?.document ?? {}) as {
|
|
|
83
93
|
securitySchemes?: Record<string, SecuritySchemeLike>;
|
|
84
94
|
};
|
|
85
95
|
security?: SecurityRequirementLike[];
|
|
86
|
-
servers?:
|
|
96
|
+
servers?: ServerLike[];
|
|
87
97
|
};
|
|
88
98
|
const pathItem = ref ? doc.paths?.[ref.path] : undefined;
|
|
89
99
|
const operation = (
|
|
@@ -117,13 +127,20 @@ const security = resolveSecurity(
|
|
|
117
127
|
const model =
|
|
118
128
|
ref && operation
|
|
119
129
|
? operationModel({
|
|
130
|
+
components,
|
|
120
131
|
method: ref.method,
|
|
121
132
|
parameters: params,
|
|
122
133
|
path: ref.path,
|
|
123
134
|
requestBody,
|
|
124
135
|
schemas,
|
|
125
136
|
security,
|
|
126
|
-
|
|
137
|
+
// An operation's own `servers` override its path item's, which
|
|
138
|
+
// override the document's.
|
|
139
|
+
servers: effectiveServers(
|
|
140
|
+
operation.servers,
|
|
141
|
+
pathItem?.servers,
|
|
142
|
+
doc.servers
|
|
143
|
+
),
|
|
127
144
|
})
|
|
128
145
|
: null;
|
|
129
146
|
const sample = model ? buildRequest(model, defaultValues(model)) : null;
|
|
@@ -179,6 +196,7 @@ const languages = sampleLanguages(spec?.codeSamples ?? []);
|
|
|
179
196
|
/>
|
|
180
197
|
)}
|
|
181
198
|
<RequestPanel
|
|
199
|
+
components={components}
|
|
182
200
|
languages={languages}
|
|
183
201
|
responses={responses}
|
|
184
202
|
sample={sample}
|
|
@@ -62,7 +62,9 @@ const TAB_CLASS =
|
|
|
62
62
|
</div>
|
|
63
63
|
<blume-panel-tabs class="block overflow-hidden rounded-blume border border-border bg-background">
|
|
64
64
|
<div class="flex items-center justify-between gap-2 border-border border-b px-3">
|
|
65
|
-
<div class="flex flex-wrap gap-4" role="tablist">
|
|
65
|
+
<div aria-label={heading} class="flex flex-wrap gap-4" role="tablist">
|
|
66
|
+
{/* Roving tabindex: only the selected tab is in the Tab order, and
|
|
67
|
+
the arrow keys, Home, and End move between tabs (panel.ts). */}
|
|
66
68
|
{panels.map((panel, index) => (
|
|
67
69
|
<button
|
|
68
70
|
aria-controls={idFor("panel", panel.key)}
|
|
@@ -71,6 +73,7 @@ const TAB_CLASS =
|
|
|
71
73
|
data-panel-tab={panel.key}
|
|
72
74
|
id={idFor("tab", panel.key)}
|
|
73
75
|
role="tab"
|
|
76
|
+
tabindex={index === 0 ? "0" : "-1"}
|
|
74
77
|
type="button"
|
|
75
78
|
>
|
|
76
79
|
{panel.label}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
import { stableId } from "../content/tooltip-id.ts";
|
|
3
|
+
import { withMountedBase } from "../islands/base-path.ts";
|
|
3
4
|
|
|
4
5
|
import { paramKey, type PlaygroundModel } from "./request.ts";
|
|
5
6
|
|
|
@@ -23,6 +24,11 @@ interface Props {
|
|
|
23
24
|
|
|
24
25
|
const { model, proxy, slug, operation } = Astro.props;
|
|
25
26
|
|
|
27
|
+
// The built-in proxy route carries the site `basePath` but, like every
|
|
28
|
+
// internal URL in the spec data, not `deployment.base`; `withMountedBase`
|
|
29
|
+
// adds it and passes an external proxy URL through untouched.
|
|
30
|
+
const proxyUrl = proxy ? withMountedBase(proxy) : undefined;
|
|
31
|
+
|
|
26
32
|
// `</script>`-proof embedding: `<` only ever occurs inside JSON strings,
|
|
27
33
|
// where the \u escape is equivalent, so a spec description can never close
|
|
28
34
|
// the model script early and inject markup.
|
|
@@ -46,7 +52,7 @@ const CHECKBOX_ROW =
|
|
|
46
52
|
|
|
47
53
|
<blume-playground
|
|
48
54
|
class="mb-6 block"
|
|
49
|
-
data-proxy={
|
|
55
|
+
data-proxy={proxyUrl}
|
|
50
56
|
data-storage-key={`blume-playground:${slug}:${operation}`}
|
|
51
57
|
>
|
|
52
58
|
<script
|
|
@@ -194,7 +200,7 @@ const CHECKBOX_ROW =
|
|
|
194
200
|
<div class={GROUP}>
|
|
195
201
|
<div class={GROUP_HEADING}>
|
|
196
202
|
Body
|
|
197
|
-
<span class="
|
|
203
|
+
<span class="ms-1.5 font-mono normal-case">
|
|
198
204
|
{model.body.contentType}
|
|
199
205
|
</span>
|
|
200
206
|
</div>
|
|
@@ -2,14 +2,21 @@
|
|
|
2
2
|
import data from "blume:data";
|
|
3
3
|
|
|
4
4
|
import { highlightCode } from "../../markdown/index.ts";
|
|
5
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
type ComponentsLike,
|
|
7
|
+
responseExample,
|
|
8
|
+
type SchemaLike,
|
|
9
|
+
type SpecValue,
|
|
10
|
+
toJson,
|
|
11
|
+
} from "./helpers.ts";
|
|
6
12
|
import { languageSamplePanels } from "./sample-panels.ts";
|
|
7
13
|
import PanelTabs from "./PanelTabs.astro";
|
|
8
14
|
import type { RequestSample, SampleLanguage } from "./snippets.ts";
|
|
9
15
|
|
|
10
16
|
interface MediaTypeLike {
|
|
11
17
|
schema?: SchemaLike;
|
|
12
|
-
example?:
|
|
18
|
+
example?: SpecValue;
|
|
19
|
+
examples?: SpecValue;
|
|
13
20
|
}
|
|
14
21
|
|
|
15
22
|
interface ResponseLike {
|
|
@@ -18,13 +25,15 @@ interface ResponseLike {
|
|
|
18
25
|
}
|
|
19
26
|
|
|
20
27
|
interface Props {
|
|
28
|
+
/** The document's `components`, which `$ref`'d examples resolve against. */
|
|
29
|
+
components?: ComponentsLike;
|
|
21
30
|
sample: RequestSample;
|
|
22
31
|
languages: SampleLanguage[];
|
|
23
32
|
responses: Record<string, ResponseLike>;
|
|
24
33
|
schemas: Record<string, SchemaLike>;
|
|
25
34
|
}
|
|
26
35
|
|
|
27
|
-
const { sample, languages, responses, schemas } = Astro.props;
|
|
36
|
+
const { components, sample, languages, responses, schemas } = Astro.props;
|
|
28
37
|
|
|
29
38
|
const requestPanels = await languageSamplePanels(
|
|
30
39
|
languages,
|
|
@@ -38,9 +47,7 @@ const responsePanels = await Promise.all(
|
|
|
38
47
|
Object.entries(response.content ?? {}).find(([type]) =>
|
|
39
48
|
type.includes("json")
|
|
40
49
|
)?.[1] ?? Object.values(response.content ?? {})[0];
|
|
41
|
-
const example = media
|
|
42
|
-
? (media.example ?? exampleValue(media.schema, schemas))
|
|
43
|
-
: undefined;
|
|
50
|
+
const example = media ? responseExample(media, schemas, components) : undefined;
|
|
44
51
|
const html =
|
|
45
52
|
example === undefined || example === null
|
|
46
53
|
? null
|