import { apiClient } from './api-client'; import type { z } from 'zod/v4'; import type { ShoppingListResponseSchema, ShoppingItemSchema, CreateShoppingListSchema, UpdateShoppingListSchema, AddShoppingItemSchema, UpdateShoppingItemSchema, ShoppingListSyncToPantryResponseSchema, BasketStoreComparisonResponseSchema, } from '@meshitrack/shared'; export type ShoppingListResponse = z.infer; export type ShoppingItem = z.infer; export type CreateShoppingListInput = z.infer; export type UpdateShoppingListInput = z.infer; export type AddShoppingItemInput = z.infer; export type UpdateShoppingItemInput = z.infer; export type ShoppingListSyncToPantryResponse = z.infer< typeof ShoppingListSyncToPantryResponseSchema >; export type BasketStoreComparisonResponse = z.infer; export async function getShoppingLists(householdId: string): Promise { return apiClient.get(`/households/${householdId}/shopping-lists`); } export async function getShoppingList( householdId: string, id: string, ): Promise { return apiClient.get(`/households/${householdId}/shopping-lists/${id}`); } export async function createShoppingList( householdId: string, data: CreateShoppingListInput, ): Promise { return apiClient.post(`/households/${householdId}/shopping-lists`, data); } export async function updateShoppingList( householdId: string, id: string, data: UpdateShoppingListInput, ): Promise { return apiClient.patch( `/households/${householdId}/shopping-lists/${id}`, data, ); } export async function deleteShoppingList(householdId: string, id: string): Promise { return apiClient.delete(`/households/${householdId}/shopping-lists/${id}`); } // -- Nested Item Operations -- export async function addShoppingItem( householdId: string, id: string, data: AddShoppingItemInput, ): Promise { return apiClient.post( `/households/${householdId}/shopping-lists/${id}/items`, data, ); } export async function updateShoppingItem( householdId: string, id: string, itemId: string, data: UpdateShoppingItemInput, ): Promise { return apiClient.patch( `/households/${householdId}/shopping-lists/${id}/items/${itemId}`, data, ); } export async function removeShoppingItem( householdId: string, id: string, itemId: string, ): Promise { return apiClient.delete( `/households/${householdId}/shopping-lists/${id}/items/${itemId}`, ); } // -- Workflows -- export async function generateFromMealPlan( householdId: string, mealPlanId: string, ): Promise { return apiClient.post( `/households/${householdId}/shopping-lists/from-meal-plan/${mealPlanId}`, ); } export async function syncToPantry( householdId: string, id: string, ): Promise { return apiClient.post( `/households/${householdId}/shopping-lists/${id}/sync-to-pantry`, ); } export async function getBasketStoreComparison( householdId: string, id: string, ): Promise { return apiClient.get( `/households/${householdId}/shopping-lists/${id}/stores`, ); } /** * Generates direct WebSocket path for collaborative checklist syncing. */ export function getShoppingListSyncSocketUrl(householdId: string, id: string): string { // Derive WS protocol based on configured API baseURL protocol (defaulting to unsafe ws for localhost) const baseUrl = apiClient.baseUrl || ''; const isSecure = baseUrl.startsWith('https'); const cleanHost = baseUrl.replace(/^https?:\/\//, ''); const protocol = isSecure ? 'wss' : 'ws'; return `${protocol}://${cleanHost}/households/${householdId}/shopping-lists/${id}/sync`; }