fix(nuxt): allow updating appConfig with non-iterable objects (#28773)

This commit is contained in:
Gianluca Di Francesco 2024-09-02 13:12:58 +02:00 committed by GitHub
parent c8cff9be54
commit 4e74246bcc
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 35 additions and 16 deletions

View File

@ -11,6 +11,15 @@ type DeepPartial<T> = T extends Function ? T : T extends Record<string, any> ? {
// Workaround for vite HMR with virtual modules // Workaround for vite HMR with virtual modules
export const _getAppConfig = () => __appConfig as AppConfig export const _getAppConfig = () => __appConfig as AppConfig
function isPojoOrArray (val: unknown): val is object {
return (
Array.isArray(val) ||
(!!val &&
typeof val === 'object' &&
val.constructor?.name === 'Object')
)
}
function deepDelete (obj: any, newObj: any) { function deepDelete (obj: any, newObj: any) {
for (const key in obj) { for (const key in obj) {
const val = newObj[key] const val = newObj[key]
@ -18,7 +27,7 @@ function deepDelete (obj: any, newObj: any) {
delete (obj as any)[key] delete (obj as any)[key]
} }
if (val !== null && typeof val === 'object') { if (isPojoOrArray(val)) {
deepDelete(obj[key], newObj[key]) deepDelete(obj[key], newObj[key])
} }
} }
@ -27,7 +36,7 @@ function deepDelete (obj: any, newObj: any) {
function deepAssign (obj: any, newObj: any) { function deepAssign (obj: any, newObj: any) {
for (const key in newObj) { for (const key in newObj) {
const val = newObj[key] const val = newObj[key]
if (val !== null && typeof val === 'object') { if (isPojoOrArray(val)) {
const defaultVal = Array.isArray(val) ? [] : {} const defaultVal = Array.isArray(val) ? [] : {}
obj[key] = obj[key] || defaultVal obj[key] = obj[key] || defaultVal
deepAssign(obj[key], val) deepAssign(obj[key], val)

View File

@ -31,23 +31,33 @@ registerEndpoint('/api/test', defineEventHandler(event => ({
describe('app config', () => { describe('app config', () => {
it('can be updated', () => { it('can be updated', () => {
const appConfig = useAppConfig() const appConfig = useAppConfig()
expect(appConfig).toMatchInlineSnapshot(` expect(appConfig).toStrictEqual({ nuxt: {} })
{
"nuxt": {}, type UpdateAppConfig = Parameters<typeof updateAppConfig>[0]
}
`) const initConfig: UpdateAppConfig = {
updateAppConfig({
new: 'value', new: 'value',
nuxt: { nested: 42 }, nuxt: { nested: 42 },
regExp: /foo/g,
date: new Date(1111, 11, 11),
arr: [1, 2, 3],
}
updateAppConfig(initConfig)
expect(appConfig).toStrictEqual(initConfig)
const newConfig: UpdateAppConfig = {
nuxt: { anotherNested: 24 },
regExp: /bar/g,
date: new Date(2222, 12, 12),
arr: [4, 5],
}
updateAppConfig(newConfig)
expect(appConfig).toStrictEqual({
...initConfig,
...newConfig,
nuxt: { ...initConfig.nuxt, ...newConfig.nuxt },
arr: [4, 5, 3],
}) })
expect(appConfig).toMatchInlineSnapshot(`
{
"new": "value",
"nuxt": {
"nested": 42,
},
}
`)
}) })
}) })