blume 2.0.3 → 2.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +1 -0
- package/CHANGELOG.md +142 -0
- package/README.md +1 -1
- package/dist/cli/{chunk-5f86nr5m.js → chunk-073rdvgb.js} +21 -48
- package/dist/cli/{chunk-5f86nr5m.js.map → chunk-073rdvgb.js.map} +4 -5
- package/dist/cli/{chunk-ga0pf4aj.js → chunk-0n9xkp3d.js} +12 -3
- package/dist/cli/{chunk-ga0pf4aj.js.map → chunk-0n9xkp3d.js.map} +3 -3
- package/dist/cli/chunk-150jk7km.js +52 -0
- package/dist/cli/chunk-150jk7km.js.map +10 -0
- package/dist/cli/{chunk-9t7a85s3.js → chunk-313vnn40.js} +30 -19
- package/dist/cli/chunk-313vnn40.js.map +10 -0
- package/dist/cli/{chunk-tkacnehg.js → chunk-3v3ffbrj.js} +2 -2
- package/dist/cli/{chunk-q58y5e6a.js → chunk-3x6x3pph.js} +46 -24
- package/dist/cli/chunk-3x6x3pph.js.map +10 -0
- package/dist/cli/{chunk-1d7ve1dm.js → chunk-42t4jxdx.js} +37 -5
- package/dist/cli/chunk-42t4jxdx.js.map +12 -0
- package/dist/cli/{chunk-8ktnccpt.js → chunk-54ztw1nj.js} +21 -2
- package/dist/cli/chunk-54ztw1nj.js.map +10 -0
- package/dist/cli/{chunk-hm3vjy5s.js → chunk-5vjtgs6e.js} +28 -10
- package/dist/cli/{chunk-hm3vjy5s.js.map → chunk-5vjtgs6e.js.map} +4 -4
- package/dist/cli/chunk-66w9j7p6.js +322 -0
- package/dist/cli/chunk-66w9j7p6.js.map +14 -0
- package/dist/cli/{chunk-2hsdwb9n.js → chunk-7ppf1rva.js} +34 -18
- package/dist/cli/chunk-7ppf1rva.js.map +10 -0
- package/dist/cli/{chunk-r9rcc4w7.js → chunk-8y2kmjv8.js} +7 -7
- package/dist/cli/{chunk-r20tn01b.js → chunk-c1y538kd.js} +8 -2
- package/dist/cli/{chunk-r20tn01b.js.map → chunk-c1y538kd.js.map} +3 -3
- package/dist/cli/{chunk-2eytanqx.js → chunk-c887fj0s.js} +2 -2
- package/dist/cli/{chunk-p3v96n38.js → chunk-cfyg47zg.js} +16 -6
- package/dist/cli/chunk-cfyg47zg.js.map +10 -0
- package/dist/cli/chunk-cm89scdv.js +443 -0
- package/dist/cli/chunk-cm89scdv.js.map +11 -0
- package/dist/cli/{chunk-akbpwfxc.js → chunk-dzwehpy7.js} +2 -2
- package/dist/cli/{chunk-wrr3j9w9.js → chunk-e6atmn4h.js} +299 -72
- package/dist/cli/chunk-e6atmn4h.js.map +36 -0
- package/dist/cli/{chunk-tzmab476.js → chunk-e8xw9qkh.js} +8 -6
- package/dist/cli/{chunk-tzmab476.js.map → chunk-e8xw9qkh.js.map} +3 -3
- package/dist/cli/{chunk-6dsbexzp.js → chunk-e9q7a2ak.js} +17 -15
- package/dist/cli/{chunk-6dsbexzp.js.map → chunk-e9q7a2ak.js.map} +2 -2
- package/dist/cli/{chunk-pv29h0wf.js → chunk-ehweg4fr.js} +5155 -1249
- package/dist/cli/chunk-ehweg4fr.js.map +218 -0
- package/dist/cli/{chunk-c8chx29p.js → chunk-ep6nd0rn.js} +390 -318
- package/dist/cli/chunk-ep6nd0rn.js.map +36 -0
- package/dist/cli/{chunk-p73c0m7w.js → chunk-fdrkhpjy.js} +18 -15
- package/dist/cli/{chunk-p73c0m7w.js.map → chunk-fdrkhpjy.js.map} +3 -3
- package/dist/cli/{chunk-2z928egk.js → chunk-ft9vfys6.js} +5 -5
- package/dist/cli/{chunk-5m5nmvyq.js → chunk-gb420vvz.js} +316 -79
- package/dist/cli/chunk-gb420vvz.js.map +17 -0
- package/dist/cli/{chunk-vg9r4eb9.js → chunk-hebn0tpx.js} +86 -13
- package/dist/cli/chunk-hebn0tpx.js.map +14 -0
- package/dist/cli/{chunk-35d4wj9f.js → chunk-htrwgabr.js} +41 -23
- package/dist/cli/chunk-htrwgabr.js.map +15 -0
- package/dist/cli/{chunk-g4hq16wv.js → chunk-hx3xqnk9.js} +16 -14
- package/dist/cli/{chunk-g4hq16wv.js.map → chunk-hx3xqnk9.js.map} +2 -2
- package/dist/cli/chunk-j134vrp2.js +65 -0
- package/dist/cli/chunk-j134vrp2.js.map +10 -0
- package/dist/cli/{chunk-a58773jm.js → chunk-kma9f6sf.js} +2 -2
- package/dist/cli/chunk-kwrg63tm.js +31 -0
- package/dist/cli/chunk-kwrg63tm.js.map +10 -0
- package/dist/cli/{chunk-ey84smr6.js → chunk-mrcccgnh.js} +6 -6
- package/dist/cli/{chunk-ey84smr6.js.map → chunk-mrcccgnh.js.map} +1 -1
- package/dist/cli/{chunk-yfyb25rh.js → chunk-n0v7m8ry.js} +24 -8
- package/dist/cli/chunk-n0v7m8ry.js.map +14 -0
- package/dist/cli/{chunk-j85vccga.js → chunk-ncj7w596.js} +576 -367
- package/dist/cli/chunk-ncj7w596.js.map +35 -0
- package/dist/cli/{chunk-5xvm6tfj.js → chunk-nq1d20w2.js} +17 -15
- package/dist/cli/{chunk-5xvm6tfj.js.map → chunk-nq1d20w2.js.map} +2 -2
- package/dist/cli/{chunk-pehfxfta.js → chunk-nrns10mj.js} +6 -98
- package/dist/cli/chunk-nrns10mj.js.map +10 -0
- package/dist/cli/{chunk-crgn1q09.js → chunk-sds923fa.js} +4 -4
- package/dist/cli/chunk-t2m5j4pr.js +104 -0
- package/dist/cli/chunk-t2m5j4pr.js.map +11 -0
- package/dist/cli/{chunk-acanzt5p.js → chunk-tdqhyxfz.js} +6 -6
- package/dist/cli/chunk-tphac74f.js +126 -0
- package/dist/cli/chunk-tphac74f.js.map +11 -0
- package/dist/cli/chunk-w1r4vase.js +18 -0
- package/dist/cli/chunk-w1r4vase.js.map +10 -0
- package/dist/cli/{chunk-3em5wd2y.js → chunk-zccbjcj0.js} +4 -3
- package/dist/cli/{chunk-3em5wd2y.js.map → chunk-zccbjcj0.js.map} +2 -2
- package/dist/cli/index.js +31 -20
- package/dist/cli/index.js.map +5 -5
- package/dist/types/ai/agent-surface.d.ts +8 -7
- package/dist/types/ai/ai-catalog.d.ts +7 -0
- package/dist/types/ai/ask-context.d.ts +26 -0
- package/dist/types/ai/ask.d.ts +271 -58
- package/dist/types/ai/component-markdown.d.ts +2 -0
- package/dist/types/ai/index.d.ts +2 -2
- package/dist/types/ai/openapi-components.d.ts +4 -1
- package/dist/types/ai/site-skill.d.ts +26 -0
- package/dist/types/ai/skills.d.ts +16 -0
- package/dist/types/astro/integration.d.ts +9 -0
- package/dist/types/astro/markdown-negotiation.d.ts +3 -0
- package/dist/types/astro/pages.d.ts +10 -0
- package/dist/types/captcha/hcaptcha.d.ts +27 -0
- package/dist/types/captcha/index.d.ts +28 -0
- package/dist/types/captcha/schema.d.ts +29 -0
- package/dist/types/captcha/turnstile.d.ts +28 -0
- package/dist/types/cli/init/scaffold.d.ts +1 -1
- package/dist/types/components/content/api-field.d.ts +62 -0
- package/dist/types/components/content/api-page.d.ts +100 -0
- package/dist/types/components/layout/nav-utils.d.ts +26 -0
- package/dist/types/components/openapi/code-samples.d.ts +29 -0
- package/dist/types/components/openapi/helpers.d.ts +158 -0
- package/dist/types/components/openapi/security.d.ts +95 -0
- package/dist/types/components/openapi/snippets.d.ts +60 -0
- package/dist/types/consent/ethyca.d.ts +48 -0
- package/dist/types/consent/index.d.ts +37 -0
- package/dist/types/consent/native.d.ts +28 -0
- package/dist/types/consent/osano.d.ts +42 -0
- package/dist/types/consent/schema.d.ts +110 -0
- package/dist/types/core/changelog-index.d.ts +8 -0
- package/dist/types/core/config-input.d.ts +217 -23
- package/dist/types/core/data.d.ts +53 -4
- package/dist/types/core/footer.d.ts +8 -0
- package/dist/types/core/i18n-ui.d.ts +88 -0
- package/dist/types/core/includes.d.ts +8 -2
- package/dist/types/core/links.d.ts +8 -0
- package/dist/types/core/localizable.d.ts +7 -0
- package/dist/types/core/page-modes.d.ts +29 -0
- package/dist/types/core/probe.d.ts +2 -0
- package/dist/types/core/project-graph.d.ts +6 -0
- package/dist/types/core/redirect-patterns.d.ts +152 -0
- package/dist/types/core/related.d.ts +40 -0
- package/dist/types/core/schema.d.ts +670 -56
- package/dist/types/core/sources/cache.d.ts +3 -0
- package/dist/types/core/sources/contentful-rich-text.d.ts +11 -2
- package/dist/types/core/sources/contentful.d.ts +17 -1
- package/dist/types/core/sources/lexical.d.ts +5 -0
- package/dist/types/core/sources/normalize.d.ts +20 -1
- package/dist/types/core/sources/read.d.ts +5 -0
- package/dist/types/core/sources/remote.d.ts +37 -10
- package/dist/types/core/sources/sanity.d.ts +1 -1
- package/dist/types/core/types.d.ts +18 -1
- package/dist/types/core/variables.d.ts +42 -0
- package/dist/types/deploy/adapter-output.d.ts +2 -1
- package/dist/types/deploy/adapters/cloudflare.d.ts +7 -5
- package/dist/types/deploy/adapters/node.d.ts +58 -23
- package/dist/types/deploy/adapters/registry.d.ts +10 -0
- package/dist/types/deploy/adapters/types.d.ts +3 -2
- package/dist/types/deploy/node-headers.d.ts +13 -2
- package/dist/types/deploy/platforms/cloudflare.d.ts +15 -7
- package/dist/types/deploy/platforms/netlify.d.ts +7 -0
- package/dist/types/deploy/platforms/node.d.ts +3 -1
- package/dist/types/deploy/platforms/types.d.ts +18 -7
- package/dist/types/deploy/platforms/vercel.d.ts +26 -1
- package/dist/types/deploy/redirects.d.ts +55 -11
- package/dist/types/deploy/sitemap.d.ts +2 -1
- package/dist/types/deploy/vercel-negotiation.d.ts +51 -21
- package/dist/types/markdown/code-title.d.ts +17 -0
- package/dist/types/markdown/features.d.ts +3 -2
- package/dist/types/narration/build.d.ts +70 -0
- package/dist/types/narration/provider.d.ts +26 -0
- package/dist/types/narration/script.d.ts +154 -0
- package/dist/types/openapi/checks.d.ts +27 -0
- package/dist/types/openapi/graphql.d.ts +6 -0
- package/dist/types/openapi/model.d.ts +27 -10
- package/dist/types/openapi/overlay.d.ts +54 -0
- package/dist/types/openapi/parse.d.ts +16 -0
- package/dist/types/openapi/references.d.ts +30 -4
- package/dist/types/ratelimit/cloudflare.d.ts +39 -0
- package/dist/types/ratelimit/index.d.ts +27 -0
- package/dist/types/ratelimit/memory.d.ts +36 -0
- package/dist/types/ratelimit/schema.d.ts +119 -0
- package/dist/types/ratelimit/upstash.d.ts +46 -0
- package/dist/types/ratelimit/wrangler.d.ts +23 -0
- package/dist/types/reference/asyncapi.d.ts +10 -10
- package/dist/types/reference/graphql.d.ts +89 -11
- package/dist/types/reference/index.d.ts +1 -1
- package/dist/types/reference/openapi.d.ts +33 -12
- package/dist/types/reference/options.d.ts +82 -6
- package/dist/types/reference/scalar.d.ts +13 -0
- package/dist/types/reference/schema.d.ts +144 -36
- package/dist/types/search/adapters/registry.d.ts +3 -0
- package/dist/types/search/adapters/typesense.d.ts +14 -4
- package/dist/types/search/build.d.ts +3 -1
- package/dist/types/search/documents.d.ts +12 -1
- package/dist/types/search/orama-index.d.ts +13 -9
- package/dist/types/search/sync/algolia.d.ts +5 -2
- package/dist/types/search/sync/index.d.ts +3 -1
- package/dist/types/search/sync/typesense.d.ts +11 -7
- package/dist/types/seo/metatags.d.ts +20 -0
- package/dist/types/sources/contentful.d.ts +16 -0
- package/dist/types/sources/github-releases.d.ts +8 -1
- package/dist/types/sources/payload.d.ts +2 -0
- package/dist/types/sources/registry.d.ts +54 -0
- package/dist/types/sources/shared.d.ts +3 -0
- package/dist/types/sources/strapi.d.ts +2 -0
- package/docs/01-quickstart.mdx +4 -2
- package/docs/02-deployment.mdx +71 -17
- package/docs/03-upgrading.mdx +4 -4
- package/docs/04-migrating.mdx +1 -1
- package/docs/advanced/changelog.mdx +13 -2
- package/docs/advanced/skills.mdx +15 -1
- package/docs/cli/audit.mdx +51 -8
- package/docs/cli/doctor.mdx +5 -1
- package/docs/cli/evals.mdx +4 -4
- package/docs/cli/index.mdx +1 -0
- package/docs/cli/translate.mdx +1 -0
- package/docs/cli/validate.mdx +4 -3
- package/docs/configuration/analytics.mdx +3 -1
- package/docs/configuration/assistant.mdx +194 -38
- package/docs/configuration/consent.mdx +100 -0
- package/docs/configuration/customization.mdx +8 -6
- package/docs/configuration/export.mdx +5 -3
- package/docs/configuration/index.mdx +64 -5
- package/docs/configuration/meta.ts +3 -0
- package/docs/configuration/narration.mdx +119 -0
- package/docs/configuration/rate-limiting.mdx +90 -0
- package/docs/configuration/search.mdx +63 -12
- package/docs/configuration/theming.mdx +3 -1
- package/docs/content/components.mdx +108 -2
- package/docs/content/frontmatter.mdx +80 -2
- package/docs/content/i18n.mdx +39 -4
- package/docs/content/includes.mdx +16 -0
- package/docs/content/meta.mdx +1 -0
- package/docs/content/meta.ts +1 -0
- package/docs/content/navigation.mdx +32 -10
- package/docs/content/sources/contentful.mdx +35 -0
- package/docs/content/sources/custom.mdx +43 -0
- package/docs/content/sources/github-releases.mdx +39 -0
- package/docs/content/sources/index.mdx +91 -0
- package/docs/content/sources/meta.ts +16 -0
- package/docs/content/sources/notion.mdx +32 -0
- package/docs/content/sources/obsidian.mdx +37 -0
- package/docs/content/sources/payload.mdx +31 -0
- package/docs/content/sources/remote-mdx.mdx +44 -0
- package/docs/content/sources/sanity.mdx +29 -0
- package/docs/content/sources/strapi.mdx +32 -0
- package/docs/content/syntax.mdx +69 -4
- package/docs/content/variables.mdx +41 -0
- package/docs/discoverability/agent-discovery.mdx +29 -2
- package/docs/discoverability/index.mdx +2 -2
- package/docs/discoverability/json-api.mdx +2 -0
- package/docs/discoverability/llms-txt.mdx +2 -2
- package/docs/discoverability/markdown.mdx +3 -1
- package/docs/discoverability/mcp.mdx +4 -0
- package/docs/discoverability/metadata.mdx +17 -0
- package/docs/discoverability/sitemap-and-robots.mdx +1 -1
- package/docs/references/api-pages.mdx +74 -0
- package/docs/references/asyncapi.mdx +4 -2
- package/docs/references/graphql.mdx +14 -2
- package/docs/references/meta.ts +1 -1
- package/docs/references/openapi.mdx +148 -7
- package/docs/references/scalar.mdx +3 -1
- package/package.json +43 -8
- package/skills/blume/SKILL.md +3 -0
- package/skills/blume-migrate/SKILL.md +6 -6
- package/skills/blume-migrate/references/docusaurus.md +7 -7
- package/skills/blume-migrate/references/fumadocs.md +17 -13
- package/skills/blume-migrate/references/mintlify.md +37 -19
- package/skills/blume-migrate/references/nextra.md +10 -7
- package/skills/blume-migrate/references/starlight.md +11 -8
- package/skills/blume-migrate/scripts/mintlify-codemod.mjs +60 -14
- package/skills/blume-write-skill/SKILL.md +82 -0
- package/src/ai/agent-readability.ts +2 -1
- package/src/ai/agent-surface.ts +9 -7
- package/src/ai/ai-catalog.ts +6 -3
- package/src/ai/ask-context.ts +103 -20
- package/src/ai/ask-data.ts +6 -0
- package/src/ai/ask-limits.ts +13 -0
- package/src/ai/ask-tools.ts +142 -0
- package/src/ai/ask.ts +354 -76
- package/src/ai/changelog-markdown.ts +11 -6
- package/src/ai/component-markdown.ts +76 -1
- package/src/ai/cors.ts +14 -3
- package/src/ai/index.ts +12 -0
- package/src/ai/llms.ts +6 -2
- package/src/ai/markdown.ts +2 -1
- package/src/ai/mcp/data.ts +6 -0
- package/src/ai/mcp/query.ts +14 -6
- package/src/ai/openapi-components.ts +36 -6
- package/src/ai/relative-links.ts +4 -38
- package/src/ai/site-skill.ts +274 -0
- package/src/ai/skills.ts +35 -2
- package/src/ai/write-skill.ts +97 -0
- package/src/astro/generate.ts +210 -66
- package/src/astro/index.ts +1 -0
- package/src/astro/integration.ts +42 -4
- package/src/astro/markdown-negotiation.ts +3 -0
- package/src/astro/module-types.ts +9 -1
- package/src/astro/pages.ts +23 -0
- package/src/astro/templates.ts +406 -108
- package/src/astro/variables.ts +31 -0
- package/src/audit/catalog.ts +38 -3
- package/src/audit/checks/contrast.ts +183 -0
- package/src/audit/checks/i18n.ts +2 -3
- package/src/audit/checks/indexability.ts +2 -3
- package/src/audit/checks/links.ts +19 -13
- package/src/audit/checks/network.ts +110 -6
- package/src/audit/checks/redirects.ts +6 -4
- package/src/audit/checks/robots.ts +58 -2
- package/src/audit/checks/sitemap.ts +2 -3
- package/src/audit/redirects.ts +46 -15
- package/src/audit/run.ts +5 -0
- package/src/audit/types.ts +4 -1
- package/src/audit/url.ts +14 -5
- package/src/blume-modules.d.ts +12 -1
- package/src/captcha/client.ts +152 -0
- package/src/captcha/hcaptcha.ts +36 -0
- package/src/captcha/index.ts +28 -0
- package/src/captcha/schema.ts +32 -0
- package/src/captcha/turnstile.ts +38 -0
- package/src/captcha/verify.ts +71 -0
- package/src/cli/args.ts +51 -0
- package/src/cli/build-failure.ts +23 -0
- package/src/cli/command-meta.ts +5 -0
- package/src/cli/commands/audit.ts +10 -1
- package/src/cli/commands/dev.ts +18 -2
- package/src/cli/commands/doctor.ts +67 -28
- package/src/cli/commands/eval.ts +36 -4
- package/src/cli/commands/init.ts +6 -4
- package/src/cli/commands/skill.ts +96 -0
- package/src/cli/commands/validate.ts +10 -1
- package/src/cli/index.ts +5 -0
- package/src/cli/init/scaffold.ts +3 -3
- package/src/cli/prepare.ts +6 -3
- package/src/cli/required-secrets.ts +72 -30
- package/src/components/BlumePage.astro +2 -0
- package/src/components/content/ApiEndpoint.astro +18 -0
- package/src/components/content/ApiField.astro +79 -0
- package/src/components/content/ApiPlayground.astro +66 -0
- package/src/components/content/ApiRail.astro +19 -0
- package/src/components/content/Color.astro +1 -0
- package/src/components/content/FileTree.astro +1 -0
- package/src/components/content/GithubInfo.astro +1 -0
- package/src/components/content/Panel.astro +1 -0
- package/src/components/content/ParamField.astro +25 -0
- package/src/components/content/RequestExample.astro +17 -0
- package/src/components/content/ResponseExample.astro +17 -0
- package/src/components/content/ResponseField.astro +32 -0
- package/src/components/content/Step.astro +1 -0
- package/src/components/content/Tile.astro +1 -0
- package/src/components/content/Tooltip.astro +1 -0
- package/src/components/content/Tree.astro +1 -0
- package/src/components/content/TypeTable.astro +4 -1
- package/src/components/content/View.astro +21 -0
- package/src/components/content/ViewSwitcher.astro +168 -0
- package/src/components/content/api-field.ts +103 -0
- package/src/components/content/api-page.ts +248 -0
- package/src/components/content/mermaid-element.ts +15 -1
- package/src/components/content/view-switcher.ts +71 -0
- package/src/components/index.ts +2 -0
- package/src/components/islands/Assistant.astro +10 -1
- package/src/components/islands/assistant.tsx +104 -14
- package/src/components/islands/code-question.ts +62 -0
- package/src/components/islands/hooks.ts +136 -21
- package/src/components/islands/support-link.ts +68 -0
- package/src/components/layout/Analytics.astro +11 -2
- package/src/components/layout/Banner.astro +14 -10
- package/src/components/layout/Breadcrumbs.astro +6 -2
- package/src/components/layout/ConsentBanner.astro +62 -0
- package/src/components/layout/ConsentHead.astro +38 -0
- package/src/components/layout/Directory.astro +94 -0
- package/src/components/layout/DrawerSwitchers.astro +51 -0
- package/src/components/layout/Empty.astro +2 -2
- package/src/components/layout/Header.astro +122 -80
- package/src/components/layout/LanguageSwitcher.astro +48 -15
- package/src/components/layout/NarrationPlayer.astro +1085 -0
- package/src/components/layout/NavSelector.astro +33 -7
- package/src/components/layout/PageActions.astro +139 -24
- package/src/components/layout/PageFeedback.astro +54 -49
- package/src/components/layout/PageLayout.astro +71 -3
- package/src/components/layout/ReferenceLayout.astro +17 -6
- package/src/components/layout/RelatedPages.astro +42 -0
- package/src/components/layout/RootLayout.astro +318 -47
- package/src/components/layout/Search.astro +47 -19
- package/src/components/layout/SiteFooter.astro +124 -0
- package/src/components/layout/SiteMetatags.astro +16 -0
- package/src/components/layout/TableOfContents.astro +24 -17
- package/src/components/layout/consent/native.ts +79 -0
- package/src/components/layout/consent/types.ts +37 -0
- package/src/components/layout/footer-links.ts +53 -0
- package/src/components/layout/footer-socials.ts +87 -0
- package/src/components/layout/head-scripts.ts +6 -1
- package/src/components/layout/locale-redirect.ts +107 -0
- package/src/components/layout/nav-utils.ts +83 -0
- package/src/components/layout/page-feedback.ts +96 -0
- package/src/components/layout/search/algolia.ts +10 -1
- package/src/components/layout/search/analytics.ts +126 -0
- package/src/components/layout/search/endpoint.ts +48 -5
- package/src/components/layout/search/flexsearch.ts +17 -5
- package/src/components/layout/search/orama-cloud.ts +26 -14
- package/src/components/layout/search/pagefind.ts +114 -5
- package/src/components/layout/search/types.ts +32 -0
- package/src/components/layout/search/typesense.ts +19 -3
- package/src/components/openapi/AsyncApiOperation.astro +14 -7
- package/src/components/openapi/Authorization.astro +10 -0
- package/src/components/openapi/GraphqlOperation.astro +5 -0
- package/src/components/openapi/Operation.astro +184 -13
- package/src/components/openapi/ParametersTable.astro +8 -4
- package/src/components/openapi/Playground.astro +7 -1
- package/src/components/openapi/RequestBody.astro +24 -5
- package/src/components/openapi/RequestPanel.astro +59 -7
- package/src/components/openapi/Responses.astro +7 -4
- package/src/components/openapi/SchemaTable.astro +15 -3
- package/src/components/openapi/async-snippets.ts +65 -9
- package/src/components/openapi/async.ts +123 -29
- package/src/components/openapi/code-samples.ts +97 -0
- package/src/components/openapi/graphql-helpers.ts +35 -12
- package/src/components/openapi/helpers.ts +36 -2
- package/src/components/openapi/message-model.ts +54 -11
- package/src/components/openapi/message.ts +14 -4
- package/src/components/openapi/operation-model.ts +16 -7
- package/src/components/openapi/playground-client.ts +24 -5
- package/src/components/openapi/playground-schema.ts +1 -1
- package/src/components/openapi/schema-tree.ts +44 -14
- package/src/components/openapi/security.ts +16 -3
- package/src/components/openapi/snippets.ts +873 -10
- package/src/components/openapi/validate-json.ts +4 -3
- package/src/components/props.ts +6 -0
- package/src/consent/client.ts +95 -0
- package/src/consent/clients.ts +19 -0
- package/src/consent/ethyca.ts +71 -0
- package/src/consent/head.ts +24 -0
- package/src/consent/index.ts +37 -0
- package/src/consent/init.ts +29 -0
- package/src/consent/native.ts +36 -0
- package/src/consent/osano.ts +59 -0
- package/src/consent/schema.ts +30 -0
- package/src/core/builtin-tags.ts +5 -0
- package/src/core/changelog-index.ts +31 -1
- package/src/core/client-address.ts +19 -0
- package/src/core/component-diagnostics.ts +53 -0
- package/src/core/component-overrides.ts +32 -0
- package/src/core/config-input.ts +225 -23
- package/src/core/data.ts +46 -4
- package/src/core/diagnostics.ts +8 -2
- package/src/core/footer.ts +26 -0
- package/src/core/graph.ts +39 -36
- package/src/core/i18n-ui.ts +84 -2
- package/src/core/includes.ts +21 -4
- package/src/core/links.ts +63 -19
- package/src/core/localizable.ts +26 -0
- package/src/core/navigation.ts +43 -12
- package/src/core/page-modes.ts +56 -0
- package/src/core/probe.ts +26 -6
- package/src/core/project-graph.ts +163 -16
- package/src/core/redirect-patterns.ts +520 -0
- package/src/core/related.ts +131 -0
- package/src/core/schema.ts +339 -66
- package/src/core/sources/cache.ts +6 -0
- package/src/core/sources/contentful-rich-text.ts +29 -6
- package/src/core/sources/contentful.ts +135 -25
- package/src/core/sources/filesystem.ts +26 -4
- package/src/core/sources/github-releases.ts +12 -1
- package/src/core/sources/lexical.ts +15 -10
- package/src/core/sources/mdx-remote.ts +62 -10
- package/src/core/sources/normalize.ts +228 -41
- package/src/core/sources/notion.ts +7 -1
- package/src/core/sources/obsidian.ts +16 -3
- package/src/core/sources/payload.ts +38 -15
- package/src/core/sources/read.ts +8 -3
- package/src/core/sources/remote.ts +72 -15
- package/src/core/sources/resolve.ts +11 -1
- package/src/core/sources/sanity.ts +43 -25
- package/src/core/sources/strapi.ts +2 -2
- package/src/core/types.ts +19 -1
- package/src/core/ui-packs/ar.ts +44 -0
- package/src/core/ui-packs/bg.ts +46 -0
- package/src/core/ui-packs/bn.ts +44 -0
- package/src/core/ui-packs/ca.ts +47 -0
- package/src/core/ui-packs/cs.ts +45 -0
- package/src/core/ui-packs/da.ts +46 -0
- package/src/core/ui-packs/de.ts +47 -0
- package/src/core/ui-packs/el.ts +46 -0
- package/src/core/ui-packs/es.ts +47 -0
- package/src/core/ui-packs/fa.ts +46 -0
- package/src/core/ui-packs/fi.ts +46 -0
- package/src/core/ui-packs/fr.ts +47 -0
- package/src/core/ui-packs/he.ts +44 -0
- package/src/core/ui-packs/hi.ts +45 -0
- package/src/core/ui-packs/hr.ts +46 -0
- package/src/core/ui-packs/hu.ts +45 -0
- package/src/core/ui-packs/id.ts +46 -0
- package/src/core/ui-packs/it.ts +46 -0
- package/src/core/ui-packs/ja.ts +46 -0
- package/src/core/ui-packs/ko.ts +45 -0
- package/src/core/ui-packs/nl.ts +47 -0
- package/src/core/ui-packs/no.ts +45 -0
- package/src/core/ui-packs/pl.ts +46 -0
- package/src/core/ui-packs/pt-br.ts +47 -0
- package/src/core/ui-packs/pt.ts +46 -0
- package/src/core/ui-packs/ro.ts +46 -0
- package/src/core/ui-packs/ru.ts +46 -0
- package/src/core/ui-packs/sk.ts +45 -0
- package/src/core/ui-packs/sr.ts +46 -0
- package/src/core/ui-packs/sv.ts +45 -0
- package/src/core/ui-packs/th.ts +44 -0
- package/src/core/ui-packs/tr.ts +46 -0
- package/src/core/ui-packs/uk.ts +46 -0
- package/src/core/ui-packs/vi.ts +46 -0
- package/src/core/ui-packs/zh-tw.ts +44 -0
- package/src/core/ui-packs/zh.ts +44 -0
- package/src/core/variables.ts +103 -0
- package/src/deploy/adapter-output.ts +7 -2
- package/src/deploy/adapters/cloudflare.ts +7 -5
- package/src/deploy/adapters/node.ts +47 -9
- package/src/deploy/adapters/types.ts +7 -3
- package/src/deploy/artifacts.ts +79 -9
- package/src/deploy/cloudflare-negotiation.ts +35 -5
- package/src/deploy/headers.ts +2 -1
- package/src/deploy/node-headers.ts +63 -9
- package/src/deploy/platforms/cloudflare.ts +45 -9
- package/src/deploy/platforms/netlify.ts +35 -2
- package/src/deploy/platforms/node.ts +12 -2
- package/src/deploy/platforms/types.ts +21 -7
- package/src/deploy/platforms/vercel.ts +149 -17
- package/src/deploy/redirects.ts +151 -24
- package/src/deploy/rss.ts +3 -1
- package/src/deploy/sitemap.ts +39 -5
- package/src/deploy/vercel-negotiation.ts +326 -102
- package/src/eval/agents.ts +18 -1
- package/src/eval/prompts.ts +6 -3
- package/src/eval/report.ts +34 -13
- package/src/eval/run.ts +5 -0
- package/src/markdown/api-rail.ts +259 -0
- package/src/markdown/code-title.ts +35 -9
- package/src/markdown/features.ts +3 -2
- package/src/markdown/fence-meta.ts +2 -0
- package/src/markdown/include.ts +11 -1
- package/src/markdown/index.ts +28 -5
- package/src/markdown/math.ts +4 -4
- package/src/markdown/relative-links.ts +3 -2
- package/src/markdown/variables.ts +56 -0
- package/src/markdown/views.ts +82 -0
- package/src/narration/build.ts +412 -0
- package/src/narration/player.ts +249 -0
- package/src/narration/provider.ts +29 -0
- package/src/narration/script.ts +592 -0
- package/src/og/card.ts +7 -6
- package/src/openapi/checks.ts +273 -0
- package/src/openapi/graphql-build.ts +21 -0
- package/src/openapi/graphql.ts +11 -0
- package/src/openapi/model.ts +72 -27
- package/src/openapi/overlay.ts +256 -0
- package/src/openapi/parse.ts +182 -4
- package/src/openapi/references.ts +64 -8
- package/src/openapi/render-mdx.ts +5 -1
- package/src/openapi/scalar.ts +40 -6
- package/src/openapi/source.ts +40 -15
- package/src/ratelimit/cloudflare.ts +54 -0
- package/src/ratelimit/index.ts +30 -0
- package/src/ratelimit/memory.ts +45 -0
- package/src/ratelimit/runtime.ts +247 -0
- package/src/ratelimit/schema.ts +28 -0
- package/src/ratelimit/upstash.ts +60 -0
- package/src/ratelimit/wrangler.ts +70 -0
- package/src/reference/asyncapi.ts +2 -2
- package/src/reference/graphql.ts +20 -3
- package/src/reference/index.ts +1 -0
- package/src/reference/openapi.ts +21 -7
- package/src/reference/options.ts +80 -8
- package/src/reference/scalar.ts +33 -8
- package/src/registry/eject.ts +23 -5
- package/src/registry/registry.ts +7 -0
- package/src/search/adapters/locale-scope.ts +30 -0
- package/src/search/adapters/typesense.ts +14 -4
- package/src/search/build.ts +21 -3
- package/src/search/documents.ts +26 -2
- package/src/search/orama-index.ts +191 -34
- package/src/search/pagefind-ranking.ts +39 -0
- package/src/search/source-pages.ts +29 -0
- package/src/search/sync/algolia.ts +111 -10
- package/src/search/sync/index.ts +52 -13
- package/src/search/sync/orama-cloud.ts +3 -0
- package/src/search/sync/typesense.ts +76 -26
- package/src/seo/metatags.ts +67 -0
- package/src/sources/contentful.ts +12 -0
- package/src/sources/github-releases.ts +7 -1
- package/src/sources/shared.ts +3 -0
- package/src/theme/chrome-icons.ts +1 -0
- package/src/theme/color.ts +500 -0
- package/src/theme/entry.ts +85 -6
- package/src/theme/palette.ts +121 -45
- package/src/translate/prompts.ts +1 -0
- package/src/translate/validate.ts +31 -3
- package/src/upgrade/upgrade.ts +4 -171
- package/dist/cli/chunk-1d7ve1dm.js.map +0 -12
- package/dist/cli/chunk-2hsdwb9n.js.map +0 -10
- package/dist/cli/chunk-35d4wj9f.js.map +0 -15
- package/dist/cli/chunk-364znk6q.js +0 -75
- package/dist/cli/chunk-364znk6q.js.map +0 -11
- package/dist/cli/chunk-5m5nmvyq.js.map +0 -13
- package/dist/cli/chunk-8ktnccpt.js.map +0 -10
- package/dist/cli/chunk-9t7a85s3.js.map +0 -10
- package/dist/cli/chunk-b07cmahc.js +0 -145
- package/dist/cli/chunk-b07cmahc.js.map +0 -11
- package/dist/cli/chunk-c8chx29p.js.map +0 -36
- package/dist/cli/chunk-e04dxsz1.js +0 -39
- package/dist/cli/chunk-e04dxsz1.js.map +0 -10
- package/dist/cli/chunk-j85vccga.js.map +0 -36
- package/dist/cli/chunk-p3v96n38.js.map +0 -10
- package/dist/cli/chunk-pehfxfta.js.map +0 -10
- package/dist/cli/chunk-pv29h0wf.js.map +0 -190
- package/dist/cli/chunk-q58y5e6a.js.map +0 -10
- package/dist/cli/chunk-vg9r4eb9.js.map +0 -14
- package/dist/cli/chunk-wrr3j9w9.js.map +0 -35
- package/dist/cli/chunk-yfyb25rh.js.map +0 -14
- package/docs/content/sources.mdx +0 -334
- /package/dist/cli/{chunk-tkacnehg.js.map → chunk-3v3ffbrj.js.map} +0 -0
- /package/dist/cli/{chunk-r9rcc4w7.js.map → chunk-8y2kmjv8.js.map} +0 -0
- /package/dist/cli/{chunk-2eytanqx.js.map → chunk-c887fj0s.js.map} +0 -0
- /package/dist/cli/{chunk-akbpwfxc.js.map → chunk-dzwehpy7.js.map} +0 -0
- /package/dist/cli/{chunk-2z928egk.js.map → chunk-ft9vfys6.js.map} +0 -0
- /package/dist/cli/{chunk-a58773jm.js.map → chunk-kma9f6sf.js.map} +0 -0
- /package/dist/cli/{chunk-crgn1q09.js.map → chunk-sds923fa.js.map} +0 -0
- /package/dist/cli/{chunk-acanzt5p.js.map → chunk-tdqhyxfz.js.map} +0 -0
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { sampleLanguageInfo } from "./snippets.ts";
|
|
2
|
+
import type { SampleLanguageInfo } from "./snippets.ts";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Hand-written code samples from a spec: the `x-codeSamples` extension on an
|
|
6
|
+
* operation (Redocly's, which Mintlify, Speakeasy, and Stainless write too),
|
|
7
|
+
* or its older spelling `x-code-samples`. Each entry names a `lang`, holds
|
|
8
|
+
* the `source`, and may carry a `label`. They render as their own tabs ahead
|
|
9
|
+
* of the generated samples and, being fixed text, the playground leaves them
|
|
10
|
+
* as written.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
/** One hand-written sample, ready to render as a tab. */
|
|
14
|
+
export interface CustomCodeSample {
|
|
15
|
+
/** A stable, unique tab key. */
|
|
16
|
+
key: string;
|
|
17
|
+
/** The tab label: the entry's own, else the language's name. */
|
|
18
|
+
label: string;
|
|
19
|
+
/** The Shiki language to highlight `source` with. */
|
|
20
|
+
lang: string;
|
|
21
|
+
source: string;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/** The two places an operation keeps them. */
|
|
25
|
+
export interface CodeSamplesCarrier {
|
|
26
|
+
"x-code-samples"?: unknown;
|
|
27
|
+
"x-codeSamples"?: unknown;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
interface RawSample {
|
|
31
|
+
label?: string;
|
|
32
|
+
lang: string;
|
|
33
|
+
source: string;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const isRawSample = (value: unknown): value is RawSample =>
|
|
37
|
+
typeof value === "object" &&
|
|
38
|
+
value !== null &&
|
|
39
|
+
"lang" in value &&
|
|
40
|
+
typeof value.lang === "string" &&
|
|
41
|
+
"source" in value &&
|
|
42
|
+
typeof value.source === "string" &&
|
|
43
|
+
(!("label" in value) || typeof value.label === "string");
|
|
44
|
+
|
|
45
|
+
// Shell tools in an `x-codeSamples` entry are usually an SDK's CLI, not curl,
|
|
46
|
+
// so they're named for the shell rather than "cURL".
|
|
47
|
+
const SHELL_LANGS = new Set(["bash", "sh", "shell", "zsh"]);
|
|
48
|
+
|
|
49
|
+
/** The display name and highlighter for a sample's `lang`. */
|
|
50
|
+
const describe = (lang: string): SampleLanguageInfo => {
|
|
51
|
+
const lower = lang.toLowerCase();
|
|
52
|
+
if (SHELL_LANGS.has(lower)) {
|
|
53
|
+
return { label: "Shell", lang: "bash" };
|
|
54
|
+
}
|
|
55
|
+
// A language Blume doesn't generate keeps its own name, and Shiki tries
|
|
56
|
+
// it as written (it knows most languages by their common names).
|
|
57
|
+
return sampleLanguageInfo(lower) ?? { label: lang, lang: lower };
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* The operation's hand-written samples, with a unique tab label each. A label
|
|
62
|
+
* two samples share gains its language (`List plants · JavaScript`), and one
|
|
63
|
+
* that still repeats gains a number. Malformed entries are skipped.
|
|
64
|
+
*/
|
|
65
|
+
export const customCodeSamples = (
|
|
66
|
+
operation: CodeSamplesCarrier
|
|
67
|
+
): CustomCodeSample[] => {
|
|
68
|
+
const raw = operation["x-codeSamples"] ?? operation["x-code-samples"];
|
|
69
|
+
if (!Array.isArray(raw)) {
|
|
70
|
+
return [];
|
|
71
|
+
}
|
|
72
|
+
const entries = raw.filter(isRawSample).map((entry) => {
|
|
73
|
+
const language = describe(entry.lang);
|
|
74
|
+
return {
|
|
75
|
+
base: entry.label?.trim() || language.label,
|
|
76
|
+
language,
|
|
77
|
+
source: entry.source.replace(/\n$/u, ""),
|
|
78
|
+
};
|
|
79
|
+
});
|
|
80
|
+
const counts = new Map<string, number>();
|
|
81
|
+
for (const { base } of entries) {
|
|
82
|
+
counts.set(base, (counts.get(base) ?? 0) + 1);
|
|
83
|
+
}
|
|
84
|
+
const used = new Set<string>();
|
|
85
|
+
return entries.map(({ base, language, source }, index) => {
|
|
86
|
+
const first =
|
|
87
|
+
(counts.get(base) ?? 0) > 1 && base !== language.label
|
|
88
|
+
? `${base} · ${language.label}`
|
|
89
|
+
: base;
|
|
90
|
+
let label = first;
|
|
91
|
+
for (let n = 2; used.has(label); n += 1) {
|
|
92
|
+
label = `${first} (${n})`;
|
|
93
|
+
}
|
|
94
|
+
used.add(label);
|
|
95
|
+
return { key: `x-${index}`, label, lang: language.lang, source };
|
|
96
|
+
});
|
|
97
|
+
};
|
|
@@ -10,8 +10,11 @@ import {
|
|
|
10
10
|
isGraphqlOperationKind,
|
|
11
11
|
} from "../../openapi/graphql.ts";
|
|
12
12
|
import type { ApiSpecData } from "../../openapi/model.ts";
|
|
13
|
+
import { endpointSecurity } from "../content/api-page.ts";
|
|
13
14
|
import type { SpecValue } from "./helpers.ts";
|
|
15
|
+
import { playgroundAuth } from "./operation-model.ts";
|
|
14
16
|
import type { PlaygroundModel } from "./request.ts";
|
|
17
|
+
import type { OperationSecurity } from "./security.ts";
|
|
15
18
|
|
|
16
19
|
/**
|
|
17
20
|
* Build-time logic behind the GraphQL reference pages: the generated example
|
|
@@ -67,9 +70,10 @@ const isComposite = (document: GraphqlDocument, name: string): boolean => {
|
|
|
67
70
|
|
|
68
71
|
/**
|
|
69
72
|
* A valid selection set for a composite type, or undefined for leaves: every
|
|
70
|
-
* scalar/enum field, plus nested composites while `depth` allows
|
|
71
|
-
*
|
|
72
|
-
*
|
|
73
|
+
* scalar/enum field, plus nested composites while `depth` allows, deprecated
|
|
74
|
+
* fields left out so the example doesn't teach them. A composite with nothing
|
|
75
|
+
* selectable at this depth falls back to `__typename`, which is legal on any
|
|
76
|
+
* composite — the set must never come out empty.
|
|
73
77
|
*/
|
|
74
78
|
export const selectionSet = (
|
|
75
79
|
document: GraphqlDocument,
|
|
@@ -85,10 +89,12 @@ export const selectionSet = (
|
|
|
85
89
|
}
|
|
86
90
|
const selections: GraphqlSelection[] = [];
|
|
87
91
|
for (const field of type.fields ?? []) {
|
|
88
|
-
// A field
|
|
89
|
-
//
|
|
90
|
-
// fill it with inline. A defaulted non-null argument is
|
|
92
|
+
// A deprecated field stays out of the example. So does a field with an
|
|
93
|
+
// argument that must be supplied — non-null and no default: there is
|
|
94
|
+
// nothing valid to fill it with inline. A defaulted non-null argument is
|
|
95
|
+
// omittable.
|
|
91
96
|
if (
|
|
97
|
+
field.deprecationReason !== undefined ||
|
|
92
98
|
field.args.some(
|
|
93
99
|
(arg) => arg.type.display.endsWith("!") && arg.default === undefined
|
|
94
100
|
)
|
|
@@ -189,10 +195,14 @@ const sampleForRef = (
|
|
|
189
195
|
if (type?.kind === "enum") {
|
|
190
196
|
named = type.enumValues?.[0]?.name ?? null;
|
|
191
197
|
} else if (type?.kind === "input" && depth > 0) {
|
|
198
|
+
// A field with a default starts at it, the value a client leaving it
|
|
199
|
+
// out gets.
|
|
192
200
|
named = Object.fromEntries(
|
|
193
201
|
(type.inputFields ?? []).map((field) => [
|
|
194
202
|
field.name,
|
|
195
|
-
|
|
203
|
+
field.defaultValue === undefined
|
|
204
|
+
? sampleForRef(document, field.type, depth - 1)
|
|
205
|
+
: field.defaultValue,
|
|
196
206
|
])
|
|
197
207
|
);
|
|
198
208
|
} else if (type?.kind === "input") {
|
|
@@ -203,7 +213,10 @@ const sampleForRef = (
|
|
|
203
213
|
return wrapLists(ref.display, named);
|
|
204
214
|
};
|
|
205
215
|
|
|
206
|
-
/**
|
|
216
|
+
/**
|
|
217
|
+
* Example `variables` for a root field's arguments, each starting at its
|
|
218
|
+
* declared default when it has one; undefined when it has none.
|
|
219
|
+
*/
|
|
207
220
|
export const exampleVariables = (
|
|
208
221
|
document: GraphqlDocument,
|
|
209
222
|
field: GraphqlField
|
|
@@ -212,7 +225,9 @@ export const exampleVariables = (
|
|
|
212
225
|
? Object.fromEntries(
|
|
213
226
|
field.args.map((arg) => [
|
|
214
227
|
arg.name,
|
|
215
|
-
|
|
228
|
+
arg.defaultValue === undefined
|
|
229
|
+
? sampleForRef(document, arg.type, VARIABLE_DEPTH)
|
|
230
|
+
: arg.defaultValue,
|
|
216
231
|
])
|
|
217
232
|
)
|
|
218
233
|
: undefined;
|
|
@@ -271,19 +286,27 @@ export const exampleResponse = (
|
|
|
271
286
|
return { data };
|
|
272
287
|
};
|
|
273
288
|
|
|
289
|
+
/**
|
|
290
|
+
* The security every operation of a GraphQL reference enforces: its `auth`
|
|
291
|
+
* option, read the way a hand-written endpoint reads the site's `api.auth`.
|
|
292
|
+
*/
|
|
293
|
+
export const graphqlSecurity = (spec: ApiSpecData): OperationSecurity =>
|
|
294
|
+
endpointSecurity(undefined, spec.auth);
|
|
295
|
+
|
|
274
296
|
/**
|
|
275
297
|
* The playground/request model for one GraphQL operation: a plain POST whose
|
|
276
298
|
* JSON body carries the query and variables. Reusing `PlaygroundModel` means
|
|
277
299
|
* the OpenAPI playground UI, its client module, and `buildRequest` all work
|
|
278
|
-
* unchanged — the samples show byte-for-byte what the Send button transmits
|
|
300
|
+
* unchanged — the samples show byte-for-byte what the Send button transmits,
|
|
301
|
+
* the configured `auth` credential included.
|
|
279
302
|
*/
|
|
280
303
|
export const graphqlPlaygroundModel = (
|
|
281
304
|
spec: ApiSpecData,
|
|
282
305
|
query: string,
|
|
283
306
|
variables?: GraphqlSampleObject
|
|
284
307
|
): PlaygroundModel => ({
|
|
285
|
-
auth:
|
|
286
|
-
authOptional:
|
|
308
|
+
auth: playgroundAuth(graphqlSecurity(spec)),
|
|
309
|
+
authOptional: false,
|
|
287
310
|
body: {
|
|
288
311
|
contentType: "application/json",
|
|
289
312
|
example: JSON.stringify(
|
|
@@ -135,7 +135,23 @@ export const mergeParameters = (
|
|
|
135
135
|
export const refName = (ref: string): string =>
|
|
136
136
|
REF_PATTERN.exec(ref)?.groups?.name ?? ref.split("/").at(-1) ?? ref;
|
|
137
137
|
|
|
138
|
-
/**
|
|
138
|
+
/**
|
|
139
|
+
* The one member of an `allOf` that only wraps it: `allOf: [{ $ref }]` beside
|
|
140
|
+
* a `description`, `readOnly`, or `default`, which is how drf-spectacular and
|
|
141
|
+
* other generators attach keywords a 3.0 `$ref` can't carry. `undefined` for
|
|
142
|
+
* a real composition: several members, or properties or branches of its own.
|
|
143
|
+
*/
|
|
144
|
+
export const soleAllOfMember = (schema: SchemaLike): SchemaLike | undefined =>
|
|
145
|
+
schema.allOf?.length === 1 &&
|
|
146
|
+
!(schema.properties || schema.oneOf || schema.anyOf)
|
|
147
|
+
? schema.allOf[0]
|
|
148
|
+
: undefined;
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Resolve one level of `$ref` against the document's component schemas. A
|
|
152
|
+
* single-member `allOf` wrapper resolves like its member, with the wrapper's
|
|
153
|
+
* own keywords on top: its `description` is about this field.
|
|
154
|
+
*/
|
|
139
155
|
export const resolveSchema = (
|
|
140
156
|
schemas: Record<string, SchemaLike>,
|
|
141
157
|
schema?: SchemaLike
|
|
@@ -143,6 +159,11 @@ export const resolveSchema = (
|
|
|
143
159
|
if (!schema) {
|
|
144
160
|
return {};
|
|
145
161
|
}
|
|
162
|
+
const member = soleAllOfMember(schema);
|
|
163
|
+
if (member) {
|
|
164
|
+
const { allOf: _wrapped, ...own } = schema;
|
|
165
|
+
return { ...resolveSchema(schemas, member), ...own };
|
|
166
|
+
}
|
|
146
167
|
if (isString(schema.$ref)) {
|
|
147
168
|
const name = REF_PATTERN.exec(schema.$ref)?.groups?.name;
|
|
148
169
|
if (name && schemas[name]) {
|
|
@@ -152,6 +173,16 @@ export const resolveSchema = (
|
|
|
152
173
|
return schema;
|
|
153
174
|
};
|
|
154
175
|
|
|
176
|
+
/**
|
|
177
|
+
* A parameter's description: its own, else its schema's (resolved one `$ref`
|
|
178
|
+
* level), which is where generators like Elysia and oRPC write it.
|
|
179
|
+
*/
|
|
180
|
+
export const parameterDescription = (
|
|
181
|
+
param: { description?: string; schema?: SchemaLike },
|
|
182
|
+
schemas: Record<string, SchemaLike>
|
|
183
|
+
): string | undefined =>
|
|
184
|
+
param.description ?? resolveSchema(schemas, param.schema).description;
|
|
185
|
+
|
|
155
186
|
const declaredTypeList = (type: string | string[] | undefined): string[] => {
|
|
156
187
|
if (!type) {
|
|
157
188
|
return [];
|
|
@@ -177,6 +208,8 @@ const isNullType = (schema: SchemaLike): boolean => {
|
|
|
177
208
|
* (`Pet`, `Pet[]`) without resolving — which also means circular refs through
|
|
178
209
|
* array items can't recurse forever. A `null` member stays out of a union's
|
|
179
210
|
* label: rows mark it with {@link isNullable}, as they do `type: [T, "null"]`.
|
|
211
|
+
* A single-member `allOf` wrapper labels as its member; a real composition is
|
|
212
|
+
* an `object`.
|
|
180
213
|
*/
|
|
181
214
|
export const typeLabel = (schema: SchemaLike): string => {
|
|
182
215
|
if (isString(schema.$ref)) {
|
|
@@ -192,7 +225,8 @@ export const typeLabel = (schema: SchemaLike): string => {
|
|
|
192
225
|
return [...new Set(labels)].join(" | ") || "any";
|
|
193
226
|
}
|
|
194
227
|
if (schema.allOf) {
|
|
195
|
-
|
|
228
|
+
const member = soleAllOfMember(schema);
|
|
229
|
+
return member ? typeLabel(member) : "object";
|
|
196
230
|
}
|
|
197
231
|
const types = nonNullTypes(schema.type);
|
|
198
232
|
const arrayLabel = (): string => `${typeLabel(schema.items ?? {})}[]`;
|
|
@@ -1,10 +1,15 @@
|
|
|
1
1
|
import type {
|
|
2
2
|
AsyncApiAction,
|
|
3
|
+
AsyncApiDocument,
|
|
3
4
|
AsyncApiServerObject,
|
|
4
5
|
} from "../../openapi/asyncapi.ts";
|
|
5
6
|
import { withServerDefaults } from "../../openapi/model.ts";
|
|
6
7
|
import type { AsyncApiMessageLike, NamedMessage } from "./async.ts";
|
|
7
|
-
import {
|
|
8
|
+
import {
|
|
9
|
+
kafkaKeySchema,
|
|
10
|
+
payloadSchema,
|
|
11
|
+
resolvedServerSecurity,
|
|
12
|
+
} from "./async.ts";
|
|
8
13
|
import { exampleValue, toJson } from "./helpers.ts";
|
|
9
14
|
import type { ParameterLike, SchemaLike } from "./helpers.ts";
|
|
10
15
|
import type {
|
|
@@ -76,14 +81,34 @@ const messagePayload = (
|
|
|
76
81
|
};
|
|
77
82
|
};
|
|
78
83
|
|
|
84
|
+
/**
|
|
85
|
+
* The first message's Kafka key as the kcat sample writes it: sampled from
|
|
86
|
+
* its binding's `key` schema the way a payload is (a declared example wins),
|
|
87
|
+
* a non-string value as JSON. None when the message declares no key.
|
|
88
|
+
*/
|
|
89
|
+
const messageKey = (
|
|
90
|
+
message: AsyncApiMessageLike | undefined,
|
|
91
|
+
schemas: Record<string, SchemaLike>,
|
|
92
|
+
components: AsyncApiDocument["components"]
|
|
93
|
+
): string | undefined => {
|
|
94
|
+
const schema = kafkaKeySchema(message, components);
|
|
95
|
+
const key = inputValue(schema ? exampleValue(schema, schemas) : null);
|
|
96
|
+
return key === "" ? undefined : key;
|
|
97
|
+
};
|
|
98
|
+
|
|
79
99
|
/**
|
|
80
100
|
* A server's base URL for the picker. Falls back to the bare host when the
|
|
81
101
|
* spec omits `protocol` — a label is a label, and the snippet builders read
|
|
82
102
|
* the server object itself rather than this string. Server variables in the
|
|
83
103
|
* host and pathname (`{env}.events.example.com`) resolve to their declared
|
|
84
104
|
* defaults, in the label and in the object the samples and connect URL read.
|
|
105
|
+
* Security refs resolve here too, so the kcat sample can name the server's
|
|
106
|
+
* SASL mechanism.
|
|
85
107
|
*/
|
|
86
|
-
const serverOption = (
|
|
108
|
+
const serverOption = (
|
|
109
|
+
spec: AsyncApiServerObject,
|
|
110
|
+
components: AsyncApiDocument["components"]
|
|
111
|
+
): MessageServerOption => {
|
|
87
112
|
const server = { ...spec };
|
|
88
113
|
if (spec.host !== undefined) {
|
|
89
114
|
server.host = withServerDefaults(spec.host, spec.variables);
|
|
@@ -91,6 +116,9 @@ const serverOption = (spec: AsyncApiServerObject): MessageServerOption => {
|
|
|
91
116
|
if (spec.pathname !== undefined) {
|
|
92
117
|
server.pathname = withServerDefaults(spec.pathname, spec.variables);
|
|
93
118
|
}
|
|
119
|
+
if (spec.security !== undefined) {
|
|
120
|
+
server.security = resolvedServerSecurity(spec, components);
|
|
121
|
+
}
|
|
94
122
|
const host = `${server.host ?? ""}${server.pathname ?? ""}`;
|
|
95
123
|
return {
|
|
96
124
|
label: server.protocol ? `${server.protocol}://${host}` : host,
|
|
@@ -102,17 +130,32 @@ const serverOption = (spec: AsyncApiServerObject): MessageServerOption => {
|
|
|
102
130
|
export const messageModel = (args: {
|
|
103
131
|
action: AsyncApiAction;
|
|
104
132
|
address: string;
|
|
133
|
+
/** The document's `components`, which bindings and security refs resolve against. */
|
|
134
|
+
components?: AsyncApiDocument["components"];
|
|
105
135
|
messages: NamedMessage[];
|
|
106
136
|
parameters: ParameterLike[];
|
|
107
137
|
protocol?: string;
|
|
108
138
|
schemas: Record<string, SchemaLike>;
|
|
109
139
|
servers: AsyncApiServerObject[];
|
|
110
|
-
}): MessageModel =>
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
140
|
+
}): MessageModel => {
|
|
141
|
+
const model: MessageModel = {
|
|
142
|
+
action: args.action,
|
|
143
|
+
address: args.address,
|
|
144
|
+
connectable: Object.hasOwn(LIVE_PROTOCOLS, args.protocol ?? ""),
|
|
145
|
+
params: messageParams(args.parameters),
|
|
146
|
+
payload: messagePayload(args.messages[0]?.message, args.schemas),
|
|
147
|
+
protocol: args.protocol,
|
|
148
|
+
servers: args.servers.map((server) =>
|
|
149
|
+
serverOption(server, args.components)
|
|
150
|
+
),
|
|
151
|
+
};
|
|
152
|
+
const key = messageKey(
|
|
153
|
+
args.messages[0]?.message,
|
|
154
|
+
args.schemas,
|
|
155
|
+
args.components
|
|
156
|
+
);
|
|
157
|
+
if (key !== undefined) {
|
|
158
|
+
model.key = key;
|
|
159
|
+
}
|
|
160
|
+
return model;
|
|
161
|
+
};
|
|
@@ -41,15 +41,19 @@ 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
|
|
45
|
-
* snippet builders read
|
|
44
|
+
* The spec server with its host/pathname variables at their defaults and
|
|
45
|
+
* its `security` refs resolved; the snippet builders read
|
|
46
|
+
* host/pathname/protocol/security.
|
|
46
47
|
*/
|
|
47
48
|
server: AsyncApiServerObject;
|
|
48
49
|
}
|
|
49
50
|
|
|
50
51
|
export interface MessageModel {
|
|
51
52
|
action: AsyncApiAction;
|
|
52
|
-
/**
|
|
53
|
+
/**
|
|
54
|
+
* Channel address with `{param}` templates intact, e.g. `user/{id}/signedup`
|
|
55
|
+
* — or the Kafka binding's `topic` when the channel names one.
|
|
56
|
+
*/
|
|
53
57
|
address: string;
|
|
54
58
|
/**
|
|
55
59
|
* Whether the panel offers a live connection. Only WebSocket bindings can be
|
|
@@ -57,6 +61,8 @@ export interface MessageModel {
|
|
|
57
61
|
* CLI samples rather than faked connectivity.
|
|
58
62
|
*/
|
|
59
63
|
connectable: boolean;
|
|
64
|
+
/** Example Kafka message key, sampled from the first message's binding. */
|
|
65
|
+
key?: string;
|
|
60
66
|
params: MessageParam[];
|
|
61
67
|
payload: MessagePayload;
|
|
62
68
|
/** Normalized binding key (`ws`, `kafka`, `mqtt`, …) when the spec implies one. */
|
|
@@ -149,7 +155,7 @@ export const buildMessage = (
|
|
|
149
155
|
} catch {
|
|
150
156
|
payload = undefined;
|
|
151
157
|
}
|
|
152
|
-
|
|
158
|
+
const sample: MessageSample = {
|
|
153
159
|
action: model.action,
|
|
154
160
|
address: model.address.replaceAll(PARAM_TEMPLATE, (template, name) => {
|
|
155
161
|
const value = values.params[String(name)] ?? "";
|
|
@@ -158,6 +164,10 @@ export const buildMessage = (
|
|
|
158
164
|
payload,
|
|
159
165
|
server: custom === "" ? picked?.server : customServer(custom),
|
|
160
166
|
};
|
|
167
|
+
if (model.key !== undefined) {
|
|
168
|
+
sample.key = model.key;
|
|
169
|
+
}
|
|
170
|
+
return sample;
|
|
161
171
|
};
|
|
162
172
|
|
|
163
173
|
/**
|
|
@@ -3,6 +3,7 @@ import {
|
|
|
3
3
|
declaredExample,
|
|
4
4
|
exampleValue,
|
|
5
5
|
objectProperties,
|
|
6
|
+
parameterDescription,
|
|
6
7
|
resolveSchema,
|
|
7
8
|
toJson,
|
|
8
9
|
} from "./helpers.ts";
|
|
@@ -142,7 +143,7 @@ const modelParams = (
|
|
|
142
143
|
const required = where === "path" ? true : param.required === true;
|
|
143
144
|
const schema = resolveSchema(schemas, param.schema);
|
|
144
145
|
params.push({
|
|
145
|
-
description: param
|
|
146
|
+
description: parameterDescription(param, schemas),
|
|
146
147
|
enum: schema.enum?.map(String),
|
|
147
148
|
in: where,
|
|
148
149
|
name: param.name,
|
|
@@ -330,6 +331,19 @@ const authInput = (
|
|
|
330
331
|
}
|
|
331
332
|
};
|
|
332
333
|
|
|
334
|
+
/**
|
|
335
|
+
* The playground's credential inputs for an operation's security: the first
|
|
336
|
+
* alternative only — the spec's preferred way to authorize, matching what the
|
|
337
|
+
* static samples always showed.
|
|
338
|
+
*/
|
|
339
|
+
export const playgroundAuth = (
|
|
340
|
+
security: OperationSecurity
|
|
341
|
+
): PlaygroundAuthInput[] =>
|
|
342
|
+
(security.alternatives[0] ?? []).flatMap((resolved) => {
|
|
343
|
+
const input = authInput(resolved);
|
|
344
|
+
return input ? [input] : [];
|
|
345
|
+
});
|
|
346
|
+
|
|
333
347
|
/** Derive the playground request model for one operation, at build time. */
|
|
334
348
|
export const operationModel = (args: {
|
|
335
349
|
method: string;
|
|
@@ -344,12 +358,7 @@ export const operationModel = (args: {
|
|
|
344
358
|
components?: ComponentsLike;
|
|
345
359
|
security: OperationSecurity;
|
|
346
360
|
}): PlaygroundModel => ({
|
|
347
|
-
|
|
348
|
-
// what the static samples always showed.
|
|
349
|
-
auth: (args.security.alternatives[0] ?? []).flatMap((resolved) => {
|
|
350
|
-
const input = authInput(resolved);
|
|
351
|
-
return input ? [input] : [];
|
|
352
|
-
}),
|
|
361
|
+
auth: playgroundAuth(args.security),
|
|
353
362
|
authOptional: args.security.optional,
|
|
354
363
|
body: modelBody(args.requestBody, args.schemas, args.components),
|
|
355
364
|
method: args.method.toUpperCase(),
|
|
@@ -26,16 +26,34 @@ import { fetchRefusesMethod, sampleLanguages } from "./snippets.ts";
|
|
|
26
26
|
import type { RequestSample } from "./snippets.ts";
|
|
27
27
|
import { validateJson } from "./validate-json.ts";
|
|
28
28
|
|
|
29
|
+
const OPENAPI_PROXY_SETTING =
|
|
30
|
+
"`playground: { proxy: true }` on the `openapi()` reference";
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* The Blume config setting that turns on the proxy for a panel, keyed by the
|
|
34
|
+
* `data-proxy-config` the rendering surface stamps on it: an `openapi()` or
|
|
35
|
+
* `graphql()` reference's `playground` option, or `api.playground` for
|
|
36
|
+
* hand-written API pages.
|
|
37
|
+
*/
|
|
38
|
+
const PROXY_SETTINGS = new Map([
|
|
39
|
+
["api", "`api: { playground: { proxy: true } }`"],
|
|
40
|
+
["graphql", "`playground: { proxy: true }` on the `graphql()` reference"],
|
|
41
|
+
["openapi", OPENAPI_PROXY_SETTING],
|
|
42
|
+
]);
|
|
43
|
+
|
|
29
44
|
/**
|
|
30
45
|
* A failed fetch surfaces as a TypeError with no status — almost always the
|
|
31
46
|
* browser's CORS wall, not the API being down — so the message explains the
|
|
32
|
-
* one fix docs authors control instead of parroting "failed to fetch"
|
|
47
|
+
* one fix docs authors control instead of parroting "failed to fetch", naming
|
|
48
|
+
* the setting for the surface this panel is on and the server output the
|
|
49
|
+
* built-in proxy needs.
|
|
33
50
|
*/
|
|
34
|
-
const
|
|
51
|
+
const corsMessage = (config: string): string =>
|
|
35
52
|
"The browser blocked this request before it reached the API — the API " +
|
|
36
53
|
"likely does not allow cross-origin requests from this docs site. Set " +
|
|
37
|
-
|
|
38
|
-
"config to route playground requests through the docs server instead."
|
|
54
|
+
`${PROXY_SETTINGS.get(config) ?? OPENAPI_PROXY_SETTING} in the Blume ` +
|
|
55
|
+
"config to route playground requests through the docs server instead. " +
|
|
56
|
+
"The proxy needs server output: a host adapter in `deployment`.";
|
|
39
57
|
|
|
40
58
|
/**
|
|
41
59
|
* `Cookie` is a forbidden header name: a page cannot set it, so a credential
|
|
@@ -294,6 +312,7 @@ export const initPlayground = (root: HTMLElement): void => {
|
|
|
294
312
|
const response = root.querySelector<HTMLElement>("[data-response]");
|
|
295
313
|
const storageKey = root.dataset.storageKey ?? "";
|
|
296
314
|
const proxy = root.dataset.proxy ?? "";
|
|
315
|
+
const proxyConfig = root.dataset.proxyConfig ?? "";
|
|
297
316
|
|
|
298
317
|
/** True while a send is outstanding, so a second click can't race it. */
|
|
299
318
|
let sending = false;
|
|
@@ -607,7 +626,7 @@ export const initPlayground = (root: HTMLElement): void => {
|
|
|
607
626
|
const crossOrigin = !proxy && !sample.url.startsWith("/");
|
|
608
627
|
message =
|
|
609
628
|
crossOrigin && (await reachable(sample.url))
|
|
610
|
-
?
|
|
629
|
+
? corsMessage(proxyConfig)
|
|
611
630
|
: UNREACHABLE_MESSAGE;
|
|
612
631
|
}
|
|
613
632
|
response.textContent = "";
|
|
@@ -62,7 +62,7 @@ const isReadOnly = (
|
|
|
62
62
|
* Prune a spec schema into the tiny subset `validate-json.ts` understands:
|
|
63
63
|
* `$ref`s resolved inline, cycles cut (the visited set is copied per branch so
|
|
64
64
|
* a ref reused by siblings still prunes fully), depth capped. Structure beyond
|
|
65
|
-
* the cut simply goes unvalidated
|
|
65
|
+
* the cut simply goes unvalidated, so it can never block a send.
|
|
66
66
|
*/
|
|
67
67
|
const pruneSchema = (
|
|
68
68
|
schema: SchemaLike | undefined,
|
|
@@ -2,6 +2,7 @@ import {
|
|
|
2
2
|
objectProperties,
|
|
3
3
|
refName,
|
|
4
4
|
resolveSchema,
|
|
5
|
+
soleAllOfMember,
|
|
5
6
|
typeLabel,
|
|
6
7
|
} from "./helpers.ts";
|
|
7
8
|
import type { SchemaLike, SpecValue } from "./helpers.ts";
|
|
@@ -67,6 +68,15 @@ export type SchemaNode =
|
|
|
67
68
|
const isString = (value: SpecValue): value is string =>
|
|
68
69
|
typeof value === "string";
|
|
69
70
|
|
|
71
|
+
/**
|
|
72
|
+
* The `$ref` a schema stands for: its own, or its member's when it is a
|
|
73
|
+
* single-member `allOf` wrapper, which plans (and stops at a circle) the same.
|
|
74
|
+
*/
|
|
75
|
+
const refOf = (schema: SchemaLike): string | undefined => {
|
|
76
|
+
const ref = schema.$ref ?? soleAllOfMember(schema)?.$ref;
|
|
77
|
+
return isString(ref) ? ref : undefined;
|
|
78
|
+
};
|
|
79
|
+
|
|
70
80
|
const typesOf = (schema: SchemaLike): (string | undefined)[] =>
|
|
71
81
|
Array.isArray(schema.type) ? schema.type : [schema.type];
|
|
72
82
|
|
|
@@ -88,13 +98,32 @@ interface PendingRef {
|
|
|
88
98
|
slot: SchemaSlot;
|
|
89
99
|
}
|
|
90
100
|
|
|
91
|
-
/**
|
|
101
|
+
/**
|
|
102
|
+
* Which way a schema's data travels, when its table has one: a request body
|
|
103
|
+
* leaves out the `readOnly` fields the server generates, and a response the
|
|
104
|
+
* `writeOnly` ones it never returns, as the examples beside them do.
|
|
105
|
+
*/
|
|
106
|
+
export type SchemaDirection = "request" | "response";
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Plan the table tree for one schema (a request body, a response, a payload).
|
|
110
|
+
* With a `direction`, every table in the tree leaves out the fields that
|
|
111
|
+
* don't travel that way.
|
|
112
|
+
*/
|
|
92
113
|
export const schemaTree = (
|
|
93
114
|
root: SchemaLike,
|
|
94
|
-
schemas: Record<string, SchemaLike
|
|
115
|
+
schemas: Record<string, SchemaLike>,
|
|
116
|
+
direction?: SchemaDirection
|
|
95
117
|
): SchemaNode => {
|
|
96
118
|
const queue: PendingRef[] = [];
|
|
97
119
|
const expanded = new Set<string>();
|
|
120
|
+
const omitted = direction === "request" ? "readOnly" : "writeOnly";
|
|
121
|
+
|
|
122
|
+
/** Whether a property stays out of this tree's tables. */
|
|
123
|
+
const hidden = (property: SchemaLike): boolean =>
|
|
124
|
+
direction !== undefined &&
|
|
125
|
+
(property[omitted] === true ||
|
|
126
|
+
resolveSchema(schemas, property)[omitted] === true);
|
|
98
127
|
|
|
99
128
|
/**
|
|
100
129
|
* A table for `schema`, where `ancestors` are the named schemas already
|
|
@@ -107,8 +136,9 @@ export const schemaTree = (
|
|
|
107
136
|
ancestors: string[],
|
|
108
137
|
resolved = false
|
|
109
138
|
): SchemaSlot => {
|
|
110
|
-
|
|
111
|
-
|
|
139
|
+
const ref = resolved ? undefined : refOf(schema);
|
|
140
|
+
if (ref) {
|
|
141
|
+
const name = refName(ref);
|
|
112
142
|
if (ancestors.includes(name)) {
|
|
113
143
|
return { node: { kind: "circular", name } };
|
|
114
144
|
}
|
|
@@ -132,10 +162,8 @@ export const schemaTree = (
|
|
|
132
162
|
}
|
|
133
163
|
// A row discloses nested structure — never a model inside itself.
|
|
134
164
|
const rowChildren = (property: SchemaLike): SchemaSlot | undefined => {
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
ancestors.includes(refName(property.$ref))
|
|
138
|
-
) {
|
|
165
|
+
const propertyRef = refOf(property);
|
|
166
|
+
if (propertyRef && ancestors.includes(refName(propertyRef))) {
|
|
139
167
|
return undefined;
|
|
140
168
|
}
|
|
141
169
|
const target = resolveSchema(schemas, property);
|
|
@@ -147,12 +175,14 @@ export const schemaTree = (
|
|
|
147
175
|
: undefined;
|
|
148
176
|
};
|
|
149
177
|
const { properties, required } = objectProperties(schema, schemas);
|
|
150
|
-
const rows: SchemaRow[] = properties
|
|
151
|
-
|
|
152
|
-
name,
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
178
|
+
const rows: SchemaRow[] = properties
|
|
179
|
+
.filter(([, property]) => !hidden(property))
|
|
180
|
+
.map(([name, property]) => ({
|
|
181
|
+
children: rowChildren(property),
|
|
182
|
+
name,
|
|
183
|
+
required: required.has(name),
|
|
184
|
+
schema: property,
|
|
185
|
+
}));
|
|
156
186
|
// Shared properties beside a `oneOf`/`anyOf` (`amount` and `currency`
|
|
157
187
|
// next to `Card | BankAccount`) render above the variants, planned first
|
|
158
188
|
// as they read first.
|