diff --git a/__tests__/unit/node/config.test.ts b/__tests__/unit/node/config.test.ts index 22f7d0348..4abb8ed6f 100644 --- a/__tests__/unit/node/config.test.ts +++ b/__tests__/unit/node/config.test.ts @@ -1,15 +1,18 @@ import type { MarkdownItAsync } from 'markdown-it-async' -import { mergeConfig } from 'node/config' +import { mergeConfig, type UserConfig } from 'node/config' describe('node/config', () => { - test('merges markdown config hooks from extended configs', async () => { + test('merges markdown hooks from extended configs', async () => { const calls: string[] = [] const md = {} as MarkdownItAsync - const merged = mergeConfig( + const merged = mergeConfig( { markdown: { lineNumbers: true, + preConfig() { + calls.push('base-pre') + }, config() { calls.push('base') } @@ -20,6 +23,9 @@ describe('node/config', () => { attrs: { allowedAttributes: ['id'] }, + async preConfig() { + calls.push('extended-pre') + }, async config() { calls.push('extended') } @@ -32,8 +38,36 @@ describe('node/config', () => { allowedAttributes: ['id'] }) + await merged.markdown?.preConfig?.(md) + await merged.markdown?.config?.(md) + + expect(calls).toEqual(['base-pre', 'extended-pre', 'base', 'extended']) + }) + + test('keeps one-sided markdown hooks when the other config omits them', async () => { + const calls: string[] = [] + const md = {} as MarkdownItAsync + + const merged = mergeConfig( + { + markdown: { + preConfig() { + calls.push('base-pre') + } + } + }, + { + markdown: { + config() { + calls.push('extended') + } + } + } + ) + + await merged.markdown?.preConfig?.(md) await merged.markdown?.config?.(md) - expect(calls).toEqual(['base', 'extended']) + expect(calls).toEqual(['base-pre', 'extended']) }) }) diff --git a/src/node/config.ts b/src/node/config.ts index 55d791e0c..749e1f39d 100644 --- a/src/node/config.ts +++ b/src/node/config.ts @@ -332,17 +332,24 @@ export function mergeConfig( function mergeMarkdownConfig(a: MarkdownOptions, b: MarkdownOptions) { const merged = mergeConfig(a, b, false) - const baseConfig = a.config - const extendedConfig = b.config - if (baseConfig && extendedConfig) { - merged.config = async (md) => { - await baseConfig(md) - await extendedConfig(md) - } - } + merged.preConfig = mergeMarkdownHooks(a.preConfig, b.preConfig) + merged.config = mergeMarkdownHooks(a.config, b.config) return merged } +function mergeMarkdownHooks( + base: MarkdownOptions['config'], + extended: MarkdownOptions['config'] +): MarkdownOptions['config'] { + if (!base || !extended) { + return base ?? extended + } + return async (md) => { + await base(md) + await extended(md) + } +} + export async function resolveSiteData( root: string, userConfig?: UserConfig,