blume 1.7.2 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +19 -0
- package/CHANGELOG.md +227 -0
- package/README.md +34 -21
- package/dist/cli/chunk-11j0384y.js +148 -0
- package/dist/cli/chunk-11j0384y.js.map +10 -0
- package/dist/cli/{chunk-xhtpx3ff.js → chunk-1w8dp3qb.js} +17 -16
- package/dist/cli/{chunk-xhtpx3ff.js.map → chunk-1w8dp3qb.js.map} +3 -3
- package/dist/cli/chunk-2q1dwty4.js +75 -0
- package/dist/cli/chunk-2q1dwty4.js.map +11 -0
- package/dist/cli/chunk-41za066z.js +122 -0
- package/dist/cli/chunk-41za066z.js.map +11 -0
- package/dist/cli/chunk-5a2z0198.js +133 -0
- package/dist/cli/chunk-5a2z0198.js.map +10 -0
- package/dist/cli/{chunk-9he6crym.js → chunk-6k8vp3ta.js} +25 -13
- package/dist/cli/{chunk-9he6crym.js.map → chunk-6k8vp3ta.js.map} +4 -4
- package/dist/cli/{chunk-mt76t7dj.js → chunk-79njf86q.js} +133 -54
- package/dist/cli/chunk-79njf86q.js.map +11 -0
- package/dist/cli/{chunk-3w7b2vcx.js → chunk-7ez8ny0t.js} +2 -2
- package/dist/cli/{chunk-688e0dde.js → chunk-88cpgt6h.js} +1 -1
- package/dist/cli/chunk-a9kptbw5.js +361 -0
- package/dist/cli/chunk-a9kptbw5.js.map +14 -0
- package/dist/cli/chunk-abh8yjkn.js +31 -0
- package/dist/cli/chunk-abh8yjkn.js.map +10 -0
- package/dist/cli/chunk-b5aj94ah.js +91 -0
- package/dist/cli/chunk-b5aj94ah.js.map +10 -0
- package/dist/cli/{chunk-hs3gbh8p.js → chunk-bctazmbk.js} +9 -5
- package/dist/cli/chunk-bctazmbk.js.map +10 -0
- package/dist/cli/chunk-beat36xx.js +279 -0
- package/dist/cli/chunk-beat36xx.js.map +10 -0
- package/dist/cli/chunk-bnbmcwfb.js +145 -0
- package/dist/cli/chunk-bnbmcwfb.js.map +11 -0
- package/dist/cli/{chunk-9bkjd11x.js → chunk-bw22s759.js} +15 -5
- package/dist/cli/{chunk-9bkjd11x.js.map → chunk-bw22s759.js.map} +4 -4
- package/dist/cli/chunk-by2290sx.js +39 -0
- package/dist/cli/chunk-by2290sx.js.map +10 -0
- package/dist/cli/chunk-d1tadaw7.js +79 -0
- package/dist/cli/chunk-d1tadaw7.js.map +10 -0
- package/dist/cli/{chunk-t3tj0dgr.js → chunk-d80hr03s.js} +24 -19
- package/dist/cli/chunk-d80hr03s.js.map +15 -0
- package/dist/cli/chunk-ernrthtr.js +97 -0
- package/dist/cli/chunk-ernrthtr.js.map +10 -0
- package/dist/cli/chunk-f2972sbt.js +374 -0
- package/dist/cli/chunk-f2972sbt.js.map +10 -0
- package/dist/cli/{chunk-exeeb35e.js → chunk-f7t03s3g.js} +2 -2
- package/dist/cli/{chunk-2z47ypj8.js → chunk-fa25z98p.js} +16 -3
- package/dist/cli/chunk-fa25z98p.js.map +11 -0
- package/dist/cli/{chunk-12dxjqk7.js → chunk-fh5hj5jt.js} +44 -21
- package/dist/cli/chunk-fh5hj5jt.js.map +10 -0
- package/dist/cli/{chunk-8cd8tj54.js → chunk-j8mw0za6.js} +86 -57
- package/dist/cli/chunk-j8mw0za6.js.map +35 -0
- package/dist/cli/chunk-jts8mvcz.js +106 -0
- package/dist/cli/{chunk-2mzebbbz.js.map → chunk-jts8mvcz.js.map} +6 -4
- package/dist/cli/{chunk-ejjx8znq.js → chunk-mnqj32sj.js} +505 -536
- package/dist/cli/chunk-mnqj32sj.js.map +12 -0
- package/dist/cli/{chunk-196vjxp9.js → chunk-mwt1k8n7.js} +100 -372
- package/dist/cli/chunk-mwt1k8n7.js.map +10 -0
- package/dist/cli/chunk-nk3ts2xk.js +51 -0
- package/dist/cli/chunk-nk3ts2xk.js.map +10 -0
- package/dist/cli/{chunk-n9sra6sy.js → chunk-pat2zzwc.js} +10 -14
- package/dist/cli/{chunk-n9sra6sy.js.map → chunk-pat2zzwc.js.map} +2 -2
- package/dist/cli/chunk-pnnvybbk.js +176 -0
- package/dist/cli/chunk-pnnvybbk.js.map +11 -0
- package/dist/cli/{chunk-cvky9gb2.js → chunk-sqn5t4q0.js} +81 -87
- package/dist/cli/chunk-sqn5t4q0.js.map +10 -0
- package/dist/cli/{chunk-eevwt1sc.js → chunk-tzne8qfq.js} +15 -15
- package/dist/cli/{chunk-eevwt1sc.js.map → chunk-tzne8qfq.js.map} +1 -1
- package/dist/cli/chunk-xaz13gwg.js +12449 -0
- package/dist/cli/chunk-xaz13gwg.js.map +182 -0
- package/dist/cli/chunk-y3e45rc8.js +102 -0
- package/dist/cli/chunk-y3e45rc8.js.map +10 -0
- package/dist/cli/chunk-z01ze5c1.js +261 -0
- package/dist/cli/chunk-z01ze5c1.js.map +10 -0
- package/dist/cli/{chunk-5n7t497w.js → chunk-z1f5arsg.js} +247 -755
- package/dist/cli/chunk-z1f5arsg.js.map +36 -0
- package/dist/cli/{chunk-hdm2dkd2.js → chunk-zg2gtj10.js} +1086 -2596
- package/dist/cli/chunk-zg2gtj10.js.map +35 -0
- package/dist/cli/{chunk-ppfvdcd4.js → chunk-zxccj738.js} +1 -1
- package/dist/cli/index.js +214 -57
- package/dist/cli/index.js.map +8 -7
- package/dist/types/ai/agent-readability.d.ts +52 -0
- package/dist/types/ai/ai-catalog.d.ts +42 -0
- package/dist/types/ai/api/paths.d.ts +17 -0
- package/dist/types/ai/api-catalog.d.ts +18 -0
- package/dist/types/ai/ask.d.ts +368 -0
- package/dist/types/ai/changelog-markdown.d.ts +2 -0
- package/dist/types/ai/component-markdown.d.ts +2 -2
- package/dist/types/ai/index.d.ts +24 -0
- package/dist/types/ai/link-headers.d.ts +24 -0
- package/dist/types/ai/llms.d.ts +25 -0
- package/dist/types/ai/markdown.d.ts +45 -0
- package/dist/types/ai/mcp/discovery.d.ts +68 -0
- package/dist/types/ai/mcp/tools.d.ts +16 -0
- package/dist/types/ai/openapi-components.d.ts +43 -0
- package/dist/types/ai/relative-links.d.ts +26 -0
- package/dist/types/ai/serializers.d.ts +15 -0
- package/dist/types/ai/skills.d.ts +42 -0
- package/dist/types/ai/tar.d.ts +25 -0
- package/dist/types/ai/visibility.d.ts +17 -0
- package/dist/types/ai/web-bot-auth.d.ts +16 -0
- package/dist/types/analytics/adobe.d.ts +35 -0
- package/dist/types/analytics/amplitude.d.ts +50 -0
- package/dist/types/analytics/clarity.d.ts +31 -0
- package/dist/types/analytics/clearbit.d.ts +29 -0
- package/dist/types/analytics/cloudflare.d.ts +41 -0
- package/dist/types/analytics/fathom.d.ts +41 -0
- package/dist/types/analytics/google-analytics.d.ts +44 -0
- package/dist/types/analytics/google-tag-manager.d.ts +40 -0
- package/dist/types/analytics/head.d.ts +30 -0
- package/dist/types/analytics/heap.d.ts +40 -0
- package/dist/types/analytics/hightouch.d.ts +44 -0
- package/dist/types/analytics/hotjar.d.ts +33 -0
- package/dist/types/analytics/index.d.ts +61 -0
- package/dist/types/analytics/inline.d.ts +17 -0
- package/dist/types/analytics/logrocket.d.ts +44 -0
- package/dist/types/analytics/mixpanel.d.ts +67 -0
- package/dist/types/analytics/pirsch.d.ts +42 -0
- package/dist/types/analytics/plausible.d.ts +56 -0
- package/dist/types/analytics/posthog.d.ts +45 -0
- package/dist/types/analytics/schema.d.ts +320 -0
- package/dist/types/analytics/script.d.ts +46 -0
- package/dist/types/analytics/segment.d.ts +50 -0
- package/dist/types/analytics/vercel.d.ts +48 -0
- package/dist/types/astro/integration.d.ts +76 -0
- package/dist/types/astro/markdown-negotiation.d.ts +23 -0
- package/dist/types/astro/module-types.d.ts +14 -0
- package/dist/types/astro/pages.d.ts +44 -0
- package/dist/types/cli/env.d.ts +12 -0
- package/dist/types/cli/init/scaffold.d.ts +154 -0
- package/dist/types/components/layout/nav-utils.d.ts +11 -0
- package/dist/types/core/adapter.d.ts +47 -0
- package/dist/types/core/api-name.d.ts +7 -0
- package/dist/types/core/changelog-index.d.ts +13 -0
- package/dist/types/core/config-input.d.ts +209 -505
- package/dist/types/core/config.d.ts +60 -34
- package/dist/types/core/content-assets.d.ts +76 -0
- package/dist/types/core/custom-pages.d.ts +33 -0
- package/dist/types/core/data.d.ts +28 -11
- package/dist/types/core/define-components.d.ts +12 -9
- package/dist/types/core/deployment-env.d.ts +6 -11
- package/dist/types/core/frontmatter.d.ts +10 -0
- package/dist/types/core/graph.d.ts +18 -0
- package/dist/types/core/heading-markers.d.ts +54 -0
- package/dist/types/core/i18n-ui.d.ts +6 -2
- package/dist/types/core/i18n.d.ts +87 -0
- package/dist/types/core/includes.d.ts +138 -0
- package/dist/types/core/last-modified.d.ts +47 -0
- package/dist/types/core/links.d.ts +95 -0
- package/dist/types/core/locale-links.d.ts +60 -0
- package/dist/types/core/manifest.d.ts +17 -0
- package/dist/types/core/meta.d.ts +38 -0
- package/dist/types/core/nav-diagnostics.d.ts +26 -0
- package/dist/types/core/navigation.d.ts +6 -0
- package/dist/types/core/node-require.d.ts +19 -0
- package/dist/types/core/package-json.d.ts +13 -0
- package/dist/types/core/probe.d.ts +42 -0
- package/dist/types/core/project-graph.d.ts +51 -0
- package/dist/types/core/project.d.ts +2 -0
- package/dist/types/core/safe-href.d.ts +2 -0
- package/dist/types/core/safe-links.d.ts +26 -0
- package/dist/types/core/schema.d.ts +2291 -441
- package/dist/types/core/site-url.d.ts +16 -0
- package/dist/types/core/sources/assets.d.ts +36 -0
- package/dist/types/core/sources/cache.d.ts +37 -0
- package/dist/types/core/sources/collection.d.ts +28 -0
- package/dist/types/core/sources/contentful-rich-text.d.ts +31 -0
- package/dist/types/core/sources/contentful.d.ts +40 -0
- package/dist/types/core/sources/filesystem.d.ts +24 -0
- package/dist/types/core/sources/github-releases.d.ts +31 -0
- package/dist/types/core/sources/json.d.ts +30 -0
- package/dist/types/core/sources/lexical.d.ts +19 -0
- package/dist/types/core/sources/lower.d.ts +75 -0
- package/dist/types/core/sources/mdx-remote.d.ts +28 -0
- package/dist/types/core/sources/normalize.d.ts +147 -0
- package/dist/types/core/sources/notion.d.ts +131 -0
- package/dist/types/core/sources/obsidian.d.ts +46 -0
- package/dist/types/core/sources/payload.d.ts +39 -0
- package/dist/types/core/sources/portable-text.d.ts +42 -0
- package/dist/types/core/sources/read.d.ts +23 -0
- package/dist/types/core/sources/remote.d.ts +74 -0
- package/dist/types/core/sources/resolve.d.ts +19 -0
- package/dist/types/core/sources/sanity.d.ts +43 -0
- package/dist/types/core/sources/strapi-blocks.d.ts +12 -0
- package/dist/types/core/sources/strapi.d.ts +33 -0
- package/dist/types/core/sources/types.d.ts +7 -0
- package/dist/types/core/sources/watch.d.ts +45 -0
- package/dist/types/core/text-width.d.ts +11 -0
- package/dist/types/core/types.d.ts +20 -1
- package/dist/types/core/unrecognized-keys.d.ts +7 -0
- package/dist/types/core/versions.d.ts +72 -0
- package/dist/types/core/yaml.d.ts +9 -0
- package/dist/types/deploy/adapter-output.d.ts +45 -0
- package/dist/types/deploy/adapters/cloudflare.d.ts +40 -0
- package/dist/types/deploy/adapters/index.d.ts +29 -0
- package/dist/types/deploy/adapters/netlify.d.ts +37 -0
- package/dist/types/deploy/adapters/node.d.ts +37 -0
- package/dist/types/deploy/adapters/registry.d.ts +133 -0
- package/dist/types/deploy/adapters/types.d.ts +71 -0
- package/dist/types/deploy/adapters/vercel.d.ts +38 -0
- package/dist/types/deploy/artifacts.d.ts +65 -0
- package/dist/types/deploy/cloudflare-negotiation.d.ts +196 -0
- package/dist/types/deploy/function-bundle.d.ts +80 -0
- package/dist/types/deploy/headers.d.ts +50 -0
- package/dist/types/deploy/node-headers.d.ts +42 -0
- package/dist/types/deploy/platforms/cloudflare.d.ts +40 -0
- package/dist/types/deploy/platforms/index.d.ts +18 -0
- package/dist/types/deploy/platforms/netlify.d.ts +13 -0
- package/dist/types/deploy/platforms/node.d.ts +11 -0
- package/dist/types/deploy/platforms/paths.d.ts +27 -0
- package/dist/types/deploy/platforms/static.d.ts +10 -0
- package/dist/types/deploy/platforms/types.d.ts +104 -0
- package/dist/types/deploy/platforms/vercel.d.ts +32 -0
- package/dist/types/deploy/redirects.d.ts +53 -0
- package/dist/types/deploy/robots.d.ts +8 -0
- package/dist/types/deploy/rss.d.ts +31 -0
- package/dist/types/deploy/sitemap.d.ts +21 -0
- package/dist/types/deploy/vercel-negotiation.d.ts +109 -0
- package/dist/types/markdown/code-title.d.ts +32 -0
- package/dist/types/markdown/fence-meta.d.ts +23 -0
- package/dist/types/markdown/themes.d.ts +3 -3
- package/dist/types/openapi/asyncapi.d.ts +129 -0
- package/dist/types/openapi/graphql-build.d.ts +8 -0
- package/dist/types/openapi/graphql.d.ts +122 -0
- package/dist/types/openapi/model.d.ts +158 -0
- package/dist/types/openapi/parse.d.ts +57 -0
- package/dist/types/openapi/references.d.ts +37 -25
- package/dist/types/openapi/render-mdx.d.ts +33 -0
- package/dist/types/openapi/sentence.d.ts +7 -0
- package/dist/types/openapi/signature.d.ts +10 -0
- package/dist/types/openapi/source.d.ts +22 -0
- package/dist/types/openapi/spec-dependency-error.d.ts +10 -0
- package/dist/types/reference/asyncapi.d.ts +166 -0
- package/dist/types/reference/graphql.d.ts +181 -0
- package/dist/types/reference/index.d.ts +32 -0
- package/dist/types/reference/openapi.d.ts +165 -0
- package/dist/types/reference/options.d.ts +157 -0
- package/dist/types/reference/scalar.d.ts +136 -0
- package/dist/types/reference/schema.d.ts +630 -0
- package/dist/types/search/adapters/algolia.d.ts +32 -0
- package/dist/types/search/adapters/flexsearch.d.ts +12 -0
- package/dist/types/search/adapters/index.d.ts +31 -0
- package/dist/types/search/adapters/mixedbread.d.ts +22 -0
- package/dist/types/search/adapters/orama-cloud.d.ts +33 -0
- package/dist/types/search/adapters/orama.d.ts +13 -0
- package/dist/types/search/adapters/pagefind.d.ts +12 -0
- package/dist/types/search/adapters/registry.d.ts +228 -0
- package/dist/types/search/adapters/types.d.ts +34 -0
- package/dist/types/search/adapters/typesense.d.ts +42 -0
- package/dist/types/search/build.d.ts +23 -0
- package/dist/types/search/documents.d.ts +90 -0
- package/dist/types/search/facets.d.ts +3 -0
- package/dist/types/search/sync/algolia.d.ts +14 -0
- package/dist/types/search/sync/index.d.ts +14 -0
- package/dist/types/search/sync/orama-cloud.d.ts +10 -0
- package/dist/types/search/sync/typesense.d.ts +14 -0
- package/dist/types/sources/contentful.d.ts +68 -0
- package/dist/types/sources/custom.d.ts +20 -0
- package/dist/types/sources/filesystem.d.ts +42 -0
- package/dist/types/sources/github-releases.d.ts +46 -0
- package/dist/types/sources/index.d.ts +48 -0
- package/dist/types/sources/mdx-remote.d.ts +63 -0
- package/dist/types/sources/notion.d.ts +65 -0
- package/dist/types/sources/obsidian.d.ts +34 -0
- package/dist/types/sources/payload.d.ts +68 -0
- package/dist/types/sources/registry.d.ts +1414 -0
- package/dist/types/sources/sanity.d.ts +69 -0
- package/dist/types/sources/shared.d.ts +46 -0
- package/dist/types/sources/strapi.d.ts +66 -0
- package/dist/types/theme/icon-kind.d.ts +11 -0
- package/dist/types/theme/icons.d.ts +20 -0
- package/docs/01-quickstart.mdx +18 -18
- package/docs/02-deployment.mdx +50 -26
- package/docs/03-upgrading.mdx +351 -0
- package/docs/04-migrating.mdx +58 -0
- package/docs/08-faq.mdx +3 -3
- package/docs/advanced/blog.mdx +13 -6
- package/docs/advanced/changelog.mdx +23 -35
- package/docs/advanced/custom-pages.mdx +20 -8
- package/docs/advanced/meta.ts +1 -8
- package/docs/advanced/skills.mdx +8 -0
- package/docs/cli/audit.mdx +646 -0
- package/docs/cli/doctor.mdx +29 -0
- package/docs/{reference/eval.mdx → cli/evals.mdx} +9 -8
- package/docs/cli/index.mdx +105 -0
- package/docs/cli/meta.ts +7 -0
- package/docs/{reference → cli}/translate.mdx +1 -1
- package/docs/cli/validate.mdx +41 -0
- package/docs/cli/version.mdx +40 -0
- package/docs/configuration/analytics.mdx +350 -59
- package/docs/configuration/ask-ai.mdx +176 -61
- package/docs/configuration/customization.mdx +15 -9
- package/docs/configuration/index.mdx +52 -31
- package/docs/configuration/search.mdx +75 -54
- package/docs/configuration/theming.mdx +24 -15
- package/docs/content/components.mdx +21 -5
- package/docs/{reference → content}/frontmatter.mdx +37 -1
- package/docs/content/i18n.mdx +8 -6
- package/docs/content/includes.mdx +2 -4
- package/docs/content/index.mdx +1 -1
- package/docs/content/islands.mdx +10 -5
- package/docs/content/meta.mdx +1 -1
- package/docs/content/meta.ts +1 -0
- package/docs/content/navigation.mdx +12 -7
- package/docs/content/sources.mdx +145 -50
- package/docs/content/syntax.mdx +26 -12
- package/docs/content/versioning.mdx +3 -3
- package/docs/discoverability/agent-discovery.mdx +91 -10
- package/docs/discoverability/index.mdx +5 -5
- package/docs/discoverability/json-api.mdx +4 -4
- package/docs/discoverability/llms-txt.mdx +6 -6
- package/docs/discoverability/markdown.mdx +4 -4
- package/docs/discoverability/mcp.mdx +11 -11
- package/docs/discoverability/sitemap-and-robots.mdx +3 -3
- package/docs/index.mdx +2 -2
- package/docs/references/asyncapi.mdx +59 -0
- package/docs/{advanced → references}/graphql.mdx +45 -32
- package/docs/{reference → references}/meta.ts +2 -2
- package/docs/references/openapi.mdx +171 -0
- package/docs/references/scalar.mdx +64 -0
- package/package.json +42 -8
- package/skills/blume/SKILL.md +21 -8
- package/skills/blume-migrate/SKILL.md +22 -21
- package/skills/blume-migrate/assets/oxfmt@0.67.0.patch +49 -0
- package/skills/blume-migrate/references/docusaurus.md +5 -4
- package/skills/blume-migrate/references/fumadocs.md +4 -4
- package/skills/blume-migrate/references/mintlify.md +23 -8
- package/skills/blume-migrate/references/monorepo.md +6 -6
- package/skills/blume-migrate/references/starlight.md +4 -4
- package/src/ai/agent-readability.ts +26 -22
- package/src/ai/ai-catalog.ts +259 -0
- package/src/ai/api/handlers.ts +46 -11
- package/src/ai/api-catalog.ts +8 -8
- package/src/ai/ask-data.ts +1 -1
- package/src/ai/ask.ts +624 -100
- package/src/ai/changelog-markdown.ts +91 -0
- package/src/ai/component-markdown.ts +328 -12
- package/src/ai/index.ts +45 -0
- package/src/ai/link-headers.ts +19 -6
- package/src/ai/llms.ts +26 -15
- package/src/ai/markdown.ts +35 -5
- package/src/ai/mcp/data.ts +9 -5
- package/src/ai/mcp/discovery.ts +1 -1
- package/src/ai/openapi-components.ts +4 -1
- package/src/ai/relative-links.ts +170 -0
- package/src/ai/serializers.ts +2 -2
- package/src/ai/skills.ts +1 -1
- package/src/ai/web-bot-auth.ts +2 -2
- package/src/analytics/adobe.ts +46 -0
- package/src/analytics/amplitude.ts +79 -0
- package/src/analytics/clarity.ts +46 -0
- package/src/analytics/clearbit.ts +47 -0
- package/src/analytics/cloudflare.ts +67 -0
- package/src/analytics/fathom.ts +64 -0
- package/src/analytics/google-analytics.ts +84 -0
- package/src/analytics/google-tag-manager.ts +61 -0
- package/src/analytics/head.ts +130 -0
- package/src/analytics/heap.ts +65 -0
- package/src/analytics/hightouch.ts +77 -0
- package/src/analytics/hotjar.ts +47 -0
- package/src/analytics/index.ts +71 -0
- package/src/analytics/inline.ts +21 -0
- package/src/analytics/logrocket.ts +71 -0
- package/src/analytics/mixpanel.ts +92 -0
- package/src/analytics/pirsch.ts +66 -0
- package/src/analytics/plausible.ts +83 -0
- package/src/analytics/posthog.ts +78 -0
- package/src/analytics/schema.ts +60 -0
- package/src/analytics/script.ts +60 -0
- package/src/analytics/segment.ts +85 -0
- package/src/analytics/vercel.ts +50 -0
- package/src/astro/adapter-root.ts +7 -9
- package/src/astro/component-slots.ts +131 -91
- package/src/astro/generate.ts +114 -345
- package/src/astro/integration.ts +2 -6
- package/src/astro/pages.ts +13 -101
- package/src/astro/render-deps.ts +379 -0
- package/src/astro/runtime-deps.ts +201 -0
- package/src/astro/templates.ts +554 -541
- package/src/audit/agent.ts +24 -0
- package/src/audit/catalog.ts +2 -2
- package/src/audit/checks/assets.ts +2 -2
- package/src/audit/checks/dns-aid.ts +1 -1
- package/src/audit/checks/duplicates.ts +3 -1
- package/src/audit/checks/i18n.ts +1 -1
- package/src/audit/checks/indexability.ts +7 -7
- package/src/audit/checks/links.ts +2 -2
- package/src/audit/checks/llms.ts +6 -6
- package/src/audit/checks/network.ts +3 -3
- package/src/audit/checks/og-image.ts +2 -2
- package/src/audit/checks/robots.ts +1 -1
- package/src/audit/checks/sitemap.ts +2 -2
- package/src/audit/checks/social.ts +1 -1
- package/src/audit/run.ts +4 -3
- package/src/audit/terms.ts +31 -0
- package/src/audit/url.ts +13 -13
- package/src/cli/command-meta.ts +10 -0
- package/src/cli/commands/audit.ts +39 -20
- package/src/cli/commands/build.ts +71 -314
- package/src/cli/commands/check.ts +1 -0
- package/src/cli/commands/dev.ts +40 -1
- package/src/cli/commands/doctor.ts +90 -14
- package/src/cli/commands/eject.ts +44 -7
- package/src/cli/commands/eval.ts +2 -2
- package/src/cli/commands/init.ts +161 -41
- package/src/cli/commands/migrate.ts +121 -0
- package/src/cli/commands/preview.ts +7 -1
- package/src/cli/commands/translate.ts +2 -2
- package/src/cli/commands/upgrade.ts +141 -0
- package/src/cli/commands/version.ts +57 -44
- package/src/cli/eject-scripts.ts +121 -6
- package/src/cli/index.ts +11 -1
- package/src/cli/init/install.ts +70 -0
- package/src/cli/init/questions.ts +7 -0
- package/src/cli/init/scaffold.ts +459 -75
- package/src/cli/lazy-command.ts +37 -1
- package/src/cli/prepare.ts +40 -6
- package/src/cli/required-secrets.ts +38 -11
- package/src/cli/unknown-flags.ts +266 -0
- package/src/cli/yarn-pnp.ts +52 -0
- package/src/components/content/AccordionItem.astro +7 -1
- package/src/components/content/Card.astro +4 -3
- package/src/components/content/ColorItem.astro +22 -4
- package/src/components/content/GithubInfo.astro +2 -2
- package/src/components/content/Prompt.astro +25 -25
- package/src/components/content/Tabs.astro +3 -1
- package/src/components/content/Tile.astro +2 -3
- package/src/components/content/Tooltip.astro +57 -9
- package/src/components/content/content-strings.ts +34 -0
- package/src/components/content/diff.ts +1 -1
- package/src/components/content/mermaid-element.ts +13 -2
- package/src/components/content/prompt-markdown.ts +292 -0
- package/src/components/content/tooltip-id.ts +41 -0
- package/src/components/islands/hooks.ts +75 -3
- package/src/components/layout/Analytics.astro +21 -79
- package/src/components/layout/Banner.astro +3 -1
- package/src/components/layout/DiscoveryLinks.astro +69 -0
- package/src/components/layout/Header.astro +83 -20
- package/src/components/layout/LanguageSwitcher.astro +4 -1
- package/src/components/layout/Logo.astro +23 -2
- package/src/components/layout/NavSelector.astro +13 -2
- package/src/components/layout/NavTree.astro +12 -3
- package/src/components/layout/NavTreeScript.astro +17 -3
- package/src/components/layout/PageActions.astro +3 -3
- package/src/components/layout/PageFeedback.astro +11 -1
- package/src/components/layout/PageLayout.astro +52 -5
- package/src/components/layout/ReferenceLayout.astro +21 -12
- package/src/components/layout/RootLayout.astro +69 -43
- package/src/components/layout/Search.astro +30 -6
- package/src/components/layout/WebMcp.astro +1 -1
- package/src/components/layout/analytics-client.ts +101 -15
- package/src/components/layout/drawer-inert.ts +113 -15
- package/src/components/layout/dropdown-clamp.ts +105 -0
- package/src/components/layout/head-scripts.ts +15 -6
- package/src/components/layout/nav-utils.ts +17 -0
- package/src/components/layout/search/algolia.ts +8 -8
- package/src/components/layout/search/orama-cloud.ts +9 -7
- package/src/components/layout/search/typesense.ts +11 -17
- package/src/components/openapi/MessageComposer.astro +2 -2
- package/src/components/openapi/Playground.astro +2 -2
- package/src/components/openapi/playground-client.ts +79 -10
- package/src/core/changelog-index.ts +24 -0
- package/src/core/component-overrides.ts +399 -154
- package/src/core/config-input.ts +212 -543
- package/src/core/config.ts +130 -41
- package/src/core/custom-pages.ts +105 -0
- package/src/core/data.ts +32 -11
- package/src/core/define-components.ts +12 -9
- package/src/core/deployment-env.ts +18 -74
- package/src/core/diagnostics.ts +14 -7
- package/src/core/graph.ts +69 -25
- package/src/core/i18n-ui.ts +6 -2
- package/src/core/i18n.ts +17 -0
- package/src/core/includes.ts +156 -38
- package/src/core/last-modified.ts +6 -11
- package/src/core/links.ts +166 -2
- package/src/core/manifest.ts +10 -3
- package/src/core/navigation.ts +137 -19
- package/src/core/new-tab.ts +35 -0
- package/src/core/node-require.ts +21 -0
- package/src/core/project-graph.ts +42 -26
- package/src/core/project.ts +9 -4
- package/src/core/request-body.ts +61 -0
- package/src/core/safe-href.ts +28 -0
- package/src/core/safe-links.ts +68 -0
- package/src/core/schema.ts +531 -721
- package/src/core/server-features.ts +8 -9
- package/src/core/sources/assets.ts +47 -11
- package/src/core/sources/collection.ts +67 -0
- package/src/core/sources/contentful-rich-text.ts +285 -0
- package/src/core/sources/contentful.ts +173 -0
- package/src/core/sources/github-releases.ts +51 -1
- package/src/core/sources/json.ts +71 -0
- package/src/core/sources/lexical.ts +195 -0
- package/src/core/sources/lower.ts +226 -0
- package/src/core/sources/normalize.ts +52 -2
- package/src/core/sources/notion.ts +39 -28
- package/src/core/sources/payload.ts +135 -0
- package/src/core/sources/portable-text.ts +11 -16
- package/src/core/sources/remote.ts +226 -0
- package/src/core/sources/resolve.ts +104 -166
- package/src/core/sources/sanity.ts +16 -49
- package/src/core/sources/strapi-blocks.ts +124 -0
- package/src/core/sources/strapi.ts +191 -0
- package/src/core/sources/types.ts +12 -1
- package/src/core/types.ts +20 -1
- package/src/core/ui-packs/ar.ts +6 -2
- package/src/core/ui-packs/bg.ts +6 -2
- package/src/core/ui-packs/bn.ts +6 -2
- package/src/core/ui-packs/ca.ts +3 -1
- package/src/core/ui-packs/cs.ts +6 -2
- package/src/core/ui-packs/da.ts +6 -2
- package/src/core/ui-packs/de.ts +6 -2
- package/src/core/ui-packs/el.ts +3 -1
- package/src/core/ui-packs/es.ts +3 -1
- package/src/core/ui-packs/fa.ts +6 -2
- package/src/core/ui-packs/fi.ts +6 -2
- package/src/core/ui-packs/fr.ts +3 -1
- package/src/core/ui-packs/he.ts +6 -2
- package/src/core/ui-packs/hi.ts +6 -2
- package/src/core/ui-packs/hr.ts +6 -2
- package/src/core/ui-packs/hu.ts +6 -2
- package/src/core/ui-packs/id.ts +6 -2
- package/src/core/ui-packs/it.ts +3 -1
- package/src/core/ui-packs/ja.ts +3 -1
- package/src/core/ui-packs/ko.ts +3 -1
- package/src/core/ui-packs/nl.ts +6 -2
- package/src/core/ui-packs/no.ts +6 -2
- package/src/core/ui-packs/pl.ts +6 -2
- package/src/core/ui-packs/pt-br.ts +3 -1
- package/src/core/ui-packs/pt.ts +3 -1
- package/src/core/ui-packs/ro.ts +6 -2
- package/src/core/ui-packs/ru.ts +6 -2
- package/src/core/ui-packs/sk.ts +6 -2
- package/src/core/ui-packs/sr.ts +6 -2
- package/src/core/ui-packs/sv.ts +6 -2
- package/src/core/ui-packs/th.ts +3 -1
- package/src/core/ui-packs/tr.ts +6 -2
- package/src/core/ui-packs/uk.ts +6 -2
- package/src/core/ui-packs/vi.ts +3 -1
- package/src/core/ui-packs/zh-tw.ts +3 -1
- package/src/core/ui-packs/zh.ts +3 -1
- package/src/core/unrecognized-keys.ts +10 -0
- package/src/core/version-cut.ts +116 -8
- package/src/deploy/adapter-output.ts +57 -97
- package/src/deploy/adapters/cloudflare.ts +39 -0
- package/src/deploy/adapters/index.ts +41 -0
- package/src/deploy/adapters/netlify.ts +34 -0
- package/src/deploy/adapters/node.ts +34 -0
- package/src/deploy/adapters/registry.ts +127 -0
- package/src/deploy/adapters/types.ts +92 -0
- package/src/deploy/adapters/vercel.ts +35 -0
- package/src/deploy/artifacts.ts +67 -28
- package/src/deploy/cloudflare-negotiation.ts +179 -100
- package/src/deploy/function-bundle.ts +18 -3
- package/src/deploy/headers.ts +129 -22
- package/src/deploy/node-headers.ts +198 -0
- package/src/deploy/platforms/cloudflare.ts +312 -0
- package/src/deploy/platforms/index.ts +67 -0
- package/src/deploy/platforms/netlify.ts +52 -0
- package/src/deploy/platforms/node.ts +40 -0
- package/src/deploy/platforms/paths.ts +42 -0
- package/src/deploy/platforms/static.ts +29 -0
- package/src/deploy/platforms/types.ts +112 -0
- package/src/deploy/platforms/vercel.ts +193 -0
- package/src/deploy/redirects.ts +30 -18
- package/src/deploy/robots.ts +3 -3
- package/src/deploy/rss.ts +2 -2
- package/src/deploy/sitemap.ts +2 -2
- package/src/deploy/vercel-negotiation.ts +27 -4
- package/src/eval/agents.ts +32 -1
- package/src/eval/findings.ts +19 -11
- package/src/eval/report.ts +10 -2
- package/src/markdown/external-links.ts +65 -0
- package/src/markdown/include.ts +45 -27
- package/src/markdown/index.ts +34 -9
- package/src/markdown/inline-code.ts +12 -6
- package/src/markdown/relative-links.ts +324 -0
- package/src/markdown/themes.ts +3 -3
- package/src/migrate/migrate.ts +149 -0
- package/src/openapi/parse.ts +64 -16
- package/src/openapi/proxy.ts +62 -10
- package/src/openapi/references.ts +147 -147
- package/src/openapi/render-mdx.ts +32 -10
- package/src/openapi/scalar.ts +15 -13
- package/src/openapi/sentence.ts +14 -0
- package/src/openapi/source.ts +37 -21
- package/src/openapi/spec-dependency-error.ts +15 -0
- package/src/reference/asyncapi.ts +83 -0
- package/src/reference/graphql.ts +89 -0
- package/src/reference/index.ts +40 -0
- package/src/reference/openapi.ts +83 -0
- package/src/reference/options.ts +201 -0
- package/src/reference/scalar.ts +136 -0
- package/src/reference/schema.ts +88 -0
- package/src/registry/eject.ts +97 -42
- package/src/search/adapters/algolia.ts +46 -0
- package/src/search/adapters/flexsearch.ts +29 -0
- package/src/search/adapters/index.ts +39 -0
- package/src/search/adapters/mixedbread.ts +39 -0
- package/src/search/adapters/orama-cloud.ts +51 -0
- package/src/search/adapters/orama.ts +24 -0
- package/src/search/adapters/pagefind.ts +27 -0
- package/src/search/adapters/registry.ts +131 -0
- package/src/search/adapters/types.ts +46 -0
- package/src/search/adapters/typesense.ts +57 -0
- package/src/search/build.ts +33 -7
- package/src/search/documents.ts +6 -0
- package/src/search/sync/algolia.ts +12 -11
- package/src/search/sync/index.ts +35 -20
- package/src/search/sync/orama-cloud.ts +12 -9
- package/src/search/sync/typesense.ts +15 -13
- package/src/sources/contentful.ts +63 -0
- package/src/sources/custom.ts +38 -0
- package/src/sources/filesystem.ts +51 -0
- package/src/sources/github-releases.ts +52 -0
- package/src/sources/index.ts +60 -0
- package/src/sources/mdx-remote.ts +76 -0
- package/src/sources/notion.ts +63 -0
- package/src/sources/obsidian.ts +38 -0
- package/src/sources/payload.ts +60 -0
- package/src/sources/registry.ts +182 -0
- package/src/sources/sanity.ts +66 -0
- package/src/sources/shared.ts +52 -0
- package/src/sources/strapi.ts +58 -0
- package/src/theme/entry.ts +47 -2
- package/src/translate/report.ts +40 -7
- package/src/upgrade/upgrade.ts +499 -0
- package/dist/cli/chunk-12dxjqk7.js.map +0 -10
- package/dist/cli/chunk-196vjxp9.js.map +0 -13
- package/dist/cli/chunk-2mzebbbz.js +0 -69
- package/dist/cli/chunk-2z47ypj8.js.map +0 -11
- package/dist/cli/chunk-30e87n55.js +0 -108
- package/dist/cli/chunk-30e87n55.js.map +0 -10
- package/dist/cli/chunk-450a7rcr.js +0 -185
- package/dist/cli/chunk-450a7rcr.js.map +0 -11
- package/dist/cli/chunk-5n7t497w.js.map +0 -40
- package/dist/cli/chunk-61j18dwk.js +0 -5342
- package/dist/cli/chunk-61j18dwk.js.map +0 -58
- package/dist/cli/chunk-88by27n5.js +0 -17
- package/dist/cli/chunk-88by27n5.js.map +0 -10
- package/dist/cli/chunk-8cd8tj54.js.map +0 -34
- package/dist/cli/chunk-aztttvb3.js +0 -381
- package/dist/cli/chunk-aztttvb3.js.map +0 -12
- package/dist/cli/chunk-cvky9gb2.js.map +0 -11
- package/dist/cli/chunk-ejjx8znq.js.map +0 -15
- package/dist/cli/chunk-fmceyezb.js +0 -1007
- package/dist/cli/chunk-fmceyezb.js.map +0 -13
- package/dist/cli/chunk-hdm2dkd2.js.map +0 -48
- package/dist/cli/chunk-hs3gbh8p.js.map +0 -10
- package/dist/cli/chunk-jbj4qhfw.js +0 -30
- package/dist/cli/chunk-jbj4qhfw.js.map +0 -10
- package/dist/cli/chunk-mqb2ka8m.js +0 -68
- package/dist/cli/chunk-mqb2ka8m.js.map +0 -10
- package/dist/cli/chunk-mt76t7dj.js.map +0 -11
- package/dist/cli/chunk-q4rae3bg.js +0 -60
- package/dist/cli/chunk-q4rae3bg.js.map +0 -10
- package/dist/cli/chunk-ra1v2nc2.js +0 -35
- package/dist/cli/chunk-ra1v2nc2.js.map +0 -10
- package/dist/cli/chunk-t3tj0dgr.js.map +0 -15
- package/dist/cli/chunk-tqa1s0k8.js +0 -69
- package/dist/cli/chunk-tqa1s0k8.js.map +0 -11
- package/dist/cli/chunk-vh9w1sgp.js +0 -73
- package/dist/cli/chunk-vh9w1sgp.js.map +0 -10
- package/dist/cli/chunk-vkrsvbr5.js +0 -107
- package/dist/cli/chunk-vkrsvbr5.js.map +0 -11
- package/dist/cli/chunk-vrfp10qk.js +0 -81
- package/dist/cli/chunk-vrfp10qk.js.map +0 -10
- package/dist/cli/chunk-wjt80jps.js +0 -1049
- package/dist/cli/chunk-wjt80jps.js.map +0 -24
- package/docs/advanced/api-reference.mdx +0 -240
- package/docs/reference/cli.mdx +0 -197
- package/skills/blume-migrate/assets/oxfmt@0.55.0.patch +0 -20
- package/src/components/content/changelog-element.ts +0 -69
- package/src/search/providers.ts +0 -91
- /package/dist/cli/{chunk-3w7b2vcx.js.map → chunk-7ez8ny0t.js.map} +0 -0
- /package/dist/cli/{chunk-688e0dde.js.map → chunk-88cpgt6h.js.map} +0 -0
- /package/dist/cli/{chunk-exeeb35e.js.map → chunk-f7t03s3g.js.map} +0 -0
- /package/dist/cli/{chunk-ppfvdcd4.js.map → chunk-zxccj738.js.map} +0 -0
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import { existsSync } from "node:fs";
|
|
2
|
+
import { readFile } from "node:fs/promises";
|
|
3
|
+
|
|
4
|
+
import { join } from "pathe";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* `blume migrate`'s logic, kept out of the command module so it runs (and is
|
|
8
|
+
* covered) in-process. Migration is judgment work — idiomatic navigation,
|
|
9
|
+
* component rewrites, what to drop — so it stays in the `blume-migrate` skill,
|
|
10
|
+
* shipped inside the package; this module only names the source (from the
|
|
11
|
+
* argument, or detected from the repo's own files) and writes the prompt that
|
|
12
|
+
* points a coding agent at the skill and that source's mappings.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
/** The docs frameworks the skill has a mapping reference for. */
|
|
16
|
+
export const MIGRATE_SOURCES = [
|
|
17
|
+
"mintlify",
|
|
18
|
+
"fumadocs",
|
|
19
|
+
"docusaurus",
|
|
20
|
+
"starlight",
|
|
21
|
+
"nextra",
|
|
22
|
+
] as const;
|
|
23
|
+
|
|
24
|
+
export type MigrateSourceId = (typeof MIGRATE_SOURCES)[number];
|
|
25
|
+
|
|
26
|
+
/** Display names, for messages and the prompt. */
|
|
27
|
+
export const MIGRATE_SOURCE_NAMES: Record<MigrateSourceId, string> = {
|
|
28
|
+
docusaurus: "Docusaurus",
|
|
29
|
+
fumadocs: "Fumadocs",
|
|
30
|
+
mintlify: "Mintlify",
|
|
31
|
+
nextra: "Nextra",
|
|
32
|
+
starlight: "Starlight",
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
/** The skill's directory inside the published package. */
|
|
36
|
+
export const MIGRATE_SKILL_DIR = join("skills", "blume-migrate");
|
|
37
|
+
|
|
38
|
+
export const isMigrateSource = (value: string): value is MigrateSourceId =>
|
|
39
|
+
MIGRATE_SOURCES.some((source) => source === value);
|
|
40
|
+
|
|
41
|
+
/** A detected source and the file or dependency that gave it away. */
|
|
42
|
+
export interface DetectedSource {
|
|
43
|
+
evidence: string;
|
|
44
|
+
source: MigrateSourceId;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/** The slice of `package.json` detection reads. */
|
|
48
|
+
interface PackageJson {
|
|
49
|
+
dependencies?: Record<string, string>;
|
|
50
|
+
devDependencies?: Record<string, string>;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/** Every dependency the project's `package.json` names, or none when unreadable. */
|
|
54
|
+
const dependencyNames = async (root: string): Promise<Set<string>> => {
|
|
55
|
+
const path = join(root, "package.json");
|
|
56
|
+
if (!existsSync(path)) {
|
|
57
|
+
return new Set();
|
|
58
|
+
}
|
|
59
|
+
try {
|
|
60
|
+
// SAFETY: package.json is a JSON object; only its dependency maps are read.
|
|
61
|
+
const pkg = JSON.parse(await readFile(path, "utf-8")) as PackageJson;
|
|
62
|
+
return new Set([
|
|
63
|
+
...Object.keys(pkg.dependencies ?? {}),
|
|
64
|
+
...Object.keys(pkg.devDependencies ?? {}),
|
|
65
|
+
]);
|
|
66
|
+
} catch {
|
|
67
|
+
// A malformed package.json is the agent's to deal with; detection just
|
|
68
|
+
// falls back to the other signals.
|
|
69
|
+
return new Set();
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Each source's tell, in the order the skill's workflow checks them: a config
|
|
75
|
+
* file the framework owns, or a dependency only it installs.
|
|
76
|
+
*/
|
|
77
|
+
const SIGNALS: {
|
|
78
|
+
deps?: string[];
|
|
79
|
+
files?: string[];
|
|
80
|
+
source: MigrateSourceId;
|
|
81
|
+
}[] = [
|
|
82
|
+
{ files: ["docs.json", "mint.json"], source: "mintlify" },
|
|
83
|
+
{
|
|
84
|
+
files: [
|
|
85
|
+
"docusaurus.config.ts",
|
|
86
|
+
"docusaurus.config.js",
|
|
87
|
+
"docusaurus.config.mjs",
|
|
88
|
+
"docusaurus.config.cjs",
|
|
89
|
+
],
|
|
90
|
+
source: "docusaurus",
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
deps: ["fumadocs-core", "fumadocs-ui", "fumadocs-mdx"],
|
|
94
|
+
files: ["source.config.ts"],
|
|
95
|
+
source: "fumadocs",
|
|
96
|
+
},
|
|
97
|
+
{ deps: ["nextra"], source: "nextra" },
|
|
98
|
+
{ deps: ["@astrojs/starlight"], source: "starlight" },
|
|
99
|
+
];
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Detect the docs framework a project is built on from its own files, or
|
|
103
|
+
* null when nothing gives it away (the skill still migrates any framework,
|
|
104
|
+
* working from its general model instead of a mapping reference).
|
|
105
|
+
*/
|
|
106
|
+
export const detectMigrateSource = async (
|
|
107
|
+
root: string
|
|
108
|
+
): Promise<DetectedSource | null> => {
|
|
109
|
+
const deps = await dependencyNames(root);
|
|
110
|
+
for (const { deps: tells = [], files = [], source } of SIGNALS) {
|
|
111
|
+
const file = files.find((name) => existsSync(join(root, name)));
|
|
112
|
+
if (file) {
|
|
113
|
+
return { evidence: file, source };
|
|
114
|
+
}
|
|
115
|
+
const dep = tells.find((name) => deps.has(name));
|
|
116
|
+
if (dep) {
|
|
117
|
+
return { evidence: `${dep} in package.json`, source };
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
return null;
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* The handoff prompt: follow the skill, where its mappings for this source
|
|
125
|
+
* are, and the few rules worth restating — the target version, and that no
|
|
126
|
+
* page or URL is lost.
|
|
127
|
+
*/
|
|
128
|
+
export const migratePrompt = (options: {
|
|
129
|
+
detected: DetectedSource | null;
|
|
130
|
+
skillDir: string;
|
|
131
|
+
source: MigrateSourceId | null;
|
|
132
|
+
version: string;
|
|
133
|
+
}): string => {
|
|
134
|
+
const { detected, skillDir, source, version } = options;
|
|
135
|
+
const evidence =
|
|
136
|
+
detected && detected.source === source
|
|
137
|
+
? ` (detected from ${detected.evidence})`
|
|
138
|
+
: "";
|
|
139
|
+
const sourceLine = source
|
|
140
|
+
? `The source is ${MIGRATE_SOURCE_NAMES[source]}${evidence}. Its exact mappings are in ${join(skillDir, "references", `${source}.md`)}.`
|
|
141
|
+
: `The source framework wasn't detected, so inventory the repo first. If it's ${MIGRATE_SOURCES.map((id) => MIGRATE_SOURCE_NAMES[id]).join(", ")}, read that framework's file in ${join(skillDir, "references")}; otherwise follow the skill's mental model directly.`;
|
|
142
|
+
return `Migrate this documentation project to Blume ${version}.
|
|
143
|
+
|
|
144
|
+
Follow the blume-migrate skill: read ${join(skillDir, "SKILL.md")} first and work through its migration workflow. Wherever the skill says \`<skill>\`, it means ${skillDir}.
|
|
145
|
+
|
|
146
|
+
${sourceLine}
|
|
147
|
+
|
|
148
|
+
Add \`blume@^${version}\` as the docs package's dependency. Keep every page, and add a redirect for any URL that moves. Report everything you drop or approximate, and run the skill's verification steps before you finish.`;
|
|
149
|
+
};
|
package/src/openapi/parse.ts
CHANGED
|
@@ -1,18 +1,24 @@
|
|
|
1
1
|
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
2
2
|
import { setTimeout as sleep } from "node:timers/promises";
|
|
3
3
|
|
|
4
|
-
import type
|
|
5
|
-
import { convert } from "@asyncapi/converter";
|
|
4
|
+
import type * as ConverterModule from "@asyncapi/converter";
|
|
6
5
|
import { normalize, upgrade } from "@scalar/openapi-parser";
|
|
7
6
|
import pRetry, { AbortError } from "p-retry";
|
|
8
7
|
import { isAbsolute, join } from "pathe";
|
|
8
|
+
import type * as UndiciModule from "undici";
|
|
9
9
|
|
|
10
|
+
import {
|
|
11
|
+
commandsFor,
|
|
12
|
+
detectProjectPackageManager,
|
|
13
|
+
} from "../cli/init/scaffold.ts";
|
|
14
|
+
import { nodeRequire } from "../core/node-require.ts";
|
|
10
15
|
import { hashText } from "../core/sources/cache.ts";
|
|
11
16
|
import type { AsyncApiDocument } from "./asyncapi.ts";
|
|
12
17
|
import { normalizeAsyncApiDocument } from "./asyncapi.ts";
|
|
13
18
|
import { buildGraphqlDocument } from "./graphql-build.ts";
|
|
14
19
|
import type { GraphqlDocument } from "./graphql.ts";
|
|
15
20
|
import type { ApiDocument } from "./model.ts";
|
|
21
|
+
import { SpecDependencyError } from "./spec-dependency-error.ts";
|
|
16
22
|
|
|
17
23
|
/**
|
|
18
24
|
* Spec loading and normalization. Blume reuses Scalar's parser
|
|
@@ -83,18 +89,21 @@ export interface SpecFetchOptions {
|
|
|
83
89
|
* spec is fetched with one configured. Node's built-in `fetch` ignores `*_PROXY`
|
|
84
90
|
* on its own; undici's env proxy agent, installed on the shared global-dispatcher
|
|
85
91
|
* symbol, wires it in without replacing `fetch` (so tests can still stub it).
|
|
86
|
-
* Best-effort and lazy: no proxy env means
|
|
92
|
+
* Best-effort and lazy: no proxy env means undici never loads, and an
|
|
87
93
|
* unavailable undici just leaves the direct connection in place.
|
|
88
94
|
*/
|
|
89
95
|
let proxyInstalled = false;
|
|
90
|
-
const ensureProxyDispatcher =
|
|
96
|
+
const ensureProxyDispatcher = (): void => {
|
|
91
97
|
// Only memoize a successful install: with no proxy configured we cheaply
|
|
92
98
|
// re-check each time, so a proxy set later in the process still takes effect.
|
|
93
99
|
if (proxyInstalled || !PROXY_ENV_VARS.some((name) => process.env[name])) {
|
|
94
100
|
return;
|
|
95
101
|
}
|
|
96
102
|
try {
|
|
97
|
-
|
|
103
|
+
// `require`, not `import()`: an ejected app scans in `astro:build:done`
|
|
104
|
+
// (see `core/node-require.ts`).
|
|
105
|
+
const { EnvHttpProxyAgent, setGlobalDispatcher }: typeof UndiciModule =
|
|
106
|
+
nodeRequire("undici");
|
|
98
107
|
setGlobalDispatcher(new EnvHttpProxyAgent());
|
|
99
108
|
proxyInstalled = true;
|
|
100
109
|
} catch {
|
|
@@ -177,7 +186,7 @@ const retryableFetchError = (
|
|
|
177
186
|
|
|
178
187
|
/** Fetch a remote spec's text, retrying transient failures with backoff. */
|
|
179
188
|
const fetchSpecText = async (spec: string): Promise<string> => {
|
|
180
|
-
|
|
189
|
+
ensureProxyDispatcher();
|
|
181
190
|
return await pRetry(
|
|
182
191
|
async () => {
|
|
183
192
|
const attempt = await attemptFetch(spec);
|
|
@@ -323,15 +332,6 @@ export interface ParsedAsyncApiSpec {
|
|
|
323
332
|
warnings: string[];
|
|
324
333
|
}
|
|
325
334
|
|
|
326
|
-
/**
|
|
327
|
-
* Read and normalize a spec to an AsyncAPI 3.x document — the AsyncAPI mirror
|
|
328
|
-
* of {@link parseSpec}. 1.x/2.x documents are lifted to 3.0 with the official
|
|
329
|
-
* `@asyncapi/converter` (channels + operations with `send`/`receive` actions),
|
|
330
|
-
* so the extractor and components only ever handle one shape; `$ref`s stay
|
|
331
|
-
* intact, matching the OpenAPI path. Error semantics match `parseSpec`: an
|
|
332
|
-
* unreadable spec throws, a readable non-AsyncAPI document throws
|
|
333
|
-
* {@link InvalidSpecError}, and callers lower both into source diagnostics.
|
|
334
|
-
*/
|
|
335
335
|
/**
|
|
336
336
|
* An object carrying a non-empty `asyncapi` version string — the only input
|
|
337
337
|
* the converter and extractor can key on. `normalize` yields undefined for
|
|
@@ -346,6 +346,53 @@ const isAsyncApiDocument = <Value>(
|
|
|
346
346
|
typeof value.asyncapi === "string" &&
|
|
347
347
|
value.asyncapi !== "";
|
|
348
348
|
|
|
349
|
+
const CONVERTER = "@asyncapi/converter";
|
|
350
|
+
|
|
351
|
+
/**
|
|
352
|
+
* Load `@asyncapi/converter`, an optional peer. Only a 1.x/2.x spec needs it,
|
|
353
|
+
* and it depends on `@asyncapi/parser` — which it never loads — and so on
|
|
354
|
+
* Spectral and Scarf's telemetry postinstall, an unapproved build script that
|
|
355
|
+
* pnpm 12 refuses to install past. Leaving it out of a default install keeps
|
|
356
|
+
* `pnpm dlx blume` working; a spec that needs it gets the install command
|
|
357
|
+
* instead, through {@link SpecDependencyError}.
|
|
358
|
+
*/
|
|
359
|
+
const loadConverter = async (
|
|
360
|
+
spec: string,
|
|
361
|
+
version: string,
|
|
362
|
+
root: string
|
|
363
|
+
): Promise<typeof ConverterModule> => {
|
|
364
|
+
try {
|
|
365
|
+
// `require`, not `import()`: see `core/node-require.ts`.
|
|
366
|
+
const converter: typeof ConverterModule = nodeRequire(CONVERTER);
|
|
367
|
+
return converter;
|
|
368
|
+
} catch (error) {
|
|
369
|
+
// SAFETY: a failed `require` throws a Node error; `code` and `message`
|
|
370
|
+
// are the only fields read.
|
|
371
|
+
const { code, message } = error as NodeJS.ErrnoException;
|
|
372
|
+
// Only the converter itself missing is the project's to fix; anything
|
|
373
|
+
// else (a broken install of one of its own dependencies) surfaces as is.
|
|
374
|
+
if (code !== "MODULE_NOT_FOUND" || !message.includes(`'${CONVERTER}'`)) {
|
|
375
|
+
throw error;
|
|
376
|
+
}
|
|
377
|
+
const { add } = commandsFor(await detectProjectPackageManager(root));
|
|
378
|
+
throw new SpecDependencyError(
|
|
379
|
+
`${spec} is AsyncAPI ${version}, and converting it to AsyncAPI 3.0 needs "${CONVERTER}", which isn't installed`,
|
|
380
|
+
`Install it with \`${add} ${CONVERTER}\`, or convert the spec to AsyncAPI 3.0.`
|
|
381
|
+
);
|
|
382
|
+
}
|
|
383
|
+
};
|
|
384
|
+
|
|
385
|
+
/**
|
|
386
|
+
* Read and normalize a spec to an AsyncAPI 3.x document — the AsyncAPI mirror
|
|
387
|
+
* of {@link parseSpec}. 1.x/2.x documents are lifted to 3.0 with the official
|
|
388
|
+
* `@asyncapi/converter` (channels + operations with `send`/`receive` actions),
|
|
389
|
+
* so the extractor and components only ever handle one shape; `$ref`s stay
|
|
390
|
+
* intact, matching the OpenAPI path. Error semantics match `parseSpec`: an
|
|
391
|
+
* unreadable spec throws, a readable non-AsyncAPI document throws
|
|
392
|
+
* {@link InvalidSpecError}, a pre-3.0 document without the converter installed
|
|
393
|
+
* throws {@link SpecDependencyError}, and callers lower all three into source
|
|
394
|
+
* diagnostics.
|
|
395
|
+
*/
|
|
349
396
|
export const parseAsyncApiSpec = async (
|
|
350
397
|
spec: string,
|
|
351
398
|
root: string,
|
|
@@ -361,6 +408,7 @@ export const parseAsyncApiSpec = async (
|
|
|
361
408
|
const version = normalized.asyncapi;
|
|
362
409
|
let document: AsyncApiDocument = normalized;
|
|
363
410
|
if (!version.startsWith("3.")) {
|
|
411
|
+
const { convert } = await loadConverter(spec, version, root);
|
|
364
412
|
// The converter reports lossy conversions (e.g. a 2.x parameter schema
|
|
365
413
|
// that 3.0 can't express) through console.warn — capture those as spec
|
|
366
414
|
// warnings instead of letting them leak into CLI output.
|
|
@@ -374,7 +422,7 @@ export const parseAsyncApiSpec = async (
|
|
|
374
422
|
// the 3.0 shape the extractor consumes; the two packages just declare
|
|
375
423
|
// the document type differently.
|
|
376
424
|
document = convert(
|
|
377
|
-
document as
|
|
425
|
+
document as Parameters<typeof convert>[0],
|
|
378
426
|
"3.0.0"
|
|
379
427
|
) as AsyncApiDocument;
|
|
380
428
|
} catch (error) {
|
package/src/openapi/proxy.ts
CHANGED
|
@@ -1,16 +1,19 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* The playground's CORS proxy. Browsers block the "Try it" panel's `fetch`
|
|
3
3
|
* whenever the documented API doesn't allow cross-origin requests from the
|
|
4
|
-
* docs site, so `
|
|
4
|
+
* docs site, so `playground: { proxy: true }` on an `openapi()` reference
|
|
5
|
+
* mounts this handler at
|
|
5
6
|
* `/_api-proxy` (server output only) and the client sends its real request
|
|
6
7
|
* here as `?url=<encoded target>` instead. The handler replays the request
|
|
7
8
|
* upstream and mirrors the response back, so the browser only ever talks
|
|
8
9
|
* same-origin.
|
|
9
10
|
*
|
|
10
|
-
* Kept dependency-
|
|
11
|
+
* Kept dependency-light and `fetch`-injectable so it unit-tests without a
|
|
11
12
|
* network and stays safe to bundle into the generated endpoint file.
|
|
12
13
|
*/
|
|
13
14
|
|
|
15
|
+
import { readCappedBody } from "../core/request-body.ts";
|
|
16
|
+
|
|
14
17
|
/**
|
|
15
18
|
* Request headers never forwarded upstream: hop-by-hop headers describe this
|
|
16
19
|
* connection (not the upstream one), `host`/`origin`/`referer` would leak or
|
|
@@ -60,6 +63,38 @@ const MAX_REDIRECTS = 20;
|
|
|
60
63
|
*/
|
|
61
64
|
const UPSTREAM_TIMEOUT_MS = 30_000;
|
|
62
65
|
|
|
66
|
+
/**
|
|
67
|
+
* Largest request body the proxy forwards: 4 MiB, under Vercel's 4.5 MB
|
|
68
|
+
* function limit, so a request that works on one host works on the others.
|
|
69
|
+
* The body is buffered before it's replayed, and a self-hosted Node server
|
|
70
|
+
* has no platform cap of its own, so without this one oversized POST could
|
|
71
|
+
* allocate its whole size in the server's memory.
|
|
72
|
+
*/
|
|
73
|
+
const MAX_BODY_BYTES = 4 * 1024 * 1024;
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Headers every proxied response carries. The proxy serves another host's
|
|
77
|
+
* bytes from the docs origin, so an upstream HTML page — an error page that
|
|
78
|
+
* echoes its input, say — would otherwise run script as the docs site for
|
|
79
|
+
* anyone who opens a crafted `/_api-proxy?url=…` link. `sandbox` gives such a
|
|
80
|
+
* page an opaque origin with scripts off, `nosniff` stops a mistyped body
|
|
81
|
+
* being rendered as HTML, and `same-origin` keeps other sites from embedding
|
|
82
|
+
* the responses. None of them affect the playground's own `fetch`.
|
|
83
|
+
*/
|
|
84
|
+
const RESPONSE_SECURITY_HEADERS = {
|
|
85
|
+
"Content-Security-Policy": "sandbox; default-src 'none'",
|
|
86
|
+
"Cross-Origin-Resource-Policy": "same-origin",
|
|
87
|
+
"X-Content-Type-Options": "nosniff",
|
|
88
|
+
} satisfies Record<string, string>;
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Media types a browser would render as a document when the proxy URL is
|
|
92
|
+
* opened directly. Their responses are also marked as downloads, so even a
|
|
93
|
+
* browser that ignores the sandbox saves the page instead of showing it.
|
|
94
|
+
*/
|
|
95
|
+
const DOCUMENT_TYPE =
|
|
96
|
+
/^\s*(?:text\/html|application\/xhtml\+xml|image\/svg\+xml)\b/iu;
|
|
97
|
+
|
|
63
98
|
/** A 400 the playground client can render verbatim. */
|
|
64
99
|
const badRequest = (error: string): Response =>
|
|
65
100
|
Response.json({ error }, { status: 400 });
|
|
@@ -99,7 +134,7 @@ const forbidden = (origin: string): Response =>
|
|
|
99
134
|
*/
|
|
100
135
|
const followUpstream = async (args: {
|
|
101
136
|
allowed: ReadonlySet<string>;
|
|
102
|
-
body: ArrayBuffer | undefined;
|
|
137
|
+
body: Uint8Array<ArrayBuffer> | undefined;
|
|
103
138
|
fetchImpl: typeof fetch;
|
|
104
139
|
headers: Headers;
|
|
105
140
|
/** Hops already followed; the chain is bounded by {@link MAX_REDIRECTS}. */
|
|
@@ -166,12 +201,15 @@ const followUpstream = async (args: {
|
|
|
166
201
|
*
|
|
167
202
|
* `timeoutMs` bounds the upstream exchange (see {@link UPSTREAM_TIMEOUT_MS});
|
|
168
203
|
* an upstream that doesn't answer in time is the same 502 as an unreachable
|
|
169
|
-
* one. Injectable so tests don't wait out the real deadline.
|
|
204
|
+
* one. Injectable so tests don't wait out the real deadline. A request body
|
|
205
|
+
* over `maxBodyBytes` (see {@link MAX_BODY_BYTES}) is a 413, and every
|
|
206
|
+
* mirrored response carries {@link RESPONSE_SECURITY_HEADERS}.
|
|
170
207
|
*/
|
|
171
208
|
export const createPlaygroundProxyHandler = (
|
|
172
209
|
origins: readonly string[],
|
|
173
210
|
fetchImpl: typeof fetch = fetch,
|
|
174
|
-
timeoutMs = UPSTREAM_TIMEOUT_MS
|
|
211
|
+
timeoutMs = UPSTREAM_TIMEOUT_MS,
|
|
212
|
+
maxBodyBytes = MAX_BODY_BYTES
|
|
175
213
|
) => {
|
|
176
214
|
const allowed = new Set(origins);
|
|
177
215
|
return async (request: Request): Promise<Response> => {
|
|
@@ -194,11 +232,19 @@ export const createPlaygroundProxyHandler = (
|
|
|
194
232
|
|
|
195
233
|
// Buffer the body instead of streaming it: GET/HEAD must not carry one
|
|
196
234
|
// (fetch rejects it), and a buffered body avoids the `duplex` requirement
|
|
197
|
-
// streaming request bodies have in Node.
|
|
198
|
-
const
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
235
|
+
// streaming request bodies have in Node. The buffer is capped.
|
|
236
|
+
const bodyless = request.method === "GET" || request.method === "HEAD";
|
|
237
|
+
const body = bodyless
|
|
238
|
+
? undefined
|
|
239
|
+
: await readCappedBody(request, maxBodyBytes);
|
|
240
|
+
if (!bodyless && body === undefined) {
|
|
241
|
+
return Response.json(
|
|
242
|
+
{
|
|
243
|
+
error: `The request body is larger than the ${maxBodyBytes}-byte limit the docs proxy forwards.`,
|
|
244
|
+
},
|
|
245
|
+
{ status: 413 }
|
|
246
|
+
);
|
|
247
|
+
}
|
|
202
248
|
|
|
203
249
|
let upstream: Response;
|
|
204
250
|
try {
|
|
@@ -233,6 +279,12 @@ export const createPlaygroundProxyHandler = (
|
|
|
233
279
|
// Marks proxied responses so the client (and debugging humans) can tell
|
|
234
280
|
// them apart from direct responses.
|
|
235
281
|
headers.set("x-blume-proxy", "1");
|
|
282
|
+
for (const [name, value] of Object.entries(RESPONSE_SECURITY_HEADERS)) {
|
|
283
|
+
headers.set(name, value);
|
|
284
|
+
}
|
|
285
|
+
if (DOCUMENT_TYPE.test(headers.get("content-type") ?? "")) {
|
|
286
|
+
headers.set("Content-Disposition", "attachment");
|
|
287
|
+
}
|
|
236
288
|
return new Response(upstream.body, {
|
|
237
289
|
headers,
|
|
238
290
|
status: upstream.status,
|