forked from crowetic/commerce
Update types (#831)
* Update product types * Cart types progress, add zod & initial schema validator * Update normalize.ts * Update with-schema-parser.ts * Updated types, schemas & providers * Fix providers after schema parse errors * Fix paths * More provider fixes * Fix kibocommerce & commercejs * Add customer updated types & fixes * Add checkout & customer types * Import core types only from commerce * Update tsconfig.json * Convert hooks interfaces to types * Requested changes * Change to relative paths * Move Zod dependency
This commit is contained in:
parent
8398a96215
commit
6c2610584d
15
README.md
15
README.md
@ -23,8 +23,8 @@ Demo live at: [demo.vercel.store](https://demo.vercel.store/)
|
|||||||
> To run a minimal version of Next.js Commerce you can start with the default local provider `@vercel/commerce-local` that has disabled all features (cart, auth) and use static files for the backend
|
> To run a minimal version of Next.js Commerce you can start with the default local provider `@vercel/commerce-local` that has disabled all features (cart, auth) and use static files for the backend
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
pnpm install # run this command in root folder of the mono repo
|
pnpm install & pnpm build # run this commands in root folder of the mono repo
|
||||||
pnpm dev
|
pnpm dev # run this commands in the site folder
|
||||||
```
|
```
|
||||||
|
|
||||||
> If you encounter any problems while installing and running for the first time, please see the Troubleshoot section
|
> If you encounter any problems while installing and running for the first time, please see the Troubleshoot section
|
||||||
@ -111,10 +111,11 @@ Our commitment to Open Source can be found [here](https://vercel.com/oss).
|
|||||||
1. [Fork](https://help.github.com/articles/fork-a-repo/) this repository to your own GitHub account and then [clone](https://help.github.com/articles/cloning-a-repository/) it to your local device.
|
1. [Fork](https://help.github.com/articles/fork-a-repo/) this repository to your own GitHub account and then [clone](https://help.github.com/articles/cloning-a-repository/) it to your local device.
|
||||||
2. Create a new branch `git checkout -b MY_BRANCH_NAME`
|
2. Create a new branch `git checkout -b MY_BRANCH_NAME`
|
||||||
3. Install the dependencies: `pnpm install`
|
3. Install the dependencies: `pnpm install`
|
||||||
4. Duplicate `site/.env.template` and rename it to `site/.env.local`
|
4. Build the packages: `pnpm build`
|
||||||
5. Add proper store values to `site/.env.local`
|
5. Duplicate `site/.env.template` and rename it to `site/.env.local`
|
||||||
6. Run `pnpm dev` to build the packages and watch for code changes
|
6. Add proper store values to `site/.env.local`
|
||||||
7. Run `pnpm turbo run build` to check the build after your changes
|
7. Run `cd site` & `pnpm dev` to watch for code changes
|
||||||
|
8. Run `pnpm turbo run build` to check the build after your changes
|
||||||
|
|
||||||
## Work in progress
|
## Work in progress
|
||||||
|
|
||||||
@ -191,7 +192,7 @@ info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this comm
|
|||||||
|
|
||||||
The error usually occurs when running `pnpm dev` inside of the `/site/` folder after installing a fresh repository.
|
The error usually occurs when running `pnpm dev` inside of the `/site/` folder after installing a fresh repository.
|
||||||
|
|
||||||
In order to fix this, run `pnpm dev` in the monorepo root folder first.
|
In order to fix this, run `pnpm build` in the monorepo root folder first.
|
||||||
|
|
||||||
> Using `pnpm dev` from the root is recommended for developing, which will run watch mode on all packages.
|
> Using `pnpm dev` from the root is recommended for developing, which will run watch mode on all packages.
|
||||||
|
|
||||||
|
@ -1130,7 +1130,7 @@ export interface definitions {
|
|||||||
*/
|
*/
|
||||||
search_keywords?: string
|
search_keywords?: string
|
||||||
/**
|
/**
|
||||||
* Image URL used for this category on the storefront. Images can be uploaded via form file post to `/brands/{brandId}/image`, or by providing a publicly accessible URL in this field.
|
* Image URL used for this category on the storefront. Images can be uploaded via form file post to `/{brandId}/image`, or by providing a publicly accessible URL in this field.
|
||||||
*/
|
*/
|
||||||
image_url?: string
|
image_url?: string
|
||||||
custom_url?: definitions['customUrl_Full']
|
custom_url?: definitions['customUrl_Full']
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
import { normalizeCart } from '../../../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/cart'
|
import type { BigcommerceCart } from '../../../types'
|
||||||
import type { CartEndpoint } from '.'
|
import type { CartEndpoint } from '.'
|
||||||
|
|
||||||
// Return current cart info
|
// Return current cart info
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { GetAPISchema, createEndpoint } from '@vercel/commerce/api'
|
import { GetAPISchema, createEndpoint } from '@vercel/commerce/api'
|
||||||
import cartEndpoint from '@vercel/commerce/api/endpoints/cart'
|
import cartEndpoint from '@vercel/commerce/api/endpoints/cart'
|
||||||
import type { CartSchema } from '../../../types/cart'
|
import type { CartSchema } from '@vercel/commerce/types/cart'
|
||||||
import type { BigcommerceAPI } from '../..'
|
import type { BigcommerceAPI } from '../..'
|
||||||
import getCart from './get-cart'
|
import getCart from './get-cart'
|
||||||
import addItem from './add-item'
|
import addItem from './add-item'
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { GetAPISchema, createEndpoint } from '@vercel/commerce/api'
|
import { GetAPISchema, createEndpoint } from '@vercel/commerce/api'
|
||||||
import productsEndpoint from '@vercel/commerce/api/endpoints/catalog/products'
|
import productsEndpoint from '@vercel/commerce/api/endpoints/catalog/products'
|
||||||
import type { ProductsSchema } from '../../../../types/product'
|
import type { ProductsSchema } from '@vercel/commerce/types/product'
|
||||||
import type { BigcommerceAPI } from '../../..'
|
import type { BigcommerceAPI } from '../../..'
|
||||||
import getProducts from './get-products'
|
import getProducts from './get-products'
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { GetAPISchema, createEndpoint } from '@vercel/commerce/api'
|
import { GetAPISchema, createEndpoint } from '@vercel/commerce/api'
|
||||||
import checkoutEndpoint from '@vercel/commerce/api/endpoints/checkout'
|
import checkoutEndpoint from '@vercel/commerce/api/endpoints/checkout'
|
||||||
import type { CheckoutSchema } from '../../../types/checkout'
|
import type { CheckoutSchema } from '@vercel/commerce/types/checkout'
|
||||||
import type { BigcommerceAPI } from '../..'
|
import type { BigcommerceAPI } from '../..'
|
||||||
import getCheckout from './get-checkout'
|
import getCheckout from './get-checkout'
|
||||||
|
|
||||||
|
@ -47,7 +47,19 @@ const getLoggedInCustomer: CustomerEndpoint['handlers']['getLoggedInCustomer'] =
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
return res.status(200).json({ data: { customer } })
|
return res.status(200).json({
|
||||||
|
data: {
|
||||||
|
customer: {
|
||||||
|
id: String(customer.entityId),
|
||||||
|
firstName: customer.firstName,
|
||||||
|
lastName: customer.lastName,
|
||||||
|
email: customer.email,
|
||||||
|
company: customer.company,
|
||||||
|
phone: customer.phone,
|
||||||
|
notes: customer.notes,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
res.status(200).json({ data: null })
|
res.status(200).json({ data: null })
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { GetAPISchema, createEndpoint } from '@vercel/commerce/api'
|
import { GetAPISchema, createEndpoint } from '@vercel/commerce/api'
|
||||||
import customerEndpoint from '@vercel/commerce/api/endpoints/customer'
|
import customerEndpoint from '@vercel/commerce/api/endpoints/customer'
|
||||||
import type { CustomerSchema } from '../../../types/customer'
|
import type { CustomerSchema } from '@vercel/commerce/types/customer'
|
||||||
import type { BigcommerceAPI } from '../..'
|
import type { BigcommerceAPI } from '../..'
|
||||||
import getLoggedInCustomer from './get-logged-in-customer'
|
import getLoggedInCustomer from './get-logged-in-customer'
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { GetAPISchema, createEndpoint } from '@vercel/commerce/api'
|
import { GetAPISchema, createEndpoint } from '@vercel/commerce/api'
|
||||||
import loginEndpoint from '@vercel/commerce/api/endpoints/login'
|
import loginEndpoint from '@vercel/commerce/api/endpoints/login'
|
||||||
import type { LoginSchema } from '../../../types/login'
|
import type { LoginSchema } from '@vercel/commerce/types/login'
|
||||||
import type { BigcommerceAPI } from '../..'
|
import type { BigcommerceAPI } from '../..'
|
||||||
import login from './login'
|
import login from './login'
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { GetAPISchema, createEndpoint } from '@vercel/commerce/api'
|
import { GetAPISchema, createEndpoint } from '@vercel/commerce/api'
|
||||||
import logoutEndpoint from '@vercel/commerce/api/endpoints/logout'
|
import logoutEndpoint from '@vercel/commerce/api/endpoints/logout'
|
||||||
import type { LogoutSchema } from '../../../types/logout'
|
import type { LogoutSchema } from '@vercel/commerce/types/logout'
|
||||||
import type { BigcommerceAPI } from '../..'
|
import type { BigcommerceAPI } from '../..'
|
||||||
import logout from './logout'
|
import logout from './logout'
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { GetAPISchema, createEndpoint } from '@vercel/commerce/api'
|
import { GetAPISchema, createEndpoint } from '@vercel/commerce/api'
|
||||||
import signupEndpoint from '@vercel/commerce/api/endpoints/signup'
|
import signupEndpoint from '@vercel/commerce/api/endpoints/signup'
|
||||||
import type { SignupSchema } from '../../../types/signup'
|
import type { SignupSchema } from '@vercel/commerce/types/signup'
|
||||||
import type { BigcommerceAPI } from '../..'
|
import type { BigcommerceAPI } from '../..'
|
||||||
import signup from './signup'
|
import signup from './signup'
|
||||||
|
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import type { Wishlist } from '../../../types/wishlist'
|
import type { Wishlist } from '@vercel/commerce/types/wishlist'
|
||||||
import type { WishlistEndpoint } from '.'
|
import type { WishlistEndpoint } from '.'
|
||||||
import getCustomerId from '../../utils/get-customer-id'
|
import getCustomerId from '../../utils/get-customer-id'
|
||||||
import getCustomerWishlist from '../../operations/get-customer-wishlist'
|
|
||||||
|
|
||||||
// Return wishlist info
|
// Return wishlist info
|
||||||
const getWishlist: WishlistEndpoint['handlers']['getWishlist'] = async ({
|
const getWishlist: WishlistEndpoint['handlers']['getWishlist'] = async ({
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { GetAPISchema, createEndpoint } from '@vercel/commerce/api'
|
import { GetAPISchema, createEndpoint } from '@vercel/commerce/api'
|
||||||
import wishlistEndpoint from '@vercel/commerce/api/endpoints/wishlist'
|
import wishlistEndpoint from '@vercel/commerce/api/endpoints/wishlist'
|
||||||
import type { WishlistSchema } from '../../../types/wishlist'
|
import type { WishlistSchema } from '@vercel/commerce/types/wishlist'
|
||||||
import type { BigcommerceAPI } from '../..'
|
import type { BigcommerceAPI } from '../..'
|
||||||
import getWishlist from './get-wishlist'
|
import getWishlist from './get-wishlist'
|
||||||
import addItem from './add-item'
|
import addItem from './add-item'
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
import type { Wishlist } from '../../../types/wishlist'
|
import type { Wishlist } from '@vercel/commerce/types/wishlist'
|
||||||
import getCustomerWishlist from '../../operations/get-customer-wishlist'
|
|
||||||
import getCustomerId from '../../utils/get-customer-id'
|
import getCustomerId from '../../utils/get-customer-id'
|
||||||
import type { WishlistEndpoint } from '.'
|
import type { WishlistEndpoint } from '.'
|
||||||
|
|
||||||
|
@ -2,10 +2,13 @@ import type {
|
|||||||
OperationContext,
|
OperationContext,
|
||||||
OperationOptions,
|
OperationOptions,
|
||||||
} from '@vercel/commerce/api/operations'
|
} from '@vercel/commerce/api/operations'
|
||||||
import type { Page, GetAllPagesOperation } from '../../types/page'
|
import type { GetAllPagesOperation } from '@vercel/commerce/types/page'
|
||||||
import type { RecursivePartial, RecursiveRequired } from '../utils/types'
|
import type { RecursivePartial, RecursiveRequired } from '../utils/types'
|
||||||
import { BigcommerceConfig, Provider } from '..'
|
import { BigcommerceConfig, Provider } from '..'
|
||||||
|
|
||||||
|
import { definitions } from '../definitions/store-content'
|
||||||
|
import { normalizePage } from '../../lib/normalize'
|
||||||
|
|
||||||
export default function getAllPagesOperation({
|
export default function getAllPagesOperation({
|
||||||
commerce,
|
commerce,
|
||||||
}: OperationContext<Provider>) {
|
}: OperationContext<Provider>) {
|
||||||
@ -33,12 +36,14 @@ export default function getAllPagesOperation({
|
|||||||
// RecursivePartial forces the method to check for every prop in the data, which is
|
// RecursivePartial forces the method to check for every prop in the data, which is
|
||||||
// required in case there's a custom `url`
|
// required in case there's a custom `url`
|
||||||
const { data } = await cfg.storeApiFetch<
|
const { data } = await cfg.storeApiFetch<
|
||||||
RecursivePartial<{ data: Page[] }>
|
RecursivePartial<{ data: definitions['page_Full'][] }>
|
||||||
>('/v3/content/pages')
|
>('/v3/content/pages')
|
||||||
const pages = (data as RecursiveRequired<typeof data>) ?? []
|
const pages = (data as RecursiveRequired<typeof data>) ?? []
|
||||||
|
|
||||||
return {
|
return {
|
||||||
pages: preview ? pages : pages.filter((p) => p.is_visible),
|
pages: preview
|
||||||
|
? pages.map(normalizePage)
|
||||||
|
: pages.filter((p) => p.is_visible).map(normalizePage),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@ import type {
|
|||||||
OperationOptions,
|
OperationOptions,
|
||||||
} from '@vercel/commerce/api/operations'
|
} from '@vercel/commerce/api/operations'
|
||||||
import type { GetAllProductPathsQuery } from '../../../schema'
|
import type { GetAllProductPathsQuery } from '../../../schema'
|
||||||
import type { GetAllProductPathsOperation } from '../../types/product'
|
import type { GetAllProductPathsOperation } from '@vercel/commerce/types/product'
|
||||||
import type { RecursivePartial, RecursiveRequired } from '../utils/types'
|
import type { RecursivePartial, RecursiveRequired } from '../utils/types'
|
||||||
import filterEdges from '../utils/filter-edges'
|
import filterEdges from '../utils/filter-edges'
|
||||||
import { BigcommerceConfig, Provider } from '..'
|
import { BigcommerceConfig, Provider } from '..'
|
||||||
|
@ -6,7 +6,7 @@ import type {
|
|||||||
GetAllProductsQuery,
|
GetAllProductsQuery,
|
||||||
GetAllProductsQueryVariables,
|
GetAllProductsQueryVariables,
|
||||||
} from '../../../schema'
|
} from '../../../schema'
|
||||||
import type { GetAllProductsOperation } from '../../types/product'
|
import type { GetAllProductsOperation } from '@vercel/commerce/types/product'
|
||||||
import type { RecursivePartial, RecursiveRequired } from '../utils/types'
|
import type { RecursivePartial, RecursiveRequired } from '../utils/types'
|
||||||
import filterEdges from '../utils/filter-edges'
|
import filterEdges from '../utils/filter-edges'
|
||||||
import setProductLocaleMeta from '../utils/set-product-locale-meta'
|
import setProductLocaleMeta from '../utils/set-product-locale-meta'
|
||||||
|
@ -5,7 +5,7 @@ import type {
|
|||||||
import type {
|
import type {
|
||||||
GetCustomerWishlistOperation,
|
GetCustomerWishlistOperation,
|
||||||
Wishlist,
|
Wishlist,
|
||||||
} from '../../types/wishlist'
|
} from '@vercel/commerce/types/wishlist'
|
||||||
import type { RecursivePartial, RecursiveRequired } from '../utils/types'
|
import type { RecursivePartial, RecursiveRequired } from '../utils/types'
|
||||||
import { BigcommerceConfig, Provider } from '..'
|
import { BigcommerceConfig, Provider } from '..'
|
||||||
import getAllProducts, { ProductEdge } from './get-all-products'
|
import getAllProducts, { ProductEdge } from './get-all-products'
|
||||||
@ -49,7 +49,7 @@ export default function getCustomerWishlistOperation({
|
|||||||
|
|
||||||
if (includeProducts && wishlist?.items?.length) {
|
if (includeProducts && wishlist?.items?.length) {
|
||||||
const ids = wishlist.items
|
const ids = wishlist.items
|
||||||
?.map((item) => (item?.product_id ? String(item?.product_id) : null))
|
?.map((item) => (item?.productId ? String(item?.productId) : null))
|
||||||
.filter((id): id is string => !!id)
|
.filter((id): id is string => !!id)
|
||||||
|
|
||||||
if (ids?.length) {
|
if (ids?.length) {
|
||||||
@ -66,7 +66,7 @@ export default function getCustomerWishlistOperation({
|
|||||||
}, {})
|
}, {})
|
||||||
// Populate the wishlist items with the graphql products
|
// Populate the wishlist items with the graphql products
|
||||||
wishlist.items.forEach((item) => {
|
wishlist.items.forEach((item) => {
|
||||||
const product = item && productsById[item.product_id!]
|
const product = item && productsById[Number(item.productId)]
|
||||||
if (item && product) {
|
if (item && product) {
|
||||||
// @ts-ignore Fix this type when the wishlist type is properly defined
|
// @ts-ignore Fix this type when the wishlist type is properly defined
|
||||||
item.product = product
|
item.product = product
|
||||||
|
@ -2,7 +2,7 @@ import type {
|
|||||||
OperationContext,
|
OperationContext,
|
||||||
OperationOptions,
|
OperationOptions,
|
||||||
} from '@vercel/commerce/api/operations'
|
} from '@vercel/commerce/api/operations'
|
||||||
import type { GetPageOperation, Page } from '../../types/page'
|
import type { GetPageOperation, Page } from '@vercel/commerce/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'
|
import { normalizePage } from '../../lib/normalize'
|
||||||
|
@ -2,7 +2,7 @@ import type {
|
|||||||
OperationContext,
|
OperationContext,
|
||||||
OperationOptions,
|
OperationOptions,
|
||||||
} from '@vercel/commerce/api/operations'
|
} from '@vercel/commerce/api/operations'
|
||||||
import type { GetProductOperation } from '../../types/product'
|
import type { GetProductOperation } from '@vercel/commerce/types/product'
|
||||||
import type { GetProductQuery, GetProductQueryVariables } from '../../../schema'
|
import type { GetProductQuery, GetProductQueryVariables } from '../../../schema'
|
||||||
import setProductLocaleMeta from '../utils/set-product-locale-meta'
|
import setProductLocaleMeta from '../utils/set-product-locale-meta'
|
||||||
import { productInfoFragment } from '../fragments/product'
|
import { productInfoFragment } from '../fragments/product'
|
||||||
@ -100,7 +100,7 @@ export default function getAllProductPathsOperation({
|
|||||||
const variables: GetProductQueryVariables = {
|
const variables: GetProductQueryVariables = {
|
||||||
locale,
|
locale,
|
||||||
hasLocale: !!locale,
|
hasLocale: !!locale,
|
||||||
path: slug ? `/${slug}/` : vars.path!,
|
path: slug ? `/${slug}` : vars.path!,
|
||||||
}
|
}
|
||||||
const { data } = await config.fetch<GetProductQuery>(query, { variables })
|
const { data } = await config.fetch<GetProductQuery>(query, { variables })
|
||||||
const product = data.site?.route?.node
|
const product = data.site?.route?.node
|
||||||
|
@ -2,12 +2,12 @@ import type {
|
|||||||
OperationContext,
|
OperationContext,
|
||||||
OperationOptions,
|
OperationOptions,
|
||||||
} from '@vercel/commerce/api/operations'
|
} from '@vercel/commerce/api/operations'
|
||||||
import type { GetSiteInfoOperation } from '../../types/site'
|
import type { GetSiteInfoOperation } from '@vercel/commerce/types/site'
|
||||||
import type { GetSiteInfoQuery } from '../../../schema'
|
import type { GetSiteInfoQuery } from '../../../schema'
|
||||||
import filterEdges from '../utils/filter-edges'
|
import filterEdges from '../utils/filter-edges'
|
||||||
import type { BigcommerceConfig, Provider } from '..'
|
import type { BigcommerceConfig, Provider } from '..'
|
||||||
import { categoryTreeItemFragment } from '../fragments/category-tree'
|
import { categoryTreeItemFragment } from '../fragments/category-tree'
|
||||||
import { normalizeCategory } from '../../lib/normalize'
|
import { normalizeBrand, normalizeCategory } from '../../lib/normalize'
|
||||||
|
|
||||||
// Get 3 levels of categories
|
// Get 3 levels of categories
|
||||||
export const getSiteInfoQuery = /* GraphQL */ `
|
export const getSiteInfoQuery = /* GraphQL */ `
|
||||||
@ -79,7 +79,7 @@ export default function getSiteInfoOperation({
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
categories: categories ?? [],
|
categories: categories ?? [],
|
||||||
brands: filterEdges(brands),
|
brands: filterEdges(brands).map(normalizeBrand),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@ import type {
|
|||||||
OperationContext,
|
OperationContext,
|
||||||
OperationOptions,
|
OperationOptions,
|
||||||
} from '@vercel/commerce/api/operations'
|
} from '@vercel/commerce/api/operations'
|
||||||
import type { LoginOperation } from '../../types/login'
|
import type { LoginOperation } from '@vercel/commerce/types/login'
|
||||||
import type { LoginMutation } from '../../../schema'
|
import type { LoginMutation } from '../../../schema'
|
||||||
import type { RecursivePartial } from '../utils/types'
|
import type { RecursivePartial } from '../utils/types'
|
||||||
import concatHeader from '../utils/concat-cookie'
|
import concatHeader from '../utils/concat-cookie'
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import type { WishlistItemBody } from '../../types/wishlist'
|
import type { WishlistItemBody } from '@vercel/commerce/types/wishlist'
|
||||||
import type { CartItemBody, OptionSelections } from '../../types/cart'
|
import type { CartItemBody, SelectedOption } from '@vercel/commerce/types/cart'
|
||||||
|
|
||||||
type BCWishlistItemBody = {
|
type BCWishlistItemBody = {
|
||||||
product_id: number
|
product_id: number
|
||||||
@ -10,7 +10,7 @@ type BCCartItemBody = {
|
|||||||
product_id: number
|
product_id: number
|
||||||
variant_id: number
|
variant_id: number
|
||||||
quantity?: number
|
quantity?: number
|
||||||
option_selections?: OptionSelections[]
|
option_selections?: SelectedOption[]
|
||||||
}
|
}
|
||||||
|
|
||||||
export const parseWishlistItem = (
|
export const parseWishlistItem = (
|
||||||
@ -24,5 +24,5 @@ export const parseCartItem = (item: CartItemBody): BCCartItemBody => ({
|
|||||||
quantity: item.quantity,
|
quantity: item.quantity,
|
||||||
product_id: Number(item.productId),
|
product_id: Number(item.productId),
|
||||||
variant_id: Number(item.variantId),
|
variant_id: Number(item.variantId),
|
||||||
option_selections: item.optionSelections,
|
option_selections: item.optionsSelected,
|
||||||
})
|
})
|
||||||
|
@ -2,7 +2,7 @@ import { useCallback } from 'react'
|
|||||||
import type { MutationHook } from '@vercel/commerce/utils/types'
|
import type { MutationHook } from '@vercel/commerce/utils/types'
|
||||||
import { CommerceError } from '@vercel/commerce/utils/errors'
|
import { CommerceError } from '@vercel/commerce/utils/errors'
|
||||||
import useLogin, { UseLogin } from '@vercel/commerce/auth/use-login'
|
import useLogin, { UseLogin } from '@vercel/commerce/auth/use-login'
|
||||||
import type { LoginHook } from '../types/login'
|
import type { LoginHook } from '@vercel/commerce/types/login'
|
||||||
import useCustomer from '../customer/use-customer'
|
import useCustomer from '../customer/use-customer'
|
||||||
|
|
||||||
export default useLogin as UseLogin<typeof handler>
|
export default useLogin as UseLogin<typeof handler>
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { useCallback } from 'react'
|
import { useCallback } from 'react'
|
||||||
import type { MutationHook } from '@vercel/commerce/utils/types'
|
import type { MutationHook } from '@vercel/commerce/utils/types'
|
||||||
import useLogout, { UseLogout } from '@vercel/commerce/auth/use-logout'
|
import useLogout, { UseLogout } from '@vercel/commerce/auth/use-logout'
|
||||||
import type { LogoutHook } from '../types/logout'
|
import type { LogoutHook } from '@vercel/commerce/types/logout'
|
||||||
import useCustomer from '../customer/use-customer'
|
import useCustomer from '../customer/use-customer'
|
||||||
|
|
||||||
export default useLogout as UseLogout<typeof handler>
|
export default useLogout as UseLogout<typeof handler>
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
import { useCallback } from 'react'
|
import { useCallback } from 'react'
|
||||||
import type { MutationHook } from '@vercel/commerce/utils/types'
|
import type { MutationHook } from '@vercel/commerce/utils/types'
|
||||||
import { CommerceError } from '@vercel/commerce/utils/errors'
|
import { CommerceError } from '@vercel/commerce/utils/errors'
|
||||||
import useSignup, { UseSignup } from '@vercel/commerce/auth/use-signup'
|
import useSignup, { type UseSignup } from '@vercel/commerce/auth/use-signup'
|
||||||
import type { SignupHook } from '../types/signup'
|
import type { SignupHook } from '@vercel/commerce/types/signup'
|
||||||
import useCustomer from '../customer/use-customer'
|
import useCustomer from '../customer/use-customer'
|
||||||
|
|
||||||
export default useSignup as UseSignup<typeof handler>
|
export default useSignup as UseSignup<typeof handler>
|
||||||
|
@ -4,8 +4,14 @@ import type {
|
|||||||
HookFetcherContext,
|
HookFetcherContext,
|
||||||
} from '@vercel/commerce/utils/types'
|
} from '@vercel/commerce/utils/types'
|
||||||
import { ValidationError } from '@vercel/commerce/utils/errors'
|
import { ValidationError } from '@vercel/commerce/utils/errors'
|
||||||
import useRemoveItem, { UseRemoveItem } from '@vercel/commerce/cart/use-remove-item'
|
import useRemoveItem, {
|
||||||
import type { Cart, LineItem, RemoveItemHook } from '@vercel/commerce/types/cart'
|
UseRemoveItem,
|
||||||
|
} from '@vercel/commerce/cart/use-remove-item'
|
||||||
|
import type {
|
||||||
|
Cart,
|
||||||
|
LineItem,
|
||||||
|
RemoveItemHook,
|
||||||
|
} from '@vercel/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
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
import { SWRHook } from '@vercel/commerce/utils/types'
|
import type { SWRHook } from '@vercel/commerce/utils/types'
|
||||||
import useCustomer, { UseCustomer } from '@vercel/commerce/customer/use-customer'
|
import useCustomer, {
|
||||||
import type { CustomerHook } from '../types/customer'
|
type UseCustomer,
|
||||||
|
} from '@vercel/commerce/customer/use-customer'
|
||||||
|
import type { CustomerHook } from '@vercel/commerce/types/customer'
|
||||||
|
|
||||||
export default useCustomer as UseCustomer<typeof handler>
|
export default useCustomer as UseCustomer<typeof handler>
|
||||||
|
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
import type { Product } from '../types/product'
|
import type { Page } from '@vercel/commerce/types/page'
|
||||||
import type { Cart, BigcommerceCart, LineItem } from '../types/cart'
|
import type { Product } from '@vercel/commerce/types/product'
|
||||||
import type { Page } from '../types/page'
|
import type { Cart, LineItem } from '@vercel/commerce/types/cart'
|
||||||
import type { BCCategory, Category } from '../types/site'
|
import type { Category, Brand } from '@vercel/commerce/types/site'
|
||||||
|
import type { BigcommerceCart, BCCategory, BCBrand } from '../types'
|
||||||
|
|
||||||
import { definitions } from '../api/definitions/store-content'
|
import { definitions } from '../api/definitions/store-content'
|
||||||
import update from './immutability'
|
import update from './immutability'
|
||||||
import getSlug from './get-slug'
|
import getSlug from './get-slug'
|
||||||
@ -12,7 +14,7 @@ function normalizeProductOption(productOption: any) {
|
|||||||
} = productOption
|
} = productOption
|
||||||
|
|
||||||
return {
|
return {
|
||||||
id: entityId,
|
id: String(entityId),
|
||||||
values: edges?.map(({ node }: any) => node),
|
values: edges?.map(({ node }: any) => node),
|
||||||
...rest,
|
...rest,
|
||||||
}
|
}
|
||||||
@ -41,7 +43,7 @@ export function normalizeProduct(productNode: any): Product {
|
|||||||
variants: {
|
variants: {
|
||||||
$apply: ({ edges }: any) =>
|
$apply: ({ edges }: any) =>
|
||||||
edges?.map(({ node: { entityId, productOptions, ...rest } }: any) => ({
|
edges?.map(({ node: { entityId, productOptions, ...rest } }: any) => ({
|
||||||
id: entityId,
|
id: String(entityId),
|
||||||
options: productOptions?.edges
|
options: productOptions?.edges
|
||||||
? productOptions.edges.map(normalizeProductOption)
|
? productOptions.edges.map(normalizeProductOption)
|
||||||
: [],
|
: [],
|
||||||
@ -54,7 +56,7 @@ export function normalizeProduct(productNode: any): Product {
|
|||||||
: [],
|
: [],
|
||||||
},
|
},
|
||||||
brand: {
|
brand: {
|
||||||
$apply: (brand: any) => (brand?.entityId ? brand?.entityId : null),
|
$apply: (brand: any) => (brand?.id ? brand.id : null),
|
||||||
},
|
},
|
||||||
slug: {
|
slug: {
|
||||||
$set: path?.replace(/^\/+|\/+$/g, ''),
|
$set: path?.replace(/^\/+|\/+$/g, ''),
|
||||||
@ -75,7 +77,8 @@ export function normalizePage(page: definitions['page_Full']): Page {
|
|||||||
name: page.name,
|
name: page.name,
|
||||||
is_visible: page.is_visible,
|
is_visible: page.is_visible,
|
||||||
sort_order: page.sort_order,
|
sort_order: page.sort_order,
|
||||||
body: page.body,
|
body: page.body ?? '',
|
||||||
|
url: page.url,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -134,3 +137,12 @@ export function normalizeCategory(category: BCCategory): Category {
|
|||||||
path: category.path,
|
path: category.path,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function normalizeBrand(brand: BCBrand): Brand {
|
||||||
|
return {
|
||||||
|
id: `${brand.node.entityId}`,
|
||||||
|
name: brand.node.name,
|
||||||
|
slug: getSlug(brand.node.path),
|
||||||
|
path: brand.node.path,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { SWRHook } from '@vercel/commerce/utils/types'
|
import { SWRHook } from '@vercel/commerce/utils/types'
|
||||||
import useSearch, { UseSearch } from '@vercel/commerce/product/use-search'
|
import useSearch, { UseSearch } from '@vercel/commerce/product/use-search'
|
||||||
import type { SearchProductsHook } from '../types/product'
|
import type { SearchProductsHook } from '@vercel/commerce/types/product'
|
||||||
|
|
||||||
export default useSearch as UseSearch<typeof handler>
|
export default useSearch as UseSearch<typeof handler>
|
||||||
|
|
||||||
|
32
packages/bigcommerce/src/types.ts
Normal file
32
packages/bigcommerce/src/types.ts
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
import type { GetSiteInfoQuery } from '../schema'
|
||||||
|
|
||||||
|
export type BCCategory = NonNullable<
|
||||||
|
GetSiteInfoQuery['site']['categoryTree']
|
||||||
|
>[0]
|
||||||
|
|
||||||
|
export type BCBrand = NonNullable<
|
||||||
|
NonNullable<GetSiteInfoQuery['site']['brands']['edges']>[0]
|
||||||
|
>
|
||||||
|
|
||||||
|
// TODO: this type should match:
|
||||||
|
// https://developer.bigcommerce.com/api-reference/cart-checkout/server-server-cart-api/cart/getacart#responses
|
||||||
|
export type BigcommerceCart = {
|
||||||
|
id: string
|
||||||
|
parent_id?: string
|
||||||
|
customer_id: number
|
||||||
|
email: string
|
||||||
|
currency: { code: string }
|
||||||
|
tax_included: boolean
|
||||||
|
base_amount: number
|
||||||
|
discount_amount: number
|
||||||
|
cart_amount: number
|
||||||
|
line_items: {
|
||||||
|
custom_items: any[]
|
||||||
|
digital_items: any[]
|
||||||
|
gift_certificates: any[]
|
||||||
|
physical_items: any[]
|
||||||
|
}
|
||||||
|
created_time: string
|
||||||
|
discounts?: { id: number; discounted_amount: number }[]
|
||||||
|
// TODO: add missing fields
|
||||||
|
}
|
@ -1,66 +0,0 @@
|
|||||||
import * as Core from '@vercel/commerce/types/cart'
|
|
||||||
|
|
||||||
export * from '@vercel/commerce/types/cart'
|
|
||||||
|
|
||||||
// TODO: this type should match:
|
|
||||||
// https://developer.bigcommerce.com/api-reference/cart-checkout/server-server-cart-api/cart/getacart#responses
|
|
||||||
export type BigcommerceCart = {
|
|
||||||
id: string
|
|
||||||
parent_id?: string
|
|
||||||
customer_id: number
|
|
||||||
email: string
|
|
||||||
currency: { code: string }
|
|
||||||
tax_included: boolean
|
|
||||||
base_amount: number
|
|
||||||
discount_amount: number
|
|
||||||
cart_amount: number
|
|
||||||
line_items: {
|
|
||||||
custom_items: any[]
|
|
||||||
digital_items: any[]
|
|
||||||
gift_certificates: any[]
|
|
||||||
physical_items: any[]
|
|
||||||
}
|
|
||||||
created_time: string
|
|
||||||
discounts?: { id: number; discounted_amount: number }[]
|
|
||||||
// TODO: add missing fields
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Extend core cart types
|
|
||||||
*/
|
|
||||||
|
|
||||||
export type Cart = Core.Cart & {
|
|
||||||
lineItems: Core.LineItem[]
|
|
||||||
}
|
|
||||||
|
|
||||||
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 CartTypes = {
|
|
||||||
cart: Cart
|
|
||||||
item: Core.LineItem
|
|
||||||
itemBody: CartItemBody
|
|
||||||
}
|
|
||||||
|
|
||||||
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']
|
|
@ -1 +0,0 @@
|
|||||||
export * from '@vercel/commerce/types/checkout'
|
|
@ -1 +0,0 @@
|
|||||||
export * from '@vercel/commerce/types/common'
|
|
@ -1,5 +0,0 @@
|
|||||||
import * as Core from '@vercel/commerce/types/customer'
|
|
||||||
|
|
||||||
export * from '@vercel/commerce/types/customer'
|
|
||||||
|
|
||||||
export type CustomerSchema = Core.CustomerSchema
|
|
@ -1,25 +0,0 @@
|
|||||||
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,
|
|
||||||
}
|
|
@ -1,8 +0,0 @@
|
|||||||
import * as Core from '@vercel/commerce/types/login'
|
|
||||||
import type { LoginMutationVariables } from '../../schema'
|
|
||||||
|
|
||||||
export * from '@vercel/commerce/types/login'
|
|
||||||
|
|
||||||
export type LoginOperation = Core.LoginOperation & {
|
|
||||||
variables: LoginMutationVariables
|
|
||||||
}
|
|
@ -1 +0,0 @@
|
|||||||
export * from '@vercel/commerce/types/logout'
|
|
@ -1,11 +0,0 @@
|
|||||||
import * as Core from '@vercel/commerce/types/page'
|
|
||||||
export * from '@vercel/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>
|
|
@ -1 +0,0 @@
|
|||||||
export * from '@vercel/commerce/types/product'
|
|
@ -1 +0,0 @@
|
|||||||
export * from '@vercel/commerce/types/signup'
|
|
@ -1,19 +0,0 @@
|
|||||||
import * as Core from '@vercel/commerce/types/site'
|
|
||||||
import type { GetSiteInfoQuery, GetSiteInfoQueryVariables } from '../../schema'
|
|
||||||
|
|
||||||
export * from '@vercel/commerce/types/site'
|
|
||||||
|
|
||||||
export type BCCategory = NonNullable<
|
|
||||||
GetSiteInfoQuery['site']['categoryTree']
|
|
||||||
>[0]
|
|
||||||
|
|
||||||
export type Brand = NonNullable<
|
|
||||||
NonNullable<GetSiteInfoQuery['site']['brands']['edges']>[0]
|
|
||||||
>
|
|
||||||
|
|
||||||
export type SiteTypes = {
|
|
||||||
category: Core.Category
|
|
||||||
brand: Brand
|
|
||||||
}
|
|
||||||
|
|
||||||
export type GetSiteInfoOperation = Core.GetSiteInfoOperation<SiteTypes>
|
|
@ -1,24 +0,0 @@
|
|||||||
import * as Core from '@vercel/commerce/types/wishlist'
|
|
||||||
import { definitions } from '../api/definitions/wishlist'
|
|
||||||
import type { ProductEdge } from '../api/operations/get-all-products'
|
|
||||||
|
|
||||||
export * from '@vercel/commerce/types/wishlist'
|
|
||||||
|
|
||||||
export type WishlistItem = NonNullable<
|
|
||||||
definitions['wishlist_Full']['items']
|
|
||||||
>[0] & {
|
|
||||||
product?: ProductEdge['node']
|
|
||||||
}
|
|
||||||
|
|
||||||
export type Wishlist = Omit<definitions['wishlist_Full'], 'items'> & {
|
|
||||||
items?: WishlistItem[]
|
|
||||||
}
|
|
||||||
|
|
||||||
export type WishlistTypes = {
|
|
||||||
wishlist: Wishlist
|
|
||||||
itemBody: Core.WishlistItemBody
|
|
||||||
}
|
|
||||||
|
|
||||||
export type WishlistSchema = Core.WishlistSchema<WishlistTypes>
|
|
||||||
export type GetCustomerWishlistOperation =
|
|
||||||
Core.GetCustomerWishlistOperation<WishlistTypes>
|
|
@ -1,8 +1,10 @@
|
|||||||
import { useCallback } from 'react'
|
import { useCallback } from 'react'
|
||||||
import type { MutationHook } from '@vercel/commerce/utils/types'
|
import type { MutationHook } from '@vercel/commerce/utils/types'
|
||||||
import { CommerceError } from '@vercel/commerce/utils/errors'
|
import { CommerceError } from '@vercel/commerce/utils/errors'
|
||||||
import useAddItem, { UseAddItem } from '@vercel/commerce/wishlist/use-add-item'
|
import useAddItem, {
|
||||||
import type { AddItemHook } from '../types/wishlist'
|
type UseAddItem,
|
||||||
|
} from '@vercel/commerce/wishlist/use-add-item'
|
||||||
|
import type { AddItemHook } from '@vercel/commerce/types/wishlist'
|
||||||
import useCustomer from '../customer/use-customer'
|
import useCustomer from '../customer/use-customer'
|
||||||
import useWishlist from './use-wishlist'
|
import useWishlist from './use-wishlist'
|
||||||
|
|
||||||
|
@ -2,9 +2,9 @@ import { useCallback } from 'react'
|
|||||||
import type { MutationHook } from '@vercel/commerce/utils/types'
|
import type { MutationHook } from '@vercel/commerce/utils/types'
|
||||||
import { CommerceError } from '@vercel/commerce/utils/errors'
|
import { CommerceError } from '@vercel/commerce/utils/errors'
|
||||||
import useRemoveItem, {
|
import useRemoveItem, {
|
||||||
UseRemoveItem,
|
type UseRemoveItem,
|
||||||
} from '@vercel/commerce/wishlist/use-remove-item'
|
} from '@vercel/commerce/wishlist/use-remove-item'
|
||||||
import type { RemoveItemHook } from '../types/wishlist'
|
import type { RemoveItemHook } from '@vercel/commerce/types/wishlist'
|
||||||
import useCustomer from '../customer/use-customer'
|
import useCustomer from '../customer/use-customer'
|
||||||
import useWishlist from './use-wishlist'
|
import useWishlist from './use-wishlist'
|
||||||
|
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
import { useMemo } from 'react'
|
import { useMemo } from 'react'
|
||||||
import { SWRHook } from '@vercel/commerce/utils/types'
|
import { SWRHook } from '@vercel/commerce/utils/types'
|
||||||
import useWishlist, {
|
import useWishlist, {
|
||||||
UseWishlist,
|
type UseWishlist,
|
||||||
} from '@vercel/commerce/wishlist/use-wishlist'
|
} from '@vercel/commerce/wishlist/use-wishlist'
|
||||||
import useCustomer from '../customer/use-customer'
|
import useCustomer from '../customer/use-customer'
|
||||||
|
|
||||||
import type { GetWishlistHook } from '../types/wishlist'
|
import type { GetWishlistHook } from '@vercel/commerce/types/wishlist'
|
||||||
|
|
||||||
export default useWishlist as UseWishlist<typeof handler>
|
export default useWishlist as UseWishlist<typeof handler>
|
||||||
export const handler: SWRHook<GetWishlistHook> = {
|
export const handler: SWRHook<GetWishlistHook> = {
|
||||||
@ -32,7 +32,7 @@ export const handler: SWRHook<GetWishlistHook> = {
|
|||||||
const { data: customer } = useCustomer()
|
const { data: customer } = useCustomer()
|
||||||
const response = useData({
|
const response = useData({
|
||||||
input: [
|
input: [
|
||||||
['customerId', customer?.entityId],
|
['customerId', customer?.id],
|
||||||
['includeProducts', input?.includeProducts],
|
['includeProducts', input?.includeProducts],
|
||||||
],
|
],
|
||||||
swrOptions: {
|
swrOptions: {
|
||||||
|
@ -52,7 +52,8 @@
|
|||||||
"import-cwd": "^3.0.0",
|
"import-cwd": "^3.0.0",
|
||||||
"js-cookie": "^3.0.1",
|
"js-cookie": "^3.0.1",
|
||||||
"swr": "^1.3.0",
|
"swr": "^1.3.0",
|
||||||
"node-fetch": "^2.6.7"
|
"node-fetch": "^2.6.7",
|
||||||
|
"zod": "^3.19.0"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"next": "^12",
|
"next": "^12",
|
||||||
|
@ -3,58 +3,60 @@ import { CommerceAPIError } from '../utils/errors'
|
|||||||
import isAllowedOperation from '../utils/is-allowed-operation'
|
import isAllowedOperation from '../utils/is-allowed-operation'
|
||||||
import type { GetAPISchema } from '..'
|
import type { GetAPISchema } from '..'
|
||||||
|
|
||||||
const cartEndpoint: GetAPISchema<any, CartSchema<any>>['endpoint']['handler'] =
|
const cartEndpoint: GetAPISchema<
|
||||||
async (ctx) => {
|
any,
|
||||||
const { req, res, handlers, config } = ctx
|
CartSchema
|
||||||
|
>['endpoint']['handler'] = async (ctx) => {
|
||||||
|
const { req, res, handlers, config } = ctx
|
||||||
|
|
||||||
if (
|
if (
|
||||||
!isAllowedOperation(req, res, {
|
!isAllowedOperation(req, res, {
|
||||||
GET: handlers['getCart'],
|
GET: handlers['getCart'],
|
||||||
POST: handlers['addItem'],
|
POST: handlers['addItem'],
|
||||||
PUT: handlers['updateItem'],
|
PUT: handlers['updateItem'],
|
||||||
DELETE: handlers['removeItem'],
|
DELETE: handlers['removeItem'],
|
||||||
})
|
})
|
||||||
) {
|
) {
|
||||||
return
|
return
|
||||||
}
|
|
||||||
|
|
||||||
const { cookies } = req
|
|
||||||
const cartId = cookies[config.cartCookie]
|
|
||||||
|
|
||||||
try {
|
|
||||||
// Return current cart info
|
|
||||||
if (req.method === 'GET') {
|
|
||||||
const body = { cartId }
|
|
||||||
return await handlers['getCart']({ ...ctx, body })
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create or add an item to the cart
|
|
||||||
if (req.method === 'POST') {
|
|
||||||
const body = { ...req.body, cartId }
|
|
||||||
return await handlers['addItem']({ ...ctx, body })
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update item in cart
|
|
||||||
if (req.method === 'PUT') {
|
|
||||||
const body = { ...req.body, cartId }
|
|
||||||
return await handlers['updateItem']({ ...ctx, body })
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove an item from the cart
|
|
||||||
if (req.method === 'DELETE') {
|
|
||||||
const body = { ...req.body, cartId }
|
|
||||||
return await handlers['removeItem']({ ...ctx, body })
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error(error)
|
|
||||||
|
|
||||||
const message =
|
|
||||||
error instanceof CommerceAPIError
|
|
||||||
? 'An unexpected error ocurred with the Commerce API'
|
|
||||||
: 'An unexpected error ocurred'
|
|
||||||
|
|
||||||
res.status(500).json({ data: null, errors: [{ message }] })
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const { cookies } = req
|
||||||
|
const cartId = cookies[config.cartCookie]
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Return current cart info
|
||||||
|
if (req.method === 'GET') {
|
||||||
|
const body = { cartId }
|
||||||
|
return await handlers['getCart']({ ...ctx, body })
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create or add an item to the cart
|
||||||
|
if (req.method === 'POST') {
|
||||||
|
const body = { ...req.body, cartId }
|
||||||
|
return await handlers['addItem']({ ...ctx, body })
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update item in cart
|
||||||
|
if (req.method === 'PUT') {
|
||||||
|
const body = { ...req.body, cartId }
|
||||||
|
return await handlers['updateItem']({ ...ctx, body })
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove an item from the cart
|
||||||
|
if (req.method === 'DELETE') {
|
||||||
|
const body = { ...req.body, cartId }
|
||||||
|
return await handlers['removeItem']({ ...ctx, body })
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error)
|
||||||
|
|
||||||
|
const message =
|
||||||
|
error instanceof CommerceAPIError
|
||||||
|
? 'An unexpected error ocurred with the Commerce API'
|
||||||
|
: 'An unexpected error ocurred'
|
||||||
|
|
||||||
|
res.status(500).json({ data: null, errors: [{ message }] })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export default cartEndpoint
|
export default cartEndpoint
|
||||||
|
@ -6,7 +6,7 @@ import isAllowedOperation from '../../utils/is-allowed-operation'
|
|||||||
|
|
||||||
const customerEndpoint: GetAPISchema<
|
const customerEndpoint: GetAPISchema<
|
||||||
any,
|
any,
|
||||||
CustomerSchema<any>
|
CustomerSchema
|
||||||
>['endpoint']['handler'] = async (ctx) => {
|
>['endpoint']['handler'] = async (ctx) => {
|
||||||
const { req, res, handlers } = ctx
|
const { req, res, handlers } = ctx
|
||||||
|
|
||||||
|
0
packages/commerce/src/api/endpoints/index.ts
Normal file
0
packages/commerce/src/api/endpoints/index.ts
Normal file
@ -5,7 +5,7 @@ import type { GetAPISchema } from '..'
|
|||||||
|
|
||||||
const loginEndpoint: GetAPISchema<
|
const loginEndpoint: GetAPISchema<
|
||||||
any,
|
any,
|
||||||
LoginSchema<any>
|
LoginSchema
|
||||||
>['endpoint']['handler'] = async (ctx) => {
|
>['endpoint']['handler'] = async (ctx) => {
|
||||||
const { req, res, handlers } = ctx
|
const { req, res, handlers } = ctx
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@ import type { GetAPISchema } from '..'
|
|||||||
|
|
||||||
const wishlistEndpoint: GetAPISchema<
|
const wishlistEndpoint: GetAPISchema<
|
||||||
any,
|
any,
|
||||||
WishlistSchema<any>
|
WishlistSchema
|
||||||
>['endpoint']['handler'] = async (ctx) => {
|
>['endpoint']['handler'] = async (ctx) => {
|
||||||
const { req, res, handlers, config } = ctx
|
const { req, res, handlers, config } = ctx
|
||||||
|
|
||||||
|
@ -11,11 +11,14 @@ import type { WishlistSchema } from '../types/wishlist'
|
|||||||
import type { CheckoutSchema } from '../types/checkout'
|
import type { CheckoutSchema } from '../types/checkout'
|
||||||
import type { CustomerCardSchema } from '../types/customer/card'
|
import type { CustomerCardSchema } from '../types/customer/card'
|
||||||
import type { CustomerAddressSchema } from '../types/customer/address'
|
import type { CustomerAddressSchema } from '../types/customer/address'
|
||||||
|
|
||||||
|
import { withOperationCallback } from './utils/with-operation-callback'
|
||||||
|
|
||||||
import {
|
import {
|
||||||
defaultOperations,
|
|
||||||
OPERATIONS,
|
OPERATIONS,
|
||||||
AllOperations,
|
AllOperations,
|
||||||
APIOperations,
|
APIOperations,
|
||||||
|
defaultOperations,
|
||||||
} from './operations'
|
} from './operations'
|
||||||
|
|
||||||
export type APISchemas =
|
export type APISchemas =
|
||||||
@ -106,7 +109,10 @@ export function getCommerceApi<P extends APIProvider>(
|
|||||||
OPERATIONS.forEach((k) => {
|
OPERATIONS.forEach((k) => {
|
||||||
const op = ops[k]
|
const op = ops[k]
|
||||||
if (op) {
|
if (op) {
|
||||||
commerce[k] = op({ commerce }) as AllOperations<P>[typeof k]
|
commerce[k] = withOperationCallback(
|
||||||
|
k,
|
||||||
|
op({ commerce })
|
||||||
|
) as AllOperations<P>[typeof k]
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -25,6 +25,13 @@ export const OPERATIONS = [
|
|||||||
'getProduct',
|
'getProduct',
|
||||||
] as const
|
] as const
|
||||||
|
|
||||||
|
export type Operation = {
|
||||||
|
[O in AllowedOperations]: {
|
||||||
|
name: O
|
||||||
|
data: Awaited<ReturnType<Operations<APIProvider>[O]>>
|
||||||
|
}
|
||||||
|
}[AllowedOperations]
|
||||||
|
|
||||||
export const defaultOperations = OPERATIONS.reduce((ops, k) => {
|
export const defaultOperations = OPERATIONS.reduce((ops, k) => {
|
||||||
ops[k] = noop
|
ops[k] = noop
|
||||||
return ops
|
return ops
|
||||||
|
@ -1,4 +1,7 @@
|
|||||||
|
import { ZodError } from 'zod'
|
||||||
|
|
||||||
import type { Response } from '@vercel/fetch'
|
import type { Response } from '@vercel/fetch'
|
||||||
|
import { CommerceError } from '../../utils/errors'
|
||||||
|
|
||||||
export class CommerceAPIError extends Error {
|
export class CommerceAPIError extends Error {
|
||||||
status: number
|
status: number
|
||||||
@ -20,3 +23,25 @@ export class CommerceNetworkError extends Error {
|
|||||||
this.name = 'CommerceNetworkError'
|
this.name = 'CommerceNetworkError'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const getOperationError = (operation: string, error: unknown) => {
|
||||||
|
if (error instanceof ZodError) {
|
||||||
|
return new CommerceError({
|
||||||
|
code: 'SCHEMA_VALIDATION_ERROR',
|
||||||
|
message:
|
||||||
|
`The ${operation} operation returned invalid data and has ${
|
||||||
|
error.issues.length
|
||||||
|
} parse ${error.issues.length === 1 ? 'error' : 'errors'}: \n` +
|
||||||
|
error.issues
|
||||||
|
.map(
|
||||||
|
(e, index) =>
|
||||||
|
`Error #${index + 1} ${
|
||||||
|
e.path.length > 0 ? `Path: ${e.path.join('.')}, ` : ''
|
||||||
|
}Code: ${e.code}, Message: ${e.message}`
|
||||||
|
)
|
||||||
|
.join('\n'),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return error
|
||||||
|
}
|
||||||
|
42
packages/commerce/src/api/utils/with-operation-callback.ts
Normal file
42
packages/commerce/src/api/utils/with-operation-callback.ts
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
import type { AllowedOperations, Operation } from '../operations'
|
||||||
|
|
||||||
|
import { z } from 'zod'
|
||||||
|
import { getOperationError } from './errors'
|
||||||
|
import { pageSchema } from '../../schemas/page'
|
||||||
|
import { siteInfoSchema } from '../../schemas/site'
|
||||||
|
import { productSchema, productsPathsSchema } from '../../schemas/product'
|
||||||
|
|
||||||
|
export const withOperationCallback =
|
||||||
|
(name: AllowedOperations, fn: (...args: any[]) => Promise<any>) =>
|
||||||
|
async (...args: any[]) => {
|
||||||
|
try {
|
||||||
|
const data = await fn(...args)
|
||||||
|
parse({ name, data })
|
||||||
|
return data
|
||||||
|
} catch (error) {
|
||||||
|
throw getOperationError(name, error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const parse = ({ name, data }: Operation) => {
|
||||||
|
switch (name) {
|
||||||
|
case 'getProduct':
|
||||||
|
productSchema.nullable().parse(data.product)
|
||||||
|
break
|
||||||
|
case 'getAllProducts':
|
||||||
|
z.array(productSchema).parse(data.products)
|
||||||
|
break
|
||||||
|
case 'getAllProductPaths':
|
||||||
|
productsPathsSchema.parse(data.products)
|
||||||
|
break
|
||||||
|
case 'getPage':
|
||||||
|
pageSchema.nullable().parse(data.page)
|
||||||
|
break
|
||||||
|
case 'getAllPages':
|
||||||
|
z.array(pageSchema).parse(data.pages)
|
||||||
|
break
|
||||||
|
case 'getSiteInfo':
|
||||||
|
siteInfoSchema.parse(data)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
@ -5,7 +5,7 @@ import type { LoginHook } from '../types/login'
|
|||||||
import type { Provider } from '..'
|
import type { Provider } from '..'
|
||||||
|
|
||||||
export type UseLogin<
|
export type UseLogin<
|
||||||
H extends MutationHook<LoginHook<any>> = MutationHook<LoginHook>
|
H extends MutationHook<LoginHook> = MutationHook<LoginHook>
|
||||||
> = ReturnType<H['useHook']>
|
> = ReturnType<H['useHook']>
|
||||||
|
|
||||||
export const fetcher: HookFetcherFn<LoginHook> = mutationFetcher
|
export const fetcher: HookFetcherFn<LoginHook> = mutationFetcher
|
||||||
|
@ -5,7 +5,7 @@ import type { LogoutHook } from '../types/logout'
|
|||||||
import type { Provider } from '..'
|
import type { Provider } from '..'
|
||||||
|
|
||||||
export type UseLogout<
|
export type UseLogout<
|
||||||
H extends MutationHook<LogoutHook<any>> = MutationHook<LogoutHook>
|
H extends MutationHook<LogoutHook> = MutationHook<LogoutHook>
|
||||||
> = ReturnType<H['useHook']>
|
> = ReturnType<H['useHook']>
|
||||||
|
|
||||||
export const fetcher: HookFetcherFn<LogoutHook> = mutationFetcher
|
export const fetcher: HookFetcherFn<LogoutHook> = mutationFetcher
|
||||||
|
@ -5,7 +5,7 @@ import type { SignupHook } from '../types/signup'
|
|||||||
import type { Provider } from '..'
|
import type { Provider } from '..'
|
||||||
|
|
||||||
export type UseSignup<
|
export type UseSignup<
|
||||||
H extends MutationHook<SignupHook<any>> = MutationHook<SignupHook>
|
H extends MutationHook<SignupHook> = MutationHook<SignupHook>
|
||||||
> = ReturnType<H['useHook']>
|
> = ReturnType<H['useHook']>
|
||||||
|
|
||||||
export const fetcher: HookFetcherFn<SignupHook> = mutationFetcher
|
export const fetcher: HookFetcherFn<SignupHook> = mutationFetcher
|
||||||
|
@ -5,7 +5,7 @@ import type { AddItemHook } from '../types/cart'
|
|||||||
import type { Provider } from '..'
|
import type { Provider } from '..'
|
||||||
|
|
||||||
export type UseAddItem<
|
export type UseAddItem<
|
||||||
H extends MutationHook<AddItemHook<any>> = MutationHook<AddItemHook>
|
H extends MutationHook<AddItemHook> = MutationHook<AddItemHook>
|
||||||
> = ReturnType<H['useHook']>
|
> = ReturnType<H['useHook']>
|
||||||
|
|
||||||
export const fetcher: HookFetcherFn<AddItemHook> = mutationFetcher
|
export const fetcher: HookFetcherFn<AddItemHook> = mutationFetcher
|
||||||
|
@ -4,9 +4,8 @@ import type { SWRHook, HookFetcherFn } from '../utils/types'
|
|||||||
import type { GetCartHook } from '../types/cart'
|
import type { GetCartHook } from '../types/cart'
|
||||||
import { Provider, useCommerce } from '..'
|
import { Provider, useCommerce } from '..'
|
||||||
|
|
||||||
export type UseCart<
|
export type UseCart<H extends SWRHook<GetCartHook> = SWRHook<GetCartHook>> =
|
||||||
H extends SWRHook<GetCartHook<any>> = SWRHook<GetCartHook>
|
ReturnType<H['useHook']>
|
||||||
> = ReturnType<H['useHook']>
|
|
||||||
|
|
||||||
export const fetcher: HookFetcherFn<GetCartHook> = async ({
|
export const fetcher: HookFetcherFn<GetCartHook> = async ({
|
||||||
options,
|
options,
|
||||||
|
@ -5,7 +5,7 @@ import type { RemoveItemHook } from '../types/cart'
|
|||||||
import type { Provider } from '..'
|
import type { Provider } from '..'
|
||||||
|
|
||||||
export type UseRemoveItem<
|
export type UseRemoveItem<
|
||||||
H extends MutationHook<RemoveItemHook<any>> = MutationHook<RemoveItemHook>
|
H extends MutationHook<RemoveItemHook> = MutationHook<RemoveItemHook>
|
||||||
> = ReturnType<H['useHook']>
|
> = ReturnType<H['useHook']>
|
||||||
|
|
||||||
export const fetcher: HookFetcherFn<RemoveItemHook> = mutationFetcher
|
export const fetcher: HookFetcherFn<RemoveItemHook> = mutationFetcher
|
||||||
|
@ -5,7 +5,7 @@ import type { UpdateItemHook } from '../types/cart'
|
|||||||
import type { Provider } from '..'
|
import type { Provider } from '..'
|
||||||
|
|
||||||
export type UseUpdateItem<
|
export type UseUpdateItem<
|
||||||
H extends MutationHook<UpdateItemHook<any>> = MutationHook<UpdateItemHook>
|
H extends MutationHook<UpdateItemHook> = MutationHook<UpdateItemHook>
|
||||||
> = ReturnType<H['useHook']>
|
> = ReturnType<H['useHook']>
|
||||||
|
|
||||||
export const fetcher: HookFetcherFn<UpdateItemHook> = mutationFetcher
|
export const fetcher: HookFetcherFn<UpdateItemHook> = mutationFetcher
|
||||||
|
@ -7,7 +7,7 @@ import { useHook, useSWRHook } from '../utils/use-hook'
|
|||||||
import { Provider, useCommerce } from '..'
|
import { Provider, useCommerce } from '..'
|
||||||
|
|
||||||
export type UseCheckout<
|
export type UseCheckout<
|
||||||
H extends SWRHook<GetCheckoutHook<any>> = SWRHook<GetCheckoutHook>
|
H extends SWRHook<GetCheckoutHook> = SWRHook<GetCheckoutHook>
|
||||||
> = ReturnType<H['useHook']>
|
> = ReturnType<H['useHook']>
|
||||||
|
|
||||||
export const fetcher: HookFetcherFn<GetCheckoutHook> = async ({
|
export const fetcher: HookFetcherFn<GetCheckoutHook> = async ({
|
||||||
|
@ -6,9 +6,7 @@ import { useHook, useMutationHook } from '../utils/use-hook'
|
|||||||
import { mutationFetcher } from '../utils/default-fetcher'
|
import { mutationFetcher } from '../utils/default-fetcher'
|
||||||
|
|
||||||
export type UseSubmitCheckout<
|
export type UseSubmitCheckout<
|
||||||
H extends MutationHook<
|
H extends MutationHook<SubmitCheckoutHook> = MutationHook<SubmitCheckoutHook>
|
||||||
SubmitCheckoutHook<any>
|
|
||||||
> = MutationHook<SubmitCheckoutHook>
|
|
||||||
> = ReturnType<H['useHook']>
|
> = ReturnType<H['useHook']>
|
||||||
|
|
||||||
export const fetcher: HookFetcherFn<SubmitCheckoutHook> = mutationFetcher
|
export const fetcher: HookFetcherFn<SubmitCheckoutHook> = mutationFetcher
|
||||||
|
@ -6,7 +6,7 @@ import { useHook, useMutationHook } from '../../utils/use-hook'
|
|||||||
import { mutationFetcher } from '../../utils/default-fetcher'
|
import { mutationFetcher } from '../../utils/default-fetcher'
|
||||||
|
|
||||||
export type UseAddItem<
|
export type UseAddItem<
|
||||||
H extends MutationHook<AddItemHook<any>> = MutationHook<AddItemHook>
|
H extends MutationHook<AddItemHook> = MutationHook<AddItemHook>
|
||||||
> = ReturnType<H['useHook']>
|
> = ReturnType<H['useHook']>
|
||||||
|
|
||||||
export const fetcher: HookFetcherFn<AddItemHook> = mutationFetcher
|
export const fetcher: HookFetcherFn<AddItemHook> = mutationFetcher
|
||||||
|
@ -7,7 +7,7 @@ import { useHook, useSWRHook } from '../../utils/use-hook'
|
|||||||
import { Provider, useCommerce } from '../..'
|
import { Provider, useCommerce } from '../..'
|
||||||
|
|
||||||
export type UseAddresses<
|
export type UseAddresses<
|
||||||
H extends SWRHook<GetAddressesHook<any>> = SWRHook<GetAddressesHook>
|
H extends SWRHook<GetAddressesHook> = SWRHook<GetAddressesHook>
|
||||||
> = ReturnType<H['useHook']>
|
> = ReturnType<H['useHook']>
|
||||||
|
|
||||||
export const fetcher: HookFetcherFn<GetAddressesHook> = async ({
|
export const fetcher: HookFetcherFn<GetAddressesHook> = async ({
|
||||||
|
@ -6,7 +6,7 @@ import { useHook, useMutationHook } from '../../utils/use-hook'
|
|||||||
import { mutationFetcher } from '../../utils/default-fetcher'
|
import { mutationFetcher } from '../../utils/default-fetcher'
|
||||||
|
|
||||||
export type UseRemoveItem<
|
export type UseRemoveItem<
|
||||||
H extends MutationHook<RemoveItemHook<any>> = MutationHook<RemoveItemHook>
|
H extends MutationHook<RemoveItemHook> = MutationHook<RemoveItemHook>
|
||||||
> = ReturnType<H['useHook']>
|
> = ReturnType<H['useHook']>
|
||||||
|
|
||||||
export const fetcher: HookFetcherFn<RemoveItemHook> = mutationFetcher
|
export const fetcher: HookFetcherFn<RemoveItemHook> = mutationFetcher
|
||||||
|
@ -6,7 +6,7 @@ import { useHook, useMutationHook } from '../../utils/use-hook'
|
|||||||
import { mutationFetcher } from '../../utils/default-fetcher'
|
import { mutationFetcher } from '../../utils/default-fetcher'
|
||||||
|
|
||||||
export type UseUpdateItem<
|
export type UseUpdateItem<
|
||||||
H extends MutationHook<UpdateItemHook<any>> = MutationHook<UpdateItemHook>
|
H extends MutationHook<UpdateItemHook> = MutationHook<UpdateItemHook>
|
||||||
> = ReturnType<H['useHook']>
|
> = ReturnType<H['useHook']>
|
||||||
|
|
||||||
export const fetcher: HookFetcherFn<UpdateItemHook> = mutationFetcher
|
export const fetcher: HookFetcherFn<UpdateItemHook> = mutationFetcher
|
||||||
|
@ -6,7 +6,7 @@ import { useHook, useMutationHook } from '../../utils/use-hook'
|
|||||||
import { mutationFetcher } from '../../utils/default-fetcher'
|
import { mutationFetcher } from '../../utils/default-fetcher'
|
||||||
|
|
||||||
export type UseAddItem<
|
export type UseAddItem<
|
||||||
H extends MutationHook<AddItemHook<any>> = MutationHook<AddItemHook>
|
H extends MutationHook<AddItemHook> = MutationHook<AddItemHook>
|
||||||
> = ReturnType<H['useHook']>
|
> = ReturnType<H['useHook']>
|
||||||
|
|
||||||
export const fetcher: HookFetcherFn<AddItemHook> = mutationFetcher
|
export const fetcher: HookFetcherFn<AddItemHook> = mutationFetcher
|
||||||
|
@ -6,9 +6,8 @@ import Cookies from 'js-cookie'
|
|||||||
import { useHook, useSWRHook } from '../../utils/use-hook'
|
import { useHook, useSWRHook } from '../../utils/use-hook'
|
||||||
import { Provider, useCommerce } from '../..'
|
import { Provider, useCommerce } from '../..'
|
||||||
|
|
||||||
export type UseCards<
|
export type UseCards<H extends SWRHook<GetCardsHook> = SWRHook<GetCardsHook>> =
|
||||||
H extends SWRHook<GetCardsHook<any>> = SWRHook<GetCardsHook>
|
ReturnType<H['useHook']>
|
||||||
> = ReturnType<H['useHook']>
|
|
||||||
|
|
||||||
export const fetcher: HookFetcherFn<GetCardsHook> = async ({
|
export const fetcher: HookFetcherFn<GetCardsHook> = async ({
|
||||||
options,
|
options,
|
||||||
|
@ -6,7 +6,7 @@ import { useHook, useMutationHook } from '../../utils/use-hook'
|
|||||||
import { mutationFetcher } from '../../utils/default-fetcher'
|
import { mutationFetcher } from '../../utils/default-fetcher'
|
||||||
|
|
||||||
export type UseRemoveItem<
|
export type UseRemoveItem<
|
||||||
H extends MutationHook<RemoveItemHook<any>> = MutationHook<RemoveItemHook>
|
H extends MutationHook<RemoveItemHook> = MutationHook<RemoveItemHook>
|
||||||
> = ReturnType<H['useHook']>
|
> = ReturnType<H['useHook']>
|
||||||
|
|
||||||
export const fetcher: HookFetcherFn<RemoveItemHook> = mutationFetcher
|
export const fetcher: HookFetcherFn<RemoveItemHook> = mutationFetcher
|
||||||
|
@ -6,7 +6,7 @@ import { useHook, useMutationHook } from '../../utils/use-hook'
|
|||||||
import { mutationFetcher } from '../../utils/default-fetcher'
|
import { mutationFetcher } from '../../utils/default-fetcher'
|
||||||
|
|
||||||
export type UseUpdateItem<
|
export type UseUpdateItem<
|
||||||
H extends MutationHook<UpdateItemHook<any>> = MutationHook<UpdateItemHook>
|
H extends MutationHook<UpdateItemHook> = MutationHook<UpdateItemHook>
|
||||||
> = ReturnType<H['useHook']>
|
> = ReturnType<H['useHook']>
|
||||||
|
|
||||||
export const fetcher: HookFetcherFn<UpdateItemHook> = mutationFetcher
|
export const fetcher: HookFetcherFn<UpdateItemHook> = mutationFetcher
|
||||||
|
@ -5,7 +5,7 @@ import type { HookFetcherFn, SWRHook } from '../utils/types'
|
|||||||
import type { Provider } from '..'
|
import type { Provider } from '..'
|
||||||
|
|
||||||
export type UseCustomer<
|
export type UseCustomer<
|
||||||
H extends SWRHook<CustomerHook<any>> = SWRHook<CustomerHook>
|
H extends SWRHook<CustomerHook> = SWRHook<CustomerHook>
|
||||||
> = ReturnType<H['useHook']>
|
> = ReturnType<H['useHook']>
|
||||||
|
|
||||||
export const fetcher: HookFetcherFn<CustomerHook> = SWRFetcher
|
export const fetcher: HookFetcherFn<CustomerHook> = SWRFetcher
|
||||||
|
@ -5,7 +5,7 @@ import type { SearchProductsHook } from '../types/product'
|
|||||||
import type { Provider } from '..'
|
import type { Provider } from '..'
|
||||||
|
|
||||||
export type UseSearch<
|
export type UseSearch<
|
||||||
H extends SWRHook<SearchProductsHook<any>> = SWRHook<SearchProductsHook>
|
H extends SWRHook<SearchProductsHook> = SWRHook<SearchProductsHook>
|
||||||
> = ReturnType<H['useHook']>
|
> = ReturnType<H['useHook']>
|
||||||
|
|
||||||
export const fetcher: HookFetcherFn<SearchProductsHook> = SWRFetcher
|
export const fetcher: HookFetcherFn<SearchProductsHook> = SWRFetcher
|
||||||
|
18
packages/commerce/src/schemas/page.ts
Normal file
18
packages/commerce/src/schemas/page.ts
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
import { z } from 'zod'
|
||||||
|
|
||||||
|
export const pageSchema = z.object({
|
||||||
|
id: z.string(),
|
||||||
|
name: z.string(),
|
||||||
|
url: z.string().startsWith('/').optional(),
|
||||||
|
body: z.string(),
|
||||||
|
is_visible: z.boolean().optional(),
|
||||||
|
sort_order: z.number().optional(),
|
||||||
|
})
|
||||||
|
|
||||||
|
export const pagesPathsSchema = z.array(
|
||||||
|
z.object({
|
||||||
|
page: z.object({
|
||||||
|
path: z.string().startsWith('/'),
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
)
|
60
packages/commerce/src/schemas/product.ts
Normal file
60
packages/commerce/src/schemas/product.ts
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
import { z } from 'zod'
|
||||||
|
|
||||||
|
export const productPriceSchema = z.object({
|
||||||
|
value: z.number(),
|
||||||
|
currencyCode: z.string().max(3).optional(),
|
||||||
|
retailPrice: z.number().optional(),
|
||||||
|
})
|
||||||
|
|
||||||
|
export const productOptionSchema = z.object({
|
||||||
|
id: z.string(),
|
||||||
|
displayName: z.string(),
|
||||||
|
values: z.array(
|
||||||
|
z.object({
|
||||||
|
label: z.string(),
|
||||||
|
hexColors: z.array(z.string()).optional(),
|
||||||
|
})
|
||||||
|
),
|
||||||
|
})
|
||||||
|
|
||||||
|
export const productImageSchema = z.object({
|
||||||
|
url: z.string().url().or(z.string().startsWith('/')),
|
||||||
|
alt: z.string().optional(),
|
||||||
|
width: z.number().optional(),
|
||||||
|
height: z.number().optional(),
|
||||||
|
})
|
||||||
|
|
||||||
|
export const productVariantSchema = z.object({
|
||||||
|
id: z.string(),
|
||||||
|
sku: z.string().nullish(),
|
||||||
|
name: z.string().optional(),
|
||||||
|
options: z.array(productOptionSchema),
|
||||||
|
image: productImageSchema.optional(),
|
||||||
|
})
|
||||||
|
|
||||||
|
export const productSchema = z.object({
|
||||||
|
id: z.string(),
|
||||||
|
name: z.string(),
|
||||||
|
description: z.string(),
|
||||||
|
descriptionHtml: z.string().optional(),
|
||||||
|
sku: z.string().nullish(),
|
||||||
|
slug: z.string(),
|
||||||
|
path: z.string().startsWith('/'),
|
||||||
|
images: z.array(productImageSchema),
|
||||||
|
variants: z.array(productVariantSchema),
|
||||||
|
price: productPriceSchema,
|
||||||
|
options: z.array(productOptionSchema),
|
||||||
|
vendor: z.string().optional(),
|
||||||
|
})
|
||||||
|
|
||||||
|
export const productsPathsSchema = z.array(
|
||||||
|
z.object({ path: z.string().startsWith('/') })
|
||||||
|
)
|
||||||
|
|
||||||
|
export const searchProductBodySchema = z.object({
|
||||||
|
search: z.string(),
|
||||||
|
categoryId: z.string(),
|
||||||
|
brandId: z.string().optional(),
|
||||||
|
sort: z.string().optional(),
|
||||||
|
locale: z.string().optional(),
|
||||||
|
})
|
18
packages/commerce/src/schemas/site.ts
Normal file
18
packages/commerce/src/schemas/site.ts
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
import { z } from 'zod'
|
||||||
|
|
||||||
|
export const siteInfoSchema = z.object({
|
||||||
|
categories: z.array(
|
||||||
|
z.object({
|
||||||
|
id: z.string(),
|
||||||
|
name: z.string(),
|
||||||
|
path: z.string().startsWith('/'),
|
||||||
|
})
|
||||||
|
),
|
||||||
|
brands: z.array(
|
||||||
|
z.object({
|
||||||
|
id: z.string(),
|
||||||
|
name: z.string(),
|
||||||
|
path: z.string().startsWith('/'),
|
||||||
|
})
|
||||||
|
),
|
||||||
|
})
|
@ -1,177 +1,264 @@
|
|||||||
import type { Discount, Measurement, Image } from './common'
|
import type { Discount, Image, Measurement } from './common'
|
||||||
|
|
||||||
export type SelectedOption = {
|
// TODO: This should use the same type as the `ProductVariant` type from `product.ts`
|
||||||
// The option's id.
|
export interface ProductVariant {
|
||||||
id?: string
|
/**
|
||||||
// The product option’s name.
|
* The unique identifier for the variant.
|
||||||
name: string
|
*/
|
||||||
/// The product option’s value.
|
|
||||||
value: string
|
|
||||||
}
|
|
||||||
|
|
||||||
export type LineItem = {
|
|
||||||
id: string
|
id: string
|
||||||
variantId: string
|
/**
|
||||||
productId: string
|
* The SKU (stock keeping unit) associated with the product variant.
|
||||||
|
*/
|
||||||
|
sku?: string
|
||||||
|
/**
|
||||||
|
* The product variant’s name, or the product's name.
|
||||||
|
*/
|
||||||
name: string
|
name: string
|
||||||
quantity: number
|
/**
|
||||||
discounts: Discount[]
|
* The product variant’s price after all discounts are applied.
|
||||||
// A human-friendly unique string automatically generated from the product’s name
|
*/
|
||||||
path: string
|
|
||||||
variant: ProductVariant
|
|
||||||
options?: SelectedOption[]
|
|
||||||
}
|
|
||||||
|
|
||||||
export type ProductVariant = {
|
|
||||||
id: string
|
|
||||||
// The SKU (stock keeping unit) associated with the product variant.
|
|
||||||
sku: string
|
|
||||||
// The product variant’s title, or the product's name.
|
|
||||||
name: string
|
|
||||||
// Whether a customer needs to provide a shipping address when placing
|
|
||||||
// an order for the product variant.
|
|
||||||
requiresShipping: boolean
|
|
||||||
// The product variant’s price after all discounts are applied.
|
|
||||||
price: number
|
price: number
|
||||||
// Product variant’s price, as quoted by the manufacturer/distributor.
|
/**
|
||||||
|
* The product variant’s price before discounts are applied.
|
||||||
|
*/
|
||||||
listPrice: number
|
listPrice: number
|
||||||
// Image associated with the product variant. Falls back to the product image
|
/**
|
||||||
// if no image is available.
|
* Indicates if the variant is available for sale.
|
||||||
image?: Image
|
*/
|
||||||
// Indicates whether this product variant is in stock.
|
|
||||||
isInStock?: boolean
|
|
||||||
// Indicates if the product variant is available for sale.
|
|
||||||
availableForSale?: boolean
|
availableForSale?: boolean
|
||||||
// The variant's weight. If a weight was not explicitly specified on the
|
/**
|
||||||
// variant this will be the product's weight.
|
* Whether a customer needs to provide a shipping address when placing
|
||||||
|
* an order for the product variant.
|
||||||
|
*/
|
||||||
|
requiresShipping?: boolean
|
||||||
|
/**
|
||||||
|
* The image associated with the variant.
|
||||||
|
*/
|
||||||
|
image?: Image
|
||||||
|
/**
|
||||||
|
* The variant's weight. If a weight was not explicitly specified on the
|
||||||
|
* variant, this will be the product's weight.
|
||||||
|
*/
|
||||||
weight?: Measurement
|
weight?: Measurement
|
||||||
// The variant's height. If a height was not explicitly specified on the
|
/**
|
||||||
// variant, this will be the product's height.
|
* The variant's height. If a height was not explicitly specified on the
|
||||||
|
* variant, this will be the product's height.
|
||||||
|
*/
|
||||||
height?: Measurement
|
height?: Measurement
|
||||||
// The variant's width. If a width was not explicitly specified on the
|
/**
|
||||||
// variant, this will be the product's width.
|
* The variant's width. If a width was not explicitly specified on the
|
||||||
|
* variant, this will be the product's width.
|
||||||
|
*/
|
||||||
width?: Measurement
|
width?: Measurement
|
||||||
// The variant's depth. If a depth was not explicitly specified on the
|
/**
|
||||||
// variant, this will be the product's depth.
|
* The variant's depth. If a depth was not explicitly specified on the
|
||||||
|
* variant, this will be the product's depth.
|
||||||
|
*/
|
||||||
depth?: Measurement
|
depth?: Measurement
|
||||||
}
|
}
|
||||||
|
|
||||||
// Shopping cart, a.k.a Checkout
|
export interface SelectedOption {
|
||||||
export type Cart = {
|
/**
|
||||||
|
* The unique identifier for the option.
|
||||||
|
*/
|
||||||
|
id?: string
|
||||||
|
/**
|
||||||
|
* The product option’s name, such as "Color" or "Size".
|
||||||
|
*/
|
||||||
|
name: string
|
||||||
|
/**
|
||||||
|
* The product option’s value, such as "Red" or "XL".
|
||||||
|
*/
|
||||||
|
value: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface LineItem {
|
||||||
|
/**
|
||||||
|
* The unique identifier for the line item.
|
||||||
|
*/
|
||||||
id: string
|
id: string
|
||||||
// ID of the customer to which the cart belongs.
|
/**
|
||||||
|
* The unique identifier for the product variant.
|
||||||
|
*/
|
||||||
|
variantId: string
|
||||||
|
/**
|
||||||
|
* The unique identifier for the product, if the variant is not provided.
|
||||||
|
*/
|
||||||
|
productId: string
|
||||||
|
/**
|
||||||
|
* This is usually the product's name.
|
||||||
|
*/
|
||||||
|
name: string
|
||||||
|
/**
|
||||||
|
* The quantity of the product variant in the line item.
|
||||||
|
*/
|
||||||
|
quantity: number
|
||||||
|
/**
|
||||||
|
* List of discounts applied to the line item.
|
||||||
|
*/
|
||||||
|
discounts: Discount[]
|
||||||
|
/**
|
||||||
|
* A human-friendly unique string automatically generated from the product’s name.
|
||||||
|
*/
|
||||||
|
path: string
|
||||||
|
/**
|
||||||
|
* The product variant.
|
||||||
|
*/
|
||||||
|
variant: ProductVariant
|
||||||
|
/**
|
||||||
|
* List of selected options, to be used when displaying the line item, such as Color: Red, Size: XL.
|
||||||
|
*/
|
||||||
|
options?: SelectedOption[]
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shopping cart, a.k.a Checkout
|
||||||
|
*/
|
||||||
|
export interface Cart {
|
||||||
|
/**
|
||||||
|
* The unique identifier for the cart.
|
||||||
|
*/
|
||||||
|
id: string
|
||||||
|
/**
|
||||||
|
* ID of the customer to which the cart belongs.
|
||||||
|
*/
|
||||||
customerId?: string
|
customerId?: string
|
||||||
// The email assigned to this cart
|
/**
|
||||||
|
* The URL of the cart.
|
||||||
|
*/
|
||||||
|
url?: string
|
||||||
|
/**
|
||||||
|
* The email assigned to this cart.
|
||||||
|
*/
|
||||||
email?: string
|
email?: string
|
||||||
// The date and time when the cart was created.
|
/**
|
||||||
|
* The date and time when the cart was created.
|
||||||
|
*/
|
||||||
createdAt: string
|
createdAt: string
|
||||||
// The currency used for this cart
|
/**
|
||||||
|
* The currency used for this cart */
|
||||||
currency: { code: string }
|
currency: { code: string }
|
||||||
// Specifies if taxes are included in the line items.
|
/**
|
||||||
|
* Indicates if taxes are included in the line items.
|
||||||
|
*/
|
||||||
taxesIncluded: boolean
|
taxesIncluded: boolean
|
||||||
|
/**
|
||||||
|
* List of cart line items.
|
||||||
|
*/
|
||||||
lineItems: LineItem[]
|
lineItems: LineItem[]
|
||||||
// The sum of all the prices of all the items in the cart.
|
/**
|
||||||
// Duties, taxes, shipping and discounts excluded.
|
* The sum of all the pricexs of all the items in the cart.
|
||||||
|
* Duties, taxes, shipping and discounts excluded.
|
||||||
|
*/
|
||||||
lineItemsSubtotalPrice: number
|
lineItemsSubtotalPrice: number
|
||||||
// Price of the cart before duties, shipping and taxes.
|
/**
|
||||||
|
* Price of the cart before duties, shipping and taxes.*/
|
||||||
subtotalPrice: number
|
subtotalPrice: number
|
||||||
// The sum of all the prices of all the items in the cart.
|
/**
|
||||||
// Duties, taxes and discounts included.
|
* The sum of all the prices of all the items in the cart.
|
||||||
|
* Duties, taxes and discounts included.
|
||||||
|
*/
|
||||||
totalPrice: number
|
totalPrice: number
|
||||||
// Discounts that have been applied on the cart.
|
/**
|
||||||
|
* Discounts that have been applied on the cart.
|
||||||
|
*/
|
||||||
discounts?: Discount[]
|
discounts?: Discount[]
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base cart item body used for cart mutations
|
* Base cart item body used for cart mutations
|
||||||
*/
|
*/
|
||||||
export type CartItemBody = {
|
export interface CartItemBody {
|
||||||
|
/**
|
||||||
|
* The unique identifier for the product variant.
|
||||||
|
*/
|
||||||
variantId: string
|
variantId: string
|
||||||
|
/**
|
||||||
|
* The unique identifier for the product, if the variant is not provided.
|
||||||
|
*/
|
||||||
productId?: string
|
productId?: string
|
||||||
|
/**
|
||||||
|
* The quantity of the product variant.
|
||||||
|
*/
|
||||||
quantity?: number
|
quantity?: number
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The product variant's selected options.
|
||||||
|
*/
|
||||||
|
optionsSelected?: SelectedOption[]
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hooks schema
|
* Cart Hooks for add, update and remove items from the cart
|
||||||
*/
|
*/
|
||||||
|
export type CartHooks = {
|
||||||
export type CartTypes = {
|
getCart: GetCartHook
|
||||||
cart?: Cart
|
addItem: AddItemHook
|
||||||
item: LineItem
|
updateItem: UpdateItemHook
|
||||||
itemBody: CartItemBody
|
removeItem: RemoveItemHook
|
||||||
}
|
}
|
||||||
|
|
||||||
export type CartHooks<T extends CartTypes = CartTypes> = {
|
export type GetCartHook = {
|
||||||
getCart: GetCartHook<T>
|
data: Cart | null
|
||||||
addItem: AddItemHook<T>
|
|
||||||
updateItem: UpdateItemHook<T>
|
|
||||||
removeItem: RemoveItemHook<T>
|
|
||||||
}
|
|
||||||
|
|
||||||
export type GetCartHook<T extends CartTypes = CartTypes> = {
|
|
||||||
data: T['cart'] | null
|
|
||||||
input: {}
|
input: {}
|
||||||
fetcherInput: { cartId?: string }
|
fetcherInput: { cartId?: string }
|
||||||
swrState: { isEmpty: boolean }
|
swrState: { isEmpty: boolean }
|
||||||
}
|
}
|
||||||
|
|
||||||
export type AddItemHook<T extends CartTypes = CartTypes> = {
|
export type AddItemHook = {
|
||||||
data: T['cart']
|
data: Cart
|
||||||
input?: T['itemBody']
|
input?: CartItemBody
|
||||||
fetcherInput: T['itemBody']
|
fetcherInput: CartItemBody
|
||||||
body: { item: T['itemBody'] }
|
body: { item: CartItemBody }
|
||||||
actionInput: T['itemBody']
|
actionInput: CartItemBody
|
||||||
}
|
}
|
||||||
|
|
||||||
export type UpdateItemHook<T extends CartTypes = CartTypes> = {
|
export type UpdateItemHook = {
|
||||||
data: T['cart'] | null
|
data: Cart | null | undefined
|
||||||
input: { item?: T['item']; wait?: number }
|
input: { item?: LineItem; wait?: number }
|
||||||
fetcherInput: { itemId: string; item: T['itemBody'] }
|
fetcherInput: { itemId: string; item: CartItemBody }
|
||||||
body: { itemId: string; item: T['itemBody'] }
|
body: { itemId: string; item: CartItemBody }
|
||||||
actionInput: T['itemBody'] & { id: string }
|
actionInput: CartItemBody & { id: string }
|
||||||
}
|
}
|
||||||
|
|
||||||
export type RemoveItemHook<T extends CartTypes = CartTypes> = {
|
export type RemoveItemHook = {
|
||||||
data: T['cart'] | null
|
data: Cart | null | undefined
|
||||||
input: { item?: T['item'] }
|
input: { item?: LineItem }
|
||||||
fetcherInput: { itemId: string }
|
fetcherInput: { itemId: string }
|
||||||
body: { itemId: string }
|
body: { itemId: string }
|
||||||
actionInput: { id: string }
|
actionInput: { id: string }
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* API Schema
|
* Cart API endpoitns & handlers for add, update and remove items from the cart
|
||||||
*/
|
*/
|
||||||
|
export type CartSchema = {
|
||||||
export type CartSchema<T extends CartTypes = CartTypes> = {
|
|
||||||
endpoint: {
|
endpoint: {
|
||||||
options: {}
|
options: {}
|
||||||
handlers: CartHandlers<T>
|
handlers: CartHandlers
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export type CartHandlers<T extends CartTypes = CartTypes> = {
|
export type CartHandlers = {
|
||||||
getCart: GetCartHandler<T>
|
getCart: GetCartHandler
|
||||||
addItem: AddItemHandler<T>
|
addItem: AddItemHandler
|
||||||
updateItem: UpdateItemHandler<T>
|
updateItem: UpdateItemHandler
|
||||||
removeItem: RemoveItemHandler<T>
|
removeItem: RemoveItemHandler
|
||||||
}
|
}
|
||||||
|
|
||||||
export type GetCartHandler<T extends CartTypes = CartTypes> = GetCartHook<T> & {
|
export type GetCartHandler = GetCartHook & {
|
||||||
body: { cartId?: string }
|
body: { cartId?: string }
|
||||||
}
|
}
|
||||||
|
|
||||||
export type AddItemHandler<T extends CartTypes = CartTypes> = AddItemHook<T> & {
|
export type AddItemHandler = AddItemHook & {
|
||||||
body: { cartId: string }
|
body: { cartId: string }
|
||||||
}
|
}
|
||||||
|
|
||||||
export type UpdateItemHandler<T extends CartTypes = CartTypes> =
|
export type UpdateItemHandler = UpdateItemHook & {
|
||||||
UpdateItemHook<T> & {
|
data: Cart
|
||||||
data: T['cart']
|
body: { cartId: string }
|
||||||
body: { cartId: string }
|
}
|
||||||
}
|
|
||||||
|
|
||||||
export type RemoveItemHandler<T extends CartTypes = CartTypes> =
|
export type RemoveItemHandler = RemoveItemHook & {
|
||||||
RemoveItemHook<T> & {
|
body: { cartId: string }
|
||||||
body: { cartId: string }
|
}
|
||||||
}
|
|
||||||
|
@ -1,57 +1,89 @@
|
|||||||
import type { UseSubmitCheckout } from '../checkout/use-submit-checkout'
|
import type { UseSubmitCheckout } from '../checkout/use-submit-checkout'
|
||||||
import type { Address, AddressFields } from './customer/address'
|
import type { AddressFields } from './customer/address'
|
||||||
import type { Card, CardFields } from './customer/card'
|
import type { Card, CardFields } from './customer/card'
|
||||||
|
import type { LineItem } from './cart'
|
||||||
|
|
||||||
// Index
|
export interface Checkout {
|
||||||
export type Checkout = any
|
/**
|
||||||
|
* Indicates if the checkout has payment iformation collected.
|
||||||
export type CheckoutTypes = {
|
*/
|
||||||
card?: Card | CardFields
|
hasPayment: boolean
|
||||||
address?: Address | AddressFields
|
/**
|
||||||
checkout?: Checkout
|
* Indicates if the checkout has shipping information collected.
|
||||||
hasPayment?: boolean
|
*/
|
||||||
hasShipping?: boolean
|
hasShipping: boolean
|
||||||
|
/**
|
||||||
|
* The unique identifier for the address that the customer has selected for shipping.
|
||||||
|
*/
|
||||||
|
addressId: string
|
||||||
|
/**
|
||||||
|
* The list of payment cards that the customer has available.
|
||||||
|
*/
|
||||||
|
payments?: Card[]
|
||||||
|
/**
|
||||||
|
* The unique identifier of the card that the customer has selected for payment.
|
||||||
|
*/
|
||||||
|
cardId?: string
|
||||||
|
/**
|
||||||
|
* List of items in the checkout.
|
||||||
|
*/
|
||||||
|
lineItems?: LineItem[]
|
||||||
}
|
}
|
||||||
|
|
||||||
export type SubmitCheckoutHook<T extends CheckoutTypes = CheckoutTypes> = {
|
export interface CheckoutBody {
|
||||||
data: T
|
/**
|
||||||
input?: T
|
* The unique identifier for the cart.
|
||||||
fetcherInput: T
|
*/
|
||||||
body: { item: T }
|
cartId?: string
|
||||||
actionInput: T
|
/**
|
||||||
|
* The Card information.
|
||||||
|
* @see CardFields
|
||||||
|
*/
|
||||||
|
card: CardFields
|
||||||
|
/**
|
||||||
|
* The Address information.
|
||||||
|
* @see AddressFields
|
||||||
|
*/
|
||||||
|
address: AddressFields
|
||||||
}
|
}
|
||||||
|
|
||||||
export type GetCheckoutHook<T extends CheckoutTypes = CheckoutTypes> = {
|
export type SubmitCheckoutHook = {
|
||||||
data: T['checkout'] | null
|
data: Checkout
|
||||||
|
input?: CheckoutBody
|
||||||
|
fetcherInput: CheckoutBody
|
||||||
|
body: { item: CheckoutBody }
|
||||||
|
actionInput: CheckoutBody
|
||||||
|
}
|
||||||
|
|
||||||
|
export type GetCheckoutHook = {
|
||||||
|
data: Checkout | null
|
||||||
input: {}
|
input: {}
|
||||||
fetcherInput: { cartId?: string }
|
fetcherInput: { cartId?: string }
|
||||||
swrState: { isEmpty: boolean }
|
swrState: { isEmpty: boolean }
|
||||||
mutations: { submit: UseSubmitCheckout }
|
mutations: { submit: UseSubmitCheckout }
|
||||||
}
|
}
|
||||||
|
|
||||||
export type CheckoutHooks<T extends CheckoutTypes = CheckoutTypes> = {
|
export type CheckoutHooks = {
|
||||||
submitCheckout?: SubmitCheckoutHook<T>
|
submitCheckout?: SubmitCheckoutHook
|
||||||
getCheckout: GetCheckoutHook<T>
|
getCheckout: GetCheckoutHook
|
||||||
}
|
}
|
||||||
|
|
||||||
export type GetCheckoutHandler<T extends CheckoutTypes = CheckoutTypes> =
|
export type GetCheckoutHandler = GetCheckoutHook & {
|
||||||
GetCheckoutHook<T> & {
|
body: { cartId: string }
|
||||||
body: { cartId: string }
|
|
||||||
}
|
|
||||||
|
|
||||||
export type SubmitCheckoutHandler<T extends CheckoutTypes = CheckoutTypes> =
|
|
||||||
SubmitCheckoutHook<T> & {
|
|
||||||
body: { cartId: string }
|
|
||||||
}
|
|
||||||
|
|
||||||
export type CheckoutHandlers<T extends CheckoutTypes = CheckoutTypes> = {
|
|
||||||
getCheckout: GetCheckoutHandler<T>
|
|
||||||
submitCheckout?: SubmitCheckoutHandler<T>
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export type CheckoutSchema<T extends CheckoutTypes = CheckoutTypes> = {
|
export type SubmitCheckoutHandler = SubmitCheckoutHook & {
|
||||||
|
body: { cartId: string }
|
||||||
|
}
|
||||||
|
|
||||||
|
export type CheckoutHandlers = {
|
||||||
|
getCheckout: GetCheckoutHandler
|
||||||
|
submitCheckout?: SubmitCheckoutHandler
|
||||||
|
}
|
||||||
|
|
||||||
|
export type CheckoutSchema = {
|
||||||
endpoint: {
|
endpoint: {
|
||||||
options: {}
|
options: {}
|
||||||
handlers: CheckoutHandlers<T>
|
handlers: CheckoutHandlers
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,16 +1,36 @@
|
|||||||
export type Discount = {
|
export interface Discount {
|
||||||
// The value of the discount, can be an amount or percentage
|
/**
|
||||||
|
* The value of the discount, can be an amount or percentage.
|
||||||
|
*/
|
||||||
value: number
|
value: number
|
||||||
}
|
}
|
||||||
|
|
||||||
export type Measurement = {
|
export interface Measurement {
|
||||||
|
/**
|
||||||
|
* The measurement's value.
|
||||||
|
*/
|
||||||
value: number
|
value: number
|
||||||
|
/**
|
||||||
|
* The measurement's unit, such as "KILOGRAMS", "GRAMS", "POUNDS" & "OOUNCES".
|
||||||
|
*/
|
||||||
unit: 'KILOGRAMS' | 'GRAMS' | 'POUNDS' | 'OUNCES'
|
unit: 'KILOGRAMS' | 'GRAMS' | 'POUNDS' | 'OUNCES'
|
||||||
}
|
}
|
||||||
|
|
||||||
export type Image = {
|
export interface Image {
|
||||||
|
/**
|
||||||
|
* The URL of the image.
|
||||||
|
*/
|
||||||
url: string
|
url: string
|
||||||
altText?: string
|
/**
|
||||||
|
* A word or phrase that describes the content of an image.
|
||||||
|
*/
|
||||||
|
alt?: string
|
||||||
|
/**
|
||||||
|
* The image's width.
|
||||||
|
*/
|
||||||
width?: number
|
width?: number
|
||||||
|
/**
|
||||||
|
* The image's height.
|
||||||
|
*/
|
||||||
height?: number
|
height?: number
|
||||||
}
|
}
|
||||||
|
@ -1,111 +1,123 @@
|
|||||||
export interface Address {
|
export interface Address {
|
||||||
|
/**
|
||||||
|
* The unique identifier for the address.
|
||||||
|
*/
|
||||||
id: string
|
id: string
|
||||||
|
/**
|
||||||
|
* The customer's first name.
|
||||||
|
*/
|
||||||
mask: string
|
mask: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface AddressFields {
|
export interface AddressFields {
|
||||||
|
/**
|
||||||
|
* The type of address.
|
||||||
|
* @example "billing, shipping"
|
||||||
|
*/
|
||||||
type: string
|
type: string
|
||||||
|
/**
|
||||||
|
* The customer's first name.
|
||||||
|
*/
|
||||||
firstName: string
|
firstName: string
|
||||||
|
/**
|
||||||
|
* The customer's last name.
|
||||||
|
*/
|
||||||
lastName: string
|
lastName: string
|
||||||
|
/**
|
||||||
|
* Company name.
|
||||||
|
*/
|
||||||
company: string
|
company: string
|
||||||
|
/**
|
||||||
|
* The customer's billing address street number.
|
||||||
|
*/
|
||||||
streetNumber: string
|
streetNumber: string
|
||||||
|
/**
|
||||||
|
* The customer's billing address apartment number.
|
||||||
|
*/
|
||||||
apartments: string
|
apartments: string
|
||||||
|
/**
|
||||||
|
* The customer's billing address zip code.
|
||||||
|
*/
|
||||||
zipCode: string
|
zipCode: string
|
||||||
|
/**
|
||||||
|
* The customer's billing address city.
|
||||||
|
*/
|
||||||
city: string
|
city: string
|
||||||
|
/**
|
||||||
|
* The customer's billing address country.
|
||||||
|
*/
|
||||||
country: string
|
country: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export type CustomerAddressTypes = {
|
/**
|
||||||
address?: Address
|
* Hooks for managing a customer's addresses.
|
||||||
fields: AddressFields
|
*/
|
||||||
}
|
|
||||||
|
|
||||||
export type GetAddressesHook<
|
export type GetAddressesHook = {
|
||||||
T extends CustomerAddressTypes = CustomerAddressTypes
|
data: Address[] | null
|
||||||
> = {
|
|
||||||
data: T['address'][] | null
|
|
||||||
input: {}
|
input: {}
|
||||||
fetcherInput: { cartId?: string }
|
fetcherInput: { cartId?: string }
|
||||||
swrState: { isEmpty: boolean }
|
swrState: { isEmpty: boolean }
|
||||||
}
|
}
|
||||||
|
|
||||||
export type AddItemHook<T extends CustomerAddressTypes = CustomerAddressTypes> =
|
export type AddItemHook = {
|
||||||
{
|
data: Address
|
||||||
data: T['address']
|
input?: AddressFields
|
||||||
input?: T['fields']
|
fetcherInput: AddressFields
|
||||||
fetcherInput: T['fields']
|
body: { item: AddressFields }
|
||||||
body: { item: T['fields'] }
|
actionInput: AddressFields
|
||||||
actionInput: T['fields']
|
|
||||||
}
|
|
||||||
|
|
||||||
export type UpdateItemHook<
|
|
||||||
T extends CustomerAddressTypes = CustomerAddressTypes
|
|
||||||
> = {
|
|
||||||
data: T['address'] | null
|
|
||||||
input: { item?: T['fields']; wait?: number }
|
|
||||||
fetcherInput: { itemId: string; item: T['fields'] }
|
|
||||||
body: { itemId: string; item: T['fields'] }
|
|
||||||
actionInput: T['fields'] & { id: string }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export type RemoveItemHook<
|
export type UpdateItemHook = {
|
||||||
T extends CustomerAddressTypes = CustomerAddressTypes
|
data: Address | null
|
||||||
> = {
|
input: { item?: AddressFields; wait?: number }
|
||||||
data: T['address'] | null
|
fetcherInput: { itemId: string; item: AddressFields }
|
||||||
input: { item?: T['address'] }
|
body: { itemId: string; item: AddressFields }
|
||||||
|
actionInput: AddressFields & { id: string }
|
||||||
|
}
|
||||||
|
|
||||||
|
export type RemoveItemHook = {
|
||||||
|
data: Address | null | undefined
|
||||||
|
input: { item?: Address }
|
||||||
fetcherInput: { itemId: string }
|
fetcherInput: { itemId: string }
|
||||||
body: { itemId: string }
|
body: { itemId: string }
|
||||||
actionInput: { id: string }
|
actionInput: { id: string }
|
||||||
}
|
}
|
||||||
|
|
||||||
export type CustomerAddressHooks<
|
export type CustomerAddressHooks = {
|
||||||
T extends CustomerAddressTypes = CustomerAddressTypes
|
getAddresses: GetAddressesHook
|
||||||
> = {
|
addItem: AddItemHook
|
||||||
getAddresses: GetAddressesHook<T>
|
updateItem: UpdateItemHook
|
||||||
addItem: AddItemHook<T>
|
removeItem: RemoveItemHook
|
||||||
updateItem: UpdateItemHook<T>
|
|
||||||
removeItem: RemoveItemHook<T>
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export type AddressHandler<
|
/**
|
||||||
T extends CustomerAddressTypes = CustomerAddressTypes
|
* API endpoints for managing a customer's addresses.
|
||||||
> = GetAddressesHook<T> & {
|
*/
|
||||||
body: { cartId?: string }
|
|
||||||
}
|
|
||||||
|
|
||||||
export type AddItemHandler<
|
export type AddItemHandler = AddItemHook & {
|
||||||
T extends CustomerAddressTypes = CustomerAddressTypes
|
|
||||||
> = AddItemHook<T> & {
|
|
||||||
body: { cartId: string }
|
body: { cartId: string }
|
||||||
}
|
}
|
||||||
|
|
||||||
export type UpdateItemHandler<
|
export type UpdateItemHandler = UpdateItemHook & {
|
||||||
T extends CustomerAddressTypes = CustomerAddressTypes
|
data: Address
|
||||||
> = UpdateItemHook<T> & {
|
|
||||||
data: T['address']
|
|
||||||
body: { cartId: string }
|
body: { cartId: string }
|
||||||
}
|
}
|
||||||
|
|
||||||
export type RemoveItemHandler<
|
export type RemoveItemHandler = RemoveItemHook & {
|
||||||
T extends CustomerAddressTypes = CustomerAddressTypes
|
|
||||||
> = RemoveItemHook<T> & {
|
|
||||||
body: { cartId: string }
|
body: { cartId: string }
|
||||||
}
|
}
|
||||||
|
|
||||||
export type CustomerAddressHandlers<
|
export type CustomerAddressHandlers = {
|
||||||
T extends CustomerAddressTypes = CustomerAddressTypes
|
getAddresses: GetAddressesHook
|
||||||
> = {
|
addItem: AddItemHandler
|
||||||
getAddresses: GetAddressesHook<T>
|
updateItem: UpdateItemHandler
|
||||||
addItem: AddItemHandler<T>
|
removeItem: RemoveItemHandler
|
||||||
updateItem: UpdateItemHandler<T>
|
|
||||||
removeItem: RemoveItemHandler<T>
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export type CustomerAddressSchema<
|
export type CustomerAddressSchema = {
|
||||||
T extends CustomerAddressTypes = CustomerAddressTypes
|
|
||||||
> = {
|
|
||||||
endpoint: {
|
endpoint: {
|
||||||
options: {}
|
options: {}
|
||||||
handlers: CustomerAddressHandlers<T>
|
handlers: CustomerAddressHandlers
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,102 +1,139 @@
|
|||||||
export interface Card {
|
export interface Card {
|
||||||
|
/**
|
||||||
|
* Unique identifier for the card.
|
||||||
|
*/
|
||||||
id: string
|
id: string
|
||||||
|
/**
|
||||||
|
* Masked card number. Contains only the last 4 digits.
|
||||||
|
* @example "4242"
|
||||||
|
*/
|
||||||
mask: string
|
mask: string
|
||||||
|
/**
|
||||||
|
* The card's brand.
|
||||||
|
* @example "Visa, Mastercard, etc."
|
||||||
|
*/
|
||||||
provider: string
|
provider: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The fields required to create a new card.
|
||||||
|
*/
|
||||||
export interface CardFields {
|
export interface CardFields {
|
||||||
|
/**
|
||||||
|
* Name on the card.
|
||||||
|
*/
|
||||||
cardHolder: string
|
cardHolder: string
|
||||||
|
/**
|
||||||
|
* The card's number, consisting of 16 digits.
|
||||||
|
*/
|
||||||
cardNumber: string
|
cardNumber: string
|
||||||
|
/**
|
||||||
|
* The card's expiry month and year, in the format MM/YY.
|
||||||
|
* @example "01/25"
|
||||||
|
*/
|
||||||
cardExpireDate: string
|
cardExpireDate: string
|
||||||
|
/**
|
||||||
|
* The card's security code, consisting of 3 digits.
|
||||||
|
*/
|
||||||
cardCvc: string
|
cardCvc: string
|
||||||
|
/**
|
||||||
|
* The customer's first name.
|
||||||
|
*/
|
||||||
firstName: string
|
firstName: string
|
||||||
|
/**
|
||||||
|
* The customer's last name.
|
||||||
|
*/
|
||||||
lastName: string
|
lastName: string
|
||||||
|
/**
|
||||||
|
* Company name.
|
||||||
|
*/
|
||||||
company: string
|
company: string
|
||||||
|
/**
|
||||||
|
* The customer's billing address street number.
|
||||||
|
*/
|
||||||
streetNumber: string
|
streetNumber: string
|
||||||
|
/**
|
||||||
|
* The customer's billing address zip code.
|
||||||
|
*/
|
||||||
zipCode: string
|
zipCode: string
|
||||||
|
/**
|
||||||
|
* The customer's billing address city.
|
||||||
|
*/
|
||||||
city: string
|
city: string
|
||||||
|
/**
|
||||||
|
* The customer's billing address country.
|
||||||
|
*/
|
||||||
country: string
|
country: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export type CustomerCardTypes = {
|
/**
|
||||||
card?: Card
|
* Hooks for managing a customer's cards.
|
||||||
fields: CardFields
|
*/
|
||||||
}
|
|
||||||
|
|
||||||
export type GetCardsHook<T extends CustomerCardTypes = CustomerCardTypes> = {
|
export type GetCardsHook = {
|
||||||
data: T['card'][] | null
|
data: Card[] | null
|
||||||
input: {}
|
input: {}
|
||||||
fetcherInput: { cartId?: string }
|
fetcherInput: { cartId?: string }
|
||||||
swrState: { isEmpty: boolean }
|
swrState: { isEmpty: boolean }
|
||||||
}
|
}
|
||||||
|
|
||||||
export type AddItemHook<T extends CustomerCardTypes = CustomerCardTypes> = {
|
export type AddItemHook = {
|
||||||
data: T['card']
|
data: Card
|
||||||
input?: T['fields']
|
input?: CardFields
|
||||||
fetcherInput: T['fields']
|
fetcherInput: CardFields
|
||||||
body: { item: T['fields'] }
|
body: { item: CardFields }
|
||||||
actionInput: T['fields']
|
actionInput: CardFields
|
||||||
}
|
}
|
||||||
|
|
||||||
export type UpdateItemHook<T extends CustomerCardTypes = CustomerCardTypes> = {
|
export type UpdateItemHook = {
|
||||||
data: T['card'] | null
|
data: Card | null | undefined
|
||||||
input: { item?: T['fields']; wait?: number }
|
input: { item?: CardFields; wait?: number }
|
||||||
fetcherInput: { itemId: string; item: T['fields'] }
|
fetcherInput: { itemId: string; item: CardFields }
|
||||||
body: { itemId: string; item: T['fields'] }
|
body: { itemId: string; item: CardFields }
|
||||||
actionInput: T['fields'] & { id: string }
|
actionInput: CardFields & { id: string }
|
||||||
}
|
}
|
||||||
|
|
||||||
export type RemoveItemHook<T extends CustomerCardTypes = CustomerCardTypes> = {
|
export type RemoveItemHook = {
|
||||||
data: T['card'] | null
|
data: Card | null | undefined
|
||||||
input: { item?: T['card'] }
|
input: { item?: Card }
|
||||||
fetcherInput: { itemId: string }
|
fetcherInput: { itemId: string }
|
||||||
body: { itemId: string }
|
body: { itemId: string }
|
||||||
actionInput: { id: string }
|
actionInput: { id: string }
|
||||||
}
|
}
|
||||||
|
|
||||||
export type CustomerCardHooks<T extends CustomerCardTypes = CustomerCardTypes> =
|
export interface CustomerCardHooks {
|
||||||
{
|
getCards: GetCardsHook
|
||||||
getCards: GetCardsHook<T>
|
addItem: AddItemHook
|
||||||
addItem: AddItemHook<T>
|
updateItem: UpdateItemHook
|
||||||
updateItem: UpdateItemHook<T>
|
removeItem: RemoveItemHook
|
||||||
removeItem: RemoveItemHook<T>
|
|
||||||
}
|
|
||||||
|
|
||||||
export type CardsHandler<T extends CustomerCardTypes = CustomerCardTypes> =
|
|
||||||
GetCardsHook<T> & {
|
|
||||||
body: { cartId?: string }
|
|
||||||
}
|
|
||||||
|
|
||||||
export type AddItemHandler<T extends CustomerCardTypes = CustomerCardTypes> =
|
|
||||||
AddItemHook<T> & {
|
|
||||||
body: { cartId: string }
|
|
||||||
}
|
|
||||||
|
|
||||||
export type UpdateItemHandler<T extends CustomerCardTypes = CustomerCardTypes> =
|
|
||||||
UpdateItemHook<T> & {
|
|
||||||
data: T['card']
|
|
||||||
body: { cartId: string }
|
|
||||||
}
|
|
||||||
|
|
||||||
export type RemoveItemHandler<T extends CustomerCardTypes = CustomerCardTypes> =
|
|
||||||
RemoveItemHook<T> & {
|
|
||||||
body: { cartId: string }
|
|
||||||
}
|
|
||||||
|
|
||||||
export type CustomerCardHandlers<
|
|
||||||
T extends CustomerCardTypes = CustomerCardTypes
|
|
||||||
> = {
|
|
||||||
getCards: GetCardsHook<T>
|
|
||||||
addItem: AddItemHandler<T>
|
|
||||||
updateItem: UpdateItemHandler<T>
|
|
||||||
removeItem: RemoveItemHandler<T>
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export type CustomerCardSchema<
|
/**
|
||||||
T extends CustomerCardTypes = CustomerCardTypes
|
* Customer card API handlers.
|
||||||
> = {
|
*/
|
||||||
|
export type AddItemHandler = AddItemHook & {
|
||||||
|
body: { cartId: string }
|
||||||
|
}
|
||||||
|
|
||||||
|
export type UpdateItemHandler = UpdateItemHook & {
|
||||||
|
data: Card
|
||||||
|
body: { cartId: string }
|
||||||
|
}
|
||||||
|
|
||||||
|
export type RemoveItemHandler = RemoveItemHook & {
|
||||||
|
body: { cartId: string }
|
||||||
|
}
|
||||||
|
|
||||||
|
export type CustomerCardHandlers = {
|
||||||
|
getCards: GetCardsHook
|
||||||
|
addItem: AddItemHandler
|
||||||
|
updateItem: UpdateItemHandler
|
||||||
|
removeItem: RemoveItemHandler
|
||||||
|
}
|
||||||
|
|
||||||
|
export type CustomerCardSchema = {
|
||||||
endpoint: {
|
endpoint: {
|
||||||
options: {}
|
options: {}
|
||||||
handlers: CustomerCardHandlers<T>
|
handlers: CustomerCardHandlers
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,24 +1,53 @@
|
|||||||
export * as Card from './card'
|
export * as Card from './card'
|
||||||
export * as Address from './address'
|
export * as Address from './address'
|
||||||
|
|
||||||
// TODO: define this type
|
export interface Customer {
|
||||||
export type Customer = any
|
/**
|
||||||
|
* The unique identifier for the customer.
|
||||||
export type CustomerTypes = {
|
*/
|
||||||
customer: Customer
|
id: string
|
||||||
|
/**
|
||||||
|
* The customer's first name.
|
||||||
|
*/
|
||||||
|
firstName: string
|
||||||
|
/**
|
||||||
|
* The customer's last name.
|
||||||
|
*/
|
||||||
|
lastName: string
|
||||||
|
/**
|
||||||
|
* The customer's email address.
|
||||||
|
*/
|
||||||
|
email?: string
|
||||||
|
/**
|
||||||
|
* The customer's phone number.
|
||||||
|
* @optional
|
||||||
|
*/
|
||||||
|
phone?: string
|
||||||
|
/**
|
||||||
|
* The customer's company name.
|
||||||
|
*/
|
||||||
|
company?: string
|
||||||
|
/**
|
||||||
|
* The customer's notes.
|
||||||
|
*/
|
||||||
|
notes?: string
|
||||||
|
/**
|
||||||
|
* Indicates wathever the customer accepts marketing, such as email newsletters.
|
||||||
|
*/
|
||||||
|
acceptsMarketing?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
export type CustomerHook<T extends CustomerTypes = CustomerTypes> = {
|
export type CustomerHook = {
|
||||||
data: T['customer'] | null
|
data: Customer | null | undefined
|
||||||
fetchData: { customer: T['customer'] } | null
|
fetchData: { customer: Customer } | null
|
||||||
}
|
}
|
||||||
|
|
||||||
export type CustomerSchema<T extends CustomerTypes = CustomerTypes> = {
|
export type CustomerSchema = {
|
||||||
endpoint: {
|
endpoint: {
|
||||||
options: {}
|
options: {}
|
||||||
handlers: {
|
handlers: {
|
||||||
getLoggedInCustomer: {
|
getLoggedInCustomer: {
|
||||||
data: { customer: T['customer'] } | null
|
data: { customer: Customer } | null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,24 +1,26 @@
|
|||||||
export type LoginBody = {
|
export interface LoginBody {
|
||||||
|
/**
|
||||||
|
* The user's email address.
|
||||||
|
*/
|
||||||
email: string
|
email: string
|
||||||
|
/**
|
||||||
|
* The user's password.
|
||||||
|
*/
|
||||||
password: string
|
password: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export type LoginTypes = {
|
export type LoginHook = {
|
||||||
body: LoginBody
|
|
||||||
}
|
|
||||||
|
|
||||||
export type LoginHook<T extends LoginTypes = LoginTypes> = {
|
|
||||||
data: null
|
data: null
|
||||||
actionInput: LoginBody
|
actionInput: LoginBody
|
||||||
fetcherInput: LoginBody
|
fetcherInput: LoginBody
|
||||||
body: T['body']
|
body: LoginBody
|
||||||
}
|
}
|
||||||
|
|
||||||
export type LoginSchema<T extends LoginTypes = LoginTypes> = {
|
export type LoginSchema = {
|
||||||
endpoint: {
|
endpoint: {
|
||||||
options: {}
|
options: {}
|
||||||
handlers: {
|
handlers: {
|
||||||
login: LoginHook<T>
|
login: LoginHook
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,17 +1,15 @@
|
|||||||
export type LogoutTypes = {
|
export type LogoutHook = {
|
||||||
body: { redirectTo?: string }
|
|
||||||
}
|
|
||||||
|
|
||||||
export type LogoutHook<T extends LogoutTypes = LogoutTypes> = {
|
|
||||||
data: null
|
data: null
|
||||||
body: T['body']
|
body: {
|
||||||
|
redirectTo?: string
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export type LogoutSchema<T extends LogoutTypes = LogoutTypes> = {
|
export type LogoutSchema = {
|
||||||
endpoint: {
|
endpoint: {
|
||||||
options: {}
|
options: {}
|
||||||
handlers: {
|
handlers: {
|
||||||
logout: LogoutHook<T>
|
logout: LogoutHook
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,28 +1,43 @@
|
|||||||
// TODO: define this type
|
|
||||||
export type Page = {
|
export type Page = {
|
||||||
// ID of the Web page.
|
/**
|
||||||
|
* The unique identifier for the page.
|
||||||
|
*/
|
||||||
id: string
|
id: string
|
||||||
// Page name, as displayed on the storefront.
|
/**
|
||||||
|
* Page name, as displayed on the storefront.
|
||||||
|
*/
|
||||||
name: string
|
name: string
|
||||||
// Relative URL on the storefront for this page.
|
/**
|
||||||
|
* Relative URL on the storefront for this page.
|
||||||
|
*/
|
||||||
url?: string
|
url?: string
|
||||||
// HTML or variable that populates this page’s `<body>` element, in default/desktop view. Required in POST if page type is `raw`.
|
/**
|
||||||
|
* HTML or variable that populates this page’s `<body>` element, in default/desktop view. Required in POST if page type is `raw`.
|
||||||
|
*/
|
||||||
body: string
|
body: string
|
||||||
// If true, this page appears in the storefront’s navigation menu.
|
/**
|
||||||
|
* If true, this page appears in the storefront’s navigation menu.
|
||||||
|
*/
|
||||||
is_visible?: boolean
|
is_visible?: boolean
|
||||||
// Order in which this page should display on the storefront. (Lower integers specify earlier display.)
|
/**
|
||||||
|
* Order in which this page should display on the storefront. (Lower integers specify earlier display.)
|
||||||
|
*/
|
||||||
sort_order?: number
|
sort_order?: number
|
||||||
}
|
}
|
||||||
|
|
||||||
export type PageTypes = {
|
/**
|
||||||
page: Page
|
* Operation to get all pages.
|
||||||
|
*/
|
||||||
|
export type GetAllPagesOperation = {
|
||||||
|
data: { pages: Page[] }
|
||||||
}
|
}
|
||||||
|
|
||||||
export type GetAllPagesOperation<T extends PageTypes = PageTypes> = {
|
export type GetPageOperation = {
|
||||||
data: { pages: T['page'][] }
|
data: { page?: Page }
|
||||||
}
|
variables: {
|
||||||
|
/**
|
||||||
export type GetPageOperation<T extends PageTypes = PageTypes> = {
|
* The unique identifier of the page.
|
||||||
data: { page?: T['page'] }
|
*/
|
||||||
variables: { id: string }
|
id: string
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,91 +1,207 @@
|
|||||||
export type ProductImage = {
|
import { Image } from './common'
|
||||||
url: string
|
|
||||||
alt?: string
|
|
||||||
}
|
|
||||||
|
|
||||||
export type ProductPrice = {
|
export interface ProductPrice {
|
||||||
|
/**
|
||||||
|
* The price after all discounts are applied.
|
||||||
|
*/
|
||||||
value: number
|
value: number
|
||||||
|
/**
|
||||||
|
* The currency code for the price. This is a 3-letter ISO 4217 code.
|
||||||
|
* @example USD
|
||||||
|
*/
|
||||||
currencyCode?: 'USD' | 'EUR' | 'ARS' | 'GBP' | string
|
currencyCode?: 'USD' | 'EUR' | 'ARS' | 'GBP' | string
|
||||||
|
/**
|
||||||
|
* The retail price of the product. This can be used to mark a product as on sale, when `retailPrice` is higher than the price a.k.a `value`.
|
||||||
|
*/
|
||||||
retailPrice?: number
|
retailPrice?: number
|
||||||
salePrice?: number
|
|
||||||
listPrice?: number
|
|
||||||
extendedSalePrice?: number
|
|
||||||
extendedListPrice?: number
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export type ProductOption = {
|
export interface ProductOption {
|
||||||
__typename?: 'MultipleChoiceOption'
|
__typename?: 'MultipleChoiceOption'
|
||||||
|
/**
|
||||||
|
* The unique identifier for the option.
|
||||||
|
*/
|
||||||
id: string
|
id: string
|
||||||
|
/**
|
||||||
|
* The product option’s name.
|
||||||
|
* @example `Color` or `Size`
|
||||||
|
*/
|
||||||
displayName: string
|
displayName: string
|
||||||
|
/**
|
||||||
|
* List of option values.
|
||||||
|
* @example `["Red", "Green", "Blue"]`
|
||||||
|
*/
|
||||||
values: ProductOptionValues[]
|
values: ProductOptionValues[]
|
||||||
}
|
}
|
||||||
|
|
||||||
export type ProductOptionValues = {
|
export interface ProductOptionValues {
|
||||||
|
/**
|
||||||
|
* A string that uniquely identifies the option value.
|
||||||
|
*/
|
||||||
label: string
|
label: string
|
||||||
|
/**
|
||||||
|
* List of hex colors used to display the actual colors in the swatches instead of the name.
|
||||||
|
*/
|
||||||
hexColors?: string[]
|
hexColors?: string[]
|
||||||
}
|
}
|
||||||
|
|
||||||
export type ProductVariant = {
|
export interface ProductVariant {
|
||||||
id: string | number
|
/**
|
||||||
|
* The unique identifier for the variant.
|
||||||
|
*/
|
||||||
|
id: string
|
||||||
|
/**
|
||||||
|
* The SKU (stock keeping unit) associated with the product variant.
|
||||||
|
*/
|
||||||
|
sku?: string
|
||||||
|
/**
|
||||||
|
* The product variant’s name, or the product's name.
|
||||||
|
*/
|
||||||
|
name?: string
|
||||||
|
/**
|
||||||
|
* List of product options.
|
||||||
|
*/
|
||||||
options: ProductOption[]
|
options: ProductOption[]
|
||||||
|
/**
|
||||||
|
* The product variant’s price after all discounts are applied.
|
||||||
|
*/
|
||||||
|
price?: ProductPrice
|
||||||
|
/**
|
||||||
|
* The retail price of the product. This can be used to mark a product as on sale, when `retailPrice` is higher than the `price`.
|
||||||
|
*/
|
||||||
|
retailPrice?: ProductPrice
|
||||||
|
/**
|
||||||
|
* Indicates if the variant is available for sale.
|
||||||
|
*/
|
||||||
availableForSale?: boolean
|
availableForSale?: boolean
|
||||||
|
/**
|
||||||
|
* Whether a customer needs to provide a shipping address when placing an order for the product variant.
|
||||||
|
*/
|
||||||
|
requiresShipping?: boolean
|
||||||
|
/**
|
||||||
|
* The image associated with the variant.
|
||||||
|
*/
|
||||||
|
image?: Image
|
||||||
}
|
}
|
||||||
|
|
||||||
export type Product = {
|
export interface Product {
|
||||||
|
/**
|
||||||
|
* The unique identifier for the product.
|
||||||
|
*/
|
||||||
id: string
|
id: string
|
||||||
|
/**
|
||||||
|
* The name of the product.
|
||||||
|
*/
|
||||||
name: string
|
name: string
|
||||||
|
/**
|
||||||
|
* Stripped description of the product, single line.
|
||||||
|
*/
|
||||||
description: string
|
description: string
|
||||||
|
/**
|
||||||
|
* The description of the product, complete with HTML formatting.
|
||||||
|
*/
|
||||||
descriptionHtml?: string
|
descriptionHtml?: string
|
||||||
|
/**
|
||||||
|
* The SKU (stock keeping unit) associated with the product.
|
||||||
|
*/
|
||||||
sku?: string
|
sku?: string
|
||||||
|
/**
|
||||||
|
* A human-friendly unique string for the product, automatically generated from its title.
|
||||||
|
*/
|
||||||
slug?: string
|
slug?: string
|
||||||
|
/**
|
||||||
|
* Relative URL on the storefront for the product.
|
||||||
|
*/
|
||||||
path?: string
|
path?: string
|
||||||
images: ProductImage[]
|
/**
|
||||||
|
* List of images associated with the product.
|
||||||
|
*/
|
||||||
|
images: Image[]
|
||||||
|
/**
|
||||||
|
* List of the product’s variants.
|
||||||
|
*/
|
||||||
variants: ProductVariant[]
|
variants: ProductVariant[]
|
||||||
|
/**
|
||||||
|
* The product's base price. Could be the minimum value, or default variant price.
|
||||||
|
*/
|
||||||
price: ProductPrice
|
price: ProductPrice
|
||||||
|
/**
|
||||||
|
* List of product's options.
|
||||||
|
*/
|
||||||
options: ProductOption[]
|
options: ProductOption[]
|
||||||
|
/**
|
||||||
|
* The product’s vendor name.
|
||||||
|
*/
|
||||||
vendor?: string
|
vendor?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export type SearchProductsBody = {
|
export interface SearchProductsBody {
|
||||||
|
/**
|
||||||
|
* The search query string to filter the products by.
|
||||||
|
*/
|
||||||
search?: string
|
search?: string
|
||||||
categoryId?: string | number
|
/**
|
||||||
brandId?: string | number
|
* The category ID to filter the products by.
|
||||||
|
*/
|
||||||
|
categoryId?: string
|
||||||
|
/**
|
||||||
|
* The brand ID to filter the products by.
|
||||||
|
*/
|
||||||
|
brandId?: string
|
||||||
|
/**
|
||||||
|
* The sort key to sort the products by.
|
||||||
|
* @example 'trending-desc' | 'latest-desc' | 'price-asc' | 'price-desc'
|
||||||
|
*/
|
||||||
sort?: string
|
sort?: string
|
||||||
|
/**
|
||||||
|
* The locale code, used to localize the product data (if the provider supports it).
|
||||||
|
*/
|
||||||
locale?: string
|
locale?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export type ProductTypes = {
|
/**
|
||||||
product: Product
|
* Fetches a list of products based on the given search criteria.
|
||||||
searchBody: SearchProductsBody
|
*/
|
||||||
}
|
export type SearchProductsHook = {
|
||||||
|
|
||||||
export type SearchProductsHook<T extends ProductTypes = ProductTypes> = {
|
|
||||||
data: {
|
data: {
|
||||||
products: T['product'][]
|
/**
|
||||||
|
* List of products matching the query.
|
||||||
|
*/
|
||||||
|
products: Product[]
|
||||||
|
/**
|
||||||
|
* Indicates if there are any products matching the query.
|
||||||
|
*/
|
||||||
found: boolean
|
found: boolean
|
||||||
}
|
}
|
||||||
body: T['searchBody']
|
body: SearchProductsBody
|
||||||
input: T['searchBody']
|
input: SearchProductsBody
|
||||||
fetcherInput: T['searchBody']
|
fetcherInput: SearchProductsBody
|
||||||
}
|
}
|
||||||
|
|
||||||
export type ProductsSchema<T extends ProductTypes = ProductTypes> = {
|
/**
|
||||||
|
* Product API schema
|
||||||
|
*/
|
||||||
|
|
||||||
|
export type ProductsSchema = {
|
||||||
endpoint: {
|
endpoint: {
|
||||||
options: {}
|
options: {}
|
||||||
handlers: {
|
handlers: {
|
||||||
getProducts: SearchProductsHook<T>
|
getProducts: SearchProductsHook
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export type GetAllProductPathsOperation<T extends ProductTypes = ProductTypes> =
|
/**
|
||||||
{
|
* Product operations
|
||||||
data: { products: Pick<T['product'], 'path'>[] }
|
*/
|
||||||
variables: { first?: number }
|
|
||||||
}
|
|
||||||
|
|
||||||
export type GetAllProductsOperation<T extends ProductTypes = ProductTypes> = {
|
export type GetAllProductPathsOperation = {
|
||||||
data: { products: T['product'][] }
|
data: { products: Pick<Product, 'path'>[] }
|
||||||
|
variables: { first?: number }
|
||||||
|
}
|
||||||
|
|
||||||
|
export type GetAllProductsOperation = {
|
||||||
|
data: { products: Product[] }
|
||||||
variables: {
|
variables: {
|
||||||
relevance?: 'featured' | 'best_selling' | 'newest'
|
relevance?: 'featured' | 'best_selling' | 'newest'
|
||||||
ids?: string[]
|
ids?: string[]
|
||||||
@ -93,7 +209,7 @@ export type GetAllProductsOperation<T extends ProductTypes = ProductTypes> = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export type GetProductOperation<T extends ProductTypes = ProductTypes> = {
|
export type GetProductOperation = {
|
||||||
data: { product?: T['product'] }
|
data: { product?: Product }
|
||||||
variables: { path: string; slug?: never } | { path?: never; slug: string }
|
variables: { path: string; slug?: never } | { path?: never; slug: string }
|
||||||
}
|
}
|
||||||
|
@ -1,26 +1,34 @@
|
|||||||
export type SignupBody = {
|
export interface SignupBody {
|
||||||
|
/**
|
||||||
|
* The user's first name.
|
||||||
|
*/
|
||||||
firstName: string
|
firstName: string
|
||||||
|
/**
|
||||||
|
* The user's last name.
|
||||||
|
*/
|
||||||
lastName: string
|
lastName: string
|
||||||
|
/**
|
||||||
|
* The user's email address.
|
||||||
|
*/
|
||||||
email: string
|
email: string
|
||||||
|
/**
|
||||||
|
* The user's password.
|
||||||
|
*/
|
||||||
password: string
|
password: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export type SignupTypes = {
|
export type SignupHook = {
|
||||||
body: SignupBody
|
|
||||||
}
|
|
||||||
|
|
||||||
export type SignupHook<T extends SignupTypes = SignupTypes> = {
|
|
||||||
data: null
|
data: null
|
||||||
body: T['body']
|
body: SignupBody
|
||||||
actionInput: T['body']
|
actionInput: SignupBody
|
||||||
fetcherInput: T['body']
|
fetcherInput: SignupBody
|
||||||
}
|
}
|
||||||
|
|
||||||
export type SignupSchema<T extends SignupTypes = SignupTypes> = {
|
export type SignupSchema = {
|
||||||
endpoint: {
|
endpoint: {
|
||||||
options: {}
|
options: {}
|
||||||
handlers: {
|
handlers: {
|
||||||
signup: SignupHook<T>
|
signup: SignupHook
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,20 +1,51 @@
|
|||||||
export type Category = {
|
export interface Category {
|
||||||
|
/**
|
||||||
|
* Unique identifier for the category.
|
||||||
|
*/
|
||||||
id: string
|
id: string
|
||||||
|
/**
|
||||||
|
* Name of the category.
|
||||||
|
*/
|
||||||
name: string
|
name: string
|
||||||
|
/**
|
||||||
|
* A human-friendly unique string for the category, automatically generated from its name.
|
||||||
|
* @example "t-shirts"
|
||||||
|
*/
|
||||||
slug: string
|
slug: string
|
||||||
|
/**
|
||||||
|
* Relative URL on the storefront for the category.
|
||||||
|
* @example /t-shirts
|
||||||
|
*/
|
||||||
path: string
|
path: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export type Brand = any
|
export interface Brand {
|
||||||
|
/**
|
||||||
export type SiteTypes = {
|
* Unique identifier for the brand.
|
||||||
category: Category
|
*/
|
||||||
brand: Brand
|
id: string
|
||||||
|
/**
|
||||||
|
* Name of the brand.
|
||||||
|
*/
|
||||||
|
name: string
|
||||||
|
/**
|
||||||
|
* A human-friendly unique string for the category, automatically generated from its name.
|
||||||
|
* @example "acme"
|
||||||
|
*/
|
||||||
|
slug: string
|
||||||
|
/**
|
||||||
|
* Relative URL on the storefront for this brand.
|
||||||
|
* @example "/acme"
|
||||||
|
*/
|
||||||
|
path: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export type GetSiteInfoOperation<T extends SiteTypes = SiteTypes> = {
|
/**
|
||||||
|
* Operation to get site information. This includes categories and brands.
|
||||||
|
*/
|
||||||
|
export type GetSiteInfoOperation = {
|
||||||
data: {
|
data: {
|
||||||
categories: T['category'][]
|
categories: Category[]
|
||||||
brands: T['brand'][]
|
brands: Brand[]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,60 +1,97 @@
|
|||||||
// TODO: define this type
|
import { Product } from './product'
|
||||||
export type Wishlist = any
|
|
||||||
|
|
||||||
export type WishlistItemBody = {
|
export interface WishlistItem {
|
||||||
variantId: string | number
|
/**
|
||||||
|
* The unique identifier for the item.
|
||||||
|
*/
|
||||||
|
id: string
|
||||||
|
/**
|
||||||
|
* The unique identifier for the product associated with the wishlist item.
|
||||||
|
*/
|
||||||
productId: string
|
productId: string
|
||||||
|
/**
|
||||||
|
* The unique identifier for the product variant associated with the wishlist item.
|
||||||
|
*/
|
||||||
|
variantId: string
|
||||||
|
/**
|
||||||
|
* The product associated with the wishlist item.
|
||||||
|
*/
|
||||||
|
product: Product
|
||||||
}
|
}
|
||||||
|
|
||||||
export type WishlistTypes = {
|
export interface Wishlist {
|
||||||
wishlist: Wishlist
|
/**
|
||||||
itemBody: WishlistItemBody
|
* The unique identifier for the wishlist.
|
||||||
|
*/
|
||||||
|
id: string
|
||||||
|
/**
|
||||||
|
* List of items in the wishlist.
|
||||||
|
*/
|
||||||
|
items: WishlistItem[]
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Some providers require a token to add an item to a wishlist
|
||||||
|
*/
|
||||||
|
token?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export type GetWishlistHook<T extends WishlistTypes = WishlistTypes> = {
|
export interface WishlistItemBody {
|
||||||
data: T['wishlist'] | null
|
/**
|
||||||
|
* The unique identifier for the product variant to associate with the wishlist.
|
||||||
|
*/
|
||||||
|
variantId: string
|
||||||
|
/**
|
||||||
|
* The unique identifier for the product to associate with the wishlist.
|
||||||
|
*/
|
||||||
|
productId: string
|
||||||
|
/**
|
||||||
|
* Some providers require to provide a token to make a request
|
||||||
|
*/
|
||||||
|
wishlistToken?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export type GetWishlistHook = {
|
||||||
|
data: Wishlist | null | undefined
|
||||||
body: { includeProducts?: boolean }
|
body: { includeProducts?: boolean }
|
||||||
input: { includeProducts?: boolean }
|
input: { includeProducts?: boolean }
|
||||||
fetcherInput: { customerId: string; includeProducts?: boolean }
|
fetcherInput: { customerId: string; includeProducts?: boolean }
|
||||||
swrState: { isEmpty: boolean }
|
swrState: { isEmpty: boolean }
|
||||||
}
|
}
|
||||||
|
|
||||||
export type AddItemHook<T extends WishlistTypes = WishlistTypes> = {
|
export type AddItemHook = {
|
||||||
data: T['wishlist']
|
data: Wishlist | null | undefined
|
||||||
body: { item: T['itemBody'] }
|
body: { item: WishlistItemBody }
|
||||||
fetcherInput: { item: T['itemBody'] }
|
fetcherInput: { item: WishlistItemBody }
|
||||||
actionInput: T['itemBody']
|
actionInput: WishlistItemBody
|
||||||
}
|
}
|
||||||
|
|
||||||
export type RemoveItemHook<T extends WishlistTypes = WishlistTypes> = {
|
export type RemoveItemHook = {
|
||||||
data: T['wishlist'] | null
|
data: Wishlist | null | undefined
|
||||||
body: { itemId: string }
|
body: { itemId: string; wishlistToken?: string }
|
||||||
fetcherInput: { itemId: string }
|
fetcherInput: { itemId: string; wishlistToken?: string }
|
||||||
actionInput: { id: string }
|
actionInput: { id: string }
|
||||||
input: { wishlist?: { includeProducts?: boolean } }
|
input: { wishlist?: { includeProducts?: boolean } }
|
||||||
}
|
}
|
||||||
|
|
||||||
export type WishlistSchema<T extends WishlistTypes = WishlistTypes> = {
|
export type WishlistSchema = {
|
||||||
endpoint: {
|
endpoint: {
|
||||||
options: {}
|
options: {}
|
||||||
handlers: {
|
handlers: {
|
||||||
getWishlist: GetWishlistHook<T> & {
|
getWishlist: GetWishlistHook & {
|
||||||
data: T['wishlist'] | null
|
data: Wishlist | null
|
||||||
body: { customerToken?: string }
|
body: { customerToken?: string }
|
||||||
}
|
}
|
||||||
addItem: AddItemHook<T> & {
|
addItem: AddItemHook & {
|
||||||
body: { customerToken?: string }
|
body: { customerToken?: string }
|
||||||
}
|
}
|
||||||
removeItem: RemoveItemHook<T> & {
|
removeItem: RemoveItemHook & {
|
||||||
body: { customerToken?: string }
|
body: { customerToken?: string }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export type GetCustomerWishlistOperation<
|
export type GetCustomerWishlistOperation = {
|
||||||
T extends WishlistTypes = WishlistTypes
|
data: { wishlist?: Wishlist }
|
||||||
> = {
|
|
||||||
data: { wishlist?: T['wishlist'] }
|
|
||||||
variables: { customerId: string }
|
variables: { customerId: string }
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@ import type { AddItemHook } from '../types/wishlist'
|
|||||||
import type { Provider } from '..'
|
import type { Provider } from '..'
|
||||||
|
|
||||||
export type UseAddItem<
|
export type UseAddItem<
|
||||||
H extends MutationHook<AddItemHook<any>> = MutationHook<AddItemHook>
|
H extends MutationHook<AddItemHook> = MutationHook<AddItemHook>
|
||||||
> = ReturnType<H['useHook']>
|
> = ReturnType<H['useHook']>
|
||||||
|
|
||||||
export const fetcher = mutationFetcher
|
export const fetcher = mutationFetcher
|
||||||
|
@ -5,7 +5,7 @@ import type { RemoveItemHook } from '../types/wishlist'
|
|||||||
import type { Provider } from '..'
|
import type { Provider } from '..'
|
||||||
|
|
||||||
export type UseRemoveItem<
|
export type UseRemoveItem<
|
||||||
H extends MutationHook<RemoveItemHook<any>> = MutationHook<RemoveItemHook>
|
H extends MutationHook<RemoveItemHook> = MutationHook<RemoveItemHook>
|
||||||
> = ReturnType<H['useHook']>
|
> = ReturnType<H['useHook']>
|
||||||
|
|
||||||
export const fetcher: HookFetcherFn<RemoveItemHook> = mutationFetcher
|
export const fetcher: HookFetcherFn<RemoveItemHook> = mutationFetcher
|
||||||
|
@ -5,7 +5,7 @@ import type { GetWishlistHook } from '../types/wishlist'
|
|||||||
import type { Provider } from '..'
|
import type { Provider } from '..'
|
||||||
|
|
||||||
export type UseWishlist<
|
export type UseWishlist<
|
||||||
H extends SWRHook<GetWishlistHook<any>> = SWRHook<GetWishlistHook>
|
H extends SWRHook<GetWishlistHook> = SWRHook<GetWishlistHook>
|
||||||
> = ReturnType<H['useHook']>
|
> = ReturnType<H['useHook']>
|
||||||
|
|
||||||
export const fetcher: HookFetcherFn<GetWishlistHook> = SWRFetcher
|
export const fetcher: HookFetcherFn<GetWishlistHook> = SWRFetcher
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { GetAPISchema, createEndpoint } from '@vercel/commerce/api'
|
import { GetAPISchema, createEndpoint } from '@vercel/commerce/api'
|
||||||
import checkoutEndpoint from '@vercel/commerce/api/endpoints/checkout'
|
import checkoutEndpoint from '@vercel/commerce/api/endpoints/checkout'
|
||||||
import type { CheckoutSchema } from '../../../types/checkout'
|
import type { CheckoutSchema } from '@vercel/commerce/types/checkout'
|
||||||
import type { CommercejsAPI } from '../..'
|
import type { CommercejsAPI } from '../..'
|
||||||
|
|
||||||
import submitCheckout from './submit-checkout'
|
import submitCheckout from './submit-checkout'
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { GetAPISchema, createEndpoint } from '@vercel/commerce/api'
|
import { GetAPISchema, createEndpoint } from '@vercel/commerce/api'
|
||||||
import loginEndpoint from '@vercel/commerce/api/endpoints/login'
|
import loginEndpoint from '@vercel/commerce/api/endpoints/login'
|
||||||
import type { LoginSchema } from '../../../types/login'
|
import type { LoginSchema } from '@vercel/commerce/types/login'
|
||||||
import type { CommercejsAPI } from '../..'
|
import type { CommercejsAPI } from '../..'
|
||||||
import login from './login'
|
import login from './login'
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import type { CommercejsConfig } from '..'
|
import type { CommercejsConfig } from '..'
|
||||||
import { GetAllPagesOperation } from '../../types/page'
|
import { GetAllPagesOperation } from '@vercel/commerce/types/page'
|
||||||
|
|
||||||
export type Page = { url: string }
|
export type Page = { url: string }
|
||||||
export type GetAllPagesResult = { pages: Page[] }
|
export type GetAllPagesResult = { pages: Page[] }
|
||||||
|
@ -1,9 +1,5 @@
|
|||||||
import type { OperationContext } from '@vercel/commerce/api/operations'
|
import type { OperationContext } from '@vercel/commerce/api/operations'
|
||||||
import type {
|
import type { GetAllProductPathsOperation } from '@vercel/commerce/types/product'
|
||||||
GetAllProductPathsOperation,
|
|
||||||
CommercejsProduct,
|
|
||||||
} from '../../types/product'
|
|
||||||
|
|
||||||
import type { CommercejsConfig, Provider } from '..'
|
import type { CommercejsConfig, Provider } from '..'
|
||||||
|
|
||||||
export type GetAllProductPathsResult = {
|
export type GetAllProductPathsResult = {
|
||||||
@ -22,7 +18,7 @@ export default function getAllProductPathsOperation({
|
|||||||
const { data } = await sdkFetch('products', 'list')
|
const { data } = await sdkFetch('products', 'list')
|
||||||
|
|
||||||
// Match a path for every product retrieved
|
// Match a path for every product retrieved
|
||||||
const productPaths = data.map(({ permalink }: CommercejsProduct) => ({
|
const productPaths = data.map(({ permalink }: { permalink: string }) => ({
|
||||||
path: `/${permalink}`,
|
path: `/${permalink}`,
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import type { OperationContext } from '@vercel/commerce/api/operations'
|
import type { OperationContext } from '@vercel/commerce/api/operations'
|
||||||
import type { GetAllProductsOperation } from '../../types/product'
|
import type { GetAllProductsOperation } from '@vercel/commerce/types/product'
|
||||||
import type { CommercejsConfig, Provider } from '../index'
|
import type { CommercejsConfig, Provider } from '../index'
|
||||||
|
|
||||||
import { normalizeProduct } from '../../utils/normalize-product'
|
import { normalizeProduct } from '../../utils/normalize-product'
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { GetPageOperation } from '../../types/page'
|
import { GetPageOperation } from '@vercel/commerce/types/page'
|
||||||
|
|
||||||
export type Page = any
|
export type Page = any
|
||||||
export type GetPageResult = { page?: Page }
|
export type GetPageResult = { page?: Page }
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user