blume 1.0.1 → 1.0.3
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/CHANGELOG.md +18 -0
- package/dist/cli/index.js +87 -57
- package/dist/cli/index.js.map +16 -15
- package/dist/types/core/config-input.d.ts +17 -14
- package/dist/types/core/config.d.ts +3 -3
- package/dist/types/core/schema.d.ts +82 -34
- package/dist/types/core/trim.d.ts +16 -0
- package/docs/advanced/custom-pages.mdx +2 -0
- package/docs/configuration/ai.mdx +6 -4
- package/docs/configuration/index.mdx +6 -8
- package/docs/content/components.mdx +25 -3
- package/package.json +1 -1
- package/src/ai/agent-readability.ts +3 -3
- package/src/ai/mcp/data.ts +2 -2
- package/src/ai/mcp/discovery.ts +2 -1
- package/src/astro/generate.ts +15 -7
- package/src/astro/templates.ts +52 -25
- package/src/blume-modules.d.ts +6 -0
- package/src/components/layout/Header.astro +15 -2
- package/src/components/layout/PageLayout.astro +15 -10
- package/src/components/layout/ReferenceLayout.astro +9 -10
- package/src/components/layout/RootLayout.astro +14 -10
- package/src/components/layout/head-scripts.ts +20 -10
- package/src/core/base-path.ts +4 -4
- package/src/core/config-input.ts +18 -19
- package/src/core/config.ts +3 -3
- package/src/core/schema.ts +15 -14
- package/src/core/server-features.ts +1 -1
- package/src/core/trim.ts +32 -0
- package/src/deploy/adapter-output.ts +11 -1
- package/src/openapi/references.ts +4 -6
- package/src/registry/eject.ts +11 -5
|
@@ -83,7 +83,17 @@ export const surfaceAdapterOutput = async (
|
|
|
83
83
|
}
|
|
84
84
|
await mkdir(dirname(to), { recursive: true });
|
|
85
85
|
await rm(to, { force: true, recursive: true });
|
|
86
|
-
|
|
86
|
+
// `verbatimSymlinks` keeps each symlink's target text as written. Without it,
|
|
87
|
+
// `cp` resolves every relative target against the *source*, rewriting it to an
|
|
88
|
+
// absolute path under `.blume` — which this function then deletes. Adapters
|
|
89
|
+
// that trace dependencies into their function bundle link one package to
|
|
90
|
+
// another that way (under an isolated linker — Bun's `isolated` mode, pnpm —
|
|
91
|
+
// that is every external dependency the function imports), so the resolved
|
|
92
|
+
// links leave the deployed function dying on its first external import with
|
|
93
|
+
// ERR_MODULE_NOT_FOUND. Verbatim, the links stay relative and internal to the
|
|
94
|
+
// bundle, surviving both this move and the platform's own (Vercel mounts the
|
|
95
|
+
// bundle at `/var/task`).
|
|
96
|
+
await cp(from, to, { recursive: true, verbatimSymlinks: true });
|
|
87
97
|
await rm(from, { force: true, recursive: true });
|
|
88
98
|
// The `.gitignore` entry is the surfaced top-level dir (`.vercel`/`.netlify`),
|
|
89
99
|
// never the moved sub-path — the platform's own state (`.vercel/project.json`,
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { withBasePath } from "../core/base-path.ts";
|
|
2
2
|
import type { ResolvedConfig } from "../core/schema.ts";
|
|
3
|
+
import { trimChar, trimEnd } from "../core/trim.ts";
|
|
3
4
|
import type { NavTab } from "../core/types.ts";
|
|
4
5
|
|
|
5
6
|
/**
|
|
@@ -52,24 +53,21 @@ export interface ReferenceSource {
|
|
|
52
53
|
}
|
|
53
54
|
|
|
54
55
|
const NON_SLUG = /[^a-z0-9]+/gu;
|
|
55
|
-
const SLUG_EDGES = /^-+|-+$/gu;
|
|
56
|
-
const ROUTE_EDGES = /^\/+|\/+$/gu;
|
|
57
|
-
const TRAILING_SLASH = /\/+$/u;
|
|
58
56
|
|
|
59
57
|
export const slugify = (text: string): string =>
|
|
60
|
-
text.toLowerCase().replace(NON_SLUG, "-")
|
|
58
|
+
trimChar(text.toLowerCase().replace(NON_SLUG, "-"), "-");
|
|
61
59
|
|
|
62
60
|
/** Normalize a configured route to a single leading slash, no trailing slash. */
|
|
63
61
|
export const normalizeRoute = (route: string): string => {
|
|
64
62
|
const trimmed = route.trim();
|
|
65
63
|
const withSlash = trimmed.startsWith("/") ? trimmed : `/${trimmed}`;
|
|
66
|
-
const noTrailing = withSlash
|
|
64
|
+
const noTrailing = trimEnd(withSlash, "/");
|
|
67
65
|
return noTrailing === "" ? "/" : noTrailing;
|
|
68
66
|
};
|
|
69
67
|
|
|
70
68
|
/** A stable per-reference token from its route: `/api/events` -> `api-events`. */
|
|
71
69
|
const routeSlug = (route: string): string =>
|
|
72
|
-
slugify(route
|
|
70
|
+
slugify(trimChar(route, "/")) || "reference";
|
|
73
71
|
|
|
74
72
|
type Block = ResolvedConfig["openapi"] | ResolvedConfig["asyncapi"];
|
|
75
73
|
|
package/src/registry/eject.ts
CHANGED
|
@@ -20,6 +20,7 @@ import { discoverIslands } from "../astro/islands.ts";
|
|
|
20
20
|
import { customOgRoutes, discoverPages, routeIsTaken } from "../astro/pages.ts";
|
|
21
21
|
import {
|
|
22
22
|
askEndpointTemplate,
|
|
23
|
+
askComponentTemplate,
|
|
23
24
|
astroConfigTemplate,
|
|
24
25
|
catchAllPageTemplate,
|
|
25
26
|
changelogIndexTemplate,
|
|
@@ -135,8 +136,8 @@ const hostsMcp = (
|
|
|
135
136
|
project: BlumeProject,
|
|
136
137
|
userPages: { pattern: string }[]
|
|
137
138
|
): boolean =>
|
|
138
|
-
project.config.mcp.enabled &&
|
|
139
|
-
!routeIsTaken(userPages, project.graph.pages, project.config.mcp.route);
|
|
139
|
+
project.config.ai.mcp.enabled &&
|
|
140
|
+
!routeIsTaken(userPages, project.graph.pages, project.config.ai.mcp.route);
|
|
140
141
|
|
|
141
142
|
/**
|
|
142
143
|
* The `.well-known` MCP discovery routes, injected as prerendered pages
|
|
@@ -174,7 +175,7 @@ const mcpFiles = async (
|
|
|
174
175
|
if (!hostsMcp(project, userPages)) {
|
|
175
176
|
return [];
|
|
176
177
|
}
|
|
177
|
-
const { route } = project.config.mcp;
|
|
178
|
+
const { route } = project.config.ai.mcp;
|
|
178
179
|
const data = await buildMcpData(project);
|
|
179
180
|
const discoveryInput = {
|
|
180
181
|
base: data.base,
|
|
@@ -356,6 +357,7 @@ export const eject = async (
|
|
|
356
357
|
}[] = [
|
|
357
358
|
{
|
|
358
359
|
content: astroConfigTemplate({
|
|
360
|
+
askPath: "./src/generated/Ask.astro",
|
|
359
361
|
config,
|
|
360
362
|
contentRoutes: project.manifest.routes.map((route) => route.path),
|
|
361
363
|
context: relContext,
|
|
@@ -390,7 +392,6 @@ export const eject = async (
|
|
|
390
392
|
},
|
|
391
393
|
{
|
|
392
394
|
content: catchAllPageTemplate({
|
|
393
|
-
askEnabled,
|
|
394
395
|
exportEpub,
|
|
395
396
|
exportPdf,
|
|
396
397
|
mathEnabled: usesMath,
|
|
@@ -441,6 +442,12 @@ export const eject = async (
|
|
|
441
442
|
path: join(genDir, "app.css"),
|
|
442
443
|
},
|
|
443
444
|
{ content: buildRuntimeData(project), path: join(genDir, "data.json") },
|
|
445
|
+
// The header's Ask trigger behind the `blume:ask` alias. Always written — it
|
|
446
|
+
// renders nothing when Ask is off — so the alias always resolves.
|
|
447
|
+
{
|
|
448
|
+
content: askComponentTemplate(askEnabled),
|
|
449
|
+
path: join(genDir, "Ask.astro"),
|
|
450
|
+
},
|
|
444
451
|
{
|
|
445
452
|
content: `${JSON.stringify(ejectOpenApiData(project))}\n`,
|
|
446
453
|
path: join(genDir, "openapi.json"),
|
|
@@ -475,7 +482,6 @@ export const eject = async (
|
|
|
475
482
|
files.push(
|
|
476
483
|
...(await mcpFiles(project, pages, srcDir, genDir)),
|
|
477
484
|
...changelogFiles(project, pages, srcDir, {
|
|
478
|
-
askEnabled,
|
|
479
485
|
exportEpub,
|
|
480
486
|
exportPdf,
|
|
481
487
|
needsReact,
|