@thallylabs/migrate 0.2.8 → 0.2.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +27 -0
- package/dist/index.js +589 -82
- package/dist/index.js.map +1 -1
- package/package.json +3 -1
package/dist/index.js
CHANGED
|
@@ -14,7 +14,7 @@ import {
|
|
|
14
14
|
statSync
|
|
15
15
|
} from "fs";
|
|
16
16
|
import { createRequire } from "module";
|
|
17
|
-
import { basename as basename3, dirname as dirname4, extname as extname5, relative as relative5, resolve as resolvePath, sep as sep2 } from "path";
|
|
17
|
+
import { basename as basename3, dirname as dirname4, extname as extname5, isAbsolute as isAbsolute2, relative as relative5, resolve as resolvePath, sep as sep2 } from "path";
|
|
18
18
|
import { parse as parseYaml4 } from "yaml";
|
|
19
19
|
import * as ts2 from "typescript";
|
|
20
20
|
|
|
@@ -54,6 +54,8 @@ function parseFrontmatter(raw) {
|
|
|
54
54
|
|
|
55
55
|
// src/mdx.ts
|
|
56
56
|
import { compileSync } from "@mdx-js/mdx";
|
|
57
|
+
import { nameToEmoji } from "gemoji";
|
|
58
|
+
import remarkGfm from "remark-gfm";
|
|
57
59
|
import remarkMdx from "remark-mdx";
|
|
58
60
|
import remarkParse from "remark-parse";
|
|
59
61
|
import { unified } from "unified";
|
|
@@ -129,7 +131,7 @@ function titleFromId(id) {
|
|
|
129
131
|
if (value === "introduction") return "Introduction";
|
|
130
132
|
return value.split(/[-_]/).filter(Boolean).map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
|
|
131
133
|
}
|
|
132
|
-
var descriptionParser = unified().use(remarkParse).use(remarkMdx);
|
|
134
|
+
var descriptionParser = unified().use(remarkParse).use(remarkGfm).use(remarkMdx);
|
|
133
135
|
function firstParagraph(content) {
|
|
134
136
|
function plainText(node) {
|
|
135
137
|
if (node.type === "text" || node.type === "inlineCode") return node.value ?? "";
|
|
@@ -286,6 +288,20 @@ var SAFE_BUILTIN_ROOTS = /* @__PURE__ */ new Set([
|
|
|
286
288
|
"BigInt",
|
|
287
289
|
"Reflect"
|
|
288
290
|
]);
|
|
291
|
+
function leadingPageHeading(body) {
|
|
292
|
+
try {
|
|
293
|
+
const root = descriptionParser.parse(body);
|
|
294
|
+
const first = root.children?.find((node) => node.type !== "mdxjsEsm" && node.type !== "html");
|
|
295
|
+
if (first?.type !== "heading" || first.depth !== 1) return void 0;
|
|
296
|
+
const text = (node) => node.type === "mdxTextExpression" || node.type === "mdxFlowExpression" ? "" : node.value ?? (node.children ?? []).map(text).join("");
|
|
297
|
+
const title = text(first).replace(/\s+/g, " ").trim();
|
|
298
|
+
const start = first.position?.start.offset;
|
|
299
|
+
const end = first.position?.end.offset;
|
|
300
|
+
return title && start !== void 0 && end !== void 0 ? { title, start, end } : void 0;
|
|
301
|
+
} catch {
|
|
302
|
+
return void 0;
|
|
303
|
+
}
|
|
304
|
+
}
|
|
289
305
|
function collectPatternNames(pattern, names) {
|
|
290
306
|
switch (pattern.type) {
|
|
291
307
|
case "Identifier":
|
|
@@ -999,6 +1015,10 @@ function normalizeMdx(body, platform, unwrapMdxCodeBlocks = true) {
|
|
|
999
1015
|
const sourceBody = runDocusaurus && unwrapMdxCodeBlocks ? unwrapDocusaurusMdxCodeBlocks(body) : body;
|
|
1000
1016
|
let rewritten = normalizeDocusaurusAdmonitions(normalizeExplicitHeadingIds(runFern ? normalizeFernCallouts(sourceBody) : sourceBody));
|
|
1001
1017
|
if (runDocusaurus) {
|
|
1018
|
+
rewritten = replaceOutsideCode(rewritten, (segment) => segment.replace(
|
|
1019
|
+
/:([+\w-]+):/g,
|
|
1020
|
+
(shortcode, name) => nameToEmoji[name] ?? shortcode
|
|
1021
|
+
));
|
|
1002
1022
|
rewritten = normalizeDocusaurusTabBlocks(normalizeDocusaurusTabs(removeGlobalDocusaurusImports(rewritten)));
|
|
1003
1023
|
rewritten = replaceOutsideCode(rewritten, (segment) => segment.replace(
|
|
1004
1024
|
/\bimport\s+([A-Za-z_$][\w$]*)\s+from\s+(['"])(@site\/[^'"]+)\2\s*;?/g,
|
|
@@ -1045,9 +1065,13 @@ function parseMarkdownPage(input) {
|
|
|
1045
1065
|
...input.locale ? { locale: input.locale } : {}
|
|
1046
1066
|
};
|
|
1047
1067
|
const identity = input.resolveIdentity?.(parsed.data, fallbackIdentity) ?? fallbackIdentity;
|
|
1048
|
-
|
|
1068
|
+
let body = normalizeMdx(parsed.content, input.platform).trim();
|
|
1049
1069
|
const keywords = Array.isArray(parsed.data.keywords) ? parsed.data.keywords.filter((value) => typeof value === "string") : [];
|
|
1050
|
-
const
|
|
1070
|
+
const heading = leadingPageHeading(body);
|
|
1071
|
+
const title = typeof parsed.data.title === "string" && parsed.data.title.trim() ? parsed.data.title.trim() : heading?.title ?? titleFromId(identity.navigationId);
|
|
1072
|
+
if (heading && heading.title === title) {
|
|
1073
|
+
body = `${body.slice(0, heading.start)}${body.slice(heading.end)}`.trim();
|
|
1074
|
+
}
|
|
1051
1075
|
const navTitle = typeof parsed.data.sidebarTitle === "string" && parsed.data.sidebarTitle.trim() ? parsed.data.sidebarTitle.trim() : typeof parsed.data.navTitle === "string" && parsed.data.navTitle.trim() ? parsed.data.navTitle.trim() : void 0;
|
|
1052
1076
|
const badge = typeof parsed.data.tag === "string" && parsed.data.tag.trim() ? parsed.data.tag.trim() : typeof parsed.data.badge === "string" && parsed.data.badge.trim() ? parsed.data.badge.trim() : void 0;
|
|
1053
1077
|
const sourceMode = typeof parsed.data.mode === "string" ? parsed.data.mode : void 0;
|
|
@@ -1060,6 +1084,7 @@ function parseMarkdownPage(input) {
|
|
|
1060
1084
|
title,
|
|
1061
1085
|
navTitle,
|
|
1062
1086
|
description,
|
|
1087
|
+
...input.platform === "docusaurus" || input.platform === "fern" ? { descriptionPlacement: "body" } : {},
|
|
1063
1088
|
badge,
|
|
1064
1089
|
keywords,
|
|
1065
1090
|
mode,
|
|
@@ -2770,6 +2795,7 @@ function projectMintlifyNavigation(config, options = {}) {
|
|
|
2770
2795
|
}) : [];
|
|
2771
2796
|
let tabs = [];
|
|
2772
2797
|
let i18n;
|
|
2798
|
+
const localizedNavigation = {};
|
|
2773
2799
|
const projectionTrace = {};
|
|
2774
2800
|
if (languages.length > 0) {
|
|
2775
2801
|
const defaultLanguage = languages.find((entry) => entry.default === true) ?? languages[0];
|
|
@@ -2805,8 +2831,11 @@ function projectMintlifyNavigation(config, options = {}) {
|
|
|
2805
2831
|
if (language === defaultLanguage) {
|
|
2806
2832
|
tabs = languageTabs;
|
|
2807
2833
|
for (const reference of references) defaultPageIds.add(reference.navigationId);
|
|
2834
|
+
} else if (languageTabs.length > 0) {
|
|
2835
|
+
localizedNavigation[locale] = languageTabs;
|
|
2808
2836
|
}
|
|
2809
2837
|
}
|
|
2838
|
+
if (Object.keys(localizedNavigation).length > 0) i18n.navigation = localizedNavigation;
|
|
2810
2839
|
} else {
|
|
2811
2840
|
const context = { references, seenReferences, warnings, warningKeys, pathPrefix: options.pathPrefix };
|
|
2812
2841
|
tabs = convertContainerToTabs(navigation, context, "Documentation", projectionTrace);
|
|
@@ -2964,11 +2993,18 @@ function isDocumentationExtension(filename) {
|
|
|
2964
2993
|
return [".md", ".mdx", ".rst", ".txt"].includes(extname2(filename).toLowerCase());
|
|
2965
2994
|
}
|
|
2966
2995
|
function pruneMissingNavigationPages(config, availableIds) {
|
|
2967
|
-
const pruneNodes = (nodes) =>
|
|
2968
|
-
|
|
2969
|
-
|
|
2970
|
-
|
|
2971
|
-
|
|
2996
|
+
const pruneNodes = (nodes) => {
|
|
2997
|
+
const seenSiblings = /* @__PURE__ */ new Set();
|
|
2998
|
+
return nodes.flatMap((node) => {
|
|
2999
|
+
if (typeof node === "string") {
|
|
3000
|
+
if (!availableIds.has(node) || seenSiblings.has(node)) return [];
|
|
3001
|
+
seenSiblings.add(node);
|
|
3002
|
+
return [node];
|
|
3003
|
+
}
|
|
3004
|
+
const pages = pruneNodes(node.pages);
|
|
3005
|
+
return pages.length > 0 ? [{ ...node, pages }] : [];
|
|
3006
|
+
});
|
|
3007
|
+
};
|
|
2972
3008
|
const tabs = config.tabs.flatMap((tab) => {
|
|
2973
3009
|
const hadPages = (tab.pages?.length ?? 0) > 0 || (tab.groups?.length ?? 0) > 0;
|
|
2974
3010
|
const pages = tab.pages ? pruneNodes(tab.pages) : void 0;
|
|
@@ -3104,7 +3140,12 @@ function rewriteDocusaurusLinks(body, current, descriptors, options = {}) {
|
|
|
3104
3140
|
return line;
|
|
3105
3141
|
}
|
|
3106
3142
|
if (codeFence) return line;
|
|
3107
|
-
return line.replace(/(\]\()([^\s)]+)(?=[\s)]|$)/g, (_match, prefix, target) => `${prefix}${rewriteTarget(target)}`).replace(/(\bhref=")([^"]+)(")/g, (_match, prefix, target, suffix) => `${prefix}${rewriteTarget(target)}${suffix}`)
|
|
3143
|
+
return line.replace(/(\]\()([^\s)]+)(?=[\s)]|$)/g, (_match, prefix, target) => `${prefix}${rewriteTarget(target)}`).replace(/(\bhref=")([^"]+)(")/g, (_match, prefix, target, suffix) => `${prefix}${rewriteTarget(target)}${suffix}`).replace(/^(\s{0,3}\[[^\]]+\]:\s*)(<[^>]+>|\S+)/, (_match, prefix, destination) => {
|
|
3144
|
+
const bracketed = destination.startsWith("<") && destination.endsWith(">");
|
|
3145
|
+
const target = bracketed ? destination.slice(1, -1) : destination;
|
|
3146
|
+
const rewritten = rewriteTarget(target);
|
|
3147
|
+
return `${prefix}${bracketed ? `<${rewritten}>` : rewritten}`;
|
|
3148
|
+
});
|
|
3108
3149
|
}).join("\n");
|
|
3109
3150
|
}
|
|
3110
3151
|
function readDocusaurusSiteOrigin(repositoryRoot) {
|
|
@@ -3279,6 +3320,14 @@ function configuredSidebarPath(repositoryRoot) {
|
|
|
3279
3320
|
const path = resolveWithin(repositoryRoot, filename);
|
|
3280
3321
|
if (!existsSync3(path)) continue;
|
|
3281
3322
|
const source = readBoundedText(path);
|
|
3323
|
+
for (const docs of source.matchAll(/\bdocs\s*:\s*/g)) {
|
|
3324
|
+
const object = matchingObjectLiteral(source, (docs.index ?? 0) + docs[0].length);
|
|
3325
|
+
const candidate2 = object && staticStringField(object, "sidebarPath")?.replace(/^\.\//, "");
|
|
3326
|
+
if (candidate2) {
|
|
3327
|
+
const resolved2 = resolveWithin(repositoryRoot, candidate2);
|
|
3328
|
+
if (existsSync3(resolved2) && lstatSync3(resolved2).isFile()) return candidate2;
|
|
3329
|
+
}
|
|
3330
|
+
}
|
|
3282
3331
|
const match = source.match(/\bsidebarPath\s*:\s*(?:require\.resolve\(\s*)?(['"])([^'"]+)\1/);
|
|
3283
3332
|
if (!match) continue;
|
|
3284
3333
|
const candidate = match[2].replace(/^\.\//, "");
|
|
@@ -3460,15 +3509,156 @@ function readDocusaurusThemeColor(repositoryRoot) {
|
|
|
3460
3509
|
if (lightMode) colors.dark = lightMode;
|
|
3461
3510
|
return Object.keys(colors).length > 0 ? colors : void 0;
|
|
3462
3511
|
}
|
|
3463
|
-
function
|
|
3512
|
+
function propertyStart(source, name) {
|
|
3513
|
+
const pattern = new RegExp(`(?:^|[,{\\n])\\s*["']?${name}["']?\\s*:\\s*`, "m");
|
|
3514
|
+
const match = pattern.exec(source);
|
|
3515
|
+
return match ? match.index + match[0].length : -1;
|
|
3516
|
+
}
|
|
3517
|
+
function staticStringBindings(source) {
|
|
3518
|
+
const bindings = /* @__PURE__ */ new Map();
|
|
3519
|
+
for (const match of source.matchAll(/\bconst\s+([A-Z][A-Z0-9_]*)\s*=\s*((?:"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'))/g)) {
|
|
3520
|
+
try {
|
|
3521
|
+
const value = JSON5.parse(match[2]);
|
|
3522
|
+
if (typeof value === "string") bindings.set(match[1], value);
|
|
3523
|
+
} catch {
|
|
3524
|
+
}
|
|
3525
|
+
}
|
|
3526
|
+
return bindings;
|
|
3527
|
+
}
|
|
3528
|
+
function staticArrayField(source, name) {
|
|
3529
|
+
const start = propertyStart(source, name);
|
|
3530
|
+
return start < 0 ? null : matchingArrayLiteral(source, start);
|
|
3531
|
+
}
|
|
3532
|
+
function staticObjectEntries(array) {
|
|
3533
|
+
if (!array) return [];
|
|
3534
|
+
const entries = [];
|
|
3535
|
+
let afterDelimiter = 1;
|
|
3536
|
+
let quote = "";
|
|
3537
|
+
let lineComment = false;
|
|
3538
|
+
let blockComment = false;
|
|
3539
|
+
for (let index = 1; index < array.length - 1; index++) {
|
|
3540
|
+
const char = array[index];
|
|
3541
|
+
const next = array[index + 1];
|
|
3542
|
+
if (lineComment) {
|
|
3543
|
+
if (char === "\n") lineComment = false;
|
|
3544
|
+
continue;
|
|
3545
|
+
}
|
|
3546
|
+
if (blockComment) {
|
|
3547
|
+
if (char === "*" && next === "/") {
|
|
3548
|
+
blockComment = false;
|
|
3549
|
+
index++;
|
|
3550
|
+
}
|
|
3551
|
+
continue;
|
|
3552
|
+
}
|
|
3553
|
+
if (quote) {
|
|
3554
|
+
if (char === "\\") {
|
|
3555
|
+
index++;
|
|
3556
|
+
continue;
|
|
3557
|
+
}
|
|
3558
|
+
if (char === quote) quote = "";
|
|
3559
|
+
continue;
|
|
3560
|
+
}
|
|
3561
|
+
if (char === "/" && next === "/") {
|
|
3562
|
+
lineComment = true;
|
|
3563
|
+
index++;
|
|
3564
|
+
continue;
|
|
3565
|
+
}
|
|
3566
|
+
if (char === "/" && next === "*") {
|
|
3567
|
+
blockComment = true;
|
|
3568
|
+
index++;
|
|
3569
|
+
continue;
|
|
3570
|
+
}
|
|
3571
|
+
if (char === '"' || char === "'" || char === "`") {
|
|
3572
|
+
quote = char;
|
|
3573
|
+
continue;
|
|
3574
|
+
}
|
|
3575
|
+
if (char === ",") {
|
|
3576
|
+
afterDelimiter = index + 1;
|
|
3577
|
+
continue;
|
|
3578
|
+
}
|
|
3579
|
+
if (char !== "{") continue;
|
|
3580
|
+
const literal = matchingObjectLiteral(array, index);
|
|
3581
|
+
if (!literal) continue;
|
|
3582
|
+
const lead = array.slice(afterDelimiter, index).replace(/\/\*[\s\S]*?\*\/|\/\/[^\n]*/g, "").trim();
|
|
3583
|
+
if (!lead) entries.push(literal);
|
|
3584
|
+
index += literal.length - 1;
|
|
3585
|
+
}
|
|
3586
|
+
return entries;
|
|
3587
|
+
}
|
|
3588
|
+
function staticStringField(source, name, bindings) {
|
|
3589
|
+
const start = propertyStart(source, name);
|
|
3590
|
+
if (start < 0) return void 0;
|
|
3591
|
+
const quoted = source.slice(start).match(/^("(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*')/);
|
|
3592
|
+
if (!quoted) {
|
|
3593
|
+
const binding = source.slice(start).match(/^([A-Z][A-Z0-9_]*)\b/)?.[1];
|
|
3594
|
+
return binding ? bindings?.get(binding) : void 0;
|
|
3595
|
+
}
|
|
3596
|
+
try {
|
|
3597
|
+
const parsed = JSON5.parse(quoted[1]);
|
|
3598
|
+
return typeof parsed === "string" ? parsed : void 0;
|
|
3599
|
+
} catch {
|
|
3600
|
+
return void 0;
|
|
3601
|
+
}
|
|
3602
|
+
}
|
|
3603
|
+
function readDocusaurusSiteSettings(repositoryRoot) {
|
|
3604
|
+
const empty = { docsRouteBasePath: "docs", navbarLinks: [], footerLinks: [] };
|
|
3464
3605
|
const configPath = findDocusaurusConfigPath(repositoryRoot);
|
|
3465
|
-
if (!configPath) return
|
|
3466
|
-
const
|
|
3467
|
-
const
|
|
3468
|
-
const
|
|
3469
|
-
const
|
|
3470
|
-
const
|
|
3471
|
-
|
|
3606
|
+
if (!configPath) return empty;
|
|
3607
|
+
const source = readBoundedText(configPath);
|
|
3608
|
+
const bindings = staticStringBindings(source);
|
|
3609
|
+
const presets = staticArrayField(source, "presets");
|
|
3610
|
+
const classicDocs = presets && [...presets.matchAll(/["']?docs["']?\s*:\s*/g)].map((match) => matchingObjectLiteral(presets, (match.index ?? 0) + match[0].length)).find((object) => Boolean(object));
|
|
3611
|
+
const docsRouteBasePath = classicDocs && staticStringField(classicDocs, "routeBasePath") || "docs";
|
|
3612
|
+
const themeStart = propertyStart(source, "themeConfig");
|
|
3613
|
+
const theme = themeStart < 0 ? null : matchingObjectLiteral(source, themeStart);
|
|
3614
|
+
const navbarStart = theme ? propertyStart(theme, "navbar") : -1;
|
|
3615
|
+
const navbar = navbarStart < 0 ? null : matchingObjectLiteral(theme, navbarStart);
|
|
3616
|
+
const logoStart = navbar ? propertyStart(navbar, "logo") : -1;
|
|
3617
|
+
const logo = logoStart < 0 ? null : matchingObjectLiteral(navbar, logoStart);
|
|
3618
|
+
const footerStart = theme ? propertyStart(theme, "footer") : -1;
|
|
3619
|
+
const footer = footerStart < 0 ? null : matchingObjectLiteral(theme, footerStart);
|
|
3620
|
+
const navbarLinks = navbar ? staticObjectEntries(staticArrayField(navbar, "items")).flatMap((item) => {
|
|
3621
|
+
if (propertyStart(item, "items") >= 0 || propertyStart(item, "dropdownItemsAfter") >= 0) return [];
|
|
3622
|
+
const docsPluginId = staticStringField(item, "docsPluginId", bindings);
|
|
3623
|
+
const href = staticStringField(item, "to", bindings) ?? staticStringField(item, "href", bindings);
|
|
3624
|
+
const docId = staticStringField(item, "docId", bindings);
|
|
3625
|
+
const sidebarId = staticStringField(item, "sidebarId", bindings);
|
|
3626
|
+
const label = staticStringField(item, "label", bindings) ?? staticStringField(item, "aria-label", bindings);
|
|
3627
|
+
return label && (href || docId || sidebarId || docsPluginId) ? [{
|
|
3628
|
+
label,
|
|
3629
|
+
...href ? { href } : {},
|
|
3630
|
+
...docId ? { docId } : {},
|
|
3631
|
+
...sidebarId ? { sidebarId } : {},
|
|
3632
|
+
...docsPluginId ? { docsPluginId } : {}
|
|
3633
|
+
}] : [];
|
|
3634
|
+
}) : [];
|
|
3635
|
+
const footerLinks = footer ? staticObjectEntries(staticArrayField(footer, "links")).flatMap((column) => {
|
|
3636
|
+
const heading = staticStringField(column, "title", bindings);
|
|
3637
|
+
if (!heading) return [];
|
|
3638
|
+
const items = staticObjectEntries(staticArrayField(column, "items")).flatMap((item) => {
|
|
3639
|
+
const href = staticStringField(item, "to", bindings) ?? staticStringField(item, "href", bindings);
|
|
3640
|
+
const label = staticStringField(item, "label", bindings);
|
|
3641
|
+
return label && href ? [{ label, href }] : [];
|
|
3642
|
+
});
|
|
3643
|
+
return items.length > 0 ? [{ heading, items }] : [];
|
|
3644
|
+
}) : [];
|
|
3645
|
+
const copyright = footer && propertyStart(footer, "copyright") >= 0 ? staticStringField(footer, "copyright") ?? footer.slice(propertyStart(footer, "copyright")).match(/^`([^`]+)`/)?.[1]?.replace(/\$\{new Date\(\)\.getFullYear\(\)\}/g, "{year}") : void 0;
|
|
3646
|
+
return {
|
|
3647
|
+
name: staticStringField(source, "title"),
|
|
3648
|
+
description: staticStringField(source, "tagline"),
|
|
3649
|
+
docsRouteBasePath,
|
|
3650
|
+
...logo && staticStringField(logo, "src") ? {
|
|
3651
|
+
logo: {
|
|
3652
|
+
light: staticStringField(logo, "src"),
|
|
3653
|
+
...staticStringField(logo, "srcDark") ? { dark: staticStringField(logo, "srcDark") } : {},
|
|
3654
|
+
showTitle: Boolean(navbar && staticStringField(navbar, "title"))
|
|
3655
|
+
}
|
|
3656
|
+
} : {},
|
|
3657
|
+
...staticStringField(source, "favicon") ? { favicon: staticStringField(source, "favicon") } : {},
|
|
3658
|
+
navbarLinks,
|
|
3659
|
+
footerLinks,
|
|
3660
|
+
...copyright ? { copyright } : {}
|
|
3661
|
+
};
|
|
3472
3662
|
}
|
|
3473
3663
|
function autogeneratedItems(dirName, context) {
|
|
3474
3664
|
const normalizedDir = dirName === "." ? "" : normalizeDocId(dirName);
|
|
@@ -3555,19 +3745,19 @@ function projectDocusaurusNavigation(input) {
|
|
|
3555
3745
|
]]];
|
|
3556
3746
|
const tabs = sidebarEntries.flatMap(([sidebarId, value]) => {
|
|
3557
3747
|
const converted = convertItems(value, context);
|
|
3558
|
-
|
|
3559
|
-
const groups = converted.filter((entry) => typeof entry !== "string");
|
|
3560
|
-
if (loosePages.length > 0) groups.unshift({ group: "Overview", pages: loosePages });
|
|
3561
|
-
if (groups.length === 0) return [];
|
|
3748
|
+
if (converted.length === 0) return [];
|
|
3562
3749
|
return [{
|
|
3563
3750
|
tab: sidebarEntries.length === 1 ? "Documentation" : titleCase2(sidebarId),
|
|
3564
|
-
|
|
3751
|
+
// Docusaurus categories are disclosures, including at the sidebar
|
|
3752
|
+
// root. Keeping them as Thally root nodes preserves their collapsed
|
|
3753
|
+
// state and the authored interleaving of documents and categories.
|
|
3754
|
+
pages: converted
|
|
3565
3755
|
}];
|
|
3566
3756
|
});
|
|
3567
3757
|
const unreferenced = input.descriptors.filter((page) => !context.referencedNavigationIds.has(page.navigationId)).sort(descriptorSort).map((page) => page.navigationId);
|
|
3568
3758
|
if (unreferenced.length > 0) {
|
|
3569
|
-
if (tabs.length === 0) tabs.push({ tab: "Documentation",
|
|
3570
|
-
tabs[0].
|
|
3759
|
+
if (tabs.length === 0) tabs.push({ tab: "Documentation", pages: [] });
|
|
3760
|
+
tabs[0].pages?.push({ group: "Additional", pages: unreferenced });
|
|
3571
3761
|
}
|
|
3572
3762
|
return {
|
|
3573
3763
|
docsConfig: { tabs },
|
|
@@ -3580,8 +3770,35 @@ function projectDocusaurusNavigation(input) {
|
|
|
3580
3770
|
// src/fern.ts
|
|
3581
3771
|
import { existsSync as existsSync4, lstatSync as lstatSync4, readFileSync as readFileSync4, readdirSync } from "fs";
|
|
3582
3772
|
import { basename as basename2, dirname as dirname3, extname as extname4, relative as relative4 } from "path";
|
|
3773
|
+
import { load } from "cheerio";
|
|
3583
3774
|
import { parse as parseYaml3 } from "yaml";
|
|
3584
3775
|
var MAX_CONFIG_BYTES2 = 2e6;
|
|
3776
|
+
function announcementMarkdown(message) {
|
|
3777
|
+
const document = load(message);
|
|
3778
|
+
document("script, style, iframe, object, embed, svg, math").remove();
|
|
3779
|
+
const escapeText = (value) => value.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/([\\`*_\[\]{}()!])/g, "\\$1");
|
|
3780
|
+
const links = /* @__PURE__ */ new Map();
|
|
3781
|
+
document("a").each((index, element) => {
|
|
3782
|
+
const marker = `THALLYANNOUNCEMENTLINK${index}TOKEN`;
|
|
3783
|
+
const label = document(element).text().trim();
|
|
3784
|
+
const rawHref = document(element).attr("href")?.trim() ?? "";
|
|
3785
|
+
let href;
|
|
3786
|
+
if (/^https?:\/\//i.test(rawHref)) {
|
|
3787
|
+
try {
|
|
3788
|
+
href = new URL(rawHref).toString();
|
|
3789
|
+
} catch {
|
|
3790
|
+
}
|
|
3791
|
+
} else if (rawHref.startsWith("/") && !rawHref.startsWith("//") && !/[\\<>\s]/.test(rawHref)) {
|
|
3792
|
+
href = rawHref;
|
|
3793
|
+
}
|
|
3794
|
+
const destination = href?.replace(/\(/g, "%28").replace(/\)/g, "%29");
|
|
3795
|
+
links.set(marker, destination && label ? `[${escapeText(label)}](${destination})` : escapeText(label));
|
|
3796
|
+
document(element).replaceWith(marker);
|
|
3797
|
+
});
|
|
3798
|
+
let text = escapeText(document("body").text());
|
|
3799
|
+
for (const [marker, link] of links) text = text.replaceAll(marker, link);
|
|
3800
|
+
return text.trim();
|
|
3801
|
+
}
|
|
3585
3802
|
function objectValue3(value) {
|
|
3586
3803
|
return value !== null && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
3587
3804
|
}
|
|
@@ -3648,7 +3865,7 @@ function uniqueNavigationId(base, context) {
|
|
|
3648
3865
|
while (context.seenNavigationIds.has(`${base}-${index}`)) index++;
|
|
3649
3866
|
return `${base}-${index}`;
|
|
3650
3867
|
}
|
|
3651
|
-
function registerPageAt(rawPath, base, context) {
|
|
3868
|
+
function registerPageAt(rawPath, base, context, navTitle, hidden = false) {
|
|
3652
3869
|
let sourcePath;
|
|
3653
3870
|
try {
|
|
3654
3871
|
const absolute = resolveWithinRoot(
|
|
@@ -3663,9 +3880,16 @@ function registerPageAt(rawPath, base, context) {
|
|
|
3663
3880
|
}
|
|
3664
3881
|
const navigationId = uniqueNavigationId(base || "introduction", context);
|
|
3665
3882
|
context.seenNavigationIds.add(navigationId);
|
|
3666
|
-
context.
|
|
3883
|
+
const isHidden = hidden || context.hiddenInherited === true;
|
|
3884
|
+
context.descriptors.push({ sourcePath, navigationId, ...navTitle ? { navTitle } : {}, ...isHidden ? { hidden: true } : {} });
|
|
3667
3885
|
const kept = context.sourcePathToNavigationId.get(sourcePath);
|
|
3668
|
-
if (kept)
|
|
3886
|
+
if (kept) {
|
|
3887
|
+
if (!isHidden) {
|
|
3888
|
+
const owner = context.descriptors.find((descriptor) => descriptor.navigationId === kept);
|
|
3889
|
+
if (owner) owner.hidden = false;
|
|
3890
|
+
}
|
|
3891
|
+
return kept;
|
|
3892
|
+
}
|
|
3669
3893
|
context.sourcePathToNavigationId.set(sourcePath, navigationId);
|
|
3670
3894
|
return navigationId;
|
|
3671
3895
|
}
|
|
@@ -3702,8 +3926,11 @@ function registerFolder(object, parentSegments, context) {
|
|
|
3702
3926
|
const stem = basename2(entry.name, extname4(entry.name));
|
|
3703
3927
|
const pageSegment = stem.toLowerCase() === "index" ? null : fernBasicSlug(stem);
|
|
3704
3928
|
const route = [...routeSegments, ...pageSegment ? [pageSegment] : []].join("/");
|
|
3705
|
-
const
|
|
3706
|
-
|
|
3929
|
+
const source = lstatSync4(path).size <= MAX_CONFIG_BYTES2 ? readFileSync4(path, "utf8") : "";
|
|
3930
|
+
const frontmatter = source.match(/^---\r?\n([\s\S]*?)\r?\n---(?:\r?\n|$)/)?.[1] ?? "";
|
|
3931
|
+
const hidden = /^hidden:\s*true\s*$/m.test(frontmatter);
|
|
3932
|
+
const registered = registerPageAt(relative4(context.fernRoot, path), route, { ...context, pathPrefix: "" }, void 0, hidden);
|
|
3933
|
+
if (registered && !hidden && !context.hiddenInherited) pages2.push(registered);
|
|
3707
3934
|
}
|
|
3708
3935
|
}
|
|
3709
3936
|
return pages2;
|
|
@@ -3718,13 +3945,19 @@ function registerPage(object, parentSegments, context) {
|
|
|
3718
3945
|
const label = typeof object.page === "string" && object.page.trim() ? object.page.trim() : "Untitled";
|
|
3719
3946
|
const segment = segmentFor(object, label, context);
|
|
3720
3947
|
const base = [...parentSegments, segment].filter(Boolean).join("/");
|
|
3721
|
-
return registerPageAt(object.path, base, context) || null;
|
|
3948
|
+
return registerPageAt(object.path, base, context, label, object.hidden === true) || null;
|
|
3722
3949
|
}
|
|
3723
3950
|
function convertNode(node, parentSegments, context) {
|
|
3724
3951
|
const object = objectValue3(node);
|
|
3725
3952
|
if (!object) return null;
|
|
3726
|
-
if (typeof object.page === "string")
|
|
3727
|
-
|
|
3953
|
+
if (typeof object.page === "string") {
|
|
3954
|
+
const page = registerPage(object, parentSegments, context);
|
|
3955
|
+
return object.hidden === true || context.hiddenInherited ? null : page;
|
|
3956
|
+
}
|
|
3957
|
+
if (typeof object.folder === "string") {
|
|
3958
|
+
const folder = registerFolder(object, parentSegments, object.hidden === true ? { ...context, hiddenInherited: true } : context);
|
|
3959
|
+
return object.hidden === true || context.hiddenInherited ? null : folder;
|
|
3960
|
+
}
|
|
3728
3961
|
if (typeof object.section === "string") {
|
|
3729
3962
|
const label = object.section;
|
|
3730
3963
|
const segment = segmentFor(object, label, context);
|
|
@@ -3733,15 +3966,16 @@ function convertNode(node, parentSegments, context) {
|
|
|
3733
3966
|
const pages = [];
|
|
3734
3967
|
const hasOwnPath = typeof object.path === "string" && object.path.trim().length > 0;
|
|
3735
3968
|
if (hasOwnPath) {
|
|
3736
|
-
const registered = registerPageAt(object.path, segments.join("/"), context);
|
|
3969
|
+
const registered = registerPageAt(object.path, segments.join("/"), context, label, object.hidden === true);
|
|
3737
3970
|
if (registered) pages.push(registered);
|
|
3738
3971
|
}
|
|
3739
3972
|
for (const child of contents) {
|
|
3740
|
-
const converted = convertNode(child, segments, context);
|
|
3973
|
+
const converted = convertNode(child, segments, object.hidden === true ? { ...context, hiddenInherited: true } : context);
|
|
3741
3974
|
if (converted) pages.push(converted);
|
|
3742
3975
|
}
|
|
3743
3976
|
if (pages.length === 0) return null;
|
|
3744
3977
|
if (!hasOwnPath && segment) addBareRouteRedirect(segments, pages, context);
|
|
3978
|
+
if (object.hidden === true || context.hiddenInherited) return null;
|
|
3745
3979
|
return {
|
|
3746
3980
|
group: label,
|
|
3747
3981
|
...typeof object.icon === "string" ? { icon: object.icon } : {},
|
|
@@ -3766,8 +4000,7 @@ function convertNode(node, parentSegments, context) {
|
|
|
3766
4000
|
return null;
|
|
3767
4001
|
}
|
|
3768
4002
|
if (typeof object.changelog === "string") {
|
|
3769
|
-
|
|
3770
|
-
return null;
|
|
4003
|
+
return registerFolder({ folder: object.changelog, title: "Changelog", "skip-slug": true }, parentSegments, context);
|
|
3771
4004
|
}
|
|
3772
4005
|
return null;
|
|
3773
4006
|
}
|
|
@@ -3840,6 +4073,43 @@ function buildTabsFromConfig(rawConfig, configDir, fernRoot, routePrefix, fallba
|
|
|
3840
4073
|
for (let index = sectionsBefore; index < context.apiSections.length; index += 1) {
|
|
3841
4074
|
context.apiSections[index].tabLabel ??= label;
|
|
3842
4075
|
}
|
|
4076
|
+
if (groups.length === 0 && typeof meta.href === "string" && /^https?:\/\//i.test(meta.href)) {
|
|
4077
|
+
return [{ tab: label, href: meta.href }];
|
|
4078
|
+
}
|
|
4079
|
+
if (groups.length === 0 && typeof meta.changelog === "string") {
|
|
4080
|
+
const changelog = registerFolder({ folder: meta.changelog, title: label, "skip-slug": true }, segments, context);
|
|
4081
|
+
if (changelog) {
|
|
4082
|
+
const indexRoute = segments.join("/");
|
|
4083
|
+
const descriptors = new Map(context.descriptors.map((descriptor) => [descriptor.navigationId, descriptor]));
|
|
4084
|
+
const visiblePages = changelog.pages.filter((page) => typeof page === "string").filter((page) => !descriptors.get(page)?.hidden);
|
|
4085
|
+
const index = visiblePages.find((page) => {
|
|
4086
|
+
const descriptor = descriptors.get(page);
|
|
4087
|
+
if (!descriptor) return false;
|
|
4088
|
+
const stem = basename2(descriptor.sourcePath, extname4(descriptor.sourcePath));
|
|
4089
|
+
return page === indexRoute || stem === "overview" || stem === "index";
|
|
4090
|
+
});
|
|
4091
|
+
const entries = visiblePages.filter((page) => page !== index).sort((left, right) => {
|
|
4092
|
+
const date = (page) => descriptors.get(page)?.sourcePath.match(/\d{4}-\d{2}-\d{2}/)?.[0] ?? "";
|
|
4093
|
+
return date(right).localeCompare(date(left)) || left.localeCompare(right);
|
|
4094
|
+
});
|
|
4095
|
+
for (const entryId of entries) {
|
|
4096
|
+
const descriptor = descriptors.get(entryId);
|
|
4097
|
+
if (descriptor) descriptor.hidden = true;
|
|
4098
|
+
}
|
|
4099
|
+
changelog.pages = [index ?? indexRoute];
|
|
4100
|
+
context.changelogIndexes.push({ route: indexRoute, entries });
|
|
4101
|
+
const latest = index ?? firstLeafId(changelog.pages);
|
|
4102
|
+
const bareRouteIndex = context.bareRouteRedirects.findIndex((redirect) => redirect.source === `/${indexRoute}`);
|
|
4103
|
+
const indexDescriptor = index ? descriptors.get(index) : void 0;
|
|
4104
|
+
const indexSource = indexDescriptor && lstatSync4(resolveWithinRoot(context.fernRoot, indexDescriptor.sourcePath, context.repositoryRoot)).size <= MAX_CONFIG_BYTES2 ? readFileSync4(resolveWithinRoot(context.fernRoot, indexDescriptor.sourcePath, context.repositoryRoot), "utf8") : "";
|
|
4105
|
+
const indexFrontmatter = indexSource.match(/^---\r?\n([\s\S]*?)\r?\n---(?:\r?\n|$)/)?.[1] ?? "";
|
|
4106
|
+
const indexSlug = indexFrontmatter.match(/^slug:\s*["']?([^\s"']+)["']?\s*$/m)?.[1]?.replace(/^\/+|\/+$/g, "");
|
|
4107
|
+
const hasBarePage = index === indexRoute || indexSlug === indexRoute;
|
|
4108
|
+
if (bareRouteIndex >= 0 && hasBarePage) context.bareRouteRedirects.splice(bareRouteIndex, 1);
|
|
4109
|
+
else if (latest && bareRouteIndex >= 0) context.bareRouteRedirects[bareRouteIndex].destination = `/${latest}`;
|
|
4110
|
+
return [{ tab: label, groups: [changelog] }];
|
|
4111
|
+
}
|
|
4112
|
+
}
|
|
3843
4113
|
if (groups.length === 0) return [];
|
|
3844
4114
|
if (segments.length > 0) addBareRouteRedirect(segments, groups, context);
|
|
3845
4115
|
return [{
|
|
@@ -3916,6 +4186,7 @@ function projectFernNavigation(input) {
|
|
|
3916
4186
|
descriptors: [],
|
|
3917
4187
|
seenNavigationIds: /* @__PURE__ */ new Set(),
|
|
3918
4188
|
apiSections: [],
|
|
4189
|
+
changelogIndexes: [],
|
|
3919
4190
|
warnings: [],
|
|
3920
4191
|
warningKeys: /* @__PURE__ */ new Set(),
|
|
3921
4192
|
bareRouteRedirects: [],
|
|
@@ -3938,6 +4209,9 @@ function projectFernNavigation(input) {
|
|
|
3938
4209
|
const label = typeof link?.text === "string" ? link.text : typeof link?.label === "string" ? link.label : link?.type === "github" ? "GitHub" : void 0;
|
|
3939
4210
|
return href && label ? [{ label, href, ...link?.type === "github" ? { type: "github" } : {} }] : [];
|
|
3940
4211
|
}) : [];
|
|
4212
|
+
const announcement = objectValue3(config.announcement);
|
|
4213
|
+
const announcementMessage = typeof announcement?.message === "string" ? announcement.message.trim() : "";
|
|
4214
|
+
const bannerContent = announcementMarkdown(announcementMessage);
|
|
3941
4215
|
const redirects = Array.isArray(config.redirects) ? config.redirects.flatMap((value) => {
|
|
3942
4216
|
const redirect = objectValue3(value);
|
|
3943
4217
|
if (!redirect || typeof redirect.source !== "string" || typeof redirect.destination !== "string") return [];
|
|
@@ -3959,13 +4233,6 @@ function projectFernNavigation(input) {
|
|
|
3959
4233
|
...typeof redirect.permanent === "boolean" ? { permanent: redirect.permanent } : {}
|
|
3960
4234
|
}];
|
|
3961
4235
|
}) : [];
|
|
3962
|
-
if (config.logo || config.favicon) {
|
|
3963
|
-
warnOnce2(
|
|
3964
|
-
context,
|
|
3965
|
-
"fern-branding",
|
|
3966
|
-
"Fern logo and favicon were not migrated; add them to public/brand/ (default-logo-light.svg, default-logo-dark.svg, default-favicon-light.svg, default-favicon-dark.svg)."
|
|
3967
|
-
);
|
|
3968
|
-
}
|
|
3969
4236
|
const authoredSources = new Set(redirects.map((redirect) => redirect.source));
|
|
3970
4237
|
const knownIds = new Set(context.descriptors.map((descriptor) => descriptor.navigationId));
|
|
3971
4238
|
const keptNavigationId = (descriptor) => context.sourcePathToNavigationId.get(descriptor.sourcePath) ?? descriptor.navigationId;
|
|
@@ -4009,12 +4276,14 @@ function projectFernNavigation(input) {
|
|
|
4009
4276
|
return {
|
|
4010
4277
|
docsConfig: {
|
|
4011
4278
|
tabs,
|
|
4279
|
+
...bannerContent ? { banner: { content: bannerContent, dismissible: true } } : {},
|
|
4012
4280
|
...navbarLinks.length > 0 ? { navbar: { links: navbarLinks } } : {},
|
|
4013
4281
|
...allRedirects.length > 0 ? { redirects: allRedirects } : {}
|
|
4014
4282
|
},
|
|
4015
4283
|
descriptors: context.descriptors,
|
|
4016
4284
|
warnings: context.warnings,
|
|
4017
|
-
apiSections: disambiguatedApiSections
|
|
4285
|
+
apiSections: disambiguatedApiSections,
|
|
4286
|
+
changelogIndexes: context.changelogIndexes
|
|
4018
4287
|
};
|
|
4019
4288
|
}
|
|
4020
4289
|
|
|
@@ -4635,12 +4904,6 @@ function fernThemeColors(value) {
|
|
|
4635
4904
|
if (lightMode) colors.dark = lightMode;
|
|
4636
4905
|
return Object.keys(colors).length > 0 ? colors : void 0;
|
|
4637
4906
|
}
|
|
4638
|
-
function mintlifyBrandAssetPaths(value) {
|
|
4639
|
-
if (typeof value === "string") return [value];
|
|
4640
|
-
if (!value || typeof value !== "object") return [];
|
|
4641
|
-
const source = value;
|
|
4642
|
-
return ["light", "dark"].map((key) => source[key]).filter((entry) => typeof entry === "string");
|
|
4643
|
-
}
|
|
4644
4907
|
function normalizedReferenceKey(value) {
|
|
4645
4908
|
return value.split(/[?#]/, 1)[0].replace(/^\/+/, "").replace(/\\/g, "/").replace(/\.(?:mdx?|rst|txt)$/i, "").replace(/\/(?:index|readme)$/i, "").replace(/^(?:index|readme)$/i, "") || "introduction";
|
|
4646
4909
|
}
|
|
@@ -4947,7 +5210,7 @@ function fernSourceSiteUrl(config) {
|
|
|
4947
5210
|
function externalizeMissingFernLinks(body, pageIds, sourceSiteUrl, externalized) {
|
|
4948
5211
|
const rewrite = (target) => {
|
|
4949
5212
|
const path = target.split(/[?#]/, 1)[0].replace(/^\//, "").replace(/\/$/, "");
|
|
4950
|
-
if (!path || pageIds.has(path)) return target;
|
|
5213
|
+
if (!path || pageIds.has(path) || ASSET_EXTENSIONS.has(extname5(path).toLowerCase())) return target;
|
|
4951
5214
|
try {
|
|
4952
5215
|
const base = new URL(`${sourceSiteUrl}/`);
|
|
4953
5216
|
const sourceLinkUrl = new URL(target.slice(1), base);
|
|
@@ -4983,15 +5246,20 @@ function rewriteMintlifyMountedLinks(body, pageIds) {
|
|
|
4983
5246
|
};
|
|
4984
5247
|
return replaceOutsideCode(body, (text) => text.replace(/(\]\()(\/[^\s)]+)(\))/g, (_match, before, target, after) => `${before}${rewrite(target)}${after}`).replace(/(\b(?:href|to)=(['"]))(\/[^'"\n]+)\2/g, (_match, before, quote, target) => `${before}${rewrite(target)}${quote}`));
|
|
4985
5248
|
}
|
|
4986
|
-
function
|
|
5249
|
+
function preserveLinkedAnchors(pages) {
|
|
4987
5250
|
const pageById = new Map(pages.map((page) => [page.id, page]));
|
|
4988
5251
|
const requested = /* @__PURE__ */ new Map();
|
|
4989
5252
|
const crossPageRequests = /* @__PURE__ */ new Set();
|
|
4990
5253
|
const addTarget = (target, currentId) => {
|
|
4991
5254
|
const hash2 = target.indexOf("#");
|
|
4992
5255
|
if (hash2 < 0) return;
|
|
4993
|
-
|
|
4994
|
-
|
|
5256
|
+
let fragment;
|
|
5257
|
+
try {
|
|
5258
|
+
fragment = decodeURIComponent(target.slice(hash2 + 1));
|
|
5259
|
+
} catch {
|
|
5260
|
+
return;
|
|
5261
|
+
}
|
|
5262
|
+
if (!/^[\p{L}\p{N}_.:$-]{1,120}$/u.test(fragment)) return;
|
|
4995
5263
|
const path = target.slice(0, hash2).split("?")[0];
|
|
4996
5264
|
const id = target.startsWith("#") ? currentId : path.startsWith("/") && !path.startsWith("//") ? path.replace(/^\//, "").replace(/\/$/, "") || "introduction" : "";
|
|
4997
5265
|
if (!pageById.has(id)) return;
|
|
@@ -5066,6 +5334,43 @@ function preserveDocusaurusLinkedAnchors(pages) {
|
|
|
5066
5334
|
]).join("\n");
|
|
5067
5335
|
}
|
|
5068
5336
|
}
|
|
5337
|
+
function closeOpenCodeFence(body) {
|
|
5338
|
+
let open = null;
|
|
5339
|
+
for (const line of body.split(/\r?\n/)) {
|
|
5340
|
+
const match = line.match(/^ {0,3}(`{3,}|~{3,})(.*)$/);
|
|
5341
|
+
if (!match) continue;
|
|
5342
|
+
const marker = match[1][0];
|
|
5343
|
+
if (!open) {
|
|
5344
|
+
open = { marker, length: match[1].length };
|
|
5345
|
+
} else if (marker === open.marker && match[1].length >= open.length && !match[2].trim()) {
|
|
5346
|
+
open = null;
|
|
5347
|
+
}
|
|
5348
|
+
}
|
|
5349
|
+
return open ? `${body}
|
|
5350
|
+
|
|
5351
|
+
${open.marker.repeat(open.length)}` : body;
|
|
5352
|
+
}
|
|
5353
|
+
function addDatedHeadingAliases(body, date) {
|
|
5354
|
+
let open = null;
|
|
5355
|
+
const existingIds = new Set([...body.matchAll(/<a\s+id=["']([^"']+)["']/g)].map((match) => match[1]));
|
|
5356
|
+
return body.split(/\r?\n/).flatMap((line) => {
|
|
5357
|
+
const fence = line.match(/^ {0,3}(`{3,}|~{3,})(.*)$/);
|
|
5358
|
+
if (fence) {
|
|
5359
|
+
const marker = fence[1][0];
|
|
5360
|
+
if (!open) open = { marker, length: fence[1].length };
|
|
5361
|
+
else if (marker === open.marker && fence[1].length >= open.length && !fence[2].trim()) open = null;
|
|
5362
|
+
return [line];
|
|
5363
|
+
}
|
|
5364
|
+
if (open) return [line];
|
|
5365
|
+
const heading = line.match(/^#{2,6}\s+(.+?)\s*#*\s*$/);
|
|
5366
|
+
if (!heading) return [line];
|
|
5367
|
+
const slug = heading[1].replace(/\[([^\]]+)\]\([^)]+\)/g, "$1").replace(/[`*_]/g, "").normalize("NFKD").toLowerCase().replace(/[^\p{L}\p{N}\s-]/gu, "").trim().replace(/\s+/g, "-");
|
|
5368
|
+
const id = `${date}-${slug}`;
|
|
5369
|
+
if (!slug || existingIds.has(id)) return [line];
|
|
5370
|
+
existingIds.add(id);
|
|
5371
|
+
return [`<a id="${id}" />`, "", line];
|
|
5372
|
+
}).join("\n");
|
|
5373
|
+
}
|
|
5069
5374
|
function resolveSnippetPath(sourcePath, currentFile, repositoryRoot, siteRoot) {
|
|
5070
5375
|
sourcePath = sourcePath.replace(/\\(?=_)/g, "");
|
|
5071
5376
|
const repositoryRelative = sourcePath.startsWith("@site/") ? relative5(repositoryRoot, resolveWithin(siteRoot, sourcePath.slice("@site/".length))).replace(/\\/g, "/") : sourcePath.startsWith("/") ? relative5(repositoryRoot, resolveWithin(siteRoot, sourcePath.replace(/^\/+/, ""))).replace(/\\/g, "/") : relative5(repositoryRoot, resolvePath(dirname4(currentFile), sourcePath)).replace(/\\/g, "/");
|
|
@@ -5113,7 +5418,11 @@ function repositoryAssetHref(value, currentFile, siteRoot, onReferenced) {
|
|
|
5113
5418
|
}
|
|
5114
5419
|
if (!ASSET_EXTENSIONS.has(extname5(decodedPath).toLowerCase())) return null;
|
|
5115
5420
|
try {
|
|
5116
|
-
const candidate = decodedPath.startsWith("/") ? resolveWithin(siteRoot, decodedPath.replace(/^\/+/, "")) :
|
|
5421
|
+
const candidate = decodedPath.startsWith("/") ? resolveWithin(siteRoot, decodedPath.replace(/^\/+/, "")) : resolveWithinRoot(dirname4(currentFile), decodedPath, siteRoot);
|
|
5422
|
+
const realRoot = realpathSync2(siteRoot);
|
|
5423
|
+
const realCandidate = realpathSync2(candidate);
|
|
5424
|
+
const realRelative = relative5(realRoot, realCandidate);
|
|
5425
|
+
if (realRelative === ".." || realRelative.startsWith(`..${sep2}`) || isAbsolute2(realRelative)) return null;
|
|
5117
5426
|
const siteRelative = relative5(siteRoot, candidate).replace(/\\/g, "/");
|
|
5118
5427
|
resolveWithin(siteRoot, siteRelative);
|
|
5119
5428
|
if (!existsSync5(candidate) || !lstatSync5(candidate).isFile()) return null;
|
|
@@ -5348,8 +5657,11 @@ function migrateRepository(options) {
|
|
|
5348
5657
|
let fernBasePath = "";
|
|
5349
5658
|
let fernVersionPath = "";
|
|
5350
5659
|
let fernApiSections = [];
|
|
5660
|
+
let fernChangelogIndexes = [];
|
|
5351
5661
|
const fernReferencedPaths = /* @__PURE__ */ new Set();
|
|
5352
5662
|
const fernSourceLinkAliases = /* @__PURE__ */ new Map();
|
|
5663
|
+
const fernNavTitles = /* @__PURE__ */ new Map();
|
|
5664
|
+
const fernHiddenIds = /* @__PURE__ */ new Set();
|
|
5353
5665
|
if (platform === "mintlify") {
|
|
5354
5666
|
try {
|
|
5355
5667
|
const config = readMintlifyConfig(mintlifyProjectRoot ?? repositoryDir);
|
|
@@ -5384,8 +5696,13 @@ function migrateRepository(options) {
|
|
|
5384
5696
|
docsConfig = projected.docsConfig;
|
|
5385
5697
|
warnings.push(...projected.warnings);
|
|
5386
5698
|
fernApiSections = projected.apiSections;
|
|
5699
|
+
fernChangelogIndexes = projected.changelogIndexes;
|
|
5387
5700
|
for (const [index, descriptor] of projected.descriptors.entries()) {
|
|
5388
5701
|
fernReferencedPaths.add(descriptor.sourcePath);
|
|
5702
|
+
if (descriptor.navTitle && !fernNavTitles.has(descriptor.navigationId)) {
|
|
5703
|
+
fernNavTitles.set(descriptor.navigationId, descriptor.navTitle);
|
|
5704
|
+
}
|
|
5705
|
+
if (descriptor.hidden) fernHiddenIds.add(descriptor.navigationId);
|
|
5389
5706
|
const sourceTail = descriptor.sourcePath.match(/(?:^|\/)pages\/(.+)\.mdx?$/i)?.[1]?.replace(/\/index$/i, "");
|
|
5390
5707
|
if (sourceTail) {
|
|
5391
5708
|
const routeSegments = descriptor.navigationId.split("/");
|
|
@@ -5587,6 +5904,11 @@ function migrateRepository(options) {
|
|
|
5587
5904
|
skipped++;
|
|
5588
5905
|
continue;
|
|
5589
5906
|
}
|
|
5907
|
+
if (platform === "fern" && !page.navTitle) {
|
|
5908
|
+
const navTitle = fernNavTitles.get(navigationId);
|
|
5909
|
+
if (navTitle && navTitle !== page.title) page.navTitle = navTitle;
|
|
5910
|
+
}
|
|
5911
|
+
if (platform === "fern" && fernHiddenIds.has(navigationId)) page.hidden = true;
|
|
5590
5912
|
if (platform === "mintlify" && mintlifyProjectRoot) {
|
|
5591
5913
|
page.body = rewriteRepositoryAssetLinks(page.body, file.absolutePath, mintlifyProjectRoot, (assetPath) => {
|
|
5592
5914
|
addAssetReference(assetPath, file.relativePath);
|
|
@@ -5895,10 +6217,10 @@ function migrateRepository(options) {
|
|
|
5895
6217
|
seenPageIds.add(page.id);
|
|
5896
6218
|
pages.push(page);
|
|
5897
6219
|
}
|
|
5898
|
-
const
|
|
6220
|
+
const assetPaths2 = new Set(assets.map((asset) => asset.path));
|
|
5899
6221
|
for (const asset of pluginBundle.assets) {
|
|
5900
|
-
if (
|
|
5901
|
-
|
|
6222
|
+
if (assetPaths2.has(asset.path)) continue;
|
|
6223
|
+
assetPaths2.add(asset.path);
|
|
5902
6224
|
assets.push(asset);
|
|
5903
6225
|
}
|
|
5904
6226
|
const pluginLabel = plugin.label;
|
|
@@ -5911,8 +6233,67 @@ function migrateRepository(options) {
|
|
|
5911
6233
|
skipped += pluginBundle.stats.skipped;
|
|
5912
6234
|
}
|
|
5913
6235
|
}
|
|
6236
|
+
if (platform === "docusaurus") {
|
|
6237
|
+
const importedRoutes = new Set(pages.map((page) => page.navigationId));
|
|
6238
|
+
docsConfig.tabs = docsConfig.tabs.map((tab) => {
|
|
6239
|
+
if (tab.href) return tab;
|
|
6240
|
+
const root = tab.tab.toLowerCase().trim().replace(/[^a-z0-9]+/g, "-");
|
|
6241
|
+
if (!root || !importedRoutes.has(root)) return tab;
|
|
6242
|
+
return {
|
|
6243
|
+
...tab,
|
|
6244
|
+
href: `/${root}`,
|
|
6245
|
+
...tab.pages ? { pages: tab.pages.map((node) => {
|
|
6246
|
+
if (typeof node === "string") return node;
|
|
6247
|
+
const index = node.pages.indexOf(root);
|
|
6248
|
+
return index > 0 ? { ...node, pages: [root, ...node.pages.filter((page) => page !== root)] } : node;
|
|
6249
|
+
}) } : {},
|
|
6250
|
+
...tab.groups ? { groups: tab.groups.map((group) => {
|
|
6251
|
+
const index = group.pages.indexOf(root);
|
|
6252
|
+
return index > 0 ? { ...group, pages: [root, ...group.pages.filter((page) => page !== root)] } : group;
|
|
6253
|
+
}) } : {}
|
|
6254
|
+
};
|
|
6255
|
+
});
|
|
6256
|
+
}
|
|
6257
|
+
if (platform === "fern") {
|
|
6258
|
+
const byId = new Map(pages.map((page) => [page.navigationId, page]));
|
|
6259
|
+
for (const changelog of fernChangelogIndexes) {
|
|
6260
|
+
let index = byId.get(changelog.route);
|
|
6261
|
+
const entries = changelog.entries.map((id) => byId.get(fernIdRenames.get(id) ?? id)).filter((page) => Boolean(page)).slice(0, 10);
|
|
6262
|
+
if (entries.length === 0) continue;
|
|
6263
|
+
if (!index) {
|
|
6264
|
+
index = {
|
|
6265
|
+
id: changelog.route,
|
|
6266
|
+
navigationId: changelog.route,
|
|
6267
|
+
title: "Release Notes",
|
|
6268
|
+
description: "Latest release notes and product updates.",
|
|
6269
|
+
descriptionPlacement: "body",
|
|
6270
|
+
keywords: [],
|
|
6271
|
+
body: "",
|
|
6272
|
+
source: entries[0].source
|
|
6273
|
+
};
|
|
6274
|
+
pages.push(index);
|
|
6275
|
+
byId.set(index.navigationId, index);
|
|
6276
|
+
docsConfig.redirects = docsConfig.redirects?.filter((redirect) => redirect.source !== `/${changelog.route}`);
|
|
6277
|
+
}
|
|
6278
|
+
if (index.body.trim()) continue;
|
|
6279
|
+
index.description ||= "Latest release notes and product updates.";
|
|
6280
|
+
index.body = entries.map((entry) => {
|
|
6281
|
+
const date = entry.source.match(/\d{4}-\d{2}-\d{2}/)?.[0];
|
|
6282
|
+
const escapeText = (value) => value.replace(/([\\{}<>\[\]*_`])/g, "\\$1");
|
|
6283
|
+
const body = /^(?:import|export)\s.+(?:from\s|\{)/m.test(entry.body) ? escapeText(entry.description) : closeOpenCodeFence(date ? addDatedHeadingAliases(entry.body.trim(), date) : entry.body.trim()) || escapeText(entry.description);
|
|
6284
|
+
const dateAnchor = date ? `<a id="${date}T00:00:00.000Z" />
|
|
6285
|
+
|
|
6286
|
+
` : "";
|
|
6287
|
+
return `${dateAnchor}## ${escapeText(entry.title)}
|
|
6288
|
+
|
|
6289
|
+
${date ? `**${date}** \xB7 ` : ""}[Read release note](/${entry.id})
|
|
6290
|
+
|
|
6291
|
+
${body}`;
|
|
6292
|
+
}).join("\n\n---\n\n");
|
|
6293
|
+
}
|
|
6294
|
+
}
|
|
5914
6295
|
docsConfig = pruneMissingNavigationPages(docsConfig, new Set(pages.map((page) => page.navigationId)));
|
|
5915
|
-
|
|
6296
|
+
preserveLinkedAnchors(pages);
|
|
5916
6297
|
if (platform === "fern" && fernRawConfig) {
|
|
5917
6298
|
const sourceSiteUrl = fernSourceSiteUrl(fernRawConfig);
|
|
5918
6299
|
if (sourceSiteUrl) {
|
|
@@ -5953,14 +6334,133 @@ function migrateRepository(options) {
|
|
|
5953
6334
|
${reasons.map((reason) => `- ${reason}`).join("\n")}` : "No importable Markdown or MDX pages were found in the repository.");
|
|
5954
6335
|
}
|
|
5955
6336
|
const isTopLevelDocusaurus = platform === "docusaurus" && docusaurusProjectRoot && !options.docusaurusSkipRedirects;
|
|
5956
|
-
const
|
|
5957
|
-
|
|
5958
|
-
|
|
5959
|
-
|
|
6337
|
+
const docusaurusSettings = isTopLevelDocusaurus ? readDocusaurusSiteSettings(docusaurusProjectRoot) : void 0;
|
|
6338
|
+
if (docusaurusSettings) {
|
|
6339
|
+
const importedRoutes = new Set(pages.map((page) => page.navigationId));
|
|
6340
|
+
const sourceOrigin = readDocusaurusSiteOrigin(docusaurusProjectRoot);
|
|
6341
|
+
const externalized = /* @__PURE__ */ new Set();
|
|
6342
|
+
const projectLink = (raw, sourceLiteral = false) => {
|
|
6343
|
+
if (/^https?:\/\//i.test(raw)) return raw;
|
|
6344
|
+
if (/^(?:[a-z][a-z0-9+.-]*:|\/\/)/i.test(raw) || raw.includes("\\")) return void 0;
|
|
6345
|
+
const suffixAt = raw.search(/[?#]/);
|
|
6346
|
+
const path = suffixAt < 0 ? raw : raw.slice(0, suffixAt);
|
|
6347
|
+
const suffix = suffixAt < 0 ? "" : raw.slice(suffixAt);
|
|
6348
|
+
const route = path.replace(/^\.?\//, "").replace(/\/+$/, "");
|
|
6349
|
+
if (route === ".." || route.startsWith("../") || route.includes("/../")) return void 0;
|
|
6350
|
+
const docsBase = docusaurusSettings.docsRouteBasePath.replace(/^\/+|\/+$/g, "");
|
|
6351
|
+
const isOutsideDocs = sourceLiteral && docsBase && route !== docsBase && !route.startsWith(`${docsBase}/`);
|
|
6352
|
+
if (isOutsideDocs && sourceOrigin) {
|
|
6353
|
+
externalized.add(raw);
|
|
6354
|
+
return new URL(raw, `${sourceOrigin}/`).toString();
|
|
6355
|
+
}
|
|
6356
|
+
const strippedDocsRoute = docsBase && route.startsWith(`${docsBase}/`) ? route.slice(docsBase.length + 1) : route;
|
|
6357
|
+
const candidates = [route, strippedDocsRoute, ...route === docsBase ? ["introduction"] : []];
|
|
6358
|
+
const imported = candidates.find((candidate) => importedRoutes.has(candidate));
|
|
6359
|
+
if (imported) return `/${imported}${suffix}`;
|
|
6360
|
+
if (sourceOrigin) {
|
|
6361
|
+
externalized.add(raw);
|
|
6362
|
+
return new URL(raw, `${sourceOrigin}/`).toString();
|
|
6363
|
+
}
|
|
6364
|
+
return path.startsWith("/") ? `${path}${suffix}` : `/${route}${suffix}`;
|
|
6365
|
+
};
|
|
6366
|
+
const firstNavigationPage = (nodes) => {
|
|
6367
|
+
for (const node of nodes) {
|
|
6368
|
+
if (typeof node === "string") return node;
|
|
6369
|
+
const nested = firstNavigationPage(node.pages);
|
|
6370
|
+
if (nested) return nested;
|
|
6371
|
+
}
|
|
6372
|
+
return void 0;
|
|
6373
|
+
};
|
|
6374
|
+
const navbarLinks = docusaurusSettings.navbarLinks.flatMap((link) => {
|
|
6375
|
+
const docRoute = link.docId && !link.docsPluginId && docusaurusDescriptors.find((page) => page.docId === link.docId)?.navigationId;
|
|
6376
|
+
const sidebar = link.sidebarId && docsConfig.tabs.find((tab) => tab.tab.toLowerCase() === link.sidebarId.toLowerCase());
|
|
6377
|
+
const sidebarRoute = sidebar && firstNavigationPage(sidebar.pages ?? sidebar.groups ?? []);
|
|
6378
|
+
const pluginRoot = link.docsPluginId && importedRoutes.has(link.docsPluginId) ? link.docsPluginId : void 0;
|
|
6379
|
+
const rawHref = link.href ?? (docRoute ? `/${docRoute}` : void 0) ?? (pluginRoot ? `/${pluginRoot}` : void 0) ?? (sidebarRoute ? `/${sidebarRoute}` : void 0) ?? (link.docsPluginId ? `/${link.docsPluginId}` : void 0);
|
|
6380
|
+
const href = rawHref && projectLink(rawHref, Boolean(link.href));
|
|
6381
|
+
return href ? [{ label: link.label, href }] : [];
|
|
6382
|
+
});
|
|
6383
|
+
const footerLinks = docusaurusSettings.footerLinks?.flatMap((column) => {
|
|
6384
|
+
const items = column.items.flatMap((item) => {
|
|
6385
|
+
const href = projectLink(item.href, true);
|
|
6386
|
+
return href ? [{ label: item.label, href }] : [];
|
|
6387
|
+
});
|
|
6388
|
+
return items.length > 0 ? [{ heading: column.heading, items }] : [];
|
|
6389
|
+
});
|
|
6390
|
+
docsConfig = {
|
|
6391
|
+
...docsConfig,
|
|
6392
|
+
...navbarLinks.length > 0 ? { navbar: { ...docsConfig.navbar, links: navbarLinks } } : {},
|
|
6393
|
+
...footerLinks?.length || docusaurusSettings.copyright ? {
|
|
6394
|
+
footer: {
|
|
6395
|
+
...docsConfig.footer,
|
|
6396
|
+
...footerLinks?.length ? { links: footerLinks } : {},
|
|
6397
|
+
...docusaurusSettings.copyright ? { copyright: docusaurusSettings.copyright } : {}
|
|
6398
|
+
}
|
|
6399
|
+
} : {}
|
|
6400
|
+
};
|
|
6401
|
+
if (externalized.size > 0) warnings.push({
|
|
5960
6402
|
code: "unsupported-config",
|
|
5961
|
-
message:
|
|
6403
|
+
message: `${externalized.size} site navigation/footer link(s) point outside the imported docs and were kept on ${sourceOrigin}.`
|
|
5962
6404
|
});
|
|
5963
6405
|
}
|
|
6406
|
+
if (!docsConfig.navigation?.display && docsConfig.tabs.filter((tab) => !tab.hidden).length > 6) {
|
|
6407
|
+
docsConfig = { ...docsConfig, navigation: { display: "dropdown" } };
|
|
6408
|
+
}
|
|
6409
|
+
const themeColors = mintlifyConfig ? mintlifyThemeColors(mintlifyConfig.colors) : fernRawConfig ? fernThemeColors(fernRawConfig.colors) : isTopLevelDocusaurus ? readDocusaurusThemeColor(docusaurusProjectRoot) : void 0;
|
|
6410
|
+
const assetPaths = new Set(assets.map((asset) => asset.path));
|
|
6411
|
+
const publicBrandPath = (value) => {
|
|
6412
|
+
if (typeof value !== "string" || /^(?:[a-z][a-z0-9+.-]*:|\/\/)/i.test(value)) return void 0;
|
|
6413
|
+
const normalized = normalizeAssetPath(value);
|
|
6414
|
+
return normalized && assetPaths.has(normalized) ? `/${normalized}` : void 0;
|
|
6415
|
+
};
|
|
6416
|
+
const brandVariants = (value) => {
|
|
6417
|
+
if (typeof value === "string") return { light: value };
|
|
6418
|
+
if (!value || typeof value !== "object") return {};
|
|
6419
|
+
const source = value;
|
|
6420
|
+
const light = source.light ?? source.src;
|
|
6421
|
+
const dark = source.dark ?? source.srcDark;
|
|
6422
|
+
return {
|
|
6423
|
+
...typeof light === "string" ? { light } : {},
|
|
6424
|
+
...typeof dark === "string" ? { dark } : {},
|
|
6425
|
+
...typeof source.showTitle === "boolean" ? { showTitle: source.showTitle } : {}
|
|
6426
|
+
};
|
|
6427
|
+
};
|
|
6428
|
+
const sourceLogo = mintlifyConfig?.logo ?? fernRawConfig?.logo ?? docusaurusSettings?.logo;
|
|
6429
|
+
const sourceFavicon = mintlifyConfig?.favicon ?? fernRawConfig?.favicon ?? docusaurusSettings?.favicon;
|
|
6430
|
+
const logo = brandVariants(sourceLogo);
|
|
6431
|
+
const favicon = brandVariants(sourceFavicon);
|
|
6432
|
+
const logoLight = publicBrandPath(logo.light);
|
|
6433
|
+
const logoDark = publicBrandPath(logo.dark);
|
|
6434
|
+
const faviconLight = publicBrandPath(favicon.light);
|
|
6435
|
+
const faviconDark = publicBrandPath(favicon.dark);
|
|
6436
|
+
if (logoLight) docsConfig = {
|
|
6437
|
+
...docsConfig,
|
|
6438
|
+
navbar: {
|
|
6439
|
+
...docsConfig.navbar,
|
|
6440
|
+
logo: {
|
|
6441
|
+
light: logoLight,
|
|
6442
|
+
...logoDark ? { dark: logoDark } : {},
|
|
6443
|
+
showTitle: mintlifyConfig || fernRawConfig ? false : logo.showTitle !== false,
|
|
6444
|
+
...typeof fernRawConfig?.logo?.["right-text"] === "string" ? { rightText: String(fernRawConfig.logo["right-text"]).trim().slice(0, 40) } : {}
|
|
6445
|
+
}
|
|
6446
|
+
}
|
|
6447
|
+
};
|
|
6448
|
+
if (faviconLight) docsConfig = {
|
|
6449
|
+
...docsConfig,
|
|
6450
|
+
favicon: { light: faviconLight, ...faviconDark ? { dark: faviconDark } : {} }
|
|
6451
|
+
};
|
|
6452
|
+
const missingBrand = [
|
|
6453
|
+
...[logo.light, logo.dark].filter((value) => typeof value === "string" && !publicBrandPath(value)),
|
|
6454
|
+
...[favicon.light, favicon.dark].filter((value) => typeof value === "string" && !publicBrandPath(value))
|
|
6455
|
+
];
|
|
6456
|
+
if (missingBrand.length > 0) warnings.push({
|
|
6457
|
+
code: "unsupported-config",
|
|
6458
|
+
message: `Brand asset(s) were referenced but not imported: ${[...new Set(missingBrand)].join(", ")}. Add these files under public/ or update docs.json.`
|
|
6459
|
+
});
|
|
6460
|
+
if (fernRawConfig?.logo && !logoLight && !logo.light) warnings.push({
|
|
6461
|
+
code: "unsupported-config",
|
|
6462
|
+
message: "Fern supplied a logo through its global theme without a local asset; add a logo path to docs.json after import."
|
|
6463
|
+
});
|
|
5964
6464
|
return {
|
|
5965
6465
|
sourceUrl: options.sourceUrl,
|
|
5966
6466
|
sourceKind: "repository",
|
|
@@ -5980,6 +6480,12 @@ ${reasons.map((reason) => `- ${reason}`).join("\n")}` : "No importable Markdown
|
|
|
5980
6480
|
...typeof fernRawConfig.title === "string" ? { name: fernRawConfig.title } : {},
|
|
5981
6481
|
...themeColors ? { colors: themeColors } : {}
|
|
5982
6482
|
}
|
|
6483
|
+
} : docusaurusSettings && (docusaurusSettings.name || docusaurusSettings.description || themeColors) ? {
|
|
6484
|
+
site: {
|
|
6485
|
+
...docusaurusSettings.name ? { name: docusaurusSettings.name } : {},
|
|
6486
|
+
...docusaurusSettings.description ? { description: docusaurusSettings.description } : {},
|
|
6487
|
+
...themeColors ? { colors: themeColors } : {}
|
|
6488
|
+
}
|
|
5983
6489
|
} : themeColors ? {
|
|
5984
6490
|
site: { colors: themeColors }
|
|
5985
6491
|
} : {},
|
|
@@ -5998,6 +6504,7 @@ function renderPage(bundle, page) {
|
|
|
5998
6504
|
`title: ${yamlString(page.title)}`,
|
|
5999
6505
|
page.navTitle ? `navTitle: ${yamlString(page.navTitle)}` : null,
|
|
6000
6506
|
`description: ${yamlString(page.description)}`,
|
|
6507
|
+
page.descriptionPlacement === "body" ? "descriptionPlacement: body" : null,
|
|
6001
6508
|
page.badge ? `badge: ${yamlString(page.badge)}` : null,
|
|
6002
6509
|
page.keywords.length > 0 ? `keywords: [${page.keywords.map(yamlString).join(", ")}]` : null,
|
|
6003
6510
|
page.mode ? `mode: ${yamlString(page.mode)}` : null,
|
|
@@ -6099,7 +6606,7 @@ function renderMigrationFiles(bundle, options = {}) {
|
|
|
6099
6606
|
}
|
|
6100
6607
|
|
|
6101
6608
|
// src/url.ts
|
|
6102
|
-
import { load } from "cheerio";
|
|
6609
|
+
import { load as load2 } from "cheerio";
|
|
6103
6610
|
import remarkMdx3 from "remark-mdx";
|
|
6104
6611
|
import remarkParse3 from "remark-parse";
|
|
6105
6612
|
import TurndownService from "turndown";
|
|
@@ -6276,7 +6783,7 @@ function machineIndexScopePath(source, documents) {
|
|
|
6276
6783
|
if (!document) continue;
|
|
6277
6784
|
const references = [...headerLinks(document)];
|
|
6278
6785
|
if (/html/i.test(document.contentType)) {
|
|
6279
|
-
const $ =
|
|
6786
|
+
const $ = load2(document.body);
|
|
6280
6787
|
references.push(...$("link[href], a[href]").map((_index, element) => $(element).attr("href") ?? "").get().filter((href) => /\/(?:llms(?:-full)?\.txt|sitemap\.xml)(?:[?#]|$)/i.test(href)));
|
|
6281
6788
|
}
|
|
6282
6789
|
for (const reference of references) {
|
|
@@ -6387,7 +6894,7 @@ function jsonObjectAfterKey(value, key) {
|
|
|
6387
6894
|
return null;
|
|
6388
6895
|
}
|
|
6389
6896
|
function embeddedMintlifyConfig(body) {
|
|
6390
|
-
const $ =
|
|
6897
|
+
const $ = load2(body);
|
|
6391
6898
|
const flightPayloads = [];
|
|
6392
6899
|
$("script").each((_index, element) => {
|
|
6393
6900
|
const script = $(element).text();
|
|
@@ -6485,7 +6992,7 @@ function isSafePortableUrl(value) {
|
|
|
6485
6992
|
}
|
|
6486
6993
|
}
|
|
6487
6994
|
function decodeHtmlAttribute(value) {
|
|
6488
|
-
const document =
|
|
6995
|
+
const document = load2(`<i data-thally-value="${value.replace(/"/g, """)}"></i>`);
|
|
6489
6996
|
return document("i").attr("data-thally-value") ?? "";
|
|
6490
6997
|
}
|
|
6491
6998
|
function escapeMarkdownText(value, escapeTableSeparator = false) {
|
|
@@ -6534,7 +7041,7 @@ function replacePortableHtmlImages(value) {
|
|
|
6534
7041
|
if (start < cursor) continue;
|
|
6535
7042
|
const end = htmlOpeningTagEnd(value, start + match[0].length);
|
|
6536
7043
|
if (end === null) continue;
|
|
6537
|
-
const fragment =
|
|
7044
|
+
const fragment = load2(value.slice(start, end));
|
|
6538
7045
|
const image = fragment("img").first();
|
|
6539
7046
|
const source = image.attr("src");
|
|
6540
7047
|
const destination = source && isSafePortableUrl(source) ? markdownLinkDestination(source) : null;
|
|
@@ -6559,7 +7066,7 @@ function replacePortableHtmlAnchors(value) {
|
|
|
6559
7066
|
const closing = closingMatch.exec(value);
|
|
6560
7067
|
if (!closing) continue;
|
|
6561
7068
|
const end = closing.index + closing[0].length;
|
|
6562
|
-
const fragment =
|
|
7069
|
+
const fragment = load2(value.slice(start, end));
|
|
6563
7070
|
const anchor = fragment("a").first();
|
|
6564
7071
|
const href = anchor.attr("href");
|
|
6565
7072
|
const label = escapeMarkdownText(anchor.text().replace(/\s+/g, " ").trim());
|
|
@@ -6940,7 +7447,7 @@ function mergeEmbeddedOpenApi(fragments) {
|
|
|
6940
7447
|
return new TextEncoder().encode(stringifyYaml(combined));
|
|
6941
7448
|
}
|
|
6942
7449
|
function htmlPage(document, id) {
|
|
6943
|
-
const $ =
|
|
7450
|
+
const $ = load2(document.body);
|
|
6944
7451
|
const links = $('nav a[href], main a[href], article a[href], [role="main"] a[href]').map((_index, element) => $(element).attr("href") ?? "").get().filter(Boolean);
|
|
6945
7452
|
const title = $("main h1, article h1, h1").first().text().trim() || $('meta[property="og:title"]').attr("content")?.trim() || $("title").text().split("|")[0].trim();
|
|
6946
7453
|
const description = $('meta[name="description"]').attr("content")?.trim() || $('meta[property="og:description"]').attr("content")?.trim();
|
|
@@ -6984,7 +7491,7 @@ function htmlPage(document, id) {
|
|
|
6984
7491
|
const element = node;
|
|
6985
7492
|
const className = element.className;
|
|
6986
7493
|
const tag = /admonition-(?:danger)/.test(className) ? "Error" : /admonition-(?:caution|warning)/.test(className) ? "Warning" : /admonition-info/.test(className) ? "Info" : "Note";
|
|
6987
|
-
const fragment =
|
|
7494
|
+
const fragment = load2(element.outerHTML);
|
|
6988
7495
|
const clone = fragment(".theme-admonition").first();
|
|
6989
7496
|
const title2 = clone.find('[class*="admonitionHeading"],.admonition-heading').first();
|
|
6990
7497
|
const titleText = title2.text().trim();
|
|
@@ -7005,7 +7512,7 @@ ${titleText ? `**${titleText}**
|
|
|
7005
7512
|
filter: (node) => node.nodeName === "DIV" && node.classList.contains("tabs-container"),
|
|
7006
7513
|
replacement: (_content, node) => {
|
|
7007
7514
|
const element = node;
|
|
7008
|
-
const fragment =
|
|
7515
|
+
const fragment = load2(element.outerHTML);
|
|
7009
7516
|
const container = fragment(".tabs-container").first();
|
|
7010
7517
|
const labels = container.children("ul.tabs").children("li").toArray().map((item) => fragment(item).text().trim() || "Tab");
|
|
7011
7518
|
const panels = container.children('div[role="tabpanel"]').toArray();
|
|
@@ -7028,7 +7535,7 @@ ${tabs.join("\n\n")}
|
|
|
7028
7535
|
turndown.addRule("gfm-table", {
|
|
7029
7536
|
filter: "table",
|
|
7030
7537
|
replacement: (_content, node) => {
|
|
7031
|
-
const fragment =
|
|
7538
|
+
const fragment = load2(node.outerHTML);
|
|
7032
7539
|
const rows = fragment("tr").toArray().map((row) => fragment(row).children("th,td").toArray().map((cell) => escapeMarkdownText(
|
|
7033
7540
|
fragment(cell).text().replace(/\s+/g, " ").trim(),
|
|
7034
7541
|
true
|
|
@@ -7049,7 +7556,7 @@ ${normalized.slice(1).map((row) => `| ${row.join(" | ")} |`).join("\n")}
|
|
|
7049
7556
|
filter: (node) => node.nodeName === "PRE",
|
|
7050
7557
|
replacement: (_content, node) => {
|
|
7051
7558
|
const element = node;
|
|
7052
|
-
const fragment =
|
|
7559
|
+
const fragment = load2(element.outerHTML);
|
|
7053
7560
|
const tokenLines = fragment(".token-line").toArray();
|
|
7054
7561
|
const code = (tokenLines.length > 0 ? tokenLines.map((line) => fragment(line).text()).join("\n") : fragment("pre").text()).replace(/\n$/, "");
|
|
7055
7562
|
const language = fragment("code").attr("class")?.match(/(?:language-|lang-)([A-Za-z0-9_+-]+)/)?.[1] ?? "";
|
|
@@ -7082,7 +7589,7 @@ ${fence}
|
|
|
7082
7589
|
};
|
|
7083
7590
|
}
|
|
7084
7591
|
function htmlNavigationLinks(document) {
|
|
7085
|
-
const $ =
|
|
7592
|
+
const $ = load2(document.body);
|
|
7086
7593
|
return $('.nav-tabs a[href], nav a[href], aside a[href], [role="navigation"] a[href]').map((_index, element) => $(element).attr("href") ?? "").get().filter(Boolean);
|
|
7087
7594
|
}
|
|
7088
7595
|
function normalizedLinkLabel(value) {
|
|
@@ -7090,7 +7597,7 @@ function normalizedLinkLabel(value) {
|
|
|
7090
7597
|
}
|
|
7091
7598
|
function readDocusaurusSidebar(document) {
|
|
7092
7599
|
if (!/html/i.test(document.contentType)) return null;
|
|
7093
|
-
const $ =
|
|
7600
|
+
const $ = load2(document.body);
|
|
7094
7601
|
const sidebar = $("ul.theme-doc-sidebar-menu").first();
|
|
7095
7602
|
if (sidebar.length === 0) return null;
|
|
7096
7603
|
function readList(list) {
|
|
@@ -7126,7 +7633,7 @@ function docusaurusSidebarHrefs(snapshot) {
|
|
|
7126
7633
|
return hrefs;
|
|
7127
7634
|
}
|
|
7128
7635
|
function deriveDocusaurusScope(source, document, submittedScopePath) {
|
|
7129
|
-
const $ =
|
|
7636
|
+
const $ = load2(document.body);
|
|
7130
7637
|
const sidebar = readDocusaurusSidebar(document);
|
|
7131
7638
|
const internalPaths = docusaurusSidebarHrefs(sidebar).flatMap((href) => {
|
|
7132
7639
|
try {
|
|
@@ -7256,7 +7763,7 @@ function docusaurusNavigationFromSnapshots(snapshots, pages, scopePath) {
|
|
|
7256
7763
|
return { tabs };
|
|
7257
7764
|
}
|
|
7258
7765
|
function htmlTopLevelNavigation(document, source, scopePath) {
|
|
7259
|
-
const $ =
|
|
7766
|
+
const $ = load2(document.body);
|
|
7260
7767
|
const collectCandidates = (selector) => {
|
|
7261
7768
|
const candidates2 = [];
|
|
7262
7769
|
$(selector).each((_containerIndex, container) => {
|
|
@@ -7317,7 +7824,7 @@ function markdownLinks(body) {
|
|
|
7317
7824
|
return [...body.matchAll(/\[[^\]]+\]\(([^)\s]+)(?:\s+['"][^'"]*['"])?\)/g)].map((match) => match[1]);
|
|
7318
7825
|
}
|
|
7319
7826
|
function sitemapLinks(body) {
|
|
7320
|
-
const $ =
|
|
7827
|
+
const $ = load2(body, { xmlMode: true });
|
|
7321
7828
|
return $("url > loc, sitemap > loc").map((_index, element) => $(element).text().trim()).get().filter(Boolean);
|
|
7322
7829
|
}
|
|
7323
7830
|
function robotsSitemaps(body) {
|
|
@@ -7356,7 +7863,7 @@ async function migrateUrl(options) {
|
|
|
7356
7863
|
const platform = options.platform ?? detectUrlPlatform(scopedHtmlProbe ?? initial);
|
|
7357
7864
|
let docusaurusHtmlProbe = platform === "docusaurus" ? scopedHtmlProbe : null;
|
|
7358
7865
|
if (docusaurusHtmlProbe && !readDocusaurusSidebar(docusaurusHtmlProbe)) {
|
|
7359
|
-
const $ =
|
|
7866
|
+
const $ = load2(docusaurusHtmlProbe.body);
|
|
7360
7867
|
const docsHref = $("nav a[href]").toArray().map((element) => ({
|
|
7361
7868
|
href: $(element).attr("href"),
|
|
7362
7869
|
label: normalizedLinkLabel($(element).text())
|