import { useCallback } from 'react' import type { MutationHook } from '@commerce/utils/types' import useLogin, { UseLogin } from '@commerce/auth/use-login' import type { LoginHook } from '@commerce/types/login' import type { AuthTokenAttr } from '@spree/storefront-api-v2-sdk/types/interfaces/Authentication' import { FetcherError, ValidationError } from '@commerce/utils/errors' import useCustomer from '../customer/use-customer' import useCart from '../cart/use-cart' import useWishlist from '../wishlist/use-wishlist' import login from '../utils/login' export default useLogin as UseLogin export const handler: MutationHook = { // Provide fetchOptions for SWR cache key fetchOptions: { url: 'authentication', query: 'getToken', }, async fetcher({ input, options, fetch }) { console.info( 'useLogin fetcher called. Configuration: ', 'input: ', input, 'options: ', options ) const { email, password } = input if (!email || !password) { throw new ValidationError({ message: 'Email and password need to be provided.', }) } const getTokenParameters: AuthTokenAttr = { username: email, password, } try { await login(fetch, getTokenParameters, false) return null } catch (getTokenError) { if ( getTokenError instanceof FetcherError && getTokenError.status === 400 ) { // Change the error message to be more user friendly. throw new FetcherError({ status: getTokenError.status, message: 'The email or password is invalid.', code: getTokenError.code, }) } throw getTokenError } }, useHook: ({ fetch }) => { const useWrappedHook: ReturnType['useHook']> = () => { const customer = useCustomer() const cart = useCart() const wishlist = useWishlist() return useCallback( async function login(input) { const data = await fetch({ input }) await customer.revalidate() await cart.revalidate() await wishlist.revalidate() return data }, [customer, cart, wishlist] ) } return useWrappedHook }, }