blume 1.7.3 → 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +19 -0
- package/CHANGELOG.md +245 -0
- package/README.md +34 -21
- package/dist/cli/{chunk-vacwm2hv.js → chunk-27g6wdth.js} +2 -2
- package/dist/cli/{chunk-ps4m1xh4.js → chunk-2hn4b8z7.js} +513 -550
- package/dist/cli/chunk-2hn4b8z7.js.map +12 -0
- package/dist/cli/chunk-5shv93fd.js +39 -0
- package/dist/cli/chunk-5shv93fd.js.map +10 -0
- package/dist/cli/chunk-6crbhc3x.js +361 -0
- package/dist/cli/chunk-6crbhc3x.js.map +14 -0
- package/dist/cli/{chunk-8cjtbafj.js → chunk-6hsn950k.js} +109 -383
- package/dist/cli/chunk-6hsn950k.js.map +10 -0
- package/dist/cli/chunk-6vm74dry.js +148 -0
- package/dist/cli/chunk-6vm74dry.js.map +10 -0
- package/dist/cli/{chunk-yg63d42r.js → chunk-79jhk4py.js} +87 -58
- package/dist/cli/chunk-79jhk4py.js.map +35 -0
- package/dist/cli/chunk-82bbrxdn.js +51 -0
- package/dist/cli/chunk-82bbrxdn.js.map +10 -0
- package/dist/cli/chunk-abh8yjkn.js +31 -0
- package/dist/cli/chunk-abh8yjkn.js.map +10 -0
- package/dist/cli/chunk-ah61y8py.js +75 -0
- package/dist/cli/chunk-ah61y8py.js.map +11 -0
- package/dist/cli/{chunk-dwgcp5sm.js → chunk-ce574jw2.js} +1 -1
- package/dist/cli/chunk-ch6g3ar0.js +102 -0
- package/dist/cli/chunk-ch6g3ar0.js.map +10 -0
- package/dist/cli/chunk-dh8cwk36.js +279 -0
- package/dist/cli/chunk-dh8cwk36.js.map +10 -0
- package/dist/cli/{chunk-rqy0s5wh.js → chunk-epjnccmv.js} +17 -16
- package/dist/cli/{chunk-rqy0s5wh.js.map → chunk-epjnccmv.js.map} +3 -3
- package/dist/cli/chunk-f2z5v128.js +97 -0
- package/dist/cli/chunk-f2z5v128.js.map +10 -0
- package/dist/cli/{chunk-2z47ypj8.js → chunk-fa25z98p.js} +16 -3
- package/dist/cli/chunk-fa25z98p.js.map +11 -0
- package/dist/cli/{chunk-1jefwnfs.js → chunk-fs23ddbb.js} +1076 -2592
- package/dist/cli/chunk-fs23ddbb.js.map +35 -0
- package/dist/cli/{chunk-e7f42gdj.js → chunk-fxypxtvm.js} +2 -2
- package/dist/cli/{chunk-bvwwhd84.js → chunk-fz5wtpmh.js} +15 -15
- package/dist/cli/{chunk-bvwwhd84.js.map → chunk-fz5wtpmh.js.map} +1 -1
- package/dist/cli/chunk-hdpx1tax.js +91 -0
- package/dist/cli/chunk-hdpx1tax.js.map +10 -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-ahnw3kxw.js → chunk-jwyddg7y.js} +27 -22
- package/dist/cli/chunk-jwyddg7y.js.map +15 -0
- package/dist/cli/{chunk-cjtn640a.js → chunk-kdp5q7ke.js} +43 -20
- package/dist/cli/chunk-kdp5q7ke.js.map +10 -0
- package/dist/cli/{chunk-5g0w1e2c.js → chunk-kpf8rrjc.js} +28 -16
- package/dist/cli/{chunk-5g0w1e2c.js.map → chunk-kpf8rrjc.js.map} +4 -4
- package/dist/cli/chunk-m3vmjgmq.js +133 -0
- package/dist/cli/chunk-m3vmjgmq.js.map +10 -0
- package/dist/cli/{chunk-b27xqwn9.js → chunk-mb2919y2.js} +9 -5
- package/dist/cli/chunk-mb2919y2.js.map +10 -0
- package/dist/cli/{chunk-5qk08vmp.js → chunk-q5163e60.js} +133 -54
- package/dist/cli/chunk-q5163e60.js.map +11 -0
- package/dist/cli/chunk-qkqwkpte.js +12437 -0
- package/dist/cli/chunk-qkqwkpte.js.map +182 -0
- package/dist/cli/{chunk-4x36ddpw.js → chunk-qs4q5p4e.js} +81 -87
- package/dist/cli/chunk-qs4q5p4e.js.map +10 -0
- package/dist/cli/{chunk-0xjyb285.js → chunk-qwsrynx5.js} +15 -5
- package/dist/cli/{chunk-0xjyb285.js.map → chunk-qwsrynx5.js.map} +4 -4
- package/dist/cli/chunk-s1p84fyh.js +261 -0
- package/dist/cli/chunk-s1p84fyh.js.map +10 -0
- package/dist/cli/chunk-s6jhgk0q.js +176 -0
- package/dist/cli/chunk-s6jhgk0q.js.map +11 -0
- package/dist/cli/chunk-vtk4a6dg.js +374 -0
- package/dist/cli/chunk-vtk4a6dg.js.map +10 -0
- package/dist/cli/{chunk-k79xp7av.js → chunk-wgm7m9qk.js} +230 -700
- package/dist/cli/chunk-wgm7m9qk.js.map +36 -0
- package/dist/cli/chunk-wm7js3j9.js +145 -0
- package/dist/cli/chunk-wm7js3j9.js.map +11 -0
- package/dist/cli/chunk-yt5n7ppj.js +79 -0
- package/dist/cli/chunk-yt5n7ppj.js.map +10 -0
- package/dist/cli/{chunk-3r45185y.js → chunk-yw7dm696.js} +9 -11
- package/dist/cli/{chunk-3r45185y.js.map → chunk-yw7dm696.js.map} +3 -3
- package/dist/cli/{chunk-nn13znc2.js → chunk-zxcczpyx.js} +1 -1
- package/dist/cli/chunk-zxh4d9vy.js +122 -0
- package/dist/cli/chunk-zxh4d9vy.js.map +11 -0
- 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-context.d.ts +7 -7
- 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 +197 -526
- package/dist/types/core/config.d.ts +61 -35
- 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 +30 -15
- 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 +12 -10
- 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 +2284 -454
- 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/orama-index.d.ts +1 -1
- 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 +52 -28
- package/docs/03-upgrading.mdx +364 -0
- package/docs/04-migrating.mdx +58 -0
- package/docs/08-faq.mdx +5 -5
- package/docs/advanced/blog.mdx +13 -6
- package/docs/advanced/changelog.mdx +23 -35
- package/docs/advanced/custom-pages.mdx +22 -10
- 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} +12 -11
- package/docs/cli/index.mdx +105 -0
- package/docs/cli/meta.ts +7 -0
- package/docs/{reference → cli}/translate.mdx +9 -9
- package/docs/cli/validate.mdx +41 -0
- package/docs/cli/version.mdx +40 -0
- package/docs/configuration/analytics.mdx +350 -59
- package/docs/configuration/assistant.mdx +357 -0
- package/docs/configuration/customization.mdx +16 -10
- package/docs/configuration/index.mdx +50 -31
- package/docs/configuration/meta.ts +1 -1
- package/docs/configuration/search.mdx +76 -55
- 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 +9 -7
- package/docs/content/includes.mdx +2 -4
- package/docs/content/index.mdx +1 -1
- package/docs/content/islands.mdx +11 -6
- 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 +12 -12
- 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 +4 -4
- 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 +23 -10
- 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 +25 -26
- package/src/ai/ai-catalog.ts +50 -32
- package/src/ai/api/handlers.ts +46 -11
- package/src/ai/api/paths.ts +1 -1
- package/src/ai/api-catalog.ts +8 -8
- package/src/ai/ask-context.ts +7 -7
- package/src/ai/ask-data.ts +3 -3
- package/src/ai/ask.ts +637 -100
- package/src/ai/changelog-markdown.ts +91 -0
- package/src/ai/component-markdown.ts +328 -12
- package/src/ai/cors.ts +3 -3
- 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 +5 -2
- package/src/ai/relative-links.ts +170 -0
- package/src/ai/serializers.ts +3 -3
- package/src/ai/skills.ts +1 -1
- package/src/ai/visibility.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 +129 -361
- package/src/astro/integration.ts +2 -6
- package/src/astro/module-types.ts +1 -1
- 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 +575 -562
- 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/blume-modules.d.ts +2 -2
- package/src/cli/command-meta.ts +10 -0
- package/src/cli/commands/audit.ts +40 -21
- 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 +92 -14
- package/src/cli/commands/eject.ts +44 -7
- package/src/cli/commands/eval.ts +5 -5
- 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 +5 -5
- 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 +39 -12
- 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/copy-feedback.ts +1 -1
- package/src/components/islands/{AskAI.astro → Assistant.astro} +10 -10
- package/src/components/islands/{ask-ai.tsx → assistant.tsx} +23 -23
- package/src/components/islands/hooks.ts +36 -11
- 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 +93 -30
- 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 +58 -11
- package/src/components/layout/Pagination.astro +7 -7
- package/src/components/layout/ReferenceLayout.astro +22 -13
- package/src/components/layout/RootLayout.astro +75 -72
- package/src/components/layout/Search.astro +43 -19
- package/src/components/layout/WebMcp.astro +1 -1
- package/src/components/layout/analytics-client.ts +73 -16
- 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/description.ts +2 -2
- package/src/components/openapi/playground-client.ts +79 -10
- package/src/core/changelog-index.ts +24 -0
- package/src/core/code-fences.ts +1 -1
- package/src/core/component-overrides.ts +399 -154
- package/src/core/config-input.ts +201 -566
- package/src/core/config.ts +131 -42
- package/src/core/custom-pages.ts +105 -0
- package/src/core/data.ts +34 -15
- 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 +41 -11
- 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 +528 -745
- package/src/core/server-features.ts +10 -11
- 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 +10 -7
- package/src/core/ui-packs/bg.ts +10 -7
- package/src/core/ui-packs/bn.ts +10 -7
- package/src/core/ui-packs/ca.ts +7 -6
- package/src/core/ui-packs/cs.ts +10 -7
- package/src/core/ui-packs/da.ts +10 -7
- package/src/core/ui-packs/de.ts +10 -7
- package/src/core/ui-packs/el.ts +7 -6
- package/src/core/ui-packs/es.ts +7 -6
- package/src/core/ui-packs/fa.ts +10 -7
- package/src/core/ui-packs/fi.ts +10 -7
- package/src/core/ui-packs/fr.ts +7 -6
- package/src/core/ui-packs/he.ts +10 -7
- package/src/core/ui-packs/hi.ts +10 -7
- package/src/core/ui-packs/hr.ts +10 -7
- package/src/core/ui-packs/hu.ts +10 -7
- package/src/core/ui-packs/id.ts +10 -7
- package/src/core/ui-packs/it.ts +7 -6
- package/src/core/ui-packs/ja.ts +7 -6
- package/src/core/ui-packs/ko.ts +7 -6
- package/src/core/ui-packs/nl.ts +10 -7
- package/src/core/ui-packs/no.ts +10 -7
- package/src/core/ui-packs/pl.ts +10 -7
- package/src/core/ui-packs/pt-br.ts +7 -6
- package/src/core/ui-packs/pt.ts +7 -6
- package/src/core/ui-packs/ro.ts +10 -7
- package/src/core/ui-packs/ru.ts +10 -7
- package/src/core/ui-packs/sk.ts +10 -7
- package/src/core/ui-packs/sr.ts +10 -7
- package/src/core/ui-packs/sv.ts +10 -7
- package/src/core/ui-packs/th.ts +7 -6
- package/src/core/ui-packs/tr.ts +10 -7
- package/src/core/ui-packs/uk.ts +10 -7
- package/src/core/ui-packs/vi.ts +7 -6
- package/src/core/ui-packs/zh-tw.ts +7 -6
- package/src/core/ui-packs/zh.ts +7 -6
- 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 +109 -53
- 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 +8 -2
- package/src/search/orama-index.ts +1 -1
- 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/configuration/ask-ai.mdx +0 -256
- 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-vacwm2hv.js.map → chunk-27g6wdth.js.map} +0 -0
- /package/dist/cli/{chunk-dwgcp5sm.js.map → chunk-ce574jw2.js.map} +0 -0
- /package/dist/cli/{chunk-e7f42gdj.js.map → chunk-fxypxtvm.js.map} +0 -0
- /package/dist/cli/{chunk-nn13znc2.js.map → chunk-zxcczpyx.js.map} +0 -0
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Search adapters for `blume.config.ts`:
|
|
3
|
+
*
|
|
4
|
+
* ```ts
|
|
5
|
+
* import { defineConfig } from "blume";
|
|
6
|
+
* import { algolia } from "blume/search";
|
|
7
|
+
*
|
|
8
|
+
* export default defineConfig({
|
|
9
|
+
* search: algolia({ appId: "…", apiKey: "…", indexName: "docs" }),
|
|
10
|
+
* });
|
|
11
|
+
* ```
|
|
12
|
+
*
|
|
13
|
+
* Each factory returns a plain, JSON-serializable descriptor — never a live
|
|
14
|
+
* client — that the generated runtime inlines as a literal.
|
|
15
|
+
*/
|
|
16
|
+
export { algolia } from "./algolia.ts";
|
|
17
|
+
export type { AlgoliaAdapter, AlgoliaOptions } from "./algolia.ts";
|
|
18
|
+
export { flexsearch } from "./flexsearch.ts";
|
|
19
|
+
export type { FlexsearchAdapter, FlexsearchOptions } from "./flexsearch.ts";
|
|
20
|
+
export { mixedbread } from "./mixedbread.ts";
|
|
21
|
+
export type { MixedbreadAdapter, MixedbreadOptions } from "./mixedbread.ts";
|
|
22
|
+
export { orama } from "./orama.ts";
|
|
23
|
+
export type { OramaAdapter, OramaOptions } from "./orama.ts";
|
|
24
|
+
export { oramaCloud } from "./orama-cloud.ts";
|
|
25
|
+
export type { OramaCloudAdapter, OramaCloudOptions } from "./orama-cloud.ts";
|
|
26
|
+
export { pagefind } from "./pagefind.ts";
|
|
27
|
+
export type { PagefindAdapter, PagefindOptions } from "./pagefind.ts";
|
|
28
|
+
export type {
|
|
29
|
+
AnySearchAdapter,
|
|
30
|
+
ResolvedSearchAdapter,
|
|
31
|
+
SearchAdapterKind,
|
|
32
|
+
} from "./registry.ts";
|
|
33
|
+
export type {
|
|
34
|
+
KeylessSearchOptions,
|
|
35
|
+
SearchAdapter,
|
|
36
|
+
SearchAdapterMode,
|
|
37
|
+
} from "./types.ts";
|
|
38
|
+
export { typesense } from "./typesense.ts";
|
|
39
|
+
export type { TypesenseAdapter, TypesenseOptions } from "./typesense.ts";
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
|
|
3
|
+
import type { JsonValue } from "../../core/adapter.ts";
|
|
4
|
+
import type { SearchAdapter } from "./types.ts";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* The Mixedbread store the generated `/api/search` endpoint queries, plus any
|
|
8
|
+
* other option, forwarded to the endpoint verbatim. JSON values only.
|
|
9
|
+
*/
|
|
10
|
+
export interface MixedbreadOptions {
|
|
11
|
+
storeId: string;
|
|
12
|
+
[option: string]: JsonValue;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export type MixedbreadAdapter = SearchAdapter<
|
|
16
|
+
"mixedbread",
|
|
17
|
+
"server",
|
|
18
|
+
MixedbreadOptions
|
|
19
|
+
>;
|
|
20
|
+
|
|
21
|
+
export const mixedbreadOptionsSchema = z
|
|
22
|
+
.object({
|
|
23
|
+
storeId: z.string(),
|
|
24
|
+
})
|
|
25
|
+
.catchall(z.json());
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Semantic search on Mixedbread. Queries go through a generated `/api/search`
|
|
29
|
+
* endpoint that holds `MIXEDBREAD_API_KEY`, so the adapter requires server
|
|
30
|
+
* output. Content is synced to the store out-of-band with the `mxbai` CLI,
|
|
31
|
+
* not by the build.
|
|
32
|
+
*/
|
|
33
|
+
export const mixedbread = (options: MixedbreadOptions): MixedbreadAdapter => ({
|
|
34
|
+
kind: "mixedbread",
|
|
35
|
+
mode: "server",
|
|
36
|
+
options,
|
|
37
|
+
requiredSecrets: ["MIXEDBREAD_API_KEY"],
|
|
38
|
+
runtimeDeps: ["@mixedbread/sdk"],
|
|
39
|
+
});
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
|
|
3
|
+
import type { JsonValue } from "../../core/adapter.ts";
|
|
4
|
+
import type { SearchAdapter } from "./types.ts";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Public Orama Cloud credentials. The browser queries `endpoint` with the
|
|
8
|
+
* public `apiKey`; the build-time sync pushes records to `indexId` with
|
|
9
|
+
* `ORAMA_PRIVATE_API_KEY`, which never enters the config.
|
|
10
|
+
*/
|
|
11
|
+
export interface OramaCloudNamedOptions {
|
|
12
|
+
/** The public API key (it ships to the browser). */
|
|
13
|
+
apiKey: string;
|
|
14
|
+
endpoint: string;
|
|
15
|
+
/** Index id used by the build-time sync; omit to skip syncing. */
|
|
16
|
+
indexId?: string;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Options for {@link oramaCloud}: the named options plus any other client
|
|
21
|
+
* option, forwarded to the browser verbatim. JSON values only.
|
|
22
|
+
*/
|
|
23
|
+
export type OramaCloudOptions = OramaCloudNamedOptions & {
|
|
24
|
+
[option: string]: JsonValue;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export type OramaCloudAdapter = SearchAdapter<
|
|
28
|
+
"orama-cloud",
|
|
29
|
+
"hosted",
|
|
30
|
+
OramaCloudOptions
|
|
31
|
+
>;
|
|
32
|
+
|
|
33
|
+
export const oramaCloudOptionsSchema = z
|
|
34
|
+
.object({
|
|
35
|
+
apiKey: z.string(),
|
|
36
|
+
endpoint: z.string(),
|
|
37
|
+
indexId: z.string().optional(),
|
|
38
|
+
})
|
|
39
|
+
.catchall(z.json());
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Hosted Orama. The browser queries your index endpoint directly; each
|
|
43
|
+
* `blume build` snapshots the records into the index and deploys it.
|
|
44
|
+
*/
|
|
45
|
+
export const oramaCloud = (options: OramaCloudOptions): OramaCloudAdapter => ({
|
|
46
|
+
kind: "orama-cloud",
|
|
47
|
+
mode: "hosted",
|
|
48
|
+
options,
|
|
49
|
+
requiredSecrets: [],
|
|
50
|
+
runtimeDeps: ["@oramacloud/client"],
|
|
51
|
+
});
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
|
|
3
|
+
import type { KeylessSearchOptions, SearchAdapter } from "./types.ts";
|
|
4
|
+
|
|
5
|
+
/** Orama takes no options; unknown keys fail config validation. */
|
|
6
|
+
export type OramaOptions = KeylessSearchOptions;
|
|
7
|
+
|
|
8
|
+
export type OramaAdapter = SearchAdapter<"orama", "static", OramaOptions>;
|
|
9
|
+
|
|
10
|
+
export const oramaOptionsSchema = z.strictObject({});
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Blume's default search: a JSON index built from the source files, served
|
|
14
|
+
* at `/blume-search.json` and queried in the browser. Keyless, and live in
|
|
15
|
+
* `blume dev`. The tokenizer follows `i18n.defaultLocale`, so non-Latin
|
|
16
|
+
* scripts are word-segmented.
|
|
17
|
+
*/
|
|
18
|
+
export const orama = (options: OramaOptions = {}): OramaAdapter => ({
|
|
19
|
+
kind: "orama",
|
|
20
|
+
mode: "static",
|
|
21
|
+
options,
|
|
22
|
+
requiredSecrets: [],
|
|
23
|
+
runtimeDeps: ["@orama/orama"],
|
|
24
|
+
});
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
|
|
3
|
+
import type { KeylessSearchOptions, SearchAdapter } from "./types.ts";
|
|
4
|
+
|
|
5
|
+
/** Pagefind takes no options; unknown keys fail config validation. */
|
|
6
|
+
export type PagefindOptions = KeylessSearchOptions;
|
|
7
|
+
|
|
8
|
+
export type PagefindAdapter = SearchAdapter<
|
|
9
|
+
"pagefind",
|
|
10
|
+
"pagefind",
|
|
11
|
+
PagefindOptions
|
|
12
|
+
>;
|
|
13
|
+
|
|
14
|
+
export const pagefindOptionsSchema = z.strictObject({});
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Pagefind indexes the built HTML after `blume build` and loads the index in
|
|
18
|
+
* shards on demand, so the initial payload stays small on very large sites.
|
|
19
|
+
* The index only exists in the production build, not in `blume dev`.
|
|
20
|
+
*/
|
|
21
|
+
export const pagefind = (options: PagefindOptions = {}): PagefindAdapter => ({
|
|
22
|
+
kind: "pagefind",
|
|
23
|
+
mode: "pagefind",
|
|
24
|
+
options,
|
|
25
|
+
requiredSecrets: [],
|
|
26
|
+
runtimeDeps: [],
|
|
27
|
+
});
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
|
|
3
|
+
import { adapterDescriptorSchema } from "../../core/adapter.ts";
|
|
4
|
+
import { algolia, algoliaOptionsSchema } from "./algolia.ts";
|
|
5
|
+
import type { AlgoliaAdapter } from "./algolia.ts";
|
|
6
|
+
import { flexsearch, flexsearchOptionsSchema } from "./flexsearch.ts";
|
|
7
|
+
import type { FlexsearchAdapter } from "./flexsearch.ts";
|
|
8
|
+
import { mixedbread, mixedbreadOptionsSchema } from "./mixedbread.ts";
|
|
9
|
+
import type { MixedbreadAdapter } from "./mixedbread.ts";
|
|
10
|
+
import { oramaCloud, oramaCloudOptionsSchema } from "./orama-cloud.ts";
|
|
11
|
+
import type { OramaCloudAdapter } from "./orama-cloud.ts";
|
|
12
|
+
import { orama, oramaOptionsSchema } from "./orama.ts";
|
|
13
|
+
import type { OramaAdapter } from "./orama.ts";
|
|
14
|
+
import { pagefind, pagefindOptionsSchema } from "./pagefind.ts";
|
|
15
|
+
import type { PagefindAdapter } from "./pagefind.ts";
|
|
16
|
+
import type {
|
|
17
|
+
KeylessSearchOptions,
|
|
18
|
+
SearchAdapter,
|
|
19
|
+
SearchAdapterMode,
|
|
20
|
+
} from "./types.ts";
|
|
21
|
+
import { typesense, typesenseOptionsSchema } from "./typesense.ts";
|
|
22
|
+
import type { TypesenseAdapter } from "./typesense.ts";
|
|
23
|
+
|
|
24
|
+
/** Every descriptor a factory can return. */
|
|
25
|
+
export type AnySearchAdapter =
|
|
26
|
+
| AlgoliaAdapter
|
|
27
|
+
| FlexsearchAdapter
|
|
28
|
+
| MixedbreadAdapter
|
|
29
|
+
| OramaAdapter
|
|
30
|
+
| OramaCloudAdapter
|
|
31
|
+
| PagefindAdapter
|
|
32
|
+
| TypesenseAdapter;
|
|
33
|
+
|
|
34
|
+
/** The resolved form of `search: false`: search is disabled. */
|
|
35
|
+
export type NoneSearchAdapter = SearchAdapter<
|
|
36
|
+
"none",
|
|
37
|
+
"none",
|
|
38
|
+
KeylessSearchOptions
|
|
39
|
+
>;
|
|
40
|
+
|
|
41
|
+
/** What `config.search.provider` resolves to: an adapter, or `none`. */
|
|
42
|
+
export type ResolvedSearchAdapter = AnySearchAdapter | NoneSearchAdapter;
|
|
43
|
+
|
|
44
|
+
/** Every adapter identity, including the resolved `none`. */
|
|
45
|
+
export type SearchAdapterKind = ResolvedSearchAdapter["kind"];
|
|
46
|
+
|
|
47
|
+
export const NONE_SEARCH_ADAPTER: NoneSearchAdapter = {
|
|
48
|
+
kind: "none",
|
|
49
|
+
mode: "none",
|
|
50
|
+
options: {},
|
|
51
|
+
requiredSecrets: [],
|
|
52
|
+
runtimeDeps: [],
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* The descriptor shape a factory returns: the shared adapter contract plus
|
|
57
|
+
* the search-specific `mode`. Only `kind` and `options` carry information —
|
|
58
|
+
* the metadata lists are validated for shape, then re-derived from the
|
|
59
|
+
* factory below so a descriptor that went through JSON resolves to the same
|
|
60
|
+
* canonical metadata Blume ships.
|
|
61
|
+
*/
|
|
62
|
+
const descriptor = <
|
|
63
|
+
Kind extends string,
|
|
64
|
+
Mode extends SearchAdapterMode,
|
|
65
|
+
Options extends z.ZodType,
|
|
66
|
+
>(
|
|
67
|
+
kind: Kind,
|
|
68
|
+
mode: Mode,
|
|
69
|
+
options: Options
|
|
70
|
+
) => adapterDescriptorSchema(kind, options).extend({ mode: z.literal(mode) });
|
|
71
|
+
|
|
72
|
+
/** One variant per public adapter factory. */
|
|
73
|
+
const adapterVariants = [
|
|
74
|
+
descriptor("algolia", "hosted", algoliaOptionsSchema),
|
|
75
|
+
descriptor("flexsearch", "static", flexsearchOptionsSchema),
|
|
76
|
+
descriptor("mixedbread", "server", mixedbreadOptionsSchema),
|
|
77
|
+
descriptor("orama", "static", oramaOptionsSchema),
|
|
78
|
+
descriptor("orama-cloud", "hosted", oramaCloudOptionsSchema),
|
|
79
|
+
descriptor("pagefind", "pagefind", pagefindOptionsSchema),
|
|
80
|
+
descriptor("typesense", "hosted", typesenseOptionsSchema),
|
|
81
|
+
] as const;
|
|
82
|
+
|
|
83
|
+
/** What a public factory returns, as the config schema accepts it. */
|
|
84
|
+
export type SearchAdapterInput = z.input<(typeof adapterVariants)[number]>;
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Validates a descriptor — one a factory returned, or the `none` descriptor
|
|
88
|
+
* the config schema substitutes for `false` — and resolves it to the
|
|
89
|
+
* canonical form, so every consumer reads `mode`, `runtimeDeps`, and
|
|
90
|
+
* `requiredSecrets` straight off the descriptor. `none` is internal: it is
|
|
91
|
+
* not part of {@link SearchAdapterInput}, so `search: { kind: "none" }` is a
|
|
92
|
+
* type error even though the runtime schema admits it.
|
|
93
|
+
*/
|
|
94
|
+
export const resolvedSearchAdapterSchema = z
|
|
95
|
+
.discriminatedUnion("kind", [
|
|
96
|
+
...adapterVariants,
|
|
97
|
+
descriptor("none", "none", z.strictObject({})),
|
|
98
|
+
])
|
|
99
|
+
.transform((value): ResolvedSearchAdapter => {
|
|
100
|
+
switch (value.kind) {
|
|
101
|
+
case "algolia": {
|
|
102
|
+
return algolia(value.options);
|
|
103
|
+
}
|
|
104
|
+
case "flexsearch": {
|
|
105
|
+
return flexsearch(value.options);
|
|
106
|
+
}
|
|
107
|
+
case "mixedbread": {
|
|
108
|
+
return mixedbread(value.options);
|
|
109
|
+
}
|
|
110
|
+
case "none": {
|
|
111
|
+
return NONE_SEARCH_ADAPTER;
|
|
112
|
+
}
|
|
113
|
+
case "orama": {
|
|
114
|
+
return orama(value.options);
|
|
115
|
+
}
|
|
116
|
+
case "orama-cloud": {
|
|
117
|
+
return oramaCloud(value.options);
|
|
118
|
+
}
|
|
119
|
+
case "pagefind": {
|
|
120
|
+
return pagefind(value.options);
|
|
121
|
+
}
|
|
122
|
+
default: {
|
|
123
|
+
// Only Typesense is left, and TypeScript has narrowed `value` to it.
|
|
124
|
+
// It returns after the switch rather than from a last case block:
|
|
125
|
+
// Bun 1.4.0's line coverage never credits the closing brace of a
|
|
126
|
+
// switch's final block, which would fail the 100% gate in CI.
|
|
127
|
+
break;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
return typesense(value.options);
|
|
131
|
+
});
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { AdapterDescriptor } from "../../core/adapter.ts";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* How a search adapter integrates with the generated runtime.
|
|
5
|
+
*
|
|
6
|
+
* - `static` adapters ship a client-side index (`blume-search.json`) that the
|
|
7
|
+
* browser loads and queries — Orama, FlexSearch.
|
|
8
|
+
* - `pagefind` builds its own index from the rendered HTML after the build.
|
|
9
|
+
* - `hosted` adapters are queried directly from the browser against an
|
|
10
|
+
* external service, with a build-time sync uploading the index — Algolia,
|
|
11
|
+
* Orama Cloud, Typesense.
|
|
12
|
+
* - `server` adapters proxy queries through a generated `/api/search` endpoint
|
|
13
|
+
* that holds a secret key, so they require server output — Mixedbread.
|
|
14
|
+
* - `none` is the resolved form of `search: false`: search is disabled.
|
|
15
|
+
*/
|
|
16
|
+
export type SearchAdapterMode =
|
|
17
|
+
| "static"
|
|
18
|
+
| "pagefind"
|
|
19
|
+
| "hosted"
|
|
20
|
+
| "server"
|
|
21
|
+
| "none";
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Options for an adapter that takes none. The generated client never reads
|
|
25
|
+
* them — the static engines are configured from `i18n`, and Pagefind indexes
|
|
26
|
+
* the built HTML — so unknown keys fail config validation instead of passing
|
|
27
|
+
* silently. Adding a real option later is then additive, never a behavior
|
|
28
|
+
* change for a key that used to be ignored.
|
|
29
|
+
*/
|
|
30
|
+
export type KeylessSearchOptions = Record<string, never>;
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* The descriptor a search adapter factory returns and `blume.config.ts`
|
|
34
|
+
* carries under `search`: the shared {@link AdapterDescriptor} contract plus
|
|
35
|
+
* the adapter's integration `mode`. It is plain data, never a live client —
|
|
36
|
+
* the runtime templates inline it as a literal into `.blume/` and ejected
|
|
37
|
+
* files, so every field must survive a JSON round-trip.
|
|
38
|
+
*/
|
|
39
|
+
export interface SearchAdapter<
|
|
40
|
+
Kind extends string = string,
|
|
41
|
+
Mode extends SearchAdapterMode = SearchAdapterMode,
|
|
42
|
+
Options = object,
|
|
43
|
+
> extends AdapterDescriptor<Kind, Options> {
|
|
44
|
+
/** How the generated runtime queries this adapter. */
|
|
45
|
+
mode: Mode;
|
|
46
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
|
|
3
|
+
import type { JsonValue } from "../../core/adapter.ts";
|
|
4
|
+
import type { SearchAdapter } from "./types.ts";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Connection details for a self-hosted or cloud Typesense node. The browser
|
|
8
|
+
* queries the collection with the search-only `apiKey`; the build-time sync
|
|
9
|
+
* recreates the collection with `TYPESENSE_ADMIN_API_KEY`, which never enters
|
|
10
|
+
* the config.
|
|
11
|
+
*/
|
|
12
|
+
export interface TypesenseNamedOptions {
|
|
13
|
+
/** The search-only API key (public — it ships to the browser). */
|
|
14
|
+
apiKey: string;
|
|
15
|
+
collection: string;
|
|
16
|
+
host: string;
|
|
17
|
+
/** Defaults to 443. */
|
|
18
|
+
port?: number;
|
|
19
|
+
/** Defaults to `https`. */
|
|
20
|
+
protocol?: "http" | "https";
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Options for {@link typesense}: the named options plus any other client
|
|
25
|
+
* option, forwarded to the browser verbatim. JSON values only.
|
|
26
|
+
*/
|
|
27
|
+
export type TypesenseOptions = TypesenseNamedOptions & {
|
|
28
|
+
[option: string]: JsonValue;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
export type TypesenseAdapter = SearchAdapter<
|
|
32
|
+
"typesense",
|
|
33
|
+
"hosted",
|
|
34
|
+
TypesenseOptions
|
|
35
|
+
>;
|
|
36
|
+
|
|
37
|
+
export const typesenseOptionsSchema = z
|
|
38
|
+
.object({
|
|
39
|
+
apiKey: z.string(),
|
|
40
|
+
collection: z.string(),
|
|
41
|
+
host: z.string(),
|
|
42
|
+
port: z.number().int().positive().optional(),
|
|
43
|
+
protocol: z.enum(["http", "https"]).optional(),
|
|
44
|
+
})
|
|
45
|
+
.catchall(z.json());
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Hosted search on Typesense. Each `blume build` drops and recreates the
|
|
49
|
+
* collection so deleted or renamed pages don't linger as stale hits.
|
|
50
|
+
*/
|
|
51
|
+
export const typesense = (options: TypesenseOptions): TypesenseAdapter => ({
|
|
52
|
+
kind: "typesense",
|
|
53
|
+
mode: "hosted",
|
|
54
|
+
options,
|
|
55
|
+
requiredSecrets: [],
|
|
56
|
+
runtimeDeps: ["typesense"],
|
|
57
|
+
});
|
package/src/search/build.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { mkdir, writeFile } from "node:fs/promises";
|
|
2
2
|
|
|
3
|
+
import { close, createIndex } from "pagefind";
|
|
3
4
|
import { dirname, join } from "pathe";
|
|
4
5
|
|
|
5
6
|
/**
|
|
@@ -8,6 +9,11 @@ import { dirname, join } from "pathe";
|
|
|
8
9
|
* `data-pagefind-ignore`, which Blume stamps on non-indexable pages
|
|
9
10
|
* (search-excluded, or hidden without the opt-in), so those stay out.
|
|
10
11
|
*
|
|
12
|
+
* Pagefind is imported statically, not with `import()`: this runs in the
|
|
13
|
+
* `astro:build:done` hook, after Astro has closed the module runner an
|
|
14
|
+
* installed Blume's config was evaluated in (see `core/node-require.ts`), and
|
|
15
|
+
* Pagefind ships only an `import` export, so `require` can't load it either.
|
|
16
|
+
*
|
|
11
17
|
* The index files are fetched with `getFiles()` and written here rather than
|
|
12
18
|
* with Pagefind's `writeFiles()`: in service mode Pagefind acknowledges
|
|
13
19
|
* `writeFiles()` once tokio has buffered the writes, not once they are on
|
|
@@ -20,9 +26,7 @@ import { dirname, join } from "pathe";
|
|
|
20
26
|
* Returns the number of pages indexed.
|
|
21
27
|
*/
|
|
22
28
|
export const buildSearchIndex = async (outDir: string): Promise<number> => {
|
|
23
|
-
const
|
|
24
|
-
|
|
25
|
-
const { index } = await pagefind.createIndex({});
|
|
29
|
+
const { index } = await createIndex({});
|
|
26
30
|
if (!index) {
|
|
27
31
|
throw new Error("Failed to create Pagefind index.");
|
|
28
32
|
}
|
|
@@ -32,7 +36,7 @@ export const buildSearchIndex = async (outDir: string): Promise<number> => {
|
|
|
32
36
|
// oxlint-disable-next-line react-doctor/async-parallel
|
|
33
37
|
const result = await index.addDirectory({ path: outDir });
|
|
34
38
|
const { files } = await index.getFiles();
|
|
35
|
-
await
|
|
39
|
+
await close();
|
|
36
40
|
|
|
37
41
|
const searchDir = join(outDir, "pagefind");
|
|
38
42
|
const directories = new Set(
|
package/src/search/documents.ts
CHANGED
|
@@ -149,7 +149,7 @@ const parseMarkdown = (
|
|
|
149
149
|
format === "mdx" ? parseMdx(markdown) : markdownToMdast(markdown, MD_PARSE);
|
|
150
150
|
|
|
151
151
|
// Fenced code is excluded from the plain index by default (ranking noise) —
|
|
152
|
-
// the "markdown" extraction keeps it for
|
|
152
|
+
// the "markdown" extraction keeps it for assistant grounding. Code-heavy docs opt
|
|
153
153
|
// in via `search.indexing.includeCodeBlocks`, which indexes the fence body and
|
|
154
154
|
// its rendered title (```ts blume.config.ts) but never the fence markers,
|
|
155
155
|
// language, or other meta keywords.
|
|
@@ -383,7 +383,7 @@ const pageBody = async (
|
|
|
383
383
|
*
|
|
384
384
|
* `content` selects the extraction: `"plain"` (default) strips Markdown to bare
|
|
385
385
|
* searchable text; `"markdown"` keeps the body's Markdown — code blocks, lists,
|
|
386
|
-
* headings — for
|
|
386
|
+
* headings — for assistant grounding, where fenced examples are often the answer
|
|
387
387
|
* and stripping them makes the model unable to cite content the docs do contain.
|
|
388
388
|
* The `"markdown"` body is agent-facing, so components are downleveled with the
|
|
389
389
|
* same serializers the `.md` mirror, llms-full.txt and MCP `get_page` use: a
|
|
@@ -433,6 +433,12 @@ export const buildSearchDocuments = async (
|
|
|
433
433
|
if (!options?.includeWhenDisabled) {
|
|
434
434
|
return route.indexable;
|
|
435
435
|
}
|
|
436
|
+
// A fallback route renders the fallback locale's page at another locale's
|
|
437
|
+
// URL, so indexing it would only repeat that page as a second hit — the
|
|
438
|
+
// reason site search leaves it out too.
|
|
439
|
+
if (route.fallback) {
|
|
440
|
+
return false;
|
|
441
|
+
}
|
|
436
442
|
const page = pageById.get(route.id);
|
|
437
443
|
return page ? contentIndexable(page, project.config) : false;
|
|
438
444
|
});
|
|
@@ -298,7 +298,7 @@ const segmentingTokenizer = (locale?: string): Tokenizer | undefined => {
|
|
|
298
298
|
|
|
299
299
|
/**
|
|
300
300
|
* Build an in-memory Orama full-text index from search documents. Shared by the
|
|
301
|
-
* Orama client loader (browser), the MCP server, and
|
|
301
|
+
* Orama client loader (browser), the MCP server, and assistant grounding (Node),
|
|
302
302
|
* so ranking is identical wherever docs are queried. `locale` — the site's
|
|
303
303
|
* `i18n.defaultLocale` — swaps in a word-segmenting tokenizer for every
|
|
304
304
|
* non-Latin script, all of which Orama's default tokenizer reduces to zero
|
|
@@ -1,14 +1,16 @@
|
|
|
1
|
+
import type * as AlgoliaSdk from "algoliasearch";
|
|
2
|
+
|
|
3
|
+
import { nodeRequire } from "../../core/node-require.ts";
|
|
4
|
+
import type { AlgoliaOptions } from "../adapters/algolia.ts";
|
|
1
5
|
import type { SearchRecord } from "../documents.ts";
|
|
2
6
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
indexName: string;
|
|
6
|
-
}
|
|
7
|
+
/** The adapter options the sync reads (the public `apiKey` is never used). */
|
|
8
|
+
export type AlgoliaSyncConfig = Pick<AlgoliaOptions, "appId" | "indexName">;
|
|
7
9
|
|
|
8
10
|
/**
|
|
9
11
|
* Upload the search records to Algolia. Uses the admin key from
|
|
10
|
-
* `ALGOLIA_ADMIN_API_KEY` (never the
|
|
11
|
-
* search-only key). Throws on a missing key
|
|
12
|
+
* `ALGOLIA_ADMIN_API_KEY` (never the adapter options, which hold only the
|
|
13
|
+
* public, search-only key). Throws on a missing key so the caller can warn.
|
|
12
14
|
*
|
|
13
15
|
* Uses `replaceAllObjects`, which atomically replaces the index contents, so
|
|
14
16
|
* pages deleted or renamed since the last sync don't linger as stale search
|
|
@@ -16,16 +18,15 @@ export interface AlgoliaSyncConfig {
|
|
|
16
18
|
*/
|
|
17
19
|
export const syncAlgolia = async (
|
|
18
20
|
records: SearchRecord[],
|
|
19
|
-
config: AlgoliaSyncConfig
|
|
21
|
+
config: AlgoliaSyncConfig
|
|
20
22
|
): Promise<void> => {
|
|
21
|
-
if (!config) {
|
|
22
|
-
throw new Error("search.algolia config is missing.");
|
|
23
|
-
}
|
|
24
23
|
const adminKey = process.env.ALGOLIA_ADMIN_API_KEY;
|
|
25
24
|
if (!adminKey) {
|
|
26
25
|
throw new Error("ALGOLIA_ADMIN_API_KEY is not set.");
|
|
27
26
|
}
|
|
28
|
-
|
|
27
|
+
// `require`, not `import()`: this runs in `astro:build:done` (see
|
|
28
|
+
// `core/node-require.ts`).
|
|
29
|
+
const { algoliasearch }: typeof AlgoliaSdk = nodeRequire("algoliasearch");
|
|
29
30
|
const client = algoliasearch(config.appId, adminKey);
|
|
30
31
|
await client.replaceAllObjects({
|
|
31
32
|
indexName: config.indexName,
|
package/src/search/sync/index.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { BlumeProject } from "../../core/project-graph.ts";
|
|
2
|
+
import type { ResolvedSearchAdapter } from "../adapters/registry.ts";
|
|
2
3
|
import { buildSearchDocuments, toSearchRecords } from "../documents.ts";
|
|
3
|
-
import {
|
|
4
|
+
import type { SearchRecord } from "../documents.ts";
|
|
4
5
|
import { syncAlgolia } from "./algolia.ts";
|
|
5
6
|
import { syncOramaCloud } from "./orama-cloud.ts";
|
|
6
7
|
import { syncTypesense } from "./typesense.ts";
|
|
@@ -13,37 +14,51 @@ export interface SyncReporter {
|
|
|
13
14
|
}
|
|
14
15
|
|
|
15
16
|
/**
|
|
16
|
-
*
|
|
17
|
-
*
|
|
17
|
+
* The sync a hosted adapter runs after a build, closed over its options, or
|
|
18
|
+
* `null` for adapters with no in-process sync (static and Pagefind indexes are
|
|
19
|
+
* built locally; Mixedbread syncs out-of-band via the `mxbai` CLI).
|
|
20
|
+
*/
|
|
21
|
+
const searchSync = (
|
|
22
|
+
provider: ResolvedSearchAdapter
|
|
23
|
+
): ((records: SearchRecord[]) => Promise<void>) | null => {
|
|
24
|
+
switch (provider.kind) {
|
|
25
|
+
case "algolia": {
|
|
26
|
+
return (records) => syncAlgolia(records, provider.options);
|
|
27
|
+
}
|
|
28
|
+
case "orama-cloud": {
|
|
29
|
+
return (records) => syncOramaCloud(records, provider.options);
|
|
30
|
+
}
|
|
31
|
+
case "typesense": {
|
|
32
|
+
return (records) => syncTypesense(records, provider.options);
|
|
33
|
+
}
|
|
34
|
+
default: {
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* After a build, upload the per-page records to the configured hosted adapter.
|
|
42
|
+
* Reads secret admin keys from the environment; if a key (or option) is
|
|
18
43
|
* missing the sync is skipped with a warning rather than failing the build —
|
|
19
|
-
* CI may sync in a separate step.
|
|
20
|
-
* (Mixedbread, which uses the `mxbai` CLI) are no-ops here.
|
|
44
|
+
* CI may sync in a separate step.
|
|
21
45
|
*/
|
|
22
46
|
export const syncSearchProvider = async (
|
|
23
47
|
project: BlumeProject,
|
|
24
48
|
reporter: SyncReporter
|
|
25
49
|
): Promise<void> => {
|
|
26
|
-
const {
|
|
27
|
-
|
|
50
|
+
const { provider } = project.config.search;
|
|
51
|
+
const sync = searchSync(provider);
|
|
52
|
+
if (!sync) {
|
|
28
53
|
return;
|
|
29
54
|
}
|
|
30
55
|
|
|
31
56
|
const records = toSearchRecords(await buildSearchDocuments(project));
|
|
32
|
-
reporter.start(`Syncing ${records.length} record(s) to ${
|
|
57
|
+
reporter.start(`Syncing ${records.length} record(s) to ${provider.kind}`);
|
|
33
58
|
|
|
34
59
|
try {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
if (search.provider === "algolia") {
|
|
38
|
-
await syncAlgolia(records, search.algolia);
|
|
39
|
-
} else if (search.provider === "orama-cloud") {
|
|
40
|
-
await syncOramaCloud(records, search.oramaCloud);
|
|
41
|
-
} else if (search.provider === "typesense") {
|
|
42
|
-
await syncTypesense(records, search.typesense);
|
|
43
|
-
}
|
|
44
|
-
reporter.success(
|
|
45
|
-
`Synced ${records.length} record(s) to ${search.provider}`
|
|
46
|
-
);
|
|
60
|
+
await sync(records);
|
|
61
|
+
reporter.success(`Synced ${records.length} record(s) to ${provider.kind}`);
|
|
47
62
|
} catch (error) {
|
|
48
63
|
// SAFETY: the three sync clients surface network/auth failures as Error
|
|
49
64
|
// instances; the message is read only to annotate the skip warning.
|
|
@@ -1,8 +1,11 @@
|
|
|
1
|
+
import type * as OramaCloudSdk from "@oramacloud/client";
|
|
2
|
+
|
|
3
|
+
import { nodeRequire } from "../../core/node-require.ts";
|
|
4
|
+
import type { OramaCloudOptions } from "../adapters/orama-cloud.ts";
|
|
1
5
|
import type { SearchRecord } from "../documents.ts";
|
|
2
6
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
}
|
|
7
|
+
/** The adapter options the sync reads (the public credentials are never used). */
|
|
8
|
+
export type OramaCloudSyncConfig = Pick<OramaCloudOptions, "indexId">;
|
|
6
9
|
|
|
7
10
|
/**
|
|
8
11
|
* Push the search records to an Orama Cloud index via `CloudManager`, using the
|
|
@@ -11,19 +14,19 @@ export interface OramaCloudSyncConfig {
|
|
|
11
14
|
*/
|
|
12
15
|
export const syncOramaCloud = async (
|
|
13
16
|
records: SearchRecord[],
|
|
14
|
-
config: OramaCloudSyncConfig
|
|
17
|
+
config: OramaCloudSyncConfig
|
|
15
18
|
): Promise<void> => {
|
|
16
|
-
if (!config) {
|
|
17
|
-
throw new Error("search.oramaCloud config is missing.");
|
|
18
|
-
}
|
|
19
19
|
if (!config.indexId) {
|
|
20
|
-
throw new Error("
|
|
20
|
+
throw new Error("oramaCloud({ indexId }) is required to sync.");
|
|
21
21
|
}
|
|
22
22
|
const privateKey = process.env.ORAMA_PRIVATE_API_KEY;
|
|
23
23
|
if (!privateKey) {
|
|
24
24
|
throw new Error("ORAMA_PRIVATE_API_KEY is not set.");
|
|
25
25
|
}
|
|
26
|
-
|
|
26
|
+
// `require`, not `import()`: this runs in `astro:build:done` (see
|
|
27
|
+
// `core/node-require.ts`).
|
|
28
|
+
const { CloudManager }: typeof OramaCloudSdk =
|
|
29
|
+
nodeRequire("@oramacloud/client");
|
|
27
30
|
const manager = new CloudManager({ api_key: privateKey });
|
|
28
31
|
const index = manager.index(config.indexId);
|
|
29
32
|
await index.snapshot(
|