import {z} from 'zod' export type GetApiRecipesComplexSearchArgs = {query?: string | undefined, cuisine?: string | undefined, excludeCuisine?: string | undefined, diet?: string | undefined, intolerances?: string | undefined, equipment?: string | undefined, includeIngredients?: string | undefined, excludeIngredients?: string | undefined, type?: string | undefined, instructionsRequired?: boolean | undefined, fillIngredients?: boolean | undefined, addRecipeInformation?: boolean | undefined, addRecipeNutrition?: boolean | undefined, author?: string | undefined, tags?: string | undefined, recipeBoxId?: number | undefined, titleMatch?: string | undefined, maxReadyTime?: number | undefined, ignorePantry?: boolean | undefined, sort?: string | undefined, sortDirection?: string | undefined, minCarbs?: number | undefined, maxCarbs?: number | undefined, minProtein?: number | undefined, maxProtein?: number | undefined, minCalories?: number | undefined, maxCalories?: number | undefined, minFat?: number | undefined, maxFat?: number | undefined, minAlcohol?: number | undefined, maxAlcohol?: number | undefined, minCaffeine?: number | undefined, maxCaffeine?: number | undefined, minCopper?: number | undefined, maxCopper?: number | undefined, minCalcium?: number | undefined, maxCalcium?: number | undefined, minCholine?: number | undefined, maxCholine?: number | undefined, minCholesterol?: number | undefined, maxCholesterol?: number | undefined, minFluoride?: number | undefined, maxFluoride?: number | undefined, minSaturatedFat?: number | undefined, maxSaturatedFat?: number | undefined, minVitaminA?: number | undefined, maxVitaminA?: number | undefined, minVitaminC?: number | undefined, maxVitaminC?: number | undefined, minVitaminD?: number | undefined, maxVitaminD?: number | undefined, minVitaminE?: number | undefined, maxVitaminE?: number | undefined, minVitaminK?: number | undefined, maxVitaminK?: number | undefined, minVitaminB1?: number | undefined, maxVitaminB1?: number | undefined, minVitaminB2?: number | undefined, maxVitaminB2?: number | undefined, minVitaminB5?: number | undefined, maxVitaminB5?: number | undefined, minVitaminB3?: number | undefined, maxVitaminB3?: number | undefined, minVitaminB6?: number | undefined, maxVitaminB6?: number | undefined, minVitaminB12?: number | undefined, maxVitaminB12?: number | undefined, minFiber?: number | undefined, maxFiber?: number | undefined, minFolate?: number | undefined, maxFolate?: number | undefined, minFolicAcid?: number | undefined, maxFolicAcid?: number | undefined, minIodine?: number | undefined, maxIodine?: number | undefined, minIron?: number | undefined, maxIron?: number | undefined, minMagnesium?: number | undefined, maxMagnesium?: number | undefined, minManganese?: number | undefined, maxManganese?: number | undefined, minPhosphorus?: number | undefined, maxPhosphorus?: number | undefined, minPotassium?: number | undefined, maxPotassium?: number | undefined, minSelenium?: number | undefined, maxSelenium?: number | undefined, minSodium?: number | undefined, maxSodium?: number | undefined, minSugar?: number | undefined, maxSugar?: number | undefined, minZinc?: number | undefined, maxZinc?: number | undefined, offset?: number | undefined, number?: number | undefined, limitLicense?: boolean | undefined}; export type GetApiRecipesComplexSearchOptions = {baseUrl?: string | undefined, apiKeyScheme?: string | undefined, fetch?: typeof fetch | undefined}; export const getApiRecipesComplexSearchResponse = z.object({offset: z.number().int(), number: z.number().int(), results: z.array(z.object({id: z.number().int(), title: z.string().min(1), calories: z.number(), carbs: z.string().min(1), fat: z.string().min(1), image: z.string().min(1), imageType: z.string().min(1), protein: z.string().min(1)})), totalResults: z.number().int()}); export const validateResponse = async ( schema: { readonly '~standard': { readonly validate: (value: unknown) => ({ readonly value: Output; readonly issues?: undefined } | { readonly issues: ReadonlyArray<{ readonly message: string; readonly path?: ReadonlyArray | undefined }> }) | Promise<{ readonly value: Output; readonly issues?: undefined } | { readonly issues: ReadonlyArray<{ readonly message: string; readonly path?: ReadonlyArray | undefined }> }> } }, value: unknown ): Promise => { const result = await schema['~standard'].validate(value) if (result.issues !== undefined) { const detail = result.issues .map(({ message, path }) => path?.length ? `${path.map((segment) => String(typeof segment === 'object' ? segment.key : segment)).join('.')}: ${message}` : message ) .join('; ') throw new Error(`Response does not match the schema: ${detail}`, { cause: { issues: result.issues } }) } return result.value }; /** * Search Recipes * * GET /recipes/complexSearch */ export const getApiRecipesComplexSearch = async (args: GetApiRecipesComplexSearchArgs, options?: GetApiRecipesComplexSearchOptions) => { const {baseUrl = "https://api.spoonacular.com", fetch: fetchFn = fetch, apiKeyScheme} = options ?? {} const query = new URLSearchParams() const headers = new Headers() headers.set('accept', "application/json") if (args.query != null) query.append("query", String(args.query)) if (args.cuisine != null) query.append("cuisine", String(args.cuisine)) if (args.excludeCuisine != null) query.append("excludeCuisine", String(args.excludeCuisine)) if (args.diet != null) query.append("diet", String(args.diet)) if (args.intolerances != null) query.append("intolerances", String(args.intolerances)) if (args.equipment != null) query.append("equipment", String(args.equipment)) if (args.includeIngredients != null) query.append("includeIngredients", String(args.includeIngredients)) if (args.excludeIngredients != null) query.append("excludeIngredients", String(args.excludeIngredients)) if (args.type != null) query.append("type", String(args.type)) if (args.instructionsRequired != null) query.append("instructionsRequired", String(args.instructionsRequired)) if (args.fillIngredients != null) query.append("fillIngredients", String(args.fillIngredients)) if (args.addRecipeInformation != null) query.append("addRecipeInformation", String(args.addRecipeInformation)) if (args.addRecipeNutrition != null) query.append("addRecipeNutrition", String(args.addRecipeNutrition)) if (args.author != null) query.append("author", String(args.author)) if (args.tags != null) query.append("tags", String(args.tags)) if (args.recipeBoxId != null) query.append("recipeBoxId", String(args.recipeBoxId)) if (args.titleMatch != null) query.append("titleMatch", String(args.titleMatch)) if (args.maxReadyTime != null) query.append("maxReadyTime", String(args.maxReadyTime)) if (args.ignorePantry != null) query.append("ignorePantry", String(args.ignorePantry)) if (args.sort != null) query.append("sort", String(args.sort)) if (args.sortDirection != null) query.append("sortDirection", String(args.sortDirection)) if (args.minCarbs != null) query.append("minCarbs", String(args.minCarbs)) if (args.maxCarbs != null) query.append("maxCarbs", String(args.maxCarbs)) if (args.minProtein != null) query.append("minProtein", String(args.minProtein)) if (args.maxProtein != null) query.append("maxProtein", String(args.maxProtein)) if (args.minCalories != null) query.append("minCalories", String(args.minCalories)) if (args.maxCalories != null) query.append("maxCalories", String(args.maxCalories)) if (args.minFat != null) query.append("minFat", String(args.minFat)) if (args.maxFat != null) query.append("maxFat", String(args.maxFat)) if (args.minAlcohol != null) query.append("minAlcohol", String(args.minAlcohol)) if (args.maxAlcohol != null) query.append("maxAlcohol", String(args.maxAlcohol)) if (args.minCaffeine != null) query.append("minCaffeine", String(args.minCaffeine)) if (args.maxCaffeine != null) query.append("maxCaffeine", String(args.maxCaffeine)) if (args.minCopper != null) query.append("minCopper", String(args.minCopper)) if (args.maxCopper != null) query.append("maxCopper", String(args.maxCopper)) if (args.minCalcium != null) query.append("minCalcium", String(args.minCalcium)) if (args.maxCalcium != null) query.append("maxCalcium", String(args.maxCalcium)) if (args.minCholine != null) query.append("minCholine", String(args.minCholine)) if (args.maxCholine != null) query.append("maxCholine", String(args.maxCholine)) if (args.minCholesterol != null) query.append("minCholesterol", String(args.minCholesterol)) if (args.maxCholesterol != null) query.append("maxCholesterol", String(args.maxCholesterol)) if (args.minFluoride != null) query.append("minFluoride", String(args.minFluoride)) if (args.maxFluoride != null) query.append("maxFluoride", String(args.maxFluoride)) if (args.minSaturatedFat != null) query.append("minSaturatedFat", String(args.minSaturatedFat)) if (args.maxSaturatedFat != null) query.append("maxSaturatedFat", String(args.maxSaturatedFat)) if (args.minVitaminA != null) query.append("minVitaminA", String(args.minVitaminA)) if (args.maxVitaminA != null) query.append("maxVitaminA", String(args.maxVitaminA)) if (args.minVitaminC != null) query.append("minVitaminC", String(args.minVitaminC)) if (args.maxVitaminC != null) query.append("maxVitaminC", String(args.maxVitaminC)) if (args.minVitaminD != null) query.append("minVitaminD", String(args.minVitaminD)) if (args.maxVitaminD != null) query.append("maxVitaminD", String(args.maxVitaminD)) if (args.minVitaminE != null) query.append("minVitaminE", String(args.minVitaminE)) if (args.maxVitaminE != null) query.append("maxVitaminE", String(args.maxVitaminE)) if (args.minVitaminK != null) query.append("minVitaminK", String(args.minVitaminK)) if (args.maxVitaminK != null) query.append("maxVitaminK", String(args.maxVitaminK)) if (args.minVitaminB1 != null) query.append("minVitaminB1", String(args.minVitaminB1)) if (args.maxVitaminB1 != null) query.append("maxVitaminB1", String(args.maxVitaminB1)) if (args.minVitaminB2 != null) query.append("minVitaminB2", String(args.minVitaminB2)) if (args.maxVitaminB2 != null) query.append("maxVitaminB2", String(args.maxVitaminB2)) if (args.minVitaminB5 != null) query.append("minVitaminB5", String(args.minVitaminB5)) if (args.maxVitaminB5 != null) query.append("maxVitaminB5", String(args.maxVitaminB5)) if (args.minVitaminB3 != null) query.append("minVitaminB3", String(args.minVitaminB3)) if (args.maxVitaminB3 != null) query.append("maxVitaminB3", String(args.maxVitaminB3)) if (args.minVitaminB6 != null) query.append("minVitaminB6", String(args.minVitaminB6)) if (args.maxVitaminB6 != null) query.append("maxVitaminB6", String(args.maxVitaminB6)) if (args.minVitaminB12 != null) query.append("minVitaminB12", String(args.minVitaminB12)) if (args.maxVitaminB12 != null) query.append("maxVitaminB12", String(args.maxVitaminB12)) if (args.minFiber != null) query.append("minFiber", String(args.minFiber)) if (args.maxFiber != null) query.append("maxFiber", String(args.maxFiber)) if (args.minFolate != null) query.append("minFolate", String(args.minFolate)) if (args.maxFolate != null) query.append("maxFolate", String(args.maxFolate)) if (args.minFolicAcid != null) query.append("minFolicAcid", String(args.minFolicAcid)) if (args.maxFolicAcid != null) query.append("maxFolicAcid", String(args.maxFolicAcid)) if (args.minIodine != null) query.append("minIodine", String(args.minIodine)) if (args.maxIodine != null) query.append("maxIodine", String(args.maxIodine)) if (args.minIron != null) query.append("minIron", String(args.minIron)) if (args.maxIron != null) query.append("maxIron", String(args.maxIron)) if (args.minMagnesium != null) query.append("minMagnesium", String(args.minMagnesium)) if (args.maxMagnesium != null) query.append("maxMagnesium", String(args.maxMagnesium)) if (args.minManganese != null) query.append("minManganese", String(args.minManganese)) if (args.maxManganese != null) query.append("maxManganese", String(args.maxManganese)) if (args.minPhosphorus != null) query.append("minPhosphorus", String(args.minPhosphorus)) if (args.maxPhosphorus != null) query.append("maxPhosphorus", String(args.maxPhosphorus)) if (args.minPotassium != null) query.append("minPotassium", String(args.minPotassium)) if (args.maxPotassium != null) query.append("maxPotassium", String(args.maxPotassium)) if (args.minSelenium != null) query.append("minSelenium", String(args.minSelenium)) if (args.maxSelenium != null) query.append("maxSelenium", String(args.maxSelenium)) if (args.minSodium != null) query.append("minSodium", String(args.minSodium)) if (args.maxSodium != null) query.append("maxSodium", String(args.maxSodium)) if (args.minSugar != null) query.append("minSugar", String(args.minSugar)) if (args.maxSugar != null) query.append("maxSugar", String(args.maxSugar)) if (args.minZinc != null) query.append("minZinc", String(args.minZinc)) if (args.maxZinc != null) query.append("maxZinc", String(args.maxZinc)) if (args.offset != null) query.append("offset", String(args.offset)) if (args.number != null) query.append("number", String(args.number)) if (args.limitLicense != null) query.append("limitLicense", String(args.limitLicense)) if (apiKeyScheme !== undefined) headers.set("x-api-key", apiKeyScheme) const url = `${baseUrl.replace(/\/+$/, '')}/recipes/complexSearch${query.size > 0 ? `?${query}` : ''}` const res = await fetchFn(url, {method: "GET", headers}) if (!res.ok) throw new Error(`Request failed with status ${res.status}`, {cause: {status: res.status, body: await res.text()}}) return validateResponse(getApiRecipesComplexSearchResponse, await res.json()) };