import {z} from 'zod' export type GetApiCompatV2UsersGetPreferencesOptions = {baseUrl?: string | undefined, Authorization?: string | undefined, fetch?: typeof fetch | undefined}; export const getApiCompatV2UsersGetPreferencesResponse = z.object({preferencesVersion: z.number().int().gte(-9007199254740991).lte(9007199254740991), "global.enableSplitPane": z.boolean(), "global.language": z.enum(["en-us", "it-it", "de-de", "uk-ua", "he", "es-es", "fr-fr", "ru-ru", "hu-hu", "da-dk", "zh-cn", "pt-pt", "pt-br", "nl", "pl", "ja", "lt", "eu", "el", "fi", "sv", "ro", "cs", "ar-sa", "hi", "es-mx", "ko", "nb-no", "tr", "zh-hant"]).nullable(), "global.fontSize": z.enum(["1rem", "14px", "16px", "18px", "20px", "22px", "24px"]), "global.theme": z.enum(["default", "light", "dark", "black", "midnight"]), "global.preferencesSync": z.enum(["enabled", "disabled"]), "global.startPage": z.enum(["myRecipes", "manageLabels", "mealPlans", "shoppingLists"]), "global.offlineModePrompt": z.enum(["ask", "never"]), "myRecipes.enableLabelIntersection": z.boolean(), "myRecipes.showLabels": z.boolean(), "myRecipes.showLabelChips": z.boolean(), "myRecipes.showImages": z.boolean(), "myRecipes.showSource": z.boolean(), "myRecipes.showRecipeDescription": z.boolean(), "myRecipes.showRating": z.boolean(), "myRecipes.viewType": z.enum(["tiles", "list", "compact"]), "myRecipes.sortBy": z.enum(["title", "-createdAt", "createdAt", "-updatedAt", "updatedAt", "-lastMadeAt", "lastMadeAt"]), "myRecipes.includeFriends": z.enum(["yes", "no", "search", "browse"]), "recipeDetails.enableWakeLock": z.boolean(), "recipeDetails.autoExpandNutrition": z.boolean(), "recipeDetails.layout": z.enum(["automatic", "stacked", "sideBySide", "sideBySideEqualWidth", "tabs"]), "cookMode.fontSize": z.enum(["1rem", "14px", "16px", "18px", "20px", "22px", "24px"]), "manageLabels.showCreatedAt": z.boolean(), "measurementConverter.enabledUnits": z.array(z.string()), "MealPlan.showAddedBy": z.boolean(), "MealPlan.showAddedOn": z.boolean(), "MealPlan.startOfWeek": z.enum(["monday", "sunday"]), "MealPlan.viewType": z.enum(["calendar", "list"]), "ShoppingList.sortBy": z.enum(["title", "-title", "createdAt", "-createdAt"]), "ShoppingList.showAddedBy": z.boolean(), "ShoppingList.showAddedOn": z.boolean(), "ShoppingList.showRecipeTitle": z.boolean(), "ShoppingList.preferDelete": z.boolean(), "ShoppingList.groupSimilar": z.boolean(), "ShoppingList.groupCategories": z.boolean(), "ShoppingList.ignoreItemTitles": z.string()}).nullable(); 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 }; /** * Get the caller's stored app preferences * * GET /compat/v2/users/getPreferences */ export const getApiCompatV2UsersGetPreferences = async (options?: GetApiCompatV2UsersGetPreferencesOptions) => { const {baseUrl = "https://api.recipesage.com", fetch: fetchFn = fetch, Authorization} = options ?? {} const query = new URLSearchParams() const headers = new Headers() headers.set('accept', "application/json") if (Authorization !== undefined) headers.set('authorization', `Bearer ${Authorization}`) const url = `${baseUrl.replace(/\/+$/, '')}/compat/v2/users/getPreferences${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(getApiCompatV2UsersGetPreferencesResponse, await res.json()) };