add grid validation utilities with legacy object normalization

This commit is contained in:
Justin Edmund 2025-11-29 17:43:34 -08:00
parent 2acc48b3c4
commit d0f7b3b89a
2 changed files with 125 additions and 3 deletions

View file

@ -11,6 +11,7 @@ import { BaseAdapter } from './base.adapter'
import type { AdapterOptions } from './types'
import type { GridWeapon, GridCharacter, GridSummon } from '$lib/types/api/party'
import { DEFAULT_ADAPTER_CONFIG } from './config'
import { validateGridWeapon, validateGridCharacter, validateGridSummon } from '$lib/utils/gridValidation'
// GridWeapon, GridCharacter, and GridSummon types are imported from types/api/party
// Re-export for test files and consumers
@ -103,7 +104,14 @@ export class GridAdapter extends BaseAdapter {
body: { weapon: params },
headers
})
return response.gridWeapon
// Validate and normalize response
const validated = validateGridWeapon(response.gridWeapon)
if (!validated) {
throw new Error('API returned incomplete GridWeapon data')
}
return validated
}
/**
@ -207,7 +215,14 @@ export class GridAdapter extends BaseAdapter {
body: { character: params },
headers
})
return response.gridCharacter
// Validate and normalize response
const validated = validateGridCharacter(response.gridCharacter)
if (!validated) {
throw new Error('API returned incomplete GridCharacter data')
}
return validated
}
/**
@ -311,7 +326,14 @@ export class GridAdapter extends BaseAdapter {
body: { summon: params },
headers
})
return response.gridSummon
// Validate and normalize response
const validated = validateGridSummon(response.gridSummon)
if (!validated) {
throw new Error('API returned incomplete GridSummon data')
}
return validated
}
/**

View file

@ -0,0 +1,100 @@
/**
* Grid Validation Utilities
*
* Validates and normalizes grid item data from API responses.
* Handles legacy 'object' property and ensures complete nested entity data.
*
* @module utils/gridValidation
*/
import type { GridWeapon, GridCharacter, GridSummon } from '$lib/types/api/party'
/**
* Validates that a GridWeapon has complete nested weapon data.
* Normalizes legacy 'object' property to 'weapon' if needed.
*
* @param raw - Raw grid weapon data from API
* @returns Validated GridWeapon or null if incomplete
*
* @example
* ```typescript
* // Valid data
* const validated = validateGridWeapon({
* id: '123',
* position: 0,
* weapon: { granblueId: '1040', name: {...} }
* })
*
* // Legacy data with 'object' property
* const validated = validateGridWeapon({
* id: '123',
* position: 0,
* object: { granblueId: '1040', name: {...} }
* }) // Automatically normalized to 'weapon'
* ```
*/
export function validateGridWeapon(raw: any): GridWeapon | null {
if (!raw || typeof raw !== 'object') return null
// Handle legacy API responses that use 'object' instead of 'weapon'
const weapon = raw.weapon || raw.object
if (!weapon || !weapon.granblueId) {
console.warn('GridWeapon missing nested weapon data:', raw)
return null
}
return {
...raw,
weapon, // Ensure 'weapon' property exists
object: undefined // Remove legacy 'object' property
} as GridWeapon
}
/**
* Validates that a GridCharacter has complete nested character data.
* Normalizes legacy 'object' property to 'character' if needed.
*
* @param raw - Raw grid character data from API
* @returns Validated GridCharacter or null if incomplete
*/
export function validateGridCharacter(raw: any): GridCharacter | null {
if (!raw || typeof raw !== 'object') return null
const character = raw.character || raw.object
if (!character || !character.granblueId) {
console.warn('GridCharacter missing nested character data:', raw)
return null
}
return {
...raw,
character,
object: undefined
} as GridCharacter
}
/**
* Validates that a GridSummon has complete nested summon data.
* Normalizes legacy 'object' property to 'summon' if needed.
*
* @param raw - Raw grid summon data from API
* @returns Validated GridSummon or null if incomplete
*/
export function validateGridSummon(raw: any): GridSummon | null {
if (!raw || typeof raw !== 'object') return null
const summon = raw.summon || raw.object
if (!summon || !summon.granblueId) {
console.warn('GridSummon missing nested summon data:', raw)
return null
}
return {
...raw,
summon,
object: undefined
} as GridSummon
}