+}
+
+const API_URL = process.env.BIGCOMMERCE_STOREFRONT_API_URL // GraphAPI
+const API_TOKEN = process.env.BIGCOMMERCE_STOREFRONT_API_TOKEN
+const STORE_API_URL = process.env.BIGCOMMERCE_STORE_API_URL // REST API
+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/packages/bigcommerce/src/api/operations/get-all-pages.ts b/packages/bigcommerce/src/api/operations/get-all-pages.ts
new file mode 100644
index 0000000..3117b73
--- /dev/null
+++ b/packages/bigcommerce/src/api/operations/get-all-pages.ts
@@ -0,0 +1,46 @@
+import type {
+ OperationContext,
+ OperationOptions,
+} from '@vercel/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/packages/bigcommerce/src/api/operations/get-all-product-paths.ts b/packages/bigcommerce/src/api/operations/get-all-product-paths.ts
new file mode 100644
index 0000000..90cdab6
--- /dev/null
+++ b/packages/bigcommerce/src/api/operations/get-all-product-paths.ts
@@ -0,0 +1,66 @@
+import type {
+ OperationContext,
+ OperationOptions,
+} from '@vercel/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