Added custom image sizes

This commit is contained in:
Luis Alvarez 2020-09-30 15:59:46 -05:00
parent 63a7ebc71d
commit af38839384
5 changed files with 115 additions and 41 deletions

View File

@ -3,7 +3,7 @@ import {
CommerceAPIOptions,
CommerceAPIFetchOptions,
} from 'lib/commerce/api';
import { GetAllProductsQuery } from '../schema';
import { GetAllProductsQuery, GetAllProductsQueryVariables } from '../schema';
import { getAllProductsQuery } from './operations/get-all-products';
type RecursivePartial<T> = {
@ -16,19 +16,61 @@ export interface GetAllProductsResult<T> {
: unknown;
}
export interface Images {
small?: ImageOptions;
medium?: ImageOptions;
large?: ImageOptions;
xl?: ImageOptions;
}
export interface ImageOptions {
width: number;
height?: number;
}
export interface BigcommerceAPIOptions extends CommerceAPIOptions {
images?: Images;
}
export type ProductImageVariables = Pick<
GetAllProductsQueryVariables,
| 'imgSmallWidth'
| 'imgSmallHeight'
| 'imgMediumWidth'
| 'imgMediumHeight'
| 'imgLargeWidth'
| 'imgLargeHeight'
| 'imgXLWidth'
| 'imgXLHeight'
>;
export type ProductVariables = Images &
Omit<GetAllProductsQueryVariables, keyof ProductImageVariables>;
export default class BigcommerceAPI implements CommerceAPI {
commerceUrl: string;
apiToken: string;
imageVariables?: ProductImageVariables;
constructor({ commerceUrl, apiToken }: CommerceAPIOptions) {
constructor({ commerceUrl, apiToken, images }: BigcommerceAPIOptions) {
this.commerceUrl = commerceUrl;
this.apiToken = apiToken;
this.imageVariables = {
imgSmallWidth: images?.small?.width,
imgSmallHeight: images?.small?.height,
imgMediumWidth: images?.medium?.height,
imgMediumHeight: images?.medium?.height,
imgLargeWidth: images?.large?.height,
imgLargeHeight: images?.large?.height,
imgXLWidth: images?.xl?.height,
imgXLHeight: images?.xl?.height,
};
}
async fetch<T>(
async fetch<Q, V = any>(
query: string,
{ variables, preview }: CommerceAPIFetchOptions = {}
): Promise<T> {
{ variables, preview }: CommerceAPIFetchOptions<V> = {}
): Promise<Q> {
const res = await fetch(this.commerceUrl + (preview ? '/preview' : ''), {
method: 'POST',
headers: {
@ -49,20 +91,33 @@ export default class BigcommerceAPI implements CommerceAPI {
return json.data;
}
async getAllProducts<T>(opts: {
async getAllProducts<T, V = any>(opts: {
query: string;
variables?: V;
}): Promise<GetAllProductsResult<T>>;
async getAllProducts(opts?: {
query?: string;
variables?: ProductVariables;
}): Promise<GetAllProductsResult<GetAllProductsQuery>>;
async getAllProducts({
query = getAllProductsQuery,
}: { query?: string } = {}): Promise<
variables: vars,
}: {
query?: string;
variables?: ProductVariables;
} = {}): Promise<
GetAllProductsResult<RecursivePartial<GetAllProductsQuery>>
> {
const data = await this.fetch<RecursivePartial<GetAllProductsQuery>>(query);
const variables: GetAllProductsQueryVariables = {
...this.imageVariables,
...vars,
};
const data = await this.fetch<RecursivePartial<GetAllProductsQuery>>(
query,
{ variables }
);
return {
products: data?.site?.products?.edges,

View File

@ -1,16 +1,17 @@
export const responsiveImageFragment = /* GraphQL */ `
fragment responsiveImage on Image {
url320wide: url(width: 320)
url640wide: url(width: 640)
url960wide: url(width: 960)
url1280wide: url(width: 1280)
}
`;
export const getAllProductsQuery = /* GraphQL */ `
query getAllProducts {
query getAllProducts(
$first: Int = 10
$imgSmallWidth: Int = 320
$imgSmallHeight: Int
$imgMediumWidth: Int = 640
$imgMediumHeight: Int
$imgLargeWidth: Int = 960
$imgLargeHeight: Int
$imgXLWidth: Int = 1280
$imgXLHeight: Int
) {
site {
products(first: 4) {
products(first: $first) {
pageInfo {
startCursor
endCursor
@ -38,7 +39,13 @@ export const getAllProductsQuery = /* GraphQL */ `
images {
edges {
node {
...responsiveImage
urlSmall: url(width: $imgSmallWidth, height: $imgSmallHeight)
urlMedium: url(
width: $imgMediumWidth
height: $imgMediumHeight
)
urlLarge: url(width: $imgLargeWidth, height: $imgLargeHeight)
urlXL: url(width: $imgXLWidth, height: $imgXLHeight)
}
}
}
@ -47,7 +54,19 @@ export const getAllProductsQuery = /* GraphQL */ `
node {
entityId
defaultImage {
...responsiveImage
urlSmall: url(
width: $imgSmallWidth
height: $imgSmallHeight
)
urlMedium: url(
width: $imgMediumWidth
height: $imgMediumHeight
)
urlLarge: url(
width: $imgLargeWidth
height: $imgLargeHeight
)
urlXL: url(width: $imgXLWidth, height: $imgXLHeight)
}
}
}
@ -74,6 +93,4 @@ export const getAllProductsQuery = /* GraphQL */ `
}
}
}
${responsiveImageFragment}
`;

View File

@ -1649,12 +1649,17 @@ export enum CurrencyCode {
export type ResponsiveImageFragment = (
{ __typename?: 'Image' }
& { url320wide: Image['url'], url640wide: Image['url'], url960wide: Image['url'], url1280wide: Image['url'] }
);
export type GetAllProductsQueryVariables = Exact<{ [key: string]: never; }>;
export type GetAllProductsQueryVariables = Exact<{
first?: Maybe<Scalars['Int']>;
imgSmallWidth?: Maybe<Scalars['Int']>;
imgSmallHeight?: Maybe<Scalars['Int']>;
imgMediumWidth?: Maybe<Scalars['Int']>;
imgMediumHeight?: Maybe<Scalars['Int']>;
imgLargeWidth?: Maybe<Scalars['Int']>;
imgLargeHeight?: Maybe<Scalars['Int']>;
imgXLWidth?: Maybe<Scalars['Int']>;
imgXLHeight?: Maybe<Scalars['Int']>;
}>;
export type GetAllProductsQuery = (
@ -1690,7 +1695,7 @@ export type GetAllProductsQuery = (
{ __typename?: 'ImageEdge' }
& { node: (
{ __typename?: 'Image' }
& ResponsiveImageFragment
& { urlSmall: Image['url'], urlMedium: Image['url'], urlLarge: Image['url'], urlXL: Image['url'] }
) }
)>>> }
), variants: (
@ -1702,7 +1707,7 @@ export type GetAllProductsQuery = (
& Pick<Variant, 'entityId'>
& { defaultImage?: Maybe<(
{ __typename?: 'Image' }
& ResponsiveImageFragment
& { urlSmall: Image['url'], urlMedium: Image['url'], urlLarge: Image['url'], urlXL: Image['url'] }
)> }
) }
)>>> }

View File

@ -3,8 +3,8 @@ export interface CommerceAPIOptions {
apiToken: string;
}
export interface CommerceAPIFetchOptions {
variables?: object;
export interface CommerceAPIFetchOptions<V> {
variables?: V;
preview?: boolean;
}
@ -12,13 +12,10 @@ export interface CommerceAPI {
commerceUrl: string;
apiToken: string;
fetch<T>(query: string, queryData?: CommerceAPIFetchOptions): Promise<T>;
fetch<Q, V = any>(
query: string,
queryData?: CommerceAPIFetchOptions<V>
): Promise<Q>;
getAllProducts(options?: { query: string }): Promise<any>;
}
// export default class CommerceAPI {
// getAllProducts(query: string) {
// }
// }

View File

@ -3,7 +3,7 @@ import { commerce } from 'lib/commerce-api';
import { Layout } from '@components/core';
export async function getStaticProps({ preview }: GetStaticPropsContext) {
const products = await commerce.getAllProducts();
const { products } = await commerce.getAllProducts();
return {
props: { products },