pruning #3
2 changed files with 25 additions and 27 deletions
|
|
@ -71,9 +71,7 @@ export function mapPurchasedShoppingList(dto: components['schemas']['PurchasedSh
|
||||||
if (listRaw) {
|
if (listRaw) {
|
||||||
const base = decodeShoppingList(listRaw)
|
const base = decodeShoppingList(listRaw)
|
||||||
if (base) {
|
if (base) {
|
||||||
const decoded = Array.isArray(listRaw.items) ? decodeShoppingListItems(listRaw.items) : []
|
const items = Array.isArray(listRaw.items) ? decodeShoppingListItems(listRaw.items) : []
|
||||||
// start with decoded items and attach refs below; treat as WithRefs variant
|
|
||||||
const items = decoded as unknown as import('@/domain/types').ShoppingListItemWithRefs[]
|
|
||||||
list = { ...base, items }
|
list = { ...base, items }
|
||||||
const lookups: ShoppingLookups = {
|
const lookups: ShoppingLookups = {
|
||||||
...(ingredientsLookup && { ingredientsLookup }),
|
...(ingredientsLookup && { ingredientsLookup }),
|
||||||
|
|
@ -117,9 +115,9 @@ export function mapCurrentShoppingList(dto: components['schemas']['CurrentShoppi
|
||||||
}
|
}
|
||||||
|
|
||||||
const dtoOut: CurrentShoppingListDTO = {
|
const dtoOut: CurrentShoppingListDTO = {
|
||||||
outstandingItems: (decodeShoppingListItems(outstandingRaw ?? []) as unknown) as ShoppingListItemWithRefs[],
|
outstandingItems: decodeShoppingListItems(outstandingRaw ?? []),
|
||||||
requestedMeals: (decodeShoppingListItems(requestedRaw ?? []) as unknown) as ShoppingListItemWithRefs[],
|
requestedMeals: decodeShoppingListItems(requestedRaw ?? []),
|
||||||
purchasedItems: (decodeShoppingListItems(purchasedRaw ?? []) as unknown) as ShoppingListItemWithRefs[],
|
purchasedItems: decodeShoppingListItems(purchasedRaw ?? []),
|
||||||
...(ingredientsLookup && { ingredientsLookup }),
|
...(ingredientsLookup && { ingredientsLookup }),
|
||||||
...(mealsLookup && { mealsLookup }),
|
...(mealsLookup && { mealsLookup }),
|
||||||
...(recipesLookup && { recipesLookup }),
|
...(recipesLookup && { recipesLookup }),
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import type { RecipeOut, Recipe, MealOut, Meal, MealRecipe, Ingredient as DomainIngredient, ShoppingList, ShoppingListItem, MealInput } from './types'
|
import type { RecipeOut, Recipe, MealOut, Meal, MealRecipe, Ingredient as DomainIngredient, ShoppingList, ShoppingListItem, ShoppingListItemWithRefs, MealInput } from './types'
|
||||||
import type { components } from '@/api/types'
|
import type { components } from '@/api/types'
|
||||||
|
|
||||||
export function toDate(value: string | Date | null | undefined): Date | null {
|
export function toDate(value: string | Date | null | undefined): Date | null {
|
||||||
|
|
@ -9,7 +9,7 @@ export function toDate(value: string | Date | null | undefined): Date | null {
|
||||||
// Small helper to decode optional lookup maps without repeating loops everywhere
|
// Small helper to decode optional lookup maps without repeating loops everywhere
|
||||||
export function decodeLookup<TIn, TOut>(
|
export function decodeLookup<TIn, TOut>(
|
||||||
raw: Record<string, TIn> | null | undefined,
|
raw: Record<string, TIn> | null | undefined,
|
||||||
decode: (v: TIn) => TOut | null
|
decode: (v: TIn) => TOut
|
||||||
): Record<string, TOut> | undefined {
|
): Record<string, TOut> | undefined {
|
||||||
if (!raw) return undefined
|
if (!raw) return undefined
|
||||||
const out: Record<string, TOut> = {}
|
const out: Record<string, TOut> = {}
|
||||||
|
|
@ -18,13 +18,13 @@ export function decodeLookup<TIn, TOut>(
|
||||||
const maybe = raw[key]
|
const maybe = raw[key]
|
||||||
if (maybe === undefined) continue
|
if (maybe === undefined) continue
|
||||||
const decoded = decode(maybe)
|
const decoded = decode(maybe)
|
||||||
if (decoded) out[String(key)] = decoded
|
out[String(key)] = decoded
|
||||||
}
|
}
|
||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
|
|
||||||
export function decodeRecipe(r: RecipeOut | null | undefined): Recipe | null {
|
export function decodeRecipe(r: RecipeOut | null | undefined): Recipe {
|
||||||
if (!r) return null
|
if (!r) throw new Error('Invalid recipe payload')
|
||||||
return {
|
return {
|
||||||
...r,
|
...r,
|
||||||
dateCreated: toDate(r.dateCreated),
|
dateCreated: toDate(r.dateCreated),
|
||||||
|
|
@ -32,11 +32,10 @@ export function decodeRecipe(r: RecipeOut | null | undefined): Recipe | null {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function decodeMeal(m: MealOut | null | undefined): Meal {
|
||||||
export function decodeMeal(m: MealOut | null | undefined): Meal | null {
|
if (!m) throw new Error('Invalid meal payload')
|
||||||
if (!m) return null
|
|
||||||
const recipes = Array.isArray(m.recipes)
|
const recipes = Array.isArray(m.recipes)
|
||||||
? m.recipes.map(mr => decodeMealRecipe(mr)).filter((r): r is MealRecipe => !!r)
|
? m.recipes.map((mr) => decodeMealRecipe(mr))
|
||||||
: []
|
: []
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|
@ -52,40 +51,41 @@ export function decodeMeal(m: MealOut | null | undefined): Meal | null {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function decodeMealRecipe(mr: components['schemas']['MealRecipe-Output'] | null | undefined): MealRecipe | null {
|
export function decodeMealRecipe(mr: components['schemas']['MealRecipe-Output'] | null | undefined): MealRecipe {
|
||||||
if (!mr) return null
|
if (!mr) throw new Error('Invalid meal recipe payload')
|
||||||
return {
|
return {
|
||||||
...mr,
|
...mr,
|
||||||
recipe: mr.recipe ? decodeRecipe(mr.recipe) : null,
|
recipe: mr.recipe ? decodeRecipe(mr.recipe) : null,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function decodeIngredient(i: components['schemas']['Ingredient'] | null | undefined): DomainIngredient | null {
|
export function decodeIngredient(i: components['schemas']['Ingredient'] | null | undefined): DomainIngredient {
|
||||||
if (!i) return null
|
if (!i) throw new Error('Invalid ingredient payload')
|
||||||
// API guarantees quantity is a number; pass through
|
// API guarantees quantity is a number; pass through
|
||||||
return { ...i }
|
return { ...i }
|
||||||
}
|
}
|
||||||
|
|
||||||
export function decodeIngredients(list: components['schemas']['Ingredient'][] | null | undefined): DomainIngredient[] {
|
export function decodeIngredients(list: components['schemas']['Ingredient'][] | null | undefined): DomainIngredient[] {
|
||||||
if (!Array.isArray(list)) return []
|
if (!Array.isArray(list)) return []
|
||||||
return list.map((i) => decodeIngredient(i)).filter((x): x is DomainIngredient => !!x)
|
return list.map((i) => decodeIngredient(i))
|
||||||
}
|
}
|
||||||
|
|
||||||
export function decodeShoppingListItem(i: components['schemas']['ShoppingListItem'] | null | undefined): ShoppingListItem | null {
|
export function decodeShoppingListItem(i: components['schemas']['ShoppingListItem'] | null | undefined): ShoppingListItem {
|
||||||
if (!i) return null
|
if (!i) throw new Error('Invalid shopping list item payload')
|
||||||
return {
|
return {
|
||||||
...i,
|
...i,
|
||||||
createdDate: toDate(i.createdDate),
|
createdDate: toDate(i.createdDate),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function decodeShoppingListItems(list: components['schemas']['ShoppingListItem'][] | null | undefined): ShoppingListItem[] {
|
export function decodeShoppingListItems(list: components['schemas']['ShoppingListItem'][] | null | undefined): ShoppingListItemWithRefs[] {
|
||||||
if (!Array.isArray(list)) return []
|
if (!Array.isArray(list)) return []
|
||||||
return list.map((i) => decodeShoppingListItem(i)).filter((x): x is ShoppingListItem => !!x)
|
// Build a new array with item clones to allow optional refs to be attached later
|
||||||
|
return list.map((raw) => ({ ...decodeShoppingListItem(raw) }))
|
||||||
}
|
}
|
||||||
|
|
||||||
export function decodeShoppingList(v: components['schemas']['ShoppingList'] | null | undefined): ShoppingList | null {
|
export function decodeShoppingList(v: components['schemas']['ShoppingList'] | null | undefined): ShoppingList {
|
||||||
if (!v) return null
|
if (!v) throw new Error('Invalid shopping list payload')
|
||||||
const { items: rawItems, ...rest } = v
|
const { items: rawItems, ...rest } = v
|
||||||
const items = Array.isArray(rawItems) ? decodeShoppingListItems(rawItems) : undefined
|
const items = Array.isArray(rawItems) ? decodeShoppingListItems(rawItems) : undefined
|
||||||
return {
|
return {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue