mirror of
https://github.com/vercel/commerce.git
synced 2025-07-23 04:36:49 +00:00
Added framework folder
This commit is contained in:
43
framework/bigcommerce/api/operations/get-all-pages.ts
Normal file
43
framework/bigcommerce/api/operations/get-all-pages.ts
Normal file
@@ -0,0 +1,43 @@
|
||||
import type { RecursivePartial, RecursiveRequired } from '../utils/types'
|
||||
import { BigcommerceConfig, getConfig } from '..'
|
||||
import { definitions } from '../definitions/store-content'
|
||||
|
||||
export type Page = definitions['page_Full']
|
||||
|
||||
export type GetAllPagesResult<
|
||||
T extends { pages: any[] } = { pages: Page[] }
|
||||
> = T
|
||||
|
||||
async function getAllPages(opts?: {
|
||||
config?: BigcommerceConfig
|
||||
preview?: boolean
|
||||
}): Promise<GetAllPagesResult>
|
||||
|
||||
async function getAllPages<T extends { pages: any[] }>(opts: {
|
||||
url: string
|
||||
config?: BigcommerceConfig
|
||||
preview?: boolean
|
||||
}): Promise<GetAllPagesResult<T>>
|
||||
|
||||
async function getAllPages({
|
||||
config,
|
||||
preview,
|
||||
}: {
|
||||
url?: string
|
||||
config?: BigcommerceConfig
|
||||
preview?: boolean
|
||||
} = {}): Promise<GetAllPagesResult> {
|
||||
config = getConfig(config)
|
||||
// RecursivePartial forces the method to check for every prop in the data, which is
|
||||
// required in case there's a custom `url`
|
||||
const { data } = await config.storeApiFetch<
|
||||
RecursivePartial<{ data: Page[] }>
|
||||
>('/v3/content/pages')
|
||||
const pages = (data as RecursiveRequired<typeof data>) ?? []
|
||||
|
||||
return {
|
||||
pages: preview ? pages : pages.filter((p) => p.is_visible),
|
||||
}
|
||||
}
|
||||
|
||||
export default getAllPages
|
@@ -0,0 +1,71 @@
|
||||
import type {
|
||||
GetAllProductPathsQuery,
|
||||
GetAllProductPathsQueryVariables,
|
||||
} from '../../schema'
|
||||
import type { RecursivePartial, RecursiveRequired } from '../utils/types'
|
||||
import filterEdges from '../utils/filter-edges'
|
||||
import { BigcommerceConfig, getConfig } from '..'
|
||||
|
||||
export const getAllProductPathsQuery = /* GraphQL */ `
|
||||
query getAllProductPaths($first: Int = 100) {
|
||||
site {
|
||||
products(first: $first) {
|
||||
edges {
|
||||
node {
|
||||
path
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
export type ProductPath = NonNullable<
|
||||
NonNullable<GetAllProductPathsQuery['site']['products']['edges']>[0]
|
||||
>
|
||||
|
||||
export type ProductPaths = ProductPath[]
|
||||
|
||||
export type { GetAllProductPathsQueryVariables }
|
||||
|
||||
export type GetAllProductPathsResult<
|
||||
T extends { products: any[] } = { products: ProductPaths }
|
||||
> = T
|
||||
|
||||
async function getAllProductPaths(opts?: {
|
||||
variables?: GetAllProductPathsQueryVariables
|
||||
config?: BigcommerceConfig
|
||||
}): Promise<GetAllProductPathsResult>
|
||||
|
||||
async function getAllProductPaths<
|
||||
T extends { products: any[] },
|
||||
V = any
|
||||
>(opts: {
|
||||
query: string
|
||||
variables?: V
|
||||
config?: BigcommerceConfig
|
||||
}): Promise<GetAllProductPathsResult<T>>
|
||||
|
||||
async function getAllProductPaths({
|
||||
query = getAllProductPathsQuery,
|
||||
variables,
|
||||
config,
|
||||
}: {
|
||||
query?: string
|
||||
variables?: GetAllProductPathsQueryVariables
|
||||
config?: BigcommerceConfig
|
||||
} = {}): Promise<GetAllProductPathsResult> {
|
||||
config = getConfig(config)
|
||||
// RecursivePartial forces the method to check for every prop in the data, which is
|
||||
// required in case there's a custom `query`
|
||||
const { data } = await config.fetch<
|
||||
RecursivePartial<GetAllProductPathsQuery>
|
||||
>(query, { variables })
|
||||
const products = data.site?.products?.edges
|
||||
|
||||
return {
|
||||
products: filterEdges(products as RecursiveRequired<typeof products>),
|
||||
}
|
||||
}
|
||||
|
||||
export default getAllProductPaths
|
132
framework/bigcommerce/api/operations/get-all-products.ts
Normal file
132
framework/bigcommerce/api/operations/get-all-products.ts
Normal file
@@ -0,0 +1,132 @@
|
||||
import type {
|
||||
GetAllProductsQuery,
|
||||
GetAllProductsQueryVariables,
|
||||
} from '../../schema'
|
||||
import type { RecursivePartial, RecursiveRequired } from '../utils/types'
|
||||
import filterEdges from '../utils/filter-edges'
|
||||
import setProductLocaleMeta from '../utils/set-product-locale-meta'
|
||||
import { productConnectionFragment } from '../fragments/product'
|
||||
import { BigcommerceConfig, getConfig } from '..'
|
||||
|
||||
export const getAllProductsQuery = /* GraphQL */ `
|
||||
query getAllProducts(
|
||||
$hasLocale: Boolean = false
|
||||
$locale: String = "null"
|
||||
$entityIds: [Int!]
|
||||
$first: Int = 10
|
||||
$products: Boolean = false
|
||||
$featuredProducts: Boolean = false
|
||||
$bestSellingProducts: Boolean = false
|
||||
$newestProducts: Boolean = false
|
||||
) {
|
||||
site {
|
||||
products(first: $first, entityIds: $entityIds) @include(if: $products) {
|
||||
...productConnnection
|
||||
}
|
||||
featuredProducts(first: $first) @include(if: $featuredProducts) {
|
||||
...productConnnection
|
||||
}
|
||||
bestSellingProducts(first: $first) @include(if: $bestSellingProducts) {
|
||||
...productConnnection
|
||||
}
|
||||
newestProducts(first: $first) @include(if: $newestProducts) {
|
||||
...productConnnection
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
${productConnectionFragment}
|
||||
`
|
||||
|
||||
export type ProductEdge = NonNullable<
|
||||
NonNullable<GetAllProductsQuery['site']['products']['edges']>[0]
|
||||
>
|
||||
|
||||
export type ProductNode = ProductEdge['node']
|
||||
|
||||
export type GetAllProductsResult<
|
||||
T extends Record<keyof GetAllProductsResult, any[]> = {
|
||||
products: ProductEdge[]
|
||||
}
|
||||
> = T
|
||||
|
||||
const FIELDS = [
|
||||
'products',
|
||||
'featuredProducts',
|
||||
'bestSellingProducts',
|
||||
'newestProducts',
|
||||
]
|
||||
|
||||
export type ProductTypes =
|
||||
| 'products'
|
||||
| 'featuredProducts'
|
||||
| 'bestSellingProducts'
|
||||
| 'newestProducts'
|
||||
|
||||
export type ProductVariables = { field?: ProductTypes } & Omit<
|
||||
GetAllProductsQueryVariables,
|
||||
ProductTypes | 'hasLocale'
|
||||
>
|
||||
|
||||
async function getAllProducts(opts?: {
|
||||
variables?: ProductVariables
|
||||
config?: BigcommerceConfig
|
||||
preview?: boolean
|
||||
}): Promise<GetAllProductsResult>
|
||||
|
||||
async function getAllProducts<
|
||||
T extends Record<keyof GetAllProductsResult, any[]>,
|
||||
V = any
|
||||
>(opts: {
|
||||
query: string
|
||||
variables?: V
|
||||
config?: BigcommerceConfig
|
||||
preview?: boolean
|
||||
}): Promise<GetAllProductsResult<T>>
|
||||
|
||||
async function getAllProducts({
|
||||
query = getAllProductsQuery,
|
||||
variables: { field = 'products', ...vars } = {},
|
||||
config,
|
||||
}: {
|
||||
query?: string
|
||||
variables?: ProductVariables
|
||||
config?: BigcommerceConfig
|
||||
preview?: boolean
|
||||
} = {}): Promise<GetAllProductsResult> {
|
||||
config = getConfig(config)
|
||||
|
||||
const locale = vars.locale || config.locale
|
||||
const variables: GetAllProductsQueryVariables = {
|
||||
...vars,
|
||||
locale,
|
||||
hasLocale: !!locale,
|
||||
}
|
||||
|
||||
if (!FIELDS.includes(field)) {
|
||||
throw new Error(
|
||||
`The field variable has to match one of ${FIELDS.join(', ')}`
|
||||
)
|
||||
}
|
||||
|
||||
variables[field] = true
|
||||
|
||||
// RecursivePartial forces the method to check for every prop in the data, which is
|
||||
// required in case there's a custom `query`
|
||||
const { data } = await config.fetch<RecursivePartial<GetAllProductsQuery>>(
|
||||
query,
|
||||
{ variables }
|
||||
)
|
||||
const edges = data.site?.[field]?.edges
|
||||
const products = filterEdges(edges as RecursiveRequired<typeof edges>)
|
||||
|
||||
if (locale && config.applyLocale) {
|
||||
products.forEach((product: RecursivePartial<ProductEdge>) => {
|
||||
if (product.node) setProductLocaleMeta(product.node)
|
||||
})
|
||||
}
|
||||
|
||||
return { products }
|
||||
}
|
||||
|
||||
export default getAllProducts
|
34
framework/bigcommerce/api/operations/get-customer-id.ts
Normal file
34
framework/bigcommerce/api/operations/get-customer-id.ts
Normal file
@@ -0,0 +1,34 @@
|
||||
import { GetCustomerIdQuery } from '../../schema'
|
||||
import { BigcommerceConfig, getConfig } from '..'
|
||||
|
||||
export const getCustomerIdQuery = /* GraphQL */ `
|
||||
query getCustomerId {
|
||||
customer {
|
||||
entityId
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
async function getCustomerId({
|
||||
customerToken,
|
||||
config,
|
||||
}: {
|
||||
customerToken: string
|
||||
config?: BigcommerceConfig
|
||||
}): Promise<number | undefined> {
|
||||
config = getConfig(config)
|
||||
|
||||
const { data } = await config.fetch<GetCustomerIdQuery>(
|
||||
getCustomerIdQuery,
|
||||
undefined,
|
||||
{
|
||||
headers: {
|
||||
cookie: `${config.customerCookie}=${customerToken}`,
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
return data?.customer?.entityId
|
||||
}
|
||||
|
||||
export default getCustomerId
|
@@ -0,0 +1,87 @@
|
||||
import type { RecursivePartial, RecursiveRequired } from '../utils/types'
|
||||
import { definitions } from '../definitions/wishlist'
|
||||
import { BigcommerceConfig, getConfig } from '..'
|
||||
import getAllProducts, { ProductEdge } from './get-all-products'
|
||||
|
||||
export type Wishlist = Omit<definitions['wishlist_Full'], 'items'> & {
|
||||
items?: WishlistItem[]
|
||||
}
|
||||
|
||||
export type WishlistItem = NonNullable<
|
||||
definitions['wishlist_Full']['items']
|
||||
>[0] & {
|
||||
product?: ProductEdge['node']
|
||||
}
|
||||
|
||||
export type GetCustomerWishlistResult<
|
||||
T extends { wishlist?: any } = { wishlist?: Wishlist }
|
||||
> = T
|
||||
|
||||
export type GetCustomerWishlistVariables = {
|
||||
customerId: number
|
||||
}
|
||||
|
||||
async function getCustomerWishlist(opts: {
|
||||
variables: GetCustomerWishlistVariables
|
||||
config?: BigcommerceConfig
|
||||
includeProducts?: boolean
|
||||
}): Promise<GetCustomerWishlistResult>
|
||||
|
||||
async function getCustomerWishlist<
|
||||
T extends { wishlist?: any },
|
||||
V = any
|
||||
>(opts: {
|
||||
url: string
|
||||
variables: V
|
||||
config?: BigcommerceConfig
|
||||
includeProducts?: boolean
|
||||
}): Promise<GetCustomerWishlistResult<T>>
|
||||
|
||||
async function getCustomerWishlist({
|
||||
config,
|
||||
variables,
|
||||
includeProducts,
|
||||
}: {
|
||||
url?: string
|
||||
variables: GetCustomerWishlistVariables
|
||||
config?: BigcommerceConfig
|
||||
includeProducts?: boolean
|
||||
}): Promise<GetCustomerWishlistResult> {
|
||||
config = getConfig(config)
|
||||
|
||||
const { data = [] } = await config.storeApiFetch<
|
||||
RecursivePartial<{ data: Wishlist[] }>
|
||||
>(`/v3/wishlists?customer_id=${variables.customerId}`)
|
||||
const wishlist = data[0]
|
||||
|
||||
if (includeProducts && wishlist?.items?.length) {
|
||||
const entityIds = wishlist.items
|
||||
?.map((item) => item?.product_id)
|
||||
.filter((id): id is number => !!id)
|
||||
|
||||
if (entityIds?.length) {
|
||||
const graphqlData = await getAllProducts({
|
||||
variables: { first: 100, entityIds },
|
||||
config,
|
||||
})
|
||||
// Put the products in an object that we can use to get them by id
|
||||
const productsById = graphqlData.products.reduce<{
|
||||
[k: number]: ProductEdge
|
||||
}>((prods, p) => {
|
||||
prods[p.node.entityId] = p
|
||||
return prods
|
||||
}, {})
|
||||
// Populate the wishlist items with the graphql products
|
||||
wishlist.items.forEach((item) => {
|
||||
const product = item && productsById[item.product_id!]
|
||||
if (item && product) {
|
||||
item.product = product.node
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return { wishlist: wishlist as RecursiveRequired<typeof wishlist> }
|
||||
}
|
||||
|
||||
export default getCustomerWishlist
|
53
framework/bigcommerce/api/operations/get-page.ts
Normal file
53
framework/bigcommerce/api/operations/get-page.ts
Normal file
@@ -0,0 +1,53 @@
|
||||
import type { RecursivePartial, RecursiveRequired } from '../utils/types'
|
||||
import { BigcommerceConfig, getConfig } from '..'
|
||||
import { definitions } from '../definitions/store-content'
|
||||
|
||||
export type Page = definitions['page_Full']
|
||||
|
||||
export type GetPageResult<T extends { page?: any } = { page?: Page }> = T
|
||||
|
||||
export type PageVariables = {
|
||||
id: number
|
||||
}
|
||||
|
||||
async function getPage(opts: {
|
||||
url?: string
|
||||
variables: PageVariables
|
||||
config?: BigcommerceConfig
|
||||
preview?: boolean
|
||||
}): Promise<GetPageResult>
|
||||
|
||||
async function getPage<T extends { page?: any }, V = any>(opts: {
|
||||
url: string
|
||||
variables: V
|
||||
config?: BigcommerceConfig
|
||||
preview?: boolean
|
||||
}): Promise<GetPageResult<T>>
|
||||
|
||||
async function getPage({
|
||||
url,
|
||||
variables,
|
||||
config,
|
||||
preview,
|
||||
}: {
|
||||
url?: string
|
||||
variables: PageVariables
|
||||
config?: BigcommerceConfig
|
||||
preview?: boolean
|
||||
}): Promise<GetPageResult> {
|
||||
config = getConfig(config)
|
||||
// RecursivePartial forces the method to check for every prop in the data, which is
|
||||
// required in case there's a custom `url`
|
||||
const { data } = await config.storeApiFetch<RecursivePartial<{ data: Page[] }>>(
|
||||
url || `/v3/content/pages?id=${variables.id}&include=body`
|
||||
)
|
||||
const firstPage = data?.[0]
|
||||
const page = firstPage as RecursiveRequired<typeof firstPage>
|
||||
|
||||
if (preview || page?.is_visible) {
|
||||
return { page }
|
||||
}
|
||||
return {}
|
||||
}
|
||||
|
||||
export default getPage
|
118
framework/bigcommerce/api/operations/get-product.ts
Normal file
118
framework/bigcommerce/api/operations/get-product.ts
Normal file
@@ -0,0 +1,118 @@
|
||||
import type { GetProductQuery, GetProductQueryVariables } from '../../schema'
|
||||
import setProductLocaleMeta from '../utils/set-product-locale-meta'
|
||||
import { productInfoFragment } from '../fragments/product'
|
||||
import { BigcommerceConfig, getConfig } from '..'
|
||||
|
||||
export const getProductQuery = /* GraphQL */ `
|
||||
query getProduct(
|
||||
$hasLocale: Boolean = false
|
||||
$locale: String = "null"
|
||||
$path: String!
|
||||
) {
|
||||
site {
|
||||
route(path: $path) {
|
||||
node {
|
||||
__typename
|
||||
... on Product {
|
||||
...productInfo
|
||||
variants {
|
||||
edges {
|
||||
node {
|
||||
entityId
|
||||
defaultImage {
|
||||
urlOriginal
|
||||
altText
|
||||
isDefault
|
||||
}
|
||||
prices {
|
||||
...productPrices
|
||||
}
|
||||
inventory {
|
||||
aggregated {
|
||||
availableToSell
|
||||
warningLevel
|
||||
}
|
||||
isInStock
|
||||
}
|
||||
productOptions {
|
||||
edges {
|
||||
node {
|
||||
__typename
|
||||
entityId
|
||||
displayName
|
||||
...multipleChoiceOption
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
${productInfoFragment}
|
||||
`
|
||||
|
||||
export type ProductNode = Extract<
|
||||
GetProductQuery['site']['route']['node'],
|
||||
{ __typename: 'Product' }
|
||||
>
|
||||
|
||||
export type GetProductResult<
|
||||
T extends { product?: any } = { product?: ProductNode }
|
||||
> = T
|
||||
|
||||
export type ProductVariables = { locale?: string } & (
|
||||
| { path: string; slug?: never }
|
||||
| { path?: never; slug: string }
|
||||
)
|
||||
|
||||
async function getProduct(opts: {
|
||||
variables: ProductVariables
|
||||
config?: BigcommerceConfig
|
||||
preview?: boolean
|
||||
}): Promise<GetProductResult>
|
||||
|
||||
async function getProduct<T extends { product?: any }, V = any>(opts: {
|
||||
query: string
|
||||
variables: V
|
||||
config?: BigcommerceConfig
|
||||
preview?: boolean
|
||||
}): Promise<GetProductResult<T>>
|
||||
|
||||
async function getProduct({
|
||||
query = getProductQuery,
|
||||
variables: { slug, ...vars },
|
||||
config,
|
||||
}: {
|
||||
query?: string
|
||||
variables: ProductVariables
|
||||
config?: BigcommerceConfig
|
||||
preview?: boolean
|
||||
}): Promise<GetProductResult> {
|
||||
config = getConfig(config)
|
||||
|
||||
const locale = vars.locale || config.locale
|
||||
const variables: GetProductQueryVariables = {
|
||||
...vars,
|
||||
locale,
|
||||
hasLocale: !!locale,
|
||||
path: slug ? `/${slug}/` : vars.path!,
|
||||
}
|
||||
const { data } = await config.fetch<GetProductQuery>(query, { variables })
|
||||
const product = data.site?.route?.node
|
||||
|
||||
if (product?.__typename === 'Product') {
|
||||
if (locale && config.applyLocale) {
|
||||
setProductLocaleMeta(product)
|
||||
}
|
||||
return { product }
|
||||
}
|
||||
|
||||
return {}
|
||||
}
|
||||
|
||||
export default getProduct
|
106
framework/bigcommerce/api/operations/get-site-info.ts
Normal file
106
framework/bigcommerce/api/operations/get-site-info.ts
Normal file
@@ -0,0 +1,106 @@
|
||||
import type { GetSiteInfoQuery, GetSiteInfoQueryVariables } from '../../schema'
|
||||
import type { RecursivePartial, RecursiveRequired } from '../utils/types'
|
||||
import filterEdges from '../utils/filter-edges'
|
||||
import { BigcommerceConfig, getConfig } from '..'
|
||||
import { categoryTreeItemFragment } from '../fragments/category-tree'
|
||||
|
||||
// Get 3 levels of categories
|
||||
export const getSiteInfoQuery = /* GraphQL */ `
|
||||
query getSiteInfo {
|
||||
site {
|
||||
categoryTree {
|
||||
...categoryTreeItem
|
||||
children {
|
||||
...categoryTreeItem
|
||||
children {
|
||||
...categoryTreeItem
|
||||
}
|
||||
}
|
||||
}
|
||||
brands {
|
||||
pageInfo {
|
||||
startCursor
|
||||
endCursor
|
||||
}
|
||||
edges {
|
||||
cursor
|
||||
node {
|
||||
entityId
|
||||
name
|
||||
defaultImage {
|
||||
urlOriginal
|
||||
altText
|
||||
}
|
||||
pageTitle
|
||||
metaDesc
|
||||
metaKeywords
|
||||
searchKeywords
|
||||
path
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
${categoryTreeItemFragment}
|
||||
`
|
||||
|
||||
export type CategoriesTree = NonNullable<
|
||||
GetSiteInfoQuery['site']['categoryTree']
|
||||
>
|
||||
|
||||
export type BrandEdge = NonNullable<
|
||||
NonNullable<GetSiteInfoQuery['site']['brands']['edges']>[0]
|
||||
>
|
||||
|
||||
export type Brands = BrandEdge[]
|
||||
|
||||
export type GetSiteInfoResult<
|
||||
T extends { categories: any[]; brands: any[] } = {
|
||||
categories: CategoriesTree
|
||||
brands: Brands
|
||||
}
|
||||
> = T
|
||||
|
||||
async function getSiteInfo(opts?: {
|
||||
variables?: GetSiteInfoQueryVariables
|
||||
config?: BigcommerceConfig
|
||||
preview?: boolean
|
||||
}): Promise<GetSiteInfoResult>
|
||||
|
||||
async function getSiteInfo<
|
||||
T extends { categories: any[]; brands: any[] },
|
||||
V = any
|
||||
>(opts: {
|
||||
query: string
|
||||
variables?: V
|
||||
config?: BigcommerceConfig
|
||||
preview?: boolean
|
||||
}): Promise<GetSiteInfoResult<T>>
|
||||
|
||||
async function getSiteInfo({
|
||||
query = getSiteInfoQuery,
|
||||
variables,
|
||||
config,
|
||||
}: {
|
||||
query?: string
|
||||
variables?: GetSiteInfoQueryVariables
|
||||
config?: BigcommerceConfig
|
||||
preview?: boolean
|
||||
} = {}): Promise<GetSiteInfoResult> {
|
||||
config = getConfig(config)
|
||||
// RecursivePartial forces the method to check for every prop in the data, which is
|
||||
// required in case there's a custom `query`
|
||||
const { data } = await config.fetch<RecursivePartial<GetSiteInfoQuery>>(
|
||||
query,
|
||||
{ variables }
|
||||
)
|
||||
const categories = data.site?.categoryTree
|
||||
const brands = data.site?.brands?.edges
|
||||
|
||||
return {
|
||||
categories: (categories as RecursiveRequired<typeof categories>) ?? [],
|
||||
brands: filterEdges(brands as RecursiveRequired<typeof brands>),
|
||||
}
|
||||
}
|
||||
|
||||
export default getSiteInfo
|
73
framework/bigcommerce/api/operations/login.ts
Normal file
73
framework/bigcommerce/api/operations/login.ts
Normal file
@@ -0,0 +1,73 @@
|
||||
import type { ServerResponse } from 'http'
|
||||
import type { LoginMutation, LoginMutationVariables } from '../../schema'
|
||||
import type { RecursivePartial } from '../utils/types'
|
||||
import concatHeader from '../utils/concat-cookie'
|
||||
import { BigcommerceConfig, getConfig } from '..'
|
||||
|
||||
export const loginMutation = /* GraphQL */ `
|
||||
mutation login($email: String!, $password: String!) {
|
||||
login(email: $email, password: $password) {
|
||||
result
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
export type LoginResult<T extends { result?: any } = { result?: string }> = T
|
||||
|
||||
export type LoginVariables = LoginMutationVariables
|
||||
|
||||
async function login(opts: {
|
||||
variables: LoginVariables
|
||||
config?: BigcommerceConfig
|
||||
res: ServerResponse
|
||||
}): Promise<LoginResult>
|
||||
|
||||
async function login<T extends { result?: any }, V = any>(opts: {
|
||||
query: string
|
||||
variables: V
|
||||
res: ServerResponse
|
||||
config?: BigcommerceConfig
|
||||
}): Promise<LoginResult<T>>
|
||||
|
||||
async function login({
|
||||
query = loginMutation,
|
||||
variables,
|
||||
res: response,
|
||||
config,
|
||||
}: {
|
||||
query?: string
|
||||
variables: LoginVariables
|
||||
res: ServerResponse
|
||||
config?: BigcommerceConfig
|
||||
}): Promise<LoginResult> {
|
||||
config = getConfig(config)
|
||||
|
||||
const { data, res } = await config.fetch<RecursivePartial<LoginMutation>>(
|
||||
query,
|
||||
{ variables }
|
||||
)
|
||||
// Bigcommerce returns a Set-Cookie header with the auth cookie
|
||||
let cookie = res.headers.get('Set-Cookie')
|
||||
|
||||
if (cookie && typeof cookie === 'string') {
|
||||
// In development, don't set a secure cookie or the browser will ignore it
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
cookie = cookie.replace('; Secure', '')
|
||||
// SameSite=none can't be set unless the cookie is Secure
|
||||
// bc seems to sometimes send back SameSite=None rather than none so make
|
||||
// this case insensitive
|
||||
cookie = cookie.replace(/; SameSite=none/gi, '; SameSite=lax')
|
||||
}
|
||||
|
||||
response.setHeader(
|
||||
'Set-Cookie',
|
||||
concatHeader(response.getHeader('Set-Cookie'), cookie)!
|
||||
)
|
||||
}
|
||||
|
||||
return {
|
||||
result: data.login?.result,
|
||||
}
|
||||
}
|
||||
|
||||
export default login
|
Reference in New Issue
Block a user