-}
-
-const API_URL = process.env.BIGCOMMERCE_STOREFRONT_API_URL
-const API_TOKEN = process.env.BIGCOMMERCE_STOREFRONT_API_TOKEN
-const STORE_API_URL = process.env.BIGCOMMERCE_STORE_API_URL
-const STORE_API_TOKEN = process.env.BIGCOMMERCE_STORE_API_TOKEN
-const STORE_API_CLIENT_ID = process.env.BIGCOMMERCE_STORE_API_CLIENT_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) {
- throw new Error(
- `The environment variable BIGCOMMERCE_STOREFRONT_API_URL is missing and it's required to access your store`
- )
-}
-
-if (!API_TOKEN) {
- throw new Error(
- `The environment variable BIGCOMMERCE_STOREFRONT_API_TOKEN is missing and it's required to access your store`
- )
-}
-
-if (!(STORE_API_URL && STORE_API_TOKEN && STORE_API_CLIENT_ID)) {
- throw new Error(
- `The environment variables BIGCOMMERCE_STORE_API_URL, BIGCOMMERCE_STORE_API_TOKEN, BIGCOMMERCE_STORE_API_CLIENT_ID have to be set in order to access the REST API of your store`
- )
-}
-
-const ONE_DAY = 60 * 60 * 24
-
-const config: BigcommerceConfig = {
- commerceUrl: API_URL,
- apiToken: API_TOKEN,
- customerCookie: 'SHOP_TOKEN',
- cartCookie: process.env.BIGCOMMERCE_CART_COOKIE ?? 'bc_cartId',
- cartCookieMaxAge: ONE_DAY * 30,
- fetch: createFetchGraphqlApi(() => getCommerceApi().getConfig()),
- applyLocale: true,
- // REST API only
- storeApiUrl: STORE_API_URL,
- storeApiToken: STORE_API_TOKEN,
- storeApiClientId: STORE_API_CLIENT_ID,
- storeChannelId: STORE_CHANNEL_ID,
- storeUrl:STORE_URL,
- storeApiClientSecret:CLIENT_SECRET,
- storeHash: STOREFRONT_HASH,
- storeApiFetch: createFetchStoreApi(() => getCommerceApi().getConfig()),
-}
-
-const operations = {
- login,
- getAllPages,
- getPage,
- getSiteInfo,
- getCustomerWishlist,
- getAllProductPaths,
- getAllProducts,
- getProduct,
-}
-
-export const provider = { config, operations }
-
-export type Provider = typeof provider
-
-export type APIs =
- | CartAPI
- | CustomerAPI
- | LoginAPI
- | LogoutAPI
- | SignupAPI
- | ProductsAPI
- | WishlistAPI
-
-export type BigcommerceAPI = CommerceAPI
-
-export function getCommerceApi
(
- customProvider: P = provider as any
-): BigcommerceAPI
{
- return commerceApi(customProvider)
-}
diff --git a/framework/bigcommerce/api/operations/get-all-pages.ts b/framework/bigcommerce/api/operations/get-all-pages.ts
deleted file mode 100644
index 3a9b64b1f..000000000
--- a/framework/bigcommerce/api/operations/get-all-pages.ts
+++ /dev/null
@@ -1,46 +0,0 @@
-import type {
- OperationContext,
- OperationOptions,
-} from '@commerce/api/operations'
-import type { Page, GetAllPagesOperation } from '../../types/page'
-import type { RecursivePartial, RecursiveRequired } from '../utils/types'
-import { BigcommerceConfig, Provider } from '..'
-
-export default function getAllPagesOperation({
- commerce,
-}: OperationContext) {
- async function getAllPages(opts?: {
- config?: Partial
- preview?: boolean
- }): Promise
-
- async function getAllPages(
- opts: {
- config?: Partial
- preview?: boolean
- } & OperationOptions
- ): Promise
-
- async function getAllPages({
- config,
- preview,
- }: {
- url?: string
- config?: Partial
- preview?: boolean
- } = {}): Promise {
- const cfg = commerce.getConfig(config)
- // RecursivePartial forces the method to check for every prop in the data, which is
- // required in case there's a custom `url`
- const { data } = await cfg.storeApiFetch<
- RecursivePartial<{ data: Page[] }>
- >('/v3/content/pages')
- const pages = (data as RecursiveRequired) ?? []
-
- return {
- pages: preview ? pages : pages.filter((p) => p.is_visible),
- }
- }
-
- return getAllPages
-}
diff --git a/framework/bigcommerce/api/operations/get-all-product-paths.ts b/framework/bigcommerce/api/operations/get-all-product-paths.ts
deleted file mode 100644
index da7b457eb..000000000
--- a/framework/bigcommerce/api/operations/get-all-product-paths.ts
+++ /dev/null
@@ -1,66 +0,0 @@
-import type {
- OperationContext,
- OperationOptions,
-} from '@commerce/api/operations'
-import type { GetAllProductPathsQuery } from '../../schema'
-import type { GetAllProductPathsOperation } from '../../types/product'
-import type { RecursivePartial, RecursiveRequired } from '../utils/types'
-import filterEdges from '../utils/filter-edges'
-import { BigcommerceConfig, Provider } from '..'
-
-export const getAllProductPathsQuery = /* GraphQL */ `
- query getAllProductPaths($first: Int = 100) {
- site {
- products(first: $first) {
- edges {
- node {
- path
- }
- }
- }
- }
- }
-`
-
-export default function getAllProductPathsOperation({
- commerce,
-}: OperationContext) {
- async function getAllProductPaths<
- T extends GetAllProductPathsOperation
- >(opts?: {
- variables?: T['variables']
- config?: BigcommerceConfig
- }): Promise
-
- async function getAllProductPaths(
- opts: {
- variables?: T['variables']
- config?: BigcommerceConfig
- } & OperationOptions
- ): Promise
-
- async function getAllProductPaths({
- query = getAllProductPathsQuery,
- variables,
- config,
- }: {
- query?: string
- variables?: T['variables']
- config?: BigcommerceConfig
- } = {}): Promise {
- config = commerce.getConfig(config)
- // RecursivePartial forces the method to check for every prop in the data, which is
- // required in case there's a custom `query`
- const { data } = await config.fetch<
- RecursivePartial
- >(query, { variables })
- const products = data.site?.products?.edges
-
- return {
- products: filterEdges(products as RecursiveRequired).map(
- ({ node }) => node
- ),
- }
- }
- return getAllProductPaths
-}
diff --git a/framework/bigcommerce/api/operations/get-all-products.ts b/framework/bigcommerce/api/operations/get-all-products.ts
deleted file mode 100644
index c2652f5bf..000000000
--- a/framework/bigcommerce/api/operations/get-all-products.ts
+++ /dev/null
@@ -1,135 +0,0 @@
-import type {
- OperationContext,
- OperationOptions,
-} from '@commerce/api/operations'
-import type {
- GetAllProductsQuery,
- GetAllProductsQueryVariables,
-} from '../../schema'
-import type { GetAllProductsOperation } from '../../types/product'
-import type { RecursivePartial, RecursiveRequired } from '../utils/types'
-import filterEdges from '../utils/filter-edges'
-import setProductLocaleMeta from '../utils/set-product-locale-meta'
-import { productConnectionFragment } from '../fragments/product'
-import { BigcommerceConfig, Provider } from '..'
-import { normalizeProduct } from '../../lib/normalize'
-
-export const getAllProductsQuery = /* GraphQL */ `
- query getAllProducts(
- $hasLocale: Boolean = false
- $locale: String = "null"
- $entityIds: [Int!]
- $first: Int = 10
- $products: Boolean = false
- $featuredProducts: Boolean = false
- $bestSellingProducts: Boolean = false
- $newestProducts: Boolean = false
- ) {
- site {
- products(first: $first, entityIds: $entityIds) @include(if: $products) {
- ...productConnnection
- }
- featuredProducts(first: $first) @include(if: $featuredProducts) {
- ...productConnnection
- }
- bestSellingProducts(first: $first) @include(if: $bestSellingProducts) {
- ...productConnnection
- }
- newestProducts(first: $first) @include(if: $newestProducts) {
- ...productConnnection
- }
- }
- }
-
- ${productConnectionFragment}
-`
-
-export type ProductEdge = NonNullable<
- NonNullable[0]
->
-
-export type ProductNode = ProductEdge['node']
-
-export type GetAllProductsResult<
- T extends Record = {
- products: ProductEdge[]
- }
-> = T
-
-function getProductsType(
- relevance?: GetAllProductsOperation['variables']['relevance']
-) {
- switch (relevance) {
- case 'featured':
- return 'featuredProducts'
- case 'best_selling':
- return 'bestSellingProducts'
- case 'newest':
- return 'newestProducts'
- default:
- return 'products'
- }
-}
-
-export default function getAllProductsOperation({
- commerce,
-}: OperationContext) {
- async function getAllProducts(opts?: {
- variables?: T['variables']
- config?: Partial
- preview?: boolean
- }): Promise
-
- async function getAllProducts(
- opts: {
- variables?: T['variables']
- config?: Partial
- preview?: boolean
- } & OperationOptions
- ): Promise
-
- async function getAllProducts({
- query = getAllProductsQuery,
- variables: vars = {},
- config: cfg,
- }: {
- query?: string
- variables?: T['variables']
- config?: Partial
- preview?: boolean
- } = {}): Promise {
- const config = commerce.getConfig(cfg)
- const { locale } = config
- const field = getProductsType(vars.relevance)
- const variables: GetAllProductsQueryVariables = {
- locale,
- hasLocale: !!locale,
- }
-
- variables[field] = true
-
- if (vars.first) variables.first = vars.first
- if (vars.ids) variables.entityIds = vars.ids.map((id) => Number(id))
-
- // RecursivePartial forces the method to check for every prop in the data, which is
- // required in case there's a custom `query`
- const { data } = await config.fetch>(
- query,
- { variables }
- )
- const edges = data.site?.[field]?.edges
- const products = filterEdges(edges as RecursiveRequired)
-
- if (locale && config.applyLocale) {
- products.forEach((product: RecursivePartial) => {
- if (product.node) setProductLocaleMeta(product.node)
- })
- }
-
- return {
- products: products.map(({ node }) => normalizeProduct(node as any)),
- }
- }
-
- return getAllProducts
-}
diff --git a/framework/bigcommerce/api/operations/get-customer-wishlist.ts b/framework/bigcommerce/api/operations/get-customer-wishlist.ts
deleted file mode 100644
index fc9487ffe..000000000
--- a/framework/bigcommerce/api/operations/get-customer-wishlist.ts
+++ /dev/null
@@ -1,81 +0,0 @@
-import type {
- OperationContext,
- OperationOptions,
-} from '@commerce/api/operations'
-import type {
- GetCustomerWishlistOperation,
- Wishlist,
-} from '../../types/wishlist'
-import type { RecursivePartial, RecursiveRequired } from '../utils/types'
-import { BigcommerceConfig, Provider } from '..'
-import getAllProducts, { ProductEdge } from './get-all-products'
-
-export default function getCustomerWishlistOperation({
- commerce,
-}: OperationContext) {
- async function getCustomerWishlist<
- T extends GetCustomerWishlistOperation
- >(opts: {
- variables: T['variables']
- config?: BigcommerceConfig
- includeProducts?: boolean
- }): Promise
-
- async function getCustomerWishlist(
- opts: {
- variables: T['variables']
- config?: BigcommerceConfig
- includeProducts?: boolean
- } & OperationOptions
- ): Promise
-
- async function getCustomerWishlist({
- config,
- variables,
- includeProducts,
- }: {
- url?: string
- variables: T['variables']
- config?: BigcommerceConfig
- includeProducts?: boolean
- }): Promise {
- config = commerce.getConfig(config)
-
- const { data = [] } = await config.storeApiFetch<
- RecursivePartial<{ data: Wishlist[] }>
- >(`/v3/wishlists?customer_id=${variables.customerId}`)
- const wishlist = data[0]
-
- if (includeProducts && wishlist?.items?.length) {
- const ids = wishlist.items
- ?.map((item) => (item?.product_id ? String(item?.product_id) : null))
- .filter((id): id is string => !!id)
-
- if (ids?.length) {
- const graphqlData = await commerce.getAllProducts({
- variables: { first: 100, ids },
- config,
- })
- // Put the products in an object that we can use to get them by id
- const productsById = graphqlData.products.reduce<{
- [k: number]: ProductEdge
- }>((prods, p) => {
- prods[Number(p.id)] = p as any
- return prods
- }, {})
- // Populate the wishlist items with the graphql products
- wishlist.items.forEach((item) => {
- const product = item && productsById[item.product_id!]
- if (item && product) {
- // @ts-ignore Fix this type when the wishlist type is properly defined
- item.product = product
- }
- })
- }
- }
-
- return { wishlist: wishlist as RecursiveRequired }
- }
-
- return getCustomerWishlist
-}
diff --git a/framework/bigcommerce/api/operations/get-page.ts b/framework/bigcommerce/api/operations/get-page.ts
deleted file mode 100644
index 6a1fea9d0..000000000
--- a/framework/bigcommerce/api/operations/get-page.ts
+++ /dev/null
@@ -1,54 +0,0 @@
-import type {
- OperationContext,
- OperationOptions,
-} from '@commerce/api/operations'
-import type { GetPageOperation, Page } from '../../types/page'
-import type { RecursivePartial, RecursiveRequired } from '../utils/types'
-import type { BigcommerceConfig, Provider } from '..'
-import { normalizePage } from '../../lib/normalize'
-
-export default function getPageOperation({
- commerce,
-}: OperationContext) {
- async function getPage(opts: {
- variables: T['variables']
- config?: Partial
- preview?: boolean
- }): Promise
-
- async function getPage(
- opts: {
- variables: T['variables']
- config?: Partial
- preview?: boolean
- } & OperationOptions
- ): Promise
-
- async function getPage({
- url,
- variables,
- config,
- preview,
- }: {
- url?: string
- variables: T['variables']
- config?: Partial
- preview?: boolean
- }): Promise {
- const cfg = commerce.getConfig(config)
- // RecursivePartial forces the method to check for every prop in the data, which is
- // required in case there's a custom `url`
- const { data } = await cfg.storeApiFetch<
- RecursivePartial<{ data: Page[] }>
- >(url || `/v3/content/pages?id=${variables.id}&include=body`)
- const firstPage = data?.[0]
- const page = firstPage as RecursiveRequired
-
- if (preview || page?.is_visible) {
- return { page: normalizePage(page as any) }
- }
- return {}
- }
-
- return getPage
-}
diff --git a/framework/bigcommerce/api/operations/get-product.ts b/framework/bigcommerce/api/operations/get-product.ts
deleted file mode 100644
index fb356e952..000000000
--- a/framework/bigcommerce/api/operations/get-product.ts
+++ /dev/null
@@ -1,119 +0,0 @@
-import type {
- OperationContext,
- OperationOptions,
-} from '@commerce/api/operations'
-import type { GetProductOperation } from '../../types/product'
-import type { GetProductQuery, GetProductQueryVariables } from '../../schema'
-import setProductLocaleMeta from '../utils/set-product-locale-meta'
-import { productInfoFragment } from '../fragments/product'
-import { BigcommerceConfig, Provider } from '..'
-import { normalizeProduct } from '../../lib/normalize'
-
-export const getProductQuery = /* GraphQL */ `
- query getProduct(
- $hasLocale: Boolean = false
- $locale: String = "null"
- $path: String!
- ) {
- site {
- route(path: $path) {
- node {
- __typename
- ... on Product {
- ...productInfo
- variants {
- edges {
- node {
- entityId
- defaultImage {
- urlOriginal
- altText
- isDefault
- }
- prices {
- ...productPrices
- }
- inventory {
- aggregated {
- availableToSell
- warningLevel
- }
- isInStock
- }
- productOptions {
- edges {
- node {
- __typename
- entityId
- displayName
- ...multipleChoiceOption
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
-
- ${productInfoFragment}
-`
-
-// TODO: See if this type is useful for defining the Product type
-// export type ProductNode = Extract<
-// GetProductQuery['site']['route']['node'],
-// { __typename: 'Product' }
-// >
-
-export default function getAllProductPathsOperation({
- commerce,
-}: OperationContext) {
- async function getProduct(opts: {
- variables: T['variables']
- config?: Partial
- preview?: boolean
- }): Promise
-
- async function getProduct(
- opts: {
- variables: T['variables']
- config?: Partial
- preview?: boolean
- } & OperationOptions
- ): Promise
-
- async function getProduct({
- query = getProductQuery,
- variables: { slug, ...vars },
- config: cfg,
- }: {
- query?: string
- variables: T['variables']
- config?: Partial
- preview?: boolean
- }): Promise {
- const config = commerce.getConfig(cfg)
- const { locale } = config
- const variables: GetProductQueryVariables = {
- locale,
- hasLocale: !!locale,
- path: slug ? `/${slug}/` : vars.path!,
- }
- const { data } = await config.fetch(query, { variables })
- const product = data.site?.route?.node
-
- if (product?.__typename === 'Product') {
- if (locale && config.applyLocale) {
- setProductLocaleMeta(product)
- }
-
- return { product: normalizeProduct(product as any) }
- }
-
- return {}
- }
- return getProduct
-}
diff --git a/framework/bigcommerce/api/operations/get-site-info.ts b/framework/bigcommerce/api/operations/get-site-info.ts
deleted file mode 100644
index 0dd94dd9d..000000000
--- a/framework/bigcommerce/api/operations/get-site-info.ts
+++ /dev/null
@@ -1,87 +0,0 @@
-import type {
- OperationContext,
- OperationOptions,
-} from '@commerce/api/operations'
-import type { GetSiteInfoOperation } from '../../types/site'
-import type { GetSiteInfoQuery } from '../../schema'
-import filterEdges from '../utils/filter-edges'
-import type { BigcommerceConfig, Provider } from '..'
-import { categoryTreeItemFragment } from '../fragments/category-tree'
-import { normalizeCategory } from '../../lib/normalize'
-
-// Get 3 levels of categories
-export const getSiteInfoQuery = /* GraphQL */ `
- query getSiteInfo {
- site {
- categoryTree {
- ...categoryTreeItem
- children {
- ...categoryTreeItem
- children {
- ...categoryTreeItem
- }
- }
- }
- brands {
- pageInfo {
- startCursor
- endCursor
- }
- edges {
- cursor
- node {
- entityId
- name
- defaultImage {
- urlOriginal
- altText
- }
- pageTitle
- metaDesc
- metaKeywords
- searchKeywords
- path
- }
- }
- }
- }
- }
- ${categoryTreeItemFragment}
-`
-
-export default function getSiteInfoOperation({
- commerce,
-}: OperationContext) {
- async function getSiteInfo(opts?: {
- config?: Partial
- preview?: boolean
- }): Promise
-
- async function getSiteInfo(
- opts: {
- config?: Partial
- preview?: boolean
- } & OperationOptions
- ): Promise
-
- async function getSiteInfo({
- query = getSiteInfoQuery,
- config,
- }: {
- query?: string
- config?: Partial
- preview?: boolean
- } = {}): Promise {
- const cfg = commerce.getConfig(config)
- const { data } = await cfg.fetch(query)
- const categories = data.site.categoryTree.map(normalizeCategory)
- const brands = data.site?.brands?.edges
-
- return {
- categories: categories ?? [],
- brands: filterEdges(brands),
- }
- }
-
- return getSiteInfo
-}
diff --git a/framework/bigcommerce/api/operations/login.ts b/framework/bigcommerce/api/operations/login.ts
deleted file mode 100644
index 021ba3c65..000000000
--- a/framework/bigcommerce/api/operations/login.ts
+++ /dev/null
@@ -1,79 +0,0 @@
-import type { ServerResponse } from 'http'
-import type {
- OperationContext,
- OperationOptions,
-} from '@commerce/api/operations'
-import type { LoginOperation } from '../../types/login'
-import type { LoginMutation } from '../../schema'
-import type { RecursivePartial } from '../utils/types'
-import concatHeader from '../utils/concat-cookie'
-import type { BigcommerceConfig, Provider } from '..'
-
-export const loginMutation = /* GraphQL */ `
- mutation login($email: String!, $password: String!) {
- login(email: $email, password: $password) {
- result
- }
- }
-`
-
-export default function loginOperation({
- commerce,
-}: OperationContext) {
- async function login(opts: {
- variables: T['variables']
- config?: BigcommerceConfig
- res: ServerResponse
- }): Promise
-
- async function login(
- opts: {
- variables: T['variables']
- config?: BigcommerceConfig
- res: ServerResponse
- } & OperationOptions
- ): Promise
-
- async function login({
- query = loginMutation,
- variables,
- res: response,
- config,
- }: {
- query?: string
- variables: T['variables']
- res: ServerResponse
- config?: BigcommerceConfig
- }): Promise {
- config = commerce.getConfig(config)
-
- const { data, res } = await config.fetch>(
- query,
- { variables }
- )
- // Bigcommerce returns a Set-Cookie header with the auth cookie
- let cookie = res.headers.get('Set-Cookie')
-
- if (cookie && typeof cookie === 'string') {
- // In development, don't set a secure cookie or the browser will ignore it
- if (process.env.NODE_ENV !== 'production') {
- cookie = cookie.replace('; Secure', '')
- // SameSite=none can't be set unless the cookie is Secure
- // bc seems to sometimes send back SameSite=None rather than none so make
- // this case insensitive
- cookie = cookie.replace(/; SameSite=none/gi, '; SameSite=lax')
- }
-
- response.setHeader(
- 'Set-Cookie',
- concatHeader(response.getHeader('Set-Cookie'), cookie)!
- )
- }
-
- return {
- result: data.login?.result,
- }
- }
-
- return login
-}
diff --git a/framework/bigcommerce/api/utils/concat-cookie.ts b/framework/bigcommerce/api/utils/concat-cookie.ts
deleted file mode 100644
index 362e12e99..000000000
--- a/framework/bigcommerce/api/utils/concat-cookie.ts
+++ /dev/null
@@ -1,14 +0,0 @@
-type Header = string | number | string[] | undefined
-
-export default function concatHeader(prev: Header, val: Header) {
- if (!val) return prev
- if (!prev) return val
-
- if (Array.isArray(prev)) return prev.concat(String(val))
-
- prev = String(prev)
-
- if (Array.isArray(val)) return [prev].concat(val)
-
- return [prev, String(val)]
-}
diff --git a/framework/bigcommerce/api/utils/errors.ts b/framework/bigcommerce/api/utils/errors.ts
deleted file mode 100644
index 77e2007fc..000000000
--- a/framework/bigcommerce/api/utils/errors.ts
+++ /dev/null
@@ -1,25 +0,0 @@
-import type { Response } from '@vercel/fetch'
-
-// Used for GraphQL errors
-export class BigcommerceGraphQLError extends Error {}
-
-export class BigcommerceApiError extends Error {
- status: number
- res: Response
- data: any
-
- constructor(msg: string, res: Response, data?: any) {
- super(msg)
- this.name = 'BigcommerceApiError'
- this.status = res.status
- this.res = res
- this.data = data
- }
-}
-
-export class BigcommerceNetworkError extends Error {
- constructor(msg: string) {
- super(msg)
- this.name = 'BigcommerceNetworkError'
- }
-}
diff --git a/framework/bigcommerce/api/utils/fetch-graphql-api.ts b/framework/bigcommerce/api/utils/fetch-graphql-api.ts
deleted file mode 100644
index 8cc76c067..000000000
--- a/framework/bigcommerce/api/utils/fetch-graphql-api.ts
+++ /dev/null
@@ -1,36 +0,0 @@
-import { FetcherError } from '@commerce/utils/errors'
-import type { GraphQLFetcher } from '@commerce/api'
-import type { BigcommerceConfig } from '../index'
-import fetch from './fetch'
-
-const fetchGraphqlApi: (getConfig: () => BigcommerceConfig) => GraphQLFetcher =
- (getConfig) =>
- async (query: string, { variables, preview } = {}, fetchOptions) => {
- // log.warn(query)
- const config = getConfig()
- const res = await fetch(config.commerceUrl + (preview ? '/preview' : ''), {
- ...fetchOptions,
- method: 'POST',
- headers: {
- Authorization: `Bearer ${config.apiToken}`,
- ...fetchOptions?.headers,
- 'Content-Type': 'application/json',
- },
- body: JSON.stringify({
- query,
- variables,
- }),
- })
-
- const json = await res.json()
- if (json.errors) {
- throw new FetcherError({
- errors: json.errors ?? [{ message: 'Failed to fetch Bigcommerce API' }],
- status: res.status,
- })
- }
-
- return { data: json.data, res }
- }
-
-export default fetchGraphqlApi
diff --git a/framework/bigcommerce/api/utils/fetch-store-api.ts b/framework/bigcommerce/api/utils/fetch-store-api.ts
deleted file mode 100644
index 1e44b28f9..000000000
--- a/framework/bigcommerce/api/utils/fetch-store-api.ts
+++ /dev/null
@@ -1,71 +0,0 @@
-import type { RequestInit, Response } from '@vercel/fetch'
-import type { BigcommerceConfig } from '../index'
-import { BigcommerceApiError, BigcommerceNetworkError } from './errors'
-import fetch from './fetch'
-
-const fetchStoreApi =
- (getConfig: () => BigcommerceConfig) =>
- async (endpoint: string, options?: RequestInit): Promise => {
- const config = getConfig()
- let res: Response
-
- try {
- res = await fetch(config.storeApiUrl + endpoint, {
- ...options,
- headers: {
- ...options?.headers,
- 'Content-Type': 'application/json',
- 'X-Auth-Token': config.storeApiToken,
- 'X-Auth-Client': config.storeApiClientId,
- },
- })
- } catch (error) {
- throw new BigcommerceNetworkError(
- `Fetch to Bigcommerce failed: ${error.message}`
- )
- }
-
- const contentType = res.headers.get('Content-Type')
- const isJSON = contentType?.includes('application/json')
-
- if (!res.ok) {
- const data = isJSON ? await res.json() : await getTextOrNull(res)
- const headers = getRawHeaders(res)
- const msg = `Big Commerce API error (${
- res.status
- }) \nHeaders: ${JSON.stringify(headers, null, 2)}\n${
- typeof data === 'string' ? data : JSON.stringify(data, null, 2)
- }`
-
- throw new BigcommerceApiError(msg, res, data)
- }
-
- if (res.status !== 204 && !isJSON) {
- throw new BigcommerceApiError(
- `Fetch to Bigcommerce API failed, expected JSON content but found: ${contentType}`,
- res
- )
- }
-
- // If something was removed, the response will be empty
- return res.status === 204 ? null : await res.json()
- }
-export default fetchStoreApi
-
-function getRawHeaders(res: Response) {
- const headers: { [key: string]: string } = {}
-
- res.headers.forEach((value, key) => {
- headers[key] = value
- })
-
- return headers
-}
-
-function getTextOrNull(res: Response) {
- try {
- return res.text()
- } catch (err) {
- return null
- }
-}
diff --git a/framework/bigcommerce/api/utils/fetch.ts b/framework/bigcommerce/api/utils/fetch.ts
deleted file mode 100644
index 9d9fff3ed..000000000
--- a/framework/bigcommerce/api/utils/fetch.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-import zeitFetch from '@vercel/fetch'
-
-export default zeitFetch()
diff --git a/framework/bigcommerce/api/utils/filter-edges.ts b/framework/bigcommerce/api/utils/filter-edges.ts
deleted file mode 100644
index 09cd20640..000000000
--- a/framework/bigcommerce/api/utils/filter-edges.ts
+++ /dev/null
@@ -1,5 +0,0 @@
-export default function filterEdges(
- edges: (T | null | undefined)[] | null | undefined
-) {
- return edges?.filter((edge): edge is T => !!edge) ?? []
-}
diff --git a/framework/bigcommerce/api/utils/get-cart-cookie.ts b/framework/bigcommerce/api/utils/get-cart-cookie.ts
deleted file mode 100644
index 7ca6cd5e4..000000000
--- a/framework/bigcommerce/api/utils/get-cart-cookie.ts
+++ /dev/null
@@ -1,20 +0,0 @@
-import { serialize, CookieSerializeOptions } from 'cookie'
-
-export default function getCartCookie(
- name: string,
- cartId?: string,
- maxAge?: number
-) {
- const options: CookieSerializeOptions =
- cartId && maxAge
- ? {
- maxAge,
- expires: new Date(Date.now() + maxAge * 1000),
- secure: process.env.NODE_ENV === 'production',
- path: '/',
- sameSite: 'lax',
- }
- : { maxAge: -1, path: '/' } // Removes the cookie
-
- return serialize(name, cartId || '', options)
-}
diff --git a/framework/bigcommerce/api/utils/get-customer-id.ts b/framework/bigcommerce/api/utils/get-customer-id.ts
deleted file mode 100644
index 7efeeed3c..000000000
--- a/framework/bigcommerce/api/utils/get-customer-id.ts
+++ /dev/null
@@ -1,32 +0,0 @@
-import type { GetCustomerIdQuery } from '../../schema'
-import type { BigcommerceConfig } from '../'
-
-export const getCustomerIdQuery = /* GraphQL */ `
- query getCustomerId {
- customer {
- entityId
- }
- }
-`
-
-async function getCustomerId({
- customerToken,
- config,
-}: {
- customerToken: string
- config: BigcommerceConfig
-}): Promise {
- const { data } = await config.fetch(
- getCustomerIdQuery,
- undefined,
- {
- headers: {
- cookie: `${config.customerCookie}=${customerToken}`,
- },
- }
- )
-
- return String(data?.customer?.entityId)
-}
-
-export default getCustomerId
diff --git a/framework/bigcommerce/api/utils/parse-item.ts b/framework/bigcommerce/api/utils/parse-item.ts
deleted file mode 100644
index 14c9ac53d..000000000
--- a/framework/bigcommerce/api/utils/parse-item.ts
+++ /dev/null
@@ -1,28 +0,0 @@
-import type { WishlistItemBody } from '../../types/wishlist'
-import type { CartItemBody, OptionSelections } from '../../types/cart'
-
-type BCWishlistItemBody = {
- product_id: number
- variant_id: number
-}
-
-type BCCartItemBody = {
- product_id: number
- variant_id: number
- quantity?: number
- option_selections?: OptionSelections
-}
-
-export const parseWishlistItem = (
- item: WishlistItemBody
-): BCWishlistItemBody => ({
- product_id: Number(item.productId),
- variant_id: Number(item.variantId),
-})
-
-export const parseCartItem = (item: CartItemBody): BCCartItemBody => ({
- quantity: item.quantity,
- product_id: Number(item.productId),
- variant_id: Number(item.variantId),
- option_selections: item.optionSelections,
-})
diff --git a/framework/bigcommerce/api/utils/set-product-locale-meta.ts b/framework/bigcommerce/api/utils/set-product-locale-meta.ts
deleted file mode 100644
index 767286477..000000000
--- a/framework/bigcommerce/api/utils/set-product-locale-meta.ts
+++ /dev/null
@@ -1,21 +0,0 @@
-import type { ProductNode } from '../operations/get-all-products'
-import type { RecursivePartial } from './types'
-
-export default function setProductLocaleMeta(
- node: RecursivePartial
-) {
- if (node.localeMeta?.edges) {
- node.localeMeta.edges = node.localeMeta.edges.filter((edge) => {
- const { key, value } = edge?.node ?? {}
- if (key && key in node) {
- ;(node as any)[key] = value
- return false
- }
- return true
- })
-
- if (!node.localeMeta.edges.length) {
- delete node.localeMeta
- }
- }
-}
diff --git a/framework/bigcommerce/api/utils/types.ts b/framework/bigcommerce/api/utils/types.ts
deleted file mode 100644
index 56f9c1728..000000000
--- a/framework/bigcommerce/api/utils/types.ts
+++ /dev/null
@@ -1,7 +0,0 @@
-export type RecursivePartial = {
- [P in keyof T]?: RecursivePartial
-}
-
-export type RecursiveRequired = {
- [P in keyof T]-?: RecursiveRequired
-}
diff --git a/framework/bigcommerce/auth/index.ts b/framework/bigcommerce/auth/index.ts
deleted file mode 100644
index 36e757a89..000000000
--- a/framework/bigcommerce/auth/index.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-export { default as useLogin } from './use-login'
-export { default as useLogout } from './use-logout'
-export { default as useSignup } from './use-signup'
diff --git a/framework/bigcommerce/auth/use-login.tsx b/framework/bigcommerce/auth/use-login.tsx
deleted file mode 100644
index 3ebacc9b7..000000000
--- a/framework/bigcommerce/auth/use-login.tsx
+++ /dev/null
@@ -1,40 +0,0 @@
-import { useCallback } from 'react'
-import type { MutationHook } from '@commerce/utils/types'
-import { CommerceError } from '@commerce/utils/errors'
-import useLogin, { UseLogin } from '@commerce/auth/use-login'
-import type { LoginHook } from '../types/login'
-import useCustomer from '../customer/use-customer'
-
-export default useLogin as UseLogin
-
-export const handler: MutationHook = {
- fetchOptions: {
- url: '/api/login',
- method: 'POST',
- },
- 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',
- })
- }
-
- return fetch({
- ...options,
- body: { email, password },
- })
- },
- useHook: ({ fetch }) => () => {
- const { revalidate } = useCustomer()
-
- return useCallback(
- async function login(input) {
- const data = await fetch({ input })
- await revalidate()
- return data
- },
- [fetch, revalidate]
- )
- },
-}
diff --git a/framework/bigcommerce/auth/use-logout.tsx b/framework/bigcommerce/auth/use-logout.tsx
deleted file mode 100644
index e75563e04..000000000
--- a/framework/bigcommerce/auth/use-logout.tsx
+++ /dev/null
@@ -1,26 +0,0 @@
-import { useCallback } from 'react'
-import type { MutationHook } from '@commerce/utils/types'
-import useLogout, { UseLogout } from '@commerce/auth/use-logout'
-import type { LogoutHook } from '../types/logout'
-import useCustomer from '../customer/use-customer'
-
-export default useLogout as UseLogout
-
-export const handler: MutationHook = {
- fetchOptions: {
- url: '/api/logout',
- method: 'GET',
- },
- useHook: ({ fetch }) => () => {
- const { mutate } = useCustomer()
-
- return useCallback(
- async function logout() {
- const data = await fetch()
- await mutate(null, false)
- return data
- },
- [fetch, mutate]
- )
- },
-}
diff --git a/framework/bigcommerce/auth/use-signup.tsx b/framework/bigcommerce/auth/use-signup.tsx
deleted file mode 100644
index da06fd3eb..000000000
--- a/framework/bigcommerce/auth/use-signup.tsx
+++ /dev/null
@@ -1,44 +0,0 @@
-import { useCallback } from 'react'
-import type { MutationHook } from '@commerce/utils/types'
-import { CommerceError } from '@commerce/utils/errors'
-import useSignup, { UseSignup } from '@commerce/auth/use-signup'
-import type { SignupHook } from '../types/signup'
-import useCustomer from '../customer/use-customer'
-
-export default useSignup as UseSignup
-
-export const handler: MutationHook = {
- fetchOptions: {
- url: '/api/signup',
- method: 'POST',
- },
- async fetcher({
- input: { firstName, lastName, email, password },
- options,
- fetch,
- }) {
- if (!(firstName && lastName && email && password)) {
- throw new CommerceError({
- message:
- 'A first name, last name, email and password are required to signup',
- })
- }
-
- return fetch({
- ...options,
- body: { firstName, lastName, email, password },
- })
- },
- useHook: ({ fetch }) => () => {
- const { revalidate } = useCustomer()
-
- return useCallback(
- async function signup(input) {
- const data = await fetch({ input })
- await revalidate()
- return data
- },
- [fetch, revalidate]
- )
- },
-}
diff --git a/framework/bigcommerce/cart/index.ts b/framework/bigcommerce/cart/index.ts
deleted file mode 100644
index 3b8ba990e..000000000
--- a/framework/bigcommerce/cart/index.ts
+++ /dev/null
@@ -1,4 +0,0 @@
-export { default as useCart } from './use-cart'
-export { default as useAddItem } from './use-add-item'
-export { default as useRemoveItem } from './use-remove-item'
-export { default as useUpdateItem } from './use-update-item'
diff --git a/framework/bigcommerce/cart/use-add-item.tsx b/framework/bigcommerce/cart/use-add-item.tsx
deleted file mode 100644
index 1ac6ac6f8..000000000
--- a/framework/bigcommerce/cart/use-add-item.tsx
+++ /dev/null
@@ -1,44 +0,0 @@
-import { useCallback } from 'react'
-import type { MutationHook } from '@commerce/utils/types'
-import { CommerceError } from '@commerce/utils/errors'
-import useAddItem, { UseAddItem } from '@commerce/cart/use-add-item'
-import type { AddItemHook } from '@commerce/types/cart'
-import useCart from './use-cart'
-
-export default useAddItem as UseAddItem
-
-export const handler: MutationHook = {
- fetchOptions: {
- url: '/api/cart',
- method: 'POST',
- },
- async fetcher({ input: item, options, fetch }) {
- 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 data = await fetch({
- ...options,
- body: { item },
- })
-
- return data
- },
- useHook: ({ fetch }) => () => {
- const { mutate } = useCart()
-
- return useCallback(
- async function addItem(input) {
- const data = await fetch({ input })
- await mutate(data, false)
- return data
- },
- [fetch, mutate]
- )
- },
-}
diff --git a/framework/bigcommerce/cart/use-cart.tsx b/framework/bigcommerce/cart/use-cart.tsx
deleted file mode 100644
index 4ba1724d9..000000000
--- a/framework/bigcommerce/cart/use-cart.tsx
+++ /dev/null
@@ -1,31 +0,0 @@
-import { useMemo } from 'react'
-import { SWRHook } from '@commerce/utils/types'
-import useCart, { UseCart } from '@commerce/cart/use-cart'
-import type { GetCartHook } from '@commerce/types/cart'
-
-export default useCart as UseCart
-
-export const handler: SWRHook = {
- fetchOptions: {
- url: '/api/cart',
- method: 'GET',
- },
- 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,
- },
- }),
- [response]
- )
- },
-}
diff --git a/framework/bigcommerce/cart/use-remove-item.tsx b/framework/bigcommerce/cart/use-remove-item.tsx
deleted file mode 100644
index 1376f29ce..000000000
--- a/framework/bigcommerce/cart/use-remove-item.tsx
+++ /dev/null
@@ -1,56 +0,0 @@
-import { useCallback } from 'react'
-import type {
- MutationHookContext,
- HookFetcherContext,
-} from '@commerce/utils/types'
-import { ValidationError } from '@commerce/utils/errors'
-import useRemoveItem, { UseRemoveItem } from '@commerce/cart/use-remove-item'
-import type { Cart, LineItem, RemoveItemHook } from '@commerce/types/cart'
-import useCart from './use-cart'
-
-export type RemoveItemFn = T extends LineItem
- ? (input?: RemoveItemActionInput) => Promise
- : (input: RemoveItemActionInput) => Promise
-
-export type RemoveItemActionInput = T extends LineItem
- ? Partial
- : RemoveItemHook['actionInput']
-
-export default useRemoveItem as UseRemoveItem
-
-export const handler = {
- fetchOptions: {
- url: '/api/cart',
- method: 'DELETE',
- },
- async fetcher({
- input: { itemId },
- options,
- fetch,
- }: HookFetcherContext) {
- return await fetch({ ...options, body: { itemId } })
- },
- useHook: ({ fetch }: MutationHookContext) => <
- T extends LineItem | undefined = undefined
- >(
- ctx: { item?: T } = {}
- ) => {
- const { item } = ctx
- const { mutate } = useCart()
- const removeItem: RemoveItemFn = async (input) => {
- const itemId = input?.id ?? item?.id
-
- if (!itemId) {
- throw new ValidationError({
- message: 'Invalid input used for this operation',
- })
- }
-
- const data = await fetch({ input: { itemId } })
- await mutate(data, false)
- return data
- }
-
- return useCallback(removeItem as RemoveItemFn, [fetch, mutate])
- },
-}
diff --git a/framework/bigcommerce/cart/use-update-item.tsx b/framework/bigcommerce/cart/use-update-item.tsx
deleted file mode 100644
index 0f9f5754d..000000000
--- a/framework/bigcommerce/cart/use-update-item.tsx
+++ /dev/null
@@ -1,84 +0,0 @@
-import { useCallback } from 'react'
-import debounce from 'lodash.debounce'
-import type {
- MutationHookContext,
- HookFetcherContext,
-} from '@commerce/utils/types'
-import { ValidationError } from '@commerce/utils/errors'
-import useUpdateItem, { UseUpdateItem } from '@commerce/cart/use-update-item'
-import type { LineItem, UpdateItemHook } from '@commerce/types/cart'
-import { handler as removeItemHandler } from './use-remove-item'
-import useCart from './use-cart'
-
-export type UpdateItemActionInput = T extends LineItem
- ? Partial
- : UpdateItemHook['actionInput']
-
-export default useUpdateItem as UseUpdateItem
-
-export const handler = {
- fetchOptions: {
- url: '/api/cart',
- method: 'PUT',
- },
- async fetcher({
- input: { itemId, item },
- options,
- fetch,
- }: HookFetcherContext) {
- 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) {
- return removeItemHandler.fetcher({
- options: removeItemHandler.fetchOptions,
- input: { itemId },
- fetch,
- })
- }
- } else if (item.quantity) {
- throw new ValidationError({
- message: 'The item quantity has to be a valid integer',
- })
- }
-
- return await fetch({
- ...options,
- body: { itemId, item },
- })
- },
- useHook: ({ fetch }: MutationHookContext) => <
- T extends LineItem | undefined = undefined
- >(
- ctx: {
- item?: T
- wait?: number
- } = {}
- ) => {
- const { item } = ctx
- const { mutate } = useCart() as any
-
- return useCallback(
- debounce(async (input: UpdateItemActionInput) => {
- 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: {
- itemId,
- item: { productId, variantId, quantity: input.quantity },
- },
- })
- await mutate(data, false)
- return data
- }, ctx.wait ?? 500),
- [fetch, mutate]
- )
- },
-}
diff --git a/framework/bigcommerce/commerce.config.json b/framework/bigcommerce/commerce.config.json
deleted file mode 100644
index 89ce5625c..000000000
--- a/framework/bigcommerce/commerce.config.json
+++ /dev/null
@@ -1,7 +0,0 @@
-{
- "provider": "bigcommerce",
- "features": {
- "wishlist": true,
- "customerAuth": true
- }
-}
diff --git a/framework/bigcommerce/customer/index.ts b/framework/bigcommerce/customer/index.ts
deleted file mode 100644
index 6c903ecc5..000000000
--- a/framework/bigcommerce/customer/index.ts
+++ /dev/null
@@ -1 +0,0 @@
-export { default as useCustomer } from './use-customer'
diff --git a/framework/bigcommerce/customer/use-customer.tsx b/framework/bigcommerce/customer/use-customer.tsx
deleted file mode 100644
index 238b1229b..000000000
--- a/framework/bigcommerce/customer/use-customer.tsx
+++ /dev/null
@@ -1,24 +0,0 @@
-import { SWRHook } from '@commerce/utils/types'
-import useCustomer, { UseCustomer } from '@commerce/customer/use-customer'
-import type { CustomerHook } from '../types/customer'
-
-export default useCustomer as UseCustomer
-
-export const handler: SWRHook = {
- fetchOptions: {
- url: '/api/customer',
- method: 'GET',
- },
- async fetcher({ options, fetch }) {
- const data = await fetch(options)
- return data?.customer ?? null
- },
- useHook: ({ useData }) => (input) => {
- return useData({
- swrOptions: {
- revalidateOnFocus: false,
- ...input?.swrOptions,
- },
- })
- },
-}
diff --git a/framework/bigcommerce/fetcher.ts b/framework/bigcommerce/fetcher.ts
deleted file mode 100644
index f8ca0c578..000000000
--- a/framework/bigcommerce/fetcher.ts
+++ /dev/null
@@ -1,41 +0,0 @@
-import { FetcherError } from '@commerce/utils/errors'
-import type { Fetcher } from '@commerce/utils/types'
-
-async function getText(res: Response) {
- try {
- return (await res.text()) || res.statusText
- } catch (error) {
- return res.statusText
- }
-}
-
-async function getError(res: Response) {
- if (res.headers.get('Content-Type')?.includes('application/json')) {
- const data = await res.json()
- return new FetcherError({ errors: data.errors, status: res.status })
- }
- return new FetcherError({ message: await getText(res), status: res.status })
-}
-
-const fetcher: Fetcher = async ({
- url,
- method = 'GET',
- variables,
- body: bodyObj,
-}) => {
- const hasBody = Boolean(variables || bodyObj)
- const body = hasBody
- ? JSON.stringify(variables ? { variables } : bodyObj)
- : undefined
- const headers = hasBody ? { 'Content-Type': 'application/json' } : undefined
- const res = await fetch(url!, { method, body, headers })
-
- if (res.ok) {
- const { data } = await res.json()
- return data
- }
-
- throw await getError(res)
-}
-
-export default fetcher
diff --git a/framework/bigcommerce/index.tsx b/framework/bigcommerce/index.tsx
deleted file mode 100644
index 024e54b56..000000000
--- a/framework/bigcommerce/index.tsx
+++ /dev/null
@@ -1,36 +0,0 @@
-import type { ReactNode } from 'react'
-import {
- CommerceConfig,
- CommerceProvider as CoreCommerceProvider,
- useCommerce as useCoreCommerce,
-} from '@commerce'
-import { bigcommerceProvider } from './provider'
-import type { BigcommerceProvider } from './provider'
-
-export { bigcommerceProvider }
-export type { BigcommerceProvider }
-
-export const bigcommerceConfig: CommerceConfig = {
- locale: 'en-us',
- cartCookie: 'bc_cartId',
-}
-
-export type BigcommerceConfig = Partial
-
-export type BigcommerceProps = {
- children?: ReactNode
- locale: string
-} & BigcommerceConfig
-
-export function CommerceProvider({ children, ...config }: BigcommerceProps) {
- return (
-
- {children}
-
- )
-}
-
-export const useCommerce = () => useCoreCommerce()
diff --git a/framework/bigcommerce/lib/get-slug.ts b/framework/bigcommerce/lib/get-slug.ts
deleted file mode 100644
index 329c5a27e..000000000
--- a/framework/bigcommerce/lib/get-slug.ts
+++ /dev/null
@@ -1,5 +0,0 @@
-// Remove trailing and leading slash, usually included in nodes
-// returned by the BigCommerce API
-const getSlug = (path: string) => path.replace(/^\/|\/$/g, '')
-
-export default getSlug
diff --git a/framework/bigcommerce/lib/immutability.ts b/framework/bigcommerce/lib/immutability.ts
deleted file mode 100644
index 488d3570f..000000000
--- a/framework/bigcommerce/lib/immutability.ts
+++ /dev/null
@@ -1,13 +0,0 @@
-import update, { Context } from 'immutability-helper'
-
-const c = new Context()
-
-c.extend('$auto', function (value, object) {
- return object ? c.update(object, value) : c.update({}, value)
-})
-
-c.extend('$autoArray', function (value, object) {
- return object ? c.update(object, value) : c.update([], value)
-})
-
-export default c.update
diff --git a/framework/bigcommerce/lib/normalize.ts b/framework/bigcommerce/lib/normalize.ts
deleted file mode 100644
index cd1c3ce5a..000000000
--- a/framework/bigcommerce/lib/normalize.ts
+++ /dev/null
@@ -1,136 +0,0 @@
-import type { Product } from '../types/product'
-import type { Cart, BigcommerceCart, LineItem } from '../types/cart'
-import type { Page } from '../types/page'
-import type { BCCategory, Category } from '../types/site'
-import { definitions } from '../api/definitions/store-content'
-import update from './immutability'
-import getSlug from './get-slug'
-
-function normalizeProductOption(productOption: any) {
- const {
- node: {
- entityId,
- values: { edges },
- ...rest
- },
- } = productOption
-
- return {
- id: entityId,
- values: edges?.map(({ node }: any) => node),
- ...rest,
- }
-}
-
-export function normalizeProduct(productNode: any): Product {
- const {
- entityId: id,
- productOptions,
- prices,
- path,
- id: _,
- options: _0,
- } = productNode
-
- return update(productNode, {
- id: { $set: String(id) },
- images: {
- $apply: ({ edges }: any) =>
- edges?.map(({ node: { urlOriginal, altText, ...rest } }: any) => ({
- url: urlOriginal,
- alt: altText,
- ...rest,
- })),
- },
- variants: {
- $apply: ({ edges }: any) =>
- edges?.map(({ node: { entityId, productOptions, ...rest } }: any) => ({
- id: entityId,
- options: productOptions?.edges
- ? productOptions.edges.map(normalizeProductOption)
- : [],
- ...rest,
- })),
- },
- options: {
- $set: productOptions.edges
- ? productOptions?.edges.map(normalizeProductOption)
- : [],
- },
- brand: {
- $apply: (brand: any) => (brand?.entityId ? brand?.entityId : null),
- },
- slug: {
- $set: path?.replace(/^\/+|\/+$/g, ''),
- },
- price: {
- $set: {
- value: prices?.price.value,
- currencyCode: prices?.price.currencyCode,
- },
- },
- $unset: ['entityId'],
- })
-}
-
-export function normalizePage(page: definitions['page_Full']): Page {
- return {
- id: String(page.id),
- name: page.name,
- is_visible: page.is_visible,
- sort_order: page.sort_order,
- body: page.body,
- }
-}
-
-export function normalizeCart(data: BigcommerceCart): Cart {
- return {
- id: data.id,
- customerId: String(data.customer_id),
- email: data.email,
- createdAt: data.created_time,
- currency: data.currency,
- taxesIncluded: data.tax_included,
- lineItems: data.line_items.physical_items.map(normalizeLineItem),
- lineItemsSubtotalPrice: data.base_amount,
- subtotalPrice: data.base_amount + data.discount_amount,
- totalPrice: data.cart_amount,
- discounts: data.discounts?.map((discount) => ({
- value: discount.discounted_amount,
- })),
- }
-}
-
-function normalizeLineItem(item: any): LineItem {
- return {
- id: item.id,
- variantId: String(item.variant_id),
- productId: String(item.product_id),
- name: item.name,
- quantity: item.quantity,
- variant: {
- id: String(item.variant_id),
- sku: item.sku,
- name: item.name,
- image: {
- url: item.image_url,
- },
- requiresShipping: item.is_require_shipping,
- price: item.sale_price,
- listPrice: item.list_price,
- },
- path: item.url.split('/')[3],
- discounts: item.discounts.map((discount: any) => ({
- value: discount.discounted_amount,
- })),
- }
-}
-
-export function normalizeCategory(category: BCCategory): Category {
- return {
- id: `${category.entityId}`,
- name: category.name,
- slug: getSlug(category.path),
- path: category.path,
- }
-}
diff --git a/framework/bigcommerce/next.config.js b/framework/bigcommerce/next.config.js
deleted file mode 100644
index f33b16630..000000000
--- a/framework/bigcommerce/next.config.js
+++ /dev/null
@@ -1,8 +0,0 @@
-const commerce = require('./commerce.config.json')
-
-module.exports = {
- commerce,
- images: {
- domains: ['cdn11.bigcommerce.com'],
- },
-}
diff --git a/framework/bigcommerce/product/index.ts b/framework/bigcommerce/product/index.ts
deleted file mode 100644
index 426a3edcd..000000000
--- a/framework/bigcommerce/product/index.ts
+++ /dev/null
@@ -1,2 +0,0 @@
-export { default as usePrice } from './use-price'
-export { default as useSearch } from './use-search'
diff --git a/framework/bigcommerce/product/use-price.tsx b/framework/bigcommerce/product/use-price.tsx
deleted file mode 100644
index 0174faf5e..000000000
--- a/framework/bigcommerce/product/use-price.tsx
+++ /dev/null
@@ -1,2 +0,0 @@
-export * from '@commerce/product/use-price'
-export { default } from '@commerce/product/use-price'
diff --git a/framework/bigcommerce/product/use-search.tsx b/framework/bigcommerce/product/use-search.tsx
deleted file mode 100644
index bea01753b..000000000
--- a/framework/bigcommerce/product/use-search.tsx
+++ /dev/null
@@ -1,50 +0,0 @@
-import { SWRHook } from '@commerce/utils/types'
-import useSearch, { UseSearch } from '@commerce/product/use-search'
-import type { SearchProductsHook } from '../types/product'
-
-export default useSearch as UseSearch
-
-export type SearchProductsInput = {
- search?: string
- categoryId?: number | string
- brandId?: number
- sort?: string
- locale?: string
-}
-
-export const handler: SWRHook = {
- fetchOptions: {
- url: '/api/catalog/products',
- method: 'GET',
- },
- fetcher({ input: { search, categoryId, brandId, sort }, options, fetch }) {
- // Use a dummy base as we only care about the relative path
- const url = new URL(options.url!, 'http://a')
-
- if (search) url.searchParams.set('search', search)
- if (Number.isInteger(categoryId))
- url.searchParams.set('categoryId', String(categoryId))
- if (Number.isInteger(brandId))
- url.searchParams.set('brandId', String(brandId))
- if (sort) url.searchParams.set('sort', sort)
-
- return fetch({
- url: url.pathname + url.search,
- method: options.method,
- })
- },
- useHook: ({ useData }) => (input = {}) => {
- return useData({
- input: [
- ['search', input.search],
- ['categoryId', input.categoryId],
- ['brandId', input.brandId],
- ['sort', input.sort],
- ],
- swrOptions: {
- revalidateOnFocus: false,
- ...input.swrOptions,
- },
- })
- },
-}
diff --git a/framework/bigcommerce/provider.ts b/framework/bigcommerce/provider.ts
deleted file mode 100644
index 196855438..000000000
--- a/framework/bigcommerce/provider.ts
+++ /dev/null
@@ -1,34 +0,0 @@
-import { handler as useCart } from './cart/use-cart'
-import { handler as useAddItem } from './cart/use-add-item'
-import { handler as useUpdateItem } from './cart/use-update-item'
-import { handler as useRemoveItem } from './cart/use-remove-item'
-
-import { handler as useWishlist } from './wishlist/use-wishlist'
-import { handler as useWishlistAddItem } from './wishlist/use-add-item'
-import { handler as useWishlistRemoveItem } from './wishlist/use-remove-item'
-
-import { handler as useCustomer } from './customer/use-customer'
-import { handler as useSearch } from './product/use-search'
-
-import { handler as useLogin } from './auth/use-login'
-import { handler as useLogout } from './auth/use-logout'
-import { handler as useSignup } from './auth/use-signup'
-
-import fetcher from './fetcher'
-
-export const bigcommerceProvider = {
- locale: 'en-us',
- cartCookie: 'bc_cartId',
- fetcher,
- cart: { useCart, useAddItem, useUpdateItem, useRemoveItem },
- wishlist: {
- useWishlist,
- useAddItem: useWishlistAddItem,
- useRemoveItem: useWishlistRemoveItem,
- },
- customer: { useCustomer },
- products: { useSearch },
- auth: { useLogin, useLogout, useSignup },
-}
-
-export type BigcommerceProvider = typeof bigcommerceProvider
diff --git a/framework/bigcommerce/schema.d.ts b/framework/bigcommerce/schema.d.ts
deleted file mode 100644
index 04824e263..000000000
--- a/framework/bigcommerce/schema.d.ts
+++ /dev/null
@@ -1,2064 +0,0 @@
-export type Maybe = T | null
-export type Exact = {
- [K in keyof T]: T[K]
-}
-/** All built-in and custom scalars, mapped to their actual values */
-export type Scalars = {
- ID: string
- String: string
- Boolean: boolean
- Int: number
- Float: number
- DateTime: any
- /** The `BigDecimal` scalar type represents signed fractional values with arbitrary precision. */
- BigDecimal: any
- /** The `Long` scalar type represents non-fractional signed whole numeric values. Long can represent values between -(2^63) and 2^63 - 1. */
- Long: any
-}
-
-/** Login result */
-export type LoginResult = {
- __typename?: 'LoginResult'
- /** The result of a login */
- result: Scalars['String']
-}
-
-/** Logout result */
-export type LogoutResult = {
- __typename?: 'LogoutResult'
- /** The result of a logout */
- result: Scalars['String']
-}
-
-export type Mutation = {
- __typename?: 'Mutation'
- login: LoginResult
- logout: LogoutResult
-}
-
-export type MutationLoginArgs = {
- email: Scalars['String']
- password: Scalars['String']
-}
-
-/** Aggregated */
-export type Aggregated = {
- __typename?: 'Aggregated'
- /** Number of available products in stock. This can be 'null' if inventory is not set orif the store's Inventory Settings disable displaying stock levels on the storefront. */
- availableToSell: Scalars['Long']
- /** Indicates a threshold low-stock level. This can be 'null' if the inventory warning level is not set or if the store's Inventory Settings disable displaying stock levels on the storefront. */
- warningLevel: Scalars['Int']
-}
-
-/** Aggregated Product Inventory */
-export type AggregatedInventory = {
- __typename?: 'AggregatedInventory'
- /** Number of available products in stock. This can be 'null' if inventory is not set orif the store's Inventory Settings disable displaying stock levels on the storefront. */
- availableToSell: Scalars['Int']
- /** Indicates a threshold low-stock level. This can be 'null' if the inventory warning level is not set or if the store's Inventory Settings disable displaying stock levels on the storefront. */
- warningLevel: Scalars['Int']
-}
-
-/** Brand */
-export type Brand = Node & {
- __typename?: 'Brand'
- /** The ID of an object */
- id: Scalars['ID']
- /** Id of the brand. */
- entityId: Scalars['Int']
- /** Name of the brand. */
- name: Scalars['String']
- /** Default image for brand. */
- defaultImage?: Maybe
- /** Page title for the brand. */
- pageTitle: Scalars['String']
- /** Meta description for the brand. */
- metaDesc: Scalars['String']
- /** Meta keywords for the brand. */
- metaKeywords: Array
- /** Search keywords for the brand. */
- searchKeywords: Array
- /** Path for the brand page. */
- path: Scalars['String']
- products: ProductConnection
- /** Metafield data related to a brand. */
- metafields: MetafieldConnection
-}
-
-/** Brand */
-export type BrandProductsArgs = {
- before?: Maybe
- after?: Maybe
- first?: Maybe
- last?: Maybe
-}
-
-/** Brand */
-export type BrandMetafieldsArgs = {
- namespace: Scalars['String']
- keys?: Maybe>
- before?: Maybe
- after?: Maybe
- first?: Maybe
- last?: Maybe
-}
-
-/** A connection to a list of items. */
-export type BrandConnection = {
- __typename?: 'BrandConnection'
- /** Information to aid in pagination. */
- pageInfo: PageInfo
- /** A list of edges. */
- edges?: Maybe>>
-}
-
-/** An edge in a connection. */
-export type BrandEdge = {
- __typename?: 'BrandEdge'
- /** The item at the end of the edge. */
- node: Brand
- /** A cursor for use in pagination. */
- cursor: Scalars['String']
-}
-
-/** Breadcrumb */
-export type Breadcrumb = {
- __typename?: 'Breadcrumb'
- /** Category id. */
- entityId: Scalars['Int']
- /** Name of the category. */
- name: Scalars['String']
-}
-
-/** A connection to a list of items. */
-export type BreadcrumbConnection = {
- __typename?: 'BreadcrumbConnection'
- /** Information to aid in pagination. */
- pageInfo: PageInfo
- /** A list of edges. */
- edges?: Maybe>>
-}
-
-/** An edge in a connection. */
-export type BreadcrumbEdge = {
- __typename?: 'BreadcrumbEdge'
- /** The item at the end of the edge. */
- node: Breadcrumb
- /** A cursor for use in pagination. */
- cursor: Scalars['String']
-}
-
-/** Bulk pricing tier that sets a fixed price for the product or variant. */
-export type BulkPricingFixedPriceDiscount = BulkPricingTier & {
- __typename?: 'BulkPricingFixedPriceDiscount'
- /** This price will override the current product price. */
- price: Scalars['BigDecimal']
- /** Minimum item quantity that applies to this bulk pricing tier. */
- minimumQuantity: Scalars['Int']
- /** Maximum item quantity that applies to this bulk pricing tier - if not defined then the tier does not have an upper bound. */
- maximumQuantity?: Maybe
-}
-
-/** Bulk pricing tier that reduces the price of the product or variant by a percentage. */
-export type BulkPricingPercentageDiscount = BulkPricingTier & {
- __typename?: 'BulkPricingPercentageDiscount'
- /** The percentage that will be removed from the product price. */
- percentOff: Scalars['BigDecimal']
- /** Minimum item quantity that applies to this bulk pricing tier. */
- minimumQuantity: Scalars['Int']
- /** Maximum item quantity that applies to this bulk pricing tier - if not defined then the tier does not have an upper bound. */
- maximumQuantity?: Maybe
-}
-
-/** Bulk pricing tier that will subtract an amount from the price of the product or variant. */
-export type BulkPricingRelativePriceDiscount = BulkPricingTier & {
- __typename?: 'BulkPricingRelativePriceDiscount'
- /** The price of the product/variant will be reduced by this priceAdjustment. */
- priceAdjustment: Scalars['BigDecimal']
- /** Minimum item quantity that applies to this bulk pricing tier. */
- minimumQuantity: Scalars['Int']
- /** Maximum item quantity that applies to this bulk pricing tier - if not defined then the tier does not have an upper bound. */
- maximumQuantity?: Maybe