@thallylabs/migrate 0.2.31 → 0.2.32
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.js +71 -27
- package/dist/index.js.map +1 -1
- package/dist/url-migration.js +71 -27
- package/dist/url-migration.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -14358,7 +14358,7 @@ function mergeSourceNavigation(existing, incoming) {
|
|
|
14358
14358
|
}
|
|
14359
14359
|
|
|
14360
14360
|
// src/url-run.ts
|
|
14361
|
-
var CONVERTER_VERSION = "url-evidence-
|
|
14361
|
+
var CONVERTER_VERSION = "url-evidence-v4";
|
|
14362
14362
|
var parser2 = unified4().use(remarkParse4).use(remarkMdx4);
|
|
14363
14363
|
var ACCEPT = "text/markdown,text/html,application/xhtml+xml;q=0.9";
|
|
14364
14364
|
var MAX_RESPONSE_BYTES = 8e6;
|
|
@@ -14617,21 +14617,22 @@ function resolveMigrationRecord(records, record) {
|
|
|
14617
14617
|
}
|
|
14618
14618
|
return record;
|
|
14619
14619
|
}
|
|
14620
|
-
function navigationConfig(
|
|
14620
|
+
function navigationConfig(checkpoint, records) {
|
|
14621
|
+
const navigation = checkpoint.navigation;
|
|
14622
|
+
const projection = localeProjection(checkpoint);
|
|
14621
14623
|
const project2 = (nodes) => nodes.flatMap((node) => {
|
|
14622
14624
|
const record = node.url ? records.get(canonical(node.url, node.url) ?? "") : void 0;
|
|
14623
14625
|
const target2 = resolveMigrationRecord(records, record);
|
|
14624
14626
|
const page = target2?.page;
|
|
14625
14627
|
const children = project2(node.children ?? []);
|
|
14626
14628
|
if (children.length) {
|
|
14627
|
-
const contains = (entries) => entries.some((entry) => typeof entry === "string" ? entry === page
|
|
14628
|
-
return [{ group: node.label || "Documentation", pages: [...page && !contains(children) ? [
|
|
14629
|
+
const contains = (entries) => entries.some((entry) => typeof entry === "string" ? entry === (page && projection.navigationId(page)) : contains(entry.pages));
|
|
14630
|
+
return [{ group: node.label || "Documentation", pages: [...page && !contains(children) ? [projection.navigationId(page)] : [], ...children] }];
|
|
14629
14631
|
}
|
|
14630
|
-
return page ? [
|
|
14632
|
+
return page ? [projection.navigationId(page)] : [];
|
|
14631
14633
|
});
|
|
14632
14634
|
const tabs = navigation.filter((node) => node.kind === "tab");
|
|
14633
14635
|
if (tabs.length) {
|
|
14634
|
-
const projection = localeProjection({ records: [...records.values()] });
|
|
14635
14636
|
const locales = [...new Set(tabs.map((tab) => tab.locale ?? projection.defaultLocale))];
|
|
14636
14637
|
const localizedTabs = (locale) => tabs.filter((tab) => (tab.locale ?? projection.defaultLocale) === locale).flatMap((tab) => {
|
|
14637
14638
|
const pages2 = project2(tab.children ?? []);
|
|
@@ -14649,16 +14650,16 @@ function navigationConfig(navigation, records) {
|
|
|
14649
14650
|
const pages = project2(navigation);
|
|
14650
14651
|
return pages.length ? { tabs: [{ tab: "Documentation", pages }] } : null;
|
|
14651
14652
|
}
|
|
14653
|
+
function canonicalLanguage(value) {
|
|
14654
|
+
if (!/^[a-z]{2,3}(?:-[a-z0-9]{2,8}){0,4}$/i.test(value)) return void 0;
|
|
14655
|
+
try {
|
|
14656
|
+
return Intl.getCanonicalLocales(value)[0];
|
|
14657
|
+
} catch {
|
|
14658
|
+
return void 0;
|
|
14659
|
+
}
|
|
14660
|
+
}
|
|
14652
14661
|
function observedLocale(document, id, scopePath) {
|
|
14653
14662
|
const issues = [];
|
|
14654
|
-
const canonicalLanguage = (value) => {
|
|
14655
|
-
if (!/^[a-z]{2,3}(?:-[a-z0-9]{2,8}){0,4}$/i.test(value)) return void 0;
|
|
14656
|
-
try {
|
|
14657
|
-
return Intl.getCanonicalLocales(value)[0];
|
|
14658
|
-
} catch {
|
|
14659
|
-
return void 0;
|
|
14660
|
-
}
|
|
14661
|
-
};
|
|
14662
14663
|
const candidates = [];
|
|
14663
14664
|
if (document.locale) {
|
|
14664
14665
|
const locale = canonicalLanguage(document.locale);
|
|
@@ -14680,25 +14681,60 @@ function observedLocale(document, id, scopePath) {
|
|
|
14680
14681
|
}
|
|
14681
14682
|
function localeProjection(checkpoint) {
|
|
14682
14683
|
const pages = checkpoint.records.flatMap((record) => record.page ? [record.page] : []);
|
|
14683
|
-
const
|
|
14684
|
+
const declaredLocale = (page) => {
|
|
14684
14685
|
try {
|
|
14685
14686
|
return page.locale ? Intl.getCanonicalLocales(page.locale)[0] : void 0;
|
|
14686
14687
|
} catch {
|
|
14687
14688
|
return void 0;
|
|
14688
14689
|
}
|
|
14689
14690
|
};
|
|
14691
|
+
const declaredLocales = [...new Set(pages.map(declaredLocale).filter((locale) => Boolean(locale)))];
|
|
14692
|
+
const defaultLocale = pages.some((page) => !page.locale) || declaredLocales.includes("en") ? "en" : declaredLocales[0] ?? "en";
|
|
14693
|
+
const records = new Map(checkpoint.records.map((record) => [record.url, record]));
|
|
14694
|
+
const memberships = /* @__PURE__ */ new Map();
|
|
14695
|
+
const observe = (nodes, parentLocale) => {
|
|
14696
|
+
for (const node of nodes) {
|
|
14697
|
+
const locale = node.locale ? canonicalLanguage(node.locale) : parentLocale;
|
|
14698
|
+
const entry = node.url ? records.get(canonical(node.url, checkpoint.sourceUrl) ?? "") : void 0;
|
|
14699
|
+
const page = resolveMigrationRecord(records, entry)?.page;
|
|
14700
|
+
if (page && locale) {
|
|
14701
|
+
const languages = memberships.get(page) ?? /* @__PURE__ */ new Set();
|
|
14702
|
+
languages.add(locale);
|
|
14703
|
+
memberships.set(page, languages);
|
|
14704
|
+
}
|
|
14705
|
+
observe(node.children ?? [], locale);
|
|
14706
|
+
}
|
|
14707
|
+
};
|
|
14708
|
+
observe(checkpoint.navigation);
|
|
14709
|
+
const primaryIds = new Set(pages.filter((page) => !declaredLocale(page) || declaredLocale(page) === defaultLocale).filter((page) => memberships.get(page)?.has(defaultLocale)).map((page) => page.navigationId));
|
|
14710
|
+
const remapped = /* @__PURE__ */ new Map();
|
|
14711
|
+
for (const page of pages) {
|
|
14712
|
+
const languages = memberships.get(page);
|
|
14713
|
+
if (languages?.size !== 1) continue;
|
|
14714
|
+
const locale = [...languages][0];
|
|
14715
|
+
const prefix = `${locale.toLowerCase()}-`;
|
|
14716
|
+
if (locale === defaultLocale || !page.navigationId.toLowerCase().startsWith(prefix)) continue;
|
|
14717
|
+
const navigationId2 = page.navigationId.slice(prefix.length);
|
|
14718
|
+
if (primaryIds.has(navigationId2)) remapped.set(page, { locale, navigationId: navigationId2 });
|
|
14719
|
+
}
|
|
14720
|
+
const canonicalLocale = (page) => remapped.get(page)?.locale ?? declaredLocale(page);
|
|
14721
|
+
const navigationId = (page) => remapped.get(page)?.navigationId ?? page.navigationId;
|
|
14690
14722
|
const locales = [...new Set(pages.map(canonicalLocale).filter((locale) => Boolean(locale)))];
|
|
14691
|
-
const defaultLocale = pages.some((page) => !page.locale) || locales.includes("en") ? "en" : locales[0] ?? "en";
|
|
14692
14723
|
const pageId = (page) => {
|
|
14693
14724
|
const locale = canonicalLocale(page);
|
|
14694
|
-
return locale ? `${locale === defaultLocale ? "" : `${locale}/`}${page
|
|
14725
|
+
return locale ? `${locale === defaultLocale ? "" : `${locale}/`}${navigationId(page)}` : page.id;
|
|
14695
14726
|
};
|
|
14696
14727
|
const route = (page) => {
|
|
14697
14728
|
const locale = canonicalLocale(page);
|
|
14698
14729
|
const prefix = locale && locale !== defaultLocale ? `/${locale}` : "";
|
|
14699
|
-
return `${prefix}${page
|
|
14730
|
+
return `${prefix}${navigationId(page) === "introduction" ? "/" : `/${navigationId(page)}`}`;
|
|
14700
14731
|
};
|
|
14701
|
-
|
|
14732
|
+
const redirects = checkpoint.records.flatMap((record) => {
|
|
14733
|
+
if (!record.page || !remapped.has(record.page)) return [];
|
|
14734
|
+
const source = new URL(record.url);
|
|
14735
|
+
return source.search || !/^\/[A-Za-z0-9/_~.%+-]*$/.test(source.pathname) ? [] : [{ source: source.pathname, destination: route(record.page), permanent: true }];
|
|
14736
|
+
});
|
|
14737
|
+
return { canonicalLocale, navigationId, locales, defaultLocale, pageId, route, redirects };
|
|
14702
14738
|
}
|
|
14703
14739
|
function validateUrlMigration(checkpoint, cancelled = false) {
|
|
14704
14740
|
const issues = [];
|
|
@@ -14707,7 +14743,7 @@ function validateUrlMigration(checkpoint, cancelled = false) {
|
|
|
14707
14743
|
const records = new Map(checkpoint.records.map((record) => [record.url, record]));
|
|
14708
14744
|
const source = new URL(checkpoint.sourceUrl);
|
|
14709
14745
|
const projection = localeProjection(checkpoint);
|
|
14710
|
-
const primaryIds = new Set(checkpoint.records.flatMap((record) => record.page && (!record.page
|
|
14746
|
+
const primaryIds = new Set(checkpoint.records.flatMap((record) => record.page && (!projection.canonicalLocale(record.page) || projection.canonicalLocale(record.page) === projection.defaultLocale) ? [projection.navigationId(record.page)] : []));
|
|
14711
14747
|
const outputIds = /* @__PURE__ */ new Set();
|
|
14712
14748
|
const resolve4 = (url) => {
|
|
14713
14749
|
const record = records.get(canonical(url, checkpoint.sourceUrl) ?? "");
|
|
@@ -14721,8 +14757,8 @@ function validateUrlMigration(checkpoint, cancelled = false) {
|
|
|
14721
14757
|
const outputId = projection.pageId(record.page);
|
|
14722
14758
|
if (outputIds.has(outputId)) issues.push({ code: "collision", source: record.url, message: `Multiple source pages map to runtime path ${outputId}.` });
|
|
14723
14759
|
outputIds.add(outputId);
|
|
14724
|
-
if (record.page
|
|
14725
|
-
issues.push({ code: "missing-page", source: record.url, message: `Secondary locale ${record.page
|
|
14760
|
+
if (projection.canonicalLocale(record.page) && projection.canonicalLocale(record.page) !== projection.defaultLocale && !primaryIds.has(projection.navigationId(record.page))) {
|
|
14761
|
+
issues.push({ code: "missing-page", source: record.url, message: `Secondary locale ${projection.canonicalLocale(record.page)} requires a primary ${projection.defaultLocale} page at ${projection.navigationId(record.page)}; the runtime cannot serve an orphan translation.` });
|
|
14726
14762
|
}
|
|
14727
14763
|
const actual = markdownCode(record.page.body);
|
|
14728
14764
|
if (JSON.stringify(actual) !== JSON.stringify(record.evidence.code)) issues.push({ code: "code-mismatch", source: record.url, message: "Source code payloads differ from converted code payloads." });
|
|
@@ -14756,13 +14792,20 @@ function validateUrlMigration(checkpoint, cancelled = false) {
|
|
|
14756
14792
|
}
|
|
14757
14793
|
}
|
|
14758
14794
|
}
|
|
14759
|
-
const visit = (nodes) => {
|
|
14795
|
+
const visit = (nodes, parentLocale) => {
|
|
14760
14796
|
for (const node of nodes) {
|
|
14797
|
+
const locale = node.locale ? canonicalLanguage(node.locale) : parentLocale;
|
|
14761
14798
|
if (node.url) {
|
|
14762
14799
|
const url = new URL(node.url, source);
|
|
14763
|
-
if (inScope(url, source, checkpoint.scopePath)
|
|
14800
|
+
if (inScope(url, source, checkpoint.scopePath)) {
|
|
14801
|
+
const page = resolve4(url.toString())?.page;
|
|
14802
|
+
if (!page) issues.push({ code: "navigation-missing", source: node.url, message: `Source navigation target ${node.label} was not imported.` });
|
|
14803
|
+
else if (locale && locale !== projection.defaultLocale && !outputIds.has(`${locale}/${projection.navigationId(page)}`)) {
|
|
14804
|
+
issues.push({ code: "navigation-missing", source: node.url, message: `The ${locale} sidebar target ${node.label} has no authored localized runtime page.` });
|
|
14805
|
+
}
|
|
14806
|
+
}
|
|
14764
14807
|
}
|
|
14765
|
-
visit(node.children ?? []);
|
|
14808
|
+
visit(node.children ?? [], locale);
|
|
14766
14809
|
}
|
|
14767
14810
|
};
|
|
14768
14811
|
visit(checkpoint.navigation);
|
|
@@ -15180,7 +15223,7 @@ ${difference}`;
|
|
|
15180
15223
|
}
|
|
15181
15224
|
};
|
|
15182
15225
|
labelPages(checkpoint.navigation);
|
|
15183
|
-
const pages = checkpoint.records.flatMap((record) => record.page ? [{ ...record.page, id: projection.pageId(record.page), ...record.page
|
|
15226
|
+
const pages = checkpoint.records.flatMap((record) => record.page ? [{ ...record.page, id: projection.pageId(record.page), navigationId: projection.navigationId(record.page), ...projection.canonicalLocale(record.page) ? { locale: projection.canonicalLocale(record.page) } : {}, ...navigationLabels.has(record.url) ? { navTitle: navigationLabels.get(record.url) } : {}, body: rewriteMarkdownDestinations(record.page.body, (value) => {
|
|
15184
15227
|
let url;
|
|
15185
15228
|
try {
|
|
15186
15229
|
url = new URL(value, record.evidence.finalUrl);
|
|
@@ -15210,11 +15253,12 @@ ${difference}`;
|
|
|
15210
15253
|
platform: options.platform ?? "generic",
|
|
15211
15254
|
pages,
|
|
15212
15255
|
assets: [...assets.values()],
|
|
15213
|
-
docsConfig: navigationConfig(checkpoint
|
|
15256
|
+
docsConfig: navigationConfig(checkpoint, records) ?? buildNavigationFromPages(pages),
|
|
15214
15257
|
warnings: [...validation.issues, ...validation.warnings ?? []].map((issue) => ({ code: issue.code === "missing-page" ? "missing-page" : "unsupported-config", message: issue.message, source: issue.source })),
|
|
15215
15258
|
urlMigrationValidation: validation,
|
|
15216
15259
|
stats: { discovered: records.size, imported: pages.length, skipped: records.size - pages.length }
|
|
15217
15260
|
};
|
|
15261
|
+
if (projection.redirects.length) bundle.docsConfig.redirects = projection.redirects;
|
|
15218
15262
|
if (projection.locales.length) {
|
|
15219
15263
|
const locales = [.../* @__PURE__ */ new Set([projection.defaultLocale, ...projection.locales])];
|
|
15220
15264
|
bundle.docsConfig.i18n = { ...bundle.docsConfig.i18n, defaultLocale: projection.defaultLocale, locales: locales.map((code) => ({ code, label: code === "en" ? "English" : code })) };
|