fix: normalize Khanegi UI config on save for userTheme schema
Prevent re-saving invalid navigation.type/header.variant/products routes. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -143,3 +143,41 @@ export function stripKhanegiSaMeta<T extends Record<string, unknown> | null | un
|
|||||||
return rest as T
|
return rest as T
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function mapLegacyRoute(route: unknown) {
|
||||||
|
return route === 'products' ? 'buyProduct' : route
|
||||||
|
}
|
||||||
|
|
||||||
|
function mapLegacyNavItems<T extends { route?: unknown }>(items: T[] | undefined) {
|
||||||
|
if (!Array.isArray(items)) return items
|
||||||
|
return items.map((item) => ({
|
||||||
|
...item,
|
||||||
|
route: mapLegacyRoute(item.route) as T['route'],
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
/** همتراز با اسکیمای userTheme (Zod) — جلوگیری از fallback تم */
|
||||||
|
export function normalizeKhanegiUiConfigForClient<T extends Record<string, any>>(ui: T): T {
|
||||||
|
if (!ui || typeof ui !== 'object') return ui
|
||||||
|
const next = JSON.parse(JSON.stringify(ui)) as T
|
||||||
|
|
||||||
|
const fixApp = (app: any) => {
|
||||||
|
if (!app || typeof app !== 'object') return
|
||||||
|
if (app.startRoute === 'products') app.startRoute = 'buyProduct'
|
||||||
|
if (app.header && typeof app.header === 'object') {
|
||||||
|
app.header.variant = 'default'
|
||||||
|
}
|
||||||
|
if (app.navigation && typeof app.navigation === 'object') {
|
||||||
|
if (app.navigation.type === 'sidebar+bottom') app.navigation.type = 'both'
|
||||||
|
app.navigation.sidebar = mapLegacyNavItems(app.navigation.sidebar)
|
||||||
|
app.navigation.bottom = mapLegacyNavItems(app.navigation.bottom)
|
||||||
|
if (app.navigation.sidebarReferral?.route === 'products') {
|
||||||
|
app.navigation.sidebarReferral.route = 'buyProduct'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fixApp((next as any).app)
|
||||||
|
fixApp((next as any).defaultSnapshot?.app)
|
||||||
|
return next
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import api from '@/api/http'
|
|||||||
import {
|
import {
|
||||||
cloneKhanegiAppSnapshot,
|
cloneKhanegiAppSnapshot,
|
||||||
createDefaultKhanegiUiConfig,
|
createDefaultKhanegiUiConfig,
|
||||||
|
normalizeKhanegiUiConfigForClient,
|
||||||
} from '@/config/defaultKhanegiUiConfig'
|
} from '@/config/defaultKhanegiUiConfig'
|
||||||
import {
|
import {
|
||||||
applyKhanegiPreset,
|
applyKhanegiPreset,
|
||||||
@@ -201,10 +202,15 @@ function buildSavePayload() {
|
|||||||
if (selectedPreset.value === 'custom') {
|
if (selectedPreset.value === 'custom') {
|
||||||
markCustomAndSyncSchemes(config)
|
markCustomAndSyncSchemes(config)
|
||||||
}
|
}
|
||||||
const payload = JSON.parse(JSON.stringify(config)) as typeof config
|
const payload = normalizeKhanegiUiConfigForClient(
|
||||||
|
JSON.parse(JSON.stringify(config)) as typeof config,
|
||||||
|
)
|
||||||
// Never drop or rewrite an existing factory snapshot on normal save
|
// Never drop or rewrite an existing factory snapshot on normal save
|
||||||
if (config.defaultSnapshot) {
|
if (config.defaultSnapshot) {
|
||||||
payload.defaultSnapshot = JSON.parse(JSON.stringify(config.defaultSnapshot))
|
payload.defaultSnapshot = normalizeKhanegiUiConfigForClient({
|
||||||
|
app: JSON.parse(JSON.stringify(config.defaultSnapshot.app)),
|
||||||
|
pages: JSON.parse(JSON.stringify(config.defaultSnapshot.pages || {})),
|
||||||
|
}) as typeof payload.defaultSnapshot
|
||||||
}
|
}
|
||||||
return payload
|
return payload
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user