blume 2.0.2 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +1 -0
- package/CHANGELOG.md +113 -0
- package/README.md +1 -1
- package/dist/cli/{chunk-6k4ftwze.js → chunk-0gz36akr.js} +18 -2
- package/dist/cli/{chunk-6k4ftwze.js.map → chunk-0gz36akr.js.map} +3 -3
- package/dist/cli/{chunk-zp79m0ts.js → chunk-1n228xqb.js} +2 -2
- package/dist/cli/{chunk-ddndchfr.js → chunk-2f3ndkpw.js} +57 -29
- package/dist/cli/chunk-2f3ndkpw.js.map +14 -0
- package/dist/cli/{chunk-fsmrqk8a.js → chunk-2f7n4qzt.js} +8 -2
- package/dist/cli/{chunk-fsmrqk8a.js.map → chunk-2f7n4qzt.js.map} +3 -3
- package/dist/cli/{chunk-ppzjqwx2.js → chunk-2n4ps1b3.js} +17 -18
- package/dist/cli/{chunk-ppzjqwx2.js.map → chunk-2n4ps1b3.js.map} +3 -3
- package/dist/cli/{chunk-5r8g91qn.js → chunk-43zcf4gz.js} +398 -159
- package/dist/cli/chunk-43zcf4gz.js.map +36 -0
- package/dist/cli/chunk-4ejxbzee.js +39 -0
- package/dist/cli/chunk-4ejxbzee.js.map +10 -0
- package/dist/cli/{chunk-hr8ne106.js → chunk-4h8z9vv5.js} +296 -77
- package/dist/cli/chunk-4h8z9vv5.js.map +16 -0
- package/dist/cli/{chunk-k7pj68a8.js → chunk-5cg2rzgf.js} +18 -16
- package/dist/cli/{chunk-k7pj68a8.js.map → chunk-5cg2rzgf.js.map} +2 -2
- package/dist/cli/{chunk-h2ez8dzb.js → chunk-5ffywsmb.js} +4 -4
- package/dist/cli/{chunk-g698a744.js → chunk-5wj2qwn2.js} +5 -5
- package/dist/cli/chunk-6bm0xpgd.js +18 -0
- package/dist/cli/chunk-6bm0xpgd.js.map +10 -0
- package/dist/cli/{chunk-3yce002v.js → chunk-713mngdq.js} +15 -8
- package/dist/cli/chunk-713mngdq.js.map +14 -0
- package/dist/cli/{chunk-91ws1n6j.js → chunk-9geymqns.js} +17 -15
- package/dist/cli/{chunk-91ws1n6j.js.map → chunk-9geymqns.js.map} +2 -2
- package/dist/cli/{chunk-6dtt0zfn.js → chunk-9xr4dgee.js} +27 -18
- package/dist/cli/chunk-9xr4dgee.js.map +10 -0
- package/dist/cli/{chunk-sqw4ekg1.js → chunk-amrb6hgh.js} +2 -2
- package/dist/cli/chunk-cm89scdv.js +443 -0
- package/dist/cli/chunk-cm89scdv.js.map +11 -0
- package/dist/cli/{chunk-wdrt2k2v.js → chunk-cmtcnh9f.js} +90 -26
- package/dist/cli/chunk-cmtcnh9f.js.map +10 -0
- package/dist/cli/chunk-cy5bm0j0.js +104 -0
- package/dist/cli/chunk-cy5bm0j0.js.map +11 -0
- package/dist/cli/{chunk-7mbqtmgb.js → chunk-e7vvk5ya.js} +21 -12
- package/dist/cli/chunk-e7vvk5ya.js.map +10 -0
- package/dist/cli/{chunk-qkb5a8sa.js → chunk-g2z9x01v.js} +6 -98
- package/dist/cli/chunk-g2z9x01v.js.map +10 -0
- package/dist/cli/{chunk-273ygyr4.js → chunk-ga0pf4aj.js} +7 -7
- package/dist/cli/{chunk-273ygyr4.js.map → chunk-ga0pf4aj.js.map} +3 -3
- package/dist/cli/{chunk-h7k3nq3v.js → chunk-gp84za0h.js} +2 -2
- package/dist/cli/{chunk-hqp2ajnh.js → chunk-h2a48yhd.js} +195 -73
- package/dist/cli/chunk-h2a48yhd.js.map +36 -0
- package/dist/cli/{chunk-pbg5a4s3.js → chunk-jnwj5kjj.js} +71 -47
- package/dist/cli/chunk-jnwj5kjj.js.map +19 -0
- package/dist/cli/chunk-kwrg63tm.js +31 -0
- package/dist/cli/chunk-kwrg63tm.js.map +10 -0
- package/dist/cli/{chunk-8g8ytmgx.js → chunk-nd1821sk.js} +21 -19
- package/dist/cli/{chunk-8g8ytmgx.js.map → chunk-nd1821sk.js.map} +2 -2
- package/dist/cli/{chunk-w4bxdvsa.js → chunk-ntv4qrt7.js} +17 -15
- package/dist/cli/{chunk-w4bxdvsa.js.map → chunk-ntv4qrt7.js.map} +2 -2
- package/dist/cli/{chunk-bfwp9vp6.js → chunk-p804f3pe.js} +7 -7
- package/dist/cli/{chunk-4e9b9ra6.js → chunk-py62fewh.js} +6 -6
- package/dist/cli/{chunk-4e9b9ra6.js.map → chunk-py62fewh.js.map} +1 -1
- package/dist/cli/chunk-q3wxxq39.js +126 -0
- package/dist/cli/chunk-q3wxxq39.js.map +11 -0
- package/dist/cli/{chunk-j85scx15.js → chunk-rekqz4qg.js} +142 -46
- package/dist/cli/chunk-rekqz4qg.js.map +10 -0
- package/dist/cli/{chunk-00gs3wqs.js → chunk-ta27feev.js} +1 -1
- package/dist/cli/{chunk-v6ya5kcb.js → chunk-xkz5xbtv.js} +4031 -1132
- package/dist/cli/chunk-xkz5xbtv.js.map +213 -0
- package/dist/cli/{chunk-bbnwccaz.js → chunk-y4ykbark.js} +2 -2
- package/dist/cli/{chunk-n1yg3tj3.js → chunk-y5h4r2y0.js} +6 -6
- package/dist/cli/{chunk-n1yg3tj3.js.map → chunk-y5h4r2y0.js.map} +3 -3
- package/dist/cli/{chunk-nfcyttvj.js → chunk-yj17vs39.js} +9 -9
- package/dist/cli/{chunk-nfcyttvj.js.map → chunk-yj17vs39.js.map} +1 -1
- package/dist/cli/{chunk-7vtckvaw.js → chunk-yxmk4pec.js} +16 -14
- package/dist/cli/{chunk-7vtckvaw.js.map → chunk-yxmk4pec.js.map} +2 -2
- package/dist/cli/{chunk-gs7r695n.js → chunk-zccbjcj0.js} +22 -8
- package/dist/cli/{chunk-gs7r695n.js.map → chunk-zccbjcj0.js.map} +3 -3
- package/dist/cli/{chunk-xh43dwgw.js → chunk-zf748avv.js} +415 -225
- package/dist/cli/chunk-zf748avv.js.map +37 -0
- package/dist/cli/{chunk-d1v5rhy0.js → chunk-zhvd6adm.js} +16 -14
- package/dist/cli/{chunk-d1v5rhy0.js.map → chunk-zhvd6adm.js.map} +2 -2
- package/dist/cli/index.js +28 -20
- package/dist/cli/index.js.map +5 -5
- package/dist/types/ai/agent-surface.d.ts +8 -7
- package/dist/types/ai/ai-catalog.d.ts +7 -0
- package/dist/types/ai/ask-context.d.ts +22 -0
- package/dist/types/ai/ask.d.ts +271 -58
- package/dist/types/ai/index.d.ts +2 -2
- package/dist/types/ai/link-headers.d.ts +8 -1
- package/dist/types/ai/openapi-components.d.ts +5 -2
- package/dist/types/ai/relative-links.d.ts +9 -7
- package/dist/types/ai/site-skill.d.ts +26 -0
- package/dist/types/ai/skills.d.ts +20 -1
- package/dist/types/ai/tar.d.ts +1 -3
- package/dist/types/analytics/index.d.ts +2 -0
- package/dist/types/analytics/one-dollar-stats.d.ts +48 -0
- package/dist/types/analytics/schema.d.ts +14 -0
- package/dist/types/astro/integration.d.ts +11 -2
- package/dist/types/captcha/hcaptcha.d.ts +27 -0
- package/dist/types/captcha/index.d.ts +28 -0
- package/dist/types/captcha/schema.d.ts +29 -0
- package/dist/types/captcha/turnstile.d.ts +28 -0
- package/dist/types/components/content/api-field.d.ts +59 -0
- package/dist/types/components/content/api-page.d.ts +95 -0
- package/dist/types/components/layout/nav-utils.d.ts +26 -0
- package/dist/types/components/openapi/helpers.d.ts +137 -0
- package/dist/types/components/openapi/security.d.ts +85 -0
- package/dist/types/consent/ethyca.d.ts +48 -0
- package/dist/types/consent/index.d.ts +37 -0
- package/dist/types/consent/native.d.ts +28 -0
- package/dist/types/consent/osano.d.ts +42 -0
- package/dist/types/consent/schema.d.ts +110 -0
- package/dist/types/core/base-path.d.ts +21 -7
- package/dist/types/core/config-input.d.ts +196 -27
- package/dist/types/core/data.d.ts +49 -4
- package/dist/types/core/directive-diagnostics.d.ts +12 -0
- package/dist/types/core/footer.d.ts +8 -0
- package/dist/types/core/heading-markers.d.ts +5 -7
- package/dist/types/core/i18n-ui.d.ts +86 -0
- package/dist/types/core/i18n.d.ts +2 -0
- package/dist/types/core/includes.d.ts +8 -2
- package/dist/types/core/last-modified.d.ts +10 -0
- package/dist/types/core/localizable.d.ts +7 -0
- package/dist/types/core/meta.d.ts +8 -0
- package/dist/types/core/page-modes.d.ts +29 -0
- package/dist/types/core/redirect-patterns.d.ts +144 -0
- package/dist/types/core/related.d.ts +40 -0
- package/dist/types/core/schema.d.ts +558 -56
- package/dist/types/core/sources/lower.d.ts +29 -16
- package/dist/types/core/sources/normalize.d.ts +13 -1
- package/dist/types/core/sources/read.d.ts +5 -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 +1 -1
- package/dist/types/core/variables.d.ts +42 -0
- package/dist/types/deploy/artifacts.d.ts +6 -4
- package/dist/types/deploy/headers.d.ts +5 -0
- package/dist/types/deploy/node-headers.d.ts +13 -2
- package/dist/types/deploy/platforms/cloudflare.d.ts +5 -0
- package/dist/types/deploy/platforms/netlify.d.ts +7 -0
- package/dist/types/deploy/platforms/types.d.ts +8 -0
- package/dist/types/deploy/platforms/vercel.d.ts +6 -0
- package/dist/types/deploy/redirects.d.ts +61 -22
- package/dist/types/deploy/vercel-negotiation.d.ts +9 -0
- package/dist/types/markdown/code-title.d.ts +17 -0
- package/dist/types/markdown/directives.d.ts +62 -0
- package/dist/types/markdown/features.d.ts +24 -2
- package/dist/types/markdown/mdast.d.ts +63 -0
- package/dist/types/narration/build.d.ts +70 -0
- package/dist/types/narration/provider.d.ts +26 -0
- package/dist/types/narration/script.d.ts +154 -0
- package/dist/types/openapi/asyncapi.d.ts +4 -2
- package/dist/types/openapi/model.d.ts +12 -6
- package/dist/types/openapi/overlay.d.ts +54 -0
- package/dist/types/openapi/parse.d.ts +13 -0
- package/dist/types/openapi/references.d.ts +14 -4
- package/dist/types/ratelimit/cloudflare.d.ts +39 -0
- package/dist/types/ratelimit/index.d.ts +27 -0
- package/dist/types/ratelimit/memory.d.ts +36 -0
- package/dist/types/ratelimit/schema.d.ts +111 -0
- package/dist/types/ratelimit/upstash.d.ts +21 -0
- package/dist/types/ratelimit/wrangler.d.ts +23 -0
- package/dist/types/reference/asyncapi.d.ts +10 -10
- package/dist/types/reference/graphql.d.ts +13 -10
- package/dist/types/reference/openapi.d.ts +33 -12
- package/dist/types/reference/options.d.ts +45 -5
- package/dist/types/reference/scalar.d.ts +13 -0
- package/dist/types/reference/schema.d.ts +60 -36
- package/dist/types/search/documents.d.ts +12 -1
- package/dist/types/search/orama-index.d.ts +4 -0
- package/dist/types/seo/metatags.d.ts +20 -0
- package/docs/02-deployment.mdx +44 -6
- package/docs/03-upgrading.mdx +4 -4
- package/docs/04-migrating.mdx +1 -1
- package/docs/08-faq.mdx +1 -1
- package/docs/advanced/changelog.mdx +2 -2
- package/docs/advanced/custom-pages.mdx +3 -3
- package/docs/advanced/skills.mdx +14 -0
- package/docs/cli/audit.mdx +38 -2
- package/docs/cli/evals.mdx +3 -3
- package/docs/cli/index.mdx +1 -0
- package/docs/cli/translate.mdx +3 -3
- package/docs/cli/version.mdx +1 -1
- package/docs/configuration/analytics.mdx +22 -1
- package/docs/configuration/assistant.mdx +188 -36
- package/docs/configuration/consent.mdx +100 -0
- package/docs/configuration/customization.mdx +6 -4
- package/docs/configuration/index.mdx +63 -5
- package/docs/configuration/meta.ts +3 -0
- package/docs/configuration/narration.mdx +119 -0
- package/docs/configuration/rate-limiting.mdx +69 -0
- package/docs/configuration/search.mdx +30 -2
- package/docs/configuration/theming.mdx +3 -1
- package/docs/content/components.mdx +107 -1
- package/docs/content/frontmatter.mdx +77 -1
- package/docs/content/i18n.mdx +40 -3
- package/docs/content/includes.mdx +16 -0
- package/docs/content/index.mdx +4 -2
- package/docs/content/islands.mdx +1 -1
- package/docs/content/meta.mdx +4 -1
- package/docs/content/meta.ts +1 -0
- package/docs/content/navigation.mdx +28 -6
- package/docs/content/sources/contentful.mdx +32 -0
- package/docs/content/sources/custom.mdx +39 -0
- package/docs/content/sources/github-releases.mdx +31 -0
- package/docs/content/sources/index.mdx +91 -0
- package/docs/content/sources/meta.ts +16 -0
- package/docs/content/sources/notion.mdx +32 -0
- package/docs/content/sources/obsidian.mdx +37 -0
- package/docs/content/sources/payload.mdx +30 -0
- package/docs/content/sources/remote-mdx.mdx +40 -0
- package/docs/content/sources/sanity.mdx +29 -0
- package/docs/content/sources/strapi.mdx +31 -0
- package/docs/content/syntax.mdx +81 -2
- package/docs/content/variables.mdx +41 -0
- package/docs/content/versioning.mdx +1 -1
- package/docs/discoverability/agent-discovery.mdx +30 -3
- package/docs/discoverability/index.mdx +3 -2
- package/docs/discoverability/llms-txt.mdx +1 -1
- package/docs/discoverability/markdown.mdx +2 -2
- package/docs/discoverability/metadata.mdx +17 -0
- package/docs/discoverability/open-graph.mdx +5 -3
- package/docs/discoverability/rss.mdx +1 -1
- package/docs/references/api-pages.mdx +74 -0
- package/docs/references/asyncapi.mdx +2 -2
- package/docs/references/graphql.mdx +3 -3
- package/docs/references/meta.ts +1 -1
- package/docs/references/openapi.mdx +106 -5
- package/docs/references/scalar.mdx +3 -1
- package/package.json +36 -1
- package/skills/blume/SKILL.md +3 -0
- package/skills/blume-migrate/SKILL.md +5 -5
- package/skills/blume-migrate/references/docusaurus.md +3 -3
- package/skills/blume-migrate/references/fumadocs.md +1 -1
- package/skills/blume-migrate/references/mintlify.md +37 -19
- package/skills/blume-migrate/references/nextra.md +3 -3
- package/skills/blume-migrate/references/starlight.md +2 -1
- package/skills/blume-migrate/scripts/mintlify-codemod.mjs +67 -16
- package/skills/blume-write-skill/SKILL.md +82 -0
- package/src/ai/agent-readability.ts +4 -3
- package/src/ai/agent-surface.ts +9 -7
- package/src/ai/ai-catalog.ts +12 -5
- package/src/ai/api/handlers.ts +2 -2
- package/src/ai/api/spec.ts +2 -2
- package/src/ai/api-catalog.ts +6 -2
- package/src/ai/ask-context.ts +73 -20
- package/src/ai/ask-data.ts +6 -0
- package/src/ai/ask-tools.ts +142 -0
- package/src/ai/ask.ts +354 -76
- package/src/ai/changelog-markdown.ts +2 -2
- package/src/ai/component-markdown.ts +75 -0
- package/src/ai/cors.ts +2 -0
- package/src/ai/index.ts +12 -0
- package/src/ai/link-headers.ts +14 -5
- package/src/ai/llms.ts +24 -9
- package/src/ai/markdown.ts +2 -1
- package/src/ai/mcp/data.ts +6 -0
- package/src/ai/mcp/discovery.ts +2 -2
- package/src/ai/mcp/query.ts +2 -2
- package/src/ai/mcp/server.ts +2 -2
- package/src/ai/openapi-components.ts +31 -9
- package/src/ai/relative-links.ts +42 -26
- package/src/ai/serializers.ts +2 -1
- package/src/ai/site-skill.ts +274 -0
- package/src/ai/skills.ts +49 -3
- package/src/ai/tar.ts +139 -12
- package/src/ai/write-skill.ts +97 -0
- package/src/analytics/head.ts +4 -0
- package/src/analytics/index.ts +5 -0
- package/src/analytics/one-dollar-stats.ts +86 -0
- package/src/analytics/schema.ts +2 -0
- package/src/astro/generate.ts +133 -19
- package/src/astro/include-hmr.ts +31 -12
- package/src/astro/include-refresh.ts +19 -8
- package/src/astro/index.ts +1 -0
- package/src/astro/integration.ts +143 -14
- package/src/astro/module-types.ts +6 -0
- package/src/astro/runtime-modules.ts +28 -13
- package/src/astro/templates.ts +364 -67
- package/src/astro/variables.ts +31 -0
- package/src/audit/catalog.ts +19 -0
- package/src/audit/checks/contrast.ts +183 -0
- package/src/audit/checks/i18n.ts +2 -3
- package/src/audit/checks/indexability.ts +2 -3
- package/src/audit/checks/links.ts +13 -13
- package/src/audit/checks/sitemap.ts +2 -3
- package/src/audit/graph.ts +3 -1
- package/src/audit/redirects.ts +46 -15
- package/src/audit/run.ts +14 -9
- package/src/audit/snapshot.ts +5 -0
- package/src/audit/types.ts +2 -1
- package/src/blume-modules.d.ts +7 -0
- package/src/captcha/client.ts +152 -0
- package/src/captcha/hcaptcha.ts +36 -0
- package/src/captcha/index.ts +28 -0
- package/src/captcha/schema.ts +32 -0
- package/src/captcha/turnstile.ts +38 -0
- package/src/captcha/verify.ts +71 -0
- package/src/cli/args.ts +32 -0
- package/src/cli/command-meta.ts +5 -0
- package/src/cli/commands/audit.ts +4 -1
- package/src/cli/commands/doctor.ts +25 -17
- package/src/cli/commands/eval.ts +19 -11
- package/src/cli/commands/skill.ts +96 -0
- package/src/cli/commands/translate.ts +9 -12
- package/src/cli/commands/validate.ts +3 -1
- package/src/cli/dev-lock.ts +157 -37
- package/src/cli/index.ts +5 -0
- package/src/cli/report-format.ts +11 -6
- package/src/cli/required-secrets.ts +71 -29
- package/src/components/BlumePage.astro +2 -0
- package/src/components/colors.ts +19 -0
- package/src/components/content/ApiEndpoint.astro +18 -0
- package/src/components/content/ApiField.astro +79 -0
- package/src/components/content/ApiPlayground.astro +62 -0
- package/src/components/content/ApiRail.astro +19 -0
- package/src/components/content/Badge.astro +5 -3
- package/src/components/content/Color.astro +1 -0
- package/src/components/content/Component.astro +2 -2
- package/src/components/content/FileTree.astro +1 -0
- package/src/components/content/GithubInfo.astro +1 -0
- package/src/components/content/Panel.astro +1 -0
- package/src/components/content/ParamField.astro +25 -0
- package/src/components/content/RequestExample.astro +17 -0
- package/src/components/content/ResponseExample.astro +17 -0
- package/src/components/content/ResponseField.astro +32 -0
- package/src/components/content/Step.astro +1 -0
- package/src/components/content/Tab.astro +0 -1
- package/src/components/content/Tabs.astro +4 -0
- package/src/components/content/Tile.astro +1 -0
- package/src/components/content/Tooltip.astro +1 -0
- package/src/components/content/Tree.astro +1 -0
- package/src/components/content/TypeTable.astro +4 -1
- package/src/components/content/View.astro +21 -0
- package/src/components/content/ViewSwitcher.astro +168 -0
- package/src/components/content/api-field.ts +100 -0
- package/src/components/content/api-page.ts +224 -0
- package/src/components/content/badge-color.ts +5 -2
- package/src/components/content/base-href.ts +13 -36
- package/src/components/content/view-switcher.ts +71 -0
- package/src/components/index.ts +2 -0
- package/src/components/islands/Assistant.astro +10 -1
- package/src/components/islands/assistant.tsx +125 -18
- package/src/components/islands/base-path.ts +47 -10
- package/src/components/islands/code-question.ts +62 -0
- package/src/components/islands/hooks.ts +145 -40
- package/src/components/islands/support-link.ts +68 -0
- package/src/components/islands/webmcp.ts +4 -2
- package/src/components/layout/Analytics.astro +11 -2
- package/src/components/layout/Banner.astro +14 -10
- package/src/components/layout/Breadcrumbs.astro +11 -4
- package/src/components/layout/ConsentBanner.astro +62 -0
- package/src/components/layout/ConsentHead.astro +38 -0
- package/src/components/layout/Directory.astro +94 -0
- package/src/components/layout/DiscoveryLinks.astro +9 -5
- package/src/components/layout/DrawerSwitchers.astro +51 -0
- package/src/components/layout/Empty.astro +2 -2
- package/src/components/layout/Header.astro +124 -82
- package/src/components/layout/LanguageSwitcher.astro +50 -17
- package/src/components/layout/NarrationPlayer.astro +1085 -0
- package/src/components/layout/NavSelector.astro +35 -9
- package/src/components/layout/NavTabMenu.astro +3 -3
- package/src/components/layout/NavTree.astro +16 -6
- package/src/components/layout/PageActions.astro +4 -3
- package/src/components/layout/PageFeedback.astro +54 -49
- package/src/components/layout/PageLayout.astro +78 -9
- package/src/components/layout/Pagination.astro +3 -3
- package/src/components/layout/ReferenceLayout.astro +17 -6
- package/src/components/layout/RelatedPages.astro +42 -0
- package/src/components/layout/RootLayout.astro +313 -50
- package/src/components/layout/Search.astro +64 -30
- package/src/components/layout/SiteFooter.astro +124 -0
- package/src/components/layout/SiteMetatags.astro +16 -0
- package/src/components/layout/VersionBanner.astro +2 -2
- package/src/components/layout/analytics-client.ts +12 -0
- package/src/components/layout/consent/native.ts +79 -0
- package/src/components/layout/consent/types.ts +37 -0
- package/src/components/layout/footer-links.ts +53 -0
- package/src/components/layout/footer-socials.ts +87 -0
- package/src/components/layout/locale-redirect.ts +107 -0
- package/src/components/layout/nav-utils.ts +83 -0
- package/src/components/layout/page-feedback.ts +96 -0
- package/src/components/layout/search/analytics.ts +98 -0
- package/src/components/layout/search/flexsearch.ts +17 -5
- package/src/components/layout/search/orama-cloud.ts +26 -14
- package/src/components/layout/search/types.ts +20 -0
- package/src/components/layout/search/typesense.ts +5 -1
- package/src/components/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/Operation.astro +163 -13
- package/src/components/openapi/Playground.astro +4 -4
- package/src/components/openapi/RequestBody.astro +6 -4
- package/src/components/openapi/RequestPanel.astro +63 -8
- package/src/components/openapi/Responses.astro +6 -4
- package/src/components/openapi/SchemaTable.astro +7 -0
- package/src/components/openapi/async-snippets.ts +4 -4
- package/src/components/openapi/async.ts +38 -6
- package/src/components/openapi/code-samples.ts +97 -0
- package/src/components/openapi/helpers.ts +19 -9
- package/src/components/openapi/message-composer.ts +6 -1
- package/src/components/openapi/message.ts +17 -2
- package/src/components/openapi/operation-model.ts +81 -11
- package/src/components/openapi/panel.ts +4 -2
- package/src/components/openapi/param-style.ts +181 -0
- package/src/components/openapi/playground-client.ts +73 -16
- package/src/components/openapi/request.ts +190 -26
- package/src/components/openapi/schema-tree.ts +30 -24
- package/src/components/openapi/security.ts +6 -3
- package/src/components/openapi/snippets.ts +953 -13
- package/src/components/openapi/ws-client.ts +18 -2
- package/src/components/props.ts +6 -0
- package/src/consent/client.ts +95 -0
- package/src/consent/clients.ts +19 -0
- package/src/consent/ethyca.ts +71 -0
- package/src/consent/head.ts +24 -0
- package/src/consent/index.ts +37 -0
- package/src/consent/init.ts +29 -0
- package/src/consent/native.ts +36 -0
- package/src/consent/osano.ts +59 -0
- package/src/consent/schema.ts +30 -0
- package/src/core/base-path.ts +62 -16
- package/src/core/builtin-tags.ts +5 -0
- package/src/core/client-address.ts +19 -0
- package/src/core/config-input.ts +203 -27
- package/src/core/data.ts +44 -4
- package/src/core/diagnostics.ts +5 -2
- package/src/core/directive-diagnostics.ts +99 -0
- package/src/core/footer.ts +26 -0
- package/src/core/frontmatter.ts +21 -18
- package/src/core/graph.ts +39 -36
- package/src/core/heading-markers.ts +5 -18
- package/src/core/i18n-ui.ts +82 -2
- package/src/core/i18n.ts +31 -3
- package/src/core/includes.ts +20 -3
- package/src/core/last-modified.ts +25 -3
- package/src/core/links.ts +16 -2
- package/src/core/locale-links.ts +5 -1
- package/src/core/localizable.ts +26 -0
- package/src/core/meta.ts +33 -19
- package/src/core/navigation.ts +71 -20
- package/src/core/page-modes.ts +56 -0
- package/src/core/project-graph.ts +138 -10
- package/src/core/redirect-patterns.ts +491 -0
- package/src/core/related.ts +131 -0
- package/src/core/schema.ts +342 -68
- package/src/core/sources/contentful-rich-text.ts +27 -20
- package/src/core/sources/filesystem.ts +20 -2
- package/src/core/sources/github-releases.ts +25 -6
- package/src/core/sources/lexical.ts +23 -18
- package/src/core/sources/lower.ts +201 -34
- package/src/core/sources/mdx-remote.ts +51 -16
- package/src/core/sources/normalize.ts +327 -91
- package/src/core/sources/notion.ts +52 -25
- package/src/core/sources/obsidian.ts +23 -6
- package/src/core/sources/portable-text.ts +38 -21
- package/src/core/sources/read.ts +8 -3
- package/src/core/sources/strapi-blocks.ts +20 -16
- package/src/core/sources/watch.ts +20 -7
- package/src/core/standard-schema.ts +10 -6
- package/src/core/types.ts +1 -1
- package/src/core/ui-packs/ar.ts +43 -0
- package/src/core/ui-packs/bg.ts +45 -0
- package/src/core/ui-packs/bn.ts +43 -0
- package/src/core/ui-packs/ca.ts +46 -0
- package/src/core/ui-packs/cs.ts +44 -0
- package/src/core/ui-packs/da.ts +45 -0
- package/src/core/ui-packs/de.ts +46 -0
- package/src/core/ui-packs/el.ts +45 -0
- package/src/core/ui-packs/es.ts +46 -0
- package/src/core/ui-packs/fa.ts +45 -0
- package/src/core/ui-packs/fi.ts +45 -0
- package/src/core/ui-packs/fr.ts +46 -0
- package/src/core/ui-packs/he.ts +43 -0
- package/src/core/ui-packs/hi.ts +44 -0
- package/src/core/ui-packs/hr.ts +45 -0
- package/src/core/ui-packs/hu.ts +44 -0
- package/src/core/ui-packs/id.ts +45 -0
- package/src/core/ui-packs/it.ts +45 -0
- package/src/core/ui-packs/ja.ts +45 -0
- package/src/core/ui-packs/ko.ts +44 -0
- package/src/core/ui-packs/nl.ts +46 -0
- package/src/core/ui-packs/no.ts +44 -0
- package/src/core/ui-packs/pl.ts +45 -0
- package/src/core/ui-packs/pt-br.ts +46 -0
- package/src/core/ui-packs/pt.ts +45 -0
- package/src/core/ui-packs/ro.ts +45 -0
- package/src/core/ui-packs/ru.ts +45 -0
- package/src/core/ui-packs/sk.ts +44 -0
- package/src/core/ui-packs/sr.ts +45 -0
- package/src/core/ui-packs/sv.ts +44 -0
- package/src/core/ui-packs/th.ts +43 -0
- package/src/core/ui-packs/tr.ts +45 -0
- package/src/core/ui-packs/uk.ts +45 -0
- package/src/core/ui-packs/vi.ts +45 -0
- package/src/core/ui-packs/zh-tw.ts +43 -0
- package/src/core/ui-packs/zh.ts +43 -0
- package/src/core/variables.ts +103 -0
- package/src/core/version-cut.ts +52 -15
- package/src/deploy/artifacts.ts +104 -14
- package/src/deploy/cloudflare-negotiation.ts +39 -17
- package/src/deploy/headers.ts +10 -5
- package/src/deploy/node-headers.ts +64 -10
- package/src/deploy/platforms/cloudflare.ts +44 -3
- package/src/deploy/platforms/netlify.ts +34 -1
- package/src/deploy/platforms/node.ts +1 -0
- package/src/deploy/platforms/static.ts +1 -0
- package/src/deploy/platforms/types.ts +8 -0
- package/src/deploy/platforms/vercel.ts +38 -2
- package/src/deploy/redirects.ts +139 -36
- 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 +36 -0
- package/src/markdown/api-rail.ts +259 -0
- package/src/markdown/base-links.ts +34 -36
- package/src/markdown/code-title.ts +35 -9
- package/src/markdown/directives.ts +242 -36
- package/src/markdown/features.ts +20 -2
- package/src/markdown/fence-meta.ts +2 -0
- package/src/markdown/include.ts +11 -1
- package/src/markdown/index.ts +35 -11
- package/src/markdown/math.ts +4 -4
- package/src/markdown/mdast.ts +5 -2
- package/src/markdown/relative-links.ts +12 -4
- package/src/markdown/variables.ts +56 -0
- package/src/markdown/views.ts +82 -0
- package/src/narration/build.ts +412 -0
- package/src/narration/player.ts +249 -0
- package/src/narration/provider.ts +29 -0
- package/src/narration/script.ts +592 -0
- package/src/og/card.ts +136 -11
- package/src/og/derive.ts +41 -31
- package/src/og/index.ts +1 -0
- package/src/openapi/asyncapi.ts +4 -2
- package/src/openapi/model.ts +77 -36
- package/src/openapi/overlay.ts +256 -0
- package/src/openapi/parse.ts +55 -2
- package/src/openapi/proxy.ts +63 -10
- package/src/openapi/references.ts +21 -5
- package/src/openapi/render-mdx.ts +46 -3
- package/src/openapi/scalar.ts +40 -6
- package/src/openapi/source.ts +1 -1
- package/src/ratelimit/cloudflare.ts +54 -0
- package/src/ratelimit/index.ts +30 -0
- package/src/ratelimit/memory.ts +45 -0
- package/src/ratelimit/runtime.ts +229 -0
- package/src/ratelimit/schema.ts +28 -0
- package/src/ratelimit/upstash.ts +30 -0
- package/src/ratelimit/wrangler.ts +70 -0
- package/src/reference/asyncapi.ts +2 -2
- package/src/reference/graphql.ts +5 -2
- package/src/reference/openapi.ts +21 -7
- package/src/reference/options.ts +51 -7
- package/src/reference/scalar.ts +33 -8
- package/src/registry/eject.ts +201 -28
- package/src/registry/registry.ts +7 -0
- package/src/search/adapters/version-scope.ts +30 -0
- package/src/search/documents.ts +93 -28
- package/src/search/orama-index.ts +28 -3
- package/src/search/pagefind-ranking.ts +39 -0
- package/src/search/popular.ts +2 -1
- package/src/search/sync/algolia.ts +15 -4
- package/src/search/sync/orama-cloud.ts +3 -0
- package/src/search/sync/typesense.ts +5 -0
- package/src/seo/jsonld.ts +7 -3
- package/src/seo/metatags.ts +67 -0
- package/src/theme/chrome-icons.ts +1 -0
- package/src/theme/color.ts +500 -0
- package/src/theme/entry.ts +56 -3
- package/src/theme/palette.ts +121 -45
- package/src/translate/meta.ts +68 -24
- package/src/translate/prompts.ts +1 -0
- package/src/translate/run.ts +3 -3
- package/src/translate/validate.ts +12 -3
- package/src/translate/work-list.ts +56 -17
- package/src/upgrade/upgrade.ts +4 -171
- package/dist/cli/chunk-3yce002v.js.map +0 -14
- package/dist/cli/chunk-5r8g91qn.js.map +0 -34
- package/dist/cli/chunk-6dtt0zfn.js.map +0 -10
- package/dist/cli/chunk-7mbqtmgb.js.map +0 -10
- package/dist/cli/chunk-ddndchfr.js.map +0 -14
- package/dist/cli/chunk-esh98wmb.js +0 -23
- package/dist/cli/chunk-esh98wmb.js.map +0 -10
- package/dist/cli/chunk-hqp2ajnh.js.map +0 -35
- package/dist/cli/chunk-hr8ne106.js.map +0 -13
- package/dist/cli/chunk-j85scx15.js.map +0 -10
- package/dist/cli/chunk-mqc662a6.js +0 -75
- package/dist/cli/chunk-mqc662a6.js.map +0 -11
- package/dist/cli/chunk-pbg5a4s3.js.map +0 -19
- package/dist/cli/chunk-qkb5a8sa.js.map +0 -10
- package/dist/cli/chunk-v6ya5kcb.js.map +0 -189
- package/dist/cli/chunk-wdrt2k2v.js.map +0 -10
- package/dist/cli/chunk-xh43dwgw.js.map +0 -36
- package/docs/content/sources.mdx +0 -338
- /package/dist/cli/{chunk-zp79m0ts.js.map → chunk-1n228xqb.js.map} +0 -0
- /package/dist/cli/{chunk-h2ez8dzb.js.map → chunk-5ffywsmb.js.map} +0 -0
- /package/dist/cli/{chunk-g698a744.js.map → chunk-5wj2qwn2.js.map} +0 -0
- /package/dist/cli/{chunk-sqw4ekg1.js.map → chunk-amrb6hgh.js.map} +0 -0
- /package/dist/cli/{chunk-h7k3nq3v.js.map → chunk-gp84za0h.js.map} +0 -0
- /package/dist/cli/{chunk-bfwp9vp6.js.map → chunk-p804f3pe.js.map} +0 -0
- /package/dist/cli/{chunk-00gs3wqs.js.map → chunk-ta27feev.js.map} +0 -0
- /package/dist/cli/{chunk-bbnwccaz.js.map → chunk-y4ykbark.js.map} +0 -0
|
@@ -16,8 +16,14 @@ import type {
|
|
|
16
16
|
PlaygroundModel,
|
|
17
17
|
RequestValues,
|
|
18
18
|
} from "./request.ts";
|
|
19
|
-
import {
|
|
20
|
-
|
|
19
|
+
import {
|
|
20
|
+
bodyEncoding,
|
|
21
|
+
buildRequest,
|
|
22
|
+
PROXY_HEADERS_HEADER,
|
|
23
|
+
redactAuth,
|
|
24
|
+
} from "./request.ts";
|
|
25
|
+
import { fetchRefusesMethod, sampleLanguages } from "./snippets.ts";
|
|
26
|
+
import type { RequestSample } from "./snippets.ts";
|
|
21
27
|
import { validateJson } from "./validate-json.ts";
|
|
22
28
|
|
|
23
29
|
/**
|
|
@@ -42,6 +48,16 @@ const COOKIE_MESSAGE =
|
|
|
42
48
|
"send the cookie credential you entered. Copy the sample above and run it " +
|
|
43
49
|
"from a terminal instead.";
|
|
44
50
|
|
|
51
|
+
/**
|
|
52
|
+
* fetch refuses the TRACE method outright, proxied or not: the browser throws
|
|
53
|
+
* before anything is sent, which the send's catch would misdiagnose as the
|
|
54
|
+
* CORS wall or an unreachable host. The cURL and Python samples can send it.
|
|
55
|
+
*/
|
|
56
|
+
const TRACE_MESSAGE =
|
|
57
|
+
"Browsers don't allow a page to send a `TRACE` request, so this panel " +
|
|
58
|
+
"can't send it. Run the cURL or Python sample above from a terminal " +
|
|
59
|
+
"instead.";
|
|
60
|
+
|
|
45
61
|
/**
|
|
46
62
|
* A fetch that fails before any response when the API couldn't be reached at
|
|
47
63
|
* all — a mistyped host, a refused connection, no network — rather than
|
|
@@ -185,6 +201,50 @@ const removeStored = (key: string): void => {
|
|
|
185
201
|
}
|
|
186
202
|
};
|
|
187
203
|
|
|
204
|
+
/**
|
|
205
|
+
* The headers a live send carries. A `Cookie` header can still arrive via a
|
|
206
|
+
* spec-declared header parameter; the browser would silently drop the
|
|
207
|
+
* forbidden name anyway, so it is stripped rather than earn a console
|
|
208
|
+
* warning. Blume's own proxy — always a path on this site — forwards only the
|
|
209
|
+
* headers named in {@link PROXY_HEADERS_HEADER}, never ones the browser or
|
|
210
|
+
* the platform add on their own; a multipart body's Content-Type is fetch's,
|
|
211
|
+
* written with the boundary, so it is named without being set. An external
|
|
212
|
+
* proxy on another origin gets no such header: it would only be one more name
|
|
213
|
+
* for its preflight to allow.
|
|
214
|
+
*/
|
|
215
|
+
const sendHeaders = (sample: RequestSample, proxy: string) => {
|
|
216
|
+
const headers = { ...sample.headers };
|
|
217
|
+
delete headers.Cookie;
|
|
218
|
+
if (proxy.startsWith("/") && !proxy.startsWith("//")) {
|
|
219
|
+
const names = Object.keys(headers);
|
|
220
|
+
if (sample.formData) {
|
|
221
|
+
names.push("Content-Type");
|
|
222
|
+
}
|
|
223
|
+
headers[PROXY_HEADERS_HEADER] = names.join(", ");
|
|
224
|
+
}
|
|
225
|
+
return headers;
|
|
226
|
+
};
|
|
227
|
+
|
|
228
|
+
/**
|
|
229
|
+
* The body a live send carries: multipart parts as `FormData`, anything else
|
|
230
|
+
* as its text. fetch throws a synchronous TypeError for a GET/HEAD with a
|
|
231
|
+
* body — which the send's catch would mislabel as CORS — so a spec that
|
|
232
|
+
* declares a GET requestBody keeps its samples, but the live send drops it.
|
|
233
|
+
*/
|
|
234
|
+
const sendBody = (sample: RequestSample): string | FormData | undefined => {
|
|
235
|
+
if (sample.method === "GET" || sample.method === "HEAD") {
|
|
236
|
+
return undefined;
|
|
237
|
+
}
|
|
238
|
+
if (!sample.formData) {
|
|
239
|
+
return sample.body;
|
|
240
|
+
}
|
|
241
|
+
const form = new FormData();
|
|
242
|
+
for (const [name, value] of sample.formData) {
|
|
243
|
+
form.append(name, value);
|
|
244
|
+
}
|
|
245
|
+
return form;
|
|
246
|
+
};
|
|
247
|
+
|
|
188
248
|
/** A one-line text element for the response/error regions. */
|
|
189
249
|
const line = (className: string, text: string): HTMLElement => {
|
|
190
250
|
const el = document.createElement("div");
|
|
@@ -332,9 +392,11 @@ export const initPlayground = (root: HTMLElement): void => {
|
|
|
332
392
|
}
|
|
333
393
|
// An emptied editor means "no body" (see `bodyFor`), not invalid JSON —
|
|
334
394
|
// reporting a syntax error there would block a send the request builder is
|
|
335
|
-
// perfectly happy to make.
|
|
395
|
+
// perfectly happy to make. A raw media type (`text/plain`, XML) isn't
|
|
396
|
+
// JSON at all, so it isn't checked as JSON either.
|
|
397
|
+
const raw = bodyEncoding(model.body?.contentType ?? "") === "raw";
|
|
336
398
|
const errors =
|
|
337
|
-
bodyArea.value.trim() === ""
|
|
399
|
+
raw || bodyArea.value.trim() === ""
|
|
338
400
|
? []
|
|
339
401
|
: validateJson(bodyArea.value, model.body?.schema);
|
|
340
402
|
bodyErrors.textContent = "";
|
|
@@ -453,6 +515,11 @@ export const initPlayground = (root: HTMLElement): void => {
|
|
|
453
515
|
if (!response || sending) {
|
|
454
516
|
return;
|
|
455
517
|
}
|
|
518
|
+
if (fetchRefusesMethod(model.method)) {
|
|
519
|
+
response.textContent = "";
|
|
520
|
+
response.append(line(ERROR_TEXT, TRACE_MESSAGE));
|
|
521
|
+
return;
|
|
522
|
+
}
|
|
456
523
|
if (validateBody().length > 0) {
|
|
457
524
|
return;
|
|
458
525
|
}
|
|
@@ -494,11 +561,7 @@ export const initPlayground = (root: HTMLElement): void => {
|
|
|
494
561
|
sample.url
|
|
495
562
|
)}`
|
|
496
563
|
: sample.url;
|
|
497
|
-
|
|
498
|
-
// the browser would silently drop the forbidden name anyway, so strip it
|
|
499
|
-
// rather than earn a console warning.
|
|
500
|
-
const headers = { ...sample.headers };
|
|
501
|
-
delete headers.Cookie;
|
|
564
|
+
const headers = sendHeaders(sample, proxy);
|
|
502
565
|
// fetch surfaces an invalid URL or header value as the same TypeError a
|
|
503
566
|
// CORS rejection produces, and the catch below would misdiagnose it as the
|
|
504
567
|
// CORS wall. Both are validated here, where the real error can be shown,
|
|
@@ -526,13 +589,7 @@ export const initPlayground = (root: HTMLElement): void => {
|
|
|
526
589
|
const start = performance.now();
|
|
527
590
|
try {
|
|
528
591
|
const res = await fetch(url, {
|
|
529
|
-
|
|
530
|
-
// which the catch below would mislabel as CORS. A spec that declares
|
|
531
|
-
// a GET requestBody keeps its samples, but the live send drops it.
|
|
532
|
-
body:
|
|
533
|
-
sample.method === "GET" || sample.method === "HEAD"
|
|
534
|
-
? undefined
|
|
535
|
-
: sample.body,
|
|
592
|
+
body: sendBody(sample),
|
|
536
593
|
headers,
|
|
537
594
|
method: sample.method,
|
|
538
595
|
// A `TimeoutError` DOMException is not a TypeError, so it reads as a
|
|
@@ -1,3 +1,14 @@
|
|
|
1
|
+
import {
|
|
2
|
+
defaultExplode,
|
|
3
|
+
defaultStyle,
|
|
4
|
+
isJsonObject,
|
|
5
|
+
memberText,
|
|
6
|
+
parseStyledValue,
|
|
7
|
+
queryPairs,
|
|
8
|
+
styledValue,
|
|
9
|
+
templateValue,
|
|
10
|
+
} from "./param-style.ts";
|
|
11
|
+
import type { JsonValue } from "./param-style.ts";
|
|
1
12
|
import type { RequestSample } from "./snippets.ts";
|
|
2
13
|
|
|
3
14
|
/**
|
|
@@ -10,7 +21,18 @@ import type { RequestSample } from "./snippets.ts";
|
|
|
10
21
|
* byte-for-byte what gets sent.
|
|
11
22
|
*/
|
|
12
23
|
|
|
13
|
-
|
|
24
|
+
/**
|
|
25
|
+
* How a parameter or form-body field serializes, as far as the spec says:
|
|
26
|
+
* the request builder applies the OpenAPI defaults for what it leaves out.
|
|
27
|
+
*/
|
|
28
|
+
export interface ParamSerialization {
|
|
29
|
+
/** The spec's `style`; else the location's default. */
|
|
30
|
+
style?: string;
|
|
31
|
+
/** The spec's `explode`; else the style's default. */
|
|
32
|
+
explode?: boolean;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export interface PlaygroundParam extends ParamSerialization {
|
|
14
36
|
name: string;
|
|
15
37
|
in: "path" | "query" | "header";
|
|
16
38
|
required: boolean;
|
|
@@ -49,9 +71,14 @@ export interface PlaygroundBody {
|
|
|
49
71
|
contentType: string;
|
|
50
72
|
/** Present when the schema is a flat object of primitives -> typed fields UI. */
|
|
51
73
|
fields?: PlaygroundBodyField[];
|
|
52
|
-
/**
|
|
74
|
+
/**
|
|
75
|
+
* Prefill for the raw editor: pretty-printed example JSON, or a raw media
|
|
76
|
+
* type's (`text/plain`, XML) string example verbatim; "" when none.
|
|
77
|
+
*/
|
|
53
78
|
example: string;
|
|
54
79
|
schema?: ValidationSchema;
|
|
80
|
+
/** A form-urlencoded body's per-field `encoding` (`style`/`explode`). */
|
|
81
|
+
encoding?: Record<string, ParamSerialization>;
|
|
55
82
|
}
|
|
56
83
|
|
|
57
84
|
export type AuthKind = "bearer" | "basic" | "apiKey" | "oauth2";
|
|
@@ -103,6 +130,38 @@ export interface RequestValues {
|
|
|
103
130
|
export const paramKey = (p: { in: string; name: string }): string =>
|
|
104
131
|
`${p.in}:${p.name}`;
|
|
105
132
|
|
|
133
|
+
/**
|
|
134
|
+
* The request header a proxied send names the headers the playground set in,
|
|
135
|
+
* comma-separated. Blume's built-in proxy forwards those and nothing else, so
|
|
136
|
+
* credentials the browser attaches on its own — HTTP Basic auth for a docs
|
|
137
|
+
* site behind a password, platform headers added in front of the docs server
|
|
138
|
+
* — never reach the documented API.
|
|
139
|
+
*/
|
|
140
|
+
export const PROXY_HEADERS_HEADER = "X-Blume-Proxy-Headers";
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* How a body's media type is put on the wire: JSON as the editor text,
|
|
144
|
+
* `application/x-www-form-urlencoded` as `name=value` pairs, and
|
|
145
|
+
* `multipart/form-data` as form parts — both from the editor's JSON object —
|
|
146
|
+
* and any other type (`text/plain`, XML) as the raw text.
|
|
147
|
+
*/
|
|
148
|
+
export type BodyEncoding = "json" | "form" | "multipart" | "raw";
|
|
149
|
+
|
|
150
|
+
/** A `+json` suffix or a `json` subtype: `application/json`, `application/vnd.api+json`. */
|
|
151
|
+
const JSON_MEDIA_TYPE = /[+/]json$/u;
|
|
152
|
+
|
|
153
|
+
/** The {@link BodyEncoding} a body's media type (parameters ignored) takes. */
|
|
154
|
+
export const bodyEncoding = (contentType: string): BodyEncoding => {
|
|
155
|
+
const type = (contentType.split(";")[0] ?? "").trim().toLowerCase();
|
|
156
|
+
if (type === "application/x-www-form-urlencoded") {
|
|
157
|
+
return "form";
|
|
158
|
+
}
|
|
159
|
+
if (type === "multipart/form-data") {
|
|
160
|
+
return "multipart";
|
|
161
|
+
}
|
|
162
|
+
return JSON_MEDIA_TYPE.test(type) ? "json" : "raw";
|
|
163
|
+
};
|
|
164
|
+
|
|
106
165
|
/** Values pre-filled from the model's precomputed examples; auth entries empty. */
|
|
107
166
|
export const defaultValues = (model: PlaygroundModel): RequestValues => ({
|
|
108
167
|
auth: Object.fromEntries(
|
|
@@ -197,48 +256,119 @@ const applyAuth = (
|
|
|
197
256
|
}
|
|
198
257
|
};
|
|
199
258
|
|
|
200
|
-
/**
|
|
259
|
+
/**
|
|
260
|
+
* A form-urlencoded body's `name=value` pairs: each field serialized like a
|
|
261
|
+
* query parameter, under the `encoding` the spec declares for it (`form`,
|
|
262
|
+
* exploded, by default — so a list repeats its name).
|
|
263
|
+
*/
|
|
264
|
+
const urlencodedBody = (
|
|
265
|
+
value: { [key: string]: JsonValue },
|
|
266
|
+
encoding: PlaygroundBody["encoding"]
|
|
267
|
+
): string =>
|
|
268
|
+
Object.entries(value)
|
|
269
|
+
.flatMap(([name, member]) => {
|
|
270
|
+
const style = encoding?.[name]?.style ?? "form";
|
|
271
|
+
return queryPairs(
|
|
272
|
+
name,
|
|
273
|
+
styledValue(member),
|
|
274
|
+
style,
|
|
275
|
+
encoding?.[name]?.explode ?? defaultExplode(style)
|
|
276
|
+
);
|
|
277
|
+
})
|
|
278
|
+
.join("&");
|
|
279
|
+
|
|
280
|
+
/** Multipart form parts in order: a list contributes one part per item. */
|
|
281
|
+
const multipartParts = (value: {
|
|
282
|
+
[key: string]: JsonValue;
|
|
283
|
+
}): [string, string][] =>
|
|
284
|
+
Object.entries(value).flatMap(([name, member]) =>
|
|
285
|
+
Array.isArray(member)
|
|
286
|
+
? member.map((item): [string, string] => [name, memberText(item)])
|
|
287
|
+
: [[name, memberText(member)]]
|
|
288
|
+
);
|
|
289
|
+
|
|
290
|
+
/**
|
|
291
|
+
* The editor text serialized for the body's media type, with a parsed mirror
|
|
292
|
+
* when it is valid JSON. A form body is built from the editor's JSON object;
|
|
293
|
+
* text that isn't one (mid-edit, or a raw media type) is sent as written.
|
|
294
|
+
*/
|
|
201
295
|
const bodyFor = (
|
|
296
|
+
body: PlaygroundBody,
|
|
202
297
|
text: string | undefined
|
|
203
|
-
): Pick<RequestSample, "body" | "bodyValue"> => {
|
|
298
|
+
): Pick<RequestSample, "body" | "bodyValue" | "formData"> => {
|
|
204
299
|
if (text === undefined || text === "") {
|
|
205
300
|
return {};
|
|
206
301
|
}
|
|
302
|
+
const encoding = bodyEncoding(body.contentType);
|
|
303
|
+
if (encoding === "raw") {
|
|
304
|
+
return { body: text };
|
|
305
|
+
}
|
|
306
|
+
let value: JsonValue;
|
|
207
307
|
try {
|
|
208
|
-
|
|
308
|
+
value = JSON.parse(text);
|
|
209
309
|
} catch {
|
|
210
|
-
// Not valid JSON (mid-edit
|
|
211
|
-
//
|
|
310
|
+
// Not valid JSON (mid-edit): still send it — the structured mirror is
|
|
311
|
+
// only a nicety for consumers of `bodyValue`.
|
|
212
312
|
return { body: text };
|
|
213
313
|
}
|
|
314
|
+
if (encoding === "json" || !isJsonObject(value)) {
|
|
315
|
+
return { body: text, bodyValue: value };
|
|
316
|
+
}
|
|
317
|
+
return encoding === "form"
|
|
318
|
+
? { body: urlencodedBody(value, body.encoding), bodyValue: value }
|
|
319
|
+
: { bodyValue: value, formData: multipartParts(value) };
|
|
214
320
|
};
|
|
215
321
|
|
|
216
|
-
/**
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
322
|
+
/**
|
|
323
|
+
* A path or header parameter's value under its `style`: an array or object
|
|
324
|
+
* parameter's JSON text becomes `dog,cat` (simple), `.dog.cat` (label), or
|
|
325
|
+
* `;tags=dog;tags=cat` (matrix) rather than its JSON.
|
|
326
|
+
*/
|
|
327
|
+
const styledParam = (
|
|
328
|
+
param: PlaygroundParam,
|
|
329
|
+
value: string,
|
|
330
|
+
encode: (text: string) => string
|
|
331
|
+
): string => {
|
|
332
|
+
const style = param.style ?? defaultStyle(param.in);
|
|
333
|
+
return templateValue(
|
|
334
|
+
param.name,
|
|
335
|
+
parseStyledValue(value, param.type),
|
|
336
|
+
style,
|
|
337
|
+
param.explode ?? defaultExplode(style),
|
|
338
|
+
encode
|
|
339
|
+
);
|
|
340
|
+
};
|
|
222
341
|
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
342
|
+
/**
|
|
343
|
+
* The model's path with each `{param}` filled in. An empty value substitutes
|
|
344
|
+
* the raw param name, so a blank form still renders a readable templated URL
|
|
345
|
+
* instead of `//`.
|
|
346
|
+
*/
|
|
347
|
+
const resolvePath = (model: PlaygroundModel, values: RequestValues): string => {
|
|
348
|
+
let resolved = model.path;
|
|
226
349
|
for (const param of model.params) {
|
|
227
350
|
if (param.in !== "path") {
|
|
228
351
|
continue;
|
|
229
352
|
}
|
|
230
353
|
const value = values.params[paramKey(param)] ?? "";
|
|
231
|
-
|
|
354
|
+
resolved = resolved.replace(
|
|
232
355
|
`{${param.name}}`,
|
|
233
|
-
value === "" ? param.name :
|
|
356
|
+
value === "" ? param.name : styledParam(param, value, encodeURIComponent)
|
|
234
357
|
);
|
|
235
358
|
}
|
|
359
|
+
return resolved;
|
|
360
|
+
};
|
|
236
361
|
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
362
|
+
/**
|
|
363
|
+
* The query parameters' `name=value` pairs in model order, each name added to
|
|
364
|
+
* `seen` so a query-borne credential can defer to it.
|
|
365
|
+
*/
|
|
366
|
+
const queryParams = (
|
|
367
|
+
model: PlaygroundModel,
|
|
368
|
+
values: RequestValues,
|
|
369
|
+
seen: Set<string>
|
|
370
|
+
): string[] => {
|
|
240
371
|
const query: string[] = [];
|
|
241
|
-
const seen = new Set<string>();
|
|
242
372
|
for (const param of model.params) {
|
|
243
373
|
if (param.in !== "query") {
|
|
244
374
|
continue;
|
|
@@ -251,10 +381,37 @@ export const buildRequest = (
|
|
|
251
381
|
continue;
|
|
252
382
|
}
|
|
253
383
|
seen.add(param.name);
|
|
384
|
+
const style = param.style ?? defaultStyle(param.in);
|
|
254
385
|
query.push(
|
|
255
|
-
|
|
386
|
+
...queryPairs(
|
|
387
|
+
param.name,
|
|
388
|
+
parseStyledValue(value, param.type),
|
|
389
|
+
style,
|
|
390
|
+
param.explode ?? defaultExplode(style)
|
|
391
|
+
)
|
|
256
392
|
);
|
|
257
393
|
}
|
|
394
|
+
return query;
|
|
395
|
+
};
|
|
396
|
+
|
|
397
|
+
/** THE one request builder: samples, copy buttons, and fetch all consume its output. */
|
|
398
|
+
export const buildRequest = (
|
|
399
|
+
model: PlaygroundModel,
|
|
400
|
+
values: RequestValues
|
|
401
|
+
): RequestSample => {
|
|
402
|
+
// The server's trailing slash only goes when a path is joined onto it: a
|
|
403
|
+
// GraphQL endpoint (no path) is sent exactly as configured, and
|
|
404
|
+
// `https://host/graphql/` is not always the same route as `…/graphql`.
|
|
405
|
+
const base =
|
|
406
|
+
model.path === ""
|
|
407
|
+
? values.server
|
|
408
|
+
: values.server.replace(TRAILING_SLASH, "");
|
|
409
|
+
|
|
410
|
+
// Query params with a value contribute in model order; a query-borne auth
|
|
411
|
+
// credential appends after — unless the spec also declares that name as an
|
|
412
|
+
// explicit query parameter, whose (better) example wins.
|
|
413
|
+
const seen = new Set<string>();
|
|
414
|
+
const query = queryParams(model, values, seen);
|
|
258
415
|
|
|
259
416
|
// Auth first, so a spec that also declares the credential as an explicit
|
|
260
417
|
// header parameter overrides it below with its own (better) example.
|
|
@@ -268,12 +425,18 @@ export const buildRequest = (
|
|
|
268
425
|
// Required headers emit even when blank, mirroring the query rule above —
|
|
269
426
|
// except a blank one never clobbers a credential auth already placed
|
|
270
427
|
// under the same name.
|
|
271
|
-
if (value !== ""
|
|
428
|
+
if (value !== "") {
|
|
429
|
+
headers[param.name] = styledParam(param, value, (text) => text);
|
|
430
|
+
} else if (param.required && headers[param.name] === undefined) {
|
|
272
431
|
headers[param.name] = value;
|
|
273
432
|
}
|
|
274
433
|
}
|
|
275
434
|
|
|
276
|
-
const { body, bodyValue } = model.body
|
|
435
|
+
const { body, bodyValue, formData } = model.body
|
|
436
|
+
? bodyFor(model.body, values.body)
|
|
437
|
+
: {};
|
|
438
|
+
// Multipart parts carry no Content-Type here: the client (curl, fetch,
|
|
439
|
+
// requests) writes it along with the boundary that separates the parts.
|
|
277
440
|
if (body !== undefined && model.body) {
|
|
278
441
|
headers["Content-Type"] = model.body.contentType;
|
|
279
442
|
}
|
|
@@ -282,8 +445,9 @@ export const buildRequest = (
|
|
|
282
445
|
return {
|
|
283
446
|
body,
|
|
284
447
|
bodyValue,
|
|
448
|
+
formData,
|
|
285
449
|
headers,
|
|
286
450
|
method: model.method.toUpperCase(),
|
|
287
|
-
url: `${base}${
|
|
451
|
+
url: `${base}${resolvePath(model, values)}${search}`,
|
|
288
452
|
};
|
|
289
453
|
};
|
|
@@ -55,6 +55,11 @@ export type SchemaNode =
|
|
|
55
55
|
kind: "branches";
|
|
56
56
|
label: "One of" | "Any of";
|
|
57
57
|
branches: { label: string; slot: SchemaSlot }[];
|
|
58
|
+
/**
|
|
59
|
+
* Properties the schema declares beside its `oneOf`/`anyOf`, which
|
|
60
|
+
* every variant shares; absent when it declares none.
|
|
61
|
+
*/
|
|
62
|
+
rows?: SchemaRow[];
|
|
58
63
|
}
|
|
59
64
|
| { kind: "properties"; rows: SchemaRow[] }
|
|
60
65
|
| { kind: "type"; label: string };
|
|
@@ -125,19 +130,6 @@ export const schemaTree = (
|
|
|
125
130
|
: { itemsLabel: typeLabel({}), kind: "array" },
|
|
126
131
|
};
|
|
127
132
|
}
|
|
128
|
-
const branches = schema.oneOf ?? schema.anyOf;
|
|
129
|
-
if (branches) {
|
|
130
|
-
return {
|
|
131
|
-
node: {
|
|
132
|
-
branches: branches.map((branch, index) => ({
|
|
133
|
-
label: typeLabel(branch) || `Option ${index + 1}`,
|
|
134
|
-
slot: table(branch, ancestors),
|
|
135
|
-
})),
|
|
136
|
-
kind: "branches",
|
|
137
|
-
label: schema.oneOf ? "One of" : "Any of",
|
|
138
|
-
},
|
|
139
|
-
};
|
|
140
|
-
}
|
|
141
133
|
// A row discloses nested structure — never a model inside itself.
|
|
142
134
|
const rowChildren = (property: SchemaLike): SchemaSlot | undefined => {
|
|
143
135
|
if (
|
|
@@ -155,18 +147,32 @@ export const schemaTree = (
|
|
|
155
147
|
: undefined;
|
|
156
148
|
};
|
|
157
149
|
const { properties, required } = objectProperties(schema, schemas);
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
150
|
+
const rows: SchemaRow[] = properties.map(([name, property]) => ({
|
|
151
|
+
children: rowChildren(property),
|
|
152
|
+
name,
|
|
153
|
+
required: required.has(name),
|
|
154
|
+
schema: property,
|
|
155
|
+
}));
|
|
156
|
+
// Shared properties beside a `oneOf`/`anyOf` (`amount` and `currency`
|
|
157
|
+
// next to `Card | BankAccount`) render above the variants, planned first
|
|
158
|
+
// as they read first.
|
|
159
|
+
const branches = schema.oneOf ?? schema.anyOf;
|
|
160
|
+
if (branches) {
|
|
161
|
+
const node: Extract<SchemaNode, { kind: "branches" }> = {
|
|
162
|
+
branches: branches.map((branch, index) => ({
|
|
163
|
+
label: typeLabel(branch) || `Option ${index + 1}`,
|
|
164
|
+
slot: table(branch, ancestors),
|
|
165
|
+
})),
|
|
166
|
+
kind: "branches",
|
|
167
|
+
label: schema.oneOf ? "One of" : "Any of",
|
|
169
168
|
};
|
|
169
|
+
if (rows.length > 0) {
|
|
170
|
+
node.rows = rows;
|
|
171
|
+
}
|
|
172
|
+
return { node };
|
|
173
|
+
}
|
|
174
|
+
if (rows.length > 0) {
|
|
175
|
+
return { node: { kind: "properties", rows } };
|
|
170
176
|
}
|
|
171
177
|
return { node: { kind: "type", label: typeLabel(schema) } };
|
|
172
178
|
};
|
|
@@ -45,12 +45,15 @@ export interface OperationSecurity {
|
|
|
45
45
|
/**
|
|
46
46
|
* The requirement list an operation actually enforces: its own `security` when
|
|
47
47
|
* declared — the OpenAPI override rule, where `[]` removes the default and
|
|
48
|
-
* makes the operation public — else the document's root `security`.
|
|
48
|
+
* makes the operation public — else the document's root `security`. A webhook
|
|
49
|
+
* takes only its own: the API sends it, so the root requirements, which guard
|
|
50
|
+
* calls to the API, say nothing about what the receiving endpoint checks.
|
|
49
51
|
*/
|
|
50
52
|
export const effectiveSecurity = (
|
|
51
53
|
operation?: SecurityRequirementLike[],
|
|
52
|
-
document?: SecurityRequirementLike[]
|
|
53
|
-
|
|
54
|
+
document?: SecurityRequirementLike[],
|
|
55
|
+
webhook = false
|
|
56
|
+
): SecurityRequirementLike[] => operation ?? (webhook ? [] : document) ?? [];
|
|
54
57
|
|
|
55
58
|
/**
|
|
56
59
|
* Resolve requirement names against `components.securitySchemes`. A name with
|