task: prettier

This commit is contained in:
Zaiste 2021-05-18 14:20:07 +02:00
parent bf68f6aff7
commit 4a652a9b6a
No known key found for this signature in database
GPG Key ID: 15DF7EBC7F2FFE35
56 changed files with 635 additions and 1480 deletions

View File

@ -2,5 +2,13 @@
"semi": false,
"singleQuote": true,
"tabWidth": 2,
"useTabs": false
"useTabs": false,
"overrides": [
{
"files": ["framework/saleor/**/*"],
"options": {
"printWidth": 120
}
}
]
}

View File

@ -127,4 +127,3 @@ a {
opacity: 1;
}
}

View File

@ -1,3 +1,3 @@
.fit {
min-height: calc(100vh - 88px);
}
}

View File

@ -49,13 +49,8 @@ const Layout: FC<Props> = ({
children,
pageProps: { categories = [], ...pageProps },
}) => {
const {
displaySidebar,
displayModal,
closeSidebar,
closeModal,
modalView,
} = useUI()
const { displaySidebar, displayModal, closeSidebar, closeModal, modalView } =
useUI()
const { acceptedCookies, onAcceptCookies } = useAcceptCookies()
const { locale = 'en-US' } = useRouter()

View File

@ -32,7 +32,7 @@ const ProductView: FC<Props> = ({ product }) => {
useEffect(() => {
// Selects the default option
const options = product.variants[0].options || [];
const options = product.variants[0].options || []
options.forEach((v) => {
setChoices((choices) => ({
...choices,
@ -128,7 +128,8 @@ const ProductView: FC<Props> = ({ product }) => {
setChoices((choices) => {
return {
...choices,
[opt.displayName.toLowerCase()]: v.label.toLowerCase(),
[opt.displayName.toLowerCase()]:
v.label.toLowerCase(),
}
})
}}

View File

@ -13,9 +13,8 @@ const Container: FC<Props> = ({ children, className, el = 'div', clean }) => {
'mx-auto max-w-8xl px-6': !clean,
})
let Component: React.ComponentType<
React.HTMLAttributes<HTMLDivElement>
> = el as any
let Component: React.ComponentType<React.HTMLAttributes<HTMLDivElement>> =
el as any
return <Component className={rootClassName}>{children}</Component>
}

View File

@ -157,24 +157,26 @@ export const handler: SWRHook<
const data = cartId ? await fetch(options) : null
return data && normalizeCart(data)
},
useHook: ({ useData }) => (input) => {
const response = useData({
swrOptions: { revalidateOnFocus: false, ...input?.swrOptions },
})
useHook:
({ useData }) =>
(input) => {
const response = useData({
swrOptions: { revalidateOnFocus: false, ...input?.swrOptions },
})
return useMemo(
() =>
Object.create(response, {
isEmpty: {
get() {
return (response.data?.lineItems.length ?? 0) <= 0
return useMemo(
() =>
Object.create(response, {
isEmpty: {
get() {
return (response.data?.lineItems.length ?? 0) <= 0
},
enumerable: true,
},
enumerable: true,
},
}),
[response]
)
},
}),
[response]
)
},
}
```
@ -218,18 +220,20 @@ export const handler: MutationHook<Cart, {}, CartItemBody> = {
return normalizeCart(data)
},
useHook: ({ fetch }) => () => {
const { mutate } = useCart()
useHook:
({ fetch }) =>
() => {
const { mutate } = useCart()
return useCallback(
async function addItem(input) {
const data = await fetch({ input })
await mutate(data, false)
return data
},
[fetch, mutate]
)
},
return useCallback(
async function addItem(input) {
const data = await fetch({ input })
await mutate(data, false)
return data
},
[fetch, mutate]
)
},
}
```

View File

@ -11,18 +11,16 @@ type InferValue<Prop extends PropertyKey, Desc> = Desc extends {
? Record<Prop, T>
: never
type DefineProperty<
Prop extends PropertyKey,
Desc extends PropertyDescriptor
> = Desc extends { writable: any; set(val: any): any }
? never
: Desc extends { writable: any; get(): any }
? never
: Desc extends { writable: false }
? Readonly<InferValue<Prop, Desc>>
: Desc extends { writable: true }
? InferValue<Prop, Desc>
: Readonly<InferValue<Prop, Desc>>
type DefineProperty<Prop extends PropertyKey, Desc extends PropertyDescriptor> =
Desc extends { writable: any; set(val: any): any }
? never
: Desc extends { writable: any; get(): any }
? never
: Desc extends { writable: false }
? Readonly<InferValue<Prop, Desc>>
: Desc extends { writable: true }
? InferValue<Prop, Desc>
: Readonly<InferValue<Prop, Desc>>
export default function defineProperty<
Obj extends object,

View File

@ -39,10 +39,10 @@ const config = new Config({
locale: 'en-US',
commerceUrl: Const.API_URL,
apiToken: Const.SALEOR_TOKEN,
cartCookie: Const.CHECKOUT_ID_COOKIE,
cartCookie: Const.CHECKOUT_ID_COOKIE,
cartCookieMaxAge: 60 * 60 * 24 * 30,
fetch: fetchGraphqlApi,
customerCookie: "",
customerCookie: '',
storeChannel: Const.API_CHANNEL,
})

View File

@ -1,11 +1,7 @@
import type { NextApiHandler, NextApiRequest, NextApiResponse } from 'next'
import { SaleorConfig, getConfig } from '..'
export type SaleorApiHandler<
T = any,
H extends SaleorHandlers = {},
Options extends {} = {}
> = (
export type SaleorApiHandler<T = any, H extends SaleorHandlers = {}, Options extends {} = {}> = (
req: NextApiRequest,
res: NextApiResponse<SaleorApiResponse<T>>,
config: SaleorConfig,
@ -30,11 +26,7 @@ export type SaleorApiResponse<T> = {
errors?: { message: string; code?: string }[]
}
export default function createApiHandler<
T = any,
H extends SaleorHandlers = {},
Options extends {} = {}
>(
export default function createApiHandler<T = any, H extends SaleorHandlers = {}, Options extends {} = {}>(
handler: SaleorApiHandler<T, H, Options>,
handlers: H,
defaultOptions: Options

View File

@ -6,14 +6,10 @@ import { getError } from '../../utils/handle-fetch-response'
import { getConfig } from '..'
import { getToken } from '@framework/utils'
const fetchGraphqlApi: GraphQLFetcher = async (
query: string,
{ variables } = {},
fetchOptions
) => {
const fetchGraphqlApi: GraphQLFetcher = async (query: string, { variables } = {}, fetchOptions) => {
// FIXME @zaiste follow the bigcommerce example
const config = getConfig()
const token = getToken();
const token = getToken()
const res = await fetch(API_URL || '', {
...fetchOptions,

View File

@ -1,13 +1,7 @@
import type { NextApiRequest, NextApiResponse } from 'next'
export default function isAllowedMethod(
req: NextApiRequest,
res: NextApiResponse,
allowedMethods: string[]
) {
const methods = allowedMethods.includes('OPTIONS')
? allowedMethods
: [...allowedMethods, 'OPTIONS']
export default function isAllowedMethod(req: NextApiRequest, res: NextApiResponse, allowedMethods: string[]) {
const methods = allowedMethods.includes('OPTIONS') ? allowedMethods : [...allowedMethods, 'OPTIONS']
if (!req.method || !methods.includes(req.method)) {
res.status(405)

View File

@ -4,10 +4,7 @@ import type { MutationHook } from '@commerce/utils/types'
import { CommerceError } from '@commerce/utils/errors'
import useCustomer from '../customer/use-customer'
import * as mutation from '../utils/mutations'
import {
Mutation,
MutationTokenCreateArgs,
} from '../schema'
import { Mutation, MutationTokenCreateArgs } from '../schema'
import useLogin, { UseLogin } from '@commerce/auth/use-login'
import { setCSRFToken, setToken, throwUserErrors, checkoutAttach, getCheckoutId } from '../utils'
@ -20,48 +17,46 @@ export const handler: MutationHook<null, {}, MutationTokenCreateArgs> = {
async fetcher({ input: { email, password }, options, fetch }) {
if (!(email && password)) {
throw new CommerceError({
message:
'A first name, last name, email and password are required to login',
message: 'A first name, last name, email and password are required to login',
})
}
const { tokenCreate } = await fetch<
Mutation,
MutationTokenCreateArgs
>({
const { tokenCreate } = await fetch<Mutation, MutationTokenCreateArgs>({
...options,
variables: { email, password },
})
throwUserErrors(tokenCreate?.errors)
const { token, csrfToken } = tokenCreate!;
const { token, csrfToken } = tokenCreate!
if (token && csrfToken) {
setToken(token)
setCSRFToken(csrfToken)
const { checkoutId } = getCheckoutId();
checkoutAttach(fetch, {
const { checkoutId } = getCheckoutId()
checkoutAttach(fetch, {
variables: { checkoutId },
headers: {
Authorization: `JWT ${token}`
}
Authorization: `JWT ${token}`,
},
})
}
return null
},
useHook: ({ fetch }) => () => {
const { revalidate } = useCustomer()
useHook:
({ fetch }) =>
() => {
const { revalidate } = useCustomer()
return useCallback(
async function login(input) {
const data = await fetch({ input })
await revalidate()
return data
},
[fetch, revalidate]
)
},
return useCallback(
async function login(input) {
const data = await fetch({ input })
await revalidate()
return data
},
[fetch, revalidate]
)
},
}

View File

@ -9,7 +9,7 @@ export default useLogout as UseLogout<typeof handler>
export const handler: MutationHook<null> = {
fetchOptions: {
query: mutation.SessionDestroy,
query: mutation.SessionDestroy,
},
async fetcher({ options, fetch }) {
await fetch({
@ -23,16 +23,18 @@ export const handler: MutationHook<null> = {
return null
},
useHook: ({ fetch }) => () => {
const { mutate } = useCustomer()
useHook:
({ fetch }) =>
() => {
const { mutate } = useCustomer()
return useCallback(
async function logout() {
const data = await fetch()
await mutate(null, false)
return data
},
[fetch, mutate]
)
},
return useCallback(
async function logout() {
const data = await fetch()
await mutate(null, false)
return data
},
[fetch, mutate]
)
},
}

View File

@ -3,42 +3,25 @@ import type { MutationHook } from '@commerce/utils/types'
import { CommerceError } from '@commerce/utils/errors'
import useSignup, { UseSignup } from '@commerce/auth/use-signup'
import useCustomer from '../customer/use-customer'
import {
AccountRegisterInput,
Mutation,
MutationAccountRegisterArgs
} from '../schema'
import { AccountRegisterInput, Mutation, MutationAccountRegisterArgs } from '../schema'
import * as mutation from '../utils/mutations'
import { handleAutomaticLogin, throwUserErrors } from '../utils'
export default useSignup as UseSignup<typeof handler>
export const handler: MutationHook<
null,
{},
AccountRegisterInput,
AccountRegisterInput
> = {
export const handler: MutationHook<null, {}, AccountRegisterInput, AccountRegisterInput> = {
fetchOptions: {
query: mutation.AccountCreate
query: mutation.AccountCreate,
},
async fetcher({
input: { email, password },
options,
fetch,
}) {
async fetcher({ input: { email, password }, options, fetch }) {
if (!(email && password)) {
throw new CommerceError({
message:
'A first name, last name, email and password are required to signup',
message: 'A first name, last name, email and password are required to signup',
})
}
const { customerCreate } = await fetch<
Mutation,
MutationAccountRegisterArgs
>({
const { customerCreate } = await fetch<Mutation, MutationAccountRegisterArgs>({
...options,
variables: {
input: {
@ -53,16 +36,18 @@ export const handler: MutationHook<
return null
},
useHook: ({ fetch }) => () => {
const { revalidate } = useCustomer()
useHook:
({ fetch }) =>
() => {
const { revalidate } = useCustomer()
return useCallback(
async function signup(input) {
const data = await fetch({ input })
await revalidate()
return data
},
[fetch, revalidate]
)
},
return useCallback(
async function signup(input) {
const data = await fetch({ input })
await revalidate()
return data
},
[fetch, revalidate]
)
},
}

View File

@ -6,10 +6,7 @@ import useCart from './use-cart'
import * as mutation from '../utils/mutations'
import {
getCheckoutId,
checkoutToCart,
} from '../utils'
import { getCheckoutId, checkoutToCart } from '../utils'
import { Cart, CartItemBody } from '../types'
import { Mutation, MutationCheckoutLinesAddArgs } from '../schema'
@ -19,19 +16,13 @@ export default useAddItem as UseAddItem<typeof handler>
export const handler: MutationHook<Cart, {}, CartItemBody> = {
fetchOptions: { query: mutation.CheckoutLineAdd },
async fetcher({ input: item, options, fetch }) {
if (
item.quantity &&
(!Number.isInteger(item.quantity) || item.quantity! < 1)
) {
if (item.quantity && (!Number.isInteger(item.quantity) || item.quantity! < 1)) {
throw new CommerceError({
message: 'The item quantity has to be a valid integer greater than 0',
})
}
const { checkoutLinesAdd } = await fetch<
Mutation,
MutationCheckoutLinesAddArgs
>({
const { checkoutLinesAdd } = await fetch<Mutation, MutationCheckoutLinesAddArgs>({
...options,
variables: {
checkoutId: getCheckoutId().checkoutId,
@ -46,16 +37,18 @@ export const handler: MutationHook<Cart, {}, CartItemBody> = {
return checkoutToCart(checkoutLinesAdd)
},
useHook: ({ fetch }) => () => {
const { mutate } = useCart()
useHook:
({ fetch }) =>
() => {
const { mutate } = useCart()
return useCallback(
async function addItem(input) {
const data = await fetch({ input })
await mutate(data, false)
return data
},
[fetch, mutate]
)
},
return useCallback(
async function addItem(input) {
const data = await fetch({ input })
await mutate(data, false)
return data
},
[fetch, mutate]
)
},
}

View File

@ -1,8 +1,5 @@
import { useMemo } from 'react'
import useCommerceCart, {
FetchCartInput,
UseCart,
} from '@commerce/cart/use-cart'
import useCommerceCart, { FetchCartInput, UseCart } from '@commerce/cart/use-cart'
import { Cart } from '../types'
import { SWRHook } from '@commerce/utils/types'
@ -11,12 +8,7 @@ import * as query from '../utils/queries'
export default useCommerceCart as UseCart<typeof handler>
export const handler: SWRHook<
Cart | null,
{},
FetchCartInput,
{ isEmpty?: boolean }
> = {
export const handler: SWRHook<Cart | null, {}, FetchCartInput, { isEmpty?: boolean }> = {
fetchOptions: {
query: query.CheckoutOne,
},
@ -24,36 +16,38 @@ export const handler: SWRHook<
let checkout
if (checkoutId) {
const checkoutId = getCheckoutId().checkoutToken;
const checkoutId = getCheckoutId().checkoutToken
const data = await fetch({
...options,
variables: { checkoutId },
})
checkout = data;
checkout = data
}
if (checkout?.completedAt || !checkoutId) {
checkout = await checkoutCreate(fetch)
}
return checkoutToCart(checkout);
return checkoutToCart(checkout)
},
useHook: ({ useData }) => (input) => {
const response = useData({
swrOptions: { revalidateOnFocus: false, ...input?.swrOptions },
})
return useMemo(
() =>
Object.create(response, {
isEmpty: {
get() {
return (response.data?.lineItems.length ?? 0) <= 0
useHook:
({ useData }) =>
(input) => {
const response = useData({
swrOptions: { revalidateOnFocus: false, ...input?.swrOptions },
})
return useMemo(
() =>
Object.create(response, {
isEmpty: {
get() {
return (response.data?.lineItems.length ?? 0) <= 0
},
enumerable: true,
},
enumerable: true,
},
}),
[response]
)
},
}),
[response]
)
},
}

View File

@ -1,20 +1,11 @@
import { useCallback } from 'react'
import type {
MutationHookContext,
HookFetcherContext,
} from '@commerce/utils/types'
import type { MutationHookContext, HookFetcherContext } from '@commerce/utils/types'
import { RemoveCartItemBody } from '@commerce/types'
import { ValidationError } from '@commerce/utils/errors'
import useRemoveItem, {
RemoveItemInput as RemoveItemInputBase,
UseRemoveItem,
} from '@commerce/cart/use-remove-item'
import useRemoveItem, { RemoveItemInput as RemoveItemInputBase, UseRemoveItem } from '@commerce/cart/use-remove-item'
import useCart from './use-cart'
import * as mutation from '../utils/mutations'
import {
getCheckoutId,
checkoutToCart,
} from '../utils'
import { getCheckoutId, checkoutToCart } from '../utils'
import { Cart, LineItem } from '../types'
import { Mutation, MutationCheckoutLineDeleteArgs } from '../schema'
@ -22,51 +13,41 @@ export type RemoveItemFn<T = any> = T extends LineItem
? (input?: RemoveItemInput<T>) => Promise<Cart | null>
: (input: RemoveItemInput<T>) => Promise<Cart | null>
export type RemoveItemInput<T = any> = T extends LineItem
? Partial<RemoveItemInputBase>
: RemoveItemInputBase
export type RemoveItemInput<T = any> = T extends LineItem ? Partial<RemoveItemInputBase> : RemoveItemInputBase
export default useRemoveItem as UseRemoveItem<typeof handler>
export const handler = {
fetchOptions: { query: mutation.CheckoutLineDelete },
async fetcher({
input: { itemId },
options,
fetch,
}: HookFetcherContext<RemoveCartItemBody>) {
async fetcher({ input: { itemId }, options, fetch }: HookFetcherContext<RemoveCartItemBody>) {
const data = await fetch<Mutation, MutationCheckoutLineDeleteArgs>({
...options,
variables: {
checkoutId: getCheckoutId().checkoutId,
lineId: itemId
variables: {
checkoutId: getCheckoutId().checkoutId,
lineId: itemId,
},
})
return checkoutToCart(data.checkoutLinesUpdate)
},
useHook: ({
fetch,
}: MutationHookContext<Cart | null, RemoveCartItemBody>) => <
T extends LineItem | undefined = undefined
>(
ctx: { item?: T } = {}
) => {
const { item } = ctx
const { mutate } = useCart()
const removeItem: RemoveItemFn<LineItem> = async (input) => {
const itemId = input?.id ?? item?.id
useHook:
({ fetch }: MutationHookContext<Cart | null, RemoveCartItemBody>) =>
<T extends LineItem | undefined = undefined>(ctx: { item?: T } = {}) => {
const { item } = ctx
const { mutate } = useCart()
const removeItem: RemoveItemFn<LineItem> = async (input) => {
const itemId = input?.id ?? item?.id
if (!itemId) {
throw new ValidationError({
message: 'Invalid input used for this operation',
})
if (!itemId) {
throw new ValidationError({
message: 'Invalid input used for this operation',
})
}
const data = await fetch({ input: { itemId } })
await mutate(data, false)
return data
}
const data = await fetch({ input: { itemId } })
await mutate(data, false)
return data
}
return useCallback(removeItem as RemoveItemFn<T>, [fetch, mutate])
},
return useCallback(removeItem as RemoveItemFn<T>, [fetch, mutate])
},
}

View File

@ -1,14 +1,8 @@
import { useCallback } from 'react'
import debounce from 'lodash.debounce'
import type {
HookFetcherContext,
MutationHookContext,
} from '@commerce/utils/types'
import type { HookFetcherContext, MutationHookContext } from '@commerce/utils/types'
import { ValidationError } from '@commerce/utils/errors'
import useUpdateItem, {
UpdateItemInput as UpdateItemInputBase,
UseUpdateItem,
} from '@commerce/cart/use-update-item'
import useUpdateItem, { UpdateItemInput as UpdateItemInputBase, UseUpdateItem } from '@commerce/cart/use-update-item'
import useCart from './use-cart'
import { handler as removeItemHandler } from './use-remove-item'
@ -27,11 +21,7 @@ export default useUpdateItem as UseUpdateItem<typeof handler>
export const handler = {
fetchOptions: { query: mutation.CheckoutLineUpdate },
async fetcher({
input: { itemId, item },
options,
fetch,
}: HookFetcherContext<UpdateCartItemBody>) {
async fetcher({ input: { itemId, item }, options, fetch }: HookFetcherContext<UpdateCartItemBody>) {
if (Number.isInteger(item.quantity)) {
// Also allow the update hook to remove an item if the quantity is lower than 1
if (item.quantity! < 1) {
@ -47,11 +37,8 @@ export const handler = {
})
}
const checkoutId = getCheckoutId().checkoutId;
const { checkoutLinesUpdate } = await fetch<
Mutation,
MutationCheckoutLinesUpdateArgs
>({
const checkoutId = getCheckoutId().checkoutId
const { checkoutLinesUpdate } = await fetch<Mutation, MutationCheckoutLinesUpdateArgs>({
...options,
variables: {
checkoutId,
@ -66,44 +53,42 @@ export const handler = {
return checkoutToCart(checkoutLinesUpdate)
},
useHook: ({
fetch,
}: MutationHookContext<Cart | null, UpdateCartItemBody>) => <
T extends LineItem | undefined = undefined
>(
ctx: {
item?: T
wait?: number
} = {}
) => {
const { item } = ctx
const { mutate } = useCart() as any
useHook:
({ fetch }: MutationHookContext<Cart | null, UpdateCartItemBody>) =>
<T extends LineItem | undefined = undefined>(
ctx: {
item?: T
wait?: number
} = {}
) => {
const { item } = ctx
const { mutate } = useCart() as any
return useCallback(
debounce(async (input: UpdateItemInput<T>) => {
const itemId = input.id ?? item?.id
const productId = input.productId ?? item?.productId
const variantId = input.productId ?? item?.variantId
if (!itemId || !productId || !variantId) {
throw new ValidationError({
message: 'Invalid input used for this operation',
})
}
return useCallback(
debounce(async (input: UpdateItemInput<T>) => {
const itemId = input.id ?? item?.id
const productId = input.productId ?? item?.productId
const variantId = input.productId ?? item?.variantId
if (!itemId || !productId || !variantId) {
throw new ValidationError({
message: 'Invalid input used for this operation',
})
}
const data = await fetch({
input: {
item: {
productId,
variantId,
quantity: input.quantity,
const data = await fetch({
input: {
item: {
productId,
variantId,
quantity: input.quantity,
},
itemId,
},
itemId,
},
})
await mutate(data, false)
return data
}, ctx.wait ?? 500),
[fetch, mutate]
)
},
})
await mutate(data, false)
return data
}, ctx.wait ?? 500),
[fetch, mutate]
)
},
}

View File

@ -28,13 +28,11 @@ const getAllPages = async (options?: {
const { locale } = config
const { data } = await config.fetch(query.PageMany, { variables })
const pages = data.pages?.edges?.map(
({ node: { title: name, slug, ...node } }: PageCountableEdge) => ({
...node,
url: `/${locale}/${slug}`,
name,
})
)
const pages = data.pages?.edges?.map(({ node: { title: name, slug, ...node } }: PageCountableEdge) => ({
...node,
url: `/${locale}/${slug}`,
name,
}))
return { pages }
}

View File

@ -3,5 +3,3 @@ export const API_CHANNEL = process.env.NEXT_PUBLIC_SALEOR_CHANNEL
export const CHECKOUT_ID_COOKIE = 'saleor.CheckoutID'
export const SALEOR_TOKEN = 'saleor.Token'
export const SALEOR_CRSF_TOKEN = 'saleor.CSRFToken'

View File

@ -13,8 +13,7 @@ async function getCustomerId({
const { data } = await config.fetch(query.CustomerOne, {
variables: {
customerAccesToken:
customerAccesToken || Cookies.get(config.customerCookie),
customerAccesToken: customerAccesToken || Cookies.get(config.customerCookie),
},
})

View File

@ -17,12 +17,14 @@ export const handler: SWRHook<Customer | null> = {
})
return data.me ?? null
},
useHook: ({ useData }) => (input) => {
return useData({
swrOptions: {
revalidateOnFocus: false,
...input?.swrOptions,
},
})
},
useHook:
({ useData }) =>
(input) => {
return useData({
swrOptions: {
revalidateOnFocus: false,
...input?.swrOptions,
},
})
},
}

View File

@ -2,13 +2,8 @@ import { Fetcher } from '@commerce/utils/types'
import { API_URL } from './const'
import { getToken, handleFetchResponse } from './utils'
const fetcher: Fetcher = async ({
url = API_URL,
method = 'POST',
variables,
query,
}) => {
const token = getToken();
const fetcher: Fetcher = async ({ url = API_URL, method = 'POST', variables, query }) => {
const token = getToken()
return handleFetchResponse(
await fetch(url!, {

View File

@ -1,21 +1,17 @@
import * as React from 'react'
import { ReactNode } from 'react'
import {
CommerceConfig,
CommerceProvider as CoreCommerceProvider,
useCommerce as useCoreCommerce,
} from '@commerce'
import { CommerceConfig, CommerceProvider as CoreCommerceProvider, useCommerce as useCoreCommerce } from '@commerce'
import { saleorProvider, SaleorProvider } from './provider'
import * as Const from './const';
import * as Const from './const'
export { saleorProvider }
export type { SaleorProvider }
export const saleorConfig: CommerceConfig = {
locale: 'en-us',
cartCookie: Const.CHECKOUT_ID_COOKIE
cartCookie: Const.CHECKOUT_ID_COOKIE,
}
export type SaleorConfig = Partial<CommerceConfig>
@ -27,10 +23,7 @@ export type SaleorProps = {
export function CommerceProvider({ children, ...config }: SaleorProps) {
return (
<CoreCommerceProvider
provider={saleorProvider}
config={{ ...saleorConfig, ...config }}
>
<CoreCommerceProvider provider={saleorProvider} config={{ ...saleorConfig, ...config }}>
{children}
</CoreCommerceProvider>
)

View File

@ -2,24 +2,18 @@ import { CollectionCountableEdge } from '../schema'
import { getConfig, SaleorConfig } from '../api'
import * as query from '../utils/queries'
const getAllCollections = async (options?: {
variables?: any
config: SaleorConfig
preview?: boolean
}) => {
const getAllCollections = async (options?: { variables?: any; config: SaleorConfig; preview?: boolean }) => {
let { config, variables = { first: 100 } } = options ?? {}
config = getConfig(config)
const { data } = await config.fetch(query.CollectionMany, { variables })
const edges = data.collections?.edges ?? []
const categories = edges.map(
({ node: { id: entityId, name, slug } }: CollectionCountableEdge) => ({
entityId,
name,
path: `/${slug}`,
})
)
const categories = edges.map(({ node: { id: entityId, name, slug } }: CollectionCountableEdge) => ({
entityId,
name,
path: `/${slug}`,
}))
return {
categories,

View File

@ -24,12 +24,11 @@ const getAllProducts = async (options: {
let { config, variables = { first: 100 } } = options ?? {}
config = getConfig(config)
const { data }: GraphQLFetcherResult = await config.fetch(query.ProductMany, { variables })
const { data }: GraphQLFetcherResult = await config.fetch(query.ProductMany, {
variables,
})
const products =
data.products?.edges?.map(({ node: p }: ProductCountableEdge) =>
normalizeProduct(p)
) ?? []
const products = data.products?.edges?.map(({ node: p }: ProductCountableEdge) => normalizeProduct(p)) ?? []
return {
products,

View File

@ -1,7 +1,7 @@
import { GraphQLFetcherResult } from '@commerce/api'
import { getConfig, SaleorConfig } from '../api'
import { normalizeProduct } from '../utils'
import * as query from '../utils/queries';
import * as query from '../utils/queries'
type Variables = {
slug: string

View File

@ -3,10 +3,7 @@ import { Product } from '@commerce/types'
import useSearch, { UseSearch } from '@commerce/product/use-search'
import { ProductCountableEdge } from '../schema'
import {
getSearchVariables,
normalizeProduct,
} from '../utils'
import { getSearchVariables, normalizeProduct } from '../utils'
import * as query from '../utils/queries'
@ -24,13 +21,9 @@ export type SearchProductsData = {
found: boolean
}
export const handler: SWRHook<
SearchProductsData,
SearchProductsInput,
SearchProductsInput
> = {
export const handler: SWRHook<SearchProductsData, SearchProductsInput, SearchProductsInput> = {
fetchOptions: {
query: query.ProductMany
query: query.ProductMany,
},
async fetcher({ input, options, fetch }) {
const { categoryId, brandId } = input
@ -57,24 +50,24 @@ export const handler: SWRHook<
}
return {
products: edges.map(({ node }: ProductCountableEdge) =>
normalizeProduct(node)
),
products: edges.map(({ node }: ProductCountableEdge) => normalizeProduct(node)),
found: !!edges.length,
}
},
useHook: ({ useData }) => (input = {}) => {
return useData({
input: [
['search', input.search],
['categoryId', input.categoryId],
['brandId', input.brandId],
['sort', input.sort],
],
swrOptions: {
revalidateOnFocus: false,
...input.swrOptions,
},
})
},
useHook:
({ useData }) =>
(input = {}) => {
return useData({
input: [
['search', input.search],
['categoryId', input.categoryId],
['brandId', input.brandId],
['sort', input.sort],
],
swrOptions: {
revalidateOnFocus: false,
...input.swrOptions,
},
})
},
}

View File

@ -14,8 +14,8 @@ import fetcher from './fetcher'
export const saleorProvider = {
locale: 'en-us',
cartCookie: "",
cartCookieToken: "",
cartCookie: '',
cartCookieToken: '',
fetcher,
cart: { useCart, useAddItem, useUpdateItem, useRemoveItem },
customer: { useCustomer },

View File

@ -2,10 +2,8 @@ export type Maybe<T> = T | null
export type Exact<T extends { [key: string]: unknown }> = {
[K in keyof T]: T[K]
}
export type MakeOptional<T, K extends keyof T> = Omit<T, K> &
{ [SubKey in K]?: Maybe<T[SubKey]> }
export type MakeMaybe<T, K extends keyof T> = Omit<T, K> &
{ [SubKey in K]: Maybe<T[SubKey]> }
export type MakeOptional<T, K extends keyof T> = Omit<T, K> & { [SubKey in K]?: Maybe<T[SubKey]> }
export type MakeMaybe<T, K extends keyof T> = Omit<T, K> & { [SubKey in K]: Maybe<T[SubKey]> }
/** All built-in and custom scalars, mapped to their actual values */
export type Scalars = {
ID: string
@ -11442,15 +11440,11 @@ export type GetAllProductPathsQueryVariables = Exact<{
export type GetAllProductPathsQuery = { __typename?: 'Query' } & {
products?: Maybe<
{ __typename?: 'ProductCountableConnection' } & {
pageInfo: { __typename?: 'PageInfo' } & Pick<
PageInfo,
'hasNextPage' | 'hasPreviousPage'
>
pageInfo: { __typename?: 'PageInfo' } & Pick<PageInfo, 'hasNextPage' | 'hasPreviousPage'>
edges: Array<
{ __typename?: 'ProductCountableEdge' } & Pick<
ProductCountableEdge,
'cursor'
> & { node: { __typename?: 'Product' } & Pick<Product, 'slug'> }
{ __typename?: 'ProductCountableEdge' } & Pick<ProductCountableEdge, 'cursor'> & {
node: { __typename?: 'Product' } & Pick<Product, 'slug'>
}
>
}
>
@ -11459,16 +11453,10 @@ export type GetAllProductPathsQuery = { __typename?: 'Query' } & {
export type ProductConnectionFragment = {
__typename?: 'ProductCountableConnection'
} & {
pageInfo: { __typename?: 'PageInfo' } & Pick<
PageInfo,
'hasNextPage' | 'hasPreviousPage'
>
pageInfo: { __typename?: 'PageInfo' } & Pick<PageInfo, 'hasNextPage' | 'hasPreviousPage'>
edges: Array<
{ __typename?: 'ProductCountableEdge' } & {
node: { __typename?: 'Product' } & Pick<
Product,
'id' | 'name' | 'description' | 'slug'
> & {
node: { __typename?: 'Product' } & Pick<Product, 'id' | 'name' | 'description' | 'slug'> & {
pricing?: Maybe<
{ __typename?: 'ProductPricingInfo' } & {
priceRange?: Maybe<
@ -11482,14 +11470,7 @@ export type ProductConnectionFragment = {
>
}
>
media?: Maybe<
Array<
{ __typename?: 'ProductMedia' } & Pick<
ProductMedia,
'url' | 'alt'
>
>
>
media?: Maybe<Array<{ __typename?: 'ProductMedia' } & Pick<ProductMedia, 'url' | 'alt'>>>
}
}
>
@ -11503,7 +11484,5 @@ export type GetAllProductsQueryVariables = Exact<{
}>
export type GetAllProductsQuery = { __typename?: 'Query' } & {
products?: Maybe<
{ __typename?: 'ProductCountableConnection' } & ProductConnectionFragment
>
products?: Maybe<{ __typename?: 'ProductCountableConnection' } & ProductConnectionFragment>
}

File diff suppressed because it is too large Load Diff

View File

@ -1,16 +1,12 @@
import * as mutation from './mutations'
import { CheckoutCustomerAttach } from '../schema'
export const checkoutAttach = async (
fetch: any,
{ variables, headers }: any,
): Promise<CheckoutCustomerAttach> => {
const data = await fetch({
export const checkoutAttach = async (fetch: any, { variables, headers }: any): Promise<CheckoutCustomerAttach> => {
const data = await fetch({
query: mutation.CheckoutAttach,
variables,
headers
variables,
headers,
})
return data;
return data
}

View File

@ -4,15 +4,13 @@ import * as mutation from './mutations'
import { CheckoutCreate } from '../schema'
import { CHECKOUT_ID_COOKIE } from '@framework/const'
export const checkoutCreate = async (
fetch: any
): Promise<CheckoutCreate> => {
export const checkoutCreate = async (fetch: any): Promise<CheckoutCreate> => {
const data = await fetch({ query: mutation.CheckoutCreate })
const checkout = data.checkoutCreate?.checkout
const checkoutId = checkout?.id
const checkoutToken = checkout?.token
const checkoutToken = checkout?.token
const value = `${checkoutId}:${checkoutToken}`;
const value = `${checkoutId}:${checkoutToken}`
if (checkoutId) {
const options = {

View File

@ -1,14 +1,7 @@
import { Cart } from '../types'
import { CommerceError } from '@commerce/utils/errors'
import {
CheckoutLinesAdd,
CheckoutLinesUpdate,
CheckoutCreate,
CheckoutError,
Checkout,
Maybe,
} from '../schema'
import { CheckoutLinesAdd, CheckoutLinesUpdate, CheckoutCreate, CheckoutError, Checkout, Maybe } from '../schema'
import { normalizeCart } from './normalize'
import throwUserErrors from './throw-user-errors'
@ -18,11 +11,7 @@ export type CheckoutQuery = {
errors?: Array<CheckoutError>
}
export type CheckoutPayload =
| CheckoutLinesAdd
| CheckoutLinesUpdate
| CheckoutCreate
| CheckoutQuery
export type CheckoutPayload = CheckoutLinesAdd | CheckoutLinesUpdate | CheckoutCreate | CheckoutQuery
const checkoutToCart = (checkoutPayload?: Maybe<CheckoutPayload>): Cart => {
if (!checkoutPayload) {

View File

@ -1,5 +1,5 @@
import Cookies, { CookieAttributes } from 'js-cookie'
import * as Const from '../const';
import * as Const from '../const'
export const getToken = () => Cookies.get(Const.SALEOR_TOKEN)
export const setToken = (token?: string, options?: CookieAttributes) => {

View File

@ -45,4 +45,4 @@ export const CheckoutDetails = `
}
}
}
`
`

View File

@ -1,2 +1,2 @@
export { ProductConnection } from './product';
export { CheckoutDetails } from './checkout-details';
export { ProductConnection } from './product'
export { CheckoutDetails } from './checkout-details'

View File

@ -1,4 +1,4 @@
export const ProductConnection = /* GraphQL */ `
export const ProductConnection = /* GraphQL */ `
fragment ProductConnection on ProductCountableConnection {
pageInfo {
hasNextPage
@ -26,4 +26,4 @@ export const ProductConnection = /* GraphQL */ `
}
}
}
`
`

View File

@ -1,6 +1,6 @@
import { SaleorConfig } from '../api'
import { CollectionCountableEdge } from '../schema'
import * as query from './queries';
import * as query from './queries'
export type Category = {
entityId: string
@ -16,13 +16,11 @@ const getCategories = async (config: SaleorConfig): Promise<Category[]> => {
})
return (
data.collections?.edges?.map(
({ node: { id: entityId, name, slug } }: CollectionCountableEdge) => ({
entityId,
name,
path: `/${slug}`,
})
) ?? []
data.collections?.edges?.map(({ node: { id: entityId, name, slug } }: CollectionCountableEdge) => ({
entityId,
name,
path: `/${slug}`,
})) ?? []
)
}

View File

@ -2,7 +2,7 @@ import Cookies from 'js-cookie'
import { CHECKOUT_ID_COOKIE } from '../const'
const getCheckoutId = (id?: string) => {
const r = Cookies.get(CHECKOUT_ID_COOKIE)?.split(":") || [];
const r = Cookies.get(CHECKOUT_ID_COOKIE)?.split(':') || []
return { checkoutId: r[0], checkoutToken: r[1] }
}

View File

@ -1,17 +1,17 @@
import { getSortVariables } from './get-sort-variables'
import type { SearchProductsInput } from '../product/use-search'
export const getSearchVariables = ({
brandId,
search,
categoryId,
sort,
}: SearchProductsInput) => {
const sortBy = { field: "NAME", direction: 'ASC', ...getSortVariables(sort, !!categoryId), channel: "default-channel"};
export const getSearchVariables = ({ brandId, search, categoryId, sort }: SearchProductsInput) => {
const sortBy = {
field: 'NAME',
direction: 'ASC',
...getSortVariables(sort, !!categoryId),
channel: 'default-channel',
}
return {
categoryId,
filter: { search },
sortBy
sortBy,
}
}

View File

@ -4,7 +4,7 @@ export const getSortVariables = (sort?: string, isCategory: boolean = false) =>
case 'price-asc':
output = {
field: 'PRICE',
direction: 'ASC'
direction: 'ASC',
}
break
case 'price-desc':
@ -22,10 +22,9 @@ export const getSortVariables = (sort?: string, isCategory: boolean = false) =>
case 'latest-desc':
output = {
field: 'DATE',
direction: 'DESC'
direction: 'DESC',
}
break
}
return output
}

View File

@ -14,18 +14,15 @@ const handleLogin = (data: CreateToken) => {
setCSRFToken(token)
}
return token
return token
}
export const handleAutomaticLogin = async (
fetch: <T = any, B = Body>(options: FetcherOptions<B>) => Promise<T>,
input: MutationTokenCreateArgs
input: MutationTokenCreateArgs
) => {
try {
const { tokenCreate } = await fetch<
Mutation,
MutationTokenCreateArgs
>({
const { tokenCreate } = await fetch<Mutation, MutationTokenCreateArgs>({
query: mutation.SessionCreate,
variables: { ...input },
})

View File

@ -7,7 +7,7 @@ export { default as getCategories } from './get-categories'
export { default as getCheckoutId } from './get-checkout-id'
export { default as checkoutCreate } from './checkout-create'
export { checkoutAttach } from './checkout-attach';
export { checkoutAttach } from './checkout-attach'
export { default as checkoutToCart } from './checkout-to-cart'
export { default as handleLogin, handleAutomaticLogin } from './handle-login'

View File

@ -1,4 +1,4 @@
import * as fragment from '../fragments';
import * as fragment from '../fragments'
export const CheckoutLineUpdate = /* GraphQL */ `
mutation CheckoutLineUpdate($checkoutId: ID!, $lineItems: [CheckoutLineInput!]!) {

View File

@ -1,12 +1,6 @@
import { Product } from '@commerce/types'
import {
Product as SaleorProduct,
Checkout,
CheckoutLine,
Money,
ProductVariant,
} from '../schema'
import { Product as SaleorProduct, Checkout, CheckoutLine, Money, ProductVariant } from '../schema'
import type { Cart, LineItem } from '../types'
@ -25,9 +19,7 @@ const normalizeProductOptions = (options: ProductVariant[]) => {
?.map((option) => option?.attributes)
.flat(1)
.reduce<any>((acc, x) => {
if (
acc.find(({ displayName }: any) => displayName === x.attribute.name)
) {
if (acc.find(({ displayName }: any) => displayName === x.attribute.name)) {
return acc.map((opt: any) => {
return opt.displayName === x.attribute.name
? {
@ -72,36 +64,20 @@ const normalizeProductVariants = (variants: ProductVariant[]) => {
}
export function normalizeProduct(productNode: SaleorProduct): Product {
const {
id,
name,
media,
variants,
description,
slug,
pricing,
...rest
} = productNode
const { id, name, media, variants, description, slug, pricing, ...rest } = productNode
const product = {
id,
name,
vendor: '',
description: description
? JSON.parse(description)?.blocks[0]?.data.text
: '',
description: description ? JSON.parse(description)?.blocks[0]?.data.text : '',
path: `/${slug}`,
slug: slug?.replace(/^\/+|\/+$/g, ''),
price:
(pricing?.priceRange?.start?.net &&
money(pricing.priceRange.start.net)) ||
0,
price: (pricing?.priceRange?.start?.net && money(pricing.priceRange.start.net)) || 0,
// TODO: Check nextjs-commerce bug if no images are added for a product
images: media?.length ? media : [{ url: placeholderImg }],
variants:
variants && variants.length > 0 ? normalizeProductVariants(variants) : [],
options:
variants && variants.length > 0 ? normalizeProductOptions(variants) : [],
variants: variants && variants.length > 0 ? normalizeProductVariants(variants) : [],
options: variants && variants.length > 0 ? normalizeProductOptions(variants) : [],
...rest,
}
@ -109,8 +85,8 @@ export function normalizeProduct(productNode: SaleorProduct): Product {
}
export function normalizeCart(checkout: Checkout): Cart {
const lines = checkout.lines as CheckoutLine[];
const lineItems: LineItem[] = lines.length > 0 ? lines?.map<LineItem>(normalizeLineItem) : [];
const lines = checkout.lines as CheckoutLine[]
const lineItems: LineItem[] = lines.length > 0 ? lines?.map<LineItem>(normalizeLineItem) : []
return {
id: checkout.id,
@ -118,12 +94,12 @@ export function normalizeCart(checkout: Checkout): Cart {
email: '',
createdAt: checkout.created,
currency: {
code: checkout.totalPrice?.currency!
code: checkout.totalPrice?.currency!,
},
taxesIncluded: false,
lineItems,
lineItemsSubtotalPrice: checkout.subtotalPrice?.gross?.amount!,
subtotalPrice: checkout.subtotalPrice?.gross?.amount!,
lineItems,
lineItemsSubtotalPrice: checkout.subtotalPrice?.gross?.amount!,
subtotalPrice: checkout.subtotalPrice?.gross?.amount!,
totalPrice: checkout.totalPrice?.gross.amount!,
discounts: [],
}
@ -145,10 +121,10 @@ function normalizeLineItem({ id, variant, quantity }: CheckoutLine): LineItem {
},
requiresShipping: false,
price: variant?.pricing?.price?.gross.amount!,
listPrice: 0
listPrice: 0,
},
path: String(variant?.product?.slug),
discounts: [],
options: [ ],
options: [],
}
}

View File

@ -1,4 +1,4 @@
import * as fragment from '../fragments';
import * as fragment from '../fragments'
export const CheckoutOne = /* GraphQL */ `
query CheckoutOne($checkoutId: UUID!) {

View File

@ -1,11 +1,7 @@
import * as fragment from '../fragments'
export const CollectionOne = /* GraphQL */ `
query getProductsFromCollection(
$categoryId: ID!
$first: Int = 100
$channel: String = "default-channel"
) {
query getProductsFromCollection($categoryId: ID!, $first: Int = 100, $channel: String = "default-channel") {
collection(id: $categoryId, channel: $channel) {
id
products(first: $first) {

View File

@ -13,4 +13,4 @@ export const getAllProductVendors = /* GraphQL */ `
}
}
}
`
`

View File

@ -1,9 +1,5 @@
export const getAllProductsPathsQuery = /* GraphQL */ `
query getAllProductPaths(
$first: Int = 100
$cursor: String
$channel: String = "default-channel"
) {
query getAllProductPaths($first: Int = 100, $cursor: String, $channel: String = "default-channel") {
products(first: $first, after: $cursor, channel: $channel) {
pageInfo {
hasNextPage

View File

@ -10,4 +10,4 @@ export const PageMany = /* GraphQL */ `
}
}
}
`
`

View File

@ -1,4 +1,4 @@
import * as fragment from '../fragments';
import * as fragment from '../fragments'
export const ProductMany = /* GraphQL */ `
query ProductMany(

View File

@ -41,4 +41,3 @@ export const ProductOneBySlug = /* GraphQL */ `
}
}
`

View File

@ -2,20 +2,16 @@ import { ValidationError } from '@commerce/utils/errors'
import { CheckoutError, CheckoutErrorCode, AppError, AccountError, AccountErrorCode } from '../schema'
export type UserErrors = Array<CheckoutError | AccountError | AppError>
export type UserErrors = Array<CheckoutError | AccountError | AppError>
export type UserErrorCode =
| CheckoutErrorCode
| AccountErrorCode
| null
| undefined
export type UserErrorCode = CheckoutErrorCode | AccountErrorCode | null | undefined
export const throwUserErrors = (errors?: UserErrors) => {
if (errors && errors.length) {
throw new ValidationError({
errors: errors.map(({ code, message }) => ({
code: code ?? 'validation_error',
message: message || "",
message: message || '',
})),
})
}

View File

@ -48,7 +48,10 @@ export async function getStaticProps({
}
}
export default function Search({ categories, brands }: InferGetStaticPropsType<typeof getStaticProps>) {
export default function Search({
categories,
brands,
}: InferGetStaticPropsType<typeof getStaticProps>) {
const [activeFilter, setActiveFilter] = useState('')
const [toggleFilter, setToggleFilter] = useState(false)