// @ts-check import { readSharedData } from '@redocly/realm/dist/server/utils/shared-data.js'; // TODO: export function from root package const INDEX_PAGE_INFO_DATA_KEY = 'index-page-items'; export function indexPages() { /** @type {import("@redocly/realm/dist/server/plugins/types").PluginInstance } */ const instance = { // hook that gets executed after all routes were created async afterRoutesCreated(actions, { cache }) { // get all the routes that are ind pages const indexRoutes = actions .getAllRoutes() .filter((route) => route.metadata?.indexPage); for (const route of indexRoutes) { // @ts-ignore this uses some internals, we will expose them in nicer way in the future releases const sidebarId = actions.routesSharedData.get(route.slug)?.['sidebar']; // TODO: implement a helper function for this /** @type {any} */ const sidebar = await readSharedData(sidebarId, actions.outdir); if (!sidebar) { console.log('[warn] Index route used with no sidebar', route.fsPath); continue; } const item = findItemDeep(sidebar.items, route.fsPath); const childrenPaths = (item.items || []) .map((item) => item.fsPath) .filter(Boolean); const childRoutes = childrenPaths.map((fsPath) => actions.getRouteByFsPath(fsPath), ); const childRoutesData = await Promise.all( childRoutes.map(async (route) => { const { data } = await cache.load( route.fsPath, 'markdown-frontmatter', ); const slug = route.slug; const title = await route.getNavText(); return { ...data?.frontmatter, slug, title, }; }), ); const sharedDataId = await actions.createSharedData( route.slug + '_' + INDEX_PAGE_INFO_DATA_KEY, childRoutesData, ); actions.addRouteSharedData( route.slug, INDEX_PAGE_INFO_DATA_KEY, sharedDataId, ); } }, }; return instance; } function findItemDeep(items, fsPath) { for (const item of items) { if (item.fsPath === fsPath) { return item; } if (item.items) { const found = findItemDeep(item.items, fsPath); if (found) { return found; } } } }