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:
Catalin Pinte
2022-10-05 09:02:29 +03:00
committed by GitHub
parent 8398a96215
commit 6c2610584d
291 changed files with 1992 additions and 1808 deletions

View File

@@ -1,6 +1,6 @@
import { GetAPISchema, createEndpoint } from '@vercel/commerce/api'
import customerEndpoint from '@vercel/commerce/api/endpoints/customer'
import type { CustomerSchema } from '../../../types/customer'
import type { CustomerSchema } from '@vercel/commerce/types/customer'
import type { KiboCommerceAPI } from '../..'
import getLoggedInCustomer from './customer'

View File

@@ -1,6 +1,6 @@
import { GetAPISchema, createEndpoint } from '@vercel/commerce/api'
import loginEndpoint from '@vercel/commerce/api/endpoints/login'
import type { LoginSchema } from '../../../types/login'
import type { LoginSchema } from '@vercel/commerce/types/login'
import type { KiboCommerceAPI } from '../..'
import login from './login'
@@ -15,6 +15,4 @@ const loginApi = createEndpoint<LoginAPI>({
handlers,
})
export default loginApi;
export default loginApi

View File

@@ -1,6 +1,6 @@
import { GetAPISchema, createEndpoint } from '@vercel/commerce/api'
import logoutEndpoint from '@vercel/commerce/api/endpoints/logout'
import type { LogoutSchema } from '../../../types/logout'
import type { LogoutSchema } from '@vercel/commerce/types/logout'
import type { KiboCommerceAPI } from '../..'
import logout from './logout'

View File

@@ -1,6 +1,6 @@
import { GetAPISchema, createEndpoint } from '@vercel/commerce/api'
import signupEndpoint from '@vercel/commerce/api/endpoints/signup'
import type { SignupSchema } from '../../../types/signup'
import type { SignupSchema } from '@vercel/commerce/types/signup'
import type { KiboCommerceAPI } from '../..'
import signup from './signup'

View File

