mirror of
https://github.com/vercel/commerce.git
synced 2025-06-19 21:51:21 +00:00
saleor: update the provider structure
This commit is contained in:
parent
79e916f6ee
commit
33992283b3
@ -34,8 +34,8 @@ const SignUpView: FC<Props> = () => {
|
||||
setMessage('')
|
||||
await signup({
|
||||
email,
|
||||
// firstName,
|
||||
// lastName,
|
||||
firstName,
|
||||
lastName,
|
||||
password,
|
||||
})
|
||||
setLoading(false)
|
||||
|
@ -120,8 +120,7 @@ const ProductView: FC<Props> = ({ product }) => {
|
||||
<Swatch
|
||||
key={`${opt.id}-${i}`}
|
||||
active={v.label.toLowerCase() === active}
|
||||
// variant={opt.displayName}
|
||||
variant={opt.variant}
|
||||
variant={opt.displayName}
|
||||
color={v.hexColors ? v.hexColors[0] : ''}
|
||||
label={v.label}
|
||||
onClick={() => {
|
||||
|
1
framework/saleor/api/endpoints/cart.ts
Normal file
1
framework/saleor/api/endpoints/cart.ts
Normal file
@ -0,0 +1 @@
|
||||
export default function (_commerce: any) {}
|
1
framework/saleor/api/endpoints/catalog/products.ts
Normal file
1
framework/saleor/api/endpoints/catalog/products.ts
Normal file
@ -0,0 +1 @@
|
||||
export default function (_commerce: any) {}
|
57
framework/saleor/api/endpoints/checkout/index.ts
Normal file
57
framework/saleor/api/endpoints/checkout/index.ts
Normal file
@ -0,0 +1,57 @@
|
||||
import { CommerceAPI, GetAPISchema, createEndpoint } from '@commerce/api'
|
||||
import checkoutEndpoint from '@commerce/api/endpoints/checkout'
|
||||
import { CheckoutSchema } from '@commerce/types/checkout'
|
||||
|
||||
export type CheckoutAPI = GetAPISchema<CommerceAPI, CheckoutSchema>
|
||||
|
||||
export type CheckoutEndpoint = CheckoutAPI['endpoint']
|
||||
|
||||
const checkout: CheckoutEndpoint['handlers']['checkout'] = async ({
|
||||
req,
|
||||
res,
|
||||
config,
|
||||
}) => {
|
||||
try {
|
||||
const html = `
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Checkout</title>
|
||||
</head>
|
||||
<body>
|
||||
<div style='margin: 10rem auto; text-align: center; font-family: SansSerif, "Segoe UI", Helvetica; color: #888;'>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" style='height: 60px; width: 60px;' fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z" />
|
||||
</svg>
|
||||
<h1>Checkout not yet implemented :(</h1>
|
||||
<p>
|
||||
See <a href='https://github.com/vercel/commerce/issues/64' target='_blank'>#64</a>
|
||||
</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
`
|
||||
|
||||
res.status(200)
|
||||
res.setHeader('Content-Type', 'text/html')
|
||||
res.write(html)
|
||||
res.end()
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
|
||||
const message = 'An unexpected error ocurred'
|
||||
|
||||
res.status(500).json({ data: null, errors: [{ message }] })
|
||||
}
|
||||
}
|
||||
|
||||
export const handlers: CheckoutEndpoint['handlers'] = { checkout }
|
||||
|
||||
const checkoutApi = createEndpoint<CheckoutAPI>({
|
||||
handler: checkoutEndpoint,
|
||||
handlers,
|
||||
})
|
||||
|
||||
export default checkoutApi
|
1
framework/saleor/api/endpoints/customer.ts
Normal file
1
framework/saleor/api/endpoints/customer.ts
Normal file
@ -0,0 +1 @@
|
||||
export default function (_commerce: any) {}
|
1
framework/saleor/api/endpoints/login.ts
Normal file
1
framework/saleor/api/endpoints/login.ts
Normal file
@ -0,0 +1 @@
|
||||
export default function (_commerce: any) {}
|
1
framework/saleor/api/endpoints/logout.ts
Normal file
1
framework/saleor/api/endpoints/logout.ts
Normal file
@ -0,0 +1 @@
|
||||
export default function (_commerce: any) {}
|
1
framework/saleor/api/endpoints/signup.ts
Normal file
1
framework/saleor/api/endpoints/signup.ts
Normal file
@ -0,0 +1 @@
|
||||
export default function (_commerce: any) {}
|
1
framework/saleor/api/endpoints/wishlist.ts
Normal file
1
framework/saleor/api/endpoints/wishlist.ts
Normal file
@ -0,0 +1 @@
|
||||
export default function (_commerce: any) {}
|
@ -16,26 +16,7 @@ export interface SaleorConfig extends CommerceAPIConfig {
|
||||
storeChannel: string
|
||||
}
|
||||
|
||||
export class Config {
|
||||
private config: SaleorConfig
|
||||
|
||||
constructor(config: SaleorConfig) {
|
||||
this.config = config
|
||||
}
|
||||
|
||||
getConfig(userConfig: Partial<SaleorConfig> = {}) {
|
||||
return Object.entries(userConfig).reduce<SaleorConfig>(
|
||||
(cfg, [key, value]) => Object.assign(cfg, { [key]: value }),
|
||||
{ ...this.config }
|
||||
)
|
||||
}
|
||||
|
||||
setConfig(newConfig: Partial<SaleorConfig>) {
|
||||
Object.assign(this.config, newConfig)
|
||||
}
|
||||
}
|
||||
|
||||
const config = new Config({
|
||||
const config: SaleorConfig = {
|
||||
locale: 'en-US',
|
||||
commerceUrl: Const.API_URL,
|
||||
apiToken: Const.SALEOR_TOKEN,
|
||||
@ -44,12 +25,25 @@ const config = new Config({
|
||||
fetch: fetchGraphqlApi,
|
||||
customerCookie: '',
|
||||
storeChannel: Const.API_CHANNEL,
|
||||
})
|
||||
|
||||
export function getConfig(userConfig?: Partial<SaleorConfig>) {
|
||||
return config.getConfig(userConfig)
|
||||
}
|
||||
|
||||
export function setConfig(newConfig: Partial<SaleorConfig>) {
|
||||
return config.setConfig(newConfig)
|
||||
import {
|
||||
CommerceAPI,
|
||||
getCommerceApi as commerceApi,
|
||||
} from '@commerce/api'
|
||||
|
||||
import * as operations from './operations'
|
||||
|
||||
export interface ShopifyConfig extends CommerceAPIConfig {}
|
||||
|
||||
export const provider = { config, operations }
|
||||
|
||||
export type Provider = typeof provider
|
||||
|
||||
export type SaleorAPI<P extends Provider = Provider> = CommerceAPI<P>
|
||||
|
||||
export function getCommerceApi<P extends Provider>(
|
||||
customProvider: P = provider as any
|
||||
): SaleorAPI<P> {
|
||||
return commerceApi(customProvider)
|
||||
}
|
||||
|
50
framework/saleor/api/operations/get-all-pages.ts
Normal file
50
framework/saleor/api/operations/get-all-pages.ts
Normal file
@ -0,0 +1,50 @@
|
||||
import type { OperationContext } from '@commerce/api/operations'
|
||||
|
||||
import { QueryPagesArgs, PageCountableEdge } from '../../schema'
|
||||
import type { SaleorConfig, Provider } from '..'
|
||||
import * as Query from '../../utils/queries'
|
||||
|
||||
export type Page = any
|
||||
|
||||
export type GetAllPagesResult<
|
||||
T extends { pages: any[] } = { pages: Page[] }
|
||||
> = T
|
||||
|
||||
export default function getAllPagesOperation({
|
||||
commerce,
|
||||
}: OperationContext<Provider>) {
|
||||
|
||||
async function getAllPages({
|
||||
query = Query.PageMany,
|
||||
config,
|
||||
variables,
|
||||
}: {
|
||||
url?: string
|
||||
config?: Partial<SaleorConfig>
|
||||
variables?: QueryPagesArgs
|
||||
preview?: boolean
|
||||
query?: string
|
||||
} = {}): Promise<GetAllPagesResult> {
|
||||
const { fetch, locale, locales = ['en-US'] } = commerce.getConfig(config)
|
||||
|
||||
const { data } = await fetch(query, { variables },
|
||||
{
|
||||
...(locale && {
|
||||
headers: {
|
||||
'Accept-Language': locale,
|
||||
},
|
||||
}),
|
||||
}
|
||||
)
|
||||
|
||||
const pages = data.pages?.edges?.map(({ node: { title: name, slug, ...node } }: PageCountableEdge) => ({
|
||||
...node,
|
||||
url: `/${locale}/${slug}`,
|
||||
name,
|
||||
}))
|
||||
|
||||
return { pages }
|
||||
}
|
||||
|
||||
return getAllPages
|
||||
}
|
46
framework/saleor/api/operations/get-all-product-paths.ts
Normal file
46
framework/saleor/api/operations/get-all-product-paths.ts
Normal file
@ -0,0 +1,46 @@
|
||||
import type { OperationContext } from '@commerce/api/operations'
|
||||
import {
|
||||
GetAllProductPathsQuery,
|
||||
GetAllProductPathsQueryVariables,
|
||||
ProductCountableEdge,
|
||||
} from '../../schema'
|
||||
import type { ShopifyConfig, Provider, SaleorConfig } from '..'
|
||||
|
||||
import { getAllProductsPathsQuery } from '../../utils/queries'
|
||||
import fetchAllProducts from '../utils/fetch-all-products'
|
||||
|
||||
export type GetAllProductPathsResult = {
|
||||
products: Array<{ path: string }>
|
||||
}
|
||||
|
||||
export default function getAllProductPathsOperation({
|
||||
commerce,
|
||||
}: OperationContext<Provider>) {
|
||||
|
||||
async function getAllProductPaths({
|
||||
query,
|
||||
config,
|
||||
variables,
|
||||
}: {
|
||||
query?: string
|
||||
config?: SaleorConfig
|
||||
variables?: any
|
||||
} = {}): Promise<GetAllProductPathsResult> {
|
||||
config = commerce.getConfig(config)
|
||||
|
||||
const products = await fetchAllProducts({
|
||||
config,
|
||||
query: getAllProductsPathsQuery,
|
||||
variables,
|
||||
})
|
||||
|
||||
return {
|
||||
products: products?.map(({ node: { slug } }: ProductCountableEdge) => ({
|
||||
path: `/${slug}`,
|
||||
})),
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return getAllProductPaths
|
||||
}
|
50
framework/saleor/api/operations/get-all-products.ts
Normal file
50
framework/saleor/api/operations/get-all-products.ts
Normal file
@ -0,0 +1,50 @@
|
||||
import type { OperationContext } from '@commerce/api/operations'
|
||||
import { Product } from '@commerce/types/product'
|
||||
|
||||
import { ProductCountableEdge } from '../../schema'
|
||||
import type { Provider, SaleorConfig } from '..'
|
||||
import { normalizeProduct } from '../../utils'
|
||||
|
||||
import * as Query from '../../utils/queries'
|
||||
|
||||
type ReturnType = {
|
||||
products: Product[]
|
||||
}
|
||||
|
||||
export default function getAllProductsOperation({
|
||||
commerce,
|
||||
}: OperationContext<Provider>) {
|
||||
async function getAllProducts({
|
||||
query = Query.ProductMany,
|
||||
variables,
|
||||
config,
|
||||
}: {
|
||||
query?: string
|
||||
variables?: any
|
||||
config?: Partial<SaleorConfig>
|
||||
preview?: boolean
|
||||
featured?: boolean
|
||||
} = {}): Promise<ReturnType> {
|
||||
const { fetch, locale } = commerce.getConfig(config)
|
||||
|
||||
const { data } = await fetch(
|
||||
query,
|
||||
{ variables },
|
||||
{
|
||||
...(locale && {
|
||||
headers: {
|
||||
'Accept-Language': locale,
|
||||
},
|
||||
}),
|
||||
}
|
||||
)
|
||||
|
||||
const products = data.products?.edges?.map(({ node: p }: ProductCountableEdge) => normalizeProduct(p)) ?? []
|
||||
|
||||
return {
|
||||
products,
|
||||
}
|
||||
}
|
||||
|
||||
return getAllProducts
|
||||
}
|
51
framework/saleor/api/operations/get-page.ts
Normal file
51
framework/saleor/api/operations/get-page.ts
Normal file
@ -0,0 +1,51 @@
|
||||
import type { OperationContext } from '@commerce/api/operations'
|
||||
import type { Provider, SaleorConfig } from '..'
|
||||
import { QueryPageArgs } from '../../schema'
|
||||
|
||||
import * as Query from '../../utils/queries'
|
||||
|
||||
export type Page = any
|
||||
|
||||
export type GetPageResult<T extends { page?: any } = { page?: Page }> = T
|
||||
|
||||
export default function getPageOperation({
|
||||
commerce,
|
||||
}: OperationContext<Provider>) {
|
||||
|
||||
async function getPage({
|
||||
query = Query.PageOne,
|
||||
variables,
|
||||
config,
|
||||
}: {
|
||||
query?: string
|
||||
variables: QueryPageArgs,
|
||||
config?: Partial<SaleorConfig>
|
||||
preview?: boolean
|
||||
}): Promise<GetPageResult> {
|
||||
const { fetch, locale = 'en-US' } = commerce.getConfig(config)
|
||||
|
||||
const {
|
||||
data: { page },
|
||||
} = await fetch(query, { variables },
|
||||
{
|
||||
...(locale && {
|
||||
headers: {
|
||||
'Accept-Language': locale,
|
||||
},
|
||||
}),
|
||||
}
|
||||
)
|
||||
|
||||
return {
|
||||
page: page
|
||||
? {
|
||||
...page,
|
||||
name: page.title,
|
||||
url: `/${locale}/${page.slug}`,
|
||||
}
|
||||
: null,
|
||||
}
|
||||
}
|
||||
|
||||
return getPage
|
||||
}
|
46
framework/saleor/api/operations/get-product.ts
Normal file
46
framework/saleor/api/operations/get-product.ts
Normal file
@ -0,0 +1,46 @@
|
||||
import type { OperationContext } from '@commerce/api/operations'
|
||||
import { normalizeProduct, } from '../../utils'
|
||||
import type { Provider, SaleorConfig } from '..'
|
||||
|
||||
import * as Query from '../../utils/queries'
|
||||
|
||||
type Variables = {
|
||||
slug: string
|
||||
}
|
||||
|
||||
type ReturnType = {
|
||||
product: any
|
||||
}
|
||||
|
||||
export default function getProductOperation({
|
||||
commerce,
|
||||
}: OperationContext<Provider>) {
|
||||
async function getProduct({
|
||||
query = Query.ProductOneBySlug,
|
||||
variables,
|
||||
config: cfg,
|
||||
}: {
|
||||
query?: string
|
||||
variables: Variables
|
||||
config?: Partial<SaleorConfig>
|
||||
preview?: boolean
|
||||
}): Promise<ReturnType> {
|
||||
const { fetch, locale } = commerce.getConfig(cfg)
|
||||
|
||||
const { data } = await fetch(query, { variables },
|
||||
{
|
||||
...(locale && {
|
||||
headers: {
|
||||
'Accept-Language': locale,
|
||||
},
|
||||
}),
|
||||
}
|
||||
)
|
||||
|
||||
return {
|
||||
product: data?.product ? normalizeProduct(data.product) : null,
|
||||
}
|
||||
}
|
||||
|
||||
return getProduct
|
||||
}
|
35
framework/saleor/api/operations/get-site-info.ts
Normal file
35
framework/saleor/api/operations/get-site-info.ts
Normal file
@ -0,0 +1,35 @@
|
||||
import type { OperationContext } from '@commerce/api/operations'
|
||||
import { Category } from '@commerce/types/site'
|
||||
import type { SaleorConfig, Provider } from '..'
|
||||
|
||||
import { getCategories, getVendors } from '../../utils'
|
||||
|
||||
interface GetSiteInfoResult {
|
||||
categories: Category[]
|
||||
brands: any[]
|
||||
}
|
||||
|
||||
export default function getSiteInfoOperation({ commerce }: OperationContext<Provider>) {
|
||||
async function getSiteInfo({
|
||||
query,
|
||||
config,
|
||||
variables,
|
||||
}: {
|
||||
query?: string
|
||||
config?: Partial<SaleorConfig>
|
||||
preview?: boolean
|
||||
variables?: any
|
||||
} = {}): Promise<GetSiteInfoResult> {
|
||||
const cfg = commerce.getConfig(config)
|
||||
|
||||
const categories = await getCategories(cfg)
|
||||
const brands = await getVendors(cfg)
|
||||
|
||||
return {
|
||||
categories,
|
||||
brands,
|
||||
}
|
||||
}
|
||||
|
||||
return getSiteInfo
|
||||
}
|
7
framework/saleor/api/operations/index.ts
Normal file
7
framework/saleor/api/operations/index.ts
Normal file
@ -0,0 +1,7 @@
|
||||
export { default as getAllPages } from './get-all-pages'
|
||||
export { default as getPage } from './get-page'
|
||||
export { default as getAllProducts } from './get-all-products'
|
||||
export { default as getAllProductPaths } from './get-all-product-paths'
|
||||
export { default as getProduct } from './get-product'
|
||||
export { default as getSiteInfo } from './get-site-info'
|
||||
export { default as login } from './login'
|
42
framework/saleor/api/operations/login.ts
Normal file
42
framework/saleor/api/operations/login.ts
Normal file
@ -0,0 +1,42 @@
|
||||
import type { ServerResponse } from 'http'
|
||||
import type { OperationContext } from '@commerce/api/operations'
|
||||
import type { Provider, SaleorConfig } from '..'
|
||||
import {
|
||||
throwUserErrors,
|
||||
} from '../../utils'
|
||||
|
||||
import * as Mutation from '../../utils/mutations'
|
||||
|
||||
export default function loginOperation({
|
||||
commerce,
|
||||
}: OperationContext<Provider>) {
|
||||
async function login({
|
||||
query = Mutation.SessionCreate,
|
||||
variables,
|
||||
config,
|
||||
}: {
|
||||
query?: string
|
||||
variables: any
|
||||
res: ServerResponse
|
||||
config?: SaleorConfig
|
||||
}): Promise<any> {
|
||||
config = commerce.getConfig(config)
|
||||
|
||||
const { data: { customerAccessTokenCreate } } = await config.fetch(query, { variables })
|
||||
|
||||
throwUserErrors(customerAccessTokenCreate?.customerUserErrors)
|
||||
|
||||
const customerAccessToken = customerAccessTokenCreate?.customerAccessToken
|
||||
const accessToken = customerAccessToken?.accessToken
|
||||
|
||||
// if (accessToken) {
|
||||
// setCustomerToken(accessToken)
|
||||
// }
|
||||
|
||||
return {
|
||||
result: customerAccessToken?.accessToken,
|
||||
}
|
||||
}
|
||||
|
||||
return login
|
||||
}
|
@ -1,50 +0,0 @@
|
||||
import type { NextApiHandler, NextApiRequest, NextApiResponse } from 'next'
|
||||
import { SaleorConfig, getConfig } from '..'
|
||||
|
||||
export type SaleorApiHandler<T = any, H extends SaleorHandlers = {}, Options extends {} = {}> = (
|
||||
req: NextApiRequest,
|
||||
res: NextApiResponse<SaleorApiResponse<T>>,
|
||||
config: SaleorConfig,
|
||||
handlers: H,
|
||||
// Custom configs that may be used by a particular handler
|
||||
options: Options
|
||||
) => void | Promise<void>
|
||||
|
||||
export type SaleorHandler<T = any, Body = null> = (options: {
|
||||
req: NextApiRequest
|
||||
res: NextApiResponse<SaleorApiResponse<T>>
|
||||
config: SaleorConfig
|
||||
body: Body
|
||||
}) => void | Promise<void>
|
||||
|
||||
export type SaleorHandlers<T = any> = {
|
||||
[k: string]: SaleorHandler<T, any>
|
||||
}
|
||||
|
||||
export type SaleorApiResponse<T> = {
|
||||
data: T | null
|
||||
errors?: { message: string; code?: string }[]
|
||||
}
|
||||
|
||||
export default function createApiHandler<T = any, H extends SaleorHandlers = {}, Options extends {} = {}>(
|
||||
handler: SaleorApiHandler<T, H, Options>,
|
||||
handlers: H,
|
||||
defaultOptions: Options
|
||||
) {
|
||||
return function getApiHandler({
|
||||
config,
|
||||
operations,
|
||||
options,
|
||||
}: {
|
||||
config?: SaleorConfig
|
||||
operations?: Partial<H>
|
||||
options?: Options extends {} ? Partial<Options> : never
|
||||
} = {}): NextApiHandler {
|
||||
const ops = { ...operations, ...handlers }
|
||||
const opts = { ...defaultOptions, ...options }
|
||||
|
||||
return function apiHandler(req, res) {
|
||||
return handler(req, res, getConfig(config), ops, opts)
|
||||
}
|
||||
}
|
||||
}
|
@ -3,12 +3,11 @@ import fetch from './fetch'
|
||||
|
||||
import { API_URL } from '../../const'
|
||||
import { getError } from '../../utils/handle-fetch-response'
|
||||
import { getConfig } from '..'
|
||||
import { getCommerceApi } from '..'
|
||||
import { getToken } from '@framework/utils'
|
||||
|
||||
const fetchGraphqlApi: GraphQLFetcher = async (query: string, { variables } = {}, fetchOptions) => {
|
||||
// FIXME @zaiste follow the bigcommerce example
|
||||
const config = getConfig()
|
||||
const config = getCommerceApi().getConfig()
|
||||
const token = getToken()
|
||||
|
||||
const res = await fetch(API_URL!, {
|
||||
|
@ -7,10 +7,11 @@ import * as mutation from '../utils/mutations'
|
||||
import { Mutation, MutationTokenCreateArgs } from '../schema'
|
||||
import useLogin, { UseLogin } from '@commerce/auth/use-login'
|
||||
import { setCSRFToken, setToken, throwUserErrors, checkoutAttach, getCheckoutId } from '../utils'
|
||||
import { LoginHook } from '@commerce/types/login'
|
||||
|
||||
export default useLogin as UseLogin<typeof handler>
|
||||
|
||||
export const handler: MutationHook<null, {}, MutationTokenCreateArgs> = {
|
||||
export const handler: MutationHook<LoginHook> = {
|
||||
fetchOptions: {
|
||||
query: mutation.SessionCreate,
|
||||
},
|
||||
|
@ -4,10 +4,11 @@ import useLogout, { UseLogout } from '@commerce/auth/use-logout'
|
||||
import useCustomer from '../customer/use-customer'
|
||||
import * as mutation from '../utils/mutations'
|
||||
import { setCSRFToken, setToken, setCheckoutToken } from '../utils/customer-token'
|
||||
import { LogoutHook } from '@commerce/types/logout'
|
||||
|
||||
export default useLogout as UseLogout<typeof handler>
|
||||
|
||||
export const handler: MutationHook<null> = {
|
||||
export const handler: MutationHook<LogoutHook> = {
|
||||
fetchOptions: {
|
||||
query: mutation.SessionDestroy,
|
||||
},
|
||||
|
@ -7,10 +7,11 @@ import { AccountRegisterInput, Mutation, MutationAccountRegisterArgs } from '../
|
||||
|
||||
import * as mutation from '../utils/mutations'
|
||||
import { handleAutomaticLogin, throwUserErrors } from '../utils'
|
||||
import { SignupHook } from '@commerce/types/signup'
|
||||
|
||||
export default useSignup as UseSignup<typeof handler>
|
||||
|
||||
export const handler: MutationHook<null, {}, AccountRegisterInput, AccountRegisterInput> = {
|
||||
export const handler: MutationHook<SignupHook> = {
|
||||
fetchOptions: {
|
||||
query: mutation.AccountCreate,
|
||||
},
|
||||
@ -27,6 +28,8 @@ export const handler: MutationHook<null, {}, AccountRegisterInput, AccountRegist
|
||||
input: {
|
||||
email,
|
||||
password,
|
||||
redirectUrl: 'https://localhost.com',
|
||||
channel: 'default-channel'
|
||||
},
|
||||
},
|
||||
})
|
||||
|
@ -8,12 +8,12 @@ import * as mutation from '../utils/mutations'
|
||||
|
||||
import { getCheckoutId, checkoutToCart } from '../utils'
|
||||
|
||||
import { Cart, CartItemBody } from '../types'
|
||||
import { Mutation, MutationCheckoutLinesAddArgs } from '../schema'
|
||||
import { AddItemHook } from '@commerce/types/cart'
|
||||
|
||||
export default useAddItem as UseAddItem<typeof handler>
|
||||
|
||||
export const handler: MutationHook<Cart, {}, CartItemBody> = {
|
||||
export const handler: MutationHook<AddItemHook> = {
|
||||
fetchOptions: { query: mutation.CheckoutLineAdd },
|
||||
async fetcher({ input: item, options, fetch }) {
|
||||
if (item.quantity && (!Number.isInteger(item.quantity) || item.quantity! < 1)) {
|
||||
|
@ -1,14 +1,14 @@
|
||||
import { useMemo } from 'react'
|
||||
import useCommerceCart, { FetchCartInput, UseCart } from '@commerce/cart/use-cart'
|
||||
import useCommerceCart, { UseCart } from '@commerce/cart/use-cart'
|
||||
|
||||
import { Cart } from '../types'
|
||||
import { SWRHook } from '@commerce/utils/types'
|
||||
import { checkoutCreate, checkoutToCart, getCheckoutId } from '../utils'
|
||||
import * as query from '../utils/queries'
|
||||
import { GetCartHook } from '@commerce/types/cart'
|
||||
|
||||
export default useCommerceCart as UseCart<typeof handler>
|
||||
|
||||
export const handler: SWRHook<Cart | null, {}, FetchCartInput, { isEmpty?: boolean }> = {
|
||||
export const handler: SWRHook<GetCartHook> = {
|
||||
fetchOptions: {
|
||||
query: query.CheckoutOne,
|
||||
},
|
||||
|
@ -1,25 +1,17 @@
|
||||
import { useCallback } from 'react'
|
||||
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 type { MutationHookContext, HookFetcherContext, MutationHook } from '@commerce/utils/types'
|
||||
import useRemoveItem, { UseRemoveItem } from '@commerce/cart/use-remove-item'
|
||||
import useCart from './use-cart'
|
||||
import * as mutation from '../utils/mutations'
|
||||
import { getCheckoutId, checkoutToCart } from '../utils'
|
||||
import { Cart, LineItem } from '../types'
|
||||
import { Mutation, MutationCheckoutLineDeleteArgs } from '../schema'
|
||||
|
||||
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
|
||||
import { LineItem, RemoveItemHook } from '../types/cart'
|
||||
|
||||
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<RemoveItemHook>) {
|
||||
const data = await fetch<Mutation, MutationCheckoutLineDeleteArgs>({
|
||||
...options,
|
||||
variables: {
|
||||
@ -29,25 +21,19 @@ export const handler = {
|
||||
})
|
||||
return checkoutToCart(data.checkoutLineDelete)
|
||||
},
|
||||
useHook:
|
||||
({ fetch }: MutationHookContext<Cart | null, RemoveCartItemBody>) =>
|
||||
<T extends LineItem | undefined = undefined>(ctx: { item?: T } = {}) => {
|
||||
const { item } = ctx
|
||||
useHook: ({ fetch }: MutationHookContext<RemoveItemHook>) => <
|
||||
T extends LineItem | undefined = undefined
|
||||
> () => {
|
||||
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',
|
||||
})
|
||||
}
|
||||
return useCallback(
|
||||
async function removeItem(input) {
|
||||
const data = await fetch({ input: { itemId: input.id } })
|
||||
await mutate(data, false)
|
||||
|
||||
const data = await fetch({ input: { itemId } })
|
||||
await mutate(data, false)
|
||||
return data
|
||||
}
|
||||
|
||||
return useCallback(removeItem as RemoveItemFn<T>, [fetch, mutate])
|
||||
return data
|
||||
},
|
||||
[fetch, mutate]
|
||||
);
|
||||
},
|
||||
}
|
||||
|
@ -2,26 +2,32 @@ import { useCallback } from 'react'
|
||||
import debounce from 'lodash.debounce'
|
||||
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, { UseUpdateItem } from '@commerce/cart/use-update-item'
|
||||
|
||||
import useCart from './use-cart'
|
||||
import { handler as removeItemHandler } from './use-remove-item'
|
||||
import type { Cart, LineItem, UpdateCartItemBody } from '../types'
|
||||
import type { LineItem } from '../types'
|
||||
import { checkoutToCart } from '../utils'
|
||||
import { getCheckoutId } from '../utils'
|
||||
import { Mutation, MutationCheckoutLinesUpdateArgs } from '../schema'
|
||||
|
||||
import * as mutation from '../utils/mutations'
|
||||
|
||||
export type UpdateItemInput<T = any> = T extends LineItem
|
||||
? Partial<UpdateItemInputBase<LineItem>>
|
||||
: UpdateItemInputBase<LineItem>
|
||||
import type { UpdateItemHook } from '../types/cart'
|
||||
|
||||
export type UpdateItemActionInput<T = any> = T extends LineItem
|
||||
? Partial<UpdateItemHook['actionInput']>
|
||||
: UpdateItemHook['actionInput']
|
||||
|
||||
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<UpdateItemHook>) {
|
||||
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) {
|
||||
@ -53,8 +59,7 @@ export const handler = {
|
||||
|
||||
return checkoutToCart(checkoutLinesUpdate)
|
||||
},
|
||||
useHook:
|
||||
({ fetch }: MutationHookContext<Cart | null, UpdateCartItemBody>) =>
|
||||
useHook: ({ fetch }: MutationHookContext<UpdateItemHook>) =>
|
||||
<T extends LineItem | undefined = undefined>(
|
||||
ctx: {
|
||||
item?: T
|
||||
@ -65,7 +70,7 @@ export const handler = {
|
||||
const { mutate } = useCart() as any
|
||||
|
||||
return useCallback(
|
||||
debounce(async (input: UpdateItemInput<T>) => {
|
||||
debounce(async (input: UpdateItemActionInput<T>) => {
|
||||
const itemId = input.id ?? item?.id
|
||||
const productId = input.productId ?? item?.productId
|
||||
const variantId = input.productId ?? item?.variantId
|
||||
|
@ -1,40 +0,0 @@
|
||||
import { getConfig, SaleorConfig } from '../api'
|
||||
import { PageCountableEdge } from '../schema'
|
||||
import * as query from '../utils/queries'
|
||||
|
||||
type Variables = {
|
||||
first?: number
|
||||
}
|
||||
|
||||
type ReturnType = {
|
||||
pages: Page[]
|
||||
}
|
||||
|
||||
export type Page = {
|
||||
id: string
|
||||
name: string
|
||||
url: string
|
||||
sort_order?: number
|
||||
body: string
|
||||
}
|
||||
|
||||
const getAllPages = async (options?: {
|
||||
variables?: Variables
|
||||
config: SaleorConfig
|
||||
preview?: boolean
|
||||
}): Promise<ReturnType> => {
|
||||
let { config, variables = { first: 100 } } = options ?? {}
|
||||
config = getConfig(config)
|
||||
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,
|
||||
}))
|
||||
|
||||
return { pages }
|
||||
}
|
||||
|
||||
export default getAllPages
|
@ -1,36 +0,0 @@
|
||||
import { getConfig, SaleorConfig } from '../api'
|
||||
import { Page } from './get-all-pages'
|
||||
|
||||
import * as query from '../utils/queries'
|
||||
|
||||
type Variables = {
|
||||
id: string
|
||||
}
|
||||
|
||||
export type GetPageResult<T extends { page?: any } = { page?: Page }> = T
|
||||
|
||||
const getPage = async (options: {
|
||||
variables: Variables
|
||||
config: SaleorConfig
|
||||
preview?: boolean
|
||||
}): Promise<GetPageResult> => {
|
||||
let { config, variables } = options ?? {}
|
||||
|
||||
config = getConfig(config)
|
||||
const { locale } = config
|
||||
|
||||
const { data } = await config.fetch(query.PageOne, { variables })
|
||||
const page = data.page
|
||||
|
||||
return {
|
||||
page: page
|
||||
? {
|
||||
...page,
|
||||
name: page.title,
|
||||
url: `/${locale}/${page.slug}`,
|
||||
}
|
||||
: null,
|
||||
}
|
||||
}
|
||||
|
||||
export default getPage
|
@ -1,31 +0,0 @@
|
||||
import getCategories, { Category } from '../utils/get-categories'
|
||||
import getVendors, { Brands } from '../utils/get-vendors'
|
||||
|
||||
import { getConfig, SaleorConfig } from '../api'
|
||||
|
||||
export type GetSiteInfoResult<
|
||||
T extends { categories: any[]; brands: any[] } = {
|
||||
categories: Category[]
|
||||
brands: Brands
|
||||
}
|
||||
> = T
|
||||
|
||||
const getSiteInfo = async (options?: {
|
||||
variables?: any
|
||||
config: SaleorConfig
|
||||
preview?: boolean
|
||||
}): Promise<GetSiteInfoResult> => {
|
||||
let { config } = options ?? {}
|
||||
|
||||
config = getConfig(config)
|
||||
|
||||
const categories = await getCategories(config)
|
||||
const brands = await getVendors(config)
|
||||
|
||||
return {
|
||||
categories,
|
||||
brands,
|
||||
}
|
||||
}
|
||||
|
||||
export default getSiteInfo
|
@ -1,23 +0,0 @@
|
||||
import { getConfig, SaleorConfig } from '../api'
|
||||
import * as query from '../utils/queries'
|
||||
import Cookies from 'js-cookie'
|
||||
|
||||
async function getCustomerId({
|
||||
customerToken: customerAccesToken,
|
||||
config,
|
||||
}: {
|
||||
customerToken: string
|
||||
config?: SaleorConfig
|
||||
}): Promise<number | undefined> {
|
||||
config = getConfig(config)
|
||||
|
||||
const { data } = await config.fetch(query.CustomerOne, {
|
||||
variables: {
|
||||
customerAccesToken: customerAccesToken || Cookies.get(config.customerCookie),
|
||||
},
|
||||
})
|
||||
|
||||
return data.customer?.id
|
||||
}
|
||||
|
||||
export default getCustomerId
|
@ -1,12 +1,12 @@
|
||||
import useCustomer, { UseCustomer } from '@commerce/customer/use-customer'
|
||||
import { Customer } from '@commerce/types'
|
||||
import { CustomerHook } from '@commerce/types/customer'
|
||||
import { SWRHook } from '@commerce/utils/types'
|
||||
|
||||
import * as query from '../utils/queries'
|
||||
|
||||
export default useCustomer as UseCustomer<typeof handler>
|
||||
|
||||
export const handler: SWRHook<Customer | null> = {
|
||||
export const handler: SWRHook<CustomerHook> = {
|
||||
fetchOptions: {
|
||||
query: query.CustomerCurrent,
|
||||
},
|
||||
|
@ -1,23 +0,0 @@
|
||||
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 }) => {
|
||||
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}`,
|
||||
}))
|
||||
|
||||
return {
|
||||
categories,
|
||||
}
|
||||
}
|
||||
|
||||
export default getAllCollections
|
@ -1,41 +0,0 @@
|
||||
import { getConfig, SaleorConfig } from '../api'
|
||||
import fetchAllProducts from '../api/utils/fetch-all-products'
|
||||
import { ProductCountableEdge } from '../schema'
|
||||
import { getAllProductsPathsQuery } from '../utils/queries'
|
||||
|
||||
type ProductPath = {
|
||||
path: string
|
||||
}
|
||||
|
||||
export type ProductPathNode = {
|
||||
node: ProductPath
|
||||
}
|
||||
|
||||
type ReturnType = {
|
||||
products: ProductPathNode[]
|
||||
}
|
||||
|
||||
const getAllProductPaths = async (options?: {
|
||||
variables?: any
|
||||
config?: SaleorConfig
|
||||
preview?: boolean
|
||||
}): Promise<ReturnType> => {
|
||||
let { config, variables = { first: 100 } } = options ?? {}
|
||||
config = getConfig(config)
|
||||
|
||||
const products = await fetchAllProducts({
|
||||
config,
|
||||
query: getAllProductsPathsQuery,
|
||||
variables,
|
||||
})
|
||||
|
||||
return {
|
||||
products: products?.map(({ node: { slug } }: ProductCountableEdge) => ({
|
||||
node: {
|
||||
path: `/${slug}`,
|
||||
},
|
||||
})),
|
||||
}
|
||||
}
|
||||
|
||||
export default getAllProductPaths
|
@ -1,54 +0,0 @@
|
||||
import { GraphQLFetcherResult } from '@commerce/api'
|
||||
import { Product } from '@commerce/types'
|
||||
|
||||
import { getConfig, SaleorConfig } from '../api'
|
||||
import { ProductCountableEdge } from '../schema'
|
||||
import { normalizeProduct } from '../utils/normalize'
|
||||
|
||||
import * as query from '../utils/queries'
|
||||
|
||||
type Variables = {
|
||||
first?: number
|
||||
field?: string
|
||||
}
|
||||
|
||||
type ReturnType = {
|
||||
products: Product[]
|
||||
}
|
||||
|
||||
const getAllProducts = async (options: {
|
||||
variables?: Variables
|
||||
config?: SaleorConfig
|
||||
preview?: boolean
|
||||
featured?: boolean
|
||||
}): Promise<ReturnType> => {
|
||||
let { config, variables = { first: 100 }, featured } = options ?? {}
|
||||
config = getConfig(config)
|
||||
|
||||
if (featured) {
|
||||
const { data }: GraphQLFetcherResult = await config.fetch(query.CollectionOne, {
|
||||
variables: { ...variables, categoryId: 'Q29sbGVjdGlvbjoxOQ==' },
|
||||
})
|
||||
|
||||
debugger
|
||||
|
||||
const products = data.collection.products?.edges?.map(({ node: p }: ProductCountableEdge) => normalizeProduct(p)) ?? []
|
||||
|
||||
return {
|
||||
products,
|
||||
}
|
||||
|
||||
} else {
|
||||
const { data }: GraphQLFetcherResult = await config.fetch(query.ProductMany, {
|
||||
variables,
|
||||
})
|
||||
|
||||
const products = data.products?.edges?.map(({ node: p }: ProductCountableEdge) => normalizeProduct(p)) ?? []
|
||||
|
||||
return {
|
||||
products,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default getAllProducts
|
@ -1,29 +0,0 @@
|
||||
import { GraphQLFetcherResult } from '@commerce/api'
|
||||
import { getConfig, SaleorConfig } from '../api'
|
||||
import { normalizeProduct } from '../utils'
|
||||
import * as query from '../utils/queries'
|
||||
|
||||
type Variables = {
|
||||
slug: string
|
||||
}
|
||||
|
||||
type ReturnType = {
|
||||
product: any
|
||||
}
|
||||
|
||||
const getProduct = async (options: {
|
||||
variables: Variables
|
||||
config: SaleorConfig
|
||||
preview?: boolean
|
||||
}): Promise<ReturnType> => {
|
||||
let { config, variables } = options ?? {}
|
||||
config = getConfig(config)
|
||||
|
||||
const { data }: GraphQLFetcherResult = await config.fetch(query.ProductOneBySlug, { variables })
|
||||
|
||||
return {
|
||||
product: data?.product ? normalizeProduct(data.product) : null,
|
||||
}
|
||||
}
|
||||
|
||||
export default getProduct
|
@ -1,18 +1,19 @@
|
||||
import { SWRHook } from '@commerce/utils/types'
|
||||
import { Product } from '@commerce/types'
|
||||
import { Product } from '@commerce/types/product'
|
||||
import useSearch, { UseSearch } from '@commerce/product/use-search'
|
||||
|
||||
import { ProductCountableEdge } from '../schema'
|
||||
import { getSearchVariables, normalizeProduct } from '../utils'
|
||||
|
||||
import * as query from '../utils/queries'
|
||||
import { SearchProductsHook } from '@commerce/types/product'
|
||||
|
||||
export default useSearch as UseSearch<typeof handler>
|
||||
|
||||
export type SearchProductsInput = {
|
||||
search?: string
|
||||
categoryId?: string
|
||||
brandId?: string
|
||||
categoryId?: string | number
|
||||
brandId?: string | number
|
||||
sort?: string
|
||||
}
|
||||
|
||||
@ -21,7 +22,7 @@ export type SearchProductsData = {
|
||||
found: boolean
|
||||
}
|
||||
|
||||
export const handler: SWRHook<SearchProductsData, SearchProductsInput, SearchProductsInput> = {
|
||||
export const handler: SWRHook<SearchProductsHook> = {
|
||||
fetchOptions: {
|
||||
query: query.ProductMany,
|
||||
},
|
||||
|
@ -1,4 +1,4 @@
|
||||
import * as Core from '@commerce/types'
|
||||
import type { Cart as CoreCart } from '@commerce/types'
|
||||
import { CheckoutLine } from './schema'
|
||||
|
||||
export type SaleorCheckout = {
|
||||
@ -7,10 +7,10 @@ export type SaleorCheckout = {
|
||||
lineItems: CheckoutLine[]
|
||||
}
|
||||
|
||||
export type Cart = Core.Cart & {
|
||||
export type Cart = CoreCart.Cart & {
|
||||
lineItems: LineItem[]
|
||||
}
|
||||
export interface LineItem extends Core.LineItem {
|
||||
export interface LineItem extends CoreCart.LineItem {
|
||||
options?: any[]
|
||||
}
|
||||
|
||||
@ -23,21 +23,21 @@ export type OptionSelections = {
|
||||
option_value: number | string
|
||||
}
|
||||
|
||||
export type CartItemBody = Core.CartItemBody & {
|
||||
export type CartItemBody = CoreCart.CartItemBody & {
|
||||
productId: string // The product id is always required for BC
|
||||
optionSelections?: OptionSelections
|
||||
}
|
||||
|
||||
export type GetCartHandlerBody = Core.GetCartHandlerBody
|
||||
// export type GetCartHandlerBody = CoreCart.GetCartHandlerBody
|
||||
|
||||
export type AddCartItemBody = Core.AddCartItemBody<CartItemBody>
|
||||
// export type AddCartItemBody = Core.AddCartItemBody<CartItemBody>
|
||||
|
||||
export type AddCartItemHandlerBody = Core.AddCartItemHandlerBody<CartItemBody>
|
||||
// export type AddCartItemHandlerBody = Core.AddCartItemHandlerBody<CartItemBody>
|
||||
|
||||
export type UpdateCartItemBody = Core.UpdateCartItemBody<CartItemBody>
|
||||
// export type UpdateCartItemBody = Core.UpdateCartItemBody<CartItemBody>
|
||||
|
||||
export type UpdateCartItemHandlerBody = Core.UpdateCartItemHandlerBody<CartItemBody>
|
||||
// export type UpdateCartItemHandlerBody = Core.UpdateCartItemHandlerBody<CartItemBody>
|
||||
|
||||
export type RemoveCartItemBody = Core.RemoveCartItemBody
|
||||
// export type RemoveCartItemBody = Core.RemoveCartItemBody
|
||||
|
||||
export type RemoveCartItemHandlerBody = Core.RemoveCartItemHandlerBody
|
||||
// export type RemoveCartItemHandlerBody = Core.RemoveCartItemHandlerBody
|
||||
|
32
framework/saleor/types/cart.ts
Normal file
32
framework/saleor/types/cart.ts
Normal file
@ -0,0 +1,32 @@
|
||||
import * as Core from '@commerce/types/cart'
|
||||
|
||||
export * from '@commerce/types/cart'
|
||||
|
||||
export type SaleorCart = {}
|
||||
|
||||
/**
|
||||
* Extend core cart types
|
||||
*/
|
||||
|
||||
export type Cart = Core.Cart & {
|
||||
lineItems: Core.LineItem[]
|
||||
url?: string
|
||||
}
|
||||
|
||||
export type CartTypes = Core.CartTypes
|
||||
|
||||
export type CartHooks = Core.CartHooks<CartTypes>
|
||||
|
||||
export type GetCartHook = CartHooks['getCart']
|
||||
export type AddItemHook = CartHooks['addItem']
|
||||
export type UpdateItemHook = CartHooks['updateItem']
|
||||
export type RemoveItemHook = CartHooks['removeItem']
|
||||
|
||||
export type CartSchema = Core.CartSchema<CartTypes>
|
||||
|
||||
export type CartHandlers = Core.CartHandlers<CartTypes>
|
||||
|
||||
export type GetCartHandler = CartHandlers['getCart']
|
||||
export type AddItemHandler = CartHandlers['addItem']
|
||||
export type UpdateItemHandler = CartHandlers['updateItem']
|
||||
export type RemoveItemHandler = CartHandlers['removeItem']
|
@ -1,13 +1,8 @@
|
||||
import { Category } from '@commerce/types/site'
|
||||
import { SaleorConfig } from '../api'
|
||||
import { CollectionCountableEdge } from '../schema'
|
||||
import * as query from './queries'
|
||||
|
||||
export type Category = {
|
||||
entityId: string
|
||||
name: string
|
||||
path: string
|
||||
}
|
||||
|
||||
const getCategories = async (config: SaleorConfig): Promise<Category[]> => {
|
||||
const { data } = await config.fetch(query.CollectionMany, {
|
||||
variables: {
|
||||
@ -16,9 +11,10 @@ const getCategories = async (config: SaleorConfig): Promise<Category[]> => {
|
||||
})
|
||||
|
||||
return (
|
||||
data.collections?.edges?.map(({ node: { id: entityId, name, slug } }: CollectionCountableEdge) => ({
|
||||
entityId,
|
||||
data.collections?.edges?.map(({ node: { id, name, slug } }: CollectionCountableEdge) => ({
|
||||
id,
|
||||
name,
|
||||
slug,
|
||||
path: `/${slug}`,
|
||||
})) ?? []
|
||||
)
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { Product } from '@commerce/types'
|
||||
import { Product } from '@commerce/types/product'
|
||||
|
||||
import { Product as SaleorProduct, Checkout, CheckoutLine, Money, ProductVariant } from '../schema'
|
||||
|
||||
@ -120,7 +120,7 @@ function normalizeLineItem({ id, variant, quantity }: CheckoutLine): LineItem {
|
||||
sku: variant?.sku ?? '',
|
||||
name: variant?.name!,
|
||||
image: {
|
||||
url: variant?.media![0].url ?? placeholderImg,
|
||||
url: variant?.media![0] ? variant?.media![0].url : placeholderImg,
|
||||
},
|
||||
requiresShipping: false,
|
||||
price: variant?.pricing?.price?.gross.amount!,
|
||||
|
@ -72,7 +72,7 @@
|
||||
"postcss-flexbugs-fixes": "^5.0.2",
|
||||
"postcss-preset-env": "^6.7.0",
|
||||
"prettier": "^2.3.0",
|
||||
"typescript": "^4.2.4"
|
||||
"typescript": "4.2.4"
|
||||
},
|
||||
"husky": {
|
||||
"hooks": {
|
||||
|
144
yarn.lock
144
yarn.lock
@ -921,25 +921,25 @@
|
||||
resolved "https://registry.yarnpkg.com/@next/react-refresh-utils/-/react-refresh-utils-10.0.9-canary.5.tgz#5ece6594ec08b48bc319d8f171d9c46a7beb04ba"
|
||||
integrity sha512-47Y2GO+PezgJF4t41/VOEmIpUe66bbzbh/jO+doldwoPiLPxrSfOMpAnlJLpm5keHquBJMCIQbwDtmSpNvPkTg==
|
||||
|
||||
"@nodelib/fs.scandir@2.1.4":
|
||||
version "2.1.4"
|
||||
resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.4.tgz#d4b3549a5db5de2683e0c1071ab4f140904bbf69"
|
||||
integrity sha512-33g3pMJk3bg5nXbL/+CY6I2eJDzZAni49PfJnL5fghPTggPvBd/pFNSgJsdAgWptuFu7qq/ERvOYFlhvsLTCKA==
|
||||
"@nodelib/fs.scandir@2.1.5":
|
||||
version "2.1.5"
|
||||
resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5"
|
||||
integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==
|
||||
dependencies:
|
||||
"@nodelib/fs.stat" "2.0.4"
|
||||
"@nodelib/fs.stat" "2.0.5"
|
||||
run-parallel "^1.1.9"
|
||||
|
||||
"@nodelib/fs.stat@2.0.4", "@nodelib/fs.stat@^2.0.2":
|
||||
version "2.0.4"
|
||||
resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.4.tgz#a3f2dd61bab43b8db8fa108a121cfffe4c676655"
|
||||
integrity sha512-IYlHJA0clt2+Vg7bccq+TzRdJvv19c2INqBSsoOLp1je7xjtr7J26+WXR72MCdvU9q1qTzIWDfhMf+DRvQJK4Q==
|
||||
"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2":
|
||||
version "2.0.5"
|
||||
resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b"
|
||||
integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==
|
||||
|
||||
"@nodelib/fs.walk@^1.2.3":
|
||||
version "1.2.6"
|
||||
resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.6.tgz#cce9396b30aa5afe9e3756608f5831adcb53d063"
|
||||
integrity sha512-8Broas6vTtW4GIXTAHDoE32hnN2M5ykgCpWGbuXHQ15vEMqr23pB76e/GZcYsZCHALv50ktd24qhEyKr6wBtow==
|
||||
version "1.2.7"
|
||||
resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.7.tgz#94c23db18ee4653e129abd26fb06f870ac9e1ee2"
|
||||
integrity sha512-BTIhocbPBSrRmHxOAJFtR18oLhxTtAFDAvL8hY1S3iU8k+E60W/YFs4jrixGzQjMpF4qPXxIQHcjVD9dz1C2QA==
|
||||
dependencies:
|
||||
"@nodelib/fs.scandir" "2.1.4"
|
||||
"@nodelib/fs.scandir" "2.1.5"
|
||||
fastq "^1.6.0"
|
||||
|
||||
"@opentelemetry/api@0.14.0":
|
||||
@ -1081,21 +1081,16 @@
|
||||
dependencies:
|
||||
"@types/node" "*"
|
||||
|
||||
"@types/node@*":
|
||||
version "15.3.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-15.3.1.tgz#23a06b87eedb524016616e886b116b8fdcb180af"
|
||||
integrity sha512-weaeiP4UF4XgF++3rpQhpIJWsCTS4QJw5gvBhQu6cFIxTwyxWIe3xbnrY/o2lTCQ0lsdb8YIUDUvLR4Vuz5rbw==
|
||||
"@types/node@*", "@types/node@^15.6.1":
|
||||
version "15.12.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-15.12.1.tgz#9b60797dee1895383a725f828a869c86c6caa5c2"
|
||||
integrity sha512-zyxJM8I1c9q5sRMtVF+zdd13Jt6RU4r4qfhTd7lQubyThvLfx6yYekWSQjGCGV2Tkecgxnlpl/DNlb6Hg+dmEw==
|
||||
|
||||
"@types/node@10.12.18":
|
||||
version "10.12.18"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-10.12.18.tgz#1d3ca764718915584fcd9f6344621b7672665c67"
|
||||
integrity sha512-fh+pAqt4xRzPfqA6eh3Z2y6fyZavRIumvjhaCL753+TVkGKGhpPeyrJG2JftD0T9q4GF00KjefsQ+PQNDdWQaQ==
|
||||
|
||||
"@types/node@^15.6.1":
|
||||
version "15.6.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-15.6.1.tgz#32d43390d5c62c5b6ec486a9bc9c59544de39a08"
|
||||
integrity sha512-7EIraBEyRHEe7CH+Fm1XvgqU6uwZN8Q7jppJGcqjROMT29qhAuuOxYB1uEY5UMYQKEmA5D+5tBnhdaPXSsLONA==
|
||||
|
||||
"@types/parse-json@^4.0.0":
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.0.tgz#2f8bb441434d163b35fb8ffdccd7138927ffb8c0"
|
||||
@ -1107,9 +1102,9 @@
|
||||
integrity sha512-KfRL3PuHmqQLOG+2tGpRO26Ctg+Cq1E01D2DMriKEATHgWLfeNDmq9e29Q9WIky0dQ3NPkd1mzYH8Lm936Z9qw==
|
||||
|
||||
"@types/react@^17.0.8":
|
||||
version "17.0.8"
|
||||
resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.8.tgz#fe76e3ba0fbb5602704110fd1e3035cf394778e3"
|
||||
integrity sha512-3sx4c0PbXujrYAKwXxNONXUtRp9C+hE2di0IuxFyf5BELD+B+AXL8G7QrmSKhVwKZDbv0igiAjQAMhXj8Yg3aw==
|
||||
version "17.0.9"
|
||||
resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.9.tgz#1147fb520024a62c9b3841f5cb4db89b73ddb87f"
|
||||
integrity sha512-2Cw7FvevpJxQrCb+k5t6GH1KIvmadj5uBbjPaLlJB/nZWUj56e1ZqcD6zsoMFB47MsJUTFl9RJ132A7hb3QFJA==
|
||||
dependencies:
|
||||
"@types/prop-types" "*"
|
||||
"@types/scheduler" "*"
|
||||
@ -1766,15 +1761,10 @@ camelcase@^5.0.0:
|
||||
resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320"
|
||||
integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==
|
||||
|
||||
caniuse-lite@^1.0.30000981, caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001173, caniuse-lite@^1.0.30001179, caniuse-lite@^1.0.30001219:
|
||||
version "1.0.30001228"
|
||||
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001228.tgz#bfdc5942cd3326fa51ee0b42fbef4da9d492a7fa"
|
||||
integrity sha512-QQmLOGJ3DEgokHbMSA8cj2a+geXqmnpyOFT0lhQV6P3/YOJvGDEwoedcwxEQ30gJIwIIunHIicunJ2rzK5gB2A==
|
||||
|
||||
caniuse-lite@^1.0.30001230:
|
||||
version "1.0.30001231"
|
||||
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001231.tgz#6c1f9b49fc27cc368b894e64b9b28b39ef80603b"
|
||||
integrity sha512-WAFFv31GgU4DiwNAy77qMo3nNyycEhH3ikcCVHvkQpPe/fO8Tb2aRYzss8kgyLQBm8mJ7OryW4X6Y4vsBCIqag==
|
||||
caniuse-lite@^1.0.30000981, caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001173, caniuse-lite@^1.0.30001179, caniuse-lite@^1.0.30001219, caniuse-lite@^1.0.30001230:
|
||||
version "1.0.30001234"
|
||||
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001234.tgz#8fc2e709e3b0679d7af7f073a1c661155c39b975"
|
||||
integrity sha512-a3gjUVKkmwLdNysa1xkUAwN2VfJUJyVW47rsi3aCbkRCtbHAfo+rOsCqVw29G6coQ8gzAPb5XBXwiGHwme3isA==
|
||||
|
||||
capital-case@^1.0.4:
|
||||
version "1.0.4"
|
||||
@ -2584,9 +2574,9 @@ ecdsa-sig-formatter@1.0.11:
|
||||
safe-buffer "^5.0.1"
|
||||
|
||||
electron-to-chromium@^1.3.634, electron-to-chromium@^1.3.723:
|
||||
version "1.3.734"
|
||||
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.734.tgz#c8d318a4eb27509190cf3a08870dbcbf06c74dcb"
|
||||
integrity sha512-iQF2mjPZ6zNNq45kbJ6MYZYCBNdv2JpGiJC/lVx4tGJWi9MNg73KkL9sWGN4X4I/CP2SBLWsT8nPADZZpAHIyw==
|
||||
version "1.3.749"
|
||||
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.749.tgz#0ecebc529ceb49dd2a7c838ae425236644c3439a"
|
||||
integrity sha512-F+v2zxZgw/fMwPz/VUGIggG4ZndDsYy0vlpthi3tjmDZlcfbhN5mYW0evXUsBr2sUtuDANFtle410A9u/sd/4A==
|
||||
|
||||
elegant-spinner@^1.0.1:
|
||||
version "1.0.1"
|
||||
@ -2672,9 +2662,9 @@ error-ex@^1.3.1:
|
||||
is-arrayish "^0.2.1"
|
||||
|
||||
es-abstract@^1.18.0-next.1:
|
||||
version "1.18.0"
|
||||
resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.18.0.tgz#ab80b359eecb7ede4c298000390bc5ac3ec7b5a4"
|
||||
integrity sha512-LJzK7MrQa8TS0ja2w3YNLzUgJCGPdPOV1yVvezjNnS89D+VR08+Szt2mz3YB2Dck/+w5tfIq/RoUAFqJJGM2yw==
|
||||
version "1.18.3"
|
||||
resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.18.3.tgz#25c4c3380a27aa203c44b2b685bba94da31b63e0"
|
||||
integrity sha512-nQIr12dxV7SSxE6r6f1l3DtAeEYdsGpps13dR0TwJg1S8gyp4ZPgy3FZcHBgbiQqnoqSTb+oC+kO4UQ0C/J8vw==
|
||||
dependencies:
|
||||
call-bind "^1.0.2"
|
||||
es-to-primitive "^1.2.1"
|
||||
@ -2684,14 +2674,14 @@ es-abstract@^1.18.0-next.1:
|
||||
has-symbols "^1.0.2"
|
||||
is-callable "^1.2.3"
|
||||
is-negative-zero "^2.0.1"
|
||||
is-regex "^1.1.2"
|
||||
is-string "^1.0.5"
|
||||
object-inspect "^1.9.0"
|
||||
is-regex "^1.1.3"
|
||||
is-string "^1.0.6"
|
||||
object-inspect "^1.10.3"
|
||||
object-keys "^1.1.1"
|
||||
object.assign "^4.1.2"
|
||||
string.prototype.trimend "^1.0.4"
|
||||
string.prototype.trimstart "^1.0.4"
|
||||
unbox-primitive "^1.0.0"
|
||||
unbox-primitive "^1.0.1"
|
||||
|
||||
es-to-primitive@^1.2.1:
|
||||
version "1.2.1"
|
||||
@ -2778,9 +2768,9 @@ evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3:
|
||||
safe-buffer "^5.1.1"
|
||||
|
||||
execa@^5.0.0:
|
||||
version "5.0.1"
|
||||
resolved "https://registry.yarnpkg.com/execa/-/execa-5.0.1.tgz#aee63b871c9b2cb56bc9addcd3c70a785c6bf0d1"
|
||||
integrity sha512-4hFTjFbFzQa3aCLobpbPJR/U+VoL1wdV5ozOWjeet0AWDeYr9UFGM1eUFWHX+VtOWFq4p0xXUXfW1YxUaP4fpw==
|
||||
version "5.1.1"
|
||||
resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd"
|
||||
integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==
|
||||
dependencies:
|
||||
cross-spawn "^7.0.3"
|
||||
get-stream "^6.0.0"
|
||||
@ -3150,9 +3140,9 @@ graphql-tag@^2.11.0:
|
||||
tslib "^2.1.0"
|
||||
|
||||
graphql-ws@^4.4.1:
|
||||
version "4.7.0"
|
||||
resolved "https://registry.yarnpkg.com/graphql-ws/-/graphql-ws-4.7.0.tgz#b323fbf35a3736eed85dac24c0054d6d10c93e62"
|
||||
integrity sha512-Md8SsmC9ZlsogFPd3Ot8HbIAAqsHh8Xoq7j4AmcIat1Bh6k91tjVyQvA0Au1/BolXSYq+RDvib6rATU2Hcf1Xw==
|
||||
version "4.8.0"
|
||||
resolved "https://registry.yarnpkg.com/graphql-ws/-/graphql-ws-4.8.0.tgz#4b0a82fa1ad00a3baa1cae980032dcaaad08b339"
|
||||
integrity sha512-0jk0c7GPfAlQfA7xZ4CKlLvFF4JBPYbczIHIXl/tk/fXoCLzmrmwQ/HNwOoOHfFMS3usbD1nt77k67pgXx2BYQ==
|
||||
|
||||
graphql@^15.5.0:
|
||||
version "15.5.0"
|
||||
@ -3559,7 +3549,7 @@ is-promise@^2.1.0:
|
||||
resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.2.2.tgz#39ab959ccbf9a774cf079f7b40c7a26f763135f1"
|
||||
integrity sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==
|
||||
|
||||
is-regex@^1.1.2:
|
||||
is-regex@^1.1.3:
|
||||
version "1.1.3"
|
||||
resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.3.tgz#d029f9aff6448b93ebbe3f33dac71511fdcbef9f"
|
||||
integrity sha512-qSVXFz28HM7y+IWX6vLCsexdlvzT1PJNFSBuaQLQ5o0IEw8UDYW6/2+eCMVyIsbM8CNLX2a/QWmSpyxYEHY7CQ==
|
||||
@ -3594,7 +3584,7 @@ is-stream@^2.0.0:
|
||||
resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.0.tgz#bde9c32680d6fae04129d6ac9d921ce7815f78e3"
|
||||
integrity sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==
|
||||
|
||||
is-string@^1.0.5:
|
||||
is-string@^1.0.5, is-string@^1.0.6:
|
||||
version "1.0.6"
|
||||
resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.6.tgz#3fe5d5992fb0d93404f32584d4b0179a71b54a5f"
|
||||
integrity sha512-2gdzbKUuqtQ3lYNrUTQYoClPhm7oQu4UdpSZMp1/DGgkHBT8E2Z1l0yMdb6D4zNAxwDiMv8MdulKROJGNl0Q0w==
|
||||
@ -4208,17 +4198,17 @@ miller-rabin@^4.0.0:
|
||||
bn.js "^4.0.0"
|
||||
brorand "^1.0.1"
|
||||
|
||||
mime-db@1.47.0:
|
||||
version "1.47.0"
|
||||
resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.47.0.tgz#8cb313e59965d3c05cfbf898915a267af46a335c"
|
||||
integrity sha512-QBmA/G2y+IfeS4oktet3qRZ+P5kPhCKRXxXnQEudYqUaEioAU1/Lq2us3D/t1Jfo4hE9REQPrbB7K5sOczJVIw==
|
||||
mime-db@1.48.0:
|
||||
version "1.48.0"
|
||||
resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.48.0.tgz#e35b31045dd7eada3aaad537ed88a33afbef2d1d"
|
||||
integrity sha512-FM3QwxV+TnZYQ2aRqhlKBMHxk10lTbMt3bBkMAp54ddrNeVSfcQYOOKuGuy3Ddrm38I04If834fOUSq1yzslJQ==
|
||||
|
||||
mime-types@^2.1.12:
|
||||
version "2.1.30"
|
||||
resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.30.tgz#6e7be8b4c479825f85ed6326695db73f9305d62d"
|
||||
integrity sha512-crmjA4bLtR8m9qLpHvgxSChT+XoSlZi8J4n/aIdn3z92e/U47Z0V/yl+Wh9W046GgFVAmoNR/fmdbZYcSSIUeg==
|
||||
version "2.1.31"
|
||||
resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.31.tgz#a00d76b74317c61f9c2db2218b8e9f8e9c5c9e6b"
|
||||
integrity sha512-XGZnNzm3QvgKxa8dpzyhFTHmpP3l5YNusmne07VUOXxou9CqUqYa/HBy124RqtVh/O2pECas/MOcsDgpilPOPg==
|
||||
dependencies:
|
||||
mime-db "1.47.0"
|
||||
mime-db "1.48.0"
|
||||
|
||||
mime@^2.3.1:
|
||||
version "2.5.2"
|
||||
@ -4512,7 +4502,7 @@ object-hash@^2.1.1:
|
||||
resolved "https://registry.yarnpkg.com/object-hash/-/object-hash-2.2.0.tgz#5ad518581eefc443bd763472b8ff2e9c2c0d54a5"
|
||||
integrity sha512-gScRMn0bS5fH+IuwyIFgnh9zBdo4DV+6GhygmWM9HyNJSgS0hScp1f5vjtm7oIIOiT9trXrShAkLFSc2IqKNgw==
|
||||
|
||||
object-inspect@^1.9.0:
|
||||
object-inspect@^1.10.3:
|
||||
version "1.10.3"
|
||||
resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.10.3.tgz#c2aa7d2d09f50c99375704f7a0adf24c5782d369"
|
||||
integrity sha512-e5mCJlSH7poANfC8z8S9s9S2IN5/4Zb3aZ33f5s8YqoazCFzNLloLU8r5VCG+G7WoqLvAAZoVMcy3tp/3X0Plw==
|
||||
@ -5210,16 +5200,7 @@ postcss@^7.0.14, postcss@^7.0.17, postcss@^7.0.2, postcss@^7.0.32, postcss@^7.0.
|
||||
source-map "^0.6.1"
|
||||
supports-color "^6.1.0"
|
||||
|
||||
postcss@^8.1.6, postcss@^8.1.7, postcss@^8.2.1:
|
||||
version "8.2.15"
|
||||
resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.2.15.tgz#9e66ccf07292817d226fc315cbbf9bc148fbca65"
|
||||
integrity sha512-2zO3b26eJD/8rb106Qu2o7Qgg52ND5HPjcyQiK2B98O388h43A448LCslC0dI2P97wCAQRJsFvwTRcXxTKds+Q==
|
||||
dependencies:
|
||||
colorette "^1.2.2"
|
||||
nanoid "^3.1.23"
|
||||
source-map "^0.6.1"
|
||||
|
||||
postcss@^8.3.0:
|
||||
postcss@^8.1.6, postcss@^8.1.7, postcss@^8.2.1, postcss@^8.3.0:
|
||||
version "8.3.0"
|
||||
resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.3.0.tgz#b1a713f6172ca427e3f05ef1303de8b65683325f"
|
||||
integrity sha512-+ogXpdAjWGa+fdYY5BQ96V/6tAo+TdSSIMP5huJBIygdWwKtVoB5JWZ7yUd4xZ8r+8Kvvx4nyg/PQ071H4UtcQ==
|
||||
@ -5258,9 +5239,9 @@ prepend-http@^2.0.0:
|
||||
integrity sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=
|
||||
|
||||
prettier@^2.3.0:
|
||||
version "2.3.0"
|
||||
resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.3.0.tgz#b6a5bf1284026ae640f17f7ff5658a7567fc0d18"
|
||||
integrity sha512-kXtO4s0Lz/DW/IJ9QdWhAf7/NmPWQXkFr/r/WkR3vyI+0v8amTDxiaQSLzs8NBlytfLWX/7uQUMIW677yLKl4w==
|
||||
version "2.3.1"
|
||||
resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.3.1.tgz#76903c3f8c4449bc9ac597acefa24dc5ad4cbea6"
|
||||
integrity sha512-p+vNbgpLjif/+D+DwAZAbndtRrR0md0MwfmOVN9N+2RgyACMT+7tfaRnT+WDPkqnuVwleyuBIG2XBxKDme3hPA==
|
||||
|
||||
pretty-hrtime@^1.0.3:
|
||||
version "1.0.3"
|
||||
@ -6151,9 +6132,9 @@ tabbable@^5.2.0:
|
||||
integrity sha512-0uyt8wbP0P3T4rrsfYg/5Rg3cIJ8Shl1RJ54QMqYxm1TLdWqJD1u6+RQjr2Lor3wmfT7JRHkirIwy99ydBsyPg==
|
||||
|
||||
tailwindcss@^2.1.2:
|
||||
version "2.1.2"
|
||||
resolved "https://registry.yarnpkg.com/tailwindcss/-/tailwindcss-2.1.2.tgz#29402bf73a445faedd03df6d3b177e7b52b7c4a1"
|
||||
integrity sha512-T5t+wwd+/hsOyRw2HJuFuv0LTUm3MUdHm2DJ94GPVgzqwPPFa9XxX0KlwLWupUuiOUj6uiKURCzYPHFcuPch/w==
|
||||
version "2.1.4"
|
||||
resolved "https://registry.yarnpkg.com/tailwindcss/-/tailwindcss-2.1.4.tgz#ee8a1b8ccc140db61960b6738f968a8a1c4cd1f8"
|
||||
integrity sha512-fh1KImDLg6se/Suaelju/5oFbqq1b0ntagmGLu0aG9LlnNPGHgO1n/4E57CbKcCtyz/VYnvVXUiWmfyfBBZQ6g==
|
||||
dependencies:
|
||||
"@fullhuman/postcss-purgecss" "^3.1.3"
|
||||
bytes "^3.0.0"
|
||||
@ -6350,12 +6331,17 @@ type-fest@^0.7.1:
|
||||
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.7.1.tgz#8dda65feaf03ed78f0a3f9678f1869147f7c5c48"
|
||||
integrity sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg==
|
||||
|
||||
typescript@4.2.4:
|
||||
version "4.2.4"
|
||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.2.4.tgz#8610b59747de028fda898a8aef0e103f156d0961"
|
||||
integrity sha512-V+evlYHZnQkaz8TRBuxTA92yZBPotr5H+WhQ7bD3hZUndx5tGOa1fuCgeSjxAzM1RiN5IzvadIXTVefuuwZCRg==
|
||||
|
||||
typescript@^3.9.5, typescript@^3.9.7:
|
||||
version "3.9.9"
|
||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.9.9.tgz#e69905c54bc0681d0518bd4d587cc6f2d0b1a674"
|
||||
integrity sha512-kdMjTiekY+z/ubJCATUPlRDl39vXYiMV9iyeMuEuXZh2we6zz80uovNN2WlAxmmdE/Z/YQe+EbOEXB5RHEED3w==
|
||||
|
||||
typescript@^4.2.3, typescript@^4.2.4:
|
||||
typescript@^4.2.3:
|
||||
version "4.3.2"
|
||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.3.2.tgz#399ab18aac45802d6f2498de5054fcbbe716a805"
|
||||
integrity sha512-zZ4hShnmnoVnAHpVHWpTcxdv7dWP60S2FsydQLV8V5PbS3FifjWFFRiHSWpDJahly88PRyV5teTSLoq4eG7mKw==
|
||||
@ -6365,7 +6351,7 @@ ua-parser-js@^0.7.18:
|
||||
resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.28.tgz#8ba04e653f35ce210239c64661685bf9121dec31"
|
||||
integrity sha512-6Gurc1n//gjp9eQNXjD9O3M/sMwVtN5S8Lv9bvOYBfKfDNiIIhqiyi01vMBO45u4zkDE420w/e0se7Vs+sIg+g==
|
||||
|
||||
unbox-primitive@^1.0.0:
|
||||
unbox-primitive@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.1.tgz#085e215625ec3162574dc8859abee78a59b14471"
|
||||
integrity sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==
|
||||
|
Loading…
x
Reference in New Issue
Block a user