blume 0.1.1 → 0.1.2

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/dist/cli/index.js CHANGED
@@ -2526,7 +2526,7 @@ import {
2526
2526
  } from "node:fs/promises";
2527
2527
  import { createRequire as createRequire4 } from "node:module";
2528
2528
  import { pathToFileURL as pathToFileURL2 } from "node:url";
2529
- import { dirname as dirname6, join as join11, normalize, relative as relative5 } from "pathe";
2529
+ import { basename as basename2, dirname as dirname6, join as join11, normalize, relative as relative5 } from "pathe";
2530
2530
  import { glob as glob4 } from "tinyglobby";
2531
2531
 
2532
2532
  // src/ai/ask.ts
@@ -3212,6 +3212,18 @@ var runtimeDependencies = (options) => {
3212
3212
  }
3213
3213
  return deps;
3214
3214
  };
3215
+ var RENDER_EXTERNAL_DEPS = [
3216
+ "@astrojs/markdown-satteri",
3217
+ "@pierre/diffs",
3218
+ "@shikijs/transformers",
3219
+ "@takumi-rs/core",
3220
+ "@takumi-rs/helpers",
3221
+ "github-slugger",
3222
+ "katex",
3223
+ "shiki",
3224
+ "simple-icons",
3225
+ "zod"
3226
+ ];
3215
3227
  var renderUserAliases = (aliases) => Object.entries(aliases ?? {}).toSorted(([a], [b]) => b.length - a.length).map(([find, replacement]) => `
3216
3228
  ${JSON.stringify(find)}: ${JSON.stringify(replacement)},`).join("");
