Add get-site-info operator

Signed-off-by: Chloe <pinkcloudvnn@gmail.com>
This commit is contained in:
Chloe 2022-04-20 15:43:05 +07:00
parent 31a283a832
commit 8eda86ae82
7 changed files with 148 additions and 34 deletions

View File

@ -1,4 +1,5 @@
{
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.formatOnSave": true
}
"editor.formatOnSave": true,
"typescript.tsdk": "node_modules/typescript/lib"
}

View File

@ -8195,3 +8195,36 @@ export type GetProductBySlugQuery = {
} | null
} | null
}
export type GetTagsQueryVariables = Exact<{
first: Scalars['ConnectionLimitInt']
shopId: Scalars['ID']
}>
export type GetTagsQuery = {
__typename?: 'Query'
tags: {
__typename?: 'TagConnection'
edges: Array<{
__typename?: 'TagEdge'
node: {
__typename?: 'Tag'
_id: string
displayTitle: string | null
slug: string | null
} | null
} | null> | null
} | null
}
export type GetAllProductVendorsQueryVariables = Exact<{
shopIds: Array<InputMaybe<Scalars['ID']>> | InputMaybe<Scalars['ID']>
}>
export type GetAllProductVendorsQuery = {
__typename?: 'Query'
vendors: {
__typename?: 'VendorConnection'
nodes: Array<{ __typename?: 'Vendor'; name: string | null } | null> | null
} | null
}

View File

@ -1,42 +1,63 @@
import { OperationContext } from '@vercel/commerce/api/operations'
import { Category } from '@vercel/commerce/types/site'
import type { OpenCommerceConfig } from '../index'
import {
OperationContext,
OperationOptions,
} from '@vercel/commerce/api/operations'
import {
GetTagsQuery,
GetAllProductVendorsQuery,
GetTagsQueryVariables,
GetAllProductVendorsQueryVariables,
} from '../../../schema'
import getTagsQuery from '../queries/get-tags-query'
import { GetSiteInfoOperation, OCCategory } from '../../types/site'
import { normalizeCategory, normalizeVendors } from '../../utils/normalize'
import type { OpenCommerceConfig, Provider } from '..'
import filterEdges from '../utils/filter-edges'
import getAllProductVendors from '../queries/get-vendors-query'
export type GetSiteInfoResult<
T extends { categories: any[]; brands: any[] } = {
categories: Category[]
brands: any[]
}
> = T
export default function getSiteInfoOperation({
commerce,
}: OperationContext<Provider>) {
async function getSiteInfo<T extends GetSiteInfoOperation>(opts?: {
config?: Partial<OpenCommerceConfig>
preview?: boolean
}): Promise<T['data']>
export default function getSiteInfoOperation({}: OperationContext<any>) {
function getSiteInfo({
query,
variables,
async function getSiteInfo<T extends GetSiteInfoOperation>(
opts: {
config?: Partial<OpenCommerceConfig>
preview?: boolean
} & OperationOptions
): Promise<T['data']>
async function getSiteInfo<T extends GetSiteInfoOperation>({
config: cfg,
}: {
query?: string
variables?: any
config?: Partial<OpenCommerceConfig>
preview?: boolean
} = {}): Promise<GetSiteInfoResult> {
return Promise.resolve({
categories: [
{
id: 'new-arrivals',
name: 'New Arrivals',
slug: 'new-arrivals',
path: '/new-arrivals',
},
{
id: 'featured',
name: 'Featured',
slug: 'featured',
path: '/featured',
},
],
brands: [],
})
} = {}): Promise<T['data']> {
const { fetch, shopId } = commerce.getConfig(cfg)
const [categoriesResponse, vendorsResponse] = await Promise.all([
await fetch<GetTagsQuery, GetTagsQueryVariables>(getTagsQuery, {
variables: { first: 250, shopId },
}),
await fetch<
GetAllProductVendorsQuery,
GetAllProductVendorsQueryVariables
>(getAllProductVendors, { variables: { shopIds: [shopId] } }),
])
const categories = filterEdges(categoriesResponse.data.tags?.edges).map(
(edge) => normalizeCategory(edge.node! as OCCategory)
)
const brands = [
...new Set(filterEdges(vendorsResponse.data.vendors?.nodes)),
].map(normalizeVendors)
return { categories, brands }
}
return getSiteInfo

View File

@ -0,0 +1,14 @@
const getTagsQuery = /* GraphQL */ `
query getTags($first: ConnectionLimitInt!, $shopId: ID!) {
tags(first: $first, shopId: $shopId) {
edges {
node {
_id
displayTitle
slug
}
}
}
}
`
export default getTagsQuery

View File

@ -0,0 +1,10 @@
const getAllProductVendors = /* GraphQL */ `
query getAllProductVendors($shopIds: [ID]!) {
vendors(shopIds: $shopIds) {
nodes {
name
}
}
}
`
export default getAllProductVendors

View File

@ -0,0 +1,15 @@
import { Vendor as QueryVender, TagEdge } from '../../schema'
export * from '@vercel/commerce/types/site'
export type OCCategory = NonNullable<NonNullable<TagEdge>['node']>
export type OCVendor = QueryVender
export type Vendor = {
node: {
entityId: string
name: string
path: string
}
}

View File

@ -4,6 +4,7 @@ import type {
ProductOptionValues,
ProductVariant,
} from '../types/product'
import { OCCategory, Category, Vendor, OCVendor } from '../types/site'
import {
CatalogItemProduct,
CatalogProduct,
@ -205,3 +206,22 @@ function colorizeProductOptionValue(
}
return value
}
export function normalizeCategory(category: OCCategory): Category {
return {
id: category._id,
name: category.displayTitle ?? '',
slug: category.slug ?? '',
path: category.slug ? `/${category.slug}` : '',
}
}
export function normalizeVendors({ name }: OCVendor): Vendor {
return {
node: {
entityId: name ?? '',
name: name ?? '',
path: `brands/${name}`,
},
}
}