UNPKG

@techsio/storefront-data

Version:

Medusa-first storefront data layer built on TanStack Query.

187 lines (186 loc) • 7.99 kB
import { useMutation, useQuery, useQueryClient, useSuspenseQuery } from "@tanstack/react-query"; import { assertStorefrontAddressValidation } from "../shared/address.js"; import { createCacheConfig } from "../shared/cache-config.js"; import { toErrorMessage } from "../shared/error-utils.js"; import { createQueryKey } from "../shared/query-keys.js"; import { createCustomerQueryKeys } from "./query-keys.js"; function createCustomerHooks({ service, buildListParams, addressAdapter, buildUpdateCustomerParams, queryKeys, authQueryKeys, queryKeyNamespace = "storefront-data", cacheConfig }) { const resolvedCacheConfig = cacheConfig ?? createCacheConfig(); const resolvedQueryKeys = queryKeys ?? createCustomerQueryKeys(queryKeyNamespace); const resolvedAuthQueryKeys = authQueryKeys ?? { customer: ()=>createQueryKey(queryKeyNamespace, "auth", "customer") }; const buildList = buildListParams ?? ((input)=>input); const buildCreate = addressAdapter?.toCreateParams ?? ((input)=>input); const buildUpdate = addressAdapter?.toUpdateParams ?? ((input)=>{ const { addressId: _addressId, ...restUpdateInput } = input; return restUpdateInput; }); const buildUpdateCustomer = buildUpdateCustomerParams ?? ((input)=>input); function useCustomerAddresses(input, options) { const { enabled: inputEnabled, ...listInput } = input; const listParams = buildList(listInput); const queryKey = resolvedQueryKeys.addresses(listParams); const enabled = inputEnabled ?? true; const query = useQuery({ queryKey, queryFn: ({ signal })=>service.getAddresses(listParams, signal), enabled, ...resolvedCacheConfig.userData, ...options?.queryOptions ?? {} }); const { data, isLoading, isFetching, isSuccess, error } = query; return { addresses: data?.addresses ?? [], isLoading, isFetching, isSuccess, error: toErrorMessage(error), query }; } function useSuspenseCustomerAddresses(input, options) { const { enabled: _inputEnabled, ...listInput } = input; const listParams = buildList(listInput); const query = useSuspenseQuery({ queryKey: resolvedQueryKeys.addresses(listParams), queryFn: ({ signal })=>service.getAddresses(listParams, signal), ...resolvedCacheConfig.userData, ...options?.queryOptions ?? {} }); const { data, isFetching } = query; return { addresses: data?.addresses ?? [], isLoading: false, isFetching, isSuccess: true, error: null, query }; } function useCreateCustomerAddress(options) { const queryClient = useQueryClient(); return useMutation({ mutationFn: (input)=>{ const normalized = addressAdapter?.normalizeCreate ? addressAdapter.normalizeCreate(input, { mode: "create" }) : input; assertStorefrontAddressValidation(addressAdapter?.validateCreate?.(normalized, { mode: "create" })); return service.createAddress(buildCreate(normalized, { mode: "create" })); }, onMutate: options?.onMutate, onSuccess: (address, variables, context)=>{ queryClient.invalidateQueries({ queryKey: resolvedQueryKeys.all() }); queryClient.invalidateQueries({ queryKey: resolvedAuthQueryKeys.customer() }); options?.onSuccess?.(address, variables, context); }, onError: (error, variables, context)=>{ options?.onError?.(error, variables, context); }, onSettled: (data, error, variables, context)=>{ options?.onSettled?.(data, error, variables, context); } }); } function useUpdateCustomerAddress(options) { const queryClient = useQueryClient(); return useMutation({ mutationFn: (input)=>{ const addressId = input.addressId; if (!addressId) throw new Error("Address id is required"); const normalized = addressAdapter?.normalizeUpdate ? addressAdapter.normalizeUpdate(input, { mode: "update" }) : input; assertStorefrontAddressValidation(addressAdapter?.validateUpdate?.(normalized, { mode: "update" })); return service.updateAddress(addressId, buildUpdate(normalized, { mode: "update" })); }, onMutate: options?.onMutate, onSuccess: (address, variables, context)=>{ queryClient.invalidateQueries({ queryKey: resolvedQueryKeys.all() }); queryClient.invalidateQueries({ queryKey: resolvedAuthQueryKeys.customer() }); options?.onSuccess?.(address, variables, context); }, onError: (error, variables, context)=>{ options?.onError?.(error, variables, context); }, onSettled: (data, error, variables, context)=>{ options?.onSettled?.(data, error, variables, context); } }); } function useDeleteCustomerAddress(options) { const queryClient = useQueryClient(); return useMutation({ mutationFn: ({ addressId })=>{ if (!addressId) throw new Error("Address id is required"); return service.deleteAddress(addressId); }, onMutate: options?.onMutate, onSuccess: (data, variables, context)=>{ queryClient.invalidateQueries({ queryKey: resolvedQueryKeys.all() }); queryClient.invalidateQueries({ queryKey: resolvedAuthQueryKeys.customer() }); options?.onSuccess?.(data, variables, context); }, onError: (error, variables, context)=>{ options?.onError?.(error, variables, context); }, onSettled: (data, error, variables, context)=>{ options?.onSettled?.(data, error, variables, context); } }); } function useUpdateCustomer(options) { const queryClient = useQueryClient(); return useMutation({ mutationFn: (input)=>{ if (!service.updateCustomer) throw new Error("updateCustomer service is not configured"); return service.updateCustomer(buildUpdateCustomer(input)); }, onMutate: options?.onMutate, onSuccess: (customer, variables, context)=>{ queryClient.invalidateQueries({ queryKey: resolvedQueryKeys.profile() }); queryClient.invalidateQueries({ queryKey: resolvedAuthQueryKeys.customer() }); options?.onSuccess?.(customer, variables, context); }, onError: (error, variables, context)=>{ options?.onError?.(error, variables, context); }, onSettled: (data, error, variables, context)=>{ options?.onSettled?.(data, error, variables, context); } }); } return { useCustomerAddresses, useSuspenseCustomerAddresses, useCreateCustomerAddress, useUpdateCustomerAddress, useDeleteCustomerAddress, useUpdateCustomer }; } export { createCustomerHooks };