mirror of
https://github.com/vercel/commerce.git
synced 2025-07-22 20:26:49 +00:00
Add swell provider folder
This commit is contained in:
58
framework/swell/api/utils/create-api-handler.ts
Normal file
58
framework/swell/api/utils/create-api-handler.ts
Normal file
@@ -0,0 +1,58 @@
|
||||
import type { NextApiHandler, NextApiRequest, NextApiResponse } from 'next'
|
||||
import { ShopifyConfig, getConfig } from '..'
|
||||
|
||||
export type ShopifyApiHandler<
|
||||
T = any,
|
||||
H extends ShopifyHandlers = {},
|
||||
Options extends {} = {}
|
||||
> = (
|
||||
req: NextApiRequest,
|
||||
res: NextApiResponse<ShopifyApiResponse<T>>,
|
||||
config: ShopifyConfig,
|
||||
handlers: H,
|
||||
// Custom configs that may be used by a particular handler
|
||||
options: Options
|
||||
) => void | Promise<void>
|
||||
|
||||
export type ShopifyHandler<T = any, Body = null> = (options: {
|
||||
req: NextApiRequest
|
||||
res: NextApiResponse<ShopifyApiResponse<T>>
|
||||
config: ShopifyConfig
|
||||
body: Body
|
||||
}) => void | Promise<void>
|
||||
|
||||
export type ShopifyHandlers<T = any> = {
|
||||
[k: string]: ShopifyHandler<T, any>
|
||||
}
|
||||
|
||||
export type ShopifyApiResponse<T> = {
|
||||
data: T | null
|
||||
errors?: { message: string; code?: string }[]
|
||||
}
|
||||
|
||||
export default function createApiHandler<
|
||||
T = any,
|
||||
H extends ShopifyHandlers = {},
|
||||
Options extends {} = {}
|
||||
>(
|
||||
handler: ShopifyApiHandler<T, H, Options>,
|
||||
handlers: H,
|
||||
defaultOptions: Options
|
||||
) {
|
||||
return function getApiHandler({
|
||||
config,
|
||||
operations,
|
||||
options,
|
||||
}: {
|
||||
config?: ShopifyConfig
|
||||
operations?: Partial<H>
|
||||
options?: Options extends {} ? Partial<Options> : never
|
||||
} = {}): NextApiHandler {
|
||||
const ops = { ...operations, ...handlers }
|
||||
const opts = { ...defaultOptions, ...options }
|
||||
|
||||
return function apiHandler(req, res) {
|
||||
return handler(req, res, getConfig(config), ops, opts)
|
||||
}
|
||||
}
|
||||
}
|
41
framework/swell/api/utils/fetch-all-products.ts
Normal file
41
framework/swell/api/utils/fetch-all-products.ts
Normal file
@@ -0,0 +1,41 @@
|
||||
import { ProductEdge } from '../../schema'
|
||||
import { ShopifyConfig } from '..'
|
||||
|
||||
const fetchAllProducts = async ({
|
||||
config,
|
||||
query,
|
||||
variables,
|
||||
acc = [],
|
||||
cursor,
|
||||
}: {
|
||||
config: ShopifyConfig
|
||||
query: string
|
||||
acc?: ProductEdge[]
|
||||
variables?: any
|
||||
cursor?: string
|
||||
}): Promise<ProductEdge[]> => {
|
||||
const { data } = await config.fetch(query, {
|
||||
variables: { ...variables, cursor },
|
||||
})
|
||||
|
||||
const edges: ProductEdge[] = data.products?.edges ?? []
|
||||
const hasNextPage = data.products?.pageInfo?.hasNextPage
|
||||
acc = acc.concat(edges)
|
||||
|
||||
if (hasNextPage) {
|
||||
const cursor = edges.pop()?.cursor
|
||||
if (cursor) {
|
||||
return fetchAllProducts({
|
||||
config,
|
||||
query,
|
||||
variables,
|
||||
acc,
|
||||
cursor,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return acc
|
||||
}
|
||||
|
||||
export default fetchAllProducts
|
34
framework/swell/api/utils/fetch-graphql-api.ts
Normal file
34
framework/swell/api/utils/fetch-graphql-api.ts
Normal file
@@ -0,0 +1,34 @@
|
||||
import type { GraphQLFetcher } from '@commerce/api'
|
||||
import fetch from './fetch'
|
||||
|
||||
import { API_URL, API_TOKEN } from '../../const'
|
||||
import { getError } from '../../utils/handle-fetch-response'
|
||||
|
||||
const fetchGraphqlApi: GraphQLFetcher = async (
|
||||
query: string,
|
||||
{ variables } = {},
|
||||
fetchOptions
|
||||
) => {
|
||||
const res = await fetch(API_URL, {
|
||||
...fetchOptions,
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'X-Shopify-Storefront-Access-Token': API_TOKEN!,
|
||||
...fetchOptions?.headers,
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
query,
|
||||
variables,
|
||||
}),
|
||||
})
|
||||
|
||||
const { data, errors, status } = await res.json()
|
||||
|
||||
if (errors) {
|
||||
throw getError(errors, status)
|
||||
}
|
||||
|
||||
return { data, res }
|
||||
}
|
||||
export default fetchGraphqlApi
|
2
framework/swell/api/utils/fetch.ts
Normal file
2
framework/swell/api/utils/fetch.ts
Normal file
@@ -0,0 +1,2 @@
|
||||
import zeitFetch from '@vercel/fetch'
|
||||
export default zeitFetch()
|
28
framework/swell/api/utils/is-allowed-method.ts
Normal file
28
framework/swell/api/utils/is-allowed-method.ts
Normal file
@@ -0,0 +1,28 @@
|
||||
import type { NextApiRequest, NextApiResponse } from 'next'
|
||||
|
||||
export default function isAllowedMethod(
|
||||
req: NextApiRequest,
|
||||
res: NextApiResponse,
|
||||
allowedMethods: string[]
|
||||
) {
|
||||
const methods = allowedMethods.includes('OPTIONS')
|
||||
? allowedMethods
|
||||
: [...allowedMethods, 'OPTIONS']
|
||||
|
||||
if (!req.method || !methods.includes(req.method)) {
|
||||
res.status(405)
|
||||
res.setHeader('Allow', methods.join(', '))
|
||||
res.end()
|
||||
return false
|
||||
}
|
||||
|
||||
if (req.method === 'OPTIONS') {
|
||||
res.status(200)
|
||||
res.setHeader('Allow', methods.join(', '))
|
||||
res.setHeader('Content-Length', '0')
|
||||
res.end()
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
Reference in New Issue
Block a user