blume 2.0.1 → 2.0.2
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 +82 -0
- package/dist/cli/{chunk-vtk4a6dg.js → chunk-00gs3wqs.js} +1 -1
- package/dist/cli/{chunk-fa25z98p.js → chunk-273ygyr4.js} +4 -3
- package/dist/cli/chunk-273ygyr4.js.map +11 -0
- package/dist/cli/{chunk-yw7dm696.js → chunk-3yce002v.js} +21 -8
- package/dist/cli/{chunk-yw7dm696.js.map → chunk-3yce002v.js.map} +3 -3
- package/dist/cli/{chunk-yt5n7ppj.js → chunk-4e9b9ra6.js} +17 -7
- package/dist/cli/chunk-4e9b9ra6.js.map +10 -0
- package/dist/cli/{chunk-fs23ddbb.js → chunk-5r8g91qn.js} +352 -676
- package/dist/cli/chunk-5r8g91qn.js.map +34 -0
- package/dist/cli/{chunk-6vm74dry.js → chunk-6dtt0zfn.js} +8 -8
- package/dist/cli/{chunk-qwsrynx5.js → chunk-6k4ftwze.js} +38 -19
- package/dist/cli/{chunk-qwsrynx5.js.map → chunk-6k4ftwze.js.map} +4 -4
- package/dist/cli/{chunk-qs4q5p4e.js → chunk-7mbqtmgb.js} +16 -7
- package/dist/cli/chunk-7mbqtmgb.js.map +10 -0
- package/dist/cli/{chunk-q5163e60.js → chunk-7vtckvaw.js} +21 -19
- package/dist/cli/chunk-7vtckvaw.js.map +11 -0
- package/dist/cli/{chunk-kdp5q7ke.js → chunk-8g8ytmgx.js} +17 -18
- package/dist/cli/{chunk-kdp5q7ke.js.map → chunk-8g8ytmgx.js.map} +2 -2
- package/dist/cli/{chunk-epjnccmv.js → chunk-91ws1n6j.js} +18 -15
- package/dist/cli/chunk-91ws1n6j.js.map +10 -0
- package/dist/cli/{chunk-fxypxtvm.js → chunk-bbnwccaz.js} +2 -2
- package/dist/cli/{chunk-m3vmjgmq.js → chunk-bfwp9vp6.js} +16 -8
- package/dist/cli/chunk-bfwp9vp6.js.map +10 -0
- package/dist/cli/{chunk-f2z5v128.js → chunk-d1v5rhy0.js} +14 -15
- package/dist/cli/{chunk-f2z5v128.js.map → chunk-d1v5rhy0.js.map} +2 -2
- package/dist/cli/{chunk-6crbhc3x.js → chunk-ddndchfr.js} +21 -6
- package/dist/cli/chunk-ddndchfr.js.map +14 -0
- package/dist/cli/{chunk-ce574jw2.js → chunk-esh98wmb.js} +1 -1
- package/dist/cli/{chunk-zxcczpyx.js → chunk-fsmrqk8a.js} +1 -1
- package/dist/cli/{chunk-hdpx1tax.js → chunk-g698a744.js} +5 -5
- package/dist/cli/{chunk-jts8mvcz.js → chunk-gs7r695n.js} +9 -3
- package/dist/cli/{chunk-jts8mvcz.js.map → chunk-gs7r695n.js.map} +3 -3
- package/dist/cli/{chunk-zxh4d9vy.js → chunk-h2ez8dzb.js} +4 -4
- package/dist/cli/{chunk-5shv93fd.js → chunk-h7k3nq3v.js} +2 -2
- package/dist/cli/{chunk-79jhk4py.js → chunk-hqp2ajnh.js} +251 -122
- package/dist/cli/chunk-hqp2ajnh.js.map +35 -0
- package/dist/cli/{chunk-2hn4b8z7.js → chunk-hr8ne106.js} +109 -40
- package/dist/cli/chunk-hr8ne106.js.map +13 -0
- package/dist/cli/{chunk-6hsn950k.js → chunk-j85scx15.js} +62 -18
- package/dist/cli/chunk-j85scx15.js.map +10 -0
- package/dist/cli/{chunk-s1p84fyh.js → chunk-k7pj68a8.js} +63 -22
- package/dist/cli/chunk-k7pj68a8.js.map +11 -0
- package/dist/cli/{chunk-ah61y8py.js → chunk-mqc662a6.js} +2 -2
- package/dist/cli/{chunk-ch6g3ar0.js → chunk-n1yg3tj3.js} +4 -4
- package/dist/cli/{chunk-mb2919y2.js → chunk-nfcyttvj.js} +17 -6
- package/dist/cli/chunk-nfcyttvj.js.map +10 -0
- package/dist/cli/{chunk-kpf8rrjc.js → chunk-pbg5a4s3.js} +56 -24
- package/dist/cli/chunk-pbg5a4s3.js.map +19 -0
- package/dist/cli/{chunk-jwyddg7y.js → chunk-ppzjqwx2.js} +21 -14
- package/dist/cli/{chunk-jwyddg7y.js.map → chunk-ppzjqwx2.js.map} +4 -4
- package/dist/cli/{chunk-dh8cwk36.js → chunk-qkb5a8sa.js} +24 -9
- package/dist/cli/chunk-qkb5a8sa.js.map +10 -0
- package/dist/cli/{chunk-wm7js3j9.js → chunk-sqw4ekg1.js} +2 -2
- package/dist/cli/{chunk-qkqwkpte.js → chunk-v6ya5kcb.js} +3083 -953
- package/dist/cli/chunk-v6ya5kcb.js.map +189 -0
- package/dist/cli/{chunk-fz5wtpmh.js → chunk-w4bxdvsa.js} +18 -15
- package/dist/cli/chunk-w4bxdvsa.js.map +10 -0
- package/dist/cli/{chunk-27g6wdth.js → chunk-wdrt2k2v.js} +2 -2
- package/dist/cli/{chunk-wgm7m9qk.js → chunk-xh43dwgw.js} +158 -43
- package/dist/cli/chunk-xh43dwgw.js.map +36 -0
- package/dist/cli/{chunk-s6jhgk0q.js → chunk-zp79m0ts.js} +2 -2
- package/dist/cli/index.js +160 -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/relative-links.d.ts +9 -4
- package/dist/types/ai/static-expression.d.ts +28 -0
- package/dist/types/analytics/databuddy.d.ts +43 -0
- package/dist/types/analytics/index.d.ts +2 -0
- package/dist/types/analytics/schema.d.ts +14 -0
- 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 +9 -0
- package/dist/types/core/config-input.d.ts +4 -4
- package/dist/types/core/config.d.ts +2 -2
- package/dist/types/core/graph.d.ts +2 -0
- package/dist/types/core/i18n-ui.d.ts +31 -0
- package/dist/types/core/i18n.d.ts +7 -1
- 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 +5 -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 +52 -13
- package/dist/types/core/sources/github-releases.d.ts +5 -0
- package/dist/types/core/sources/lower.d.ts +14 -2
- package/dist/types/core/sources/normalize.d.ts +10 -1
- 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/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/cloudflare-negotiation.d.ts +3 -2
- package/dist/types/deploy/headers.d.ts +31 -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 +7 -0
- package/dist/types/deploy/platforms/vercel.d.ts +3 -2
- package/dist/types/deploy/redirects.d.ts +7 -2
- package/dist/types/deploy/vercel-negotiation.d.ts +3 -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 +17 -8
- package/docs/08-faq.mdx +9 -2
- package/docs/advanced/changelog.mdx +1 -1
- package/docs/advanced/custom-pages.mdx +4 -2
- package/docs/cli/audit.mdx +2 -2
- package/docs/cli/doctor.mdx +2 -2
- package/docs/cli/evals.mdx +2 -2
- package/docs/cli/index.mdx +4 -1
- package/docs/cli/translate.mdx +1 -1
- package/docs/configuration/analytics.mdx +23 -2
- package/docs/configuration/assistant.mdx +1 -1
- package/docs/configuration/customization.mdx +4 -3
- package/docs/configuration/index.mdx +5 -3
- package/docs/configuration/search.mdx +1 -1
- package/docs/content/components.mdx +1 -1
- package/docs/content/frontmatter.mdx +5 -1
- package/docs/content/i18n.mdx +1 -1
- package/docs/content/index.mdx +4 -2
- package/docs/content/meta.mdx +5 -3
- package/docs/content/navigation.mdx +29 -4
- package/docs/content/sources.mdx +18 -12
- package/docs/content/versioning.mdx +1 -0
- package/docs/discoverability/agent-discovery.mdx +21 -7
- package/docs/discoverability/index.mdx +2 -2
- package/docs/discoverability/llms-txt.mdx +2 -5
- package/docs/discoverability/markdown.mdx +5 -3
- package/docs/discoverability/mcp.mdx +4 -0
- package/docs/discoverability/metadata.mdx +3 -2
- package/docs/discoverability/open-graph.mdx +6 -4
- package/docs/discoverability/rss.mdx +3 -1
- package/docs/references/asyncapi.mdx +1 -1
- package/docs/references/graphql.mdx +2 -2
- package/docs/references/openapi.mdx +3 -3
- 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/mintlify.md +3 -3
- package/skills/blume-migrate/references/monorepo.md +1 -1
- package/skills/blume-migrate/references/nextra.md +1 -1
- package/skills/blume-migrate/references/starlight.md +5 -5
- package/skills/blume-migrate/scripts/mintlify-codemod.mjs +2 -2
- package/skills/blume-update-docs/references/audit-checklist.md +1 -1
- package/src/ai/agent-surface.ts +56 -0
- package/src/ai/api/spec.ts +15 -2
- package/src/ai/api-catalog.ts +7 -1
- package/src/ai/ask-context.ts +14 -2
- package/src/ai/ask-data.ts +26 -12
- package/src/ai/component-markdown.ts +43 -37
- package/src/ai/link-headers.ts +8 -3
- package/src/ai/llms.ts +4 -3
- package/src/ai/markdown.ts +23 -11
- package/src/ai/mcp/server.ts +78 -7
- package/src/ai/relative-links.ts +78 -10
- package/src/ai/static-expression.ts +416 -0
- package/src/ai/visibility.ts +45 -14
- package/src/analytics/databuddy.ts +67 -0
- package/src/analytics/head.ts +4 -0
- package/src/analytics/index.ts +2 -0
- package/src/analytics/posthog.ts +21 -3
- package/src/analytics/schema.ts +2 -0
- package/src/astro/generate.ts +71 -27
- package/src/astro/templates.ts +61 -23
- 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 +14 -0
- 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/report.ts +54 -17
- package/src/audit/run.ts +1 -0
- package/src/audit/types.ts +18 -0
- package/src/audit/url.ts +37 -6
- package/src/cli/build-failure.ts +50 -0
- package/src/cli/commands/audit.ts +7 -0
- package/src/cli/commands/build.ts +19 -5
- package/src/cli/commands/check.ts +2 -0
- package/src/cli/commands/eval.ts +1 -7
- 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 +9 -6
- package/src/cli/commands/upgrade.ts +11 -0
- 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/components/content/AccordionItem.astro +26 -22
- package/src/components/content/Badge.astro +2 -9
- package/src/components/content/Card.astro +2 -2
- package/src/components/content/Component.astro +9 -3
- 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/Tabs.astro +54 -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 +17 -0
- package/src/components/content/base-href.ts +18 -3
- package/src/components/content/inline-markdown.ts +27 -7
- package/src/components/copy-feedback.ts +35 -8
- package/src/components/islands/assistant.tsx +16 -2
- package/src/components/islands/hooks.ts +7 -2
- package/src/components/islands/webmcp.ts +12 -8
- package/src/components/layout/Banner.astro +23 -4
- package/src/components/layout/Header.astro +22 -9
- package/src/components/layout/Logo.astro +5 -0
- package/src/components/layout/NavSelector.astro +6 -1
- package/src/components/layout/NavTabMenu.astro +133 -0
- package/src/components/layout/NavTree.astro +15 -6
- package/src/components/layout/NavTreeCache.astro +5 -2
- package/src/components/layout/NavTreeScript.astro +45 -5
- package/src/components/layout/PageLayout.astro +22 -8
- package/src/components/layout/ReferenceLayout.astro +4 -1
- package/src/components/layout/RootLayout.astro +21 -8
- package/src/components/layout/Search.astro +5 -1
- package/src/components/layout/analytics-client.ts +2 -0
- package/src/components/openapi/GraphqlType.astro +11 -3
- package/src/components/openapi/MessageComposer.astro +1 -1
- package/src/components/openapi/Operation.astro +21 -5
- package/src/components/openapi/PanelTabs.astro +4 -1
- package/src/components/openapi/Playground.astro +8 -2
- package/src/components/openapi/RequestPanel.astro +9 -5
- package/src/components/openapi/SchemaProperty.astro +11 -33
- package/src/components/openapi/SchemaTable.astro +27 -52
- package/src/components/openapi/helpers.ts +90 -12
- package/src/components/openapi/message-composer.ts +8 -0
- package/src/components/openapi/message-model.ts +12 -2
- package/src/components/openapi/message.ts +4 -1
- package/src/components/openapi/operation-model.ts +40 -8
- package/src/components/openapi/panel.ts +29 -5
- package/src/components/openapi/playground-client.ts +37 -7
- package/src/components/openapi/playground-schema.ts +25 -6
- package/src/components/openapi/request.ts +2 -0
- package/src/components/openapi/schema-tree.ts +203 -0
- package/src/components/openapi/snippets.ts +30 -15
- package/src/components/openapi/validate-json.ts +1 -1
- package/src/core/base-path.ts +15 -0
- package/src/core/config-input.ts +4 -4
- package/src/core/config.ts +18 -4
- package/src/core/diagnostics.ts +217 -30
- package/src/core/graph.ts +120 -11
- package/src/core/i18n-ui.ts +39 -2
- package/src/core/i18n.ts +13 -2
- package/src/core/links.ts +7 -4
- package/src/core/load-module.ts +20 -0
- package/src/core/locale-links.ts +17 -17
- package/src/core/manifest.ts +3 -2
- package/src/core/meta.ts +69 -6
- package/src/core/nav-diagnostics.ts +56 -1
- package/src/core/navigation.ts +245 -76
- package/src/core/ordering-prefix.ts +27 -0
- package/src/core/project-graph.ts +23 -1
- package/src/core/safe-href.ts +53 -1
- package/src/core/safe-links.ts +11 -2
- package/src/core/schema.ts +70 -14
- package/src/core/sources/assets.ts +83 -41
- package/src/core/sources/contentful-rich-text.ts +3 -2
- package/src/core/sources/contentful.ts +25 -12
- package/src/core/sources/filesystem.ts +5 -1
- package/src/core/sources/github-releases.ts +106 -5
- package/src/core/sources/lexical.ts +9 -4
- package/src/core/sources/lower.ts +79 -26
- package/src/core/sources/mdx-remote.ts +1 -0
- package/src/core/sources/normalize.ts +132 -30
- package/src/core/sources/notion.ts +26 -10
- package/src/core/sources/obsidian.ts +17 -3
- package/src/core/sources/payload.ts +1 -0
- package/src/core/sources/portable-text.ts +63 -44
- 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 +9 -4
- package/src/core/sources/strapi.ts +1 -0
- package/src/core/sources/types.ts +31 -0
- 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 +17 -2
- 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 +25 -5
- package/src/deploy/cloudflare-negotiation.ts +23 -4
- package/src/deploy/headers.ts +67 -51
- package/src/deploy/node-headers.ts +148 -27
- package/src/deploy/platforms/cloudflare.ts +1 -0
- package/src/deploy/platforms/netlify.ts +82 -5
- package/src/deploy/platforms/node.ts +7 -5
- package/src/deploy/platforms/static.ts +1 -0
- package/src/deploy/platforms/types.ts +7 -0
- package/src/deploy/platforms/vercel.ts +9 -3
- package/src/deploy/redirects.ts +14 -3
- 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 +55 -8
- package/src/markdown/index.ts +6 -3
- package/src/markdown/relative-links.ts +3 -23
- package/src/markdown/route-snapshot.ts +37 -0
- package/src/og/card.ts +20 -4
- package/src/og/derive.ts +145 -4
- package/src/openapi/graphql-build.ts +28 -2
- package/src/openapi/model.ts +77 -13
- package/src/openapi/render-mdx.ts +10 -1
- package/src/registry/eject.ts +119 -22
- package/src/search/documents.ts +22 -1
- package/src/search/sync/algolia.ts +36 -2
- 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 +11 -3
- package/src/translate/run.ts +11 -5
- package/src/translate/validate.ts +10 -1
- package/src/translate/work-list.ts +36 -3
- package/src/upgrade/upgrade.ts +36 -4
- 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-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-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-vtk4a6dg.js.map → chunk-00gs3wqs.js.map} +0 -0
- /package/dist/cli/{chunk-6vm74dry.js.map → chunk-6dtt0zfn.js.map} +0 -0
- /package/dist/cli/{chunk-fxypxtvm.js.map → chunk-bbnwccaz.js.map} +0 -0
- /package/dist/cli/{chunk-ce574jw2.js.map → chunk-esh98wmb.js.map} +0 -0
- /package/dist/cli/{chunk-zxcczpyx.js.map → chunk-fsmrqk8a.js.map} +0 -0
- /package/dist/cli/{chunk-hdpx1tax.js.map → chunk-g698a744.js.map} +0 -0
- /package/dist/cli/{chunk-zxh4d9vy.js.map → chunk-h2ez8dzb.js.map} +0 -0
- /package/dist/cli/{chunk-5shv93fd.js.map → chunk-h7k3nq3v.js.map} +0 -0
- /package/dist/cli/{chunk-ah61y8py.js.map → chunk-mqc662a6.js.map} +0 -0
- /package/dist/cli/{chunk-ch6g3ar0.js.map → chunk-n1yg3tj3.js.map} +0 -0
- /package/dist/cli/{chunk-wm7js3j9.js.map → chunk-sqw4ekg1.js.map} +0 -0
- /package/dist/cli/{chunk-27g6wdth.js.map → chunk-wdrt2k2v.js.map} +0 -0
- /package/dist/cli/{chunk-s6jhgk0q.js.map → chunk-zp79m0ts.js.map} +0 -0
|
@@ -67,6 +67,7 @@ const kbd = "rounded border border-border bg-muted px-1 py-0.5 font-mono";
|
|
|
67
67
|
data-i18n-dev={s.devOnly}
|
|
68
68
|
data-i18n-empty={s.noResults}
|
|
69
69
|
data-i18n-error={s.error}
|
|
70
|
+
data-i18n-latest={s.latest}
|
|
70
71
|
data-i18n-popular={s.popular}
|
|
71
72
|
data-i18n-results={s.results}
|
|
72
73
|
data-locale={locale || undefined}
|
|
@@ -328,6 +329,7 @@ const kbd = "rounded border border-border bg-muted px-1 py-0.5 font-mono";
|
|
|
328
329
|
allMsg = "All";
|
|
329
330
|
popularMsg = "Popular";
|
|
330
331
|
resultsMsg = "Results";
|
|
332
|
+
latestMsg = "latest";
|
|
331
333
|
// The active locale to filter to (null when i18n is off), and whether the
|
|
332
334
|
// reader has opted to search across every language instead.
|
|
333
335
|
locale: string | null = null;
|
|
@@ -382,6 +384,8 @@ const kbd = "rounded border border-border bg-muted px-1 py-0.5 font-mono";
|
|
|
382
384
|
this.getAttribute("data-i18n-popular") || this.popularMsg;
|
|
383
385
|
this.resultsMsg =
|
|
384
386
|
this.getAttribute("data-i18n-results") || this.resultsMsg;
|
|
387
|
+
this.latestMsg =
|
|
388
|
+
this.getAttribute("data-i18n-latest") || this.latestMsg;
|
|
385
389
|
this.locale = this.getAttribute("data-locale");
|
|
386
390
|
// "" (the current docs) is a real version value, so a presence flag —
|
|
387
391
|
// not the attribute's truthiness — decides whether filtering is on.
|
|
@@ -765,7 +769,7 @@ const kbd = "rounded border border-border bg-muted px-1 py-0.5 font-mono";
|
|
|
765
769
|
// reader knows they're about to leave the docs they're viewing.
|
|
766
770
|
const versionTag =
|
|
767
771
|
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 ||
|
|
772
|
+
? `<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
773
|
: "";
|
|
770
774
|
el.innerHTML = `
|
|
771
775
|
<span class="mt-0.5 shrink-0 text-muted-foreground">${svg("file")}</span>
|
|
@@ -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 };
|
|
@@ -82,6 +83,7 @@ const trackGlobals = (
|
|
|
82
83
|
attempt(() => (w.__blumeGtmLayer ?? w.dataLayer)?.push({ ...props, event }));
|
|
83
84
|
// Privacy-first counters take a name, some with properties.
|
|
84
85
|
attempt(() => w.plausible?.(event, { props }));
|
|
86
|
+
attempt(() => w.databuddy?.track?.(event, props));
|
|
85
87
|
attempt(() => w.fathom?.trackEvent?.(event));
|
|
86
88
|
// Pirsch stringifies `meta` values in place, so it gets its own copy and
|
|
87
89
|
// the `blume:track` listeners still see the original types.
|
|
@@ -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 = (
|
|
@@ -123,7 +133,13 @@ const model =
|
|
|
123
133
|
requestBody,
|
|
124
134
|
schemas,
|
|
125
135
|
security,
|
|
126
|
-
|
|
136
|
+
// An operation's own `servers` override its path item's, which
|
|
137
|
+
// override the document's.
|
|
138
|
+
servers: effectiveServers(
|
|
139
|
+
operation.servers,
|
|
140
|
+
pathItem?.servers,
|
|
141
|
+
doc.servers
|
|
142
|
+
),
|
|
127
143
|
})
|
|
128
144
|
: null;
|
|
129
145
|
const sample = model ? buildRequest(model, defaultValues(model)) : null;
|
|
@@ -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 { withBase } 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`; `withBase` adds it
|
|
29
|
+
// and passes an external proxy URL through untouched.
|
|
30
|
+
const proxyUrl = proxy ? withBase(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,20 @@
|
|
|
2
2
|
import data from "blume:data";
|
|
3
3
|
|
|
4
4
|
import { highlightCode } from "../../markdown/index.ts";
|
|
5
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
responseExample,
|
|
7
|
+
type SchemaLike,
|
|
8
|
+
type SpecValue,
|
|
9
|
+
toJson,
|
|
10
|
+
} from "./helpers.ts";
|
|
6
11
|
import { languageSamplePanels } from "./sample-panels.ts";
|
|
7
12
|
import PanelTabs from "./PanelTabs.astro";
|
|
8
13
|
import type { RequestSample, SampleLanguage } from "./snippets.ts";
|
|
9
14
|
|
|
10
15
|
interface MediaTypeLike {
|
|
11
16
|
schema?: SchemaLike;
|
|
12
|
-
example?:
|
|
17
|
+
example?: SpecValue;
|
|
18
|
+
examples?: SpecValue;
|
|
13
19
|
}
|
|
14
20
|
|
|
15
21
|
interface ResponseLike {
|
|
@@ -38,9 +44,7 @@ const responsePanels = await Promise.all(
|
|
|
38
44
|
Object.entries(response.content ?? {}).find(([type]) =>
|
|
39
45
|
type.includes("json")
|
|
40
46
|
)?.[1] ?? Object.values(response.content ?? {})[0];
|
|
41
|
-
const example = media
|
|
42
|
-
? (media.example ?? exampleValue(media.schema, schemas))
|
|
43
|
-
: undefined;
|
|
47
|
+
const example = media ? responseExample(media, schemas) : undefined;
|
|
44
48
|
const html =
|
|
45
49
|
example === undefined || example === null
|
|
46
50
|
? null
|
|
@@ -3,33 +3,23 @@ import Description from "./Description.astro";
|
|
|
3
3
|
import {
|
|
4
4
|
constraints,
|
|
5
5
|
isNullable,
|
|
6
|
-
refName,
|
|
7
6
|
resolveSchema,
|
|
8
7
|
type SchemaLike,
|
|
9
8
|
typeLabel,
|
|
10
9
|
} from "./helpers.ts";
|
|
10
|
+
import { rowExpands, type SchemaRow } from "./schema-tree.ts";
|
|
11
11
|
import SchemaTable from "./SchemaTable.astro";
|
|
12
12
|
|
|
13
13
|
interface Props {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
required?: boolean;
|
|
14
|
+
/** One planned row of the parent table (see `schema-tree.ts`). */
|
|
15
|
+
row: SchemaRow;
|
|
17
16
|
schemas: Record<string, SchemaLike>;
|
|
18
|
-
seen?: string[];
|
|
19
17
|
expandAll?: boolean;
|
|
20
18
|
}
|
|
21
19
|
|
|
22
|
-
const {
|
|
23
|
-
|
|
24
|
-
schema,
|
|
25
|
-
required = false,
|
|
26
|
-
schemas,
|
|
27
|
-
seen = [],
|
|
28
|
-
expandAll = false,
|
|
29
|
-
} = Astro.props;
|
|
20
|
+
const { row, schemas, expandAll = false } = Astro.props;
|
|
21
|
+
const { name, schema, required } = row;
|
|
30
22
|
|
|
31
|
-
const refLabel = typeof schema.$ref === "string" ? refName(schema.$ref) : null;
|
|
32
|
-
const circular = refLabel !== null && seen.includes(refLabel);
|
|
33
23
|
const resolved = resolveSchema(schemas, schema);
|
|
34
24
|
|
|
35
25
|
const type = typeLabel(schema);
|
|
@@ -39,20 +29,9 @@ const nullable = isNullable(resolved);
|
|
|
39
29
|
const enumValues = Array.isArray(resolved.enum) ? resolved.enum : null;
|
|
40
30
|
const limits = constraints(resolved);
|
|
41
31
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
const
|
|
45
|
-
|
|
46
|
-
const hasObjectShape = (candidate: SchemaLike): boolean =>
|
|
47
|
-
Boolean(
|
|
48
|
-
candidate.properties ||
|
|
49
|
-
candidate.allOf ||
|
|
50
|
-
candidate.oneOf ||
|
|
51
|
-
candidate.anyOf ||
|
|
52
|
-
typeof candidate.$ref === "string"
|
|
53
|
-
);
|
|
54
|
-
const expandable =
|
|
55
|
-
!circular && (hasObjectShape(resolved) || Boolean(items && hasObjectShape(items)));
|
|
32
|
+
// Circles and schemas expanded elsewhere in the tree have no disclosure; the
|
|
33
|
+
// type label names them.
|
|
34
|
+
const children = rowExpands(row) ? row.children : undefined;
|
|
56
35
|
---
|
|
57
36
|
|
|
58
37
|
{/* The row's vertical scale is 8 / 12 / 16px, and every other reference table copies it. A
|
|
@@ -103,17 +82,16 @@ const expandable =
|
|
|
103
82
|
)
|
|
104
83
|
}
|
|
105
84
|
{
|
|
106
|
-
|
|
85
|
+
children && (
|
|
107
86
|
<details class="mt-3" open={expandAll}>
|
|
108
87
|
<summary class="cursor-pointer select-none text-accent text-xs hover:underline">
|
|
109
88
|
<span class="[details[open]>summary_&]:hidden">Show properties</span>
|
|
110
89
|
<span class="hidden [details[open]>summary_&]:inline">Hide properties</span>
|
|
111
90
|
</summary>
|
|
112
|
-
<div class="mt-3 border-border border-
|
|
91
|
+
<div class="mt-3 border-border border-s ps-4">
|
|
113
92
|
<SchemaTable
|
|
114
|
-
|
|
93
|
+
node={children.node}
|
|
115
94
|
schemas={schemas}
|
|
116
|
-
seen={seen}
|
|
117
95
|
expandAll={expandAll}
|
|
118
96
|
/>
|
|
119
97
|
</div>
|
|
@@ -1,86 +1,61 @@
|
|
|
1
1
|
---
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
refName,
|
|
5
|
-
resolveSchema,
|
|
6
|
-
type SchemaLike,
|
|
7
|
-
typeLabel,
|
|
8
|
-
} from "./helpers.ts";
|
|
2
|
+
import type { SchemaLike } from "./helpers.ts";
|
|
3
|
+
import { type SchemaNode, schemaTree } from "./schema-tree.ts";
|
|
9
4
|
import SchemaProperty from "./SchemaProperty.astro";
|
|
10
5
|
|
|
11
6
|
interface Props {
|
|
12
|
-
schema
|
|
7
|
+
/** The schema to render, planned here when no `node` is given. */
|
|
8
|
+
schema?: SchemaLike;
|
|
9
|
+
/** An already-planned subtree: how nested tables render. */
|
|
10
|
+
node?: SchemaNode;
|
|
13
11
|
schemas: Record<string, SchemaLike>;
|
|
14
|
-
/** `$ref` names already on the current branch, to break circular schemas. */
|
|
15
|
-
seen?: string[];
|
|
16
12
|
expandAll?: boolean;
|
|
17
13
|
}
|
|
18
14
|
|
|
19
|
-
const { schema
|
|
15
|
+
const { schema = {}, node: planned, schemas, expandAll = false } = Astro.props;
|
|
20
16
|
|
|
21
|
-
//
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
const circular = refLabel !== null && seen.includes(refLabel);
|
|
25
|
-
const nextSeen = refLabel ? [...seen, refLabel] : seen;
|
|
26
|
-
const resolved = circular ? schema : resolveSchema(schemas, schema);
|
|
27
|
-
|
|
28
|
-
const types = Array.isArray(resolved.type) ? resolved.type : [resolved.type];
|
|
29
|
-
const isArray = types.includes("array");
|
|
30
|
-
// Keep array items unresolved so a self-referential item `$ref` stays trackable
|
|
31
|
-
// via `seen` — resolving here would drop the name and loop forever.
|
|
32
|
-
const items = isArray ? (resolved.items ?? null) : null;
|
|
33
|
-
const branches = resolved.oneOf ?? resolved.anyOf ?? null;
|
|
34
|
-
|
|
35
|
-
const { properties, required } = circular
|
|
36
|
-
? { properties: [] as [string, SchemaLike][], required: new Set<string>() }
|
|
37
|
-
: objectProperties(resolved, schemas);
|
|
17
|
+
// The whole tree is planned once, at the top-level table, so that which named
|
|
18
|
+
// schemas expand is decided for the tree as a whole (see `schema-tree.ts`).
|
|
19
|
+
const node = planned ?? schemaTree(schema, schemas);
|
|
38
20
|
---
|
|
39
21
|
|
|
40
22
|
{
|
|
41
|
-
circular ? (
|
|
23
|
+
node.kind === "circular" ? (
|
|
42
24
|
<div class="text-muted-foreground text-sm">
|
|
43
|
-
Circular reference to <code class="text-foreground">{
|
|
25
|
+
Circular reference to <code class="text-foreground">{node.name}</code>.
|
|
44
26
|
</div>
|
|
45
|
-
) :
|
|
27
|
+
) : node.kind === "array" ? (
|
|
46
28
|
<div>
|
|
47
29
|
<div class="mb-2 text-muted-foreground text-xs">
|
|
48
|
-
Array of <code class="text-foreground">{
|
|
30
|
+
Array of <code class="text-foreground">{node.itemsLabel}</code>
|
|
49
31
|
</div>
|
|
50
|
-
{items && (
|
|
51
|
-
<Astro.self
|
|
32
|
+
{node.items && (
|
|
33
|
+
<Astro.self node={node.items.node} schemas={schemas} expandAll={expandAll} />
|
|
52
34
|
)}
|
|
53
35
|
</div>
|
|
54
|
-
) : branches ? (
|
|
36
|
+
) : node.kind === "branches" ? (
|
|
55
37
|
<div class="flex flex-col gap-3">
|
|
56
|
-
<div class="text-muted-foreground text-xs">
|
|
57
|
-
|
|
58
|
-
</div>
|
|
59
|
-
{branches.map((branch, index) => (
|
|
38
|
+
<div class="text-muted-foreground text-xs">{node.label}:</div>
|
|
39
|
+
{node.branches.map((branch) => (
|
|
60
40
|
<div class="rounded-blume border border-border p-3">
|
|
61
41
|
<div class="mb-2 font-medium text-foreground text-xs">
|
|
62
|
-
{
|
|
42
|
+
{branch.label}
|
|
63
43
|
</div>
|
|
64
|
-
<Astro.self
|
|
44
|
+
<Astro.self node={branch.slot.node} schemas={schemas} expandAll={expandAll} />
|
|
65
45
|
</div>
|
|
66
46
|
))}
|
|
67
47
|
</div>
|
|
68
|
-
) :
|
|
48
|
+
) : node.kind === "properties" ? (
|
|
69
49
|
<div class="not-prose">
|
|
70
|
-
{
|
|
71
|
-
<SchemaProperty
|
|
72
|
-
name={name}
|
|
73
|
-
schema={prop}
|
|
74
|
-
required={required.has(name)}
|
|
75
|
-
schemas={schemas}
|
|
76
|
-
seen={nextSeen}
|
|
77
|
-
expandAll={expandAll}
|
|
78
|
-
/>
|
|
50
|
+
{node.rows.map((row) => (
|
|
51
|
+
<SchemaProperty row={row} schemas={schemas} expandAll={expandAll} />
|
|
79
52
|
))}
|
|
80
53
|
</div>
|
|
81
54
|
) : (
|
|
82
55
|
<div class="text-muted-foreground text-sm">
|
|
83
|
-
<code class="text-foreground">
|
|
56
|
+
<code class="text-foreground">
|
|
57
|
+
{node.kind === "named" ? node.name : node.label}
|
|
58
|
+
</code>
|
|
84
59
|
</div>
|
|
85
60
|
)
|
|
86
61
|
}
|
|
@@ -152,17 +152,31 @@ export const resolveSchema = (
|
|
|
152
152
|
return schema;
|
|
153
153
|
};
|
|
154
154
|
|
|
155
|
-
const
|
|
155
|
+
const declaredTypeList = (type: string | string[] | undefined): string[] => {
|
|
156
156
|
if (!type) {
|
|
157
157
|
return [];
|
|
158
158
|
}
|
|
159
|
-
return
|
|
159
|
+
return Array.isArray(type) ? type : [type];
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
const nonNullTypes = (type: string | string[] | undefined): string[] =>
|
|
163
|
+
declaredTypeList(type).filter((t) => t !== "null");
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* Whether a schema admits only `null`: `{ type: "null" }`, the branch Scalar's
|
|
167
|
+
* upgrade pairs with a 3.0 `nullable: true` `$ref` (`anyOf: [$ref, { type:
|
|
168
|
+
* "null" }]`).
|
|
169
|
+
*/
|
|
170
|
+
const isNullType = (schema: SchemaLike): boolean => {
|
|
171
|
+
const types = declaredTypeList(schema.type);
|
|
172
|
+
return types.length > 0 && types.every((type) => type === "null");
|
|
160
173
|
};
|
|
161
174
|
|
|
162
175
|
/**
|
|
163
176
|
* A short, human-readable type label for a schema row. `$ref`s label by name
|
|
164
177
|
* (`Pet`, `Pet[]`) without resolving — which also means circular refs through
|
|
165
|
-
* array items can't recurse forever.
|
|
178
|
+
* array items can't recurse forever. A `null` member stays out of a union's
|
|
179
|
+
* label: rows mark it with {@link isNullable}, as they do `type: [T, "null"]`.
|
|
166
180
|
*/
|
|
167
181
|
export const typeLabel = (schema: SchemaLike): string => {
|
|
168
182
|
if (isString(schema.$ref)) {
|
|
@@ -170,24 +184,42 @@ export const typeLabel = (schema: SchemaLike): string => {
|
|
|
170
184
|
}
|
|
171
185
|
if (schema.oneOf || schema.anyOf) {
|
|
172
186
|
const branches = schema.oneOf ?? schema.anyOf ?? [];
|
|
173
|
-
const
|
|
187
|
+
const members = branches.filter((branch) => !isNullType(branch));
|
|
188
|
+
if (members.length === 0 && branches.length > 0) {
|
|
189
|
+
return "null";
|
|
190
|
+
}
|
|
191
|
+
const labels = members.map((branch) => typeLabel(branch));
|
|
174
192
|
return [...new Set(labels)].join(" | ") || "any";
|
|
175
193
|
}
|
|
176
194
|
if (schema.allOf) {
|
|
177
195
|
return "object";
|
|
178
196
|
}
|
|
179
197
|
const types = nonNullTypes(schema.type);
|
|
198
|
+
const arrayLabel = (): string => `${typeLabel(schema.items ?? {})}[]`;
|
|
199
|
+
if (types.length > 1) {
|
|
200
|
+
// A 3.1 type array names every type the value may take, not just the first.
|
|
201
|
+
return types
|
|
202
|
+
.map((type) => (type === "array" ? arrayLabel() : type))
|
|
203
|
+
.join(" | ");
|
|
204
|
+
}
|
|
180
205
|
if (types.includes("array")) {
|
|
181
|
-
return
|
|
206
|
+
return arrayLabel();
|
|
207
|
+
}
|
|
208
|
+
if (types.length === 0 && isNullType(schema)) {
|
|
209
|
+
return "null";
|
|
182
210
|
}
|
|
183
211
|
const base = types[0] ?? (schema.properties ? "object" : "any");
|
|
184
212
|
return schema.format ? `${base}<${schema.format}>` : base;
|
|
185
213
|
};
|
|
186
214
|
|
|
187
|
-
/**
|
|
215
|
+
/**
|
|
216
|
+
* Whether this schema is nullable: 3.0 `nullable`, a 3.1 `"null"` in `type`,
|
|
217
|
+
* or a `{ type: "null" }` member of a `oneOf`/`anyOf` union.
|
|
218
|
+
*/
|
|
188
219
|
export const isNullable = (schema: SchemaLike): boolean =>
|
|
189
220
|
schema.nullable === true ||
|
|
190
|
-
(Array.isArray(schema.type) && schema.type.includes("null"))
|
|
221
|
+
(Array.isArray(schema.type) && schema.type.includes("null")) ||
|
|
222
|
+
[...(schema.oneOf ?? []), ...(schema.anyOf ?? [])].some(isNullType);
|
|
191
223
|
|
|
192
224
|
/** Human-readable validation constraints for a schema, in display order. */
|
|
193
225
|
export const constraints = (schema: SchemaLike): string[] => {
|
|
@@ -263,23 +295,26 @@ export const objectProperties = (
|
|
|
263
295
|
* Build a representative example value for a schema via openapi-sampler
|
|
264
296
|
* (Redoc's generator): declared `example`/`const`/`default`/`enum` values
|
|
265
297
|
* win, formats produce realistic placeholders (`email`, `uuid`, `date-time`),
|
|
266
|
-
* `
|
|
267
|
-
*
|
|
268
|
-
*
|
|
298
|
+
* and circular `$ref` chains — which keeping refs intact allows — terminate
|
|
299
|
+
* safely. A request sample skips `readOnly` fields (a server-generated field
|
|
300
|
+
* has no place in one); a response sample skips `writeOnly` fields (a
|
|
301
|
+
* password the client sends never comes back) and keeps the `readOnly` ones.
|
|
269
302
|
*/
|
|
270
303
|
export const exampleValue = (
|
|
271
304
|
schema: SchemaLike | undefined,
|
|
272
|
-
schemas: Record<string, SchemaLike
|
|
305
|
+
schemas: Record<string, SchemaLike>,
|
|
306
|
+
direction: "request" | "response" = "request"
|
|
273
307
|
): SpecValue => {
|
|
274
308
|
if (!schema) {
|
|
275
309
|
return null;
|
|
276
310
|
}
|
|
311
|
+
const response = direction === "response";
|
|
277
312
|
try {
|
|
278
313
|
// SAFETY: SchemaLike structurally covers the JSONSchema7 fields the
|
|
279
314
|
// sampler reads, and the sampler only ever assembles JSON values.
|
|
280
315
|
return sample(
|
|
281
316
|
schema as Parameters<typeof sample>[0],
|
|
282
|
-
{ quiet: true, skipReadOnly:
|
|
317
|
+
{ quiet: true, skipReadOnly: !response, skipWriteOnly: response },
|
|
283
318
|
{ components: { schemas } }
|
|
284
319
|
) as SpecValue;
|
|
285
320
|
} catch {
|
|
@@ -289,5 +324,48 @@ export const exampleValue = (
|
|
|
289
324
|
}
|
|
290
325
|
};
|
|
291
326
|
|
|
327
|
+
/** Where an author can declare an example: a parameter or a media type. */
|
|
328
|
+
export interface ExampleCarrier {
|
|
329
|
+
example?: SpecValue;
|
|
330
|
+
examples?: SpecValue;
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
const isRecord = (value: SpecValue): value is Record<string, SpecValue> =>
|
|
334
|
+
typeof value === "object" && value !== null && !Array.isArray(value);
|
|
335
|
+
|
|
336
|
+
/**
|
|
337
|
+
* The example a parameter or media type declares: its `example`, else the
|
|
338
|
+
* first inline `value` in its `examples` map. Scalar's upgrade moves every
|
|
339
|
+
* OpenAPI 3.0 and Swagger 2.0 `example` into `examples.default.value`, and
|
|
340
|
+
* 3.1 authors write that map directly, so reading `example` alone would drop
|
|
341
|
+
* them all. `undefined` when nothing is declared.
|
|
342
|
+
*/
|
|
343
|
+
export const declaredExample = (carrier: ExampleCarrier): SpecValue => {
|
|
344
|
+
if (carrier.example !== undefined) {
|
|
345
|
+
return carrier.example;
|
|
346
|
+
}
|
|
347
|
+
const { examples } = carrier;
|
|
348
|
+
if (!isRecord(examples)) {
|
|
349
|
+
return undefined;
|
|
350
|
+
}
|
|
351
|
+
for (const entry of Object.values(examples)) {
|
|
352
|
+
if (isRecord(entry) && entry.value !== undefined) {
|
|
353
|
+
return entry.value;
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
return undefined;
|
|
357
|
+
};
|
|
358
|
+
|
|
359
|
+
/**
|
|
360
|
+
* A response media type's example for the Response panel: the declared one,
|
|
361
|
+
* else a sample built for the response direction (`readOnly` kept,
|
|
362
|
+
* `writeOnly` skipped).
|
|
363
|
+
*/
|
|
364
|
+
export const responseExample = (
|
|
365
|
+
media: ExampleCarrier & { schema?: SchemaLike },
|
|
366
|
+
schemas: Record<string, SchemaLike>
|
|
367
|
+
): SpecValue =>
|
|
368
|
+
declaredExample(media) ?? exampleValue(media.schema, schemas, "response");
|
|
369
|
+
|
|
292
370
|
/** Pretty-print a JSON value for an example/code block. */
|
|
293
371
|
export const toJson = <T>(value: T): string => JSON.stringify(value, null, 2);
|
|
@@ -199,6 +199,14 @@ export const initComposer = (root: HTMLElement): void => {
|
|
|
199
199
|
|
|
200
200
|
const client = createWsClient({ onFrame: renderFrame, onState: renderState });
|
|
201
201
|
|
|
202
|
+
// A ClientRouter navigation swaps this panel out of the document without
|
|
203
|
+
// unloading the page, so a live socket would stay open behind the next page
|
|
204
|
+
// — and coming back and connecting again would open a second one. Every
|
|
205
|
+
// swap replaces the panel, so the first one closes the socket for good.
|
|
206
|
+
document.addEventListener("astro:before-swap", () => client.disconnect(), {
|
|
207
|
+
once: true,
|
|
208
|
+
});
|
|
209
|
+
|
|
202
210
|
connectButton?.addEventListener("click", () => {
|
|
203
211
|
if (validatePayload().length > 0) {
|
|
204
212
|
return;
|
|
@@ -2,6 +2,7 @@ import type {
|
|
|
2
2
|
AsyncApiAction,
|
|
3
3
|
AsyncApiServerObject,
|
|
4
4
|
} from "../../openapi/asyncapi.ts";
|
|
5
|
+
import { withServerDefaults } from "../../openapi/model.ts";
|
|
5
6
|
import type { AsyncApiMessageLike, NamedMessage } from "./async.ts";
|
|
6
7
|
import { payloadSchema } from "./async.ts";
|
|
7
8
|
import { exampleValue, toJson } from "./helpers.ts";
|
|
@@ -78,9 +79,18 @@ const messagePayload = (
|
|
|
78
79
|
/**
|
|
79
80
|
* A server's base URL for the picker. Falls back to the bare host when the
|
|
80
81
|
* spec omits `protocol` — a label is a label, and the snippet builders read
|
|
81
|
-
* the server object itself rather than this string.
|
|
82
|
+
* the server object itself rather than this string. Server variables in the
|
|
83
|
+
* host and pathname (`{env}.events.example.com`) resolve to their declared
|
|
84
|
+
* defaults, in the label and in the object the samples and connect URL read.
|
|
82
85
|
*/
|
|
83
|
-
const serverOption = (
|
|
86
|
+
const serverOption = (spec: AsyncApiServerObject): MessageServerOption => {
|
|
87
|
+
const server = { ...spec };
|
|
88
|
+
if (spec.host !== undefined) {
|
|
89
|
+
server.host = withServerDefaults(spec.host, spec.variables);
|
|
90
|
+
}
|
|
91
|
+
if (spec.pathname !== undefined) {
|
|
92
|
+
server.pathname = withServerDefaults(spec.pathname, spec.variables);
|
|
93
|
+
}
|
|
84
94
|
const host = `${server.host ?? ""}${server.pathname ?? ""}`;
|
|
85
95
|
return {
|
|
86
96
|
label: server.protocol ? `${server.protocol}://${host}` : host,
|
|
@@ -40,7 +40,10 @@ export interface MessagePayload {
|
|
|
40
40
|
export interface MessageServerOption {
|
|
41
41
|
/** `protocol://host+pathname` — what the reader picks between. */
|
|
42
42
|
label: string;
|
|
43
|
-
/**
|
|
43
|
+
/**
|
|
44
|
+
* The spec server with its host/pathname variables at their defaults; the
|
|
45
|
+
* snippet builders read host/pathname/protocol.
|
|
46
|
+
*/
|
|
44
47
|
server: AsyncApiServerObject;
|
|
45
48
|
}
|
|
46
49
|
|