The raw value read from the user_settings store.
The migrated settings object, or raw when it isn't an object.
migrateUserSettings({ caching: true, cacheTtlMinutes: 60 });
// => { caching: { enabled: true, doNotCacheEmptyResults: undefined, ttlMinutes: 60 } }
export function migrateUserSettings(raw: unknown): unknown {
if (!isRecord(raw)) return raw;
const out: Record<string, unknown> = { ...raw };
if (
!isRecord(out.caching) &&
('caching' in out || 'cacheTtlMinutes' in out || 'doNotCacheEmptyResults' in out)
) {
out.caching = {
enabled: typeof raw.caching === 'boolean' ? raw.caching : undefined,
doNotCacheEmptyResults: raw.doNotCacheEmptyResults,
ttlMinutes: raw.cacheTtlMinutes,
};
}
delete out.cacheTtlMinutes;
delete out.doNotCacheEmptyResults;
if (
!isRecord(out.priceTracking) &&
('trackPriceHistory' in out || 'priceHistoryMaxPoints' in out)
) {
out.priceTracking = {
enabled: raw.trackPriceHistory,
maxDataPoints: raw.priceHistoryMaxPoints,
};
}
delete out.trackPriceHistory;
delete out.priceHistoryMaxPoints;
const legacyEnabled = Array.isArray(raw.suppliers) ? raw.suppliers : undefined;
if (
legacyEnabled ||
'disabledSuppliers' in out ||
'excludeNonShippingSuppliers' in out ||
'supplierResultLimit' in out
) {
const existing = isRecord(out.suppliers) ? out.suppliers : {};
out.suppliers = {
...existing,
enabled: legacyEnabled ?? existing.enabled,
disabled: raw.disabledSuppliers ?? existing.disabled,
excludeNonShipping: raw.excludeNonShippingSuppliers ?? existing.excludeNonShipping,
resultLimit: raw.supplierResultLimit ?? existing.resultLimit,
};
}
delete out.disabledSuppliers;
delete out.excludeNonShippingSuppliers;
delete out.supplierResultLimit;
return out;
}
Migrates legacy flat user-settings keys into the current nested objects:
caching(boolean) +cacheTtlMinutes+doNotCacheEmptyResults→caching: { enabled, ttlMinutes, doNotCacheEmptyResults }trackPriceHistory+priceHistoryMaxPoints→priceTracking: { enabled, maxDataPoints }suppliers(array) +disabledSuppliers+excludeNonShippingSuppliers+supplierResultLimit→suppliers: { enabled, disabled, excludeNonShipping, resultLimit }Idempotent (already-nested input passes through untouched) and non-mutating. Non-object input (e.g.
undefined) is returned unchanged.