diff --git a/components/cart/CartItem/CartItem.tsx b/components/cart/CartItem/CartItem.tsx index 846d1d49e..bc614722f 100644 --- a/components/cart/CartItem/CartItem.tsx +++ b/components/cart/CartItem/CartItem.tsx @@ -5,7 +5,7 @@ import Link from 'next/link' import s from './CartItem.module.css' import { Trash, Plus, Minus } from '@components/icons' import { useUI } from '@components/ui/context' -import type { LineItem } from '@framework/types' +import type { LineItem } from '@commerce/types/cart' import usePrice from '@framework/product/use-price' import useUpdateItem from '@framework/cart/use-update-item' import useRemoveItem from '@framework/cart/use-remove-item' diff --git a/components/common/Footer/Footer.tsx b/components/common/Footer/Footer.tsx index 75b2806ef..a15cfdc2d 100644 --- a/components/common/Footer/Footer.tsx +++ b/components/common/Footer/Footer.tsx @@ -2,7 +2,7 @@ import { FC } from 'react' import cn from 'classnames' import Link from 'next/link' import { useRouter } from 'next/router' -import type { Page } from '@framework/common/get-all-pages' +import type { Page } from '@commerce/types/page' import getSlug from '@lib/get-slug' import { Github, Vercel } from '@components/icons' import { Logo, Container } from '@components/ui' diff --git a/components/common/HomeAllProductsGrid/HomeAllProductsGrid.tsx b/components/common/HomeAllProductsGrid/HomeAllProductsGrid.tsx index 423048f75..8d8ea1adf 100644 --- a/components/common/HomeAllProductsGrid/HomeAllProductsGrid.tsx +++ b/components/common/HomeAllProductsGrid/HomeAllProductsGrid.tsx @@ -1,6 +1,6 @@ import { FC } from 'react' import Link from 'next/link' -import type { Product } from '@commerce/types' +import type { Product } from '@commerce/types/product' import { Grid } from '@components/ui' import { ProductCard } from '@components/product' import s from './HomeAllProductsGrid.module.css' diff --git a/components/common/Layout/Layout.tsx b/components/common/Layout/Layout.tsx index 54749c46b..37f5933e7 100644 --- a/components/common/Layout/Layout.tsx +++ b/components/common/Layout/Layout.tsx @@ -11,7 +11,7 @@ import CartSidebarView from '@components/cart/CartSidebarView' import LoginView from '@components/auth/LoginView' import { CommerceProvider } from '@framework' -import type { Page } from '@framework/common/get-all-pages' +import type { Page } from '@commerce/types/page' const Loading = () => (
diff --git a/components/common/UserNav/UserNav.tsx b/components/common/UserNav/UserNav.tsx index 4d00970a9..83422a8cf 100644 --- a/components/common/UserNav/UserNav.tsx +++ b/components/common/UserNav/UserNav.tsx @@ -1,7 +1,7 @@ import { FC } from 'react' import Link from 'next/link' import cn from 'classnames' -import type { LineItem } from '@framework/types' +import type { LineItem } from '@commerce/types/cart' import useCart from '@framework/cart/use-cart' import useCustomer from '@framework/customer/use-customer' import { Avatar } from '@components/common' diff --git a/components/product/ProductCard/ProductCard.tsx b/components/product/ProductCard/ProductCard.tsx index ade53380c..f23b01d35 100644 --- a/components/product/ProductCard/ProductCard.tsx +++ b/components/product/ProductCard/ProductCard.tsx @@ -1,7 +1,7 @@ import { FC } from 'react' import cn from 'classnames' import Link from 'next/link' -import type { Product } from '@commerce/types' +import type { Product } from '@commerce/types/product' import s from './ProductCard.module.css' import Image, { ImageProps } from 'next/image' import WishlistButton from '@components/wishlist/WishlistButton' diff --git a/components/product/ProductView/ProductView.tsx b/components/product/ProductView/ProductView.tsx index 3b09fa39a..a9385b2f0 100644 --- a/components/product/ProductView/ProductView.tsx +++ b/components/product/ProductView/ProductView.tsx @@ -5,7 +5,7 @@ import { FC, useEffect, useState } from 'react' import s from './ProductView.module.css' import { Swatch, ProductSlider } from '@components/product' import { Button, Container, Text, useUI } from '@components/ui' -import type { Product } from '@commerce/types' +import type { Product } from '@commerce/types/product' import usePrice from '@framework/product/use-price' import { useAddItem } from '@framework/cart' import { getVariant, SelectedOptions } from '../helpers' @@ -18,6 +18,8 @@ interface Props { } const ProductView: FC = ({ product }) => { + // TODO: fix this missing argument issue + /* @ts-ignore */ const addItem = useAddItem() const { price } = usePrice({ amount: product.price.value, @@ -146,8 +148,11 @@ const ProductView: FC = ({ product }) => { className={s.button} onClick={addToCart} loading={loading} + disabled={variant?.availableForSale === false} > - Add to Cart + {variant?.availableForSale === false + ? 'Not Available' + : 'Add To Cart'}
diff --git a/components/product/Swatch/Swatch.tsx b/components/product/Swatch/Swatch.tsx index 34244321f..663d01dfa 100644 --- a/components/product/Swatch/Swatch.tsx +++ b/components/product/Swatch/Swatch.tsx @@ -52,4 +52,4 @@ const Swatch: FC & Props> = ({ ) } -export default Swatch +export default Swatch \ No newline at end of file diff --git a/components/product/helpers.ts b/components/product/helpers.ts index a0ceb7aa5..19ec2a171 100644 --- a/components/product/helpers.ts +++ b/components/product/helpers.ts @@ -1,4 +1,4 @@ -import type { Product } from '@commerce/types' +import type { Product } from '@commerce/types/product' export type SelectedOptions = Record export function getVariant(product: Product, opts: SelectedOptions) { diff --git a/components/wishlist/WishlistButton/WishlistButton.tsx b/components/wishlist/WishlistButton/WishlistButton.tsx index 6dc59b900..5841de11e 100644 --- a/components/wishlist/WishlistButton/WishlistButton.tsx +++ b/components/wishlist/WishlistButton/WishlistButton.tsx @@ -6,7 +6,7 @@ import useAddItem from '@framework/wishlist/use-add-item' import useCustomer from '@framework/customer/use-customer' import useWishlist from '@framework/wishlist/use-wishlist' import useRemoveItem from '@framework/wishlist/use-remove-item' -import type { Product, ProductVariant } from '@commerce/types' +import type { Product, ProductVariant } from '@commerce/types/product' type Props = { productId: Product['id'] diff --git a/components/wishlist/WishlistCard/WishlistCard.tsx b/components/wishlist/WishlistCard/WishlistCard.tsx index 1568d9e7e..52b17e6da 100644 --- a/components/wishlist/WishlistCard/WishlistCard.tsx +++ b/components/wishlist/WishlistCard/WishlistCard.tsx @@ -7,7 +7,7 @@ import { Trash } from '@components/icons' import { Button, Text } from '@components/ui' import { useUI } from '@components/ui/context' -import type { Product } from '@commerce/types' +import type { Product } from '@commerce/types/product' import usePrice from '@framework/product/use-price' import useAddItem from '@framework/cart/use-add-item' import useRemoveItem from '@framework/wishlist/use-remove-item' @@ -18,14 +18,17 @@ interface Props { const WishlistCard: FC = ({ product }) => { const { price } = usePrice({ - amount: product.prices?.price?.value, - baseAmount: product.prices?.retailPrice?.value, - currencyCode: product.prices?.price?.currencyCode!, + amount: product.price?.value, + baseAmount: product.price?.retailPrice, + currencyCode: product.price?.currencyCode!, }) // @ts-ignore Wishlist is not always enabled const removeItem = useRemoveItem({ wishlist: { includeProducts: true } }) const [loading, setLoading] = useState(false) const [removing, setRemoving] = useState(false) + + // TODO: fix this missing argument issue + /* @ts-ignore */ const addItem = useAddItem() const { openSidebar } = useUI() diff --git a/framework/bigcommerce/api/endpoints/cart/add-item.ts b/framework/bigcommerce/api/endpoints/cart/add-item.ts index b13e07d15..52ef1223d 100644 --- a/framework/bigcommerce/api/endpoints/cart/add-item.ts +++ b/framework/bigcommerce/api/endpoints/cart/add-item.ts @@ -1,4 +1,4 @@ -import { normalizeCart } from '@framework/lib/normalize' +import { normalizeCart } from '../../../lib/normalize' import { parseCartItem } from '../../utils/parse-item' import getCartCookie from '../../utils/get-cart-cookie' import type { CartEndpoint } from '.' diff --git a/framework/bigcommerce/api/endpoints/cart/get-cart.ts b/framework/bigcommerce/api/endpoints/cart/get-cart.ts index 110efc873..d3bb309e2 100644 --- a/framework/bigcommerce/api/endpoints/cart/get-cart.ts +++ b/framework/bigcommerce/api/endpoints/cart/get-cart.ts @@ -1,7 +1,7 @@ -import { normalizeCart } from '@framework/lib/normalize' +import { normalizeCart } from '../../../lib/normalize' import { BigcommerceApiError } from '../../utils/errors' import getCartCookie from '../../utils/get-cart-cookie' -import type { BigcommerceCart } from '../../../types' +import type { BigcommerceCart } from '../../../types/cart' import type { CartEndpoint } from '.' // Return current cart info diff --git a/framework/bigcommerce/api/endpoints/cart/remove-item.ts b/framework/bigcommerce/api/endpoints/cart/remove-item.ts index c6844978a..baf10c80f 100644 --- a/framework/bigcommerce/api/endpoints/cart/remove-item.ts +++ b/framework/bigcommerce/api/endpoints/cart/remove-item.ts @@ -1,4 +1,4 @@ -import { normalizeCart } from '@framework/lib/normalize' +import { normalizeCart } from '../../../lib/normalize' import getCartCookie from '../../utils/get-cart-cookie' import type { CartEndpoint } from '.' diff --git a/framework/bigcommerce/api/endpoints/cart/update-item.ts b/framework/bigcommerce/api/endpoints/cart/update-item.ts index 1222921fe..113553fad 100644 --- a/framework/bigcommerce/api/endpoints/cart/update-item.ts +++ b/framework/bigcommerce/api/endpoints/cart/update-item.ts @@ -1,4 +1,4 @@ -import { normalizeCart } from '@framework/lib/normalize' +import { normalizeCart } from '../../../lib/normalize' import { parseCartItem } from '../../utils/parse-item' import getCartCookie from '../../utils/get-cart-cookie' import type { CartEndpoint } from '.' diff --git a/framework/bigcommerce/api/endpoints/catalog/products/get-products.ts b/framework/bigcommerce/api/endpoints/catalog/products/get-products.ts index 707f43811..6dde39e28 100644 --- a/framework/bigcommerce/api/endpoints/catalog/products/get-products.ts +++ b/framework/bigcommerce/api/endpoints/catalog/products/get-products.ts @@ -25,10 +25,10 @@ const getProducts: ProductsEndpoint['handlers']['getProducts'] = async ({ if (search) url.searchParams.set('keyword', search) if (categoryId && Number.isInteger(Number(categoryId))) - url.searchParams.set('categories:in', categoryId) + url.searchParams.set('categories:in', String(categoryId)) if (brandId && Number.isInteger(Number(brandId))) - url.searchParams.set('brand_id', brandId) + url.searchParams.set('brand_id', String(brandId)) if (sort) { const [_sort, direction] = sort.split('-') diff --git a/framework/bigcommerce/api/operations/get-all-product-paths.ts b/framework/bigcommerce/api/operations/get-all-product-paths.ts index 302a4017b..da7b457eb 100644 --- a/framework/bigcommerce/api/operations/get-all-product-paths.ts +++ b/framework/bigcommerce/api/operations/get-all-product-paths.ts @@ -32,12 +32,12 @@ export default function getAllProductPathsOperation({ config?: BigcommerceConfig }): Promise - async function getAllProductPaths< - T extends GetAllProductPathsOperation - >(opts: { - variables?: T['variables'] - config?: BigcommerceConfig - } & OperationOptions): Promise + async function getAllProductPaths( + opts: { + variables?: T['variables'] + config?: BigcommerceConfig + } & OperationOptions + ): Promise async function getAllProductPaths({ query = getAllProductPathsQuery, diff --git a/framework/bigcommerce/api/operations/get-page.ts b/framework/bigcommerce/api/operations/get-page.ts index e8f852e92..6a1fea9d0 100644 --- a/framework/bigcommerce/api/operations/get-page.ts +++ b/framework/bigcommerce/api/operations/get-page.ts @@ -5,6 +5,7 @@ import type { 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, @@ -44,7 +45,7 @@ export default function getPageOperation({ const page = firstPage as RecursiveRequired if (preview || page?.is_visible) { - return { page } + return { page: normalizePage(page as any) } } return {} } diff --git a/framework/bigcommerce/api/utils/parse-item.ts b/framework/bigcommerce/api/utils/parse-item.ts index 7c8cd4728..14c9ac53d 100644 --- a/framework/bigcommerce/api/utils/parse-item.ts +++ b/framework/bigcommerce/api/utils/parse-item.ts @@ -1,5 +1,5 @@ -import type { ItemBody as WishlistItemBody } from '../wishlist' -import type { CartItemBody, OptionSelections } from '../../types' +import type { WishlistItemBody } from '../../types/wishlist' +import type { CartItemBody, OptionSelections } from '../../types/cart' type BCWishlistItemBody = { product_id: number diff --git a/framework/bigcommerce/cart/use-add-item.tsx b/framework/bigcommerce/cart/use-add-item.tsx index 205ee82c1..1ac6ac6f8 100644 --- a/framework/bigcommerce/cart/use-add-item.tsx +++ b/framework/bigcommerce/cart/use-add-item.tsx @@ -2,7 +2,7 @@ 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 '../types/cart' +import type { AddItemHook } from '@commerce/types/cart' import useCart from './use-cart' export default useAddItem as UseAddItem diff --git a/framework/bigcommerce/cart/use-cart.tsx b/framework/bigcommerce/cart/use-cart.tsx index 768c3ffd7..4ba1724d9 100644 --- a/framework/bigcommerce/cart/use-cart.tsx +++ b/framework/bigcommerce/cart/use-cart.tsx @@ -1,7 +1,7 @@ import { useMemo } from 'react' import { SWRHook } from '@commerce/utils/types' import useCart, { UseCart } from '@commerce/cart/use-cart' -import type { GetCartHook } from '../types/cart' +import type { GetCartHook } from '@commerce/types/cart' export default useCart as UseCart diff --git a/framework/bigcommerce/cart/use-remove-item.tsx b/framework/bigcommerce/cart/use-remove-item.tsx index 8d0659ecb..1376f29ce 100644 --- a/framework/bigcommerce/cart/use-remove-item.tsx +++ b/framework/bigcommerce/cart/use-remove-item.tsx @@ -5,11 +5,11 @@ import type { } 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 '../types/cart' +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 : (input: RemoveItemActionInput) => Promise export type RemoveItemActionInput = T extends LineItem diff --git a/framework/bigcommerce/cart/use-update-item.tsx b/framework/bigcommerce/cart/use-update-item.tsx index cf1f98226..0f9f5754d 100644 --- a/framework/bigcommerce/cart/use-update-item.tsx +++ b/framework/bigcommerce/cart/use-update-item.tsx @@ -6,7 +6,7 @@ import type { } from '@commerce/utils/types' import { ValidationError } from '@commerce/utils/errors' import useUpdateItem, { UseUpdateItem } from '@commerce/cart/use-update-item' -import type { LineItem, UpdateItemHook } from '../types/cart' +import type { LineItem, UpdateItemHook } from '@commerce/types/cart' import { handler as removeItemHandler } from './use-remove-item' import useCart from './use-cart' diff --git a/framework/bigcommerce/lib/normalize.ts b/framework/bigcommerce/lib/normalize.ts index cc7606099..5e5ebc8e4 100644 --- a/framework/bigcommerce/lib/normalize.ts +++ b/framework/bigcommerce/lib/normalize.ts @@ -1,6 +1,8 @@ -import type { Product } from '@commerce/types' -import type { Cart, BigcommerceCart, LineItem } from '../types' +import type { Product } from '../types/product' +import type { Cart, BigcommerceCart, LineItem } from '../types/cart' +import type { Page } from '../types/page' import update from './immutability' +import { definitions } from '../api/definitions/store-content' function normalizeProductOption(productOption: any) { const { @@ -69,6 +71,16 @@ export function normalizeProduct(productNode: any): Product { }) } +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, diff --git a/framework/bigcommerce/product/use-search.tsx b/framework/bigcommerce/product/use-search.tsx index 3c81d1171..4aa4f4246 100644 --- a/framework/bigcommerce/product/use-search.tsx +++ b/framework/bigcommerce/product/use-search.tsx @@ -9,6 +9,7 @@ export type SearchProductsInput = { categoryId?: number brandId?: number sort?: string + locale?: string } export const handler: SWRHook = { diff --git a/framework/bigcommerce/types/page.ts b/framework/bigcommerce/types/page.ts index 8f1adeb24..2bccfade2 100644 --- a/framework/bigcommerce/types/page.ts +++ b/framework/bigcommerce/types/page.ts @@ -1,9 +1,7 @@ import * as Core from '@commerce/types/page' -import { definitions } from '../api/definitions/store-content' - export * from '@commerce/types/page' -export type Page = definitions['page_Full'] +export type Page = Core.Page export type PageTypes = { page: Page diff --git a/framework/commerce/api/index.ts b/framework/commerce/api/index.ts index 8a08b92ee..8b44bea33 100644 --- a/framework/commerce/api/index.ts +++ b/framework/commerce/api/index.ts @@ -148,6 +148,7 @@ export const createEndpoint = >( export interface CommerceAPIConfig { locale?: string + locales?: string[] commerceUrl: string apiToken: string cartCookie: string diff --git a/framework/commerce/index.tsx b/framework/commerce/index.tsx index 07bf74a22..7ecb44dc1 100644 --- a/framework/commerce/index.tsx +++ b/framework/commerce/index.tsx @@ -6,35 +6,44 @@ import { useMemo, useRef, } from 'react' -import { Fetcher, SWRHook, MutationHook } from './utils/types' -import type { FetchCartInput } from './cart/use-cart' -import type { Cart, Wishlist, Customer, SearchProductsData } from './types' + +import type { + Customer, + Wishlist, + Cart, + Product, + Signup, + Login, + Logout, +} from '@commerce/types' + +import type { Fetcher, SWRHook, MutationHook } from './utils/types' const Commerce = createContext | {}>({}) export type Provider = CommerceConfig & { fetcher: Fetcher cart?: { - useCart?: SWRHook - useAddItem?: MutationHook - useUpdateItem?: MutationHook - useRemoveItem?: MutationHook + useCart?: SWRHook + useAddItem?: MutationHook + useUpdateItem?: MutationHook + useRemoveItem?: MutationHook } wishlist?: { - useWishlist?: SWRHook - useAddItem?: MutationHook - useRemoveItem?: MutationHook + useWishlist?: SWRHook + useAddItem?: MutationHook + useRemoveItem?: MutationHook } customer?: { - useCustomer?: SWRHook + useCustomer?: SWRHook } products?: { - useSearch?: SWRHook + useSearch?: SWRHook } auth?: { - useSignup?: MutationHook - useLogin?: MutationHook - useLogout?: MutationHook + useSignup?: MutationHook + useLogin?: MutationHook + useLogout?: MutationHook } } diff --git a/framework/commerce/types/cart.ts b/framework/commerce/types/cart.ts index e27374d98..7826f9b2d 100644 --- a/framework/commerce/types/cart.ts +++ b/framework/commerce/types/cart.ts @@ -1,5 +1,14 @@ import type { Discount, Measurement, Image } from './common' +export type SelectedOption = { + // The option's id. + id?: string + // The product option’s name. + name: string + /// The product option’s value. + value: string +} + export type LineItem = { id: string variantId: string @@ -10,6 +19,7 @@ export type LineItem = { // A human-friendly unique string automatically generated from the product’s name path: string variant: ProductVariant + options?: SelectedOption[] } export type ProductVariant = { @@ -86,7 +96,7 @@ export type CartItemBody = { */ export type CartTypes = { - cart: Cart + cart?: Cart item: LineItem itemBody: CartItemBody } diff --git a/framework/commerce/types/page.ts b/framework/commerce/types/page.ts index 334c81521..89f82c1a6 100644 --- a/framework/commerce/types/page.ts +++ b/framework/commerce/types/page.ts @@ -1,5 +1,18 @@ // TODO: define this type -export type Page = any +export type Page = { + // ID of the Web page. + id: string + // Page name, as displayed on the storefront. + name: string + // Relative URL on the storefront for this page. + url?: string + // HTML or variable that populates this page’s `` element, in default/desktop view. Required in POST if page type is `raw`. + body: string + // If true, this page appears in the storefront’s navigation menu. + is_visible?: boolean + // Order in which this page should display on the storefront. (Lower integers specify earlier display.) + sort_order?: number +} export type PageTypes = { page: Page diff --git a/framework/commerce/types/product.ts b/framework/commerce/types/product.ts index 27e98598a..a12e332b4 100644 --- a/framework/commerce/types/product.ts +++ b/framework/commerce/types/product.ts @@ -14,6 +14,8 @@ export type ProductPrice = { } export type ProductOption = { + __typename?: 'MultipleChoiceOption' + id: string displayName: string values: ProductOptionValues[] } @@ -26,6 +28,7 @@ export type ProductOptionValues = { export type ProductVariant = { id: string | number options: ProductOption[] + availableForSale?: boolean } export type Product = { @@ -44,9 +47,10 @@ export type Product = { export type SearchProductsBody = { search?: string - categoryId?: string - brandId?: string + categoryId?: string | number + brandId?: string | number sort?: string + locale?: string } export type ProductTypes = { diff --git a/framework/commerce/types/wishlist.ts b/framework/commerce/types/wishlist.ts index e71cdc7e4..b3759849c 100644 --- a/framework/commerce/types/wishlist.ts +++ b/framework/commerce/types/wishlist.ts @@ -2,7 +2,7 @@ export type Wishlist = any export type WishlistItemBody = { - variantId: string + variantId: string | number productId: string } diff --git a/framework/shopify/README.md b/framework/shopify/README.md index d67111a41..d5c4aa942 100644 --- a/framework/shopify/README.md +++ b/framework/shopify/README.md @@ -121,3 +121,15 @@ const pages = await getAllPages({ config, }) ``` + +## Code generation + +This provider makes use of GraphQL code generation. The [schema.graphql](./schema.graphql) and [schema.d.ts](./schema.d.ts) files contain the generated types & schema introspection results. + +When developing the provider, changes to any GraphQL operations should be followed by re-generation of the types and schema files: + +From the project root dir, run: + +```sh +yarn generate:shopify +``` diff --git a/framework/shopify/api/cart/index.ts b/framework/shopify/api/cart/index.ts deleted file mode 100644 index ea9b101e1..000000000 --- a/framework/shopify/api/cart/index.ts +++ /dev/null @@ -1 +0,0 @@ -export default function () {} diff --git a/framework/shopify/api/catalog/index.ts b/framework/shopify/api/catalog/index.ts deleted file mode 100644 index ea9b101e1..000000000 --- a/framework/shopify/api/catalog/index.ts +++ /dev/null @@ -1 +0,0 @@ -export default function () {} diff --git a/framework/shopify/api/catalog/products.ts b/framework/shopify/api/catalog/products.ts deleted file mode 100644 index ea9b101e1..000000000 --- a/framework/shopify/api/catalog/products.ts +++ /dev/null @@ -1 +0,0 @@ -export default function () {} diff --git a/framework/shopify/api/customer.ts b/framework/shopify/api/customer.ts deleted file mode 100644 index ea9b101e1..000000000 --- a/framework/shopify/api/customer.ts +++ /dev/null @@ -1 +0,0 @@ -export default function () {} diff --git a/framework/shopify/api/customers/index.ts b/framework/shopify/api/customers/index.ts deleted file mode 100644 index ea9b101e1..000000000 --- a/framework/shopify/api/customers/index.ts +++ /dev/null @@ -1 +0,0 @@ -export default function () {} diff --git a/framework/shopify/api/customers/login.ts b/framework/shopify/api/customers/login.ts deleted file mode 100644 index ea9b101e1..000000000 --- a/framework/shopify/api/customers/login.ts +++ /dev/null @@ -1 +0,0 @@ -export default function () {} diff --git a/framework/shopify/api/customers/logout.ts b/framework/shopify/api/customers/logout.ts deleted file mode 100644 index ea9b101e1..000000000 --- a/framework/shopify/api/customers/logout.ts +++ /dev/null @@ -1 +0,0 @@ -export default function () {} diff --git a/framework/shopify/api/customers/signup.ts b/framework/shopify/api/customers/signup.ts deleted file mode 100644 index ea9b101e1..000000000 --- a/framework/shopify/api/customers/signup.ts +++ /dev/null @@ -1 +0,0 @@ -export default function () {} diff --git a/framework/shopify/api/endpoints/cart.ts b/framework/shopify/api/endpoints/cart.ts new file mode 100644 index 000000000..d09c976c3 --- /dev/null +++ b/framework/shopify/api/endpoints/cart.ts @@ -0,0 +1 @@ +export default function (_commerce: any) {} diff --git a/framework/shopify/api/endpoints/catalog/products.ts b/framework/shopify/api/endpoints/catalog/products.ts new file mode 100644 index 000000000..d09c976c3 --- /dev/null +++ b/framework/shopify/api/endpoints/catalog/products.ts @@ -0,0 +1 @@ +export default function (_commerce: any) {} diff --git a/framework/shopify/api/checkout/index.ts b/framework/shopify/api/endpoints/checkout/checkout.ts similarity index 56% rename from framework/shopify/api/checkout/index.ts rename to framework/shopify/api/endpoints/checkout/checkout.ts index 244078466..0c340a129 100644 --- a/framework/shopify/api/checkout/index.ts +++ b/framework/shopify/api/endpoints/checkout/checkout.ts @@ -1,24 +1,16 @@ -import isAllowedMethod from '../utils/is-allowed-method' -import createApiHandler, { - ShopifyApiHandler, -} from '../utils/create-api-handler' - import { SHOPIFY_CHECKOUT_ID_COOKIE, SHOPIFY_CHECKOUT_URL_COOKIE, SHOPIFY_CUSTOMER_TOKEN_COOKIE, -} from '../../const' - -import { getConfig } from '..' -import associateCustomerWithCheckoutMutation from '../../utils/mutations/associate-customer-with-checkout' - -const METHODS = ['GET'] - -const checkoutApi: ShopifyApiHandler = async (req, res, config) => { - if (!isAllowedMethod(req, res, METHODS)) return - - config = getConfig() +} from '../../../const' +import associateCustomerWithCheckoutMutation from '../../../utils/mutations/associate-customer-with-checkout' +import type { CheckoutEndpoint } from '.' +const checkout: CheckoutEndpoint['handlers']['checkout'] = async ({ + req, + res, + config, +}) => { const { cookies } = req const checkoutUrl = cookies[SHOPIFY_CHECKOUT_URL_COOKIE] const customerCookie = cookies[SHOPIFY_CUSTOMER_TOKEN_COOKIE] @@ -43,4 +35,4 @@ const checkoutApi: ShopifyApiHandler = async (req, res, config) => { } } -export default createApiHandler(checkoutApi, {}, {}) +export default checkout diff --git a/framework/shopify/api/endpoints/checkout/index.ts b/framework/shopify/api/endpoints/checkout/index.ts new file mode 100644 index 000000000..5d78f451b --- /dev/null +++ b/framework/shopify/api/endpoints/checkout/index.ts @@ -0,0 +1,18 @@ +import { GetAPISchema, createEndpoint } from '@commerce/api' +import checkoutEndpoint from '@commerce/api/endpoints/checkout' +import type { CheckoutSchema } from '../../../types/checkout' +import type { ShopifyAPI } from '../..' +import checkout from './checkout' + +export type CheckoutAPI = GetAPISchema + +export type CheckoutEndpoint = CheckoutAPI['endpoint'] + +export const handlers: CheckoutEndpoint['handlers'] = { checkout } + +const checkoutApi = createEndpoint({ + handler: checkoutEndpoint, + handlers, +}) + +export default checkoutApi diff --git a/framework/shopify/api/endpoints/customer.ts b/framework/shopify/api/endpoints/customer.ts new file mode 100644 index 000000000..d09c976c3 --- /dev/null +++ b/framework/shopify/api/endpoints/customer.ts @@ -0,0 +1 @@ +export default function (_commerce: any) {} diff --git a/framework/shopify/api/endpoints/login.ts b/framework/shopify/api/endpoints/login.ts new file mode 100644 index 000000000..d09c976c3 --- /dev/null +++ b/framework/shopify/api/endpoints/login.ts @@ -0,0 +1 @@ +export default function (_commerce: any) {} diff --git a/framework/shopify/api/endpoints/logout.ts b/framework/shopify/api/endpoints/logout.ts new file mode 100644 index 000000000..d09c976c3 --- /dev/null +++ b/framework/shopify/api/endpoints/logout.ts @@ -0,0 +1 @@ +export default function (_commerce: any) {} diff --git a/framework/shopify/api/endpoints/signup.ts b/framework/shopify/api/endpoints/signup.ts new file mode 100644 index 000000000..d09c976c3 --- /dev/null +++ b/framework/shopify/api/endpoints/signup.ts @@ -0,0 +1 @@ +export default function (_commerce: any) {} diff --git a/framework/shopify/api/endpoints/wishlist.ts b/framework/shopify/api/endpoints/wishlist.ts new file mode 100644 index 000000000..d09c976c3 --- /dev/null +++ b/framework/shopify/api/endpoints/wishlist.ts @@ -0,0 +1 @@ +export default function (_commerce: any) {} diff --git a/framework/shopify/api/index.ts b/framework/shopify/api/index.ts index 387ed02fc..28c7d34b3 100644 --- a/framework/shopify/api/index.ts +++ b/framework/shopify/api/index.ts @@ -1,12 +1,20 @@ -import type { CommerceAPIConfig } from '@commerce/api' +import { + CommerceAPI, + CommerceAPIConfig, + getCommerceApi as commerceApi, +} from '@commerce/api' import { API_URL, API_TOKEN, - SHOPIFY_CHECKOUT_ID_COOKIE, SHOPIFY_CUSTOMER_TOKEN_COOKIE, + SHOPIFY_CHECKOUT_ID_COOKIE, } from '../const' +import fetchGraphqlApi from './utils/fetch-graphql-api' + +import * as operations from './operations' + if (!API_URL) { throw new Error( `The environment variable NEXT_PUBLIC_SHOPIFY_STORE_DOMAIN is missing and it's required to access your store` @@ -18,44 +26,30 @@ if (!API_TOKEN) { `The environment variable NEXT_PUBLIC_SHOPIFY_STOREFRONT_ACCESS_TOKEN is missing and it's required to access your store` ) } - -import fetchGraphqlApi from './utils/fetch-graphql-api' - export interface ShopifyConfig extends CommerceAPIConfig {} -export class Config { - private config: ShopifyConfig +const ONE_DAY = 60 * 60 * 24 - constructor(config: ShopifyConfig) { - this.config = config - } - - getConfig(userConfig: Partial = {}) { - return Object.entries(userConfig).reduce( - (cfg, [key, value]) => Object.assign(cfg, { [key]: value }), - { ...this.config } - ) - } - - setConfig(newConfig: Partial) { - Object.assign(this.config, newConfig) - } -} - -const config = new Config({ - locale: 'en-US', +const config: ShopifyConfig = { commerceUrl: API_URL, - apiToken: API_TOKEN!, - cartCookie: SHOPIFY_CHECKOUT_ID_COOKIE, - cartCookieMaxAge: 60 * 60 * 24 * 30, - fetch: fetchGraphqlApi, + apiToken: API_TOKEN, customerCookie: SHOPIFY_CUSTOMER_TOKEN_COOKIE, -}) - -export function getConfig(userConfig?: Partial) { - return config.getConfig(userConfig) + cartCookie: SHOPIFY_CHECKOUT_ID_COOKIE, + cartCookieMaxAge: ONE_DAY * 30, + fetch: fetchGraphqlApi, } -export function setConfig(newConfig: Partial) { - return config.setConfig(newConfig) +export const provider = { + config, + operations, +} + +export type Provider = typeof provider + +export type ShopifyAPI

= CommerceAPI

+ +export function getCommerceApi

( + customProvider: P = provider as any +): ShopifyAPI

{ + return commerceApi(customProvider) } diff --git a/framework/shopify/api/operations/get-all-pages.ts b/framework/shopify/api/operations/get-all-pages.ts new file mode 100644 index 000000000..ab0af9ff7 --- /dev/null +++ b/framework/shopify/api/operations/get-all-pages.ts @@ -0,0 +1,67 @@ +import type { + OperationContext, + OperationOptions, +} from '@commerce/api/operations' +import { + GetAllPagesQuery, + GetAllPagesQueryVariables, + PageEdge, +} from '../../schema' +import { normalizePages } from '../../utils' +import type { ShopifyConfig, Provider } from '..' +import type { GetAllPagesOperation, Page } from '../../types/page' +import getAllPagesQuery from '../../utils/queries/get-all-pages-query' + +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({ + query = getAllPagesQuery, + config, + variables, + }: { + url?: string + config?: Partial + variables?: GetAllPagesQueryVariables + preview?: boolean + query?: string + } = {}): Promise { + const { fetch, locale, locales = ['en-US'] } = commerce.getConfig(config) + + const { data } = await fetch( + query, + { + variables, + }, + { + ...(locale && { + headers: { + 'Accept-Language': locale, + }, + }), + } + ) + + return { + pages: locales.reduce( + (arr, locale) => + arr.concat(normalizePages(data.pages.edges as PageEdge[], locale)), + [] + ), + } + } + + return getAllPages +} diff --git a/framework/shopify/api/operations/get-all-product-paths.ts b/framework/shopify/api/operations/get-all-product-paths.ts new file mode 100644 index 000000000..c84f8c90a --- /dev/null +++ b/framework/shopify/api/operations/get-all-product-paths.ts @@ -0,0 +1,55 @@ +import type { + OperationContext, + OperationOptions, +} from '@commerce/api/operations' +import { GetAllProductPathsOperation } from '../../types/product' +import { + GetAllProductPathsQuery, + GetAllProductPathsQueryVariables, + ProductEdge, +} from '../../schema' +import type { ShopifyConfig, Provider } from '..' +import { getAllProductsQuery } from '../../utils' + +export default function getAllProductPathsOperation({ + commerce, +}: OperationContext) { + async function getAllProductPaths< + T extends GetAllProductPathsOperation + >(opts?: { + variables?: T['variables'] + config?: ShopifyConfig + }): Promise + + async function getAllProductPaths( + opts: { + variables?: T['variables'] + config?: ShopifyConfig + } & OperationOptions + ): Promise + + async function getAllProductPaths({ + query = getAllProductsQuery, + config, + variables, + }: { + query?: string + config?: ShopifyConfig + variables?: T['variables'] + } = {}): Promise { + config = commerce.getConfig(config) + + const { data } = await config.fetch< + GetAllProductPathsQuery, + GetAllProductPathsQueryVariables + >(query, { variables }) + + return { + products: data.products.edges.map(({ node: { handle } }) => ({ + path: `/${handle}`, + })), + } + } + + return getAllProductPaths +} diff --git a/framework/shopify/api/operations/get-all-products.ts b/framework/shopify/api/operations/get-all-products.ts new file mode 100644 index 000000000..08d781d5c --- /dev/null +++ b/framework/shopify/api/operations/get-all-products.ts @@ -0,0 +1,67 @@ +import type { + OperationContext, + OperationOptions, +} from '@commerce/api/operations' +import { GetAllProductsOperation } from '../../types/product' +import { + GetAllProductsQuery, + GetAllProductsQueryVariables, + Product as ShopifyProduct, +} from '../../schema' +import type { ShopifyConfig, Provider } from '..' +import getAllProductsQuery from '../../utils/queries/get-all-products-query' +import { normalizeProduct } from '../../utils' + +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, + config, + }: { + query?: string + variables?: T['variables'] + config?: Partial + preview?: boolean + } = {}): Promise { + const { fetch, locale } = commerce.getConfig(config) + + const { data } = await fetch< + GetAllProductsQuery, + GetAllProductsQueryVariables + >( + query, + { variables }, + { + ...(locale && { + headers: { + 'Accept-Language': locale, + }, + }), + } + ) + + return { + products: data.products.edges.map(({ node }) => + normalizeProduct(node as ShopifyProduct) + ), + } + } + + return getAllProducts +} diff --git a/framework/shopify/api/operations/get-page.ts b/framework/shopify/api/operations/get-page.ts new file mode 100644 index 000000000..67e135ebe --- /dev/null +++ b/framework/shopify/api/operations/get-page.ts @@ -0,0 +1,64 @@ +import type { + OperationContext, + OperationOptions, +} from '@commerce/api/operations' +import { normalizePage } from '../../utils' +import type { ShopifyConfig, Provider } from '..' +import { + GetPageQuery, + GetPageQueryVariables, + Page as ShopifyPage, +} from '../../schema' +import { GetPageOperation } from '../../types/page' +import getPageQuery from '../../utils/queries/get-page-query' + +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({ + query = getPageQuery, + variables, + config, + }: { + query?: string + variables: T['variables'] + config?: Partial + preview?: boolean + }): Promise { + const { fetch, locale = 'en-US' } = commerce.getConfig(config) + + const { + data: { node: page }, + } = await fetch( + query, + { + variables, + }, + { + ...(locale && { + headers: { + 'Accept-Language': locale, + }, + }), + } + ) + + return page ? { page: normalizePage(page as ShopifyPage, locale) } : {} + } + + return getPage +} diff --git a/framework/shopify/api/operations/get-product.ts b/framework/shopify/api/operations/get-product.ts new file mode 100644 index 000000000..447b5c792 --- /dev/null +++ b/framework/shopify/api/operations/get-product.ts @@ -0,0 +1,63 @@ +import type { + OperationContext, + OperationOptions, +} from '@commerce/api/operations' +import { GetProductOperation } from '../../types/product' +import { normalizeProduct, getProductQuery } from '../../utils' +import type { ShopifyConfig, Provider } from '..' +import { GetProductBySlugQuery, Product as ShopifyProduct } from '../../schema' + +export default function getProductOperation({ + 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, + config: cfg, + }: { + query?: string + variables: T['variables'] + config?: Partial + preview?: boolean + }): Promise { + const { fetch, locale } = commerce.getConfig(cfg) + + const { + data: { productByHandle }, + } = await fetch( + query, + { + variables, + }, + { + ...(locale && { + headers: { + 'Accept-Language': locale, + }, + }), + } + ) + + return { + ...(productByHandle && { + product: normalizeProduct(productByHandle as ShopifyProduct), + }), + } + } + + return getProduct +} diff --git a/framework/shopify/api/operations/get-site-info.ts b/framework/shopify/api/operations/get-site-info.ts new file mode 100644 index 000000000..27b63b0f9 --- /dev/null +++ b/framework/shopify/api/operations/get-site-info.ts @@ -0,0 +1,62 @@ +import type { + OperationContext, + OperationOptions, +} from '@commerce/api/operations' +import { GetSiteInfoQueryVariables } from '../../schema' +import type { ShopifyConfig, Provider } from '..' +import { GetSiteInfoOperation } from '../../types/site' + +import { getCategories, getBrands, getSiteInfoQuery } from '../../utils' + +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, + variables, + }: { + query?: string + config?: Partial + preview?: boolean + variables?: GetSiteInfoQueryVariables + } = {}): Promise { + const cfg = commerce.getConfig(config) + + const categories = await getCategories(cfg) + const brands = await getBrands(cfg) + /* + const { fetch, locale } = cfg + const { data } = await fetch( + query, + { variables }, + { + ...(locale && { + headers: { + 'Accept-Language': locale, + }, + }), + } + ) + */ + + return { + categories, + brands, + } + } + + return getSiteInfo +} diff --git a/framework/shopify/api/operations/index.ts b/framework/shopify/api/operations/index.ts new file mode 100644 index 000000000..7872a20b6 --- /dev/null +++ b/framework/shopify/api/operations/index.ts @@ -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' diff --git a/framework/shopify/api/operations/login.ts b/framework/shopify/api/operations/login.ts new file mode 100644 index 000000000..41e837a3f --- /dev/null +++ b/framework/shopify/api/operations/login.ts @@ -0,0 +1,48 @@ +import type { ServerResponse } from 'http' +import type { OperationContext } from '@commerce/api/operations' +import type { LoginOperation } from '../../types/login' +import type { ShopifyConfig, Provider } from '..' +import { + customerAccessTokenCreateMutation, + setCustomerToken, + throwUserErrors, +} from '../../utils' +import { CustomerAccessTokenCreateMutation } from '../../schema' + +export default function loginOperation({ + commerce, +}: OperationContext) { + async function login({ + query = customerAccessTokenCreateMutation, + variables, + config, + }: { + query?: string + variables: T['variables'] + res: ServerResponse + config?: ShopifyConfig + }): Promise { + 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 +} diff --git a/framework/shopify/api/utils/create-api-handler.ts b/framework/shopify/api/utils/create-api-handler.ts deleted file mode 100644 index 8820aeabc..000000000 --- a/framework/shopify/api/utils/create-api-handler.ts +++ /dev/null @@ -1,58 +0,0 @@ -import type { NextApiHandler, NextApiRequest, NextApiResponse } from 'next' -import { ShopifyConfig, getConfig } from '..' - -export type ShopifyApiHandler< - T = any, - H extends ShopifyHandlers = {}, - Options extends {} = {} -> = ( - req: NextApiRequest, - res: NextApiResponse>, - config: ShopifyConfig, - handlers: H, - // Custom configs that may be used by a particular handler - options: Options -) => void | Promise - -export type ShopifyHandler = (options: { - req: NextApiRequest - res: NextApiResponse> - config: ShopifyConfig - body: Body -}) => void | Promise - -export type ShopifyHandlers = { - [k: string]: ShopifyHandler -} - -export type ShopifyApiResponse = { - data: T | null - errors?: { message: string; code?: string }[] -} - -export default function createApiHandler< - T = any, - H extends ShopifyHandlers = {}, - Options extends {} = {} ->( - handler: ShopifyApiHandler, - handlers: H, - defaultOptions: Options -) { - return function getApiHandler({ - config, - operations, - options, - }: { - config?: ShopifyConfig - operations?: Partial - options?: Options extends {} ? Partial : never - } = {}): NextApiHandler { - const ops = { ...operations, ...handlers } - const opts = { ...defaultOptions, ...options } - - return function apiHandler(req, res) { - return handler(req, res, getConfig(config), ops, opts) - } - } -} diff --git a/framework/shopify/api/utils/fetch-all-products.ts b/framework/shopify/api/utils/fetch-all-products.ts deleted file mode 100644 index 9fa70a5ee..000000000 --- a/framework/shopify/api/utils/fetch-all-products.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { ProductEdge } from '../../schema' -import { ShopifyConfig } from '..' - -const fetchAllProducts = async ({ - config, - query, - variables, - acc = [], - cursor, -}: { - config: ShopifyConfig - query: string - acc?: ProductEdge[] - variables?: any - cursor?: string -}): Promise => { - const { data } = await config.fetch(query, { - variables: { ...variables, cursor }, - }) - - const edges: ProductEdge[] = data.products?.edges ?? [] - const hasNextPage = data.products?.pageInfo?.hasNextPage - acc = acc.concat(edges) - - if (hasNextPage) { - const cursor = edges.pop()?.cursor - if (cursor) { - return fetchAllProducts({ - config, - query, - variables, - acc, - cursor, - }) - } - } - - return acc -} - -export default fetchAllProducts diff --git a/framework/shopify/api/utils/is-allowed-method.ts b/framework/shopify/api/utils/is-allowed-method.ts deleted file mode 100644 index 78bbba568..000000000 --- a/framework/shopify/api/utils/is-allowed-method.ts +++ /dev/null @@ -1,28 +0,0 @@ -import type { NextApiRequest, NextApiResponse } from 'next' - -export default function isAllowedMethod( - req: NextApiRequest, - res: NextApiResponse, - allowedMethods: string[] -) { - const methods = allowedMethods.includes('OPTIONS') - ? allowedMethods - : [...allowedMethods, 'OPTIONS'] - - if (!req.method || !methods.includes(req.method)) { - res.status(405) - res.setHeader('Allow', methods.join(', ')) - res.end() - return false - } - - if (req.method === 'OPTIONS') { - res.status(200) - res.setHeader('Allow', methods.join(', ')) - res.setHeader('Content-Length', '0') - res.end() - return false - } - - return true -} diff --git a/framework/shopify/api/wishlist/index.tsx b/framework/shopify/api/wishlist/index.tsx deleted file mode 100644 index a72856673..000000000 --- a/framework/shopify/api/wishlist/index.tsx +++ /dev/null @@ -1,2 +0,0 @@ -export type WishlistItem = { product: any; id: number } -export default function () {} diff --git a/framework/shopify/auth/use-login.tsx b/framework/shopify/auth/use-login.tsx index 7993822cd..d4369b7c2 100644 --- a/framework/shopify/auth/use-login.tsx +++ b/framework/shopify/auth/use-login.tsx @@ -1,31 +1,22 @@ import { useCallback } from 'react' import type { MutationHook } from '@commerce/utils/types' -import { CommerceError, ValidationError } from '@commerce/utils/errors' -import useCustomer from '../customer/use-customer' -import createCustomerAccessTokenMutation from '../utils/mutations/customer-access-token-create' -import { - CustomerAccessTokenCreateInput, - CustomerUserError, - Mutation, - MutationCheckoutCreateArgs, -} from '../schema' +import { CommerceError } from '@commerce/utils/errors' import useLogin, { UseLogin } from '@commerce/auth/use-login' -import { setCustomerToken, throwUserErrors } from '../utils' +import type { LoginHook } from '../types/login' +import useCustomer from '../customer/use-customer' + +import { + setCustomerToken, + throwUserErrors, + customerAccessTokenCreateMutation, +} from '../utils' +import { Mutation, MutationCustomerAccessTokenCreateArgs } from '../schema' export default useLogin as UseLogin -const getErrorMessage = ({ code, message }: CustomerUserError) => { - switch (code) { - case 'UNIDENTIFIED_CUSTOMER': - message = 'Cannot find an account that matches the provided credentials' - break - } - return message -} - -export const handler: MutationHook = { +export const handler: MutationHook = { fetchOptions: { - query: createCustomerAccessTokenMutation, + query: customerAccessTokenCreateMutation, }, async fetcher({ input: { email, password }, options, fetch }) { if (!(email && password)) { @@ -37,7 +28,7 @@ export const handler: MutationHook = { const { customerAccessTokenCreate } = await fetch< Mutation, - MutationCheckoutCreateArgs + MutationCustomerAccessTokenCreateArgs >({ ...options, variables: { diff --git a/framework/shopify/auth/use-logout.tsx b/framework/shopify/auth/use-logout.tsx index 81a3b8cdd..30074b8d5 100644 --- a/framework/shopify/auth/use-logout.tsx +++ b/framework/shopify/auth/use-logout.tsx @@ -1,13 +1,14 @@ 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' import customerAccessTokenDeleteMutation from '../utils/mutations/customer-access-token-delete' import { getCustomerToken, setCustomerToken } from '../utils/customer-token' export default useLogout as UseLogout -export const handler: MutationHook = { +export const handler: MutationHook = { fetchOptions: { query: customerAccessTokenDeleteMutation, }, diff --git a/framework/shopify/auth/use-signup.tsx b/framework/shopify/auth/use-signup.tsx index 9ca5c682f..29557e960 100644 --- a/framework/shopify/auth/use-signup.tsx +++ b/framework/shopify/auth/use-signup.tsx @@ -1,25 +1,20 @@ import { useCallback } from 'react' import type { MutationHook } from '@commerce/utils/types' -import { CommerceError, ValidationError } from '@commerce/utils/errors' +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' -import { - CustomerCreateInput, - Mutation, - MutationCustomerCreateArgs, -} from '../schema' +import { Mutation, MutationCustomerCreateArgs } from '../schema' -import { customerCreateMutation } from '../utils/mutations' -import { handleAutomaticLogin, throwUserErrors } from '../utils' +import { + handleAutomaticLogin, + throwUserErrors, + customerCreateMutation, +} from '../utils' export default useSignup as UseSignup -export const handler: MutationHook< - null, - {}, - CustomerCreateInput, - CustomerCreateInput -> = { +export const handler: MutationHook = { fetchOptions: { query: customerCreateMutation, }, diff --git a/framework/shopify/cart/use-add-item.tsx b/framework/shopify/cart/use-add-item.tsx index cce0950e9..5f0809d01 100644 --- a/framework/shopify/cart/use-add-item.tsx +++ b/framework/shopify/cart/use-add-item.tsx @@ -2,18 +2,19 @@ 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 '../types/cart' import useCart from './use-cart' + import { checkoutLineItemAddMutation, getCheckoutId, checkoutToCart, } from '../utils' -import { Cart, CartItemBody } from '../types' import { Mutation, MutationCheckoutLineItemsAddArgs } from '../schema' export default useAddItem as UseAddItem -export const handler: MutationHook = { +export const handler: MutationHook = { fetchOptions: { query: checkoutLineItemAddMutation, }, diff --git a/framework/shopify/cart/use-cart.tsx b/framework/shopify/cart/use-cart.tsx index 5f77360bb..d920d058a 100644 --- a/framework/shopify/cart/use-cart.tsx +++ b/framework/shopify/cart/use-cart.tsx @@ -1,22 +1,20 @@ 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 } from '../utils' import getCheckoutQuery from '../utils/queries/get-checkout-query' +import { GetCartHook } from '../types/cart' + +import { + GetCheckoutQuery, + GetCheckoutQueryVariables, + CheckoutDetailsFragment, +} from '../schema' export default useCommerceCart as UseCart -export const handler: SWRHook< - Cart | null, - {}, - FetchCartInput, - { isEmpty?: boolean } -> = { +export const handler: SWRHook = { fetchOptions: { query: getCheckoutQuery, }, diff --git a/framework/shopify/cart/use-remove-item.tsx b/framework/shopify/cart/use-remove-item.tsx index 8db38eac2..bf9fb2d95 100644 --- a/framework/shopify/cart/use-remove-item.tsx +++ b/framework/shopify/cart/use-remove-item.tsx @@ -3,31 +3,29 @@ import type { MutationHookContext, HookFetcherContext, } from '@commerce/utils/types' -import { RemoveCartItemBody } from '@commerce/types' import { ValidationError } from '@commerce/utils/errors' -import useRemoveItem, { - RemoveItemInput as RemoveItemInputBase, - UseRemoveItem, -} from '@commerce/cart/use-remove-item' +import useRemoveItem, { UseRemoveItem } from '@commerce/cart/use-remove-item' +import type { Cart, LineItem, RemoveItemHook } from '../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 + import { checkoutLineItemRemoveMutation, getCheckoutId, checkoutToCart, } from '../utils' -import { Cart, LineItem } from '../types' + import { Mutation, MutationCheckoutLineItemsRemoveArgs } from '../schema' -export type RemoveItemFn = T extends LineItem - ? (input?: RemoveItemInput) => Promise - : (input: RemoveItemInput) => Promise - -export type RemoveItemInput = T extends LineItem - ? Partial - : RemoveItemInputBase - -export default useRemoveItem as UseRemoveItem - export const handler = { fetchOptions: { query: checkoutLineItemRemoveMutation, @@ -36,16 +34,14 @@ export const handler = { input: { itemId }, options, fetch, - }: HookFetcherContext) { + }: HookFetcherContext) { const data = await fetch({ ...options, variables: { checkoutId: getCheckoutId(), lineItemIds: [itemId] }, }) return checkoutToCart(data.checkoutLineItemsRemove) }, - useHook: ({ - fetch, - }: MutationHookContext) => < + useHook: ({ fetch }: MutationHookContext) => < T extends LineItem | undefined = undefined >( ctx: { item?: T } = {} diff --git a/framework/shopify/cart/use-update-item.tsx b/framework/shopify/cart/use-update-item.tsx index 49dd6be14..3f1cf4315 100644 --- a/framework/shopify/cart/use-update-item.tsx +++ b/framework/shopify/cart/use-update-item.tsx @@ -5,21 +5,21 @@ import type { 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 { checkoutToCart } from '../utils' -import { getCheckoutId, checkoutLineItemUpdateMutation } from '../utils' +import type { UpdateItemHook, LineItem } from '../types/cart' +import { + getCheckoutId, + checkoutLineItemUpdateMutation, + checkoutToCart, +} from '../utils' import { Mutation, MutationCheckoutLineItemsUpdateArgs } from '../schema' -export type UpdateItemInput = T extends LineItem - ? Partial> - : UpdateItemInputBase +export type UpdateItemActionInput = T extends LineItem + ? Partial + : UpdateItemHook['actionInput'] export default useUpdateItem as UseUpdateItem @@ -31,7 +31,7 @@ export const handler = { input: { itemId, item }, options, fetch, - }: HookFetcherContext) { + }: 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) { @@ -64,9 +64,7 @@ export const handler = { return checkoutToCart(checkoutLineItemsUpdate) }, - useHook: ({ - fetch, - }: MutationHookContext) => < + useHook: ({ fetch }: MutationHookContext) => < T extends LineItem | undefined = undefined >( ctx: { @@ -78,7 +76,7 @@ export const handler = { const { mutate } = useCart() as any return useCallback( - debounce(async (input: UpdateItemInput) => { + debounce(async (input: UpdateItemActionInput) => { const itemId = input.id ?? item?.id const productId = input.productId ?? item?.productId const variantId = input.productId ?? item?.variantId diff --git a/framework/shopify/codegen.json b/framework/shopify/codegen.json new file mode 100644 index 000000000..f0a757142 --- /dev/null +++ b/framework/shopify/codegen.json @@ -0,0 +1,32 @@ +{ + "schema": { + "https://${NEXT_PUBLIC_SHOPIFY_STORE_DOMAIN}/api/2021-01/graphql.json": { + "headers": { + "X-Shopify-Storefront-Access-Token": "${NEXT_PUBLIC_SHOPIFY_STOREFRONT_ACCESS_TOKEN}" + } + } + }, + "documents": [ + { + "./framework/shopify/**/*.{ts,tsx}": { + "noRequire": true + } + } + ], + "generates": { + "./framework/shopify/schema.d.ts": { + "plugins": ["typescript", "typescript-operations"], + "config": { + "scalars": { + "ID": "string" + } + } + }, + "./framework/shopify/schema.graphql": { + "plugins": ["schema-ast"] + } + }, + "hooks": { + "afterAllFileWrite": ["prettier --write"] + } +} diff --git a/framework/shopify/common/get-all-pages.ts b/framework/shopify/common/get-all-pages.ts deleted file mode 100644 index 54231ed03..000000000 --- a/framework/shopify/common/get-all-pages.ts +++ /dev/null @@ -1,42 +0,0 @@ -import { getConfig, ShopifyConfig } from '../api' -import { PageEdge } from '../schema' -import { getAllPagesQuery } 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: ShopifyConfig - preview?: boolean -}): Promise => { - let { config, variables = { first: 250 } } = options ?? {} - config = getConfig(config) - const { locale } = config - const { data } = await config.fetch(getAllPagesQuery, { variables }) - - const pages = data.pages?.edges?.map( - ({ node: { title: name, handle, ...node } }: PageEdge) => ({ - ...node, - url: `/${locale}/${handle}`, - name, - }) - ) - - return { pages } -} - -export default getAllPages diff --git a/framework/shopify/common/get-page.ts b/framework/shopify/common/get-page.ts deleted file mode 100644 index be934aa42..000000000 --- a/framework/shopify/common/get-page.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { getConfig, ShopifyConfig } from '../api' -import getPageQuery from '../utils/queries/get-page-query' -import { Page } from './get-all-pages' - -type Variables = { - id: string -} - -export type GetPageResult = T - -const getPage = async (options: { - variables: Variables - config: ShopifyConfig - preview?: boolean -}): Promise => { - let { config, variables } = options ?? {} - - config = getConfig(config) - const { locale } = config - - const { data } = await config.fetch(getPageQuery, { - variables, - }) - const page = data.node - - return { - page: page - ? { - ...page, - name: page.title, - url: `/${locale}/${page.handle}`, - } - : null, - } -} - -export default getPage diff --git a/framework/shopify/common/get-site-info.ts b/framework/shopify/common/get-site-info.ts deleted file mode 100644 index cbbacf5b6..000000000 --- a/framework/shopify/common/get-site-info.ts +++ /dev/null @@ -1,31 +0,0 @@ -import getCategories, { Category } from '../utils/get-categories' -import getVendors, { Brands } from '../utils/get-vendors' - -import { getConfig, ShopifyConfig } from '../api' - -export type GetSiteInfoResult< - T extends { categories: any[]; brands: any[] } = { - categories: Category[] - brands: Brands - } -> = T - -const getSiteInfo = async (options?: { - variables?: any - config: ShopifyConfig - preview?: boolean -}): Promise => { - let { config } = options ?? {} - - config = getConfig(config) - - const categories = await getCategories(config) - const brands = await getVendors(config) - - return { - categories, - brands, - } -} - -export default getSiteInfo diff --git a/framework/shopify/customer/get-customer-id.ts b/framework/shopify/customer/get-customer-id.ts deleted file mode 100644 index ca096645a..000000000 --- a/framework/shopify/customer/get-customer-id.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { getConfig, ShopifyConfig } from '../api' -import getCustomerIdQuery from '../utils/queries/get-customer-id-query' -import Cookies from 'js-cookie' - -async function getCustomerId({ - customerToken: customerAccesToken, - config, -}: { - customerToken: string - config?: ShopifyConfig -}): Promise { - config = getConfig(config) - - const { data } = await config.fetch(getCustomerIdQuery, { - variables: { - customerAccesToken: - customerAccesToken || Cookies.get(config.customerCookie), - }, - }) - - return data.customer?.id -} - -export default getCustomerId diff --git a/framework/shopify/customer/use-customer.tsx b/framework/shopify/customer/use-customer.tsx index 7b600838e..be097fe80 100644 --- a/framework/shopify/customer/use-customer.tsx +++ b/framework/shopify/customer/use-customer.tsx @@ -1,18 +1,19 @@ import useCustomer, { UseCustomer } from '@commerce/customer/use-customer' -import { Customer } from '@commerce/types' +import type { CustomerHook } from '../types/customer' import { SWRHook } from '@commerce/utils/types' import { getCustomerQuery, getCustomerToken } from '../utils' +import { GetCustomerQuery, GetCustomerQueryVariables } from '../schema' export default useCustomer as UseCustomer -export const handler: SWRHook = { +export const handler: SWRHook = { fetchOptions: { query: getCustomerQuery, }, async fetcher({ options, fetch }) { const customerAccessToken = getCustomerToken() if (customerAccessToken) { - const data = await fetch({ + const data = await fetch({ ...options, variables: { customerAccessToken: getCustomerToken() }, }) diff --git a/framework/shopify/fetcher.ts b/framework/shopify/fetcher.ts index a69150503..9a8d2d8d5 100644 --- a/framework/shopify/fetcher.ts +++ b/framework/shopify/fetcher.ts @@ -8,13 +8,17 @@ const fetcher: Fetcher = async ({ variables, query, }) => { + const { locale, ...vars } = variables ?? {} return handleFetchResponse( await fetch(url, { method, - body: JSON.stringify({ query, variables }), + body: JSON.stringify({ query, variables: vars }), headers: { 'X-Shopify-Storefront-Access-Token': API_TOKEN!, 'Content-Type': 'application/json', + ...(locale && { + 'Accept-Language': locale, + }), }, }) ) diff --git a/framework/shopify/index.tsx b/framework/shopify/index.tsx index 5b25d6b21..13ff9d1f8 100644 --- a/framework/shopify/index.tsx +++ b/framework/shopify/index.tsx @@ -36,4 +36,4 @@ export function CommerceProvider({ children, ...config }: ShopifyProps) { ) } -export const useCommerce = () => useCoreCommerce() +export const useCommerce = () => useCoreCommerce() diff --git a/framework/shopify/product/get-all-collections.ts b/framework/shopify/product/get-all-collections.ts deleted file mode 100644 index 15c4bc51a..000000000 --- a/framework/shopify/product/get-all-collections.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { CollectionEdge } from '../schema' -import { getConfig, ShopifyConfig } from '../api' -import getAllCollectionsQuery from '../utils/queries/get-all-collections-query' - -const getAllCollections = async (options?: { - variables?: any - config: ShopifyConfig - preview?: boolean -}) => { - let { config, variables = { first: 250 } } = options ?? {} - config = getConfig(config) - - const { data } = await config.fetch(getAllCollectionsQuery, { variables }) - const edges = data.collections?.edges ?? [] - - const categories = edges.map( - ({ node: { id: entityId, title: name, handle } }: CollectionEdge) => ({ - entityId, - name, - path: `/${handle}`, - }) - ) - - return { - categories, - } -} - -export default getAllCollections diff --git a/framework/shopify/product/get-all-product-paths.ts b/framework/shopify/product/get-all-product-paths.ts deleted file mode 100644 index e8ee04065..000000000 --- a/framework/shopify/product/get-all-product-paths.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { getConfig, ShopifyConfig } from '../api' -import { ProductEdge } from '../schema' -import getAllProductsPathsQuery from '../utils/queries/get-all-products-paths-query' - -type ProductPath = { - path: string -} - -export type ProductPathNode = { - node: ProductPath -} - -type ReturnType = { - products: ProductPathNode[] -} - -const getAllProductPaths = async (options?: { - variables?: any - config?: ShopifyConfig - preview?: boolean -}): Promise => { - let { config, variables = { first: 100, sortKey: 'BEST_SELLING' } } = - options ?? {} - config = getConfig(config) - - const { data } = await config.fetch(getAllProductsPathsQuery, { - variables, - }) - - return { - products: data.products?.edges?.map( - ({ node: { handle } }: ProductEdge) => ({ - node: { - path: `/${handle}`, - }, - }) - ), - } -} - -export default getAllProductPaths diff --git a/framework/shopify/product/get-all-products.ts b/framework/shopify/product/get-all-products.ts deleted file mode 100644 index 3915abebf..000000000 --- a/framework/shopify/product/get-all-products.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { GraphQLFetcherResult } from '@commerce/api' -import { getConfig, ShopifyConfig } from '../api' -import { ProductEdge } from '../schema' -import { getAllProductsQuery } from '../utils/queries' -import { normalizeProduct } from '../utils/normalize' -import { Product } from '@commerce/types' - -type Variables = { - first?: number - field?: string -} - -type ReturnType = { - products: Product[] -} - -const getAllProducts = async (options: { - variables?: Variables - config?: ShopifyConfig - preview?: boolean -}): Promise => { - let { config, variables = { first: 250 } } = options ?? {} - config = getConfig(config) - - const { data }: GraphQLFetcherResult = await config.fetch( - getAllProductsQuery, - { variables } - ) - - const products = data.products?.edges?.map(({ node: p }: ProductEdge) => - normalizeProduct(p) - ) - - return { - products, - } -} - -export default getAllProducts diff --git a/framework/shopify/product/get-product.ts b/framework/shopify/product/get-product.ts deleted file mode 100644 index 1d861e1a1..000000000 --- a/framework/shopify/product/get-product.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { GraphQLFetcherResult } from '@commerce/api' -import { getConfig, ShopifyConfig } from '../api' -import { normalizeProduct, getProductQuery } from '../utils' - -type Variables = { - slug: string -} - -type ReturnType = { - product: any -} - -const getProduct = async (options: { - variables: Variables - config: ShopifyConfig - preview?: boolean -}): Promise => { - let { config, variables } = options ?? {} - config = getConfig(config) - - const { data }: GraphQLFetcherResult = await config.fetch(getProductQuery, { - variables, - }) - const { productByHandle } = data - - return { - product: productByHandle ? normalizeProduct(productByHandle) : null, - } -} - -export default getProduct diff --git a/framework/shopify/product/use-search.tsx b/framework/shopify/product/use-search.tsx index bf812af3d..9588b65a2 100644 --- a/framework/shopify/product/use-search.tsx +++ b/framework/shopify/product/use-search.tsx @@ -1,7 +1,14 @@ import { SWRHook } from '@commerce/utils/types' import useSearch, { UseSearch } from '@commerce/product/use-search' -import { ProductEdge } from '../schema' +import { + CollectionEdge, + GetAllProductsQuery, + GetProductsFromCollectionQueryVariables, + Product as ShopifyProduct, + ProductEdge, +} from '../schema' + import { getAllProductsQuery, getCollectionProductsQuery, @@ -9,56 +16,59 @@ import { normalizeProduct, } from '../utils' -import { Product } from '@commerce/types' - -export default useSearch as UseSearch +import type { SearchProductsHook } from '../types/product' export type SearchProductsInput = { search?: string - categoryId?: string - brandId?: string + categoryId?: number + brandId?: number sort?: string + locale?: string } -export type SearchProductsData = { - products: Product[] - found: boolean -} +export default useSearch as UseSearch -export const handler: SWRHook< - SearchProductsData, - SearchProductsInput, - SearchProductsInput -> = { +export const handler: SWRHook = { fetchOptions: { query: getAllProductsQuery, }, async fetcher({ input, options, fetch }) { const { categoryId, brandId } = input + const method = options?.method + const variables = getSearchVariables(input) + let products - const data = await fetch({ - query: categoryId ? getCollectionProductsQuery : options.query, - method: options?.method, - variables: getSearchVariables(input), - }) - - let edges - + // change the query to getCollectionProductsQuery when categoryId is set if (categoryId) { - edges = data.node?.products?.edges ?? [] - if (brandId) { - edges = edges.filter( - ({ node: { vendor } }: ProductEdge) => - vendor.replace(/\s+/g, '-').toLowerCase() === brandId - ) - } + const data = await fetch< + CollectionEdge, + GetProductsFromCollectionQueryVariables + >({ + query: getCollectionProductsQuery, + method, + variables, + }) + // filter on client when brandId & categoryId are set since is not available on collection product query + products = brandId + ? data.node.products.edges.filter( + ({ node: { vendor } }: ProductEdge) => + vendor.replace(/\s+/g, '-').toLowerCase() === brandId + ) + : data.node.products.edges } else { - edges = data.products?.edges ?? [] + const data = await fetch({ + query: options.query, + method, + variables, + }) + products = data.products.edges } return { - products: edges.map(({ node }: ProductEdge) => normalizeProduct(node)), - found: !!edges.length, + products: products?.map(({ node }) => + normalizeProduct(node as ShopifyProduct) + ), + found: !!products?.length, } }, useHook: ({ useData }) => (input = {}) => { @@ -68,6 +78,7 @@ export const handler: SWRHook< ['categoryId', input.categoryId], ['brandId', input.brandId], ['sort', input.sort], + ['locale', input.locale], ], swrOptions: { revalidateOnFocus: false, diff --git a/framework/shopify/schema.d.ts b/framework/shopify/schema.d.ts index b1b23a3e5..328f0ff1b 100644 --- a/framework/shopify/schema.d.ts +++ b/framework/shopify/schema.d.ts @@ -37,7 +37,7 @@ export type ApiVersion = { displayName: Scalars['String'] /** The unique identifier of an ApiVersion. All supported API versions have a date-based (YYYY-MM) or `unstable` handle. */ handle: Scalars['String'] - /** Whether the version is supported by Shopify. */ + /** Whether the version is actively supported by Shopify. Supported API versions are guaranteed to be stable. Unsupported API versions include unstable, release candidate, and end-of-life versions that are marked as unsupported. For more information, refer to [Versioning](https://shopify.dev/concepts/about-apis/versioning). */ supported: Scalars['Boolean'] } @@ -306,17 +306,17 @@ export enum BlogSortKeys { /** Card brand, such as Visa or Mastercard, which can be used for payments. */ export enum CardBrand { - /** Visa */ + /** Visa. */ Visa = 'VISA', - /** Mastercard */ + /** Mastercard. */ Mastercard = 'MASTERCARD', - /** Discover */ + /** Discover. */ Discover = 'DISCOVER', - /** American Express */ + /** American Express. */ AmericanExpress = 'AMERICAN_EXPRESS', - /** Diners Club */ + /** Diners Club. */ DinersClub = 'DINERS_CLUB', - /** JCB */ + /** JCB. */ Jcb = 'JCB', } @@ -1195,6 +1195,8 @@ export enum CountryCode { Am = 'AM', /** Aruba. */ Aw = 'AW', + /** Ascension Island. */ + Ac = 'AC', /** Australia. */ Au = 'AU', /** Austria. */ @@ -1613,6 +1615,8 @@ export enum CountryCode { To = 'TO', /** Trinidad & Tobago. */ Tt = 'TT', + /** Tristan da Cunha. */ + Ta = 'TA', /** Tunisia. */ Tn = 'TN', /** Turkey. */ @@ -1687,7 +1691,7 @@ export type CreditCard = { export type CreditCardPaymentInput = { /** The amount of the payment. */ amount: Scalars['Money'] - /** A unique client generated key used to avoid duplicate charges. When a duplicate payment is found, the original is returned instead of creating a new one. */ + /** A unique client generated key used to avoid duplicate charges. When a duplicate payment is found, the original is returned instead of creating a new one. For more information, refer to [Idempotent requests](https://shopify.dev/concepts/about-apis/idempotent-requests). */ idempotencyKey: Scalars['String'] /** The billing address for the payment. */ billingAddress: MailingAddressInput @@ -1704,7 +1708,7 @@ export type CreditCardPaymentInput = { export type CreditCardPaymentInputV2 = { /** The amount and currency of the payment. */ paymentAmount: MoneyInput - /** A unique client generated key used to avoid duplicate charges. When a duplicate payment is found, the original is returned instead of creating a new one. */ + /** A unique client generated key used to avoid duplicate charges. When a duplicate payment is found, the original is returned instead of creating a new one. For more information, refer to [Idempotent requests](https://shopify.dev/concepts/about-apis/idempotent-requests). */ idempotencyKey: Scalars['String'] /** The billing address for the payment. */ billingAddress: MailingAddressInput @@ -1766,10 +1770,6 @@ export enum CurrencyCode { Bhd = 'BHD', /** Burundian Franc (BIF). */ Bif = 'BIF', - /** Belarusian Ruble (BYN). */ - Byn = 'BYN', - /** Belarusian Ruble (BYR). */ - Byr = 'BYR', /** Belize Dollar (BZD). */ Bzd = 'BZD', /** Bermudian Dollar (BMD). */ @@ -1816,26 +1816,18 @@ export enum CurrencyCode { Czk = 'CZK', /** Danish Kroner (DKK). */ Dkk = 'DKK', - /** Djiboutian Franc (DJF). */ - Djf = 'DJF', /** Dominican Peso (DOP). */ Dop = 'DOP', /** East Caribbean Dollar (XCD). */ Xcd = 'XCD', /** Egyptian Pound (EGP). */ Egp = 'EGP', - /** Eritrean Nakfa (ERN). */ - Ern = 'ERN', /** Ethiopian Birr (ETB). */ Etb = 'ETB', - /** Falkland Islands Pounds (FKP). */ - Fkp = 'FKP', /** CFP Franc (XPF). */ Xpf = 'XPF', /** Fijian Dollars (FJD). */ Fjd = 'FJD', - /** Gibraltar Pounds (GIP). */ - Gip = 'GIP', /** Gambian Dalasi (GMD). */ Gmd = 'GMD', /** Ghanaian Cedi (GHS). */ @@ -1846,8 +1838,6 @@ export enum CurrencyCode { Gyd = 'GYD', /** Georgian Lari (GEL). */ Gel = 'GEL', - /** Guinean Franc (GNF). */ - Gnf = 'GNF', /** Haitian Gourde (HTG). */ Htg = 'HTG', /** Honduran Lempira (HNL). */ @@ -1864,8 +1854,6 @@ export enum CurrencyCode { Idr = 'IDR', /** Israeli New Shekel (NIS). */ Ils = 'ILS', - /** Iranian Rial (IRR). */ - Irr = 'IRR', /** Iraqi Dinar (IQD). */ Iqd = 'IQD', /** Jamaican Dollars (JMD). */ @@ -1880,8 +1868,6 @@ export enum CurrencyCode { Kzt = 'KZT', /** Kenyan Shilling (KES). */ Kes = 'KES', - /** Kiribati Dollar (KID). */ - Kid = 'KID', /** Kuwaiti Dinar (KWD). */ Kwd = 'KWD', /** Kyrgyzstani Som (KGS). */ @@ -1896,8 +1882,6 @@ export enum CurrencyCode { Lsl = 'LSL', /** Liberian Dollar (LRD). */ Lrd = 'LRD', - /** Libyan Dinar (LYD). */ - Lyd = 'LYD', /** Lithuanian Litai (LTL). */ Ltl = 'LTL', /** Malagasy Ariary (MGA). */ @@ -1910,8 +1894,6 @@ export enum CurrencyCode { Mwk = 'MWK', /** Maldivian Rufiyaa (MVR). */ Mvr = 'MVR', - /** Mauritanian Ouguiya (MRU). */ - Mru = 'MRU', /** Mexican Pesos (MXN). */ Mxn = 'MXN', /** Malaysian Ringgits (MYR). */ @@ -1966,8 +1948,6 @@ export enum CurrencyCode { Rwf = 'RWF', /** Samoan Tala (WST). */ Wst = 'WST', - /** Saint Helena Pounds (SHP). */ - Shp = 'SHP', /** Saudi Riyal (SAR). */ Sar = 'SAR', /** Sao Tome And Principe Dobra (STD). */ @@ -1976,14 +1956,10 @@ export enum CurrencyCode { Rsd = 'RSD', /** Seychellois Rupee (SCR). */ Scr = 'SCR', - /** Sierra Leonean Leone (SLL). */ - Sll = 'SLL', /** Singapore Dollars (SGD). */ Sgd = 'SGD', /** Sudanese Pound (SDG). */ Sdg = 'SDG', - /** Somali Shilling (SOS). */ - Sos = 'SOS', /** Syrian Pound (SYP). */ Syp = 'SYP', /** South African Rand (ZAR). */ @@ -2008,12 +1984,8 @@ export enum CurrencyCode { Twd = 'TWD', /** Thai baht (THB). */ Thb = 'THB', - /** Tajikistani Somoni (TJS). */ - Tjs = 'TJS', /** Tanzanian Shilling (TZS). */ Tzs = 'TZS', - /** Tongan Pa'anga (TOP). */ - Top = 'TOP', /** Trinidad and Tobago Dollars (TTD). */ Ttd = 'TTD', /** Tunisian Dinar (TND). */ @@ -2034,10 +2006,6 @@ export enum CurrencyCode { Uzs = 'UZS', /** Vanuatu Vatu (VUV). */ Vuv = 'VUV', - /** Venezuelan Bolivares (VEF). */ - Vef = 'VEF', - /** Venezuelan Bolivares (VES). */ - Ves = 'VES', /** Vietnamese đồng (VND). */ Vnd = 'VND', /** West African CFA franc (XOF). */ @@ -2046,6 +2014,42 @@ export enum CurrencyCode { Yer = 'YER', /** Zambian Kwacha (ZMW). */ Zmw = 'ZMW', + /** Belarusian Ruble (BYN). */ + Byn = 'BYN', + /** Belarusian Ruble (BYR). */ + Byr = 'BYR', + /** Djiboutian Franc (DJF). */ + Djf = 'DJF', + /** Eritrean Nakfa (ERN). */ + Ern = 'ERN', + /** Falkland Islands Pounds (FKP). */ + Fkp = 'FKP', + /** Gibraltar Pounds (GIP). */ + Gip = 'GIP', + /** Guinean Franc (GNF). */ + Gnf = 'GNF', + /** Iranian Rial (IRR). */ + Irr = 'IRR', + /** Kiribati Dollar (KID). */ + Kid = 'KID', + /** Libyan Dinar (LYD). */ + Lyd = 'LYD', + /** Mauritanian Ouguiya (MRU). */ + Mru = 'MRU', + /** Sierra Leonean Leone (SLL). */ + Sll = 'SLL', + /** Saint Helena Pounds (SHP). */ + Shp = 'SHP', + /** Somali Shilling (SOS). */ + Sos = 'SOS', + /** Tajikistani Somoni (TJS). */ + Tjs = 'TJS', + /** Tongan Pa'anga (TOP). */ + Top = 'TOP', + /** Venezuelan Bolivares (VEF). */ + Vef = 'VEF', + /** Venezuelan Bolivares (VES). */ + Ves = 'VES', } /** A customer represents a customer account with the shop. Customer accounts store contact information for the customer, saving logged-in customers the trouble of having to provide it at every checkout. */ @@ -3817,7 +3821,11 @@ export type Payment = Node & { errorMessage?: Maybe /** Globally unique identifier. */ id: Scalars['ID'] - /** A client-side generated token to identify a payment and perform idempotent operations. */ + /** + * A client-side generated token to identify a payment and perform idempotent operations. + * For more information, refer to + * [Idempotent requests](https://shopify.dev/concepts/about-apis/idempotent-requests). + */ idempotencyKey?: Maybe /** The URL where the customer needs to be redirected so they can complete the 3D Secure payment flow. */ nextActionUrl?: Maybe @@ -4386,7 +4394,9 @@ export type QueryRoot = { collections: CollectionConnection /** Find a customer by its access token. */ customer?: Maybe + /** Returns a specific node by ID. */ node?: Maybe + /** Returns the list of nodes with the given IDs. */ nodes: Array> /** Find a page by its handle. */ pageByHandle?: Maybe @@ -4768,7 +4778,7 @@ export type StringEdge = { export type TokenizedPaymentInput = { /** The amount of the payment. */ amount: Scalars['Money'] - /** A unique client generated key used to avoid duplicate charges. When a duplicate payment is found, the original is returned instead of creating a new one. */ + /** A unique client generated key used to avoid duplicate charges. When a duplicate payment is found, the original is returned instead of creating a new one. For more information, refer to [Idempotent requests](https://shopify.dev/concepts/about-apis/idempotent-requests). */ idempotencyKey: Scalars['String'] /** The billing address for the payment. */ billingAddress: MailingAddressInput @@ -4789,7 +4799,7 @@ export type TokenizedPaymentInput = { export type TokenizedPaymentInputV2 = { /** The amount and currency of the payment. */ paymentAmount: MoneyInput - /** A unique client generated key used to avoid duplicate charges. When a duplicate payment is found, the original is returned instead of creating a new one. */ + /** A unique client generated key used to avoid duplicate charges. When a duplicate payment is found, the original is returned instead of creating a new one. For more information, refer to [Idempotent requests](https://shopify.dev/concepts/about-apis/idempotent-requests). */ idempotencyKey: Scalars['String'] /** The billing address for the payment. */ billingAddress: MailingAddressInput @@ -4810,7 +4820,7 @@ export type TokenizedPaymentInputV2 = { export type TokenizedPaymentInputV3 = { /** The amount and currency of the payment. */ paymentAmount: MoneyInput - /** A unique client generated key used to avoid duplicate charges. When a duplicate payment is found, the original is returned instead of creating a new one. */ + /** A unique client generated key used to avoid duplicate charges. When a duplicate payment is found, the original is returned instead of creating a new one. For more information, refer to [Idempotent requests](https://shopify.dev/concepts/about-apis/idempotent-requests). */ idempotencyKey: Scalars['String'] /** The billing address for the payment. */ billingAddress: MailingAddressInput @@ -4847,18 +4857,32 @@ export type Transaction = { test: Scalars['Boolean'] } +/** The different kinds of order transactions. */ export enum TransactionKind { + /** An authorization and capture performed together in a single step. */ Sale = 'SALE', + /** A transfer of the money that was reserved during the authorization stage. */ Capture = 'CAPTURE', + /** + * An amount reserved against the cardholder's funding source. + * Money does not change hands until the authorization is captured. + */ Authorization = 'AUTHORIZATION', + /** An authorization for a payment taken with an EMV credit card reader. */ EmvAuthorization = 'EMV_AUTHORIZATION', + /** Money returned to the customer when they have paid too much. */ Change = 'CHANGE', } +/** Transaction statuses describe the status of a transaction. */ export enum TransactionStatus { + /** The transaction is pending. */ Pending = 'PENDING', + /** The transaction succeeded. */ Success = 'SUCCESS', + /** The transaction failed. */ Failure = 'FAILURE', + /** There was an error while processing the transaction. */ Error = 'ERROR', } @@ -4967,19 +4991,596 @@ export enum WeightUnit { Ounces = 'OUNCES', } -export type Unnamed_1_QueryVariables = Exact<{ +export type AssociateCustomerWithCheckoutMutationVariables = Exact<{ + checkoutId: Scalars['ID'] + customerAccessToken: Scalars['String'] +}> + +export type AssociateCustomerWithCheckoutMutation = { + __typename?: 'Mutation' +} & { + checkoutCustomerAssociateV2?: Maybe< + { __typename?: 'CheckoutCustomerAssociateV2Payload' } & { + checkout?: Maybe<{ __typename?: 'Checkout' } & Pick> + checkoutUserErrors: Array< + { __typename?: 'CheckoutUserError' } & Pick< + CheckoutUserError, + 'code' | 'field' | 'message' + > + > + customer?: Maybe<{ __typename?: 'Customer' } & Pick> + } + > +} + +export type CheckoutCreateMutationVariables = Exact<{ + input?: Maybe +}> + +export type CheckoutCreateMutation = { __typename?: 'Mutation' } & { + checkoutCreate?: Maybe< + { __typename?: 'CheckoutCreatePayload' } & { + checkoutUserErrors: Array< + { __typename?: 'CheckoutUserError' } & Pick< + CheckoutUserError, + 'code' | 'field' | 'message' + > + > + checkout?: Maybe<{ __typename?: 'Checkout' } & CheckoutDetailsFragment> + } + > +} + +export type CheckoutLineItemAddMutationVariables = Exact<{ + checkoutId: Scalars['ID'] + lineItems: Array | CheckoutLineItemInput +}> + +export type CheckoutLineItemAddMutation = { __typename?: 'Mutation' } & { + checkoutLineItemsAdd?: Maybe< + { __typename?: 'CheckoutLineItemsAddPayload' } & { + checkoutUserErrors: Array< + { __typename?: 'CheckoutUserError' } & Pick< + CheckoutUserError, + 'code' | 'field' | 'message' + > + > + checkout?: Maybe<{ __typename?: 'Checkout' } & CheckoutDetailsFragment> + } + > +} + +export type CheckoutLineItemRemoveMutationVariables = Exact<{ + checkoutId: Scalars['ID'] + lineItemIds: Array | Scalars['ID'] +}> + +export type CheckoutLineItemRemoveMutation = { __typename?: 'Mutation' } & { + checkoutLineItemsRemove?: Maybe< + { __typename?: 'CheckoutLineItemsRemovePayload' } & { + checkoutUserErrors: Array< + { __typename?: 'CheckoutUserError' } & Pick< + CheckoutUserError, + 'code' | 'field' | 'message' + > + > + checkout?: Maybe<{ __typename?: 'Checkout' } & CheckoutDetailsFragment> + } + > +} + +export type CheckoutLineItemUpdateMutationVariables = Exact<{ + checkoutId: Scalars['ID'] + lineItems: Array | CheckoutLineItemUpdateInput +}> + +export type CheckoutLineItemUpdateMutation = { __typename?: 'Mutation' } & { + checkoutLineItemsUpdate?: Maybe< + { __typename?: 'CheckoutLineItemsUpdatePayload' } & { + checkoutUserErrors: Array< + { __typename?: 'CheckoutUserError' } & Pick< + CheckoutUserError, + 'code' | 'field' | 'message' + > + > + checkout?: Maybe<{ __typename?: 'Checkout' } & CheckoutDetailsFragment> + } + > +} + +export type CustomerAccessTokenCreateMutationVariables = Exact<{ + input: CustomerAccessTokenCreateInput +}> + +export type CustomerAccessTokenCreateMutation = { __typename?: 'Mutation' } & { + customerAccessTokenCreate?: Maybe< + { __typename?: 'CustomerAccessTokenCreatePayload' } & { + customerAccessToken?: Maybe< + { __typename?: 'CustomerAccessToken' } & Pick< + CustomerAccessToken, + 'accessToken' | 'expiresAt' + > + > + customerUserErrors: Array< + { __typename?: 'CustomerUserError' } & Pick< + CustomerUserError, + 'code' | 'field' | 'message' + > + > + } + > +} + +export type CustomerAccessTokenDeleteMutationVariables = Exact<{ + customerAccessToken: Scalars['String'] +}> + +export type CustomerAccessTokenDeleteMutation = { __typename?: 'Mutation' } & { + customerAccessTokenDelete?: Maybe< + { __typename?: 'CustomerAccessTokenDeletePayload' } & Pick< + CustomerAccessTokenDeletePayload, + 'deletedAccessToken' | 'deletedCustomerAccessTokenId' + > & { + userErrors: Array< + { __typename?: 'UserError' } & Pick + > + } + > +} + +export type CustomerActivateByUrlMutationVariables = Exact<{ + activationUrl: Scalars['URL'] + password: Scalars['String'] +}> + +export type CustomerActivateByUrlMutation = { __typename?: 'Mutation' } & { + customerActivateByUrl?: Maybe< + { __typename?: 'CustomerActivateByUrlPayload' } & { + customer?: Maybe<{ __typename?: 'Customer' } & Pick> + customerAccessToken?: Maybe< + { __typename?: 'CustomerAccessToken' } & Pick< + CustomerAccessToken, + 'accessToken' | 'expiresAt' + > + > + customerUserErrors: Array< + { __typename?: 'CustomerUserError' } & Pick< + CustomerUserError, + 'code' | 'field' | 'message' + > + > + } + > +} + +export type CustomerActivateMutationVariables = Exact<{ + id: Scalars['ID'] + input: CustomerActivateInput +}> + +export type CustomerActivateMutation = { __typename?: 'Mutation' } & { + customerActivate?: Maybe< + { __typename?: 'CustomerActivatePayload' } & { + customer?: Maybe<{ __typename?: 'Customer' } & Pick> + customerAccessToken?: Maybe< + { __typename?: 'CustomerAccessToken' } & Pick< + CustomerAccessToken, + 'accessToken' | 'expiresAt' + > + > + customerUserErrors: Array< + { __typename?: 'CustomerUserError' } & Pick< + CustomerUserError, + 'code' | 'field' | 'message' + > + > + } + > +} + +export type CustomerCreateMutationVariables = Exact<{ + input: CustomerCreateInput +}> + +export type CustomerCreateMutation = { __typename?: 'Mutation' } & { + customerCreate?: Maybe< + { __typename?: 'CustomerCreatePayload' } & { + customerUserErrors: Array< + { __typename?: 'CustomerUserError' } & Pick< + CustomerUserError, + 'code' | 'field' | 'message' + > + > + customer?: Maybe<{ __typename?: 'Customer' } & Pick> + } + > +} + +export type GetSiteCollectionsQueryVariables = Exact<{ first: Scalars['Int'] }> -export type Unnamed_1_Query = { __typename?: 'QueryRoot' } & { - pages: { __typename?: 'PageConnection' } & { +export type GetSiteCollectionsQuery = { __typename?: 'QueryRoot' } & { + collections: { __typename?: 'CollectionConnection' } & { edges: Array< - { __typename?: 'PageEdge' } & { - node: { __typename?: 'Page' } & Pick< - Page, - 'id' | 'title' | 'handle' | 'body' | 'bodySummary' | 'url' + { __typename?: 'CollectionEdge' } & { + node: { __typename?: 'Collection' } & Pick< + Collection, + 'id' | 'title' | 'handle' > } > } } + +export type GetAllPagesQueryVariables = Exact<{ + first?: Maybe +}> + +export type GetAllPagesQuery = { __typename?: 'QueryRoot' } & { + pages: { __typename?: 'PageConnection' } & { + edges: Array< + { __typename?: 'PageEdge' } & { + node: { __typename?: 'Page' } & Pick + } + > + } +} + +export type GetAllProductVendorsQueryVariables = Exact<{ + first?: Maybe + cursor?: Maybe +}> + +export type GetAllProductVendorsQuery = { __typename?: 'QueryRoot' } & { + products: { __typename?: 'ProductConnection' } & { + pageInfo: { __typename?: 'PageInfo' } & Pick< + PageInfo, + 'hasNextPage' | 'hasPreviousPage' + > + edges: Array< + { __typename?: 'ProductEdge' } & Pick & { + node: { __typename?: 'Product' } & Pick + } + > + } +} + +export type GetAllProductPathsQueryVariables = Exact<{ + first?: Maybe + cursor?: Maybe +}> + +export type GetAllProductPathsQuery = { __typename?: 'QueryRoot' } & { + products: { __typename?: 'ProductConnection' } & { + pageInfo: { __typename?: 'PageInfo' } & Pick< + PageInfo, + 'hasNextPage' | 'hasPreviousPage' + > + edges: Array< + { __typename?: 'ProductEdge' } & Pick & { + node: { __typename?: 'Product' } & Pick + } + > + } +} + +export type ProductConnectionFragment = { __typename?: 'ProductConnection' } & { + pageInfo: { __typename?: 'PageInfo' } & Pick< + PageInfo, + 'hasNextPage' | 'hasPreviousPage' + > + edges: Array< + { __typename?: 'ProductEdge' } & { + node: { __typename?: 'Product' } & Pick< + Product, + 'id' | 'title' | 'vendor' | 'handle' + > & { + priceRange: { __typename?: 'ProductPriceRange' } & { + minVariantPrice: { __typename?: 'MoneyV2' } & Pick< + MoneyV2, + 'amount' | 'currencyCode' + > + } + images: { __typename?: 'ImageConnection' } & { + pageInfo: { __typename?: 'PageInfo' } & Pick< + PageInfo, + 'hasNextPage' | 'hasPreviousPage' + > + edges: Array< + { __typename?: 'ImageEdge' } & { + node: { __typename?: 'Image' } & Pick< + Image, + 'originalSrc' | 'altText' | 'width' | 'height' + > + } + > + } + } + } + > +} + +export type GetAllProductsQueryVariables = Exact<{ + first?: Maybe + query?: Maybe + sortKey?: Maybe + reverse?: Maybe +}> + +export type GetAllProductsQuery = { __typename?: 'QueryRoot' } & { + products: { __typename?: 'ProductConnection' } & ProductConnectionFragment +} + +export type CheckoutDetailsFragment = { __typename?: 'Checkout' } & Pick< + Checkout, + 'id' | 'webUrl' | 'completedAt' | 'createdAt' | 'taxesIncluded' +> & { + subtotalPriceV2: { __typename?: 'MoneyV2' } & Pick< + MoneyV2, + 'amount' | 'currencyCode' + > + totalTaxV2: { __typename?: 'MoneyV2' } & Pick< + MoneyV2, + 'amount' | 'currencyCode' + > + totalPriceV2: { __typename?: 'MoneyV2' } & Pick< + MoneyV2, + 'amount' | 'currencyCode' + > + lineItems: { __typename?: 'CheckoutLineItemConnection' } & { + pageInfo: { __typename?: 'PageInfo' } & Pick< + PageInfo, + 'hasNextPage' | 'hasPreviousPage' + > + edges: Array< + { __typename?: 'CheckoutLineItemEdge' } & { + node: { __typename?: 'CheckoutLineItem' } & Pick< + CheckoutLineItem, + 'id' | 'title' | 'quantity' + > & { + variant?: Maybe< + { __typename?: 'ProductVariant' } & Pick< + ProductVariant, + 'id' | 'sku' | 'title' + > & { + image?: Maybe< + { __typename?: 'Image' } & Pick< + Image, + 'originalSrc' | 'altText' | 'width' | 'height' + > + > + priceV2: { __typename?: 'MoneyV2' } & Pick< + MoneyV2, + 'amount' | 'currencyCode' + > + compareAtPriceV2?: Maybe< + { __typename?: 'MoneyV2' } & Pick< + MoneyV2, + 'amount' | 'currencyCode' + > + > + product: { __typename?: 'Product' } & Pick< + Product, + 'handle' + > + } + > + } + } + > + } + } + +export type GetCheckoutQueryVariables = Exact<{ + checkoutId: Scalars['ID'] +}> + +export type GetCheckoutQuery = { __typename?: 'QueryRoot' } & { + node?: Maybe< + | { __typename?: 'AppliedGiftCard' } + | { __typename?: 'Article' } + | { __typename?: 'Blog' } + | ({ __typename?: 'Checkout' } & CheckoutDetailsFragment) + | { __typename?: 'CheckoutLineItem' } + | { __typename?: 'Collection' } + | { __typename?: 'Comment' } + | { __typename?: 'ExternalVideo' } + | { __typename?: 'MailingAddress' } + | { __typename?: 'MediaImage' } + | { __typename?: 'Metafield' } + | { __typename?: 'Model3d' } + | { __typename?: 'Order' } + | { __typename?: 'Page' } + | { __typename?: 'Payment' } + | { __typename?: 'Product' } + | { __typename?: 'ProductOption' } + | { __typename?: 'ProductVariant' } + | { __typename?: 'ShopPolicy' } + | { __typename?: 'Video' } + > +} + +export type GetProductsFromCollectionQueryVariables = Exact<{ + categoryId: Scalars['ID'] + first?: Maybe + sortKey?: Maybe + reverse?: Maybe +}> + +export type GetProductsFromCollectionQuery = { __typename?: 'QueryRoot' } & { + node?: Maybe< + | ({ __typename?: 'AppliedGiftCard' } & Pick) + | ({ __typename?: 'Article' } & Pick) + | ({ __typename?: 'Blog' } & Pick) + | ({ __typename?: 'Checkout' } & Pick) + | ({ __typename?: 'CheckoutLineItem' } & Pick) + | ({ __typename?: 'Collection' } & Pick & { + products: { + __typename?: 'ProductConnection' + } & ProductConnectionFragment + }) + | ({ __typename?: 'Comment' } & Pick) + | ({ __typename?: 'ExternalVideo' } & Pick) + | ({ __typename?: 'MailingAddress' } & Pick) + | ({ __typename?: 'MediaImage' } & Pick) + | ({ __typename?: 'Metafield' } & Pick) + | ({ __typename?: 'Model3d' } & Pick) + | ({ __typename?: 'Order' } & Pick) + | ({ __typename?: 'Page' } & Pick) + | ({ __typename?: 'Payment' } & Pick) + | ({ __typename?: 'Product' } & Pick) + | ({ __typename?: 'ProductOption' } & Pick) + | ({ __typename?: 'ProductVariant' } & Pick) + | ({ __typename?: 'ShopPolicy' } & Pick) + | ({ __typename?: 'Video' } & Pick) + > +} + +export type GetCustomerIdQueryVariables = Exact<{ + customerAccessToken: Scalars['String'] +}> + +export type GetCustomerIdQuery = { __typename?: 'QueryRoot' } & { + customer?: Maybe<{ __typename?: 'Customer' } & Pick> +} + +export type GetCustomerQueryVariables = Exact<{ + customerAccessToken: Scalars['String'] +}> + +export type GetCustomerQuery = { __typename?: 'QueryRoot' } & { + customer?: Maybe< + { __typename?: 'Customer' } & Pick< + Customer, + | 'id' + | 'firstName' + | 'lastName' + | 'displayName' + | 'email' + | 'phone' + | 'tags' + | 'acceptsMarketing' + | 'createdAt' + > + > +} + +export type GetPageQueryVariables = Exact<{ + id: Scalars['ID'] +}> + +export type GetPageQuery = { __typename?: 'QueryRoot' } & { + node?: Maybe< + | ({ __typename?: 'AppliedGiftCard' } & Pick) + | ({ __typename?: 'Article' } & Pick) + | ({ __typename?: 'Blog' } & Pick) + | ({ __typename?: 'Checkout' } & Pick) + | ({ __typename?: 'CheckoutLineItem' } & Pick) + | ({ __typename?: 'Collection' } & Pick) + | ({ __typename?: 'Comment' } & Pick) + | ({ __typename?: 'ExternalVideo' } & Pick) + | ({ __typename?: 'MailingAddress' } & Pick) + | ({ __typename?: 'MediaImage' } & Pick) + | ({ __typename?: 'Metafield' } & Pick) + | ({ __typename?: 'Model3d' } & Pick) + | ({ __typename?: 'Order' } & Pick) + | ({ __typename?: 'Page' } & Pick< + Page, + 'title' | 'handle' | 'body' | 'bodySummary' | 'id' + >) + | ({ __typename?: 'Payment' } & Pick) + | ({ __typename?: 'Product' } & Pick) + | ({ __typename?: 'ProductOption' } & Pick) + | ({ __typename?: 'ProductVariant' } & Pick) + | ({ __typename?: 'ShopPolicy' } & Pick) + | ({ __typename?: 'Video' } & Pick) + > +} + +export type GetProductBySlugQueryVariables = Exact<{ + slug: Scalars['String'] +}> + +export type GetProductBySlugQuery = { __typename?: 'QueryRoot' } & { + productByHandle?: Maybe< + { __typename?: 'Product' } & Pick< + Product, + | 'id' + | 'handle' + | 'title' + | 'productType' + | 'vendor' + | 'description' + | 'descriptionHtml' + > & { + options: Array< + { __typename?: 'ProductOption' } & Pick< + ProductOption, + 'id' | 'name' | 'values' + > + > + priceRange: { __typename?: 'ProductPriceRange' } & { + maxVariantPrice: { __typename?: 'MoneyV2' } & Pick< + MoneyV2, + 'amount' | 'currencyCode' + > + minVariantPrice: { __typename?: 'MoneyV2' } & Pick< + MoneyV2, + 'amount' | 'currencyCode' + > + } + variants: { __typename?: 'ProductVariantConnection' } & { + pageInfo: { __typename?: 'PageInfo' } & Pick< + PageInfo, + 'hasNextPage' | 'hasPreviousPage' + > + edges: Array< + { __typename?: 'ProductVariantEdge' } & { + node: { __typename?: 'ProductVariant' } & Pick< + ProductVariant, + 'id' | 'title' | 'sku' + > & { + selectedOptions: Array< + { __typename?: 'SelectedOption' } & Pick< + SelectedOption, + 'name' | 'value' + > + > + priceV2: { __typename?: 'MoneyV2' } & Pick< + MoneyV2, + 'amount' | 'currencyCode' + > + compareAtPriceV2?: Maybe< + { __typename?: 'MoneyV2' } & Pick< + MoneyV2, + 'amount' | 'currencyCode' + > + > + } + } + > + } + images: { __typename?: 'ImageConnection' } & { + pageInfo: { __typename?: 'PageInfo' } & Pick< + PageInfo, + 'hasNextPage' | 'hasPreviousPage' + > + edges: Array< + { __typename?: 'ImageEdge' } & { + node: { __typename?: 'Image' } & Pick< + Image, + 'originalSrc' | 'altText' | 'width' | 'height' + > + } + > + } + } + > +} + +export type GetSiteInfoQueryVariables = Exact<{ [key: string]: never }> + +export type GetSiteInfoQuery = { __typename?: 'QueryRoot' } & { + shop: { __typename?: 'Shop' } & Pick +} diff --git a/framework/shopify/schema.graphql b/framework/shopify/schema.graphql index 822e6007e..9c657fe43 100644 --- a/framework/shopify/schema.graphql +++ b/framework/shopify/schema.graphql @@ -13,6 +13,16 @@ directive @accessRestricted( reason: String = null ) on FIELD_DEFINITION | OBJECT +""" +Contextualize data. +""" +directive @inContext( + """ + The country code for context. + """ + country: CountryCode! +) on QUERY | MUTATION + """ A version of the API. """ @@ -28,7 +38,7 @@ type ApiVersion { handle: String! """ - Whether the version is supported by Shopify. + Whether the version is actively supported by Shopify. Supported API versions are guaranteed to be stable. Unsupported API versions include unstable, release candidate, and end-of-life versions that are marked as unsupported. For more information, refer to [Versioning](https://shopify.dev/concepts/about-apis/versioning). """ supported: Boolean! } @@ -547,32 +557,32 @@ Card brand, such as Visa or Mastercard, which can be used for payments. """ enum CardBrand { """ - Visa + Visa. """ VISA """ - Mastercard + Mastercard. """ MASTERCARD """ - Discover + Discover. """ DISCOVER """ - American Express + American Express. """ AMERICAN_EXPRESS """ - Diners Club + Diners Club. """ DINERS_CLUB """ - JCB + JCB. """ JCB } @@ -2142,6 +2152,11 @@ enum CountryCode { """ AW + """ + Ascension Island. + """ + AC + """ Australia. """ @@ -3187,6 +3202,11 @@ enum CountryCode { """ TT + """ + Tristan da Cunha. + """ + TA + """ Tunisia. """ @@ -3354,7 +3374,7 @@ input CreditCardPaymentInput { amount: Money! """ - A unique client generated key used to avoid duplicate charges. When a duplicate payment is found, the original is returned instead of creating a new one. + A unique client generated key used to avoid duplicate charges. When a duplicate payment is found, the original is returned instead of creating a new one. For more information, refer to [Idempotent requests](https://shopify.dev/concepts/about-apis/idempotent-requests). """ idempotencyKey: String! @@ -3385,7 +3405,7 @@ input CreditCardPaymentInputV2 { paymentAmount: MoneyInput! """ - A unique client generated key used to avoid duplicate charges. When a duplicate payment is found, the original is returned instead of creating a new one. + A unique client generated key used to avoid duplicate charges. When a duplicate payment is found, the original is returned instead of creating a new one. For more information, refer to [Idempotent requests](https://shopify.dev/concepts/about-apis/idempotent-requests). """ idempotencyKey: String! @@ -3529,16 +3549,6 @@ enum CurrencyCode { """ BIF - """ - Belarusian Ruble (BYN). - """ - BYN - - """ - Belarusian Ruble (BYR). - """ - BYR - """ Belize Dollar (BZD). """ @@ -3654,11 +3664,6 @@ enum CurrencyCode { """ DKK - """ - Djiboutian Franc (DJF). - """ - DJF - """ Dominican Peso (DOP). """ @@ -3674,21 +3679,11 @@ enum CurrencyCode { """ EGP - """ - Eritrean Nakfa (ERN). - """ - ERN - """ Ethiopian Birr (ETB). """ ETB - """ - Falkland Islands Pounds (FKP). - """ - FKP - """ CFP Franc (XPF). """ @@ -3699,11 +3694,6 @@ enum CurrencyCode { """ FJD - """ - Gibraltar Pounds (GIP). - """ - GIP - """ Gambian Dalasi (GMD). """ @@ -3729,11 +3719,6 @@ enum CurrencyCode { """ GEL - """ - Guinean Franc (GNF). - """ - GNF - """ Haitian Gourde (HTG). """ @@ -3774,11 +3759,6 @@ enum CurrencyCode { """ ILS - """ - Iranian Rial (IRR). - """ - IRR - """ Iraqi Dinar (IQD). """ @@ -3814,11 +3794,6 @@ enum CurrencyCode { """ KES - """ - Kiribati Dollar (KID). - """ - KID - """ Kuwaiti Dinar (KWD). """ @@ -3854,11 +3829,6 @@ enum CurrencyCode { """ LRD - """ - Libyan Dinar (LYD). - """ - LYD - """ Lithuanian Litai (LTL). """ @@ -3889,11 +3859,6 @@ enum CurrencyCode { """ MVR - """ - Mauritanian Ouguiya (MRU). - """ - MRU - """ Mexican Pesos (MXN). """ @@ -4029,11 +3994,6 @@ enum CurrencyCode { """ WST - """ - Saint Helena Pounds (SHP). - """ - SHP - """ Saudi Riyal (SAR). """ @@ -4054,11 +4014,6 @@ enum CurrencyCode { """ SCR - """ - Sierra Leonean Leone (SLL). - """ - SLL - """ Singapore Dollars (SGD). """ @@ -4069,11 +4024,6 @@ enum CurrencyCode { """ SDG - """ - Somali Shilling (SOS). - """ - SOS - """ Syrian Pound (SYP). """ @@ -4134,21 +4084,11 @@ enum CurrencyCode { """ THB - """ - Tajikistani Somoni (TJS). - """ - TJS - """ Tanzanian Shilling (TZS). """ TZS - """ - Tongan Pa'anga (TOP). - """ - TOP - """ Trinidad and Tobago Dollars (TTD). """ @@ -4199,16 +4139,6 @@ enum CurrencyCode { """ VUV - """ - Venezuelan Bolivares (VEF). - """ - VEF - - """ - Venezuelan Bolivares (VES). - """ - VES - """ Vietnamese đồng (VND). """ @@ -4228,6 +4158,96 @@ enum CurrencyCode { Zambian Kwacha (ZMW). """ ZMW + + """ + Belarusian Ruble (BYN). + """ + BYN + + """ + Belarusian Ruble (BYR). + """ + BYR + + """ + Djiboutian Franc (DJF). + """ + DJF + + """ + Eritrean Nakfa (ERN). + """ + ERN + + """ + Falkland Islands Pounds (FKP). + """ + FKP + + """ + Gibraltar Pounds (GIP). + """ + GIP + + """ + Guinean Franc (GNF). + """ + GNF + + """ + Iranian Rial (IRR). + """ + IRR + + """ + Kiribati Dollar (KID). + """ + KID + + """ + Libyan Dinar (LYD). + """ + LYD + + """ + Mauritanian Ouguiya (MRU). + """ + MRU + + """ + Sierra Leonean Leone (SLL). + """ + SLL + + """ + Saint Helena Pounds (SHP). + """ + SHP + + """ + Somali Shilling (SOS). + """ + SOS + + """ + Tajikistani Somoni (TJS). + """ + TJS + + """ + Tongan Pa'anga (TOP). + """ + TOP + + """ + Venezuelan Bolivares (VEF). + """ + VEF + + """ + Venezuelan Bolivares (VES). + """ + VES } """ @@ -7355,6 +7375,8 @@ type Payment implements Node { """ A client-side generated token to identify a payment and perform idempotent operations. + For more information, refer to + [Idempotent requests](https://shopify.dev/concepts/about-apis/idempotent-requests). """ idempotencyKey: String @@ -8589,12 +8611,20 @@ type QueryRoot { """ customerAccessToken: String! ): Customer + + """ + Returns a specific node by ID. + """ node( """ The ID of the Node to return. """ id: ID! ): Node + + """ + Returns the list of nodes with the given IDs. + """ nodes( """ The IDs of the Nodes to return. @@ -9246,7 +9276,7 @@ input TokenizedPaymentInput { amount: Money! """ - A unique client generated key used to avoid duplicate charges. When a duplicate payment is found, the original is returned instead of creating a new one. + A unique client generated key used to avoid duplicate charges. When a duplicate payment is found, the original is returned instead of creating a new one. For more information, refer to [Idempotent requests](https://shopify.dev/concepts/about-apis/idempotent-requests). """ idempotencyKey: String! @@ -9287,7 +9317,7 @@ input TokenizedPaymentInputV2 { paymentAmount: MoneyInput! """ - A unique client generated key used to avoid duplicate charges. When a duplicate payment is found, the original is returned instead of creating a new one. + A unique client generated key used to avoid duplicate charges. When a duplicate payment is found, the original is returned instead of creating a new one. For more information, refer to [Idempotent requests](https://shopify.dev/concepts/about-apis/idempotent-requests). """ idempotencyKey: String! @@ -9328,7 +9358,7 @@ input TokenizedPaymentInputV3 { paymentAmount: MoneyInput! """ - A unique client generated key used to avoid duplicate charges. When a duplicate payment is found, the original is returned instead of creating a new one. + A unique client generated key used to avoid duplicate charges. When a duplicate payment is found, the original is returned instead of creating a new one. For more information, refer to [Idempotent requests](https://shopify.dev/concepts/about-apis/idempotent-requests). """ idempotencyKey: String! @@ -9393,18 +9423,59 @@ type Transaction { test: Boolean! } +""" +The different kinds of order transactions. +""" enum TransactionKind { + """ + An authorization and capture performed together in a single step. + """ SALE + + """ + A transfer of the money that was reserved during the authorization stage. + """ CAPTURE + + """ + An amount reserved against the cardholder's funding source. + Money does not change hands until the authorization is captured. + """ AUTHORIZATION + + """ + An authorization for a payment taken with an EMV credit card reader. + """ EMV_AUTHORIZATION + + """ + Money returned to the customer when they have paid too much. + """ CHANGE } +""" +Transaction statuses describe the status of a transaction. +""" enum TransactionStatus { + """ + The transaction is pending. + """ PENDING + + """ + The transaction succeeded. + """ SUCCESS + + """ + The transaction failed. + """ FAILURE + + """ + There was an error while processing the transaction. + """ ERROR } diff --git a/framework/shopify/types.ts b/framework/shopify/types.ts deleted file mode 100644 index e7bcb2476..000000000 --- a/framework/shopify/types.ts +++ /dev/null @@ -1,43 +0,0 @@ -import * as Core from '@commerce/types' -import { CheckoutLineItem } from './schema' - -export type ShopifyCheckout = { - id: string - webUrl: string - lineItems: CheckoutLineItem[] -} - -export type Cart = Core.Cart & { - lineItems: LineItem[] -} -export interface LineItem extends Core.LineItem { - options?: any[] -} - -/** - * Cart mutations - */ - -export type OptionSelections = { - option_id: number - option_value: number | string -} - -export type CartItemBody = Core.CartItemBody & { - productId: string // The product id is always required for BC - optionSelections?: OptionSelections -} - -export type GetCartHandlerBody = Core.GetCartHandlerBody - -export type AddCartItemBody = Core.AddCartItemBody - -export type AddCartItemHandlerBody = Core.AddCartItemHandlerBody - -export type UpdateCartItemBody = Core.UpdateCartItemBody - -export type UpdateCartItemHandlerBody = Core.UpdateCartItemHandlerBody - -export type RemoveCartItemBody = Core.RemoveCartItemBody - -export type RemoveCartItemHandlerBody = Core.RemoveCartItemHandlerBody diff --git a/framework/shopify/types/cart.ts b/framework/shopify/types/cart.ts new file mode 100644 index 000000000..09410740a --- /dev/null +++ b/framework/shopify/types/cart.ts @@ -0,0 +1,32 @@ +import * as Core from '@commerce/types/cart' + +export * from '@commerce/types/cart' + +export type ShopifyCart = {} + +/** + * Extend core cart types + */ + +export type Cart = Core.Cart & { + lineItems: Core.LineItem[] + url?: string +} + +export type CartTypes = Core.CartTypes + +export type CartHooks = Core.CartHooks + +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 + +export type CartHandlers = Core.CartHandlers + +export type GetCartHandler = CartHandlers['getCart'] +export type AddItemHandler = CartHandlers['addItem'] +export type UpdateItemHandler = CartHandlers['updateItem'] +export type RemoveItemHandler = CartHandlers['removeItem'] diff --git a/framework/shopify/types/checkout.ts b/framework/shopify/types/checkout.ts new file mode 100644 index 000000000..4e2412ef6 --- /dev/null +++ b/framework/shopify/types/checkout.ts @@ -0,0 +1 @@ +export * from '@commerce/types/checkout' diff --git a/framework/shopify/types/common.ts b/framework/shopify/types/common.ts new file mode 100644 index 000000000..b52c33a4d --- /dev/null +++ b/framework/shopify/types/common.ts @@ -0,0 +1 @@ +export * from '@commerce/types/common' diff --git a/framework/shopify/types/customer.ts b/framework/shopify/types/customer.ts new file mode 100644 index 000000000..427bc0b03 --- /dev/null +++ b/framework/shopify/types/customer.ts @@ -0,0 +1,5 @@ +import * as Core from '@commerce/types/customer' + +export * from '@commerce/types/customer' + +export type CustomerSchema = Core.CustomerSchema diff --git a/framework/shopify/types/index.ts b/framework/shopify/types/index.ts new file mode 100644 index 000000000..7ab0b7f64 --- /dev/null +++ b/framework/shopify/types/index.ts @@ -0,0 +1,25 @@ +import * as Cart from './cart' +import * as Checkout from './checkout' +import * as Common from './common' +import * as Customer from './customer' +import * as Login from './login' +import * as Logout from './logout' +import * as Page from './page' +import * as Product from './product' +import * as Signup from './signup' +import * as Site from './site' +import * as Wishlist from './wishlist' + +export type { + Cart, + Checkout, + Common, + Customer, + Login, + Logout, + Page, + Product, + Signup, + Site, + Wishlist, +} diff --git a/framework/shopify/types/login.ts b/framework/shopify/types/login.ts new file mode 100644 index 000000000..964ac89e2 --- /dev/null +++ b/framework/shopify/types/login.ts @@ -0,0 +1,8 @@ +import * as Core from '@commerce/types/login' +import type { CustomerAccessTokenCreateInput } from '../schema' + +export * from '@commerce/types/login' + +export type LoginOperation = Core.LoginOperation & { + variables: CustomerAccessTokenCreateInput +} diff --git a/framework/shopify/types/logout.ts b/framework/shopify/types/logout.ts new file mode 100644 index 000000000..9f0a466af --- /dev/null +++ b/framework/shopify/types/logout.ts @@ -0,0 +1 @@ +export * from '@commerce/types/logout' diff --git a/framework/shopify/types/page.ts b/framework/shopify/types/page.ts new file mode 100644 index 000000000..2bccfade2 --- /dev/null +++ b/framework/shopify/types/page.ts @@ -0,0 +1,11 @@ +import * as Core from '@commerce/types/page' +export * from '@commerce/types/page' + +export type Page = Core.Page + +export type PageTypes = { + page: Page +} + +export type GetAllPagesOperation = Core.GetAllPagesOperation +export type GetPageOperation = Core.GetPageOperation diff --git a/framework/shopify/types/product.ts b/framework/shopify/types/product.ts new file mode 100644 index 000000000..c776d58fa --- /dev/null +++ b/framework/shopify/types/product.ts @@ -0,0 +1 @@ +export * from '@commerce/types/product' diff --git a/framework/shopify/types/signup.ts b/framework/shopify/types/signup.ts new file mode 100644 index 000000000..58543c6f6 --- /dev/null +++ b/framework/shopify/types/signup.ts @@ -0,0 +1 @@ +export * from '@commerce/types/signup' diff --git a/framework/shopify/types/site.ts b/framework/shopify/types/site.ts new file mode 100644 index 000000000..bfef69cf9 --- /dev/null +++ b/framework/shopify/types/site.ts @@ -0,0 +1 @@ +export * from '@commerce/types/site' diff --git a/framework/shopify/types/wishlist.ts b/framework/shopify/types/wishlist.ts new file mode 100644 index 000000000..8907fbf82 --- /dev/null +++ b/framework/shopify/types/wishlist.ts @@ -0,0 +1 @@ +export * from '@commerce/types/wishlist' diff --git a/framework/shopify/utils/checkout-to-cart.ts b/framework/shopify/utils/checkout-to-cart.ts index 034ff11d7..e2531cc78 100644 --- a/framework/shopify/utils/checkout-to-cart.ts +++ b/framework/shopify/utils/checkout-to-cart.ts @@ -1,4 +1,4 @@ -import { Cart } from '../types' +import type { Cart } from '../types/cart' import { CommerceError } from '@commerce/utils/errors' import { @@ -27,12 +27,6 @@ export type CheckoutPayload = | CheckoutQuery const checkoutToCart = (checkoutPayload?: Maybe): Cart => { - if (!checkoutPayload) { - throw new CommerceError({ - message: 'Missing checkout payload from response', - }) - } - const checkout = checkoutPayload?.checkout throwUserErrors(checkoutPayload?.checkoutUserErrors) diff --git a/framework/shopify/utils/get-vendors.ts b/framework/shopify/utils/get-brands.ts similarity index 56% rename from framework/shopify/utils/get-vendors.ts rename to framework/shopify/utils/get-brands.ts index 24843f177..3065e4ae8 100644 --- a/framework/shopify/utils/get-vendors.ts +++ b/framework/shopify/utils/get-brands.ts @@ -1,5 +1,8 @@ +import { + GetAllProductVendorsQuery, + GetAllProductVendorsQueryVariables, +} from '../schema' import { ShopifyConfig } from '../api' -import fetchAllProducts from '../api/utils/fetch-all-products' import getAllProductVendors from './queries/get-all-product-vendors-query' export type Brand = { @@ -14,16 +17,17 @@ export type BrandEdge = { export type Brands = BrandEdge[] -const getVendors = async (config: ShopifyConfig): Promise => { - const vendors = await fetchAllProducts({ - config, - query: getAllProductVendors, +const getBrands = async (config: ShopifyConfig): Promise => { + const { data } = await config.fetch< + GetAllProductVendorsQuery, + GetAllProductVendorsQueryVariables + >(getAllProductVendors, { variables: { first: 250, }, }) - let vendorsStrings = vendors.map(({ node: { vendor } }) => vendor) + let vendorsStrings = data.products.edges.map(({ node: { vendor } }) => vendor) return [...new Set(vendorsStrings)].map((v) => { const id = v.replace(/\s+/g, '-').toLowerCase() @@ -37,4 +41,4 @@ const getVendors = async (config: ShopifyConfig): Promise => { }) } -export default getVendors +export default getBrands diff --git a/framework/shopify/utils/get-categories.ts b/framework/shopify/utils/get-categories.ts index cce4b2ad7..f217ff49b 100644 --- a/framework/shopify/utils/get-categories.ts +++ b/framework/shopify/utils/get-categories.ts @@ -8,12 +8,25 @@ export type Category = { path: string } -const getCategories = async (config: ShopifyConfig): Promise => { - const { data } = await config.fetch(getSiteCollectionsQuery, { - variables: { - first: 250, +const getCategories = async ({ + fetch, + locale, +}: ShopifyConfig): Promise => { + const { data } = await fetch( + getSiteCollectionsQuery, + { + variables: { + first: 250, + }, }, - }) + { + ...(locale && { + headers: { + 'Accept-Language': locale, + }, + }), + } + ) return ( data.collections?.edges?.map( diff --git a/framework/shopify/utils/get-search-variables.ts b/framework/shopify/utils/get-search-variables.ts index c1b40ae5d..f4863650d 100644 --- a/framework/shopify/utils/get-search-variables.ts +++ b/framework/shopify/utils/get-search-variables.ts @@ -1,26 +1,30 @@ import getSortVariables from './get-sort-variables' -import type { SearchProductsInput } from '../product/use-search' +import { SearchProductsBody } from '../types/product' export const getSearchVariables = ({ brandId, search, categoryId, sort, -}: SearchProductsInput) => { + locale, +}: SearchProductsBody) => { let query = '' if (search) { - query += `product_type:${search} OR title:${search} OR tag:${search}` + query += `product_type:${search} OR title:${search} OR tag:${search} ` } if (brandId) { - query += `${search ? ' AND ' : ''}vendor:${brandId}` + query += `${search ? 'AND ' : ''}vendor:${brandId}` } return { categoryId, query, ...getSortVariables(sort, !!categoryId), + ...(locale && { + locale, + }), } } diff --git a/framework/shopify/utils/index.ts b/framework/shopify/utils/index.ts index 61e5975d7..a8454ffca 100644 --- a/framework/shopify/utils/index.ts +++ b/framework/shopify/utils/index.ts @@ -1,7 +1,7 @@ export { default as handleFetchResponse } from './handle-fetch-response' export { default as getSearchVariables } from './get-search-variables' export { default as getSortVariables } from './get-sort-variables' -export { default as getVendors } from './get-vendors' +export { default as getBrands } from './get-brands' export { default as getCategories } from './get-categories' export { default as getCheckoutId } from './get-checkout-id' export { default as checkoutCreate } from './checkout-create' diff --git a/framework/shopify/utils/mutations/checkout-create.ts b/framework/shopify/utils/mutations/checkout-create.ts index ffbd555c7..7bff7e757 100644 --- a/framework/shopify/utils/mutations/checkout-create.ts +++ b/framework/shopify/utils/mutations/checkout-create.ts @@ -1,17 +1,19 @@ import { checkoutDetailsFragment } from '../queries/get-checkout-query' const checkoutCreateMutation = /* GraphQL */ ` - mutation { - checkoutCreate(input: {}) { + mutation checkoutCreate($input: CheckoutCreateInput = {}) { + checkoutCreate(input: $input) { checkoutUserErrors { code field message } checkout { - ${checkoutDetailsFragment} + ...checkoutDetails } } } + + ${checkoutDetailsFragment} ` export default checkoutCreateMutation diff --git a/framework/shopify/utils/mutations/checkout-line-item-add.ts b/framework/shopify/utils/mutations/checkout-line-item-add.ts index 2282c4e26..02f5b7107 100644 --- a/framework/shopify/utils/mutations/checkout-line-item-add.ts +++ b/framework/shopify/utils/mutations/checkout-line-item-add.ts @@ -1,7 +1,10 @@ import { checkoutDetailsFragment } from '../queries/get-checkout-query' const checkoutLineItemAddMutation = /* GraphQL */ ` - mutation($checkoutId: ID!, $lineItems: [CheckoutLineItemInput!]!) { + mutation checkoutLineItemAdd( + $checkoutId: ID! + $lineItems: [CheckoutLineItemInput!]! + ) { checkoutLineItemsAdd(checkoutId: $checkoutId, lineItems: $lineItems) { checkoutUserErrors { code @@ -9,9 +12,11 @@ const checkoutLineItemAddMutation = /* GraphQL */ ` message } checkout { - ${checkoutDetailsFragment} + ...checkoutDetails } } } + + ${checkoutDetailsFragment} ` export default checkoutLineItemAddMutation diff --git a/framework/shopify/utils/mutations/checkout-line-item-remove.ts b/framework/shopify/utils/mutations/checkout-line-item-remove.ts index 8dea4ce08..30cb83028 100644 --- a/framework/shopify/utils/mutations/checkout-line-item-remove.ts +++ b/framework/shopify/utils/mutations/checkout-line-item-remove.ts @@ -1,7 +1,7 @@ import { checkoutDetailsFragment } from '../queries/get-checkout-query' const checkoutLineItemRemoveMutation = /* GraphQL */ ` - mutation($checkoutId: ID!, $lineItemIds: [ID!]!) { + mutation checkoutLineItemRemove($checkoutId: ID!, $lineItemIds: [ID!]!) { checkoutLineItemsRemove( checkoutId: $checkoutId lineItemIds: $lineItemIds @@ -12,9 +12,10 @@ const checkoutLineItemRemoveMutation = /* GraphQL */ ` message } checkout { - ${checkoutDetailsFragment} + ...checkoutDetails } } } + ${checkoutDetailsFragment} ` export default checkoutLineItemRemoveMutation diff --git a/framework/shopify/utils/mutations/checkout-line-item-update.ts b/framework/shopify/utils/mutations/checkout-line-item-update.ts index 76254341e..fca617fb7 100644 --- a/framework/shopify/utils/mutations/checkout-line-item-update.ts +++ b/framework/shopify/utils/mutations/checkout-line-item-update.ts @@ -1,7 +1,10 @@ import { checkoutDetailsFragment } from '../queries/get-checkout-query' const checkoutLineItemUpdateMutation = /* GraphQL */ ` - mutation($checkoutId: ID!, $lineItems: [CheckoutLineItemUpdateInput!]!) { + mutation checkoutLineItemUpdate( + $checkoutId: ID! + $lineItems: [CheckoutLineItemUpdateInput!]! + ) { checkoutLineItemsUpdate(checkoutId: $checkoutId, lineItems: $lineItems) { checkoutUserErrors { code @@ -9,9 +12,11 @@ const checkoutLineItemUpdateMutation = /* GraphQL */ ` message } checkout { - ${checkoutDetailsFragment} + ...checkoutDetails } } } + + ${checkoutDetailsFragment} ` export default checkoutLineItemUpdateMutation diff --git a/framework/shopify/utils/normalize.ts b/framework/shopify/utils/normalize.ts index 4ebc3a1ae..39a4cd00f 100644 --- a/framework/shopify/utils/normalize.ts +++ b/framework/shopify/utils/normalize.ts @@ -1,4 +1,6 @@ -import { Product } from '@commerce/types' +import type { Page } from '../types/page' +import type { Product } from '../types/product' +import type { Cart, LineItem } from '../types/cart' import { Product as ShopifyProduct, @@ -9,9 +11,10 @@ import { ProductVariantConnection, MoneyV2, ProductOption, + Page as ShopifyPage, + PageEdge, } from '../schema' - -import type { Cart, LineItem } from '../types' +import { colorMap } from '@lib/colors' const money = ({ amount, currencyCode }: MoneyV2) => { return { @@ -28,15 +31,18 @@ const normalizeProductOption = ({ return { __typename: 'MultipleChoiceOption', id, - displayName, + displayName: displayName.toLowerCase(), values: values.map((value) => { let output: any = { label: value, } if (displayName.match(/colou?r/gi)) { - output = { - ...output, - hexColors: [value], + const mapedColor = colorMap[value] + if (mapedColor) { + output = { + ...output, + hexColors: [mapedColor], + } } } return output @@ -53,7 +59,16 @@ const normalizeProductImages = ({ edges }: ImageConnection) => const normalizeProductVariants = ({ edges }: ProductVariantConnection) => { return edges?.map( ({ - node: { id, selectedOptions, sku, title, priceV2, compareAtPriceV2 }, + node: { + id, + selectedOptions, + sku, + title, + priceV2, + compareAtPriceV2, + requiresShipping, + availableForSale, + }, }) => { return { id, @@ -61,7 +76,8 @@ const normalizeProductVariants = ({ edges }: ProductVariantConnection) => { sku: sku ?? id, price: +priceV2.amount, listPrice: +compareAtPriceV2?.amount, - requiresShipping: true, + requiresShipping, + availableForSale, options: selectedOptions.map(({ name, value }: SelectedOption) => { const options = normalizeProductOption({ id, @@ -75,22 +91,21 @@ const normalizeProductVariants = ({ edges }: ProductVariantConnection) => { ) } -export function normalizeProduct(productNode: ShopifyProduct): Product { - const { - id, - title: name, - vendor, - images, - variants, - description, - descriptionHtml, - handle, - priceRange, - options, - ...rest - } = productNode - - const product = { +export function normalizeProduct({ + id, + title: name, + vendor, + images, + variants, + description, + descriptionHtml, + handle, + priceRange, + options, + metafields, + ...rest +}: ShopifyProduct): Product { + return { id, name, vendor, @@ -108,13 +123,12 @@ export function normalizeProduct(productNode: ShopifyProduct): Product { ...(descriptionHtml && { descriptionHtml }), ...rest, } - - return product } export function normalizeCart(checkout: Checkout): Cart { return { id: checkout.id, + url: checkout.webUrl, customerId: '', email: '', createdAt: checkout.createdAt, @@ -131,7 +145,7 @@ export function normalizeCart(checkout: Checkout): Cart { } function normalizeLineItem({ - node: { id, title, variant, quantity, ...rest }, + node: { id, title, variant, quantity }, }: CheckoutLineItemEdge): LineItem { return { id, @@ -144,7 +158,7 @@ function normalizeLineItem({ sku: variant?.sku ?? '', name: variant?.title!, image: { - url: variant?.image?.originalSrc ?? '/product-img-placeholder.svg', + url: variant?.image?.originalSrc || '/product-img-placeholder.svg', }, requiresShipping: variant?.requiresShipping ?? false, price: variant?.priceV2?.amount, @@ -152,14 +166,18 @@ function normalizeLineItem({ }, path: String(variant?.product?.handle), discounts: [], - options: - // By default Shopify adds a default variant with default names, we're removing it. https://community.shopify.com/c/Shopify-APIs-SDKs/Adding-new-product-variant-is-automatically-adding-quot-Default/td-p/358095 - variant?.title == 'Default Title' - ? [] - : [ - { - value: variant?.title, - }, - ], + options: variant?.title == 'Default Title' ? [] : variant?.selectedOptions, } } + +export const normalizePage = ( + { title: name, handle, ...page }: ShopifyPage, + locale: string +): Page => ({ + ...page, + url: `/${locale}/${handle}`, + name, +}) + +export const normalizePages = (edges: PageEdge[], locale: string): Page[] => + edges?.map((edge) => normalizePage(edge.node, locale)) diff --git a/framework/shopify/utils/queries/get-all-products-query.ts b/framework/shopify/utils/queries/get-all-products-query.ts index f48140d31..179cf9812 100644 --- a/framework/shopify/utils/queries/get-all-products-query.ts +++ b/framework/shopify/utils/queries/get-all-products-query.ts @@ -1,46 +1,38 @@ -export const productConnection = ` -pageInfo { - hasNextPage - hasPreviousPage -} -edges { - node { - id - title - vendor - handle - priceRange { - minVariantPrice { - amount - currencyCode - } +export const productConnectionFragment = /* GraphQL */ ` + fragment productConnection on ProductConnection { + pageInfo { + hasNextPage + hasPreviousPage } - images(first: 1) { - pageInfo { - hasNextPage - hasPreviousPage - } - edges { - node { - originalSrc - altText - width - height + edges { + node { + id + title + vendor + handle + priceRange { + minVariantPrice { + amount + currencyCode + } + } + images(first: 1) { + pageInfo { + hasNextPage + hasPreviousPage + } + edges { + node { + originalSrc + altText + width + height + } + } } } } } -}` - -export const productsFragment = ` -products( - first: $first - sortKey: $sortKey - reverse: $reverse - query: $query -) { - ${productConnection} -} ` const getAllProductsQuery = /* GraphQL */ ` @@ -50,7 +42,16 @@ const getAllProductsQuery = /* GraphQL */ ` $sortKey: ProductSortKeys = RELEVANCE $reverse: Boolean = false ) { - ${productsFragment} + products( + first: $first + sortKey: $sortKey + reverse: $reverse + query: $query + ) { + ...productConnection + } } + + ${productConnectionFragment} ` export default getAllProductsQuery diff --git a/framework/shopify/utils/queries/get-checkout-query.ts b/framework/shopify/utils/queries/get-checkout-query.ts index d8758e321..9969e67c0 100644 --- a/framework/shopify/utils/queries/get-checkout-query.ts +++ b/framework/shopify/utils/queries/get-checkout-query.ts @@ -1,65 +1,70 @@ -export const checkoutDetailsFragment = ` - id - webUrl - subtotalPriceV2{ - amount - currencyCode - } - totalTaxV2 { - amount - currencyCode - } - totalPriceV2 { - amount - currencyCode - } - completedAt - createdAt - taxesIncluded - lineItems(first: 250) { - pageInfo { - hasNextPage - hasPreviousPage +export const checkoutDetailsFragment = /* GraphQL */ ` + fragment checkoutDetails on Checkout { + id + webUrl + subtotalPriceV2 { + amount + currencyCode } - edges { - node { - id - title - variant { + totalTaxV2 { + amount + currencyCode + } + totalPriceV2 { + amount + currencyCode + } + completedAt + createdAt + taxesIncluded + lineItems(first: 250) { + pageInfo { + hasNextPage + hasPreviousPage + } + edges { + node { id - sku title - image { - originalSrc - altText - width - height - } - priceV2{ - amount - currencyCode - } - compareAtPriceV2{ - amount - currencyCode - } - product { - handle + variant { + id + sku + title + selectedOptions { + name + value + } + image { + originalSrc + altText + width + height + } + priceV2 { + amount + currencyCode + } + compareAtPriceV2 { + amount + currencyCode + } + product { + handle + } } + quantity } - quantity } } } ` const getCheckoutQuery = /* GraphQL */ ` - query($checkoutId: ID!) { + query getCheckout($checkoutId: ID!) { node(id: $checkoutId) { - ... on Checkout { - ${checkoutDetailsFragment} - } + ...checkoutDetails } } + ${checkoutDetailsFragment} ` export default getCheckoutQuery diff --git a/framework/shopify/utils/queries/get-collection-products-query.ts b/framework/shopify/utils/queries/get-collection-products-query.ts index 04766caa4..b773a7e65 100644 --- a/framework/shopify/utils/queries/get-collection-products-query.ts +++ b/framework/shopify/utils/queries/get-collection-products-query.ts @@ -1,4 +1,4 @@ -import { productConnection } from './get-all-products-query' +import { productConnectionFragment } from './get-all-products-query' const getCollectionProductsQuery = /* GraphQL */ ` query getProductsFromCollection( @@ -10,15 +10,12 @@ const getCollectionProductsQuery = /* GraphQL */ ` node(id: $categoryId) { id ... on Collection { - products( - first: $first - sortKey: $sortKey - reverse: $reverse - ) { - ${productConnection} + products(first: $first, sortKey: $sortKey, reverse: $reverse) { + ...productConnection } } } } + ${productConnectionFragment} ` export default getCollectionProductsQuery diff --git a/framework/shopify/utils/queries/get-page-query.ts b/framework/shopify/utils/queries/get-page-query.ts index 2ca79abd4..7939f0278 100644 --- a/framework/shopify/utils/queries/get-page-query.ts +++ b/framework/shopify/utils/queries/get-page-query.ts @@ -1,5 +1,5 @@ export const getPageQuery = /* GraphQL */ ` - query($id: ID!) { + query getPage($id: ID!) { node(id: $id) { id ... on Page { diff --git a/framework/shopify/utils/queries/get-product-query.ts b/framework/shopify/utils/queries/get-product-query.ts index 5c109901b..b2998a40a 100644 --- a/framework/shopify/utils/queries/get-product-query.ts +++ b/framework/shopify/utils/queries/get-product-query.ts @@ -3,6 +3,7 @@ const getProductQuery = /* GraphQL */ ` productByHandle(handle: $slug) { id handle + availableForSale title productType vendor @@ -33,6 +34,8 @@ const getProductQuery = /* GraphQL */ ` id title sku + availableForSale + requiresShipping selectedOptions { name value diff --git a/framework/shopify/utils/queries/get-site-info-query.ts b/framework/shopify/utils/queries/get-site-info-query.ts new file mode 100644 index 000000000..74215572a --- /dev/null +++ b/framework/shopify/utils/queries/get-site-info-query.ts @@ -0,0 +1,8 @@ +const getSiteInfoQuery = /* GraphQL */ ` + query getSiteInfo { + shop { + name + } + } +` +export default getSiteInfoQuery diff --git a/framework/shopify/utils/queries/index.ts b/framework/shopify/utils/queries/index.ts index e19be9c8c..953113491 100644 --- a/framework/shopify/utils/queries/index.ts +++ b/framework/shopify/utils/queries/index.ts @@ -8,3 +8,4 @@ export { default as getCheckoutQuery } from './get-checkout-query' export { default as getAllPagesQuery } from './get-all-pages-query' export { default as getPageQuery } from './get-page-query' export { default as getCustomerQuery } from './get-customer-query' +export { default as getSiteInfoQuery } from './get-site-info-query' diff --git a/lib/colors.ts b/lib/colors.ts index 139cda23d..3013de956 100644 --- a/lib/colors.ts +++ b/lib/colors.ts @@ -42,7 +42,7 @@ function hexToRgb(hex: string = '') { return [r, g, b] } -const colorMap: Record = { +export const colorMap: Record = { aliceblue: '#F0F8FF', antiquewhite: '#FAEBD7', aqua: '#00FFFF', @@ -56,6 +56,8 @@ const colorMap: Record = { blueviolet: '#8A2BE2', brown: '#A52A2A', burlywood: '#DEB887', + burgandy: '#800020', + burgundy: '#800020', cadetblue: '#5F9EA0', chartreuse: '#7FFF00', chocolate: '#D2691E', diff --git a/package.json b/package.json index 85810ca91..93b4c5572 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,8 @@ "prettier-fix": "prettier --write .", "find:unused": "next-unused", "generate": "graphql-codegen", - "generate:definitions": "node framework/bigcommerce/scripts/generate-definitions.js" + "generate:definitions": "node framework/bigcommerce/scripts/generate-definitions.js", + "generate:shopify": "DOTENV_CONFIG_PATH=./.env.local graphql-codegen -r dotenv/config --config framework/shopify/codegen.json" }, "sideEffects": false, "license": "MIT", diff --git a/pages/[...pages].tsx b/pages/[...pages].tsx index 3e6ef65c9..7467a76b6 100644 --- a/pages/[...pages].tsx +++ b/pages/[...pages].tsx @@ -14,8 +14,9 @@ export async function getStaticProps({ preview, params, locale, + locales, }: GetStaticPropsContext<{ pages: string[] }>) { - const config = { locale } + const config = { locale, locales } const { pages } = await commerce.getAllPages({ preview, config }) const path = params?.pages.join('/') const slug = locale ? `${locale}/${path}` : path @@ -42,7 +43,8 @@ export async function getStaticProps({ } export async function getStaticPaths({ locales }: GetStaticPathsContext) { - const { pages } = await commerce.getAllPages() + const config = { locales } + const { pages } = await commerce.getAllPages({ config }) const [invalidPaths, log] = missingLocaleInPages() const paths = pages .map((page) => page.url) diff --git a/pages/blog.tsx b/pages/blog.tsx index c1bdc4624..6daf1297e 100644 --- a/pages/blog.tsx +++ b/pages/blog.tsx @@ -6,8 +6,9 @@ import { Container } from '@components/ui' export async function getStaticProps({ preview, locale, + locales, }: GetStaticPropsContext) { - const config = { locale } + const config = { locale, locales } const { pages } = await commerce.getAllPages({ config, preview }) return { props: { pages }, diff --git a/pages/cart.tsx b/pages/cart.tsx index d14a7bfd2..4e1358943 100644 --- a/pages/cart.tsx +++ b/pages/cart.tsx @@ -10,8 +10,9 @@ import { CartItem } from '@components/cart' export async function getStaticProps({ preview, locale, + locales, }: GetStaticPropsContext) { - const config = { locale } + const config = { locale, locales } const { pages } = await commerce.getAllPages({ config, preview }) return { props: { pages }, diff --git a/pages/index.tsx b/pages/index.tsx index 87881d2b9..86d7a9da4 100644 --- a/pages/index.tsx +++ b/pages/index.tsx @@ -8,15 +8,16 @@ import type { GetStaticPropsContext, InferGetStaticPropsType } from 'next' export async function getStaticProps({ preview, locale, + locales, }: GetStaticPropsContext) { - const config = { locale } + const config = { locale, locales } const { products } = await commerce.getAllProducts({ variables: { first: 12 }, config, preview, }) - const { categories, brands } = await commerce.getSiteInfo({ config, preview }) + const { pages } = await commerce.getAllPages({ config, preview }) return { diff --git a/pages/orders.tsx b/pages/orders.tsx index c43ff9e5a..5a6a26d43 100644 --- a/pages/orders.tsx +++ b/pages/orders.tsx @@ -7,8 +7,9 @@ import { Container, Text } from '@components/ui' export async function getStaticProps({ preview, locale, + locales, }: GetStaticPropsContext) { - const config = { locale } + const config = { locale, locales } const { pages } = await commerce.getAllPages({ config, preview }) return { props: { pages }, diff --git a/pages/product/[slug].tsx b/pages/product/[slug].tsx index bf71ac21e..5415e67f9 100644 --- a/pages/product/[slug].tsx +++ b/pages/product/[slug].tsx @@ -11,9 +11,10 @@ import { ProductView } from '@components/product' export async function getStaticProps({ params, locale, + locales, preview, }: GetStaticPropsContext<{ slug: string }>) { - const config = { locale } + const config = { locale, locales } const { pages } = await commerce.getAllPages({ config, preview }) const { product } = await commerce.getProduct({ variables: { slug: params!.slug }, diff --git a/pages/profile.tsx b/pages/profile.tsx index b73469fa5..b569025da 100644 --- a/pages/profile.tsx +++ b/pages/profile.tsx @@ -7,8 +7,9 @@ import { Container, Text } from '@components/ui' export async function getStaticProps({ preview, locale, + locales, }: GetStaticPropsContext) { - const config = { locale } + const config = { locale, locales } const { pages } = await commerce.getAllPages({ config, preview }) return { props: { pages }, diff --git a/pages/search.tsx b/pages/search.tsx index 400217a26..958db5526 100644 --- a/pages/search.tsx +++ b/pages/search.tsx @@ -6,6 +6,7 @@ import { useRouter } from 'next/router' import { Layout } from '@components/common' import { ProductCard } from '@components/product' +import type { Product } from '@commerce/types/product' import { Container, Grid, Skeleton } from '@components/ui' import useSearch from '@framework/product/use-search' @@ -33,8 +34,9 @@ const SORT = Object.entries({ export async function getStaticProps({ preview, locale, + locales, }: GetStaticPropsContext) { - const config = { locale } + const config = { locale, locales } const { pages } = await commerce.getAllPages({ config, preview }) const { categories, brands } = await commerce.getSiteInfo({ config, preview }) return { @@ -54,7 +56,7 @@ export default function Search({ const [toggleFilter, setToggleFilter] = useState(false) const router = useRouter() - const { asPath } = router + const { asPath, locale } = router const { q, sort } = router.query // `q` can be included but because categories and designers can't be searched // in the same way of products, it's better to ignore the search input if one @@ -74,6 +76,7 @@ export default function Search({ categoryId: activeCategory?.entityId, brandId: activeBrand?.entityId, sort: typeof sort === 'string' ? sort : '', + locale, }) const handleClick = (event: any, filter: string) => { diff --git a/pages/wishlist.tsx b/pages/wishlist.tsx index 9927c536a..a667d33f8 100644 --- a/pages/wishlist.tsx +++ b/pages/wishlist.tsx @@ -11,6 +11,7 @@ import useWishlist from '@framework/wishlist/use-wishlist' export async function getStaticProps({ preview, locale, + locales, }: GetStaticPropsContext) { // Disabling page if Feature is not available if (!process.env.COMMERCE_WISHLIST_ENABLED) { @@ -19,7 +20,7 @@ export async function getStaticProps({ } } - const config = { locale } + const config = { locale, locales } const { pages } = await commerce.getAllPages({ config, preview }) return { props: { diff --git a/tsconfig.json b/tsconfig.json index 9e712fb18..e20f37099 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -22,8 +22,8 @@ "@components/*": ["components/*"], "@commerce": ["framework/commerce"], "@commerce/*": ["framework/commerce/*"], - "@framework": ["framework/bigcommerce"], - "@framework/*": ["framework/bigcommerce/*"] + "@framework": ["framework/shopify"], + "@framework/*": ["framework/shopify/*"] } }, "include": ["next-env.d.ts", "**/*.d.ts", "**/*.ts", "**/*.tsx", "**/*.js"],