mirror of
https://github.com/vercel/commerce.git
synced 2025-06-08 17:26:59 +00:00
commit
5270d5b9cf
@ -7,6 +7,10 @@ BIGCOMMERCE_STORE_API_URL=
|
|||||||
BIGCOMMERCE_STORE_API_TOKEN=
|
BIGCOMMERCE_STORE_API_TOKEN=
|
||||||
BIGCOMMERCE_STORE_API_CLIENT_ID=
|
BIGCOMMERCE_STORE_API_CLIENT_ID=
|
||||||
BIGCOMMERCE_CHANNEL_ID=
|
BIGCOMMERCE_CHANNEL_ID=
|
||||||
|
BIGCOMMERCE_STORE_URL=
|
||||||
|
BIGCOMMERCE_STORE_API_STORE_HASH=
|
||||||
|
BIGCOMMERCE_STORE_API_CLIENT_SECRET=
|
||||||
|
|
||||||
|
|
||||||
NEXT_PUBLIC_SHOPIFY_STORE_DOMAIN=
|
NEXT_PUBLIC_SHOPIFY_STORE_DOMAIN=
|
||||||
NEXT_PUBLIC_SHOPIFY_STOREFRONT_ACCESS_TOKEN=
|
NEXT_PUBLIC_SHOPIFY_STOREFRONT_ACCESS_TOKEN=
|
||||||
|
10
README.md
10
README.md
@ -66,14 +66,20 @@ Every provider defines the features that it supports under `framework/{provider}
|
|||||||
|
|
||||||
#### Features Available
|
#### Features Available
|
||||||
|
|
||||||
|
The following features can be enabled or disabled. This means that the UI will remove all code related to the feature.
|
||||||
|
For example: Turning `cart` off will disable Cart capabilities.
|
||||||
|
|
||||||
|
- cart
|
||||||
|
- search
|
||||||
- wishlist
|
- wishlist
|
||||||
|
- customerAuth
|
||||||
- customCheckout
|
- customCheckout
|
||||||
|
|
||||||
#### How to turn Features on and off
|
#### How to turn Features on and off
|
||||||
|
|
||||||
> NOTE: The selected provider should support the feature that you are toggling. (This means that you can't turn wishlist on if the provider doesn't support this functionality out the box)
|
> NOTE: The selected provider should support the feature that you are toggling. (This means that you can't turn wishlist on if the provider doesn't support this functionality out the box)
|
||||||
|
|
||||||
- Open `commerce.config.json`
|
- Open `commerce.config.json`
|
||||||
- You'll see a config file like this:
|
- You'll see a config file like this:
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
@ -83,7 +89,7 @@ Every provider defines the features that it supports under `framework/{provider}
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
- Turn wishlist on by setting wishlist to true.
|
- Turn `wishlist` on by setting `wishlist` to `true`.
|
||||||
- Run the app and the wishlist functionality should be back on.
|
- Run the app and the wishlist functionality should be back on.
|
||||||
|
|
||||||
### How to create a new provider
|
### How to create a new provider
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
{
|
{
|
||||||
"features": {
|
"features": {
|
||||||
|
"cart": true,
|
||||||
|
"search": true,
|
||||||
"wishlist": false,
|
"wishlist": false,
|
||||||
|
"customerAuth": false,
|
||||||
"customCheckout": false
|
"customCheckout": false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
.root {
|
.root {
|
||||||
@apply sticky top-0 bg-primary z-40 transition-all duration-150;
|
@apply sticky top-0 bg-primary z-40 transition-all duration-150;
|
||||||
|
min-height: 74px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav {
|
.nav {
|
||||||
|
@ -34,9 +34,11 @@ const Navbar: FC<NavbarProps> = ({ links }) => (
|
|||||||
))}
|
))}
|
||||||
</nav>
|
</nav>
|
||||||
</div>
|
</div>
|
||||||
<div className="justify-center flex-1 hidden lg:flex">
|
{process.env.COMMERCE_SEARCH_ENABLED && (
|
||||||
<Searchbar />
|
<div className="justify-center flex-1 hidden lg:flex">
|
||||||
</div>
|
<Searchbar />
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
<div className="flex items-center justify-end flex-1 space-x-8">
|
<div className="flex items-center justify-end flex-1 space-x-8">
|
||||||
<UserNav />
|
<UserNav />
|
||||||
</div>
|
</div>
|
||||||
|
@ -25,10 +25,12 @@ const UserNav: FC<Props> = ({ className }) => {
|
|||||||
return (
|
return (
|
||||||
<nav className={cn(s.root, className)}>
|
<nav className={cn(s.root, className)}>
|
||||||
<ul className={s.list}>
|
<ul className={s.list}>
|
||||||
<li className={s.item} onClick={toggleSidebar}>
|
{process.env.COMMERCE_CART_ENABLED && (
|
||||||
<Bag />
|
<li className={s.item} onClick={toggleSidebar}>
|
||||||
{itemsCount > 0 && <span className={s.bagCount}>{itemsCount}</span>}
|
<Bag />
|
||||||
</li>
|
{itemsCount > 0 && <span className={s.bagCount}>{itemsCount}</span>}
|
||||||
|
</li>
|
||||||
|
)}
|
||||||
{process.env.COMMERCE_WISHLIST_ENABLED && (
|
{process.env.COMMERCE_WISHLIST_ENABLED && (
|
||||||
<li className={s.item}>
|
<li className={s.item}>
|
||||||
<Link href="/wishlist">
|
<Link href="/wishlist">
|
||||||
@ -38,7 +40,7 @@ const UserNav: FC<Props> = ({ className }) => {
|
|||||||
</Link>
|
</Link>
|
||||||
</li>
|
</li>
|
||||||
)}
|
)}
|
||||||
{process.env.COMMERCE_CUSTOMER_ENABLED && (
|
{process.env.COMMERCE_CUSTOMERAUTH_ENABLED && (
|
||||||
<li className={s.item}>
|
<li className={s.item}>
|
||||||
{customer ? (
|
{customer ? (
|
||||||
<DropdownMenu />
|
<DropdownMenu />
|
||||||
|
@ -11,7 +11,7 @@ interface Props {
|
|||||||
className?: string
|
className?: string
|
||||||
product: Product
|
product: Product
|
||||||
noNameTag?: boolean
|
noNameTag?: boolean
|
||||||
imgProps?: Omit<ImageProps, 'src'>
|
imgProps?: Omit<ImageProps, 'src' | 'layout' | 'placeholder' | 'blurDataURL'>
|
||||||
variant?: 'default' | 'slim' | 'simple'
|
variant?: 'default' | 'slim' | 'simple'
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -83,7 +83,7 @@ const ProductCard: FC<Props> = ({
|
|||||||
<Image
|
<Image
|
||||||
alt={product.name || 'Product Image'}
|
alt={product.name || 'Product Image'}
|
||||||
className={s.productImage}
|
className={s.productImage}
|
||||||
src={product.images[0].url || placeholderImg}
|
src={product.images[0]?.url || placeholderImg}
|
||||||
height={540}
|
height={540}
|
||||||
width={540}
|
width={540}
|
||||||
quality="85"
|
quality="85"
|
||||||
|
@ -56,18 +56,20 @@ const ProductSidebar: FC<ProductSidebarProps> = ({ product, className }) => {
|
|||||||
<div className="text-accent-6 pr-1 font-medium text-sm">36 reviews</div>
|
<div className="text-accent-6 pr-1 font-medium text-sm">36 reviews</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<Button
|
{process.env.COMMERCE_CART_ENABLED && (
|
||||||
aria-label="Add to Cart"
|
<Button
|
||||||
type="button"
|
aria-label="Add to Cart"
|
||||||
className={s.button}
|
type="button"
|
||||||
onClick={addToCart}
|
className={s.button}
|
||||||
loading={loading}
|
onClick={addToCart}
|
||||||
disabled={variant?.availableForSale === false}
|
loading={loading}
|
||||||
>
|
disabled={variant?.availableForSale === false}
|
||||||
{variant?.availableForSale === false
|
>
|
||||||
? 'Not Available'
|
{variant?.availableForSale === false
|
||||||
: 'Add To Cart'}
|
? 'Not Available'
|
||||||
</Button>
|
: 'Add To Cart'}
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div className="mt-6">
|
<div className="mt-6">
|
||||||
<Collapse title="Care">
|
<Collapse title="Care">
|
||||||
|
@ -1,4 +1,7 @@
|
|||||||
import type { CheckoutEndpoint } from '.'
|
import type { CheckoutEndpoint } from '.'
|
||||||
|
import getCustomerId from '../../utils/get-customer-id'
|
||||||
|
import jwt from 'jsonwebtoken'
|
||||||
|
import { uuid } from 'uuidv4'
|
||||||
|
|
||||||
const fullCheckout = true
|
const fullCheckout = true
|
||||||
|
|
||||||
@ -9,22 +12,47 @@ const checkout: CheckoutEndpoint['handlers']['checkout'] = async ({
|
|||||||
}) => {
|
}) => {
|
||||||
const { cookies } = req
|
const { cookies } = req
|
||||||
const cartId = cookies[config.cartCookie]
|
const cartId = cookies[config.cartCookie]
|
||||||
|
const customerToken = cookies[config.customerCookie]
|
||||||
if (!cartId) {
|
if (!cartId) {
|
||||||
res.redirect('/cart')
|
res.redirect('/cart')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const { data } = await config.storeApiFetch(
|
const { data } = await config.storeApiFetch(
|
||||||
`/v3/carts/${cartId}/redirect_urls`,
|
`/v3/carts/${cartId}/redirect_urls`,
|
||||||
{
|
{
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
const customerId =
|
||||||
|
customerToken && (await getCustomerId({ customerToken, config }))
|
||||||
|
|
||||||
if (fullCheckout) {
|
//if there is a customer create a jwt token
|
||||||
res.redirect(data.checkout_url)
|
if (!customerId) {
|
||||||
return
|
if (fullCheckout) {
|
||||||
|
res.redirect(data.checkout_url)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const dateCreated = Math.round(new Date().getTime() / 1000)
|
||||||
|
const payload = {
|
||||||
|
iss: config.storeApiClientId,
|
||||||
|
iat: dateCreated,
|
||||||
|
jti: uuid(),
|
||||||
|
operation: 'customer_login',
|
||||||
|
store_hash: config.storeHash,
|
||||||
|
customer_id: customerId,
|
||||||
|
channel_id: config.storeChannelId,
|
||||||
|
redirect_to: data.checkout_url,
|
||||||
|
}
|
||||||
|
let token = jwt.sign(payload, config.storeApiClientSecret!, {
|
||||||
|
algorithm: 'HS256',
|
||||||
|
})
|
||||||
|
let checkouturl = `${config.storeUrl}/login/token/${token}`
|
||||||
|
console.log('checkouturl', checkouturl)
|
||||||
|
if (fullCheckout) {
|
||||||
|
res.redirect(checkouturl)
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: make the embedded checkout work too!
|
// TODO: make the embedded checkout work too!
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import getCustomerWishlist from '../../operations/get-customer-wishlist'
|
import getCustomerWishlist from '../../operations/get-customer-wishlist'
|
||||||
import { parseWishlistItem } from '../../utils/parse-item'
|
import { parseWishlistItem } from '../../utils/parse-item'
|
||||||
import getCustomerId from './utils/get-customer-id'
|
import getCustomerId from '../../utils/get-customer-id'
|
||||||
import type { WishlistEndpoint } from '.'
|
import type { WishlistEndpoint } from '.'
|
||||||
|
|
||||||
// Return wishlist info
|
// Return wishlist info
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import type { Wishlist } from '../../../types/wishlist'
|
import type { Wishlist } from '../../../types/wishlist'
|
||||||
import type { WishlistEndpoint } from '.'
|
import type { WishlistEndpoint } from '.'
|
||||||
import getCustomerId from './utils/get-customer-id'
|
import getCustomerId from '../../utils/get-customer-id'
|
||||||
import getCustomerWishlist from '../../operations/get-customer-wishlist'
|
import getCustomerWishlist from '../../operations/get-customer-wishlist'
|
||||||
|
|
||||||
// Return wishlist info
|
// Return wishlist info
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import type { Wishlist } from '../../../types/wishlist'
|
import type { Wishlist } from '../../../types/wishlist'
|
||||||
import getCustomerWishlist from '../../operations/get-customer-wishlist'
|
import getCustomerWishlist from '../../operations/get-customer-wishlist'
|
||||||
import getCustomerId from './utils/get-customer-id'
|
import getCustomerId from '../../utils/get-customer-id'
|
||||||
import type { WishlistEndpoint } from '.'
|
import type { WishlistEndpoint } from '.'
|
||||||
|
|
||||||
// Return wishlist info
|
// Return wishlist info
|
||||||
|
@ -32,6 +32,9 @@ export interface BigcommerceConfig extends CommerceAPIConfig {
|
|||||||
storeApiToken: string
|
storeApiToken: string
|
||||||
storeApiClientId: string
|
storeApiClientId: string
|
||||||
storeChannelId?: string
|
storeChannelId?: string
|
||||||
|
storeUrl?: string
|
||||||
|
storeApiClientSecret?: string
|
||||||
|
storeHash?:string
|
||||||
storeApiFetch<T>(endpoint: string, options?: RequestInit): Promise<T>
|
storeApiFetch<T>(endpoint: string, options?: RequestInit): Promise<T>
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -41,6 +44,9 @@ const STORE_API_URL = process.env.BIGCOMMERCE_STORE_API_URL
|
|||||||
const STORE_API_TOKEN = process.env.BIGCOMMERCE_STORE_API_TOKEN
|
const STORE_API_TOKEN = process.env.BIGCOMMERCE_STORE_API_TOKEN
|
||||||
const STORE_API_CLIENT_ID = process.env.BIGCOMMERCE_STORE_API_CLIENT_ID
|
const STORE_API_CLIENT_ID = process.env.BIGCOMMERCE_STORE_API_CLIENT_ID
|
||||||
const STORE_CHANNEL_ID = process.env.BIGCOMMERCE_CHANNEL_ID
|
const STORE_CHANNEL_ID = process.env.BIGCOMMERCE_CHANNEL_ID
|
||||||
|
const STORE_URL = process.env.BIGCOMMERCE_STORE_URL
|
||||||
|
const CLIENT_SECRET = process.env.BIGCOMMERCE_STORE_API_CLIENT_SECRET
|
||||||
|
const STOREFRONT_HASH = process.env.BIGCOMMERCE_STORE_API_STORE_HASH
|
||||||
|
|
||||||
if (!API_URL) {
|
if (!API_URL) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
@ -75,6 +81,9 @@ const config: BigcommerceConfig = {
|
|||||||
storeApiToken: STORE_API_TOKEN,
|
storeApiToken: STORE_API_TOKEN,
|
||||||
storeApiClientId: STORE_API_CLIENT_ID,
|
storeApiClientId: STORE_API_CLIENT_ID,
|
||||||
storeChannelId: STORE_CHANNEL_ID,
|
storeChannelId: STORE_CHANNEL_ID,
|
||||||
|
storeUrl:STORE_URL,
|
||||||
|
storeApiClientSecret:CLIENT_SECRET,
|
||||||
|
storeHash: STOREFRONT_HASH,
|
||||||
storeApiFetch: createFetchStoreApi(() => getCommerceApi().getConfig()),
|
storeApiFetch: createFetchStoreApi(() => getCommerceApi().getConfig()),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import type { GetCustomerIdQuery } from '../../../../schema'
|
import type { GetCustomerIdQuery } from '../../schema'
|
||||||
import type { BigcommerceConfig } from '../../..'
|
import type { BigcommerceConfig } from '../'
|
||||||
|
|
||||||
export const getCustomerIdQuery = /* GraphQL */ `
|
export const getCustomerIdQuery = /* GraphQL */ `
|
||||||
query getCustomerId {
|
query getCustomerId {
|
@ -1,6 +1,7 @@
|
|||||||
{
|
{
|
||||||
"provider": "bigcommerce",
|
"provider": "bigcommerce",
|
||||||
"features": {
|
"features": {
|
||||||
"wishlist": true
|
"wishlist": true,
|
||||||
|
"customerAuth": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -57,11 +57,27 @@ function withCommerceConfig(nextConfig = {}) {
|
|||||||
|
|
||||||
// Update paths in `tsconfig.json` to point to the selected provider
|
// Update paths in `tsconfig.json` to point to the selected provider
|
||||||
if (config.commerce.updateTSConfig !== false) {
|
if (config.commerce.updateTSConfig !== false) {
|
||||||
const staticTsconfigPath = path.join(process.cwd(), 'tsconfig.json')
|
const tsconfigPath = path.join(process.cwd(), 'tsconfig.json')
|
||||||
const tsconfig = require('../../tsconfig.js')
|
const tsconfig = require(tsconfigPath)
|
||||||
|
|
||||||
|
tsconfig.compilerOptions.paths['@framework'] = [`framework/${name}`]
|
||||||
|
tsconfig.compilerOptions.paths['@framework/*'] = [`framework/${name}/*`]
|
||||||
|
|
||||||
|
// When running for production it may be useful to exclude the other providers
|
||||||
|
// from TS checking
|
||||||
|
if (process.env.VERCEL) {
|
||||||
|
const exclude = tsconfig.exclude.filter(
|
||||||
|
(item) => !item.startsWith('framework/')
|
||||||
|
)
|
||||||
|
|
||||||
|
tsconfig.exclude = PROVIDERS.reduce((exclude, current) => {
|
||||||
|
if (current !== name) exclude.push(`framework/${current}`)
|
||||||
|
return exclude
|
||||||
|
}, exclude)
|
||||||
|
}
|
||||||
|
|
||||||
fs.writeFileSync(
|
fs.writeFileSync(
|
||||||
staticTsconfigPath,
|
tsconfigPath,
|
||||||
prettier.format(JSON.stringify(tsconfig), { parser: 'json' })
|
prettier.format(JSON.stringify(tsconfig), { parser: 'json' })
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import useSWR, { responseInterface } from 'swr'
|
import useSWR, { SWRResponse } from 'swr'
|
||||||
import type {
|
import type {
|
||||||
HookSWRInput,
|
HookSWRInput,
|
||||||
HookFetchInput,
|
HookFetchInput,
|
||||||
@ -11,7 +11,7 @@ import type {
|
|||||||
import defineProperty from './define-property'
|
import defineProperty from './define-property'
|
||||||
import { CommerceError } from './errors'
|
import { CommerceError } from './errors'
|
||||||
|
|
||||||
export type ResponseState<Result> = responseInterface<Result, CommerceError> & {
|
export type ResponseState<Result> = SWRResponse<Result, CommerceError> & {
|
||||||
isLoading: boolean
|
isLoading: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -72,7 +72,7 @@ const useData: UseData = (options, input, fetcherFn, swrOptions) => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
return response
|
return response as typeof response & { isLoading: boolean }
|
||||||
}
|
}
|
||||||
|
|
||||||
export default useData
|
export default useData
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
{
|
{
|
||||||
"provider": "local",
|
"provider": "local",
|
||||||
"features": {
|
"features": {
|
||||||
"wishlist": false
|
"wishlist": false,
|
||||||
|
"cart": false,
|
||||||
|
"search": false,
|
||||||
|
"customerAuth": false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"schema": {
|
"schema": {
|
||||||
"https://${NEXT_PUBLIC_SHOPIFY_STORE_DOMAIN}/api/2021-01/graphql.json": {
|
"https://${NEXT_PUBLIC_SHOPIFY_STORE_DOMAIN}/api/2021-07/graphql.json": {
|
||||||
"headers": {
|
"headers": {
|
||||||
"X-Shopify-Storefront-Access-Token": "${NEXT_PUBLIC_SHOPIFY_STOREFRONT_ACCESS_TOKEN}"
|
"X-Shopify-Storefront-Access-Token": "${NEXT_PUBLIC_SHOPIFY_STOREFRONT_ACCESS_TOKEN}"
|
||||||
}
|
}
|
||||||
|
1
next-env.d.ts
vendored
1
next-env.d.ts
vendored
@ -1,2 +1,3 @@
|
|||||||
/// <reference types="next" />
|
/// <reference types="next" />
|
||||||
/// <reference types="next/types/global" />
|
/// <reference types="next/types/global" />
|
||||||
|
/// <reference types="next/image-types/global" />
|
||||||
|
@ -12,9 +12,6 @@ const isSwell = provider === 'swell'
|
|||||||
const isVendure = provider === 'vendure'
|
const isVendure = provider === 'vendure'
|
||||||
|
|
||||||
module.exports = withCommerceConfig({
|
module.exports = withCommerceConfig({
|
||||||
future: {
|
|
||||||
webpack5: true,
|
|
||||||
},
|
|
||||||
commerce,
|
commerce,
|
||||||
i18n: {
|
i18n: {
|
||||||
locales: ['en-US', 'es'],
|
locales: ['en-US', 'es'],
|
||||||
|
11033
package-lock.json
generated
11033
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
31
package.json
31
package.json
@ -7,7 +7,7 @@
|
|||||||
"start": "next start",
|
"start": "next start",
|
||||||
"analyze": "BUNDLE_ANALYZE=both yarn build",
|
"analyze": "BUNDLE_ANALYZE=both yarn build",
|
||||||
"prettier-fix": "prettier --write .",
|
"prettier-fix": "prettier --write .",
|
||||||
"find:unused": "next-unused",
|
"find:unused": "npx next-unused",
|
||||||
"generate": "graphql-codegen",
|
"generate": "graphql-codegen",
|
||||||
"generate:shopify": "DOTENV_CONFIG_PATH=./.env.local graphql-codegen -r dotenv/config --config framework/shopify/codegen.json",
|
"generate:shopify": "DOTENV_CONFIG_PATH=./.env.local graphql-codegen -r dotenv/config --config framework/shopify/codegen.json",
|
||||||
"generate:vendure": "graphql-codegen --config framework/vendure/codegen.json",
|
"generate:vendure": "graphql-codegen --config framework/vendure/codegen.json",
|
||||||
@ -23,39 +23,36 @@
|
|||||||
"@vercel/fetch": "^6.1.0",
|
"@vercel/fetch": "^6.1.0",
|
||||||
"autoprefixer": "^10.2.6",
|
"autoprefixer": "^10.2.6",
|
||||||
"body-scroll-lock": "^3.1.5",
|
"body-scroll-lock": "^3.1.5",
|
||||||
"bowser": "^2.11.0",
|
|
||||||
"classnames": "^2.3.1",
|
"classnames": "^2.3.1",
|
||||||
"cookie": "^0.4.1",
|
"cookie": "^0.4.1",
|
||||||
"dot-object": "^2.1.4",
|
|
||||||
"email-validator": "^2.0.4",
|
"email-validator": "^2.0.4",
|
||||||
"immutability-helper": "^3.1.1",
|
"immutability-helper": "^3.1.1",
|
||||||
"isomorphic-unfetch": "^3.1.0",
|
|
||||||
"js-cookie": "^2.2.1",
|
"js-cookie": "^2.2.1",
|
||||||
"keen-slider": "^5.4.1",
|
"keen-slider": "^5.5.1",
|
||||||
"lodash.debounce": "^4.0.8",
|
"lodash.debounce": "^4.0.8",
|
||||||
"lodash.random": "^3.2.0",
|
"lodash.random": "^3.2.0",
|
||||||
"lodash.throttle": "^4.1.1",
|
"lodash.throttle": "^4.1.1",
|
||||||
"next": "10.0.9-canary.5",
|
"next": "^11.0.0",
|
||||||
"next-seo": "^4.24.0",
|
"next-seo": "^4.26.0",
|
||||||
"next-themes": "^0.0.14",
|
"next-themes": "^0.0.14",
|
||||||
"postcss": "^8.3.0",
|
"postcss": "^8.3.5",
|
||||||
"postcss-nesting": "^8.0.1",
|
"postcss-nesting": "^8.0.1",
|
||||||
"react": "^17.0.2",
|
"react": "^17.0.2",
|
||||||
"react-dom": "^17.0.2",
|
"react-dom": "^17.0.2",
|
||||||
"react-fast-marquee": "^1.1.3",
|
"react-fast-marquee": "^1.1.4",
|
||||||
"react-merge-refs": "^1.1.0",
|
"react-merge-refs": "^1.1.0",
|
||||||
"react-use-measure": "^2.0.4",
|
"react-use-measure": "^2.0.4",
|
||||||
"shopify-buy": "^2.11.0",
|
|
||||||
"swell-js": "^4.0.0-next.0",
|
"swell-js": "^4.0.0-next.0",
|
||||||
"swr": "^0.5.6",
|
"swr": "^0.5.6",
|
||||||
"tabbable": "^5.2.0",
|
"tabbable": "^5.2.0",
|
||||||
"tailwindcss": "^2.1.2"
|
"tailwindcss": "^2.2.2",
|
||||||
|
"uuidv4": "^6.2.10"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@graphql-codegen/cli": "^1.21.5",
|
"@graphql-codegen/cli": "^1.21.5",
|
||||||
"@graphql-codegen/schema-ast": "^1.18.3",
|
"@graphql-codegen/schema-ast": "^1.18.3",
|
||||||
"@graphql-codegen/typescript": "^1.22.1",
|
"@graphql-codegen/typescript": "^1.22.2",
|
||||||
"@graphql-codegen/typescript-operations": "^1.18.0",
|
"@graphql-codegen/typescript-operations": "^1.18.1",
|
||||||
"@next/bundle-analyzer": "^10.2.3",
|
"@next/bundle-analyzer": "^10.2.3",
|
||||||
"@types/body-scroll-lock": "^2.6.1",
|
"@types/body-scroll-lock": "^2.6.1",
|
||||||
"@types/cookie": "^0.4.0",
|
"@types/cookie": "^0.4.0",
|
||||||
@ -63,18 +60,16 @@
|
|||||||
"@types/lodash.debounce": "^4.0.6",
|
"@types/lodash.debounce": "^4.0.6",
|
||||||
"@types/lodash.random": "^3.2.6",
|
"@types/lodash.random": "^3.2.6",
|
||||||
"@types/lodash.throttle": "^4.1.6",
|
"@types/lodash.throttle": "^4.1.6",
|
||||||
"@types/node": "^15.6.1",
|
"@types/node": "^15.12.4",
|
||||||
"@types/react": "^17.0.8",
|
"@types/react": "^17.0.8",
|
||||||
"@types/shopify-buy": "^2.10.5",
|
|
||||||
"deepmerge": "^4.2.2",
|
"deepmerge": "^4.2.2",
|
||||||
"graphql": "^15.5.0",
|
"graphql": "^15.5.1",
|
||||||
"husky": "^6.0.0",
|
"husky": "^6.0.0",
|
||||||
"lint-staged": "^11.0.0",
|
"lint-staged": "^11.0.0",
|
||||||
"next-unused": "^0.0.6",
|
|
||||||
"postcss-flexbugs-fixes": "^5.0.2",
|
"postcss-flexbugs-fixes": "^5.0.2",
|
||||||
"postcss-preset-env": "^6.7.0",
|
"postcss-preset-env": "^6.7.0",
|
||||||
"prettier": "^2.3.0",
|
"prettier": "^2.3.0",
|
||||||
"typescript": "4.2.4"
|
"typescript": "4.3.4"
|
||||||
},
|
},
|
||||||
"husky": {
|
"husky": {
|
||||||
"hooks": {
|
"hooks": {
|
||||||
|
57
tsconfig.js
57
tsconfig.js
@ -1,57 +0,0 @@
|
|||||||
const PROVIDERS = ['bigcommerce', 'shopify', 'swell', 'vendure', 'saleor']
|
|
||||||
|
|
||||||
function getProviderName() {
|
|
||||||
return (
|
|
||||||
process.env.COMMERCE_PROVIDER ||
|
|
||||||
(process.env.BIGCOMMERCE_STOREFRONT_API_URL
|
|
||||||
? 'bigcommerce'
|
|
||||||
: process.env.NEXT_PUBLIC_SHOPIFY_STORE_DOMAIN
|
|
||||||
? 'shopify'
|
|
||||||
: process.env.NEXT_PUBLIC_SWELL_STORE_ID
|
|
||||||
? 'swell'
|
|
||||||
: 'local')
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
const name = getProviderName()
|
|
||||||
const EXCLUDED_PROVIDERS = PROVIDERS.filter((p) => p !== name).map(
|
|
||||||
(p) => `./framework/${p}`
|
|
||||||
)
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
compilerOptions: {
|
|
||||||
baseUrl: '.',
|
|
||||||
target: 'esnext',
|
|
||||||
lib: ['dom', 'dom.iterable', 'esnext'],
|
|
||||||
allowJs: true,
|
|
||||||
skipLibCheck: true,
|
|
||||||
strict: true,
|
|
||||||
forceConsistentCasingInFileNames: true,
|
|
||||||
noEmit: true,
|
|
||||||
esModuleInterop: true,
|
|
||||||
module: 'esnext',
|
|
||||||
moduleResolution: 'node',
|
|
||||||
resolveJsonModule: true,
|
|
||||||
isolatedModules: true,
|
|
||||||
jsx: 'preserve',
|
|
||||||
paths: {
|
|
||||||
'@lib/*': ['lib/*'],
|
|
||||||
'@utils/*': ['utils/*'],
|
|
||||||
'@config/*': ['config/*'],
|
|
||||||
'@assets/*': ['assets/*'],
|
|
||||||
'@components/*': ['components/*'],
|
|
||||||
'@commerce': ['framework/commerce'],
|
|
||||||
'@commerce/*': ['framework/commerce/*'],
|
|
||||||
// Update paths to point to the selected provider
|
|
||||||
'@framework': [`framework/${name}`],
|
|
||||||
'@framework/*': [`framework/${name}/*`],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
include: ['next-env.d.ts', '**/*.d.ts', '**/*.ts', '**/*.tsx', '**/*.js'],
|
|
||||||
exclude: [
|
|
||||||
'node_modules',
|
|
||||||
// It may be useful to exclude the other providers
|
|
||||||
// from TS checking
|
|
||||||
...EXCLUDED_PROVIDERS,
|
|
||||||
],
|
|
||||||
}
|
|
@ -14,6 +14,7 @@
|
|||||||
"resolveJsonModule": true,
|
"resolveJsonModule": true,
|
||||||
"isolatedModules": true,
|
"isolatedModules": true,
|
||||||
"jsx": "preserve",
|
"jsx": "preserve",
|
||||||
|
"incremental": true,
|
||||||
"paths": {
|
"paths": {
|
||||||
"@lib/*": ["lib/*"],
|
"@lib/*": ["lib/*"],
|
||||||
"@utils/*": ["utils/*"],
|
"@utils/*": ["utils/*"],
|
||||||
|
Loading…
x
Reference in New Issue
Block a user