4
0
forked from crowetic/commerce

Improved types and added method for product

This commit is contained in:
Luis Alvarez
2020-10-01 14:53:29 -05:00
parent 2971b4f802
commit fdb306a988
5 changed files with 245 additions and 20 deletions

View File

@@ -1,9 +1,9 @@
import {
import type {
GetAllProductsQuery,
GetAllProductsQueryVariables,
} from 'lib/bigcommerce/schema';
import type { RecursivePartial, RecursiveRequired } from '../types';
import { getConfig, Images, ProductImageVariables } from '..';
import { RecursivePartial } from '../types';
export const getAllProductsQuery = /* GraphQL */ `
query getAllProducts(
@@ -104,42 +104,45 @@ export const getAllProductsQuery = /* GraphQL */ `
export interface GetAllProductsResult<T> {
products: T extends GetAllProductsQuery
? T['site']['products']['edges']
? NonNullable<T['site']['products']['edges']>
: unknown;
}
export type ProductVariables = Images &
Omit<GetAllProductsQueryVariables, keyof ProductImageVariables>;
async function getAllProducts<T, V = any>(opts: {
query: string;
variables?: V;
}): Promise<GetAllProductsResult<T>>;
async function getAllProducts(opts?: {
query?: string;
variables?: ProductVariables;
}): Promise<GetAllProductsResult<GetAllProductsQuery>>;
async function getAllProducts<T, V = any>(opts: {
query: string;
variables?: V;
}): Promise<GetAllProductsResult<T>>;
async function getAllProducts({
query = getAllProductsQuery,
variables: vars,
}: {
query?: string;
variables?: ProductVariables;
} = {}): Promise<GetAllProductsResult<RecursivePartial<GetAllProductsQuery>>> {
} = {}): Promise<GetAllProductsResult<GetAllProductsQuery>> {
const config = getConfig();
const variables: GetAllProductsQueryVariables = {
...config.imageVariables,
...vars,
};
// 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<GetAllProductsQuery>>(
query,
{ variables }
);
const products = data.site?.products?.edges;
return {
products: data?.site?.products?.edges,
products: (products as RecursiveRequired<typeof products>) ?? [],
};
}

View File

@@ -0,0 +1,131 @@
import type {
GetProductQuery,
GetProductQueryVariables,
} from 'lib/bigcommerce/schema';
import type { RecursivePartial, RecursiveRequired } from '../types';
import { getConfig, Images, ProductImageVariables } from '..';
export const getProductQuery = /* GraphQL */ `
query getProduct(
$slug: String!
$imgSmallWidth: Int = 320
$imgSmallHeight: Int
$imgMediumWidth: Int = 640
$imgMediumHeight: Int
$imgLargeWidth: Int = 960
$imgLargeHeight: Int
$imgXLWidth: Int = 1280
$imgXLHeight: Int
) {
site {
route(path: $slug) {
node {
__typename
... on Product {
entityId
name
path
brand {
name
}
description
prices {
price {
currencyCode
value
}
salePrice {
currencyCode
value
}
}
images {
edges {
node {
urlSmall: url(width: $imgSmallWidth, height: $imgSmallHeight)
urlMedium: url(
width: $imgMediumWidth
height: $imgMediumHeight
)
urlLarge: url(width: $imgLargeWidth, height: $imgLargeHeight)
urlXL: url(width: $imgXLWidth, height: $imgXLHeight)
}
}
}
variants {
edges {
node {
entityId
}
}
}
options {
edges {
node {
entityId
displayName
isRequired
values {
edges {
node {
entityId
label
}
}
}
}
}
}
}
}
}
}
}
`;
export interface GetProductResult<T> {
product?: T extends GetProductQuery
? Extract<T['site']['route']['node'], { __typename: 'Product' }>
: unknown;
}
export type ProductVariables = Images &
Omit<GetProductQueryVariables, keyof ProductImageVariables>;
async function getProduct(opts: {
query?: string;
variables: ProductVariables;
}): Promise<GetProductResult<GetProductQuery>>;
async function getProduct<T, V = any>(opts: {
query: string;
variables: V;
}): Promise<GetProductResult<T>>;
async function getProduct({
query = getProductQuery,
variables: vars,
}: {
query?: string;
variables: ProductVariables;
}): Promise<GetProductResult<GetProductQuery>> {
const config = getConfig();
const variables: GetProductQueryVariables = {
...config.imageVariables,
...vars,
};
const data = await config.fetch<RecursivePartial<GetProductQuery>>(query, {
variables,
});
const product = data.site?.route?.node;
if (product?.__typename === 'Product') {
return {
product: product as RecursiveRequired<typeof product>,
};
}
return {};
}
export default getProduct;

View File

@@ -1,3 +1,7 @@
export type RecursivePartial<T> = {
[P in keyof T]?: RecursivePartial<T[P]>;
};
export type RecursiveRequired<T> = {
[P in keyof T]-?: RecursiveRequired<T[P]>;
};