UNPKG

@techsio/storefront-data

Version:

Medusa-first storefront data layer built on TanStack Query.

262 lines (261 loc) • 10.3 kB
import { useMutation, useQuery, useQueryClient, useSuspenseQuery } from "@tanstack/react-query"; import { createCacheConfig } from "../shared/cache-config.js"; import { toErrorMessage } from "../shared/error-utils.js"; import { createQueryKey } from "../shared/query-keys.js"; import { createAuthQueryKeys } from "./query-keys.js"; function createAuthHooks({ service, queryKeys, queryKeyNamespace = "storefront-data", cacheConfig, invalidateOnAuthChange }) { const resolvedCacheConfig = cacheConfig ?? createCacheConfig(); const resolvedQueryKeys = queryKeys ?? createAuthQueryKeys(queryKeyNamespace); const includeDefaultInvalidation = invalidateOnAuthChange?.includeDefaults ?? true; const defaultInvalidateKeys = includeDefaultInvalidation ? [ createQueryKey(queryKeyNamespace, "customer"), createQueryKey(queryKeyNamespace, "orders") ] : []; const invalidateKeys = [ ...defaultInvalidateKeys, ...invalidateOnAuthChange?.invalidate ?? [] ]; const removeOnLogoutKeys = [ ...defaultInvalidateKeys, ...invalidateOnAuthChange?.removeOnLogout ?? [] ]; const invalidateCrossDomain = (queryClient)=>{ for (const queryKey of invalidateKeys)queryClient.invalidateQueries({ queryKey }); }; const removeCrossDomainOnLogout = (queryClient)=>{ for (const queryKey of removeOnLogoutKeys)queryClient.removeQueries({ queryKey }); }; const clearCustomerSessionCache = (queryClient)=>{ queryClient.setQueryData(resolvedQueryKeys.customer(), null); queryClient.removeQueries({ queryKey: resolvedQueryKeys.all() }); removeCrossDomainOnLogout(queryClient); }; function useAuth(options) { const query = useQuery({ queryKey: resolvedQueryKeys.customer(), queryFn: ({ signal })=>service.getCustomer(signal), enabled: options?.enabled ?? true, retry: false, ...resolvedCacheConfig.userData, ...options?.queryOptions ?? {} }); const { data, isLoading, isFetching, isSuccess, error } = query; const customer = data ?? null; return { customer, isAuthenticated: null !== customer, isLoading, isFetching, isSuccess, error: toErrorMessage(error), query }; } function useSuspenseAuth(options) { const query = useSuspenseQuery({ queryKey: resolvedQueryKeys.customer(), queryFn: ({ signal })=>service.getCustomer(signal), ...resolvedCacheConfig.userData, ...options?.queryOptions ?? {} }); const { data, isFetching } = query; const customer = data ?? null; return { customer, isAuthenticated: null !== customer, isLoading: false, isFetching, isSuccess: true, error: null, query }; } function useLogin(options) { const queryClient = useQueryClient(); return useMutation({ mutationFn: (input)=>service.login(input), retry: false, onMutate: options?.onMutate, onSuccess: (data, variables, context)=>{ queryClient.invalidateQueries({ queryKey: resolvedQueryKeys.customer() }); invalidateCrossDomain(queryClient); 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 useRegister(options) { const queryClient = useQueryClient(); return useMutation({ mutationFn: (input)=>service.register(input), retry: false, onMutate: options?.onMutate, onSuccess: (data, variables, context)=>{ queryClient.invalidateQueries({ queryKey: resolvedQueryKeys.customer() }); invalidateCrossDomain(queryClient); 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 useCreateCustomer(options) { const queryClient = useQueryClient(); return useMutation({ mutationFn: (input)=>{ if (!service.createCustomer) throw new Error("createCustomer service is not configured"); return service.createCustomer(input); }, retry: false, onMutate: options?.onMutate, onSuccess: (data, variables, context)=>{ queryClient.invalidateQueries({ queryKey: resolvedQueryKeys.customer() }); invalidateCrossDomain(queryClient); 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 useLogout(options) { const queryClient = useQueryClient(); return useMutation({ mutationFn: ()=>service.logout(), retry: false, onMutate: options?.onMutate, onSuccess: (_data, _variables, context)=>{ clearCustomerSessionCache(queryClient); options?.onSuccess?.(void 0, void 0, context); }, onError: (error, variables, context)=>{ options?.onError?.(error, variables, context); }, onSettled: (data, error, variables, context)=>{ options?.onSettled?.(data, error, variables, context); } }); } function useRequestAccountDeactivation(options) { return useMutation({ mutationFn: ()=>{ if (!service.requestAccountDeactivation) throw new Error("requestAccountDeactivation service is not configured"); return service.requestAccountDeactivation(); }, retry: false, onMutate: options?.onMutate, onSuccess: (data, variables, context)=>{ 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 useConfirmAccountDeactivation(options) { const queryClient = useQueryClient(); return useMutation({ mutationFn: (input)=>{ if (!service.confirmAccountDeactivation) throw new Error("confirmAccountDeactivation service is not configured"); return service.confirmAccountDeactivation(input); }, retry: false, onMutate: options?.onMutate, onSuccess: (data, variables, context)=>{ clearCustomerSessionCache(queryClient); 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(input); }, retry: false, onMutate: options?.onMutate, onSuccess: (data, variables, context)=>{ queryClient.setQueryData(resolvedQueryKeys.customer(), data); 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 useRefreshAuth(options) { const queryClient = useQueryClient(); return useMutation({ mutationFn: ()=>{ if (!service.refresh) throw new Error("refresh service is not configured"); return service.refresh(); }, retry: false, onMutate: options?.onMutate, onSuccess: (data, variables, context)=>{ queryClient.invalidateQueries({ queryKey: resolvedQueryKeys.customer() }); invalidateCrossDomain(queryClient); 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); } }); } return { useAuth, useSuspenseAuth, useLogin, useRegister, useCreateCustomer, useRequestAccountDeactivation, useConfirmAccountDeactivation, useLogout, useUpdateCustomer, useRefreshAuth }; } export { createAuthHooks };