ardo 3.4.0 → 3.6.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 +1 -1
- package/dist/{DocPage-Dy7OrCP2.js → DocPage-Yt8MMpBg.js} +354 -70
- package/dist/DocPage-Yt8MMpBg.js.map +1 -0
- package/dist/assets/src/ui/components/Accordion.css.ts.vanilla-BPEoNgJt.css +103 -0
- package/dist/assets/src/ui/components/Badge.css.ts.vanilla-D9jsj0rg.css +44 -0
- package/dist/assets/src/ui/components/Card.css.ts.vanilla-CO6uiEzC.css +97 -0
- package/dist/assets/src/ui/components/{CodeBlock.css.ts.vanilla-BxDJ2gKc.css → CodeBlock.css.ts.vanilla-DYyQRTxk.css} +4 -4
- package/dist/assets/src/ui/components/{Container.css.ts.vanilla-CUhRUA9t.css → Container.css.ts.vanilla-B8_jKj0Q.css} +6 -0
- package/dist/assets/src/ui/components/{Features.css.ts.vanilla-ggYasCFy.css → Features.css.ts.vanilla-CcCxB5Q6.css} +1 -1
- package/dist/assets/src/ui/{content.css.ts.vanilla-CJnrOQNh.css → content.css.ts.vanilla-B5a1kmaY.css} +12 -2
- package/dist/assets/src/ui/theme/{dark.css.ts.vanilla-CQef5pk2.css → dark.css.ts.vanilla-yFCWJiX4.css} +4 -0
- package/dist/assets/src/ui/theme/{light.css.ts.vanilla-D8gxaS1c.css → light.css.ts.vanilla-DDKnXFOi.css} +4 -0
- package/dist/{brand-icons-Di8w0Nu9.js → brand-icons-DBTSSnty.js} +1 -1
- package/dist/{brand-icons-Di8w0Nu9.js.map → brand-icons-DBTSSnty.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 +5 -0
- package/dist/config/index.js.map +1 -1
- package/dist/{contract.css-qPyk_asd.d.ts → contract.css-BwTjjNXQ.d.ts} +5 -1
- package/dist/contract.css-BwTjjNXQ.d.ts.map +1 -0
- package/dist/{favicon-Cx-inut3.js → favicon-DN3ymUVm.js} +1 -1
- package/dist/{favicon-Cx-inut3.js.map → favicon-DN3ymUVm.js.map} +1 -1
- package/dist/{generator-CYSyo4Vz.js → generator-Cc4WGRdf.js} +1 -1
- package/dist/{generator-CYSyo4Vz.js.map → generator-Cc4WGRdf.js.map} +1 -1
- package/dist/icons/index.d.ts +5 -6
- package/dist/icons/index.d.ts.map +1 -1
- package/dist/icons/index.js +1 -1
- package/dist/{index-CuMTHUxX.d.ts → index-BSWG2TdH.d.ts} +6 -8
- package/dist/index-BSWG2TdH.d.ts.map +1 -0
- package/dist/{index-BcekgOfA.d.ts → index-Dg1xEJ_Y.d.ts} +132 -45
- package/dist/index-Dg1xEJ_Y.d.ts.map +1 -0
- package/dist/index.d.ts +3 -3
- package/dist/index.js +3 -3
- package/dist/mdx/provider.d.ts +1 -1
- package/dist/mdx/provider.d.ts.map +1 -1
- package/dist/mdx/provider.js +6 -1
- package/dist/mdx/provider.js.map +1 -1
- package/dist/runtime/index.d.ts +2 -2
- package/dist/runtime/index.js +1 -1
- package/dist/{sidebar-utils-C06DJsx4.js → sidebar-utils-tTBVAPLE.js} +1 -1
- package/dist/{sidebar-utils-C06DJsx4.js.map → sidebar-utils-tTBVAPLE.js.map} +1 -1
- package/dist/theme/index.d.ts +9 -1
- package/dist/theme/index.d.ts.map +1 -1
- package/dist/theme/index.js +11 -0
- package/dist/theme/index.js.map +1 -1
- package/dist/typedoc/components/index.d.ts +8 -8
- package/dist/typedoc/components/index.d.ts.map +1 -1
- package/dist/typedoc/components/index.js.map +1 -1
- package/dist/typedoc/index.d.ts +1 -1
- package/dist/typedoc/index.d.ts.map +1 -1
- package/dist/typedoc/index.js +3 -3
- package/dist/typedoc/index.js.map +1 -1
- package/dist/{types-Ck2Vm7NB.d.ts → types-DZKj8kWR.d.ts} +1 -1
- package/dist/types-DZKj8kWR.d.ts.map +1 -0
- package/dist/{types-B75OhnGa.d.ts → types-iGO1oGpR.d.ts} +49 -4
- package/dist/types-iGO1oGpR.d.ts.map +1 -0
- package/dist/ui/index.d.ts +2 -2
- package/dist/ui/index.js +3 -3
- package/dist/ui/styles.css +231 -7
- package/dist/ui/styles.js +8 -6
- package/dist/{ui-AGPGBunC.js → ui-Cs2nhBpA.js} +289 -132
- package/dist/ui-Cs2nhBpA.js.map +1 -0
- package/dist/vite/index.d.ts +1 -1
- package/dist/vite/index.d.ts.map +1 -1
- package/dist/vite/index.js +543 -33
- package/dist/vite/index.js.map +1 -1
- package/package.json +15 -15
- package/dist/DocPage-Dy7OrCP2.js.map +0 -1
- package/dist/contract.css-qPyk_asd.d.ts.map +0 -1
- package/dist/index-BcekgOfA.d.ts.map +0 -1
- package/dist/index-CuMTHUxX.d.ts.map +0 -1
- package/dist/types-B75OhnGa.d.ts.map +0 -1
- package/dist/types-Ck2Vm7NB.d.ts.map +0 -1
- package/dist/ui-AGPGBunC.js.map +0 -1
package/dist/vite/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { defaultMarkdownConfig, resolveConfig } from "../config/index.js";
|
|
2
|
-
import { n as ARDO_FAVICON_SVG } from "../favicon-
|
|
3
|
-
import { n as generateApiDocs } from "../generator-
|
|
2
|
+
import { n as ARDO_FAVICON_SVG } from "../favicon-DN3ymUVm.js";
|
|
3
|
+
import { n as generateApiDocs } from "../generator-Cc4WGRdf.js";
|
|
4
4
|
import path from "node:path";
|
|
5
5
|
import matter from "gray-matter";
|
|
6
6
|
import rehypeStringify from "rehype-stringify";
|
|
@@ -13,7 +13,7 @@ import { visit } from "unist-util-visit";
|
|
|
13
13
|
import { createHighlighter } from "shiki";
|
|
14
14
|
import fs, { readFile } from "node:fs/promises";
|
|
15
15
|
import { vanillaExtractPlugin } from "@vanilla-extract/vite-plugin";
|
|
16
|
-
import
|
|
16
|
+
import fs$1, { existsSync } from "node:fs";
|
|
17
17
|
import { execSync } from "node:child_process";
|
|
18
18
|
import { Resvg } from "@resvg/resvg-js";
|
|
19
19
|
import mdx from "@mdx-js/rollup";
|
|
@@ -84,7 +84,7 @@ function buildCodeBlockHtml(shikiHtml, options) {
|
|
|
84
84
|
}
|
|
85
85
|
function renderTitle(title) {
|
|
86
86
|
if (title == null || title.length === 0) return "";
|
|
87
|
-
return `<div data-title>${escapeHtml(title)}</div>`;
|
|
87
|
+
return `<div data-title>${escapeHtml$1(title)}</div>`;
|
|
88
88
|
}
|
|
89
89
|
function renderCodeLines(params) {
|
|
90
90
|
const { highlightLines, lineNumbers, shikiHtml } = params;
|
|
@@ -128,7 +128,7 @@ function stripTags(html) {
|
|
|
128
128
|
function decodeCommonEntities(text) {
|
|
129
129
|
return text.replaceAll("<", "<").replaceAll(">", ">").replaceAll("&", "&").replaceAll(""", "\"").replaceAll("'", "'");
|
|
130
130
|
}
|
|
131
|
-
function escapeHtml(text) {
|
|
131
|
+
function escapeHtml$1(text) {
|
|
132
132
|
return text.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll("\"", """).replaceAll("'", "'");
|
|
133
133
|
}
|
|
134
134
|
//#endregion
|
|
@@ -224,11 +224,11 @@ function isElementNode(node) {
|
|
|
224
224
|
return isRecord$6(node) && node.type === "element";
|
|
225
225
|
}
|
|
226
226
|
function getMetaString(codeNode) {
|
|
227
|
-
const properties = toRecord(codeNode.properties);
|
|
227
|
+
const properties = toRecord$1(codeNode.properties);
|
|
228
228
|
return typeof properties.metastring === "string" ? properties.metastring : "";
|
|
229
229
|
}
|
|
230
230
|
function getLanguage(codeNode) {
|
|
231
|
-
const languageClass = toClassNameList(toRecord(codeNode.properties).className).find((className) => className.startsWith("language-"));
|
|
231
|
+
const languageClass = toClassNameList(toRecord$1(codeNode.properties).className).find((className) => className.startsWith("language-"));
|
|
232
232
|
return languageClass == null ? "text" : languageClass.replace("language-", "");
|
|
233
233
|
}
|
|
234
234
|
function toClassNameList(className) {
|
|
@@ -257,7 +257,7 @@ function replaceNodeWithShikiContainer(parent, index, innerHtml) {
|
|
|
257
257
|
function hasChildrenArray(value) {
|
|
258
258
|
return isRecord$6(value) && Array.isArray(value.children);
|
|
259
259
|
}
|
|
260
|
-
function toRecord(value) {
|
|
260
|
+
function toRecord$1(value) {
|
|
261
261
|
return isRecord$6(value) ? value : {};
|
|
262
262
|
}
|
|
263
263
|
function isRecord$6(value) {
|
|
@@ -705,6 +705,230 @@ function normalizePath(p) {
|
|
|
705
705
|
return `/${p.replaceAll("\\", "/").replace(/^\/+/u, "")}`;
|
|
706
706
|
}
|
|
707
707
|
//#endregion
|
|
708
|
+
//#region src/vite/build-outputs.ts
|
|
709
|
+
function generateSitemap(entries, config) {
|
|
710
|
+
const sitemapConfig = typeof config.seo.sitemap === "object" ? config.seo.sitemap : {};
|
|
711
|
+
const changefreq = sitemapConfig.changefreq ?? "weekly";
|
|
712
|
+
const priority = sitemapConfig.priority ?? .7;
|
|
713
|
+
return [
|
|
714
|
+
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>",
|
|
715
|
+
"<urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\">",
|
|
716
|
+
...entries.filter((entry) => entry.frontmatter.sitemap !== false).map((entry) => {
|
|
717
|
+
return [
|
|
718
|
+
" <url>",
|
|
719
|
+
` <loc>${escapeXml(toAbsoluteUrl$1(entry.path, config))}</loc>`,
|
|
720
|
+
` <lastmod>${entry.lastmod.toISOString()}</lastmod>`,
|
|
721
|
+
` <changefreq>${changefreq}</changefreq>`,
|
|
722
|
+
` <priority>${priority.toFixed(1)}</priority>`,
|
|
723
|
+
" </url>"
|
|
724
|
+
].join("\n");
|
|
725
|
+
}),
|
|
726
|
+
"</urlset>",
|
|
727
|
+
""
|
|
728
|
+
].join("\n");
|
|
729
|
+
}
|
|
730
|
+
function generateRobots(config) {
|
|
731
|
+
const robotsConfig = typeof config.seo.robots === "object" ? config.seo.robots : {};
|
|
732
|
+
const allowRules = robotsConfig.allow ?? ["/"];
|
|
733
|
+
const disallowRules = robotsConfig.disallow ?? [];
|
|
734
|
+
const lines = ["User-agent: *"];
|
|
735
|
+
for (const rule of allowRules) lines.push(`Allow: ${rule}`);
|
|
736
|
+
for (const rule of disallowRules) lines.push(`Disallow: ${rule}`);
|
|
737
|
+
lines.push(`Sitemap: ${toAbsoluteUrl$1("/sitemap.xml", config)}`);
|
|
738
|
+
return `${lines.join("\n")}\n`;
|
|
739
|
+
}
|
|
740
|
+
function collectRedirects(entries, config) {
|
|
741
|
+
const redirects = [...config.redirects];
|
|
742
|
+
for (const entry of entries) for (const from of entry.frontmatter.redirectFrom ?? []) redirects.push({
|
|
743
|
+
from,
|
|
744
|
+
to: entry.path
|
|
745
|
+
});
|
|
746
|
+
return dedupeRedirects(redirects);
|
|
747
|
+
}
|
|
748
|
+
function generateRedirectHtml(to) {
|
|
749
|
+
const escapedTo = escapeHtml(to);
|
|
750
|
+
return [
|
|
751
|
+
"<!doctype html>",
|
|
752
|
+
"<html lang=\"en\">",
|
|
753
|
+
"<head>",
|
|
754
|
+
" <meta charset=\"utf-8\">",
|
|
755
|
+
` <meta http-equiv="refresh" content="0; url=${escapedTo}">`,
|
|
756
|
+
` <link rel="canonical" href="${escapedTo}">`,
|
|
757
|
+
` <script>location.replace(${JSON.stringify(to)})<\/script>`,
|
|
758
|
+
"</head>",
|
|
759
|
+
`<body><a href="${escapedTo}">Continue</a></body>`,
|
|
760
|
+
"</html>",
|
|
761
|
+
""
|
|
762
|
+
].join("\n");
|
|
763
|
+
}
|
|
764
|
+
function generateNetlifyRedirects(redirects) {
|
|
765
|
+
return `${redirects.map((redirect) => `${redirect.from} ${redirect.to} 301`).join("\n")}\n`;
|
|
766
|
+
}
|
|
767
|
+
function generateVercelRedirects(redirects) {
|
|
768
|
+
return `${JSON.stringify({ redirects: redirects.map((redirect) => ({
|
|
769
|
+
source: redirect.from,
|
|
770
|
+
destination: redirect.to,
|
|
771
|
+
permanent: true
|
|
772
|
+
})) }, null, 2)}\n`;
|
|
773
|
+
}
|
|
774
|
+
function checkInternalLinks(entries, config) {
|
|
775
|
+
if (config.linkCheck.enabled === false) return [];
|
|
776
|
+
const excludedPatterns = config.linkCheck.exclude ?? [];
|
|
777
|
+
const routeMap = new Map(entries.map((entry) => [entry.path, entry]));
|
|
778
|
+
const diagnostics = [];
|
|
779
|
+
for (const entry of entries) diagnostics.push(...checkEntryLinks(entry, {
|
|
780
|
+
config,
|
|
781
|
+
excludedPatterns,
|
|
782
|
+
routeMap
|
|
783
|
+
}));
|
|
784
|
+
return diagnostics;
|
|
785
|
+
}
|
|
786
|
+
function createBuildOutputAssets(entries, config) {
|
|
787
|
+
const assets = [];
|
|
788
|
+
if (shouldEmitSitemap(config)) assets.push({
|
|
789
|
+
fileName: "sitemap.xml",
|
|
790
|
+
source: generateSitemap(entries, config)
|
|
791
|
+
});
|
|
792
|
+
if (shouldEmitRobots(config)) assets.push({
|
|
793
|
+
fileName: "robots.txt",
|
|
794
|
+
source: generateRobots(config)
|
|
795
|
+
});
|
|
796
|
+
const redirects = collectRedirects(entries, config);
|
|
797
|
+
if (redirects.length === 0) return assets;
|
|
798
|
+
assets.push({
|
|
799
|
+
fileName: "_redirects",
|
|
800
|
+
source: generateNetlifyRedirects(redirects)
|
|
801
|
+
});
|
|
802
|
+
assets.push({
|
|
803
|
+
fileName: "vercel.json",
|
|
804
|
+
source: generateVercelRedirects(redirects)
|
|
805
|
+
});
|
|
806
|
+
for (const redirect of redirects) assets.push({
|
|
807
|
+
fileName: toRedirectAssetName(redirect.from),
|
|
808
|
+
source: generateRedirectHtml(redirect.to)
|
|
809
|
+
});
|
|
810
|
+
return assets;
|
|
811
|
+
}
|
|
812
|
+
function formatLinkCheckDiagnostics(diagnostics) {
|
|
813
|
+
return diagnostics.map((diagnostic) => `${diagnostic.filePath}: ${diagnostic.message}`).join("\n");
|
|
814
|
+
}
|
|
815
|
+
function shouldEmitSitemap(config) {
|
|
816
|
+
return config.seo.sitemap !== false;
|
|
817
|
+
}
|
|
818
|
+
function shouldEmitRobots(config) {
|
|
819
|
+
return config.seo.robots !== false;
|
|
820
|
+
}
|
|
821
|
+
function extractInternalLinks(content) {
|
|
822
|
+
const links = /* @__PURE__ */ new Set();
|
|
823
|
+
collectMarkdownLinks(content, links);
|
|
824
|
+
collectJsxHrefLinks(content, links);
|
|
825
|
+
return [...links].filter((link) => link !== "" && !link.startsWith("//"));
|
|
826
|
+
}
|
|
827
|
+
function normalizeInternalPath(hrefPath, currentPath) {
|
|
828
|
+
if (hrefPath === "") return currentPath;
|
|
829
|
+
return hrefPath.length > 1 ? hrefPath.replace(/\/$/u, "") : hrefPath;
|
|
830
|
+
}
|
|
831
|
+
function isExcludedLink(href, patterns) {
|
|
832
|
+
return patterns.some((pattern) => matchesPattern(href, pattern));
|
|
833
|
+
}
|
|
834
|
+
function matchesPattern(value, pattern) {
|
|
835
|
+
if (!pattern.includes("*")) return value === pattern;
|
|
836
|
+
const [prefix = "", suffix = ""] = pattern.split("*");
|
|
837
|
+
return value.startsWith(prefix) && value.endsWith(suffix);
|
|
838
|
+
}
|
|
839
|
+
function checkEntryLinks(entry, context) {
|
|
840
|
+
const diagnostics = [];
|
|
841
|
+
for (const href of extractInternalLinks(entry.content)) {
|
|
842
|
+
const diagnostic = checkSingleLink(entry, href, context);
|
|
843
|
+
if (diagnostic != null) diagnostics.push(diagnostic);
|
|
844
|
+
}
|
|
845
|
+
return diagnostics;
|
|
846
|
+
}
|
|
847
|
+
function checkSingleLink(entry, href, context) {
|
|
848
|
+
if (isExcludedLink(href, context.excludedPatterns)) return null;
|
|
849
|
+
const [targetPath = "", targetAnchor = ""] = href.split("#");
|
|
850
|
+
const normalizedPath = normalizeInternalPath(targetPath, entry.path);
|
|
851
|
+
const targetEntry = context.routeMap.get(normalizedPath);
|
|
852
|
+
if (targetEntry == null) return {
|
|
853
|
+
filePath: entry.filePath,
|
|
854
|
+
href,
|
|
855
|
+
message: `Missing internal route: ${href}`
|
|
856
|
+
};
|
|
857
|
+
if (context.config.linkCheck.checkAnchors !== false && targetAnchor !== "" && !targetEntry.anchors.includes(targetAnchor)) return {
|
|
858
|
+
filePath: entry.filePath,
|
|
859
|
+
href,
|
|
860
|
+
message: `Missing anchor "${targetAnchor}" on ${normalizedPath}`
|
|
861
|
+
};
|
|
862
|
+
return null;
|
|
863
|
+
}
|
|
864
|
+
function collectMarkdownLinks(content, links) {
|
|
865
|
+
let offset = 0;
|
|
866
|
+
while (offset < content.length) {
|
|
867
|
+
const start = content.indexOf("](/", offset);
|
|
868
|
+
if (start === -1) return;
|
|
869
|
+
const hrefStart = start + 2;
|
|
870
|
+
const hrefEnd = content.indexOf(")", hrefStart);
|
|
871
|
+
if (hrefEnd === -1) return;
|
|
872
|
+
links.add(content.slice(hrefStart, hrefEnd));
|
|
873
|
+
offset = hrefEnd + 1;
|
|
874
|
+
}
|
|
875
|
+
}
|
|
876
|
+
function collectJsxHrefLinks(content, links) {
|
|
877
|
+
collectQuotedHrefLinks({
|
|
878
|
+
content,
|
|
879
|
+
links,
|
|
880
|
+
marker: "href=\"/",
|
|
881
|
+
quote: "\""
|
|
882
|
+
});
|
|
883
|
+
collectQuotedHrefLinks({
|
|
884
|
+
content,
|
|
885
|
+
links,
|
|
886
|
+
marker: "href='/",
|
|
887
|
+
quote: "'"
|
|
888
|
+
});
|
|
889
|
+
}
|
|
890
|
+
function collectQuotedHrefLinks({ content, links, marker, quote }) {
|
|
891
|
+
let offset = 0;
|
|
892
|
+
while (offset < content.length) {
|
|
893
|
+
const start = content.indexOf(marker, offset);
|
|
894
|
+
if (start === -1) return;
|
|
895
|
+
const hrefStart = start + marker.length - 1;
|
|
896
|
+
const hrefEnd = content.indexOf(quote, hrefStart);
|
|
897
|
+
if (hrefEnd === -1) return;
|
|
898
|
+
links.add(content.slice(hrefStart, hrefEnd));
|
|
899
|
+
offset = hrefEnd + 1;
|
|
900
|
+
}
|
|
901
|
+
}
|
|
902
|
+
function toRedirectAssetName(from) {
|
|
903
|
+
return `${from.replace(/^\//u, "").replace(/\/$/u, "")}/index.html`;
|
|
904
|
+
}
|
|
905
|
+
function dedupeRedirects(redirects) {
|
|
906
|
+
const seen = /* @__PURE__ */ new Set();
|
|
907
|
+
const deduped = [];
|
|
908
|
+
for (const redirect of redirects) {
|
|
909
|
+
const key = `${redirect.from}\n${redirect.to}`;
|
|
910
|
+
if (!seen.has(key)) {
|
|
911
|
+
seen.add(key);
|
|
912
|
+
deduped.push(redirect);
|
|
913
|
+
}
|
|
914
|
+
}
|
|
915
|
+
return deduped;
|
|
916
|
+
}
|
|
917
|
+
function toAbsoluteUrl$1(routePath, config) {
|
|
918
|
+
const basePath = joinUrlPath(config.base, routePath);
|
|
919
|
+
if (config.siteUrl === "") return basePath;
|
|
920
|
+
return `${config.siteUrl.replace(/\/$/u, "")}${basePath}`;
|
|
921
|
+
}
|
|
922
|
+
function joinUrlPath(basePath, routePath) {
|
|
923
|
+
return `${basePath === "/" ? "" : `/${basePath.replaceAll(/^\/|\/$/gu, "")}`}${routePath === "/" ? "/" : `/${routePath.replaceAll(/^\/|\/$/gu, "")}`}` || "/";
|
|
924
|
+
}
|
|
925
|
+
function escapeXml(value) {
|
|
926
|
+
return value.replaceAll("&", "&").replaceAll("\"", """).replaceAll("'", "'").replaceAll("<", "<").replaceAll(">", ">");
|
|
927
|
+
}
|
|
928
|
+
function escapeHtml(value) {
|
|
929
|
+
return value.replaceAll("&", "&").replaceAll("\"", """).replaceAll("<", "<");
|
|
930
|
+
}
|
|
931
|
+
//#endregion
|
|
708
932
|
//#region src/vite/codeblock-scan.ts
|
|
709
933
|
const OPENING_TAG = "<ArdoCodeBlock";
|
|
710
934
|
const CLOSING_TAG = "</ArdoCodeBlock>";
|
|
@@ -992,7 +1216,7 @@ function findPackageRoot(cwd) {
|
|
|
992
1216
|
while (currentDir !== filesystemRoot) {
|
|
993
1217
|
const parentDir = path.dirname(currentDir);
|
|
994
1218
|
const packageJsonPath = path.join(parentDir, "package.json");
|
|
995
|
-
if (
|
|
1219
|
+
if (fs$1.existsSync(packageJsonPath)) {
|
|
996
1220
|
const relativePath = path.relative(cwd, parentDir);
|
|
997
1221
|
return relativePath === "" ? "." : relativePath;
|
|
998
1222
|
}
|
|
@@ -1028,12 +1252,12 @@ function detectGitHubBasename(cwd) {
|
|
|
1028
1252
|
* Recursively copies files from src to dest, overwriting existing files.
|
|
1029
1253
|
*/
|
|
1030
1254
|
function copyRecursive(src, dest) {
|
|
1031
|
-
if (!
|
|
1032
|
-
|
|
1255
|
+
if (!fs$1.statSync(src).isDirectory()) {
|
|
1256
|
+
fs$1.copyFileSync(src, dest);
|
|
1033
1257
|
return;
|
|
1034
1258
|
}
|
|
1035
|
-
if (!
|
|
1036
|
-
for (const item of
|
|
1259
|
+
if (!fs$1.existsSync(dest)) fs$1.mkdirSync(dest, { recursive: true });
|
|
1260
|
+
for (const item of fs$1.readdirSync(src)) copyRecursive(path.join(src, item), path.join(dest, item));
|
|
1037
1261
|
}
|
|
1038
1262
|
function runGitCommand(cwd, command) {
|
|
1039
1263
|
try {
|
|
@@ -1077,10 +1301,10 @@ function createFlattenPlugin() {
|
|
|
1077
1301
|
if (baseName === "") return;
|
|
1078
1302
|
const buildDir = path.join(process.cwd(), "build", "client");
|
|
1079
1303
|
const nestedDir = path.join(buildDir, baseName);
|
|
1080
|
-
if (!
|
|
1304
|
+
if (!fs$1.existsSync(nestedDir)) return;
|
|
1081
1305
|
console.log(`[ardo] Flattening build/client/${baseName}/ to build/client/ for GitHub Pages`);
|
|
1082
1306
|
copyRecursive(nestedDir, buildDir);
|
|
1083
|
-
|
|
1307
|
+
fs$1.rmSync(nestedDir, {
|
|
1084
1308
|
recursive: true,
|
|
1085
1309
|
force: true
|
|
1086
1310
|
});
|
|
@@ -1097,7 +1321,7 @@ function trimSlashes(value) {
|
|
|
1097
1321
|
}
|
|
1098
1322
|
//#endregion
|
|
1099
1323
|
//#region src/vite/icons.ts
|
|
1100
|
-
const ICON_FILES = new Set([
|
|
1324
|
+
const ICON_FILES = /* @__PURE__ */ new Set([
|
|
1101
1325
|
"favicon.ico",
|
|
1102
1326
|
"icon.svg",
|
|
1103
1327
|
"apple-touch-icon.png"
|
|
@@ -1236,12 +1460,28 @@ function transformMarkdownMeta(code, id, state) {
|
|
|
1236
1460
|
if (!shouldInjectMeta(code, id, state)) return;
|
|
1237
1461
|
const pageTitle = extractFrontmatterValue(code, "title");
|
|
1238
1462
|
if (pageTitle == null || pageTitle === "") return;
|
|
1463
|
+
const siteTitle = state.resolvedConfig?.title ?? "Ardo";
|
|
1464
|
+
const titleSeparator = state.resolvedConfig?.titleSeparator ?? " | ";
|
|
1465
|
+
const siteDescription = state.resolvedConfig?.description ?? "";
|
|
1466
|
+
const description = extractFrontmatterValue(code, "description") ?? siteDescription;
|
|
1239
1467
|
return {
|
|
1240
1468
|
code: `${code}\nexport const meta = () => [${buildMetaEntries({
|
|
1469
|
+
canonical: extractFrontmatterValue(code, "canonical"),
|
|
1241
1470
|
pageTitle,
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1471
|
+
routePath: getRoutePathFromId(id, state.routesDir, state.resolvedConfig?.base ?? "/"),
|
|
1472
|
+
siteMetadata: state.resolvedConfig?.metadata ?? {},
|
|
1473
|
+
siteUrl: state.resolvedConfig?.siteUrl ?? "",
|
|
1474
|
+
siteTitle,
|
|
1475
|
+
titleSeparator,
|
|
1476
|
+
description,
|
|
1477
|
+
ogDescription: extractFrontmatterValue(code, "ogDescription"),
|
|
1478
|
+
ogImage: extractFrontmatterValue(code, "ogImage"),
|
|
1479
|
+
ogTitle: extractFrontmatterValue(code, "ogTitle"),
|
|
1480
|
+
ogType: extractFrontmatterValue(code, "ogType"),
|
|
1481
|
+
twitterCard: extractFrontmatterValue(code, "twitterCard"),
|
|
1482
|
+
twitterDescription: extractFrontmatterValue(code, "twitterDescription"),
|
|
1483
|
+
twitterImage: extractFrontmatterValue(code, "twitterImage"),
|
|
1484
|
+
twitterTitle: extractFrontmatterValue(code, "twitterTitle")
|
|
1245
1485
|
}).join(", ")}];\n`,
|
|
1246
1486
|
map: null
|
|
1247
1487
|
};
|
|
@@ -1250,11 +1490,65 @@ function shouldInjectMeta(code, id, state) {
|
|
|
1250
1490
|
return isMarkdownFile(id) && id.startsWith(state.routesDir) && !hasMetaExport(code);
|
|
1251
1491
|
}
|
|
1252
1492
|
function buildMetaEntries(input) {
|
|
1493
|
+
const meta = resolveSocialMeta(input);
|
|
1494
|
+
return [
|
|
1495
|
+
...buildBaseMetaEntries(meta),
|
|
1496
|
+
...buildOpenGraphMetaEntries(meta),
|
|
1497
|
+
...buildTwitterMetaEntries(meta)
|
|
1498
|
+
];
|
|
1499
|
+
}
|
|
1500
|
+
function resolveSocialMeta(input) {
|
|
1253
1501
|
const fullTitle = `${input.pageTitle}${input.titleSeparator}${input.siteTitle}`;
|
|
1254
|
-
const
|
|
1255
|
-
|
|
1502
|
+
const description = input.description ?? "";
|
|
1503
|
+
const ogTitle = input.ogTitle ?? fullTitle;
|
|
1504
|
+
const ogDescription = input.ogDescription ?? description;
|
|
1505
|
+
const ogImage = toAbsoluteUrl(input.ogImage ?? input.siteMetadata.image, input.siteUrl);
|
|
1506
|
+
return {
|
|
1507
|
+
canonicalUrl: toAbsoluteUrl(input.canonical ?? input.routePath, input.siteUrl),
|
|
1508
|
+
description,
|
|
1509
|
+
fullTitle,
|
|
1510
|
+
ogDescription,
|
|
1511
|
+
ogImage,
|
|
1512
|
+
ogTitle,
|
|
1513
|
+
ogType: input.ogType ?? input.siteMetadata.ogType ?? "article",
|
|
1514
|
+
twitterCard: input.twitterCard ?? input.siteMetadata.twitterCard ?? defaultTwitterCard(ogImage),
|
|
1515
|
+
twitterDescription: input.twitterDescription ?? ogDescription,
|
|
1516
|
+
twitterImage: toAbsoluteUrl(input.twitterImage ?? ogImage, input.siteUrl),
|
|
1517
|
+
twitterSite: input.siteMetadata.twitterSite,
|
|
1518
|
+
twitterTitle: input.twitterTitle ?? ogTitle
|
|
1519
|
+
};
|
|
1520
|
+
}
|
|
1521
|
+
function buildBaseMetaEntries(meta) {
|
|
1522
|
+
const entries = [`{ title: ${JSON.stringify(meta.fullTitle)} }`];
|
|
1523
|
+
if (meta.description !== "") entries.push(`{ name: "description", content: ${JSON.stringify(meta.description)} }`);
|
|
1256
1524
|
return entries;
|
|
1257
1525
|
}
|
|
1526
|
+
function buildOpenGraphMetaEntries(meta) {
|
|
1527
|
+
return [
|
|
1528
|
+
`{ property: "og:title", content: ${JSON.stringify(meta.ogTitle)} }`,
|
|
1529
|
+
...optionalMetaEntry("property", "og:description", meta.ogDescription),
|
|
1530
|
+
`{ property: "og:type", content: ${JSON.stringify(meta.ogType)} }`,
|
|
1531
|
+
...optionalMetaEntry("property", "og:image", meta.ogImage),
|
|
1532
|
+
...optionalCanonicalEntries(meta.canonicalUrl)
|
|
1533
|
+
];
|
|
1534
|
+
}
|
|
1535
|
+
function buildTwitterMetaEntries(meta) {
|
|
1536
|
+
return [
|
|
1537
|
+
`{ name: "twitter:card", content: ${JSON.stringify(meta.twitterCard)} }`,
|
|
1538
|
+
`{ name: "twitter:title", content: ${JSON.stringify(meta.twitterTitle)} }`,
|
|
1539
|
+
...optionalMetaEntry("name", "twitter:description", meta.twitterDescription),
|
|
1540
|
+
...optionalMetaEntry("name", "twitter:image", meta.twitterImage),
|
|
1541
|
+
...optionalMetaEntry("name", "twitter:site", meta.twitterSite)
|
|
1542
|
+
];
|
|
1543
|
+
}
|
|
1544
|
+
function optionalMetaEntry(attribute, key, value) {
|
|
1545
|
+
if (value == null || value === "") return [];
|
|
1546
|
+
return [`{ ${attribute}: ${JSON.stringify(key)}, content: ${JSON.stringify(value)} }`];
|
|
1547
|
+
}
|
|
1548
|
+
function optionalCanonicalEntries(canonicalUrl) {
|
|
1549
|
+
if (canonicalUrl == null) return [];
|
|
1550
|
+
return [`{ tagName: "link", rel: "canonical", href: ${JSON.stringify(canonicalUrl)} }`, `{ property: "og:url", content: ${JSON.stringify(canonicalUrl)} }`];
|
|
1551
|
+
}
|
|
1258
1552
|
function isMarkdownFile(id) {
|
|
1259
1553
|
return id.endsWith(".md") || id.endsWith(".mdx");
|
|
1260
1554
|
}
|
|
@@ -1264,13 +1558,92 @@ function hasMetaExport(code) {
|
|
|
1264
1558
|
function extractFrontmatterValue(code, key) {
|
|
1265
1559
|
const frontmatterStart = code.indexOf("export const frontmatter");
|
|
1266
1560
|
if (frontmatterStart === -1) return;
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
const
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1561
|
+
return findFrontmatterStringValue(code.slice(frontmatterStart), key);
|
|
1562
|
+
}
|
|
1563
|
+
function findFrontmatterStringValue(code, key) {
|
|
1564
|
+
const keyPrefix = `${key}:`;
|
|
1565
|
+
let searchIndex = 0;
|
|
1566
|
+
while (searchIndex < code.length) {
|
|
1567
|
+
const keyIndex = code.indexOf(keyPrefix, searchIndex);
|
|
1568
|
+
if (keyIndex === -1) return;
|
|
1569
|
+
const result = readFrontmatterStringAtKey(code, keyIndex, keyPrefix);
|
|
1570
|
+
if (result.found) return result.value;
|
|
1571
|
+
searchIndex = result.nextIndex;
|
|
1572
|
+
}
|
|
1573
|
+
}
|
|
1574
|
+
function readFrontmatterStringAtKey(code, keyIndex, keyPrefix) {
|
|
1575
|
+
if (!hasFrontmatterKeyBoundary(code, keyIndex)) return {
|
|
1576
|
+
found: false,
|
|
1577
|
+
nextIndex: keyIndex + keyPrefix.length
|
|
1578
|
+
};
|
|
1579
|
+
const valueIndex = skipWhitespace(code, keyIndex + keyPrefix.length);
|
|
1580
|
+
if (code[valueIndex] !== "\"") return {
|
|
1581
|
+
found: false,
|
|
1582
|
+
nextIndex: valueIndex + 1
|
|
1583
|
+
};
|
|
1584
|
+
return {
|
|
1585
|
+
found: true,
|
|
1586
|
+
value: parseQuotedFrontmatterString(code, valueIndex)
|
|
1587
|
+
};
|
|
1588
|
+
}
|
|
1589
|
+
function hasFrontmatterKeyBoundary(code, keyIndex) {
|
|
1590
|
+
if (keyIndex === 0) return true;
|
|
1591
|
+
const previous = code[keyIndex - 1];
|
|
1592
|
+
return previous === "{" || previous === "," || isWhitespace(previous);
|
|
1593
|
+
}
|
|
1594
|
+
function isWhitespace(value) {
|
|
1595
|
+
return value === " " || value === "\n" || value === "\r" || value === " ";
|
|
1596
|
+
}
|
|
1597
|
+
function skipWhitespace(code, startIndex) {
|
|
1598
|
+
let index = startIndex;
|
|
1599
|
+
while (isWhitespace(code[index])) index += 1;
|
|
1600
|
+
return index;
|
|
1601
|
+
}
|
|
1602
|
+
function parseQuotedFrontmatterString(code, quoteIndex) {
|
|
1603
|
+
let index = quoteIndex + 1;
|
|
1604
|
+
let escaped = false;
|
|
1605
|
+
while (index < code.length) {
|
|
1606
|
+
const char = code[index];
|
|
1607
|
+
if (char === "\"" && !escaped) return parseJsonString(code.slice(quoteIndex, index + 1));
|
|
1608
|
+
escaped = char === "\\" && !escaped;
|
|
1609
|
+
if (char !== "\\") escaped = false;
|
|
1610
|
+
index += 1;
|
|
1611
|
+
}
|
|
1612
|
+
}
|
|
1613
|
+
function parseJsonString(value) {
|
|
1614
|
+
try {
|
|
1615
|
+
const parsedValue = JSON.parse(value);
|
|
1616
|
+
return typeof parsedValue === "string" ? parsedValue : void 0;
|
|
1617
|
+
} catch {
|
|
1618
|
+
return;
|
|
1619
|
+
}
|
|
1620
|
+
}
|
|
1621
|
+
function getRoutePathFromId(id, routesDir, base) {
|
|
1622
|
+
const withoutExtension = id.slice(routesDir.length).replaceAll("\\", "/").replace(/^\//u, "").replace(/\.(?:md|mdx)$/u, "");
|
|
1623
|
+
if (withoutExtension === "index" || withoutExtension === "home") return joinBasePath(base, "/");
|
|
1624
|
+
if (withoutExtension.endsWith("/index") || withoutExtension.endsWith("/home")) return joinBasePath(base, `/${withoutExtension.slice(0, withoutExtension.lastIndexOf("/"))}`);
|
|
1625
|
+
return joinBasePath(base, `/${withoutExtension}`);
|
|
1626
|
+
}
|
|
1627
|
+
function joinBasePath(base, routePath) {
|
|
1628
|
+
const trimmedBase = base.trim();
|
|
1629
|
+
if (trimmedBase === "" || trimmedBase === "/") return routePath;
|
|
1630
|
+
return `${trimTrailingSlashes(trimmedBase.startsWith("/") ? trimmedBase : `/${trimmedBase}`)}${routePath.startsWith("/") ? routePath : `/${routePath}`}`;
|
|
1631
|
+
}
|
|
1632
|
+
function toAbsoluteUrl(value, siteUrl) {
|
|
1633
|
+
const trimmedValue = value?.trim();
|
|
1634
|
+
if (trimmedValue == null || trimmedValue === "") return;
|
|
1635
|
+
if (trimmedValue.startsWith("http://") || trimmedValue.startsWith("https://") || trimmedValue.startsWith("//")) return trimmedValue;
|
|
1636
|
+
const normalizedSiteUrl = trimTrailingSlashes(siteUrl.trim());
|
|
1637
|
+
if (normalizedSiteUrl === "") return;
|
|
1638
|
+
return `${normalizedSiteUrl}${trimmedValue.startsWith("/") ? trimmedValue : `/${trimmedValue}`}`;
|
|
1639
|
+
}
|
|
1640
|
+
function trimTrailingSlashes(value) {
|
|
1641
|
+
let end = value.length;
|
|
1642
|
+
while (end > 0 && value[end - 1] === "/") end -= 1;
|
|
1643
|
+
return value.slice(0, end);
|
|
1644
|
+
}
|
|
1645
|
+
function defaultTwitterCard(image) {
|
|
1646
|
+
return image == null ? "summary" : "summary_large_image";
|
|
1274
1647
|
}
|
|
1275
1648
|
//#endregion
|
|
1276
1649
|
//#region src/markdown/remark-callouts.ts
|
|
@@ -2629,7 +3002,7 @@ function isShikiThemeObject(themeConfig) {
|
|
|
2629
3002
|
function readProjectMeta(root) {
|
|
2630
3003
|
const packageJsonPath = path.join(root, "package.json");
|
|
2631
3004
|
try {
|
|
2632
|
-
const rawPackageJson =
|
|
3005
|
+
const rawPackageJson = fs$1.readFileSync(packageJsonPath, "utf8");
|
|
2633
3006
|
const parsedPackageJson = JSON.parse(rawPackageJson);
|
|
2634
3007
|
if (!isPackageJsonShape(parsedPackageJson)) return {};
|
|
2635
3008
|
const repository = extractRepository(parsedPackageJson.repository);
|
|
@@ -2663,6 +3036,122 @@ function isPackageJsonShape(value) {
|
|
|
2663
3036
|
return typeof value === "object" && value != null;
|
|
2664
3037
|
}
|
|
2665
3038
|
//#endregion
|
|
3039
|
+
//#region src/vite/route-manifest.ts
|
|
3040
|
+
async function scanRouteManifest(routesDir) {
|
|
3041
|
+
const entries = [];
|
|
3042
|
+
await scanRouteDirectory(routesDir, routesDir, entries);
|
|
3043
|
+
return entries.sort((left, right) => left.path.localeCompare(right.path));
|
|
3044
|
+
}
|
|
3045
|
+
async function scanRouteDirectory(dir, routesDir, manifestEntries) {
|
|
3046
|
+
let entries;
|
|
3047
|
+
try {
|
|
3048
|
+
entries = await fs.readdir(dir, { withFileTypes: true });
|
|
3049
|
+
} catch {
|
|
3050
|
+
return;
|
|
3051
|
+
}
|
|
3052
|
+
for (const entry of entries) {
|
|
3053
|
+
const fullPath = path.join(dir, entry.name);
|
|
3054
|
+
if (entry.isDirectory()) {
|
|
3055
|
+
await scanRouteDirectory(fullPath, routesDir, manifestEntries);
|
|
3056
|
+
continue;
|
|
3057
|
+
}
|
|
3058
|
+
const manifestEntry = await createManifestEntry(fullPath, routesDir);
|
|
3059
|
+
if (manifestEntry != null) manifestEntries.push(manifestEntry);
|
|
3060
|
+
}
|
|
3061
|
+
}
|
|
3062
|
+
async function createManifestEntry(filePath, routesDir) {
|
|
3063
|
+
const extension = getRouteExtension$1(filePath);
|
|
3064
|
+
if (extension == null || isIgnoredRouteFile$1(path.basename(filePath))) return null;
|
|
3065
|
+
const content = await fs.readFile(filePath, "utf8");
|
|
3066
|
+
const parsed = extension === ".tsx" ? {
|
|
3067
|
+
content,
|
|
3068
|
+
data: {}
|
|
3069
|
+
} : matter(content);
|
|
3070
|
+
const data = toRecord(parsed.data);
|
|
3071
|
+
const stat = await fs.stat(filePath);
|
|
3072
|
+
const relativePath = path.relative(routesDir, filePath);
|
|
3073
|
+
return {
|
|
3074
|
+
anchors: extractAnchors(parsed.content),
|
|
3075
|
+
content: parsed.content,
|
|
3076
|
+
filePath,
|
|
3077
|
+
frontmatter: {
|
|
3078
|
+
redirectFrom: parseRedirectFrom(data.redirectFrom),
|
|
3079
|
+
sitemap: typeof data.sitemap === "boolean" ? data.sitemap : void 0
|
|
3080
|
+
},
|
|
3081
|
+
lastmod: stat.mtime,
|
|
3082
|
+
path: toRoutePath$1(relativePath, extension)
|
|
3083
|
+
};
|
|
3084
|
+
}
|
|
3085
|
+
function getRouteExtension$1(filePath) {
|
|
3086
|
+
if (filePath.endsWith(".mdx")) return ".mdx";
|
|
3087
|
+
if (filePath.endsWith(".md")) return ".md";
|
|
3088
|
+
if (filePath.endsWith(".tsx")) return ".tsx";
|
|
3089
|
+
return null;
|
|
3090
|
+
}
|
|
3091
|
+
function isIgnoredRouteFile$1(entryName) {
|
|
3092
|
+
return entryName === "root.tsx" || entryName.startsWith("_");
|
|
3093
|
+
}
|
|
3094
|
+
function toRoutePath$1(relativePath, extension) {
|
|
3095
|
+
const withoutExtension = relativePath.replaceAll("\\", "/").slice(0, -extension.length);
|
|
3096
|
+
const segments = withoutExtension.split("/");
|
|
3097
|
+
const lastSegment = segments.at(-1);
|
|
3098
|
+
if (lastSegment === "index" || lastSegment === "home") {
|
|
3099
|
+
const parentSegments = segments.slice(0, -1);
|
|
3100
|
+
return parentSegments.length === 0 ? "/" : `/${parentSegments.join("/")}`;
|
|
3101
|
+
}
|
|
3102
|
+
return `/${withoutExtension}`.replaceAll(/\$(\w+)/gu, ":$1");
|
|
3103
|
+
}
|
|
3104
|
+
function parseRedirectFrom(value) {
|
|
3105
|
+
if (typeof value === "string") return [value];
|
|
3106
|
+
if (Array.isArray(value)) {
|
|
3107
|
+
const redirects = value.filter((entry) => typeof entry === "string");
|
|
3108
|
+
return redirects.length === 0 ? void 0 : redirects;
|
|
3109
|
+
}
|
|
3110
|
+
}
|
|
3111
|
+
function extractAnchors(content) {
|
|
3112
|
+
const anchors = /* @__PURE__ */ new Set();
|
|
3113
|
+
for (const line of content.split("\n")) {
|
|
3114
|
+
const headingText = getMarkdownHeadingText(line);
|
|
3115
|
+
if (headingText != null) anchors.add(slugifyHeading(headingText));
|
|
3116
|
+
}
|
|
3117
|
+
return [...anchors];
|
|
3118
|
+
}
|
|
3119
|
+
function getMarkdownHeadingText(line) {
|
|
3120
|
+
const trimmed = line.trimStart();
|
|
3121
|
+
let level = 0;
|
|
3122
|
+
for (const character of trimmed) {
|
|
3123
|
+
if (character !== "#") break;
|
|
3124
|
+
level++;
|
|
3125
|
+
}
|
|
3126
|
+
if (level === 0 || level > 6 || trimmed[level] !== " ") return null;
|
|
3127
|
+
return trimmed.slice(level + 1);
|
|
3128
|
+
}
|
|
3129
|
+
function slugifyHeading(value) {
|
|
3130
|
+
return stripHtmlTags(value).replaceAll(/[`*_~[\]()]/gu, "").trim().toLowerCase().replaceAll(/[^\d\p{Letter}\s-]/gu, "").replaceAll(/\s+/gu, "-");
|
|
3131
|
+
}
|
|
3132
|
+
function stripHtmlTags(value) {
|
|
3133
|
+
let result = "";
|
|
3134
|
+
let isInsideTag = false;
|
|
3135
|
+
for (const character of value) {
|
|
3136
|
+
if (character === "<") {
|
|
3137
|
+
isInsideTag = true;
|
|
3138
|
+
continue;
|
|
3139
|
+
}
|
|
3140
|
+
if (character === ">") {
|
|
3141
|
+
isInsideTag = false;
|
|
3142
|
+
continue;
|
|
3143
|
+
}
|
|
3144
|
+
if (!isInsideTag) result += character;
|
|
3145
|
+
}
|
|
3146
|
+
return result;
|
|
3147
|
+
}
|
|
3148
|
+
function toRecord(value) {
|
|
3149
|
+
if (typeof value !== "object" || value == null || Array.isArray(value)) return {};
|
|
3150
|
+
const record = {};
|
|
3151
|
+
for (const [key, entry] of Object.entries(value)) record[key] = entry;
|
|
3152
|
+
return record;
|
|
3153
|
+
}
|
|
3154
|
+
//#endregion
|
|
2666
3155
|
//#region src/vite/routes-core.ts
|
|
2667
3156
|
function scanRoutesSync(params) {
|
|
2668
3157
|
const { dir, rootDir } = params;
|
|
@@ -2688,7 +3177,7 @@ function scanRoutesSync(params) {
|
|
|
2688
3177
|
}
|
|
2689
3178
|
function readDirectoryEntries(dir) {
|
|
2690
3179
|
try {
|
|
2691
|
-
return
|
|
3180
|
+
return fs$1.readdirSync(dir, { withFileTypes: true });
|
|
2692
3181
|
} catch {
|
|
2693
3182
|
return [];
|
|
2694
3183
|
}
|
|
@@ -2769,13 +3258,13 @@ function writeRoutesFileSync(params) {
|
|
|
2769
3258
|
if (routes.length === 0) return;
|
|
2770
3259
|
const content = generateRoutesFile(routes);
|
|
2771
3260
|
if (!hasRoutesContentChangedSync(routesFilePath, content)) return;
|
|
2772
|
-
|
|
2773
|
-
|
|
3261
|
+
fs$1.mkdirSync(appDir, { recursive: true });
|
|
3262
|
+
fs$1.writeFileSync(routesFilePath, content, "utf8");
|
|
2774
3263
|
console.log(`[ardo] Generated routes.ts with ${routes.length} routes`);
|
|
2775
3264
|
}
|
|
2776
3265
|
function hasRoutesContentChangedSync(routesFilePath, nextContent) {
|
|
2777
3266
|
try {
|
|
2778
|
-
return
|
|
3267
|
+
return fs$1.readFileSync(routesFilePath, "utf8") !== nextContent;
|
|
2779
3268
|
} catch {
|
|
2780
3269
|
return true;
|
|
2781
3270
|
}
|
|
@@ -3225,6 +3714,7 @@ function createMainPlugin(state, options) {
|
|
|
3225
3714
|
});
|
|
3226
3715
|
},
|
|
3227
3716
|
configResolved(config) {
|
|
3717
|
+
state.isSsrBuild = config.build.ssr !== false;
|
|
3228
3718
|
state.routesDir = resolveRoutesDir(config.root, options.routesDirOption);
|
|
3229
3719
|
state.resolvedConfig = resolveArdoConfig(config.root, state.routesDir, options.pressConfig);
|
|
3230
3720
|
},
|
|
@@ -3236,9 +3726,29 @@ function createMainPlugin(state, options) {
|
|
|
3236
3726
|
},
|
|
3237
3727
|
transform(code, id) {
|
|
3238
3728
|
return transformMarkdownMeta(code, id, state);
|
|
3729
|
+
},
|
|
3730
|
+
async generateBundle(outputOptions) {
|
|
3731
|
+
if (state.isSsrBuild || isServerOutput(outputOptions.dir) || state.resolvedConfig == null) return;
|
|
3732
|
+
const manifest = await scanRouteManifest(state.routesDir);
|
|
3733
|
+
reportLinkDiagnostics(this, manifest, state.resolvedConfig);
|
|
3734
|
+
for (const asset of createBuildOutputAssets(manifest, state.resolvedConfig)) this.emitFile({
|
|
3735
|
+
type: "asset",
|
|
3736
|
+
fileName: asset.fileName,
|
|
3737
|
+
source: asset.source
|
|
3738
|
+
});
|
|
3239
3739
|
}
|
|
3240
3740
|
};
|
|
3241
3741
|
}
|
|
3742
|
+
function isServerOutput(outputDir) {
|
|
3743
|
+
return outputDir?.replaceAll("\\", "/").endsWith("/server") === true;
|
|
3744
|
+
}
|
|
3745
|
+
function reportLinkDiagnostics(context, manifest, config) {
|
|
3746
|
+
const diagnostics = checkInternalLinks(manifest, config);
|
|
3747
|
+
if (diagnostics.length === 0) return;
|
|
3748
|
+
const message = `[ardo] Broken internal links found:\n${formatLinkCheckDiagnostics(diagnostics)}`;
|
|
3749
|
+
if (config.linkCheck.level === "error") context.error(message);
|
|
3750
|
+
else context.warn(message);
|
|
3751
|
+
}
|
|
3242
3752
|
function createMainConfig(state, input) {
|
|
3243
3753
|
const { command, githubPages, routesDirOption, userConfig } = input;
|
|
3244
3754
|
const root = userConfig.root ?? process.cwd();
|