@thallylabs/migrate 0.2.2 → 0.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -6
- package/dist/index.d.ts +8 -0
- package/dist/index.js +117 -62
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -5,12 +5,13 @@ Cloud. It imports documentation repositories and public documentation URLs
|
|
|
5
5
|
into one canonical bundle before any caller writes files.
|
|
6
6
|
|
|
7
7
|
Repository migration includes dedicated Mintlify and Docusaurus adapters.
|
|
8
|
-
Mintlify repositories are located inside monorepos automatically
|
|
9
|
-
`docs.json`/`mint.json`
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
8
|
+
Mintlify repositories are located inside monorepos automatically. Their
|
|
9
|
+
`docs.json`/`mint.json` page and group trees are projected without flattening
|
|
10
|
+
authored nesting or order. The adapter supports tabs, dropdowns, products,
|
|
11
|
+
versions, languages, and reusable `$ref` navigation files; it also preserves
|
|
12
|
+
dropdown presentation, collection descriptions and icons, explicit default
|
|
13
|
+
versions, page route casing, redirects, local snippets, static assets,
|
|
14
|
+
compatible page frontmatter, site identity, and OpenAPI configuration. For public Mintlify
|
|
14
15
|
sites, the URL adapter reads the structured configuration embedded in the
|
|
15
16
|
rendered application before falling back to DOM link inference.
|
|
16
17
|
|
package/dist/index.d.ts
CHANGED
|
@@ -12,8 +12,12 @@ interface MigrationNavigationGroup {
|
|
|
12
12
|
}
|
|
13
13
|
interface MigrationNavigationTab {
|
|
14
14
|
tab: string;
|
|
15
|
+
description?: string;
|
|
16
|
+
icon?: string;
|
|
15
17
|
href?: string;
|
|
16
18
|
hidden?: boolean;
|
|
19
|
+
/** Root page/group nodes used when the source has no synthetic section heading. */
|
|
20
|
+
pages?: Array<string | MigrationNavigationGroup>;
|
|
17
21
|
groups?: Array<MigrationNavigationGroup>;
|
|
18
22
|
api?: {
|
|
19
23
|
source: string;
|
|
@@ -54,6 +58,10 @@ interface MigrationFooterConfig {
|
|
|
54
58
|
}
|
|
55
59
|
interface MigrationDocsConfig {
|
|
56
60
|
tabs: Array<MigrationNavigationTab>;
|
|
61
|
+
navigation?: {
|
|
62
|
+
/** How sibling documentation collections are presented to readers. */
|
|
63
|
+
display?: 'tabs' | 'dropdown';
|
|
64
|
+
};
|
|
57
65
|
theme?: 'default' | 'maple' | 'sharp' | 'minimal';
|
|
58
66
|
banner?: MigrationBannerConfig;
|
|
59
67
|
navbar?: MigrationNavbarConfig;
|
package/dist/index.js
CHANGED
|
@@ -776,6 +776,12 @@ function iconName(value) {
|
|
|
776
776
|
const icon = objectValue2(value);
|
|
777
777
|
return typeof icon?.name === "string" && icon.name ? icon.name : void 0;
|
|
778
778
|
}
|
|
779
|
+
function containerPresentation(value) {
|
|
780
|
+
return {
|
|
781
|
+
...typeof value.description === "string" && value.description.trim() ? { description: value.description.trim() } : {},
|
|
782
|
+
...iconName(value.icon) ? { icon: iconName(value.icon) } : {}
|
|
783
|
+
};
|
|
784
|
+
}
|
|
779
785
|
function registerReference(value, context) {
|
|
780
786
|
const localePrefix = context.locale ? `${context.locale}/` : "";
|
|
781
787
|
const localizedValue = localePrefix && value.replace(/^\/+/, "").startsWith(localePrefix) ? value.replace(/^\/+/, "").slice(localePrefix.length) : value;
|
|
@@ -825,56 +831,76 @@ function convertPage(value, context) {
|
|
|
825
831
|
}
|
|
826
832
|
return null;
|
|
827
833
|
}
|
|
828
|
-
function
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
if (!converted) continue;
|
|
834
|
-
if (typeof converted === "string") loosePages.push(converted);
|
|
835
|
-
else groups.push(converted);
|
|
836
|
-
}
|
|
837
|
-
if (loosePages.length > 0) groups.unshift({ group: fallbackGroup, pages: loosePages });
|
|
838
|
-
return groups;
|
|
834
|
+
function convertNavigationValues(values, context) {
|
|
835
|
+
return values.flatMap((value) => {
|
|
836
|
+
const page = convertPage(value, context);
|
|
837
|
+
return page ? [page] : [];
|
|
838
|
+
});
|
|
839
839
|
}
|
|
840
|
-
function convertContainerToTabs(containerValue, context, fallbackTab) {
|
|
840
|
+
function convertContainerToTabs(containerValue, context, fallbackTab, trace, depth = 0) {
|
|
841
841
|
const container = objectValue2(containerValue);
|
|
842
842
|
if (!container) return [];
|
|
843
|
-
|
|
843
|
+
const containerKeys = ["tabs", "anchors", "products", "dropdowns", "versions", "menus"];
|
|
844
|
+
for (const key of containerKeys) {
|
|
844
845
|
if (!Array.isArray(container[key])) continue;
|
|
845
|
-
const
|
|
846
|
+
const entries = [...container[key]];
|
|
847
|
+
if (key === "versions") {
|
|
848
|
+
entries.sort((left, right) => Number(objectValue2(right)?.default === true) - Number(objectValue2(left)?.default === true));
|
|
849
|
+
}
|
|
850
|
+
const tabs = entries.flatMap((value, index) => {
|
|
846
851
|
const object = objectValue2(value);
|
|
847
852
|
if (!object) return [];
|
|
848
853
|
const tab = labelFor(object, `${fallbackTab} ${index + 1}`);
|
|
849
854
|
const href = projectedHref(object.href);
|
|
850
|
-
|
|
851
|
-
|
|
855
|
+
const hasNestedContainers = containerKeys.some((containerKey) => Array.isArray(object[containerKey]));
|
|
856
|
+
if (href && !object.pages && !object.groups && !hasNestedContainers) {
|
|
857
|
+
return [{
|
|
858
|
+
tab,
|
|
859
|
+
href,
|
|
860
|
+
...containerPresentation(object),
|
|
861
|
+
...object.hidden === true ? { hidden: true } : {}
|
|
862
|
+
}];
|
|
852
863
|
}
|
|
853
|
-
const nested = convertContainerToTabs(object, context, tab);
|
|
864
|
+
const nested = convertContainerToTabs(object, context, tab, trace, depth + 1);
|
|
854
865
|
if (nested.length > 0) {
|
|
855
866
|
if (nested.length === 1) {
|
|
856
867
|
return [{
|
|
857
868
|
...nested[0],
|
|
858
869
|
tab,
|
|
870
|
+
...containerPresentation(object),
|
|
859
871
|
...href ? { href } : {},
|
|
860
872
|
...object.hidden === true ? { hidden: true } : {}
|
|
861
873
|
}];
|
|
862
874
|
}
|
|
863
|
-
|
|
875
|
+
const presentation = containerPresentation(object);
|
|
876
|
+
return nested.map((item, childIndex) => ({
|
|
877
|
+
...presentation,
|
|
878
|
+
...item,
|
|
879
|
+
tab: `${tab}: ${item.tab}`,
|
|
880
|
+
...childIndex === 0 && href && !item.href ? { href } : {},
|
|
881
|
+
...object.hidden === true ? { hidden: true } : {}
|
|
882
|
+
}));
|
|
864
883
|
}
|
|
865
884
|
return [];
|
|
866
885
|
});
|
|
867
|
-
if (tabs.length > 0)
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
886
|
+
if (tabs.length > 0) {
|
|
887
|
+
if (depth === 0 && trace) trace.rootContainerKind = key;
|
|
888
|
+
return tabs;
|
|
889
|
+
}
|
|
890
|
+
}
|
|
891
|
+
const rawGroups = Array.isArray(container.groups) ? container.groups : [];
|
|
892
|
+
const rawPages = Array.isArray(container.pages) ? container.pages : [];
|
|
893
|
+
const hasRootNodes = typeof container.root === "string" || rawPages.length > 0;
|
|
894
|
+
const values = [
|
|
895
|
+
...typeof container.root === "string" ? [container.root] : [],
|
|
896
|
+
...rawGroups,
|
|
897
|
+
...rawPages
|
|
872
898
|
];
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
return groups.length > 0 ? [{
|
|
899
|
+
const children = convertNavigationValues(values, context);
|
|
900
|
+
return children.length > 0 ? [{
|
|
876
901
|
tab: fallbackTab,
|
|
877
|
-
groups,
|
|
902
|
+
...hasRootNodes ? { pages: children } : { groups: children },
|
|
903
|
+
...containerPresentation(container),
|
|
878
904
|
...projectedHref(container.href) ? { href: projectedHref(container.href) } : {},
|
|
879
905
|
...container.hidden === true ? { hidden: true } : {}
|
|
880
906
|
}] : [];
|
|
@@ -1003,9 +1029,10 @@ function projectMintlifyNavigation(config, options = {}) {
|
|
|
1003
1029
|
const languages = Array.isArray(navigation.languages) ? navigation.languages.map(objectValue2).filter((value) => Boolean(value)) : [];
|
|
1004
1030
|
let tabs = [];
|
|
1005
1031
|
let i18n;
|
|
1032
|
+
const projectionTrace = {};
|
|
1006
1033
|
if (languages.length > 0) {
|
|
1007
1034
|
const defaultLanguage = languages.find((entry) => entry.default === true) ?? languages[0];
|
|
1008
|
-
const defaultLocale = String(defaultLanguage.language ?? "en");
|
|
1035
|
+
const defaultLocale = String(defaultLanguage.language ?? defaultLanguage.locale ?? "en");
|
|
1009
1036
|
const locales = languages.map((entry) => {
|
|
1010
1037
|
const code = String(entry.language ?? entry.locale ?? "en");
|
|
1011
1038
|
let label = LANGUAGE_LABELS[code];
|
|
@@ -1026,15 +1053,26 @@ function projectMintlifyNavigation(config, options = {}) {
|
|
|
1026
1053
|
warnings,
|
|
1027
1054
|
warningKeys
|
|
1028
1055
|
};
|
|
1029
|
-
const languageTabs = convertContainerToTabs(
|
|
1056
|
+
const languageTabs = convertContainerToTabs(
|
|
1057
|
+
language,
|
|
1058
|
+
context,
|
|
1059
|
+
"Documentation",
|
|
1060
|
+
language === defaultLanguage ? projectionTrace : void 0
|
|
1061
|
+
);
|
|
1030
1062
|
if (language === defaultLanguage) tabs = languageTabs;
|
|
1031
1063
|
}
|
|
1032
1064
|
} else {
|
|
1033
1065
|
const context = { references, seenReferences, warnings, warningKeys, pathPrefix: options.pathPrefix };
|
|
1034
|
-
tabs = convertContainerToTabs(navigation, context, "Documentation");
|
|
1066
|
+
tabs = convertContainerToTabs(navigation, context, "Documentation", projectionTrace);
|
|
1035
1067
|
if (tabs.length === 0 && Array.isArray(config.navigation)) {
|
|
1036
|
-
const
|
|
1037
|
-
if (
|
|
1068
|
+
const children = convertNavigationValues(config.navigation, context);
|
|
1069
|
+
if (children.length > 0) {
|
|
1070
|
+
const hasRootPages = children.some((page) => typeof page === "string");
|
|
1071
|
+
tabs = [{
|
|
1072
|
+
tab: "Documentation",
|
|
1073
|
+
...hasRootPages ? { pages: children } : { groups: children }
|
|
1074
|
+
}];
|
|
1075
|
+
}
|
|
1038
1076
|
}
|
|
1039
1077
|
}
|
|
1040
1078
|
if (tabs.length === 0) {
|
|
@@ -1058,6 +1096,7 @@ function projectMintlifyNavigation(config, options = {}) {
|
|
|
1058
1096
|
return {
|
|
1059
1097
|
docsConfig: {
|
|
1060
1098
|
tabs,
|
|
1099
|
+
...projectionTrace.rootContainerKind === "dropdowns" ? { navigation: { display: "dropdown" } } : {},
|
|
1061
1100
|
...projectedCompatibleConfig(config),
|
|
1062
1101
|
...i18n ? { i18n } : {},
|
|
1063
1102
|
...redirects.length > 0 ? { redirects } : {}
|
|
@@ -1927,41 +1966,56 @@ function mergeMigrationConfig(existing, incoming) {
|
|
|
1927
1966
|
const tabs = existing.tabs.filter((tab) => tab.tab.toLowerCase() !== "changelog");
|
|
1928
1967
|
const names = new Set(tabs.map((tab) => tab.tab.toLowerCase()));
|
|
1929
1968
|
const seenPages = /* @__PURE__ */ new Set();
|
|
1930
|
-
function recordPages(
|
|
1931
|
-
for (const
|
|
1932
|
-
|
|
1933
|
-
|
|
1934
|
-
else recordPages([page]);
|
|
1935
|
-
}
|
|
1969
|
+
function recordPages(pages = []) {
|
|
1970
|
+
for (const page of pages) {
|
|
1971
|
+
if (typeof page === "string") seenPages.add(page);
|
|
1972
|
+
else recordPages(page.pages);
|
|
1936
1973
|
}
|
|
1937
1974
|
}
|
|
1938
|
-
for (const tab of tabs)
|
|
1939
|
-
|
|
1940
|
-
|
|
1941
|
-
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
|
|
1950
|
-
return
|
|
1975
|
+
for (const tab of tabs) {
|
|
1976
|
+
recordPages(tab.pages);
|
|
1977
|
+
recordPages(tab.groups);
|
|
1978
|
+
}
|
|
1979
|
+
function uniquePages(pages = []) {
|
|
1980
|
+
return pages.flatMap((page) => {
|
|
1981
|
+
if (typeof page === "string") {
|
|
1982
|
+
if (seenPages.has(page)) return [];
|
|
1983
|
+
seenPages.add(page);
|
|
1984
|
+
return [page];
|
|
1985
|
+
}
|
|
1986
|
+
const children = uniquePages(page.pages);
|
|
1987
|
+
return children.length > 0 ? [{ ...page, pages: children }] : [];
|
|
1951
1988
|
});
|
|
1952
1989
|
}
|
|
1990
|
+
function uniqueGroups(groups) {
|
|
1991
|
+
return uniquePages(groups ?? []);
|
|
1992
|
+
}
|
|
1953
1993
|
for (const tab of incoming.tabs) {
|
|
1954
1994
|
if (tab.tab.toLowerCase() === "changelog") continue;
|
|
1955
|
-
const uniqueTab = {
|
|
1956
|
-
|
|
1995
|
+
const uniqueTab = {
|
|
1996
|
+
...tab,
|
|
1997
|
+
...tab.pages ? { pages: uniquePages(tab.pages) } : {},
|
|
1998
|
+
...tab.groups ? { groups: uniqueGroups(tab.groups) } : {}
|
|
1999
|
+
};
|
|
2000
|
+
if ((tab.pages || tab.groups) && !uniqueTab.pages?.length && !uniqueTab.groups?.length && !tab.href && !tab.api) continue;
|
|
1957
2001
|
if (!names.has(tab.tab.toLowerCase())) {
|
|
1958
2002
|
tabs.push(uniqueTab);
|
|
1959
2003
|
names.add(tab.tab.toLowerCase());
|
|
1960
2004
|
continue;
|
|
1961
2005
|
}
|
|
1962
2006
|
const target = tabs.find((item) => item.tab.toLowerCase() === tab.tab.toLowerCase());
|
|
1963
|
-
if (!target
|
|
1964
|
-
|
|
2007
|
+
if (!target) continue;
|
|
2008
|
+
const incomingRootNodes = [
|
|
2009
|
+
...uniqueTab.pages ?? [],
|
|
2010
|
+
...uniqueTab.groups ?? []
|
|
2011
|
+
];
|
|
2012
|
+
if (uniqueTab.pages?.length) {
|
|
2013
|
+
target.pages = [...target.pages ?? target.groups ?? [], ...incomingRootNodes];
|
|
2014
|
+
delete target.groups;
|
|
2015
|
+
} else if (uniqueTab.groups?.length) {
|
|
2016
|
+
if (target.pages) target.pages = [...target.pages, ...uniqueTab.groups];
|
|
2017
|
+
else target.groups = [...target.groups ?? [], ...uniqueTab.groups];
|
|
2018
|
+
}
|
|
1965
2019
|
}
|
|
1966
2020
|
const changelog = existing.tabs.find((tab) => tab.tab.toLowerCase() === "changelog") ?? incoming.tabs.find((tab) => tab.tab.toLowerCase() === "changelog");
|
|
1967
2021
|
if (changelog) tabs.push(changelog);
|
|
@@ -1975,6 +2029,9 @@ function mergeMigrationConfig(existing, incoming) {
|
|
|
1975
2029
|
...incoming,
|
|
1976
2030
|
...existing,
|
|
1977
2031
|
tabs,
|
|
2032
|
+
// Collection presentation belongs to the imported information
|
|
2033
|
+
// architecture; starter defaults must not coerce source dropdowns to tabs.
|
|
2034
|
+
navigation: incoming.navigation ?? existing.navigation,
|
|
1978
2035
|
...i18n ? { i18n } : {}
|
|
1979
2036
|
};
|
|
1980
2037
|
}
|
|
@@ -3025,15 +3082,17 @@ function htmlTopLevelNavigation(document, source, scopePath) {
|
|
|
3025
3082
|
}
|
|
3026
3083
|
function remapNavigationHome(config, sourceHomePageId) {
|
|
3027
3084
|
if (!sourceHomePageId || sourceHomePageId === "introduction") return config;
|
|
3085
|
+
const remapPages = (pages) => pages.map((page) => typeof page === "string" ? page === sourceHomePageId ? "introduction" : page : { ...page, pages: remapPages(page.pages) });
|
|
3028
3086
|
const remapGroups = (groups) => groups.map((group) => ({
|
|
3029
3087
|
...group,
|
|
3030
|
-
pages: group.pages
|
|
3088
|
+
pages: remapPages(group.pages)
|
|
3031
3089
|
}));
|
|
3032
3090
|
return {
|
|
3033
3091
|
...config,
|
|
3034
3092
|
tabs: config.tabs.map((tab) => ({
|
|
3035
3093
|
...tab,
|
|
3036
3094
|
...tab.href === `/${sourceHomePageId}` ? { href: "/" } : {},
|
|
3095
|
+
...tab.pages ? { pages: remapPages(tab.pages) } : {},
|
|
3037
3096
|
...tab.groups ? { groups: remapGroups(tab.groups) } : {}
|
|
3038
3097
|
}))
|
|
3039
3098
|
};
|
|
@@ -3352,12 +3411,8 @@ async function migrateUrl(options) {
|
|
|
3352
3411
|
const openApiAsset = mergeEmbeddedOpenApi(openApiFragments);
|
|
3353
3412
|
if (openApiAsset) {
|
|
3354
3413
|
const operationPageIds = new Set(pages.filter((page) => page.openapi).map((page) => page.navigationId));
|
|
3355
|
-
const
|
|
3356
|
-
|
|
3357
|
-
return typeof page === "string" ? operationPageIds.has(page) : containsOperation(page.pages);
|
|
3358
|
-
});
|
|
3359
|
-
return containsOperation(group.pages);
|
|
3360
|
-
})) ?? docsConfig.tabs[0];
|
|
3414
|
+
const containsOperation = (navigationPages = []) => navigationPages.some((page) => typeof page === "string" ? operationPageIds.has(page) : containsOperation(page.pages));
|
|
3415
|
+
const apiTab = docsConfig.tabs.find((tab) => containsOperation(tab.pages) || containsOperation(tab.groups)) ?? docsConfig.tabs[0];
|
|
3361
3416
|
if (apiTab) {
|
|
3362
3417
|
apiTab.api = { source: "/openapi.yaml", navigation: false };
|
|
3363
3418
|
}
|