blume 1.7.3 → 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 +217 -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-rqy0s5wh.js → chunk-1w8dp3qb.js} +17 -16
- package/dist/cli/{chunk-rqy0s5wh.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-5g0w1e2c.js → chunk-6k8vp3ta.js} +25 -13
- package/dist/cli/{chunk-5g0w1e2c.js.map → chunk-6k8vp3ta.js.map} +4 -4
- package/dist/cli/{chunk-5qk08vmp.js → chunk-79njf86q.js} +133 -54
- package/dist/cli/chunk-79njf86q.js.map +11 -0
- package/dist/cli/{chunk-e7f42gdj.js → chunk-7ez8ny0t.js} +2 -2
- package/dist/cli/{chunk-nn13znc2.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-b27xqwn9.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-0xjyb285.js → chunk-bw22s759.js} +15 -5
- package/dist/cli/{chunk-0xjyb285.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-ahnw3kxw.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-vacwm2hv.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-cjtn640a.js → chunk-fh5hj5jt.js} +43 -20
- package/dist/cli/chunk-fh5hj5jt.js.map +10 -0
- package/dist/cli/{chunk-yg63d42r.js → chunk-j8mw0za6.js} +86 -57
- package/dist/cli/chunk-j8mw0za6.js.map +35 -0
- package/dist/cli/{chunk-ct47dqpx.js → chunk-jts8mvcz.js} +67 -7
- package/dist/cli/{chunk-2mzebbbz.js.map → chunk-jts8mvcz.js.map} +6 -4
- package/dist/cli/{chunk-ps4m1xh4.js → chunk-mnqj32sj.js} +505 -542
- package/dist/cli/chunk-mnqj32sj.js.map +12 -0
- package/dist/cli/{chunk-8cjtbafj.js → chunk-mwt1k8n7.js} +100 -374
- 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-3r45185y.js → chunk-pat2zzwc.js} +9 -11
- package/dist/cli/{chunk-3r45185y.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-4x36ddpw.js → chunk-sqn5t4q0.js} +81 -87
- package/dist/cli/chunk-sqn5t4q0.js.map +10 -0
- package/dist/cli/{chunk-bvwwhd84.js → chunk-tzne8qfq.js} +15 -15
- package/dist/cli/{chunk-bvwwhd84.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-k79xp7av.js → chunk-z1f5arsg.js} +219 -689
- package/dist/cli/chunk-z1f5arsg.js.map +36 -0
- package/dist/cli/{chunk-1jefwnfs.js → chunk-zg2gtj10.js} +1076 -2592
- package/dist/cli/chunk-zg2gtj10.js.map +35 -0
- package/dist/cli/{chunk-dwgcp5sm.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 +186 -515
- 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 +27 -12
- 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 +2282 -452
- 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 +15 -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 +162 -61
- package/docs/configuration/customization.mdx +15 -9
- package/docs/configuration/index.mdx +50 -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 +35 -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 +9 -7
- package/docs/content/sources.mdx +145 -50
- package/docs/content/syntax.mdx +16 -12
- package/docs/content/versioning.mdx +3 -3
- package/docs/discoverability/agent-discovery.mdx +11 -11
- package/docs/discoverability/index.mdx +4 -4
- 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 +21 -22
- package/src/ai/ai-catalog.ts +50 -32
- 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 +7 -6
- package/src/ai/llms.ts +20 -15
- package/src/ai/markdown.ts +35 -5
- package/src/ai/mcp/data.ts +9 -5
- 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 +112 -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 -316
- 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 +25 -2
- 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 -66
- package/src/components/layout/Search.astro +30 -6
- package/src/components/layout/WebMcp.astro +1 -1
- package/src/components/layout/analytics-client.ts +72 -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 +188 -553
- package/src/core/config.ts +130 -41
- package/src/core/custom-pages.ts +105 -0
- package/src/core/data.ts +31 -12
- 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 +115 -16
- 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 +517 -739
- 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 +15 -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 +55 -27
- package/src/deploy/cloudflare-negotiation.ts +179 -100
- package/src/deploy/function-bundle.ts +18 -3
- package/src/deploy/headers.ts +124 -23
- 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 +2 -2
- 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 +8 -4
- 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 +24 -2
- package/src/translate/report.ts +40 -7
- package/src/upgrade/upgrade.ts +499 -0
- package/dist/cli/chunk-0qymqwzz.js +0 -164
- package/dist/cli/chunk-0qymqwzz.js.map +0 -15
- package/dist/cli/chunk-1jefwnfs.js.map +0 -48
- package/dist/cli/chunk-2mzebbbz.js +0 -69
- package/dist/cli/chunk-2z47ypj8.js.map +0 -11
- package/dist/cli/chunk-4x36ddpw.js.map +0 -11
- package/dist/cli/chunk-5093q3n7.js +0 -68
- package/dist/cli/chunk-5093q3n7.js.map +0 -10
- package/dist/cli/chunk-5qk08vmp.js.map +0 -11
- package/dist/cli/chunk-7s8hm3b6.js +0 -5347
- package/dist/cli/chunk-7s8hm3b6.js.map +0 -58
- package/dist/cli/chunk-8cjtbafj.js.map +0 -13
- package/dist/cli/chunk-97r59kpr.js +0 -381
- package/dist/cli/chunk-97r59kpr.js.map +0 -12
- package/dist/cli/chunk-ahnw3kxw.js.map +0 -15
- package/dist/cli/chunk-b27xqwn9.js.map +0 -10
- package/dist/cli/chunk-bf6bt1xt.js +0 -185
- package/dist/cli/chunk-bf6bt1xt.js.map +0 -11
- package/dist/cli/chunk-cjtn640a.js.map +0 -10
- package/dist/cli/chunk-ct47dqpx.js.map +0 -11
- package/dist/cli/chunk-esphfr8p.js +0 -107
- package/dist/cli/chunk-esphfr8p.js.map +0 -11
- package/dist/cli/chunk-ex56aa81.js +0 -1016
- package/dist/cli/chunk-ex56aa81.js.map +0 -13
- package/dist/cli/chunk-garjf5z9.js +0 -30
- package/dist/cli/chunk-garjf5z9.js.map +0 -10
- package/dist/cli/chunk-js7saxwm.js +0 -1045
- package/dist/cli/chunk-js7saxwm.js.map +0 -22
- package/dist/cli/chunk-k79xp7av.js.map +0 -39
- package/dist/cli/chunk-ps4m1xh4.js.map +0 -15
- package/dist/cli/chunk-q4rae3bg.js +0 -60
- package/dist/cli/chunk-q4rae3bg.js.map +0 -10
- package/dist/cli/chunk-rz9jmfhz.js +0 -108
- package/dist/cli/chunk-rz9jmfhz.js.map +0 -10
- package/dist/cli/chunk-vh9w1sgp.js +0 -73
- package/dist/cli/chunk-vh9w1sgp.js.map +0 -10
- package/dist/cli/chunk-vrfp10qk.js +0 -81
- package/dist/cli/chunk-vrfp10qk.js.map +0 -10
- package/dist/cli/chunk-yg63d42r.js.map +0 -34
- 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-e7f42gdj.js.map → chunk-7ez8ny0t.js.map} +0 -0
- /package/dist/cli/{chunk-nn13znc2.js.map → chunk-88cpgt6h.js.map} +0 -0
- /package/dist/cli/{chunk-vacwm2hv.js.map → chunk-f7t03s3g.js.map} +0 -0
- /package/dist/cli/{chunk-dwgcp5sm.js.map → chunk-zxccj738.js.map} +0 -0
package/src/cli/lazy-command.ts
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
import type { ArgsDef, CommandDef, CommandMeta } from "citty";
|
|
2
2
|
|
|
3
|
+
import { BlumeError } from "../core/diagnostics.ts";
|
|
4
|
+
import { reportInternalError } from "./internal-error.ts";
|
|
5
|
+
import { reportDiagnostics } from "./log.ts";
|
|
6
|
+
import {
|
|
7
|
+
COMMAND_HANDLED_FLAGS,
|
|
8
|
+
unknownFlags,
|
|
9
|
+
unknownFlagsDiagnostic,
|
|
10
|
+
} from "./unknown-flags.ts";
|
|
11
|
+
|
|
3
12
|
/**
|
|
4
13
|
* Wrap a command so its module is imported only when citty needs its `args`
|
|
5
14
|
* or runs it. `meta` stays static (from `command-meta.ts`), so rendering root
|
|
@@ -11,6 +20,12 @@ import type { ArgsDef, CommandDef, CommandMeta } from "citty";
|
|
|
11
20
|
*
|
|
12
21
|
* Only `args`, `setup`, `run`, and `cleanup` are forwarded: no Blume command
|
|
13
22
|
* declares `default`, `plugins`, or nested `subCommands`.
|
|
23
|
+
*
|
|
24
|
+
* Two behaviors every command shares live here rather than in each command:
|
|
25
|
+
* `setup` rejects flags the command doesn't declare (citty accepts and drops
|
|
26
|
+
* them, so `blume build --isolatd` would run a real, non-isolated build), and
|
|
27
|
+
* `run` reports a {@link BlumeError} a command lets escape — a config that
|
|
28
|
+
* fails validation, say — as its diagnostic instead of citty's raw stack dump.
|
|
14
29
|
*/
|
|
15
30
|
export const lazyCommand = <Args extends ArgsDef, Key extends string>(
|
|
16
31
|
meta: CommandMeta,
|
|
@@ -21,6 +36,7 @@ export const lazyCommand = <Args extends ArgsDef, Key extends string>(
|
|
|
21
36
|
const module = await load();
|
|
22
37
|
return module[key];
|
|
23
38
|
};
|
|
39
|
+
const name = meta.name ?? key;
|
|
24
40
|
return {
|
|
25
41
|
args: async () => {
|
|
26
42
|
const { args } = await command();
|
|
@@ -37,10 +53,30 @@ export const lazyCommand = <Args extends ArgsDef, Key extends string>(
|
|
|
37
53
|
meta,
|
|
38
54
|
run: async (context) => {
|
|
39
55
|
const loaded = await command();
|
|
40
|
-
|
|
56
|
+
try {
|
|
57
|
+
await loaded.run?.(context);
|
|
58
|
+
} catch (error) {
|
|
59
|
+
if (error instanceof BlumeError) {
|
|
60
|
+
reportDiagnostics([error.diagnostic], process.cwd());
|
|
61
|
+
} else {
|
|
62
|
+
reportInternalError(error);
|
|
63
|
+
}
|
|
64
|
+
process.exit(1);
|
|
65
|
+
}
|
|
41
66
|
},
|
|
42
67
|
setup: async (context) => {
|
|
43
68
|
const loaded = await command();
|
|
69
|
+
// SAFETY: as for `args` above, every command's `args` is a plain object.
|
|
70
|
+
const argsDef = (loaded.args ?? {}) as ArgsDef;
|
|
71
|
+
const unknown = unknownFlags(
|
|
72
|
+
context.rawArgs,
|
|
73
|
+
argsDef,
|
|
74
|
+
COMMAND_HANDLED_FLAGS.get(name)
|
|
75
|
+
);
|
|
76
|
+
if (unknown.length > 0) {
|
|
77
|
+
reportDiagnostics([unknownFlagsDiagnostic(name, unknown, argsDef)]);
|
|
78
|
+
process.exit(1);
|
|
79
|
+
}
|
|
44
80
|
await loaded.setup?.(context);
|
|
45
81
|
},
|
|
46
82
|
};
|
package/src/cli/prepare.ts
CHANGED
|
@@ -11,11 +11,19 @@ import { loadEnvFiles } from "./env.ts";
|
|
|
11
11
|
import { reportInternalError } from "./internal-error.ts";
|
|
12
12
|
import { logger, reportDiagnostics } from "./log.ts";
|
|
13
13
|
import { checkRequiredSecrets } from "./required-secrets.ts";
|
|
14
|
+
import { yarnPnpDiagnostic } from "./yarn-pnp.ts";
|
|
14
15
|
|
|
15
16
|
export interface PrepareOptions {
|
|
16
17
|
root: string;
|
|
17
18
|
mode?: BuildMode;
|
|
18
19
|
strict?: boolean;
|
|
20
|
+
/**
|
|
21
|
+
* Whether the command is strict only on request (`blume check --strict`),
|
|
22
|
+
* which changes how the abort message says to continue. Defaults to true in
|
|
23
|
+
* dev mode (`blume dev`, `blume sync`) and false otherwise, where strict is
|
|
24
|
+
* the default a user turns off with `--no-strict` (`blume build`).
|
|
25
|
+
*/
|
|
26
|
+
strictOptIn?: boolean;
|
|
19
27
|
/** Local dev server URL, used as the `deployment.site` fallback (dev only). */
|
|
20
28
|
devServerUrl?: string;
|
|
21
29
|
/** Render drafts and fetch unpublished CMS content. */
|
|
@@ -35,6 +43,14 @@ export interface PrepareOptions {
|
|
|
35
43
|
export const prepareProject = async (
|
|
36
44
|
options: PrepareOptions
|
|
37
45
|
): Promise<BlumeProject> => {
|
|
46
|
+
// Under Yarn Plug'n'Play the generated runtime can't resolve anything; say
|
|
47
|
+
// so before scanning, instead of failing inside Astro's config load.
|
|
48
|
+
const pnp = yarnPnpDiagnostic(options.root);
|
|
49
|
+
if (pnp) {
|
|
50
|
+
reportDiagnostics([pnp], options.root);
|
|
51
|
+
process.exit(1);
|
|
52
|
+
}
|
|
53
|
+
|
|
38
54
|
// Load `.env` files from the project root before the scan: remote sources
|
|
39
55
|
// read their tokens from `process.env` during `scanProject`, and
|
|
40
56
|
// `loadEnvFiles` never overrides variables that are already set.
|
|
@@ -62,18 +78,23 @@ export const prepareProject = async (
|
|
|
62
78
|
// Hard gate: server-only features cannot ship in a static build.
|
|
63
79
|
if (
|
|
64
80
|
options.mode === "build" &&
|
|
65
|
-
project.config.deployment.output === "static"
|
|
81
|
+
project.config.deployment.options.output === "static"
|
|
66
82
|
) {
|
|
67
83
|
const features = serverFeatures(project.config);
|
|
68
84
|
if (features.length > 0) {
|
|
85
|
+
// A host adapter already names the target, so only its
|
|
86
|
+
// `output: "static"` stands in the way; otherwise name one.
|
|
87
|
+
const { kind } = project.config.deployment;
|
|
69
88
|
reportDiagnostics(
|
|
70
89
|
[
|
|
71
90
|
{
|
|
72
91
|
code: "BLUME_SERVER_FEATURE_REQUIRED",
|
|
73
|
-
message: `${features.join(", ")} require server output, but
|
|
92
|
+
message: `${features.join(", ")} ${features.length === 1 ? "requires" : "require"} server output, but this is a static build.`,
|
|
74
93
|
severity: "error",
|
|
75
94
|
suggestion:
|
|
76
|
-
|
|
95
|
+
kind === "static"
|
|
96
|
+
? 'Set deployment to a host adapter from "blume/deploy" in blume.config.ts, e.g. `deployment: vercel()`.'
|
|
97
|
+
: `Drop \`output: "static"\` from \`deployment: ${kind}()\` in blume.config.ts to build for the server.`,
|
|
77
98
|
},
|
|
78
99
|
],
|
|
79
100
|
options.root
|
|
@@ -87,19 +108,32 @@ export const prepareProject = async (
|
|
|
87
108
|
project.droppedPages > 0
|
|
88
109
|
? `${project.droppedPages} page(s) failed frontmatter validation and were dropped from the site. `
|
|
89
110
|
: "";
|
|
111
|
+
const optIn = options.strictOptIn ?? options.mode === "dev";
|
|
90
112
|
if (hadErrors && options.strict) {
|
|
91
113
|
logger.error(
|
|
92
|
-
`Aborting due to errors. ${dropped}Fix the diagnostics above, or pass --no-strict to continue despite them.`
|
|
114
|
+
`Aborting due to errors. ${dropped}Fix the diagnostics above, or ${optIn ? "drop --strict" : "pass --no-strict"} to continue despite them.`
|
|
93
115
|
);
|
|
94
116
|
process.exit(1);
|
|
95
117
|
}
|
|
96
118
|
if (hasErrors(project.diagnostics) && !options.strict) {
|
|
97
119
|
logger.warn(
|
|
98
|
-
`Continuing despite errors. ${dropped}
|
|
120
|
+
`Continuing despite errors. ${dropped}${optIn ? "Pass --strict" : "Drop --no-strict"} to fail instead.`
|
|
99
121
|
);
|
|
100
122
|
}
|
|
101
123
|
|
|
102
|
-
|
|
124
|
+
let warnings: string[];
|
|
125
|
+
try {
|
|
126
|
+
({ warnings } = await generateRuntime(project));
|
|
127
|
+
} catch (error) {
|
|
128
|
+
// A config error the generator raised (an unplannable `components.ts`
|
|
129
|
+
// override, a missing font file) is the user's to fix, not an internal
|
|
130
|
+
// failure: report the diagnostic and stop, like a scan-time error.
|
|
131
|
+
if (error instanceof BlumeError) {
|
|
132
|
+
reportDiagnostics([error.diagnostic], options.root);
|
|
133
|
+
process.exit(1);
|
|
134
|
+
}
|
|
135
|
+
throw error;
|
|
136
|
+
}
|
|
103
137
|
for (const warning of warnings) {
|
|
104
138
|
logger.warn(warning);
|
|
105
139
|
}
|
|
@@ -25,20 +25,47 @@ export const checkRequiredSecrets = (config: ResolvedConfig): Diagnostic[] => {
|
|
|
25
25
|
};
|
|
26
26
|
|
|
27
27
|
if (config.ai.ask?.enabled && !config.ai.ask.endpoint) {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
"on Vercel the gateway can also authenticate via OIDC"
|
|
34
|
-
);
|
|
35
|
-
} else {
|
|
36
|
-
requireSecret("Ask AI", backend.apiKeyEnv);
|
|
28
|
+
// The adapter descriptor names the env vars its route reads.
|
|
29
|
+
const { provider } = config.ai.ask;
|
|
30
|
+
const backend = resolveAskBackend(provider);
|
|
31
|
+
for (const env of provider.requiredSecrets) {
|
|
32
|
+
requireSecret(`Ask AI (${backend.label})`, env, backend.secretNote);
|
|
37
33
|
}
|
|
38
34
|
}
|
|
39
35
|
|
|
40
|
-
|
|
41
|
-
|
|
36
|
+
// Each search adapter declares the secrets its generated runtime reads.
|
|
37
|
+
const { provider } = config.search;
|
|
38
|
+
for (const env of provider.requiredSecrets) {
|
|
39
|
+
requireSecret(`Search (${provider.kind})`, env);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Adapters name their own secrets; the built-in analytics adapters ship
|
|
43
|
+
// public tokens in the page and declare none.
|
|
44
|
+
for (const adapter of config.analytics) {
|
|
45
|
+
for (const env of adapter.requiredSecrets) {
|
|
46
|
+
requireSecret(`Analytics (${adapter.kind})`, env);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// Each content source adapter declares the env vars its fetch reads.
|
|
51
|
+
for (const source of config.content.sources) {
|
|
52
|
+
for (const env of source.requiredSecrets) {
|
|
53
|
+
requireSecret(`Content source (${source.kind})`, env);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// Adapters name their own secrets; the built-in reference adapters read
|
|
58
|
+
// public specs and declare none.
|
|
59
|
+
for (const adapter of config.reference) {
|
|
60
|
+
for (const env of adapter.requiredSecrets) {
|
|
61
|
+
requireSecret(`API reference (${adapter.kind})`, env);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// The deployment adapter names its own secrets; the built-in host adapters
|
|
66
|
+
// read platform-injected env and declare none.
|
|
67
|
+
for (const env of config.deployment.requiredSecrets) {
|
|
68
|
+
requireSecret(`Deployment (${config.deployment.kind})`, env);
|
|
42
69
|
}
|
|
43
70
|
|
|
44
71
|
return diagnostics;
|
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
import type { ArgsDef } from "citty";
|
|
2
|
+
|
|
3
|
+
import type { Diagnostic } from "../core/types.ts";
|
|
4
|
+
|
|
5
|
+
/** A flag the command doesn't declare, with the declared one it most resembles. */
|
|
6
|
+
export interface UnknownFlag {
|
|
7
|
+
/** The flag as typed, without any `=value`. */
|
|
8
|
+
flag: string;
|
|
9
|
+
/** The closest declared flag (`--isolated` for `--isolatd`), if one is close. */
|
|
10
|
+
suggestion?: string;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/** What a declared option spelling means for the token that follows it. */
|
|
14
|
+
interface KnownFlag {
|
|
15
|
+
/** Whether it's a boolean switch, which `--no-<name>` turns off. */
|
|
16
|
+
boolean: boolean;
|
|
17
|
+
/**
|
|
18
|
+
* How the flags a command takes list it: `--kebab-name`, or `--no-<name>`
|
|
19
|
+
* for a boolean that's on by default, since that's the form anyone types.
|
|
20
|
+
*/
|
|
21
|
+
display: string;
|
|
22
|
+
/** The canonical kebab-case name, which typos are matched against. */
|
|
23
|
+
name: string;
|
|
24
|
+
/** Whether it reads the next token as its value (`--port 4000`). */
|
|
25
|
+
takesValue: boolean;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/** `budgetJs` → `budget-js`; a name already in kebab case is unchanged. */
|
|
29
|
+
const kebabCase = (name: string): string =>
|
|
30
|
+
name.replaceAll(/(?<upper>[A-Z])/gu, (letter) => `-${letter.toLowerCase()}`);
|
|
31
|
+
|
|
32
|
+
/** `budget-js` → `budgetJs`; a name already in camel case is unchanged. */
|
|
33
|
+
const camelCase = (name: string): string =>
|
|
34
|
+
name.replaceAll(/-(?<letter>[a-z])/gu, (match) =>
|
|
35
|
+
match.slice(1).toUpperCase()
|
|
36
|
+
);
|
|
37
|
+
|
|
38
|
+
const aliasesOf = (alias: string | string[] | undefined): string[] => {
|
|
39
|
+
if (alias === undefined) {
|
|
40
|
+
return [];
|
|
41
|
+
}
|
|
42
|
+
return Array.isArray(alias) ? alias : [alias];
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Every spelling citty accepts for each declared option — the name, its camel
|
|
47
|
+
* and kebab forms, and its aliases — mapped to what that option is. Positional
|
|
48
|
+
* arguments aren't flags and don't appear.
|
|
49
|
+
*/
|
|
50
|
+
const knownFlags = (argsDef: ArgsDef): Map<string, KnownFlag> => {
|
|
51
|
+
const flags = new Map<string, KnownFlag>();
|
|
52
|
+
for (const [name, def] of Object.entries(argsDef)) {
|
|
53
|
+
if (def.type === "positional") {
|
|
54
|
+
continue;
|
|
55
|
+
}
|
|
56
|
+
const kebab = kebabCase(name);
|
|
57
|
+
const boolean = def.type === "boolean";
|
|
58
|
+
const onByDefault = boolean && "default" in def && def.default === true;
|
|
59
|
+
const flag = {
|
|
60
|
+
boolean,
|
|
61
|
+
display: onByDefault ? `--no-${kebab}` : `--${kebab}`,
|
|
62
|
+
name: kebab,
|
|
63
|
+
takesValue: def.type === "string" || def.type === "enum",
|
|
64
|
+
};
|
|
65
|
+
for (const spelling of [
|
|
66
|
+
name,
|
|
67
|
+
kebabCase(name),
|
|
68
|
+
camelCase(name),
|
|
69
|
+
...aliasesOf("alias" in def ? def.alias : undefined),
|
|
70
|
+
]) {
|
|
71
|
+
flags.set(spelling, flag);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
return flags;
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
/** Edit distance between two short strings (insertions, deletions, swaps of one letter). */
|
|
78
|
+
const distance = (from: string, to: string): number => {
|
|
79
|
+
let previous = Array.from({ length: to.length + 1 }, (_, index) => index);
|
|
80
|
+
for (const [row, fromChar] of [...from].entries()) {
|
|
81
|
+
const current = [row + 1];
|
|
82
|
+
for (const [column, toChar] of [...to].entries()) {
|
|
83
|
+
current.push(
|
|
84
|
+
Math.min(
|
|
85
|
+
(previous[column + 1] ?? 0) + 1,
|
|
86
|
+
(current[column] ?? 0) + 1,
|
|
87
|
+
(previous[column] ?? 0) + (fromChar === toChar ? 0 : 1)
|
|
88
|
+
)
|
|
89
|
+
);
|
|
90
|
+
}
|
|
91
|
+
previous = current;
|
|
92
|
+
}
|
|
93
|
+
return previous[to.length] ?? 0;
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* The candidate closest to `name`, when it's close enough to be the likely
|
|
98
|
+
* intent: at most two edits away, and fewer edits than half the candidate's
|
|
99
|
+
* length, so a short typo doesn't "suggest" an unrelated short word.
|
|
100
|
+
*/
|
|
101
|
+
export const closestMatch = (
|
|
102
|
+
name: string,
|
|
103
|
+
candidates: readonly string[]
|
|
104
|
+
): string | undefined => {
|
|
105
|
+
let best: { candidate: string; edits: number } | undefined;
|
|
106
|
+
for (const candidate of candidates) {
|
|
107
|
+
const edits = distance(name, candidate);
|
|
108
|
+
if (
|
|
109
|
+
edits <= 2 &&
|
|
110
|
+
edits * 2 < candidate.length &&
|
|
111
|
+
(best === undefined || edits < best.edits)
|
|
112
|
+
) {
|
|
113
|
+
best = { candidate, edits };
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
return best?.candidate;
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
/** A `--name`, `--no-name`, `--name=value`, or `-n` token, taken apart. */
|
|
120
|
+
interface FlagToken {
|
|
121
|
+
/** Whether it carries its value inline (`--port=4000`). */
|
|
122
|
+
hasValue: boolean;
|
|
123
|
+
/** `--name` rather than `-n`. */
|
|
124
|
+
long: boolean;
|
|
125
|
+
/** The name as typed, without dashes or `=value`. */
|
|
126
|
+
name: string;
|
|
127
|
+
/** The negated flag's name, for a `--no-name` token. */
|
|
128
|
+
negated: string | undefined;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
const parseToken = (arg: string): FlagToken => {
|
|
132
|
+
const long = arg.startsWith("--");
|
|
133
|
+
const [name = ""] = arg.slice(long ? 2 : 1).split("=");
|
|
134
|
+
return {
|
|
135
|
+
hasValue: arg.includes("="),
|
|
136
|
+
long,
|
|
137
|
+
name,
|
|
138
|
+
negated: long && name.startsWith("no-") ? name.slice(3) : undefined,
|
|
139
|
+
};
|
|
140
|
+
};
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* How many tokens after this one a declared flag consumes — one for a string
|
|
144
|
+
* flag's separate value (`--port 4000`, read whatever it looks like, as
|
|
145
|
+
* citty's parser does), none otherwise — or undefined when the token names no
|
|
146
|
+
* declared flag. A negation never reads a value; grouped single-letter
|
|
147
|
+
* booleans (`-ab`) are declared when every letter is.
|
|
148
|
+
*/
|
|
149
|
+
const declaredWidth = (
|
|
150
|
+
token: FlagToken,
|
|
151
|
+
flags: Map<string, KnownFlag>
|
|
152
|
+
): number | undefined => {
|
|
153
|
+
const known =
|
|
154
|
+
flags.get(token.name) ??
|
|
155
|
+
(token.negated === undefined ? undefined : flags.get(token.negated));
|
|
156
|
+
if (known) {
|
|
157
|
+
return known.takesValue && !token.hasValue && token.negated === undefined
|
|
158
|
+
? 1
|
|
159
|
+
: 0;
|
|
160
|
+
}
|
|
161
|
+
const grouped =
|
|
162
|
+
!token.long &&
|
|
163
|
+
token.name.length > 1 &&
|
|
164
|
+
[...token.name].every((letter) => flags.get(letter)?.takesValue === false);
|
|
165
|
+
return grouped ? 0 : undefined;
|
|
166
|
+
};
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* An undeclared token as reported, with the declared flag it most resembles.
|
|
170
|
+
* A mistyped negation keeps its `no-` in the suggestion (`--no-instal` →
|
|
171
|
+
* `--no-install`), so the fix doesn't flip what was asked for; negating a flag
|
|
172
|
+
* that takes a value means nothing, so those suggest the flag itself.
|
|
173
|
+
*/
|
|
174
|
+
const describeUnknown = (
|
|
175
|
+
token: FlagToken,
|
|
176
|
+
flags: Map<string, KnownFlag>
|
|
177
|
+
): UnknownFlag => {
|
|
178
|
+
const unknown: UnknownFlag = {
|
|
179
|
+
flag: `${token.long ? "--" : "-"}${token.name}`,
|
|
180
|
+
};
|
|
181
|
+
const names = [...new Set([...flags.values()].map((flag) => flag.name))];
|
|
182
|
+
const match = closestMatch(token.negated ?? token.name, names);
|
|
183
|
+
if (match) {
|
|
184
|
+
const negate = token.negated !== undefined && flags.get(match)?.boolean;
|
|
185
|
+
unknown.suggestion = negate ? `--no-${match}` : `--${match}`;
|
|
186
|
+
}
|
|
187
|
+
return unknown;
|
|
188
|
+
};
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* The flags in `rawArgs` that the command's `args` don't declare. citty itself
|
|
192
|
+
* accepts any flag and drops the ones it doesn't know, so a typo like
|
|
193
|
+
* `--isolatd` would silently run a different command than the one intended.
|
|
194
|
+
*
|
|
195
|
+
* Mirrors what citty accepts: every spelling from {@link knownFlags}, a
|
|
196
|
+
* `--no-<flag>` negation of any of them, `--flag=value`, a declared string
|
|
197
|
+
* flag's separate value token, grouped single-letter boolean aliases, and
|
|
198
|
+
* everything after a bare `--`. `accepted` names extra flags the command
|
|
199
|
+
* handles itself (the removed `blume build --adapter`, which gets its own
|
|
200
|
+
* migration message).
|
|
201
|
+
*/
|
|
202
|
+
export const unknownFlags = (
|
|
203
|
+
rawArgs: readonly string[],
|
|
204
|
+
argsDef: ArgsDef,
|
|
205
|
+
accepted: readonly string[] = []
|
|
206
|
+
): UnknownFlag[] => {
|
|
207
|
+
const flags = knownFlags(argsDef);
|
|
208
|
+
const unknown: UnknownFlag[] = [];
|
|
209
|
+
for (let index = 0; index < rawArgs.length; index += 1) {
|
|
210
|
+
const arg = rawArgs[index] ?? "";
|
|
211
|
+
if (arg === "--") {
|
|
212
|
+
break;
|
|
213
|
+
}
|
|
214
|
+
if (!arg.startsWith("-") || arg === "-") {
|
|
215
|
+
continue;
|
|
216
|
+
}
|
|
217
|
+
const token = parseToken(arg);
|
|
218
|
+
const width = declaredWidth(token, flags);
|
|
219
|
+
if (width !== undefined) {
|
|
220
|
+
index += width;
|
|
221
|
+
} else if (!accepted.includes(token.negated ?? token.name)) {
|
|
222
|
+
unknown.push(describeUnknown(token, flags));
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
return unknown;
|
|
226
|
+
};
|
|
227
|
+
|
|
228
|
+
/**
|
|
229
|
+
* Flags a command reads from its raw arguments itself instead of declaring
|
|
230
|
+
* them, keyed by command name. `blume build` answers the Blume 1 `--adapter`,
|
|
231
|
+
* `--output`, and `--base` with the `deployment` setting that replaced each,
|
|
232
|
+
* which says more than "unknown option" would.
|
|
233
|
+
*/
|
|
234
|
+
export const COMMAND_HANDLED_FLAGS = new Map([
|
|
235
|
+
["build", ["adapter", "output", "base"]],
|
|
236
|
+
]);
|
|
237
|
+
|
|
238
|
+
/**
|
|
239
|
+
* The error for a command run with flags it doesn't declare: each unknown
|
|
240
|
+
* flag (with its likely intended spelling), then every flag the command does
|
|
241
|
+
* take, so the fix is on screen without a trip to `--help`.
|
|
242
|
+
*/
|
|
243
|
+
export const unknownFlagsDiagnostic = (
|
|
244
|
+
command: string,
|
|
245
|
+
unknown: readonly UnknownFlag[],
|
|
246
|
+
argsDef: ArgsDef
|
|
247
|
+
): Diagnostic => {
|
|
248
|
+
const listed = unknown
|
|
249
|
+
.map(({ flag, suggestion }) =>
|
|
250
|
+
suggestion ? `${flag} (did you mean ${suggestion}?)` : flag
|
|
251
|
+
)
|
|
252
|
+
.join(", ");
|
|
253
|
+
const declared = [
|
|
254
|
+
...new Set([...knownFlags(argsDef).values()].map((flag) => flag.display)),
|
|
255
|
+
].toSorted();
|
|
256
|
+
const takes =
|
|
257
|
+
declared.length > 0
|
|
258
|
+
? `It takes ${declared.join(", ")}.`
|
|
259
|
+
: "It takes no options.";
|
|
260
|
+
return {
|
|
261
|
+
code: "BLUME_UNKNOWN_OPTION",
|
|
262
|
+
message: `blume ${command} doesn't know ${unknown.length === 1 ? "the option" : "the options"} ${listed}.`,
|
|
263
|
+
severity: "error",
|
|
264
|
+
suggestion: `${takes} Run \`blume ${command} --help\` for what each does.`,
|
|
265
|
+
};
|
|
266
|
+
};
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { existsSync } from "node:fs";
|
|
2
|
+
|
|
3
|
+
import { dirname, join } from "pathe";
|
|
4
|
+
|
|
5
|
+
import { packageDirFrom } from "../astro/render-deps.ts";
|
|
6
|
+
import type { Diagnostic } from "../core/types.ts";
|
|
7
|
+
|
|
8
|
+
/** Whether `root` or one of its ancestors holds a Yarn Plug'n'Play manifest. */
|
|
9
|
+
const hasPnpManifest = (root: string): boolean => {
|
|
10
|
+
let dir = root;
|
|
11
|
+
while (true) {
|
|
12
|
+
if (existsSync(join(dir, ".pnp.cjs")) || existsSync(join(dir, ".pnp.js"))) {
|
|
13
|
+
return true;
|
|
14
|
+
}
|
|
15
|
+
const parent = dirname(dir);
|
|
16
|
+
if (parent === dir) {
|
|
17
|
+
return false;
|
|
18
|
+
}
|
|
19
|
+
dir = parent;
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* The diagnostic for a project installed with Yarn Plug'n'Play, or null.
|
|
25
|
+
*
|
|
26
|
+
* Plug'n'Play installs no `node_modules`, and the Astro project Blume
|
|
27
|
+
* generates in `.blume/` imports Astro and Blume's dependencies by name, which
|
|
28
|
+
* only a `node_modules` tree resolves — so under PnP the build dies loading
|
|
29
|
+
* `astro/config`, a failure that reads like a bug in Blume. Caught up front
|
|
30
|
+
* instead: when the command runs under the PnP runtime (`process.versions.pnp`,
|
|
31
|
+
* set by `yarn run`), or when a `.pnp.cjs` manifest sits in the project with no
|
|
32
|
+
* `node_modules` copy of Blume beside it.
|
|
33
|
+
*/
|
|
34
|
+
export const yarnPnpDiagnostic = (
|
|
35
|
+
root: string,
|
|
36
|
+
pnpVersion: string | undefined = process.versions.pnp
|
|
37
|
+
): Diagnostic | null => {
|
|
38
|
+
const underPnp =
|
|
39
|
+
pnpVersion !== undefined ||
|
|
40
|
+
(hasPnpManifest(root) && packageDirFrom("blume", root) === null);
|
|
41
|
+
if (!underPnp) {
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
return {
|
|
45
|
+
code: "BLUME_YARN_PNP",
|
|
46
|
+
message:
|
|
47
|
+
"Yarn Plug'n'Play isn't supported: the Astro project Blume generates in `.blume/` resolves Astro and Blume's dependencies from a `node_modules` folder, which Plug'n'Play doesn't create.",
|
|
48
|
+
severity: "error",
|
|
49
|
+
suggestion:
|
|
50
|
+
"Add `nodeLinker: node-modules` to `.yarnrc.yml`, run `yarn install`, then run this command again.",
|
|
51
|
+
};
|
|
52
|
+
};
|
|
@@ -110,7 +110,13 @@ const accordionId = id ?? componentSlug(title);
|
|
|
110
110
|
return;
|
|
111
111
|
}
|
|
112
112
|
|
|
113
|
-
|
|
113
|
+
// Keep the entry's state: the client router ignores a popstate whose
|
|
114
|
+
// state is null, so Back to this page would change only the URL.
|
|
115
|
+
history.replaceState(
|
|
116
|
+
history.state,
|
|
117
|
+
"",
|
|
118
|
+
`#${encodeURIComponent(accordion.id)}`
|
|
119
|
+
);
|
|
114
120
|
},
|
|
115
121
|
true
|
|
116
122
|
);
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
---
|
|
2
|
+
import { isExternalUrl } from "../../core/base-path.ts";
|
|
3
|
+
import { newTabAttrs } from "../../core/new-tab.ts";
|
|
2
4
|
import {
|
|
3
5
|
ADMONITION_ICON,
|
|
4
6
|
ADMONITION_ICON_CLASS,
|
|
@@ -23,7 +25,7 @@ interface Props {
|
|
|
23
25
|
const { arrow, color, cta, horizontal, href, icon, img, title, type } =
|
|
24
26
|
Astro.props;
|
|
25
27
|
const Tag = href ? "a" : "div";
|
|
26
|
-
const external = href
|
|
28
|
+
const external = href !== undefined && isExternalUrl(href);
|
|
27
29
|
const isHorizontal = horizontal === true || horizontal === "true";
|
|
28
30
|
const showArrow =
|
|
29
31
|
href && arrow === undefined ? external : arrow === true || arrow === "true";
|
|
@@ -51,8 +53,7 @@ const variantClass = {
|
|
|
51
53
|
]}
|
|
52
54
|
data-blume-card
|
|
53
55
|
href={href === undefined ? undefined : contentHref(href)}
|
|
54
|
-
|
|
55
|
-
target={external ? "_blank" : undefined}
|
|
56
|
+
{...newTabAttrs(href)}
|
|
56
57
|
>
|
|
57
58
|
{
|
|
58
59
|
img && (
|
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
---
|
|
2
|
+
import data from "blume:data";
|
|
3
|
+
|
|
4
|
+
import { contentStrings } from "./content-strings.ts";
|
|
5
|
+
|
|
2
6
|
interface ColorValue {
|
|
3
7
|
dark?: string;
|
|
4
8
|
light?: string;
|
|
@@ -17,12 +21,22 @@ const displayValue =
|
|
|
17
21
|
lightValue && darkValue && lightValue !== darkValue
|
|
18
22
|
? `${lightValue} / ${darkValue}`
|
|
19
23
|
: lightValue;
|
|
24
|
+
const { actions: actionStrings, content: strings } = contentStrings(
|
|
25
|
+
data,
|
|
26
|
+
Astro.currentLocale
|
|
27
|
+
);
|
|
28
|
+
const label = strings.copyColor
|
|
29
|
+
.replace("{name}", name)
|
|
30
|
+
.replace("{value}", displayValue ?? "");
|
|
20
31
|
---
|
|
21
32
|
|
|
22
33
|
<button
|
|
23
|
-
aria-label={
|
|
34
|
+
aria-label={label}
|
|
24
35
|
class="group flex w-full cursor-pointer flex-col gap-2.5 text-center focus:outline-none"
|
|
25
|
-
data-blume-color-copy
|
|
36
|
+
data-blume-color-copy
|
|
37
|
+
data-copied={actionStrings.copied}
|
|
38
|
+
data-dark={darkValue}
|
|
39
|
+
data-light={lightValue}
|
|
26
40
|
style={`--blume-color-light:${lightValue};--blume-color-dark:${darkValue};`}
|
|
27
41
|
type="button"
|
|
28
42
|
>
|
|
@@ -69,13 +83,17 @@ const displayValue =
|
|
|
69
83
|
return;
|
|
70
84
|
}
|
|
71
85
|
|
|
72
|
-
|
|
86
|
+
// The value the swatch shows right now: a theme-aware color copies the
|
|
87
|
+
// active theme's value, not the "light / dark" pair it lists.
|
|
88
|
+
const dark = document.documentElement.dataset.theme === "dark";
|
|
89
|
+
const value = (dark ? button.dataset.dark : button.dataset.light) ?? "";
|
|
90
|
+
if (!(await copyText(value))) {
|
|
73
91
|
return;
|
|
74
92
|
}
|
|
75
93
|
|
|
76
94
|
const status = button.querySelector<HTMLElement>("[data-blume-color-status]");
|
|
77
95
|
if (status) {
|
|
78
|
-
flashLabel(status, "Copied");
|
|
96
|
+
flashLabel(status, button.dataset.copied ?? "Copied!");
|
|
79
97
|
}
|
|
80
98
|
});
|
|
81
99
|
}
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
// If the API is unreachable the card still renders, just without counts.
|
|
6
6
|
import { getSecret } from "astro:env/server";
|
|
7
7
|
import { apiUrl, PUBLIC_HOST_URL } from "../../core/github.ts";
|
|
8
|
+
import { NEW_TAB_ATTRS } from "../../core/new-tab.ts";
|
|
8
9
|
import { resolveIcon } from "../../theme/icons.ts";
|
|
9
10
|
import data from "blume:data";
|
|
10
11
|
import { GITHUB_MARK } from "../github-mark.ts";
|
|
@@ -69,8 +70,7 @@ const statIcon =
|
|
|
69
70
|
<a
|
|
70
71
|
class="not-prose my-6 flex flex-col gap-2 rounded-blume border border-border p-4 no-underline! transition-colors hover:border-foreground/30 hover:bg-muted/40"
|
|
71
72
|
href={`${host}/${owner}/${repo}`}
|
|
72
|
-
|
|
73
|
-
target="_blank"
|
|
73
|
+
{...NEW_TAB_ATTRS}
|
|
74
74
|
>
|
|
75
75
|
<span class="flex items-center gap-2 font-medium text-foreground text-sm">
|
|
76
76
|
<svg
|