Divide fetcher with rest and graphql

This commit is contained in:
goncy 2021-08-25 19:51:15 -03:00
parent d4adfd079f
commit 5d76337f9e
16 changed files with 69 additions and 94 deletions

View File

@ -9,7 +9,7 @@ import { formatCart } from '../../utils/cart'
const addItem: CartEndpoint['handlers']['addItem'] = async ({ const addItem: CartEndpoint['handlers']['addItem'] = async ({
res, res,
body: { cartId, item }, body: { cartId, item },
config: { fetch, cartCookie }, config: { storeRestFetch, cartCookie },
}) => { }) => {
// Return an error if no item is present // Return an error if no item is present
if (!item) { if (!item) {
@ -24,7 +24,7 @@ const addItem: CartEndpoint['handlers']['addItem'] = async ({
// Create an order if it doesn't exist // Create an order if it doesn't exist
if (!cartId) { if (!cartId) {
cartId = await fetch('POST', `/orders/Outgoing`, {}).then( cartId = await storeRestFetch('POST', `/orders/Outgoing`).then(
(response: { ID: string }) => response.ID (response: { ID: string }) => response.ID
) )
} }
@ -46,14 +46,14 @@ const addItem: CartEndpoint['handlers']['addItem'] = async ({
// If a variant is present, fetch its specs // If a variant is present, fetch its specs
if (item.variantId) { if (item.variantId) {
specs = await fetch( specs = await storeRestFetch(
'GET', 'GET',
`/me/products/${item.productId}/variants/${item.variantId}` `/me/products/${item.productId}/variants/${item.variantId}`
).then((res: RawVariant) => res.Specs) ).then((res: RawVariant) => res.Specs)
} }
// Add the item to the order // Add the item to the order
await fetch('POST', `/orders/Outgoing/${cartId}/lineitems`, { await storeRestFetch('POST', `/orders/Outgoing/${cartId}/lineitems`, {
ProductID: item.productId, ProductID: item.productId,
Quantity: item.quantity, Quantity: item.quantity,
Specs: specs, Specs: specs,
@ -61,8 +61,8 @@ const addItem: CartEndpoint['handlers']['addItem'] = async ({
// Get cart // Get cart
const [cart, lineItems] = await Promise.all([ const [cart, lineItems] = await Promise.all([
fetch('GET', `/orders/Outgoing/${cartId}`), storeRestFetch('GET', `/orders/Outgoing/${cartId}`),
fetch('GET', `/orders/Outgoing/${cartId}/lineitems`).then( storeRestFetch('GET', `/orders/Outgoing/${cartId}/lineitems`).then(
(response: { Items: OrdercloudLineItem[] }) => response.Items (response: { Items: OrdercloudLineItem[] }) => response.Items
), ),
]) ])

View File

@ -9,7 +9,7 @@ import { formatCart } from '../../utils/cart'
const getCart: CartEndpoint['handlers']['getCart'] = async ({ const getCart: CartEndpoint['handlers']['getCart'] = async ({
res, res,
body: { cartId }, body: { cartId },
config: { fetch, cartCookie }, config: { storeRestFetch, cartCookie },
}) => { }) => {
if (!cartId) { if (!cartId) {
return res.status(400).json({ return res.status(400).json({
@ -20,10 +20,10 @@ const getCart: CartEndpoint['handlers']['getCart'] = async ({
try { try {
// Get cart // Get cart
const cart = await fetch('GET', `/orders/Outgoing/${cartId}`) const cart = await storeRestFetch('GET', `/orders/Outgoing/${cartId}`)
// Get line items // Get line items
const lineItems = await fetch( const lineItems = await storeRestFetch(
'GET', 'GET',
`/orders/Outgoing/${cartId}/lineitems` `/orders/Outgoing/${cartId}/lineitems`
).then((response: { Items: OrdercloudLineItem[] }) => response.Items) ).then((response: { Items: OrdercloudLineItem[] }) => response.Items)

View File

@ -6,7 +6,7 @@ import { OrdercloudLineItem } from '../../../types/cart'
const removeItem: CartEndpoint['handlers']['removeItem'] = async ({ const removeItem: CartEndpoint['handlers']['removeItem'] = async ({
res, res,
body: { cartId, itemId }, body: { cartId, itemId },
config: { fetch }, config: { storeRestFetch },
}) => { }) => {
if (!cartId || !itemId) { if (!cartId || !itemId) {
return res.status(400).json({ return res.status(400).json({
@ -16,12 +16,15 @@ const removeItem: CartEndpoint['handlers']['removeItem'] = async ({
} }
// Remove the item to the order // Remove the item to the order
await fetch('DELETE', `/orders/Outgoing/${cartId}/lineitems/${itemId}`) await storeRestFetch(
'DELETE',
`/orders/Outgoing/${cartId}/lineitems/${itemId}`
)
// Get cart // Get cart
const [cart, lineItems] = await Promise.all([ const [cart, lineItems] = await Promise.all([
fetch('GET', `/orders/Outgoing/${cartId}`), storeRestFetch('GET', `/orders/Outgoing/${cartId}`),
fetch('GET', `/orders/Outgoing/${cartId}/lineitems`).then( storeRestFetch('GET', `/orders/Outgoing/${cartId}/lineitems`).then(
(response: { Items: OrdercloudLineItem[] }) => response.Items (response: { Items: OrdercloudLineItem[] }) => response.Items
), ),
]) ])

View File

@ -7,7 +7,7 @@ import { formatCart } from '../../utils/cart'
const updateItem: CartEndpoint['handlers']['updateItem'] = async ({ const updateItem: CartEndpoint['handlers']['updateItem'] = async ({
res, res,
body: { cartId, itemId, item }, body: { cartId, itemId, item },
config: { fetch }, config: { storeRestFetch },
}) => { }) => {
if (!cartId || !itemId || !item) { if (!cartId || !itemId || !item) {
return res.status(400).json({ return res.status(400).json({
@ -21,23 +21,27 @@ const updateItem: CartEndpoint['handlers']['updateItem'] = async ({
// If a variant is present, fetch its specs // If a variant is present, fetch its specs
if (item.variantId) { if (item.variantId) {
specs = await fetch( specs = await storeRestFetch(
'GET', 'GET',
`/me/products/${item.productId}/variants/${item.variantId}` `/me/products/${item.productId}/variants/${item.variantId}`
).then((res: RawVariant) => res.Specs) ).then((res: RawVariant) => res.Specs)
} }
// Add the item to the order // Add the item to the order
await fetch('PATCH', `/orders/Outgoing/${cartId}/lineitems/${itemId}`, { await storeRestFetch(
'PATCH',
`/orders/Outgoing/${cartId}/lineitems/${itemId}`,
{
ProductID: item.productId, ProductID: item.productId,
Quantity: item.quantity, Quantity: item.quantity,
Specs: specs, Specs: specs,
}) }
)
// Get cart // Get cart
const [cart, lineItems] = await Promise.all([ const [cart, lineItems] = await Promise.all([
fetch('GET', `/orders/Outgoing/${cartId}`), storeRestFetch('GET', `/orders/Outgoing/${cartId}`),
fetch('GET', `/orders/Outgoing/${cartId}/lineitems`).then( storeRestFetch('GET', `/orders/Outgoing/${cartId}/lineitems`).then(
(response: { Items: OrdercloudLineItem[] }) => response.Items (response: { Items: OrdercloudLineItem[] }) => response.Items
), ),
]) ])

View File

@ -1,18 +1,17 @@
import type { CommerceAPI, CommerceAPIConfig } from '@commerce/api' import type { CommerceAPI, CommerceAPIConfig } from '@commerce/api'
import { getCommerceApi as commerceApi } from '@commerce/api' import { getCommerceApi as commerceApi } from '@commerce/api'
import createFetcher from './utils/fetch' import createRestFetcher from './utils/fetch-rest'
import createGraphqlFetcher from './utils/fetch-graphql'
import getAllPages from './operations/get-all-pages'
import getPage from './operations/get-page'
import getSiteInfo from './operations/get-site-info' import getSiteInfo from './operations/get-site-info'
import getCustomerWishlist from './operations/get-customer-wishlist'
import getAllProductPaths from './operations/get-all-product-paths' import getAllProductPaths from './operations/get-all-product-paths'
import getAllProducts from './operations/get-all-products' import getAllProducts from './operations/get-all-products'
import getProduct from './operations/get-product' import getProduct from './operations/get-product'
import { API_URL, CART_COOKIE, CUSTOMER_COOKIE } from '../constants' import { API_URL, CART_COOKIE, CUSTOMER_COOKIE } from '../constants'
export interface OrdercloudConfig extends Omit<CommerceAPIConfig, 'fetch'> { export interface OrdercloudConfig extends CommerceAPIConfig {
fetch: <T>( fetch: any
storeRestFetch: <T>(
method: string, method: string,
resource: string, resource: string,
body?: Record<string, unknown>, body?: Record<string, unknown>,
@ -26,14 +25,12 @@ const config: OrdercloudConfig = {
cartCookie: CART_COOKIE, cartCookie: CART_COOKIE,
customerCookie: CUSTOMER_COOKIE, customerCookie: CUSTOMER_COOKIE,
cartCookieMaxAge: 2592000, cartCookieMaxAge: 2592000,
fetch: createFetcher(() => getCommerceApi().getConfig()), storeRestFetch: createRestFetcher(() => getCommerceApi().getConfig()),
fetch: createGraphqlFetcher(() => getCommerceApi().getConfig()),
} }
const operations = { const operations = {
getAllPages,
getPage,
getSiteInfo, getSiteInfo,
getCustomerWishlist,
getAllProductPaths, getAllProductPaths,
getAllProducts, getAllProducts,
getProduct, getProduct,

View File

@ -1,19 +0,0 @@
export type Page = { url: string }
export type GetAllPagesResult = { pages: Page[] }
import type { OrdercloudConfig } from '../index'
export default function getAllPagesOperation() {
function getAllPages({
config,
preview,
}: {
url?: string
config?: Partial<OrdercloudConfig>
preview?: boolean
}): Promise<GetAllPagesResult> {
return Promise.resolve({
pages: [],
})
}
return getAllPages
}

View File

@ -2,7 +2,7 @@ import type { OperationContext } from '@commerce/api/operations'
import type { GetAllProductPathsOperation } from '@commerce/types/product' import type { GetAllProductPathsOperation } from '@commerce/types/product'
import type { RawProduct } from '../../types/product' import type { RawProduct } from '../../types/product'
import type { OrdercloudConfig, Provider } from '../index' import type { OrdercloudConfig, Provider } from '../'
export type GetAllProductPathsResult = { export type GetAllProductPathsResult = {
products: Array<{ path: string }> products: Array<{ path: string }>
@ -17,13 +17,12 @@ export default function getAllProductPathsOperation({
config?: Partial<OrdercloudConfig> config?: Partial<OrdercloudConfig>
} = {}): Promise<T['data']> { } = {}): Promise<T['data']> {
// Get fetch from the config // Get fetch from the config
const { fetch } = commerce.getConfig(config) const { storeRestFetch } = commerce.getConfig(config)
// Get all products // Get all products
const rawProducts: RawProduct[] = await fetch<{ Items: RawProduct[] }>( const rawProducts: RawProduct[] = await storeRestFetch<{
'GET', Items: RawProduct[]
'/me/products' }>('GET', '/me/products').then((response) => response.Items)
).then((response) => response.Items)
return { return {
// Match a path for every product retrieved // Match a path for every product retrieved

View File

@ -18,13 +18,12 @@ export default function getAllProductsOperation({
preview?: boolean preview?: boolean
} = {}): Promise<T['data']> { } = {}): Promise<T['data']> {
// Get fetch from the config // Get fetch from the config
const { fetch } = commerce.getConfig(config) const { storeRestFetch } = commerce.getConfig(config)
// Get all products // Get all products
const rawProducts: RawProduct[] = await fetch<{ Items: RawProduct[] }>( const rawProducts: RawProduct[] = await storeRestFetch<{
'GET', Items: RawProduct[]
'/me/products' }>('GET', '/me/products').then((response) => response.Items)
).then((response) => response.Items)
return { return {
// Normalize products to commerce schema // Normalize products to commerce schema

View File

@ -1,6 +0,0 @@
export default function getCustomerWishlistOperation() {
function getCustomerWishlist(): any {
return { wishlist: {} }
}
return getCustomerWishlist
}

View File

@ -1,13 +0,0 @@
export type Page = any
export type GetPageResult = { page?: Page }
export type PageVariables = {
id: number
}
export default function getPageOperation() {
function getPage(): Promise<GetPageResult> {
return Promise.resolve({})
}
return getPage
}

View File

@ -19,22 +19,22 @@ export default function getProductOperation({
preview?: boolean preview?: boolean
} = {}): Promise<T['data']> { } = {}): Promise<T['data']> {
// Get fetch from the config // Get fetch from the config
const { fetch } = commerce.getConfig(config) const { storeRestFetch } = commerce.getConfig(config)
// Get a single product // Get a single product
const productPromise = fetch<RawProduct>( const productPromise = storeRestFetch<RawProduct>(
'GET', 'GET',
`/me/products/${variables?.slug}` `/me/products/${variables?.slug}`
) )
// Get product specs // Get product specs
const specsPromise = fetch<{ Items: RawSpec[] }>( const specsPromise = storeRestFetch<{ Items: RawSpec[] }>(
'GET', 'GET',
`/me/products/${variables?.slug}/specs` `/me/products/${variables?.slug}/specs`
).then((res) => res.Items) ).then((res) => res.Items)
// Get product variants // Get product variants
const variantsPromise = fetch<{ Items: RawVariant[] }>( const variantsPromise = storeRestFetch<{ Items: RawVariant[] }>(
'GET', 'GET',
`/me/products/${variables?.slug}/variants` `/me/products/${variables?.slug}/variants`
).then((res) => res.Items) ).then((res) => res.Items)

View File

@ -23,13 +23,12 @@ export default function getSiteInfoOperation({
preview?: boolean preview?: boolean
} = {}): Promise<T['data']> { } = {}): Promise<T['data']> {
// Get fetch from the config // Get fetch from the config
const { fetch } = commerce.getConfig(config) const { storeRestFetch } = commerce.getConfig(config)
// Get list of categories // Get list of categories
const rawCategories: RawCategory[] = await fetch<{ Items: RawCategory[] }>( const rawCategories: RawCategory[] = await storeRestFetch<{
'GET', Items: RawCategory[]
`/me/categories` }>('GET', `/me/categories`).then((response) => response.Items)
).then((response) => response.Items)
return { return {
// Normalize categories // Normalize categories

View File

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

View File

@ -0,0 +1,14 @@
import type { GraphQLFetcher } from '@commerce/api'
import type { OrdercloudConfig } from '../'
import { FetcherError } from '@commerce/utils/errors'
const fetchGraphqlApi: (getConfig: () => OrdercloudConfig) => GraphQLFetcher =
() => async () => {
throw new FetcherError({
errors: [{ message: 'GraphQL fetch is not implemented' }],
status: 500,
})
}
export default fetchGraphqlApi

View File

@ -64,7 +64,7 @@ export async function fetchData<T>(
} }
// Do the request with the correct headers // Do the request with the correct headers
const dataResponse = await fetch(`${baseUrl}/v1${path}`, { const dataResponse = await fetch(`${baseUrl}${path}`, {
...fetchOptions, ...fetchOptions,
method, method,
headers: { headers: {

View File

@ -1,4 +1,4 @@
export const CART_COOKIE = 'ordercloud.cart' export const CART_COOKIE = 'ordercloud.cart'
export const CUSTOMER_COOKIE = 'ordercloud.customer' export const CUSTOMER_COOKIE = 'ordercloud.customer'
export const API_URL = 'https://sandboxapi.ordercloud.io' export const API_URL = 'https://sandboxapi.ordercloud.io/v1'
export const LOCALE = 'en-us' export const LOCALE = 'en-us'