blume 2.1.1 → 2.1.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 +23 -0
- package/dist/cli/{chunk-ncj7w596.js → chunk-0pmb4tr4.js} +22 -18
- package/dist/cli/{chunk-ncj7w596.js.map → chunk-0pmb4tr4.js.map} +3 -3
- package/dist/cli/{chunk-nq1d20w2.js → chunk-0w6hs479.js} +15 -15
- package/dist/cli/{chunk-ehweg4fr.js → chunk-124fvmzq.js} +1031 -903
- package/dist/cli/{chunk-ehweg4fr.js.map → chunk-124fvmzq.js.map} +20 -18
- package/dist/cli/{chunk-kma9f6sf.js → chunk-1f882900.js} +2 -2
- package/dist/cli/{chunk-e8xw9qkh.js → chunk-297ajdcv.js} +4 -4
- package/dist/cli/{chunk-e6atmn4h.js → chunk-32khwcb6.js} +7 -7
- package/dist/cli/{chunk-073rdvgb.js → chunk-36bxs9c7.js} +16 -16
- package/dist/cli/{chunk-mrcccgnh.js → chunk-53jqw8z0.js} +3 -3
- package/dist/cli/{chunk-ft9vfys6.js → chunk-58bt3hag.js} +4 -4
- package/dist/cli/{chunk-sds923fa.js → chunk-5cmts6dv.js} +3 -3
- package/dist/cli/{chunk-cfyg47zg.js → chunk-60hz265r.js} +4 -4
- package/dist/cli/{chunk-j134vrp2.js → chunk-74wfhv79.js} +1 -1
- package/dist/cli/{chunk-nrns10mj.js → chunk-9qzgg6mj.js} +3 -3
- package/dist/cli/{chunk-tphac74f.js → chunk-a57yh0h9.js} +5 -5
- package/dist/cli/{chunk-hebn0tpx.js → chunk-ave1wcbr.js} +1 -1
- package/dist/cli/{chunk-htrwgabr.js → chunk-bqxaqn5p.js} +6 -6
- package/dist/cli/{chunk-5vjtgs6e.js → chunk-bxwhtvw8.js} +5 -5
- package/dist/cli/{chunk-66w9j7p6.js → chunk-ckrcm08h.js} +5 -3
- package/dist/cli/{chunk-66w9j7p6.js.map → chunk-ckrcm08h.js.map} +3 -3
- package/dist/cli/{chunk-n0v7m8ry.js → chunk-desvm72z.js} +3 -3
- package/dist/cli/{chunk-3v3ffbrj.js → chunk-dhwtqnnd.js} +2 -2
- package/dist/cli/{chunk-gb420vvz.js → chunk-dpy8qdjf.js} +7 -4
- package/dist/cli/chunk-dpy8qdjf.js.map +17 -0
- package/dist/cli/{chunk-c1y538kd.js → chunk-dqhg54mr.js} +1 -1
- package/dist/cli/{chunk-42t4jxdx.js → chunk-dv2z0rzf.js} +1 -1
- package/dist/cli/{chunk-cm89scdv.js → chunk-es8h0v3j.js} +9 -11
- package/dist/cli/{chunk-cm89scdv.js.map → chunk-es8h0v3j.js.map} +3 -3
- package/dist/cli/{chunk-hx3xqnk9.js → chunk-gfc5fqvf.js} +14 -14
- package/dist/cli/{chunk-7ppf1rva.js → chunk-gxtg6ed2.js} +16 -16
- package/dist/cli/{chunk-8y2kmjv8.js → chunk-hvcxng5f.js} +6 -6
- package/dist/cli/{chunk-54ztw1nj.js → chunk-j1x92mx9.js} +1 -1
- package/dist/cli/{chunk-313vnn40.js → chunk-k3gr1nm9.js} +11 -9
- package/dist/cli/chunk-k3gr1nm9.js.map +10 -0
- package/dist/cli/{chunk-c887fj0s.js → chunk-kdpzw38a.js} +2 -2
- package/dist/cli/{chunk-t2m5j4pr.js → chunk-ms9z66nz.js} +2 -2
- package/dist/cli/{chunk-t2m5j4pr.js.map → chunk-ms9z66nz.js.map} +2 -2
- package/dist/cli/{chunk-ep6nd0rn.js → chunk-nbyvgnnm.js} +26 -14
- package/dist/cli/{chunk-ep6nd0rn.js.map → chunk-nbyvgnnm.js.map} +7 -7
- package/dist/cli/{chunk-w1r4vase.js → chunk-s0bdnc7v.js} +2 -2
- package/dist/cli/{chunk-fdrkhpjy.js → chunk-sc93apfs.js} +14 -14
- package/dist/cli/{chunk-dzwehpy7.js → chunk-tfycddbt.js} +2 -2
- package/dist/cli/{chunk-3x6x3pph.js → chunk-twy7psdz.js} +7 -7
- package/dist/cli/{chunk-e9q7a2ak.js → chunk-y4msrwm9.js} +15 -15
- package/dist/cli/{chunk-tdqhyxfz.js → chunk-ydp3065p.js} +5 -5
- package/dist/cli/index.js +18 -18
- package/dist/types/ai/ask.d.ts +24 -5
- package/dist/types/analytics/clics.d.ts +37 -0
- package/dist/types/analytics/index.d.ts +2 -0
- package/dist/types/analytics/schema.d.ts +18 -0
- package/dist/types/astro/integration.d.ts +6 -0
- package/dist/types/core/config-input.d.ts +7 -3
- package/dist/types/core/powered-by.d.ts +12 -0
- package/dist/types/core/schema.d.ts +109 -3
- package/dist/types/core/sources/lower.d.ts +10 -2
- package/dist/types/core/sources/notion.d.ts +8 -0
- package/dist/types/deploy/cloudflare-negotiation.d.ts +5 -2
- package/dist/types/deploy/node-headers.d.ts +12 -4
- package/dist/types/deploy/platforms/vercel.d.ts +2 -2
- package/dist/types/deploy/vercel-negotiation.d.ts +4 -2
- package/dist/types/narration/build.d.ts +34 -12
- package/dist/types/narration/provider.d.ts +96 -8
- package/dist/types/openapi/sentence.d.ts +11 -1
- package/dist/types/seo/jsonld.d.ts +11 -6
- package/dist/types/sources/notion.d.ts +8 -0
- package/dist/types/sources/registry.d.ts +9 -0
- package/docs/02-deployment.mdx +29 -1
- package/docs/03-upgrading.mdx +2 -1
- package/docs/04-migrating.mdx +9 -9
- package/docs/08-faq.mdx +12 -12
- package/docs/advanced/changelog.mdx +19 -2
- package/docs/advanced/custom-pages.mdx +1 -1
- package/docs/cli/doctor.mdx +1 -1
- package/docs/configuration/analytics.mdx +19 -1
- package/docs/configuration/index.mdx +1 -0
- package/docs/configuration/narration.mdx +43 -6
- package/docs/content/navigation.mdx +4 -2
- package/docs/content/sources/contentful.mdx +2 -0
- package/docs/content/sources/github-releases.mdx +2 -0
- package/docs/content/sources/notion.mdx +16 -1
- package/docs/content/sources/obsidian.mdx +2 -0
- package/docs/content/sources/payload.mdx +2 -0
- package/docs/content/sources/remote-mdx.mdx +2 -0
- package/docs/content/sources/sanity.mdx +2 -0
- package/docs/content/sources/strapi.mdx +2 -0
- package/docs/discoverability/mcp.mdx +2 -0
- package/docs/discoverability/structured-data.mdx +8 -6
- package/docs/references/asyncapi.mdx +2 -0
- package/docs/references/graphql.mdx +2 -0
- package/docs/references/openapi.mdx +14 -0
- package/package.json +7 -6
- package/skills/blume/SKILL.md +1 -1
- package/skills/blume-migrate/SKILL.md +1 -1
- package/skills/blume-migrate/assets/{oxfmt@0.67.0.patch → oxfmt@0.71.0.patch} +7 -7
- package/skills/blume-migrate/references/monorepo.md +5 -5
- package/src/ai/ask.ts +24 -6
- package/src/analytics/clics.ts +58 -0
- package/src/analytics/head.ts +5 -0
- package/src/analytics/index.ts +2 -0
- package/src/analytics/schema.ts +2 -0
- package/src/astro/generate.ts +13 -8
- package/src/astro/integration.ts +56 -9
- package/src/astro/render-deps.ts +10 -5
- package/src/astro/runtime-deps.ts +23 -2
- package/src/astro/templates.ts +4 -1
- package/src/cli/init/scaffold.ts +6 -3
- package/src/cli/required-secrets.ts +2 -1
- package/src/components/content/view-switcher.ts +7 -4
- package/src/components/layout/NavTree.astro +49 -5
- package/src/components/layout/NavTreeScript.astro +18 -0
- package/src/components/layout/PageLayout.astro +13 -3
- package/src/components/layout/RootLayout.astro +17 -12
- package/src/components/layout/analytics-client.ts +8 -8
- package/src/components/openapi/playground-client.ts +53 -53
- package/src/components/powered-by-middleware.ts +33 -0
- package/src/core/config-input.ts +11 -3
- package/src/core/powered-by.ts +12 -0
- package/src/core/schema.ts +5 -4
- package/src/core/sources/lower.ts +19 -3
- package/src/core/sources/notion.ts +27 -9
- package/src/deploy/cloudflare-negotiation.ts +36 -7
- package/src/deploy/headers.ts +15 -1
- package/src/deploy/node-headers.ts +32 -20
- package/src/deploy/platforms/cloudflare.ts +1 -0
- package/src/deploy/platforms/vercel.ts +4 -3
- package/src/deploy/vercel-negotiation.ts +38 -4
- package/src/markdown/base-links.ts +15 -14
- package/src/markdown/package-commands.ts +9 -8
- package/src/narration/build.ts +218 -40
- package/src/narration/provider.ts +89 -9
- package/src/openapi/render-mdx.ts +68 -8
- package/src/openapi/sentence.ts +29 -2
- package/src/registry/eject.ts +5 -1
- package/src/seo/jsonld.ts +38 -20
- package/src/sources/notion.ts +7 -0
- package/src/theme/color.ts +9 -10
- package/src/theme/entry.ts +14 -3
- package/dist/cli/chunk-313vnn40.js.map +0 -10
- package/dist/cli/chunk-gb420vvz.js.map +0 -17
- /package/dist/cli/{chunk-nq1d20w2.js.map → chunk-0w6hs479.js.map} +0 -0
- /package/dist/cli/{chunk-kma9f6sf.js.map → chunk-1f882900.js.map} +0 -0
- /package/dist/cli/{chunk-e8xw9qkh.js.map → chunk-297ajdcv.js.map} +0 -0
- /package/dist/cli/{chunk-e6atmn4h.js.map → chunk-32khwcb6.js.map} +0 -0
- /package/dist/cli/{chunk-073rdvgb.js.map → chunk-36bxs9c7.js.map} +0 -0
- /package/dist/cli/{chunk-mrcccgnh.js.map → chunk-53jqw8z0.js.map} +0 -0
- /package/dist/cli/{chunk-ft9vfys6.js.map → chunk-58bt3hag.js.map} +0 -0
- /package/dist/cli/{chunk-sds923fa.js.map → chunk-5cmts6dv.js.map} +0 -0
- /package/dist/cli/{chunk-cfyg47zg.js.map → chunk-60hz265r.js.map} +0 -0
- /package/dist/cli/{chunk-j134vrp2.js.map → chunk-74wfhv79.js.map} +0 -0
- /package/dist/cli/{chunk-nrns10mj.js.map → chunk-9qzgg6mj.js.map} +0 -0
- /package/dist/cli/{chunk-tphac74f.js.map → chunk-a57yh0h9.js.map} +0 -0
- /package/dist/cli/{chunk-hebn0tpx.js.map → chunk-ave1wcbr.js.map} +0 -0
- /package/dist/cli/{chunk-htrwgabr.js.map → chunk-bqxaqn5p.js.map} +0 -0
- /package/dist/cli/{chunk-5vjtgs6e.js.map → chunk-bxwhtvw8.js.map} +0 -0
- /package/dist/cli/{chunk-n0v7m8ry.js.map → chunk-desvm72z.js.map} +0 -0
- /package/dist/cli/{chunk-3v3ffbrj.js.map → chunk-dhwtqnnd.js.map} +0 -0
- /package/dist/cli/{chunk-c1y538kd.js.map → chunk-dqhg54mr.js.map} +0 -0
- /package/dist/cli/{chunk-42t4jxdx.js.map → chunk-dv2z0rzf.js.map} +0 -0
- /package/dist/cli/{chunk-hx3xqnk9.js.map → chunk-gfc5fqvf.js.map} +0 -0
- /package/dist/cli/{chunk-7ppf1rva.js.map → chunk-gxtg6ed2.js.map} +0 -0
- /package/dist/cli/{chunk-8y2kmjv8.js.map → chunk-hvcxng5f.js.map} +0 -0
- /package/dist/cli/{chunk-54ztw1nj.js.map → chunk-j1x92mx9.js.map} +0 -0
- /package/dist/cli/{chunk-c887fj0s.js.map → chunk-kdpzw38a.js.map} +0 -0
- /package/dist/cli/{chunk-w1r4vase.js.map → chunk-s0bdnc7v.js.map} +0 -0
- /package/dist/cli/{chunk-fdrkhpjy.js.map → chunk-sc93apfs.js.map} +0 -0
- /package/dist/cli/{chunk-dzwehpy7.js.map → chunk-tfycddbt.js.map} +0 -0
- /package/dist/cli/{chunk-3x6x3pph.js.map → chunk-twy7psdz.js.map} +0 -0
- /package/dist/cli/{chunk-e9q7a2ak.js.map → chunk-y4msrwm9.js.map} +0 -0
- /package/dist/cli/{chunk-tdqhyxfz.js.map → chunk-ydp3065p.js.map} +0 -0
package/src/seo/jsonld.ts
CHANGED
|
@@ -19,7 +19,7 @@ export interface PostalAddressIdentity {
|
|
|
19
19
|
|
|
20
20
|
/**
|
|
21
21
|
* `seo.organization`: the organization behind the site, emitted on every page
|
|
22
|
-
* as an `Organization` node the WebSite and
|
|
22
|
+
* as an `Organization` node the WebSite and page nodes cite as publisher.
|
|
23
23
|
*/
|
|
24
24
|
export interface OrganizationIdentity {
|
|
25
25
|
address?: PostalAddressIdentity;
|
|
@@ -73,6 +73,12 @@ export interface StructuredDataInput {
|
|
|
73
73
|
description?: string;
|
|
74
74
|
/** Page route, e.g. `/blog/post`. */
|
|
75
75
|
route: string;
|
|
76
|
+
/**
|
|
77
|
+
* The route of this page's homepage: the navigation tree root
|
|
78
|
+
* (`navigation.root` — `/fr` for a locale, `/docs` under a `basePath`,
|
|
79
|
+
* `/v1.0` in an archived version). Defaults to `/`.
|
|
80
|
+
*/
|
|
81
|
+
homeRoute?: string;
|
|
76
82
|
/** Deployment base (`import.meta.env.BASE_URL`); prefixed onto absolute URLs. */
|
|
77
83
|
base?: string;
|
|
78
84
|
/** Content type — `blog` and `changelog` map to richer article types. */
|
|
@@ -246,24 +252,41 @@ const softwareNode = (
|
|
|
246
252
|
return node;
|
|
247
253
|
};
|
|
248
254
|
|
|
249
|
-
/** The page
|
|
250
|
-
const
|
|
255
|
+
/** The page's schema.org `@type`: a `WebPage` for a homepage, else an article. */
|
|
256
|
+
const pageSchemaType = (input: StructuredDataInput, home: boolean): string => {
|
|
257
|
+
if (home) {
|
|
258
|
+
return "WebPage";
|
|
259
|
+
}
|
|
260
|
+
const pageType = input.pageType ?? "";
|
|
261
|
+
return isArticleType(pageType) ? ARTICLE_TYPES[pageType] : "TechArticle";
|
|
262
|
+
};
|
|
263
|
+
|
|
264
|
+
/**
|
|
265
|
+
* The page's own node: a homepage is a `WebPage` (it isn't an article, but it
|
|
266
|
+
* still needs a machine-readable date, or search engines take whatever other
|
|
267
|
+
* date the page shows), and every other page an article (`BlogPosting`/
|
|
268
|
+
* `TechArticle`) with a `headline`. Both carry the language, description,
|
|
269
|
+
* dates, the WebSite they belong to, and the publisher.
|
|
270
|
+
*/
|
|
271
|
+
const pageNode = (
|
|
251
272
|
input: StructuredDataInput,
|
|
252
273
|
context: {
|
|
253
274
|
base: string | null;
|
|
275
|
+
home: boolean;
|
|
254
276
|
organizationId: string | null;
|
|
255
277
|
pageUrl: string;
|
|
256
278
|
}
|
|
257
279
|
): JsonLdNode => {
|
|
258
|
-
const pageType = input.pageType ?? "";
|
|
259
280
|
const node: JsonLdNode = {
|
|
260
281
|
"@id": `${context.pageUrl}#page`,
|
|
261
|
-
"@type":
|
|
262
|
-
headline: input.title,
|
|
282
|
+
"@type": pageSchemaType(input, context.home),
|
|
263
283
|
inLanguage: input.locale || "en",
|
|
264
284
|
name: input.title,
|
|
265
285
|
url: context.pageUrl,
|
|
266
286
|
};
|
|
287
|
+
if (!context.home) {
|
|
288
|
+
node.headline = input.title;
|
|
289
|
+
}
|
|
267
290
|
if (input.description) {
|
|
268
291
|
node.description = input.description;
|
|
269
292
|
}
|
|
@@ -315,14 +338,11 @@ const breadcrumbNode = (
|
|
|
315
338
|
/**
|
|
316
339
|
* Build a schema.org JSON-LD `@graph` for a page: site identity (the WebSite,
|
|
317
340
|
* plus the configured Organization everywhere and the SoftwareApplication on
|
|
318
|
-
* the homepage), the page
|
|
319
|
-
*
|
|
320
|
-
*
|
|
321
|
-
* route-relative.
|
|
341
|
+
* the homepage), the page itself (a WebPage on the homepage, an article
|
|
342
|
+
* elsewhere), and an article's breadcrumb trail. URLs are absolute when
|
|
343
|
+
* `siteUrl` is set, otherwise route-relative.
|
|
322
344
|
*/
|
|
323
|
-
export const buildStructuredData = (
|
|
324
|
-
input: StructuredDataInput
|
|
325
|
-
): JsonLdNode | null => {
|
|
345
|
+
export const buildStructuredData = (input: StructuredDataInput): JsonLdNode => {
|
|
326
346
|
const base = input.siteUrl ? trimSlash(input.siteUrl) : null;
|
|
327
347
|
// Routes carry `basePath`; a `deployment.base` subdirectory is layered on top
|
|
328
348
|
// so JSON-LD URLs match the served location.
|
|
@@ -365,9 +385,11 @@ export const buildStructuredData = (
|
|
|
365
385
|
);
|
|
366
386
|
}
|
|
367
387
|
|
|
368
|
-
// The homepage is
|
|
369
|
-
//
|
|
370
|
-
|
|
388
|
+
// The homepage is a WebPage, next to the product when one is configured;
|
|
389
|
+
// deeper pages are articles with a breadcrumb trail.
|
|
390
|
+
const home = input.route === (input.homeRoute ?? "/");
|
|
391
|
+
graph.push(pageNode(input, { base, home, organizationId, pageUrl }));
|
|
392
|
+
if (home) {
|
|
371
393
|
if (software && base) {
|
|
372
394
|
graph.push(
|
|
373
395
|
softwareNode(software, {
|
|
@@ -380,15 +402,11 @@ export const buildStructuredData = (
|
|
|
380
402
|
);
|
|
381
403
|
}
|
|
382
404
|
} else {
|
|
383
|
-
graph.push(articleNode(input, { base, organizationId, pageUrl }));
|
|
384
405
|
const breadcrumbs = breadcrumbNode(input.breadcrumbs, base, deployBase);
|
|
385
406
|
if (breadcrumbs) {
|
|
386
407
|
graph.push(breadcrumbs);
|
|
387
408
|
}
|
|
388
409
|
}
|
|
389
410
|
|
|
390
|
-
if (graph.length === 0) {
|
|
391
|
-
return null;
|
|
392
|
-
}
|
|
393
411
|
return { "@context": "https://schema.org", "@graph": graph };
|
|
394
412
|
};
|
package/src/sources/notion.ts
CHANGED
|
@@ -11,6 +11,12 @@ export interface NotionOptions extends SharedSourceOptions {
|
|
|
11
11
|
concurrency?: number;
|
|
12
12
|
/** Notion database id. */
|
|
13
13
|
database: string;
|
|
14
|
+
/**
|
|
15
|
+
* Read text typed in Notion as MDX, so components and Markdown in it
|
|
16
|
+
* render. Anyone who can edit the database can then run code at build
|
|
17
|
+
* time. Default false: text renders as written.
|
|
18
|
+
*/
|
|
19
|
+
mdx?: boolean;
|
|
14
20
|
/** Notion property names mapped onto Blume meta. */
|
|
15
21
|
properties?: {
|
|
16
22
|
/** Property holding the page description. */
|
|
@@ -31,6 +37,7 @@ export interface NotionOptions extends SharedSourceOptions {
|
|
|
31
37
|
export const notionOptionsSchema = sharedSourceOptionsSchema.extend({
|
|
32
38
|
concurrency: z.number().positive().optional(),
|
|
33
39
|
database: z.string(),
|
|
40
|
+
mdx: z.boolean().optional(),
|
|
34
41
|
properties: z
|
|
35
42
|
.strictObject({
|
|
36
43
|
description: z.string().optional(),
|
package/src/theme/color.ts
CHANGED
|
@@ -374,16 +374,15 @@ const rectangular = (lightness: number, chroma: number, hue: number) => {
|
|
|
374
374
|
/** A color function's channels, converted to sRGB with `alpha`. */
|
|
375
375
|
type Converter = (channels: Channels, alpha: number) => Rgba;
|
|
376
376
|
|
|
377
|
-
const
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
};
|
|
377
|
+
const rgbChannel = (component: Component): number =>
|
|
378
|
+
clamp(scaled(component, 255) / 255);
|
|
379
|
+
|
|
380
|
+
const rgb: Converter = ([red, green, blue], alpha) => ({
|
|
381
|
+
alpha,
|
|
382
|
+
blue: rgbChannel(blue),
|
|
383
|
+
green: rgbChannel(green),
|
|
384
|
+
red: rgbChannel(red),
|
|
385
|
+
});
|
|
387
386
|
|
|
388
387
|
/** A converter for a hue-and-two-percentages function (`hsl()`, `hwb()`). */
|
|
389
388
|
const cylindrical =
|
package/src/theme/entry.ts
CHANGED
|
@@ -263,13 +263,24 @@ ${THEME_MAPPING}
|
|
|
263
263
|
so a large site's HTML is mostly this markup — one utility per row kind
|
|
264
264
|
instead of the dozen classes each expands to keeps every page (and the
|
|
265
265
|
build's HTML output) small. Kept in sync with NavTree.astro: a page row,
|
|
266
|
-
a page-mode group's drill-in
|
|
267
|
-
|
|
266
|
+
a page-mode group's drill-in row (or, when the group has a page, the
|
|
267
|
+
link and chevron button it splits into), a collapsible group's summary
|
|
268
|
+
and the link inside it, and a flat group's heading and the link inside
|
|
269
|
+
it. */
|
|
268
270
|
@utility blume-nav-link {
|
|
269
271
|
@apply block rounded-[0.65rem] px-2.5 py-1.5 text-muted-foreground text-sm transition-colors hover:bg-muted hover:text-foreground aria-[current=page]:bg-muted aria-[current=page]:font-medium aria-[current=page]:text-foreground;
|
|
270
272
|
}
|
|
271
273
|
@utility blume-nav-drill {
|
|
272
|
-
@apply flex w-full items-center gap-2 rounded-[0.65rem] px-2.5 py-1.5 text-start font-medium text-foreground text-sm transition-colors hover:bg-muted;
|
|
274
|
+
@apply flex w-full items-center gap-2 rounded-[0.65rem] px-2.5 py-1.5 text-start font-medium text-foreground text-sm transition-colors hover:bg-muted aria-[current]:bg-muted;
|
|
275
|
+
}
|
|
276
|
+
/* A routed drill row's label and chevron are separate pills, like a panel's
|
|
277
|
+
back button and title, so each shows which one the pointer is on. The
|
|
278
|
+
chevron's padding matches the drill row's, so chevrons line up. */
|
|
279
|
+
@utility blume-nav-drill-link {
|
|
280
|
+
@apply flex min-w-0 flex-1 items-center gap-2 rounded-[0.65rem] px-2.5 py-1.5 font-medium text-foreground text-sm transition-colors hover:bg-muted aria-[current]:bg-muted;
|
|
281
|
+
}
|
|
282
|
+
@utility blume-nav-drill-toggle {
|
|
283
|
+
@apply flex shrink-0 items-center justify-center self-stretch rounded-[0.65rem] px-2.5 text-muted-foreground transition-colors hover:bg-muted hover:text-foreground;
|
|
273
284
|
}
|
|
274
285
|
@utility blume-nav-summary {
|
|
275
286
|
@apply flex cursor-pointer list-none items-center gap-1.5 rounded-[0.65rem] px-2.5 py-1.5 text-muted-foreground text-sm transition-colors hover:bg-muted hover:text-foreground [&::-webkit-details-marker]:hidden;
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../src/registry/eject.ts"],
|
|
4
|
-
"sourcesContent": [
|
|
5
|
-
"import { existsSync } from \"node:fs\";\nimport { cp, mkdir, readFile, rm, writeFile } from \"node:fs/promises\";\n\nimport { join, relative } from \"pathe\";\n\nimport { OPENAPI_PATH } from \"../ai/api/paths.ts\";\nimport { buildApiSpec } from \"../ai/api/spec.ts\";\nimport { buildAskData } from \"../ai/ask-data.ts\";\nimport { resolveAskBackend } from \"../ai/ask.ts\";\nimport { buildRawMarkdown } from \"../ai/markdown.ts\";\nimport { buildMcpData } from \"../ai/mcp/data.ts\";\nimport type { McpData } from \"../ai/mcp/data.ts\";\nimport { buildMcpDiscovery, buildMcpServerCard } from \"../ai/mcp/discovery.ts\";\nimport { planComponentSlots } from \"../astro/component-slots.ts\";\nimport {\n EXAMPLE_SCAN_GLOB,\n discoverExamples,\n exampleMarkdownLookup,\n exampleScanRoots,\n} from \"../astro/examples.ts\";\nimport {\n analyzeComponentsFile,\n buildRuntimeData,\n clientFeaturesFor,\n collectStaged,\n detectNeedsReact,\n detectUsesMath,\n languageIconCssFor,\n PLAYGROUND_PROXY_ENTRY,\n playgroundProxyPattern,\n proxyAllowlistWarnings,\n specOrigins,\n} from \"../astro/generate.ts\";\nimport { discoverIslands } from \"../astro/islands.ts\";\nimport { customOgRoutes, discoverPages, routeIsTaken } from \"../astro/pages.ts\";\nimport {\n apiNavigationTemplate,\n apiNotFoundTemplate,\n apiPagesIndexTemplate,\n apiPageTemplate,\n apiSearchTemplate,\n askComponentTemplate,\n askEndpointTemplate,\n astroConfigTemplate,\n catchAllPageTemplate,\n changelogIndexTemplate,\n contentAssetsEndpointTemplate,\n contentConfigTemplate,\n exampleMapTemplate,\n exampleSlug,\n examplesPageTemplate,\n exampleWrapperTemplate,\n featuresTemplate,\n mcpEndpointTemplate,\n mcpPageFile,\n mixedbreadSearchEndpointTemplate,\n notFoundJsonTemplate,\n notFoundMarkdownTemplate,\n notFoundPageTemplate,\n ogEndpointTemplate,\n playgroundProxyTemplate,\n rawMarkdownEndpointTemplate,\n rssEndpointTemplate,\n runtimeDependencies,\n runtimeTsconfigTemplate,\n consentClientTemplate,\n searchClientTemplate,\n searchEndpointTemplate,\n staticJsonEndpointTemplate,\n} from \"../astro/templates.ts\";\nimport { collectContentAssets } from \"../core/content-assets.ts\";\nimport { buildIncludeGraph } from \"../core/includes.ts\";\nimport { packageRoot } from \"../core/package-root.ts\";\nimport { scanProject } from \"../core/project-graph.ts\";\nimport type { BlumeProject } from \"../core/project-graph.ts\";\nimport {\n resolveDocsCollection,\n sourcesOfKind,\n} from \"../core/sources/collection.ts\";\nimport type { ProjectContext } from \"../core/types.ts\";\nimport { buildRssFeeds, renderRssFeed } from \"../deploy/rss.ts\";\nimport { resolveOgFonts } from \"../og/derive.ts\";\nimport type { OpenApiData } from \"../openapi/model.ts\";\nimport {\n hasScalarReferences,\n needsPlaygroundProxy,\n} from \"../openapi/references.ts\";\nimport { buildReferenceFiles } from \"../openapi/scalar.ts\";\nimport { isOpenApiSource } from \"../openapi/source.ts\";\nimport { buildSearchDocuments } from \"../search/documents.ts\";\nimport { sourcePages } from \"../search/source-pages.ts\";\nimport {\n examplesEntryTemplate,\n tailwindEntryTemplate,\n} from \"../theme/entry.ts\";\nimport { fontLocaleCodes } from \"../theme/fonts.ts\";\nimport { buildThemeCss } from \"../theme/palette.ts\";\nimport { rebaseSourceDirectives } from \"../theme/sources.ts\";\nimport { twoslashCss } from \"../theme/twoslash.ts\";\n\nconst toPosix = (path: string): string => path.split(\"\\\\\").join(\"/\");\n\n/** The portable `@source` guess: blume in the project's own node_modules. */\nconst LOCAL_BLUME_SOURCE = \"../../node_modules/blume/src/**/*.{astro,ts,tsx}\";\n\n/**\n * The `@source` glob pointing Tailwind at Blume's own source, relative to the\n * ejected `src/generated/app.css`. The project-local `node_modules/blume` is\n * preferred (portable, and under pnpm the symlink survives version bumps), but\n * hoisted installs (npm/yarn workspaces lift blume into the workspace root's\n * node_modules) would make that guess match nothing and silently drop utility\n * classes — so fall back to the package's real installed location, and when\n * even that fails, warn instead of failing silently.\n *\n * Exported for testing.\n */\nexport const blumeSourceGlob = (\n root: string,\n genDir: string,\n resolveBlumeRoot: () => string = packageRoot\n): string => {\n if (existsSync(join(root, \"node_modules\", \"blume\"))) {\n return LOCAL_BLUME_SOURCE;\n }\n try {\n const src = join(resolveBlumeRoot(), \"src\");\n return `${toPosix(relative(genDir, src))}/**/*.{astro,ts,tsx}`;\n } catch {\n console.warn(\n 'blume: could not locate the installed blume package; src/generated/app.css keeps its default `@source \"../../node_modules/blume/...\"` glob. If blume is hoisted elsewhere, point that glob at its install location or Blume\\'s utility classes will be missing.'\n );\n return LOCAL_BLUME_SOURCE;\n }\n};\n\n/** The `blume:openapi` payload for the ejected app (`{}` when none). */\nconst ejectOpenApiData = (project: BlumeProject): OpenApiData => {\n const source = project.sources.find(isOpenApiSource);\n return source ? source.openApiData() : {};\n};\n\n/**\n * The assistant endpoint plus, unless the backend runs its own retrieval (Inkeep),\n * its grounding snapshot. Empty when the assistant is disabled.\n */\nconst askFiles = async (\n project: BlumeProject,\n srcDir: string,\n genDir: string\n): Promise<{ content: string; path: string }[]> => {\n const { assistant } = project.config.ai;\n if (!(assistant?.enabled && !assistant.endpoint)) {\n const endpointPath = join(srcDir, \"pages\", \"api\", \"ask.ts\");\n if (existsSync(endpointPath)) {\n const content = await readFile(endpointPath, \"utf-8\");\n if (content.startsWith(\"// Generated by Blume. Do not edit.\")) {\n await rm(endpointPath, { force: true });\n }\n }\n await rm(join(genDir, \"ask-data.json\"), { force: true });\n return [];\n }\n const backend = resolveAskBackend(assistant.provider);\n const files = [\n {\n content: askEndpointTemplate(backend, {\n captcha: assistant.captcha,\n cors: assistant.cors,\n instructions: assistant.instructions,\n rateLimit: project.config.rateLimit,\n retrieval: assistant.retrieval,\n tools: assistant.tools ?? backend.toolsByDefault,\n }),\n path: join(srcDir, \"pages\", \"api\", \"ask.ts\"),\n },\n ];\n if (backend.grounded) {\n files.push({\n content: `${JSON.stringify(await buildAskData(project))}\\n`,\n path: join(genDir, \"ask-data.json\"),\n });\n }\n return files;\n};\n\n/** Whether the ejected app hosts the MCP server (enabled and route free). */\nconst hostsMcp = (\n project: BlumeProject,\n userPages: { pattern: string }[]\n): boolean =>\n project.config.agents.mcp.enabled &&\n !routeIsTaken(\n userPages,\n project.graph.pages,\n project.config.agents.mcp.route\n );\n\n/**\n * The `.well-known` MCP discovery routes, injected as prerendered pages\n * alongside the user's own so the ejected Astro config wires them in. Empty\n * when the server is disabled or its route is already owned by a page.\n */\nconst mcpDiscoveryPages = (\n project: BlumeProject,\n userPages: { pattern: string }[]\n): { entrypoint: string; pattern: string }[] =>\n hostsMcp(project, userPages)\n ? [\n {\n entrypoint: \"src/blume-mcp/discovery.ts\",\n pattern: \"/.well-known/mcp.json\",\n },\n {\n entrypoint: \"src/blume-mcp/server-card.ts\",\n pattern: \"/.well-known/mcp/server-card.json\",\n },\n ]\n : [];\n\n/**\n * The playground's built-in CORS proxy route (`playground: { proxy: true }`),\n * mirroring `planPlaygroundProxy` in generate.ts: injected like the MCP\n * discovery routes, because Astro treats a `_`-prefixed page file as private,\n * and mounted under `basePath` at the URL the playground sends to. Empty when\n * no reference routes its playground through it.\n */\nconst playgroundProxyPages = (\n config: BlumeProject[\"config\"]\n): { entrypoint: string; pattern: string }[] =>\n needsPlaygroundProxy(config)\n ? [\n {\n entrypoint: toPosix(join(\"src\", PLAYGROUND_PROXY_ENTRY)),\n pattern: playgroundProxyPattern(config),\n },\n ]\n : [];\n\n/**\n * The proxy endpoint behind {@link playgroundProxyPages}, with the origin\n * allowlist baked in from the same parsed specs the reference pages render.\n */\nconst playgroundProxyFiles = (\n config: BlumeProject[\"config\"],\n openApiData: OpenApiData,\n srcDir: string\n): { content: string; path: string }[] =>\n needsPlaygroundProxy(config)\n ? [\n {\n content: playgroundProxyTemplate(\n specOrigins(openApiData),\n config.rateLimit\n ),\n path: join(srcDir, PLAYGROUND_PROXY_ENTRY),\n },\n ]\n : [];\n\n/**\n * The agent data snapshot (`blume:mcp-data`) behind the MCP server and the\n * JSON docs API, mirroring `publishAgentData` in generate.ts: built when\n * either is on, null when neither needs it.\n */\nconst ejectAgentData = async (\n project: BlumeProject,\n userPages: { pattern: string }[]\n): Promise<McpData | null> =>\n hostsMcp(project, userPages) || project.config.agents.api\n ? await buildMcpData(project)\n : null;\n\n/**\n * The MCP server endpoint and `.well-known` discovery documents, mirroring\n * `writeMcpFiles` in generate.ts. Empty when the server is disabled or its\n * route is already owned by a page.\n */\nconst mcpFiles = (\n project: BlumeProject,\n userPages: { pattern: string }[],\n srcDir: string,\n data: McpData | null\n): { content: string; path: string }[] => {\n if (!(data && hostsMcp(project, userPages))) {\n return [];\n }\n const { route } = project.config.agents.mcp;\n const discoveryInput = {\n base: data.base,\n name: data.name,\n route,\n site: data.site,\n version: data.version,\n };\n return [\n {\n content: mcpEndpointTemplate(),\n path: join(srcDir, \"pages\", mcpPageFile(route)),\n },\n {\n content: staticJsonEndpointTemplate(buildMcpDiscovery(discoveryInput)),\n path: join(srcDir, \"blume-mcp\", \"discovery.ts\"),\n },\n {\n content: staticJsonEndpointTemplate(buildMcpServerCard(discoveryInput)),\n path: join(srcDir, \"blume-mcp\", \"server-card.ts\"),\n },\n ];\n};\n\n/**\n * The JSON docs API, mirroring `planApi` and `writeApiFiles` in generate.ts:\n * the prerendered page index, per-page documents, and navigation; on server\n * output the search endpoint and, unless a user page or a content page already\n * lives under `/api/`, the JSON 404 catch-all; and `/openapi.json`, unless a\n * `public/openapi.json` or a page owns that route. The ejected `llms.txt`,\n * homepage `Link` header, and 404 page advertise these routes, so the ejected\n * app serves them. Empty when `agents.api` is off.\n */\nconst apiFiles = (\n project: BlumeProject,\n userPages: { pattern: string }[],\n root: string,\n srcDir: string,\n data: McpData | null\n): { content: string; path: string }[] => {\n const { config } = project;\n if (!(data && config.agents.api)) {\n return [];\n }\n const server = config.deployment.options.output === \"server\";\n const apiDir = join(srcDir, \"pages\", \"api\");\n const files = [\n {\n content: apiPagesIndexTemplate(),\n path: join(apiDir, \"docs\", \"pages.json.ts\"),\n },\n {\n content: apiPageTemplate(),\n path: join(apiDir, \"docs\", \"pages\", \"[...route].json.ts\"),\n },\n {\n content: apiNavigationTemplate(),\n path: join(apiDir, \"docs\", \"navigation.json.ts\"),\n },\n ];\n if (server) {\n files.push({\n content: apiSearchTemplate(),\n path: join(apiDir, \"docs\", \"search.ts\"),\n });\n }\n const apiOwned =\n userPages.some((page) => page.pattern.startsWith(\"/api/[\")) ||\n project.graph.pages.some(\n (page) => page.route === \"/api\" || page.route.startsWith(\"/api/\")\n );\n if (server && !apiOwned) {\n files.push({\n content: apiNotFoundTemplate({ base: data.base, site: data.site }),\n path: join(apiDir, \"[...path].ts\"),\n });\n }\n if (\n !(\n routeIsTaken(userPages, project.graph.pages, OPENAPI_PATH) ||\n existsSync(join(root, \"public\", \"openapi.json\"))\n )\n ) {\n files.push({\n content: staticJsonEndpointTemplate(\n buildApiSpec({\n agentReadability: config.agents.agentReadability,\n base: data.base,\n description: config.description,\n llmsTxt: config.agents.llmsTxt.enabled,\n mcpRoute: hostsMcp(project, userPages)\n ? config.agents.mcp.route\n : null,\n name: config.title,\n search: server,\n site: data.site,\n version: data.version,\n })\n ),\n path: join(srcDir, \"pages\", \"openapi.json.ts\"),\n });\n }\n return files;\n};\n\n/**\n * The `/changelog` index page, mirroring `shouldGenerateChangelog` in\n * generate.ts: emitted when `type: changelog` entries or a release-backed\n * changelog source exist, unless a user page already owns the route.\n */\nconst changelogFiles = (\n project: BlumeProject,\n userPages: { pattern: string }[],\n srcDir: string,\n options: Parameters<typeof changelogIndexTemplate>[0]\n): { content: string; path: string }[] => {\n const hasChangelog = project.graph.pages.some(\n (page) =>\n page.contentType === \"changelog\" &&\n !(page.meta.draft || page.meta.sidebar.hidden)\n );\n const hasChangelogSource =\n sourcesOfKind(project.config, \"github-releases\").length > 0;\n if (\n !(hasChangelog || hasChangelogSource) ||\n routeIsTaken(userPages, project.graph.pages, \"/changelog\")\n ) {\n return [];\n }\n return [\n {\n content: changelogIndexTemplate(options),\n path: join(srcDir, \"pages\", \"changelog.astro\"),\n },\n ];\n};\n\n/**\n * The colocated-image map and the `/blume-assets/[...asset]` endpoint that\n * serves it, mirroring generate.ts: the ejected raw Markdown points\n * `` at `/blume-assets/content/…`, and the config aliases\n * `blume:content-assets` to the map. Each original's path is written relative\n * to the project root (the directory `astro dev`/`astro build` run from), so\n * the ejected app builds from any checkout. Remote-source images need no\n * endpoint: eject copies them into the project's own `public/blume-assets`.\n */\nconst contentAssetFiles = async (\n project: BlumeProject,\n root: string,\n srcDir: string,\n genDir: string\n): Promise<{ content: string; path: string }[]> => {\n const assets = await collectContentAssets(project);\n const portable = Object.fromEntries(\n Object.entries(assets).map(([param, abs]) => [\n param,\n toPosix(relative(root, abs)),\n ])\n );\n return [\n {\n content: `${JSON.stringify(portable)}\\n`,\n path: join(genDir, \"content-assets.json\"),\n },\n {\n content: contentAssetsEndpointTemplate(null),\n path: join(srcDir, \"pages\", \"blume-assets\", \"[...asset].ts\"),\n },\n ];\n};\n\n/**\n * The partial → including-pages map with every path relative to the project\n * root, like every other path in the ejected app, so it holds in any checkout.\n * Its readers (`includeHmrPlugin`, `withIncludeRefresh`) resolve each path\n * against the app's root, which after eject is the project itself.\n */\nconst portableIncludeGraph = (\n project: BlumeProject,\n root: string\n): Record<string, string[]> =>\n Object.fromEntries(\n Object.entries(buildIncludeGraph(project.graph.pages)).map(\n ([partial, includers]) => [\n toPosix(relative(root, partial)),\n includers.map((page) => toPosix(relative(root, page))),\n ]\n )\n );\n\n/** Contents of the configured `examples.css`, or `\"\"` when unset/absent. */\n/**\n * Read a user stylesheet that eject inlines into a generated entry under\n * `genDir`, re-rooting its relative `@source` paths from the user's file.\n * Resolves to an empty string when the file is unset or absent.\n */\nconst readUserCss = async (\n file: string | null,\n genDir: string\n): Promise<string> => {\n if (!(file && existsSync(file))) {\n return \"\";\n }\n const css = await readFile(file, \"utf-8\");\n return rebaseSourceDirectives(css, { from: file, to: genDir });\n};\n\n/**\n * The per-example preview route `<Component />` iframes embed, nested under\n * `basePath` so it stays reachable behind a proxy that only forwards the\n * base. Empty when the project has no examples.\n */\nconst examplesPreviewFiles = (\n srcDir: string,\n basePath: string,\n hasExamples: boolean\n): { content: string; path: string }[] =>\n hasExamples\n ? [\n {\n content: examplesPageTemplate(),\n path: join(\n srcDir,\n \"pages\",\n ...basePath.split(\"/\").filter(Boolean),\n \"blume-examples\",\n \"[...path].astro\"\n ),\n },\n ]\n : [];\n\n/**\n * The packages the ejected app imports by bare name: Astro, Tailwind's Vite\n * plugin, Tailwind and its typography plugin (which the generated `app.css`\n * and `examples.css` import by name), `blume` itself, the integrations the\n * config wires in, whatever the configured adapters declare, and React when\n * islands, examples, or the assistant render with it (Blume ships React, so\n * projects rarely list it). They have to be the project's own dependencies\n * after eject — under a strict linker such as pnpm nothing else makes them\n * resolvable, and `astro build` fails. The hidden runtime reaches the same\n * packages through its `node_modules` junction into Blume's own, so only\n * eject declares the ones its generated files import directly: the AI SDK the\n * assistant route streams through (unless `ai.assistant.endpoint` points\n * elsewhere, when no route is written) and the EPUB generator's browser bundle\n * `features.ts` loads (only named there when `export.epub` is on).\n */\nconst ejectDependencies = (\n options: Parameters<typeof runtimeDependencies>[0]\n): string[] => {\n const { assistant } = options.config.ai;\n return [\n ...new Set([\n \"astro\",\n \"@tailwindcss/vite\",\n \"tailwindcss\",\n \"@tailwindcss/typography\",\n \"blume\",\n ...runtimeDependencies(options),\n ...(options.needsReact ? [\"react\", \"react-dom\"] : []),\n ...(assistant?.enabled && !assistant.endpoint ? [\"ai\"] : []),\n ...(options.config.export.epub ? [\"epub-gen-memory\"] : []),\n ]),\n ];\n};\n\nconst ejectIntegrationBridge = (\n config: BlumeProject[\"config\"],\n root: string,\n configFile: string | null\n): Parameters<typeof astroConfigTemplate>[0][\"integrationBridge\"] =>\n config.integrations.length > 0 && configFile\n ? { configFile: toPosix(relative(root, configFile)) }\n : undefined;\n\n/**\n * Promote the generated runtime into the project as an owned Astro app. After\n * eject the project has a normal `astro.config.mjs` and `src/`, the `blume` CLI\n * is no longer required, and the `blume` package remains importable.\n *\n * Returns the written files plus non-fatal warnings, mirroring the generated\n * runtime (e.g. a Scalar reference spec that wasn't found, or a reference\n * route colliding with a content page), and the packages the ejected app\n * imports by bare name, for the caller to add to package.json.\n */\nexport const eject = async (\n root: string\n): Promise<{ dependencies: string[]; files: string[]; warnings: string[] }> => {\n const project = await scanProject(root, { mode: \"build\" });\n const { context, config } = project;\n\n const srcDir = join(root, \"src\");\n const genDir = join(srcDir, \"generated\");\n const assistantEnabled = config.ai.assistant?.enabled ?? false;\n const exportPdf = config.export.pdf;\n const exportEpub = config.export.epub;\n\n // Discover examples first and expose them on the project, so the agent-facing\n // Markdown built below (raw `.md`, MCP) downlevels `<Component>` to its source.\n const examples = await discoverExamples(root, config.examples.source);\n project.examples = exampleMarkdownLookup(examples.examples);\n\n const [\n pages,\n needsReactRaw,\n usesMath,\n userTheme,\n userExamplesCss,\n rawMarkdown,\n islands,\n overrideAnalysis,\n ] = await Promise.all([\n context.pagesRoot ? discoverPages(context.pagesRoot) : Promise.resolve([]),\n detectNeedsReact(root),\n detectUsesMath(root),\n readUserCss(context.themeFile, genDir),\n readUserCss(\n config.examples.css ? join(root, config.examples.css) : null,\n genDir\n ),\n buildRawMarkdown(project),\n discoverIslands(root),\n analyzeComponentsFile(context.componentsFile),\n ]);\n // The `islands/` convention and `components.ts` share the same static plan\n // the CLI uses, with every import written relative to its generated file so\n // the ejected app builds from any checkout (like the example wrappers below).\n const slotPlan = planComponentSlots(islands.islands, overrideAnalysis, {\n relativeTo: genDir,\n });\n // Island/example/override frameworks drive which Astro renderers the ejected\n // config wires in; React also switches on for project `.tsx`/`.jsx` and the assistant.\n const frameworks = new Set<string>([\n ...islands.islands.map((island) => island.framework),\n ...examples.examples.map((example) => example.framework),\n ...slotPlan.frameworks,\n ]);\n const needsReact =\n needsReactRaw || assistantEnabled || frameworks.has(\"react\");\n const needsVue = frameworks.has(\"vue\");\n const needsSvelte = frameworks.has(\"svelte\");\n\n // A project-relative context so generated files use portable paths.\n const relContext: ProjectContext = {\n ...context,\n contentRoot: toPosix(relative(root, context.contentRoot)),\n distDir: \"./dist\",\n outDir: \".\",\n pagesRoot: context.pagesRoot\n ? `./${toPosix(relative(root, context.pagesRoot))}`\n : null,\n root: \".\",\n };\n // The `docs` collection resolves its base against the real project root and\n // is then relativized like everything else, so the ejected content config\n // never bakes in the absolute path `eject` happened to run from.\n const docsCollection = resolveDocsCollection(config, root);\n const relCollection = {\n ...docsCollection,\n base: toPosix(relative(root, docsCollection.base)),\n };\n\n const relPages = [\n ...pages.map((page) => ({\n entrypoint: toPosix(relative(root, page.entrypoint)),\n pattern: page.pattern,\n })),\n ...mcpDiscoveryPages(project, pages),\n ...playgroundProxyPages(config),\n ];\n const openApiData = ejectOpenApiData(project);\n\n // Non-filesystem sources eject their materialized MDX into `<root>/blume-staged`\n // (a dedicated dir so it never clashes with a content root literally named\n // `content`; the relative `staged` collection points there).\n const staged = collectStaged(project);\n const hasStaged = staged.size > 0;\n const stagedDir = \"blume-staged\";\n const features = await clientFeaturesFor(project);\n const languageIcons = await languageIconCssFor(project);\n\n const files: {\n path: string;\n content: string;\n /** Don't overwrite a file the user already owns (e.g. a tuned tsconfig). */\n skipIfExists?: boolean;\n }[] = [\n {\n content: astroConfigTemplate({\n askPath: \"./src/generated/Ask.astro\",\n config,\n consentClientPath: \"./src/generated/consent-client.ts\",\n contentRoot: relContext.contentRoot,\n contentRoutes: project.manifest.routes.map((route) => route.path),\n context: relContext,\n examplesPath: \"./src/generated/examples.ts\",\n examplesThemePath: \"./src/generated/examples.css\",\n features,\n featuresPath: \"./src/generated/features.ts\",\n // No CLI publishes the runtime data modules in memory after eject, so\n // the config aliases each to the JSON snapshot written below.\n generatedModulesDir: \"./src/generated\",\n integrationBridge: ejectIntegrationBridge(\n config,\n root,\n context.configFile\n ),\n needsReact,\n needsSvelte,\n needsVue,\n pages: relPages,\n searchClientPath: \"./src/generated/search-client.ts\",\n themePath: \"./src/generated/app.css\",\n }),\n path: join(root, \"astro.config.mjs\"),\n },\n {\n content: runtimeTsconfigTemplate(),\n path: join(root, \"tsconfig.json\"),\n // Never clobber a hand-tuned tsconfig; only write ours if none exists.\n skipIfExists: true,\n },\n {\n content: contentConfigTemplate({\n collection: relCollection,\n config,\n context: relContext,\n staged: hasStaged,\n stagedBase: stagedDir,\n }),\n path: join(srcDir, \"content.config.ts\"),\n },\n {\n content: catchAllPageTemplate({\n exportEpub,\n exportPdf,\n mathEnabled: usesMath,\n needsReact,\n }),\n path: join(srcDir, \"pages\", \"[...slug].astro\"),\n },\n {\n content: slotPlan.module,\n path: join(genDir, \"components.ts\"),\n },\n // The example map the catch-all imports; written even when empty so the\n // `blume:examples` alias always resolves.\n {\n content: exampleMapTemplate(examples.examples, config.basePath),\n path: join(genDir, \"examples.ts\"),\n },\n {\n // The isolated Tailwind entry for `<Component />` preview frames.\n // Relative sources keep the ejected app portable.\n content: examplesEntryTemplate({\n configTokens: buildThemeCss(config.theme),\n sources: exampleScanRoots(root, examples.dir).map(\n (dir) => `${relative(genDir, dir)}/${EXAMPLE_SCAN_GLOB}`\n ),\n userCss: userExamplesCss,\n }),\n path: join(genDir, \"examples.css\"),\n },\n {\n content: tailwindEntryTemplate({\n configTokens: buildThemeCss(config.theme),\n languageIcons,\n // Relative paths from src/generated/app.css keep the ejected app\n // portable; the blume glob resolves the real install location when\n // the package is hoisted out of the project's own node_modules.\n sources: [\n blumeSourceGlob(root, genDir),\n \"../../**/*.{astro,jsx,mdx,ts,tsx}\",\n ],\n twoslashCss: twoslashCss(),\n userTheme,\n }),\n path: join(genDir, \"app.css\"),\n },\n { content: buildRuntimeData(project), path: join(genDir, \"data.json\") },\n // The header's Ask trigger behind the `blume:ask` alias. Always written — it\n // renders nothing when Ask is off — so the alias always resolves.\n {\n content: askComponentTemplate(assistantEnabled),\n path: join(genDir, \"Ask.astro\"),\n },\n {\n content: `${JSON.stringify(openApiData)}\\n`,\n path: join(genDir, \"openapi.json\"),\n },\n {\n content: `${JSON.stringify(rawMarkdown)}\\n`,\n path: join(genDir, \"raw-markdown.json\"),\n },\n {\n // The partial → including-pages map behind `includeHmrPlugin`, which the\n // ejected astro.config wires at this exact path — without the file every\n // hot update's read would silently no-op and partial edits would serve\n // stale pages. A snapshot like the rest of `src/generated`: the ejected\n // app owns (and may regenerate or prune) it.\n content: `${JSON.stringify(portableIncludeGraph(project, root))}\\n`,\n path: join(genDir, \"includes.json\"),\n },\n {\n content: rawMarkdownEndpointTemplate(\"md\"),\n path: join(srcDir, \"pages\", \"[...slug].md.ts\"),\n },\n {\n content: rawMarkdownEndpointTemplate(\"mdx\"),\n path: join(srcDir, \"pages\", \"[...slug].mdx.ts\"),\n },\n ];\n\n files.push(...(await contentAssetFiles(project, root, srcDir, genDir)));\n\n if (assistantEnabled) {\n files.push(...(await askFiles(project, srcDir, genDir)));\n }\n\n // The `/changelog` index, mirrored from the generated runtime (`[]` when\n // the project has no changelog). The OG endpoint below adds its card.\n const changelog = changelogFiles(project, pages, srcDir, {\n exportEpub,\n exportPdf,\n needsReact,\n staged: hasStaged,\n });\n\n if (config.seo.og.enabled) {\n // The default script fallbacks ride along (Google family names, nothing\n // machine-specific), so a non-Latin card still renders after eject. An\n // explicit seo.og.fonts replaces them, and isn't carried over.\n const { fallbacks, families } = resolveOgFonts(\n {\n locales: fontLocaleCodes(config.i18n),\n ogFonts: config.seo.og.fonts,\n themeFonts: config.theme.fonts,\n themeFontsConfigured: false,\n },\n root\n );\n files.push({\n content: ogEndpointTemplate(\n customOgRoutes(pages, config.title, config.seo.og.titles),\n {\n fallbacks,\n families,\n pageDescriptions: config.seo.og.description !== false,\n },\n changelog.length > 0\n ),\n path: join(srcDir, \"pages\", \"og\", \"[...slug].png.ts\"),\n });\n }\n\n // The hosted MCP server, the JSON docs API, and the playground's built-in\n // proxy, mirrored from the generated runtime (`[]` when each is off). The\n // server and the API share one agent data snapshot.\n const agentData = await ejectAgentData(project, pages);\n if (agentData) {\n files.push({\n content: `${JSON.stringify(agentData)}\\n`,\n path: join(genDir, \"mcp-data.json\"),\n });\n }\n files.push(\n ...mcpFiles(project, pages, srcDir, agentData),\n ...apiFiles(project, pages, root, srcDir, agentData),\n ...changelog,\n ...playgroundProxyFiles(config, openApiData, srcDir)\n );\n\n // Default 404 page and its Markdown (`/404.md`) and JSON (`/404.json`)\n // twins, mirroring `writeNotFoundPage` in generate.ts: all three are skipped\n // when the project already owns `/404` (a custom `pages/404.astro` or a\n // `404.md` content page). The ejected project owns the files afterwards and\n // can edit or remove them.\n if (!routeIsTaken(pages, project.graph.pages, \"/404\")) {\n files.push(\n {\n content: notFoundPageTemplate(),\n path: join(srcDir, \"pages\", \"404.astro\"),\n },\n {\n content: notFoundMarkdownTemplate(),\n path: join(srcDir, \"pages\", \"404.md.ts\"),\n },\n {\n content: notFoundJsonTemplate(),\n path: join(srcDir, \"pages\", \"404.json.ts\"),\n }\n );\n }\n\n // The client-feature loaders behind the `blume:features` alias, the\n // provider-specific client loader behind `blume:search-client`, and the\n // consent adapter's browser module behind `blume:consent-client`.\n files.push(\n {\n content: featuresTemplate(features),\n path: join(genDir, \"features.ts\"),\n },\n {\n content: searchClientTemplate(config),\n path: join(genDir, \"search-client.ts\"),\n },\n {\n content: consentClientTemplate(config.consent),\n path: join(genDir, \"consent-client.ts\"),\n }\n );\n\n const searchAdapter = config.search.provider;\n if (searchAdapter.mode === \"static\") {\n const documents = await buildSearchDocuments(project);\n files.push(\n {\n content: `${JSON.stringify(documents)}\\n`,\n path: join(genDir, \"search.json\"),\n },\n {\n content: searchEndpointTemplate(),\n path: join(srcDir, \"pages\", \"blume-search.json.ts\"),\n }\n );\n }\n\n if (searchAdapter.kind === \"mixedbread\") {\n files.push({\n content: mixedbreadSearchEndpointTemplate(\n searchAdapter.options,\n sourcePages(project),\n config.rateLimit\n ),\n path: join(srcDir, \"pages\", \"api\", \"search.ts\"),\n });\n }\n\n const feeds = buildRssFeeds(project);\n if (feeds.length > 0) {\n const feedXml = Object.fromEntries(\n feeds.map((feed) => [feed.type, renderRssFeed(feed)])\n );\n files.push(\n {\n content: `${JSON.stringify(feedXml)}\\n`,\n path: join(genDir, \"rss.json\"),\n },\n {\n content: rssEndpointTemplate(),\n path: join(srcDir, \"pages\", \"[section]\", \"rss.xml.ts\"),\n }\n );\n }\n\n // Scalar API/AsyncAPI reference pages, mirrored from the generated runtime so\n // the ejected app keeps its reference routes — including the warnings (a\n // missing spec file, a route collision), which the caller surfaces exactly\n // like the generated-runtime path does.\n // A proxied spec with no origin to allow gets the generated runtime's\n // diagnostic too.\n const warnings: string[] = proxyAllowlistWarnings(config, openApiData);\n if (hasScalarReferences(config)) {\n const references = await buildReferenceFiles({\n config,\n contentRoutes: new Set(project.graph.pages.map((page) => page.route)),\n root,\n });\n warnings.push(...references.warnings);\n for (const file of references.files) {\n files.push({\n content: file.content,\n path: join(srcDir, \"pages\", file.pagePath),\n });\n }\n }\n\n // Per-override and per-example live wrappers referenced by the maps above.\n files.push(\n ...slotPlan.wrappers.map((wrapper) => ({\n content: wrapper.content,\n path: join(genDir, \"component-slots\", `${wrapper.name}.astro`),\n })),\n ...examples.examples.map((example) => ({\n content: exampleWrapperTemplate(example, join(genDir, \"examples\")),\n path: join(genDir, \"examples\", `${exampleSlug(example.path)}.astro`),\n })),\n ...examplesPreviewFiles(\n srcDir,\n config.basePath,\n examples.examples.length > 0\n )\n );\n\n // Materialize staged source bodies under `<root>/blume-staged/<source>/<ref>`,\n // matching the relative `staged` collection base in the ejected config.\n for (const [entryId, content] of staged) {\n files.push({ content, path: join(root, stagedDir, entryId) });\n }\n\n const written = files.filter(\n (file) => !(file.skipIfExists && existsSync(file.path))\n );\n await Promise.all(\n written.map(async (file) => {\n await mkdir(join(file.path, \"..\"), { recursive: true });\n await writeFile(file.path, file.content, \"utf-8\");\n })\n );\n\n // Materialized source assets (e.g. downloaded Notion images) live under the\n // hidden runtime's public dir; copy them into the owned project's `public/`\n // so the staged content's `/blume-assets/…` references still resolve.\n const assetsSrc = join(context.outDir, \"public\", \"blume-assets\");\n if (existsSync(assetsSrc)) {\n await cp(assetsSrc, join(root, \"public\", \"blume-assets\"), {\n recursive: true,\n });\n }\n\n // The hidden runtime is no longer the source of truth.\n await rm(context.outDir, { force: true, recursive: true });\n\n return {\n dependencies: ejectDependencies({\n config,\n needsReact,\n needsSvelte,\n needsVue,\n }),\n files: written.map((file) => file.path),\n warnings,\n };\n};\n"
|
|
6
|
-
],
|
|
7
|
-
"mappings": "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",
|
|
8
|
-
"debugId": "D33846DF3713FFC264756E2164756E21",
|
|
9
|
-
"names": []
|
|
10
|
-
}
|