ardo 3.2.1 → 3.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/README.md +49 -41
- package/dist/{DocPage-CIBiCAxZ.js → DocPage-Dy7OrCP2.js} +160 -31
- package/dist/DocPage-Dy7OrCP2.js.map +1 -0
- package/dist/assets/src/ui/DocPage.css.ts.vanilla-CWL92vUE.css +117 -0
- package/dist/assets/src/ui/ErrorBoundary.css.ts.vanilla-C4usIU4z.css +112 -0
- package/dist/assets/src/ui/Footer.css.ts.vanilla-DGTyff5Y.css +171 -0
- package/dist/assets/src/ui/{Header.css.ts.vanilla-8QL0Jzgk.css → Header.css.ts.vanilla-DEcLj8r0.css} +53 -27
- package/dist/assets/src/ui/{Layout.css.ts.vanilla-Bpx_-gJt.css → Layout.css.ts.vanilla-ClOa1YZm.css} +6 -10
- package/dist/assets/src/ui/Sidebar.css.ts.vanilla-IxNEQEBv.css +199 -0
- package/dist/assets/src/ui/{Toc.css.ts.vanilla-CYqcWgvD.css → Toc.css.ts.vanilla-CQbpEdTg.css} +9 -21
- package/dist/assets/src/ui/components/{CodeBlock.css.ts.vanilla-lNKqskjQ.css → CodeBlock.css.ts.vanilla-BxDJ2gKc.css} +38 -20
- package/dist/assets/src/ui/components/{CopyButton.css.ts.vanilla-DZZ5jgTM.css → CopyButton.css.ts.vanilla-CO2awD6S.css} +6 -7
- package/dist/assets/src/ui/components/{Features.css.ts.vanilla-D-pNXM9Q.css → Features.css.ts.vanilla-ggYasCFy.css} +7 -3
- package/dist/assets/src/ui/components/HeaderSearch.css.ts.vanilla-KAo_Mlc-.css +68 -0
- package/dist/assets/src/ui/components/{Hero.css.ts.vanilla-DHJVZ6GX.css → Hero.css.ts.vanilla-DY_BH0W6.css} +9 -6
- package/dist/assets/src/ui/components/{Search.css.ts.vanilla-BYpWHzky.css → Search.css.ts.vanilla-NQZH1eLo.css} +19 -7
- package/dist/assets/src/ui/{content.css.ts.vanilla-O_RaSPXm.css → content.css.ts.vanilla-CJnrOQNh.css} +43 -17
- package/dist/assets/src/ui/theme/{dark.css.ts.vanilla-2iJgcpbU.css → dark.css.ts.vanilla-CQef5pk2.css} +32 -28
- package/dist/assets/src/ui/theme/{light.css.ts.vanilla-CwinfWSf.css → light.css.ts.vanilla-D8gxaS1c.css} +32 -28
- package/dist/assets/src/ui/theme/{reset.css.ts.vanilla-0Q3pLjfC.css → reset.css.ts.vanilla-e2dF1d0f.css} +4 -0
- package/dist/{brand-icons-DLJKqTun.js → brand-icons-Di8w0Nu9.js} +1 -1
- package/dist/{brand-icons-DLJKqTun.js.map → brand-icons-Di8w0Nu9.js.map} +1 -1
- package/dist/config/index.d.ts +2 -2
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/index.js +1 -0
- package/dist/config/index.js.map +1 -1
- package/dist/{contract.css-DYvFVCFE.d.ts → contract.css-qPyk_asd.d.ts} +5 -1
- package/dist/contract.css-qPyk_asd.d.ts.map +1 -0
- package/dist/favicon-Cx-inut3.js +7 -0
- package/dist/favicon-Cx-inut3.js.map +1 -0
- package/dist/{generator-DPtRXxM_.js → generator-CYSyo4Vz.js} +7 -6
- package/dist/generator-CYSyo4Vz.js.map +1 -0
- package/dist/icons/index.js +1 -1
- package/dist/{index-BTeHvysI.d.ts → index-BcekgOfA.d.ts} +82 -12
- package/dist/index-BcekgOfA.d.ts.map +1 -0
- package/dist/{index-DySzkJlC.d.ts → index-CuMTHUxX.d.ts} +8 -2
- package/dist/index-CuMTHUxX.d.ts.map +1 -0
- package/dist/index.d.ts +4 -4
- package/dist/index.js +3 -3
- package/dist/mdx/provider.js +1 -1
- package/dist/runtime/index.d.ts +1 -1
- package/dist/runtime/index.js +1 -1
- package/dist/{sidebar-utils-1Skqle1Q.js → sidebar-utils-C06DJsx4.js} +15 -4
- package/dist/sidebar-utils-C06DJsx4.js.map +1 -0
- package/dist/theme/index.d.ts +16 -4
- package/dist/theme/index.d.ts.map +1 -1
- package/dist/theme/index.js +84 -59
- package/dist/theme/index.js.map +1 -1
- package/dist/typedoc/components/index.d.ts +1 -1
- package/dist/typedoc/index.d.ts +1 -1
- package/dist/typedoc/index.d.ts.map +1 -1
- package/dist/typedoc/index.js +1 -1
- package/dist/{types-CTd_mkrv.d.ts → types-B75OhnGa.d.ts} +21 -3
- package/dist/types-B75OhnGa.d.ts.map +1 -0
- package/dist/{types-BCuJBsJu.d.ts → types-Ck2Vm7NB.d.ts} +2 -2
- package/dist/{types-BCuJBsJu.d.ts.map → types-Ck2Vm7NB.d.ts.map} +1 -1
- package/dist/ui/index.d.ts +2 -2
- package/dist/ui/index.js +3 -3
- package/dist/ui/styles.css +704 -382
- package/dist/ui/styles.js +15 -15
- package/dist/{ui-3grzJSsq.js → ui-AGPGBunC.js} +729 -280
- package/dist/ui-AGPGBunC.js.map +1 -0
- package/dist/vite/index.d.ts +18 -2
- package/dist/vite/index.d.ts.map +1 -1
- package/dist/vite/index.js +446 -121
- package/dist/vite/index.js.map +1 -1
- package/package.json +14 -13
- package/dist/DocPage-CIBiCAxZ.js.map +0 -1
- package/dist/assets/src/ui/DocPage.css.ts.vanilla-CXKuz4U-.css +0 -34
- package/dist/assets/src/ui/Footer.css.ts.vanilla-BSzPIPt4.css +0 -100
- package/dist/assets/src/ui/Sidebar.css.ts.vanilla-D70qXTEr.css +0 -115
- package/dist/contract.css-DYvFVCFE.d.ts.map +0 -1
- package/dist/generator-DPtRXxM_.js.map +0 -1
- package/dist/index-BTeHvysI.d.ts.map +0 -1
- package/dist/index-DySzkJlC.d.ts.map +0 -1
- package/dist/sidebar-utils-1Skqle1Q.js.map +0 -1
- package/dist/types-CTd_mkrv.d.ts.map +0 -1
- package/dist/ui-3grzJSsq.js.map +0 -1
package/dist/vite/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { defaultMarkdownConfig, resolveConfig } from "../config/index.js";
|
|
2
|
-
import { n as
|
|
2
|
+
import { n as ARDO_FAVICON_SVG } from "../favicon-Cx-inut3.js";
|
|
3
|
+
import { n as generateApiDocs } from "../generator-CYSyo4Vz.js";
|
|
3
4
|
import path from "node:path";
|
|
4
5
|
import matter from "gray-matter";
|
|
5
6
|
import rehypeStringify from "rehype-stringify";
|
|
@@ -10,10 +11,11 @@ import remarkRehype from "remark-rehype";
|
|
|
10
11
|
import { unified } from "unified";
|
|
11
12
|
import { visit } from "unist-util-visit";
|
|
12
13
|
import { createHighlighter } from "shiki";
|
|
13
|
-
import fs from "node:fs/promises";
|
|
14
|
+
import fs, { readFile } from "node:fs/promises";
|
|
14
15
|
import { vanillaExtractPlugin } from "@vanilla-extract/vite-plugin";
|
|
15
|
-
import fsSync from "node:fs";
|
|
16
|
+
import fsSync, { existsSync } from "node:fs";
|
|
16
17
|
import { execSync } from "node:child_process";
|
|
18
|
+
import { Resvg } from "@resvg/resvg-js";
|
|
17
19
|
import mdx from "@mdx-js/rollup";
|
|
18
20
|
import { reactRouter } from "@react-router/dev/vite";
|
|
19
21
|
import rehypeShiki from "@shikijs/rehype";
|
|
@@ -219,7 +221,7 @@ function getCodeNode(node) {
|
|
|
219
221
|
return firstChild;
|
|
220
222
|
}
|
|
221
223
|
function isElementNode(node) {
|
|
222
|
-
return isRecord$
|
|
224
|
+
return isRecord$6(node) && node.type === "element";
|
|
223
225
|
}
|
|
224
226
|
function getMetaString(codeNode) {
|
|
225
227
|
const properties = toRecord(codeNode.properties);
|
|
@@ -253,12 +255,12 @@ function replaceNodeWithShikiContainer(parent, index, innerHtml) {
|
|
|
253
255
|
};
|
|
254
256
|
}
|
|
255
257
|
function hasChildrenArray(value) {
|
|
256
|
-
return isRecord$
|
|
258
|
+
return isRecord$6(value) && Array.isArray(value.children);
|
|
257
259
|
}
|
|
258
260
|
function toRecord(value) {
|
|
259
|
-
return isRecord$
|
|
261
|
+
return isRecord$6(value) ? value : {};
|
|
260
262
|
}
|
|
261
|
-
function isRecord$
|
|
263
|
+
function isRecord$6(value) {
|
|
262
264
|
return value != null && typeof value === "object";
|
|
263
265
|
}
|
|
264
266
|
//#endregion
|
|
@@ -285,9 +287,9 @@ function ensureNodeData(node) {
|
|
|
285
287
|
return node.data;
|
|
286
288
|
}
|
|
287
289
|
function ensureRecord(value) {
|
|
288
|
-
return isRecord$
|
|
290
|
+
return isRecord$5(value) ? value : {};
|
|
289
291
|
}
|
|
290
|
-
function isRecord$
|
|
292
|
+
function isRecord$5(value) {
|
|
291
293
|
return value != null && typeof value === "object";
|
|
292
294
|
}
|
|
293
295
|
/**
|
|
@@ -321,7 +323,7 @@ function ardoLineTransformer(options = {}) {
|
|
|
321
323
|
};
|
|
322
324
|
}
|
|
323
325
|
function getMetaRaw(meta) {
|
|
324
|
-
if (!isRecord$
|
|
326
|
+
if (!isRecord$5(meta)) return "";
|
|
325
327
|
const raw = meta.__raw;
|
|
326
328
|
return typeof raw === "string" ? raw : "";
|
|
327
329
|
}
|
|
@@ -407,7 +409,7 @@ function remarkExtractToc(options) {
|
|
|
407
409
|
let headingIndex = 0;
|
|
408
410
|
visit(tree, "heading", (node) => {
|
|
409
411
|
if (node.depth < minLevel || node.depth > maxLevel) return;
|
|
410
|
-
const text = getHeadingText$
|
|
412
|
+
const text = getHeadingText$2(node);
|
|
411
413
|
const slug = slugify$1(text);
|
|
412
414
|
const id = slug === "" ? `heading-${headingIndex}` : slug;
|
|
413
415
|
headingIndex++;
|
|
@@ -422,10 +424,10 @@ function remarkExtractToc(options) {
|
|
|
422
424
|
tocExtraction.toc = buildTocTree(headings);
|
|
423
425
|
};
|
|
424
426
|
}
|
|
425
|
-
function getHeadingText$
|
|
427
|
+
function getHeadingText$2(node) {
|
|
426
428
|
const textParts = [];
|
|
427
429
|
function extractText(child) {
|
|
428
|
-
if (!isRecord$
|
|
430
|
+
if (!isRecord$4(child)) return;
|
|
429
431
|
if (child.type === "text") textParts.push(typeof child.value === "string" ? child.value : "");
|
|
430
432
|
else if (child.type === "inlineCode") textParts.push(typeof child.value === "string" ? child.value : "");
|
|
431
433
|
else if (Array.isArray(child.children)) child.children.forEach((nestedChild) => {
|
|
@@ -480,10 +482,10 @@ function buildTocTree(headings) {
|
|
|
480
482
|
function ensureHProperties$1(node) {
|
|
481
483
|
const data = node.data ?? {};
|
|
482
484
|
node.data = data;
|
|
483
|
-
if (!isRecord$
|
|
485
|
+
if (!isRecord$4(data.hProperties)) data.hProperties = {};
|
|
484
486
|
return data.hProperties;
|
|
485
487
|
}
|
|
486
|
-
function isRecord$
|
|
488
|
+
function isRecord$4(value) {
|
|
487
489
|
return value != null && typeof value === "object";
|
|
488
490
|
}
|
|
489
491
|
//#endregion
|
|
@@ -514,9 +516,9 @@ async function transformMarkdownToReact(content, config) {
|
|
|
514
516
|
return transformMarkdown(content, config);
|
|
515
517
|
}
|
|
516
518
|
function readPageFrontmatter(data) {
|
|
517
|
-
return isRecord$
|
|
519
|
+
return isRecord$3(data) ? data : {};
|
|
518
520
|
}
|
|
519
|
-
function isRecord$
|
|
521
|
+
function isRecord$3(value) {
|
|
520
522
|
return value != null && typeof value === "object";
|
|
521
523
|
}
|
|
522
524
|
//#endregion
|
|
@@ -641,7 +643,7 @@ function isMarkdownPage(entryName) {
|
|
|
641
643
|
async function createDirectorySidebarItem(fullPath, relativePath, rootDir) {
|
|
642
644
|
const children = await scanDirectoryForSidebar(fullPath, rootDir);
|
|
643
645
|
if (children.length === 0) return null;
|
|
644
|
-
const metadata = await readDirectoryIndexMetadata(fullPath, relativePath);
|
|
646
|
+
const metadata = await readDirectoryIndexMetadata$1(fullPath, relativePath);
|
|
645
647
|
const title = metadata.title ?? formatTitle$2(path.basename(fullPath));
|
|
646
648
|
return {
|
|
647
649
|
collapsed: false,
|
|
@@ -651,7 +653,7 @@ async function createDirectorySidebarItem(fullPath, relativePath, rootDir) {
|
|
|
651
653
|
text: title
|
|
652
654
|
};
|
|
653
655
|
}
|
|
654
|
-
async function readDirectoryIndexMetadata(fullPath, relativePath) {
|
|
656
|
+
async function readDirectoryIndexMetadata$1(fullPath, relativePath) {
|
|
655
657
|
const frontmatter = await readFrontmatter$1(path.join(fullPath, "index.md"));
|
|
656
658
|
return {
|
|
657
659
|
link: frontmatter == null ? void 0 : normalizePath(relativePath),
|
|
@@ -678,14 +680,14 @@ async function readFrontmatter$1(filePath) {
|
|
|
678
680
|
}
|
|
679
681
|
}
|
|
680
682
|
function toSidebarFrontmatter(data) {
|
|
681
|
-
if (!isRecord$
|
|
683
|
+
if (!isRecord$2(data)) return {};
|
|
682
684
|
return {
|
|
683
685
|
order: typeof data.order === "number" ? data.order : void 0,
|
|
684
686
|
sidebar: typeof data.sidebar === "boolean" ? data.sidebar : void 0,
|
|
685
687
|
title: typeof data.title === "string" ? data.title : void 0
|
|
686
688
|
};
|
|
687
689
|
}
|
|
688
|
-
function isRecord$
|
|
690
|
+
function isRecord$2(value) {
|
|
689
691
|
return value != null && typeof value === "object";
|
|
690
692
|
}
|
|
691
693
|
function sortSidebarItems(items) {
|
|
@@ -1094,6 +1096,228 @@ function trimSlashes(value) {
|
|
|
1094
1096
|
return trimmed;
|
|
1095
1097
|
}
|
|
1096
1098
|
//#endregion
|
|
1099
|
+
//#region src/vite/icons.ts
|
|
1100
|
+
const ICON_FILES = new Set([
|
|
1101
|
+
"favicon.ico",
|
|
1102
|
+
"icon.svg",
|
|
1103
|
+
"apple-touch-icon.png"
|
|
1104
|
+
]);
|
|
1105
|
+
function createIconsPlugin(options) {
|
|
1106
|
+
if (options === false) return [];
|
|
1107
|
+
let config;
|
|
1108
|
+
let assetsPromise;
|
|
1109
|
+
const getAssets = async () => {
|
|
1110
|
+
assetsPromise ??= createIconAssets(config.root, options);
|
|
1111
|
+
return assetsPromise;
|
|
1112
|
+
};
|
|
1113
|
+
return [{
|
|
1114
|
+
name: "ardo:icons",
|
|
1115
|
+
configResolved(resolvedConfig) {
|
|
1116
|
+
config = resolvedConfig;
|
|
1117
|
+
},
|
|
1118
|
+
configureServer(server) {
|
|
1119
|
+
server.middlewares.use((request, response, next) => {
|
|
1120
|
+
serveIconRequest({
|
|
1121
|
+
config,
|
|
1122
|
+
getAssets,
|
|
1123
|
+
response,
|
|
1124
|
+
url: request.url
|
|
1125
|
+
}).then((served) => {
|
|
1126
|
+
if (!served) next();
|
|
1127
|
+
}).catch((error) => {
|
|
1128
|
+
if (error instanceof Error) next(error);
|
|
1129
|
+
else next(new Error(String(error)));
|
|
1130
|
+
});
|
|
1131
|
+
});
|
|
1132
|
+
},
|
|
1133
|
+
async generateBundle() {
|
|
1134
|
+
if (config.build.ssr !== false) return;
|
|
1135
|
+
const assets = await getAssets();
|
|
1136
|
+
for (const asset of assets) {
|
|
1137
|
+
if (hasPublicAsset(config, asset.fileName)) continue;
|
|
1138
|
+
this.emitFile({
|
|
1139
|
+
type: "asset",
|
|
1140
|
+
fileName: asset.fileName,
|
|
1141
|
+
source: asset.source
|
|
1142
|
+
});
|
|
1143
|
+
}
|
|
1144
|
+
}
|
|
1145
|
+
}];
|
|
1146
|
+
}
|
|
1147
|
+
async function serveIconRequest(input) {
|
|
1148
|
+
const { config, getAssets, response, url } = input;
|
|
1149
|
+
const fileName = getIconRequestFileName(url);
|
|
1150
|
+
if (fileName == null || hasPublicAsset(config, fileName)) return false;
|
|
1151
|
+
const asset = (await getAssets()).find((candidate) => candidate.fileName === fileName);
|
|
1152
|
+
if (asset == null) return false;
|
|
1153
|
+
response.statusCode = 200;
|
|
1154
|
+
response.setHeader("Content-Type", asset.contentType);
|
|
1155
|
+
response.setHeader("Cache-Control", "no-cache");
|
|
1156
|
+
response.end(asset.source);
|
|
1157
|
+
return true;
|
|
1158
|
+
}
|
|
1159
|
+
async function createIconAssets(root, options) {
|
|
1160
|
+
const svg = await resolveIconSvg(root, options?.source);
|
|
1161
|
+
const faviconPng = renderPng(svg, 32);
|
|
1162
|
+
const appleTouchIcon = renderPng(svg, 180);
|
|
1163
|
+
return [
|
|
1164
|
+
{
|
|
1165
|
+
fileName: "favicon.ico",
|
|
1166
|
+
contentType: "image/x-icon",
|
|
1167
|
+
source: createIco(faviconPng, 32)
|
|
1168
|
+
},
|
|
1169
|
+
{
|
|
1170
|
+
fileName: "icon.svg",
|
|
1171
|
+
contentType: "image/svg+xml",
|
|
1172
|
+
source: svg
|
|
1173
|
+
},
|
|
1174
|
+
{
|
|
1175
|
+
fileName: "apple-touch-icon.png",
|
|
1176
|
+
contentType: "image/png",
|
|
1177
|
+
source: appleTouchIcon
|
|
1178
|
+
}
|
|
1179
|
+
];
|
|
1180
|
+
}
|
|
1181
|
+
async function resolveIconSvg(root, source) {
|
|
1182
|
+
if (source == null) return ARDO_FAVICON_SVG;
|
|
1183
|
+
const trimmedSource = source.trim();
|
|
1184
|
+
if (trimmedSource.startsWith("<svg")) return trimmedSource;
|
|
1185
|
+
return readFile(path.resolve(root, source), "utf8");
|
|
1186
|
+
}
|
|
1187
|
+
function renderPng(svg, size) {
|
|
1188
|
+
return new Resvg(svg, { fitTo: {
|
|
1189
|
+
mode: "width",
|
|
1190
|
+
value: size
|
|
1191
|
+
} }).render().asPng();
|
|
1192
|
+
}
|
|
1193
|
+
function createIco(png, size) {
|
|
1194
|
+
const imageOffset = 22;
|
|
1195
|
+
const ico = new Uint8Array(imageOffset + png.length);
|
|
1196
|
+
const view = new DataView(ico.buffer);
|
|
1197
|
+
writeIcoHeader(view);
|
|
1198
|
+
writeIcoDirectory({
|
|
1199
|
+
ico,
|
|
1200
|
+
imageOffset,
|
|
1201
|
+
pngLength: png.length,
|
|
1202
|
+
size,
|
|
1203
|
+
view
|
|
1204
|
+
});
|
|
1205
|
+
ico.set(png, imageOffset);
|
|
1206
|
+
return ico;
|
|
1207
|
+
}
|
|
1208
|
+
function writeIcoHeader(view) {
|
|
1209
|
+
view.setUint16(0, 0, true);
|
|
1210
|
+
view.setUint16(2, 1, true);
|
|
1211
|
+
view.setUint16(4, 1, true);
|
|
1212
|
+
}
|
|
1213
|
+
function writeIcoDirectory(input) {
|
|
1214
|
+
const { ico, imageOffset, pngLength, size, view } = input;
|
|
1215
|
+
ico[6] = size >= 256 ? 0 : size;
|
|
1216
|
+
ico[7] = size >= 256 ? 0 : size;
|
|
1217
|
+
ico[8] = 0;
|
|
1218
|
+
ico[9] = 0;
|
|
1219
|
+
view.setUint16(10, 1, true);
|
|
1220
|
+
view.setUint16(12, 32, true);
|
|
1221
|
+
view.setUint32(14, pngLength, true);
|
|
1222
|
+
view.setUint32(18, imageOffset, true);
|
|
1223
|
+
}
|
|
1224
|
+
function getIconRequestFileName(url) {
|
|
1225
|
+
if (url == null) return;
|
|
1226
|
+
const [pathname] = url.split("?", 1);
|
|
1227
|
+
const fileName = pathname.startsWith("/") ? pathname.slice(1) : pathname;
|
|
1228
|
+
return ICON_FILES.has(fileName) ? fileName : void 0;
|
|
1229
|
+
}
|
|
1230
|
+
function hasPublicAsset(config, fileName) {
|
|
1231
|
+
return existsSync(path.join(config.publicDir, fileName));
|
|
1232
|
+
}
|
|
1233
|
+
//#endregion
|
|
1234
|
+
//#region src/vite/markdown-meta.ts
|
|
1235
|
+
function transformMarkdownMeta(code, id, state) {
|
|
1236
|
+
if (!shouldInjectMeta(code, id, state)) return;
|
|
1237
|
+
const pageTitle = extractFrontmatterValue(code, "title");
|
|
1238
|
+
if (pageTitle == null || pageTitle === "") return;
|
|
1239
|
+
return {
|
|
1240
|
+
code: `${code}\nexport const meta = () => [${buildMetaEntries({
|
|
1241
|
+
pageTitle,
|
|
1242
|
+
siteTitle: state.resolvedConfig?.title ?? "Ardo",
|
|
1243
|
+
titleSeparator: state.resolvedConfig?.titleSeparator ?? " | ",
|
|
1244
|
+
description: extractFrontmatterValue(code, "description")
|
|
1245
|
+
}).join(", ")}];\n`,
|
|
1246
|
+
map: null
|
|
1247
|
+
};
|
|
1248
|
+
}
|
|
1249
|
+
function shouldInjectMeta(code, id, state) {
|
|
1250
|
+
return isMarkdownFile(id) && id.startsWith(state.routesDir) && !hasMetaExport(code);
|
|
1251
|
+
}
|
|
1252
|
+
function buildMetaEntries(input) {
|
|
1253
|
+
const fullTitle = `${input.pageTitle}${input.titleSeparator}${input.siteTitle}`;
|
|
1254
|
+
const entries = [`{ title: ${JSON.stringify(fullTitle)} }`];
|
|
1255
|
+
if (input.description != null && input.description !== "") entries.push(`{ name: "description", content: ${JSON.stringify(input.description)} }`);
|
|
1256
|
+
return entries;
|
|
1257
|
+
}
|
|
1258
|
+
function isMarkdownFile(id) {
|
|
1259
|
+
return id.endsWith(".md") || id.endsWith(".mdx");
|
|
1260
|
+
}
|
|
1261
|
+
function hasMetaExport(code) {
|
|
1262
|
+
return code.includes("export const meta") || code.includes("export function meta");
|
|
1263
|
+
}
|
|
1264
|
+
function extractFrontmatterValue(code, key) {
|
|
1265
|
+
const frontmatterStart = code.indexOf("export const frontmatter");
|
|
1266
|
+
if (frontmatterStart === -1) return;
|
|
1267
|
+
const valuePrefix = `${key}: "`;
|
|
1268
|
+
const valueStart = code.indexOf(valuePrefix, frontmatterStart);
|
|
1269
|
+
if (valueStart === -1) return;
|
|
1270
|
+
const startIndex = valueStart + valuePrefix.length;
|
|
1271
|
+
const endIndex = code.indexOf("\"", startIndex);
|
|
1272
|
+
if (endIndex === -1) return;
|
|
1273
|
+
return code.slice(startIndex, endIndex);
|
|
1274
|
+
}
|
|
1275
|
+
//#endregion
|
|
1276
|
+
//#region src/markdown/remark-callouts.ts
|
|
1277
|
+
const TYPE_MAP = {
|
|
1278
|
+
NOTE: "Note",
|
|
1279
|
+
TIP: "Tip",
|
|
1280
|
+
IMPORTANT: "Info",
|
|
1281
|
+
WARNING: "Warning",
|
|
1282
|
+
CAUTION: "Danger"
|
|
1283
|
+
};
|
|
1284
|
+
const ALERT_REGEX = /^\[!(NOTE|TIP|IMPORTANT|WARNING|CAUTION)\][ \t]*\r?\n?/i;
|
|
1285
|
+
function remarkCallouts() {
|
|
1286
|
+
return function(tree) {
|
|
1287
|
+
visit(tree, "blockquote", (node, index, parent) => {
|
|
1288
|
+
if (parent == null || index == null) return;
|
|
1289
|
+
const componentName = extractCalloutType(node);
|
|
1290
|
+
if (componentName == null) return;
|
|
1291
|
+
const replacement = {
|
|
1292
|
+
type: "mdxJsxFlowElement",
|
|
1293
|
+
name: componentName,
|
|
1294
|
+
attributes: [],
|
|
1295
|
+
children: node.children
|
|
1296
|
+
};
|
|
1297
|
+
parent.children[index] = replacement;
|
|
1298
|
+
});
|
|
1299
|
+
};
|
|
1300
|
+
}
|
|
1301
|
+
function extractCalloutType(node) {
|
|
1302
|
+
const firstChild = node.children[0];
|
|
1303
|
+
if (firstChild?.type !== "paragraph") return void 0;
|
|
1304
|
+
const firstParaChild = firstChild.children[0];
|
|
1305
|
+
if (firstParaChild?.type !== "text") return void 0;
|
|
1306
|
+
const match = ALERT_REGEX.exec(firstParaChild.value);
|
|
1307
|
+
if (match === null) return void 0;
|
|
1308
|
+
const calloutName = TYPE_MAP[match[1].toUpperCase()];
|
|
1309
|
+
firstParaChild.value = firstParaChild.value.slice(match[0].length);
|
|
1310
|
+
if (firstParaChild.value === "") {
|
|
1311
|
+
firstChild.children.shift();
|
|
1312
|
+
stripLeadingBreak(firstChild.children);
|
|
1313
|
+
}
|
|
1314
|
+
if (firstChild.children.length === 0) node.children.shift();
|
|
1315
|
+
return calloutName;
|
|
1316
|
+
}
|
|
1317
|
+
function stripLeadingBreak(children) {
|
|
1318
|
+
if (children[0]?.type === "break") children.shift();
|
|
1319
|
+
}
|
|
1320
|
+
//#endregion
|
|
1097
1321
|
//#region ../../node_modules/.pnpm/estree-util-value-to-estree@3.5.0/node_modules/estree-util-value-to-estree/dist/estree-util-value-to-estree.js
|
|
1098
1322
|
/**
|
|
1099
1323
|
* Create an ESTree identifier node for a given name.
|
|
@@ -2128,6 +2352,23 @@ function define(ast, file, variables, options) {
|
|
|
2128
2352
|
}
|
|
2129
2353
|
}
|
|
2130
2354
|
//#endregion
|
|
2355
|
+
//#region src/markdown/remark-mdx-handle.ts
|
|
2356
|
+
function remarkMdxHandle() {
|
|
2357
|
+
return function(tree, file) {
|
|
2358
|
+
const yamlNode = tree.children.find((node) => node.type === "yaml");
|
|
2359
|
+
if (yamlNode === void 0) return;
|
|
2360
|
+
const layout = extractLayoutValue(yamlNode.value);
|
|
2361
|
+
if (layout === void 0) return;
|
|
2362
|
+
define(tree, file, { handle: valueToEstree({ layout }) });
|
|
2363
|
+
};
|
|
2364
|
+
}
|
|
2365
|
+
function extractLayoutValue(yaml) {
|
|
2366
|
+
const match = /^layout:[ \t]+(\S.*)$/m.exec(yaml);
|
|
2367
|
+
if (match === null) return void 0;
|
|
2368
|
+
const raw = match[1].trim().replaceAll(/^["']|["']$/g, "");
|
|
2369
|
+
if (raw === "bare" || raw === "default") return raw;
|
|
2370
|
+
}
|
|
2371
|
+
//#endregion
|
|
2131
2372
|
//#region src/markdown/remark-mdx-toc.ts
|
|
2132
2373
|
function remarkMdxToc(options = {}) {
|
|
2133
2374
|
const { name = "toc", levels = [2, 3] } = options;
|
|
@@ -2137,7 +2378,7 @@ function remarkMdxToc(options = {}) {
|
|
|
2137
2378
|
let headingIndex = 0;
|
|
2138
2379
|
visit(tree, "heading", (node) => {
|
|
2139
2380
|
if (node.depth < minLevel || node.depth > maxLevel) return;
|
|
2140
|
-
const text = getHeadingText(node);
|
|
2381
|
+
const text = getHeadingText$1(node);
|
|
2141
2382
|
const slug = slugify(text);
|
|
2142
2383
|
const id = slug === "" ? `heading-${String(headingIndex)}` : slug;
|
|
2143
2384
|
headingIndex++;
|
|
@@ -2152,10 +2393,10 @@ function remarkMdxToc(options = {}) {
|
|
|
2152
2393
|
define(tree, file, { [name]: valueToEstree(items) });
|
|
2153
2394
|
};
|
|
2154
2395
|
}
|
|
2155
|
-
function getHeadingText(node) {
|
|
2396
|
+
function getHeadingText$1(node) {
|
|
2156
2397
|
const parts = [];
|
|
2157
2398
|
function extract(child) {
|
|
2158
|
-
if (!isRecord(child)) return;
|
|
2399
|
+
if (!isRecord$1(child)) return;
|
|
2159
2400
|
if (child.type === "text" || child.type === "inlineCode") parts.push(typeof child.value === "string" ? child.value : "");
|
|
2160
2401
|
else if (Array.isArray(child.children)) for (const nested of child.children) extract(nested);
|
|
2161
2402
|
}
|
|
@@ -2170,9 +2411,42 @@ function slugify(text) {
|
|
|
2170
2411
|
function ensureHProperties(node) {
|
|
2171
2412
|
const data = node.data ?? {};
|
|
2172
2413
|
node.data = data;
|
|
2173
|
-
if (!isRecord(data.hProperties)) data.hProperties = {};
|
|
2414
|
+
if (!isRecord$1(data.hProperties)) data.hProperties = {};
|
|
2174
2415
|
return data.hProperties;
|
|
2175
2416
|
}
|
|
2417
|
+
function isRecord$1(value) {
|
|
2418
|
+
return value != null && typeof value === "object";
|
|
2419
|
+
}
|
|
2420
|
+
//#endregion
|
|
2421
|
+
//#region src/markdown/remark-strip-frontmatter-h1.ts
|
|
2422
|
+
function remarkStripFrontmatterH1() {
|
|
2423
|
+
return function(tree) {
|
|
2424
|
+
const yamlNode = tree.children.find((node) => node.type === "yaml");
|
|
2425
|
+
if (yamlNode === void 0) return;
|
|
2426
|
+
const title = extractYamlTitle(yamlNode.value);
|
|
2427
|
+
if (title === "") return;
|
|
2428
|
+
const firstH1Index = tree.children.findIndex((node) => node.type === "heading" && node.depth === 1);
|
|
2429
|
+
if (firstH1Index === -1) return;
|
|
2430
|
+
const h1Node = tree.children[firstH1Index];
|
|
2431
|
+
if (h1Node.type !== "heading") return;
|
|
2432
|
+
if (getHeadingText(h1Node).trim() === title) tree.children.splice(firstH1Index, 1);
|
|
2433
|
+
};
|
|
2434
|
+
}
|
|
2435
|
+
function extractYamlTitle(yaml) {
|
|
2436
|
+
const match = /^title:[ \t]+(\S.*)$/m.exec(yaml);
|
|
2437
|
+
if (match === null) return "";
|
|
2438
|
+
return match[1].trim().replaceAll(/^["']|["']$/g, "");
|
|
2439
|
+
}
|
|
2440
|
+
function getHeadingText(node) {
|
|
2441
|
+
const parts = [];
|
|
2442
|
+
function extract(child) {
|
|
2443
|
+
if (!isRecord(child)) return;
|
|
2444
|
+
if (child.type === "text" || child.type === "inlineCode") parts.push(typeof child.value === "string" ? child.value : "");
|
|
2445
|
+
else if (Array.isArray(child.children)) for (const nested of child.children) extract(nested);
|
|
2446
|
+
}
|
|
2447
|
+
for (const child of node.children) extract(child);
|
|
2448
|
+
return parts.join("");
|
|
2449
|
+
}
|
|
2176
2450
|
function isRecord(value) {
|
|
2177
2451
|
return value != null && typeof value === "object";
|
|
2178
2452
|
}
|
|
@@ -2327,8 +2601,11 @@ function createMdxPlugin(markdownConfig) {
|
|
|
2327
2601
|
include: /\.(md|mdx)$/,
|
|
2328
2602
|
remarkPlugins: [
|
|
2329
2603
|
remarkFrontmatter,
|
|
2604
|
+
remarkStripFrontmatterH1,
|
|
2330
2605
|
[remarkMdxFrontmatter, { name: "frontmatter" }],
|
|
2606
|
+
remarkMdxHandle,
|
|
2331
2607
|
remarkGfm,
|
|
2608
|
+
remarkCallouts,
|
|
2332
2609
|
remarkCodeMeta,
|
|
2333
2610
|
[remarkMdxToc, { levels: markdownConfig?.toc?.level ?? [2, 3] }]
|
|
2334
2611
|
],
|
|
@@ -2692,13 +2969,38 @@ function formatTitle$1(name) {
|
|
|
2692
2969
|
}
|
|
2693
2970
|
//#endregion
|
|
2694
2971
|
//#region src/vite/sidebar-index.ts
|
|
2695
|
-
async function generateSidebar$1(routesDir) {
|
|
2972
|
+
async function generateSidebar$1(routesDir, options = {}) {
|
|
2696
2973
|
try {
|
|
2697
|
-
|
|
2974
|
+
const nodes = await scanSidebarDirectory(routesDir, routesDir);
|
|
2975
|
+
sortNodesBySectionOrder(nodes, options.sectionOrder);
|
|
2976
|
+
return nodes.map((node) => stripOrderFromNode(node));
|
|
2698
2977
|
} catch {
|
|
2699
2978
|
return [];
|
|
2700
2979
|
}
|
|
2701
2980
|
}
|
|
2981
|
+
/**
|
|
2982
|
+
* Build one sidebar tree per top-level routes folder.
|
|
2983
|
+
*
|
|
2984
|
+
* The flat `generateSidebar` returns a single nested array — fine for sites
|
|
2985
|
+
* where everything lives in one column. For context-driven sites (Guide vs.
|
|
2986
|
+
* API vs. …) each top-level folder gets its own subtree, keyed by folder
|
|
2987
|
+
* name (`guide`, `api-reference`, …). Top-level files like `home.tsx` are
|
|
2988
|
+
* skipped — they belong to a bare layout, not a sidebar context.
|
|
2989
|
+
*/
|
|
2990
|
+
async function generateContextSidebars(routesDir) {
|
|
2991
|
+
try {
|
|
2992
|
+
const entries = await fs.readdir(routesDir, { withFileTypes: true });
|
|
2993
|
+
const sidebars = {};
|
|
2994
|
+
for (const entry of entries) {
|
|
2995
|
+
if (!entry.isDirectory()) continue;
|
|
2996
|
+
const nodes = await scanSidebarDirectory(path.join(routesDir, entry.name), routesDir);
|
|
2997
|
+
if (nodes.length > 0) sidebars[entry.name] = nodes.map((node) => stripOrderFromNode(node));
|
|
2998
|
+
}
|
|
2999
|
+
return sidebars;
|
|
3000
|
+
} catch {
|
|
3001
|
+
return {};
|
|
3002
|
+
}
|
|
3003
|
+
}
|
|
2702
3004
|
async function scanSidebarDirectory(dir, rootDir) {
|
|
2703
3005
|
const entries = await fs.readdir(dir, { withFileTypes: true });
|
|
2704
3006
|
const nodes = [];
|
|
@@ -2718,32 +3020,68 @@ async function scanSidebarDirectory(dir, rootDir) {
|
|
|
2718
3020
|
}
|
|
2719
3021
|
async function createDirectoryNode(entry, fullPath, rootDir) {
|
|
2720
3022
|
const relativePath = path.relative(rootDir, fullPath);
|
|
3023
|
+
const metadata = await readDirectoryIndexMetadata(fullPath);
|
|
3024
|
+
if (metadata?.sidebar === false) return null;
|
|
3025
|
+
const link = metadata == null ? void 0 : `/${relativePath.replaceAll("\\", "/")}`;
|
|
3026
|
+
if (metadata?.sidebar === "leaf") {
|
|
3027
|
+
if (link === void 0) return null;
|
|
3028
|
+
return {
|
|
3029
|
+
text: metadata.title ?? formatTitle(entry.name),
|
|
3030
|
+
link,
|
|
3031
|
+
order: metadata.order,
|
|
3032
|
+
sectionId: entry.name
|
|
3033
|
+
};
|
|
3034
|
+
}
|
|
2721
3035
|
const children = await scanSidebarDirectory(fullPath, rootDir);
|
|
2722
3036
|
if (children.length === 0) return null;
|
|
2723
|
-
const link = await fileExists(path.join(fullPath, "index.mdx")) ? `/${relativePath.replaceAll("\\", "/")}` : void 0;
|
|
2724
3037
|
return {
|
|
2725
|
-
text: formatTitle(entry.name),
|
|
3038
|
+
text: metadata?.title ?? formatTitle(entry.name),
|
|
2726
3039
|
link,
|
|
2727
|
-
items: children
|
|
3040
|
+
items: children,
|
|
3041
|
+
collapsed: metadata?.collapsed,
|
|
3042
|
+
order: metadata?.order,
|
|
3043
|
+
sectionId: entry.name
|
|
2728
3044
|
};
|
|
2729
3045
|
}
|
|
2730
3046
|
async function createMarkdownNode(entry, fullPath, relativePath) {
|
|
2731
3047
|
if (!isSidebarMarkdownFile(entry.name)) return null;
|
|
2732
3048
|
const extension = entry.name.endsWith(".mdx") ? ".mdx" : ".md";
|
|
2733
3049
|
const frontmatter = readFrontmatter(await fs.readFile(fullPath, "utf8"));
|
|
3050
|
+
if (frontmatter.sidebar === false) return null;
|
|
2734
3051
|
return {
|
|
2735
3052
|
text: frontmatter.title ?? formatTitle(entry.name.replace(extension, "")),
|
|
2736
3053
|
link: `/${relativePath.replace(extension, "").replaceAll("\\", "/")}`,
|
|
2737
|
-
order: frontmatter.order
|
|
3054
|
+
order: frontmatter.order,
|
|
3055
|
+
sectionId: entry.name.replace(extension, "")
|
|
2738
3056
|
};
|
|
2739
3057
|
}
|
|
3058
|
+
async function readDirectoryIndexMetadata(fullPath) {
|
|
3059
|
+
for (const indexFileName of ["index.mdx", "index.md"]) {
|
|
3060
|
+
const metadata = await readFrontmatterFile(path.join(fullPath, indexFileName));
|
|
3061
|
+
if (metadata != null) return metadata;
|
|
3062
|
+
}
|
|
3063
|
+
return null;
|
|
3064
|
+
}
|
|
3065
|
+
async function readFrontmatterFile(filePath) {
|
|
3066
|
+
try {
|
|
3067
|
+
return readFrontmatter(await fs.readFile(filePath, "utf8"));
|
|
3068
|
+
} catch {
|
|
3069
|
+
return null;
|
|
3070
|
+
}
|
|
3071
|
+
}
|
|
2740
3072
|
function readFrontmatter(fileContent) {
|
|
2741
3073
|
const parsed = matter(fileContent);
|
|
2742
3074
|
return {
|
|
2743
3075
|
title: typeof parsed.data.title === "string" ? parsed.data.title : void 0,
|
|
2744
|
-
order: typeof parsed.data.order === "number" ? parsed.data.order : void 0
|
|
3076
|
+
order: typeof parsed.data.order === "number" ? parsed.data.order : void 0,
|
|
3077
|
+
collapsed: typeof parsed.data.collapsed === "boolean" ? parsed.data.collapsed : void 0,
|
|
3078
|
+
sidebar: parseSidebarValue(parsed.data.sidebar)
|
|
2745
3079
|
};
|
|
2746
3080
|
}
|
|
3081
|
+
function parseSidebarValue(raw) {
|
|
3082
|
+
if (typeof raw === "boolean") return raw;
|
|
3083
|
+
if (raw === "leaf") return "leaf";
|
|
3084
|
+
}
|
|
2747
3085
|
function sortNodes(nodes) {
|
|
2748
3086
|
nodes.sort((leftNode, rightNode) => {
|
|
2749
3087
|
if (leftNode.order != null && rightNode.order != null) return leftNode.order - rightNode.order;
|
|
@@ -2752,6 +3090,23 @@ function sortNodes(nodes) {
|
|
|
2752
3090
|
return leftNode.text.localeCompare(rightNode.text);
|
|
2753
3091
|
});
|
|
2754
3092
|
}
|
|
3093
|
+
function sortNodesBySectionOrder(nodes, sectionOrder) {
|
|
3094
|
+
if (sectionOrder == null || sectionOrder.length === 0) return;
|
|
3095
|
+
const sectionOrderMap = /* @__PURE__ */ new Map();
|
|
3096
|
+
for (const [index, section] of sectionOrder.entries()) {
|
|
3097
|
+
const normalizedSection = normalizeSectionId(section);
|
|
3098
|
+
if (normalizedSection !== "" && !sectionOrderMap.has(normalizedSection)) sectionOrderMap.set(normalizedSection, index);
|
|
3099
|
+
}
|
|
3100
|
+
if (sectionOrderMap.size === 0) return;
|
|
3101
|
+
nodes.sort((leftNode, rightNode) => {
|
|
3102
|
+
const leftIndex = sectionOrderMap.get(leftNode.sectionId);
|
|
3103
|
+
const rightIndex = sectionOrderMap.get(rightNode.sectionId);
|
|
3104
|
+
if (leftIndex != null && rightIndex != null) return leftIndex - rightIndex;
|
|
3105
|
+
if (leftIndex != null) return -1;
|
|
3106
|
+
if (rightIndex != null) return 1;
|
|
3107
|
+
return 0;
|
|
3108
|
+
});
|
|
3109
|
+
}
|
|
2755
3110
|
function isSidebarMarkdownFile(fileName) {
|
|
2756
3111
|
return (fileName.endsWith(".mdx") || fileName.endsWith(".md")) && !(fileName === "index.mdx" || fileName === "index.md");
|
|
2757
3112
|
}
|
|
@@ -2762,36 +3117,80 @@ function stripOrderFromNode(node) {
|
|
|
2762
3117
|
return {
|
|
2763
3118
|
text: node.text,
|
|
2764
3119
|
link: node.link,
|
|
3120
|
+
collapsed: node.collapsed,
|
|
2765
3121
|
items: node.items?.map((item) => stripOrderFromNode(item))
|
|
2766
3122
|
};
|
|
2767
3123
|
}
|
|
2768
|
-
|
|
2769
|
-
|
|
2770
|
-
|
|
2771
|
-
|
|
2772
|
-
|
|
2773
|
-
|
|
2774
|
-
|
|
3124
|
+
function normalizeSectionId(section) {
|
|
3125
|
+
const normalizedSection = section.replaceAll("\\", "/");
|
|
3126
|
+
let startIndex = 0;
|
|
3127
|
+
let endIndex = normalizedSection.length;
|
|
3128
|
+
while (startIndex < endIndex && normalizedSection[startIndex] === "/") startIndex += 1;
|
|
3129
|
+
while (endIndex > startIndex && normalizedSection[endIndex - 1] === "/") endIndex -= 1;
|
|
3130
|
+
return normalizedSection.slice(startIndex, endIndex);
|
|
3131
|
+
}
|
|
3132
|
+
//#endregion
|
|
3133
|
+
//#region src/vite/typedoc-plugin.ts
|
|
3134
|
+
let typedocGenerated = false;
|
|
3135
|
+
function resolveTypedocConfig(typedoc) {
|
|
3136
|
+
if (typedoc == null) return;
|
|
3137
|
+
const packageRoot = findPackageRoot(process.cwd());
|
|
3138
|
+
const defaultEntryPoint = packageRoot != null ? `${packageRoot}/src/index.ts` : "./src/index.ts";
|
|
3139
|
+
const defaultTsconfig = packageRoot != null ? `${packageRoot}/tsconfig.json` : "./tsconfig.json";
|
|
3140
|
+
const defaults = {
|
|
3141
|
+
enabled: true,
|
|
3142
|
+
entryPoints: [defaultEntryPoint],
|
|
3143
|
+
tsconfig: defaultTsconfig,
|
|
3144
|
+
out: "api-reference",
|
|
3145
|
+
excludePrivate: true,
|
|
3146
|
+
excludeInternal: true
|
|
3147
|
+
};
|
|
3148
|
+
return typedoc === true ? defaults : {
|
|
3149
|
+
...defaults,
|
|
3150
|
+
...typedoc
|
|
3151
|
+
};
|
|
3152
|
+
}
|
|
3153
|
+
function createTypeDocPlugin(typedocConfig, routesDir) {
|
|
3154
|
+
return {
|
|
3155
|
+
name: "ardo:typedoc",
|
|
3156
|
+
async buildStart() {
|
|
3157
|
+
if (!typedocConfig.enabled || typedocGenerated) return;
|
|
3158
|
+
typedocGenerated = true;
|
|
3159
|
+
console.log("[ardo] Generating API documentation with TypeDoc...");
|
|
3160
|
+
const startTime = Date.now();
|
|
3161
|
+
try {
|
|
3162
|
+
const docs = await generateApiDocs(typedocConfig, routesDir);
|
|
3163
|
+
const duration = Date.now() - startTime;
|
|
3164
|
+
console.log(`[ardo] Generated ${docs.length} API documentation pages in ${duration}ms`);
|
|
3165
|
+
} catch (error) {
|
|
3166
|
+
console.warn("[ardo] TypeDoc generation failed. API documentation will not be available.");
|
|
3167
|
+
console.warn("[ardo] Check your typedoc.entryPoints configuration.");
|
|
3168
|
+
if (error instanceof Error) console.warn(`[ardo] Error: ${error.message}`);
|
|
3169
|
+
}
|
|
3170
|
+
}
|
|
3171
|
+
};
|
|
2775
3172
|
}
|
|
2776
3173
|
//#endregion
|
|
2777
3174
|
//#region src/vite/plugin.ts
|
|
2778
3175
|
const VIRTUAL_MODULE_ID = "virtual:ardo/config";
|
|
2779
3176
|
const VIRTUAL_SIDEBAR_ID = "virtual:ardo/sidebar";
|
|
3177
|
+
const VIRTUAL_SIDEBARS_ID = "virtual:ardo/sidebars";
|
|
2780
3178
|
const VIRTUAL_SEARCH_ID = "virtual:ardo/search-index";
|
|
2781
3179
|
const RESOLVED_IDS = {
|
|
2782
3180
|
[VIRTUAL_MODULE_ID]: `\0${VIRTUAL_MODULE_ID}`,
|
|
2783
3181
|
[VIRTUAL_SIDEBAR_ID]: `\0${VIRTUAL_SIDEBAR_ID}`,
|
|
3182
|
+
[VIRTUAL_SIDEBARS_ID]: `\0${VIRTUAL_SIDEBARS_ID}`,
|
|
2784
3183
|
[VIRTUAL_SEARCH_ID]: `\0${VIRTUAL_SEARCH_ID}`
|
|
2785
3184
|
};
|
|
2786
|
-
let typedocGenerated = false;
|
|
2787
3185
|
function ardoPlugin(options = {}) {
|
|
2788
|
-
const { routes, typedoc, githubPages = true, routesDir: routesDirOption, ...pressConfig } = options;
|
|
3186
|
+
const { icons = {}, routes, typedoc, githubPages = true, routesDir: routesDirOption, ...pressConfig } = options;
|
|
2789
3187
|
const state = { routesDir: resolveRoutesDir(process.cwd(), routesDirOption) };
|
|
2790
3188
|
const plugins = [createMainPlugin(state, {
|
|
2791
3189
|
githubPages,
|
|
2792
3190
|
pressConfig,
|
|
2793
3191
|
routesDirOption
|
|
2794
3192
|
})];
|
|
3193
|
+
plugins.push(...createIconsPlugin(icons));
|
|
2795
3194
|
addRoutesPlugin(plugins, routes, routesDirOption);
|
|
2796
3195
|
addTypeDocPlugin(plugins, typedoc, state);
|
|
2797
3196
|
plugins.push(ardoCodeBlockPlugin(pressConfig.markdown));
|
|
@@ -2811,7 +3210,7 @@ function addRoutesPlugin(plugins, routes, routesDirOption) {
|
|
|
2811
3210
|
}
|
|
2812
3211
|
function addTypeDocPlugin(plugins, typedoc, state) {
|
|
2813
3212
|
const typedocConfig = resolveTypedocConfig(typedoc);
|
|
2814
|
-
if (typedocConfig != null) plugins.unshift(createTypeDocPlugin(typedocConfig, state));
|
|
3213
|
+
if (typedocConfig != null) plugins.unshift(createTypeDocPlugin(typedocConfig, state.routesDir));
|
|
2815
3214
|
}
|
|
2816
3215
|
function createMainPlugin(state, options) {
|
|
2817
3216
|
return {
|
|
@@ -2889,92 +3288,18 @@ async function loadVirtualModule(id, state) {
|
|
|
2889
3288
|
return `export default ${JSON.stringify(clientConfig)}`;
|
|
2890
3289
|
}
|
|
2891
3290
|
if (id === RESOLVED_IDS[VIRTUAL_SIDEBAR_ID]) {
|
|
2892
|
-
const sidebar = await generateSidebar$1(state.routesDir);
|
|
3291
|
+
const sidebar = await generateSidebar$1(state.routesDir, state.resolvedConfig.sidebar);
|
|
2893
3292
|
return `export default ${JSON.stringify(sidebar)}`;
|
|
2894
3293
|
}
|
|
3294
|
+
if (id === RESOLVED_IDS[VIRTUAL_SIDEBARS_ID]) {
|
|
3295
|
+
const sidebars = await generateContextSidebars(state.routesDir);
|
|
3296
|
+
return `export default ${JSON.stringify(sidebars)}`;
|
|
3297
|
+
}
|
|
2895
3298
|
if (id === RESOLVED_IDS[VIRTUAL_SEARCH_ID]) {
|
|
2896
3299
|
const searchIndex = await generateSearchIndex(state.routesDir);
|
|
2897
3300
|
return `export default ${JSON.stringify(searchIndex)}`;
|
|
2898
3301
|
}
|
|
2899
3302
|
}
|
|
2900
|
-
function transformMarkdownMeta(code, id, state) {
|
|
2901
|
-
if (!shouldInjectMeta(code, id, state)) return;
|
|
2902
|
-
const pageTitle = extractFrontmatterValue(code, "title");
|
|
2903
|
-
if (pageTitle == null || pageTitle === "") return;
|
|
2904
|
-
return {
|
|
2905
|
-
code: `${code}\nexport const meta = () => [${buildMetaEntries({
|
|
2906
|
-
pageTitle,
|
|
2907
|
-
siteTitle: state.resolvedConfig?.title ?? "Ardo",
|
|
2908
|
-
titleSeparator: state.resolvedConfig?.titleSeparator ?? " | ",
|
|
2909
|
-
description: extractFrontmatterValue(code, "description")
|
|
2910
|
-
}).join(", ")}];\n`,
|
|
2911
|
-
map: null
|
|
2912
|
-
};
|
|
2913
|
-
}
|
|
2914
|
-
function shouldInjectMeta(code, id, state) {
|
|
2915
|
-
return isMarkdownFile(id) && id.startsWith(state.routesDir) && !hasMetaExport(code);
|
|
2916
|
-
}
|
|
2917
|
-
function buildMetaEntries(input) {
|
|
2918
|
-
const fullTitle = `${input.pageTitle}${input.titleSeparator}${input.siteTitle}`;
|
|
2919
|
-
const entries = [`{ title: ${JSON.stringify(fullTitle)} }`];
|
|
2920
|
-
if (input.description != null && input.description !== "") entries.push(`{ name: "description", content: ${JSON.stringify(input.description)} }`);
|
|
2921
|
-
return entries;
|
|
2922
|
-
}
|
|
2923
|
-
function isMarkdownFile(id) {
|
|
2924
|
-
return id.endsWith(".md") || id.endsWith(".mdx");
|
|
2925
|
-
}
|
|
2926
|
-
function hasMetaExport(code) {
|
|
2927
|
-
return code.includes("export const meta") || code.includes("export function meta");
|
|
2928
|
-
}
|
|
2929
|
-
function extractFrontmatterValue(code, key) {
|
|
2930
|
-
const frontmatterStart = code.indexOf("export const frontmatter");
|
|
2931
|
-
if (frontmatterStart === -1) return;
|
|
2932
|
-
const valuePrefix = `${key}: "`;
|
|
2933
|
-
const valueStart = code.indexOf(valuePrefix, frontmatterStart);
|
|
2934
|
-
if (valueStart === -1) return;
|
|
2935
|
-
const startIndex = valueStart + valuePrefix.length;
|
|
2936
|
-
const endIndex = code.indexOf("\"", startIndex);
|
|
2937
|
-
if (endIndex === -1) return;
|
|
2938
|
-
return code.slice(startIndex, endIndex);
|
|
2939
|
-
}
|
|
2940
|
-
function resolveTypedocConfig(typedoc) {
|
|
2941
|
-
if (typedoc == null) return;
|
|
2942
|
-
const packageRoot = findPackageRoot(process.cwd());
|
|
2943
|
-
const defaultEntryPoint = packageRoot != null ? `${packageRoot}/src/index.ts` : "./src/index.ts";
|
|
2944
|
-
const defaultTsconfig = packageRoot != null ? `${packageRoot}/tsconfig.json` : "./tsconfig.json";
|
|
2945
|
-
const defaults = {
|
|
2946
|
-
enabled: true,
|
|
2947
|
-
entryPoints: [defaultEntryPoint],
|
|
2948
|
-
tsconfig: defaultTsconfig,
|
|
2949
|
-
out: "api-reference",
|
|
2950
|
-
excludePrivate: true,
|
|
2951
|
-
excludeInternal: true
|
|
2952
|
-
};
|
|
2953
|
-
return typedoc === true ? defaults : {
|
|
2954
|
-
...defaults,
|
|
2955
|
-
...typedoc
|
|
2956
|
-
};
|
|
2957
|
-
}
|
|
2958
|
-
function createTypeDocPlugin(typedocConfig, state) {
|
|
2959
|
-
return {
|
|
2960
|
-
name: "ardo:typedoc",
|
|
2961
|
-
async buildStart() {
|
|
2962
|
-
if (!typedocConfig.enabled || typedocGenerated) return;
|
|
2963
|
-
typedocGenerated = true;
|
|
2964
|
-
console.log("[ardo] Generating API documentation with TypeDoc...");
|
|
2965
|
-
const startTime = Date.now();
|
|
2966
|
-
try {
|
|
2967
|
-
const docs = await generateApiDocs(typedocConfig, state.routesDir);
|
|
2968
|
-
const duration = Date.now() - startTime;
|
|
2969
|
-
console.log(`[ardo] Generated ${docs.length} API documentation pages in ${duration}ms`);
|
|
2970
|
-
} catch (error) {
|
|
2971
|
-
console.warn("[ardo] TypeDoc generation failed. API documentation will not be available.");
|
|
2972
|
-
console.warn("[ardo] Check your typedoc.entryPoints configuration.");
|
|
2973
|
-
if (error instanceof Error) console.warn(`[ardo] Error: ${error.message}`);
|
|
2974
|
-
}
|
|
2975
|
-
}
|
|
2976
|
-
};
|
|
2977
|
-
}
|
|
2978
3303
|
function resolveRoutesDir(root, routesDirOption) {
|
|
2979
3304
|
return routesDirOption ?? path.join(root, "app", "routes");
|
|
2980
3305
|
}
|