diff --git a/__tests__/e2e/dynamic-routes/[id].paths.ts b/__tests__/e2e/dynamic-routes/[id].paths.ts index 48e35261..a5036936 100644 --- a/__tests__/e2e/dynamic-routes/[id].paths.ts +++ b/__tests__/e2e/dynamic-routes/[id].paths.ts @@ -1,3 +1,4 @@ +import type { PageData } from 'client/shared' import paths from './paths' export default { @@ -5,5 +6,9 @@ export default { console.log('watchedFiles', watchedFiles) return paths }, - watch: ['**/data-loading/**/*.json'] + watch: ['**/data-loading/**/*.json'], + async transformPageData(pageData: PageData) { + console.log('transformPageData', pageData.filePath) + pageData.title += ' - transformed' + } } diff --git a/src/node/markdownToVue.ts b/src/node/markdownToVue.ts index 8212800e..d4576cda 100644 --- a/src/node/markdownToVue.ts +++ b/src/node/markdownToVue.ts @@ -9,6 +9,7 @@ import { type MarkdownOptions, type MarkdownRenderer } from './markdown/markdown' +import { getPageDataTransformer } from './plugins/dynamicRoutesPlugin' import { EXTERNAL_URL_RE, getLocaleForPath, @@ -42,8 +43,9 @@ export function clearCache(id?: string) { } let __pages: string[] = [] -let __dynamicRoutes = new Map() +let __dynamicRoutes = new Map() let __rewrites = new Map() +let __ts: number function getResolutionCache(siteConfig: SiteConfig) { // @ts-expect-error internal @@ -53,7 +55,7 @@ function getResolutionCache(siteConfig: SiteConfig) { __dynamicRoutes = new Map( siteConfig.dynamicRoutes.map((r) => [ r.fullPath, - slash(path.join(siteConfig.srcDir, r.route)) + [slash(path.join(siteConfig.srcDir, r.route)), r.loaderPath] ]) ) @@ -64,6 +66,8 @@ function getResolutionCache(siteConfig: SiteConfig) { ]) ) + __ts = Date.now() + // @ts-expect-error internal siteConfig.__dirty = false } @@ -71,7 +75,8 @@ function getResolutionCache(siteConfig: SiteConfig) { return { pages: __pages, dynamicRoutes: __dynamicRoutes, - rewrites: __rewrites + rewrites: __rewrites, + ts: __ts } } @@ -96,13 +101,25 @@ export async function createMarkdownToVueRenderFn( file: string, publicDir: string ): Promise => { - const { pages, dynamicRoutes, rewrites } = getResolutionCache(siteConfig) + const { pages, dynamicRoutes, rewrites, ts } = + getResolutionCache(siteConfig) + + const dynamicRoute = dynamicRoutes.get(file) + const fileOrig = dynamicRoute?.[0] || file + const transformPageData = [ + siteConfig?.transformPageData, + getPageDataTransformer(dynamicRoute?.[1]!) + ].filter((fn) => fn != null) - const fileOrig = dynamicRoutes.get(file) || file file = rewrites.get(file) || file const relativePath = slash(path.relative(srcDir, file)) - const cacheKey = JSON.stringify({ src, file: relativePath, id: fileOrig }) + const cacheKey = JSON.stringify({ + src, + ts, + file: relativePath, + id: fileOrig + }) if (isBuild || options.cache !== false) { const cached = cache.get(cacheKey) if (cached) { @@ -224,14 +241,14 @@ export async function createMarkdownToVueRenderFn( } } - if (siteConfig?.transformPageData) { - const dataToMerge = await siteConfig.transformPageData(pageData, { - siteConfig - }) - if (dataToMerge) { - pageData = { - ...pageData, - ...dataToMerge + for (const fn of transformPageData) { + if (fn) { + const dataToMerge = await fn(pageData, { siteConfig }) + if (dataToMerge) { + pageData = { + ...pageData, + ...dataToMerge + } } } } diff --git a/src/node/plugins/dynamicRoutesPlugin.ts b/src/node/plugins/dynamicRoutesPlugin.ts index 5aabf2e6..38909916 100644 --- a/src/node/plugins/dynamicRoutesPlugin.ts +++ b/src/node/plugins/dynamicRoutesPlugin.ts @@ -50,6 +50,7 @@ interface ResolvedRouteModule { watch: string[] | undefined routes: ResolvedRouteConfig[] | undefined loader: RouteModule['paths'] + transformPageData?: UserConfig['transformPageData'] } const dynamicRouteRE = /\[(\w+?)\]/g @@ -196,6 +197,12 @@ export const dynamicRoutesPlugin = async ( } } +export function getPageDataTransformer( + loaderPath: string +): UserConfig['transformPageData'] | undefined { + return routeModuleCache.get(loaderPath)?.transformPageData +} + async function resolveDynamicRoutes( srcDir: string, routes: string[], @@ -227,6 +234,7 @@ async function resolveDynamicRoutes( // load the paths loader module let watch: ResolvedRouteModule['watch'] let loader: ResolvedRouteModule['loader'] + let extras: Partial const loaderPath = normalizePath(pathsFile) const existing = routeModuleCache.get(loaderPath) @@ -238,7 +246,7 @@ async function resolveDynamicRoutes( continue } - ;({ watch, loader } = existing) + ;({ watch, loader, ...extras } = existing) } else { let mod try { @@ -265,9 +273,9 @@ async function resolveDynamicRoutes( continue } - const routeModule = mod.config as RouteModule + // @ts-ignore + ;({ paths: loader, watch, ...extras } = mod.config) - loader = routeModule.paths if (!loader) { logger.warn( c.yellow( @@ -278,10 +286,7 @@ async function resolveDynamicRoutes( continue } - watch = - typeof routeModule.watch === 'string' - ? [routeModule.watch] - : routeModule.watch + watch = typeof watch === 'string' ? [watch] : watch if (watch) { watch = watch.map((p) => p.startsWith('.') @@ -329,7 +334,7 @@ async function resolveDynamicRoutes( } }) - routeModuleCache.set(loaderPath, { watch, routes, loader }) + routeModuleCache.set(loaderPath, { ...extras, watch, routes, loader }) return routes }