@@ -1,35 +1,29 @@
import type { OperationContext } from '@vercel/commerce/api/operations'
import type { KiboCommerceConfig } from '../index'
import { getAllPagesQuery } from '../queries/get-all-pages-query'
import { GetPagesQueryParams } from "../../types/page";
import { normalizePage } from '../../lib/normalize'
export type GetAllPagesResult<
T extends { pages: any[] } = { pages: any[] }
> = T
export type GetAllPagesResult<T extends { pages: any[] } = { pages: any[] }> = T
export default function getAllPagesOperation({
commerce,
}: OperationContext<any>) {
async function getAllPages({
query = getAllPagesQuery,
config,
variables,
}: {
url?: string
config?: Partial<KiboCommerceConfig>
variables?: GetPagesQueryParams
preview?: boolean
query?: string
} = {}): Promise<GetAllPagesResult> {
const cfg = commerce.getConfig(config)
variables = {
documentListName: cfg.documentListName
const variables = {
documentListName: cfg.documentListName,
}
const { data } = await cfg.fetch(query, { variables });
const { data } = await cfg.fetch(query, { variables })
const pages = data.documentListDocuments.items.map(normalizePage);
const pages = data.documentListDocuments.items.map(normalizePage)
return { pages }
}

View File

@@ -2,7 +2,7 @@ import { Product } from '@vercel/commerce/types/product'
import { GetAllProductsOperation } from '@vercel/commerce/types/product'
import type { OperationContext } from '@vercel/commerce/api/operations'
import type { KiboCommerceConfig } from '../index'
import { getAllProductsQuery } from '../queries/get-all-products-query';
import { getAllProductsQuery } from '../queries/get-all-products-query'
import { normalizeProduct } from '../../lib/normalize'
export default function getAllProductsOperation({
@@ -18,11 +18,12 @@ export default function getAllProductsOperation({
config?: Partial<KiboCommerceConfig>
preview?: boolean
} = {}): Promise<{ products: Product[] | any[] }> {
const cfg = commerce.getConfig(config)
const { data } = await cfg.fetch(query);
const { data } = await cfg.fetch(query)
let normalizedProducts = data.products.items ? data.products.items.map( (item:any) => normalizeProduct(item, cfg)) : [];
let normalizedProducts = data.products.items
? data.products.items.map((item: any) => normalizeProduct(item, cfg))
: []
return {
products: normalizedProducts,

View File

@@ -2,14 +2,11 @@ import type {
OperationContext,
OperationOptions,
} from '@vercel/commerce/api/operations'
import type {
GetCustomerWishlistOperation,
Wishlist,
} from '@vercel/commerce/types/wishlist'
import type { GetCustomerWishlistOperation } from '@vercel/commerce/types/wishlist'
// import type { RecursivePartial, RecursiveRequired } from '../utils/types'
import { KiboCommerceConfig } from '..'
// import getAllProducts, { ProductEdge } from './get-all-products'
import {getCustomerWishlistQuery} from '../queries/get-customer-wishlist-query'
import { getCustomerWishlistQuery } from '../queries/get-customer-wishlist-query'
export default function getCustomerWishlistOperation({
commerce,
@@ -40,14 +37,15 @@ export default function getCustomerWishlistOperation({
config?: KiboCommerceConfig
includeProducts?: boolean
}): Promise<T['data']> {
let customerWishlist ={}
let customerWishlist = {}
try {
config = commerce.getConfig(config)
const result= await config?.fetch(getCustomerWishlistQuery,{variables})
customerWishlist= result?.data?.customerWishlist;
} catch(e) {
customerWishlist= {}
const result = await config?.fetch(getCustomerWishlistQuery, {
variables,
})
customerWishlist = result?.data?.customerWishlist
} catch (e) {
customerWishlist = {}
}
return { wishlist: customerWishlist as any }

View File

@@ -1,15 +1,11 @@
import type {
OperationContext,
} from '@vercel/commerce/api/operations'
import type { OperationContext } from '@vercel/commerce/api/operations'
import type { KiboCommerceConfig, KiboCommerceProvider } from '..'
import { normalizePage } from '../../lib/normalize'
import { getPageQuery } from '../queries/get-page-query'
import type { Page, GetPageQueryParams } from "../../types/page";
import type { Page, GetPageOperation } from '@vercel/commerce/types/page'
import type { Document } from '../../../schema'
export default function getPageOperation({
commerce,
}: OperationContext<any>) {
export default function getPageOperation({ commerce }: OperationContext<any>) {
async function getPage<T extends Page>({
url,
variables,
@@ -17,18 +13,21 @@ export default function getPageOperation({
preview,
}: {
url?: string
variables: GetPageQueryParams
variables: GetPageOperation['variables']
config?: Partial<KiboCommerceConfig>
preview?: boolean
}): Promise<any> {
// RecursivePartial forces the method to check for every prop in the data, which is
// required in case there's a custom `url`
const cfg = commerce.getConfig(config)
const pageVariables = { documentListName: cfg.documentListName, filter: `id eq ${variables.id}` }
const pageVariables = {
documentListName: cfg.documentListName,
filter: `id eq ${variables.id}`,
}
const { data } = await cfg.fetch(getPageQuery, { variables: pageVariables })
const firstPage = data.documentListDocuments.items?.[0];
const firstPage = data.documentListDocuments.items?.[0]
const page = firstPage as Document
if (preview || page?.properties?.is_visible) {
return { page: normalizePage(page as any) }

View File

@@ -1,7 +1,7 @@
import { OperationContext } from '@vercel/commerce/api/operations'
import { Category } from '@vercel/commerce/types/site'
import { KiboCommerceConfig } from '../index'
import {categoryTreeQuery} from '../queries/get-categories-tree-query'
import { categoryTreeQuery } from '../queries/get-categories-tree-query'
import { normalizeCategory } from '../../lib/normalize'
export type GetSiteInfoResult<
@@ -11,9 +11,11 @@ export type GetSiteInfoResult<
}
> = T
export default function getSiteInfoOperation({commerce}: OperationContext<any>) {
export default function getSiteInfoOperation({
commerce,
}: OperationContext<any>) {
async function getSiteInfo({
query= categoryTreeQuery,
query = categoryTreeQuery,
variables,
config,
}: {
@@ -23,12 +25,13 @@ export default function getSiteInfoOperation({commerce}: OperationContext<any>)
preview?: boolean
} = {}): Promise<GetSiteInfoResult> {
const cfg = commerce.getConfig(config)
const { data } = await cfg.fetch(query);
const categories= data.categories.items.map(normalizeCategory);
return Promise.resolve({
const { data } = await cfg.fetch(query)
const categories = data.categories.items.map(normalizeCategory)
return {
categories: categories ?? [],
brands: [],
})
}
}
return getSiteInfo

View File

@@ -1,9 +1,9 @@
import { MutationHook } from '@vercel/commerce/utils/types'
import useLogin, { UseLogin } from '@vercel/commerce/auth/use-login'
import type { MutationHook } from '@vercel/commerce/utils/types'
import useLogin, { type UseLogin } from '@vercel/commerce/auth/use-login'
import { useCallback } from 'react'
import { CommerceError } from '@vercel/commerce/utils/errors'
import type { LoginHook } from '../types/login'
import type { LoginHook } from '@vercel/commerce/types/login'
import useCustomer from '../customer/use-customer'
import useCart from '../cart/use-cart'
export default useLogin as UseLogin<typeof handler>

View File

@@ -1,7 +1,7 @@
import { useCallback } from 'react'
import type { MutationHook } from '@vercel/commerce/utils/types'
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 useCart from '../cart/use-cart'
@@ -12,18 +12,20 @@ export const handler: MutationHook<LogoutHook> = {
url: '/api/logout',
method: 'GET',
},
useHook: ({ fetch }) => () => {
const { mutate } = useCustomer()
const { mutate: mutateCart } = useCart()
useHook:
({ fetch }) =>
() => {
const { mutate } = useCustomer()
const { mutate: mutateCart } = useCart()
return useCallback(
async function logout() {
const data = await fetch()
await mutate(null, false)
await mutateCart(null, false)
return data
},
[fetch, mutate, mutateCart]
)
},
return useCallback(
async function logout() {
const data = await fetch()
await mutate(null, false)
await mutateCart(null, false)
return data
},
[fetch, mutate, mutateCart]
)
},
}

View File

@@ -1,8 +1,8 @@
import { useCallback } from 'react'
import type { MutationHook } from '@vercel/commerce/utils/types'
import { CommerceError } from '@vercel/commerce/utils/errors'
import useSignup, { UseSignup } from '@vercel/commerce/auth/use-signup'
import type { SignupHook } from '../types/signup'
import useSignup, { type UseSignup } from '@vercel/commerce/auth/use-signup'
import type { SignupHook } from '@vercel/commerce/types/signup'
import useCustomer from '../customer/use-customer'
export default useSignup as UseSignup<typeof handler>

View File

@@ -1,6 +1,8 @@
import { SWRHook } from '@vercel/commerce/utils/types'
import useCustomer, { UseCustomer } from '@vercel/commerce/customer/use-customer'
import type { CustomerHook } from '../types/customer'
import useCustomer, {
type UseCustomer,
} from '@vercel/commerce/customer/use-customer'
import type { CustomerHook } from '@vercel/commerce/types/customer'
export default useCustomer as UseCustomer<typeof handler>
@@ -13,12 +15,14 @@ export const handler: SWRHook<CustomerHook> = {
const data = await fetch(options)
return data?.customer ?? null
},
useHook: ({ useData }) => (input) => {
return useData({
swrOptions: {
revalidateOnFocus: false,
...input?.swrOptions,
},
})
},
useHook:
({ useData }) =>
(input) => {
return useData({
swrOptions: {
revalidateOnFocus: false,
...input?.swrOptions,
},
})
},
}

View File

@@ -1,50 +1,59 @@
import type { PrCategory, CustomerAccountInput, Document } from '../../schema'
import { Page } from '../types/page';
import { Customer } from '../types/customer'
import type {
PrCategory,
CustomerAccountInput,
Document,
Product as KiboProduct,
} from '../../schema'
export function normalizeProduct(productNode: any, config: any): any {
import type { Page } from '@vercel/commerce/types/page'
import type { Category } from '@vercel/commerce/types/site'
import type { Product } from '@vercel/commerce/types/product'
import type { Customer } from '@vercel/commerce/types/customer'
import type { Cart, LineItem } from '@vercel/commerce/types/cart'
import type { WishlistItem } from '@vercel/commerce/types/wishlist'
export function normalizeProduct(
productNode: KiboProduct,
config: any
): Product {
const product = {
id: productNode.productCode,
name: productNode.content.productName,
id: productNode.productCode || '',
name: productNode.content?.productName || '',
vendor: '',
path: `/${productNode.productCode}`,
slug: productNode.productCode,
slug: productNode.productCode || '',
price: {
value: productNode?.price?.price,
value: productNode?.price?.price ?? 0,
currencyCode: config.currencyCode,
},
descriptionHtml: productNode.content.productShortDescription,
images: productNode.content.productImages.map((p: any) => ({
url: `http:${p.imageUrl}`,
altText: p.imageLabel,
})),
variants: productNode.variations?.map((v: any) => ({
id: v.productCode,
options: v.options.map((o: any) => ({
['__typename']: 'MultipleChoiceOption',
id: o.attributeFQN,
displayName:
o.attributeFQN.split('~')[1][0].toUpperCase() +
o.attributeFQN.split('~')[1].slice(1).toLowerCase(),
values: [{ label: o.value.toString() }],
})),
})) || [
{
id: '',
},
],
description: productNode.content?.productFullDescription || '',
descriptionHtml: productNode.content?.productFullDescription || '',
images:
productNode.content?.productImages?.map((p: any) => ({
url: `http:${p.imageUrl}`,
altText: p.imageLabel,
})) || [],
variants:
productNode.variations?.map((v: any) => ({
id: v.productCode,
options:
v.options?.map((o: any) => ({
['__typename']: 'MultipleChoiceOption',
id: o.attributeFQN,
displayName:
o.attributeFQN.split('~')[1][0].toUpperCase() +
o.attributeFQN.split('~')[1].slice(1).toLowerCase(),
values: [{ label: o.value.toString() }],
})) ?? [],
})) ?? [],
options:
productNode.options?.map((o: any) => ({
id: o.attributeFQN,
displayName: o.attributeDetail.name,
values: o.values.map((v: any) => ({
label: v.value.toString(),
hexColors: '',
})),
})) || [],
})) ?? [],
}
return product
@@ -57,11 +66,11 @@ export function normalizePage(page: Document): Page {
url: page.properties.url,
body: page.properties.body,
is_visible: page.properties.is_visible,
sort_order: page.properties.sort_order
sort_order: page.properties.sort_order,
}
}
export function normalizeCart(data: any): any {
export function normalizeCart(data: any): Cart {
return {
id: data.id,
customerId: data.userId,
@@ -86,16 +95,15 @@ export function normalizeCart(data: any): any {
export function normalizeCustomer(customer: CustomerAccountInput): Customer {
return {
id: customer.id,
firstName: customer.firstName,
lastName: customer.lastName,
email: customer.emailAddress,
userName: customer.userName,
isAnonymous: customer.isAnonymous
id: String(customer.id),
firstName: customer.firstName || '',
lastName: customer.lastName || '',
email: customer.emailAddress || '',
acceptsMarketing: !!customer.acceptsMarketing,
}
}
function normalizeLineItem(item: any): any {
function normalizeLineItem(item: any): LineItem {
return {
id: item.id,
variantId: item.product.variationProductCode,
@@ -113,7 +121,7 @@ function normalizeLineItem(item: any): any {
price: item?.unitPrice.extendedAmount,
listPrice: 0,
},
options: item.product.options,
options: item.product.options ?? [],
path: `${item.product.productCode}`,
discounts: item?.discounts?.map((discount: any) => ({
value: discount.discounted_amount,
@@ -121,11 +129,11 @@ function normalizeLineItem(item: any): any {
}
}
export function normalizeCategory(category: PrCategory): any {
export function normalizeCategory(category: PrCategory): Category {
return {
id: category?.categoryCode,
name: category?.content?.name,
slug: category?.content?.slug,
id: category?.categoryCode || '',
name: category?.content?.name || '',
slug: category?.content?.slug || '',
path: `/${category?.content?.slug}`,
}
}
@@ -133,11 +141,13 @@ export function normalizeCategory(category: PrCategory): any {
export function normalizeWishlistItem(
item: any,
config: any,
includeProducts=false
): any {
includeProducts = false
): WishlistItem {
if (includeProducts) {
return {
id: item.id,
productId: String(item.product.productCode),
variantId: item.product.variationProductCode,
product: getProuducts(item, config),
}
} else {
@@ -173,7 +183,7 @@ function getProuducts(item: any, config: any): any {
},
},
],
options: item.product.options,
options: item.product.options ?? [],
path: `/${item.product.productCode}`,
description: item.product.description,
}

View File

@@ -1,27 +0,0 @@
import * as Core from '@vercel/commerce/types/customer'
export type Maybe<T> = T | null
export * from '@vercel/commerce/types/customer'
export type Scalars = {
ID: string
String: string
Boolean: boolean
Int: number
Float: number
/** The `AnyScalar` type allows any scalar value by examining the input and passing the serialize, parseValue, and parseLiteral operations to their respective types. */
AnyScalar: any
/** DateTime custom scalar type */
DateTime: any
/** Object custom scalar type */
Object: any
}
export type Customer = {
id: Scalars['Int'],
firstName?: Maybe<Scalars['String']>,
lastName?: Maybe<Scalars['String']>,
email?: Maybe<Scalars['String']>,
userName?: Maybe<Scalars['String']>,
isAnonymous?: Maybe<Scalars['Boolean']>
}
export type CustomerSchema = Core.CustomerSchema

View File

@@ -1,8 +0,0 @@
import * as Core from '@vercel/commerce/types/login'
import type { CustomerUserAuthInfoInput } from '../../schema'
export * from '@vercel/commerce/types/login'
export type LoginOperation = Core.LoginOperation & {
variables: CustomerUserAuthInfoInput
}

View File

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

View File

@@ -1,35 +0,0 @@
import * as Core from '@vercel/commerce/types/page'
export type Maybe<T> = T | null
export type Scalars = {
ID: string
String: string
Boolean: boolean
Int: number
Float: number
/** The `AnyScalar` type allows any scalar value by examining the input and passing the serialize, parseValue, and parseLiteral operations to their respective types. */
AnyScalar: any
/** DateTime custom scalar type */
DateTime: any
/** Object custom scalar type */
Object: any
}
export * from '@vercel/commerce/types/page'
export type Page = Core.Page
export type PageTypes = {
page: Page
}
export type GetPagesQueryParams = {
documentListName: Maybe<Scalars["String"]>
}
export type GetPageQueryParams = {
id: Maybe<Scalars["String"]>
documentListName: Maybe<Scalars["String"]>
}
export type GetAllPagesOperation = Core.GetAllPagesOperation<PageTypes>
export type GetPageOperation = Core.GetPageOperation<PageTypes>

View File

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