3217
3229
  var astroConfigTemplate = (options) => {
@@ -3259,7 +3271,7 @@ var astroConfigTemplate = (options) => {
3259
3271
  ` : "";
3260
3272
  const svelteImport = needsSvelte ? `import svelte from "@astrojs/svelte";
3261
3273
  ` : "";
3262
- const blumeImport = `import { blumeIntegration } from "blume/astro";
3274
+ const blumeImport = `import { blumeIntegration, prerenderDepsPlugin } from "blume/astro";
3263
3275
  `;
3264
3276
  const twoslashImport = `import { transformerTwoslash } from "@shikijs/twoslash";
3265
3277
  `;
@@ -3310,19 +3322,14 @@ export default defineConfig({
3310
3322
  },
3311
3323
  devToolbar: { enabled: false },
3312
3324
  vite: {
3313
- plugins: [tailwindcss()],
3314
- // @takumi-rs/core (OG image rendering) is a native NAPI addon that loads a
3315
- // platform-specific .node binding via createRequire(import.meta.url). Astro's
3316
- // build bundles it into the per-environment output by default, which
3317
- // relocates import.meta.url and breaks the binding lookup ("Cannot find
3318
- // native binding") on other platforms (e.g. the Linux CI runner). Astro 7
3319
- // configures externalization per Vite environment, so it must be forced
3320
- // external on the prerender (static) and ssr (server) environments -- a
3321
- // top-level ssr.external only reaches the latter -- so the binding resolves
3322
- // from node_modules at runtime instead.
3325
+ plugins: [tailwindcss(), prerenderDepsPlugin()],
3326
+ // Blume's render-time deps are forced external on both build environments so
3327
+ // native bindings resolve at runtime and isolated linkers don't bundle
3328
+ // symlinked store copies (which would surface their children as unresolvable
3329
+ // imports). See RENDER_EXTERNAL_DEPS / prerenderDepsPlugin.
3323
3330
  environments: {
3324
- prerender: { resolve: { external: ["@takumi-rs/core"] } },
3325
- ssr: { resolve: { external: ["@takumi-rs/core"] } },
3331
+ prerender: { resolve: { external: ${JSON.stringify(RENDER_EXTERNAL_DEPS)} } },
3332
+ ssr: { resolve: { external: ${JSON.stringify(RENDER_EXTERNAL_DEPS)} } },
3326
3333
  },
3327
3334
  resolve: {
3328
3335
  alias: {
@@ -5105,8 +5112,8 @@ var FRAMEWORK_BY_EXT2 = {
5105
5112
  vue: "vue"
5106
5113
  };
5107
5114
  var EXAMPLE_FILE = /\.(?<ext>astro|jsx|svelte|tsx|vue)$/u;
5108
- var discoverExamples = async (root) => {
5109
- const dir = join10(root, "examples");
5115
+ var discoverExamples = async (root, subdir = "examples") => {
5116
+ const dir = join10(root, subdir);
5110
5117
  const matches = await glob2(["**/*.{astro,jsx,svelte,tsx,vue}"], {
5111
5118
  absolute: true,
5112
5119
  cwd: dir,
@@ -5204,16 +5211,7 @@ var blumeDepsDir = (pkgDir = packageRoot()) => {
5204
5211
  const candidates = [join11(pkgDir, "node_modules"), dirname6(pkgDir)];
5205
5212
  return candidates.find((dir) => existsSync5(join11(dir, "astro"))) ?? null;
5206
5213
  };
5207
- var ensureDepsLink = async (outDir, pkgDir = packageRoot()) => {
5208
- const depsDir = blumeDepsDir(pkgDir);
5209
- if (!depsDir || !existsSync5(join11(depsDir, "@astrojs", "mdx"))) {
5210
- return;
5211
- }
5212
- const blumeAstro = resolvedAstroPath(depsDir);
5213
- if (blumeAstro && resolvedAstroPath(outDir) === blumeAstro) {
5214
- return;
5215
- }
5216
- const link = join11(outDir, "node_modules");
5214
+ var linkDepsJunction = async (link, depsDir) => {
5217
5215
  const existing = await lstat(link).catch(() => null);
5218
5216
  if (existing) {
5219
5217
  if (!existing.isSymbolicLink()) {
@@ -5221,9 +5219,42 @@ var ensureDepsLink = async (outDir, pkgDir = packageRoot()) => {
5221
5219
  }
5222
5220
  await rm(link, { force: true });
5223
5221
  }
5224
- await mkdir2(outDir, { recursive: true });
5222
+ await mkdir2(dirname6(link), { recursive: true });
5225
5223
  await symlink(depsDir, link, "junction");
5226
5224
  };
5225
+ var readPkgVersion = (pkgJsonPath) => {
5226
+ if (!pkgJsonPath) {
5227
+ return null;
5228
+ }
5229
+ try {
5230
+ return JSON.parse(readFileSync5(pkgJsonPath, "utf-8")).version ?? null;
5231
+ } catch {
5232
+ return null;
5233
+ }
5234
+ };
5235
+ var astroConflictWarning = (blumeAstroPkg, shadowAstroPkg) => {
5236
+ const blume = readPkgVersion(blumeAstroPkg);
5237
+ const shadow = readPkgVersion(shadowAstroPkg);
5238
+ const versions = blume && shadow ? `astro@${shadow} shadowing Blume's astro@${blume}` : "a second copy of Astro shadowing Blume's";
5239
+ const pin = blume ?? "<Blume's astro version>";
5240
+ return `Astro version conflict: another dependency hoisted ${versions} to the project root, so @astrojs/mdx binds to the wrong copy and the build fails on a missing export (e.g. "chunkToString"). A single symlink can't reconcile a split install — pin Blume's Astro by adding a package.json "overrides" (npm/bun/pnpm) or "resolutions" (yarn) entry { "astro": "${pin}" }, then reinstall. Run \`npm ls astro\` to find the dependency pulling the older copy.`;
5241
+ };
5242
+ var ensureDepsLink = async (outDir, pkgDir = packageRoot()) => {
5243
+ const depsDir = blumeDepsDir(pkgDir);
5244
+ if (!depsDir) {
5245
+ return null;
5246
+ }
5247
+ const blumeAstro = resolvedAstroPath(depsDir);
5248
+ const outDirAstro = resolvedAstroPath(outDir);
5249
+ if (blumeAstro && outDirAstro === blumeAstro) {
5250
+ return null;
5251
+ }
5252
+ if (existsSync5(join11(depsDir, "@astrojs", "mdx"))) {
5253
+ await linkDepsJunction(join11(outDir, "node_modules"), depsDir);
5254
+ return null;
5255
+ }
5256
+ return astroConflictWarning(blumeAstro, outDirAstro);
5257
+ };
5227
5258
  var ISLAND_FRAMEWORK_DEPS = {
5228
5259
  svelte: "@astrojs/svelte",
5229
5260
  vue: "@astrojs/vue"
@@ -5561,7 +5592,7 @@ var generateRuntime = async (project) => {
5561
5592
  written.add(normalize(path));
5562
5593
  return writeIfChanged(path, content);
5563
5594
  };
5564
- await ensureDepsLink(out);
5595
+ const depsLinkWarning = await ensureDepsLink(out);
5565
5596
  const askEnabled = config.ai.ask?.enabled ?? false;
5566
5597
  const exportPdf = config.export.pdf;
5567
5598
  const exportEpub = config.export.epub;
@@ -5570,7 +5601,7 @@ var generateRuntime = async (project) => {
5570
5601
  detectNeedsReact(context.root),
5571
5602
  readOptional(context.themeFile),
5572
5603
  discoverIslands(context.root),
5573
- discoverExamples(context.root)
5604
+ discoverExamples(context.root, config.examples)
5574
5605
  ]);
5575
5606
  const frameworks = new Set([
5576
5607
  ...islandDiscovery.islands.map((island) => island.framework),
@@ -5663,6 +5694,7 @@ var generateRuntime = async (project) => {
5663
5694
  ]);
5664
5695
  }
5665
5696
  const warnings = [
5697
+ ...depsLinkWarning ? [depsLinkWarning] : [],
5666
5698
  ...mcp.warnings,
5667
5699
  ...islandDiscovery.warnings,
5668
5700
  ...exampleDiscovery.warnings
@@ -7139,6 +7171,7 @@ var blumeConfigSchema = z2.object({
7139
7171
  contextual: contextualConfigSchema.default({}),
7140
7172
  deployment: deploymentConfigSchema.default({}),
7141
7173
  description: z2.string().optional(),
7174
+ examples: z2.string().default("examples"),
7142
7175
  export: exportConfigSchema.default(false),
7143
7176
  favicon: faviconConfigSchema.optional(),
7144
7177
  feedback: z2.boolean().default(true),
@@ -7602,7 +7635,7 @@ var gitLastModifiedTimes = (root, contentRoot, sourcePaths) => {
7602
7635
  };
7603
7636
 
7604
7637
  // src/core/meta.ts
7605
- import { basename as basename2, dirname as dirname8, relative as relative8 } from "pathe";
7638
+ import { basename as basename3, dirname as dirname8, relative as relative8 } from "pathe";
7606
7639
  import { glob as glob5 } from "tinyglobby";
7607
7640
  var META_FILES = [
7608
7641
  "**/meta.ts",
@@ -7644,7 +7677,7 @@ var discoverFolderMeta = async (contentRoot) => {
7644
7677
  }
7645
7678
  const result = folderMetaSchema.safeParse(entry.value);
7646
7679
  if (result.success) {
7647
- const target = basename2(entry.file).startsWith("meta.$.") ? shared : meta;
7680
+ const target = basename3(entry.file).startsWith("meta.$.") ? shared : meta;
7648
7681
  target.set(dir, result.data);
7649
7682
  } else {
7650
7683
  diagnostics.push(...diagnosticsFromZod(result.error, {
@@ -10269,7 +10302,7 @@ The blume package remains importable.`);
10269
10302
  import { existsSync as existsSync13 } from "node:fs";
10270
10303
  import { mkdir as mkdir6, writeFile as writeFile9 } from "node:fs/promises";
10271
10304
  import { defineCommand as defineCommand6 } from "citty";
10272
- import { basename as basename3, dirname as dirname11, join as join26 } from "pathe";
10305
+ import { basename as basename4, dirname as dirname11, join as join26 } from "pathe";
10273
10306
  var toPackageName = (raw) => raw.toLowerCase().replaceAll(/[^a-z0-9._-]+/gu, "-").replaceAll(/^[-_.]+|[-_.]+$/gu, "") || "docs";
10274
10307
  var packageTemplate = (name, version) => `{
10275
10308
  "name": ${JSON.stringify(name)},
@@ -10329,7 +10362,7 @@ var initCommand = defineCommand6({
10329
10362
  async run({ args }) {
10330
10363
  const root = process.cwd();
10331
10364
  const contentDir = args["content-dir"] ?? "docs";
10332
- const createdPackage = await writeFileSafe(join26(root, "package.json"), packageTemplate(toPackageName(basename3(root)), getBlumeVersion()));
10365
+ const createdPackage = await writeFileSafe(join26(root, "package.json"), packageTemplate(toPackageName(basename4(root)), getBlumeVersion()));
10333
10366
  await writeFileSafe(join26(root, "blume.config.ts"), CONFIG_TEMPLATE);
10334
10367
  await writeFileSafe(join26(root, contentDir, "index.mdx"), INDEX_TEMPLATE);
10335
10368
  const nextSteps = createdPackage ? `Next steps:
@@ -10356,7 +10389,7 @@ import { glob as glob8 } from "tinyglobby";
10356
10389
  // src/migrate/fumadocs/config.ts
10357
10390
  import { existsSync as existsSync14 } from "node:fs";
10358
10391
  import { readFile as readFile16 } from "node:fs/promises";
10359
- import { basename as basename4, dirname as dirname12, join as join27 } from "pathe";
10392
+ import { basename as basename5, dirname as dirname12, join as join27 } from "pathe";
10360
10393
  var SOURCE_FILES = [
10361
10394
  "lib/source.ts",
10362
10395
  "app/source.ts",
@@ -10411,7 +10444,7 @@ var readTitle = async (root) => {
10411
10444
  if (GENERIC_NAMES.has(bareName(name).toLowerCase())) {
10412
10445
  const repoRoot = gitRepoRoot(root);
10413
10446
  if (repoRoot && repoRoot !== root) {
10414
- const repoTitle = prettifyTitle(basename4(repoRoot));
10447
+ const repoTitle = prettifyTitle(basename5(repoRoot));
10415
10448
  if (repoTitle !== "Documentation") {
10416
10449
  return repoTitle;
10417
10450
  }
@@ -10699,7 +10732,7 @@ var normalizeFumadocsPageMeta = (value) => {
10699
10732
  // src/migrate/fumadocs/groups.ts
10700
10733
  import { existsSync as existsSync16, statSync as statSync2 } from "node:fs";
10701
10734
  import { mkdir as mkdir7, rename as rename2, writeFile as writeFile10 } from "node:fs/promises";
10702
- import { basename as basename5, join as join28 } from "pathe";
10735
+ import { basename as basename6, join as join28 } from "pathe";
10703
10736
 
10704
10737
  // src/migrate/fumadocs/meta.ts
10705
10738
  var SEPARATOR = /^---(?<label>.*)---$/u;
@@ -10885,7 +10918,7 @@ var moveItemIntoGroup = async (item, docsDir, groupDir, label, warnings) => {
10885
10918
  warnings.push(`Sidebar entry "${item.name}" in section "${label}" matched no page or folder; skipped.`);
10886
10919
  return null;
10887
10920
  }
10888
- const dest = join28(groupDir, basename5(resolved.path));
10921
+ const dest = join28(groupDir, basename6(resolved.path));
10889
10922
  if (existsSync16(dest)) {
10890
10923
  warnings.push(`Skipped moving "${item.name}" into section "${label}" (target already exists).`);
10891
10924
  return null;
@@ -11330,7 +11363,7 @@ var migrateMintlifyProject = async (root) => {
11330
11363
  // src/migrate/nextra/index.ts
11331
11364
  import { existsSync as existsSync19 } from "node:fs";
11332
11365
  import { mkdir as mkdir10, readFile as readFile19, rename as rename5, rm as rm5, writeFile as writeFile13 } from "node:fs/promises";
11333
- import { basename as basename6, dirname as dirname16, extname as extname6, join as join31, relative as relative16 } from "pathe";
11366
+ import { basename as basename7, dirname as dirname16, extname as extname6, join as join31, relative as relative16 } from "pathe";
11334
11367
  import { glob as glob10 } from "tinyglobby";
11335
11368
 
11336
11369
  // src/migrate/nextra/content.ts
@@ -11567,7 +11600,7 @@ var indexFolders = (base, pageFiles, metaFiles) => {
11567
11600
  for (const abs of pageFiles) {
11568
11601
  const rel = relative16(base, abs);
11569
11602
  const dir = normalizeDir(dirname16(rel));
11570
- const slug = basename6(rel).replace(/\.mdx?$/u, "");
11603
+ const slug = basename7(rel).replace(/\.mdx?$/u, "");
11571
11604
  const folder = pagesByDir.get(dir) ?? new Map;
11572
11605
  folder.set(slug, abs);
11573
11606
  pagesByDir.set(dir, folder);
@@ -11583,7 +11616,7 @@ var indexFolders = (base, pageFiles, metaFiles) => {
11583
11616
  }
11584
11617
  const parent = normalizeDir(dirname16(dir));
11585
11618
  const children = childDirs.get(parent) ?? new Set;
11586
- children.add(basename6(dir));
11619
+ children.add(basename7(dir));
11587
11620
  childDirs.set(parent, children);
11588
11621
  }
11589
11622
  return { childDirs, pagesByDir };
@@ -12692,5 +12725,5 @@ var main = defineCommand11({
12692
12725
  });
12693
12726
  runMain(main);
12694
12727
 
12695
- //# debugId=37F2F7467962582064756E2164756E21
12728
+ //# debugId=C5E764B7F3B6157B64756E2164756E21
12696
12729
  //# sourceMappingURL=index.js.map