@thallylabs/migrate 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +11 -1
- package/dist/index.js +304 -25
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -149,8 +149,18 @@ interface MintlifyNavigationResult {
|
|
|
149
149
|
declare function readMintlifyConfig(repositoryRoot: string): Record<string, unknown> | null;
|
|
150
150
|
/** Convert current and legacy Mintlify navigation into Thally's schema. */
|
|
151
151
|
declare function projectMintlifyNavigation(config: Record<string, unknown>): MintlifyNavigationResult;
|
|
152
|
+
interface GeneratedNavigationOptions {
|
|
153
|
+
/** Dedicated docs platforms expose their primary sections as top-level tabs. */
|
|
154
|
+
topLevelTabs?: boolean;
|
|
155
|
+
/** Ordered tabs recovered from the source site's rendered navigation. */
|
|
156
|
+
topLevelNavigation?: ReadonlyArray<{
|
|
157
|
+
section: string;
|
|
158
|
+
label: string;
|
|
159
|
+
pageId: string;
|
|
160
|
+
}>;
|
|
161
|
+
}
|
|
152
162
|
/** Build deterministic fallback navigation from imported default-locale pages. */
|
|
153
|
-
declare function buildNavigationFromPages(pages: Array<MigrationPage
|
|
163
|
+
declare function buildNavigationFromPages(pages: Array<MigrationPage>, options?: GeneratedNavigationOptions): MigrationDocsConfig;
|
|
154
164
|
|
|
155
165
|
/** Markdown/MDX normalization that preserves every component Thally supports. */
|
|
156
166
|
|
package/dist/index.js
CHANGED
|
@@ -308,9 +308,91 @@ function projectMintlifyNavigation(config) {
|
|
|
308
308
|
function titleCase(value) {
|
|
309
309
|
return value.split(/[-_]/).map((word) => ["api", "cli", "sdk", "ui"].includes(word.toLowerCase()) ? word.toUpperCase() : word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
|
|
310
310
|
}
|
|
311
|
-
|
|
311
|
+
var TOP_LEVEL_LABELS = {
|
|
312
|
+
"api-reference": "API Reference",
|
|
313
|
+
cli: "CLI",
|
|
314
|
+
faqs: "FAQs",
|
|
315
|
+
introduction: "Overview",
|
|
316
|
+
"mcp-server": "MCP Server",
|
|
317
|
+
sdk: "SDK"
|
|
318
|
+
};
|
|
319
|
+
function topLevelLabel(segment) {
|
|
320
|
+
return TOP_LEVEL_LABELS[segment] ?? titleCase(segment);
|
|
321
|
+
}
|
|
322
|
+
function groupsWithinSection(section, pageIds, sectionLabel = topLevelLabel(section)) {
|
|
323
|
+
const groups = /* @__PURE__ */ new Map();
|
|
324
|
+
for (const id of pageIds) {
|
|
325
|
+
const relative4 = id === "introduction" ? "" : id.startsWith(`${section}/`) ? id.slice(section.length + 1) : id;
|
|
326
|
+
const nestedSegment = relative4.includes("/") ? relative4.split("/", 1)[0] : "overview";
|
|
327
|
+
const group = groups.get(nestedSegment) ?? [];
|
|
328
|
+
group.push(id);
|
|
329
|
+
groups.set(nestedSegment, group);
|
|
330
|
+
}
|
|
331
|
+
return [...groups].map(([segment, pages]) => ({
|
|
332
|
+
group: segment === "overview" ? sectionLabel : titleCase(segment),
|
|
333
|
+
pages
|
|
334
|
+
}));
|
|
335
|
+
}
|
|
336
|
+
function preferredLandingPage(section, pageIds) {
|
|
337
|
+
const candidates = [
|
|
338
|
+
section === "introduction" ? "introduction" : void 0,
|
|
339
|
+
`${section}/overview`,
|
|
340
|
+
`${section}/introduction`,
|
|
341
|
+
section
|
|
342
|
+
];
|
|
343
|
+
return candidates.find((candidate) => Boolean(candidate && pageIds.includes(candidate)));
|
|
344
|
+
}
|
|
345
|
+
function buildNavigationFromPages(pages, options = {}) {
|
|
312
346
|
const ids = pages.filter((page) => !page.locale || page.locale === "en").map((page) => page.navigationId);
|
|
313
347
|
const ordered = [...new Set(ids)];
|
|
348
|
+
if (options.topLevelTabs) {
|
|
349
|
+
const sourceNavigation = (options.topLevelNavigation ?? []).flatMap((entry) => {
|
|
350
|
+
const sectionPages = ordered.filter((id) => id === entry.section || id.startsWith(`${entry.section}/`));
|
|
351
|
+
const pageId = ordered.includes(entry.pageId) ? entry.pageId : preferredLandingPage(entry.section, sectionPages) ?? sectionPages[0];
|
|
352
|
+
return pageId ? [{ ...entry, pageId }] : [];
|
|
353
|
+
});
|
|
354
|
+
if (sourceNavigation.length > 1) {
|
|
355
|
+
const claimedIds = /* @__PURE__ */ new Set();
|
|
356
|
+
const tabs = sourceNavigation.map((entry) => {
|
|
357
|
+
const pageIds = ordered.filter((id) => {
|
|
358
|
+
const matches = id === entry.pageId || id === entry.section || id.startsWith(`${entry.section}/`);
|
|
359
|
+
if (matches) claimedIds.add(id);
|
|
360
|
+
return matches;
|
|
361
|
+
});
|
|
362
|
+
return { entry, pageIds };
|
|
363
|
+
});
|
|
364
|
+
tabs[0].pageIds.push(...ordered.filter((id) => !claimedIds.has(id)));
|
|
365
|
+
return {
|
|
366
|
+
tabs: tabs.map(({ entry, pageIds }) => ({
|
|
367
|
+
tab: entry.label,
|
|
368
|
+
href: entry.pageId === "introduction" ? "/" : `/${entry.pageId}`,
|
|
369
|
+
groups: groupsWithinSection(entry.section, [...new Set(pageIds)], entry.label)
|
|
370
|
+
}))
|
|
371
|
+
};
|
|
372
|
+
}
|
|
373
|
+
const sectionNames = [...new Set(ordered.filter((id) => id.includes("/")).map((id) => id.split("/", 1)[0]))];
|
|
374
|
+
if (sectionNames.length > 1) {
|
|
375
|
+
const defaultSection = sectionNames.includes("introduction") ? "introduction" : sectionNames[0];
|
|
376
|
+
const sections = /* @__PURE__ */ new Map();
|
|
377
|
+
for (const id of ordered) {
|
|
378
|
+
const section = id.includes("/") ? id.split("/", 1)[0] : defaultSection;
|
|
379
|
+
const bucket = sections.get(section) ?? [];
|
|
380
|
+
bucket.push(id);
|
|
381
|
+
sections.set(section, bucket);
|
|
382
|
+
}
|
|
383
|
+
return {
|
|
384
|
+
tabs: [...sections].map(([section, pageIds]) => {
|
|
385
|
+
const label = topLevelLabel(section);
|
|
386
|
+
const landingPage = preferredLandingPage(section, pageIds);
|
|
387
|
+
return {
|
|
388
|
+
tab: label,
|
|
389
|
+
...landingPage ? { href: landingPage === "introduction" ? "/" : `/${landingPage}` } : {},
|
|
390
|
+
groups: groupsWithinSection(section, pageIds)
|
|
391
|
+
};
|
|
392
|
+
})
|
|
393
|
+
};
|
|
394
|
+
}
|
|
395
|
+
}
|
|
314
396
|
const buckets = /* @__PURE__ */ new Map();
|
|
315
397
|
for (const id of ordered) {
|
|
316
398
|
const segment = id.includes("/") ? id.split("/", 1)[0] : "overview";
|
|
@@ -857,8 +939,12 @@ var LOCALE_CODES = /* @__PURE__ */ new Set([
|
|
|
857
939
|
"tr",
|
|
858
940
|
"uk",
|
|
859
941
|
"vi",
|
|
860
|
-
"zh"
|
|
942
|
+
"zh",
|
|
943
|
+
"pt-br",
|
|
944
|
+
"zh-hans",
|
|
945
|
+
"zh-hant"
|
|
861
946
|
]);
|
|
947
|
+
var PORTABLE_URL_PROPS = "href|src|img|primaryHref|secondaryHref";
|
|
862
948
|
function validateMigrationUrl(value) {
|
|
863
949
|
let url;
|
|
864
950
|
try {
|
|
@@ -921,6 +1007,27 @@ function docsScopePath(source) {
|
|
|
921
1007
|
const segments = path.split("/").filter(Boolean);
|
|
922
1008
|
return `/${segments.length > 1 ? segments[0] : segments.join("/")}`;
|
|
923
1009
|
}
|
|
1010
|
+
function machineIndexScopePath(source, documents) {
|
|
1011
|
+
const candidates = /* @__PURE__ */ new Set();
|
|
1012
|
+
for (const document of documents) {
|
|
1013
|
+
if (!document) continue;
|
|
1014
|
+
const references = [...headerLinks(document)];
|
|
1015
|
+
if (/html/i.test(document.contentType)) {
|
|
1016
|
+
const $ = load(document.body);
|
|
1017
|
+
references.push(...$("link[href], a[href]").map((_index, element) => $(element).attr("href") ?? "").get().filter((href) => /\/(?:llms(?:-full)?\.txt|sitemap\.xml)(?:[?#]|$)/i.test(href)));
|
|
1018
|
+
}
|
|
1019
|
+
for (const reference of references) {
|
|
1020
|
+
try {
|
|
1021
|
+
const indexUrl = new URL(reference, document.finalUrl);
|
|
1022
|
+
if (indexUrl.origin !== source.origin) continue;
|
|
1023
|
+
const scope = indexUrl.pathname.replace(/\/(?:llms(?:-full)?\.txt|sitemap\.xml)$/i, "") || "/";
|
|
1024
|
+
if (isInScope(source, source, scope)) candidates.add(scope);
|
|
1025
|
+
} catch {
|
|
1026
|
+
}
|
|
1027
|
+
}
|
|
1028
|
+
}
|
|
1029
|
+
return [...candidates].sort((left, right) => right.length - left.length)[0] ?? null;
|
|
1030
|
+
}
|
|
924
1031
|
function isInScope(url, source, scopePath) {
|
|
925
1032
|
if (url.origin !== source.origin || !["http:", "https:"].includes(url.protocol)) return false;
|
|
926
1033
|
const path = url.pathname.replace(/\/+$/, "") || "/";
|
|
@@ -932,6 +1039,8 @@ function normalizeCandidate(value, base, source, scopePath) {
|
|
|
932
1039
|
const url = new URL(value, base);
|
|
933
1040
|
url.hash = "";
|
|
934
1041
|
if (!isInScope(url, source, scopePath)) return null;
|
|
1042
|
+
if (url.pathname.startsWith("/cdn-cgi/")) return null;
|
|
1043
|
+
if (/\/(?:llms(?:-full)?|robots)\.txt$/i.test(url.pathname) || /\/sitemap\.xml$/i.test(url.pathname)) return null;
|
|
935
1044
|
if (/\.(?:avif|bmp|gif|ico|jpe?g|mp[34]|pdf|png|svg|webm|webp|zip)$/i.test(url.pathname)) return null;
|
|
936
1045
|
return url;
|
|
937
1046
|
} catch {
|
|
@@ -951,9 +1060,19 @@ function pageIdForUrl(url, scopePath) {
|
|
|
951
1060
|
}
|
|
952
1061
|
return pageIdFromReference(path.replace(/^\/+/, "") || "introduction");
|
|
953
1062
|
}
|
|
1063
|
+
function canonicalLocalizedPageId(id) {
|
|
1064
|
+
const [segment, ...rest] = id.split("/");
|
|
1065
|
+
if (LOCALE_CODES.has(segment)) return rest.length > 0 ? id : `${segment}/introduction`;
|
|
1066
|
+
for (const locale of LOCALE_CODES) {
|
|
1067
|
+
if (segment !== `${locale}-api-reference`) continue;
|
|
1068
|
+
return [locale, "api-reference", ...rest].join("/");
|
|
1069
|
+
}
|
|
1070
|
+
return id;
|
|
1071
|
+
}
|
|
954
1072
|
function detectUrlPlatform(document) {
|
|
955
|
-
const
|
|
956
|
-
|
|
1073
|
+
const headers = Object.entries(document.headers ?? {}).map(([key, value2]) => `${key}:${value2 ?? ""}`).join(" ");
|
|
1074
|
+
const value = `${document.body.slice(0, 2e5)} ${headers}`.toLowerCase();
|
|
1075
|
+
if (value.includes("__mintlify") || value.includes("/mintlify-assets/") || value.includes("x-mintlify-") || value.includes("/_mintlify/")) return "mintlify";
|
|
957
1076
|
if (value.includes("docusaurus") || value.includes("__docusaurus")) return "docusaurus";
|
|
958
1077
|
if (value.includes("gitbook") || value.includes("gitbook.io")) return "gitbook";
|
|
959
1078
|
if (value.includes("nextra")) return "nextra";
|
|
@@ -982,6 +1101,71 @@ function withoutFencedCode(body) {
|
|
|
982
1101
|
return fenceCharacter ? "" : line;
|
|
983
1102
|
}).join("\n");
|
|
984
1103
|
}
|
|
1104
|
+
function eventHandlerPropEnd(value, start) {
|
|
1105
|
+
const opening = value[start];
|
|
1106
|
+
if (opening === '"' || opening === "'") {
|
|
1107
|
+
for (let index = start + 1; index < value.length; index += 1) {
|
|
1108
|
+
if (value[index] === opening && value[index - 1] !== "\\") return index + 1;
|
|
1109
|
+
}
|
|
1110
|
+
return null;
|
|
1111
|
+
}
|
|
1112
|
+
if (opening !== "{") {
|
|
1113
|
+
const match = value.slice(start).match(/^[^\s>]+/);
|
|
1114
|
+
return match ? start + match[0].length : null;
|
|
1115
|
+
}
|
|
1116
|
+
let depth = 0;
|
|
1117
|
+
let quote = "";
|
|
1118
|
+
for (let index = start; index < value.length; index += 1) {
|
|
1119
|
+
const character = value[index];
|
|
1120
|
+
if (quote) {
|
|
1121
|
+
if (character === quote && value[index - 1] !== "\\") quote = "";
|
|
1122
|
+
continue;
|
|
1123
|
+
}
|
|
1124
|
+
if (character === '"' || character === "'" || character === "`") {
|
|
1125
|
+
quote = character;
|
|
1126
|
+
continue;
|
|
1127
|
+
}
|
|
1128
|
+
if (character === "{") depth += 1;
|
|
1129
|
+
if (character === "}") {
|
|
1130
|
+
depth -= 1;
|
|
1131
|
+
if (depth === 0) return index + 1;
|
|
1132
|
+
}
|
|
1133
|
+
}
|
|
1134
|
+
return null;
|
|
1135
|
+
}
|
|
1136
|
+
function stripEventHandlerProps(line) {
|
|
1137
|
+
const matcher = /\s+on[A-Z][A-Za-z0-9]*\s*=\s*/g;
|
|
1138
|
+
let cursor = 0;
|
|
1139
|
+
let result = "";
|
|
1140
|
+
for (const match of line.matchAll(matcher)) {
|
|
1141
|
+
const start = match.index;
|
|
1142
|
+
const valueStart = start + match[0].length;
|
|
1143
|
+
const end = eventHandlerPropEnd(line, valueStart);
|
|
1144
|
+
if (end === null) continue;
|
|
1145
|
+
result += line.slice(cursor, start);
|
|
1146
|
+
cursor = end;
|
|
1147
|
+
}
|
|
1148
|
+
return cursor === 0 ? line : `${result}${line.slice(cursor)}`;
|
|
1149
|
+
}
|
|
1150
|
+
function hasUnsafeUrlScheme(value) {
|
|
1151
|
+
const normalized = value.trim().replace(/[\u0000-\u0020]/g, "").replace(/&(?:#x0*3a|#0*58|colon);/gi, ":");
|
|
1152
|
+
return /^(?:javascript|data|vbscript):/i.test(normalized);
|
|
1153
|
+
}
|
|
1154
|
+
function hasUnsafePortableUrlProp(value) {
|
|
1155
|
+
const quotedProps = new RegExp(`\\b(?:${PORTABLE_URL_PROPS})\\s*=\\s*(['"])([^'"\\r\\n]*)\\1`, "gi");
|
|
1156
|
+
for (const match of value.matchAll(quotedProps)) {
|
|
1157
|
+
if (hasUnsafeUrlScheme(match[2])) return true;
|
|
1158
|
+
}
|
|
1159
|
+
const expressionProps = new RegExp(`\\b(?:${PORTABLE_URL_PROPS})\\s*=\\s*\\{\\s*("(?:\\\\.|[^"\\\\])*")\\s*\\}`, "gi");
|
|
1160
|
+
for (const match of value.matchAll(expressionProps)) {
|
|
1161
|
+
try {
|
|
1162
|
+
if (hasUnsafeUrlScheme(JSON.parse(match[1]))) return true;
|
|
1163
|
+
} catch {
|
|
1164
|
+
return true;
|
|
1165
|
+
}
|
|
1166
|
+
}
|
|
1167
|
+
return false;
|
|
1168
|
+
}
|
|
985
1169
|
function sanitizeRemoteMarkdown(body) {
|
|
986
1170
|
let fenceCharacter = "";
|
|
987
1171
|
let fenceLength = 0;
|
|
@@ -998,12 +1182,14 @@ function sanitizeRemoteMarkdown(body) {
|
|
|
998
1182
|
return line;
|
|
999
1183
|
}
|
|
1000
1184
|
if (fenceCharacter) return line;
|
|
1001
|
-
return line.replace(
|
|
1185
|
+
return stripEventHandlerProps(line.replace(/!\[([^\]]*)\]\(\s*([^)]+)\)/g, (original, alternative, destination) => {
|
|
1186
|
+
return hasUnsafeUrlScheme(destination.replace(/^<|>$/g, "")) ? alternative : original;
|
|
1187
|
+
}).replace(/<\/?div\b[^>]*>/gi, "").replace(/<img\s+([^>]*?)\/?\s*>/gi, (original, attributes) => {
|
|
1002
1188
|
const source = attributes.match(/\bsrc\s*=\s*(['"])(.*?)\1/i)?.[2];
|
|
1003
1189
|
const alternative = attributes.match(/\balt\s*=\s*(['"])(.*?)\1/i)?.[2] ?? "";
|
|
1004
|
-
if (!source ||
|
|
1190
|
+
if (!source || hasUnsafeUrlScheme(source)) return "";
|
|
1005
1191
|
return `![${alternative.replace(/]/g, "\\]")}](${source})`;
|
|
1006
|
-
});
|
|
1192
|
+
}));
|
|
1007
1193
|
}).join("\n");
|
|
1008
1194
|
const executable = withoutFencedCode(sanitized).replace(/\{\/\*[\s\S]*?\*\/\}/g, "").replace(/<(?:https?:\/\/|mailto:)[^>]+>/gi, "").replace(/(`+)[\s\S]*?\1/g, "");
|
|
1009
1195
|
if (/^\s*(?:import|export)\s/m.test(executable)) return null;
|
|
@@ -1017,27 +1203,31 @@ function sanitizeRemoteMarkdown(body) {
|
|
|
1017
1203
|
return original;
|
|
1018
1204
|
}
|
|
1019
1205
|
}).replace(/\\[{}]/g, "");
|
|
1020
|
-
if (hasUnsafeExpression || /[{}]/.test(withoutStaticProps) || /\bon[A-Z][A-Za-z]*\s*=/g.test(withoutStaticProps) ||
|
|
1206
|
+
if (hasUnsafeExpression || /[{}]/.test(withoutStaticProps) || /\bon[A-Z][A-Za-z]*\s*=/g.test(withoutStaticProps) || hasUnsafePortableUrlProp(executable)) return null;
|
|
1021
1207
|
for (const match of withoutStaticProps.matchAll(/<\/?([A-Za-z][A-Za-z0-9.]*)(?:\s|>|\/)/g)) {
|
|
1022
1208
|
const component = match[1].split(".", 1)[0];
|
|
1023
1209
|
if (!PORTABLE_MDX_COMPONENTS.has(component)) return null;
|
|
1024
1210
|
}
|
|
1025
1211
|
return sanitized;
|
|
1026
1212
|
}
|
|
1027
|
-
function migratedHref(href, currentUrl, source, scopePath, importedIds) {
|
|
1213
|
+
function migratedHref(href, currentUrl, source, scopePath, importedIds, sourceHomePageId) {
|
|
1028
1214
|
if (/^(?:javascript|data|vbscript):/i.test(href)) return "#";
|
|
1029
1215
|
if (href.startsWith("#") || /^(?:mailto|tel):/i.test(href)) return href;
|
|
1030
1216
|
try {
|
|
1031
1217
|
const target = new URL(href, currentUrl);
|
|
1032
1218
|
if (target.origin !== source.origin) return href;
|
|
1219
|
+
if (scopePath === "/" && candidateIdentity(target) === candidateIdentity(source)) {
|
|
1220
|
+
return `/${target.search}${target.hash}`;
|
|
1221
|
+
}
|
|
1033
1222
|
let path = target.pathname;
|
|
1034
1223
|
if (scopePath !== "/" && (path === scopePath || path.startsWith(`${scopePath}/`))) {
|
|
1035
1224
|
path = path.slice(scopePath.length);
|
|
1036
1225
|
}
|
|
1037
1226
|
const id = pageIdFromReference(path.replace(/^\/+/, "") || "introduction");
|
|
1038
|
-
const localizedId = id
|
|
1039
|
-
|
|
1040
|
-
|
|
1227
|
+
const localizedId = id ? canonicalLocalizedPageId(id) : id;
|
|
1228
|
+
const destinationId = localizedId === sourceHomePageId ? "introduction" : localizedId;
|
|
1229
|
+
if (destinationId && importedIds.has(destinationId)) {
|
|
1230
|
+
const destination = destinationId === "introduction" ? "/" : `/${destinationId}`;
|
|
1041
1231
|
return `${destination}${target.search}${target.hash}`;
|
|
1042
1232
|
}
|
|
1043
1233
|
return target.toString();
|
|
@@ -1045,13 +1235,13 @@ function migratedHref(href, currentUrl, source, scopePath, importedIds) {
|
|
|
1045
1235
|
return href;
|
|
1046
1236
|
}
|
|
1047
1237
|
}
|
|
1048
|
-
function rewriteInternalLinks(body, currentUrl, source, scopePath, importedIds) {
|
|
1238
|
+
function rewriteInternalLinks(body, currentUrl, source, scopePath, importedIds, sourceHomePageId) {
|
|
1049
1239
|
const markdown = body.replace(/(?<!!)\[([^\]]+)\]\(([^)\s]+)(\s+['"][^'"]*['"])?\)/g, (original, label, href, title = "") => {
|
|
1050
|
-
const destination = migratedHref(href, currentUrl, source, scopePath, importedIds);
|
|
1240
|
+
const destination = migratedHref(href, currentUrl, source, scopePath, importedIds, sourceHomePageId);
|
|
1051
1241
|
return destination === href ? original : `[${label}](${destination}${title})`;
|
|
1052
1242
|
});
|
|
1053
1243
|
return markdown.replace(/\bhref=(['"])([^'"]+)\1/g, (_original, quote, href) => {
|
|
1054
|
-
const destination = migratedHref(href, currentUrl, source, scopePath, importedIds);
|
|
1244
|
+
const destination = migratedHref(href, currentUrl, source, scopePath, importedIds, sourceHomePageId);
|
|
1055
1245
|
return `href=${quote}${destination}${quote}`;
|
|
1056
1246
|
});
|
|
1057
1247
|
}
|
|
@@ -1080,17 +1270,35 @@ function remoteMarkdownMetadata(body) {
|
|
|
1080
1270
|
description: scalar("description")
|
|
1081
1271
|
};
|
|
1082
1272
|
}
|
|
1273
|
+
function stripMintlifyDocumentationIndex(body) {
|
|
1274
|
+
const lines = body.split(/\r?\n/);
|
|
1275
|
+
if (!/^>\s*##\s+Documentation Index\s*$/i.test(lines[0] ?? "") || !/^>.*\/llms(?:-full)?\.txt/i.test(lines[1] ?? "") || !/^>.*discover all available pages/i.test(lines[2] ?? "")) return body;
|
|
1276
|
+
let index = 3;
|
|
1277
|
+
while (index < lines.length && /^>/.test(lines[index])) index += 1;
|
|
1278
|
+
while (index < lines.length && lines[index].trim() === "") index += 1;
|
|
1279
|
+
return lines.slice(index).join("\n");
|
|
1280
|
+
}
|
|
1083
1281
|
function markdownPage(document, id) {
|
|
1084
1282
|
const parsed = remoteMarkdownMetadata(document.body);
|
|
1085
|
-
|
|
1283
|
+
let content = stripMintlifyDocumentationIndex(parsed.content).trimStart();
|
|
1284
|
+
const titleMatch = content.match(/^#\s+(.+)\r?\n/);
|
|
1086
1285
|
const title = parsed.title ?? titleMatch?.[1] ?? id.split("/").at(-1) ?? "Introduction";
|
|
1286
|
+
if (titleMatch) content = content.slice(titleMatch[0].length).trimStart();
|
|
1287
|
+
let description = parsed.description;
|
|
1288
|
+
if (!description) {
|
|
1289
|
+
const quoteMatch = content.match(/^(>[^\r\n]*(?:\r?\n>[^\r\n]*)*)\r?\n/);
|
|
1290
|
+
if (quoteMatch) {
|
|
1291
|
+
description = plainDescription(quoteMatch[1].replace(/^>\s?/gm, ""));
|
|
1292
|
+
content = content.slice(quoteMatch[0].length).trimStart();
|
|
1293
|
+
}
|
|
1294
|
+
}
|
|
1087
1295
|
const raw = [
|
|
1088
1296
|
"---",
|
|
1089
1297
|
`title: ${JSON.stringify(title)}`,
|
|
1090
|
-
...
|
|
1298
|
+
...description ? [`description: ${JSON.stringify(description)}`] : [],
|
|
1091
1299
|
"---",
|
|
1092
1300
|
"",
|
|
1093
|
-
|
|
1301
|
+
content
|
|
1094
1302
|
].join("\n");
|
|
1095
1303
|
return parseMarkdownPage({ id, raw, source: document.finalUrl.toString() });
|
|
1096
1304
|
}
|
|
@@ -1166,6 +1374,48 @@ ${fence}
|
|
|
1166
1374
|
links
|
|
1167
1375
|
};
|
|
1168
1376
|
}
|
|
1377
|
+
function htmlNavigationLinks(document) {
|
|
1378
|
+
const $ = load(document.body);
|
|
1379
|
+
return $('.nav-tabs a[href], nav a[href], aside a[href], [role="navigation"] a[href]').map((_index, element) => $(element).attr("href") ?? "").get().filter(Boolean);
|
|
1380
|
+
}
|
|
1381
|
+
function htmlTopLevelNavigation(document, source, scopePath) {
|
|
1382
|
+
const $ = load(document.body);
|
|
1383
|
+
const collectCandidates = (selector) => {
|
|
1384
|
+
const candidates2 = [];
|
|
1385
|
+
$(selector).each((_containerIndex, container) => {
|
|
1386
|
+
const entries = [];
|
|
1387
|
+
const seenSections = /* @__PURE__ */ new Set();
|
|
1388
|
+
let anchorCount = 0;
|
|
1389
|
+
$(container).find("a[href]").each((_index, element) => {
|
|
1390
|
+
const label = $(element).text().replace(/\s+/g, " ").trim();
|
|
1391
|
+
const href = $(element).attr("href");
|
|
1392
|
+
if (!label || !href) return;
|
|
1393
|
+
try {
|
|
1394
|
+
const target = new URL(href, document.finalUrl);
|
|
1395
|
+
if (!isInScope(target, source, scopePath)) return;
|
|
1396
|
+
anchorCount += 1;
|
|
1397
|
+
const targetId = canonicalLocalizedPageId(pageIdForUrl(target, scopePath) ?? "");
|
|
1398
|
+
const pageId = targetId;
|
|
1399
|
+
const section = targetId.split("/", 1)[0] || "introduction";
|
|
1400
|
+
if (!pageId || seenSections.has(section)) return;
|
|
1401
|
+
seenSections.add(section);
|
|
1402
|
+
entries.push({ section, label, pageId });
|
|
1403
|
+
} catch {
|
|
1404
|
+
}
|
|
1405
|
+
});
|
|
1406
|
+
if (entries.length > 1) {
|
|
1407
|
+
candidates2.push({ entries, anchorCount });
|
|
1408
|
+
}
|
|
1409
|
+
});
|
|
1410
|
+
return candidates2;
|
|
1411
|
+
};
|
|
1412
|
+
const tabCandidates = collectCandidates(".nav-tabs");
|
|
1413
|
+
const candidates = tabCandidates.length > 0 ? tabCandidates : collectCandidates('nav, [role="navigation"]');
|
|
1414
|
+
return candidates.sort((left, right) => {
|
|
1415
|
+
const densityDifference = right.entries.length / right.anchorCount - left.entries.length / left.anchorCount;
|
|
1416
|
+
return densityDifference || right.entries.length - left.entries.length;
|
|
1417
|
+
})[0]?.entries ?? [];
|
|
1418
|
+
}
|
|
1169
1419
|
function markdownLinks(body) {
|
|
1170
1420
|
return [...body.matchAll(/\[[^\]]+\]\(([^)\s]+)(?:\s+['"][^'"]*['"])?\)/g)].map((match) => match[1]);
|
|
1171
1421
|
}
|
|
@@ -1199,12 +1449,17 @@ async function migrateUrl(options) {
|
|
|
1199
1449
|
const maxPages = Math.max(1, Math.min(options.maxPages ?? DEFAULT_MAX_PAGES, 1e3));
|
|
1200
1450
|
const concurrency = Math.max(1, Math.min(options.concurrency ?? 5, 10));
|
|
1201
1451
|
const maxTotalBytes = Math.max(1e6, Math.min(options.maxTotalBytes ?? DEFAULT_MAX_TOTAL_BYTES, 5e8));
|
|
1202
|
-
const
|
|
1452
|
+
const submittedScopePath = docsScopePath(source);
|
|
1203
1453
|
const initial = await fetcher(source, { accept: "text/markdown,text/html,application/xhtml+xml;q=0.9" });
|
|
1204
|
-
if (!isInScope(initial.finalUrl, source,
|
|
1454
|
+
if (!isInScope(initial.finalUrl, source, submittedScopePath)) {
|
|
1205
1455
|
throw new Error("The documentation URL redirected outside the submitted docs origin or path.");
|
|
1206
1456
|
}
|
|
1207
|
-
const
|
|
1457
|
+
const htmlProbe = /html/i.test(initial.contentType) ? initial : await safeFetch(fetcher, source, "text/html,application/xhtml+xml");
|
|
1458
|
+
const scopedHtmlProbe = htmlProbe && isInScope(htmlProbe.finalUrl, source, submittedScopePath) ? htmlProbe : null;
|
|
1459
|
+
const platform = detectUrlPlatform(scopedHtmlProbe ?? initial);
|
|
1460
|
+
const scopePath = platform === "mintlify" ? machineIndexScopePath(source, [initial, scopedHtmlProbe]) ?? submittedScopePath : submittedScopePath;
|
|
1461
|
+
const sourceTopLevelNavigation = platform === "mintlify" && scopedHtmlProbe && /html/i.test(scopedHtmlProbe.contentType) ? htmlTopLevelNavigation(scopedHtmlProbe, source, scopePath) : void 0;
|
|
1462
|
+
const sourceHomePageId = sourceTopLevelNavigation?.[0]?.pageId ?? (platform === "mintlify" && scopePath === "/" ? canonicalLocalizedPageId(pageIdForUrl(source, scopePath) ?? "") || void 0 : void 0);
|
|
1208
1463
|
const cache = /* @__PURE__ */ new Map([[source.toString(), initial]]);
|
|
1209
1464
|
const queue = [source];
|
|
1210
1465
|
const queued = /* @__PURE__ */ new Set([candidateIdentity(source)]);
|
|
@@ -1217,6 +1472,9 @@ async function migrateUrl(options) {
|
|
|
1217
1472
|
queued.add(candidateIdentity(url));
|
|
1218
1473
|
queue.push(url);
|
|
1219
1474
|
}
|
|
1475
|
+
if (scopedHtmlProbe && /html/i.test(scopedHtmlProbe.contentType)) {
|
|
1476
|
+
for (const link of htmlNavigationLinks(scopedHtmlProbe)) enqueue(link, scopedHtmlProbe.finalUrl);
|
|
1477
|
+
}
|
|
1220
1478
|
async function discoverDocumentLinks(document, depth = 0) {
|
|
1221
1479
|
const links = sitemapLinks(document.body);
|
|
1222
1480
|
for (const link of links) {
|
|
@@ -1283,6 +1541,7 @@ async function migrateUrl(options) {
|
|
|
1283
1541
|
}
|
|
1284
1542
|
const pages = [];
|
|
1285
1543
|
const seenIds = /* @__PURE__ */ new Set();
|
|
1544
|
+
const seenSources = /* @__PURE__ */ new Set();
|
|
1286
1545
|
const visited = /* @__PURE__ */ new Set();
|
|
1287
1546
|
let importedBytes = 0;
|
|
1288
1547
|
let isByteBudgetExhausted = false;
|
|
@@ -1320,6 +1579,8 @@ async function migrateUrl(options) {
|
|
|
1320
1579
|
const htmlDocument = await safeFetch(fetcher, htmlUrl, "text/html,application/xhtml+xml");
|
|
1321
1580
|
if (htmlDocument && isInScope(htmlDocument.finalUrl, source, scopePath) && /html/i.test(htmlDocument.contentType)) {
|
|
1322
1581
|
document = htmlDocument;
|
|
1582
|
+
} else {
|
|
1583
|
+
return { candidate, page: null, links: [], failure: false };
|
|
1323
1584
|
}
|
|
1324
1585
|
} else if (sanitizedMarkdown !== null) {
|
|
1325
1586
|
document = { ...document, body: sanitizedMarkdown };
|
|
@@ -1330,7 +1591,8 @@ async function migrateUrl(options) {
|
|
|
1330
1591
|
return { candidate, page: null, links: [], failure: false, budgetExceeded: true };
|
|
1331
1592
|
}
|
|
1332
1593
|
importedBytes += responseBytes;
|
|
1333
|
-
const
|
|
1594
|
+
const discoveredId = pageIdForUrl(document.finalUrl, scopePath) ?? pageIdForUrl(candidate, scopePath);
|
|
1595
|
+
const id = discoveredId && canonicalLocalizedPageId(discoveredId) === sourceHomePageId ? "introduction" : discoveredId;
|
|
1334
1596
|
if (!id) return { candidate, page: null, links: [], failure: false };
|
|
1335
1597
|
if (/(?:markdown|text\/plain)/i.test(document.contentType) || /\.mdx?$/i.test(document.finalUrl.pathname)) {
|
|
1336
1598
|
return {
|
|
@@ -1350,9 +1612,12 @@ async function migrateUrl(options) {
|
|
|
1350
1612
|
continue;
|
|
1351
1613
|
}
|
|
1352
1614
|
if (result.budgetExceeded) continue;
|
|
1353
|
-
if (result.page
|
|
1615
|
+
if (result.page) result.page.id = canonicalLocalizedPageId(result.page.id);
|
|
1616
|
+
const sourceIdentity = result.page ? candidateIdentity(new URL(result.page.source)) : null;
|
|
1617
|
+
if (result.page && sourceIdentity && !seenSources.has(sourceIdentity) && !seenIds.has(result.page.id) && pages.length < maxPages) {
|
|
1354
1618
|
pages.push(result.page);
|
|
1355
1619
|
seenIds.add(result.page.id);
|
|
1620
|
+
seenSources.add(sourceIdentity);
|
|
1356
1621
|
}
|
|
1357
1622
|
for (const link of result.links) enqueue(link, result.base ?? result.candidate);
|
|
1358
1623
|
}
|
|
@@ -1368,14 +1633,28 @@ async function migrateUrl(options) {
|
|
|
1368
1633
|
}
|
|
1369
1634
|
const importedIds = new Set(pages.map((page) => page.id));
|
|
1370
1635
|
for (const page of pages) {
|
|
1371
|
-
page.body = rewriteInternalLinks(
|
|
1636
|
+
page.body = rewriteInternalLinks(
|
|
1637
|
+
page.body,
|
|
1638
|
+
new URL(page.source),
|
|
1639
|
+
source,
|
|
1640
|
+
scopePath,
|
|
1641
|
+
importedIds,
|
|
1642
|
+
sourceHomePageId
|
|
1643
|
+
);
|
|
1372
1644
|
}
|
|
1373
1645
|
if (isByteBudgetExhausted) {
|
|
1374
1646
|
warnings.push({ code: "limit-reached", message: `Import stopped after reaching the ${Math.round(maxTotalBytes / 1e6)} MB content budget.` });
|
|
1375
1647
|
} else if (queue.length > 0 || queued.size >= MAX_DISCOVERED_URLS) {
|
|
1376
1648
|
warnings.push({ code: "limit-reached", message: `Import stopped after ${pages.length} pages; narrow the URL or raise the caller limit to import more.` });
|
|
1377
1649
|
}
|
|
1378
|
-
const
|
|
1650
|
+
const topLevelNavigation = sourceTopLevelNavigation?.map((entry) => ({
|
|
1651
|
+
...entry,
|
|
1652
|
+
pageId: entry.pageId === sourceHomePageId ? "introduction" : entry.pageId
|
|
1653
|
+
}));
|
|
1654
|
+
const docsConfig = buildNavigationFromPages(pages, {
|
|
1655
|
+
topLevelTabs: platform === "mintlify",
|
|
1656
|
+
topLevelNavigation
|
|
1657
|
+
});
|
|
1379
1658
|
const locales = [...new Set(pages.map((page) => page.locale).filter((value) => Boolean(value)))];
|
|
1380
1659
|
if (locales.length > 0) {
|
|
1381
1660
|
docsConfig.i18n = {
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/repository.ts","../src/mdx.ts","../src/navigation.ts","../src/path.ts","../src/render.ts","../src/url.ts"],"sourcesContent":["/**\n * Repository adapter for the shared migration engine. Traversal is bounded,\n * symbolic links are ignored, and Git is always invoked with an argument array\n * so source-controlled branch names can never become shell commands.\n */\n\nimport { spawn } from 'node:child_process'\nimport {\n existsSync,\n lstatSync,\n readFileSync,\n readdirSync,\n} from 'node:fs'\nimport { basename, dirname, extname, relative } from 'node:path'\n\nimport { parseMarkdownPage } from './mdx.js'\nimport {\n buildNavigationFromPages,\n isDocumentationExtension,\n projectMintlifyNavigation,\n readMintlifyConfig,\n} from './navigation.js'\nimport { normalizeAssetPath, pageIdFromReference, resolveWithin } from './path.js'\nimport type {\n MigrationAsset,\n MigrationBundle,\n MigrationDocsConfig,\n MigrationPage,\n MigrationPlatform,\n MigrationWarning,\n} from './types.js'\n\nconst MAX_SOURCE_FILES = 5_000\nconst MAX_PAGE_BYTES = 2_000_000\nconst MAX_ASSET_BYTES = 25_000_000\nconst MAX_TOTAL_ASSET_BYTES = 100_000_000\nconst IGNORED_DIRECTORIES = new Set([\n '.git', '.github', '.next', '.turbo', '.vercel', '.vscode',\n 'node_modules', 'dist', 'build', 'coverage',\n])\nconst ASSET_DIRECTORIES = new Set(['assets', 'images', 'img', 'media', 'public', 'static'])\nconst ASSET_EXTENSIONS = new Set([\n '.avif', '.bmp', '.gif', '.ico', '.jpeg', '.jpg', '.mp3', '.mp4',\n '.pdf', '.png', '.svg', '.webm', '.webp',\n])\nconst REPOSITORY_ONLY_DOCUMENTS = new Set([\n 'agents.md', 'claude.md', 'code_of_conduct.md', 'contributing.md',\n 'license.md', 'readme.md', 'security.md',\n])\nconst SNIPPET_DIRECTORIES = new Set(['snippets', '_snippets', 'partials', '_partials'])\nconst OPENAPI_FILENAMES = new Set([\n 'openapi.json', 'openapi.yaml', 'openapi.yml',\n 'swagger.json', 'swagger.yaml', 'swagger.yml',\n])\n\nexport interface GitHubRepositorySource {\n owner: string\n repo: string\n branch: string\n docsDir: string\n cloneUrl: string\n}\n\nexport interface RepositoryMigrationOptions {\n repositoryDir: string\n sourceUrl: string\n docsDir?: string\n platform?: MigrationPlatform\n}\n\n/** Parse and validate a public GitHub repository URL. */\nexport function parseGitHubRepositoryUrl(rawUrl: string): GitHubRepositorySource {\n let url: URL\n try {\n url = new URL(rawUrl)\n } catch {\n throw new Error(`Invalid GitHub URL: ${rawUrl}`)\n }\n if (url.protocol !== 'https:' || url.hostname.toLowerCase() !== 'github.com') {\n throw new Error('Repository migrations require an https://github.com URL.')\n }\n if (url.username || url.password || url.port) {\n throw new Error('GitHub repository URLs cannot include credentials or custom ports.')\n }\n const segments = url.pathname.split('/').filter(Boolean).map(decodeURIComponent)\n const [owner, rawRepo] = segments\n const repo = rawRepo?.replace(/\\.git$/i, '')\n const safeName = /^[A-Za-z0-9_.-]+$/\n if (!owner || !repo || !safeName.test(owner) || !safeName.test(repo)) {\n throw new Error('GitHub URL must include a valid owner and repository name.')\n }\n let branch = 'HEAD'\n let docsDir = ''\n if (segments[2] === 'tree' && segments[3]) {\n branch = segments[3]\n docsDir = segments.slice(4).join('/')\n }\n return {\n owner,\n repo,\n branch,\n docsDir,\n cloneUrl: `https://github.com/${owner}/${repo}.git`,\n }\n}\n\n/** Clone a repository without a shell; callers own and remove `targetDir`. */\nexport async function cloneGitHubRepository(\n source: GitHubRepositorySource,\n targetDir: string,\n): Promise<void> {\n const args = ['clone', '--depth', '1', '--single-branch']\n if (source.branch !== 'HEAD') args.push('--branch', source.branch)\n args.push('--', source.cloneUrl, targetDir)\n await new Promise<void>((resolve, reject) => {\n const child = spawn('git', args, { stdio: ['ignore', 'ignore', 'pipe'] })\n let stderr = ''\n child.stderr.setEncoding('utf8')\n child.stderr.on('data', (chunk: string) => {\n if (stderr.length < 16_000) stderr += chunk\n })\n child.on('error', reject)\n child.on('close', (code) => {\n if (code === 0) resolve()\n else reject(new Error(`Failed to clone ${source.owner}/${source.repo}: ${stderr.trim() || `git exited ${code}`}`))\n })\n })\n}\n\n/** Detect a supported repository docs platform from unambiguous config files. */\nexport function detectRepositoryPlatform(repositoryDir: string): MigrationPlatform {\n if (existsSync(resolveWithin(repositoryDir, 'mint.json'))) return 'mintlify'\n const docsJson = resolveWithin(repositoryDir, 'docs.json')\n if (existsSync(docsJson)) {\n try {\n const config = JSON.parse(readFileSync(docsJson, 'utf8')) as Record<string, unknown>\n if (String(config.$schema ?? '').includes('mintlify') || 'navigation' in config) return 'mintlify'\n if (Array.isArray(config.tabs)) return 'thally'\n } catch {\n // A malformed source config is reported later; platform detection falls through.\n }\n }\n if (['docusaurus.config.js', 'docusaurus.config.ts', 'docusaurus.config.mjs']\n .some((name) => existsSync(resolveWithin(repositoryDir, name)))) return 'docusaurus'\n if (existsSync(resolveWithin(repositoryDir, 'SUMMARY.md'))) return 'gitbook'\n if (existsSync(resolveWithin(repositoryDir, '.vitepress'))) return 'vitepress'\n if (['astro.config.mjs', 'astro.config.ts']\n .some((name) => existsSync(resolveWithin(repositoryDir, name)))) return 'starlight'\n if (['pages/_meta.json', '_meta.json']\n .some((name) => existsSync(resolveWithin(repositoryDir, name)))) return 'nextra'\n return 'unknown'\n}\n\nfunction containsMarkdown(directory: string, depth = 0): boolean {\n if (depth > 4) return false\n for (const entry of readdirSync(directory, { withFileTypes: true })) {\n if (IGNORED_DIRECTORIES.has(entry.name) || entry.isSymbolicLink()) continue\n const path = resolveWithin(directory, entry.name)\n if (entry.isFile() && ['.md', '.mdx'].includes(extname(entry.name).toLowerCase())) return true\n if (entry.isDirectory() && containsMarkdown(path, depth + 1)) return true\n }\n return false\n}\n\n/** Pick the first conventional content root containing Markdown. */\nexport function detectRepositoryDocsDir(repositoryDir: string): string {\n for (const candidate of ['docs', 'documentation', 'content', 'pages', 'src/content', 'src/pages', 'guide', 'guides', '']) {\n const path = resolveWithin(repositoryDir, candidate)\n if (existsSync(path) && lstatSync(path).isDirectory() && containsMarkdown(path)) return candidate\n }\n return ''\n}\n\ninterface ScannedFile {\n absolutePath: string\n relativePath: string\n}\n\nfunction scanFiles(root: string): Array<ScannedFile> {\n const files: Array<ScannedFile> = []\n function visit(directory: string): void {\n if (files.length >= MAX_SOURCE_FILES) return\n for (const entry of readdirSync(directory, { withFileTypes: true })) {\n if (files.length >= MAX_SOURCE_FILES) return\n if (IGNORED_DIRECTORIES.has(entry.name) || entry.isSymbolicLink()) continue\n const path = resolveWithin(directory, entry.name)\n if (entry.isDirectory()) visit(path)\n else if (entry.isFile()) files.push({ absolutePath: path, relativePath: relative(root, path).replace(/\\\\/g, '/') })\n }\n }\n visit(root)\n return files\n}\n\nfunction normalizedReferenceKey(value: string): string {\n return value.split(/[?#]/, 1)[0]\n .replace(/^\\/+/, '')\n .replace(/\\\\/g, '/')\n .replace(/\\.(?:mdx?|rst|txt)$/i, '')\n .replace(/\\/(?:index|readme)$/i, '')\n .replace(/^(?:index|readme)$/i, '') || 'introduction'\n}\n\nfunction findOpenApi(files: Array<ScannedFile>): ScannedFile | null {\n return files.find((file) => OPENAPI_FILENAMES.has(basename(file.relativePath).toLowerCase())) ?? null\n}\n\nfunction withoutFrontmatter(value: string): string {\n return value.replace(/^---\\r?\\n[\\s\\S]*?\\r?\\n---\\r?\\n?/, '').trim()\n}\n\nfunction inlineMdxSnippets(\n raw: string,\n currentFile: string,\n repositoryRoot: string,\n warnings: Array<MigrationWarning>,\n depth = 0,\n): string {\n if (depth >= 8) return raw\n const snippets = new Map<string, string>()\n const withoutImports = raw.replace(\n /^import\\s+([A-Z][A-Za-z0-9_]*)\\s+from\\s+['\"]([^'\"]+\\.mdx?)['\"]\\s*;?\\s*$/gm,\n (_statement, componentName: string, sourcePath: string) => {\n try {\n const candidate = sourcePath.startsWith('/')\n ? resolveWithin(repositoryRoot, sourcePath.replace(/^\\/+/, ''))\n : resolveWithin(dirname(currentFile), sourcePath)\n // Prove a relative import resolved under the repository, not merely\n // under the current directory's parent chain.\n resolveWithin(repositoryRoot, relative(repositoryRoot, candidate))\n if (!existsSync(candidate) || !lstatSync(candidate).isFile()) throw new Error('file not found')\n const nested = inlineMdxSnippets(\n withoutFrontmatter(readFileSync(candidate, 'utf8')),\n candidate,\n repositoryRoot,\n warnings,\n depth + 1,\n )\n snippets.set(componentName, nested)\n return ''\n } catch {\n warnings.push({\n code: 'missing-page',\n message: `Imported snippet ${sourcePath} could not be resolved and was left as a comment.`,\n source: relative(repositoryRoot, currentFile).replace(/\\\\/g, '/'),\n })\n snippets.set(componentName, `{/* Missing imported snippet: ${sourcePath} */}`)\n return ''\n }\n },\n )\n let result = withoutImports\n for (const [componentName, snippet] of snippets) {\n result = result\n .replace(new RegExp(`<${componentName}(?:\\\\s[^>]*)?\\\\s*/>`, 'g'), snippet)\n .replace(new RegExp(`<${componentName}(?:\\\\s[^>]*)?>(?:[\\\\s\\\\S]*?)<\\\\/${componentName}>`, 'g'), snippet)\n }\n return result\n}\n\nfunction injectOpenApi(config: MigrationDocsConfig, filename: string): MigrationDocsConfig {\n const tabs = config.tabs.filter((tab) => !tab.tab.toLowerCase().includes('api'))\n const apiTab: MigrationDocsConfig['tabs'][number] = {\n tab: 'API Reference',\n api: { source: `/${filename}` },\n }\n const changelog = tabs.findIndex((tab) => tab.tab.toLowerCase() === 'changelog')\n if (changelog >= 0) tabs.splice(changelog, 0, apiTab)\n else tabs.push(apiTab)\n return { ...config, tabs }\n}\n\n/** Import an already-available repository directory into a canonical bundle. */\nexport function migrateRepository(options: RepositoryMigrationOptions): MigrationBundle {\n const repositoryDir = options.repositoryDir\n const platform = options.platform ?? detectRepositoryPlatform(repositoryDir)\n const warnings: Array<MigrationWarning> = []\n let docsConfig: MigrationDocsConfig = { tabs: [] }\n const referenceMap = new Map<string, { navigationId: string; locale?: string }>()\n const referenceOrder = new Map<string, number>()\n\n if (platform === 'mintlify') {\n try {\n const config = readMintlifyConfig(repositoryDir)\n if (config) {\n const projected = projectMintlifyNavigation(config)\n docsConfig = projected.docsConfig\n warnings.push(...projected.warnings)\n for (const [index, reference] of projected.pageReferences.entries()) {\n const key = normalizedReferenceKey(reference.ref)\n referenceMap.set(key, reference)\n referenceOrder.set(key, index)\n }\n }\n } catch (error) {\n warnings.push({\n code: 'unsupported-config',\n message: `Mintlify config could not be read: ${error instanceof Error ? error.message : String(error)}`,\n })\n }\n }\n\n const configuredDocsDir = options.docsDir ?? (platform === 'mintlify' ? '' : detectRepositoryDocsDir(repositoryDir))\n const contentRoot = resolveWithin(repositoryDir, configuredDocsDir)\n if (!existsSync(contentRoot) || !lstatSync(contentRoot).isDirectory()) {\n throw new Error(`Documentation directory does not exist: ${configuredDocsDir || '.'}`)\n }\n const files = scanFiles(contentRoot)\n const pages: Array<MigrationPage> = []\n const assets: Array<MigrationAsset> = []\n const seenPageIds = new Set<string>()\n let skipped = 0\n\n const localeConfig = docsConfig.i18n\n const pageFiles = [...files].sort((left, right) => {\n const leftOrder = referenceOrder.get(normalizedReferenceKey(left.relativePath)) ?? Number.MAX_SAFE_INTEGER\n const rightOrder = referenceOrder.get(normalizedReferenceKey(right.relativePath)) ?? Number.MAX_SAFE_INTEGER\n return leftOrder - rightOrder || left.relativePath.localeCompare(right.relativePath)\n })\n for (const file of pageFiles) {\n if (!isDocumentationExtension(file.relativePath)) continue\n if (file.relativePath.split('/').some((segment) => SNIPPET_DIRECTORIES.has(segment.toLowerCase()))) {\n skipped++\n continue\n }\n const rootFilename = !file.relativePath.includes('/') ? basename(file.relativePath).toLowerCase() : ''\n if (REPOSITORY_ONLY_DOCUMENTS.has(rootFilename)) {\n skipped++\n continue\n }\n if (!['.md', '.mdx'].includes(extname(file.relativePath).toLowerCase())) {\n skipped++\n warnings.push({ code: 'skipped-file', message: 'Only Markdown and MDX are imported without an explicit converter.', source: file.relativePath })\n continue\n }\n const size = lstatSync(file.absolutePath).size\n if (size > MAX_PAGE_BYTES) {\n skipped++\n warnings.push({ code: 'skipped-file', message: 'Page exceeded the 2 MB repository import limit.', source: file.relativePath })\n continue\n }\n const key = normalizedReferenceKey(file.relativePath)\n const referenced = referenceMap.get(key)\n let locale = referenced?.locale\n let navigationId = referenced?.navigationId ?? pageIdFromReference(file.relativePath)\n if (!referenced && localeConfig) {\n const prefix = file.relativePath.split('/', 1)[0]\n if (localeConfig.locales.some((entry) => entry.code === prefix)) {\n locale = prefix\n navigationId = pageIdFromReference(file.relativePath.slice(prefix.length + 1))\n }\n }\n if (!navigationId) {\n skipped++\n warnings.push({ code: 'invalid-page', message: 'Page path could not be normalized safely.', source: file.relativePath })\n continue\n }\n const isDefaultLocale = !locale || locale === localeConfig?.defaultLocale\n const id = isDefaultLocale ? navigationId : `${locale}/${navigationId}`\n if (seenPageIds.has(id)) {\n skipped++\n warnings.push({ code: 'collision', message: `Multiple source files map to ${id}; the first file was kept.`, source: file.relativePath })\n continue\n }\n const raw = inlineMdxSnippets(\n readFileSync(file.absolutePath, 'utf8'),\n file.absolutePath,\n repositoryDir,\n warnings,\n )\n const page = parseMarkdownPage({\n id,\n navigationId,\n ...(locale ? { locale } : {}),\n raw,\n source: `${options.sourceUrl}#${file.relativePath}`,\n })\n if (!page) {\n skipped++\n continue\n }\n seenPageIds.add(id)\n pages.push(page)\n }\n\n const discoveredReferenceKeys = new Set(files.map((file) => normalizedReferenceKey(file.relativePath)))\n for (const [key] of referenceMap) {\n if (!discoveredReferenceKeys.has(key)) {\n warnings.push({ code: 'missing-page', message: 'A navigation entry did not resolve to a source page.', source: key })\n }\n }\n\n let totalAssetBytes = 0\n for (const file of files) {\n const firstSegment = file.relativePath.split('/', 1)[0].toLowerCase()\n if (!ASSET_DIRECTORIES.has(firstSegment) || !ASSET_EXTENSIONS.has(extname(file.relativePath).toLowerCase())) continue\n const size = lstatSync(file.absolutePath).size\n if (size > MAX_ASSET_BYTES || totalAssetBytes + size > MAX_TOTAL_ASSET_BYTES) {\n warnings.push({ code: 'limit-reached', message: 'An asset was skipped because the migration asset budget was exhausted.', source: file.relativePath })\n continue\n }\n const assetPath = normalizeAssetPath(firstSegment === 'public'\n ? file.relativePath.slice('public/'.length)\n : file.relativePath)\n if (!assetPath) continue\n assets.push({ path: assetPath, content: readFileSync(file.absolutePath) })\n totalAssetBytes += size\n }\n\n if (files.length >= MAX_SOURCE_FILES) {\n warnings.push({ code: 'limit-reached', message: `Repository discovery stopped at ${MAX_SOURCE_FILES} files.` })\n }\n if (docsConfig.tabs.length === 0) docsConfig = buildNavigationFromPages(pages)\n const openApi = findOpenApi(files)\n if (openApi) {\n const filename = basename(openApi.relativePath)\n if (!assets.some((asset) => asset.path === filename)) {\n assets.push({ path: filename, content: readFileSync(openApi.absolutePath) })\n }\n docsConfig = injectOpenApi(docsConfig, filename)\n }\n\n if (pages.length === 0) throw new Error('No importable Markdown or MDX pages were found in the repository.')\n return {\n sourceUrl: options.sourceUrl,\n sourceKind: 'repository',\n platform,\n pages,\n assets,\n docsConfig,\n warnings,\n stats: { discovered: files.length, imported: pages.length, skipped },\n }\n}\n","/** Markdown/MDX normalization that preserves every component Thally supports. */\n\nimport matter from 'gray-matter'\n\nimport type { MigrationPage } from './types.js'\n\nfunction titleFromId(id: string): string {\n const value = id.split('/').at(-1) ?? id\n if (value === 'introduction') return 'Introduction'\n return value\n .split(/[-_]/)\n .filter(Boolean)\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1))\n .join(' ')\n}\n\nfunction firstParagraph(content: string): string {\n for (const block of content.split(/\\n\\s*\\n/)) {\n const value = block.replace(/\\s+/g, ' ').trim()\n if (!value || /^(?:#|```|:::|<|import\\s|export\\s)/.test(value)) continue\n return value.replace(/\\[([^\\]]+)\\]\\([^)]+\\)/g, '$1').slice(0, 240)\n }\n return ''\n}\n\n/** Normalize only syntax Thally cannot render; supported Mintlify JSX stays intact. */\nexport function normalizeMdx(body: string): string {\n return body\n .replace(/<!--([\\s\\S]*?)-->/g, (_match, content: string) => `{/*${content}*/}`)\n .replace(/<Danger(\\s[^>]*)?>/g, '<Error$1>')\n .replace(/<\\/Danger>/g, '</Error>')\n .replace(/<Check(\\s[^>]*)?>/g, '<Note$1>')\n .replace(/<\\/Check>/g, '</Note>')\n .replace(/<Tree\\.Folder/g, '<Folder')\n .replace(/<\\/Tree\\.Folder>/g, '</Folder>')\n .replace(/<Tree\\.File/g, '<File')\n .replace(/<\\/Tree\\.File>/g, '</File>')\n}\n\n/** Parse source Markdown or MDX into the canonical page representation. */\nexport function parseMarkdownPage(input: {\n id: string\n navigationId?: string\n locale?: string\n raw: string\n source: string\n}): MigrationPage | null {\n const parsed = matter(input.raw)\n const body = normalizeMdx(parsed.content).trim()\n if (parsed.data.openapi && !body) return null\n const keywords = Array.isArray(parsed.data.keywords)\n ? parsed.data.keywords.filter((value): value is string => typeof value === 'string')\n : []\n const title = typeof parsed.data.title === 'string' && parsed.data.title.trim()\n ? parsed.data.title.trim()\n : titleFromId(input.navigationId ?? input.id)\n const description = typeof parsed.data.description === 'string' && parsed.data.description.trim()\n ? parsed.data.description.trim()\n : firstParagraph(body)\n return {\n id: input.id,\n navigationId: input.navigationId ?? input.id,\n locale: input.locale,\n title,\n description,\n keywords,\n body,\n source: input.source,\n }\n}\n","/**\n * Navigation projection for imported sites. Mintlify's schema is intentionally\n * more expressive than Thally's tab/group model, so complex containers are\n * flattened predictably while preserving page order and nested groups.\n */\n\nimport { existsSync, readFileSync } from 'node:fs'\nimport { dirname, extname, relative } from 'node:path'\n\nimport { pageIdFromReference, resolveWithin } from './path.js'\nimport type {\n MigrationDocsConfig,\n MigrationNavigationGroup,\n MigrationNavigationTab,\n MigrationPage,\n MigrationWarning,\n} from './types.js'\n\ninterface MintlifyPageReference {\n ref: string\n navigationId: string\n locale?: string\n}\n\nexport interface MintlifyNavigationResult {\n docsConfig: MigrationDocsConfig\n pageReferences: Array<MintlifyPageReference>\n warnings: Array<MigrationWarning>\n}\n\nconst LANGUAGE_LABELS: Record<string, string> = {\n ar: 'Arabic',\n de: 'German',\n en: 'English',\n es: 'Spanish',\n fr: 'French',\n hi: 'Hindi',\n it: 'Italian',\n ja: 'Japanese',\n ko: 'Korean',\n nl: 'Dutch',\n pl: 'Polish',\n pt: 'Portuguese',\n ru: 'Russian',\n tr: 'Turkish',\n uk: 'Ukrainian',\n zh: 'Chinese',\n}\n\nfunction objectValue(value: unknown): Record<string, unknown> | null {\n return value !== null && typeof value === 'object' && !Array.isArray(value)\n ? value as Record<string, unknown>\n : null\n}\n\nfunction labelFor(value: Record<string, unknown>, fallback: string): string {\n for (const key of ['tab', 'group', 'anchor', 'product', 'dropdown', 'version', 'menu', 'label', 'name', 'title']) {\n if (typeof value[key] === 'string' && value[key]) return String(value[key])\n }\n return fallback\n}\n\nfunction localReference(value: string): string {\n return value.split('#', 1)[0]\n}\n\nfunction jsonPointer(root: unknown, pointer: string): unknown {\n if (!pointer || pointer === '#') return root\n const tokens = pointer.replace(/^#\\/?/, '').split('/').filter(Boolean)\n return tokens.reduce<unknown>((current, token) => {\n const object = objectValue(current)\n if (!object) return undefined\n return object[token.replace(/~1/g, '/').replace(/~0/g, '~')]\n }, root)\n}\n\nfunction resolveJsonReferences(\n value: unknown,\n currentFile: string,\n repositoryRoot: string,\n stack: Set<string>,\n): unknown {\n if (Array.isArray(value)) {\n return value.map((entry) => resolveJsonReferences(entry, currentFile, repositoryRoot, stack))\n }\n const object = objectValue(value)\n if (!object) return value\n if (typeof object.$ref === 'string') {\n const [filePart, pointer = ''] = object.$ref.split('#', 2)\n const referencedFile = filePart\n ? resolveWithin(dirname(currentFile), filePart)\n : currentFile\n const relativePath = relative(repositoryRoot, referencedFile)\n resolveWithin(repositoryRoot, relativePath)\n const stackKey = `${referencedFile}#${pointer}`\n if (stack.has(stackKey)) throw new Error(`Circular Mintlify $ref: ${object.$ref}`)\n stack.add(stackKey)\n const referencedRoot = JSON.parse(readFileSync(referencedFile, 'utf8')) as unknown\n const referenced = jsonPointer(referencedRoot, pointer ? `#${pointer}` : '')\n const resolved = resolveJsonReferences(referenced, referencedFile, repositoryRoot, stack)\n stack.delete(stackKey)\n return resolved\n }\n return Object.fromEntries(\n Object.entries(object).map(([key, entry]) => [\n key,\n resolveJsonReferences(entry, currentFile, repositoryRoot, stack),\n ]),\n )\n}\n\n/** Read `docs.json`/`mint.json`, including bounded local JSON references. */\nexport function readMintlifyConfig(repositoryRoot: string): Record<string, unknown> | null {\n const configPath = ['docs.json', 'mint.json']\n .map((filename) => resolveWithin(repositoryRoot, filename))\n .find(existsSync)\n if (!configPath) return null\n const raw = JSON.parse(readFileSync(configPath, 'utf8')) as unknown\n return resolveJsonReferences(raw, configPath, repositoryRoot, new Set()) as Record<string, unknown>\n}\n\nfunction normalizePageRef(value: string): string | null {\n if (/^(?:https?:)?\\/\\//i.test(value) || value.startsWith('#')) return null\n const ref = localReference(value).replace(/^\\/+/, '').replace(/\\.(?:mdx?|rst|txt)$/i, '')\n return pageIdFromReference(ref)\n}\n\ninterface ProjectionContext {\n locale?: string\n references: Array<MintlifyPageReference>\n seenReferences: Set<string>\n}\n\nfunction registerReference(value: string, context: ProjectionContext): string | null {\n const localePrefix = context.locale ? `${context.locale}/` : ''\n const localizedValue = localePrefix && value.replace(/^\\/+/, '').startsWith(localePrefix)\n ? value.replace(/^\\/+/, '').slice(localePrefix.length)\n : value\n const navigationId = normalizePageRef(localizedValue)\n if (!navigationId) return null\n const key = `${context.locale ?? ''}:${value}`\n if (!context.seenReferences.has(key)) {\n context.seenReferences.add(key)\n context.references.push({ ref: value, navigationId, locale: context.locale })\n }\n return navigationId\n}\n\nfunction convertPage(\n value: unknown,\n context: ProjectionContext,\n): string | MigrationNavigationGroup | null {\n if (typeof value === 'string') return registerReference(value, context)\n const object = objectValue(value)\n if (!object) return null\n if (typeof object.page === 'string') return registerReference(object.page, context)\n const pages = Array.isArray(object.pages) ? object.pages : []\n if ('group' in object || pages.length > 0) {\n const children: Array<string | MigrationNavigationGroup> = []\n if (typeof object.root === 'string') {\n const root = registerReference(object.root, context)\n if (root) children.push(root)\n }\n for (const page of pages) {\n const converted = convertPage(page, context)\n if (converted) children.push(converted)\n }\n if (children.length === 0) return null\n return {\n group: labelFor(object, 'Documentation'),\n ...(typeof object.icon === 'string' ? { icon: object.icon } : {}),\n pages: children,\n }\n }\n return null\n}\n\nfunction convertGroups(\n values: Array<unknown>,\n context: ProjectionContext,\n fallbackGroup: string,\n): Array<MigrationNavigationGroup> {\n const groups: Array<MigrationNavigationGroup> = []\n const loosePages: Array<string | MigrationNavigationGroup> = []\n for (const value of values) {\n const converted = convertPage(value, context)\n if (!converted) continue\n if (typeof converted === 'string') loosePages.push(converted)\n else groups.push(converted)\n }\n if (loosePages.length > 0) groups.unshift({ group: fallbackGroup, pages: loosePages })\n return groups\n}\n\nfunction convertContainerToTabs(\n containerValue: unknown,\n context: ProjectionContext,\n fallbackTab: string,\n): Array<MigrationNavigationTab> {\n const container = objectValue(containerValue)\n if (!container) return []\n for (const key of ['tabs', 'anchors', 'products', 'dropdowns', 'versions', 'menus']) {\n if (!Array.isArray(container[key])) continue\n const tabs = (container[key] as Array<unknown>).flatMap((value, index) => {\n const object = objectValue(value)\n if (!object) return []\n const tab = labelFor(object, `${fallbackTab} ${index + 1}`)\n if (typeof object.href === 'string' && !object.pages && !object.groups) {\n return [{ tab, href: object.href }]\n }\n const nested = convertContainerToTabs(object, context, tab)\n if (nested.length > 0) {\n if (nested.length === 1) return [{ ...nested[0], tab }]\n return nested.map((item) => ({ ...item, tab: `${tab}: ${item.tab}` }))\n }\n return []\n })\n if (tabs.length > 0) return tabs\n }\n const rawPages = [\n ...(Array.isArray(container.groups) ? container.groups : []),\n ...(Array.isArray(container.pages) ? container.pages : []),\n ]\n if (typeof container.root === 'string') rawPages.unshift(container.root)\n const groups = convertGroups(rawPages, context, 'Overview')\n return groups.length > 0 ? [{ tab: fallbackTab, groups }] : []\n}\n\n/** Convert current and legacy Mintlify navigation into Thally's schema. */\nexport function projectMintlifyNavigation(config: Record<string, unknown>): MintlifyNavigationResult {\n const warnings: Array<MigrationWarning> = []\n const references: Array<MintlifyPageReference> = []\n const seenReferences = new Set<string>()\n const navigation = objectValue(config.navigation) ?? config\n const languages = Array.isArray(navigation.languages)\n ? navigation.languages.map(objectValue).filter((value): value is Record<string, unknown> => Boolean(value))\n : []\n let tabs: Array<MigrationNavigationTab> = []\n let i18n: MigrationDocsConfig['i18n']\n\n if (languages.length > 0) {\n const defaultLanguage = languages.find((entry) => entry.language === 'en') ?? languages[0]\n const defaultLocale = String(defaultLanguage.language ?? 'en')\n const locales = languages.map((entry) => {\n const code = String(entry.language ?? entry.locale ?? 'en')\n return { code, label: LANGUAGE_LABELS[code] ?? code.toUpperCase() }\n })\n i18n = { defaultLocale, locales }\n for (const language of languages) {\n const locale = String(language.language ?? language.locale ?? defaultLocale)\n const context: ProjectionContext = {\n locale,\n references,\n seenReferences,\n }\n const languageTabs = convertContainerToTabs(language, context, 'Documentation')\n if (language === defaultLanguage) tabs = languageTabs\n }\n } else {\n tabs = convertContainerToTabs(navigation, { references, seenReferences }, 'Documentation')\n if (tabs.length === 0 && Array.isArray(config.navigation)) {\n const groups = convertGroups(config.navigation, { references, seenReferences }, 'Overview')\n if (groups.length > 0) tabs = [{ tab: 'Documentation', groups }]\n }\n }\n\n if (tabs.length === 0) {\n warnings.push({\n code: 'unsupported-config',\n message: 'Mintlify navigation could not be projected; generated navigation will be used.',\n })\n }\n if (!tabs.some((tab) => tab.tab.toLowerCase() === 'changelog')) {\n tabs.push({ tab: 'Changelog', href: '/changelog' })\n }\n const redirects = Array.isArray(config.redirects)\n ? config.redirects.flatMap((value) => {\n const redirect = objectValue(value)\n if (!redirect || typeof redirect.source !== 'string' || typeof redirect.destination !== 'string') return []\n return [{\n source: redirect.source,\n destination: redirect.destination,\n ...(typeof redirect.permanent === 'boolean' ? { permanent: redirect.permanent } : {}),\n }]\n })\n : []\n return {\n docsConfig: { tabs, ...(i18n ? { i18n } : {}), ...(redirects.length > 0 ? { redirects } : {}) },\n pageReferences: references,\n warnings,\n }\n}\n\nfunction titleCase(value: string): string {\n return value\n .split(/[-_]/)\n .map((word) => ['api', 'cli', 'sdk', 'ui'].includes(word.toLowerCase())\n ? word.toUpperCase()\n : word.charAt(0).toUpperCase() + word.slice(1))\n .join(' ')\n}\n\n/** Build deterministic fallback navigation from imported default-locale pages. */\nexport function buildNavigationFromPages(pages: Array<MigrationPage>): MigrationDocsConfig {\n const ids = pages.filter((page) => !page.locale || page.locale === 'en').map((page) => page.navigationId)\n const ordered = [...new Set(ids)]\n const buckets = new Map<string, Array<string>>()\n for (const id of ordered) {\n const segment = id.includes('/') ? id.split('/', 1)[0] : 'overview'\n const bucket = buckets.get(segment) ?? []\n bucket.push(id)\n buckets.set(segment, bucket)\n }\n const groups = [...buckets].map(([segment, pageIds]) => ({\n group: segment === 'overview' ? 'Overview' : titleCase(segment),\n pages: pageIds,\n }))\n return { tabs: [{ tab: 'Documentation', groups }] }\n}\n\n/** Exposed for repository discovery and focused unit tests. */\nexport function isDocumentationExtension(filename: string): boolean {\n return ['.md', '.mdx', '.rst', '.txt'].includes(extname(filename).toLowerCase())\n}\n","/** Safe path normalization used before reading or writing migrated content. */\n\nimport { isAbsolute, relative, resolve, sep } from 'node:path'\n\nconst SAFE_SEGMENT = /[^a-z0-9._-]+/g\n\n/** Turn a source path segment into a stable URL/file-system slug. */\nexport function slugifySegment(value: string): string {\n let decoded = value\n try {\n decoded = decodeURIComponent(value)\n } catch {\n // Malformed percent escapes are legal in source filenames. Treat them as\n // literal slug input instead of letting one file abort the whole import.\n }\n return decoded\n .toLowerCase()\n .replace(/\\.(?:html?|mdx?)$/i, '')\n .replace(SAFE_SEGMENT, '-')\n .replace(/(^-|-$)/g, '')\n}\n\n/**\n * Normalize a page reference to a Thally content id. Invalid or traversal\n * references return `null` instead of being allowed near the file system.\n */\nexport function pageIdFromReference(value: string): string | null {\n const withoutQuery = value.split(/[?#]/, 1)[0].replace(/\\\\/g, '/').replace(/^\\/+/, '')\n if (!withoutQuery || withoutQuery.includes('\\0')) return null\n const rawSegments = withoutQuery.split('/').filter(Boolean)\n if (rawSegments.some((segment) => segment === '..' || segment === '.')) return null\n const last = rawSegments.at(-1)?.replace(/\\.(?:mdx?|rst|txt)$/i, '') ?? ''\n const baseSegments = /^(?:index|readme)$/i.test(last) ? rawSegments.slice(0, -1) : rawSegments\n if (!/^(?:index|readme)$/i.test(last)) {\n baseSegments[baseSegments.length - 1] = last\n }\n const segments = baseSegments.map(slugifySegment).filter(Boolean)\n return segments.join('/') || 'introduction'\n}\n\n/** Resolve an untrusted relative path and prove it remains below `root`. */\nexport function resolveWithin(root: string, candidate: string): string {\n if (isAbsolute(candidate) || candidate.includes('\\0')) {\n throw new Error(`Unsafe migration path: ${candidate}`)\n }\n const target = resolve(root, candidate)\n const fromRoot = relative(resolve(root), target)\n if (fromRoot === '..' || fromRoot.startsWith(`..${sep}`) || isAbsolute(fromRoot)) {\n throw new Error(`Migration path escapes its root: ${candidate}`)\n }\n return target\n}\n\n/** Return a slash-separated, traversal-free asset path. */\nexport function normalizeAssetPath(value: string): string | null {\n const normalized = value.replace(/\\\\/g, '/').replace(/^\\/+/, '')\n if (!normalized || normalized.includes('\\0')) return null\n const segments = normalized.split('/').filter(Boolean)\n if (segments.some((segment) => segment === '.' || segment === '..')) return null\n return segments.join('/')\n}\n","/** Render canonical migration bundles into a portable Thally repository tree. */\n\nimport type {\n MigrationBundle,\n MigrationDocsConfig,\n MigrationNavigationGroup,\n RenderedMigrationFile,\n} from './types.js'\n\nfunction yamlString(value: string): string {\n return JSON.stringify(value.replace(/\\s+/g, ' ').trim())\n}\n\nfunction renderPage(bundle: MigrationBundle, page: MigrationBundle['pages'][number]): string {\n return [\n '---',\n `title: ${yamlString(page.title)}`,\n `description: ${yamlString(page.description)}`,\n page.keywords.length > 0 ? `keywords: [${page.keywords.map(yamlString).join(', ')}]` : null,\n bundle.sourceKind === 'url' ? `source: ${yamlString(page.source)}` : null,\n '---',\n '',\n page.body,\n '',\n ].filter((line) => line !== null).join('\\n')\n}\n\n/** Merge imported tabs into an existing site without duplicating changelog tabs. */\nexport function mergeMigrationConfig(\n existing: MigrationDocsConfig,\n incoming: MigrationDocsConfig,\n): MigrationDocsConfig {\n const tabs = existing.tabs.filter((tab) => tab.tab.toLowerCase() !== 'changelog')\n const names = new Set(tabs.map((tab) => tab.tab.toLowerCase()))\n const seenPages = new Set<string>()\n function recordPages(groups: MigrationDocsConfig['tabs'][number]['groups']): void {\n for (const group of groups ?? []) {\n for (const page of group.pages) {\n if (typeof page === 'string') seenPages.add(page)\n else recordPages([page])\n }\n }\n }\n for (const tab of tabs) recordPages(tab.groups)\n function uniqueGroups(\n groups: Array<MigrationNavigationGroup> | undefined,\n ): Array<MigrationNavigationGroup> {\n return (groups ?? []).flatMap<MigrationNavigationGroup>((group) => {\n const pages = group.pages.flatMap<string | MigrationNavigationGroup>((page) => {\n if (typeof page === 'string') {\n if (seenPages.has(page)) return []\n seenPages.add(page)\n return [page]\n }\n const [nested]: Array<MigrationNavigationGroup> = uniqueGroups([page])\n return nested ? [nested] : []\n })\n return pages.length > 0 ? [{ ...group, pages }] : []\n })\n }\n for (const tab of incoming.tabs) {\n if (tab.tab.toLowerCase() === 'changelog') continue\n const uniqueTab = { ...tab, ...(tab.groups ? { groups: uniqueGroups(tab.groups) } : {}) }\n if (tab.groups && uniqueTab.groups?.length === 0 && !tab.href && !tab.api) continue\n if (!names.has(tab.tab.toLowerCase())) {\n tabs.push(uniqueTab)\n names.add(tab.tab.toLowerCase())\n continue\n }\n const target = tabs.find((item) => item.tab.toLowerCase() === tab.tab.toLowerCase())\n if (!target || !uniqueTab.groups) continue\n target.groups = [...(target.groups ?? []), ...uniqueTab.groups]\n }\n const changelog = existing.tabs.find((tab) => tab.tab.toLowerCase() === 'changelog')\n ?? incoming.tabs.find((tab) => tab.tab.toLowerCase() === 'changelog')\n if (changelog) tabs.push(changelog)\n const i18n = existing.i18n || incoming.i18n\n ? {\n defaultLocale: existing.i18n?.defaultLocale ?? incoming.i18n?.defaultLocale ?? 'en',\n locales: [...new Map(\n [...(existing.i18n?.locales ?? []), ...(incoming.i18n?.locales ?? [])]\n .map((locale) => [locale.code, locale]),\n ).values()],\n }\n : undefined\n return {\n ...incoming,\n ...existing,\n tabs,\n ...(i18n ? { i18n } : {}),\n }\n}\n\n/** Materialize every canonical page, asset, and config as repository file changes. */\nexport function renderMigrationFiles(\n bundle: MigrationBundle,\n options: { existingConfig?: MigrationDocsConfig } = {},\n): Array<RenderedMigrationFile> {\n const config = options.existingConfig\n ? mergeMigrationConfig(options.existingConfig, bundle.docsConfig)\n : bundle.docsConfig\n return [\n ...bundle.pages.map((page) => ({\n path: `src/content/${page.id}.mdx`,\n content: renderPage(bundle, page),\n })),\n ...bundle.assets.map((asset) => ({ path: `public/${asset.path}`, content: asset.content })),\n { path: 'docs.json', content: `${JSON.stringify(config, null, 2)}\\n` },\n ]\n}\n","/**\n * Public URL adapter for the shared migration engine. Discovery prefers\n * machine-readable Markdown and sitemaps, remains scoped to the submitted docs\n * path, then falls back to bounded navigation crawling and HTML extraction.\n */\n\nimport { load } from 'cheerio'\nimport TurndownService from 'turndown'\n\nimport { parseMarkdownPage } from './mdx.js'\nimport { buildNavigationFromPages } from './navigation.js'\nimport { pageIdFromReference } from './path.js'\nimport type {\n MigrationBundle,\n MigrationFetcher,\n MigrationFetchResponse,\n MigrationPage,\n MigrationPlatform,\n MigrationWarning,\n} from './types.js'\n\nconst DEFAULT_MAX_PAGES = 1_000\nconst DEFAULT_MAX_TOTAL_BYTES = 100_000_000\nconst MAX_DISCOVERED_URLS = 5_000\nconst MAX_LOCAL_RESPONSE_BYTES = 2_000_000\nconst MAX_SITEMAP_DOCUMENTS = 25\nconst PORTABLE_MDX_COMPONENTS = new Set([\n 'Accordion', 'AccordionGroup', 'Badge', 'Callout', 'Card', 'CardGroup',\n 'Check', 'CodeGroup', 'Color', 'Column', 'Columns', 'Danger', 'Error', 'Expandable',\n 'File', 'Folder', 'Frame', 'Hero', 'Icon', 'Info', 'Latex', 'Mermaid',\n 'Note', 'Panel', 'ParamField', 'Prompt', 'PromptAssistant', 'PromptUser',\n 'RequestExample', 'ResponseExample', 'ResponseField', 'Step', 'Steps',\n 'Tab', 'Tabs', 'Tile', 'TileGroup', 'Tip', 'Tooltip', 'Tree', 'Update',\n 'View', 'Warning',\n])\nconst LOCALE_CODES = new Set([\n 'ar', 'cs', 'da', 'de', 'el', 'es', 'fi', 'fr', 'he', 'hi', 'hu', 'id',\n 'it', 'ja', 'ko', 'ms', 'nl', 'no', 'pl', 'pt', 'ro', 'ru', 'sk', 'sv',\n 'th', 'tr', 'uk', 'vi', 'zh',\n])\n\nexport interface UrlMigrationOptions {\n sourceUrl: string\n fetcher?: MigrationFetcher\n maxPages?: number\n concurrency?: number\n maxTotalBytes?: number\n}\n\n/** Validate the transport-level shape of a docs URL; hosted callers add SSRF checks. */\nexport function validateMigrationUrl(value: string): URL {\n let url: URL\n try {\n url = new URL(value)\n } catch {\n throw new Error('Enter a complete documentation URL, including https://.')\n }\n if (!['http:', 'https:'].includes(url.protocol)) {\n throw new Error('Documentation imports support only HTTP and HTTPS URLs.')\n }\n if (url.username || url.password) throw new Error('Documentation URLs cannot contain credentials.')\n url.hash = ''\n return url\n}\n\nasync function readResponseBody(response: Response): Promise<string> {\n const contentLength = Number(response.headers.get('content-length') ?? 0)\n if (contentLength > MAX_LOCAL_RESPONSE_BYTES) throw new Error('A documentation response exceeded the 2 MB import limit.')\n if (!response.body) return ''\n const reader = response.body.getReader()\n const chunks: Array<Uint8Array> = []\n let size = 0\n while (true) {\n const { done, value } = await reader.read()\n if (done) break\n size += value.byteLength\n if (size > MAX_LOCAL_RESPONSE_BYTES) {\n await reader.cancel()\n throw new Error('A documentation response exceeded the 2 MB import limit.')\n }\n chunks.push(value)\n }\n const body = new Uint8Array(size)\n let offset = 0\n for (const chunk of chunks) {\n body.set(chunk, offset)\n offset += chunk.byteLength\n }\n return new TextDecoder().decode(body)\n}\n\n/** Fetch implementation for local CLI usage. Cloud injects its pinned network boundary. */\nexport const defaultMigrationFetcher: MigrationFetcher = async (url, request) => {\n const response = await fetch(url, {\n headers: {\n Accept: request.accept,\n 'User-Agent': 'Thally-Migrate/1.0 (+https://thally.io)',\n },\n redirect: 'follow',\n signal: AbortSignal.timeout(15_000),\n })\n if (!response.ok) throw new Error(`Documentation server returned ${response.status}.`)\n return {\n finalUrl: new URL(response.url),\n body: await readResponseBody(response),\n contentType: response.headers.get('content-type') ?? '',\n headers: Object.fromEntries(response.headers.entries()),\n }\n}\n\nfunction docsScopePath(source: URL): string {\n const path = source.pathname.replace(/\\/+$/, '') || '/'\n if (path === '/') return '/'\n const segments = path.split('/').filter(Boolean)\n return `/${segments.length > 1 ? segments[0] : segments.join('/')}`\n}\n\nfunction isInScope(url: URL, source: URL, scopePath: string): boolean {\n if (url.origin !== source.origin || !['http:', 'https:'].includes(url.protocol)) return false\n const path = url.pathname.replace(/\\/+$/, '') || '/'\n if (scopePath === '/') return true\n return path === scopePath || path === `${scopePath}.md` || path.startsWith(`${scopePath}/`)\n}\n\nfunction normalizeCandidate(value: string, base: URL, source: URL, scopePath: string): URL | null {\n try {\n const url = new URL(value, base)\n url.hash = ''\n if (!isInScope(url, source, scopePath)) return null\n if (/\\.(?:avif|bmp|gif|ico|jpe?g|mp[34]|pdf|png|svg|webm|webp|zip)$/i.test(url.pathname)) return null\n return url\n } catch {\n return null\n }\n}\n\nfunction candidateIdentity(url: URL): string {\n const pathname = url.pathname.replace(/\\.mdx?$/i, '').replace(/\\/+$/, '') || '/'\n return `${url.origin}${pathname}${url.search}`\n}\n\nfunction pageIdForUrl(url: URL, scopePath: string): string | null {\n let path = url.pathname.replace(/\\/+$/, '')\n if (scopePath !== '/') {\n if (path === `${scopePath}.md`) path = ''\n else if (path === scopePath) path = ''\n else if (path.startsWith(`${scopePath}/`)) path = path.slice(scopePath.length + 1)\n }\n return pageIdFromReference(path.replace(/^\\/+/, '') || 'introduction')\n}\n\nfunction detectUrlPlatform(document: MigrationFetchResponse): MigrationPlatform {\n const value = `${document.body.slice(0, 200_000)} ${document.headers?.['x-powered-by'] ?? ''}`.toLowerCase()\n if (value.includes('mintlify') || value.includes('__mintlify')) return 'mintlify'\n if (value.includes('docusaurus') || value.includes('__docusaurus')) return 'docusaurus'\n if (value.includes('gitbook') || value.includes('gitbook.io')) return 'gitbook'\n if (value.includes('nextra')) return 'nextra'\n if (value.includes('vitepress')) return 'vitepress'\n if (value.includes('starlight')) return 'starlight'\n return 'generic'\n}\n\nfunction plainDescription(value: string): string {\n return value\n .replace(/\\[([^\\]]+)\\]\\([^)]+\\)/g, '$1')\n .replace(/[`*_>#-]/g, '')\n .replace(/\\s+/g, ' ')\n .trim()\n .slice(0, 240)\n}\n\nfunction withoutFencedCode(body: string): string {\n let fenceCharacter = ''\n let fenceLength = 0\n return body.split('\\n').map((line) => {\n const match = line.match(/^\\s{0,3}(`{3,}|~{3,})(.*)$/)\n if (match && !fenceCharacter) {\n fenceCharacter = match[1][0]\n fenceLength = match[1].length\n return ''\n }\n if (match && match[1][0] === fenceCharacter && match[1].length >= fenceLength\n && match[2].trim() === '') {\n fenceCharacter = ''\n fenceLength = 0\n return ''\n }\n return fenceCharacter ? '' : line\n }).join('\\n')\n}\n\nfunction sanitizeRemoteMarkdown(body: string): string | null {\n let fenceCharacter = ''\n let fenceLength = 0\n const sanitized = body.split('\\n').map((line) => {\n const fence = line.match(/^\\s{0,3}(`{3,}|~{3,})(.*)$/)\n if (fence && !fenceCharacter) {\n fenceCharacter = fence[1][0]\n fenceLength = fence[1].length\n return line\n }\n if (fence && fence[1][0] === fenceCharacter && fence[1].length >= fenceLength\n && fence[2].trim() === '') {\n fenceCharacter = ''\n fenceLength = 0\n return line\n }\n if (fenceCharacter) return line\n return line\n .replace(/<\\/?div\\b[^>]*>/gi, '')\n .replace(/<img\\s+([^>]*?)\\/?\\s*>/gi, (original, attributes: string) => {\n const source = attributes.match(/\\bsrc\\s*=\\s*(['\"])(.*?)\\1/i)?.[2]\n const alternative = attributes.match(/\\balt\\s*=\\s*(['\"])(.*?)\\1/i)?.[2] ?? ''\n if (!source || /^(?:javascript|data):/i.test(source)) return ''\n return `![${alternative.replace(/]/g, '\\\\]')}](${source})`\n })\n }).join('\\n')\n const executable = withoutFencedCode(sanitized)\n .replace(/\\{\\/\\*[\\s\\S]*?\\*\\/\\}/g, '')\n .replace(/<(?:https?:\\/\\/|mailto:)[^>]+>/gi, '')\n .replace(/(`+)[\\s\\S]*?\\1/g, '')\n if (/^\\s*(?:import|export)\\s/m.test(executable)) return null\n // A public Markdown endpoint is still attacker-controlled MDX. Preserve\n // known documentation primitives and JSON-literal props, but never compile\n // executable expressions, raw HTML, event handlers, or local components.\n let hasUnsafeExpression = false\n const withoutStaticProps = executable.replace(/=\\{([^{}\\n]*)\\}/g, (original, value: string) => {\n try {\n JSON.parse(value)\n return '=\"\"'\n } catch {\n hasUnsafeExpression = true\n return original\n }\n }).replace(/\\\\[{}]/g, '')\n if (hasUnsafeExpression || /[{}]/.test(withoutStaticProps)\n || /\\bon[A-Z][A-Za-z]*\\s*=/g.test(withoutStaticProps)\n || /\\b(?:href|src)\\s*=\\s*(['\"])\\s*(?:javascript|data):/gi.test(withoutStaticProps)) return null\n for (const match of withoutStaticProps.matchAll(/<\\/?([A-Za-z][A-Za-z0-9.]*)(?:\\s|>|\\/)/g)) {\n const component = match[1].split('.', 1)[0]\n if (!PORTABLE_MDX_COMPONENTS.has(component)) return null\n }\n return sanitized\n}\n\nfunction migratedHref(\n href: string,\n currentUrl: URL,\n source: URL,\n scopePath: string,\n importedIds: Set<string>,\n): string {\n if (/^(?:javascript|data|vbscript):/i.test(href)) return '#'\n if (href.startsWith('#') || /^(?:mailto|tel):/i.test(href)) return href\n try {\n const target = new URL(href, currentUrl)\n if (target.origin !== source.origin) return href\n let path = target.pathname\n if (scopePath !== '/' && (path === scopePath || path.startsWith(`${scopePath}/`))) {\n path = path.slice(scopePath.length)\n }\n const id = pageIdFromReference(path.replace(/^\\/+/, '') || 'introduction')\n const localizedId = id && LOCALE_CODES.has(id) ? `${id}/introduction` : id\n if (localizedId && importedIds.has(localizedId)) {\n const destination = localizedId === 'introduction' ? '/' : `/${localizedId.replace(/\\/introduction$/, '')}`\n return `${destination}${target.search}${target.hash}`\n }\n // Same-origin marketing and intentionally missing example links remain\n // valid external URLs instead of becoming broken links in the new site.\n return target.toString()\n } catch {\n return href\n }\n}\n\nfunction rewriteInternalLinks(\n body: string,\n currentUrl: URL,\n source: URL,\n scopePath: string,\n importedIds: Set<string>,\n): string {\n const markdown = body.replace(/(?<!!)\\[([^\\]]+)\\]\\(([^)\\s]+)(\\s+['\"][^'\"]*['\"])?\\)/g, (\n original,\n label: string,\n href: string,\n title = '',\n ) => {\n const destination = migratedHref(href, currentUrl, source, scopePath, importedIds)\n return destination === href ? original : `[${label}](${destination}${title})`\n })\n return markdown.replace(/\\bhref=(['\"])([^'\"]+)\\1/g, (_original, quote: string, href: string) => {\n const destination = migratedHref(href, currentUrl, source, scopePath, importedIds)\n return `href=${quote}${destination}${quote}`\n })\n}\n\nfunction remoteMarkdownMetadata(body: string): {\n content: string\n title?: string\n description?: string\n} {\n if (!/^---\\r?\\n/.test(body)) return { content: body }\n const end = body.slice(4, 65_540).search(/\\r?\\n---(?:\\r?\\n|$)/)\n if (end < 0) return { content: body }\n const frontmatter = body.slice(4, end + 4)\n const contentStart = end + 4 + body.slice(end + 4).match(/^\\r?\\n---(?:\\r?\\n|$)/)![0].length\n function scalar(key: string): string | undefined {\n const value = frontmatter.match(new RegExp(`^${key}:\\\\s*(.+)$`, 'm'))?.[1].trim()\n if (!value) return undefined\n if (/^['\"].*['\"]$/.test(value)) {\n try {\n const parsed = JSON.parse(value.replace(/^'/, '\"').replace(/'$/, '\"'))\n return typeof parsed === 'string' ? parsed : undefined\n } catch {\n return value.slice(1, -1)\n }\n }\n return value.slice(0, 500)\n }\n return {\n content: body.slice(contentStart),\n title: scalar('title'),\n description: scalar('description'),\n }\n}\n\nfunction markdownPage(document: MigrationFetchResponse, id: string): MigrationPage | null {\n const parsed = remoteMarkdownMetadata(document.body)\n const titleMatch = parsed.content.match(/^#\\s+(.+)$/m)\n const title = parsed.title ?? titleMatch?.[1] ?? id.split('/').at(-1) ?? 'Introduction'\n // Re-emit only scalar metadata we parsed ourselves. `gray-matter` remains in\n // the shared page parser for trusted repository sources, but never receives\n // attacker-controlled YAML aliases from a public URL.\n const raw = [\n '---',\n `title: ${JSON.stringify(title)}`,\n ...(parsed.description ? [`description: ${JSON.stringify(parsed.description)}`] : []),\n '---',\n '',\n parsed.content,\n ].join('\\n')\n return parseMarkdownPage({ id, raw, source: document.finalUrl.toString() })\n}\n\nfunction htmlPage(\n document: MigrationFetchResponse,\n id: string,\n): { page: MigrationPage | null; links: Array<string> } {\n const $ = load(document.body)\n const links = $('nav a[href], main a[href], article a[href], [role=\"main\"] a[href]')\n .map((_index, element) => $(element).attr('href') ?? '')\n .get()\n .filter(Boolean)\n const title = $('main h1, article h1, h1').first().text().trim()\n || $('meta[property=\"og:title\"]').attr('content')?.trim()\n || $('title').text().split('|')[0].trim()\n const description = $('meta[name=\"description\"]').attr('content')?.trim()\n || $('meta[property=\"og:description\"]').attr('content')?.trim()\n const content = $('main article, article, main, [role=\"main\"]').first()\n const root = content.length ? content : $('body')\n root.find('script,style,noscript,nav,header,footer,aside,form,button,svg,iframe,object,embed,link,meta').remove()\n root.find('a[href]').each((_index, element) => {\n const href = $(element).attr('href')\n if (!href) return\n try {\n const resolved = new URL(href, document.finalUrl)\n if (['http:', 'https:', 'mailto:', 'tel:'].includes(resolved.protocol)) {\n $(element).attr('href', resolved.toString())\n } else {\n $(element).removeAttr('href')\n }\n } catch {\n $(element).removeAttr('href')\n }\n })\n root.find('img[src]').each((_index, element) => {\n const src = $(element).attr('src')\n if (!src) return\n try {\n const resolved = new URL(src, document.finalUrl)\n if (['http:', 'https:'].includes(resolved.protocol)) {\n $(element).attr('src', resolved.toString())\n } else {\n $(element).removeAttr('src')\n }\n } catch {\n $(element).removeAttr('src')\n }\n })\n const turndown = new TurndownService({ codeBlockStyle: 'fenced', emDelimiter: '_', headingStyle: 'atx' })\n turndown.remove(['script', 'style', 'noscript'])\n turndown.addRule('migration-safe-fenced-code', {\n filter: (node) => node.nodeName === 'PRE',\n replacement: (_content, node) => {\n const element = node as HTMLElement\n const code = element.textContent?.replace(/\\n$/, '') ?? ''\n const language = element.querySelector('code')?.className.match(/(?:language-|lang-)([A-Za-z0-9_+-]+)/)?.[1] ?? ''\n const longestFence = Math.max(0, ...[...code.matchAll(/`+/g)].map((match) => match[0].length))\n const fence = '`'.repeat(Math.max(3, longestFence + 1))\n return `\\n\\n${fence}${language}\\n${code}\\n${fence}\\n\\n`\n },\n })\n const escape = turndown.escape.bind(turndown)\n turndown.escape = (text: string) => escape(text).replace(/[<{]/g, (match) => `\\\\${match}`)\n const body = turndown.turndown(root.html() ?? '').trim()\n if (!title || body.length < 40) return { page: null, links }\n return {\n page: {\n id,\n navigationId: id,\n title,\n description: description || plainDescription(body) || `Documentation imported from ${document.finalUrl.hostname}.`,\n keywords: [],\n body,\n source: document.finalUrl.toString(),\n },\n links,\n }\n}\n\nfunction markdownLinks(body: string): Array<string> {\n return [...body.matchAll(/\\[[^\\]]+\\]\\(([^)\\s]+)(?:\\s+['\"][^'\"]*['\"])?\\)/g)]\n .map((match) => match[1])\n}\n\nfunction sitemapLinks(body: string): Array<string> {\n const $ = load(body, { xmlMode: true })\n return $('url > loc, sitemap > loc').map((_index, element) => $(element).text().trim()).get().filter(Boolean)\n}\n\nfunction robotsSitemaps(body: string): Array<string> {\n return body.split('\\n')\n .map((line) => line.match(/^\\s*Sitemap:\\s*(\\S+)/i)?.[1])\n .filter((value): value is string => Boolean(value))\n}\n\nfunction headerLinks(document: MigrationFetchResponse): Array<string> {\n const links: Array<string> = []\n const llms = document.headers?.['x-llms-txt']\n if (llms) links.push(llms)\n const linkHeader = document.headers?.link ?? ''\n for (const match of linkHeader.matchAll(/<([^>]+)>\\s*;[^,]*(?:rel=[\"']?(?:alternate|llms-txt)[\"']?|type=[\"']text\\/(?:markdown|plain)[\"'])/gi)) {\n links.push(match[1])\n }\n return links\n}\n\nasync function safeFetch(\n fetcher: MigrationFetcher,\n url: URL,\n accept: string,\n): Promise<MigrationFetchResponse | null> {\n try {\n return await fetcher(url, { accept })\n } catch {\n return null\n }\n}\n\n/** Crawl one public docs origin into a canonical, caller-independent bundle. */\nexport async function migrateUrl(options: UrlMigrationOptions): Promise<MigrationBundle> {\n const source = validateMigrationUrl(options.sourceUrl)\n const fetcher = options.fetcher ?? defaultMigrationFetcher\n const maxPages = Math.max(1, Math.min(options.maxPages ?? DEFAULT_MAX_PAGES, 1_000))\n const concurrency = Math.max(1, Math.min(options.concurrency ?? 5, 10))\n const maxTotalBytes = Math.max(1_000_000, Math.min(options.maxTotalBytes ?? DEFAULT_MAX_TOTAL_BYTES, 500_000_000))\n const scopePath = docsScopePath(source)\n const initial = await fetcher(source, { accept: 'text/markdown,text/html,application/xhtml+xml;q=0.9' })\n if (!isInScope(initial.finalUrl, source, scopePath)) {\n throw new Error('The documentation URL redirected outside the submitted docs origin or path.')\n }\n const platform = detectUrlPlatform(initial)\n const cache = new Map([[source.toString(), initial]])\n const queue: Array<URL> = [source]\n const queued = new Set([candidateIdentity(source)])\n const warnings: Array<MigrationWarning> = []\n const fetchedSitemaps = new Set<string>()\n\n function enqueue(value: string, base: URL): void {\n if (queued.size >= MAX_DISCOVERED_URLS) return\n const url = normalizeCandidate(value, base, source, scopePath)\n if (!url || queued.has(candidateIdentity(url))) return\n queued.add(candidateIdentity(url))\n queue.push(url)\n }\n\n async function discoverDocumentLinks(document: MigrationFetchResponse, depth = 0): Promise<void> {\n const links = sitemapLinks(document.body)\n for (const link of links) {\n let url: URL\n try {\n url = new URL(link, document.finalUrl)\n } catch {\n continue\n }\n if (depth < 2 && /\\.xml(?:$|\\?)/i.test(url.pathname)) {\n if (url.origin !== source.origin || fetchedSitemaps.size >= MAX_SITEMAP_DOCUMENTS\n || fetchedSitemaps.has(url.toString())) continue\n fetchedSitemaps.add(url.toString())\n const nested = await safeFetch(fetcher, url, 'application/xml,text/xml')\n if (nested && nested.finalUrl.origin === source.origin) await discoverDocumentLinks(nested, depth + 1)\n } else {\n enqueue(link, document.finalUrl)\n }\n }\n }\n\n for (const link of headerLinks(initial)) {\n let url: URL\n try {\n url = new URL(link, initial.finalUrl)\n } catch {\n continue\n }\n if (url.origin !== source.origin) continue\n const document = await safeFetch(fetcher, url, 'text/plain,text/markdown')\n if (!document || document.finalUrl.origin !== source.origin) continue\n for (const candidate of markdownLinks(document.body)) enqueue(candidate, document.finalUrl)\n }\n\n const pathRoot = scopePath === '/' ? source.origin : `${source.origin}${scopePath}`\n const discoveryUrls = [\n new URL('/llms.txt', source.origin),\n new URL(`${pathRoot.replace(source.origin, '')}/llms.txt`, source.origin),\n new URL('/robots.txt', source.origin),\n new URL('/sitemap.xml', source.origin),\n new URL(`${pathRoot.replace(source.origin, '')}/sitemap.xml`, source.origin),\n ]\n const uniqueDiscovery = [...new Map(discoveryUrls.map((url) => [url.toString(), url])).values()]\n for (const url of uniqueDiscovery) {\n const document = await safeFetch(fetcher, url, 'text/plain,application/xml,text/xml;q=0.9')\n if (!document || document.finalUrl.origin !== source.origin) continue\n const isRobots = url.pathname.endsWith('robots.txt')\n const isSitemap = url.pathname.endsWith('sitemap.xml') || document.contentType.includes('xml')\n if (isRobots) {\n for (const link of robotsSitemaps(document.body)) {\n let sitemapUrl: URL\n try {\n sitemapUrl = new URL(link, document.finalUrl)\n } catch {\n continue\n }\n if (sitemapUrl.origin !== source.origin || fetchedSitemaps.size >= MAX_SITEMAP_DOCUMENTS\n || fetchedSitemaps.has(sitemapUrl.toString())) continue\n fetchedSitemaps.add(sitemapUrl.toString())\n const sitemap = await safeFetch(fetcher, sitemapUrl, 'application/xml,text/xml')\n if (sitemap && sitemap.finalUrl.origin === source.origin) await discoverDocumentLinks(sitemap)\n }\n } else if (isSitemap) {\n await discoverDocumentLinks(document)\n } else {\n for (const link of markdownLinks(document.body)) enqueue(link, document.finalUrl)\n }\n }\n\n const pages: Array<MigrationPage> = []\n const seenIds = new Set<string>()\n const visited = new Set<string>()\n let importedBytes = 0\n let isByteBudgetExhausted = false\n while (queue.length > 0 && pages.length < maxPages && !isByteBudgetExhausted) {\n const batch: Array<URL> = []\n while (queue.length > 0 && batch.length < Math.min(concurrency, maxPages - pages.length)) {\n const candidate = queue.shift()\n if (!candidate || visited.has(candidate.toString())) continue\n visited.add(candidate.toString())\n batch.push(candidate)\n }\n if (batch.length === 0) continue\n const results = await Promise.all(batch.map(async (candidate) => {\n let document = cache.get(candidate.toString())\n ?? await safeFetch(fetcher, candidate, 'text/markdown,text/html,application/xhtml+xml;q=0.9')\n if (!document) {\n return { candidate, page: null, links: [] as Array<string>, failure: true }\n }\n if (!isInScope(document.finalUrl, source, scopePath)) {\n return { candidate, page: null, links: [] as Array<string>, failure: false }\n }\n const isMarkdown = /(?:markdown|text\\/plain)/i.test(document.contentType)\n || /\\.mdx?$/i.test(document.finalUrl.pathname)\n if (!isMarkdown && !/\\.mdx?$/i.test(candidate.pathname)) {\n const markdownUrl = new URL(candidate)\n markdownUrl.pathname = `${markdownUrl.pathname.replace(/\\/$/, '')}.md`\n const markdownDocument = await safeFetch(fetcher, markdownUrl, 'text/markdown,text/plain')\n if (markdownDocument && isInScope(markdownDocument.finalUrl, source, scopePath)\n && /(?:markdown|text\\/plain)/i.test(markdownDocument.contentType)) {\n document = markdownDocument\n }\n }\n const isResolvedMarkdown = /(?:markdown|text\\/plain)/i.test(document.contentType)\n || /\\.mdx?$/i.test(document.finalUrl.pathname)\n const sanitizedMarkdown = isResolvedMarkdown ? sanitizeRemoteMarkdown(document.body) : null\n if (isResolvedMarkdown && sanitizedMarkdown === null) {\n const htmlUrl = new URL(candidate)\n htmlUrl.pathname = htmlUrl.pathname.replace(/\\.mdx?$/i, '') || '/'\n const htmlDocument = await safeFetch(fetcher, htmlUrl, 'text/html,application/xhtml+xml')\n if (htmlDocument && isInScope(htmlDocument.finalUrl, source, scopePath)\n && /html/i.test(htmlDocument.contentType)) {\n document = htmlDocument\n }\n } else if (sanitizedMarkdown !== null) {\n document = { ...document, body: sanitizedMarkdown }\n }\n const responseBytes = Buffer.byteLength(document.body, 'utf8')\n if (importedBytes + responseBytes > maxTotalBytes) {\n isByteBudgetExhausted = true\n return { candidate, page: null, links: [] as Array<string>, failure: false, budgetExceeded: true }\n }\n importedBytes += responseBytes\n const id = pageIdForUrl(document.finalUrl, scopePath)\n ?? pageIdForUrl(candidate, scopePath)\n if (!id) return { candidate, page: null, links: [] as Array<string>, failure: false }\n if (/(?:markdown|text\\/plain)/i.test(document.contentType) || /\\.mdx?$/i.test(document.finalUrl.pathname)) {\n return {\n candidate,\n page: markdownPage(document, id),\n links: markdownLinks(document.body),\n base: document.finalUrl,\n failure: false,\n }\n }\n const extracted = htmlPage(document, id)\n return { candidate, page: extracted.page, links: extracted.links, base: document.finalUrl, failure: false }\n }))\n for (const result of results) {\n if (result.failure) {\n warnings.push({ code: 'fetch-failed', message: 'A discovered documentation page could not be fetched.', source: result.candidate.toString() })\n continue\n }\n if (result.budgetExceeded) continue\n if (result.page && !seenIds.has(result.page.id) && pages.length < maxPages) {\n pages.push(result.page)\n seenIds.add(result.page.id)\n }\n for (const link of result.links) enqueue(link, result.base ?? result.candidate)\n }\n }\n\n if (pages.length === 0) throw new Error('No readable documentation pages were found at that URL.')\n for (const page of pages) {\n const [locale, ...navigationSegments] = page.id.split('/')\n if (LOCALE_CODES.has(locale)) {\n if (navigationSegments.length === 0) page.id = `${locale}/introduction`\n page.locale = locale\n page.navigationId = navigationSegments.join('/') || 'introduction'\n }\n }\n const importedIds = new Set(pages.map((page) => page.id))\n for (const page of pages) {\n page.body = rewriteInternalLinks(page.body, new URL(page.source), source, scopePath, importedIds)\n }\n if (isByteBudgetExhausted) {\n warnings.push({ code: 'limit-reached', message: `Import stopped after reaching the ${Math.round(maxTotalBytes / 1_000_000)} MB content budget.` })\n } else if (queue.length > 0 || queued.size >= MAX_DISCOVERED_URLS) {\n warnings.push({ code: 'limit-reached', message: `Import stopped after ${pages.length} pages; narrow the URL or raise the caller limit to import more.` })\n }\n const docsConfig = buildNavigationFromPages(pages)\n const locales = [...new Set(pages.map((page) => page.locale).filter((value): value is string => Boolean(value)))]\n if (locales.length > 0) {\n docsConfig.i18n = {\n defaultLocale: 'en',\n locales: [\n { code: 'en', label: 'English' },\n ...locales.filter((locale) => locale !== 'en').map((locale) => ({ code: locale, label: locale.toUpperCase() })),\n ],\n }\n }\n return {\n sourceUrl: source.toString(),\n sourceKind: 'url',\n platform,\n pages,\n assets: [],\n docsConfig,\n warnings,\n stats: {\n discovered: visited.size,\n imported: pages.length,\n skipped: Math.max(0, visited.size - pages.length),\n },\n }\n}\n"],"mappings":"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","names":["existsSync","readFileSync","dirname","extname","relative","relative","relative","resolve","existsSync","readFileSync","extname","relative","dirname"]}
|
|
1
|
+
{"version":3,"sources":["../src/repository.ts","../src/mdx.ts","../src/navigation.ts","../src/path.ts","../src/render.ts","../src/url.ts"],"sourcesContent":["/**\n * Repository adapter for the shared migration engine. Traversal is bounded,\n * symbolic links are ignored, and Git is always invoked with an argument array\n * so source-controlled branch names can never become shell commands.\n */\n\nimport { spawn } from 'node:child_process'\nimport {\n existsSync,\n lstatSync,\n readFileSync,\n readdirSync,\n} from 'node:fs'\nimport { basename, dirname, extname, relative } from 'node:path'\n\nimport { parseMarkdownPage } from './mdx.js'\nimport {\n buildNavigationFromPages,\n isDocumentationExtension,\n projectMintlifyNavigation,\n readMintlifyConfig,\n} from './navigation.js'\nimport { normalizeAssetPath, pageIdFromReference, resolveWithin } from './path.js'\nimport type {\n MigrationAsset,\n MigrationBundle,\n MigrationDocsConfig,\n MigrationPage,\n MigrationPlatform,\n MigrationWarning,\n} from './types.js'\n\nconst MAX_SOURCE_FILES = 5_000\nconst MAX_PAGE_BYTES = 2_000_000\nconst MAX_ASSET_BYTES = 25_000_000\nconst MAX_TOTAL_ASSET_BYTES = 100_000_000\nconst IGNORED_DIRECTORIES = new Set([\n '.git', '.github', '.next', '.turbo', '.vercel', '.vscode',\n 'node_modules', 'dist', 'build', 'coverage',\n])\nconst ASSET_DIRECTORIES = new Set(['assets', 'images', 'img', 'media', 'public', 'static'])\nconst ASSET_EXTENSIONS = new Set([\n '.avif', '.bmp', '.gif', '.ico', '.jpeg', '.jpg', '.mp3', '.mp4',\n '.pdf', '.png', '.svg', '.webm', '.webp',\n])\nconst REPOSITORY_ONLY_DOCUMENTS = new Set([\n 'agents.md', 'claude.md', 'code_of_conduct.md', 'contributing.md',\n 'license.md', 'readme.md', 'security.md',\n])\nconst SNIPPET_DIRECTORIES = new Set(['snippets', '_snippets', 'partials', '_partials'])\nconst OPENAPI_FILENAMES = new Set([\n 'openapi.json', 'openapi.yaml', 'openapi.yml',\n 'swagger.json', 'swagger.yaml', 'swagger.yml',\n])\n\nexport interface GitHubRepositorySource {\n owner: string\n repo: string\n branch: string\n docsDir: string\n cloneUrl: string\n}\n\nexport interface RepositoryMigrationOptions {\n repositoryDir: string\n sourceUrl: string\n docsDir?: string\n platform?: MigrationPlatform\n}\n\n/** Parse and validate a public GitHub repository URL. */\nexport function parseGitHubRepositoryUrl(rawUrl: string): GitHubRepositorySource {\n let url: URL\n try {\n url = new URL(rawUrl)\n } catch {\n throw new Error(`Invalid GitHub URL: ${rawUrl}`)\n }\n if (url.protocol !== 'https:' || url.hostname.toLowerCase() !== 'github.com') {\n throw new Error('Repository migrations require an https://github.com URL.')\n }\n if (url.username || url.password || url.port) {\n throw new Error('GitHub repository URLs cannot include credentials or custom ports.')\n }\n const segments = url.pathname.split('/').filter(Boolean).map(decodeURIComponent)\n const [owner, rawRepo] = segments\n const repo = rawRepo?.replace(/\\.git$/i, '')\n const safeName = /^[A-Za-z0-9_.-]+$/\n if (!owner || !repo || !safeName.test(owner) || !safeName.test(repo)) {\n throw new Error('GitHub URL must include a valid owner and repository name.')\n }\n let branch = 'HEAD'\n let docsDir = ''\n if (segments[2] === 'tree' && segments[3]) {\n branch = segments[3]\n docsDir = segments.slice(4).join('/')\n }\n return {\n owner,\n repo,\n branch,\n docsDir,\n cloneUrl: `https://github.com/${owner}/${repo}.git`,\n }\n}\n\n/** Clone a repository without a shell; callers own and remove `targetDir`. */\nexport async function cloneGitHubRepository(\n source: GitHubRepositorySource,\n targetDir: string,\n): Promise<void> {\n const args = ['clone', '--depth', '1', '--single-branch']\n if (source.branch !== 'HEAD') args.push('--branch', source.branch)\n args.push('--', source.cloneUrl, targetDir)\n await new Promise<void>((resolve, reject) => {\n const child = spawn('git', args, { stdio: ['ignore', 'ignore', 'pipe'] })\n let stderr = ''\n child.stderr.setEncoding('utf8')\n child.stderr.on('data', (chunk: string) => {\n if (stderr.length < 16_000) stderr += chunk\n })\n child.on('error', reject)\n child.on('close', (code) => {\n if (code === 0) resolve()\n else reject(new Error(`Failed to clone ${source.owner}/${source.repo}: ${stderr.trim() || `git exited ${code}`}`))\n })\n })\n}\n\n/** Detect a supported repository docs platform from unambiguous config files. */\nexport function detectRepositoryPlatform(repositoryDir: string): MigrationPlatform {\n if (existsSync(resolveWithin(repositoryDir, 'mint.json'))) return 'mintlify'\n const docsJson = resolveWithin(repositoryDir, 'docs.json')\n if (existsSync(docsJson)) {\n try {\n const config = JSON.parse(readFileSync(docsJson, 'utf8')) as Record<string, unknown>\n if (String(config.$schema ?? '').includes('mintlify') || 'navigation' in config) return 'mintlify'\n if (Array.isArray(config.tabs)) return 'thally'\n } catch {\n // A malformed source config is reported later; platform detection falls through.\n }\n }\n if (['docusaurus.config.js', 'docusaurus.config.ts', 'docusaurus.config.mjs']\n .some((name) => existsSync(resolveWithin(repositoryDir, name)))) return 'docusaurus'\n if (existsSync(resolveWithin(repositoryDir, 'SUMMARY.md'))) return 'gitbook'\n if (existsSync(resolveWithin(repositoryDir, '.vitepress'))) return 'vitepress'\n if (['astro.config.mjs', 'astro.config.ts']\n .some((name) => existsSync(resolveWithin(repositoryDir, name)))) return 'starlight'\n if (['pages/_meta.json', '_meta.json']\n .some((name) => existsSync(resolveWithin(repositoryDir, name)))) return 'nextra'\n return 'unknown'\n}\n\nfunction containsMarkdown(directory: string, depth = 0): boolean {\n if (depth > 4) return false\n for (const entry of readdirSync(directory, { withFileTypes: true })) {\n if (IGNORED_DIRECTORIES.has(entry.name) || entry.isSymbolicLink()) continue\n const path = resolveWithin(directory, entry.name)\n if (entry.isFile() && ['.md', '.mdx'].includes(extname(entry.name).toLowerCase())) return true\n if (entry.isDirectory() && containsMarkdown(path, depth + 1)) return true\n }\n return false\n}\n\n/** Pick the first conventional content root containing Markdown. */\nexport function detectRepositoryDocsDir(repositoryDir: string): string {\n for (const candidate of ['docs', 'documentation', 'content', 'pages', 'src/content', 'src/pages', 'guide', 'guides', '']) {\n const path = resolveWithin(repositoryDir, candidate)\n if (existsSync(path) && lstatSync(path).isDirectory() && containsMarkdown(path)) return candidate\n }\n return ''\n}\n\ninterface ScannedFile {\n absolutePath: string\n relativePath: string\n}\n\nfunction scanFiles(root: string): Array<ScannedFile> {\n const files: Array<ScannedFile> = []\n function visit(directory: string): void {\n if (files.length >= MAX_SOURCE_FILES) return\n for (const entry of readdirSync(directory, { withFileTypes: true })) {\n if (files.length >= MAX_SOURCE_FILES) return\n if (IGNORED_DIRECTORIES.has(entry.name) || entry.isSymbolicLink()) continue\n const path = resolveWithin(directory, entry.name)\n if (entry.isDirectory()) visit(path)\n else if (entry.isFile()) files.push({ absolutePath: path, relativePath: relative(root, path).replace(/\\\\/g, '/') })\n }\n }\n visit(root)\n return files\n}\n\nfunction normalizedReferenceKey(value: string): string {\n return value.split(/[?#]/, 1)[0]\n .replace(/^\\/+/, '')\n .replace(/\\\\/g, '/')\n .replace(/\\.(?:mdx?|rst|txt)$/i, '')\n .replace(/\\/(?:index|readme)$/i, '')\n .replace(/^(?:index|readme)$/i, '') || 'introduction'\n}\n\nfunction findOpenApi(files: Array<ScannedFile>): ScannedFile | null {\n return files.find((file) => OPENAPI_FILENAMES.has(basename(file.relativePath).toLowerCase())) ?? null\n}\n\nfunction withoutFrontmatter(value: string): string {\n return value.replace(/^---\\r?\\n[\\s\\S]*?\\r?\\n---\\r?\\n?/, '').trim()\n}\n\nfunction inlineMdxSnippets(\n raw: string,\n currentFile: string,\n repositoryRoot: string,\n warnings: Array<MigrationWarning>,\n depth = 0,\n): string {\n if (depth >= 8) return raw\n const snippets = new Map<string, string>()\n const withoutImports = raw.replace(\n /^import\\s+([A-Z][A-Za-z0-9_]*)\\s+from\\s+['\"]([^'\"]+\\.mdx?)['\"]\\s*;?\\s*$/gm,\n (_statement, componentName: string, sourcePath: string) => {\n try {\n const candidate = sourcePath.startsWith('/')\n ? resolveWithin(repositoryRoot, sourcePath.replace(/^\\/+/, ''))\n : resolveWithin(dirname(currentFile), sourcePath)\n // Prove a relative import resolved under the repository, not merely\n // under the current directory's parent chain.\n resolveWithin(repositoryRoot, relative(repositoryRoot, candidate))\n if (!existsSync(candidate) || !lstatSync(candidate).isFile()) throw new Error('file not found')\n const nested = inlineMdxSnippets(\n withoutFrontmatter(readFileSync(candidate, 'utf8')),\n candidate,\n repositoryRoot,\n warnings,\n depth + 1,\n )\n snippets.set(componentName, nested)\n return ''\n } catch {\n warnings.push({\n code: 'missing-page',\n message: `Imported snippet ${sourcePath} could not be resolved and was left as a comment.`,\n source: relative(repositoryRoot, currentFile).replace(/\\\\/g, '/'),\n })\n snippets.set(componentName, `{/* Missing imported snippet: ${sourcePath} */}`)\n return ''\n }\n },\n )\n let result = withoutImports\n for (const [componentName, snippet] of snippets) {\n result = result\n .replace(new RegExp(`<${componentName}(?:\\\\s[^>]*)?\\\\s*/>`, 'g'), snippet)\n .replace(new RegExp(`<${componentName}(?:\\\\s[^>]*)?>(?:[\\\\s\\\\S]*?)<\\\\/${componentName}>`, 'g'), snippet)\n }\n return result\n}\n\nfunction injectOpenApi(config: MigrationDocsConfig, filename: string): MigrationDocsConfig {\n const tabs = config.tabs.filter((tab) => !tab.tab.toLowerCase().includes('api'))\n const apiTab: MigrationDocsConfig['tabs'][number] = {\n tab: 'API Reference',\n api: { source: `/${filename}` },\n }\n const changelog = tabs.findIndex((tab) => tab.tab.toLowerCase() === 'changelog')\n if (changelog >= 0) tabs.splice(changelog, 0, apiTab)\n else tabs.push(apiTab)\n return { ...config, tabs }\n}\n\n/** Import an already-available repository directory into a canonical bundle. */\nexport function migrateRepository(options: RepositoryMigrationOptions): MigrationBundle {\n const repositoryDir = options.repositoryDir\n const platform = options.platform ?? detectRepositoryPlatform(repositoryDir)\n const warnings: Array<MigrationWarning> = []\n let docsConfig: MigrationDocsConfig = { tabs: [] }\n const referenceMap = new Map<string, { navigationId: string; locale?: string }>()\n const referenceOrder = new Map<string, number>()\n\n if (platform === 'mintlify') {\n try {\n const config = readMintlifyConfig(repositoryDir)\n if (config) {\n const projected = projectMintlifyNavigation(config)\n docsConfig = projected.docsConfig\n warnings.push(...projected.warnings)\n for (const [index, reference] of projected.pageReferences.entries()) {\n const key = normalizedReferenceKey(reference.ref)\n referenceMap.set(key, reference)\n referenceOrder.set(key, index)\n }\n }\n } catch (error) {\n warnings.push({\n code: 'unsupported-config',\n message: `Mintlify config could not be read: ${error instanceof Error ? error.message : String(error)}`,\n })\n }\n }\n\n const configuredDocsDir = options.docsDir ?? (platform === 'mintlify' ? '' : detectRepositoryDocsDir(repositoryDir))\n const contentRoot = resolveWithin(repositoryDir, configuredDocsDir)\n if (!existsSync(contentRoot) || !lstatSync(contentRoot).isDirectory()) {\n throw new Error(`Documentation directory does not exist: ${configuredDocsDir || '.'}`)\n }\n const files = scanFiles(contentRoot)\n const pages: Array<MigrationPage> = []\n const assets: Array<MigrationAsset> = []\n const seenPageIds = new Set<string>()\n let skipped = 0\n\n const localeConfig = docsConfig.i18n\n const pageFiles = [...files].sort((left, right) => {\n const leftOrder = referenceOrder.get(normalizedReferenceKey(left.relativePath)) ?? Number.MAX_SAFE_INTEGER\n const rightOrder = referenceOrder.get(normalizedReferenceKey(right.relativePath)) ?? Number.MAX_SAFE_INTEGER\n return leftOrder - rightOrder || left.relativePath.localeCompare(right.relativePath)\n })\n for (const file of pageFiles) {\n if (!isDocumentationExtension(file.relativePath)) continue\n if (file.relativePath.split('/').some((segment) => SNIPPET_DIRECTORIES.has(segment.toLowerCase()))) {\n skipped++\n continue\n }\n const rootFilename = !file.relativePath.includes('/') ? basename(file.relativePath).toLowerCase() : ''\n if (REPOSITORY_ONLY_DOCUMENTS.has(rootFilename)) {\n skipped++\n continue\n }\n if (!['.md', '.mdx'].includes(extname(file.relativePath).toLowerCase())) {\n skipped++\n warnings.push({ code: 'skipped-file', message: 'Only Markdown and MDX are imported without an explicit converter.', source: file.relativePath })\n continue\n }\n const size = lstatSync(file.absolutePath).size\n if (size > MAX_PAGE_BYTES) {\n skipped++\n warnings.push({ code: 'skipped-file', message: 'Page exceeded the 2 MB repository import limit.', source: file.relativePath })\n continue\n }\n const key = normalizedReferenceKey(file.relativePath)\n const referenced = referenceMap.get(key)\n let locale = referenced?.locale\n let navigationId = referenced?.navigationId ?? pageIdFromReference(file.relativePath)\n if (!referenced && localeConfig) {\n const prefix = file.relativePath.split('/', 1)[0]\n if (localeConfig.locales.some((entry) => entry.code === prefix)) {\n locale = prefix\n navigationId = pageIdFromReference(file.relativePath.slice(prefix.length + 1))\n }\n }\n if (!navigationId) {\n skipped++\n warnings.push({ code: 'invalid-page', message: 'Page path could not be normalized safely.', source: file.relativePath })\n continue\n }\n const isDefaultLocale = !locale || locale === localeConfig?.defaultLocale\n const id = isDefaultLocale ? navigationId : `${locale}/${navigationId}`\n if (seenPageIds.has(id)) {\n skipped++\n warnings.push({ code: 'collision', message: `Multiple source files map to ${id}; the first file was kept.`, source: file.relativePath })\n continue\n }\n const raw = inlineMdxSnippets(\n readFileSync(file.absolutePath, 'utf8'),\n file.absolutePath,\n repositoryDir,\n warnings,\n )\n const page = parseMarkdownPage({\n id,\n navigationId,\n ...(locale ? { locale } : {}),\n raw,\n source: `${options.sourceUrl}#${file.relativePath}`,\n })\n if (!page) {\n skipped++\n continue\n }\n seenPageIds.add(id)\n pages.push(page)\n }\n\n const discoveredReferenceKeys = new Set(files.map((file) => normalizedReferenceKey(file.relativePath)))\n for (const [key] of referenceMap) {\n if (!discoveredReferenceKeys.has(key)) {\n warnings.push({ code: 'missing-page', message: 'A navigation entry did not resolve to a source page.', source: key })\n }\n }\n\n let totalAssetBytes = 0\n for (const file of files) {\n const firstSegment = file.relativePath.split('/', 1)[0].toLowerCase()\n if (!ASSET_DIRECTORIES.has(firstSegment) || !ASSET_EXTENSIONS.has(extname(file.relativePath).toLowerCase())) continue\n const size = lstatSync(file.absolutePath).size\n if (size > MAX_ASSET_BYTES || totalAssetBytes + size > MAX_TOTAL_ASSET_BYTES) {\n warnings.push({ code: 'limit-reached', message: 'An asset was skipped because the migration asset budget was exhausted.', source: file.relativePath })\n continue\n }\n const assetPath = normalizeAssetPath(firstSegment === 'public'\n ? file.relativePath.slice('public/'.length)\n : file.relativePath)\n if (!assetPath) continue\n assets.push({ path: assetPath, content: readFileSync(file.absolutePath) })\n totalAssetBytes += size\n }\n\n if (files.length >= MAX_SOURCE_FILES) {\n warnings.push({ code: 'limit-reached', message: `Repository discovery stopped at ${MAX_SOURCE_FILES} files.` })\n }\n if (docsConfig.tabs.length === 0) docsConfig = buildNavigationFromPages(pages)\n const openApi = findOpenApi(files)\n if (openApi) {\n const filename = basename(openApi.relativePath)\n if (!assets.some((asset) => asset.path === filename)) {\n assets.push({ path: filename, content: readFileSync(openApi.absolutePath) })\n }\n docsConfig = injectOpenApi(docsConfig, filename)\n }\n\n if (pages.length === 0) throw new Error('No importable Markdown or MDX pages were found in the repository.')\n return {\n sourceUrl: options.sourceUrl,\n sourceKind: 'repository',\n platform,\n pages,\n assets,\n docsConfig,\n warnings,\n stats: { discovered: files.length, imported: pages.length, skipped },\n }\n}\n","/** Markdown/MDX normalization that preserves every component Thally supports. */\n\nimport matter from 'gray-matter'\n\nimport type { MigrationPage } from './types.js'\n\nfunction titleFromId(id: string): string {\n const value = id.split('/').at(-1) ?? id\n if (value === 'introduction') return 'Introduction'\n return value\n .split(/[-_]/)\n .filter(Boolean)\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1))\n .join(' ')\n}\n\nfunction firstParagraph(content: string): string {\n for (const block of content.split(/\\n\\s*\\n/)) {\n const value = block.replace(/\\s+/g, ' ').trim()\n if (!value || /^(?:#|```|:::|<|import\\s|export\\s)/.test(value)) continue\n return value.replace(/\\[([^\\]]+)\\]\\([^)]+\\)/g, '$1').slice(0, 240)\n }\n return ''\n}\n\n/** Normalize only syntax Thally cannot render; supported Mintlify JSX stays intact. */\nexport function normalizeMdx(body: string): string {\n return body\n .replace(/<!--([\\s\\S]*?)-->/g, (_match, content: string) => `{/*${content}*/}`)\n .replace(/<Danger(\\s[^>]*)?>/g, '<Error$1>')\n .replace(/<\\/Danger>/g, '</Error>')\n .replace(/<Check(\\s[^>]*)?>/g, '<Note$1>')\n .replace(/<\\/Check>/g, '</Note>')\n .replace(/<Tree\\.Folder/g, '<Folder')\n .replace(/<\\/Tree\\.Folder>/g, '</Folder>')\n .replace(/<Tree\\.File/g, '<File')\n .replace(/<\\/Tree\\.File>/g, '</File>')\n}\n\n/** Parse source Markdown or MDX into the canonical page representation. */\nexport function parseMarkdownPage(input: {\n id: string\n navigationId?: string\n locale?: string\n raw: string\n source: string\n}): MigrationPage | null {\n const parsed = matter(input.raw)\n const body = normalizeMdx(parsed.content).trim()\n if (parsed.data.openapi && !body) return null\n const keywords = Array.isArray(parsed.data.keywords)\n ? parsed.data.keywords.filter((value): value is string => typeof value === 'string')\n : []\n const title = typeof parsed.data.title === 'string' && parsed.data.title.trim()\n ? parsed.data.title.trim()\n : titleFromId(input.navigationId ?? input.id)\n const description = typeof parsed.data.description === 'string' && parsed.data.description.trim()\n ? parsed.data.description.trim()\n : firstParagraph(body)\n return {\n id: input.id,\n navigationId: input.navigationId ?? input.id,\n locale: input.locale,\n title,\n description,\n keywords,\n body,\n source: input.source,\n }\n}\n","/**\n * Navigation projection for imported sites. Mintlify's schema is intentionally\n * more expressive than Thally's tab/group model, so complex containers are\n * flattened predictably while preserving page order and nested groups.\n */\n\nimport { existsSync, readFileSync } from 'node:fs'\nimport { dirname, extname, relative } from 'node:path'\n\nimport { pageIdFromReference, resolveWithin } from './path.js'\nimport type {\n MigrationDocsConfig,\n MigrationNavigationGroup,\n MigrationNavigationTab,\n MigrationPage,\n MigrationWarning,\n} from './types.js'\n\ninterface MintlifyPageReference {\n ref: string\n navigationId: string\n locale?: string\n}\n\nexport interface MintlifyNavigationResult {\n docsConfig: MigrationDocsConfig\n pageReferences: Array<MintlifyPageReference>\n warnings: Array<MigrationWarning>\n}\n\nconst LANGUAGE_LABELS: Record<string, string> = {\n ar: 'Arabic',\n de: 'German',\n en: 'English',\n es: 'Spanish',\n fr: 'French',\n hi: 'Hindi',\n it: 'Italian',\n ja: 'Japanese',\n ko: 'Korean',\n nl: 'Dutch',\n pl: 'Polish',\n pt: 'Portuguese',\n ru: 'Russian',\n tr: 'Turkish',\n uk: 'Ukrainian',\n zh: 'Chinese',\n}\n\nfunction objectValue(value: unknown): Record<string, unknown> | null {\n return value !== null && typeof value === 'object' && !Array.isArray(value)\n ? value as Record<string, unknown>\n : null\n}\n\nfunction labelFor(value: Record<string, unknown>, fallback: string): string {\n for (const key of ['tab', 'group', 'anchor', 'product', 'dropdown', 'version', 'menu', 'label', 'name', 'title']) {\n if (typeof value[key] === 'string' && value[key]) return String(value[key])\n }\n return fallback\n}\n\nfunction localReference(value: string): string {\n return value.split('#', 1)[0]\n}\n\nfunction jsonPointer(root: unknown, pointer: string): unknown {\n if (!pointer || pointer === '#') return root\n const tokens = pointer.replace(/^#\\/?/, '').split('/').filter(Boolean)\n return tokens.reduce<unknown>((current, token) => {\n const object = objectValue(current)\n if (!object) return undefined\n return object[token.replace(/~1/g, '/').replace(/~0/g, '~')]\n }, root)\n}\n\nfunction resolveJsonReferences(\n value: unknown,\n currentFile: string,\n repositoryRoot: string,\n stack: Set<string>,\n): unknown {\n if (Array.isArray(value)) {\n return value.map((entry) => resolveJsonReferences(entry, currentFile, repositoryRoot, stack))\n }\n const object = objectValue(value)\n if (!object) return value\n if (typeof object.$ref === 'string') {\n const [filePart, pointer = ''] = object.$ref.split('#', 2)\n const referencedFile = filePart\n ? resolveWithin(dirname(currentFile), filePart)\n : currentFile\n const relativePath = relative(repositoryRoot, referencedFile)\n resolveWithin(repositoryRoot, relativePath)\n const stackKey = `${referencedFile}#${pointer}`\n if (stack.has(stackKey)) throw new Error(`Circular Mintlify $ref: ${object.$ref}`)\n stack.add(stackKey)\n const referencedRoot = JSON.parse(readFileSync(referencedFile, 'utf8')) as unknown\n const referenced = jsonPointer(referencedRoot, pointer ? `#${pointer}` : '')\n const resolved = resolveJsonReferences(referenced, referencedFile, repositoryRoot, stack)\n stack.delete(stackKey)\n return resolved\n }\n return Object.fromEntries(\n Object.entries(object).map(([key, entry]) => [\n key,\n resolveJsonReferences(entry, currentFile, repositoryRoot, stack),\n ]),\n )\n}\n\n/** Read `docs.json`/`mint.json`, including bounded local JSON references. */\nexport function readMintlifyConfig(repositoryRoot: string): Record<string, unknown> | null {\n const configPath = ['docs.json', 'mint.json']\n .map((filename) => resolveWithin(repositoryRoot, filename))\n .find(existsSync)\n if (!configPath) return null\n const raw = JSON.parse(readFileSync(configPath, 'utf8')) as unknown\n return resolveJsonReferences(raw, configPath, repositoryRoot, new Set()) as Record<string, unknown>\n}\n\nfunction normalizePageRef(value: string): string | null {\n if (/^(?:https?:)?\\/\\//i.test(value) || value.startsWith('#')) return null\n const ref = localReference(value).replace(/^\\/+/, '').replace(/\\.(?:mdx?|rst|txt)$/i, '')\n return pageIdFromReference(ref)\n}\n\ninterface ProjectionContext {\n locale?: string\n references: Array<MintlifyPageReference>\n seenReferences: Set<string>\n}\n\nfunction registerReference(value: string, context: ProjectionContext): string | null {\n const localePrefix = context.locale ? `${context.locale}/` : ''\n const localizedValue = localePrefix && value.replace(/^\\/+/, '').startsWith(localePrefix)\n ? value.replace(/^\\/+/, '').slice(localePrefix.length)\n : value\n const navigationId = normalizePageRef(localizedValue)\n if (!navigationId) return null\n const key = `${context.locale ?? ''}:${value}`\n if (!context.seenReferences.has(key)) {\n context.seenReferences.add(key)\n context.references.push({ ref: value, navigationId, locale: context.locale })\n }\n return navigationId\n}\n\nfunction convertPage(\n value: unknown,\n context: ProjectionContext,\n): string | MigrationNavigationGroup | null {\n if (typeof value === 'string') return registerReference(value, context)\n const object = objectValue(value)\n if (!object) return null\n if (typeof object.page === 'string') return registerReference(object.page, context)\n const pages = Array.isArray(object.pages) ? object.pages : []\n if ('group' in object || pages.length > 0) {\n const children: Array<string | MigrationNavigationGroup> = []\n if (typeof object.root === 'string') {\n const root = registerReference(object.root, context)\n if (root) children.push(root)\n }\n for (const page of pages) {\n const converted = convertPage(page, context)\n if (converted) children.push(converted)\n }\n if (children.length === 0) return null\n return {\n group: labelFor(object, 'Documentation'),\n ...(typeof object.icon === 'string' ? { icon: object.icon } : {}),\n pages: children,\n }\n }\n return null\n}\n\nfunction convertGroups(\n values: Array<unknown>,\n context: ProjectionContext,\n fallbackGroup: string,\n): Array<MigrationNavigationGroup> {\n const groups: Array<MigrationNavigationGroup> = []\n const loosePages: Array<string | MigrationNavigationGroup> = []\n for (const value of values) {\n const converted = convertPage(value, context)\n if (!converted) continue\n if (typeof converted === 'string') loosePages.push(converted)\n else groups.push(converted)\n }\n if (loosePages.length > 0) groups.unshift({ group: fallbackGroup, pages: loosePages })\n return groups\n}\n\nfunction convertContainerToTabs(\n containerValue: unknown,\n context: ProjectionContext,\n fallbackTab: string,\n): Array<MigrationNavigationTab> {\n const container = objectValue(containerValue)\n if (!container) return []\n for (const key of ['tabs', 'anchors', 'products', 'dropdowns', 'versions', 'menus']) {\n if (!Array.isArray(container[key])) continue\n const tabs = (container[key] as Array<unknown>).flatMap((value, index) => {\n const object = objectValue(value)\n if (!object) return []\n const tab = labelFor(object, `${fallbackTab} ${index + 1}`)\n if (typeof object.href === 'string' && !object.pages && !object.groups) {\n return [{ tab, href: object.href }]\n }\n const nested = convertContainerToTabs(object, context, tab)\n if (nested.length > 0) {\n if (nested.length === 1) return [{ ...nested[0], tab }]\n return nested.map((item) => ({ ...item, tab: `${tab}: ${item.tab}` }))\n }\n return []\n })\n if (tabs.length > 0) return tabs\n }\n const rawPages = [\n ...(Array.isArray(container.groups) ? container.groups : []),\n ...(Array.isArray(container.pages) ? container.pages : []),\n ]\n if (typeof container.root === 'string') rawPages.unshift(container.root)\n const groups = convertGroups(rawPages, context, 'Overview')\n return groups.length > 0 ? [{ tab: fallbackTab, groups }] : []\n}\n\n/** Convert current and legacy Mintlify navigation into Thally's schema. */\nexport function projectMintlifyNavigation(config: Record<string, unknown>): MintlifyNavigationResult {\n const warnings: Array<MigrationWarning> = []\n const references: Array<MintlifyPageReference> = []\n const seenReferences = new Set<string>()\n const navigation = objectValue(config.navigation) ?? config\n const languages = Array.isArray(navigation.languages)\n ? navigation.languages.map(objectValue).filter((value): value is Record<string, unknown> => Boolean(value))\n : []\n let tabs: Array<MigrationNavigationTab> = []\n let i18n: MigrationDocsConfig['i18n']\n\n if (languages.length > 0) {\n const defaultLanguage = languages.find((entry) => entry.language === 'en') ?? languages[0]\n const defaultLocale = String(defaultLanguage.language ?? 'en')\n const locales = languages.map((entry) => {\n const code = String(entry.language ?? entry.locale ?? 'en')\n return { code, label: LANGUAGE_LABELS[code] ?? code.toUpperCase() }\n })\n i18n = { defaultLocale, locales }\n for (const language of languages) {\n const locale = String(language.language ?? language.locale ?? defaultLocale)\n const context: ProjectionContext = {\n locale,\n references,\n seenReferences,\n }\n const languageTabs = convertContainerToTabs(language, context, 'Documentation')\n if (language === defaultLanguage) tabs = languageTabs\n }\n } else {\n tabs = convertContainerToTabs(navigation, { references, seenReferences }, 'Documentation')\n if (tabs.length === 0 && Array.isArray(config.navigation)) {\n const groups = convertGroups(config.navigation, { references, seenReferences }, 'Overview')\n if (groups.length > 0) tabs = [{ tab: 'Documentation', groups }]\n }\n }\n\n if (tabs.length === 0) {\n warnings.push({\n code: 'unsupported-config',\n message: 'Mintlify navigation could not be projected; generated navigation will be used.',\n })\n }\n if (!tabs.some((tab) => tab.tab.toLowerCase() === 'changelog')) {\n tabs.push({ tab: 'Changelog', href: '/changelog' })\n }\n const redirects = Array.isArray(config.redirects)\n ? config.redirects.flatMap((value) => {\n const redirect = objectValue(value)\n if (!redirect || typeof redirect.source !== 'string' || typeof redirect.destination !== 'string') return []\n return [{\n source: redirect.source,\n destination: redirect.destination,\n ...(typeof redirect.permanent === 'boolean' ? { permanent: redirect.permanent } : {}),\n }]\n })\n : []\n return {\n docsConfig: { tabs, ...(i18n ? { i18n } : {}), ...(redirects.length > 0 ? { redirects } : {}) },\n pageReferences: references,\n warnings,\n }\n}\n\nfunction titleCase(value: string): string {\n return value\n .split(/[-_]/)\n .map((word) => ['api', 'cli', 'sdk', 'ui'].includes(word.toLowerCase())\n ? word.toUpperCase()\n : word.charAt(0).toUpperCase() + word.slice(1))\n .join(' ')\n}\n\ninterface GeneratedNavigationOptions {\n /** Dedicated docs platforms expose their primary sections as top-level tabs. */\n topLevelTabs?: boolean\n /** Ordered tabs recovered from the source site's rendered navigation. */\n topLevelNavigation?: ReadonlyArray<{\n section: string\n label: string\n pageId: string\n }>\n}\n\nconst TOP_LEVEL_LABELS: Record<string, string> = {\n 'api-reference': 'API Reference',\n cli: 'CLI',\n faqs: 'FAQs',\n introduction: 'Overview',\n 'mcp-server': 'MCP Server',\n sdk: 'SDK',\n}\n\nfunction topLevelLabel(segment: string): string {\n return TOP_LEVEL_LABELS[segment] ?? titleCase(segment)\n}\n\nfunction groupsWithinSection(\n section: string,\n pageIds: Array<string>,\n sectionLabel = topLevelLabel(section),\n): Array<MigrationNavigationGroup> {\n const groups = new Map<string, Array<string>>()\n for (const id of pageIds) {\n const relative = id === 'introduction'\n ? ''\n : id.startsWith(`${section}/`)\n ? id.slice(section.length + 1)\n : id\n const nestedSegment = relative.includes('/') ? relative.split('/', 1)[0] : 'overview'\n const group = groups.get(nestedSegment) ?? []\n group.push(id)\n groups.set(nestedSegment, group)\n }\n return [...groups].map(([segment, pages]) => ({\n group: segment === 'overview' ? sectionLabel : titleCase(segment),\n pages,\n }))\n}\n\nfunction preferredLandingPage(\n section: string,\n pageIds: Array<string>,\n): string | undefined {\n const candidates = [\n section === 'introduction' ? 'introduction' : undefined,\n `${section}/overview`,\n `${section}/introduction`,\n section,\n ]\n return candidates.find((candidate): candidate is string => Boolean(candidate && pageIds.includes(candidate)))\n}\n\n/** Build deterministic fallback navigation from imported default-locale pages. */\nexport function buildNavigationFromPages(\n pages: Array<MigrationPage>,\n options: GeneratedNavigationOptions = {},\n): MigrationDocsConfig {\n const ids = pages.filter((page) => !page.locale || page.locale === 'en').map((page) => page.navigationId)\n const ordered = [...new Set(ids)]\n if (options.topLevelTabs) {\n const sourceNavigation = (options.topLevelNavigation ?? []).flatMap((entry) => {\n const sectionPages = ordered.filter((id) => id === entry.section || id.startsWith(`${entry.section}/`))\n const pageId = ordered.includes(entry.pageId)\n ? entry.pageId\n : preferredLandingPage(entry.section, sectionPages) ?? sectionPages[0]\n return pageId ? [{ ...entry, pageId }] : []\n })\n if (sourceNavigation.length > 1) {\n const claimedIds = new Set<string>()\n const tabs = sourceNavigation.map((entry) => {\n const pageIds = ordered.filter((id) => {\n const matches = id === entry.pageId\n || id === entry.section\n || id.startsWith(`${entry.section}/`)\n if (matches) claimedIds.add(id)\n return matches\n })\n return { entry, pageIds }\n })\n // Mintlify's first tab is the documentation home and owns pages that do\n // not belong to another product tab (for example /create and /deploy).\n tabs[0].pageIds.push(...ordered.filter((id) => !claimedIds.has(id)))\n return {\n tabs: tabs.map(({ entry, pageIds }) => ({\n tab: entry.label,\n href: entry.pageId === 'introduction' ? '/' : `/${entry.pageId}`,\n groups: groupsWithinSection(entry.section, [...new Set(pageIds)], entry.label),\n })),\n }\n }\n const sectionNames = [...new Set(ordered\n .filter((id) => id.includes('/'))\n .map((id) => id.split('/', 1)[0]))]\n if (sectionNames.length > 1) {\n const defaultSection = sectionNames.includes('introduction')\n ? 'introduction'\n : sectionNames[0]\n const sections = new Map<string, Array<string>>()\n for (const id of ordered) {\n const section = id.includes('/') ? id.split('/', 1)[0] : defaultSection\n const bucket = sections.get(section) ?? []\n bucket.push(id)\n sections.set(section, bucket)\n }\n return {\n tabs: [...sections].map(([section, pageIds]) => {\n const label = topLevelLabel(section)\n const landingPage = preferredLandingPage(section, pageIds)\n return {\n tab: label,\n ...(landingPage\n ? { href: landingPage === 'introduction' ? '/' : `/${landingPage}` }\n : {}),\n groups: groupsWithinSection(section, pageIds),\n }\n }),\n }\n }\n }\n const buckets = new Map<string, Array<string>>()\n for (const id of ordered) {\n const segment = id.includes('/') ? id.split('/', 1)[0] : 'overview'\n const bucket = buckets.get(segment) ?? []\n bucket.push(id)\n buckets.set(segment, bucket)\n }\n const groups = [...buckets].map(([segment, pageIds]) => ({\n group: segment === 'overview' ? 'Overview' : titleCase(segment),\n pages: pageIds,\n }))\n return { tabs: [{ tab: 'Documentation', groups }] }\n}\n\n/** Exposed for repository discovery and focused unit tests. */\nexport function isDocumentationExtension(filename: string): boolean {\n return ['.md', '.mdx', '.rst', '.txt'].includes(extname(filename).toLowerCase())\n}\n","/** Safe path normalization used before reading or writing migrated content. */\n\nimport { isAbsolute, relative, resolve, sep } from 'node:path'\n\nconst SAFE_SEGMENT = /[^a-z0-9._-]+/g\n\n/** Turn a source path segment into a stable URL/file-system slug. */\nexport function slugifySegment(value: string): string {\n let decoded = value\n try {\n decoded = decodeURIComponent(value)\n } catch {\n // Malformed percent escapes are legal in source filenames. Treat them as\n // literal slug input instead of letting one file abort the whole import.\n }\n return decoded\n .toLowerCase()\n .replace(/\\.(?:html?|mdx?)$/i, '')\n .replace(SAFE_SEGMENT, '-')\n .replace(/(^-|-$)/g, '')\n}\n\n/**\n * Normalize a page reference to a Thally content id. Invalid or traversal\n * references return `null` instead of being allowed near the file system.\n */\nexport function pageIdFromReference(value: string): string | null {\n const withoutQuery = value.split(/[?#]/, 1)[0].replace(/\\\\/g, '/').replace(/^\\/+/, '')\n if (!withoutQuery || withoutQuery.includes('\\0')) return null\n const rawSegments = withoutQuery.split('/').filter(Boolean)\n if (rawSegments.some((segment) => segment === '..' || segment === '.')) return null\n const last = rawSegments.at(-1)?.replace(/\\.(?:mdx?|rst|txt)$/i, '') ?? ''\n const baseSegments = /^(?:index|readme)$/i.test(last) ? rawSegments.slice(0, -1) : rawSegments\n if (!/^(?:index|readme)$/i.test(last)) {\n baseSegments[baseSegments.length - 1] = last\n }\n const segments = baseSegments.map(slugifySegment).filter(Boolean)\n return segments.join('/') || 'introduction'\n}\n\n/** Resolve an untrusted relative path and prove it remains below `root`. */\nexport function resolveWithin(root: string, candidate: string): string {\n if (isAbsolute(candidate) || candidate.includes('\\0')) {\n throw new Error(`Unsafe migration path: ${candidate}`)\n }\n const target = resolve(root, candidate)\n const fromRoot = relative(resolve(root), target)\n if (fromRoot === '..' || fromRoot.startsWith(`..${sep}`) || isAbsolute(fromRoot)) {\n throw new Error(`Migration path escapes its root: ${candidate}`)\n }\n return target\n}\n\n/** Return a slash-separated, traversal-free asset path. */\nexport function normalizeAssetPath(value: string): string | null {\n const normalized = value.replace(/\\\\/g, '/').replace(/^\\/+/, '')\n if (!normalized || normalized.includes('\\0')) return null\n const segments = normalized.split('/').filter(Boolean)\n if (segments.some((segment) => segment === '.' || segment === '..')) return null\n return segments.join('/')\n}\n","/** Render canonical migration bundles into a portable Thally repository tree. */\n\nimport type {\n MigrationBundle,\n MigrationDocsConfig,\n MigrationNavigationGroup,\n RenderedMigrationFile,\n} from './types.js'\n\nfunction yamlString(value: string): string {\n return JSON.stringify(value.replace(/\\s+/g, ' ').trim())\n}\n\nfunction renderPage(bundle: MigrationBundle, page: MigrationBundle['pages'][number]): string {\n return [\n '---',\n `title: ${yamlString(page.title)}`,\n `description: ${yamlString(page.description)}`,\n page.keywords.length > 0 ? `keywords: [${page.keywords.map(yamlString).join(', ')}]` : null,\n bundle.sourceKind === 'url' ? `source: ${yamlString(page.source)}` : null,\n '---',\n '',\n page.body,\n '',\n ].filter((line) => line !== null).join('\\n')\n}\n\n/** Merge imported tabs into an existing site without duplicating changelog tabs. */\nexport function mergeMigrationConfig(\n existing: MigrationDocsConfig,\n incoming: MigrationDocsConfig,\n): MigrationDocsConfig {\n const tabs = existing.tabs.filter((tab) => tab.tab.toLowerCase() !== 'changelog')\n const names = new Set(tabs.map((tab) => tab.tab.toLowerCase()))\n const seenPages = new Set<string>()\n function recordPages(groups: MigrationDocsConfig['tabs'][number]['groups']): void {\n for (const group of groups ?? []) {\n for (const page of group.pages) {\n if (typeof page === 'string') seenPages.add(page)\n else recordPages([page])\n }\n }\n }\n for (const tab of tabs) recordPages(tab.groups)\n function uniqueGroups(\n groups: Array<MigrationNavigationGroup> | undefined,\n ): Array<MigrationNavigationGroup> {\n return (groups ?? []).flatMap<MigrationNavigationGroup>((group) => {\n const pages = group.pages.flatMap<string | MigrationNavigationGroup>((page) => {\n if (typeof page === 'string') {\n if (seenPages.has(page)) return []\n seenPages.add(page)\n return [page]\n }\n const [nested]: Array<MigrationNavigationGroup> = uniqueGroups([page])\n return nested ? [nested] : []\n })\n return pages.length > 0 ? [{ ...group, pages }] : []\n })\n }\n for (const tab of incoming.tabs) {\n if (tab.tab.toLowerCase() === 'changelog') continue\n const uniqueTab = { ...tab, ...(tab.groups ? { groups: uniqueGroups(tab.groups) } : {}) }\n if (tab.groups && uniqueTab.groups?.length === 0 && !tab.href && !tab.api) continue\n if (!names.has(tab.tab.toLowerCase())) {\n tabs.push(uniqueTab)\n names.add(tab.tab.toLowerCase())\n continue\n }\n const target = tabs.find((item) => item.tab.toLowerCase() === tab.tab.toLowerCase())\n if (!target || !uniqueTab.groups) continue\n target.groups = [...(target.groups ?? []), ...uniqueTab.groups]\n }\n const changelog = existing.tabs.find((tab) => tab.tab.toLowerCase() === 'changelog')\n ?? incoming.tabs.find((tab) => tab.tab.toLowerCase() === 'changelog')\n if (changelog) tabs.push(changelog)\n const i18n = existing.i18n || incoming.i18n\n ? {\n defaultLocale: existing.i18n?.defaultLocale ?? incoming.i18n?.defaultLocale ?? 'en',\n locales: [...new Map(\n [...(existing.i18n?.locales ?? []), ...(incoming.i18n?.locales ?? [])]\n .map((locale) => [locale.code, locale]),\n ).values()],\n }\n : undefined\n return {\n ...incoming,\n ...existing,\n tabs,\n ...(i18n ? { i18n } : {}),\n }\n}\n\n/** Materialize every canonical page, asset, and config as repository file changes. */\nexport function renderMigrationFiles(\n bundle: MigrationBundle,\n options: { existingConfig?: MigrationDocsConfig } = {},\n): Array<RenderedMigrationFile> {\n const config = options.existingConfig\n ? mergeMigrationConfig(options.existingConfig, bundle.docsConfig)\n : bundle.docsConfig\n return [\n ...bundle.pages.map((page) => ({\n path: `src/content/${page.id}.mdx`,\n content: renderPage(bundle, page),\n })),\n ...bundle.assets.map((asset) => ({ path: `public/${asset.path}`, content: asset.content })),\n { path: 'docs.json', content: `${JSON.stringify(config, null, 2)}\\n` },\n ]\n}\n","/**\n * Public URL adapter for the shared migration engine. Discovery prefers\n * machine-readable Markdown and sitemaps, remains scoped to the submitted docs\n * path, then falls back to bounded navigation crawling and HTML extraction.\n */\n\nimport { load } from 'cheerio'\nimport TurndownService from 'turndown'\n\nimport { parseMarkdownPage } from './mdx.js'\nimport { buildNavigationFromPages } from './navigation.js'\nimport { pageIdFromReference } from './path.js'\nimport type {\n MigrationBundle,\n MigrationFetcher,\n MigrationFetchResponse,\n MigrationPage,\n MigrationPlatform,\n MigrationWarning,\n} from './types.js'\n\nconst DEFAULT_MAX_PAGES = 1_000\nconst DEFAULT_MAX_TOTAL_BYTES = 100_000_000\nconst MAX_DISCOVERED_URLS = 5_000\nconst MAX_LOCAL_RESPONSE_BYTES = 2_000_000\nconst MAX_SITEMAP_DOCUMENTS = 25\nconst PORTABLE_MDX_COMPONENTS = new Set([\n 'Accordion', 'AccordionGroup', 'Badge', 'Callout', 'Card', 'CardGroup',\n 'Check', 'CodeGroup', 'Color', 'Column', 'Columns', 'Danger', 'Error', 'Expandable',\n 'File', 'Folder', 'Frame', 'Hero', 'Icon', 'Info', 'Latex', 'Mermaid',\n 'Note', 'Panel', 'ParamField', 'Prompt', 'PromptAssistant', 'PromptUser',\n 'RequestExample', 'ResponseExample', 'ResponseField', 'Step', 'Steps',\n 'Tab', 'Tabs', 'Tile', 'TileGroup', 'Tip', 'Tooltip', 'Tree', 'Update',\n 'View', 'Warning',\n])\nconst LOCALE_CODES = new Set([\n 'ar', 'cs', 'da', 'de', 'el', 'es', 'fi', 'fr', 'he', 'hi', 'hu', 'id',\n 'it', 'ja', 'ko', 'ms', 'nl', 'no', 'pl', 'pt', 'ro', 'ru', 'sk', 'sv',\n 'th', 'tr', 'uk', 'vi', 'zh', 'pt-br', 'zh-hans', 'zh-hant',\n])\nconst PORTABLE_URL_PROPS = 'href|src|img|primaryHref|secondaryHref'\n\nexport interface UrlMigrationOptions {\n sourceUrl: string\n fetcher?: MigrationFetcher\n maxPages?: number\n concurrency?: number\n maxTotalBytes?: number\n}\n\n/** Validate the transport-level shape of a docs URL; hosted callers add SSRF checks. */\nexport function validateMigrationUrl(value: string): URL {\n let url: URL\n try {\n url = new URL(value)\n } catch {\n throw new Error('Enter a complete documentation URL, including https://.')\n }\n if (!['http:', 'https:'].includes(url.protocol)) {\n throw new Error('Documentation imports support only HTTP and HTTPS URLs.')\n }\n if (url.username || url.password) throw new Error('Documentation URLs cannot contain credentials.')\n url.hash = ''\n return url\n}\n\nasync function readResponseBody(response: Response): Promise<string> {\n const contentLength = Number(response.headers.get('content-length') ?? 0)\n if (contentLength > MAX_LOCAL_RESPONSE_BYTES) throw new Error('A documentation response exceeded the 2 MB import limit.')\n if (!response.body) return ''\n const reader = response.body.getReader()\n const chunks: Array<Uint8Array> = []\n let size = 0\n while (true) {\n const { done, value } = await reader.read()\n if (done) break\n size += value.byteLength\n if (size > MAX_LOCAL_RESPONSE_BYTES) {\n await reader.cancel()\n throw new Error('A documentation response exceeded the 2 MB import limit.')\n }\n chunks.push(value)\n }\n const body = new Uint8Array(size)\n let offset = 0\n for (const chunk of chunks) {\n body.set(chunk, offset)\n offset += chunk.byteLength\n }\n return new TextDecoder().decode(body)\n}\n\n/** Fetch implementation for local CLI usage. Cloud injects its pinned network boundary. */\nexport const defaultMigrationFetcher: MigrationFetcher = async (url, request) => {\n const response = await fetch(url, {\n headers: {\n Accept: request.accept,\n 'User-Agent': 'Thally-Migrate/1.0 (+https://thally.io)',\n },\n redirect: 'follow',\n signal: AbortSignal.timeout(15_000),\n })\n if (!response.ok) throw new Error(`Documentation server returned ${response.status}.`)\n return {\n finalUrl: new URL(response.url),\n body: await readResponseBody(response),\n contentType: response.headers.get('content-type') ?? '',\n headers: Object.fromEntries(response.headers.entries()),\n }\n}\n\nfunction docsScopePath(source: URL): string {\n const path = source.pathname.replace(/\\/+$/, '') || '/'\n if (path === '/') return '/'\n const segments = path.split('/').filter(Boolean)\n return `/${segments.length > 1 ? segments[0] : segments.join('/')}`\n}\n\nfunction machineIndexScopePath(\n source: URL,\n documents: Array<MigrationFetchResponse | null>,\n): string | null {\n const candidates = new Set<string>()\n for (const document of documents) {\n if (!document) continue\n const references = [...headerLinks(document)]\n if (/html/i.test(document.contentType)) {\n const $ = load(document.body)\n references.push(...$('link[href], a[href]')\n .map((_index, element) => $(element).attr('href') ?? '')\n .get()\n .filter((href) => /\\/(?:llms(?:-full)?\\.txt|sitemap\\.xml)(?:[?#]|$)/i.test(href)))\n }\n for (const reference of references) {\n try {\n const indexUrl = new URL(reference, document.finalUrl)\n if (indexUrl.origin !== source.origin) continue\n const scope = indexUrl.pathname.replace(/\\/(?:llms(?:-full)?\\.txt|sitemap\\.xml)$/i, '') || '/'\n if (isInScope(source, source, scope)) candidates.add(scope)\n } catch {\n // Malformed discovery hints are ignored just like malformed page links.\n }\n }\n }\n return [...candidates].sort((left, right) => right.length - left.length)[0] ?? null\n}\n\nfunction isInScope(url: URL, source: URL, scopePath: string): boolean {\n if (url.origin !== source.origin || !['http:', 'https:'].includes(url.protocol)) return false\n const path = url.pathname.replace(/\\/+$/, '') || '/'\n if (scopePath === '/') return true\n return path === scopePath || path === `${scopePath}.md` || path.startsWith(`${scopePath}/`)\n}\n\nfunction normalizeCandidate(value: string, base: URL, source: URL, scopePath: string): URL | null {\n try {\n const url = new URL(value, base)\n url.hash = ''\n if (!isInScope(url, source, scopePath)) return null\n if (url.pathname.startsWith('/cdn-cgi/')) return null\n if (/\\/(?:llms(?:-full)?|robots)\\.txt$/i.test(url.pathname)\n || /\\/sitemap\\.xml$/i.test(url.pathname)) return null\n if (/\\.(?:avif|bmp|gif|ico|jpe?g|mp[34]|pdf|png|svg|webm|webp|zip)$/i.test(url.pathname)) return null\n return url\n } catch {\n return null\n }\n}\n\nfunction candidateIdentity(url: URL): string {\n const pathname = url.pathname.replace(/\\.mdx?$/i, '').replace(/\\/+$/, '') || '/'\n return `${url.origin}${pathname}${url.search}`\n}\n\nfunction pageIdForUrl(url: URL, scopePath: string): string | null {\n let path = url.pathname.replace(/\\/+$/, '')\n if (scopePath !== '/') {\n if (path === `${scopePath}.md`) path = ''\n else if (path === scopePath) path = ''\n else if (path.startsWith(`${scopePath}/`)) path = path.slice(scopePath.length + 1)\n }\n return pageIdFromReference(path.replace(/^\\/+/, '') || 'introduction')\n}\n\nfunction canonicalLocalizedPageId(id: string): string {\n const [segment, ...rest] = id.split('/')\n if (LOCALE_CODES.has(segment)) return rest.length > 0 ? id : `${segment}/introduction`\n for (const locale of LOCALE_CODES) {\n if (segment !== `${locale}-api-reference`) continue\n return [locale, 'api-reference', ...rest].join('/')\n }\n return id\n}\n\nfunction detectUrlPlatform(document: MigrationFetchResponse): MigrationPlatform {\n const headers = Object.entries(document.headers ?? {})\n .map(([key, value]) => `${key}:${value ?? ''}`)\n .join(' ')\n const value = `${document.body.slice(0, 200_000)} ${headers}`.toLowerCase()\n if (value.includes('__mintlify') || value.includes('/mintlify-assets/')\n || value.includes('x-mintlify-') || value.includes('/_mintlify/')) return 'mintlify'\n if (value.includes('docusaurus') || value.includes('__docusaurus')) return 'docusaurus'\n if (value.includes('gitbook') || value.includes('gitbook.io')) return 'gitbook'\n if (value.includes('nextra')) return 'nextra'\n if (value.includes('vitepress')) return 'vitepress'\n if (value.includes('starlight')) return 'starlight'\n return 'generic'\n}\n\nfunction plainDescription(value: string): string {\n return value\n .replace(/\\[([^\\]]+)\\]\\([^)]+\\)/g, '$1')\n .replace(/[`*_>#-]/g, '')\n .replace(/\\s+/g, ' ')\n .trim()\n .slice(0, 240)\n}\n\nfunction withoutFencedCode(body: string): string {\n let fenceCharacter = ''\n let fenceLength = 0\n return body.split('\\n').map((line) => {\n const match = line.match(/^\\s{0,3}(`{3,}|~{3,})(.*)$/)\n if (match && !fenceCharacter) {\n fenceCharacter = match[1][0]\n fenceLength = match[1].length\n return ''\n }\n if (match && match[1][0] === fenceCharacter && match[1].length >= fenceLength\n && match[2].trim() === '') {\n fenceCharacter = ''\n fenceLength = 0\n return ''\n }\n return fenceCharacter ? '' : line\n }).join('\\n')\n}\n\nfunction eventHandlerPropEnd(value: string, start: number): number | null {\n const opening = value[start]\n if (opening === '\"' || opening === \"'\") {\n for (let index = start + 1; index < value.length; index += 1) {\n if (value[index] === opening && value[index - 1] !== '\\\\') return index + 1\n }\n return null\n }\n if (opening !== '{') {\n const match = value.slice(start).match(/^[^\\s>]+/)\n return match ? start + match[0].length : null\n }\n let depth = 0\n let quote = ''\n for (let index = start; index < value.length; index += 1) {\n const character = value[index]\n if (quote) {\n if (character === quote && value[index - 1] !== '\\\\') quote = ''\n continue\n }\n if (character === '\"' || character === \"'\" || character === '`') {\n quote = character\n continue\n }\n if (character === '{') depth += 1\n if (character === '}') {\n depth -= 1\n if (depth === 0) return index + 1\n }\n }\n return null\n}\n\nfunction stripEventHandlerProps(line: string): string {\n const matcher = /\\s+on[A-Z][A-Za-z0-9]*\\s*=\\s*/g\n let cursor = 0\n let result = ''\n for (const match of line.matchAll(matcher)) {\n const start = match.index\n const valueStart = start + match[0].length\n const end = eventHandlerPropEnd(line, valueStart)\n if (end === null) continue\n result += line.slice(cursor, start)\n cursor = end\n }\n return cursor === 0 ? line : `${result}${line.slice(cursor)}`\n}\n\nfunction hasUnsafeUrlScheme(value: string): boolean {\n const normalized = value\n .trim()\n .replace(/[\\u0000-\\u0020]/g, '')\n .replace(/&(?:#x0*3a|#0*58|colon);/gi, ':')\n return /^(?:javascript|data|vbscript):/i.test(normalized)\n}\n\nfunction hasUnsafePortableUrlProp(value: string): boolean {\n const quotedProps = new RegExp(`\\\\b(?:${PORTABLE_URL_PROPS})\\\\s*=\\\\s*(['\"])([^'\"\\\\r\\\\n]*)\\\\1`, 'gi')\n for (const match of value.matchAll(quotedProps)) {\n if (hasUnsafeUrlScheme(match[2])) return true\n }\n const expressionProps = new RegExp(`\\\\b(?:${PORTABLE_URL_PROPS})\\\\s*=\\\\s*\\\\{\\\\s*(\"(?:\\\\\\\\.|[^\"\\\\\\\\])*\")\\\\s*\\\\}`, 'gi')\n for (const match of value.matchAll(expressionProps)) {\n try {\n if (hasUnsafeUrlScheme(JSON.parse(match[1]))) return true\n } catch {\n return true\n }\n }\n return false\n}\n\nfunction sanitizeRemoteMarkdown(body: string): string | null {\n let fenceCharacter = ''\n let fenceLength = 0\n const sanitized = body.split('\\n').map((line) => {\n const fence = line.match(/^\\s{0,3}(`{3,}|~{3,})(.*)$/)\n if (fence && !fenceCharacter) {\n fenceCharacter = fence[1][0]\n fenceLength = fence[1].length\n return line\n }\n if (fence && fence[1][0] === fenceCharacter && fence[1].length >= fenceLength\n && fence[2].trim() === '') {\n fenceCharacter = ''\n fenceLength = 0\n return line\n }\n if (fenceCharacter) return line\n return stripEventHandlerProps(line\n .replace(/!\\[([^\\]]*)\\]\\(\\s*([^)]+)\\)/g, (original, alternative: string, destination: string) => {\n return hasUnsafeUrlScheme(destination.replace(/^<|>$/g, '')) ? alternative : original\n })\n .replace(/<\\/?div\\b[^>]*>/gi, '')\n .replace(/<img\\s+([^>]*?)\\/?\\s*>/gi, (original, attributes: string) => {\n const source = attributes.match(/\\bsrc\\s*=\\s*(['\"])(.*?)\\1/i)?.[2]\n const alternative = attributes.match(/\\balt\\s*=\\s*(['\"])(.*?)\\1/i)?.[2] ?? ''\n if (!source || hasUnsafeUrlScheme(source)) return ''\n return `![${alternative.replace(/]/g, '\\\\]')}](${source})`\n }))\n }).join('\\n')\n const executable = withoutFencedCode(sanitized)\n .replace(/\\{\\/\\*[\\s\\S]*?\\*\\/\\}/g, '')\n .replace(/<(?:https?:\\/\\/|mailto:)[^>]+>/gi, '')\n .replace(/(`+)[\\s\\S]*?\\1/g, '')\n if (/^\\s*(?:import|export)\\s/m.test(executable)) return null\n // A public Markdown endpoint is still attacker-controlled MDX. Preserve\n // known documentation primitives and JSON-literal props, but never compile\n // executable expressions, raw HTML, event handlers, or local components.\n let hasUnsafeExpression = false\n const withoutStaticProps = executable.replace(/=\\{([^{}\\n]*)\\}/g, (original, value: string) => {\n try {\n JSON.parse(value)\n return '=\"\"'\n } catch {\n hasUnsafeExpression = true\n return original\n }\n }).replace(/\\\\[{}]/g, '')\n if (hasUnsafeExpression || /[{}]/.test(withoutStaticProps)\n || /\\bon[A-Z][A-Za-z]*\\s*=/g.test(withoutStaticProps)\n || hasUnsafePortableUrlProp(executable)) return null\n for (const match of withoutStaticProps.matchAll(/<\\/?([A-Za-z][A-Za-z0-9.]*)(?:\\s|>|\\/)/g)) {\n const component = match[1].split('.', 1)[0]\n if (!PORTABLE_MDX_COMPONENTS.has(component)) return null\n }\n return sanitized\n}\n\nfunction migratedHref(\n href: string,\n currentUrl: URL,\n source: URL,\n scopePath: string,\n importedIds: Set<string>,\n sourceHomePageId?: string,\n): string {\n if (/^(?:javascript|data|vbscript):/i.test(href)) return '#'\n if (href.startsWith('#') || /^(?:mailto|tel):/i.test(href)) return href\n try {\n const target = new URL(href, currentUrl)\n if (target.origin !== source.origin) return href\n if (scopePath === '/' && candidateIdentity(target) === candidateIdentity(source)) {\n return `/${target.search}${target.hash}`\n }\n let path = target.pathname\n if (scopePath !== '/' && (path === scopePath || path.startsWith(`${scopePath}/`))) {\n path = path.slice(scopePath.length)\n }\n const id = pageIdFromReference(path.replace(/^\\/+/, '') || 'introduction')\n const localizedId = id ? canonicalLocalizedPageId(id) : id\n const destinationId = localizedId === sourceHomePageId ? 'introduction' : localizedId\n if (destinationId && importedIds.has(destinationId)) {\n const destination = destinationId === 'introduction' ? '/' : `/${destinationId}`\n return `${destination}${target.search}${target.hash}`\n }\n // Same-origin marketing and intentionally missing example links remain\n // valid external URLs instead of becoming broken links in the new site.\n return target.toString()\n } catch {\n return href\n }\n}\n\nfunction rewriteInternalLinks(\n body: string,\n currentUrl: URL,\n source: URL,\n scopePath: string,\n importedIds: Set<string>,\n sourceHomePageId?: string,\n): string {\n const markdown = body.replace(/(?<!!)\\[([^\\]]+)\\]\\(([^)\\s]+)(\\s+['\"][^'\"]*['\"])?\\)/g, (\n original,\n label: string,\n href: string,\n title = '',\n ) => {\n const destination = migratedHref(href, currentUrl, source, scopePath, importedIds, sourceHomePageId)\n return destination === href ? original : `[${label}](${destination}${title})`\n })\n return markdown.replace(/\\bhref=(['\"])([^'\"]+)\\1/g, (_original, quote: string, href: string) => {\n const destination = migratedHref(href, currentUrl, source, scopePath, importedIds, sourceHomePageId)\n return `href=${quote}${destination}${quote}`\n })\n}\n\nfunction remoteMarkdownMetadata(body: string): {\n content: string\n title?: string\n description?: string\n} {\n if (!/^---\\r?\\n/.test(body)) return { content: body }\n const end = body.slice(4, 65_540).search(/\\r?\\n---(?:\\r?\\n|$)/)\n if (end < 0) return { content: body }\n const frontmatter = body.slice(4, end + 4)\n const contentStart = end + 4 + body.slice(end + 4).match(/^\\r?\\n---(?:\\r?\\n|$)/)![0].length\n function scalar(key: string): string | undefined {\n const value = frontmatter.match(new RegExp(`^${key}:\\\\s*(.+)$`, 'm'))?.[1].trim()\n if (!value) return undefined\n if (/^['\"].*['\"]$/.test(value)) {\n try {\n const parsed = JSON.parse(value.replace(/^'/, '\"').replace(/'$/, '\"'))\n return typeof parsed === 'string' ? parsed : undefined\n } catch {\n return value.slice(1, -1)\n }\n }\n return value.slice(0, 500)\n }\n return {\n content: body.slice(contentStart),\n title: scalar('title'),\n description: scalar('description'),\n }\n}\n\nfunction stripMintlifyDocumentationIndex(body: string): string {\n const lines = body.split(/\\r?\\n/)\n if (!/^>\\s*##\\s+Documentation Index\\s*$/i.test(lines[0] ?? '')\n || !/^>.*\\/llms(?:-full)?\\.txt/i.test(lines[1] ?? '')\n || !/^>.*discover all available pages/i.test(lines[2] ?? '')) return body\n let index = 3\n while (index < lines.length && /^>/.test(lines[index])) index += 1\n while (index < lines.length && lines[index].trim() === '') index += 1\n return lines.slice(index).join('\\n')\n}\n\nfunction markdownPage(document: MigrationFetchResponse, id: string): MigrationPage | null {\n const parsed = remoteMarkdownMetadata(document.body)\n let content = stripMintlifyDocumentationIndex(parsed.content).trimStart()\n const titleMatch = content.match(/^#\\s+(.+)\\r?\\n/)\n const title = parsed.title ?? titleMatch?.[1] ?? id.split('/').at(-1) ?? 'Introduction'\n if (titleMatch) content = content.slice(titleMatch[0].length).trimStart()\n let description = parsed.description\n if (!description) {\n const quoteMatch = content.match(/^(>[^\\r\\n]*(?:\\r?\\n>[^\\r\\n]*)*)\\r?\\n/)\n if (quoteMatch) {\n description = plainDescription(quoteMatch[1].replace(/^>\\s?/gm, ''))\n content = content.slice(quoteMatch[0].length).trimStart()\n }\n }\n // Re-emit only scalar metadata we parsed ourselves. `gray-matter` remains in\n // the shared page parser for trusted repository sources, but never receives\n // attacker-controlled YAML aliases from a public URL.\n const raw = [\n '---',\n `title: ${JSON.stringify(title)}`,\n ...(description ? [`description: ${JSON.stringify(description)}`] : []),\n '---',\n '',\n content,\n ].join('\\n')\n return parseMarkdownPage({ id, raw, source: document.finalUrl.toString() })\n}\n\nfunction htmlPage(\n document: MigrationFetchResponse,\n id: string,\n): { page: MigrationPage | null; links: Array<string> } {\n const $ = load(document.body)\n const links = $('nav a[href], main a[href], article a[href], [role=\"main\"] a[href]')\n .map((_index, element) => $(element).attr('href') ?? '')\n .get()\n .filter(Boolean)\n const title = $('main h1, article h1, h1').first().text().trim()\n || $('meta[property=\"og:title\"]').attr('content')?.trim()\n || $('title').text().split('|')[0].trim()\n const description = $('meta[name=\"description\"]').attr('content')?.trim()\n || $('meta[property=\"og:description\"]').attr('content')?.trim()\n const content = $('main article, article, main, [role=\"main\"]').first()\n const root = content.length ? content : $('body')\n root.find('script,style,noscript,nav,header,footer,aside,form,button,svg,iframe,object,embed,link,meta').remove()\n root.find('a[href]').each((_index, element) => {\n const href = $(element).attr('href')\n if (!href) return\n try {\n const resolved = new URL(href, document.finalUrl)\n if (['http:', 'https:', 'mailto:', 'tel:'].includes(resolved.protocol)) {\n $(element).attr('href', resolved.toString())\n } else {\n $(element).removeAttr('href')\n }\n } catch {\n $(element).removeAttr('href')\n }\n })\n root.find('img[src]').each((_index, element) => {\n const src = $(element).attr('src')\n if (!src) return\n try {\n const resolved = new URL(src, document.finalUrl)\n if (['http:', 'https:'].includes(resolved.protocol)) {\n $(element).attr('src', resolved.toString())\n } else {\n $(element).removeAttr('src')\n }\n } catch {\n $(element).removeAttr('src')\n }\n })\n const turndown = new TurndownService({ codeBlockStyle: 'fenced', emDelimiter: '_', headingStyle: 'atx' })\n turndown.remove(['script', 'style', 'noscript'])\n turndown.addRule('migration-safe-fenced-code', {\n filter: (node) => node.nodeName === 'PRE',\n replacement: (_content, node) => {\n const element = node as HTMLElement\n const code = element.textContent?.replace(/\\n$/, '') ?? ''\n const language = element.querySelector('code')?.className.match(/(?:language-|lang-)([A-Za-z0-9_+-]+)/)?.[1] ?? ''\n const longestFence = Math.max(0, ...[...code.matchAll(/`+/g)].map((match) => match[0].length))\n const fence = '`'.repeat(Math.max(3, longestFence + 1))\n return `\\n\\n${fence}${language}\\n${code}\\n${fence}\\n\\n`\n },\n })\n const escape = turndown.escape.bind(turndown)\n turndown.escape = (text: string) => escape(text).replace(/[<{]/g, (match) => `\\\\${match}`)\n const body = turndown.turndown(root.html() ?? '').trim()\n if (!title || body.length < 40) return { page: null, links }\n return {\n page: {\n id,\n navigationId: id,\n title,\n description: description || plainDescription(body) || `Documentation imported from ${document.finalUrl.hostname}.`,\n keywords: [],\n body,\n source: document.finalUrl.toString(),\n },\n links,\n }\n}\n\nfunction htmlNavigationLinks(document: MigrationFetchResponse): Array<string> {\n const $ = load(document.body)\n return $('.nav-tabs a[href], nav a[href], aside a[href], [role=\"navigation\"] a[href]')\n .map((_index, element) => $(element).attr('href') ?? '')\n .get()\n .filter(Boolean)\n}\n\ninterface SourceNavigationTab {\n section: string\n label: string\n pageId: string\n}\n\nfunction htmlTopLevelNavigation(\n document: MigrationFetchResponse,\n source: URL,\n scopePath: string,\n): Array<SourceNavigationTab> {\n const $ = load(document.body)\n interface NavigationCandidate {\n entries: Array<SourceNavigationTab>\n anchorCount: number\n }\n const collectCandidates = (selector: string): Array<NavigationCandidate> => {\n const candidates: Array<NavigationCandidate> = []\n $(selector).each((_containerIndex, container) => {\n const entries: Array<SourceNavigationTab> = []\n const seenSections = new Set<string>()\n let anchorCount = 0\n $(container).find('a[href]').each((_index, element) => {\n const label = $(element).text().replace(/\\s+/g, ' ').trim()\n const href = $(element).attr('href')\n if (!label || !href) return\n try {\n const target = new URL(href, document.finalUrl)\n if (!isInScope(target, source, scopePath)) return\n anchorCount += 1\n const targetId = canonicalLocalizedPageId(pageIdForUrl(target, scopePath) ?? '')\n const pageId = targetId\n const section = targetId.split('/', 1)[0] || 'introduction'\n if (!pageId || seenSections.has(section)) return\n seenSections.add(section)\n entries.push({ section, label, pageId })\n } catch {\n // Ignore malformed navigation targets; discovery applies the same rule.\n }\n })\n if (entries.length > 1) {\n candidates.push({ entries, anchorCount })\n }\n })\n return candidates\n }\n // Mintlify marks its product-tab strip consistently. Prefer that explicit\n // platform signal; generic nav elements usually describe only the sidebar.\n const tabCandidates = collectCandidates('.nav-tabs')\n const candidates = tabCandidates.length > 0\n ? tabCandidates\n : collectCandidates('nav, [role=\"navigation\"]')\n return candidates.sort((left, right) => {\n const densityDifference = (right.entries.length / right.anchorCount)\n - (left.entries.length / left.anchorCount)\n return densityDifference || right.entries.length - left.entries.length\n })[0]?.entries ?? []\n}\n\nfunction markdownLinks(body: string): Array<string> {\n return [...body.matchAll(/\\[[^\\]]+\\]\\(([^)\\s]+)(?:\\s+['\"][^'\"]*['\"])?\\)/g)]\n .map((match) => match[1])\n}\n\nfunction sitemapLinks(body: string): Array<string> {\n const $ = load(body, { xmlMode: true })\n return $('url > loc, sitemap > loc').map((_index, element) => $(element).text().trim()).get().filter(Boolean)\n}\n\nfunction robotsSitemaps(body: string): Array<string> {\n return body.split('\\n')\n .map((line) => line.match(/^\\s*Sitemap:\\s*(\\S+)/i)?.[1])\n .filter((value): value is string => Boolean(value))\n}\n\nfunction headerLinks(document: MigrationFetchResponse): Array<string> {\n const links: Array<string> = []\n const llms = document.headers?.['x-llms-txt']\n if (llms) links.push(llms)\n const linkHeader = document.headers?.link ?? ''\n for (const match of linkHeader.matchAll(/<([^>]+)>\\s*;[^,]*(?:rel=[\"']?(?:alternate|llms-txt)[\"']?|type=[\"']text\\/(?:markdown|plain)[\"'])/gi)) {\n links.push(match[1])\n }\n return links\n}\n\nasync function safeFetch(\n fetcher: MigrationFetcher,\n url: URL,\n accept: string,\n): Promise<MigrationFetchResponse | null> {\n try {\n return await fetcher(url, { accept })\n } catch {\n return null\n }\n}\n\n/** Crawl one public docs origin into a canonical, caller-independent bundle. */\nexport async function migrateUrl(options: UrlMigrationOptions): Promise<MigrationBundle> {\n const source = validateMigrationUrl(options.sourceUrl)\n const fetcher = options.fetcher ?? defaultMigrationFetcher\n const maxPages = Math.max(1, Math.min(options.maxPages ?? DEFAULT_MAX_PAGES, 1_000))\n const concurrency = Math.max(1, Math.min(options.concurrency ?? 5, 10))\n const maxTotalBytes = Math.max(1_000_000, Math.min(options.maxTotalBytes ?? DEFAULT_MAX_TOTAL_BYTES, 500_000_000))\n const submittedScopePath = docsScopePath(source)\n const initial = await fetcher(source, { accept: 'text/markdown,text/html,application/xhtml+xml;q=0.9' })\n if (!isInScope(initial.finalUrl, source, submittedScopePath)) {\n throw new Error('The documentation URL redirected outside the submitted docs origin or path.')\n }\n const htmlProbe = /html/i.test(initial.contentType)\n ? initial\n : await safeFetch(fetcher, source, 'text/html,application/xhtml+xml')\n // Content negotiation must not let an HTML-only redirect escape the path\n // boundary already validated for the submitted documentation response.\n const scopedHtmlProbe = htmlProbe && isInScope(htmlProbe.finalUrl, source, submittedScopePath)\n ? htmlProbe\n : null\n const platform = detectUrlPlatform(scopedHtmlProbe ?? initial)\n // A Mintlify site may own an entire docs origin or a path below a marketing\n // site. Its llms/sitemap location is the authoritative crawl boundary.\n const scopePath = platform === 'mintlify'\n ? machineIndexScopePath(source, [initial, scopedHtmlProbe]) ?? submittedScopePath\n : submittedScopePath\n const sourceTopLevelNavigation = platform === 'mintlify' && scopedHtmlProbe && /html/i.test(scopedHtmlProbe.contentType)\n ? htmlTopLevelNavigation(scopedHtmlProbe, source, scopePath)\n : undefined\n // The submitted URL can be any page. Mintlify's first authored product tab,\n // rather than the submitted page, defines which source page becomes `/`.\n // Older single-section themes do not expose a tab strip, so they retain the\n // legacy dedicated-origin fallback when no authored home can be recovered.\n const sourceHomePageId = sourceTopLevelNavigation?.[0]?.pageId\n ?? (platform === 'mintlify' && scopePath === '/'\n ? canonicalLocalizedPageId(pageIdForUrl(source, scopePath) ?? '') || undefined\n : undefined)\n const cache = new Map([[source.toString(), initial]])\n const queue: Array<URL> = [source]\n const queued = new Set([candidateIdentity(source)])\n const warnings: Array<MigrationWarning> = []\n const fetchedSitemaps = new Set<string>()\n\n function enqueue(value: string, base: URL): void {\n if (queued.size >= MAX_DISCOVERED_URLS) return\n const url = normalizeCandidate(value, base, source, scopePath)\n if (!url || queued.has(candidateIdentity(url))) return\n queued.add(candidateIdentity(url))\n queue.push(url)\n }\n\n // Mintlify renders the authored navigation into the HTML shell. Seed the\n // queue from that order before machine indexes add completeness fallbacks.\n if (scopedHtmlProbe && /html/i.test(scopedHtmlProbe.contentType)) {\n for (const link of htmlNavigationLinks(scopedHtmlProbe)) enqueue(link, scopedHtmlProbe.finalUrl)\n }\n\n async function discoverDocumentLinks(document: MigrationFetchResponse, depth = 0): Promise<void> {\n const links = sitemapLinks(document.body)\n for (const link of links) {\n let url: URL\n try {\n url = new URL(link, document.finalUrl)\n } catch {\n continue\n }\n if (depth < 2 && /\\.xml(?:$|\\?)/i.test(url.pathname)) {\n if (url.origin !== source.origin || fetchedSitemaps.size >= MAX_SITEMAP_DOCUMENTS\n || fetchedSitemaps.has(url.toString())) continue\n fetchedSitemaps.add(url.toString())\n const nested = await safeFetch(fetcher, url, 'application/xml,text/xml')\n if (nested && nested.finalUrl.origin === source.origin) await discoverDocumentLinks(nested, depth + 1)\n } else {\n enqueue(link, document.finalUrl)\n }\n }\n }\n\n for (const link of headerLinks(initial)) {\n let url: URL\n try {\n url = new URL(link, initial.finalUrl)\n } catch {\n continue\n }\n if (url.origin !== source.origin) continue\n const document = await safeFetch(fetcher, url, 'text/plain,text/markdown')\n if (!document || document.finalUrl.origin !== source.origin) continue\n for (const candidate of markdownLinks(document.body)) enqueue(candidate, document.finalUrl)\n }\n\n const pathRoot = scopePath === '/' ? source.origin : `${source.origin}${scopePath}`\n const discoveryUrls = [\n new URL('/llms.txt', source.origin),\n new URL(`${pathRoot.replace(source.origin, '')}/llms.txt`, source.origin),\n new URL('/robots.txt', source.origin),\n new URL('/sitemap.xml', source.origin),\n new URL(`${pathRoot.replace(source.origin, '')}/sitemap.xml`, source.origin),\n ]\n const uniqueDiscovery = [...new Map(discoveryUrls.map((url) => [url.toString(), url])).values()]\n for (const url of uniqueDiscovery) {\n const document = await safeFetch(fetcher, url, 'text/plain,application/xml,text/xml;q=0.9')\n if (!document || document.finalUrl.origin !== source.origin) continue\n const isRobots = url.pathname.endsWith('robots.txt')\n const isSitemap = url.pathname.endsWith('sitemap.xml') || document.contentType.includes('xml')\n if (isRobots) {\n for (const link of robotsSitemaps(document.body)) {\n let sitemapUrl: URL\n try {\n sitemapUrl = new URL(link, document.finalUrl)\n } catch {\n continue\n }\n if (sitemapUrl.origin !== source.origin || fetchedSitemaps.size >= MAX_SITEMAP_DOCUMENTS\n || fetchedSitemaps.has(sitemapUrl.toString())) continue\n fetchedSitemaps.add(sitemapUrl.toString())\n const sitemap = await safeFetch(fetcher, sitemapUrl, 'application/xml,text/xml')\n if (sitemap && sitemap.finalUrl.origin === source.origin) await discoverDocumentLinks(sitemap)\n }\n } else if (isSitemap) {\n await discoverDocumentLinks(document)\n } else {\n for (const link of markdownLinks(document.body)) enqueue(link, document.finalUrl)\n }\n }\n\n const pages: Array<MigrationPage> = []\n const seenIds = new Set<string>()\n const seenSources = new Set<string>()\n const visited = new Set<string>()\n let importedBytes = 0\n let isByteBudgetExhausted = false\n while (queue.length > 0 && pages.length < maxPages && !isByteBudgetExhausted) {\n const batch: Array<URL> = []\n while (queue.length > 0 && batch.length < Math.min(concurrency, maxPages - pages.length)) {\n const candidate = queue.shift()\n if (!candidate || visited.has(candidate.toString())) continue\n visited.add(candidate.toString())\n batch.push(candidate)\n }\n if (batch.length === 0) continue\n const results = await Promise.all(batch.map(async (candidate) => {\n let document = cache.get(candidate.toString())\n ?? await safeFetch(fetcher, candidate, 'text/markdown,text/html,application/xhtml+xml;q=0.9')\n if (!document) {\n return { candidate, page: null, links: [] as Array<string>, failure: true }\n }\n if (!isInScope(document.finalUrl, source, scopePath)) {\n return { candidate, page: null, links: [] as Array<string>, failure: false }\n }\n const isMarkdown = /(?:markdown|text\\/plain)/i.test(document.contentType)\n || /\\.mdx?$/i.test(document.finalUrl.pathname)\n if (!isMarkdown && !/\\.mdx?$/i.test(candidate.pathname)) {\n const markdownUrl = new URL(candidate)\n markdownUrl.pathname = `${markdownUrl.pathname.replace(/\\/$/, '')}.md`\n const markdownDocument = await safeFetch(fetcher, markdownUrl, 'text/markdown,text/plain')\n if (markdownDocument && isInScope(markdownDocument.finalUrl, source, scopePath)\n && /(?:markdown|text\\/plain)/i.test(markdownDocument.contentType)) {\n document = markdownDocument\n }\n }\n const isResolvedMarkdown = /(?:markdown|text\\/plain)/i.test(document.contentType)\n || /\\.mdx?$/i.test(document.finalUrl.pathname)\n const sanitizedMarkdown = isResolvedMarkdown ? sanitizeRemoteMarkdown(document.body) : null\n if (isResolvedMarkdown && sanitizedMarkdown === null) {\n const htmlUrl = new URL(candidate)\n htmlUrl.pathname = htmlUrl.pathname.replace(/\\.mdx?$/i, '') || '/'\n const htmlDocument = await safeFetch(fetcher, htmlUrl, 'text/html,application/xhtml+xml')\n if (htmlDocument && isInScope(htmlDocument.finalUrl, source, scopePath)\n && /html/i.test(htmlDocument.contentType)) {\n document = htmlDocument\n } else {\n // Never recover by compiling the rejected MDX. A source that does\n // not expose a safe rendered representation is skipped instead.\n return { candidate, page: null, links: [] as Array<string>, failure: false }\n }\n } else if (sanitizedMarkdown !== null) {\n document = { ...document, body: sanitizedMarkdown }\n }\n const responseBytes = Buffer.byteLength(document.body, 'utf8')\n if (importedBytes + responseBytes > maxTotalBytes) {\n isByteBudgetExhausted = true\n return { candidate, page: null, links: [] as Array<string>, failure: false, budgetExceeded: true }\n }\n importedBytes += responseBytes\n const discoveredId = pageIdForUrl(document.finalUrl, scopePath)\n ?? pageIdForUrl(candidate, scopePath)\n const id = discoveredId && canonicalLocalizedPageId(discoveredId) === sourceHomePageId\n ? 'introduction'\n : discoveredId\n if (!id) return { candidate, page: null, links: [] as Array<string>, failure: false }\n if (/(?:markdown|text\\/plain)/i.test(document.contentType) || /\\.mdx?$/i.test(document.finalUrl.pathname)) {\n return {\n candidate,\n page: markdownPage(document, id),\n links: markdownLinks(document.body),\n base: document.finalUrl,\n failure: false,\n }\n }\n const extracted = htmlPage(document, id)\n return { candidate, page: extracted.page, links: extracted.links, base: document.finalUrl, failure: false }\n }))\n for (const result of results) {\n if (result.failure) {\n warnings.push({ code: 'fetch-failed', message: 'A discovered documentation page could not be fetched.', source: result.candidate.toString() })\n continue\n }\n if (result.budgetExceeded) continue\n if (result.page) result.page.id = canonicalLocalizedPageId(result.page.id)\n const sourceIdentity = result.page\n ? candidateIdentity(new URL(result.page.source))\n : null\n if (result.page && sourceIdentity && !seenSources.has(sourceIdentity)\n && !seenIds.has(result.page.id) && pages.length < maxPages) {\n pages.push(result.page)\n seenIds.add(result.page.id)\n seenSources.add(sourceIdentity)\n }\n for (const link of result.links) enqueue(link, result.base ?? result.candidate)\n }\n }\n\n if (pages.length === 0) throw new Error('No readable documentation pages were found at that URL.')\n for (const page of pages) {\n const [locale, ...navigationSegments] = page.id.split('/')\n if (LOCALE_CODES.has(locale)) {\n if (navigationSegments.length === 0) page.id = `${locale}/introduction`\n page.locale = locale\n page.navigationId = navigationSegments.join('/') || 'introduction'\n }\n }\n const importedIds = new Set(pages.map((page) => page.id))\n for (const page of pages) {\n page.body = rewriteInternalLinks(\n page.body,\n new URL(page.source),\n source,\n scopePath,\n importedIds,\n sourceHomePageId,\n )\n }\n if (isByteBudgetExhausted) {\n warnings.push({ code: 'limit-reached', message: `Import stopped after reaching the ${Math.round(maxTotalBytes / 1_000_000)} MB content budget.` })\n } else if (queue.length > 0 || queued.size >= MAX_DISCOVERED_URLS) {\n warnings.push({ code: 'limit-reached', message: `Import stopped after ${pages.length} pages; narrow the URL or raise the caller limit to import more.` })\n }\n const topLevelNavigation = sourceTopLevelNavigation?.map((entry) => ({\n ...entry,\n pageId: entry.pageId === sourceHomePageId ? 'introduction' : entry.pageId,\n }))\n const docsConfig = buildNavigationFromPages(pages, {\n topLevelTabs: platform === 'mintlify',\n topLevelNavigation,\n })\n const locales = [...new Set(pages.map((page) => page.locale).filter((value): value is string => Boolean(value)))]\n if (locales.length > 0) {\n docsConfig.i18n = {\n defaultLocale: 'en',\n locales: [\n { code: 'en', label: 'English' },\n ...locales.filter((locale) => locale !== 'en').map((locale) => ({ code: locale, label: locale.toUpperCase() })),\n ],\n }\n }\n return {\n sourceUrl: source.toString(),\n sourceKind: 'url',\n platform,\n pages,\n assets: [],\n docsConfig,\n warnings,\n stats: {\n discovered: visited.size,\n imported: pages.length,\n skipped: Math.max(0, visited.size - pages.length),\n },\n }\n}\n"],"mappings":"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","names":["existsSync","readFileSync","dirname","extname","relative","relative","relative","resolve","existsSync","readFileSync","extname","relative","dirname","value","candidates"]}
|