@ox-content/vite-plugin 2.2.0 → 2.4.0
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/LICENSE +21 -0
- package/dist/index.cjs +373 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +270 -1
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +270 -1
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +479 -114
- package/dist/index.mjs.map +1 -1
- package/package.json +7 -2
package/dist/index.mjs
CHANGED
|
@@ -4,18 +4,20 @@ import { n as transformYouTube, t as extractVideoId } from "./youtube2.mjs";
|
|
|
4
4
|
import { i as transformGitHub, n as fetchRepoData, r as prefetchGitHubRepos, t as collectGitHubRepos } from "./github2.mjs";
|
|
5
5
|
import { i as transformOgp, n as fetchOgpData, r as prefetchOgpData, t as collectOgpUrls } from "./ogp2.mjs";
|
|
6
6
|
import { createRequire } from "node:module";
|
|
7
|
-
import * as path$
|
|
7
|
+
import * as path$2 from "path";
|
|
8
8
|
import path from "path";
|
|
9
9
|
import { unified } from "unified";
|
|
10
10
|
import rehypeParse from "rehype-parse";
|
|
11
11
|
import rehypeStringify from "rehype-stringify";
|
|
12
12
|
import { createHighlighter } from "shiki";
|
|
13
|
+
import * as path$1 from "node:path";
|
|
13
14
|
import { dirname, join } from "node:path";
|
|
14
|
-
import * as fs$
|
|
15
|
+
import * as fs$2 from "fs";
|
|
15
16
|
import { createHash } from "node:crypto";
|
|
16
|
-
import * as fs from "fs/promises";
|
|
17
|
+
import * as fs$1 from "fs/promises";
|
|
17
18
|
import { glob } from "glob";
|
|
18
19
|
import * as crypto from "crypto";
|
|
20
|
+
import * as fs from "node:fs/promises";
|
|
19
21
|
import { mkdir, writeFile } from "node:fs/promises";
|
|
20
22
|
//#region \0rolldown/runtime.js
|
|
21
23
|
var __create = Object.create;
|
|
@@ -7546,11 +7548,22 @@ function renderDetailsControlsHtml(targetSelector) {
|
|
|
7546
7548
|
<button type="button" class="ox-api-controls__button" data-ox-api-toggle="collapse">Close all</button>
|
|
7547
7549
|
</div>`;
|
|
7548
7550
|
}
|
|
7551
|
+
function normalizeDocFilePath(filePath) {
|
|
7552
|
+
const normalized = filePath.replace(/\\/g, "/");
|
|
7553
|
+
return normalized.match(/(?:^|\/)((?:npm|packages|crates|src)\/.+)$/)?.[1] ?? normalized.replace(/^\/+/, "");
|
|
7554
|
+
}
|
|
7549
7555
|
function buildDocsData(docs) {
|
|
7550
7556
|
return {
|
|
7551
7557
|
version: 1,
|
|
7552
7558
|
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
7553
|
-
modules: docs
|
|
7559
|
+
modules: docs.map((doc) => ({
|
|
7560
|
+
...doc,
|
|
7561
|
+
file: normalizeDocFilePath(doc.file),
|
|
7562
|
+
entries: doc.entries.map((entry) => ({
|
|
7563
|
+
...entry,
|
|
7564
|
+
file: normalizeDocFilePath(entry.file)
|
|
7565
|
+
}))
|
|
7566
|
+
}))
|
|
7554
7567
|
};
|
|
7555
7568
|
}
|
|
7556
7569
|
/**
|
|
@@ -7644,12 +7657,12 @@ async function findFiles(dir, options) {
|
|
|
7644
7657
|
async function walk(currentDir) {
|
|
7645
7658
|
let entries;
|
|
7646
7659
|
try {
|
|
7647
|
-
entries = await fs$
|
|
7660
|
+
entries = await fs$2.promises.readdir(currentDir, { withFileTypes: true });
|
|
7648
7661
|
} catch {
|
|
7649
7662
|
return;
|
|
7650
7663
|
}
|
|
7651
7664
|
for (const entry of entries) {
|
|
7652
|
-
const fullPath = path$
|
|
7665
|
+
const fullPath = path$2.join(currentDir, entry.name);
|
|
7653
7666
|
if (entry.isDirectory()) {
|
|
7654
7667
|
if (!isExcluded(fullPath, options.exclude)) await walk(fullPath);
|
|
7655
7668
|
} else if (entry.isFile()) {
|
|
@@ -7806,7 +7819,7 @@ function generateMarkdown(docs, options) {
|
|
|
7806
7819
|
if (options.groupBy === "file") {
|
|
7807
7820
|
const docToFile = /* @__PURE__ */ new Map();
|
|
7808
7821
|
for (const doc of sortedDocs) {
|
|
7809
|
-
let fileName = path$
|
|
7822
|
+
let fileName = path$2.basename(doc.file, path$2.extname(doc.file));
|
|
7810
7823
|
if (fileName === "index") fileName = "index-module";
|
|
7811
7824
|
docToFile.set(doc, fileName);
|
|
7812
7825
|
const markdown = generateFileMarkdown(doc, options, fileName, symbolMap);
|
|
@@ -7839,10 +7852,10 @@ function sortExtractedDocs(docs) {
|
|
|
7839
7852
|
return [...docs].map((doc) => ({
|
|
7840
7853
|
...doc,
|
|
7841
7854
|
entries: [...doc.entries].sort(compareEntriesByName)
|
|
7842
|
-
})).sort((a, b) => compareStrings(path$
|
|
7855
|
+
})).sort((a, b) => compareStrings(path$2.basename(a.file), path$2.basename(b.file)));
|
|
7843
7856
|
}
|
|
7844
7857
|
function generateFileMarkdown(doc, options, currentFileName, symbolMap) {
|
|
7845
|
-
let md = `# ${path$
|
|
7858
|
+
let md = `# ${path$2.basename(doc.file)}\n\n`;
|
|
7846
7859
|
if (options.githubUrl) {
|
|
7847
7860
|
const sourceLink = generateSourceLink(doc.file, options.githubUrl);
|
|
7848
7861
|
if (sourceLink) md += sourceLink + "\n\n";
|
|
@@ -7945,7 +7958,7 @@ function generateIndex(docs, docToFile) {
|
|
|
7945
7958
|
md += "## Modules\n\n";
|
|
7946
7959
|
if (docs.length > 1) md += renderDetailsControlsHtml(".ox-api-module") + "\n\n";
|
|
7947
7960
|
for (const doc of docs) {
|
|
7948
|
-
const displayName = path$
|
|
7961
|
+
const displayName = path$2.basename(doc.file, path$2.extname(doc.file));
|
|
7949
7962
|
let fileName = displayName;
|
|
7950
7963
|
if (docToFile && docToFile.has(doc)) fileName = docToFile.get(doc);
|
|
7951
7964
|
else if (fileName === "index") fileName = "index-module";
|
|
@@ -8026,7 +8039,7 @@ function convertSymbolLinks(text, currentFileName, symbolMap) {
|
|
|
8026
8039
|
function buildSymbolMap(docs) {
|
|
8027
8040
|
const map = /* @__PURE__ */ new Map();
|
|
8028
8041
|
for (const doc of docs) {
|
|
8029
|
-
let fileName = path$
|
|
8042
|
+
let fileName = path$2.basename(doc.file, path$2.extname(doc.file));
|
|
8030
8043
|
if (fileName === "index") fileName = "index-module";
|
|
8031
8044
|
for (const entry of doc.entries) map.set(entry.name, {
|
|
8032
8045
|
name: entry.name,
|
|
@@ -8040,32 +8053,32 @@ function buildSymbolMap(docs) {
|
|
|
8040
8053
|
* Writes generated documentation to the output directory.
|
|
8041
8054
|
*/
|
|
8042
8055
|
async function writeDocs(docs, outDir, extractedDocs, options) {
|
|
8043
|
-
await fs$
|
|
8056
|
+
await fs$2.promises.mkdir(outDir, { recursive: true });
|
|
8044
8057
|
const generatedFiles = new Set(Object.keys(docs));
|
|
8045
8058
|
if (extractedDocs && options?.generateNav && options.groupBy === "file") generatedFiles.add("nav.ts");
|
|
8046
8059
|
if (extractedDocs) generatedFiles.add(DOCS_DATA_FILE);
|
|
8047
|
-
const manifestPath = path$
|
|
8060
|
+
const manifestPath = path$2.join(outDir, DOCS_MANIFEST_FILE);
|
|
8048
8061
|
let previousFiles = [];
|
|
8049
8062
|
try {
|
|
8050
|
-
previousFiles = JSON.parse(await fs$
|
|
8063
|
+
previousFiles = JSON.parse(await fs$2.promises.readFile(manifestPath, "utf-8"));
|
|
8051
8064
|
} catch {
|
|
8052
8065
|
previousFiles = [];
|
|
8053
8066
|
}
|
|
8054
8067
|
for (const staleFile of previousFiles) {
|
|
8055
8068
|
if (generatedFiles.has(staleFile)) continue;
|
|
8056
|
-
await fs$
|
|
8069
|
+
await fs$2.promises.rm(path$2.join(outDir, staleFile), { force: true });
|
|
8057
8070
|
}
|
|
8058
8071
|
for (const [fileName, content] of Object.entries(docs)) {
|
|
8059
|
-
const filePath = path$
|
|
8060
|
-
await fs$
|
|
8072
|
+
const filePath = path$2.join(outDir, fileName);
|
|
8073
|
+
await fs$2.promises.writeFile(filePath, content, "utf-8");
|
|
8061
8074
|
}
|
|
8062
8075
|
if (extractedDocs && options?.generateNav && options.groupBy === "file") {
|
|
8063
8076
|
const navCode = generateNavCode(generateNavMetadata(extractedDocs, "/api"), "apiNav");
|
|
8064
|
-
const navFilePath = path$
|
|
8065
|
-
await fs$
|
|
8077
|
+
const navFilePath = path$2.join(outDir, "nav.ts");
|
|
8078
|
+
await fs$2.promises.writeFile(navFilePath, navCode, "utf-8");
|
|
8066
8079
|
}
|
|
8067
|
-
if (extractedDocs) await fs$
|
|
8068
|
-
await fs$
|
|
8080
|
+
if (extractedDocs) await fs$2.promises.writeFile(path$2.join(outDir, DOCS_DATA_FILE), JSON.stringify(buildDocsData(extractedDocs), null, 2), "utf-8");
|
|
8081
|
+
await fs$2.promises.writeFile(manifestPath, JSON.stringify([...generatedFiles].sort(), null, 2), "utf-8");
|
|
8069
8082
|
}
|
|
8070
8083
|
/**
|
|
8071
8084
|
* Resolves docs options with defaults.
|
|
@@ -8080,7 +8093,7 @@ async function writeDocs(docs, outDir, extractedDocs, options) {
|
|
|
8080
8093
|
* @returns Absolute GitHub URL to source code
|
|
8081
8094
|
*/
|
|
8082
8095
|
function generateSourceHref(filePath, githubUrl, lineNumber, endLineNumber) {
|
|
8083
|
-
return `${githubUrl}/blob/main/${filePath
|
|
8096
|
+
return `${githubUrl}/blob/main/${normalizeDocFilePath(filePath)}${lineNumber ? endLineNumber && endLineNumber > lineNumber ? `#L${lineNumber}-L${endLineNumber}` : `#L${lineNumber}` : ""}`;
|
|
8084
8097
|
}
|
|
8085
8098
|
function generateSourceLink(filePath, githubUrl, lineNumber, endLineNumber) {
|
|
8086
8099
|
return `**[Source](${generateSourceHref(filePath, githubUrl, lineNumber, endLineNumber)})**`;
|
|
@@ -8150,10 +8163,10 @@ async function renderHtmlToPng(page, html, width, height, publicDir) {
|
|
|
8150
8163
|
await route.continue();
|
|
8151
8164
|
return;
|
|
8152
8165
|
}
|
|
8153
|
-
const filePath = path$
|
|
8166
|
+
const filePath = path$2.join(publicDir, url.pathname);
|
|
8154
8167
|
try {
|
|
8155
8168
|
const body = await fs.readFile(filePath);
|
|
8156
|
-
const ext = path$
|
|
8169
|
+
const ext = path$2.extname(filePath).toLowerCase();
|
|
8157
8170
|
await route.fulfill({
|
|
8158
8171
|
body,
|
|
8159
8172
|
contentType: {
|
|
@@ -8338,9 +8351,9 @@ function computeCacheKey(templateSource, props, width, height) {
|
|
|
8338
8351
|
* Returns the cached file path if found, null otherwise.
|
|
8339
8352
|
*/
|
|
8340
8353
|
async function getCached(cacheDir, key) {
|
|
8341
|
-
const filePath = path$
|
|
8354
|
+
const filePath = path$2.join(cacheDir, `${key}.png`);
|
|
8342
8355
|
try {
|
|
8343
|
-
return await fs.readFile(filePath);
|
|
8356
|
+
return await fs$1.readFile(filePath);
|
|
8344
8357
|
} catch {
|
|
8345
8358
|
return null;
|
|
8346
8359
|
}
|
|
@@ -8349,9 +8362,9 @@ async function getCached(cacheDir, key) {
|
|
|
8349
8362
|
* Writes a PNG buffer to the cache.
|
|
8350
8363
|
*/
|
|
8351
8364
|
async function writeCache(cacheDir, key, png) {
|
|
8352
|
-
await fs.mkdir(cacheDir, { recursive: true });
|
|
8353
|
-
const filePath = path$
|
|
8354
|
-
await fs.writeFile(filePath, png);
|
|
8365
|
+
await fs$1.mkdir(cacheDir, { recursive: true });
|
|
8366
|
+
const filePath = path$2.join(cacheDir, `${key}.png`);
|
|
8367
|
+
await fs$1.writeFile(filePath, png);
|
|
8355
8368
|
}
|
|
8356
8369
|
//#endregion
|
|
8357
8370
|
//#region \0@oxc-project+runtime@0.115.0/helpers/usingCtx.js
|
|
@@ -8441,14 +8454,14 @@ function resolveOgImageOptions(options) {
|
|
|
8441
8454
|
*/
|
|
8442
8455
|
async function resolveTemplate(options, root) {
|
|
8443
8456
|
if (!options.template) return getDefaultTemplate();
|
|
8444
|
-
const templatePath = path$
|
|
8457
|
+
const templatePath = path$2.resolve(root, options.template);
|
|
8445
8458
|
const fs = await import("fs/promises");
|
|
8446
8459
|
try {
|
|
8447
8460
|
await fs.access(templatePath);
|
|
8448
8461
|
} catch {
|
|
8449
8462
|
throw new Error(`[ox-content:og-image] Template file not found: ${templatePath}`);
|
|
8450
8463
|
}
|
|
8451
|
-
switch (path$
|
|
8464
|
+
switch (path$2.extname(templatePath).toLowerCase()) {
|
|
8452
8465
|
case ".vue": return resolveVueTemplate(templatePath, options, root);
|
|
8453
8466
|
case ".svelte": return resolveSvelteTemplate(templatePath, root);
|
|
8454
8467
|
case ".tsx":
|
|
@@ -8462,9 +8475,9 @@ async function resolveTemplate(options, root) {
|
|
|
8462
8475
|
async function resolveTsTemplate(templatePath, options, root) {
|
|
8463
8476
|
const fs = await import("fs/promises");
|
|
8464
8477
|
const { rolldown } = await import("rolldown");
|
|
8465
|
-
const cacheDir = path$
|
|
8478
|
+
const cacheDir = path$2.join(root, ".cache", "og-images");
|
|
8466
8479
|
await fs.mkdir(cacheDir, { recursive: true });
|
|
8467
|
-
const outfile = path$
|
|
8480
|
+
const outfile = path$2.join(cacheDir, "_template.mjs");
|
|
8468
8481
|
const bundle = await rolldown({
|
|
8469
8482
|
input: templatePath,
|
|
8470
8483
|
platform: "node"
|
|
@@ -8487,9 +8500,9 @@ async function resolveTsTemplate(templatePath, options, root) {
|
|
|
8487
8500
|
async function resolveVueTemplate(templatePath, options, root) {
|
|
8488
8501
|
const fs = await import("fs/promises");
|
|
8489
8502
|
const { rolldown } = await import("rolldown");
|
|
8490
|
-
const cacheDir = path$
|
|
8503
|
+
const cacheDir = path$2.join(root, ".cache", "og-images");
|
|
8491
8504
|
await fs.mkdir(cacheDir, { recursive: true });
|
|
8492
|
-
const outfile = path$
|
|
8505
|
+
const outfile = path$2.join(cacheDir, "_template_vue.mjs");
|
|
8493
8506
|
const bundle = await rolldown({
|
|
8494
8507
|
input: templatePath,
|
|
8495
8508
|
platform: "node",
|
|
@@ -8585,9 +8598,9 @@ async function getVizejsPlugin() {
|
|
|
8585
8598
|
async function resolveSvelteTemplate(templatePath, root) {
|
|
8586
8599
|
const fs = await import("fs/promises");
|
|
8587
8600
|
const { rolldown } = await import("rolldown");
|
|
8588
|
-
const cacheDir = path$
|
|
8601
|
+
const cacheDir = path$2.join(root, ".cache", "og-images");
|
|
8589
8602
|
await fs.mkdir(cacheDir, { recursive: true });
|
|
8590
|
-
const outfile = path$
|
|
8603
|
+
const outfile = path$2.join(cacheDir, "_template_svelte.mjs");
|
|
8591
8604
|
const bundle = await rolldown({
|
|
8592
8605
|
input: templatePath,
|
|
8593
8606
|
platform: "node",
|
|
@@ -8643,9 +8656,9 @@ function createSvelteCompilerPlugin() {
|
|
|
8643
8656
|
async function resolveReactTemplate(templatePath, root) {
|
|
8644
8657
|
const fs = await import("fs/promises");
|
|
8645
8658
|
const { rolldown } = await import("rolldown");
|
|
8646
|
-
const cacheDir = path$
|
|
8659
|
+
const cacheDir = path$2.join(root, ".cache", "og-images");
|
|
8647
8660
|
await fs.mkdir(cacheDir, { recursive: true });
|
|
8648
|
-
const outfile = path$
|
|
8661
|
+
const outfile = path$2.join(cacheDir, "_template_react.mjs");
|
|
8649
8662
|
const bundle = await rolldown({
|
|
8650
8663
|
input: templatePath,
|
|
8651
8664
|
platform: "node",
|
|
@@ -8695,7 +8708,7 @@ async function resolveReactTemplate(templatePath, root) {
|
|
|
8695
8708
|
async function computeTemplateSource(options, root) {
|
|
8696
8709
|
if (!options.template) return "__default__";
|
|
8697
8710
|
const fs = await import("fs/promises");
|
|
8698
|
-
const templatePath = path$
|
|
8711
|
+
const templatePath = path$2.resolve(root, options.template);
|
|
8699
8712
|
const content = await fs.readFile(templatePath, "utf-8");
|
|
8700
8713
|
return crypto.createHash("sha256").update(content).digest("hex");
|
|
8701
8714
|
}
|
|
@@ -8713,7 +8726,7 @@ async function generateOgImages(pages, options, root) {
|
|
|
8713
8726
|
if (pages.length === 0) return [];
|
|
8714
8727
|
const templateFn = await resolveTemplate(options, root);
|
|
8715
8728
|
const templateSource = await computeTemplateSource(options, root);
|
|
8716
|
-
const cacheDir = path$
|
|
8729
|
+
const cacheDir = path$2.join(root, ".cache", "og-images");
|
|
8717
8730
|
if (options.cache) {
|
|
8718
8731
|
const allCached = await tryServeAllFromCache(pages, templateSource, options, cacheDir);
|
|
8719
8732
|
if (allCached) return allCached;
|
|
@@ -8725,7 +8738,7 @@ async function generateOgImages(pages, options, root) {
|
|
|
8725
8738
|
error: "Chromium not available"
|
|
8726
8739
|
}));
|
|
8727
8740
|
const results = [];
|
|
8728
|
-
const publicDir = path$
|
|
8741
|
+
const publicDir = path$2.join(root, "public");
|
|
8729
8742
|
const concurrency = Math.max(1, options.concurrency);
|
|
8730
8743
|
for (let i = 0; i < pages.length; i += concurrency) {
|
|
8731
8744
|
const batch = pages.slice(i, i + concurrency);
|
|
@@ -8749,7 +8762,7 @@ async function tryServeAllFromCache(pages, templateSource, options, cacheDir) {
|
|
|
8749
8762
|
for (const entry of pages) {
|
|
8750
8763
|
const cached = await getCached(cacheDir, computeCacheKey(templateSource, entry.props, options.width, options.height));
|
|
8751
8764
|
if (!cached) return null;
|
|
8752
|
-
await fs.mkdir(path$
|
|
8765
|
+
await fs.mkdir(path$2.dirname(entry.outputPath), { recursive: true });
|
|
8753
8766
|
await fs.writeFile(entry.outputPath, cached);
|
|
8754
8767
|
results.push({
|
|
8755
8768
|
outputPath: entry.outputPath,
|
|
@@ -8767,7 +8780,7 @@ async function renderSinglePage(entry, templateFn, templateSource, options, cach
|
|
|
8767
8780
|
if (options.cache) {
|
|
8768
8781
|
const cached = await getCached(cacheDir, computeCacheKey(templateSource, entry.props, options.width, options.height));
|
|
8769
8782
|
if (cached) {
|
|
8770
|
-
await fs.mkdir(path$
|
|
8783
|
+
await fs.mkdir(path$2.dirname(entry.outputPath), { recursive: true });
|
|
8771
8784
|
await fs.writeFile(entry.outputPath, cached);
|
|
8772
8785
|
return {
|
|
8773
8786
|
outputPath: entry.outputPath,
|
|
@@ -8777,7 +8790,7 @@ async function renderSinglePage(entry, templateFn, templateSource, options, cach
|
|
|
8777
8790
|
}
|
|
8778
8791
|
const html = await templateFn(entry.props);
|
|
8779
8792
|
const png = await session.renderPage(html, options.width, options.height, publicDir);
|
|
8780
|
-
await fs.mkdir(path$
|
|
8793
|
+
await fs.mkdir(path$2.dirname(entry.outputPath), { recursive: true });
|
|
8781
8794
|
await fs.writeFile(entry.outputPath, png);
|
|
8782
8795
|
if (options.cache) await writeCache(cacheDir, computeCacheKey(templateSource, entry.props, options.width, options.height), png);
|
|
8783
8796
|
return {
|
|
@@ -10657,7 +10670,7 @@ function createSharedAssetChunk(type, label, content, outDir, base) {
|
|
|
10657
10670
|
const hash = createContentHash(content);
|
|
10658
10671
|
const fileName = `ox-content-${sanitizeChunkLabel(label)}-${hash}.${type}`;
|
|
10659
10672
|
return {
|
|
10660
|
-
outputPath: path$
|
|
10673
|
+
outputPath: path$2.join(outDir, "assets", fileName),
|
|
10661
10674
|
publicPath: toPublicAssetPath(base, fileName),
|
|
10662
10675
|
content
|
|
10663
10676
|
};
|
|
@@ -10747,8 +10760,8 @@ async function externalizeSharedPageAssets(pages, outDir, base) {
|
|
|
10747
10760
|
});
|
|
10748
10761
|
const chunks = [...cssChunks.values(), ...jsChunks.values()];
|
|
10749
10762
|
await Promise.all(chunks.map(async (chunk) => {
|
|
10750
|
-
await fs.mkdir(path$
|
|
10751
|
-
await fs.writeFile(chunk.outputPath, chunk.content, "utf-8");
|
|
10763
|
+
await fs$1.mkdir(path$2.dirname(chunk.outputPath), { recursive: true });
|
|
10764
|
+
await fs$1.writeFile(chunk.outputPath, chunk.content, "utf-8");
|
|
10752
10765
|
}));
|
|
10753
10766
|
return {
|
|
10754
10767
|
pages: optimizedPages,
|
|
@@ -10759,16 +10772,16 @@ async function externalizeSharedPageAssets(pages, outDir, base) {
|
|
|
10759
10772
|
* Converts a markdown file path to its corresponding HTML output path.
|
|
10760
10773
|
*/
|
|
10761
10774
|
function getOutputPath(inputPath, srcDir, outDir, extension) {
|
|
10762
|
-
const baseName = path$
|
|
10763
|
-
if (baseName.endsWith(`index${extension}`)) return path$
|
|
10775
|
+
const baseName = path$2.relative(srcDir, inputPath).replace(/\.(?:md|markdown)$/i, extension);
|
|
10776
|
+
if (baseName.endsWith(`index${extension}`)) return path$2.join(outDir, baseName);
|
|
10764
10777
|
const dirName = baseName.replace(new RegExp(`\\${extension}$`), "");
|
|
10765
|
-
return path$
|
|
10778
|
+
return path$2.join(outDir, dirName, `index${extension}`);
|
|
10766
10779
|
}
|
|
10767
10780
|
/**
|
|
10768
10781
|
* Converts a markdown file path to a relative URL path.
|
|
10769
10782
|
*/
|
|
10770
10783
|
function getUrlPath$1(inputPath, srcDir) {
|
|
10771
|
-
const baseName = path$
|
|
10784
|
+
const baseName = path$2.relative(srcDir, inputPath).replace(/\.(?:md|markdown)$/i, "");
|
|
10772
10785
|
if (baseName === "index" || baseName.endsWith("/index")) return baseName.replace(/\/?index$/, "") || "/";
|
|
10773
10786
|
return baseName;
|
|
10774
10787
|
}
|
|
@@ -10784,12 +10797,12 @@ function getHref(inputPath, srcDir, base, extension) {
|
|
|
10784
10797
|
* Gets the OG image output path for a given markdown file.
|
|
10785
10798
|
*/
|
|
10786
10799
|
function getOgImagePath(inputPath, srcDir, outDir) {
|
|
10787
|
-
const baseName = path$
|
|
10800
|
+
const baseName = path$2.relative(srcDir, inputPath).replace(/\.(?:md|markdown)$/i, "");
|
|
10788
10801
|
if (baseName === "index" || baseName.endsWith("/index")) {
|
|
10789
10802
|
const dirPath = baseName.replace(/\/?index$/, "") || "";
|
|
10790
|
-
return path$
|
|
10803
|
+
return path$2.join(outDir, dirPath, "og-image.png");
|
|
10791
10804
|
}
|
|
10792
|
-
return path$
|
|
10805
|
+
return path$2.join(outDir, baseName, "og-image.png");
|
|
10793
10806
|
}
|
|
10794
10807
|
/**
|
|
10795
10808
|
* Gets the OG image URL for use in meta tags.
|
|
@@ -10807,9 +10820,9 @@ function getOgImageUrl(inputPath, srcDir, base, siteUrl) {
|
|
|
10807
10820
|
* Gets display title from file path.
|
|
10808
10821
|
*/
|
|
10809
10822
|
function getDisplayTitle(filePath) {
|
|
10810
|
-
const fileName = path$
|
|
10823
|
+
const fileName = path$2.basename(filePath, path$2.extname(filePath));
|
|
10811
10824
|
if (fileName === "index") {
|
|
10812
|
-
const dirName = path$
|
|
10825
|
+
const dirName = path$2.basename(path$2.dirname(filePath));
|
|
10813
10826
|
if (dirName && dirName !== ".") return formatTitle(dirName);
|
|
10814
10827
|
return "Home";
|
|
10815
10828
|
}
|
|
@@ -10825,7 +10838,7 @@ function formatTitle(name) {
|
|
|
10825
10838
|
* Collects all markdown files from the source directory.
|
|
10826
10839
|
*/
|
|
10827
10840
|
async function collectMarkdownFiles$1(srcDir) {
|
|
10828
|
-
return (await glob(path$
|
|
10841
|
+
return (await glob(path$2.join(srcDir, "**/*.{md,markdown}"), {
|
|
10829
10842
|
nodir: true,
|
|
10830
10843
|
ignore: [
|
|
10831
10844
|
"**/node_modules/**",
|
|
@@ -10846,7 +10859,7 @@ function buildNavItems(markdownFiles, srcDir, base, extension) {
|
|
|
10846
10859
|
"api"
|
|
10847
10860
|
];
|
|
10848
10861
|
for (const file of markdownFiles) {
|
|
10849
|
-
const parts = path$
|
|
10862
|
+
const parts = path$2.relative(srcDir, file).split(path$2.sep);
|
|
10850
10863
|
let groupKey = "";
|
|
10851
10864
|
if (parts.length > 1) groupKey = parts[0];
|
|
10852
10865
|
if (!groups.has(groupKey)) groups.set(groupKey, []);
|
|
@@ -10895,14 +10908,14 @@ async function buildSsg(options, root) {
|
|
|
10895
10908
|
files: [],
|
|
10896
10909
|
errors: []
|
|
10897
10910
|
};
|
|
10898
|
-
const srcDir = path$
|
|
10899
|
-
const outDir = path$
|
|
10911
|
+
const srcDir = path$2.resolve(root, options.srcDir);
|
|
10912
|
+
const outDir = path$2.resolve(root, options.outDir);
|
|
10900
10913
|
const base = options.base.endsWith("/") ? options.base : options.base + "/";
|
|
10901
10914
|
const generatedFiles = [];
|
|
10902
10915
|
const generatedPages = [];
|
|
10903
10916
|
const errors = [];
|
|
10904
10917
|
if (ssgOptions.clean) try {
|
|
10905
|
-
await fs.rm(outDir, {
|
|
10918
|
+
await fs$1.rm(outDir, {
|
|
10906
10919
|
recursive: true,
|
|
10907
10920
|
force: true
|
|
10908
10921
|
});
|
|
@@ -10911,8 +10924,8 @@ async function buildSsg(options, root) {
|
|
|
10911
10924
|
const navItems = buildNavItems(markdownFiles, srcDir, base, ssgOptions.extension);
|
|
10912
10925
|
let siteName = ssgOptions.siteName ?? "Documentation";
|
|
10913
10926
|
if (!ssgOptions.siteName) try {
|
|
10914
|
-
const pkgPath = path$
|
|
10915
|
-
const pkg = JSON.parse(await fs.readFile(pkgPath, "utf-8"));
|
|
10927
|
+
const pkgPath = path$2.join(root, "package.json");
|
|
10928
|
+
const pkg = JSON.parse(await fs$1.readFile(pkgPath, "utf-8"));
|
|
10916
10929
|
if (pkg.name) siteName = formatTitle(pkg.name);
|
|
10917
10930
|
} catch {}
|
|
10918
10931
|
const ogImageEntries = [];
|
|
@@ -10921,7 +10934,7 @@ async function buildSsg(options, root) {
|
|
|
10921
10934
|
const shouldGenerateOgImages = (options.ogImage || ssgOptions.generateOgImage) && !ssgOptions.bare;
|
|
10922
10935
|
const pageResults = [];
|
|
10923
10936
|
for (const inputPath of markdownFiles) try {
|
|
10924
|
-
const result = await transformMarkdown(await fs.readFile(inputPath, "utf-8"), inputPath, options, {
|
|
10937
|
+
const result = await transformMarkdown(await fs$1.readFile(inputPath, "utf-8"), inputPath, options, {
|
|
10925
10938
|
convertMdLinks: true,
|
|
10926
10939
|
baseUrl: base,
|
|
10927
10940
|
sourcePath: inputPath
|
|
@@ -11025,8 +11038,8 @@ async function buildSsg(options, root) {
|
|
|
11025
11038
|
const optimizedOutput = await externalizeSharedPageAssets(generatedPages, outDir, base);
|
|
11026
11039
|
generatedFiles.push(...optimizedOutput.assets);
|
|
11027
11040
|
for (const page of optimizedOutput.pages) {
|
|
11028
|
-
await fs.mkdir(path$
|
|
11029
|
-
await fs.writeFile(page.outputPath, page.html, "utf-8");
|
|
11041
|
+
await fs$1.mkdir(path$2.dirname(page.outputPath), { recursive: true });
|
|
11042
|
+
await fs$1.writeFile(page.outputPath, page.html, "utf-8");
|
|
11030
11043
|
generatedFiles.push(page.outputPath);
|
|
11031
11044
|
}
|
|
11032
11045
|
return {
|
|
@@ -11078,9 +11091,9 @@ async function collectMarkdownFiles(dir) {
|
|
|
11078
11091
|
const files = [];
|
|
11079
11092
|
async function walk(currentDir) {
|
|
11080
11093
|
try {
|
|
11081
|
-
const entries = await fs.readdir(currentDir, { withFileTypes: true });
|
|
11094
|
+
const entries = await fs$1.readdir(currentDir, { withFileTypes: true });
|
|
11082
11095
|
for (const entry of entries) {
|
|
11083
|
-
const fullPath = path$
|
|
11096
|
+
const fullPath = path$2.join(currentDir, entry.name);
|
|
11084
11097
|
if (entry.isDirectory() && !entry.name.startsWith(".") && entry.name !== "node_modules") await walk(fullPath);
|
|
11085
11098
|
else if (entry.isFile() && entry.name.endsWith(".md")) files.push(fullPath);
|
|
11086
11099
|
}
|
|
@@ -11104,8 +11117,8 @@ async function buildSearchIndex(srcDir, base) {
|
|
|
11104
11117
|
const files = await collectMarkdownFiles(srcDir);
|
|
11105
11118
|
const documents = [];
|
|
11106
11119
|
for (const file of files) try {
|
|
11107
|
-
const content = await fs.readFile(file, "utf-8");
|
|
11108
|
-
const relativePath = path$
|
|
11120
|
+
const content = await fs$1.readFile(file, "utf-8");
|
|
11121
|
+
const relativePath = path$2.relative(srcDir, file);
|
|
11109
11122
|
const url = base + relativePath.replace(/\.md$/, "").replace(/\\/g, "/");
|
|
11110
11123
|
const id = relativePath.replace(/\.md$/, "").replace(/\\/g, "/");
|
|
11111
11124
|
const extractSearchContent = napi.extractSearchContent;
|
|
@@ -11134,9 +11147,9 @@ async function buildSearchIndex(srcDir, base) {
|
|
|
11134
11147
|
* Writes the search index to a file.
|
|
11135
11148
|
*/
|
|
11136
11149
|
async function writeSearchIndex(indexJson, outDir) {
|
|
11137
|
-
const indexPath = path$
|
|
11138
|
-
await fs.mkdir(outDir, { recursive: true });
|
|
11139
|
-
await fs.writeFile(indexPath, indexJson, "utf-8");
|
|
11150
|
+
const indexPath = path$2.join(outDir, "search-index.json");
|
|
11151
|
+
await fs$1.mkdir(outDir, { recursive: true });
|
|
11152
|
+
await fs$1.writeFile(indexPath, indexJson, "utf-8");
|
|
11140
11153
|
}
|
|
11141
11154
|
/**
|
|
11142
11155
|
* Client-side search module code.
|
|
@@ -11436,14 +11449,14 @@ async function resolveMarkdownFile(url, srcDir) {
|
|
|
11436
11449
|
let relativePath;
|
|
11437
11450
|
if (pathname === "/") relativePath = "index.md";
|
|
11438
11451
|
else relativePath = pathname.slice(1) + ".md";
|
|
11439
|
-
const filePath = path$
|
|
11452
|
+
const filePath = path$2.join(srcDir, relativePath);
|
|
11440
11453
|
try {
|
|
11441
|
-
await fs.access(filePath);
|
|
11454
|
+
await fs$1.access(filePath);
|
|
11442
11455
|
return filePath;
|
|
11443
11456
|
} catch {
|
|
11444
|
-
const indexPath = path$
|
|
11457
|
+
const indexPath = path$2.join(srcDir, pathname === "/" ? "" : pathname.slice(1), "index.md");
|
|
11445
11458
|
try {
|
|
11446
|
-
await fs.access(indexPath);
|
|
11459
|
+
await fs$1.access(indexPath);
|
|
11447
11460
|
return indexPath;
|
|
11448
11461
|
} catch {
|
|
11449
11462
|
return null;
|
|
@@ -11485,8 +11498,8 @@ function invalidatePageCache(cache, filePath) {
|
|
|
11485
11498
|
async function resolveSiteName(options, root) {
|
|
11486
11499
|
if (options.ssg.siteName) return options.ssg.siteName;
|
|
11487
11500
|
try {
|
|
11488
|
-
const pkgPath = path$
|
|
11489
|
-
const pkg = JSON.parse(await fs.readFile(pkgPath, "utf-8"));
|
|
11501
|
+
const pkgPath = path$2.join(root, "package.json");
|
|
11502
|
+
const pkg = JSON.parse(await fs$1.readFile(pkgPath, "utf-8"));
|
|
11490
11503
|
if (pkg.name) return formatTitle(pkg.name);
|
|
11491
11504
|
} catch {}
|
|
11492
11505
|
return "Documentation";
|
|
@@ -11495,10 +11508,10 @@ async function resolveSiteName(options, root) {
|
|
|
11495
11508
|
* Render a single markdown page to full HTML.
|
|
11496
11509
|
*/
|
|
11497
11510
|
async function renderPage$1(filePath, options, navGroups, siteName, base, root) {
|
|
11498
|
-
const srcDir = path$
|
|
11511
|
+
const srcDir = path$2.resolve(root, options.srcDir);
|
|
11499
11512
|
resetTabGroupCounter();
|
|
11500
11513
|
resetIslandCounter();
|
|
11501
|
-
const result = await transformMarkdown(await fs.readFile(filePath, "utf-8"), filePath, options, {
|
|
11514
|
+
const result = await transformMarkdown(await fs$1.readFile(filePath, "utf-8"), filePath, options, {
|
|
11502
11515
|
convertMdLinks: true,
|
|
11503
11516
|
baseUrl: base,
|
|
11504
11517
|
sourcePath: filePath
|
|
@@ -11540,7 +11553,7 @@ async function renderPage$1(filePath, options, navGroups, siteName, base, root)
|
|
|
11540
11553
|
* Create the dev server middleware for SSG page serving.
|
|
11541
11554
|
*/
|
|
11542
11555
|
function createDevServerMiddleware(options, root, cache) {
|
|
11543
|
-
const srcDir = path$
|
|
11556
|
+
const srcDir = path$2.resolve(root, options.srcDir);
|
|
11544
11557
|
const base = options.base.endsWith("/") ? options.base : options.base + "/";
|
|
11545
11558
|
return async (req, res, next) => {
|
|
11546
11559
|
const url = req.url;
|
|
@@ -11605,7 +11618,7 @@ function extractTitle(content, frontmatter) {
|
|
|
11605
11618
|
return match ? match[1].trim() : "";
|
|
11606
11619
|
}
|
|
11607
11620
|
function getUrlPath(filePath, srcDir) {
|
|
11608
|
-
let rel = path$
|
|
11621
|
+
let rel = path$2.relative(srcDir, filePath).replace(/\\/g, "/");
|
|
11609
11622
|
rel = rel.replace(/\.md$/, "");
|
|
11610
11623
|
if (rel === "index") return "/";
|
|
11611
11624
|
if (rel.endsWith("/index")) rel = rel.slice(0, -6);
|
|
@@ -11645,7 +11658,7 @@ function validatePage(page, options) {
|
|
|
11645
11658
|
return warnings;
|
|
11646
11659
|
}
|
|
11647
11660
|
async function collectPages(options, root) {
|
|
11648
|
-
const srcDir = path$
|
|
11661
|
+
const srcDir = path$2.resolve(root, options.srcDir);
|
|
11649
11662
|
const files = await glob("**/*.md", {
|
|
11650
11663
|
cwd: srcDir,
|
|
11651
11664
|
absolute: true
|
|
@@ -11653,7 +11666,7 @@ async function collectPages(options, root) {
|
|
|
11653
11666
|
const pages = [];
|
|
11654
11667
|
const generateOgImage = options.ogImage || options.ssg.generateOgImage;
|
|
11655
11668
|
for (const file of files.sort()) {
|
|
11656
|
-
const content = fs$
|
|
11669
|
+
const content = fs$2.readFileSync(file, "utf-8");
|
|
11657
11670
|
const frontmatter = parseFrontmatter(content);
|
|
11658
11671
|
if (frontmatter.layout === "entry") continue;
|
|
11659
11672
|
const title = extractTitle(content, frontmatter);
|
|
@@ -11663,7 +11676,7 @@ async function collectPages(options, root) {
|
|
|
11663
11676
|
const urlPath = getUrlPath(file, srcDir);
|
|
11664
11677
|
const ogImageUrl = computeOgImageUrl(urlPath, options.base, options.ssg.siteUrl, generateOgImage, options.ssg.ogImage);
|
|
11665
11678
|
const page = {
|
|
11666
|
-
path: path$
|
|
11679
|
+
path: path$2.relative(srcDir, file),
|
|
11667
11680
|
urlPath,
|
|
11668
11681
|
title,
|
|
11669
11682
|
description,
|
|
@@ -11976,8 +11989,8 @@ function createI18nPlugin(resolvedOptions) {
|
|
|
11976
11989
|
},
|
|
11977
11990
|
async buildStart() {
|
|
11978
11991
|
if (!i18nOptions || !i18nOptions.check) return;
|
|
11979
|
-
const dictDir = path$
|
|
11980
|
-
if (!fs$
|
|
11992
|
+
const dictDir = path$2.resolve(root, i18nOptions.dir);
|
|
11993
|
+
if (!fs$2.existsSync(dictDir)) {
|
|
11981
11994
|
console.warn(`[ox-content:i18n] Dictionary directory not found: ${dictDir}`);
|
|
11982
11995
|
return;
|
|
11983
11996
|
}
|
|
@@ -11998,8 +12011,8 @@ function createI18nPlugin(resolvedOptions) {
|
|
|
11998
12011
|
},
|
|
11999
12012
|
configureServer(server) {
|
|
12000
12013
|
if (!i18nOptions) return;
|
|
12001
|
-
const dictDir = path$
|
|
12002
|
-
if (fs$
|
|
12014
|
+
const dictDir = path$2.resolve(root, i18nOptions.dir);
|
|
12015
|
+
if (fs$2.existsSync(dictDir)) {
|
|
12003
12016
|
server.watcher.add(dictDir);
|
|
12004
12017
|
server.watcher.on("change", (filePath) => {
|
|
12005
12018
|
if (!filePath.startsWith(dictDir)) return;
|
|
@@ -12025,7 +12038,7 @@ function createI18nPlugin(resolvedOptions) {
|
|
|
12025
12038
|
* Generates the virtual module for i18n configuration.
|
|
12026
12039
|
*/
|
|
12027
12040
|
function generateI18nModule(options, root) {
|
|
12028
|
-
const dictDir = path$
|
|
12041
|
+
const dictDir = path$2.resolve(root, options.dir);
|
|
12029
12042
|
const localesJson = JSON.stringify(options.locales);
|
|
12030
12043
|
const defaultLocale = JSON.stringify(options.defaultLocale);
|
|
12031
12044
|
let dictionariesCode = "{}";
|
|
@@ -12108,15 +12121,15 @@ function flattenObject(obj, prefix, result) {
|
|
|
12108
12121
|
function loadDictionariesFallback(options, dictDir) {
|
|
12109
12122
|
const dictData = {};
|
|
12110
12123
|
for (const locale of options.locales) {
|
|
12111
|
-
const localeDir = path$
|
|
12112
|
-
if (!fs$
|
|
12113
|
-
const files = fs$
|
|
12124
|
+
const localeDir = path$2.join(dictDir, locale.code);
|
|
12125
|
+
if (!fs$2.existsSync(localeDir)) continue;
|
|
12126
|
+
const files = fs$2.readdirSync(localeDir);
|
|
12114
12127
|
const localeDict = {};
|
|
12115
12128
|
for (const file of files) {
|
|
12116
12129
|
if (!file.endsWith(".json")) continue;
|
|
12117
|
-
const filePath = path$
|
|
12118
|
-
const content = fs$
|
|
12119
|
-
const namespace = path$
|
|
12130
|
+
const filePath = path$2.join(localeDir, file);
|
|
12131
|
+
const content = fs$2.readFileSync(filePath, "utf-8");
|
|
12132
|
+
const namespace = path$2.basename(file, ".json");
|
|
12120
12133
|
try {
|
|
12121
12134
|
flattenObject(JSON.parse(content), namespace, localeDict);
|
|
12122
12135
|
} catch {}
|
|
@@ -12129,17 +12142,17 @@ function loadDictionariesFallback(options, dictDir) {
|
|
|
12129
12142
|
* Collects translation keys from source files using NAPI extractTranslationKeys.
|
|
12130
12143
|
*/
|
|
12131
12144
|
function collectKeysFromSource(root, extractTranslationKeys, options) {
|
|
12132
|
-
const srcDir = path$
|
|
12145
|
+
const srcDir = path$2.resolve(root, "src");
|
|
12133
12146
|
const keys = /* @__PURE__ */ new Set();
|
|
12134
|
-
if (fs$
|
|
12135
|
-
const usages = extractTranslationKeys(fs$
|
|
12147
|
+
if (fs$2.existsSync(srcDir)) walkDir(srcDir, /\.(ts|tsx|js|jsx)$/, (filePath) => {
|
|
12148
|
+
const usages = extractTranslationKeys(fs$2.readFileSync(filePath, "utf-8"), filePath, options.functionNames);
|
|
12136
12149
|
for (const usage of usages) keys.add(usage.key);
|
|
12137
12150
|
});
|
|
12138
|
-
const contentDir = path$
|
|
12139
|
-
if (fs$
|
|
12151
|
+
const contentDir = path$2.resolve(root, "content");
|
|
12152
|
+
if (fs$2.existsSync(contentDir)) {
|
|
12140
12153
|
const tPattern = /\{\{t\(['"]([^'"]+)['"]\)\}\}/g;
|
|
12141
12154
|
walkDir(contentDir, /\.(md|mdx)$/, (filePath) => {
|
|
12142
|
-
const content = fs$
|
|
12155
|
+
const content = fs$2.readFileSync(filePath, "utf-8");
|
|
12143
12156
|
let match;
|
|
12144
12157
|
while ((match = tPattern.exec(content)) !== null) keys.add(match[1]);
|
|
12145
12158
|
tPattern.lastIndex = 0;
|
|
@@ -12151,9 +12164,9 @@ function collectKeysFromSource(root, extractTranslationKeys, options) {
|
|
|
12151
12164
|
* Recursively walks a directory, calling the callback for files matching the pattern.
|
|
12152
12165
|
*/
|
|
12153
12166
|
function walkDir(dir, pattern, callback) {
|
|
12154
|
-
const entries = fs$
|
|
12167
|
+
const entries = fs$2.readdirSync(dir, { withFileTypes: true });
|
|
12155
12168
|
for (const entry of entries) {
|
|
12156
|
-
const fullPath = path$
|
|
12169
|
+
const fullPath = path$2.join(dir, entry.name);
|
|
12157
12170
|
if (entry.isDirectory()) {
|
|
12158
12171
|
if (entry.name === "node_modules" || entry.name === ".git") continue;
|
|
12159
12172
|
walkDir(fullPath, pattern, callback);
|
|
@@ -12161,6 +12174,358 @@ function walkDir(dir, pattern, callback) {
|
|
|
12161
12174
|
}
|
|
12162
12175
|
}
|
|
12163
12176
|
//#endregion
|
|
12177
|
+
//#region src/lint.ts
|
|
12178
|
+
const require$1 = createRequire(import.meta.url);
|
|
12179
|
+
const SUPPORTED_MARKDOWN_LINT_LANGUAGES = [
|
|
12180
|
+
"en",
|
|
12181
|
+
"ja",
|
|
12182
|
+
"zh",
|
|
12183
|
+
"fr",
|
|
12184
|
+
"de",
|
|
12185
|
+
"pl"
|
|
12186
|
+
];
|
|
12187
|
+
const DEFAULT_LANGUAGES = ["en"];
|
|
12188
|
+
const DEFAULT_RULES = {
|
|
12189
|
+
duplicateHeadings: true,
|
|
12190
|
+
headingIncrement: true,
|
|
12191
|
+
maxConsecutiveBlankLines: 1,
|
|
12192
|
+
repeatedPunctuation: true,
|
|
12193
|
+
repeatedWords: true,
|
|
12194
|
+
spellcheck: true,
|
|
12195
|
+
trailingSpaces: true
|
|
12196
|
+
};
|
|
12197
|
+
const DEFAULT_CSPELL_IMPORTS = {
|
|
12198
|
+
de: "@cspell/dict-de-de/cspell-ext.json",
|
|
12199
|
+
en: "@cspell/dict-en_us/cspell-ext.json",
|
|
12200
|
+
fr: "@cspell/dict-fr-fr/cspell-ext.json",
|
|
12201
|
+
pl: "@cspell/dict-pl_pl/cspell-ext.json"
|
|
12202
|
+
};
|
|
12203
|
+
let napiBinding;
|
|
12204
|
+
let cspellLibPromise;
|
|
12205
|
+
/**
|
|
12206
|
+
* Lints Markdown prose with the Rust-backed built-in rule engine.
|
|
12207
|
+
*/
|
|
12208
|
+
function lintMarkdown(source, options = {}) {
|
|
12209
|
+
return lintMarkdownWithNormalizedOptions(source, normalizeLintOptions(options));
|
|
12210
|
+
}
|
|
12211
|
+
/**
|
|
12212
|
+
* Async Markdown linter that supports opt-in standard dictionaries.
|
|
12213
|
+
*/
|
|
12214
|
+
async function lintMarkdownAsync(source, options = {}) {
|
|
12215
|
+
const normalizedOptions = normalizeLintOptions(options);
|
|
12216
|
+
const [result] = await lintMarkdownDocumentsWithNormalizedOptions([source], normalizedOptions);
|
|
12217
|
+
return result ?? createEmptyLintResult$1();
|
|
12218
|
+
}
|
|
12219
|
+
/**
|
|
12220
|
+
* Internal batched Markdown linting entry point used by file-based workflows.
|
|
12221
|
+
*/
|
|
12222
|
+
async function lintMarkdownDocumentsAsync(sources, options = {}) {
|
|
12223
|
+
return lintMarkdownDocumentsWithNormalizedOptions(sources, normalizeLintOptions(options));
|
|
12224
|
+
}
|
|
12225
|
+
function lintMarkdownWithNormalizedOptions(source, normalizedOptions) {
|
|
12226
|
+
if (normalizedOptions.dictionary.standard) throw new Error("[ox-content] lintMarkdownAsync is required when dictionary.standard is enabled.");
|
|
12227
|
+
return stripMaskedDocument(loadNapiBindingSync().lintMarkdown(source, toNapiMarkdownLintOptions(normalizedOptions)));
|
|
12228
|
+
}
|
|
12229
|
+
async function lintMarkdownDocumentsWithNormalizedOptions(sources, normalizedOptions) {
|
|
12230
|
+
if (sources.length === 0) return [];
|
|
12231
|
+
const napi = loadNapiBindingSync();
|
|
12232
|
+
const napiOptions = toNapiMarkdownLintOptions(normalizedOptions, Boolean(normalizedOptions.dictionary.standard));
|
|
12233
|
+
const builtInResults = typeof napi.lintMarkdownDocuments === "function" ? napi.lintMarkdownDocuments(sources, napiOptions) : sources.map((source) => napi.lintMarkdown(source, napiOptions));
|
|
12234
|
+
if (!normalizedOptions.rules.spellcheck || !normalizedOptions.dictionary.standard) return builtInResults.map(stripMaskedDocument);
|
|
12235
|
+
const standardDiagnostics = await runStandardSpellcheckDocuments(builtInResults.map((result) => result.maskedDocument), normalizedOptions);
|
|
12236
|
+
return builtInResults.map((result, index) => summarizeDiagnostics(sortDiagnostics(result.diagnostics.concat(standardDiagnostics[index] ?? []))));
|
|
12237
|
+
}
|
|
12238
|
+
function loadNapiBindingSync() {
|
|
12239
|
+
if (napiBinding) return napiBinding;
|
|
12240
|
+
if (napiBinding === null) throw new Error("[ox-content] @ox-content/napi is required for Markdown linting. Please ensure the NAPI module is built.");
|
|
12241
|
+
try {
|
|
12242
|
+
const loaded = require$1("@ox-content/napi");
|
|
12243
|
+
napiBinding = loaded.default && typeof loaded.default === "object" ? {
|
|
12244
|
+
...loaded.default,
|
|
12245
|
+
...loaded
|
|
12246
|
+
} : loaded;
|
|
12247
|
+
return napiBinding;
|
|
12248
|
+
} catch {
|
|
12249
|
+
napiBinding = null;
|
|
12250
|
+
throw new Error("[ox-content] @ox-content/napi is required for Markdown linting. Please ensure the NAPI module is built.");
|
|
12251
|
+
}
|
|
12252
|
+
}
|
|
12253
|
+
function toNapiMarkdownLintOptions(options, disableBuiltinSpellcheck = false) {
|
|
12254
|
+
return {
|
|
12255
|
+
dictionary: {
|
|
12256
|
+
byLanguage: Object.entries(options.dictionary.byLanguage ?? {}).map(([language, words]) => ({
|
|
12257
|
+
language,
|
|
12258
|
+
words
|
|
12259
|
+
})),
|
|
12260
|
+
ignoredWords: options.dictionary.ignoredWords,
|
|
12261
|
+
words: options.dictionary.words
|
|
12262
|
+
},
|
|
12263
|
+
languages: options.languages,
|
|
12264
|
+
rules: {
|
|
12265
|
+
...options.rules,
|
|
12266
|
+
spellcheck: disableBuiltinSpellcheck ? false : options.rules.spellcheck
|
|
12267
|
+
}
|
|
12268
|
+
};
|
|
12269
|
+
}
|
|
12270
|
+
function stripMaskedDocument(result) {
|
|
12271
|
+
return {
|
|
12272
|
+
diagnostics: result.diagnostics,
|
|
12273
|
+
errorCount: result.errorCount,
|
|
12274
|
+
infoCount: result.infoCount,
|
|
12275
|
+
warningCount: result.warningCount
|
|
12276
|
+
};
|
|
12277
|
+
}
|
|
12278
|
+
function normalizeLintOptions(options) {
|
|
12279
|
+
const languages = options.languages?.filter((language) => SUPPORTED_MARKDOWN_LINT_LANGUAGES.includes(language)) ?? options.dictionary?.standard?.languages?.filter((language) => SUPPORTED_MARKDOWN_LINT_LANGUAGES.includes(language)) ?? [...DEFAULT_LANGUAGES];
|
|
12280
|
+
const standard = normalizeStandardDictionaryOptions(options.dictionary?.standard, languages);
|
|
12281
|
+
return {
|
|
12282
|
+
dictionary: {
|
|
12283
|
+
...options.dictionary,
|
|
12284
|
+
standard
|
|
12285
|
+
},
|
|
12286
|
+
languages: [...new Set(languages)],
|
|
12287
|
+
rules: {
|
|
12288
|
+
duplicateHeadings: options.rules?.duplicateHeadings ?? DEFAULT_RULES.duplicateHeadings,
|
|
12289
|
+
headingIncrement: options.rules?.headingIncrement ?? DEFAULT_RULES.headingIncrement,
|
|
12290
|
+
maxConsecutiveBlankLines: options.rules?.maxConsecutiveBlankLines ?? DEFAULT_RULES.maxConsecutiveBlankLines,
|
|
12291
|
+
repeatedPunctuation: options.rules?.repeatedPunctuation ?? DEFAULT_RULES.repeatedPunctuation,
|
|
12292
|
+
repeatedWords: options.rules?.repeatedWords ?? DEFAULT_RULES.repeatedWords,
|
|
12293
|
+
spellcheck: options.rules?.spellcheck ?? DEFAULT_RULES.spellcheck,
|
|
12294
|
+
trailingSpaces: options.rules?.trailingSpaces ?? DEFAULT_RULES.trailingSpaces
|
|
12295
|
+
}
|
|
12296
|
+
};
|
|
12297
|
+
}
|
|
12298
|
+
function normalizeStandardDictionaryOptions(standard, fallbackLanguages) {
|
|
12299
|
+
if (!standard) return false;
|
|
12300
|
+
const languages = standard.languages?.filter((language) => SUPPORTED_MARKDOWN_LINT_LANGUAGES.includes(language)) ?? fallbackLanguages;
|
|
12301
|
+
const customImports = standard.imports ?? [];
|
|
12302
|
+
const missingPresetLanguages = languages.filter((language) => !DEFAULT_CSPELL_IMPORTS[language]);
|
|
12303
|
+
if (missingPresetLanguages.length > 0 && customImports.length === 0) throw new Error(`[ox-content] No bundled standard dictionary preset exists for ${missingPresetLanguages.join(", ")}. Provide dictionary.standard.imports to enable those languages.`);
|
|
12304
|
+
const imports = [...languages.map((language) => DEFAULT_CSPELL_IMPORTS[language]).filter((value) => Boolean(value)), ...customImports];
|
|
12305
|
+
if (imports.length === 0) throw new Error("[ox-content] dictionary.standard requires at least one bundled preset language or custom import.");
|
|
12306
|
+
return {
|
|
12307
|
+
imports: [...new Set(imports)],
|
|
12308
|
+
languages: [...new Set(languages)],
|
|
12309
|
+
provider: standard.provider ?? "cspell",
|
|
12310
|
+
resolveImportsRelativeTo: standard.resolveImportsRelativeTo ?? new URL(".", import.meta.url)
|
|
12311
|
+
};
|
|
12312
|
+
}
|
|
12313
|
+
async function runStandardSpellcheckDocuments(maskedDocuments, options) {
|
|
12314
|
+
const standard = options.dictionary.standard;
|
|
12315
|
+
if (!standard || maskedDocuments.length === 0) return maskedDocuments.map(() => []);
|
|
12316
|
+
try {
|
|
12317
|
+
const { spellCheckDocument } = await loadCspellLib();
|
|
12318
|
+
const locale = standard.languages.join(",");
|
|
12319
|
+
const settings = createStandardSpellcheckSettings(options, locale);
|
|
12320
|
+
return Promise.all(maskedDocuments.map(async (maskedDocument, index) => {
|
|
12321
|
+
if (maskedDocument.trim().length === 0) return [];
|
|
12322
|
+
return (await spellCheckDocument({
|
|
12323
|
+
languageId: "plaintext",
|
|
12324
|
+
locale,
|
|
12325
|
+
text: maskedDocument,
|
|
12326
|
+
uri: `file:///ox-content-lint-${index}.md`
|
|
12327
|
+
}, {
|
|
12328
|
+
generateSuggestions: true,
|
|
12329
|
+
noConfigSearch: true,
|
|
12330
|
+
numSuggestions: 3,
|
|
12331
|
+
resolveImportsRelativeTo: standard.resolveImportsRelativeTo
|
|
12332
|
+
}, settings)).issues.map((issue) => mapStandardIssueToDiagnostic(issue, standard.languages));
|
|
12333
|
+
}));
|
|
12334
|
+
} catch (error) {
|
|
12335
|
+
const imports = standard.imports.join(", ");
|
|
12336
|
+
const message = imports.length > 0 ? `[ox-content] Failed to load standard dictionaries from ${imports}. Verify the imports and install the referenced CSpell packages.` : "[ox-content] Failed to load the configured standard dictionaries.";
|
|
12337
|
+
throw new Error(message, { cause: error });
|
|
12338
|
+
}
|
|
12339
|
+
}
|
|
12340
|
+
function createStandardSpellcheckSettings(options, locale) {
|
|
12341
|
+
return {
|
|
12342
|
+
import: options.dictionary.standard ? options.dictionary.standard.imports : [],
|
|
12343
|
+
ignoreWords: options.dictionary.ignoredWords,
|
|
12344
|
+
language: locale,
|
|
12345
|
+
version: "0.2",
|
|
12346
|
+
words: [...options.dictionary.words ?? [], ...Object.values(options.dictionary.byLanguage ?? {}).flat()]
|
|
12347
|
+
};
|
|
12348
|
+
}
|
|
12349
|
+
async function loadCspellLib() {
|
|
12350
|
+
cspellLibPromise ??= import("cspell-lib");
|
|
12351
|
+
return cspellLibPromise;
|
|
12352
|
+
}
|
|
12353
|
+
function mapStandardIssueToDiagnostic(issue, languages) {
|
|
12354
|
+
const line = issue.line.position.line + 1;
|
|
12355
|
+
const column = issue.offset - issue.line.offset + 1;
|
|
12356
|
+
return {
|
|
12357
|
+
column,
|
|
12358
|
+
endColumn: column + (issue.length ?? issue.text.length),
|
|
12359
|
+
endLine: line,
|
|
12360
|
+
language: inferStandardIssueLanguage(issue.text, languages),
|
|
12361
|
+
line,
|
|
12362
|
+
message: `Unknown word "${issue.text}".`,
|
|
12363
|
+
ruleId: "spellcheck",
|
|
12364
|
+
severity: "warning",
|
|
12365
|
+
suggestions: issue.suggestions?.slice(0, 3)
|
|
12366
|
+
};
|
|
12367
|
+
}
|
|
12368
|
+
function inferStandardIssueLanguage(word, languages) {
|
|
12369
|
+
if (/[\p{Script=Hiragana}\p{Script=Katakana}]/u.test(word) && languages.includes("ja")) return "ja";
|
|
12370
|
+
if (/[\p{Script=Han}]/u.test(word)) {
|
|
12371
|
+
if (languages.includes("zh") && !languages.includes("ja")) return "zh";
|
|
12372
|
+
if (languages.includes("ja") && !languages.includes("zh")) return "ja";
|
|
12373
|
+
}
|
|
12374
|
+
if (/[\p{Script=Latin}]/u.test(word)) {
|
|
12375
|
+
const latinLanguages = languages.filter((language) => language !== "ja" && language !== "zh");
|
|
12376
|
+
if (latinLanguages.length === 1) return latinLanguages[0];
|
|
12377
|
+
return inferLatinLanguageFromCharacters(word, latinLanguages);
|
|
12378
|
+
}
|
|
12379
|
+
}
|
|
12380
|
+
function inferLatinLanguageFromCharacters(word, languages) {
|
|
12381
|
+
if (languages.includes("pl") && /[ąćęłńóśźż]/iu.test(word)) return "pl";
|
|
12382
|
+
if (languages.includes("de") && /[äöüß]/iu.test(word)) return "de";
|
|
12383
|
+
if (languages.includes("fr") && /[àâæçéèêëîïôœùûüÿ]/iu.test(word)) return "fr";
|
|
12384
|
+
}
|
|
12385
|
+
function summarizeDiagnostics(diagnostics) {
|
|
12386
|
+
let errorCount = 0;
|
|
12387
|
+
let warningCount = 0;
|
|
12388
|
+
let infoCount = 0;
|
|
12389
|
+
for (const diagnostic of diagnostics) if (diagnostic.severity === "error") errorCount += 1;
|
|
12390
|
+
else if (diagnostic.severity === "warning") warningCount += 1;
|
|
12391
|
+
else infoCount += 1;
|
|
12392
|
+
return {
|
|
12393
|
+
diagnostics,
|
|
12394
|
+
errorCount,
|
|
12395
|
+
infoCount,
|
|
12396
|
+
warningCount
|
|
12397
|
+
};
|
|
12398
|
+
}
|
|
12399
|
+
function createEmptyLintResult$1() {
|
|
12400
|
+
return summarizeDiagnostics([]);
|
|
12401
|
+
}
|
|
12402
|
+
function sortDiagnostics(diagnostics) {
|
|
12403
|
+
return [...diagnostics].sort((left, right) => {
|
|
12404
|
+
if (left.line !== right.line) return left.line - right.line;
|
|
12405
|
+
if (left.column !== right.column) return left.column - right.column;
|
|
12406
|
+
return left.ruleId.localeCompare(right.ruleId);
|
|
12407
|
+
});
|
|
12408
|
+
}
|
|
12409
|
+
//#endregion
|
|
12410
|
+
//#region src/lint-files.ts
|
|
12411
|
+
const DEFAULT_LINT_FILE_INCLUDE = ["**/*.md", "**/*.markdown"];
|
|
12412
|
+
const DEFAULT_LINT_FILE_EXCLUDE = [
|
|
12413
|
+
"**/node_modules/**",
|
|
12414
|
+
"**/.git/**",
|
|
12415
|
+
"**/dist/**"
|
|
12416
|
+
];
|
|
12417
|
+
/**
|
|
12418
|
+
* Returns true if the file path is included by the configured glob filters.
|
|
12419
|
+
*/
|
|
12420
|
+
function shouldLintMarkdownFile(filePath, options = {}) {
|
|
12421
|
+
const resolvedOptions = resolveMarkdownLintFileOptions(options);
|
|
12422
|
+
return shouldLintAbsoluteFile(path$1.resolve(resolvedOptions.cwd, filePath), resolvedOptions);
|
|
12423
|
+
}
|
|
12424
|
+
/**
|
|
12425
|
+
* Lints a single Markdown file using project-style include/exclude settings.
|
|
12426
|
+
*
|
|
12427
|
+
* If the file is filtered out by `include` / `exclude`, the returned result is
|
|
12428
|
+
* marked as `skipped` and contains no diagnostics.
|
|
12429
|
+
*/
|
|
12430
|
+
async function lintMarkdownFile(filePath, options = {}) {
|
|
12431
|
+
const resolvedOptions = resolveMarkdownLintFileOptions(options);
|
|
12432
|
+
return lintMarkdownFileWithResolvedOptions(path$1.resolve(resolvedOptions.cwd, filePath), resolvedOptions);
|
|
12433
|
+
}
|
|
12434
|
+
/**
|
|
12435
|
+
* Lints all Markdown files matched by the configured include/exclude patterns.
|
|
12436
|
+
*/
|
|
12437
|
+
async function lintMarkdownFiles(options = {}) {
|
|
12438
|
+
const resolvedOptions = resolveMarkdownLintFileOptions(options);
|
|
12439
|
+
const matchedFiles = await collectMarkdownLintFileEntries(resolvedOptions);
|
|
12440
|
+
const results = await lintMarkdownDocumentsAsync(await Promise.all(matchedFiles.map((file) => fs.readFile(file.filePath, "utf-8"))), resolvedOptions.lintOptions);
|
|
12441
|
+
const files = matchedFiles.map((file, index) => ({
|
|
12442
|
+
...results[index] ?? createEmptyLintResult(),
|
|
12443
|
+
filePath: file.filePath,
|
|
12444
|
+
relativePath: file.relativePath,
|
|
12445
|
+
skipped: false
|
|
12446
|
+
}));
|
|
12447
|
+
const diagnostics = files.flatMap((fileResult) => fileResult.diagnostics.map((diagnostic) => ({
|
|
12448
|
+
...diagnostic,
|
|
12449
|
+
filePath: fileResult.filePath,
|
|
12450
|
+
relativePath: fileResult.relativePath
|
|
12451
|
+
})));
|
|
12452
|
+
return {
|
|
12453
|
+
checkedFileCount: files.length,
|
|
12454
|
+
diagnostics,
|
|
12455
|
+
errorCount: files.reduce((count, fileResult) => count + fileResult.errorCount, 0),
|
|
12456
|
+
files,
|
|
12457
|
+
infoCount: files.reduce((count, fileResult) => count + fileResult.infoCount, 0),
|
|
12458
|
+
warningCount: files.reduce((count, fileResult) => count + fileResult.warningCount, 0)
|
|
12459
|
+
};
|
|
12460
|
+
}
|
|
12461
|
+
function resolveMarkdownLintFileOptions(options) {
|
|
12462
|
+
return {
|
|
12463
|
+
cwd: path$1.resolve(options.cwd ?? process.cwd()),
|
|
12464
|
+
exclude: [...new Set([...options.exclude ?? DEFAULT_LINT_FILE_EXCLUDE, ...options.ignore ?? []])],
|
|
12465
|
+
include: [...new Set(options.include ?? DEFAULT_LINT_FILE_INCLUDE)],
|
|
12466
|
+
lintOptions: {
|
|
12467
|
+
dictionary: options.dictionary,
|
|
12468
|
+
languages: options.languages,
|
|
12469
|
+
rules: options.rules
|
|
12470
|
+
}
|
|
12471
|
+
};
|
|
12472
|
+
}
|
|
12473
|
+
async function lintMarkdownFileWithResolvedOptions(filePath, options) {
|
|
12474
|
+
const absoluteFilePath = path$1.resolve(filePath);
|
|
12475
|
+
const relativePath = normalizePath(path$1.relative(options.cwd, absoluteFilePath));
|
|
12476
|
+
if (!shouldLintAbsoluteFile(absoluteFilePath, options)) return {
|
|
12477
|
+
...createEmptyLintResult(),
|
|
12478
|
+
filePath: absoluteFilePath,
|
|
12479
|
+
relativePath,
|
|
12480
|
+
skipped: true
|
|
12481
|
+
};
|
|
12482
|
+
return {
|
|
12483
|
+
...await lintMarkdownAsync(await fs.readFile(absoluteFilePath, "utf-8"), options.lintOptions),
|
|
12484
|
+
filePath: absoluteFilePath,
|
|
12485
|
+
relativePath,
|
|
12486
|
+
skipped: false
|
|
12487
|
+
};
|
|
12488
|
+
}
|
|
12489
|
+
async function collectMarkdownLintFileEntries(options) {
|
|
12490
|
+
const files = /* @__PURE__ */ new Map();
|
|
12491
|
+
for (const pattern of options.include) {
|
|
12492
|
+
const matches = await glob(pattern, {
|
|
12493
|
+
absolute: true,
|
|
12494
|
+
cwd: options.cwd,
|
|
12495
|
+
ignore: options.exclude,
|
|
12496
|
+
nodir: true
|
|
12497
|
+
});
|
|
12498
|
+
for (const filePath of matches) {
|
|
12499
|
+
const absoluteFilePath = path$1.resolve(filePath);
|
|
12500
|
+
if (shouldLintAbsoluteFile(absoluteFilePath, options)) files.set(absoluteFilePath, {
|
|
12501
|
+
filePath: absoluteFilePath,
|
|
12502
|
+
relativePath: normalizePath(path$1.relative(options.cwd, absoluteFilePath))
|
|
12503
|
+
});
|
|
12504
|
+
}
|
|
12505
|
+
}
|
|
12506
|
+
return [...files.values()].sort((left, right) => left.filePath.localeCompare(right.filePath));
|
|
12507
|
+
}
|
|
12508
|
+
function shouldLintAbsoluteFile(filePath, options) {
|
|
12509
|
+
const absolutePath = normalizePath(path$1.resolve(filePath));
|
|
12510
|
+
const relativePath = normalizePath(path$1.relative(options.cwd, absolutePath));
|
|
12511
|
+
const matches = (patterns) => patterns.some((pattern) => {
|
|
12512
|
+
const normalizedPattern = normalizePath(pattern);
|
|
12513
|
+
return path$1.matchesGlob(relativePath, normalizedPattern) || path$1.matchesGlob(absolutePath, normalizedPattern);
|
|
12514
|
+
});
|
|
12515
|
+
return matches(options.include) && !matches(options.exclude);
|
|
12516
|
+
}
|
|
12517
|
+
function normalizePath(value) {
|
|
12518
|
+
return value.split(path$1.sep).join("/");
|
|
12519
|
+
}
|
|
12520
|
+
function createEmptyLintResult() {
|
|
12521
|
+
return {
|
|
12522
|
+
diagnostics: [],
|
|
12523
|
+
errorCount: 0,
|
|
12524
|
+
infoCount: 0,
|
|
12525
|
+
warningCount: 0
|
|
12526
|
+
};
|
|
12527
|
+
}
|
|
12528
|
+
//#endregion
|
|
12164
12529
|
//#region src/jsx-runtime.ts
|
|
12165
12530
|
/**
|
|
12166
12531
|
* Custom JSX Runtime for Static HTML Generation
|
|
@@ -12733,8 +13098,8 @@ function oxContent(options = {}) {
|
|
|
12733
13098
|
async function regenerateDocs(root) {
|
|
12734
13099
|
const docsOptions = resolvedOptions.docs;
|
|
12735
13100
|
if (!docsOptions || !docsOptions.enabled) return 0;
|
|
12736
|
-
const srcDirs = docsOptions.src.map((src) => path$
|
|
12737
|
-
const outDir = path$
|
|
13101
|
+
const srcDirs = docsOptions.src.map((src) => path$2.resolve(root, src));
|
|
13102
|
+
const outDir = path$2.resolve(root, docsOptions.out);
|
|
12738
13103
|
const extracted = await extractDocs(srcDirs, docsOptions);
|
|
12739
13104
|
const generated = generateMarkdown(extracted, docsOptions);
|
|
12740
13105
|
await writeDocs(generated, outDir, extracted, docsOptions);
|
|
@@ -12803,7 +13168,7 @@ function oxContent(options = {}) {
|
|
|
12803
13168
|
const docsOptions = resolvedOptions.docs;
|
|
12804
13169
|
if (!docsOptions || !docsOptions.enabled) return;
|
|
12805
13170
|
const root = config?.root || process.cwd();
|
|
12806
|
-
const srcDirs = docsOptions.src.map((src) => path$
|
|
13171
|
+
const srcDirs = docsOptions.src.map((src) => path$2.resolve(root, src));
|
|
12807
13172
|
for (const srcDir of srcDirs) devServer.watcher.add(srcDir);
|
|
12808
13173
|
devServer.watcher.on("all", async (event, file) => {
|
|
12809
13174
|
if (event !== "add" && event !== "change" && event !== "unlink") return;
|
|
@@ -12819,7 +13184,7 @@ function oxContent(options = {}) {
|
|
|
12819
13184
|
configureServer(devServer) {
|
|
12820
13185
|
if (!resolvedOptions.ssg.enabled) return;
|
|
12821
13186
|
const root = config?.root || process.cwd();
|
|
12822
|
-
const srcDir = path$
|
|
13187
|
+
const srcDir = path$2.resolve(root, resolvedOptions.srcDir);
|
|
12823
13188
|
devServer.middlewares.use(createDevServerMiddleware(resolvedOptions, root, ssgDevCache));
|
|
12824
13189
|
devServer.watcher.on("add", (file) => {
|
|
12825
13190
|
if (file.startsWith(srcDir) && file.endsWith(".md")) {
|
|
@@ -12886,7 +13251,7 @@ function oxContent(options = {}) {
|
|
|
12886
13251
|
async buildStart() {
|
|
12887
13252
|
if (!resolvedOptions.search.enabled) return;
|
|
12888
13253
|
const root = config?.root || process.cwd();
|
|
12889
|
-
const srcDir = path$
|
|
13254
|
+
const srcDir = path$2.resolve(root, resolvedOptions.srcDir);
|
|
12890
13255
|
try {
|
|
12891
13256
|
searchIndexJson = await buildSearchIndex(srcDir, resolvedOptions.base);
|
|
12892
13257
|
console.log("[ox-content] Search index built");
|
|
@@ -12897,10 +13262,10 @@ function oxContent(options = {}) {
|
|
|
12897
13262
|
async closeBundle() {
|
|
12898
13263
|
if (!resolvedOptions.search.enabled || !searchIndexJson) return;
|
|
12899
13264
|
const root = config?.root || process.cwd();
|
|
12900
|
-
const outDir = path$
|
|
13265
|
+
const outDir = path$2.resolve(root, resolvedOptions.outDir);
|
|
12901
13266
|
try {
|
|
12902
13267
|
await writeSearchIndex(searchIndexJson, outDir);
|
|
12903
|
-
console.log("[ox-content] Search index written to", path$
|
|
13268
|
+
console.log("[ox-content] Search index written to", path$2.join(outDir, "search-index.json"));
|
|
12904
13269
|
} catch (err) {
|
|
12905
13270
|
console.warn("[ox-content] Failed to write search index:", err);
|
|
12906
13271
|
}
|
|
@@ -12980,6 +13345,6 @@ function generateVirtualModule(path, options) {
|
|
|
12980
13345
|
return "export default {};";
|
|
12981
13346
|
}
|
|
12982
13347
|
//#endregion
|
|
12983
|
-
export { DEFAULT_HTML_TEMPLATE, DefaultTheme, Fragment, buildSearchIndex, buildSsg, clearRenderContext, collectGitHubRepos, collectOgpUrls, createI18nPlugin, createMarkdownEnvironment, createTheme, defaultTheme, defineTheme, each, extractDocs, extractIslandInfo, extractVideoId, fetchOgpData, fetchRepoData, generateFrontmatterTypes, generateHydrationScript, generateMarkdown, generateOgImages, generateTabsCSS, generateTypes, hasIslands, inferType, jsx, jsxs, mergeThemes, mermaidClientScript, oxContent, prefetchGitHubRepos, prefetchOgpData, raw, renderAllPages, renderPage, renderToString, resolveDocsOptions, resolveI18nOptions, resolveOgImageOptions, resolveSearchOptions, resolveSsgOptions, resolveTheme, setRenderContext, transformAllPlugins, transformGitHub, transformIslands, transformMarkdown, transformMermaidStatic, transformOgp, transformTabs, transformYouTube, useIsActive, useNav, usePageProps, useRenderContext, useSiteConfig, when, writeDocs, writeSearchIndex };
|
|
13348
|
+
export { DEFAULT_HTML_TEMPLATE, DefaultTheme, Fragment, buildSearchIndex, buildSsg, clearRenderContext, collectGitHubRepos, collectOgpUrls, createI18nPlugin, createMarkdownEnvironment, createTheme, defaultTheme, defineTheme, each, extractDocs, extractIslandInfo, extractVideoId, fetchOgpData, fetchRepoData, generateFrontmatterTypes, generateHydrationScript, generateMarkdown, generateOgImages, generateTabsCSS, generateTypes, hasIslands, inferType, jsx, jsxs, lintMarkdown, lintMarkdownAsync, lintMarkdownFile, lintMarkdownFiles, mergeThemes, mermaidClientScript, oxContent, prefetchGitHubRepos, prefetchOgpData, raw, renderAllPages, renderPage, renderToString, resolveDocsOptions, resolveI18nOptions, resolveOgImageOptions, resolveSearchOptions, resolveSsgOptions, resolveTheme, setRenderContext, shouldLintMarkdownFile, transformAllPlugins, transformGitHub, transformIslands, transformMarkdown, transformMermaidStatic, transformOgp, transformTabs, transformYouTube, useIsActive, useNav, usePageProps, useRenderContext, useSiteConfig, when, writeDocs, writeSearchIndex };
|
|
12984
13349
|
|
|
12985
13350
|
//# sourceMappingURL=index.mjs.map
|