@void/md 1.5.0 → 1.6.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.
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import { t as extractHeadings } from "./metadata-
|
|
2
|
-
import matter from "gray-matter";
|
|
1
|
+
import { r as parseFrontmatter, t as extractHeadings } from "./metadata-DDtNQG1v.mjs";
|
|
3
2
|
import MarkdownExit from "markdown-exit";
|
|
4
3
|
import anchor from "markdown-it-anchor";
|
|
5
4
|
import footnote from "markdown-it-footnote";
|
|
@@ -289,7 +288,7 @@ async function createCompiler(options) {
|
|
|
289
288
|
return markdown;
|
|
290
289
|
}
|
|
291
290
|
async function compile(source, options) {
|
|
292
|
-
const {
|
|
291
|
+
const { frontmatter, content } = parseFrontmatter(source);
|
|
293
292
|
const compiler = await getCompiler(options);
|
|
294
293
|
const env = {};
|
|
295
294
|
const tokens = compiler.parse(content, env);
|
|
@@ -32,8 +32,20 @@ function extractHeadings(tokens) {
|
|
|
32
32
|
}
|
|
33
33
|
return headings;
|
|
34
34
|
}
|
|
35
|
+
function parseFrontmatter(source) {
|
|
36
|
+
try {
|
|
37
|
+
const { data: frontmatter, content } = matter(source, {});
|
|
38
|
+
return {
|
|
39
|
+
frontmatter,
|
|
40
|
+
content
|
|
41
|
+
};
|
|
42
|
+
} catch (error) {
|
|
43
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
44
|
+
throw new Error(`Invalid frontmatter: ${message}`, { cause: error });
|
|
45
|
+
}
|
|
46
|
+
}
|
|
35
47
|
function extractMetadata(source) {
|
|
36
|
-
const {
|
|
48
|
+
const { frontmatter, content } = parseFrontmatter(source);
|
|
37
49
|
const headings = extractHeadings(getMetadataCompiler().parse(content, {}));
|
|
38
50
|
return {
|
|
39
51
|
frontmatter,
|
|
@@ -41,4 +53,4 @@ function extractMetadata(source) {
|
|
|
41
53
|
title: frontmatter.title ?? headings.find((heading) => heading.depth === 1)?.text ?? ""
|
|
42
54
|
};
|
|
43
55
|
}
|
|
44
|
-
export { extractMetadata as n, extractHeadings as t };
|
|
56
|
+
export { extractMetadata as n, parseFrontmatter as r, extractHeadings as t };
|
package/dist/plugin.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { n as extractMetadata } from "./metadata-
|
|
1
|
+
import { n as extractMetadata } from "./metadata-DDtNQG1v.mjs";
|
|
2
2
|
import { createHash } from "node:crypto";
|
|
3
|
-
import { existsSync, readFileSync
|
|
3
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
4
4
|
import { dirname, join, relative, resolve } from "pathslash";
|
|
5
5
|
import { glob } from "tinyglobby";
|
|
6
6
|
import { normalizePath } from "vite";
|
|
@@ -299,26 +299,16 @@ function mdRouteName(file, env) {
|
|
|
299
299
|
if (name === "index") return "";
|
|
300
300
|
return name.endsWith("/index") ? name.slice(0, -6) : name;
|
|
301
301
|
}
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
const fullPath = join(entry.parentPath, entry.name);
|
|
309
|
-
const content = readFileSync(fullPath, "utf-8");
|
|
310
|
-
if (/^<script\b/m.test(content)) return true;
|
|
311
|
-
}
|
|
312
|
-
} catch {}
|
|
313
|
-
return false;
|
|
302
|
+
/** The Markdown files that `environment` keeps, relative to `pagesDir`. */
|
|
303
|
+
async function listMdFiles(pagesDir, environment) {
|
|
304
|
+
return (await glob("**/*.md", { cwd: pagesDir })).filter((file) => {
|
|
305
|
+
const fileEnv = pageFileEnvironment(file);
|
|
306
|
+
return !fileEnv || fileEnv === environment;
|
|
307
|
+
});
|
|
314
308
|
}
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
withFileTypes: true,
|
|
319
|
-
recursive: true
|
|
320
|
-
})) if (entry.isFile() && /\.island\./.test(entry.name)) return true;
|
|
321
|
-
} catch {}
|
|
309
|
+
/** Whether any page has client code. Without it, pages would load an empty client entry. */
|
|
310
|
+
async function hasMdClientCode(pagesDir, environment) {
|
|
311
|
+
for (const file of await listMdFiles(pagesDir, environment)) if (extractScript(readFileSync(join(pagesDir, file), "utf-8")).clientCode) return true;
|
|
322
312
|
return false;
|
|
323
313
|
}
|
|
324
314
|
function voidMarkdown(options) {
|
|
@@ -326,31 +316,51 @@ function voidMarkdown(options) {
|
|
|
326
316
|
let mdPages = [];
|
|
327
317
|
let root = "";
|
|
328
318
|
let pagesDir = "";
|
|
319
|
+
let logger;
|
|
329
320
|
let mdEnvironment = "prod";
|
|
330
321
|
const svelteModules = /* @__PURE__ */ new Map();
|
|
331
322
|
const solidModules = /* @__PURE__ */ new Map();
|
|
332
323
|
const clientScripts = /* @__PURE__ */ new Map();
|
|
324
|
+
const loggedPageErrors = /* @__PURE__ */ new Map();
|
|
333
325
|
function createVirtualModuleId(prefix, importerId, source, extension) {
|
|
334
326
|
return `${prefix}${Buffer.from(importerId).toString("base64url")}.${createHash("sha1").update(source).digest("hex").slice(0, 8)}.${extension}`;
|
|
335
327
|
}
|
|
328
|
+
function createPageError(file, error) {
|
|
329
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
330
|
+
return new Error(`void-md: ${relative(root, file)}: ${message}`, { cause: error });
|
|
331
|
+
}
|
|
336
332
|
async function scanMdPages() {
|
|
337
333
|
if (!existsSync(pagesDir)) return [];
|
|
338
|
-
const liveFiles =
|
|
339
|
-
const fileEnv = pageFileEnvironment(file);
|
|
340
|
-
return !fileEnv || fileEnv === mdEnvironment;
|
|
341
|
-
});
|
|
334
|
+
const liveFiles = await listMdFiles(pagesDir, mdEnvironment);
|
|
342
335
|
return (await Promise.all(liveFiles.map(async (file) => {
|
|
343
|
-
const
|
|
344
|
-
const
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
336
|
+
const path = "/" + mdRouteName(file, pageFileEnvironment(file));
|
|
337
|
+
const filePath = join(pagesDir, file);
|
|
338
|
+
try {
|
|
339
|
+
const { body, clientCode } = extractScript(readFileSync(filePath, "utf-8"));
|
|
340
|
+
const result = extractMetadata(body);
|
|
341
|
+
const componentId = stripPageSuffix(file) || "index";
|
|
342
|
+
if (clientCode) clientScripts.set(componentId, clientCode);
|
|
343
|
+
loggedPageErrors.delete(file);
|
|
344
|
+
return {
|
|
345
|
+
path,
|
|
346
|
+
title: result.title,
|
|
347
|
+
frontmatter: result.frontmatter,
|
|
348
|
+
headings: result.headings
|
|
349
|
+
};
|
|
350
|
+
} catch (error) {
|
|
351
|
+
const pageError = createPageError(filePath, error);
|
|
352
|
+
if (mdEnvironment === "prod") throw pageError;
|
|
353
|
+
if (error.code === "ENOENT") return;
|
|
354
|
+
if (loggedPageErrors.get(file) !== pageError.message) {
|
|
355
|
+
loggedPageErrors.set(file, pageError.message);
|
|
356
|
+
logger?.error(pageError.message, {
|
|
357
|
+
error: pageError,
|
|
358
|
+
timestamp: true
|
|
359
|
+
});
|
|
360
|
+
}
|
|
361
|
+
return mdPages.find((page) => page.path === path);
|
|
362
|
+
}
|
|
363
|
+
}))).filter((page) => page !== void 0).sort((leftPage, rightPage) => leftPage.path.localeCompare(rightPage.path));
|
|
354
364
|
}
|
|
355
365
|
return [{
|
|
356
366
|
name: "void-md",
|
|
@@ -361,16 +371,17 @@ function voidMarkdown(options) {
|
|
|
361
371
|
return clientScripts;
|
|
362
372
|
}
|
|
363
373
|
},
|
|
364
|
-
config(config, env) {
|
|
374
|
+
async config(config, env) {
|
|
365
375
|
mdEnvironment = env.command === "serve" && !env.isPreview ? "dev" : "prod";
|
|
366
376
|
if (env.command === "serve") return;
|
|
367
377
|
const configRoot = config.root || process.cwd();
|
|
368
378
|
const pagesDir = resolvePagesDir(configRoot);
|
|
369
379
|
if (!existsSync(pagesDir)) return;
|
|
370
|
-
if (
|
|
380
|
+
if (await hasMdClientCode(pagesDir, mdEnvironment)) return { environments: { client: { build: { rollupOptions: { input: { "md-client": MD_CLIENT_ENTRY_ID } } } } } };
|
|
371
381
|
},
|
|
372
382
|
configResolved(config) {
|
|
373
383
|
root = config.root;
|
|
384
|
+
logger = config.logger;
|
|
374
385
|
pagesDir = resolvePagesDir(root);
|
|
375
386
|
for (const plugin of config.plugins) {
|
|
376
387
|
const match = ADAPTER_PLUGIN_NAMES[plugin.name];
|
|
@@ -392,7 +403,15 @@ function voidMarkdown(options) {
|
|
|
392
403
|
const isInPagesDir = (file) => file === normalizedPagesDir || file.startsWith(normalizedPagesDir + "/");
|
|
393
404
|
const handleMdChange = async (file) => {
|
|
394
405
|
if (!file.endsWith(".md") || !isInPagesDir(normalizePath(file))) return;
|
|
395
|
-
|
|
406
|
+
try {
|
|
407
|
+
mdPages = await scanMdPages();
|
|
408
|
+
} catch (error) {
|
|
409
|
+
server.config.logger.error(error instanceof Error ? error.message : String(error), {
|
|
410
|
+
error: error instanceof Error ? error : void 0,
|
|
411
|
+
timestamp: true
|
|
412
|
+
});
|
|
413
|
+
return;
|
|
414
|
+
}
|
|
396
415
|
const mod = server.moduleGraph.getModuleById("\0void-md-pages");
|
|
397
416
|
if (mod) server.moduleGraph.invalidateModule(mod);
|
|
398
417
|
for (const [compId] of clientScripts) {
|
|
@@ -481,8 +500,10 @@ export function useFrontmatter() { return useContext(FrontmatterContext) ?? {};
|
|
|
481
500
|
islandId
|
|
482
501
|
};
|
|
483
502
|
});
|
|
484
|
-
const { compile } = await import("./compile-
|
|
485
|
-
const result = await compile(body, { shiki: options?.shiki })
|
|
503
|
+
const { compile } = await import("./compile-5IQ1Trxe.mjs");
|
|
504
|
+
const result = await compile(body, { shiki: options?.shiki }).catch((error) => {
|
|
505
|
+
throw createPageError(_id, error);
|
|
506
|
+
});
|
|
486
507
|
if (adapter === "vue") return {
|
|
487
508
|
code: emitVueComponent(result, islands),
|
|
488
509
|
map: null
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@void/md",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.6.1",
|
|
4
4
|
"description": "Markdown pages with layouts and interactive islands for Void.",
|
|
5
5
|
"homepage": "https://void.cloud",
|
|
6
6
|
"bugs": {
|
|
@@ -54,11 +54,11 @@
|
|
|
54
54
|
"@types/node": "^26.6.6",
|
|
55
55
|
"vite": "npm:@voidzero-dev/vite-plus-core@1.4.0",
|
|
56
56
|
"vite-plus": "1.4.0",
|
|
57
|
-
"void": "1.
|
|
57
|
+
"void": "1.6.1"
|
|
58
58
|
},
|
|
59
59
|
"peerDependencies": {
|
|
60
60
|
"vite": "^8.0.0",
|
|
61
|
-
"void": "1.
|
|
61
|
+
"void": "1.6.1"
|
|
62
62
|
},
|
|
63
63
|
"scripts": {
|
|
64
64
|
"build": "vp pack",
|