blume 2.0.0 → 2.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +1 -1
- package/CHANGELOG.md +110 -0
- package/README.md +2 -2
- package/dist/cli/{chunk-f2972sbt.js → chunk-00gs3wqs.js} +1 -1
- package/dist/cli/{chunk-fa25z98p.js → chunk-273ygyr4.js} +4 -3
- package/dist/cli/chunk-273ygyr4.js.map +11 -0
- package/dist/cli/{chunk-pat2zzwc.js → chunk-3yce002v.js} +21 -8
- package/dist/cli/{chunk-pat2zzwc.js.map → chunk-3yce002v.js.map} +4 -4
- package/dist/cli/{chunk-d1tadaw7.js → chunk-4e9b9ra6.js} +17 -7
- package/dist/cli/chunk-4e9b9ra6.js.map +10 -0
- package/dist/cli/{chunk-zg2gtj10.js → chunk-5r8g91qn.js} +352 -676
- package/dist/cli/chunk-5r8g91qn.js.map +34 -0
- package/dist/cli/{chunk-11j0384y.js → chunk-6dtt0zfn.js} +14 -14
- package/dist/cli/{chunk-11j0384y.js.map → chunk-6dtt0zfn.js.map} +3 -3
- package/dist/cli/{chunk-bw22s759.js → chunk-6k4ftwze.js} +38 -19
- package/dist/cli/{chunk-bw22s759.js.map → chunk-6k4ftwze.js.map} +4 -4
- package/dist/cli/{chunk-sqn5t4q0.js → chunk-7mbqtmgb.js} +16 -7
- package/dist/cli/chunk-7mbqtmgb.js.map +10 -0
- package/dist/cli/{chunk-79njf86q.js → chunk-7vtckvaw.js} +21 -19
- package/dist/cli/chunk-7vtckvaw.js.map +11 -0
- package/dist/cli/{chunk-fh5hj5jt.js → chunk-8g8ytmgx.js} +17 -18
- package/dist/cli/{chunk-fh5hj5jt.js.map → chunk-8g8ytmgx.js.map} +2 -2
- package/dist/cli/{chunk-1w8dp3qb.js → chunk-91ws1n6j.js} +18 -15
- package/dist/cli/chunk-91ws1n6j.js.map +10 -0
- package/dist/cli/{chunk-7ez8ny0t.js → chunk-bbnwccaz.js} +2 -2
- package/dist/cli/{chunk-5a2z0198.js → chunk-bfwp9vp6.js} +18 -10
- package/dist/cli/chunk-bfwp9vp6.js.map +10 -0
- package/dist/cli/{chunk-ernrthtr.js → chunk-d1v5rhy0.js} +14 -15
- package/dist/cli/{chunk-ernrthtr.js.map → chunk-d1v5rhy0.js.map} +2 -2
- package/dist/cli/{chunk-a9kptbw5.js → chunk-ddndchfr.js} +21 -6
- package/dist/cli/chunk-ddndchfr.js.map +14 -0
- package/dist/cli/{chunk-zxccj738.js → chunk-esh98wmb.js} +1 -1
- package/dist/cli/{chunk-88cpgt6h.js → chunk-fsmrqk8a.js} +1 -1
- package/dist/cli/{chunk-b5aj94ah.js → chunk-g698a744.js} +5 -5
- package/dist/cli/{chunk-jts8mvcz.js → chunk-gs7r695n.js} +9 -3
- package/dist/cli/{chunk-jts8mvcz.js.map → chunk-gs7r695n.js.map} +3 -3
- package/dist/cli/{chunk-41za066z.js → chunk-h2ez8dzb.js} +4 -4
- package/dist/cli/{chunk-by2290sx.js → chunk-h7k3nq3v.js} +2 -2
- package/dist/cli/{chunk-j8mw0za6.js → chunk-hqp2ajnh.js} +252 -123
- package/dist/cli/chunk-hqp2ajnh.js.map +35 -0
- package/dist/cli/{chunk-mnqj32sj.js → chunk-hr8ne106.js} +119 -50
- package/dist/cli/chunk-hr8ne106.js.map +13 -0
- package/dist/cli/{chunk-mwt1k8n7.js → chunk-j85scx15.js} +74 -30
- package/dist/cli/chunk-j85scx15.js.map +10 -0
- package/dist/cli/{chunk-z01ze5c1.js → chunk-k7pj68a8.js} +63 -22
- package/dist/cli/chunk-k7pj68a8.js.map +11 -0
- package/dist/cli/{chunk-2q1dwty4.js → chunk-mqc662a6.js} +8 -8
- package/dist/cli/{chunk-2q1dwty4.js.map → chunk-mqc662a6.js.map} +4 -4
- package/dist/cli/{chunk-y3e45rc8.js → chunk-n1yg3tj3.js} +4 -4
- package/dist/cli/{chunk-bctazmbk.js → chunk-nfcyttvj.js} +17 -6
- package/dist/cli/chunk-nfcyttvj.js.map +10 -0
- package/dist/cli/{chunk-6k8vp3ta.js → chunk-pbg5a4s3.js} +60 -28
- package/dist/cli/chunk-pbg5a4s3.js.map +19 -0
- package/dist/cli/{chunk-d80hr03s.js → chunk-ppzjqwx2.js} +24 -17
- package/dist/cli/{chunk-d80hr03s.js.map → chunk-ppzjqwx2.js.map} +4 -4
- package/dist/cli/{chunk-beat36xx.js → chunk-qkb5a8sa.js} +25 -10
- package/dist/cli/chunk-qkb5a8sa.js.map +10 -0
- package/dist/cli/{chunk-bnbmcwfb.js → chunk-sqw4ekg1.js} +5 -5
- package/dist/cli/{chunk-bnbmcwfb.js.map → chunk-sqw4ekg1.js.map} +3 -3
- package/dist/cli/{chunk-xaz13gwg.js → chunk-v6ya5kcb.js} +3268 -1150
- package/dist/cli/chunk-v6ya5kcb.js.map +189 -0
- package/dist/cli/{chunk-tzne8qfq.js → chunk-w4bxdvsa.js} +18 -15
- package/dist/cli/chunk-w4bxdvsa.js.map +10 -0
- package/dist/cli/{chunk-f7t03s3g.js → chunk-wdrt2k2v.js} +2 -2
- package/dist/cli/{chunk-z1f5arsg.js → chunk-xh43dwgw.js} +170 -55
- package/dist/cli/chunk-xh43dwgw.js.map +36 -0
- package/dist/cli/{chunk-pnnvybbk.js → chunk-zp79m0ts.js} +5 -5
- package/dist/cli/{chunk-pnnvybbk.js.map → chunk-zp79m0ts.js.map} +2 -2
- package/dist/cli/index.js +160 -35
- package/dist/cli/index.js.map +4 -4
- package/dist/types/ai/agent-readability.d.ts +1 -1
- package/dist/types/ai/agent-surface.d.ts +32 -0
- package/dist/types/ai/api/paths.d.ts +1 -1
- package/dist/types/ai/api-catalog.d.ts +7 -1
- package/dist/types/ai/ask-context.d.ts +14 -7
- package/dist/types/ai/ask.d.ts +43 -43
- package/dist/types/ai/component-markdown.d.ts +4 -4
- package/dist/types/ai/index.d.ts +3 -3
- package/dist/types/ai/openapi-components.d.ts +1 -1
- package/dist/types/ai/relative-links.d.ts +9 -4
- package/dist/types/ai/serializers.d.ts +1 -1
- package/dist/types/ai/static-expression.d.ts +28 -0
- package/dist/types/ai/visibility.d.ts +1 -1
- package/dist/types/analytics/databuddy.d.ts +43 -0
- package/dist/types/analytics/index.d.ts +2 -0
- package/dist/types/analytics/schema.d.ts +14 -0
- package/dist/types/cli/env.d.ts +5 -0
- package/dist/types/cli/init/scaffold.d.ts +19 -3
- package/dist/types/cli/init/starter-spec.d.ts +11 -0
- package/dist/types/core/base-path.d.ts +9 -0
- package/dist/types/core/config-input.d.ts +21 -21
- package/dist/types/core/config.d.ts +5 -5
- package/dist/types/core/data.d.ts +3 -3
- package/dist/types/core/graph.d.ts +2 -0
- package/dist/types/core/i18n-ui.d.ts +37 -8
- package/dist/types/core/i18n.d.ts +7 -1
- package/dist/types/core/links.d.ts +3 -1
- package/dist/types/core/load-module.d.ts +10 -0
- package/dist/types/core/locale-links.d.ts +12 -2
- package/dist/types/core/meta.d.ts +5 -1
- package/dist/types/core/nav-diagnostics.d.ts +10 -0
- package/dist/types/core/navigation.d.ts +38 -0
- package/dist/types/core/ordering-prefix.d.ts +4 -0
- package/dist/types/core/safe-links.d.ts +3 -1
- package/dist/types/core/schema.d.ts +57 -18
- package/dist/types/core/sources/github-releases.d.ts +5 -0
- package/dist/types/core/sources/lower.d.ts +14 -2
- package/dist/types/core/sources/normalize.d.ts +10 -1
- package/dist/types/core/sources/remote.d.ts +11 -1
- package/dist/types/core/sources/resolve.d.ts +12 -0
- package/dist/types/core/sources/types.d.ts +31 -0
- package/dist/types/core/types.d.ts +9 -0
- package/dist/types/core/unrecognized-keys.d.ts +1 -1
- package/dist/types/deploy/adapters/node.d.ts +5 -2
- package/dist/types/deploy/adapters/types.d.ts +7 -0
- package/dist/types/deploy/cloudflare-negotiation.d.ts +3 -2
- package/dist/types/deploy/headers.d.ts +31 -7
- package/dist/types/deploy/node-headers.d.ts +43 -8
- package/dist/types/deploy/platforms/netlify.d.ts +27 -2
- package/dist/types/deploy/platforms/node.d.ts +6 -5
- package/dist/types/deploy/platforms/types.d.ts +7 -0
- package/dist/types/deploy/platforms/vercel.d.ts +3 -2
- package/dist/types/deploy/redirects.d.ts +7 -2
- package/dist/types/deploy/vercel-negotiation.d.ts +3 -2
- package/dist/types/openapi/model.d.ts +20 -6
- package/dist/types/search/documents.d.ts +1 -1
- package/dist/types/search/orama-index.d.ts +1 -1
- package/dist/types/search/sync/algolia.d.ts +3 -1
- package/docs/01-quickstart.mdx +3 -2
- package/docs/02-deployment.mdx +21 -12
- package/docs/03-upgrading.mdx +22 -9
- package/docs/04-migrating.mdx +4 -4
- package/docs/08-faq.mdx +12 -5
- package/docs/advanced/changelog.mdx +1 -1
- package/docs/advanced/custom-pages.mdx +5 -3
- package/docs/advanced/skills.mdx +1 -1
- package/docs/cli/audit.mdx +5 -5
- package/docs/cli/doctor.mdx +4 -4
- package/docs/cli/evals.mdx +9 -9
- package/docs/cli/index.mdx +6 -3
- package/docs/cli/translate.mdx +8 -8
- package/docs/configuration/analytics.mdx +23 -2
- package/docs/configuration/{ask-ai.mdx → assistant.mdx} +20 -20
- package/docs/configuration/customization.mdx +5 -4
- package/docs/configuration/index.mdx +7 -5
- package/docs/configuration/meta.ts +1 -1
- package/docs/configuration/search.mdx +2 -2
- package/docs/content/components.mdx +1 -1
- package/docs/content/frontmatter.mdx +5 -1
- package/docs/content/i18n.mdx +3 -3
- package/docs/content/index.mdx +4 -2
- package/docs/content/islands.mdx +1 -1
- package/docs/content/meta.mdx +5 -3
- package/docs/content/navigation.mdx +29 -4
- package/docs/content/sources.mdx +18 -12
- package/docs/content/versioning.mdx +1 -0
- package/docs/discoverability/agent-discovery.mdx +22 -8
- package/docs/discoverability/index.mdx +3 -3
- package/docs/discoverability/llms-txt.mdx +2 -5
- package/docs/discoverability/markdown.mdx +5 -3
- package/docs/discoverability/mcp.mdx +4 -0
- package/docs/discoverability/metadata.mdx +3 -2
- package/docs/discoverability/open-graph.mdx +6 -4
- package/docs/discoverability/rss.mdx +3 -1
- package/docs/index.mdx +2 -2
- package/docs/references/asyncapi.mdx +1 -1
- package/docs/references/graphql.mdx +2 -2
- package/docs/references/openapi.mdx +3 -3
- package/package.json +1 -1
- package/skills/blume/SKILL.md +5 -5
- package/skills/blume-migrate/SKILL.md +6 -6
- package/skills/blume-migrate/references/docusaurus.md +6 -6
- package/skills/blume-migrate/references/mintlify.md +3 -3
- package/skills/blume-migrate/references/monorepo.md +1 -1
- package/skills/blume-migrate/references/nextra.md +1 -1
- package/skills/blume-migrate/references/starlight.md +5 -5
- package/skills/blume-migrate/scripts/mintlify-codemod.mjs +2 -2
- package/skills/blume-update-docs/references/audit-checklist.md +1 -1
- package/src/ai/agent-readability.ts +4 -4
- package/src/ai/agent-surface.ts +56 -0
- package/src/ai/api/paths.ts +1 -1
- package/src/ai/api/spec.ts +15 -2
- package/src/ai/api-catalog.ts +7 -1
- package/src/ai/ask-context.ts +21 -9
- package/src/ai/ask-data.ts +28 -14
- package/src/ai/ask.ts +84 -71
- package/src/ai/component-markdown.ts +43 -37
- package/src/ai/cors.ts +3 -3
- package/src/ai/index.ts +16 -16
- package/src/ai/link-headers.ts +8 -3
- package/src/ai/llms.ts +4 -3
- package/src/ai/markdown.ts +23 -11
- package/src/ai/mcp/server.ts +78 -7
- package/src/ai/openapi-components.ts +1 -1
- package/src/ai/relative-links.ts +78 -10
- package/src/ai/serializers.ts +1 -1
- package/src/ai/static-expression.ts +416 -0
- package/src/ai/visibility.ts +46 -15
- package/src/analytics/databuddy.ts +67 -0
- package/src/analytics/head.ts +4 -0
- package/src/analytics/index.ts +2 -0
- package/src/analytics/posthog.ts +21 -3
- package/src/analytics/schema.ts +2 -0
- package/src/astro/generate.ts +90 -45
- package/src/astro/module-types.ts +1 -1
- package/src/astro/runtime-deps.ts +6 -6
- package/src/astro/templates.ts +87 -49
- package/src/audit/catalog.ts +2 -2
- package/src/audit/checks/assets.ts +25 -5
- package/src/audit/checks/content.ts +20 -2
- package/src/audit/checks/i18n.ts +46 -8
- package/src/audit/checks/indexability.ts +39 -19
- package/src/audit/checks/links.ts +14 -0
- package/src/audit/checks/llms.ts +6 -3
- package/src/audit/checks/network.ts +3 -1
- package/src/audit/checks/og-image.ts +10 -0
- package/src/audit/checks/robots.ts +6 -1
- package/src/audit/checks/sitemap.ts +56 -31
- package/src/audit/checks/social.ts +21 -2
- package/src/audit/crawl.ts +88 -15
- package/src/audit/report.ts +54 -17
- package/src/audit/run.ts +1 -0
- package/src/audit/types.ts +18 -0
- package/src/audit/url.ts +37 -6
- package/src/blume-modules.d.ts +2 -2
- package/src/cli/build-failure.ts +50 -0
- package/src/cli/commands/audit.ts +8 -1
- package/src/cli/commands/build.ts +19 -5
- package/src/cli/commands/check.ts +2 -0
- package/src/cli/commands/doctor.ts +7 -5
- package/src/cli/commands/eval.ts +4 -10
- package/src/cli/commands/init.ts +15 -5
- package/src/cli/commands/migrate.ts +2 -2
- package/src/cli/commands/preview.ts +15 -0
- package/src/cli/commands/sync.ts +2 -0
- package/src/cli/commands/translate.ts +12 -9
- package/src/cli/commands/upgrade.ts +13 -2
- package/src/cli/eject-scripts.ts +32 -7
- package/src/cli/env.ts +12 -1
- package/src/cli/init/scaffold.ts +117 -11
- package/src/cli/init/starter-spec.ts +235 -0
- package/src/cli/required-secrets.ts +3 -3
- package/src/components/content/AccordionItem.astro +26 -22
- package/src/components/content/Badge.astro +2 -9
- package/src/components/content/Card.astro +2 -2
- package/src/components/content/Component.astro +9 -3
- package/src/components/content/Expandable.astro +5 -1
- package/src/components/content/Frame.astro +2 -7
- package/src/components/content/GithubInfo.astro +12 -2
- package/src/components/content/Prompt.astro +2 -7
- package/src/components/content/Tabs.astro +54 -5
- package/src/components/content/Tile.astro +1 -1
- package/src/components/content/Tooltip.astro +69 -7
- package/src/components/content/Tree.astro +7 -2
- package/src/components/content/TypeTable.astro +10 -5
- package/src/components/content/Update.astro +8 -2
- package/src/components/content/auto-type-table.ts +4 -1
- package/src/components/content/badge-color.ts +17 -0
- package/src/components/content/base-href.ts +18 -3
- package/src/components/content/inline-markdown.ts +27 -7
- package/src/components/copy-feedback.ts +36 -9
- package/src/components/islands/{AskAI.astro → Assistant.astro} +10 -10
- package/src/components/islands/{ask-ai.tsx → assistant.tsx} +39 -25
- package/src/components/islands/hooks.ts +21 -14
- package/src/components/islands/webmcp.ts +12 -8
- package/src/components/layout/Banner.astro +23 -4
- package/src/components/layout/Header.astro +32 -19
- package/src/components/layout/Logo.astro +5 -0
- package/src/components/layout/NavSelector.astro +6 -1
- package/src/components/layout/NavTabMenu.astro +133 -0
- package/src/components/layout/NavTree.astro +15 -6
- package/src/components/layout/NavTreeCache.astro +5 -2
- package/src/components/layout/NavTreeScript.astro +45 -5
- package/src/components/layout/PageLayout.astro +28 -14
- package/src/components/layout/Pagination.astro +7 -7
- package/src/components/layout/ReferenceLayout.astro +5 -2
- package/src/components/layout/RootLayout.astro +27 -14
- package/src/components/layout/Search.astro +18 -14
- package/src/components/layout/analytics-client.ts +3 -1
- package/src/components/layout/drawer-inert.ts +1 -1
- package/src/components/openapi/GraphqlType.astro +11 -3
- package/src/components/openapi/MessageComposer.astro +1 -1
- package/src/components/openapi/Operation.astro +21 -5
- package/src/components/openapi/PanelTabs.astro +4 -1
- package/src/components/openapi/Playground.astro +8 -2
- package/src/components/openapi/RequestPanel.astro +9 -5
- package/src/components/openapi/SchemaProperty.astro +11 -33
- package/src/components/openapi/SchemaTable.astro +27 -52
- package/src/components/openapi/description.ts +2 -2
- package/src/components/openapi/helpers.ts +90 -12
- package/src/components/openapi/message-composer.ts +8 -0
- package/src/components/openapi/message-model.ts +12 -2
- package/src/components/openapi/message.ts +4 -1
- package/src/components/openapi/operation-model.ts +40 -8
- package/src/components/openapi/panel.ts +29 -5
- package/src/components/openapi/playground-client.ts +37 -7
- package/src/components/openapi/playground-schema.ts +25 -6
- package/src/components/openapi/request.ts +2 -0
- package/src/components/openapi/schema-tree.ts +203 -0
- package/src/components/openapi/snippets.ts +30 -15
- package/src/components/openapi/validate-json.ts +1 -1
- package/src/core/base-path.ts +15 -0
- package/src/core/code-fences.ts +1 -1
- package/src/core/config-input.ts +23 -23
- package/src/core/config.ts +21 -7
- package/src/core/data.ts +3 -3
- package/src/core/diagnostics.ts +217 -30
- package/src/core/graph.ts +120 -11
- package/src/core/i18n-ui.ts +74 -11
- package/src/core/i18n.ts +13 -2
- package/src/core/links.ts +7 -4
- package/src/core/load-module.ts +20 -0
- package/src/core/locale-links.ts +17 -17
- package/src/core/manifest.ts +3 -2
- package/src/core/meta.ts +69 -6
- package/src/core/nav-diagnostics.ts +56 -1
- package/src/core/navigation.ts +245 -76
- package/src/core/ordering-prefix.ts +27 -0
- package/src/core/project-graph.ts +23 -1
- package/src/core/request-body.ts +1 -1
- package/src/core/safe-href.ts +53 -1
- package/src/core/safe-links.ts +11 -2
- package/src/core/schema.ts +95 -34
- package/src/core/server-features.ts +2 -2
- package/src/core/sources/assets.ts +83 -41
- package/src/core/sources/contentful-rich-text.ts +3 -2
- package/src/core/sources/contentful.ts +25 -12
- package/src/core/sources/filesystem.ts +5 -1
- package/src/core/sources/github-releases.ts +106 -5
- package/src/core/sources/lexical.ts +9 -4
- package/src/core/sources/lower.ts +79 -26
- package/src/core/sources/mdx-remote.ts +1 -0
- package/src/core/sources/normalize.ts +132 -30
- package/src/core/sources/notion.ts +26 -10
- package/src/core/sources/obsidian.ts +17 -3
- package/src/core/sources/payload.ts +1 -0
- package/src/core/sources/portable-text.ts +63 -44
- package/src/core/sources/remote.ts +18 -2
- package/src/core/sources/resolve.ts +52 -33
- package/src/core/sources/sanity.ts +1 -0
- package/src/core/sources/strapi-blocks.ts +9 -4
- package/src/core/sources/strapi.ts +1 -0
- package/src/core/sources/types.ts +31 -0
- package/src/core/types.ts +9 -0
- package/src/core/ui-packs/ar.ts +17 -5
- package/src/core/ui-packs/bg.ts +17 -5
- package/src/core/ui-packs/bn.ts +17 -5
- package/src/core/ui-packs/ca.ts +17 -5
- package/src/core/ui-packs/cs.ts +17 -5
- package/src/core/ui-packs/da.ts +17 -5
- package/src/core/ui-packs/de.ts +17 -5
- package/src/core/ui-packs/el.ts +17 -5
- package/src/core/ui-packs/es.ts +17 -5
- package/src/core/ui-packs/fa.ts +17 -5
- package/src/core/ui-packs/fi.ts +17 -5
- package/src/core/ui-packs/fr.ts +17 -5
- package/src/core/ui-packs/he.ts +17 -5
- package/src/core/ui-packs/hi.ts +17 -5
- package/src/core/ui-packs/hr.ts +17 -5
- package/src/core/ui-packs/hu.ts +17 -5
- package/src/core/ui-packs/id.ts +17 -5
- package/src/core/ui-packs/it.ts +17 -5
- package/src/core/ui-packs/ja.ts +17 -5
- package/src/core/ui-packs/ko.ts +17 -5
- package/src/core/ui-packs/nl.ts +17 -5
- package/src/core/ui-packs/no.ts +17 -5
- package/src/core/ui-packs/pl.ts +17 -5
- package/src/core/ui-packs/pt-br.ts +17 -5
- package/src/core/ui-packs/pt.ts +17 -5
- package/src/core/ui-packs/ro.ts +17 -5
- package/src/core/ui-packs/ru.ts +17 -5
- package/src/core/ui-packs/sk.ts +17 -5
- package/src/core/ui-packs/sr.ts +17 -5
- package/src/core/ui-packs/sv.ts +17 -5
- package/src/core/ui-packs/th.ts +17 -5
- package/src/core/ui-packs/tr.ts +17 -5
- package/src/core/ui-packs/uk.ts +17 -5
- package/src/core/ui-packs/vi.ts +17 -5
- package/src/core/ui-packs/zh-tw.ts +17 -5
- package/src/core/ui-packs/zh.ts +17 -5
- package/src/core/unrecognized-keys.ts +1 -1
- package/src/core/version-cut.ts +17 -2
- package/src/core/versions.ts +4 -1
- package/src/deploy/adapters/node.ts +5 -2
- package/src/deploy/adapters/registry.ts +2 -1
- package/src/deploy/adapters/types.ts +13 -1
- package/src/deploy/artifacts.ts +25 -5
- package/src/deploy/cloudflare-negotiation.ts +23 -4
- package/src/deploy/headers.ts +67 -51
- package/src/deploy/node-headers.ts +148 -27
- package/src/deploy/platforms/cloudflare.ts +1 -0
- package/src/deploy/platforms/netlify.ts +82 -5
- package/src/deploy/platforms/node.ts +7 -5
- package/src/deploy/platforms/static.ts +1 -0
- package/src/deploy/platforms/types.ts +7 -0
- package/src/deploy/platforms/vercel.ts +9 -3
- package/src/deploy/redirects.ts +14 -3
- package/src/deploy/vercel-negotiation.ts +35 -3
- package/src/eval/agents.ts +10 -2
- package/src/eval/run.ts +25 -0
- package/src/markdown/base-links.ts +55 -8
- package/src/markdown/index.ts +6 -3
- package/src/markdown/relative-links.ts +3 -23
- package/src/markdown/route-snapshot.ts +37 -0
- package/src/og/card.ts +20 -4
- package/src/og/derive.ts +145 -4
- package/src/openapi/graphql-build.ts +28 -2
- package/src/openapi/model.ts +77 -13
- package/src/openapi/render-mdx.ts +10 -1
- package/src/registry/eject.ts +135 -37
- package/src/search/documents.ts +24 -3
- package/src/search/orama-index.ts +1 -1
- package/src/search/sync/algolia.ts +36 -2
- package/src/sources/registry.ts +5 -0
- package/src/theme/entry.ts +11 -4
- package/src/translate/agents.ts +6 -1
- package/src/translate/ledger.ts +26 -3
- package/src/translate/meta.ts +11 -3
- package/src/translate/report.ts +1 -1
- package/src/translate/run.ts +11 -5
- package/src/translate/validate.ts +10 -1
- package/src/translate/work-list.ts +36 -3
- package/src/upgrade/upgrade.ts +37 -5
- package/dist/cli/chunk-1w8dp3qb.js.map +0 -10
- package/dist/cli/chunk-5a2z0198.js.map +0 -10
- package/dist/cli/chunk-6k8vp3ta.js.map +0 -19
- package/dist/cli/chunk-79njf86q.js.map +0 -11
- package/dist/cli/chunk-a9kptbw5.js.map +0 -14
- package/dist/cli/chunk-abh8yjkn.js +0 -31
- package/dist/cli/chunk-abh8yjkn.js.map +0 -10
- package/dist/cli/chunk-bctazmbk.js.map +0 -10
- package/dist/cli/chunk-beat36xx.js.map +0 -10
- package/dist/cli/chunk-d1tadaw7.js.map +0 -10
- package/dist/cli/chunk-fa25z98p.js.map +0 -11
- package/dist/cli/chunk-j8mw0za6.js.map +0 -35
- package/dist/cli/chunk-mnqj32sj.js.map +0 -12
- package/dist/cli/chunk-mwt1k8n7.js.map +0 -10
- package/dist/cli/chunk-nk3ts2xk.js +0 -51
- package/dist/cli/chunk-nk3ts2xk.js.map +0 -10
- package/dist/cli/chunk-sqn5t4q0.js.map +0 -10
- package/dist/cli/chunk-tzne8qfq.js.map +0 -10
- package/dist/cli/chunk-xaz13gwg.js.map +0 -182
- package/dist/cli/chunk-z01ze5c1.js.map +0 -10
- package/dist/cli/chunk-z1f5arsg.js.map +0 -36
- package/dist/cli/chunk-zg2gtj10.js.map +0 -35
- /package/dist/cli/{chunk-f2972sbt.js.map → chunk-00gs3wqs.js.map} +0 -0
- /package/dist/cli/{chunk-7ez8ny0t.js.map → chunk-bbnwccaz.js.map} +0 -0
- /package/dist/cli/{chunk-zxccj738.js.map → chunk-esh98wmb.js.map} +0 -0
- /package/dist/cli/{chunk-88cpgt6h.js.map → chunk-fsmrqk8a.js.map} +0 -0
- /package/dist/cli/{chunk-b5aj94ah.js.map → chunk-g698a744.js.map} +0 -0
- /package/dist/cli/{chunk-41za066z.js.map → chunk-h2ez8dzb.js.map} +0 -0
- /package/dist/cli/{chunk-by2290sx.js.map → chunk-h7k3nq3v.js.map} +0 -0
- /package/dist/cli/{chunk-y3e45rc8.js.map → chunk-n1yg3tj3.js.map} +0 -0
- /package/dist/cli/{chunk-f7t03s3g.js.map → chunk-wdrt2k2v.js.map} +0 -0
package/src/cli/init/scaffold.ts
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import { existsSync, readFileSync } from "node:fs";
|
|
2
2
|
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
3
3
|
|
|
4
|
+
import { loadAll } from "js-yaml";
|
|
4
5
|
import { detect } from "package-manager-detector/detect";
|
|
5
6
|
import { basename, dirname, isAbsolute, join, relative } from "pathe";
|
|
7
|
+
import picomatch from "picomatch";
|
|
8
|
+
import { z } from "zod";
|
|
6
9
|
|
|
7
10
|
import { blumePackageJson, toPackageName } from "../../core/package-json.ts";
|
|
8
11
|
import { contentful } from "../../sources/contentful.ts";
|
|
@@ -14,6 +17,7 @@ import { payload } from "../../sources/payload.ts";
|
|
|
14
17
|
import type { AnySourceAdapter } from "../../sources/registry.ts";
|
|
15
18
|
import { sanity } from "../../sources/sanity.ts";
|
|
16
19
|
import { strapi } from "../../sources/strapi.ts";
|
|
20
|
+
import { STARTER_OPENAPI_JSON } from "./starter-spec.ts";
|
|
17
21
|
|
|
18
22
|
export const TEMPLATES = ["docs", "api", "sdk", "changelog"] as const;
|
|
19
23
|
export type Template = (typeof TEMPLATES)[number];
|
|
@@ -64,6 +68,11 @@ interface Starter {
|
|
|
64
68
|
/** Import lines the fragment needs, placed after the `defineConfig` import. */
|
|
65
69
|
configImports: string[];
|
|
66
70
|
files: (contentDir: string) => { content: string; path: string }[];
|
|
71
|
+
/**
|
|
72
|
+
* Files the config itself reads (the `api` starter's spec), written beside
|
|
73
|
+
* it whichever content sources are selected.
|
|
74
|
+
*/
|
|
75
|
+
projectFiles?: { content: string; path: string }[];
|
|
67
76
|
}
|
|
68
77
|
|
|
69
78
|
const page = (title: string, description: string, body: string): string =>
|
|
@@ -77,8 +86,8 @@ export const STARTERS = {
|
|
|
77
86
|
route: "/api",
|
|
78
87
|
sources: [
|
|
79
88
|
{
|
|
80
|
-
label: "
|
|
81
|
-
spec: "
|
|
89
|
+
label: "Pet Store",
|
|
90
|
+
spec: "./openapi.json",
|
|
82
91
|
},
|
|
83
92
|
],
|
|
84
93
|
}),
|
|
@@ -89,11 +98,12 @@ export const STARTERS = {
|
|
|
89
98
|
content: page(
|
|
90
99
|
"API Reference",
|
|
91
100
|
"Reference documentation for the API, generated from its OpenAPI spec, with every endpoint, its parameters, request bodies, and responses.",
|
|
92
|
-
"
|
|
101
|
+
"The example spec in `openapi.json` renders at [`/api`](/api). Replace it with your own, or point `openapi()` at your spec in `blume.config.ts`."
|
|
93
102
|
),
|
|
94
103
|
path: join(dir, "index.mdx"),
|
|
95
104
|
},
|
|
96
105
|
],
|
|
106
|
+
projectFiles: [{ content: STARTER_OPENAPI_JSON, path: "openapi.json" }],
|
|
97
107
|
},
|
|
98
108
|
changelog: {
|
|
99
109
|
configExtra: `
|
|
@@ -173,6 +183,20 @@ export const commandsFor = (pm: PackageManager) => ({
|
|
|
173
183
|
install: `${pm} install`,
|
|
174
184
|
});
|
|
175
185
|
|
|
186
|
+
// A path every shell (POSIX, cmd, PowerShell) takes as one bare word.
|
|
187
|
+
const SHELL_SAFE_PATH = /^[\w./:-]+$/u;
|
|
188
|
+
// What a double-quoted POSIX word still interprets.
|
|
189
|
+
const DOUBLE_QUOTE_SPECIAL = /["$\\`]/gu;
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* The `cd` into the new project, quoting a directory a shell would split or
|
|
193
|
+
* expand: `blume init "my docs"` prints `cd "my docs"`, not `cd my docs`.
|
|
194
|
+
*/
|
|
195
|
+
export const cdCommand = (directory: string): string =>
|
|
196
|
+
SHELL_SAFE_PATH.test(directory)
|
|
197
|
+
? `cd ${directory}`
|
|
198
|
+
: `cd "${directory.replaceAll(DOUBLE_QUOTE_SPECIAL, String.raw`\$&`)}"`;
|
|
199
|
+
|
|
176
200
|
const isPackageManager = (value: string): value is PackageManager =>
|
|
177
201
|
PACKAGE_MANAGERS.some((pm) => pm === value);
|
|
178
202
|
|
|
@@ -525,6 +549,70 @@ const readText = (path: string): string => {
|
|
|
525
549
|
const pnpmWorkspaceRoot = (root: string): string | null =>
|
|
526
550
|
nearestAncestor(root, (dir) => existsSync(join(dir, "pnpm-workspace.yaml")));
|
|
527
551
|
|
|
552
|
+
/** The slice of `pnpm-workspace.yaml` the membership check reads. */
|
|
553
|
+
const pnpmWorkspaceSchema = z.looseObject({
|
|
554
|
+
packages: z.array(z.string()).default([]),
|
|
555
|
+
});
|
|
556
|
+
|
|
557
|
+
// A glob's leading `./` and trailing `/`, which pnpm ignores.
|
|
558
|
+
const GLOB_EDGES = /^\.\/|\/+$/gu;
|
|
559
|
+
|
|
560
|
+
/** Whether any of `globs` matches the workspace-relative path `at`. */
|
|
561
|
+
const matchesAny = (globs: string[], at: string): boolean =>
|
|
562
|
+
globs.length > 0 && picomatch(globs)(at);
|
|
563
|
+
|
|
564
|
+
/**
|
|
565
|
+
* Whether the pnpm workspace at `workspace` lists `root` as one of its
|
|
566
|
+
* packages: the workspace root itself, or a folder its `packages` globs match
|
|
567
|
+
* and no `!` glob excludes. pnpm installs only those, so an install run in any
|
|
568
|
+
* other folder beneath it succeeds without installing that folder's
|
|
569
|
+
* dependencies. A workspace file that doesn't parse counts as listing it, so
|
|
570
|
+
* `init` never claims what it can't tell.
|
|
571
|
+
*/
|
|
572
|
+
const listsPackage = (workspace: string, root: string): boolean => {
|
|
573
|
+
const at = relative(workspace, root);
|
|
574
|
+
if (at === "") {
|
|
575
|
+
return true;
|
|
576
|
+
}
|
|
577
|
+
let parsed: ReturnType<typeof pnpmWorkspaceSchema.safeParse>;
|
|
578
|
+
try {
|
|
579
|
+
// `loadAll`, not `load`: js-yaml 5 throws on a file with no document (empty,
|
|
580
|
+
// or comments only), which pnpm reads as a workspace of the root alone.
|
|
581
|
+
const [document] = loadAll(
|
|
582
|
+
readText(join(workspace, "pnpm-workspace.yaml"))
|
|
583
|
+
);
|
|
584
|
+
parsed = pnpmWorkspaceSchema.safeParse(document ?? {});
|
|
585
|
+
} catch {
|
|
586
|
+
return true;
|
|
587
|
+
}
|
|
588
|
+
if (!parsed.success) {
|
|
589
|
+
return true;
|
|
590
|
+
}
|
|
591
|
+
const globs = parsed.data.packages;
|
|
592
|
+
const pattern = (glob: string): string => glob.replaceAll(GLOB_EDGES, "");
|
|
593
|
+
const included = globs.filter((glob) => !glob.startsWith("!")).map(pattern);
|
|
594
|
+
const excluded = globs
|
|
595
|
+
.filter((glob) => glob.startsWith("!"))
|
|
596
|
+
.map((glob) => pattern(glob.slice(1)));
|
|
597
|
+
return matchesAny(included, at) && !matchesAny(excluded, at);
|
|
598
|
+
};
|
|
599
|
+
|
|
600
|
+
/**
|
|
601
|
+
* Whether `init` installs with pnpm into a folder that sits inside a pnpm
|
|
602
|
+
* workspace without being one of its packages. pnpm would install that
|
|
603
|
+
* workspace's own packages from there and exit 0, leaving `blume` uninstalled.
|
|
604
|
+
*/
|
|
605
|
+
export const outsidePnpmWorkspace = (
|
|
606
|
+
root: string,
|
|
607
|
+
answers: InitAnswers
|
|
608
|
+
): boolean => {
|
|
609
|
+
if (answers.packageManager !== "pnpm") {
|
|
610
|
+
return false;
|
|
611
|
+
}
|
|
612
|
+
const workspace = pnpmWorkspaceRoot(root);
|
|
613
|
+
return workspace !== null && !listsPackage(workspace, root);
|
|
614
|
+
};
|
|
615
|
+
|
|
528
616
|
/**
|
|
529
617
|
* The Yarn project enclosing `root`: a directory holding a lockfile, a
|
|
530
618
|
* `.yarnrc.yml`, or a `package.json` that declares workspaces.
|
|
@@ -585,10 +673,13 @@ const packageManagerConfigFor = (
|
|
|
585
673
|
return [];
|
|
586
674
|
};
|
|
587
675
|
|
|
676
|
+
const ESBUILD_APPROVAL = " allowBuilds:\n esbuild: true";
|
|
677
|
+
|
|
588
678
|
/**
|
|
589
|
-
* What the project still needs from a workspace it
|
|
590
|
-
* that workspace's config alone:
|
|
591
|
-
* (pnpm
|
|
679
|
+
* What the project still needs from a workspace it sits in, when `init` left
|
|
680
|
+
* that workspace's config alone: a place in a pnpm workspace's `packages`
|
|
681
|
+
* (pnpm skips a folder it doesn't list), pnpm's approval for esbuild's build
|
|
682
|
+
* script (pnpm 10 and later fail the install without it), or Yarn Berry's
|
|
592
683
|
* `node_modules` linker. Undefined when the workspace already has it, or the
|
|
593
684
|
* project doesn't sit in one.
|
|
594
685
|
*/
|
|
@@ -599,11 +690,21 @@ export const workspaceNote = (
|
|
|
599
690
|
): string | undefined => {
|
|
600
691
|
if (answers.packageManager === "pnpm") {
|
|
601
692
|
const workspace = pnpmWorkspaceRoot(root);
|
|
602
|
-
|
|
603
|
-
|
|
693
|
+
if (!workspace) {
|
|
694
|
+
return;
|
|
695
|
+
}
|
|
696
|
+
const file = join(workspace, "pnpm-workspace.yaml");
|
|
697
|
+
const approved = readText(file).includes("esbuild");
|
|
698
|
+
if (!listsPackage(workspace, root)) {
|
|
699
|
+
const entry = ` packages:\n - ${relative(workspace, root)}`;
|
|
700
|
+
return approved
|
|
701
|
+
? `This folder sits inside the pnpm workspace at ${file}, which doesn't list it under packages, so pnpm won't install it. Add it there before installing:\n\n${entry}`
|
|
702
|
+
: `This folder sits inside the pnpm workspace at ${file}, which doesn't list it under packages, so pnpm won't install it. Add it there before installing, and approve esbuild's build script, or pnpm 10 and later stop the install:\n\n${entry}\n${ESBUILD_APPROVAL}`;
|
|
703
|
+
}
|
|
704
|
+
if (approved) {
|
|
604
705
|
return;
|
|
605
706
|
}
|
|
606
|
-
return `This project joins the pnpm workspace at ${file}. Approve esbuild's build script there before installing, or pnpm 10 and later stop the install:\n\n
|
|
707
|
+
return `This project joins the pnpm workspace at ${file}. Approve esbuild's build script there before installing, or pnpm 10 and later stop the install:\n\n${ESBUILD_APPROVAL}`;
|
|
607
708
|
}
|
|
608
709
|
if (answers.packageManager !== "yarn" || yarnMajor(env.userAgent) === 1) {
|
|
609
710
|
return;
|
|
@@ -622,6 +723,7 @@ export const buildPlan = (
|
|
|
622
723
|
answers: InitAnswers,
|
|
623
724
|
env: PlanEnvironment = {}
|
|
624
725
|
): ScaffoldFile[] => {
|
|
726
|
+
const starter: Starter = STARTERS[answers.template];
|
|
625
727
|
const files: ScaffoldFile[] = [
|
|
626
728
|
{
|
|
627
729
|
content: blumePackageJson(
|
|
@@ -632,11 +734,15 @@ export const buildPlan = (
|
|
|
632
734
|
},
|
|
633
735
|
...packageManagerConfigFor(root, answers, env),
|
|
634
736
|
{ content: buildConfig(answers), path: join(root, "blume.config.ts") },
|
|
737
|
+
...(starter.projectFiles ?? []).map((file) => ({
|
|
738
|
+
...file,
|
|
739
|
+
path: join(root, file.path),
|
|
740
|
+
})),
|
|
635
741
|
];
|
|
636
742
|
// Seed pages only make sense when a local filesystem source will read them.
|
|
637
743
|
if (answers.sources.length === 0 || answers.sources.includes("filesystem")) {
|
|
638
744
|
files.push(
|
|
639
|
-
...
|
|
745
|
+
...starter
|
|
640
746
|
.files(answers.contentDir)
|
|
641
747
|
.map((file) => ({ ...file, path: join(root, file.path) }))
|
|
642
748
|
);
|
|
@@ -771,7 +877,7 @@ export const nextSteps = (
|
|
|
771
877
|
const commands = commandsFor(answers.packageManager);
|
|
772
878
|
const lines: string[] = [];
|
|
773
879
|
if (answers.directory !== ".") {
|
|
774
|
-
lines.push(
|
|
880
|
+
lines.push(cdCommand(answers.directory));
|
|
775
881
|
}
|
|
776
882
|
if (needsInstall) {
|
|
777
883
|
lines.push(commands.install);
|
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The OpenAPI document the `api` starter writes beside `blume.config.ts`, so a
|
|
3
|
+
* new project's first build reads a local file instead of depending on a
|
|
4
|
+
* third-party server. Small, but it exercises what a real reference renders:
|
|
5
|
+
* path and query parameters, request bodies, shared schemas, error responses,
|
|
6
|
+
* and bearer auth. Each operation's description is sized so its page's meta
|
|
7
|
+
* description, with the endpoint sentence Blume appends, fits the range
|
|
8
|
+
* `blume audit` checks.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
const petId = {
|
|
12
|
+
description: "The pet's ID.",
|
|
13
|
+
in: "path",
|
|
14
|
+
name: "petId",
|
|
15
|
+
required: true,
|
|
16
|
+
schema: { type: "string" },
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
const errorResponse = (description: string) => ({
|
|
20
|
+
content: {
|
|
21
|
+
"application/json": { schema: { $ref: "#/components/schemas/Error" } },
|
|
22
|
+
},
|
|
23
|
+
description,
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
const petResponse = (description: string) => ({
|
|
27
|
+
content: {
|
|
28
|
+
"application/json": { schema: { $ref: "#/components/schemas/Pet" } },
|
|
29
|
+
},
|
|
30
|
+
description,
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
// Built from entries rather than a literal so the written file keeps the
|
|
34
|
+
// conventional section order (`openapi`, `info`, …) instead of the sorted one.
|
|
35
|
+
const STARTER_SPEC = Object.fromEntries([
|
|
36
|
+
["openapi", "3.1.0"],
|
|
37
|
+
[
|
|
38
|
+
"info",
|
|
39
|
+
{
|
|
40
|
+
description:
|
|
41
|
+
"A small example API for a pet store: list, create, read, update, and delete pets. Replace openapi.json with your own spec to document your API.",
|
|
42
|
+
title: "Pet Store API",
|
|
43
|
+
version: "1.0.0",
|
|
44
|
+
},
|
|
45
|
+
],
|
|
46
|
+
["servers", [{ url: "https://api.example.com/v1" }]],
|
|
47
|
+
["security", [{ bearerAuth: [] }]],
|
|
48
|
+
[
|
|
49
|
+
"tags",
|
|
50
|
+
[
|
|
51
|
+
{
|
|
52
|
+
description:
|
|
53
|
+
"Every pet in the store, with its name, species, and status.",
|
|
54
|
+
name: "Pets",
|
|
55
|
+
},
|
|
56
|
+
],
|
|
57
|
+
],
|
|
58
|
+
[
|
|
59
|
+
"paths",
|
|
60
|
+
{
|
|
61
|
+
"/pets": {
|
|
62
|
+
get: {
|
|
63
|
+
description:
|
|
64
|
+
"Returns the pets in the store, newest first, filtered by status and paged with a cursor.",
|
|
65
|
+
operationId: "listPets",
|
|
66
|
+
parameters: [
|
|
67
|
+
{
|
|
68
|
+
description: "Only return pets with this status.",
|
|
69
|
+
in: "query",
|
|
70
|
+
name: "status",
|
|
71
|
+
schema: { $ref: "#/components/schemas/Status" },
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
description: "The most pets to return.",
|
|
75
|
+
in: "query",
|
|
76
|
+
name: "limit",
|
|
77
|
+
schema: {
|
|
78
|
+
default: 20,
|
|
79
|
+
maximum: 100,
|
|
80
|
+
minimum: 1,
|
|
81
|
+
type: "integer",
|
|
82
|
+
},
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
description: "The `nextCursor` from the previous page.",
|
|
86
|
+
in: "query",
|
|
87
|
+
name: "cursor",
|
|
88
|
+
schema: { type: "string" },
|
|
89
|
+
},
|
|
90
|
+
],
|
|
91
|
+
responses: {
|
|
92
|
+
"200": {
|
|
93
|
+
content: {
|
|
94
|
+
"application/json": {
|
|
95
|
+
schema: { $ref: "#/components/schemas/PetList" },
|
|
96
|
+
},
|
|
97
|
+
},
|
|
98
|
+
description: "A page of pets.",
|
|
99
|
+
},
|
|
100
|
+
},
|
|
101
|
+
summary: "List pets",
|
|
102
|
+
tags: ["Pets"],
|
|
103
|
+
},
|
|
104
|
+
post: {
|
|
105
|
+
description:
|
|
106
|
+
"Adds a pet to the store and returns it with its new ID and an available status.",
|
|
107
|
+
operationId: "createPet",
|
|
108
|
+
requestBody: {
|
|
109
|
+
content: {
|
|
110
|
+
"application/json": {
|
|
111
|
+
schema: { $ref: "#/components/schemas/NewPet" },
|
|
112
|
+
},
|
|
113
|
+
},
|
|
114
|
+
required: true,
|
|
115
|
+
},
|
|
116
|
+
responses: {
|
|
117
|
+
"201": petResponse("The new pet."),
|
|
118
|
+
"422": errorResponse("The pet's fields are invalid."),
|
|
119
|
+
},
|
|
120
|
+
summary: "Create a pet",
|
|
121
|
+
tags: ["Pets"],
|
|
122
|
+
},
|
|
123
|
+
},
|
|
124
|
+
"/pets/{petId}": {
|
|
125
|
+
delete: {
|
|
126
|
+
description:
|
|
127
|
+
"Removes a pet from the store for good, or returns a 404 error when no pet has that ID.",
|
|
128
|
+
operationId: "deletePet",
|
|
129
|
+
parameters: [petId],
|
|
130
|
+
responses: {
|
|
131
|
+
"204": { description: "The pet was deleted." },
|
|
132
|
+
"404": errorResponse("No pet has that ID."),
|
|
133
|
+
},
|
|
134
|
+
summary: "Delete a pet",
|
|
135
|
+
tags: ["Pets"],
|
|
136
|
+
},
|
|
137
|
+
get: {
|
|
138
|
+
description:
|
|
139
|
+
"Returns a single pet by its ID, or a 404 error when no pet has that ID.",
|
|
140
|
+
operationId: "getPet",
|
|
141
|
+
parameters: [petId],
|
|
142
|
+
responses: {
|
|
143
|
+
"200": petResponse("The pet."),
|
|
144
|
+
"404": errorResponse("No pet has that ID."),
|
|
145
|
+
},
|
|
146
|
+
summary: "Get a pet",
|
|
147
|
+
tags: ["Pets"],
|
|
148
|
+
},
|
|
149
|
+
patch: {
|
|
150
|
+
description:
|
|
151
|
+
"Changes the fields you send on an existing pet and leaves the rest as they were.",
|
|
152
|
+
operationId: "updatePet",
|
|
153
|
+
parameters: [petId],
|
|
154
|
+
requestBody: {
|
|
155
|
+
content: {
|
|
156
|
+
"application/json": {
|
|
157
|
+
schema: { $ref: "#/components/schemas/PetUpdate" },
|
|
158
|
+
},
|
|
159
|
+
},
|
|
160
|
+
required: true,
|
|
161
|
+
},
|
|
162
|
+
responses: {
|
|
163
|
+
"200": petResponse("The updated pet."),
|
|
164
|
+
"404": errorResponse("No pet has that ID."),
|
|
165
|
+
},
|
|
166
|
+
summary: "Update a pet",
|
|
167
|
+
tags: ["Pets"],
|
|
168
|
+
},
|
|
169
|
+
},
|
|
170
|
+
},
|
|
171
|
+
],
|
|
172
|
+
[
|
|
173
|
+
"components",
|
|
174
|
+
{
|
|
175
|
+
schemas: {
|
|
176
|
+
Error: {
|
|
177
|
+
properties: {
|
|
178
|
+
code: { example: "not_found", type: "string" },
|
|
179
|
+
message: { example: "No pet has that ID.", type: "string" },
|
|
180
|
+
},
|
|
181
|
+
required: ["code", "message"],
|
|
182
|
+
type: "object",
|
|
183
|
+
},
|
|
184
|
+
NewPet: {
|
|
185
|
+
properties: {
|
|
186
|
+
name: { example: "Mochi", type: "string" },
|
|
187
|
+
species: { $ref: "#/components/schemas/Species" },
|
|
188
|
+
},
|
|
189
|
+
required: ["name", "species"],
|
|
190
|
+
type: "object",
|
|
191
|
+
},
|
|
192
|
+
Pet: {
|
|
193
|
+
properties: {
|
|
194
|
+
createdAt: { format: "date-time", type: "string" },
|
|
195
|
+
id: { example: "pet_01h2x", type: "string" },
|
|
196
|
+
name: { example: "Mochi", type: "string" },
|
|
197
|
+
species: { $ref: "#/components/schemas/Species" },
|
|
198
|
+
status: { $ref: "#/components/schemas/Status" },
|
|
199
|
+
},
|
|
200
|
+
required: ["id", "name", "species", "status", "createdAt"],
|
|
201
|
+
type: "object",
|
|
202
|
+
},
|
|
203
|
+
PetList: {
|
|
204
|
+
properties: {
|
|
205
|
+
data: {
|
|
206
|
+
items: { $ref: "#/components/schemas/Pet" },
|
|
207
|
+
type: "array",
|
|
208
|
+
},
|
|
209
|
+
nextCursor: {
|
|
210
|
+
description: "Pass as `cursor` to fetch the next page.",
|
|
211
|
+
type: ["string", "null"],
|
|
212
|
+
},
|
|
213
|
+
},
|
|
214
|
+
required: ["data", "nextCursor"],
|
|
215
|
+
type: "object",
|
|
216
|
+
},
|
|
217
|
+
PetUpdate: {
|
|
218
|
+
properties: {
|
|
219
|
+
name: { type: "string" },
|
|
220
|
+
status: { $ref: "#/components/schemas/Status" },
|
|
221
|
+
},
|
|
222
|
+
type: "object",
|
|
223
|
+
},
|
|
224
|
+
Species: { enum: ["cat", "dog", "bird", "rabbit"], type: "string" },
|
|
225
|
+
Status: { enum: ["available", "pending", "adopted"], type: "string" },
|
|
226
|
+
},
|
|
227
|
+
securitySchemes: {
|
|
228
|
+
bearerAuth: { scheme: "bearer", type: "http" },
|
|
229
|
+
},
|
|
230
|
+
},
|
|
231
|
+
],
|
|
232
|
+
]);
|
|
233
|
+
|
|
234
|
+
/** The starter spec as the `openapi.json` text `init` writes. */
|
|
235
|
+
export const STARTER_OPENAPI_JSON = `${JSON.stringify(STARTER_SPEC, null, 2)}\n`;
|
|
@@ -24,12 +24,12 @@ export const checkRequiredSecrets = (config: ResolvedConfig): Diagnostic[] => {
|
|
|
24
24
|
});
|
|
25
25
|
};
|
|
26
26
|
|
|
27
|
-
if (config.ai.
|
|
27
|
+
if (config.ai.assistant?.enabled && !config.ai.assistant.endpoint) {
|
|
28
28
|
// The adapter descriptor names the env vars its route reads.
|
|
29
|
-
const { provider } = config.ai.
|
|
29
|
+
const { provider } = config.ai.assistant;
|
|
30
30
|
const backend = resolveAskBackend(provider);
|
|
31
31
|
for (const env of provider.requiredSecrets) {
|
|
32
|
-
requireSecret(`
|
|
32
|
+
requireSecret(`Assistant (${backend.label})`, env, backend.secretNote);
|
|
33
33
|
}
|
|
34
34
|
}
|
|
35
35
|
|
|
@@ -97,29 +97,33 @@ const accordionId = id ?? componentSlug(title);
|
|
|
97
97
|
});
|
|
98
98
|
};
|
|
99
99
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
100
|
+
// Only the reader opening an item points the hash at it, so this keys on
|
|
101
|
+
// the summary's click (pointer, Enter, or Space) rather than `toggle`: a
|
|
102
|
+
// `defaultOpen` item a client-router swap inserts fires `toggle` too, and
|
|
103
|
+
// that must not overwrite the hash the reader arrived with.
|
|
104
|
+
document.addEventListener("click", (event) => {
|
|
105
|
+
const summary =
|
|
106
|
+
event.target instanceof Element ? event.target.closest("summary") : null;
|
|
107
|
+
const accordion = summary?.parentElement;
|
|
108
|
+
if (
|
|
109
|
+
event.defaultPrevented ||
|
|
110
|
+
!(accordion instanceof HTMLDetailsElement) ||
|
|
111
|
+
!accordion.matches("[data-blume-accordion]") ||
|
|
112
|
+
// Open now means this click closes it.
|
|
113
|
+
accordion.open ||
|
|
114
|
+
!accordion.id
|
|
115
|
+
) {
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
112
118
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
true
|
|
122
|
-
);
|
|
119
|
+
// Keep the entry's state: the client router ignores a popstate whose
|
|
120
|
+
// state is null, so Back to this page would change only the URL.
|
|
121
|
+
history.replaceState(
|
|
122
|
+
history.state,
|
|
123
|
+
"",
|
|
124
|
+
`#${encodeURIComponent(accordion.id)}`
|
|
125
|
+
);
|
|
126
|
+
});
|
|
123
127
|
|
|
124
128
|
const init = () => {
|
|
125
129
|
dedupeAccordionIds();
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
import { STROKE, TINT } from "../colors.ts";
|
|
3
3
|
import Icon from "../Icon.astro";
|
|
4
|
+
import { badgeColorName } from "./badge-color.ts";
|
|
4
5
|
|
|
5
6
|
type BadgeVariant = "default" | "accent" | "success" | "warning" | "danger";
|
|
6
7
|
type BadgeSize = "xs" | "sm" | "md" | "lg";
|
|
@@ -34,15 +35,7 @@ const {
|
|
|
34
35
|
|
|
35
36
|
const activeStroke = stroke === true || stroke === "true";
|
|
36
37
|
const isDisabled = disabled === true || disabled === "true";
|
|
37
|
-
const colorName =
|
|
38
|
-
color ??
|
|
39
|
-
{
|
|
40
|
-
accent: "blue",
|
|
41
|
-
danger: "red",
|
|
42
|
-
default: "gray",
|
|
43
|
-
success: "green",
|
|
44
|
-
warning: "orange",
|
|
45
|
-
}[variant];
|
|
38
|
+
const colorName = badgeColorName(variant, color);
|
|
46
39
|
const customColor = colorName.startsWith("#") ? colorName : null;
|
|
47
40
|
|
|
48
41
|
// The hue rows come from the shared table (see colors.ts for the contrast
|
|
@@ -80,7 +80,7 @@ const variantClass = {
|
|
|
80
80
|
<p class="mt-0! mb-1.5! flex items-center gap-1.5 font-medium text-foreground">
|
|
81
81
|
{title}
|
|
82
82
|
{showArrow && (
|
|
83
|
-
<Icon class="text-muted-foreground" name="arrow-right" size={14} />
|
|
83
|
+
<Icon class="text-muted-foreground rtl:-scale-x-100" name="arrow-right" size={14} />
|
|
84
84
|
)}
|
|
85
85
|
</p>
|
|
86
86
|
)
|
|
@@ -92,7 +92,7 @@ const variantClass = {
|
|
|
92
92
|
cta && (
|
|
93
93
|
<p class="mt-4! mb-0! flex items-center gap-1.5 font-medium text-accent text-sm">
|
|
94
94
|
{cta}
|
|
95
|
-
{showArrow && <Icon name="arrow-right" size={14} />}
|
|
95
|
+
{showArrow && <Icon class="rtl:-scale-x-100" name="arrow-right" size={14} />}
|
|
96
96
|
</p>
|
|
97
97
|
)
|
|
98
98
|
}
|
|
@@ -14,6 +14,7 @@ import { CODE_PADDING_BLOCK_REM } from "../../theme/code-block-padding.ts";
|
|
|
14
14
|
|
|
15
15
|
import { highlightCode } from "../../markdown/index.ts";
|
|
16
16
|
import { withBase } from "../islands/base-path.ts";
|
|
17
|
+
import { contentStrings } from "./content-strings.ts";
|
|
17
18
|
import { EXAMPLE_PANE_MIN_PX } from "./example-pane.ts";
|
|
18
19
|
import Tab from "./Tab.astro";
|
|
19
20
|
import Tabs from "./Tabs.astro";
|
|
@@ -26,6 +27,7 @@ interface Props {
|
|
|
26
27
|
|
|
27
28
|
const { path } = Astro.props;
|
|
28
29
|
const entry = examples[path];
|
|
30
|
+
const { content: strings } = contentStrings(data, Astro.currentLocale);
|
|
29
31
|
|
|
30
32
|
// The live preview renders in its own generated route, embedded as an iframe:
|
|
31
33
|
// the frame boundary is what keeps the docs CSS (prose typography, component
|
|
@@ -103,17 +105,21 @@ const paneClass =
|
|
|
103
105
|
<Tab
|
|
104
106
|
class={`overflow-hidden p-0! ${paneClass}`}
|
|
105
107
|
style={paneStyle}
|
|
106
|
-
title=
|
|
108
|
+
title={strings.preview}
|
|
107
109
|
>
|
|
108
110
|
<iframe
|
|
109
111
|
class="h-full w-full"
|
|
110
112
|
data-blume-example-frame
|
|
111
113
|
loading="lazy"
|
|
112
114
|
src={previewSrc}
|
|
113
|
-
title={
|
|
115
|
+
title={`${strings.preview}: ${path}`}
|
|
114
116
|
/>
|
|
115
117
|
</Tab>
|
|
116
|
-
<Tab
|
|
118
|
+
<Tab
|
|
119
|
+
class={`overflow-hidden ${paneClass}`}
|
|
120
|
+
style={paneStyle}
|
|
121
|
+
title={strings.code}
|
|
122
|
+
>
|
|
117
123
|
<Fragment set:html={codeHtml} />
|
|
118
124
|
</Tab>
|
|
119
125
|
</Tabs>
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
---
|
|
2
|
+
import data from "blume:data";
|
|
3
|
+
|
|
2
4
|
import AccordionItem from "./AccordionItem.astro";
|
|
5
|
+
import { contentStrings } from "./content-strings.ts";
|
|
3
6
|
|
|
4
|
-
const {
|
|
7
|
+
const { content: strings } = contentStrings(data, Astro.currentLocale);
|
|
8
|
+
const { defaultOpen = false, title = strings.showMore } = Astro.props;
|
|
5
9
|
---
|
|
6
10
|
|
|
7
11
|
<div class="not-prose my-4 overflow-hidden rounded-blume border border-border">
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
import { escapeRawHtml, unwrapParagraph } from "./inline-markdown.ts";
|
|
2
|
+
import { renderInlineMarkdown } from "./inline-markdown.ts";
|
|
5
3
|
|
|
6
4
|
interface Props {
|
|
7
5
|
caption?: string;
|
|
@@ -10,10 +8,7 @@ interface Props {
|
|
|
10
8
|
|
|
11
9
|
const { caption, hint } = Astro.props;
|
|
12
10
|
|
|
13
|
-
const
|
|
14
|
-
const captionHtml = caption
|
|
15
|
-
? unwrapParagraph((await markdownProcessor.render(escapeRawHtml(caption))).code)
|
|
16
|
-
: undefined;
|
|
11
|
+
const captionHtml = caption ? await renderInlineMarkdown(caption) : undefined;
|
|
17
12
|
---
|
|
18
13
|
|
|
19
14
|
<blume-frame class="not-prose my-6 block">
|