From 110977424d54baa1259c7d801c5ea50fc7d3304f Mon Sep 17 00:00:00 2001 From: cond0r <1243434+cond0r@users.noreply.github.com> Date: Mon, 5 Sep 2022 21:09:12 +0300 Subject: [PATCH] Update product types --- packages/commerce/src/product/use-search.tsx | 2 +- packages/commerce/src/types/cart.ts | 133 +++++++++++------- packages/commerce/src/types/product.ts | 132 +++++++++++++---- .../shopify/src/api/operations/get-product.ts | 18 +-- 4 files changed, 195 insertions(+), 90 deletions(-) diff --git a/packages/commerce/src/product/use-search.tsx b/packages/commerce/src/product/use-search.tsx index 342b49e6e..7998e9994 100644 --- a/packages/commerce/src/product/use-search.tsx +++ b/packages/commerce/src/product/use-search.tsx @@ -5,7 +5,7 @@ import type { SearchProductsHook } from '../types/product' import type { Provider } from '..' export type UseSearch< - H extends SWRHook> = SWRHook + H extends SWRHook = SWRHook > = ReturnType export const fetcher: HookFetcherFn = SWRFetcher diff --git a/packages/commerce/src/types/cart.ts b/packages/commerce/src/types/cart.ts index e4af878de..f76f71d5c 100644 --- a/packages/commerce/src/types/cart.ts +++ b/packages/commerce/src/types/cart.ts @@ -1,14 +1,68 @@ import type { Discount, Measurement, Image } from './common' export type SelectedOption = { - // The option's id. + /** + * The selected option's id + */ id?: string - // The product option’s name. + /** + * The product option’s name. */ name: string - /// The product option’s value. + /** + * The product option’s value. */ value: string } +export type ProductVariant = { + /** + * The variant's id. */ + id: string + /** + * The SKU (stock keeping unit) associated with the product variant. */ + sku: string + /** + * The product variant’s title, or the product's name. */ + name: string + /** + * Whether a customer needs to provide a shipping address when placing + * an order for the product variant. */ + requiresShipping: boolean + /** + * The product variant’s price after all discounts are applied. */ + price: number + /** + * Product variant’s price, as quoted by the manufacturer/distributor. */ + listPrice: number + /** + * Image associated with the product variant. Falls back to the product image + * if no image is available. */ + image?: Image + /** + * Indicates whether this product variant is in stock. */ + isInStock?: boolean + /** + * Indicates if the product variant is available for sale. */ + availableForSale?: boolean + /** + * The variant's weight. If a weight was not explicitly specified on the */ + /** + * variant this will be the product's weight. */ + weight?: Measurement + /** + * The variant's height. If a height was not explicitly specified on the + * variant, this will be the product's height. */ + height?: Measurement + /** + * The variant's width. If a width was not explicitly specified on the + + * variant, this will be the product's width. */ + width?: Measurement + /** + * The variant's depth. If a depth was not explicitly specified on the + * variant, this will be the product's depth. */ + depth?: Measurement +} + export type LineItem = { id: string variantId: string @@ -16,69 +70,50 @@ export type LineItem = { name: string quantity: number discounts: Discount[] - // A human-friendly unique string automatically generated from the product’s name + /** + * A human-friendly unique string automatically generated from the product’s name. */ path: string variant: ProductVariant options?: SelectedOption[] } -export type ProductVariant = { - id: string - // The SKU (stock keeping unit) associated with the product variant. - sku: string - // The product variant’s title, or the product's name. - name: string - // Whether a customer needs to provide a shipping address when placing - // an order for the product variant. - requiresShipping: boolean - // The product variant’s price after all discounts are applied. - price: number - // Product variant’s price, as quoted by the manufacturer/distributor. - listPrice: number - // Image associated with the product variant. Falls back to the product image - // if no image is available. - image?: Image - // Indicates whether this product variant is in stock. - isInStock?: boolean - // Indicates if the product variant is available for sale. - availableForSale?: boolean - // The variant's weight. If a weight was not explicitly specified on the - // variant this will be the product's weight. - weight?: Measurement - // The variant's height. If a height was not explicitly specified on the - // variant, this will be the product's height. - height?: Measurement - // The variant's width. If a width was not explicitly specified on the - // variant, this will be the product's width. - width?: Measurement - // The variant's depth. If a depth was not explicitly specified on the - // variant, this will be the product's depth. - depth?: Measurement -} - // Shopping cart, a.k.a Checkout + export type Cart = { + /** + * The cart's id. */ id: string - // ID of the customer to which the cart belongs. + /** + * ID of the customer to which the cart belongs. */ customerId?: string - // The email assigned to this cart + /** + * The email assigned to this cart. */ email?: string - // The date and time when the cart was created. + /** + * The date and time when the cart was created. */ createdAt: string - // The currency used for this cart + /** + * The currency used for this cart */ currency: { code: string } - // Specifies if taxes are included in the line items. + /** + * Specifies if taxes are included in the line items. */ taxesIncluded: boolean lineItems: LineItem[] - // The sum of all the prices of all the items in the cart. - // Duties, taxes, shipping and discounts excluded. + /** + * The sum of all the prices of all the items in the cart. */ + /** + * Duties, taxes, shipping and discounts excluded. */ lineItemsSubtotalPrice: number - // Price of the cart before duties, shipping and taxes. + /** + * Price of the cart before duties, shipping and taxes.*/ subtotalPrice: number - // The sum of all the prices of all the items in the cart. - // Duties, taxes and discounts included. + /** + * The sum of all the prices of all the items in the cart.*/ + /** + * Duties, taxes and discounts included.*/ totalPrice: number - // Discounts that have been applied on the cart. + /** + * Discounts that have been applied on the cart.*/ discounts?: Discount[] } diff --git a/packages/commerce/src/types/product.ts b/packages/commerce/src/types/product.ts index fb48ba00b..0fa24e7bb 100644 --- a/packages/commerce/src/types/product.ts +++ b/packages/commerce/src/types/product.ts @@ -1,91 +1,157 @@ -export type ProductImage = { +export interface ProductImage { + /** + * The URL of the product image. + */ url: string + /** + * A word or phrase that describes the content of an image. + */ alt?: string } -export type ProductPrice = { +export interface ProductPrice { + /** + * Decimal price amount. */ value: number + /** + * Currency of the product price. */ currencyCode?: 'USD' | 'EUR' | 'ARS' | 'GBP' | string + /** + * The retail price of the product. This can be used to mark a product as on sale, when `retailPrice` is higher than the price a.k.a `value`. */ retailPrice?: number - salePrice?: number - listPrice?: number + extendedSalePrice?: number extendedListPrice?: number } -export type ProductOption = { +export interface ProductOption { __typename?: 'MultipleChoiceOption' + /** + * The option's id. */ id: string + /** + * The option's name. */ displayName: string + /** + * List of option values. */ values: ProductOptionValues[] } -export type ProductOptionValues = { +export interface ProductOptionValues { + /** + * A string that uniquely identifies the option value. */ label: string + /** + * List of hex colors used to display the actual colors in the swatches instead of the name. */ hexColors?: string[] } - -export type ProductVariant = { +export interface ProductVariant { + /** + * The variant's id. */ id: string | number + /** + * List of product options. */ options: ProductOption[] + /** + * Indicates if the variant is available for sale. */ availableForSale?: boolean } -export type Product = { +export interface Product { + /** + * The product's id. */ id: string + /** + * The product's name. */ name: string + /** + * Stripped description of the product, single line. */ description: string + /** + * The description of the product, complete with HTML formatting. */ descriptionHtml?: string + /** + * The SKU (stock keeping unit) associated with the product. + */ sku?: string + /** + * A human-friendly unique string for the product, automatically generated from its title. */ slug?: string + /** + * A human-friendly string for the product, containing U. */ path?: string + /** + * List of images associated with the product. */ images: ProductImage[] + /** + * List of the product’s variants. */ variants: ProductVariant[] + /** + * The product's base price. Could be the minimum value, or default variant price. */ price: ProductPrice + /** + * The product's price. */ options: ProductOption[] + /** + * The product’s vendor name. */ vendor?: string } -export type SearchProductsBody = { +export interface SearchProductsBody { + /** + * The search query string to filter the products by. + */ search?: string + /** + * The category ID to filter the products by. + */ categoryId?: string | number + /** + * The brand ID to filter the products by. + */ brandId?: string | number + /** + * The sort order to sort the products by. + */ sort?: string + /** + * The locale code, used to localize the product data (if the provider supports it). + */ locale?: string } -export type ProductTypes = { - product: Product - searchBody: SearchProductsBody -} - -export type SearchProductsHook = { +export interface SearchProductsHook { data: { - products: T['product'][] + /** + * List of products matching the query. */ + products: Product[] + /** + * Indicates if there are any products matching the query. */ found: boolean } - body: T['searchBody'] - input: T['searchBody'] - fetcherInput: T['searchBody'] + body: SearchProductsBody + /** + * Indicates if the request is loading. */ + input: SearchProductsBody + fetcherInput: SearchProductsBody } -export type ProductsSchema = { +export interface ProductsSchema { endpoint: { options: {} handlers: { - getProducts: SearchProductsHook + getProducts: SearchProductsHook } } } -export type GetAllProductPathsOperation = - { - data: { products: Pick[] } - variables: { first?: number } - } +export interface GetAllProductPathsOperation { + data: { products: Pick[] } + variables: { first?: number } +} -export type GetAllProductsOperation = { - data: { products: T['product'][] } +export interface GetAllProductsOperation { + data: { products: Product[] } variables: { relevance?: 'featured' | 'best_selling' | 'newest' ids?: string[] @@ -93,7 +159,11 @@ export type GetAllProductsOperation = { } } -export type GetProductOperation = { - data: { product?: T['product'] } +export interface GetProductOperation { + /** + * Returned data from the operation. */ + data: { product?: Product } + /** + * The variables to pass to the operation.*/ variables: { path: string; slug?: never } | { path?: never; slug: string } } diff --git a/packages/shopify/src/api/operations/get-product.ts b/packages/shopify/src/api/operations/get-product.ts index 1697b0feb..eeaa3f161 100644 --- a/packages/shopify/src/api/operations/get-product.ts +++ b/packages/shopify/src/api/operations/get-product.ts @@ -13,30 +13,30 @@ import { export default function getProductOperation({ commerce, }: OperationContext) { - async function getProduct(opts: { - variables: T['variables'] + async function getProduct(opts: { + variables: GetProductOperation['variables'] config?: Partial preview?: boolean - }): Promise + }): Promise - async function getProduct( + async function getProduct( opts: { - variables: T['variables'] + variables: GetProductOperation['variables'] config?: Partial preview?: boolean } & OperationOptions - ): Promise + ): Promise - async function getProduct({ + async function getProduct({ query = getProductQuery, variables, config: cfg, }: { query?: string - variables: T['variables'] + variables: GetProductOperation['variables'] config?: Partial preview?: boolean - }): Promise { + }): Promise { const { fetch, locale } = commerce.getConfig(cfg) const {