Added category type and normalizer

This commit is contained in:
Luis Alvarez 2021-06-01 01:03:44 -05:00
parent 4611748fee
commit a908ebadfd
8 changed files with 45 additions and 28 deletions

View File

@ -4,10 +4,10 @@ import type {
} from '@commerce/api/operations' } from '@commerce/api/operations'
import type { GetSiteInfoOperation } from '../../types/site' import type { GetSiteInfoOperation } from '../../types/site'
import type { GetSiteInfoQuery } from '../../schema' import type { GetSiteInfoQuery } from '../../schema'
import type { RecursivePartial, RecursiveRequired } from '../utils/types'
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'
// Get 3 levels of categories // Get 3 levels of categories
export const getSiteInfoQuery = /* GraphQL */ ` export const getSiteInfoQuery = /* GraphQL */ `
@ -73,15 +73,13 @@ export default function getSiteInfoOperation({
preview?: boolean preview?: boolean
} = {}): Promise<T['data']> { } = {}): Promise<T['data']> {
const cfg = commerce.getConfig(config) const cfg = commerce.getConfig(config)
// RecursivePartial forces the method to check for every prop in the data, which is const { data } = await cfg.fetch<GetSiteInfoQuery>(query)
// required in case there's a custom `query` const categories = data.site.categoryTree.map(normalizeCategory)
const { data } = await cfg.fetch<RecursivePartial<GetSiteInfoQuery>>(query)
const categories = data.site?.categoryTree
const brands = data.site?.brands?.edges const brands = data.site?.brands?.edges
return { return {
categories: (categories as RecursiveRequired<typeof categories>) ?? [], categories: categories ?? [],
brands: filterEdges(brands as RecursiveRequired<typeof brands>), brands: filterEdges(brands),
} }
} }

View File

@ -0,0 +1,5 @@
// Remove trailing and leading slash, usually included in nodes
// returned by the BigCommerce API
const getSlug = (path: string) => path.replace(/^\/|\/$/g, '')
export default getSlug

View File

@ -1,8 +1,10 @@
import type { Product } from '../types/product' import type { Product } from '../types/product'
import type { Cart, BigcommerceCart, LineItem } from '../types/cart' import type { Cart, BigcommerceCart, LineItem } from '../types/cart'
import type { Page } from '../types/page' import type { Page } from '../types/page'
import update from './immutability' import type { BCCategory, Category } from '../types/site'
import { definitions } from '../api/definitions/store-content' import { definitions } from '../api/definitions/store-content'
import update from './immutability'
import getSlug from './get-slug'
function normalizeProductOption(productOption: any) { function normalizeProductOption(productOption: any) {
const { const {
@ -123,3 +125,12 @@ function normalizeLineItem(item: any): LineItem {
})), })),
} }
} }
export function normalizeCategory(category: BCCategory): Category {
return {
id: `${category.entityId}`,
name: category.name,
slug: getSlug(category.path),
path: category.path,
}
}

View File

@ -3,14 +3,16 @@ import type { GetSiteInfoQuery, GetSiteInfoQueryVariables } from '../schema'
export * from '@commerce/types/site' export * from '@commerce/types/site'
export type Category = NonNullable<GetSiteInfoQuery['site']['categoryTree']>[0] export type BCCategory = NonNullable<
GetSiteInfoQuery['site']['categoryTree']
>[0]
export type Brand = NonNullable< export type Brand = NonNullable<
NonNullable<GetSiteInfoQuery['site']['brands']['edges']>[0] NonNullable<GetSiteInfoQuery['site']['brands']['edges']>[0]
> >
export type SiteTypes = { export type SiteTypes = {
category: Category category: Core.Category
brand: Brand brand: Brand
} }

View File

@ -139,15 +139,6 @@ export type RemoveItemHook<T extends CartTypes = CartTypes> = {
actionInput: { id: string } actionInput: { id: string }
} }
export type Category = {
id: string
name: string
slug: string
path: string
}
export type Page = any
/** /**
* API Schema * API Schema
*/ */

View File

@ -1,4 +1,9 @@
export type Category = any export type Category = {
id: string
name: string
slug: string
path: string
}
export type Brand = any export type Brand = any

View File

@ -1,7 +1,8 @@
import type { Category } from '../types/site'
import { ShopifyConfig } from '../api' import { ShopifyConfig } from '../api'
import { CollectionEdge } from '../schema' import { CollectionEdge } from '../schema'
import { normalizeCategory } from './normalize'
import getSiteCollectionsQuery from './queries/get-all-collections-query' import getSiteCollectionsQuery from './queries/get-all-collections-query'
import { Category } from '@commerce/types'
const getCategories = async ({ const getCategories = async ({
fetch, fetch,
@ -24,13 +25,8 @@ const getCategories = async ({
) )
return ( return (
data.collections?.edges?.map( data.collections?.edges?.map(({ node }: CollectionEdge) =>
({ node: { id, title: name, handle } }: CollectionEdge) => ({ normalizeCategory(node)
id,
name,
slug: handle,
path: `/${handle}`,
})
) ?? [] ) ?? []
) )
} }

View File

@ -1,6 +1,7 @@
import type { Page } from '../types/page' import type { Page } from '../types/page'
import type { Product } from '../types/product' import type { Product } from '../types/product'
import type { Cart, LineItem } from '../types/cart' import type { Cart, LineItem } from '../types/cart'
import type { Category } from '../types/site'
import { import {
Product as ShopifyProduct, Product as ShopifyProduct,
@ -181,3 +182,11 @@ export const normalizePage = (
export const normalizePages = (edges: PageEdge[], locale: string): Page[] => export const normalizePages = (edges: PageEdge[], locale: string): Page[] =>
edges?.map((edge) => normalizePage(edge.node, locale)) edges?.map((edge) => normalizePage(edge.node, locale))
export const normalizeCategory = (category: any): Category => ({
id: category.id,
name: category.name,
slug: category.handle,
path: `/${category.handle}`,
})