Updated Shopify Provider Structure (#340)

* Add codegen, update fragments & schemas

* Update checkout-create.ts

* Update checkout-create.ts

* Update README.md

* Update product mutations & queries

* Uptate customer fetch types

* Update schemas

* Start updates

* Moved Page, AllPages & Site Info

* Moved product, all products (paths)

* Add translations, update operations & fixes

* Update api endpoints, types & fixes

* Add api checkout endpoint

* Updates

* Fixes

* Update commerce.config.json

Co-authored-by: B <curciobelen@gmail.com>
This commit is contained in:
cond0r 2021-05-31 20:39:13 +03:00 committed by GitHub
parent 7f2a0d903a
commit 30174c597c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
127 changed files with 1954 additions and 1031 deletions

View File

@ -5,7 +5,7 @@ import Link from 'next/link'
import s from './CartItem.module.css' import s from './CartItem.module.css'
import { Trash, Plus, Minus } from '@components/icons' import { Trash, Plus, Minus } from '@components/icons'
import { useUI } from '@components/ui/context' 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 usePrice from '@framework/product/use-price'
import useUpdateItem from '@framework/cart/use-update-item' import useUpdateItem from '@framework/cart/use-update-item'
import useRemoveItem from '@framework/cart/use-remove-item' import useRemoveItem from '@framework/cart/use-remove-item'

View File

@ -2,7 +2,7 @@ import { FC } from 'react'
import cn from 'classnames' import cn from 'classnames'
import Link from 'next/link' import Link from 'next/link'
import { useRouter } from 'next/router' 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 getSlug from '@lib/get-slug'
import { Github, Vercel } from '@components/icons' import { Github, Vercel } from '@components/icons'
import { Logo, Container } from '@components/ui' import { Logo, Container } from '@components/ui'

View File

@ -1,6 +1,6 @@
import { FC } from 'react' import { FC } from 'react'
import Link from 'next/link' import Link from 'next/link'
import type { Product } from '@commerce/types' import type { Product } from '@commerce/types/product'
import { Grid } from '@components/ui' import { Grid } from '@components/ui'
import { ProductCard } from '@components/product' import { ProductCard } from '@components/product'
import s from './HomeAllProductsGrid.module.css' import s from './HomeAllProductsGrid.module.css'

View File

@ -11,7 +11,7 @@ import CartSidebarView from '@components/cart/CartSidebarView'
import LoginView from '@components/auth/LoginView' import LoginView from '@components/auth/LoginView'
import { CommerceProvider } from '@framework' import { CommerceProvider } from '@framework'
import type { Page } from '@framework/common/get-all-pages' import type { Page } from '@commerce/types/page'
const Loading = () => ( const Loading = () => (
<div className="w-80 h-80 flex items-center text-center justify-center p-3"> <div className="w-80 h-80 flex items-center text-center justify-center p-3">

View File

@ -1,7 +1,7 @@
import { FC } from 'react' import { FC } from 'react'
import Link from 'next/link' import Link from 'next/link'
import cn from 'classnames' 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 useCart from '@framework/cart/use-cart'
import useCustomer from '@framework/customer/use-customer' import useCustomer from '@framework/customer/use-customer'
import { Avatar } from '@components/common' import { Avatar } from '@components/common'

View File

@ -1,7 +1,7 @@
import { FC } from 'react' import { FC } from 'react'
import cn from 'classnames' import cn from 'classnames'
import Link from 'next/link' 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 s from './ProductCard.module.css'
import Image, { ImageProps } from 'next/image' import Image, { ImageProps } from 'next/image'
import WishlistButton from '@components/wishlist/WishlistButton' import WishlistButton from '@components/wishlist/WishlistButton'

View File

@ -5,7 +5,7 @@ import { FC, useEffect, useState } from 'react'
import s from './ProductView.module.css' import s from './ProductView.module.css'
import { Swatch, ProductSlider } from '@components/product' import { Swatch, ProductSlider } from '@components/product'
import { Button, Container, Text, useUI } from '@components/ui' 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 usePrice from '@framework/product/use-price'
import { useAddItem } from '@framework/cart' import { useAddItem } from '@framework/cart'
import { getVariant, SelectedOptions } from '../helpers' import { getVariant, SelectedOptions } from '../helpers'
@ -18,6 +18,8 @@ interface Props {
} }
const ProductView: FC<Props> = ({ product }) => { const ProductView: FC<Props> = ({ product }) => {
// TODO: fix this missing argument issue
/* @ts-ignore */
const addItem = useAddItem() const addItem = useAddItem()
const { price } = usePrice({ const { price } = usePrice({
amount: product.price.value, amount: product.price.value,
@ -146,8 +148,11 @@ const ProductView: FC<Props> = ({ product }) => {
className={s.button} className={s.button}
onClick={addToCart} onClick={addToCart}
loading={loading} loading={loading}
disabled={variant?.availableForSale === false}
> >
Add to Cart {variant?.availableForSale === false
? 'Not Available'
: 'Add To Cart'}
</Button> </Button>
</div> </div>
</div> </div>

View File

@ -52,4 +52,4 @@ const Swatch: FC<Omit<ButtonProps, 'variant'> & Props> = ({
) )
} }
export default Swatch export default Swatch

View File

@ -1,4 +1,4 @@
import type { Product } from '@commerce/types' import type { Product } from '@commerce/types/product'
export type SelectedOptions = Record<string, string | null> export type SelectedOptions = Record<string, string | null>
export function getVariant(product: Product, opts: SelectedOptions) { export function getVariant(product: Product, opts: SelectedOptions) {

View File

@ -6,7 +6,7 @@ import useAddItem from '@framework/wishlist/use-add-item'
import useCustomer from '@framework/customer/use-customer' import useCustomer from '@framework/customer/use-customer'
import useWishlist from '@framework/wishlist/use-wishlist' import useWishlist from '@framework/wishlist/use-wishlist'
import useRemoveItem from '@framework/wishlist/use-remove-item' 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 = { type Props = {
productId: Product['id'] productId: Product['id']

View File

@ -7,7 +7,7 @@ import { Trash } from '@components/icons'
import { Button, Text } from '@components/ui' import { Button, Text } from '@components/ui'
import { useUI } from '@components/ui/context' 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 usePrice from '@framework/product/use-price'
import useAddItem from '@framework/cart/use-add-item' import useAddItem from '@framework/cart/use-add-item'
import useRemoveItem from '@framework/wishlist/use-remove-item' import useRemoveItem from '@framework/wishlist/use-remove-item'
@ -18,14 +18,17 @@ interface Props {
const WishlistCard: FC<Props> = ({ product }) => { const WishlistCard: FC<Props> = ({ product }) => {
const { price } = usePrice({ const { price } = usePrice({
amount: product.prices?.price?.value, amount: product.price?.value,
baseAmount: product.prices?.retailPrice?.value, baseAmount: product.price?.retailPrice,
currencyCode: product.prices?.price?.currencyCode!, currencyCode: product.price?.currencyCode!,
}) })
// @ts-ignore Wishlist is not always enabled // @ts-ignore Wishlist is not always enabled
const removeItem = useRemoveItem({ wishlist: { includeProducts: true } }) const removeItem = useRemoveItem({ wishlist: { includeProducts: true } })
const [loading, setLoading] = useState(false) const [loading, setLoading] = useState(false)
const [removing, setRemoving] = useState(false) const [removing, setRemoving] = useState(false)
// TODO: fix this missing argument issue
/* @ts-ignore */
const addItem = useAddItem() const addItem = useAddItem()
const { openSidebar } = useUI() const { openSidebar } = useUI()

View File

@ -1,4 +1,4 @@
import { normalizeCart } from '@framework/lib/normalize' import { normalizeCart } from '../../../lib/normalize'
import { parseCartItem } from '../../utils/parse-item' import { parseCartItem } from '../../utils/parse-item'
import getCartCookie from '../../utils/get-cart-cookie' import getCartCookie from '../../utils/get-cart-cookie'
import type { CartEndpoint } from '.' import type { CartEndpoint } from '.'

View File

@ -1,7 +1,7 @@
import { normalizeCart } from '@framework/lib/normalize' import { normalizeCart } from '../../../lib/normalize'
import { BigcommerceApiError } from '../../utils/errors' import { BigcommerceApiError } from '../../utils/errors'
import getCartCookie from '../../utils/get-cart-cookie' import getCartCookie from '../../utils/get-cart-cookie'
import type { BigcommerceCart } from '../../../types' import type { BigcommerceCart } from '../../../types/cart'
import type { CartEndpoint } from '.' import type { CartEndpoint } from '.'
// Return current cart info // Return current cart info

View File

@ -1,4 +1,4 @@
import { normalizeCart } from '@framework/lib/normalize' import { normalizeCart } from '../../../lib/normalize'
import getCartCookie from '../../utils/get-cart-cookie' import getCartCookie from '../../utils/get-cart-cookie'
import type { CartEndpoint } from '.' import type { CartEndpoint } from '.'

View File

@ -1,4 +1,4 @@
import { normalizeCart } from '@framework/lib/normalize' import { normalizeCart } from '../../../lib/normalize'
import { parseCartItem } from '../../utils/parse-item' import { parseCartItem } from '../../utils/parse-item'
import getCartCookie from '../../utils/get-cart-cookie' import getCartCookie from '../../utils/get-cart-cookie'
import type { CartEndpoint } from '.' import type { CartEndpoint } from '.'

View File

@ -25,10 +25,10 @@ const getProducts: ProductsEndpoint['handlers']['getProducts'] = async ({
if (search) url.searchParams.set('keyword', search) if (search) url.searchParams.set('keyword', search)
if (categoryId && Number.isInteger(Number(categoryId))) 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))) if (brandId && Number.isInteger(Number(brandId)))
url.searchParams.set('brand_id', brandId) url.searchParams.set('brand_id', String(brandId))
if (sort) { if (sort) {
const [_sort, direction] = sort.split('-') const [_sort, direction] = sort.split('-')

View File

@ -32,12 +32,12 @@ export default function getAllProductPathsOperation({
config?: BigcommerceConfig config?: BigcommerceConfig
}): Promise<T['data']> }): Promise<T['data']>
async function getAllProductPaths< async function getAllProductPaths<T extends GetAllProductPathsOperation>(
T extends GetAllProductPathsOperation opts: {
>(opts: { variables?: T['variables']
variables?: T['variables'] config?: BigcommerceConfig
config?: BigcommerceConfig } & OperationOptions
} & OperationOptions): Promise<T['data']> ): Promise<T['data']>
async function getAllProductPaths<T extends GetAllProductPathsOperation>({ async function getAllProductPaths<T extends GetAllProductPathsOperation>({
query = getAllProductPathsQuery, query = getAllProductPathsQuery,

View File

@ -5,6 +5,7 @@ import type {
import type { GetPageOperation, Page } from '../../types/page' import type { GetPageOperation, Page } from '../../types/page'
import type { RecursivePartial, RecursiveRequired } from '../utils/types' import type { RecursivePartial, RecursiveRequired } from '../utils/types'
import type { BigcommerceConfig, Provider } from '..' import type { BigcommerceConfig, Provider } from '..'
import { normalizePage } from '../../lib/normalize'
export default function getPageOperation({ export default function getPageOperation({
commerce, commerce,
@ -44,7 +45,7 @@ export default function getPageOperation({
const page = firstPage as RecursiveRequired<typeof firstPage> const page = firstPage as RecursiveRequired<typeof firstPage>
if (preview || page?.is_visible) { if (preview || page?.is_visible) {
return { page } return { page: normalizePage(page as any) }
} }
return {} return {}
} }

View File

@ -1,5 +1,5 @@
import type { ItemBody as WishlistItemBody } from '../wishlist' import type { WishlistItemBody } from '../../types/wishlist'
import type { CartItemBody, OptionSelections } from '../../types' import type { CartItemBody, OptionSelections } from '../../types/cart'
type BCWishlistItemBody = { type BCWishlistItemBody = {
product_id: number product_id: number

View File

@ -2,7 +2,7 @@ import { useCallback } from 'react'
import type { MutationHook } from '@commerce/utils/types' import type { MutationHook } from '@commerce/utils/types'
import { CommerceError } from '@commerce/utils/errors' import { CommerceError } from '@commerce/utils/errors'
import useAddItem, { UseAddItem } from '@commerce/cart/use-add-item' 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' import useCart from './use-cart'
export default useAddItem as UseAddItem<typeof handler> export default useAddItem as UseAddItem<typeof handler>

View File

@ -1,7 +1,7 @@
import { useMemo } from 'react' import { useMemo } from 'react'
import { SWRHook } from '@commerce/utils/types' import { SWRHook } from '@commerce/utils/types'
import useCart, { UseCart } from '@commerce/cart/use-cart' 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<typeof handler> export default useCart as UseCart<typeof handler>

View File

@ -5,11 +5,11 @@ import type {
} from '@commerce/utils/types' } from '@commerce/utils/types'
import { ValidationError } from '@commerce/utils/errors' import { ValidationError } from '@commerce/utils/errors'
import useRemoveItem, { 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 type { Cart, LineItem, RemoveItemHook } from '@commerce/types/cart'
import useCart from './use-cart' import useCart from './use-cart'
export type RemoveItemFn<T = any> = T extends LineItem export type RemoveItemFn<T = any> = T extends LineItem
? (input?: RemoveItemActionInput<T>) => Promise<Cart | null> ? (input?: RemoveItemActionInput<T>) => Promise<Cart | null | undefined>
: (input: RemoveItemActionInput<T>) => Promise<Cart | null> : (input: RemoveItemActionInput<T>) => Promise<Cart | null>
export type RemoveItemActionInput<T = any> = T extends LineItem export type RemoveItemActionInput<T = any> = T extends LineItem

View File

@ -6,7 +6,7 @@ import type {
} from '@commerce/utils/types' } from '@commerce/utils/types'
import { ValidationError } from '@commerce/utils/errors' import { ValidationError } from '@commerce/utils/errors'
import useUpdateItem, { UseUpdateItem } from '@commerce/cart/use-update-item' 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 { handler as removeItemHandler } from './use-remove-item'
import useCart from './use-cart' import useCart from './use-cart'

View File

@ -1,6 +1,8 @@
import type { Product } from '@commerce/types' import type { Product } from '../types/product'
import type { Cart, BigcommerceCart, LineItem } from '../types' import type { Cart, BigcommerceCart, LineItem } from '../types/cart'
import type { Page } from '../types/page'
import update from './immutability' import update from './immutability'
import { definitions } from '../api/definitions/store-content'
function normalizeProductOption(productOption: any) { function normalizeProductOption(productOption: any) {
const { 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 { export function normalizeCart(data: BigcommerceCart): Cart {
return { return {
id: data.id, id: data.id,

View File

@ -9,6 +9,7 @@ export type SearchProductsInput = {
categoryId?: number categoryId?: number
brandId?: number brandId?: number
sort?: string sort?: string
locale?: string
} }
export const handler: SWRHook<SearchProductsHook> = { export const handler: SWRHook<SearchProductsHook> = {

View File

@ -1,9 +1,7 @@
import * as Core from '@commerce/types/page' import * as Core from '@commerce/types/page'
import { definitions } from '../api/definitions/store-content'
export * from '@commerce/types/page' export * from '@commerce/types/page'
export type Page = definitions['page_Full'] export type Page = Core.Page
export type PageTypes = { export type PageTypes = {
page: Page page: Page

View File

@ -148,6 +148,7 @@ export const createEndpoint = <API extends GetAPISchema<any, any>>(
export interface CommerceAPIConfig { export interface CommerceAPIConfig {
locale?: string locale?: string
locales?: string[]
commerceUrl: string commerceUrl: string
apiToken: string apiToken: string
cartCookie: string cartCookie: string

View File

@ -6,35 +6,44 @@ import {
useMemo, useMemo,
useRef, useRef,
} from 'react' } from 'react'
import { Fetcher, SWRHook, MutationHook } from './utils/types'
import type { FetchCartInput } from './cart/use-cart' import type {
import type { Cart, Wishlist, Customer, SearchProductsData } from './types' Customer,
Wishlist,
Cart,
Product,
Signup,
Login,
Logout,
} from '@commerce/types'
import type { Fetcher, SWRHook, MutationHook } from './utils/types'
const Commerce = createContext<CommerceContextValue<any> | {}>({}) const Commerce = createContext<CommerceContextValue<any> | {}>({})
export type Provider = CommerceConfig & { export type Provider = CommerceConfig & {
fetcher: Fetcher fetcher: Fetcher
cart?: { cart?: {
useCart?: SWRHook<Cart | null, any, FetchCartInput> useCart?: SWRHook<Cart.GetCartHook>
useAddItem?: MutationHook<any, any, any> useAddItem?: MutationHook<Cart.AddItemHook>
useUpdateItem?: MutationHook<any, any, any> useUpdateItem?: MutationHook<Cart.UpdateItemHook>
useRemoveItem?: MutationHook<any, any, any> useRemoveItem?: MutationHook<Cart.RemoveItemHook>
} }
wishlist?: { wishlist?: {
useWishlist?: SWRHook<Wishlist | null, any, any> useWishlist?: SWRHook<Wishlist.GetWishlistHook>
useAddItem?: MutationHook<any, any, any> useAddItem?: MutationHook<Wishlist.AddItemHook>
useRemoveItem?: MutationHook<any, any, any> useRemoveItem?: MutationHook<Wishlist.RemoveItemHook>
} }
customer?: { customer?: {
useCustomer?: SWRHook<Customer | null, any, any> useCustomer?: SWRHook<Customer.CustomerHook>
} }
products?: { products?: {
useSearch?: SWRHook<SearchProductsData, any, any> useSearch?: SWRHook<Product.SearchProductsHook>
} }
auth?: { auth?: {
useSignup?: MutationHook<any, any, any> useSignup?: MutationHook<Signup.SignupHook>
useLogin?: MutationHook<any, any, any> useLogin?: MutationHook<Login.LoginHook>
useLogout?: MutationHook<any, any, any> useLogout?: MutationHook<Logout.LogoutHook>
} }
} }

View File

@ -1,5 +1,14 @@
import type { Discount, Measurement, Image } from './common' import type { Discount, Measurement, Image } from './common'
export type SelectedOption = {
// The option's id.
id?: string
// The product options name.
name: string
/// The product options value.
value: string
}
export type LineItem = { export type LineItem = {
id: string id: string
variantId: string variantId: string
@ -10,6 +19,7 @@ export type LineItem = {
// A human-friendly unique string automatically generated from the products name // A human-friendly unique string automatically generated from the products name
path: string path: string
variant: ProductVariant variant: ProductVariant
options?: SelectedOption[]
} }
export type ProductVariant = { export type ProductVariant = {
@ -86,7 +96,7 @@ export type CartItemBody = {
*/ */
export type CartTypes = { export type CartTypes = {
cart: Cart cart?: Cart
item: LineItem item: LineItem
itemBody: CartItemBody itemBody: CartItemBody
} }

View File

@ -1,5 +1,18 @@
// TODO: define this type // 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 pages `<body>` element, in default/desktop view. Required in POST if page type is `raw`.
body: string
// If true, this page appears in the storefronts 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 = { export type PageTypes = {
page: Page page: Page

View File

@ -14,6 +14,8 @@ export type ProductPrice = {
} }
export type ProductOption = { export type ProductOption = {
__typename?: 'MultipleChoiceOption'
id: string
displayName: string displayName: string
values: ProductOptionValues[] values: ProductOptionValues[]
} }
@ -26,6 +28,7 @@ export type ProductOptionValues = {
export type ProductVariant = { export type ProductVariant = {
id: string | number id: string | number
options: ProductOption[] options: ProductOption[]
availableForSale?: boolean
} }
export type Product = { export type Product = {
@ -44,9 +47,10 @@ export type Product = {
export type SearchProductsBody = { export type SearchProductsBody = {
search?: string search?: string
categoryId?: string categoryId?: string | number
brandId?: string brandId?: string | number
sort?: string sort?: string
locale?: string
} }
export type ProductTypes = { export type ProductTypes = {

View File

@ -2,7 +2,7 @@
export type Wishlist = any export type Wishlist = any
export type WishlistItemBody = { export type WishlistItemBody = {
variantId: string variantId: string | number
productId: string productId: string
} }

View File

@ -121,3 +121,15 @@ const pages = await getAllPages({
config, 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
```

View File

@ -1 +0,0 @@
export default function () {}

View File

@ -1 +0,0 @@
export default function () {}

View File

@ -1 +0,0 @@
export default function () {}

View File

@ -1 +0,0 @@
export default function () {}

View File

@ -1 +0,0 @@
export default function () {}

View File

@ -1 +0,0 @@
export default function () {}

View File

@ -1 +0,0 @@
export default function () {}

View File

@ -1 +0,0 @@
export default function () {}

View File

@ -0,0 +1 @@
export default function (_commerce: any) {}

View File

@ -0,0 +1 @@
export default function (_commerce: any) {}

View File

@ -1,24 +1,16 @@
import isAllowedMethod from '../utils/is-allowed-method'
import createApiHandler, {
ShopifyApiHandler,
} from '../utils/create-api-handler'
import { import {
SHOPIFY_CHECKOUT_ID_COOKIE, SHOPIFY_CHECKOUT_ID_COOKIE,
SHOPIFY_CHECKOUT_URL_COOKIE, SHOPIFY_CHECKOUT_URL_COOKIE,
SHOPIFY_CUSTOMER_TOKEN_COOKIE, SHOPIFY_CUSTOMER_TOKEN_COOKIE,
} from '../../const' } from '../../../const'
import associateCustomerWithCheckoutMutation from '../../../utils/mutations/associate-customer-with-checkout'
import { getConfig } from '..' import type { CheckoutEndpoint } from '.'
import associateCustomerWithCheckoutMutation from '../../utils/mutations/associate-customer-with-checkout'
const METHODS = ['GET']
const checkoutApi: ShopifyApiHandler<any> = async (req, res, config) => {
if (!isAllowedMethod(req, res, METHODS)) return
config = getConfig()
const checkout: CheckoutEndpoint['handlers']['checkout'] = async ({
req,
res,
config,
}) => {
const { cookies } = req const { cookies } = req
const checkoutUrl = cookies[SHOPIFY_CHECKOUT_URL_COOKIE] const checkoutUrl = cookies[SHOPIFY_CHECKOUT_URL_COOKIE]
const customerCookie = cookies[SHOPIFY_CUSTOMER_TOKEN_COOKIE] const customerCookie = cookies[SHOPIFY_CUSTOMER_TOKEN_COOKIE]
@ -43,4 +35,4 @@ const checkoutApi: ShopifyApiHandler<any> = async (req, res, config) => {
} }
} }
export default createApiHandler(checkoutApi, {}, {}) export default checkout

View File

@ -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<ShopifyAPI, CheckoutSchema>
export type CheckoutEndpoint = CheckoutAPI['endpoint']
export const handlers: CheckoutEndpoint['handlers'] = { checkout }
const checkoutApi = createEndpoint<CheckoutAPI>({
handler: checkoutEndpoint,
handlers,
})
export default checkoutApi

View File

@ -0,0 +1 @@
export default function (_commerce: any) {}

View File

@ -0,0 +1 @@
export default function (_commerce: any) {}

View File

@ -0,0 +1 @@
export default function (_commerce: any) {}

View File

@ -0,0 +1 @@
export default function (_commerce: any) {}

View File

@ -0,0 +1 @@
export default function (_commerce: any) {}

View File

@ -1,12 +1,20 @@
import type { CommerceAPIConfig } from '@commerce/api' import {
CommerceAPI,
CommerceAPIConfig,
getCommerceApi as commerceApi,
} from '@commerce/api'
import { import {
API_URL, API_URL,
API_TOKEN, API_TOKEN,
SHOPIFY_CHECKOUT_ID_COOKIE,
SHOPIFY_CUSTOMER_TOKEN_COOKIE, SHOPIFY_CUSTOMER_TOKEN_COOKIE,
SHOPIFY_CHECKOUT_ID_COOKIE,
} from '../const' } from '../const'
import fetchGraphqlApi from './utils/fetch-graphql-api'
import * as operations from './operations'
if (!API_URL) { if (!API_URL) {
throw new Error( throw new Error(
`The environment variable NEXT_PUBLIC_SHOPIFY_STORE_DOMAIN is missing and it's required to access your store` `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` `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 interface ShopifyConfig extends CommerceAPIConfig {}
export class Config { const ONE_DAY = 60 * 60 * 24
private config: ShopifyConfig
constructor(config: ShopifyConfig) { const config: ShopifyConfig = {
this.config = config
}
getConfig(userConfig: Partial<ShopifyConfig> = {}) {
return Object.entries(userConfig).reduce<ShopifyConfig>(
(cfg, [key, value]) => Object.assign(cfg, { [key]: value }),
{ ...this.config }
)
}
setConfig(newConfig: Partial<ShopifyConfig>) {
Object.assign(this.config, newConfig)
}
}
const config = new Config({
locale: 'en-US',
commerceUrl: API_URL, commerceUrl: API_URL,
apiToken: API_TOKEN!, apiToken: API_TOKEN,
cartCookie: SHOPIFY_CHECKOUT_ID_COOKIE,
cartCookieMaxAge: 60 * 60 * 24 * 30,
fetch: fetchGraphqlApi,
customerCookie: SHOPIFY_CUSTOMER_TOKEN_COOKIE, customerCookie: SHOPIFY_CUSTOMER_TOKEN_COOKIE,
}) cartCookie: SHOPIFY_CHECKOUT_ID_COOKIE,
cartCookieMaxAge: ONE_DAY * 30,
export function getConfig(userConfig?: Partial<ShopifyConfig>) { fetch: fetchGraphqlApi,
return config.getConfig(userConfig)
} }
export function setConfig(newConfig: Partial<ShopifyConfig>) { export const provider = {
return config.setConfig(newConfig) config,
operations,
}
export type Provider = typeof provider
export type ShopifyAPI<P extends Provider = Provider> = CommerceAPI<P>
export function getCommerceApi<P extends Provider>(
customProvider: P = provider as any
): ShopifyAPI<P> {
return commerceApi(customProvider)
} }

View File

@ -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<Provider>) {
async function getAllPages<T extends GetAllPagesOperation>(opts?: {
config?: Partial<ShopifyConfig>
preview?: boolean
}): Promise<T['data']>
async function getAllPages<T extends GetAllPagesOperation>(
opts: {
config?: Partial<ShopifyConfig>
preview?: boolean
} & OperationOptions
): Promise<T['data']>
async function getAllPages<T extends GetAllPagesOperation>({
query = getAllPagesQuery,
config,
variables,
}: {
url?: string
config?: Partial<ShopifyConfig>
variables?: GetAllPagesQueryVariables
preview?: boolean
query?: string
} = {}): Promise<T['data']> {
const { fetch, locale, locales = ['en-US'] } = commerce.getConfig(config)
const { data } = await fetch<GetAllPagesQuery, GetAllPagesQueryVariables>(
query,
{
variables,
},
{
...(locale && {
headers: {
'Accept-Language': locale,
},
}),
}
)
return {
pages: locales.reduce<Page[]>(
(arr, locale) =>
arr.concat(normalizePages(data.pages.edges as PageEdge[], locale)),
[]
),
}
}
return getAllPages
}

View File

@ -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<Provider>) {
async function getAllProductPaths<
T extends GetAllProductPathsOperation
>(opts?: {
variables?: T['variables']
config?: ShopifyConfig
}): Promise<T['data']>
async function getAllProductPaths<T extends GetAllProductPathsOperation>(
opts: {
variables?: T['variables']
config?: ShopifyConfig
} & OperationOptions
): Promise<T['data']>
async function getAllProductPaths<T extends GetAllProductPathsOperation>({
query = getAllProductsQuery,
config,
variables,
}: {
query?: string
config?: ShopifyConfig
variables?: T['variables']
} = {}): Promise<T['data']> {
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
}

View File

@ -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<Provider>) {
async function getAllProducts<T extends GetAllProductsOperation>(opts?: {
variables?: T['variables']
config?: Partial<ShopifyConfig>
preview?: boolean
}): Promise<T['data']>
async function getAllProducts<T extends GetAllProductsOperation>(
opts: {
variables?: T['variables']
config?: Partial<ShopifyConfig>
preview?: boolean
} & OperationOptions
): Promise<T['data']>
async function getAllProducts<T extends GetAllProductsOperation>({
query = getAllProductsQuery,
variables,
config,
}: {
query?: string
variables?: T['variables']
config?: Partial<ShopifyConfig>
preview?: boolean
} = {}): Promise<T['data']> {
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
}

View File

@ -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<Provider>) {
async function getPage<T extends GetPageOperation>(opts: {
variables: T['variables']
config?: Partial<ShopifyConfig>
preview?: boolean
}): Promise<T['data']>
async function getPage<T extends GetPageOperation>(
opts: {
variables: T['variables']
config?: Partial<ShopifyConfig>
preview?: boolean
} & OperationOptions
): Promise<T['data']>
async function getPage<T extends GetPageOperation>({
query = getPageQuery,
variables,
config,
}: {
query?: string
variables: T['variables']
config?: Partial<ShopifyConfig>
preview?: boolean
}): Promise<T['data']> {
const { fetch, locale = 'en-US' } = commerce.getConfig(config)
const {
data: { node: page },
} = await fetch<GetPageQuery, GetPageQueryVariables>(
query,
{
variables,
},
{
...(locale && {
headers: {
'Accept-Language': locale,
},
}),
}
)
return page ? { page: normalizePage(page as ShopifyPage, locale) } : {}
}
return getPage
}

View File

@ -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<Provider>) {
async function getProduct<T extends GetProductOperation>(opts: {
variables: T['variables']
config?: Partial<ShopifyConfig>
preview?: boolean
}): Promise<T['data']>
async function getProduct<T extends GetProductOperation>(
opts: {
variables: T['variables']
config?: Partial<ShopifyConfig>
preview?: boolean
} & OperationOptions
): Promise<T['data']>
async function getProduct<T extends GetProductOperation>({
query = getProductQuery,
variables,
config: cfg,
}: {
query?: string
variables: T['variables']
config?: Partial<ShopifyConfig>
preview?: boolean
}): Promise<T['data']> {
const { fetch, locale } = commerce.getConfig(cfg)
const {
data: { productByHandle },
} = await fetch<GetProductBySlugQuery>(
query,
{
variables,
},
{
...(locale && {
headers: {
'Accept-Language': locale,
},
}),
}
)
return {
...(productByHandle && {
product: normalizeProduct(productByHandle as ShopifyProduct),
}),
}
}
return getProduct
}

View File

@ -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<Provider>) {
async function getSiteInfo<T extends GetSiteInfoOperation>(opts?: {
config?: Partial<ShopifyConfig>
preview?: boolean
}): Promise<T['data']>
async function getSiteInfo<T extends GetSiteInfoOperation>(
opts: {
config?: Partial<ShopifyConfig>
preview?: boolean
} & OperationOptions
): Promise<T['data']>
async function getSiteInfo<T extends GetSiteInfoOperation>({
query = getSiteInfoQuery,
config,
variables,
}: {
query?: string
config?: Partial<ShopifyConfig>
preview?: boolean
variables?: GetSiteInfoQueryVariables
} = {}): Promise<T['data']> {
const cfg = commerce.getConfig(config)
const categories = await getCategories(cfg)
const brands = await getBrands(cfg)
/*
const { fetch, locale } = cfg
const { data } = await fetch<GetSiteInfoQuery, GetSiteInfoQueryVariables>(
query,
{ variables },
{
...(locale && {
headers: {
'Accept-Language': locale,
},
}),
}
)
*/
return {
categories,
brands,
}
}
return getSiteInfo
}

View File

@ -0,0 +1,7 @@
export { default as getAllPages } from './get-all-pages'
export { default as getPage } from './get-page'
export { default as getAllProducts } from './get-all-products'
export { default as getAllProductPaths } from './get-all-product-paths'
export { default as getProduct } from './get-product'
export { default as getSiteInfo } from './get-site-info'
export { default as login } from './login'

View File

@ -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<Provider>) {
async function login<T extends LoginOperation>({
query = customerAccessTokenCreateMutation,
variables,
config,
}: {
query?: string
variables: T['variables']
res: ServerResponse
config?: ShopifyConfig
}): Promise<T['data']> {
config = commerce.getConfig(config)
const {
data: { customerAccessTokenCreate },
} = await config.fetch<CustomerAccessTokenCreateMutation>(query, {
variables,
})
throwUserErrors(customerAccessTokenCreate?.customerUserErrors)
const customerAccessToken = customerAccessTokenCreate?.customerAccessToken
const accessToken = customerAccessToken?.accessToken
if (accessToken) {
setCustomerToken(accessToken)
}
return {
result: customerAccessToken?.accessToken,
}
}
return login
}

View File

@ -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<ShopifyApiResponse<T>>,
config: ShopifyConfig,
handlers: H,
// Custom configs that may be used by a particular handler
options: Options
) => void | Promise<void>
export type ShopifyHandler<T = any, Body = null> = (options: {
req: NextApiRequest
res: NextApiResponse<ShopifyApiResponse<T>>
config: ShopifyConfig
body: Body
}) => void | Promise<void>
export type ShopifyHandlers<T = any> = {
[k: string]: ShopifyHandler<T, any>
}
export type ShopifyApiResponse<T> = {
data: T | null
errors?: { message: string; code?: string }[]
}
export default function createApiHandler<
T = any,
H extends ShopifyHandlers = {},
Options extends {} = {}
>(
handler: ShopifyApiHandler<T, H, Options>,
handlers: H,
defaultOptions: Options
) {
return function getApiHandler({
config,
operations,
options,
}: {
config?: ShopifyConfig
operations?: Partial<H>
options?: Options extends {} ? Partial<Options> : never
} = {}): NextApiHandler {
const ops = { ...operations, ...handlers }
const opts = { ...defaultOptions, ...options }
return function apiHandler(req, res) {
return handler(req, res, getConfig(config), ops, opts)
}
}
}

View File

@ -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<ProductEdge[]> => {
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

View File

@ -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
}

View File

@ -1,2 +0,0 @@
export type WishlistItem = { product: any; id: number }
export default function () {}

View File

@ -1,31 +1,22 @@
import { useCallback } from 'react' import { useCallback } from 'react'
import type { MutationHook } from '@commerce/utils/types' import type { MutationHook } from '@commerce/utils/types'
import { CommerceError, ValidationError } from '@commerce/utils/errors' import { CommerceError } 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 useLogin, { UseLogin } from '@commerce/auth/use-login' 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<typeof handler> export default useLogin as UseLogin<typeof handler>
const getErrorMessage = ({ code, message }: CustomerUserError) => { export const handler: MutationHook<LoginHook> = {
switch (code) {
case 'UNIDENTIFIED_CUSTOMER':
message = 'Cannot find an account that matches the provided credentials'
break
}
return message
}
export const handler: MutationHook<null, {}, CustomerAccessTokenCreateInput> = {
fetchOptions: { fetchOptions: {
query: createCustomerAccessTokenMutation, query: customerAccessTokenCreateMutation,
}, },
async fetcher({ input: { email, password }, options, fetch }) { async fetcher({ input: { email, password }, options, fetch }) {
if (!(email && password)) { if (!(email && password)) {
@ -37,7 +28,7 @@ export const handler: MutationHook<null, {}, CustomerAccessTokenCreateInput> = {
const { customerAccessTokenCreate } = await fetch< const { customerAccessTokenCreate } = await fetch<
Mutation, Mutation,
MutationCheckoutCreateArgs MutationCustomerAccessTokenCreateArgs
>({ >({
...options, ...options,
variables: { variables: {

View File

@ -1,13 +1,14 @@
import { useCallback } from 'react' import { useCallback } from 'react'
import type { MutationHook } from '@commerce/utils/types' import type { MutationHook } from '@commerce/utils/types'
import useLogout, { UseLogout } from '@commerce/auth/use-logout' import useLogout, { UseLogout } from '@commerce/auth/use-logout'
import type { LogoutHook } from '../types/logout'
import useCustomer from '../customer/use-customer' import useCustomer from '../customer/use-customer'
import customerAccessTokenDeleteMutation from '../utils/mutations/customer-access-token-delete' import customerAccessTokenDeleteMutation from '../utils/mutations/customer-access-token-delete'
import { getCustomerToken, setCustomerToken } from '../utils/customer-token' import { getCustomerToken, setCustomerToken } from '../utils/customer-token'
export default useLogout as UseLogout<typeof handler> export default useLogout as UseLogout<typeof handler>
export const handler: MutationHook<null> = { export const handler: MutationHook<LogoutHook> = {
fetchOptions: { fetchOptions: {
query: customerAccessTokenDeleteMutation, query: customerAccessTokenDeleteMutation,
}, },

View File

@ -1,25 +1,20 @@
import { useCallback } from 'react' import { useCallback } from 'react'
import type { MutationHook } from '@commerce/utils/types' 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 useSignup, { UseSignup } from '@commerce/auth/use-signup'
import type { SignupHook } from '../types/signup'
import useCustomer from '../customer/use-customer' import useCustomer from '../customer/use-customer'
import { import { Mutation, MutationCustomerCreateArgs } from '../schema'
CustomerCreateInput,
Mutation,
MutationCustomerCreateArgs,
} from '../schema'
import { customerCreateMutation } from '../utils/mutations' import {
import { handleAutomaticLogin, throwUserErrors } from '../utils' handleAutomaticLogin,
throwUserErrors,
customerCreateMutation,
} from '../utils'
export default useSignup as UseSignup<typeof handler> export default useSignup as UseSignup<typeof handler>
export const handler: MutationHook< export const handler: MutationHook<SignupHook> = {
null,
{},
CustomerCreateInput,
CustomerCreateInput
> = {
fetchOptions: { fetchOptions: {
query: customerCreateMutation, query: customerCreateMutation,
}, },

View File

@ -2,18 +2,19 @@ import { useCallback } from 'react'
import type { MutationHook } from '@commerce/utils/types' import type { MutationHook } from '@commerce/utils/types'
import { CommerceError } from '@commerce/utils/errors' import { CommerceError } from '@commerce/utils/errors'
import useAddItem, { UseAddItem } from '@commerce/cart/use-add-item' import useAddItem, { UseAddItem } from '@commerce/cart/use-add-item'
import type { AddItemHook } from '../types/cart'
import useCart from './use-cart' import useCart from './use-cart'
import { import {
checkoutLineItemAddMutation, checkoutLineItemAddMutation,
getCheckoutId, getCheckoutId,
checkoutToCart, checkoutToCart,
} from '../utils' } from '../utils'
import { Cart, CartItemBody } from '../types'
import { Mutation, MutationCheckoutLineItemsAddArgs } from '../schema' import { Mutation, MutationCheckoutLineItemsAddArgs } from '../schema'
export default useAddItem as UseAddItem<typeof handler> export default useAddItem as UseAddItem<typeof handler>
export const handler: MutationHook<Cart, {}, CartItemBody> = { export const handler: MutationHook<AddItemHook> = {
fetchOptions: { fetchOptions: {
query: checkoutLineItemAddMutation, query: checkoutLineItemAddMutation,
}, },

View File

@ -1,22 +1,20 @@
import { useMemo } from 'react' import { useMemo } from 'react'
import useCommerceCart, { import useCommerceCart, { UseCart } from '@commerce/cart/use-cart'
FetchCartInput,
UseCart,
} from '@commerce/cart/use-cart'
import { Cart } from '../types'
import { SWRHook } from '@commerce/utils/types' import { SWRHook } from '@commerce/utils/types'
import { checkoutCreate, checkoutToCart } from '../utils' import { checkoutCreate, checkoutToCart } from '../utils'
import getCheckoutQuery from '../utils/queries/get-checkout-query' import getCheckoutQuery from '../utils/queries/get-checkout-query'
import { GetCartHook } from '../types/cart'
import {
GetCheckoutQuery,
GetCheckoutQueryVariables,
CheckoutDetailsFragment,
} from '../schema'
export default useCommerceCart as UseCart<typeof handler> export default useCommerceCart as UseCart<typeof handler>
export const handler: SWRHook< export const handler: SWRHook<GetCartHook> = {
Cart | null,
{},
FetchCartInput,
{ isEmpty?: boolean }
> = {
fetchOptions: { fetchOptions: {
query: getCheckoutQuery, query: getCheckoutQuery,
}, },

View File

@ -3,31 +3,29 @@ import type {
MutationHookContext, MutationHookContext,
HookFetcherContext, HookFetcherContext,
} from '@commerce/utils/types' } from '@commerce/utils/types'
import { RemoveCartItemBody } from '@commerce/types'
import { ValidationError } from '@commerce/utils/errors' import { ValidationError } from '@commerce/utils/errors'
import useRemoveItem, { import useRemoveItem, { UseRemoveItem } from '@commerce/cart/use-remove-item'
RemoveItemInput as RemoveItemInputBase, import type { Cart, LineItem, RemoveItemHook } from '../types/cart'
UseRemoveItem,
} from '@commerce/cart/use-remove-item'
import useCart from './use-cart' import useCart from './use-cart'
export type RemoveItemFn<T = any> = T extends LineItem
? (input?: RemoveItemActionInput<T>) => Promise<Cart | null | undefined>
: (input: RemoveItemActionInput<T>) => Promise<Cart | null>
export type RemoveItemActionInput<T = any> = T extends LineItem
? Partial<RemoveItemHook['actionInput']>
: RemoveItemHook['actionInput']
export default useRemoveItem as UseRemoveItem<typeof handler>
import { import {
checkoutLineItemRemoveMutation, checkoutLineItemRemoveMutation,
getCheckoutId, getCheckoutId,
checkoutToCart, checkoutToCart,
} from '../utils' } from '../utils'
import { Cart, LineItem } from '../types'
import { Mutation, MutationCheckoutLineItemsRemoveArgs } from '../schema' import { Mutation, MutationCheckoutLineItemsRemoveArgs } from '../schema'
export type RemoveItemFn<T = any> = T extends LineItem
? (input?: RemoveItemInput<T>) => Promise<Cart | null>
: (input: RemoveItemInput<T>) => Promise<Cart | null>
export type RemoveItemInput<T = any> = T extends LineItem
? Partial<RemoveItemInputBase>
: RemoveItemInputBase
export default useRemoveItem as UseRemoveItem<typeof handler>
export const handler = { export const handler = {
fetchOptions: { fetchOptions: {
query: checkoutLineItemRemoveMutation, query: checkoutLineItemRemoveMutation,
@ -36,16 +34,14 @@ export const handler = {
input: { itemId }, input: { itemId },
options, options,
fetch, fetch,
}: HookFetcherContext<RemoveCartItemBody>) { }: HookFetcherContext<RemoveItemHook>) {
const data = await fetch<Mutation, MutationCheckoutLineItemsRemoveArgs>({ const data = await fetch<Mutation, MutationCheckoutLineItemsRemoveArgs>({
...options, ...options,
variables: { checkoutId: getCheckoutId(), lineItemIds: [itemId] }, variables: { checkoutId: getCheckoutId(), lineItemIds: [itemId] },
}) })
return checkoutToCart(data.checkoutLineItemsRemove) return checkoutToCart(data.checkoutLineItemsRemove)
}, },
useHook: ({ useHook: ({ fetch }: MutationHookContext<RemoveItemHook>) => <
fetch,
}: MutationHookContext<Cart | null, RemoveCartItemBody>) => <
T extends LineItem | undefined = undefined T extends LineItem | undefined = undefined
>( >(
ctx: { item?: T } = {} ctx: { item?: T } = {}

View File

@ -5,21 +5,21 @@ import type {
MutationHookContext, MutationHookContext,
} from '@commerce/utils/types' } from '@commerce/utils/types'
import { ValidationError } from '@commerce/utils/errors' import { ValidationError } from '@commerce/utils/errors'
import useUpdateItem, { import useUpdateItem, { UseUpdateItem } from '@commerce/cart/use-update-item'
UpdateItemInput as UpdateItemInputBase,
UseUpdateItem,
} from '@commerce/cart/use-update-item'
import useCart from './use-cart' import useCart from './use-cart'
import { handler as removeItemHandler } from './use-remove-item' import { handler as removeItemHandler } from './use-remove-item'
import type { Cart, LineItem, UpdateCartItemBody } from '../types' import type { UpdateItemHook, LineItem } from '../types/cart'
import { checkoutToCart } from '../utils' import {
import { getCheckoutId, checkoutLineItemUpdateMutation } from '../utils' getCheckoutId,
checkoutLineItemUpdateMutation,
checkoutToCart,
} from '../utils'
import { Mutation, MutationCheckoutLineItemsUpdateArgs } from '../schema' import { Mutation, MutationCheckoutLineItemsUpdateArgs } from '../schema'
export type UpdateItemInput<T = any> = T extends LineItem export type UpdateItemActionInput<T = any> = T extends LineItem
? Partial<UpdateItemInputBase<LineItem>> ? Partial<UpdateItemHook['actionInput']>
: UpdateItemInputBase<LineItem> : UpdateItemHook['actionInput']
export default useUpdateItem as UseUpdateItem<typeof handler> export default useUpdateItem as UseUpdateItem<typeof handler>
@ -31,7 +31,7 @@ export const handler = {
input: { itemId, item }, input: { itemId, item },
options, options,
fetch, fetch,
}: HookFetcherContext<UpdateCartItemBody>) { }: HookFetcherContext<UpdateItemHook>) {
if (Number.isInteger(item.quantity)) { if (Number.isInteger(item.quantity)) {
// Also allow the update hook to remove an item if the quantity is lower than 1 // Also allow the update hook to remove an item if the quantity is lower than 1
if (item.quantity! < 1) { if (item.quantity! < 1) {
@ -64,9 +64,7 @@ export const handler = {
return checkoutToCart(checkoutLineItemsUpdate) return checkoutToCart(checkoutLineItemsUpdate)
}, },
useHook: ({ useHook: ({ fetch }: MutationHookContext<UpdateItemHook>) => <
fetch,
}: MutationHookContext<Cart | null, UpdateCartItemBody>) => <
T extends LineItem | undefined = undefined T extends LineItem | undefined = undefined
>( >(
ctx: { ctx: {
@ -78,7 +76,7 @@ export const handler = {
const { mutate } = useCart() as any const { mutate } = useCart() as any
return useCallback( return useCallback(
debounce(async (input: UpdateItemInput<T>) => { debounce(async (input: UpdateItemActionInput<T>) => {
const itemId = input.id ?? item?.id const itemId = input.id ?? item?.id
const productId = input.productId ?? item?.productId const productId = input.productId ?? item?.productId
const variantId = input.productId ?? item?.variantId const variantId = input.productId ?? item?.variantId

View File

@ -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"]
}
}

View File

@ -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<ReturnType> => {
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

View File

@ -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 extends { page?: any } = { page?: Page }> = T
const getPage = async (options: {
variables: Variables
config: ShopifyConfig
preview?: boolean
}): Promise<GetPageResult> => {
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

View File

@ -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<GetSiteInfoResult> => {
let { config } = options ?? {}
config = getConfig(config)
const categories = await getCategories(config)
const brands = await getVendors(config)
return {
categories,
brands,
}
}
export default getSiteInfo

View File

@ -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<number | undefined> {
config = getConfig(config)
const { data } = await config.fetch(getCustomerIdQuery, {
variables: {
customerAccesToken:
customerAccesToken || Cookies.get(config.customerCookie),
},
})
return data.customer?.id
}
export default getCustomerId

View File

@ -1,18 +1,19 @@
import useCustomer, { UseCustomer } from '@commerce/customer/use-customer' 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 { SWRHook } from '@commerce/utils/types'
import { getCustomerQuery, getCustomerToken } from '../utils' import { getCustomerQuery, getCustomerToken } from '../utils'
import { GetCustomerQuery, GetCustomerQueryVariables } from '../schema'
export default useCustomer as UseCustomer<typeof handler> export default useCustomer as UseCustomer<typeof handler>
export const handler: SWRHook<Customer | null> = { export const handler: SWRHook<CustomerHook> = {
fetchOptions: { fetchOptions: {
query: getCustomerQuery, query: getCustomerQuery,
}, },
async fetcher({ options, fetch }) { async fetcher({ options, fetch }) {
const customerAccessToken = getCustomerToken() const customerAccessToken = getCustomerToken()
if (customerAccessToken) { if (customerAccessToken) {
const data = await fetch({ const data = await fetch<GetCustomerQuery, GetCustomerQueryVariables>({
...options, ...options,
variables: { customerAccessToken: getCustomerToken() }, variables: { customerAccessToken: getCustomerToken() },
}) })

View File

@ -8,13 +8,17 @@ const fetcher: Fetcher = async ({
variables, variables,
query, query,
}) => { }) => {
const { locale, ...vars } = variables ?? {}
return handleFetchResponse( return handleFetchResponse(
await fetch(url, { await fetch(url, {
method, method,
body: JSON.stringify({ query, variables }), body: JSON.stringify({ query, variables: vars }),
headers: { headers: {
'X-Shopify-Storefront-Access-Token': API_TOKEN!, 'X-Shopify-Storefront-Access-Token': API_TOKEN!,
'Content-Type': 'application/json', 'Content-Type': 'application/json',
...(locale && {
'Accept-Language': locale,
}),
}, },
}) })
) )

View File

@ -36,4 +36,4 @@ export function CommerceProvider({ children, ...config }: ShopifyProps) {
) )
} }
export const useCommerce = () => useCoreCommerce() export const useCommerce = () => useCoreCommerce<ShopifyProvider>()

View File

@ -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

View File

@ -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<ReturnType> => {
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

View File

@ -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<ReturnType> => {
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

View File

@ -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<ReturnType> => {
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

View File

@ -1,7 +1,14 @@
import { SWRHook } from '@commerce/utils/types' import { SWRHook } from '@commerce/utils/types'
import useSearch, { UseSearch } from '@commerce/product/use-search' import useSearch, { UseSearch } from '@commerce/product/use-search'
import { ProductEdge } from '../schema' import {
CollectionEdge,
GetAllProductsQuery,
GetProductsFromCollectionQueryVariables,
Product as ShopifyProduct,
ProductEdge,
} from '../schema'
import { import {
getAllProductsQuery, getAllProductsQuery,
getCollectionProductsQuery, getCollectionProductsQuery,
@ -9,56 +16,59 @@ import {
normalizeProduct, normalizeProduct,
} from '../utils' } from '../utils'
import { Product } from '@commerce/types' import type { SearchProductsHook } from '../types/product'
export default useSearch as UseSearch<typeof handler>
export type SearchProductsInput = { export type SearchProductsInput = {
search?: string search?: string
categoryId?: string categoryId?: number
brandId?: string brandId?: number
sort?: string sort?: string
locale?: string
} }
export type SearchProductsData = { export default useSearch as UseSearch<typeof handler>
products: Product[]
found: boolean
}
export const handler: SWRHook< export const handler: SWRHook<SearchProductsHook> = {
SearchProductsData,
SearchProductsInput,
SearchProductsInput
> = {
fetchOptions: { fetchOptions: {
query: getAllProductsQuery, query: getAllProductsQuery,
}, },
async fetcher({ input, options, fetch }) { async fetcher({ input, options, fetch }) {
const { categoryId, brandId } = input const { categoryId, brandId } = input
const method = options?.method
const variables = getSearchVariables(input)
let products
const data = await fetch({ // change the query to getCollectionProductsQuery when categoryId is set
query: categoryId ? getCollectionProductsQuery : options.query,
method: options?.method,
variables: getSearchVariables(input),
})
let edges
if (categoryId) { if (categoryId) {
edges = data.node?.products?.edges ?? [] const data = await fetch<
if (brandId) { CollectionEdge,
edges = edges.filter( GetProductsFromCollectionQueryVariables
({ node: { vendor } }: ProductEdge) => >({
vendor.replace(/\s+/g, '-').toLowerCase() === brandId 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 { } else {
edges = data.products?.edges ?? [] const data = await fetch<GetAllProductsQuery>({
query: options.query,
method,
variables,
})
products = data.products.edges
} }
return { return {
products: edges.map(({ node }: ProductEdge) => normalizeProduct(node)), products: products?.map(({ node }) =>
found: !!edges.length, normalizeProduct(node as ShopifyProduct)
),
found: !!products?.length,
} }
}, },
useHook: ({ useData }) => (input = {}) => { useHook: ({ useData }) => (input = {}) => {
@ -68,6 +78,7 @@ export const handler: SWRHook<
['categoryId', input.categoryId], ['categoryId', input.categoryId],
['brandId', input.brandId], ['brandId', input.brandId],
['sort', input.sort], ['sort', input.sort],
['locale', input.locale],
], ],
swrOptions: { swrOptions: {
revalidateOnFocus: false, revalidateOnFocus: false,

View File

@ -37,7 +37,7 @@ export type ApiVersion = {
displayName: Scalars['String'] displayName: Scalars['String']
/** The unique identifier of an ApiVersion. All supported API versions have a date-based (YYYY-MM) or `unstable` handle. */ /** The unique identifier of an ApiVersion. All supported API versions have a date-based (YYYY-MM) or `unstable` handle. */
handle: Scalars['String'] 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'] supported: Scalars['Boolean']
} }
@ -306,17 +306,17 @@ export enum BlogSortKeys {
/** Card brand, such as Visa or Mastercard, which can be used for payments. */ /** Card brand, such as Visa or Mastercard, which can be used for payments. */
export enum CardBrand { export enum CardBrand {
/** Visa */ /** Visa. */
Visa = 'VISA', Visa = 'VISA',
/** Mastercard */ /** Mastercard. */
Mastercard = 'MASTERCARD', Mastercard = 'MASTERCARD',
/** Discover */ /** Discover. */
Discover = 'DISCOVER', Discover = 'DISCOVER',
/** American Express */ /** American Express. */
AmericanExpress = 'AMERICAN_EXPRESS', AmericanExpress = 'AMERICAN_EXPRESS',
/** Diners Club */ /** Diners Club. */
DinersClub = 'DINERS_CLUB', DinersClub = 'DINERS_CLUB',
/** JCB */ /** JCB. */
Jcb = 'JCB', Jcb = 'JCB',
} }
@ -1195,6 +1195,8 @@ export enum CountryCode {
Am = 'AM', Am = 'AM',
/** Aruba. */ /** Aruba. */
Aw = 'AW', Aw = 'AW',
/** Ascension Island. */
Ac = 'AC',
/** Australia. */ /** Australia. */
Au = 'AU', Au = 'AU',
/** Austria. */ /** Austria. */
@ -1613,6 +1615,8 @@ export enum CountryCode {
To = 'TO', To = 'TO',
/** Trinidad & Tobago. */ /** Trinidad & Tobago. */
Tt = 'TT', Tt = 'TT',
/** Tristan da Cunha. */
Ta = 'TA',
/** Tunisia. */ /** Tunisia. */
Tn = 'TN', Tn = 'TN',
/** Turkey. */ /** Turkey. */
@ -1687,7 +1691,7 @@ export type CreditCard = {
export type CreditCardPaymentInput = { export type CreditCardPaymentInput = {
/** The amount of the payment. */ /** The amount of the payment. */
amount: Scalars['Money'] 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'] idempotencyKey: Scalars['String']
/** The billing address for the payment. */ /** The billing address for the payment. */
billingAddress: MailingAddressInput billingAddress: MailingAddressInput
@ -1704,7 +1708,7 @@ export type CreditCardPaymentInput = {
export type CreditCardPaymentInputV2 = { export type CreditCardPaymentInputV2 = {
/** The amount and currency of the payment. */ /** The amount and currency of the payment. */
paymentAmount: MoneyInput 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'] idempotencyKey: Scalars['String']
/** The billing address for the payment. */ /** The billing address for the payment. */
billingAddress: MailingAddressInput billingAddress: MailingAddressInput
@ -1766,10 +1770,6 @@ export enum CurrencyCode {
Bhd = 'BHD', Bhd = 'BHD',
/** Burundian Franc (BIF). */ /** Burundian Franc (BIF). */
Bif = 'BIF', Bif = 'BIF',
/** Belarusian Ruble (BYN). */
Byn = 'BYN',
/** Belarusian Ruble (BYR). */
Byr = 'BYR',
/** Belize Dollar (BZD). */ /** Belize Dollar (BZD). */
Bzd = 'BZD', Bzd = 'BZD',
/** Bermudian Dollar (BMD). */ /** Bermudian Dollar (BMD). */
@ -1816,26 +1816,18 @@ export enum CurrencyCode {
Czk = 'CZK', Czk = 'CZK',
/** Danish Kroner (DKK). */ /** Danish Kroner (DKK). */
Dkk = 'DKK', Dkk = 'DKK',
/** Djiboutian Franc (DJF). */
Djf = 'DJF',
/** Dominican Peso (DOP). */ /** Dominican Peso (DOP). */
Dop = 'DOP', Dop = 'DOP',
/** East Caribbean Dollar (XCD). */ /** East Caribbean Dollar (XCD). */
Xcd = 'XCD', Xcd = 'XCD',
/** Egyptian Pound (EGP). */ /** Egyptian Pound (EGP). */
Egp = 'EGP', Egp = 'EGP',
/** Eritrean Nakfa (ERN). */
Ern = 'ERN',
/** Ethiopian Birr (ETB). */ /** Ethiopian Birr (ETB). */
Etb = 'ETB', Etb = 'ETB',
/** Falkland Islands Pounds (FKP). */
Fkp = 'FKP',
/** CFP Franc (XPF). */ /** CFP Franc (XPF). */
Xpf = 'XPF', Xpf = 'XPF',
/** Fijian Dollars (FJD). */ /** Fijian Dollars (FJD). */
Fjd = 'FJD', Fjd = 'FJD',
/** Gibraltar Pounds (GIP). */
Gip = 'GIP',
/** Gambian Dalasi (GMD). */ /** Gambian Dalasi (GMD). */
Gmd = 'GMD', Gmd = 'GMD',
/** Ghanaian Cedi (GHS). */ /** Ghanaian Cedi (GHS). */
@ -1846,8 +1838,6 @@ export enum CurrencyCode {
Gyd = 'GYD', Gyd = 'GYD',
/** Georgian Lari (GEL). */ /** Georgian Lari (GEL). */
Gel = 'GEL', Gel = 'GEL',
/** Guinean Franc (GNF). */
Gnf = 'GNF',
/** Haitian Gourde (HTG). */ /** Haitian Gourde (HTG). */
Htg = 'HTG', Htg = 'HTG',
/** Honduran Lempira (HNL). */ /** Honduran Lempira (HNL). */
@ -1864,8 +1854,6 @@ export enum CurrencyCode {
Idr = 'IDR', Idr = 'IDR',
/** Israeli New Shekel (NIS). */ /** Israeli New Shekel (NIS). */
Ils = 'ILS', Ils = 'ILS',
/** Iranian Rial (IRR). */
Irr = 'IRR',
/** Iraqi Dinar (IQD). */ /** Iraqi Dinar (IQD). */
Iqd = 'IQD', Iqd = 'IQD',
/** Jamaican Dollars (JMD). */ /** Jamaican Dollars (JMD). */
@ -1880,8 +1868,6 @@ export enum CurrencyCode {
Kzt = 'KZT', Kzt = 'KZT',
/** Kenyan Shilling (KES). */ /** Kenyan Shilling (KES). */
Kes = 'KES', Kes = 'KES',
/** Kiribati Dollar (KID). */
Kid = 'KID',
/** Kuwaiti Dinar (KWD). */ /** Kuwaiti Dinar (KWD). */
Kwd = 'KWD', Kwd = 'KWD',
/** Kyrgyzstani Som (KGS). */ /** Kyrgyzstani Som (KGS). */
@ -1896,8 +1882,6 @@ export enum CurrencyCode {
Lsl = 'LSL', Lsl = 'LSL',
/** Liberian Dollar (LRD). */ /** Liberian Dollar (LRD). */
Lrd = 'LRD', Lrd = 'LRD',
/** Libyan Dinar (LYD). */
Lyd = 'LYD',
/** Lithuanian Litai (LTL). */ /** Lithuanian Litai (LTL). */
Ltl = 'LTL', Ltl = 'LTL',
/** Malagasy Ariary (MGA). */ /** Malagasy Ariary (MGA). */
@ -1910,8 +1894,6 @@ export enum CurrencyCode {
Mwk = 'MWK', Mwk = 'MWK',
/** Maldivian Rufiyaa (MVR). */ /** Maldivian Rufiyaa (MVR). */
Mvr = 'MVR', Mvr = 'MVR',
/** Mauritanian Ouguiya (MRU). */
Mru = 'MRU',
/** Mexican Pesos (MXN). */ /** Mexican Pesos (MXN). */
Mxn = 'MXN', Mxn = 'MXN',
/** Malaysian Ringgits (MYR). */ /** Malaysian Ringgits (MYR). */
@ -1966,8 +1948,6 @@ export enum CurrencyCode {
Rwf = 'RWF', Rwf = 'RWF',
/** Samoan Tala (WST). */ /** Samoan Tala (WST). */
Wst = 'WST', Wst = 'WST',
/** Saint Helena Pounds (SHP). */
Shp = 'SHP',
/** Saudi Riyal (SAR). */ /** Saudi Riyal (SAR). */
Sar = 'SAR', Sar = 'SAR',
/** Sao Tome And Principe Dobra (STD). */ /** Sao Tome And Principe Dobra (STD). */
@ -1976,14 +1956,10 @@ export enum CurrencyCode {
Rsd = 'RSD', Rsd = 'RSD',
/** Seychellois Rupee (SCR). */ /** Seychellois Rupee (SCR). */
Scr = 'SCR', Scr = 'SCR',
/** Sierra Leonean Leone (SLL). */
Sll = 'SLL',
/** Singapore Dollars (SGD). */ /** Singapore Dollars (SGD). */
Sgd = 'SGD', Sgd = 'SGD',
/** Sudanese Pound (SDG). */ /** Sudanese Pound (SDG). */
Sdg = 'SDG', Sdg = 'SDG',
/** Somali Shilling (SOS). */
Sos = 'SOS',
/** Syrian Pound (SYP). */ /** Syrian Pound (SYP). */
Syp = 'SYP', Syp = 'SYP',
/** South African Rand (ZAR). */ /** South African Rand (ZAR). */
@ -2008,12 +1984,8 @@ export enum CurrencyCode {
Twd = 'TWD', Twd = 'TWD',
/** Thai baht (THB). */ /** Thai baht (THB). */
Thb = 'THB', Thb = 'THB',
/** Tajikistani Somoni (TJS). */
Tjs = 'TJS',
/** Tanzanian Shilling (TZS). */ /** Tanzanian Shilling (TZS). */
Tzs = 'TZS', Tzs = 'TZS',
/** Tongan Pa'anga (TOP). */
Top = 'TOP',
/** Trinidad and Tobago Dollars (TTD). */ /** Trinidad and Tobago Dollars (TTD). */
Ttd = 'TTD', Ttd = 'TTD',
/** Tunisian Dinar (TND). */ /** Tunisian Dinar (TND). */
@ -2034,10 +2006,6 @@ export enum CurrencyCode {
Uzs = 'UZS', Uzs = 'UZS',
/** Vanuatu Vatu (VUV). */ /** Vanuatu Vatu (VUV). */
Vuv = 'VUV', Vuv = 'VUV',
/** Venezuelan Bolivares (VEF). */
Vef = 'VEF',
/** Venezuelan Bolivares (VES). */
Ves = 'VES',
/** Vietnamese đồng (VND). */ /** Vietnamese đồng (VND). */
Vnd = 'VND', Vnd = 'VND',
/** West African CFA franc (XOF). */ /** West African CFA franc (XOF). */
@ -2046,6 +2014,42 @@ export enum CurrencyCode {
Yer = 'YER', Yer = 'YER',
/** Zambian Kwacha (ZMW). */ /** Zambian Kwacha (ZMW). */
Zmw = '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. */ /** 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<Scalars['String']> errorMessage?: Maybe<Scalars['String']>
/** Globally unique identifier. */ /** Globally unique identifier. */
id: Scalars['ID'] 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<Scalars['String']> idempotencyKey?: Maybe<Scalars['String']>
/** The URL where the customer needs to be redirected so they can complete the 3D Secure payment flow. */ /** The URL where the customer needs to be redirected so they can complete the 3D Secure payment flow. */
nextActionUrl?: Maybe<Scalars['URL']> nextActionUrl?: Maybe<Scalars['URL']>
@ -4386,7 +4394,9 @@ export type QueryRoot = {
collections: CollectionConnection collections: CollectionConnection
/** Find a customer by its access token. */ /** Find a customer by its access token. */
customer?: Maybe<Customer> customer?: Maybe<Customer>
/** Returns a specific node by ID. */
node?: Maybe<Node> node?: Maybe<Node>
/** Returns the list of nodes with the given IDs. */
nodes: Array<Maybe<Node>> nodes: Array<Maybe<Node>>
/** Find a page by its handle. */ /** Find a page by its handle. */
pageByHandle?: Maybe<Page> pageByHandle?: Maybe<Page>
@ -4768,7 +4778,7 @@ export type StringEdge = {
export type TokenizedPaymentInput = { export type TokenizedPaymentInput = {
/** The amount of the payment. */ /** The amount of the payment. */
amount: Scalars['Money'] 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'] idempotencyKey: Scalars['String']
/** The billing address for the payment. */ /** The billing address for the payment. */
billingAddress: MailingAddressInput billingAddress: MailingAddressInput
@ -4789,7 +4799,7 @@ export type TokenizedPaymentInput = {
export type TokenizedPaymentInputV2 = { export type TokenizedPaymentInputV2 = {
/** The amount and currency of the payment. */ /** The amount and currency of the payment. */
paymentAmount: MoneyInput 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'] idempotencyKey: Scalars['String']
/** The billing address for the payment. */ /** The billing address for the payment. */
billingAddress: MailingAddressInput billingAddress: MailingAddressInput
@ -4810,7 +4820,7 @@ export type TokenizedPaymentInputV2 = {
export type TokenizedPaymentInputV3 = { export type TokenizedPaymentInputV3 = {
/** The amount and currency of the payment. */ /** The amount and currency of the payment. */
paymentAmount: MoneyInput 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'] idempotencyKey: Scalars['String']
/** The billing address for the payment. */ /** The billing address for the payment. */
billingAddress: MailingAddressInput billingAddress: MailingAddressInput
@ -4847,18 +4857,32 @@ export type Transaction = {
test: Scalars['Boolean'] test: Scalars['Boolean']
} }
/** The different kinds of order transactions. */
export enum TransactionKind { export enum TransactionKind {
/** An authorization and capture performed together in a single step. */
Sale = 'SALE', Sale = 'SALE',
/** A transfer of the money that was reserved during the authorization stage. */
Capture = 'CAPTURE', Capture = 'CAPTURE',
/**
* An amount reserved against the cardholder's funding source.
* Money does not change hands until the authorization is captured.
*/
Authorization = 'AUTHORIZATION', Authorization = 'AUTHORIZATION',
/** An authorization for a payment taken with an EMV credit card reader. */
EmvAuthorization = 'EMV_AUTHORIZATION', EmvAuthorization = 'EMV_AUTHORIZATION',
/** Money returned to the customer when they have paid too much. */
Change = 'CHANGE', Change = 'CHANGE',
} }
/** Transaction statuses describe the status of a transaction. */
export enum TransactionStatus { export enum TransactionStatus {
/** The transaction is pending. */
Pending = 'PENDING', Pending = 'PENDING',
/** The transaction succeeded. */
Success = 'SUCCESS', Success = 'SUCCESS',
/** The transaction failed. */
Failure = 'FAILURE', Failure = 'FAILURE',
/** There was an error while processing the transaction. */
Error = 'ERROR', Error = 'ERROR',
} }
@ -4967,19 +4991,596 @@ export enum WeightUnit {
Ounces = 'OUNCES', 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<Checkout, 'id'>>
checkoutUserErrors: Array<
{ __typename?: 'CheckoutUserError' } & Pick<
CheckoutUserError,
'code' | 'field' | 'message'
>
>
customer?: Maybe<{ __typename?: 'Customer' } & Pick<Customer, 'id'>>
}
>
}
export type CheckoutCreateMutationVariables = Exact<{
input?: Maybe<CheckoutCreateInput>
}>
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> | 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']> | 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> | 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<UserError, 'field' | 'message'>
>
}
>
}
export type CustomerActivateByUrlMutationVariables = Exact<{
activationUrl: Scalars['URL']
password: Scalars['String']
}>
export type CustomerActivateByUrlMutation = { __typename?: 'Mutation' } & {
customerActivateByUrl?: Maybe<
{ __typename?: 'CustomerActivateByUrlPayload' } & {
customer?: Maybe<{ __typename?: 'Customer' } & Pick<Customer, 'id'>>
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<Customer, 'id'>>
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<Customer, 'id'>>
}
>
}
export type GetSiteCollectionsQueryVariables = Exact<{
first: Scalars['Int'] first: Scalars['Int']
}> }>
export type Unnamed_1_Query = { __typename?: 'QueryRoot' } & { export type GetSiteCollectionsQuery = { __typename?: 'QueryRoot' } & {
pages: { __typename?: 'PageConnection' } & { collections: { __typename?: 'CollectionConnection' } & {
edges: Array< edges: Array<
{ __typename?: 'PageEdge' } & { { __typename?: 'CollectionEdge' } & {
node: { __typename?: 'Page' } & Pick< node: { __typename?: 'Collection' } & Pick<
Page, Collection,
'id' | 'title' | 'handle' | 'body' | 'bodySummary' | 'url' 'id' | 'title' | 'handle'
> >
} }
> >
} }
} }
export type GetAllPagesQueryVariables = Exact<{
first?: Maybe<Scalars['Int']>
}>
export type GetAllPagesQuery = { __typename?: 'QueryRoot' } & {
pages: { __typename?: 'PageConnection' } & {
edges: Array<
{ __typename?: 'PageEdge' } & {
node: { __typename?: 'Page' } & Pick<Page, 'id' | 'title' | 'handle'>
}
>
}
}
export type GetAllProductVendorsQueryVariables = Exact<{
first?: Maybe<Scalars['Int']>
cursor?: Maybe<Scalars['String']>
}>
export type GetAllProductVendorsQuery = { __typename?: 'QueryRoot' } & {
products: { __typename?: 'ProductConnection' } & {
pageInfo: { __typename?: 'PageInfo' } & Pick<
PageInfo,
'hasNextPage' | 'hasPreviousPage'
>
edges: Array<
{ __typename?: 'ProductEdge' } & Pick<ProductEdge, 'cursor'> & {
node: { __typename?: 'Product' } & Pick<Product, 'vendor'>
}
>
}
}
export type GetAllProductPathsQueryVariables = Exact<{
first?: Maybe<Scalars['Int']>
cursor?: Maybe<Scalars['String']>
}>
export type GetAllProductPathsQuery = { __typename?: 'QueryRoot' } & {
products: { __typename?: 'ProductConnection' } & {
pageInfo: { __typename?: 'PageInfo' } & Pick<
PageInfo,
'hasNextPage' | 'hasPreviousPage'
>
edges: Array<
{ __typename?: 'ProductEdge' } & Pick<ProductEdge, 'cursor'> & {
node: { __typename?: 'Product' } & Pick<Product, 'handle'>
}
>
}
}
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<Scalars['Int']>
query?: Maybe<Scalars['String']>
sortKey?: Maybe<ProductSortKeys>
reverse?: Maybe<Scalars['Boolean']>
}>
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<Scalars['Int']>
sortKey?: Maybe<ProductCollectionSortKeys>
reverse?: Maybe<Scalars['Boolean']>
}>
export type GetProductsFromCollectionQuery = { __typename?: 'QueryRoot' } & {
node?: Maybe<
| ({ __typename?: 'AppliedGiftCard' } & Pick<AppliedGiftCard, 'id'>)
| ({ __typename?: 'Article' } & Pick<Article, 'id'>)
| ({ __typename?: 'Blog' } & Pick<Blog, 'id'>)
| ({ __typename?: 'Checkout' } & Pick<Checkout, 'id'>)
| ({ __typename?: 'CheckoutLineItem' } & Pick<CheckoutLineItem, 'id'>)
| ({ __typename?: 'Collection' } & Pick<Collection, 'id'> & {
products: {
__typename?: 'ProductConnection'
} & ProductConnectionFragment
})
| ({ __typename?: 'Comment' } & Pick<Comment, 'id'>)
| ({ __typename?: 'ExternalVideo' } & Pick<ExternalVideo, 'id'>)
| ({ __typename?: 'MailingAddress' } & Pick<MailingAddress, 'id'>)
| ({ __typename?: 'MediaImage' } & Pick<MediaImage, 'id'>)
| ({ __typename?: 'Metafield' } & Pick<Metafield, 'id'>)
| ({ __typename?: 'Model3d' } & Pick<Model3d, 'id'>)
| ({ __typename?: 'Order' } & Pick<Order, 'id'>)
| ({ __typename?: 'Page' } & Pick<Page, 'id'>)
| ({ __typename?: 'Payment' } & Pick<Payment, 'id'>)
| ({ __typename?: 'Product' } & Pick<Product, 'id'>)
| ({ __typename?: 'ProductOption' } & Pick<ProductOption, 'id'>)
| ({ __typename?: 'ProductVariant' } & Pick<ProductVariant, 'id'>)
| ({ __typename?: 'ShopPolicy' } & Pick<ShopPolicy, 'id'>)
| ({ __typename?: 'Video' } & Pick<Video, 'id'>)
>
}
export type GetCustomerIdQueryVariables = Exact<{
customerAccessToken: Scalars['String']
}>
export type GetCustomerIdQuery = { __typename?: 'QueryRoot' } & {
customer?: Maybe<{ __typename?: 'Customer' } & Pick<Customer, 'id'>>
}
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<AppliedGiftCard, 'id'>)
| ({ __typename?: 'Article' } & Pick<Article, 'id'>)
| ({ __typename?: 'Blog' } & Pick<Blog, 'id'>)
| ({ __typename?: 'Checkout' } & Pick<Checkout, 'id'>)
| ({ __typename?: 'CheckoutLineItem' } & Pick<CheckoutLineItem, 'id'>)
| ({ __typename?: 'Collection' } & Pick<Collection, 'id'>)
| ({ __typename?: 'Comment' } & Pick<Comment, 'id'>)
| ({ __typename?: 'ExternalVideo' } & Pick<ExternalVideo, 'id'>)
| ({ __typename?: 'MailingAddress' } & Pick<MailingAddress, 'id'>)
| ({ __typename?: 'MediaImage' } & Pick<MediaImage, 'id'>)
| ({ __typename?: 'Metafield' } & Pick<Metafield, 'id'>)
| ({ __typename?: 'Model3d' } & Pick<Model3d, 'id'>)
| ({ __typename?: 'Order' } & Pick<Order, 'id'>)
| ({ __typename?: 'Page' } & Pick<
Page,
'title' | 'handle' | 'body' | 'bodySummary' | 'id'
>)
| ({ __typename?: 'Payment' } & Pick<Payment, 'id'>)
| ({ __typename?: 'Product' } & Pick<Product, 'id'>)
| ({ __typename?: 'ProductOption' } & Pick<ProductOption, 'id'>)
| ({ __typename?: 'ProductVariant' } & Pick<ProductVariant, 'id'>)
| ({ __typename?: 'ShopPolicy' } & Pick<ShopPolicy, 'id'>)
| ({ __typename?: 'Video' } & Pick<Video, 'id'>)
>
}
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<Shop, 'name'>
}

View File

@ -13,6 +13,16 @@ directive @accessRestricted(
reason: String = null reason: String = null
) on FIELD_DEFINITION | OBJECT ) on FIELD_DEFINITION | OBJECT
"""
Contextualize data.
"""
directive @inContext(
"""
The country code for context.
"""
country: CountryCode!
) on QUERY | MUTATION
""" """
A version of the API. A version of the API.
""" """
@ -28,7 +38,7 @@ type ApiVersion {
handle: String! 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! supported: Boolean!
} }
@ -547,32 +557,32 @@ Card brand, such as Visa or Mastercard, which can be used for payments.
""" """
enum CardBrand { enum CardBrand {
""" """
Visa Visa.
""" """
VISA VISA
""" """
Mastercard Mastercard.
""" """
MASTERCARD MASTERCARD
""" """
Discover Discover.
""" """
DISCOVER DISCOVER
""" """
American Express American Express.
""" """
AMERICAN_EXPRESS AMERICAN_EXPRESS
""" """
Diners Club Diners Club.
""" """
DINERS_CLUB DINERS_CLUB
""" """
JCB JCB.
""" """
JCB JCB
} }
@ -2142,6 +2152,11 @@ enum CountryCode {
""" """
AW AW
"""
Ascension Island.
"""
AC
""" """
Australia. Australia.
""" """
@ -3187,6 +3202,11 @@ enum CountryCode {
""" """
TT TT
"""
Tristan da Cunha.
"""
TA
""" """
Tunisia. Tunisia.
""" """
@ -3354,7 +3374,7 @@ input CreditCardPaymentInput {
amount: Money! 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! idempotencyKey: String!
@ -3385,7 +3405,7 @@ input CreditCardPaymentInputV2 {
paymentAmount: MoneyInput! 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! idempotencyKey: String!
@ -3529,16 +3549,6 @@ enum CurrencyCode {
""" """
BIF BIF
"""
Belarusian Ruble (BYN).
"""
BYN
"""
Belarusian Ruble (BYR).
"""
BYR
""" """
Belize Dollar (BZD). Belize Dollar (BZD).
""" """
@ -3654,11 +3664,6 @@ enum CurrencyCode {
""" """
DKK DKK
"""
Djiboutian Franc (DJF).
"""
DJF
""" """
Dominican Peso (DOP). Dominican Peso (DOP).
""" """
@ -3674,21 +3679,11 @@ enum CurrencyCode {
""" """
EGP EGP
"""
Eritrean Nakfa (ERN).
"""
ERN
""" """
Ethiopian Birr (ETB). Ethiopian Birr (ETB).
""" """
ETB ETB
"""
Falkland Islands Pounds (FKP).
"""
FKP
""" """
CFP Franc (XPF). CFP Franc (XPF).
""" """
@ -3699,11 +3694,6 @@ enum CurrencyCode {
""" """
FJD FJD
"""
Gibraltar Pounds (GIP).
"""
GIP
""" """
Gambian Dalasi (GMD). Gambian Dalasi (GMD).
""" """
@ -3729,11 +3719,6 @@ enum CurrencyCode {
""" """
GEL GEL
"""
Guinean Franc (GNF).
"""
GNF
""" """
Haitian Gourde (HTG). Haitian Gourde (HTG).
""" """
@ -3774,11 +3759,6 @@ enum CurrencyCode {
""" """
ILS ILS
"""
Iranian Rial (IRR).
"""
IRR
""" """
Iraqi Dinar (IQD). Iraqi Dinar (IQD).
""" """
@ -3814,11 +3794,6 @@ enum CurrencyCode {
""" """
KES KES
"""
Kiribati Dollar (KID).
"""
KID
""" """
Kuwaiti Dinar (KWD). Kuwaiti Dinar (KWD).
""" """
@ -3854,11 +3829,6 @@ enum CurrencyCode {
""" """
LRD LRD
"""
Libyan Dinar (LYD).
"""
LYD
""" """
Lithuanian Litai (LTL). Lithuanian Litai (LTL).
""" """
@ -3889,11 +3859,6 @@ enum CurrencyCode {
""" """
MVR MVR
"""
Mauritanian Ouguiya (MRU).
"""
MRU
""" """
Mexican Pesos (MXN). Mexican Pesos (MXN).
""" """
@ -4029,11 +3994,6 @@ enum CurrencyCode {
""" """
WST WST
"""
Saint Helena Pounds (SHP).
"""
SHP
""" """
Saudi Riyal (SAR). Saudi Riyal (SAR).
""" """
@ -4054,11 +4014,6 @@ enum CurrencyCode {
""" """
SCR SCR
"""
Sierra Leonean Leone (SLL).
"""
SLL
""" """
Singapore Dollars (SGD). Singapore Dollars (SGD).
""" """
@ -4069,11 +4024,6 @@ enum CurrencyCode {
""" """
SDG SDG
"""
Somali Shilling (SOS).
"""
SOS
""" """
Syrian Pound (SYP). Syrian Pound (SYP).
""" """
@ -4134,21 +4084,11 @@ enum CurrencyCode {
""" """
THB THB
"""
Tajikistani Somoni (TJS).
"""
TJS
""" """
Tanzanian Shilling (TZS). Tanzanian Shilling (TZS).
""" """
TZS TZS
"""
Tongan Pa'anga (TOP).
"""
TOP
""" """
Trinidad and Tobago Dollars (TTD). Trinidad and Tobago Dollars (TTD).
""" """
@ -4199,16 +4139,6 @@ enum CurrencyCode {
""" """
VUV VUV
"""
Venezuelan Bolivares (VEF).
"""
VEF
"""
Venezuelan Bolivares (VES).
"""
VES
""" """
Vietnamese đồng (VND). Vietnamese đồng (VND).
""" """
@ -4228,6 +4158,96 @@ enum CurrencyCode {
Zambian Kwacha (ZMW). Zambian Kwacha (ZMW).
""" """
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. 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 idempotencyKey: String
@ -8589,12 +8611,20 @@ type QueryRoot {
""" """
customerAccessToken: String! customerAccessToken: String!
): Customer ): Customer
"""
Returns a specific node by ID.
"""
node( node(
""" """
The ID of the Node to return. The ID of the Node to return.
""" """
id: ID! id: ID!
): Node ): Node
"""
Returns the list of nodes with the given IDs.
"""
nodes( nodes(
""" """
The IDs of the Nodes to return. The IDs of the Nodes to return.
@ -9246,7 +9276,7 @@ input TokenizedPaymentInput {
amount: Money! 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! idempotencyKey: String!
@ -9287,7 +9317,7 @@ input TokenizedPaymentInputV2 {
paymentAmount: MoneyInput! 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! idempotencyKey: String!
@ -9328,7 +9358,7 @@ input TokenizedPaymentInputV3 {
paymentAmount: MoneyInput! 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! idempotencyKey: String!
@ -9393,18 +9423,59 @@ type Transaction {
test: Boolean! test: Boolean!
} }
"""
The different kinds of order transactions.
"""
enum TransactionKind { 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.
"""
EMV_AUTHORIZATION EMV_AUTHORIZATION
"""
Money returned to the customer when they have paid too much.
"""
CHANGE CHANGE
} }
"""
Transaction statuses describe the status of a transaction.
"""
enum TransactionStatus { 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
} }

View File

@ -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<CartItemBody>
export type AddCartItemHandlerBody = Core.AddCartItemHandlerBody<CartItemBody>
export type UpdateCartItemBody = Core.UpdateCartItemBody<CartItemBody>
export type UpdateCartItemHandlerBody = Core.UpdateCartItemHandlerBody<CartItemBody>
export type RemoveCartItemBody = Core.RemoveCartItemBody
export type RemoveCartItemHandlerBody = Core.RemoveCartItemHandlerBody

View File

@ -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<CartTypes>
export type GetCartHook = CartHooks['getCart']
export type AddItemHook = CartHooks['addItem']
export type UpdateItemHook = CartHooks['updateItem']
export type RemoveItemHook = CartHooks['removeItem']
export type CartSchema = Core.CartSchema<CartTypes>
export type CartHandlers = Core.CartHandlers<CartTypes>
export type GetCartHandler = CartHandlers['getCart']
export type AddItemHandler = CartHandlers['addItem']
export type UpdateItemHandler = CartHandlers['updateItem']
export type RemoveItemHandler = CartHandlers['removeItem']

View File

@ -0,0 +1 @@
export * from '@commerce/types/checkout'

View File

@ -0,0 +1 @@
export * from '@commerce/types/common'

View File

@ -0,0 +1,5 @@
import * as Core from '@commerce/types/customer'
export * from '@commerce/types/customer'
export type CustomerSchema = Core.CustomerSchema

View File

@ -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,
}

View File

@ -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
}

View File

@ -0,0 +1 @@
export * from '@commerce/types/logout'

View File

@ -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<PageTypes>
export type GetPageOperation = Core.GetPageOperation<PageTypes>

View File

@ -0,0 +1 @@
export * from '@commerce/types/product'

View File

@ -0,0 +1 @@
export * from '@commerce/types/signup'

View File

@ -0,0 +1 @@
export * from '@commerce/types/site'

View File

@ -0,0 +1 @@
export * from '@commerce/types/wishlist'

View File

@ -1,4 +1,4 @@
import { Cart } from '../types' import type { Cart } from '../types/cart'
import { CommerceError } from '@commerce/utils/errors' import { CommerceError } from '@commerce/utils/errors'
import { import {
@ -27,12 +27,6 @@ export type CheckoutPayload =
| CheckoutQuery | CheckoutQuery
const checkoutToCart = (checkoutPayload?: Maybe<CheckoutPayload>): Cart => { const checkoutToCart = (checkoutPayload?: Maybe<CheckoutPayload>): Cart => {
if (!checkoutPayload) {
throw new CommerceError({
message: 'Missing checkout payload from response',
})
}
const checkout = checkoutPayload?.checkout const checkout = checkoutPayload?.checkout
throwUserErrors(checkoutPayload?.checkoutUserErrors) throwUserErrors(checkoutPayload?.checkoutUserErrors)

View File

@ -1,5 +1,8 @@
import {
GetAllProductVendorsQuery,
GetAllProductVendorsQueryVariables,
} from '../schema'
import { ShopifyConfig } from '../api' import { ShopifyConfig } from '../api'
import fetchAllProducts from '../api/utils/fetch-all-products'
import getAllProductVendors from './queries/get-all-product-vendors-query' import getAllProductVendors from './queries/get-all-product-vendors-query'
export type Brand = { export type Brand = {
@ -14,16 +17,17 @@ export type BrandEdge = {
export type Brands = BrandEdge[] export type Brands = BrandEdge[]
const getVendors = async (config: ShopifyConfig): Promise<BrandEdge[]> => { const getBrands = async (config: ShopifyConfig): Promise<BrandEdge[]> => {
const vendors = await fetchAllProducts({ const { data } = await config.fetch<
config, GetAllProductVendorsQuery,
query: getAllProductVendors, GetAllProductVendorsQueryVariables
>(getAllProductVendors, {
variables: { variables: {
first: 250, first: 250,
}, },
}) })
let vendorsStrings = vendors.map(({ node: { vendor } }) => vendor) let vendorsStrings = data.products.edges.map(({ node: { vendor } }) => vendor)
return [...new Set(vendorsStrings)].map((v) => { return [...new Set(vendorsStrings)].map((v) => {
const id = v.replace(/\s+/g, '-').toLowerCase() const id = v.replace(/\s+/g, '-').toLowerCase()
@ -37,4 +41,4 @@ const getVendors = async (config: ShopifyConfig): Promise<BrandEdge[]> => {
}) })
} }
export default getVendors export default getBrands

Some files were not shown because too many files have changed in this diff Show More