fix(config): merge markdown hooks when extending config

pull/5205/head
Jonathan Doughty 3 weeks ago
parent ee028266a8
commit f4cfe2f650

@ -0,0 +1,42 @@
import { mergeConfig } from 'node/config'
describe('node/config', () => {
test('composes markdown hooks when merging configs', async () => {
const calls: string[] = []
const md = {} as any
const merged = mergeConfig(
{
markdown: {
preConfig: () => {
calls.push('base-pre')
},
config: async () => {
calls.push('base')
},
externalLinks: { rel: 'noopener' }
}
},
{
markdown: {
preConfig: async () => {
calls.push('child-pre')
},
config: () => {
calls.push('child')
},
externalLinks: { target: '_blank' }
}
}
)
await merged.markdown?.preConfig?.(md)
await merged.markdown?.config?.(md)
expect(calls).toEqual(['base-pre', 'child-pre', 'base', 'child'])
expect(merged.markdown?.externalLinks).toEqual({
rel: 'noopener',
target: '_blank'
})
})
})

@ -289,9 +289,13 @@ async function resolveConfigExtends(
}
export function mergeConfig(a: UserConfig, b: UserConfig, isRoot = true) {
return mergeObjectConfig(a, b, isRoot)
}
function mergeObjectConfig<T extends object>(a: T, b: T, isRoot = true): T {
const merged: Record<string, any> = { ...a }
for (const key in b) {
const value = b[key as keyof UserConfig]
const value = b[key as keyof T] as any
if (value == null) {
continue
}
@ -303,16 +307,41 @@ export function mergeConfig(a: UserConfig, b: UserConfig, isRoot = true) {
if (isObject(existing) && isObject(value)) {
if (isRoot && key === 'vite') {
merged[key] = mergeViteConfig(existing, value)
} else if (key === 'markdown') {
merged[key] = mergeMarkdownConfig(existing, value)
} else {
merged[key] = mergeConfig(existing, value, false)
merged[key] = mergeObjectConfig(existing, value, false)
}
continue
}
merged[key] = value
}
return merged as T
}
function mergeMarkdownConfig(
a: NonNullable<UserConfig['markdown']>,
b: NonNullable<UserConfig['markdown']>
) {
const merged = mergeObjectConfig(a, b, false)
merged.preConfig = mergeConfigHooks(a.preConfig, b.preConfig)
merged.config = mergeConfigHooks(a.config, b.config)
return merged
}
function mergeConfigHooks<T extends (...args: any[]) => Awaitable<void>>(
a: T | undefined,
b: T | undefined
): T | undefined {
if (!a) return b
if (!b) return a
return (async (...args: Parameters<T>) => {
await a(...args)
await b(...args)
}) as unknown as T
}
export async function resolveSiteData(
root: string,
userConfig?: UserConfig,

Loading…
Cancel
Save