refactor: update auth and fix error handling

This commit is contained in:
Bolaji Ayodeji 2021-08-17 11:19:54 +01:00 committed by Alessandro Casazza
parent eaf96bad18
commit 1f0c79e68a
No known key found for this signature in database
GPG Key ID: 3AF41B06C6495D3D
5 changed files with 111 additions and 27 deletions

View File

@ -2,14 +2,14 @@ import { MutationHook } from '@commerce/utils/types'
import useLogin, { UseLogin } from '@commerce/auth/use-login' import useLogin, { UseLogin } from '@commerce/auth/use-login'
import { CommerceError } from '@commerce/utils/errors' import { CommerceError } from '@commerce/utils/errors'
import { getCustomerToken } from '@commercelayer/js-auth' import { getCustomerToken } from '@commercelayer/js-auth'
import { ENDPOINT, CLIENTID, SCOPE } from '../const'
import setCookie from '@framework/api/utils/cookies' import setCookie from '@framework/api/utils/cookies'
export default useLogin as UseLogin<typeof handler> export default useLogin as UseLogin<typeof handler>
export const handler: MutationHook<any> = { export const handler: MutationHook<any> = {
fetchOptions: { fetchOptions: {
// query: 'login', url: `${ENDPOINT}/api/customers`,
url: '/customer',
}, },
async fetcher({ input: { email, password }, options, fetch }) { async fetcher({ input: { email, password }, options, fetch }) {
if (!(email && password)) { if (!(email && password)) {
@ -17,17 +17,26 @@ export const handler: MutationHook<any> = {
message: 'An email and password are required to login', message: 'An email and password are required to login',
}) })
} }
try {
const token = await getCustomerToken( const token = await getCustomerToken(
{ {
endpoint: process.env.NEXT_PUBLIC_COMMERCELAYER_ENDPOINT as string, endpoint: ENDPOINT,
clientId: process.env.NEXT_PUBLIC_COMMERCELAYER_CLIENT_ID as string, clientId: CLIENTID,
scope: process.env.NEXT_PUBLIC_COMMERCELAYER_MARKET_SCOPE as string, scope: SCOPE,
}, },
{ username: email, password } { username: email, password }
) )
token && token &&
setCookie('CL_TOKEN', token.accessToken, { expires: token.expires }) setCookie('CL_TOKEN', token.accessToken, { expires: token.expires })
alert(`User "${email}" has successfully been logged in.`)
return token return token
} catch (error) {
console.error(error)
throw new CommerceError({
message: `${error}`,
})
}
}, },
useHook: useHook:
({ fetch }) => ({ fetch }) =>

View File

@ -2,18 +2,46 @@ import { useCallback } from 'react'
import useCustomer from '../customer/use-customer' import useCustomer from '../customer/use-customer'
import { MutationHook } from '@commerce/utils/types' import { MutationHook } from '@commerce/utils/types'
import useSignup, { UseSignup } from '@commerce/auth/use-signup' import useSignup, { UseSignup } from '@commerce/auth/use-signup'
import { CommerceError } from '@commerce/utils/errors'
import {ENDPOINT} from '../const'
export default useSignup as UseSignup<typeof handler> export default useSignup as UseSignup<typeof handler>
export const handler: MutationHook<any> = { export const handler: MutationHook<any> = {
fetchOptions: { fetchOptions: {
query: '', query: 'customers',
url: `${ENDPOINT}/api/customers`,
method: 'POST'
}, },
async fetcher() { async fetcher({ input: { email, password }, options, fetch }) {
return null if (!(email && password)) {
throw new CommerceError({
message: 'An email and password are required to signup',
})
}
try {
const data = await fetch({
...options,
variables: {
email,
password,
},
})
alert(`User "${email}" has successfully been created.`)
return data
} catch (error) {
throw new CommerceError({
message: `${error}`,
})
}
}, },
useHook: useHook:
({ fetch }) => ({ fetch }) =>
() => () => {
() => {}, return async function signup(input) {
const data = await fetch({ input })
return data
}
},
} }

View File

@ -0,0 +1,3 @@
export const ENDPOINT = process.env.NEXT_PUBLIC_COMMERCELAYER_ENDPOINT as string;
export const CLIENTID = process.env.NEXT_PUBLIC_COMMERCELAYER_CLIENT_ID as string;
export const SCOPE = process.env.NEXT_PUBLIC_COMMERCELAYER_MARKET_SCOPE as string;

View File

@ -1,12 +1,29 @@
import { Fetcher } from '@commerce/utils/types' import { Fetcher } from '@commerce/utils/types'
import handleFetchResponse from './utils/handle-fetch-response'
import { ENDPOINT, CLIENTID, SCOPE } from './const'
import { getSalesChannelToken } from '@commercelayer/js-auth'
export const fetcher: Fetcher = async () => { export const fetcher: Fetcher = async ({ url, method, variables, query }) => {
console.log('FETCHER') const token = await getSalesChannelToken({
debugger endpoint: ENDPOINT,
const res = await fetch('./data.json') clientId: CLIENTID,
if (res.ok) { scope: SCOPE,
const { data } = await res.json() })
return data
} return handleFetchResponse(
throw res await fetch(url!, {
method,
headers: {
Accept: 'application/vnd.api+json',
Authorization: `Bearer ${token.accessToken}`,
'Content-Type': 'application/vnd.api+json',
},
body: JSON.stringify({
data: {
type: query,
attributes: variables,
},
}),
})
)
} }

View File

@ -0,0 +1,27 @@
import { FetcherError } from '@commerce/utils/errors'
export function getError(errors: any[], status: number) {
errors = errors ?? [{ message: 'Failed to fetch Commerce Layer API' }]
return new FetcherError({ errors, status })
}
export async function getAsyncError(res: Response) {
const data = await res.json()
return getError(data.errors, res.status)
}
const handleFetchResponse = async (res: Response) => {
if (res.ok) {
const { data, errors } = await res.json()
if (errors && errors.length) {
throw getError(errors, res.status)
}
return data
}
throw await getAsyncError(res)
}
export default handleFetchResponse