Moved getSiteInfo

This commit is contained in:
Luis Alvarez 2021-05-21 18:49:11 -05:00
parent 74a93b4900
commit f2c79d07a7
8 changed files with 145 additions and 112 deletions

View File

@ -18,6 +18,7 @@ import type { SignupAPI } from './endpoints/signup'
import login from './operations/login' import login from './operations/login'
import getAllPages from './operations/get-all-pages' import getAllPages from './operations/get-all-pages'
import getPage from './operations/get-page' import getPage from './operations/get-page'
import getSiteInfo from './operations/get-site-info'
export interface BigcommerceConfig extends CommerceAPIConfig { export interface BigcommerceConfig extends CommerceAPIConfig {
// Indicates if the returned metadata with translations should be applied to the // Indicates if the returned metadata with translations should be applied to the
@ -113,7 +114,7 @@ const config2: BigcommerceConfig = {
export const provider = { export const provider = {
config: config2, config: config2,
operations: { login, getAllPages, getPage }, operations: { login, getAllPages, getPage, getSiteInfo },
} }
export type Provider = typeof provider export type Provider = typeof provider

View File

@ -0,0 +1,91 @@
import type {
OperationContext,
OperationOptions,
} from '@commerce/api/operations'
import type { GetSiteInfoOperation } from '../../types/site'
import type { GetSiteInfoQuery } from '../../schema'
import type { RecursivePartial, RecursiveRequired } from '../utils/types'
import filterEdges from '../utils/filter-edges'
import type { BigcommerceConfig, Provider } from '..'
import { categoryTreeItemFragment } from '../fragments/category-tree'
// Get 3 levels of categories
export const getSiteInfoQuery = /* GraphQL */ `
query getSiteInfo {
site {
categoryTree {
...categoryTreeItem
children {
...categoryTreeItem
children {
...categoryTreeItem
}
}
}
brands {
pageInfo {
startCursor
endCursor
}
edges {
cursor
node {
entityId
name
defaultImage {
urlOriginal
altText
}
pageTitle
metaDesc
metaKeywords
searchKeywords
path
}
}
}
}
}
${categoryTreeItemFragment}
`
export default function getSiteInfoOperation({
commerce,
}: OperationContext<Provider>) {
async function getSiteInfo<T extends GetSiteInfoOperation>(opts?: {
config?: BigcommerceConfig
preview?: boolean
}): Promise<T['data']>
async function getSiteInfo<T extends GetSiteInfoOperation>(
opts: {
config?: BigcommerceConfig
preview?: boolean
} & OperationOptions
): Promise<T['data']>
async function getSiteInfo<T extends GetSiteInfoOperation>({
query = getSiteInfoQuery,
config,
}: {
query?: string
config?: BigcommerceConfig
preview?: boolean
} = {}): Promise<T['data']> {
config = commerce.getConfig(config)
// RecursivePartial forces the method to check for every prop in the data, which is
// required in case there's a custom `query`
const { data } = await config.fetch<RecursivePartial<GetSiteInfoQuery>>(
query
)
const categories = data.site?.categoryTree
const brands = data.site?.brands?.edges
return {
categories: (categories as RecursiveRequired<typeof categories>) ?? [],
brands: filterEdges(brands as RecursiveRequired<typeof brands>),
}
}
return getSiteInfo
}

View File

@ -1,106 +0,0 @@
import type { GetSiteInfoQuery, GetSiteInfoQueryVariables } from '../schema'
import type { RecursivePartial, RecursiveRequired } from '../api/utils/types'
import filterEdges from '../api/utils/filter-edges'
import { BigcommerceConfig, getConfig } from '../api'
import { categoryTreeItemFragment } from '../api/fragments/category-tree'
// Get 3 levels of categories
export const getSiteInfoQuery = /* GraphQL */ `
query getSiteInfo {
site {
categoryTree {
...categoryTreeItem
children {
...categoryTreeItem
children {
...categoryTreeItem
}
}
}
brands {
pageInfo {
startCursor
endCursor
}
edges {
cursor
node {
entityId
name
defaultImage {
urlOriginal
altText
}
pageTitle
metaDesc
metaKeywords
searchKeywords
path
}
}
}
}
}
${categoryTreeItemFragment}
`
export type CategoriesTree = NonNullable<
GetSiteInfoQuery['site']['categoryTree']
>
export type BrandEdge = NonNullable<
NonNullable<GetSiteInfoQuery['site']['brands']['edges']>[0]
>
export type Brands = BrandEdge[]
export type GetSiteInfoResult<
T extends { categories: any[]; brands: any[] } = {
categories: CategoriesTree
brands: Brands
}
> = T
async function getSiteInfo(opts?: {
variables?: GetSiteInfoQueryVariables
config?: BigcommerceConfig
preview?: boolean
}): Promise<GetSiteInfoResult>
async function getSiteInfo<
T extends { categories: any[]; brands: any[] },
V = any
>(opts: {
query: string
variables?: V
config?: BigcommerceConfig
preview?: boolean
}): Promise<GetSiteInfoResult<T>>
async function getSiteInfo({
query = getSiteInfoQuery,
variables,
config,
}: {
query?: string
variables?: GetSiteInfoQueryVariables
config?: BigcommerceConfig
preview?: boolean
} = {}): Promise<GetSiteInfoResult> {
config = getConfig(config)
// RecursivePartial forces the method to check for every prop in the data, which is
// required in case there's a custom `query`
const { data } = await config.fetch<RecursivePartial<GetSiteInfoQuery>>(
query,
{ variables }
)
const categories = data.site?.categoryTree
const brands = data.site?.brands?.edges
return {
categories: (categories as RecursiveRequired<typeof categories>) ?? [],
brands: filterEdges(brands as RecursiveRequired<typeof brands>),
}
}
export default getSiteInfo

View File

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

View File

@ -1,6 +1,7 @@
import type { ServerResponse } from 'http'
import type { LoginOperation } from '../types/login' import type { LoginOperation } from '../types/login'
import type { GetAllPagesOperation, GetPageOperation } from '../types/page' import type { GetAllPagesOperation, GetPageOperation } from '../types/page'
import type { ServerResponse } from 'http' import type { GetSiteInfoOperation } from '../types/site'
import type { APIProvider, CommerceAPI } from '.' import type { APIProvider, CommerceAPI } from '.'
const noop = () => { const noop = () => {
@ -32,6 +33,7 @@ export type Operations<P extends APIProvider> = {
} & OperationOptions } & OperationOptions
): Promise<T['data']> ): Promise<T['data']>
} }
getAllPages: { getAllPages: {
<T extends GetAllPagesOperation>(opts?: { <T extends GetAllPagesOperation>(opts?: {
config?: P['config'] config?: P['config']
@ -45,6 +47,7 @@ export type Operations<P extends APIProvider> = {
} & OperationOptions } & OperationOptions
): Promise<T['data']> ): Promise<T['data']>
} }
getPage: { getPage: {
<T extends GetPageOperation>(opts: { <T extends GetPageOperation>(opts: {
variables: T['variables'] variables: T['variables']
@ -60,6 +63,20 @@ export type Operations<P extends APIProvider> = {
} & OperationOptions } & OperationOptions
): Promise<T['data']> ): Promise<T['data']>
} }
getSiteInfo: {
<T extends GetSiteInfoOperation>(opts: {
config?: P['config']
preview?: boolean
}): Promise<T['data']>
<T extends GetSiteInfoOperation>(
opts: {
config?: P['config']
preview?: boolean
} & OperationOptions
): Promise<T['data']>
}
} }
export type APIOperations<P extends APIProvider> = { export type APIOperations<P extends APIProvider> = {

View File

@ -0,0 +1,15 @@
export type Category = any
export type Brand = any
export type SiteTypes = {
category: Category
brand: Brand
}
export type GetSiteInfoOperation<T extends SiteTypes = SiteTypes> = {
data: {
categories: T['category'][]
brands: T['brand'][]
}
}

View File

@ -7,7 +7,6 @@ import type { GetStaticPropsContext, InferGetStaticPropsType } from 'next'
import { getConfig } from '@framework/api' import { getConfig } from '@framework/api'
import getAllProducts from '@framework/product/get-all-products' import getAllProducts from '@framework/product/get-all-products'
import getSiteInfo from '@framework/common/get-site-info'
export async function getStaticProps({ export async function getStaticProps({
preview, preview,
@ -21,7 +20,7 @@ export async function getStaticProps({
preview, preview,
}) })
const { categories, brands } = await getSiteInfo({ config, preview }) const { categories, brands } = await commerce.getSiteInfo({ config, preview })
const { pages } = await commerce.getAllPages({ config, preview }) const { pages } = await commerce.getAllPages({ config, preview })
return { return {

View File

@ -10,7 +10,6 @@ import { Container, Grid, Skeleton } from '@components/ui'
import { getConfig } from '@framework/api' import { getConfig } from '@framework/api'
import useSearch from '@framework/product/use-search' import useSearch from '@framework/product/use-search'
import getSiteInfo from '@framework/common/get-site-info'
import commerce from '@lib/api/commerce' import commerce from '@lib/api/commerce'
import rangeMap from '@lib/range-map' import rangeMap from '@lib/range-map'
@ -39,7 +38,7 @@ export async function getStaticProps({
}: GetStaticPropsContext) { }: GetStaticPropsContext) {
const config = getConfig({ locale }) const config = getConfig({ locale })
const { pages } = await commerce.getAllPages({ config, preview }) const { pages } = await commerce.getAllPages({ config, preview })
const { categories, brands } = await getSiteInfo({ config, preview }) const { categories, brands } = await commerce.getSiteInfo({ config, preview })
return { return {
props: { props: {
pages, pages,