mirror of
https://github.com/vercel/commerce.git
synced 2025-05-18 15:36:58 +00:00
commit
7bfc5c8873
@ -24,3 +24,8 @@ export type SignupSchema<T extends SignupTypes = SignupTypes> = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type SignupOperation = {
|
||||||
|
data: { result?: string }
|
||||||
|
variables: unknown
|
||||||
|
}
|
@ -1 +1,18 @@
|
|||||||
export default function noopApi(...args: any[]): void {}
|
import { GetAPISchema, createEndpoint } from '@commerce/api'
|
||||||
|
import signupEndpoint from '@commerce/api/endpoints/signup'
|
||||||
|
import type { SignupSchema } from '../../../../commerce/types/signup'
|
||||||
|
import type { ElasticpathAPI } from '../..'
|
||||||
|
import signup from './signup'
|
||||||
|
|
||||||
|
export type SignupAPI = GetAPISchema<ElasticpathAPI, SignupSchema>
|
||||||
|
|
||||||
|
export type SignupEndpoint = SignupAPI['endpoint']
|
||||||
|
|
||||||
|
export const handlers: SignupEndpoint['handlers'] = { signup }
|
||||||
|
|
||||||
|
const signupApi = createEndpoint<SignupAPI>({
|
||||||
|
handler: signupEndpoint,
|
||||||
|
handlers,
|
||||||
|
})
|
||||||
|
|
||||||
|
export default signupApi
|
||||||
|
54
framework/elasticpath/api/endpoints/signup/signup.ts
Normal file
54
framework/elasticpath/api/endpoints/signup/signup.ts
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
import type { SignupEndpoint } from '.'
|
||||||
|
|
||||||
|
const MoltinGateway = require('@moltin/sdk').gateway
|
||||||
|
const Moltin = MoltinGateway({
|
||||||
|
client_id: process.env.NEXT_PUBLIC_ELASTICPATH_CLIENTID,
|
||||||
|
client_secret: process.env.ELASTICPATH_SECRET
|
||||||
|
})
|
||||||
|
|
||||||
|
const signup: SignupEndpoint['handlers']['signup'] = async ({
|
||||||
|
res,
|
||||||
|
body: { firstName, lastName, email, password },
|
||||||
|
config,
|
||||||
|
commerce,
|
||||||
|
}) => {
|
||||||
|
// TODO: Add proper validations with something like Ajv
|
||||||
|
if (!(firstName && lastName && email && password)) {
|
||||||
|
return res.status(400).json({
|
||||||
|
data: null,
|
||||||
|
errors: [{ message: 'Invalid request' }],
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// TODO: validate the firstname, lastname, password and email
|
||||||
|
// Passwords must be at least 7 characters and contain both alphabetic
|
||||||
|
// and numeric characters.
|
||||||
|
const customer = {
|
||||||
|
type: 'customer',
|
||||||
|
name: firstName + lastName,
|
||||||
|
email: email,
|
||||||
|
password: password
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
let customerAPI = await Moltin.Customers.Create(customer)
|
||||||
|
return res.status(200).json(customerAPI);
|
||||||
|
} catch (error) {
|
||||||
|
let errorData = error.errors[0];
|
||||||
|
// Check if the email and password didn't match an existing account
|
||||||
|
if (errorData.status == 409) {
|
||||||
|
return res.status(401).json({
|
||||||
|
data: null,
|
||||||
|
errors: [
|
||||||
|
{
|
||||||
|
message:
|
||||||
|
'Account not created. Please try again',
|
||||||
|
code: 'invalid_credentials',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
throw error
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default signup
|
@ -7,8 +7,11 @@ import {
|
|||||||
import createFetcher from './utils/fetch-local'
|
import createFetcher from './utils/fetch-local'
|
||||||
|
|
||||||
import type { LoginAPI } from './endpoints/login'
|
import type { LoginAPI } from './endpoints/login'
|
||||||
|
import type { SignupAPI } from './endpoints/signup'
|
||||||
|
|
||||||
import login from './operations/login'
|
import login from './operations/login'
|
||||||
|
import signup from './operations/signup'
|
||||||
|
|
||||||
import getAllPages from './operations/get-all-pages'
|
import getAllPages from './operations/get-all-pages'
|
||||||
import getPage from './operations/get-page'
|
import getPage from './operations/get-page'
|
||||||
import getSiteInfo from './operations/get-site-info'
|
import getSiteInfo from './operations/get-site-info'
|
||||||
@ -17,6 +20,9 @@ import getAllProductPaths from './operations/get-all-product-paths'
|
|||||||
import getAllProducts from './operations/get-all-products'
|
import getAllProducts from './operations/get-all-products'
|
||||||
import getProduct from './operations/get-product'
|
import getProduct from './operations/get-product'
|
||||||
|
|
||||||
|
import { Login } from '@commerce/types'
|
||||||
|
import { Signup } from '@commerce/types'
|
||||||
|
|
||||||
const API_URL = process.env.NEXT_PUBLIC_ELASTICPATH_BASE
|
const API_URL = process.env.NEXT_PUBLIC_ELASTICPATH_BASE
|
||||||
const STOREID = process.env.NEXT_PUBLIC_ELASTICPATH_STOREID
|
const STOREID = process.env.NEXT_PUBLIC_ELASTICPATH_STOREID
|
||||||
const SECRET = process.env.NEXT_PUBLIC_ELASTICPATH_SECRET
|
const SECRET = process.env.NEXT_PUBLIC_ELASTICPATH_SECRET
|
||||||
@ -45,7 +51,7 @@ const config: any = {
|
|||||||
|
|
||||||
const operations = {
|
const operations = {
|
||||||
login,
|
login,
|
||||||
|
signup,
|
||||||
getAllPages,
|
getAllPages,
|
||||||
getPage,
|
getPage,
|
||||||
getSiteInfo,
|
getSiteInfo,
|
||||||
@ -64,7 +70,7 @@ export const provider = { config, operations }
|
|||||||
export type Provider = typeof provider
|
export type Provider = typeof provider
|
||||||
|
|
||||||
export type APIs =
|
export type APIs =
|
||||||
| LoginAPI
|
| LoginAPI | SignupAPI
|
||||||
|
|
||||||
export type ElasticpathAPI<P extends Provider = Provider> = CommerceAPI<P | any>
|
export type ElasticpathAPI<P extends Provider = Provider> = CommerceAPI<P | any>
|
||||||
|
|
||||||
|
46
framework/elasticpath/api/operations/signup.ts
Normal file
46
framework/elasticpath/api/operations/signup.ts
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
import type { ServerResponse } from 'http'
|
||||||
|
import type {
|
||||||
|
OperationContext,
|
||||||
|
OperationOptions,
|
||||||
|
} from '@commerce/api/operations'
|
||||||
|
import type { SignupOperation } from '../../types/signup'
|
||||||
|
import { Provider, ElasticpathConfig } from '..'
|
||||||
|
|
||||||
|
export default function signupOperation({
|
||||||
|
commerce,
|
||||||
|
}: OperationContext<Provider | any>) {
|
||||||
|
async function signup<T extends SignupOperation>(opts: {
|
||||||
|
variables: T['variables']
|
||||||
|
config?: Partial<ElasticpathConfig>
|
||||||
|
res: ServerResponse
|
||||||
|
}): Promise<T['data']>
|
||||||
|
|
||||||
|
async function signup<T extends SignupOperation>(
|
||||||
|
opts: {
|
||||||
|
variables: T['variables']
|
||||||
|
config?: Partial<ElasticpathConfig>
|
||||||
|
res: ServerResponse
|
||||||
|
} & OperationOptions
|
||||||
|
): Promise<T['data']>
|
||||||
|
|
||||||
|
async function signup<T extends SignupOperation>({
|
||||||
|
variables,
|
||||||
|
res: response,
|
||||||
|
config: cfg,
|
||||||
|
}: {
|
||||||
|
query?: string
|
||||||
|
variables: T['variables']
|
||||||
|
res: ServerResponse
|
||||||
|
config?: Partial<ElasticpathConfig>
|
||||||
|
}): Promise<T['data']> {
|
||||||
|
const config = commerce.getConfig(cfg)
|
||||||
|
|
||||||
|
const { data } = await config.fetch('account', 'signup', [variables])
|
||||||
|
|
||||||
|
return {
|
||||||
|
result: data,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return signup
|
||||||
|
}
|
@ -1,19 +1,45 @@
|
|||||||
import { useCallback } from 'react'
|
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 { CommerceError } from '@commerce/utils/errors'
|
||||||
import useSignup, { UseSignup } from '@commerce/auth/use-signup'
|
import useSignup, { UseSignup } from '@commerce/auth/use-signup'
|
||||||
|
|
||||||
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: '',
|
url: '/api/signup',
|
||||||
|
method: 'POST',
|
||||||
},
|
},
|
||||||
async fetcher() {
|
async fetcher({ input: { firstName, lastName, email, password }, options, fetch }) {
|
||||||
return null
|
console.log("input", firstName)
|
||||||
|
if (!(firstName && lastName && email && password)) {
|
||||||
|
throw new CommerceError({
|
||||||
|
message:
|
||||||
|
'A first name, last name, email and password are required to login',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return fetch({
|
||||||
|
...options,
|
||||||
|
variables: {
|
||||||
|
firstName,
|
||||||
|
lastName,
|
||||||
|
email,
|
||||||
|
password
|
||||||
|
},
|
||||||
|
});
|
||||||
|
},
|
||||||
|
useHook: ({ fetch }) => () => {
|
||||||
|
const { revalidate } = useCustomer()
|
||||||
|
|
||||||
|
return useCallback(
|
||||||
|
async function signup(input) {
|
||||||
|
const data = await fetch({ input })
|
||||||
|
await revalidate()
|
||||||
|
return data
|
||||||
|
},
|
||||||
|
[fetch, revalidate]
|
||||||
|
)
|
||||||
},
|
},
|
||||||
useHook:
|
|
||||||
({ fetch }) =>
|
|
||||||
() =>
|
|
||||||
() => {},
|
|
||||||
}
|
}
|
||||||
|
10
framework/elasticpath/types/signup.ts
Normal file
10
framework/elasticpath/types/signup.ts
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
import * as Core from '@commerce/types/signup'
|
||||||
|
|
||||||
|
export * from '@commerce/types/signup'
|
||||||
|
|
||||||
|
export type SignupOperation = Core.SignupOperation & {
|
||||||
|
variables: {
|
||||||
|
email: string
|
||||||
|
password: string
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user