in packages/docusaurus-migrate/src/index.ts [522:638]
async function migrateVersionedSidebar(
context: MigrationContext,
versions: string[],
versionRegex: RegExp,
) {
const {siteDir, newDir} = context;
if (await fs.pathExists(path.join(siteDir, 'versioned_sidebars'))) {
await fs.mkdirp(path.join(newDir, 'versioned_sidebars'));
const sidebars: {
entries: SidebarEntries;
version: string;
}[] = [];
// Order matters: if a sidebar file doesn't exist, we have to use the
// previous version's
for (let i = 0; i < versions.length; i += 1) {
const version = versions[i]!;
let sidebarEntries: SidebarEntries;
const sidebarPath = path.join(
siteDir,
'versioned_sidebars',
`version-${version}-sidebars.json`,
);
try {
sidebarEntries = JSON.parse(await fs.readFile(sidebarPath, 'utf-8'));
} catch {
sidebars.push({version, entries: sidebars[i - 1]!.entries});
return;
}
const newSidebar = Object.entries(sidebarEntries).reduce(
(topLevel: SidebarEntries, value) => {
const key = value[0].replace(versionRegex, '');
topLevel[key] = Object.entries(value[1]).reduce((acc, val) => {
acc[val[0].replace(versionRegex, '')] = (
val[1] as SidebarEntry[]
).map((item) => {
if (typeof item === 'string') {
return item.replace(versionRegex, '');
}
return {
type: 'category',
label: item.label,
ids: item.ids.map((id) => id.replace(versionRegex, '')),
};
});
return acc;
}, {} as {[key: string]: Array<string | {[key: string]: unknown}>});
return topLevel;
},
{},
);
sidebars.push({version, entries: newSidebar});
}
await Promise.all(
sidebars.map(async (sidebar) => {
const newSidebar = Object.entries(sidebar.entries).reduce(
(acc, val) => {
const key = `version-${sidebar.version}/${val[0]}`;
acc[key] = Object.entries(val[1]).map((value) => ({
type: 'category',
label: value[0],
items: (value[1] as SidebarEntry[]).map((sidebarItem) => {
if (typeof sidebarItem === 'string') {
return {
type: 'doc',
id: `version-${sidebar.version}/${sidebarItem}`,
};
}
return {
type: 'category',
label: sidebarItem.label,
items: sidebarItem.ids.map((id) => ({
type: 'doc',
id: `version-${sidebar.version}/${id}`,
})),
};
}),
}));
return acc;
},
{} as SidebarEntries,
);
await fs.outputFile(
path.join(
newDir,
'versioned_sidebars',
`version-${sidebar.version}-sidebars.json`,
),
JSON.stringify(newSidebar, null, 2),
);
}),
);
context.v2Config.themeConfig.navbar.items.push({
label: 'Version',
to: 'docs',
position: 'right',
items: [
{
label: versions[versions.length - 1],
to: 'docs/',
activeBaseRegex: `docs/(?!${versions.join('|')}|next)`,
},
...versions
.reverse()
.slice(1)
.map((version) => ({
label: version,
to: `docs/${version}/`,
})),
{
label: 'Main/Unreleased',
to: `docs/next/`,
activeBaseRegex: `docs/next/(?!support|team|resources)`,
},
],
});
}
}