115 lines
3.9 KiB
JavaScript
115 lines
3.9 KiB
JavaScript
/**
|
|
* Inventory Migration Module
|
|
* Handles conversion from v1 (string) to v2 (structured) inventory format
|
|
*/
|
|
|
|
// Type imports
|
|
/** @typedef {import('../types/inventory.js').InventoryV1} InventoryV1 */
|
|
/** @typedef {import('../types/inventory.js').InventoryV2} InventoryV2 */
|
|
/** @typedef {import('../types/inventory.js').MigrationResult} MigrationResult */
|
|
|
|
/**
|
|
* Default v2 inventory structure for new/empty inventories
|
|
* @type {InventoryV2}
|
|
*/
|
|
const DEFAULT_INVENTORY_V2 = {
|
|
version: 2,
|
|
onPerson: "None",
|
|
clothing: "None",
|
|
stored: {},
|
|
assets: "None"
|
|
};
|
|
|
|
/**
|
|
* Migrates inventory data from v1 (string) to v2 (structured) format.
|
|
* Handles all edge cases: null, undefined, "None", already-migrated data.
|
|
*
|
|
* @param {InventoryV1 | InventoryV2 | null | undefined} inventory - Inventory data to migrate
|
|
* @returns {MigrationResult} Migration result with v2 inventory and metadata
|
|
*/
|
|
export function migrateInventory(inventory) {
|
|
// Case 1: v2 format missing version property (parser output)
|
|
// Parser returns v2 structure but without the version tag
|
|
if (inventory && typeof inventory === 'object' &&
|
|
'onPerson' in inventory && 'clothing' in inventory &&
|
|
'stored' in inventory && 'assets' in inventory &&
|
|
!('version' in inventory)) {
|
|
// console.log('[RPG Companion Migration] v2 inventory missing version tag, adding it');
|
|
return {
|
|
inventory: {
|
|
version: 2,
|
|
...inventory
|
|
},
|
|
migrated: true,
|
|
source: 'parser-output'
|
|
};
|
|
}
|
|
|
|
// Case 2: Already v2 format (has version property and is an object)
|
|
if (inventory && typeof inventory === 'object' && inventory.version === 2) {
|
|
// Check if clothing field exists (v2.1 upgrade)
|
|
if (!inventory.hasOwnProperty('clothing')) {
|
|
// console.log('[RPG Companion Migration] Upgrading v2 inventory to v2.1 (adding clothing field)');
|
|
inventory.clothing = "None";
|
|
return {
|
|
inventory: inventory,
|
|
migrated: true,
|
|
source: 'v2-upgrade'
|
|
};
|
|
}
|
|
|
|
// console.log('[RPG Companion Migration] Inventory already v2, no migration needed');
|
|
return {
|
|
inventory: inventory,
|
|
migrated: false,
|
|
source: 'v2'
|
|
};
|
|
}
|
|
|
|
// Case 3: null or undefined → use defaults
|
|
if (inventory === null || inventory === undefined) {
|
|
// console.log('[RPG Companion Migration] Inventory is null/undefined, using defaults');
|
|
return {
|
|
inventory: { ...DEFAULT_INVENTORY_V2 },
|
|
migrated: true,
|
|
source: 'null'
|
|
};
|
|
}
|
|
|
|
// Case 4: v1 string format → migrate to v2
|
|
if (typeof inventory === 'string') {
|
|
// Check if it's an empty/default string
|
|
const trimmed = inventory.trim();
|
|
if (trimmed === '' || trimmed.toLowerCase() === 'none') {
|
|
// console.log('[RPG Companion Migration] Inventory is empty/None, using defaults');
|
|
return {
|
|
inventory: { ...DEFAULT_INVENTORY_V2 },
|
|
migrated: true,
|
|
source: 'v1'
|
|
};
|
|
}
|
|
|
|
// Non-empty v1 string → migrate to v2.onPerson
|
|
// console.log('[RPG Companion Migration] Migrating v1 string to v2.onPerson:', inventory);
|
|
return {
|
|
inventory: {
|
|
version: 2,
|
|
onPerson: inventory,
|
|
clothing: "None",
|
|
stored: {},
|
|
assets: "None"
|
|
},
|
|
migrated: true,
|
|
source: 'v1'
|
|
};
|
|
}
|
|
|
|
// Case 4: Unknown format (malformed object, number, etc.) → use defaults
|
|
console.warn('[RPG Companion Migration] Unknown inventory format, using defaults:', inventory);
|
|
return {
|
|
inventory: { ...DEFAULT_INVENTORY_V2 },
|
|
migrated: true,
|
|
source: 'default'
|
|
};
|
|
}
|