84 lines
2.8 KiB
TypeScript
84 lines
2.8 KiB
TypeScript
|
|
import type { RecipeOut, Recipe, MealOut, Meal, MealRecipe, Ingredient as DomainIngredient, ShoppingList, ShoppingListItem } from './types'
|
||
|
|
import type { components } from '@/api/types'
|
||
|
|
|
||
|
|
export function toDate(value: string | Date | null | undefined): Date | null {
|
||
|
|
if (value === null || value === undefined) return null
|
||
|
|
return typeof value === 'string' ? new Date(value) : value
|
||
|
|
}
|
||
|
|
|
||
|
|
export function decodeRecipe(r: RecipeOut | null | undefined): Recipe | null {
|
||
|
|
if (!r) return null
|
||
|
|
return {
|
||
|
|
...r,
|
||
|
|
dateCreated: toDate(r.dateCreated),
|
||
|
|
dateHidden: toDate(r.dateHidden),
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
export function decodeRecipes(list: RecipeOut[] | null | undefined): Recipe[] {
|
||
|
|
if (!Array.isArray(list)) return []
|
||
|
|
return list.map((r) => decodeRecipe(r)).filter((r): r is Recipe => !!r)
|
||
|
|
}
|
||
|
|
|
||
|
|
export function decodeMeal(m: MealOut | null | undefined): Meal | null {
|
||
|
|
if (!m) return null
|
||
|
|
const recipes = Array.isArray(m.recipes)
|
||
|
|
? m.recipes.map(mr => decodeMealRecipe(mr)).filter((r): r is MealRecipe => !!r)
|
||
|
|
: []
|
||
|
|
|
||
|
|
return {
|
||
|
|
...m,
|
||
|
|
suggestedDate: toDate(m.suggestedDate),
|
||
|
|
purchaseDate: toDate(m.purchaseDate),
|
||
|
|
consumedDate: toDate(m.consumedDate),
|
||
|
|
recipes,
|
||
|
|
chefs: m.chefs ?? [],
|
||
|
|
consumers: m.consumers ?? [],
|
||
|
|
cleanup: m.cleanup ?? [],
|
||
|
|
extraIngredients: m.extraIngredients ?? [],
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
export function decodeMealRecipe(mr: components['schemas']['MealRecipe-Output'] | null | undefined): MealRecipe | null {
|
||
|
|
if (!mr) return null
|
||
|
|
return {
|
||
|
|
...mr,
|
||
|
|
recipe: mr.recipe ? decodeRecipe(mr.recipe) : null,
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
export function decodeIngredient(i: components['schemas']['Ingredient'] | null | undefined): DomainIngredient | null {
|
||
|
|
if (!i) return null
|
||
|
|
// API guarantees quantity is a number; pass through
|
||
|
|
return { ...i }
|
||
|
|
}
|
||
|
|
|
||
|
|
export function decodeIngredients(list: components['schemas']['Ingredient'][] | null | undefined): DomainIngredient[] {
|
||
|
|
if (!Array.isArray(list)) return []
|
||
|
|
return list.map((i) => decodeIngredient(i)).filter((x): x is DomainIngredient => !!x)
|
||
|
|
}
|
||
|
|
|
||
|
|
export function decodeShoppingListItem(i: components['schemas']['ShoppingListItem'] | null | undefined): ShoppingListItem | null {
|
||
|
|
if (!i) return null
|
||
|
|
return {
|
||
|
|
...i,
|
||
|
|
createdDate: toDate(i.createdDate),
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
export function decodeShoppingListItems(list: components['schemas']['ShoppingListItem'][] | null | undefined): ShoppingListItem[] {
|
||
|
|
if (!Array.isArray(list)) return []
|
||
|
|
return list.map((i) => decodeShoppingListItem(i)).filter((x): x is ShoppingListItem => !!x)
|
||
|
|
}
|
||
|
|
|
||
|
|
export function decodeShoppingList(v: components['schemas']['ShoppingList'] | null | undefined): ShoppingList | null {
|
||
|
|
if (!v) return null
|
||
|
|
const { items: rawItems, ...rest } = v
|
||
|
|
const items = Array.isArray(rawItems) ? decodeShoppingListItems(rawItems) : undefined
|
||
|
|
return {
|
||
|
|
...rest,
|
||
|
|
createdDate: toDate(v.createdDate),
|
||
|
|
...(items ? { items } : {}),
|
||
|
|
}
|
||
|
|
}
|