From a8814983a6dad2142e616e6646a99b2ffd5134c6 Mon Sep 17 00:00:00 2001 From: Belen Curcio Date: Wed, 6 Jan 2021 17:01:32 -0300 Subject: [PATCH 001/216] changes --- .../ProductCard/FUTURE_ProductCard.tsx | 57 +++++++++++++++++++ framework/types.d.ts | 25 ++++++++ 2 files changed, 82 insertions(+) create mode 100644 components/product/ProductCard/FUTURE_ProductCard.tsx create mode 100644 framework/types.d.ts diff --git a/components/product/ProductCard/FUTURE_ProductCard.tsx b/components/product/ProductCard/FUTURE_ProductCard.tsx new file mode 100644 index 000000000..0b5c3aece --- /dev/null +++ b/components/product/ProductCard/FUTURE_ProductCard.tsx @@ -0,0 +1,57 @@ +import { FC } from 'react' +import cn from 'classnames' +import Image from 'next/image' +import s from './ProductCard.module.css' +// import WishlistButton from '@components/wishlist/WishlistButton' + +interface Props { + className?: string + product: Product + variant?: 'slim' | 'simple' +} + +const ProductCard: FC = ({ className, product, variant }) => { + const defaultImageProps = { + layout: 'responsive', + } + + return ( + + {variant === 'slim' ? ( +
+
+ + {product.name} + + {/* Image */} +
+
+ ) : ( + <> +
+
+
+

+ {product.name} +

+ {product.price} +
+
+
+ {/* Image */} + + {product.name} +
+ + )} +
+ ) +} + +export default ProductCard diff --git a/framework/types.d.ts b/framework/types.d.ts new file mode 100644 index 000000000..40d7390a7 --- /dev/null +++ b/framework/types.d.ts @@ -0,0 +1,25 @@ +interface Product { + id: string | number + name: string + description: string + images: Images[] + slug: string + price: string + variantId: string +} + +interface Images { + src: string + alt?: string +} + +interface NextImage { + src: string + width: number | string + height: number | string + layout?: 'fixed' | 'intrinsic' | 'responsive' | undefined + priority?: boolean + loading?: 'eager' | 'lazy' + sizes?: string + alt?: string +} From 36396e23c10110c29d125b1daae555b04ebefffd Mon Sep 17 00:00:00 2001 From: Belen Curcio Date: Wed, 6 Jan 2021 21:24:09 -0300 Subject: [PATCH 002/216] Progress --- .../ProductCard/FUTURE_ProductCard.tsx | 19 +-- framework/types.d.ts | 20 +-- pages/index copy.tsx | 152 ++++++++++++++++++ pages/index.tsx | 32 ++-- 4 files changed, 188 insertions(+), 35 deletions(-) create mode 100644 pages/index copy.tsx diff --git a/components/product/ProductCard/FUTURE_ProductCard.tsx b/components/product/ProductCard/FUTURE_ProductCard.tsx index 0b5c3aece..7ef41b0be 100644 --- a/components/product/ProductCard/FUTURE_ProductCard.tsx +++ b/components/product/ProductCard/FUTURE_ProductCard.tsx @@ -1,20 +1,18 @@ import { FC } from 'react' import cn from 'classnames' -import Image from 'next/image' +import Image, { ImageProps } from 'next/image' import s from './ProductCard.module.css' +// Restore Wishlist func // import WishlistButton from '@components/wishlist/WishlistButton' interface Props { className?: string product: Product variant?: 'slim' | 'simple' + imgProps?: Omit } -const ProductCard: FC = ({ className, product, variant }) => { - const defaultImageProps = { - layout: 'responsive', - } - +const ProductCard: FC = ({ className, product, variant, imgProps }) => { return ( {variant === 'slim' ? ( @@ -38,14 +36,13 @@ const ProductCard: FC = ({ className, product, variant }) => {
- {/* Image */} - {product.name}
diff --git a/framework/types.d.ts b/framework/types.d.ts index 40d7390a7..a05f03a69 100644 --- a/framework/types.d.ts +++ b/framework/types.d.ts @@ -13,13 +13,13 @@ interface Images { alt?: string } -interface NextImage { - src: string - width: number | string - height: number | string - layout?: 'fixed' | 'intrinsic' | 'responsive' | undefined - priority?: boolean - loading?: 'eager' | 'lazy' - sizes?: string - alt?: string -} +// interface NextImageProps { +// src: string +// width: number | string +// height: number | string +// layout?: 'fixed' | 'intrinsic' | 'responsive' | undefined +// priority?: boolean +// loading?: 'eager' | 'lazy' +// sizes?: string +// alt?: string +// } diff --git a/pages/index copy.tsx b/pages/index copy.tsx new file mode 100644 index 000000000..ef1c0a96e --- /dev/null +++ b/pages/index copy.tsx @@ -0,0 +1,152 @@ +import rangeMap from '@lib/range-map' +import { Layout } from '@components/common' +import { ProductCard } from '@components/product' +import { Grid, Marquee, Hero } from '@components/ui' +import HomeAllProductsGrid from '@components/common/HomeAllProductsGrid' +import type { GetStaticPropsContext, InferGetStaticPropsType } from 'next' + +import { getConfig } from '@framework/api' +import getAllProducts from '@framework/api/operations/get-all-products' +import getSiteInfo from '@framework/api/operations/get-site-info' +import getAllPages from '@framework/api/operations/get-all-pages' + +export async function getStaticProps({ + preview, + locale, +}: GetStaticPropsContext) { + const config = getConfig({ locale }) + + // Get Featured Products + const { products: featuredProducts } = await getAllProducts({ + variables: { field: 'featuredProducts', first: 6 }, + config, + preview, + }) + + // Get Best Selling Products + const { products: bestSellingProducts } = await getAllProducts({ + variables: { field: 'bestSellingProducts', first: 6 }, + config, + preview, + }) + + // Get Best Newest Products + const { products: newestProducts } = await getAllProducts({ + variables: { field: 'newestProducts', first: 12 }, + config, + preview, + }) + + const { categories, brands } = await getSiteInfo({ config, preview }) + const { pages } = await getAllPages({ config, preview }) + + // These are the products that are going to be displayed in the landing. + // We prefer to do the computation at buildtime/servertime + const { featured, bestSelling } = (() => { + // Create a copy of products that we can mutate + const products = [...newestProducts] + // If the lists of featured and best selling products don't have enough + // products, then fill them with products from the products list, this + // is useful for new commerce sites that don't have a lot of products + return { + featured: rangeMap(6, (i) => featuredProducts[i] ?? products.shift()) + .filter(nonNullable) + .sort((a, b) => a.node.prices.price.value - b.node.prices.price.value) + .reverse(), + bestSelling: rangeMap( + 6, + (i) => bestSellingProducts[i] ?? products.shift() + ).filter(nonNullable), + } + })() + + return { + props: { + featured, + bestSelling, + newestProducts, + categories, + brands, + pages, + }, + revalidate: 14400, + } +} + +const nonNullable = (v: any) => v + +export default function Home({ + featured, + bestSelling, + brands, + categories, + newestProducts, +}: InferGetStaticPropsType) { + return ( +
+ + {featured.slice(0, 3).map(({ node }, i) => ( + + ))} + + + {bestSelling.slice(3, 6).map(({ node }) => ( + + ))} + + + + {featured.slice(3, 6).map(({ node }, i) => ( + + ))} + + + {bestSelling.slice(0, 3).map(({ node }) => ( + + ))} + + +
+ ) +} + +Home.Layout = Layout diff --git a/pages/index.tsx b/pages/index.tsx index ef1c0a96e..3266bc053 100644 --- a/pages/index.tsx +++ b/pages/index.tsx @@ -1,6 +1,6 @@ import rangeMap from '@lib/range-map' import { Layout } from '@components/common' -import { ProductCard } from '@components/product' +import ProductCard from '@components/product/ProductCard/FUTURE_ProductCard' import { Grid, Marquee, Hero } from '@components/ui' import HomeAllProductsGrid from '@components/common/HomeAllProductsGrid' import type { GetStaticPropsContext, InferGetStaticPropsType } from 'next' @@ -89,10 +89,10 @@ export default function Home({ ))} @@ -102,9 +102,10 @@ export default function Home({ key={node.path} product={node} variant="slim" - imgWidth={320} - imgHeight={320} - imgLayout="fixed" + imgProps={{ + width: 320, + height: 320, + }} /> ))} @@ -123,8 +124,10 @@ export default function Home({ ))} @@ -134,16 +137,17 @@ export default function Home({ key={node.path} product={node} variant="slim" - imgWidth={320} - imgHeight={320} - imgLayout="fixed" + imgProps={{ + width: 320, + height: 320, + }} /> ))} ) From f7956f8d01d11bef183eb3a605bdac6403a679ae Mon Sep 17 00:00:00 2001 From: Belen Curcio Date: Thu, 7 Jan 2021 11:01:47 -0300 Subject: [PATCH 003/216] Normalized Products output --- pages/index.tsx | 80 +++++++++++++++++++------------------------------ 1 file changed, 30 insertions(+), 50 deletions(-) diff --git a/pages/index.tsx b/pages/index.tsx index 3266bc053..6ebbc8d40 100644 --- a/pages/index.tsx +++ b/pages/index.tsx @@ -10,61 +10,45 @@ import getAllProducts from '@framework/api/operations/get-all-products' import getSiteInfo from '@framework/api/operations/get-site-info' import getAllPages from '@framework/api/operations/get-all-pages' +// Outputs from providers should already be normalized +// TODO (bc) move this to the provider +function normalize(arr: any[]) { + // Normalizes products arr response and flattens node edges + return arr.map( + ({ + node: { entityId: id, images, variants, productOptions, ...rest }, + }) => ({ + id, + images: images.edges, + variants: variants.edges, + productOptions: productOptions.edges, + ...rest, + }) + ) +} + export async function getStaticProps({ preview, locale, }: GetStaticPropsContext) { const config = getConfig({ locale }) - // Get Featured Products - const { products: featuredProducts } = await getAllProducts({ - variables: { field: 'featuredProducts', first: 6 }, + const { products: rawProducts } = await getAllProducts({ + variables: { first: 12 }, config, preview, }) - // Get Best Selling Products - const { products: bestSellingProducts } = await getAllProducts({ - variables: { field: 'bestSellingProducts', first: 6 }, - config, - preview, - }) + const products = normalize(rawProducts) - // Get Best Newest Products - const { products: newestProducts } = await getAllProducts({ - variables: { field: 'newestProducts', first: 12 }, - config, - preview, - }) + console.log(products) const { categories, brands } = await getSiteInfo({ config, preview }) const { pages } = await getAllPages({ config, preview }) - // These are the products that are going to be displayed in the landing. - // We prefer to do the computation at buildtime/servertime - const { featured, bestSelling } = (() => { - // Create a copy of products that we can mutate - const products = [...newestProducts] - // If the lists of featured and best selling products don't have enough - // products, then fill them with products from the products list, this - // is useful for new commerce sites that don't have a lot of products - return { - featured: rangeMap(6, (i) => featuredProducts[i] ?? products.shift()) - .filter(nonNullable) - .sort((a, b) => a.node.prices.price.value - b.node.prices.price.value) - .reverse(), - bestSelling: rangeMap( - 6, - (i) => bestSellingProducts[i] ?? products.shift() - ).filter(nonNullable), - } - })() - return { props: { - featured, - bestSelling, - newestProducts, + products, categories, brands, pages, @@ -73,22 +57,18 @@ export async function getStaticProps({ } } -const nonNullable = (v: any) => v - export default function Home({ - featured, - bestSelling, + products, brands, categories, - newestProducts, }: InferGetStaticPropsType) { return (
- {featured.slice(0, 3).map(({ node }, i) => ( + {products.slice(0, 3).map(({ p }, i) => ( ))} - + {/* {bestSelling.slice(3, 6).map(({ node }) => ( ))} - - */} + {/* + /> */} ) } From 812535caffef9938051c8e0d4de85467c249404e Mon Sep 17 00:00:00 2001 From: Belen Curcio Date: Thu, 7 Jan 2021 11:19:28 -0300 Subject: [PATCH 004/216] Progress --- .../ProductCard/FUTURE_ProductCard.tsx | 19 ++++++++++------- framework/types.d.ts | 4 ++-- pages/index.tsx | 21 ++++++++++++------- 3 files changed, 27 insertions(+), 17 deletions(-) diff --git a/components/product/ProductCard/FUTURE_ProductCard.tsx b/components/product/ProductCard/FUTURE_ProductCard.tsx index 7ef41b0be..9ca615d90 100644 --- a/components/product/ProductCard/FUTURE_ProductCard.tsx +++ b/components/product/ProductCard/FUTURE_ProductCard.tsx @@ -13,6 +13,7 @@ interface Props { } const ProductCard: FC = ({ className, product, variant, imgProps }) => { + const firstImage = product.images[0] return ( {variant === 'slim' ? ( @@ -36,14 +37,16 @@ const ProductCard: FC = ({ className, product, variant, imgProps }) => {
- {product.name} + {firstImage.src && ( + {product.name} + )}
)} diff --git a/framework/types.d.ts b/framework/types.d.ts index a05f03a69..de5deb080 100644 --- a/framework/types.d.ts +++ b/framework/types.d.ts @@ -2,13 +2,13 @@ interface Product { id: string | number name: string description: string - images: Images[] + images: Image[] slug: string price: string variantId: string } -interface Images { +interface Image { src: string alt?: string } diff --git a/pages/index.tsx b/pages/index.tsx index 6ebbc8d40..8406b333c 100644 --- a/pages/index.tsx +++ b/pages/index.tsx @@ -12,6 +12,7 @@ import getAllPages from '@framework/api/operations/get-all-pages' // Outputs from providers should already be normalized // TODO (bc) move this to the provider + function normalize(arr: any[]) { // Normalizes products arr response and flattens node edges return arr.map( @@ -19,9 +20,15 @@ function normalize(arr: any[]) { node: { entityId: id, images, variants, productOptions, ...rest }, }) => ({ id, - images: images.edges, - variants: variants.edges, - productOptions: productOptions.edges, + images: images.edges.map( + ({ node: { urlOriginal, altText, ...rest } }: any) => ({ + url: urlOriginal, + alt: altText, + ...rest, + }) + ), + variants: variants.edges.map(({ node }: any) => node), + productOptions: productOptions.edges.map(({ node }: any) => node), ...rest, }) ) @@ -41,7 +48,7 @@ export async function getStaticProps({ const products = normalize(rawProducts) - console.log(products) + // console.log(products) const { categories, brands } = await getSiteInfo({ config, preview }) const { pages } = await getAllPages({ config, preview }) @@ -65,10 +72,10 @@ export default function Home({ return (
- {products.slice(0, 3).map(({ p }, i) => ( + {products.slice(0, 3).map((product, i) => ( Date: Thu, 7 Jan 2021 11:58:00 -0300 Subject: [PATCH 005/216] Restored Index Agnostic --- .../ProductCard/FUTURE_ProductCard.tsx | 80 ++++++++++++------- components/ui/Marquee/Marquee.module.css | 11 +-- framework/types.d.ts | 29 +++---- pages/index.tsx | 52 +++++++----- 4 files changed, 101 insertions(+), 71 deletions(-) diff --git a/components/product/ProductCard/FUTURE_ProductCard.tsx b/components/product/ProductCard/FUTURE_ProductCard.tsx index 9ca615d90..604b91460 100644 --- a/components/product/ProductCard/FUTURE_ProductCard.tsx +++ b/components/product/ProductCard/FUTURE_ProductCard.tsx @@ -1,5 +1,6 @@ import { FC } from 'react' import cn from 'classnames' +import Link from 'next/link' import Image, { ImageProps } from 'next/image' import s from './ProductCard.module.css' // Restore Wishlist func @@ -13,44 +14,63 @@ interface Props { } const ProductCard: FC = ({ className, product, variant, imgProps }) => { - const firstImage = product.images[0] return ( - - {variant === 'slim' ? ( -
-
- - {product.name} - - {/* Image */} -
-
- ) : ( - <> -
-
-
-

- {product.name} -

- {product.price} + +
+ {variant === 'slim' ? ( +
+
+ + {product.name} +
-
-
- {firstImage.src && ( + {product.images[0] && ( {product.name} )}
- - )} -
+ ) : ( + <> +
+
+
+

+ {product.name} +

+ + {product.prices[0].value} +   + {product.prices[0].currencyCode} + +
+
+
+ {product.images[0] && ( + {product.name} + )} +
+ + )} + + ) } diff --git a/components/ui/Marquee/Marquee.module.css b/components/ui/Marquee/Marquee.module.css index 32601a54e..1fabc2ca8 100644 --- a/components/ui/Marquee/Marquee.module.css +++ b/components/ui/Marquee/Marquee.module.css @@ -1,15 +1,16 @@ .root { - @apply w-full; + @apply w-full relative; + height: 320px; min-width: 100%; } .container { @apply flex flex-row items-center; +} - & > * { - @apply flex-1 px-16 py-4; - width: 430px; - } +.container > * { + @apply relative flex-1 px-16 py-4 h-full; + min-height: 320px; } .primary { diff --git a/framework/types.d.ts b/framework/types.d.ts index de5deb080..4098e5c7e 100644 --- a/framework/types.d.ts +++ b/framework/types.d.ts @@ -1,25 +1,20 @@ +interface ProductImage { + url: string + alt?: string +} + interface Product { id: string | number name: string description: string - images: Image[] + images: ProductImage[] + prices: ProductPrice[] slug: string - price: string - variantId: string + path?: string } -interface Image { - src: string - alt?: string +interface ProductPrice { + value: number | string + currencyCode: 'USD' | 'ARS' + type?: 'price' | 'retail' | 'sale' | string } - -// interface NextImageProps { -// src: string -// width: number | string -// height: number | string -// layout?: 'fixed' | 'intrinsic' | 'responsive' | undefined -// priority?: boolean -// loading?: 'eager' | 'lazy' -// sizes?: string -// alt?: string -// } diff --git a/pages/index.tsx b/pages/index.tsx index 8406b333c..186da09f6 100644 --- a/pages/index.tsx +++ b/pages/index.tsx @@ -13,13 +13,23 @@ import getAllPages from '@framework/api/operations/get-all-pages' // Outputs from providers should already be normalized // TODO (bc) move this to the provider -function normalize(arr: any[]) { +function productsNormalizer(arr: any[]) { // Normalizes products arr response and flattens node edges return arr.map( ({ - node: { entityId: id, images, variants, productOptions, ...rest }, + node: { + entityId: id, + images, + variants, + productOptions, + prices, + path, + ...rest + }, }) => ({ id, + path, + slug: path.slice(1, -1), images: images.edges.map( ({ node: { urlOriginal, altText, ...rest } }: any) => ({ url: urlOriginal, @@ -29,6 +39,12 @@ function normalize(arr: any[]) { ), variants: variants.edges.map(({ node }: any) => node), productOptions: productOptions.edges.map(({ node }: any) => node), + prices: [ + { + value: prices.price.value, + currencyCode: prices.price.currencyCode, + }, + ], ...rest, }) ) @@ -46,10 +62,8 @@ export async function getStaticProps({ preview, }) - const products = normalize(rawProducts) - - // console.log(products) - + // Remove normalizer and send to framework provider. + const products = productsNormalizer(rawProducts) const { categories, brands } = await getSiteInfo({ config, preview }) const { pages } = await getAllPages({ config, preview }) @@ -83,11 +97,11 @@ export default function Home({ /> ))} - {/* - {bestSelling.slice(3, 6).map(({ node }) => ( + + {products.slice(0, 3).map((product, i) => ( - {featured.slice(3, 6).map(({ node }, i) => ( + {products.slice(0, 3).map((product, i) => ( ))} - {bestSelling.slice(0, 3).map(({ node }) => ( + {products.slice(0, 3).map((product, i) => ( ))} - */} + {/* Date: Thu, 7 Jan 2021 16:28:50 -0300 Subject: [PATCH 006/216] Progress --- README.md | 22 +++++++++++++--- .../ProductCard/FUTURE_ProductCard.tsx | 10 ++++--- .../WishlistButton/WishlistButton.tsx | 26 +++++++++---------- framework/bigcommerce/api/wishlist/index.ts | 4 +-- framework/bigcommerce/wishlist/index.ts | 4 +++ framework/types.d.ts | 14 ++++++---- 6 files changed, 53 insertions(+), 27 deletions(-) create mode 100644 framework/bigcommerce/wishlist/index.ts diff --git a/README.md b/README.md index 935c433cf..de1452b75 100644 --- a/README.md +++ b/README.md @@ -84,10 +84,10 @@ Our commitment to Open Source can be found [here](https://vercel.com/oss). ## Goals -* **Next.js Commerce** should have a completely data **agnostic** UI -* **Aware of schema**: should ship with the right data schemas and types. -* All providers should return the right data types and schemas to blend correctly with Next.js Commerce. -* `@framework` will be the alias utilized in commerce and it will map to the ecommerce provider of preference- e.g BigCommerce, Shopify, Swell. All providers should expose the same standardized functions. _Note that the same applies for recipes using a CMS + an ecommerce provider._ +- **Next.js Commerce** should have a completely data **agnostic** UI +- **Aware of schema**: should ship with the right data schemas and types. +- All providers should return the right data types and schemas to blend correctly with Next.js Commerce. +- `@framework` will be the alias utilized in commerce and it will map to the ecommerce provider of preference- e.g BigCommerce, Shopify, Swell. All providers should expose the same standardized functions. _Note that the same applies for recipes using a CMS + an ecommerce provider._ There is a `framework` folder in the root folder that will contain multiple ecommerce providers. @@ -95,5 +95,19 @@ Additionally, we need to ensure feature parity (not all providers have e.g. wish People actively working on this project: @okbel & @lfades. +## Framework +Framework is where the data comes from. Contains mostly hooks and functions. +## Structure + +- ## product +- wishlist + - useWishlist + - addWishlistItem + - removeWishlistItem +- auth + +- config.json + +## Wishlist diff --git a/components/product/ProductCard/FUTURE_ProductCard.tsx b/components/product/ProductCard/FUTURE_ProductCard.tsx index 604b91460..6ccc79fb9 100644 --- a/components/product/ProductCard/FUTURE_ProductCard.tsx +++ b/components/product/ProductCard/FUTURE_ProductCard.tsx @@ -1,10 +1,9 @@ import { FC } from 'react' import cn from 'classnames' import Link from 'next/link' -import Image, { ImageProps } from 'next/image' import s from './ProductCard.module.css' -// Restore Wishlist func -// import WishlistButton from '@components/wishlist/WishlistButton' +import Image, { ImageProps } from 'next/image' +import WishlistButton from '@components/wishlist/WishlistButton' interface Props { className?: string @@ -52,6 +51,11 @@ const ProductCard: FC = ({ className, product, variant, imgProps }) => { {product.prices[0].currencyCode} +
{product.images[0] && ( diff --git a/components/wishlist/WishlistButton/WishlistButton.tsx b/components/wishlist/WishlistButton/WishlistButton.tsx index b8b41c90d..fda78a4bf 100644 --- a/components/wishlist/WishlistButton/WishlistButton.tsx +++ b/components/wishlist/WishlistButton/WishlistButton.tsx @@ -1,16 +1,17 @@ import React, { FC, useState } from 'react' import cn from 'classnames' -import type { ProductNode } from '@framework/api/operations/get-all-products' -import useAddItem from '@framework/wishlist/use-add-item' -import useRemoveItem from '@framework/wishlist/use-remove-item' -import useWishlist from '@framework/wishlist/use-wishlist' -import useCustomer from '@framework/use-customer' import { Heart } from '@components/icons' import { useUI } from '@components/ui/context' +import type { ProductNode } from '@framework/api/operations/get-all-products' +import useCustomer from '@framework/use-customer' +import useAddItem from '@framework/wishlist/use-add-item' +import useWishlist from '@framework/wishlist/use-wishlist' +import useRemoveItem from '@framework/wishlist/use-remove-item' + type Props = { - productId: number - variant: NonNullable[0] + productId: Product['id'] + variant: ProductVariant } & React.ButtonHTMLAttributes const WishlistButton: FC = ({ @@ -19,16 +20,15 @@ const WishlistButton: FC = ({ className, ...props }) => { + const { data } = useWishlist() const addItem = useAddItem() const removeItem = useRemoveItem() - const { data } = useWishlist() const { data: customer } = useCustomer() - const [loading, setLoading] = useState(false) const { openModal, setModalView } = useUI() + const [loading, setLoading] = useState(false) + const itemInWishlist = data?.items?.find( - (item) => - item.product_id === productId && - item.variant_id === variant?.node.entityId + (item) => item.product_id === productId && item.variant_id === variant.id ) const handleWishlistChange = async (e: any) => { @@ -50,7 +50,7 @@ const WishlistButton: FC = ({ } else { await addItem({ productId, - variantId: variant?.node.entityId!, + variantId: variant?.id, }) } diff --git a/framework/bigcommerce/api/wishlist/index.ts b/framework/bigcommerce/api/wishlist/index.ts index 94194dd41..e78f0d9b9 100644 --- a/framework/bigcommerce/api/wishlist/index.ts +++ b/framework/bigcommerce/api/wishlist/index.ts @@ -15,8 +15,8 @@ import removeItem from './handlers/remove-item' export type { Wishlist, WishlistItem } export type ItemBody = { - productId: number - variantId: number + productId: Product['id'] + variantId: ProductVariant['id'] } export type AddItemBody = { item: ItemBody } diff --git a/framework/bigcommerce/wishlist/index.ts b/framework/bigcommerce/wishlist/index.ts new file mode 100644 index 000000000..9ea28291c --- /dev/null +++ b/framework/bigcommerce/wishlist/index.ts @@ -0,0 +1,4 @@ +export { default as useAddItem } from './use-add-item' +export { default as useWishlist } from './use-wishlist' +export { default as useRemoveItem } from './use-remove-item' +export { default as useWishlistActions } from './use-wishlist-actions' diff --git a/framework/types.d.ts b/framework/types.d.ts index 4098e5c7e..5d171b5b0 100644 --- a/framework/types.d.ts +++ b/framework/types.d.ts @@ -1,17 +1,21 @@ -interface ProductImage { - url: string - alt?: string -} - interface Product { id: string | number name: string description: string images: ProductImage[] + variants: ProductVariant[] prices: ProductPrice[] slug: string path?: string } +interface ProductImage { + url: string + alt?: string +} + +interface ProductVariant { + id: string | number +} interface ProductPrice { value: number | string From 4499f33f13d43385979c101229e278b9f8497e37 Mon Sep 17 00:00:00 2001 From: Belen Curcio Date: Thu, 7 Jan 2021 16:49:26 -0300 Subject: [PATCH 007/216] Reordering --- README.md | 25 ++++++++++++++----- components/auth/LoginView.tsx | 2 +- components/auth/SignUpView.tsx | 2 +- components/cart/CartItem/CartItem.tsx | 2 +- .../cart/CartSidebarView/CartSidebarView.tsx | 2 +- components/common/UserNav/DropdownMenu.tsx | 2 +- components/common/UserNav/UserNav.tsx | 2 +- .../product/ProductCard/ProductCard.tsx | 2 +- .../product/ProductView/ProductView.tsx | 2 +- .../WishlistButton/WishlistButton.tsx | 2 +- .../wishlist/WishlistCard/WishlistCard.tsx | 2 +- framework/bigcommerce/auth/index.ts | 3 +++ .../bigcommerce/{ => auth}/use-login.tsx | 4 +-- .../bigcommerce/{ => auth}/use-logout.tsx | 2 +- .../bigcommerce/{ => auth}/use-signup.tsx | 4 +-- framework/bigcommerce/cart/index.ts | 5 ++++ framework/bigcommerce/customer/index.ts | 1 + .../{ => customer}/use-customer.tsx | 2 +- framework/bigcommerce/product/index.ts | 2 ++ .../bigcommerce/{ => product}/use-price.tsx | 0 .../{products => product}/use-search.tsx | 0 .../bigcommerce/wishlist/use-add-item.tsx | 2 +- .../bigcommerce/wishlist/use-remove-item.tsx | 2 +- .../bigcommerce/wishlist/use-wishlist.tsx | 2 +- pages/cart.tsx | 2 +- pages/profile.tsx | 2 +- pages/search.tsx | 2 +- 27 files changed, 52 insertions(+), 28 deletions(-) create mode 100644 framework/bigcommerce/auth/index.ts rename framework/bigcommerce/{ => auth}/use-login.tsx (91%) rename framework/bigcommerce/{ => auth}/use-logout.tsx (94%) rename framework/bigcommerce/{ => auth}/use-signup.tsx (91%) create mode 100644 framework/bigcommerce/cart/index.ts create mode 100644 framework/bigcommerce/customer/index.ts rename framework/bigcommerce/{ => customer}/use-customer.tsx (93%) create mode 100644 framework/bigcommerce/product/index.ts rename framework/bigcommerce/{ => product}/use-price.tsx (100%) rename framework/bigcommerce/{products => product}/use-search.tsx (100%) diff --git a/README.md b/README.md index de1452b75..54f021f74 100644 --- a/README.md +++ b/README.md @@ -97,17 +97,30 @@ People actively working on this project: @okbel & @lfades. ## Framework -Framework is where the data comes from. Contains mostly hooks and functions. +Framework is where the data comes from. It contains mostly hooks and functions. ## Structure -- ## product -- wishlist +Main folder and its exposed functions + +- `product` + - usePrice + - useSearch +- `wishlist` - useWishlist - addWishlistItem - removeWishlistItem -- auth +- `auth` + - useLogin + - useLogout + - useSignup +- `cart` -- config.json + - useCart + - useAddItem + - useRemoveItem + - useCartActions + - useUpdateItem -## Wishlist +- `config.json` +- README.md diff --git a/components/auth/LoginView.tsx b/components/auth/LoginView.tsx index 9102a53c6..89d5bf893 100644 --- a/components/auth/LoginView.tsx +++ b/components/auth/LoginView.tsx @@ -1,6 +1,6 @@ import { FC, useEffect, useState, useCallback } from 'react' import { Logo, Button, Input } from '@components/ui' -import useLogin from '@framework/use-login' +import useLogin from '@framework/auth/use-login' import { useUI } from '@components/ui/context' import { validate } from 'email-validator' diff --git a/components/auth/SignUpView.tsx b/components/auth/SignUpView.tsx index c49637d47..1b619828b 100644 --- a/components/auth/SignUpView.tsx +++ b/components/auth/SignUpView.tsx @@ -3,7 +3,7 @@ import { validate } from 'email-validator' import { Info } from '@components/icons' import { useUI } from '@components/ui/context' import { Logo, Button, Input } from '@components/ui' -import useSignup from '@framework/use-signup' +import useSignup from '@framework/auth/use-signup' interface Props {} diff --git a/components/cart/CartItem/CartItem.tsx b/components/cart/CartItem/CartItem.tsx index 283f3fa40..ac78d1849 100644 --- a/components/cart/CartItem/CartItem.tsx +++ b/components/cart/CartItem/CartItem.tsx @@ -3,7 +3,7 @@ import cn from 'classnames' import Image from 'next/image' import Link from 'next/link' import { Trash, Plus, Minus } from '@components/icons' -import usePrice from '@framework/use-price' +import usePrice from '@framework/product/use-price' import useUpdateItem from '@framework/cart/use-update-item' import useRemoveItem from '@framework/cart/use-remove-item' import s from './CartItem.module.css' diff --git a/components/cart/CartSidebarView/CartSidebarView.tsx b/components/cart/CartSidebarView/CartSidebarView.tsx index b313bdea9..2a58fd74f 100644 --- a/components/cart/CartSidebarView/CartSidebarView.tsx +++ b/components/cart/CartSidebarView/CartSidebarView.tsx @@ -5,7 +5,7 @@ import { Button } from '@components/ui' import { Bag, Cross, Check } from '@components/icons' import { useUI } from '@components/ui/context' import useCart from '@framework/cart/use-cart' -import usePrice from '@framework/use-price' +import usePrice from '@framework/product/use-price' import CartItem from '../CartItem' import s from './CartSidebarView.module.css' diff --git a/components/common/UserNav/DropdownMenu.tsx b/components/common/UserNav/DropdownMenu.tsx index 7b02c863a..a5bc5fd86 100644 --- a/components/common/UserNav/DropdownMenu.tsx +++ b/components/common/UserNav/DropdownMenu.tsx @@ -15,7 +15,7 @@ import { clearAllBodyScrollLocks, } from 'body-scroll-lock' -import useLogout from '@framework/use-logout' +import useLogout from '@framework/auth/use-logout' interface DropdownMenuProps { open?: boolean diff --git a/components/common/UserNav/UserNav.tsx b/components/common/UserNav/UserNav.tsx index 31852f658..7b912422d 100644 --- a/components/common/UserNav/UserNav.tsx +++ b/components/common/UserNav/UserNav.tsx @@ -2,7 +2,7 @@ import { FC } from 'react' import Link from 'next/link' import cn from 'classnames' import useCart from '@framework/cart/use-cart' -import useCustomer from '@framework/use-customer' +import useCustomer from '@framework/customer/use-customer' import { Heart, Bag } from '@components/icons' import { useUI } from '@components/ui/context' import DropdownMenu from './DropdownMenu' diff --git a/components/product/ProductCard/ProductCard.tsx b/components/product/ProductCard/ProductCard.tsx index 85e69b3f2..58a201e8b 100644 --- a/components/product/ProductCard/ProductCard.tsx +++ b/components/product/ProductCard/ProductCard.tsx @@ -5,7 +5,7 @@ import type { FC } from 'react' import s from './ProductCard.module.css' import WishlistButton from '@components/wishlist/WishlistButton' -import usePrice from '@framework/use-price' +import usePrice from '@framework/product/use-price' import type { ProductNode } from '@framework/api/operations/get-all-products' interface Props { diff --git a/components/product/ProductView/ProductView.tsx b/components/product/ProductView/ProductView.tsx index 9703156a1..97342242d 100644 --- a/components/product/ProductView/ProductView.tsx +++ b/components/product/ProductView/ProductView.tsx @@ -8,7 +8,7 @@ import { useUI } from '@components/ui/context' import { Swatch, ProductSlider } from '@components/product' import { Button, Container, Text } from '@components/ui' -import usePrice from '@framework/use-price' +import usePrice from '@framework/product/use-price' import useAddItem from '@framework/cart/use-add-item' import type { ProductNode } from '@framework/api/operations/get-product' import { diff --git a/components/wishlist/WishlistButton/WishlistButton.tsx b/components/wishlist/WishlistButton/WishlistButton.tsx index fda78a4bf..ea4abbb51 100644 --- a/components/wishlist/WishlistButton/WishlistButton.tsx +++ b/components/wishlist/WishlistButton/WishlistButton.tsx @@ -4,7 +4,7 @@ import { Heart } from '@components/icons' import { useUI } from '@components/ui/context' import type { ProductNode } from '@framework/api/operations/get-all-products' -import useCustomer from '@framework/use-customer' +import useCustomer from '@framework/customer/use-customer' import useAddItem from '@framework/wishlist/use-add-item' import useWishlist from '@framework/wishlist/use-wishlist' import useRemoveItem from '@framework/wishlist/use-remove-item' diff --git a/components/wishlist/WishlistCard/WishlistCard.tsx b/components/wishlist/WishlistCard/WishlistCard.tsx index 8cbd38bc7..b9b1a2f3e 100644 --- a/components/wishlist/WishlistCard/WishlistCard.tsx +++ b/components/wishlist/WishlistCard/WishlistCard.tsx @@ -3,7 +3,7 @@ import cn from 'classnames' import Link from 'next/link' import Image from 'next/image' import type { WishlistItem } from '@framework/api/wishlist' -import usePrice from '@framework/use-price' +import usePrice from '@framework/product/use-price' import useRemoveItem from '@framework/wishlist/use-remove-item' import useAddItem from '@framework/cart/use-add-item' import { useUI } from '@components/ui/context' diff --git a/framework/bigcommerce/auth/index.ts b/framework/bigcommerce/auth/index.ts new file mode 100644 index 000000000..36e757a89 --- /dev/null +++ b/framework/bigcommerce/auth/index.ts @@ -0,0 +1,3 @@ +export { default as useLogin } from './use-login' +export { default as useLogout } from './use-logout' +export { default as useSignup } from './use-signup' diff --git a/framework/bigcommerce/use-login.tsx b/framework/bigcommerce/auth/use-login.tsx similarity index 91% rename from framework/bigcommerce/use-login.tsx rename to framework/bigcommerce/auth/use-login.tsx index 62d4ecbd7..fa2294666 100644 --- a/framework/bigcommerce/use-login.tsx +++ b/framework/bigcommerce/auth/use-login.tsx @@ -2,8 +2,8 @@ import { useCallback } from 'react' import type { HookFetcher } from '@commerce/utils/types' import { CommerceError } from '@commerce/utils/errors' import useCommerceLogin from '@commerce/use-login' -import type { LoginBody } from './api/customers/login' -import useCustomer from './use-customer' +import type { LoginBody } from '../api/customers/login' +import useCustomer from '../customer/use-customer' const defaultOpts = { url: '/api/bigcommerce/customers/login', diff --git a/framework/bigcommerce/use-logout.tsx b/framework/bigcommerce/auth/use-logout.tsx similarity index 94% rename from framework/bigcommerce/use-logout.tsx rename to framework/bigcommerce/auth/use-logout.tsx index a9131ed3a..6aaee29f9 100644 --- a/framework/bigcommerce/use-logout.tsx +++ b/framework/bigcommerce/auth/use-logout.tsx @@ -1,7 +1,7 @@ import { useCallback } from 'react' import type { HookFetcher } from '@commerce/utils/types' import useCommerceLogout from '@commerce/use-logout' -import useCustomer from './use-customer' +import useCustomer from '../customer/use-customer' const defaultOpts = { url: '/api/bigcommerce/customers/logout', diff --git a/framework/bigcommerce/use-signup.tsx b/framework/bigcommerce/auth/use-signup.tsx similarity index 91% rename from framework/bigcommerce/use-signup.tsx rename to framework/bigcommerce/auth/use-signup.tsx index 4d907c5ac..c68ce7b7a 100644 --- a/framework/bigcommerce/use-signup.tsx +++ b/framework/bigcommerce/auth/use-signup.tsx @@ -2,8 +2,8 @@ import { useCallback } from 'react' import type { HookFetcher } from '@commerce/utils/types' import { CommerceError } from '@commerce/utils/errors' import useCommerceSignup from '@commerce/use-signup' -import type { SignupBody } from './api/customers/signup' -import useCustomer from './use-customer' +import type { SignupBody } from '../api/customers/signup' +import useCustomer from '../customer/use-customer' const defaultOpts = { url: '/api/bigcommerce/customers/signup', diff --git a/framework/bigcommerce/cart/index.ts b/framework/bigcommerce/cart/index.ts new file mode 100644 index 000000000..43c6db2b7 --- /dev/null +++ b/framework/bigcommerce/cart/index.ts @@ -0,0 +1,5 @@ +export { default as useCart } from './use-cart' +export { default as useAddItem } from './use-add-item' +export { default as useRemoveItem } from './use-remove-item' +export { default as useWishlistActions } from './use-cart-actions' +export { default as useUpdateItem } from './use-cart-actions' diff --git a/framework/bigcommerce/customer/index.ts b/framework/bigcommerce/customer/index.ts new file mode 100644 index 000000000..6c903ecc5 --- /dev/null +++ b/framework/bigcommerce/customer/index.ts @@ -0,0 +1 @@ +export { default as useCustomer } from './use-customer' diff --git a/framework/bigcommerce/use-customer.tsx b/framework/bigcommerce/customer/use-customer.tsx similarity index 93% rename from framework/bigcommerce/use-customer.tsx rename to framework/bigcommerce/customer/use-customer.tsx index 4a08a0330..f44f16c1f 100644 --- a/framework/bigcommerce/use-customer.tsx +++ b/framework/bigcommerce/customer/use-customer.tsx @@ -1,7 +1,7 @@ import type { HookFetcher } from '@commerce/utils/types' import type { SwrOptions } from '@commerce/utils/use-data' import useCommerceCustomer from '@commerce/use-customer' -import type { Customer, CustomerData } from './api/customers' +import type { Customer, CustomerData } from '../api/customers' const defaultOpts = { url: '/api/bigcommerce/customers', diff --git a/framework/bigcommerce/product/index.ts b/framework/bigcommerce/product/index.ts new file mode 100644 index 000000000..426a3edcd --- /dev/null +++ b/framework/bigcommerce/product/index.ts @@ -0,0 +1,2 @@ +export { default as usePrice } from './use-price' +export { default as useSearch } from './use-search' diff --git a/framework/bigcommerce/use-price.tsx b/framework/bigcommerce/product/use-price.tsx similarity index 100% rename from framework/bigcommerce/use-price.tsx rename to framework/bigcommerce/product/use-price.tsx diff --git a/framework/bigcommerce/products/use-search.tsx b/framework/bigcommerce/product/use-search.tsx similarity index 100% rename from framework/bigcommerce/products/use-search.tsx rename to framework/bigcommerce/product/use-search.tsx diff --git a/framework/bigcommerce/wishlist/use-add-item.tsx b/framework/bigcommerce/wishlist/use-add-item.tsx index 0c355c181..6e7d9de41 100644 --- a/framework/bigcommerce/wishlist/use-add-item.tsx +++ b/framework/bigcommerce/wishlist/use-add-item.tsx @@ -3,7 +3,7 @@ import { HookFetcher } from '@commerce/utils/types' import { CommerceError } from '@commerce/utils/errors' import useWishlistAddItem from '@commerce/wishlist/use-add-item' import type { ItemBody, AddItemBody } from '../api/wishlist' -import useCustomer from '../use-customer' +import useCustomer from '../customer/use-customer' import useWishlist, { UseWishlistOptions, Wishlist } from './use-wishlist' const defaultOpts = { diff --git a/framework/bigcommerce/wishlist/use-remove-item.tsx b/framework/bigcommerce/wishlist/use-remove-item.tsx index 5ff55b5f2..86614a21a 100644 --- a/framework/bigcommerce/wishlist/use-remove-item.tsx +++ b/framework/bigcommerce/wishlist/use-remove-item.tsx @@ -3,7 +3,7 @@ import { HookFetcher } from '@commerce/utils/types' import { CommerceError } from '@commerce/utils/errors' import useWishlistRemoveItem from '@commerce/wishlist/use-remove-item' import type { RemoveItemBody } from '../api/wishlist' -import useCustomer from '../use-customer' +import useCustomer from '../customer/use-customer' import useWishlist, { UseWishlistOptions, Wishlist } from './use-wishlist' const defaultOpts = { diff --git a/framework/bigcommerce/wishlist/use-wishlist.tsx b/framework/bigcommerce/wishlist/use-wishlist.tsx index 4ab581155..6ebc8459d 100644 --- a/framework/bigcommerce/wishlist/use-wishlist.tsx +++ b/framework/bigcommerce/wishlist/use-wishlist.tsx @@ -2,7 +2,7 @@ import { HookFetcher } from '@commerce/utils/types' import { SwrOptions } from '@commerce/utils/use-data' import useCommerceWishlist from '@commerce/wishlist/use-wishlist' import type { Wishlist } from '../api/wishlist' -import useCustomer from '../use-customer' +import useCustomer from '../customer/use-customer' const defaultOpts = { url: '/api/bigcommerce/wishlist', diff --git a/pages/cart.tsx b/pages/cart.tsx index 7e6d17b21..fc06c4ced 100644 --- a/pages/cart.tsx +++ b/pages/cart.tsx @@ -2,7 +2,7 @@ import type { GetStaticPropsContext } from 'next' import { getConfig } from '@framework/api' import getAllPages from '@framework/api/operations/get-all-pages' import useCart from '@framework/cart/use-cart' -import usePrice from '@framework/use-price' +import usePrice from '@framework/product/use-price' import { Layout } from '@components/common' import { Button } from '@components/ui' import { Bag, Cross, Check } from '@components/icons' diff --git a/pages/profile.tsx b/pages/profile.tsx index 63de0b234..8b8c1a3b1 100644 --- a/pages/profile.tsx +++ b/pages/profile.tsx @@ -1,7 +1,7 @@ import type { GetStaticPropsContext } from 'next' import { getConfig } from '@framework/api' import getAllPages from '@framework/api/operations/get-all-pages' -import useCustomer from '@framework/use-customer' +import useCustomer from '@framework/customer/use-customer' import { Layout } from '@components/common' import { Container, Text } from '@components/ui' diff --git a/pages/search.tsx b/pages/search.tsx index 5110aba55..18b0d9c1a 100644 --- a/pages/search.tsx +++ b/pages/search.tsx @@ -6,7 +6,7 @@ import { useRouter } from 'next/router' import { getConfig } from '@framework/api' import getAllPages from '@framework/api/operations/get-all-pages' import getSiteInfo from '@framework/api/operations/get-site-info' -import useSearch from '@framework/products/use-search' +import useSearch from '@framework/product/use-search' import { Layout } from '@components/common' import { ProductCard } from '@components/product' import { Container, Grid, Skeleton } from '@components/ui' From 27dd4bfb69c35256cef1607da559aa57067097b9 Mon Sep 17 00:00:00 2001 From: Belen Curcio Date: Thu, 7 Jan 2021 16:58:58 -0300 Subject: [PATCH 008/216] Moved normalizer to BC function --- .../api/operations/get-all-products.ts | 43 +++++++++++++++++-- pages/index.tsx | 42 +----------------- 2 files changed, 41 insertions(+), 44 deletions(-) diff --git a/framework/bigcommerce/api/operations/get-all-products.ts b/framework/bigcommerce/api/operations/get-all-products.ts index 0cd9737c2..036602639 100644 --- a/framework/bigcommerce/api/operations/get-all-products.ts +++ b/framework/bigcommerce/api/operations/get-all-products.ts @@ -8,6 +8,43 @@ import setProductLocaleMeta from '../utils/set-product-locale-meta' import { productConnectionFragment } from '../fragments/product' import { BigcommerceConfig, getConfig } from '..' +function productsNormalizer(arr: any[]): Product[] { + // Normalizes products arr response and flattens node edges + return arr.map( + ({ + node: { + entityId: id, + images, + variants, + productOptions, + prices, + path, + ...rest + }, + }) => ({ + id, + path, + slug: path.slice(1, -1), + images: images.edges.map( + ({ node: { urlOriginal, altText, ...rest } }: any) => ({ + url: urlOriginal, + alt: altText, + ...rest, + }) + ), + variants: variants.edges.map(({ node }: any) => node), + productOptions: productOptions.edges.map(({ node }: any) => node), + prices: [ + { + value: prices.price.value, + currencyCode: prices.price.currencyCode, + }, + ], + ...rest, + }) + ) +} + export const getAllProductsQuery = /* GraphQL */ ` query getAllProducts( $hasLocale: Boolean = false @@ -72,7 +109,7 @@ async function getAllProducts(opts?: { variables?: ProductVariables config?: BigcommerceConfig preview?: boolean -}): Promise +}): Promise<{ products: Product[] }> async function getAllProducts< T extends Record, @@ -93,7 +130,7 @@ async function getAllProducts({ variables?: ProductVariables config?: BigcommerceConfig preview?: boolean -} = {}): Promise { +} = {}): Promise<{ products: Product[] }> { config = getConfig(config) const locale = vars.locale || config.locale @@ -126,7 +163,7 @@ async function getAllProducts({ }) } - return { products } + return { products: productsNormalizer(products) } } export default getAllProducts diff --git a/pages/index.tsx b/pages/index.tsx index 186da09f6..9bb1e09a6 100644 --- a/pages/index.tsx +++ b/pages/index.tsx @@ -11,44 +11,6 @@ import getSiteInfo from '@framework/api/operations/get-site-info' import getAllPages from '@framework/api/operations/get-all-pages' // Outputs from providers should already be normalized -// TODO (bc) move this to the provider - -function productsNormalizer(arr: any[]) { - // Normalizes products arr response and flattens node edges - return arr.map( - ({ - node: { - entityId: id, - images, - variants, - productOptions, - prices, - path, - ...rest - }, - }) => ({ - id, - path, - slug: path.slice(1, -1), - images: images.edges.map( - ({ node: { urlOriginal, altText, ...rest } }: any) => ({ - url: urlOriginal, - alt: altText, - ...rest, - }) - ), - variants: variants.edges.map(({ node }: any) => node), - productOptions: productOptions.edges.map(({ node }: any) => node), - prices: [ - { - value: prices.price.value, - currencyCode: prices.price.currencyCode, - }, - ], - ...rest, - }) - ) -} export async function getStaticProps({ preview, @@ -56,14 +18,12 @@ export async function getStaticProps({ }: GetStaticPropsContext) { const config = getConfig({ locale }) - const { products: rawProducts } = await getAllProducts({ + const { products } = await getAllProducts({ variables: { first: 12 }, config, preview, }) - // Remove normalizer and send to framework provider. - const products = productsNormalizer(rawProducts) const { categories, brands } = await getSiteInfo({ config, preview }) const { pages } = await getAllPages({ config, preview }) From 4259136983c461db7887f34a1da0af72dfdecfb2 Mon Sep 17 00:00:00 2001 From: Belen Curcio Date: Thu, 7 Jan 2021 17:10:27 -0300 Subject: [PATCH 009/216] Removed Futures --- .../ProductCard/FUTURE_ProductCard.tsx | 81 ---------------- .../product/ProductCard/ProductCard.tsx | 97 ++++++++----------- pages/index.tsx | 3 +- 3 files changed, 39 insertions(+), 142 deletions(-) delete mode 100644 components/product/ProductCard/FUTURE_ProductCard.tsx diff --git a/components/product/ProductCard/FUTURE_ProductCard.tsx b/components/product/ProductCard/FUTURE_ProductCard.tsx deleted file mode 100644 index 6ccc79fb9..000000000 --- a/components/product/ProductCard/FUTURE_ProductCard.tsx +++ /dev/null @@ -1,81 +0,0 @@ -import { FC } from 'react' -import cn from 'classnames' -import Link from 'next/link' -import s from './ProductCard.module.css' -import Image, { ImageProps } from 'next/image' -import WishlistButton from '@components/wishlist/WishlistButton' - -interface Props { - className?: string - product: Product - variant?: 'slim' | 'simple' - imgProps?: Omit -} - -const ProductCard: FC = ({ className, product, variant, imgProps }) => { - return ( - - - {variant === 'slim' ? ( -
-
- - {product.name} - -
- {product.images[0] && ( - {product.name} - )} -
- ) : ( - <> -
-
-
-

- {product.name} -

- - {product.prices[0].value} -   - {product.prices[0].currencyCode} - -
- -
-
- {product.images[0] && ( - {product.name} - )} -
- - )} -
- - ) -} - -export default ProductCard diff --git a/components/product/ProductCard/ProductCard.tsx b/components/product/ProductCard/ProductCard.tsx index 58a201e8b..6ccc79fb9 100644 --- a/components/product/ProductCard/ProductCard.tsx +++ b/components/product/ProductCard/ProductCard.tsx @@ -1,45 +1,20 @@ +import { FC } from 'react' import cn from 'classnames' import Link from 'next/link' -import Image from 'next/image' -import type { FC } from 'react' import s from './ProductCard.module.css' +import Image, { ImageProps } from 'next/image' import WishlistButton from '@components/wishlist/WishlistButton' -import usePrice from '@framework/product/use-price' -import type { ProductNode } from '@framework/api/operations/get-all-products' - interface Props { className?: string - product: ProductNode + product: Product variant?: 'slim' | 'simple' - imgWidth: number | string - imgHeight: number | string - imgLayout?: 'fixed' | 'intrinsic' | 'responsive' | undefined - imgPriority?: boolean - imgLoading?: 'eager' | 'lazy' - imgSizes?: string + imgProps?: Omit } -const ProductCard: FC = ({ - className, - product: p, - variant, - imgWidth, - imgHeight, - imgPriority, - imgLoading, - imgSizes, - imgLayout = 'responsive', -}) => { - const src = p.images.edges?.[0]?.node?.urlOriginal! - const { price } = usePrice({ - amount: p.prices?.price?.value, - baseAmount: p.prices?.retailPrice?.value, - currencyCode: p.prices?.price?.currencyCode!, - }) - +const ProductCard: FC = ({ className, product, variant, imgProps }) => { return ( - + @@ -47,20 +22,20 @@ const ProductCard: FC = ({
- {p.name} + {product.name}
- {p.images.edges?.[0]?.node.altText + {product.images[0] && ( + {product.name} + )}
) : ( <> @@ -68,29 +43,33 @@ const ProductCard: FC = ({

- {p.name} + {product.name}

- {price} + + {product.prices[0].value} +   + {product.prices[0].currencyCode} +
- {p.name} + {product.images[0] && ( + {product.name} + )}
)} diff --git a/pages/index.tsx b/pages/index.tsx index 9bb1e09a6..76299673d 100644 --- a/pages/index.tsx +++ b/pages/index.tsx @@ -1,7 +1,6 @@ -import rangeMap from '@lib/range-map' import { Layout } from '@components/common' -import ProductCard from '@components/product/ProductCard/FUTURE_ProductCard' import { Grid, Marquee, Hero } from '@components/ui' +import { ProductCard } from '@components/product' import HomeAllProductsGrid from '@components/common/HomeAllProductsGrid' import type { GetStaticPropsContext, InferGetStaticPropsType } from 'next' From 4f0898281ddc4ca98daf95e8551c177f4a77d764 Mon Sep 17 00:00:00 2001 From: Belen Curcio Date: Sat, 9 Jan 2021 12:05:40 -0300 Subject: [PATCH 010/216] More Types --- framework/types.d.ts | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/framework/types.d.ts b/framework/types.d.ts index 5d171b5b0..f15bde593 100644 --- a/framework/types.d.ts +++ b/framework/types.d.ts @@ -22,3 +22,17 @@ interface ProductPrice { currencyCode: 'USD' | 'ARS' type?: 'price' | 'retail' | 'sale' | string } + +interface Wishlist { + id: string + products: Pick[] +} + +interface Customer { + id: string + name: string +} + +interface Category {} + +interface Brand {} From c3c1ac7cf595344973b5486a1b16f1ab49bda41e Mon Sep 17 00:00:00 2001 From: Belen Curcio Date: Sat, 9 Jan 2021 12:07:17 -0300 Subject: [PATCH 011/216] More Types --- framework/types.d.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/framework/types.d.ts b/framework/types.d.ts index f15bde593..b804b68a5 100644 --- a/framework/types.d.ts +++ b/framework/types.d.ts @@ -25,7 +25,12 @@ interface ProductPrice { interface Wishlist { id: string - products: Pick[] + products: Pick[] +} + +interface Wishlist { + id: string + products: Pick[] } interface Customer { From ab16960ddb0fa7efaeffa2147a3224e09be0252b Mon Sep 17 00:00:00 2001 From: Belen Curcio Date: Sat, 9 Jan 2021 12:17:31 -0300 Subject: [PATCH 012/216] More Types --- framework/types.d.ts | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/framework/types.d.ts b/framework/types.d.ts index b804b68a5..2f1329071 100644 --- a/framework/types.d.ts +++ b/framework/types.d.ts @@ -23,7 +23,7 @@ interface ProductPrice { type?: 'price' | 'retail' | 'sale' | string } -interface Wishlist { +interface Cart { id: string products: Pick[] } @@ -33,11 +33,22 @@ interface Wishlist { products: Pick[] } +interface Order {} + interface Customer { id: string name: string + email: string } -interface Category {} +interface Category { + id: string + name: string +} -interface Brand {} +interface Brand { + id: string + name: string +} + +type Features = 'wishlist' | 'customer' From e593eab9cc130257e067f5bd5da49248d899fcf5 Mon Sep 17 00:00:00 2001 From: Belen Curcio Date: Sat, 9 Jan 2021 12:39:18 -0300 Subject: [PATCH 013/216] Fix useCallback --- components/ui/Modal/Modal.tsx | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/components/ui/Modal/Modal.tsx b/components/ui/Modal/Modal.tsx index c3b0c8df2..300a99192 100644 --- a/components/ui/Modal/Modal.tsx +++ b/components/ui/Modal/Modal.tsx @@ -19,12 +19,14 @@ interface Props { const Modal: FC = ({ children, open, onClose, onEnter = null }) => { const ref = useRef() as React.MutableRefObject - const handleKey = (e: KeyboardEvent) => - useCallback(() => { + const handleKey = useCallback( + (e: KeyboardEvent) => { if (e.key === 'Escape') { return onClose() } - }, [onClose]) + }, + [onClose] + ) useEffect(() => { if (ref.current) { From 0d4355b43195834d3caee6470fecba5efc90f4e3 Mon Sep 17 00:00:00 2001 From: Belen Curcio Date: Sun, 10 Jan 2021 13:08:34 -0300 Subject: [PATCH 014/216] Progress, Changes types, readme and restoring functionality --- .gitignore | 1 + README.md | 8 ++++++++ components/ui/index.ts | 1 + components/wishlist/WishlistButton/WishlistButton.tsx | 9 +++------ framework/bigcommerce/api/wishlist/index.ts | 4 ++-- .../bigcommerce/{scripts => lib}/generate-definitions.js | 0 framework/bigcommerce/wishlist/use-wishlist.tsx | 2 +- framework/types.d.ts | 4 ++-- package.json | 2 +- pages/index.tsx | 2 -- tsconfig.json | 2 +- 11 files changed, 20 insertions(+), 15 deletions(-) rename framework/bigcommerce/{scripts => lib}/generate-definitions.js (100%) diff --git a/.gitignore b/.gitignore index bcbf6047a..50d4285ba 100644 --- a/.gitignore +++ b/.gitignore @@ -25,6 +25,7 @@ yarn-debug.log* yarn-error.log* # local env files +.env .env.local .env.development.local .env.test.local diff --git a/README.md b/README.md index 54f021f74..e944c7569 100644 --- a/README.md +++ b/README.md @@ -124,3 +124,11 @@ Main folder and its exposed functions - `config.json` - README.md + +#### Example of correct usage of Commece Framework + +```js +import { useUI } from '@components/ui' +import { useCustomer } from '@framework/customer' +import { useAddItem, useWishlist, useRemoveItem } from '@framework/wishlist' +``` diff --git a/components/ui/index.ts b/components/ui/index.ts index 581c12d53..f2a293200 100644 --- a/components/ui/index.ts +++ b/components/ui/index.ts @@ -10,3 +10,4 @@ export { default as Skeleton } from './Skeleton' export { default as Modal } from './Modal' export { default as Text } from './Text' export { default as Input } from './Input' +export { useUI } from './context' diff --git a/components/wishlist/WishlistButton/WishlistButton.tsx b/components/wishlist/WishlistButton/WishlistButton.tsx index ea4abbb51..db9ca4b67 100644 --- a/components/wishlist/WishlistButton/WishlistButton.tsx +++ b/components/wishlist/WishlistButton/WishlistButton.tsx @@ -1,13 +1,10 @@ import React, { FC, useState } from 'react' import cn from 'classnames' import { Heart } from '@components/icons' -import { useUI } from '@components/ui/context' -import type { ProductNode } from '@framework/api/operations/get-all-products' -import useCustomer from '@framework/customer/use-customer' -import useAddItem from '@framework/wishlist/use-add-item' -import useWishlist from '@framework/wishlist/use-wishlist' -import useRemoveItem from '@framework/wishlist/use-remove-item' +import { useUI } from '@components/ui' +import { useCustomer } from '@framework/customer' +import { useAddItem, useWishlist, useRemoveItem } from '@framework/wishlist' type Props = { productId: Product['id'] diff --git a/framework/bigcommerce/api/wishlist/index.ts b/framework/bigcommerce/api/wishlist/index.ts index e78f0d9b9..b50c5e97f 100644 --- a/framework/bigcommerce/api/wishlist/index.ts +++ b/framework/bigcommerce/api/wishlist/index.ts @@ -21,10 +21,10 @@ export type ItemBody = { export type AddItemBody = { item: ItemBody } -export type RemoveItemBody = { itemId: string } +export type RemoveItemBody = { itemId: Product['id'] } export type WishlistBody = { - customer_id: number + customer_id: Customer['id'] is_public: number name: string items: any[] diff --git a/framework/bigcommerce/scripts/generate-definitions.js b/framework/bigcommerce/lib/generate-definitions.js similarity index 100% rename from framework/bigcommerce/scripts/generate-definitions.js rename to framework/bigcommerce/lib/generate-definitions.js diff --git a/framework/bigcommerce/wishlist/use-wishlist.tsx b/framework/bigcommerce/wishlist/use-wishlist.tsx index 6ebc8459d..455fdc9ff 100644 --- a/framework/bigcommerce/wishlist/use-wishlist.tsx +++ b/framework/bigcommerce/wishlist/use-wishlist.tsx @@ -16,7 +16,7 @@ export interface UseWishlistOptions { } export interface UseWishlistInput extends UseWishlistOptions { - customerId?: number + customerId?: Customer['id'] } export const fetcher: HookFetcher = ( diff --git a/framework/types.d.ts b/framework/types.d.ts index 2f1329071..881218ca8 100644 --- a/framework/types.d.ts +++ b/framework/types.d.ts @@ -2,11 +2,11 @@ interface Product { id: string | number name: string description: string + slug: string + path?: string images: ProductImage[] variants: ProductVariant[] prices: ProductPrice[] - slug: string - path?: string } interface ProductImage { url: string diff --git a/package.json b/package.json index 1030e8479..35e8d5cb5 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,7 @@ "analyze": "BUNDLE_ANALYZE=both yarn build", "find:unused": "next-unused", "generate": "graphql-codegen", - "generate:definitions": "node framework/bigcommerce/scripts/generate-definitions.js" + "generate:definitions": "node framework/bigcommerce/lib/generate-definitions.js" }, "prettier": { "semi": false, diff --git a/pages/index.tsx b/pages/index.tsx index 76299673d..e194366c4 100644 --- a/pages/index.tsx +++ b/pages/index.tsx @@ -9,8 +9,6 @@ import getAllProducts from '@framework/api/operations/get-all-products' import getSiteInfo from '@framework/api/operations/get-site-info' import getAllPages from '@framework/api/operations/get-all-pages' -// Outputs from providers should already be normalized - export async function getStaticProps({ preview, locale, diff --git a/tsconfig.json b/tsconfig.json index 98639f61e..43dfd2a27 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -26,6 +26,6 @@ "@framework": ["framework/bigcommerce"] } }, - "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", "**/*.js"], + "include": ["next-env.d.ts", "**/*.d.ts", "**/*.ts", "**/*.tsx", "**/*.js"], "exclude": ["node_modules"] } From 3ba60fcafcf2433cb0db39dad5bf631f24c4dc5f Mon Sep 17 00:00:00 2001 From: Belen Curcio Date: Sun, 10 Jan 2021 14:11:00 -0300 Subject: [PATCH 015/216] Changes --- framework/bigcommerce/wishlist/use-wishlist.tsx | 2 +- framework/commerce/wishlist/index.ts | 3 +++ framework/types.d.ts | 9 ++++++--- pages/wishlist.tsx | 4 +++- 4 files changed, 13 insertions(+), 5 deletions(-) create mode 100644 framework/commerce/wishlist/index.ts diff --git a/framework/bigcommerce/wishlist/use-wishlist.tsx b/framework/bigcommerce/wishlist/use-wishlist.tsx index 455fdc9ff..6ebc8459d 100644 --- a/framework/bigcommerce/wishlist/use-wishlist.tsx +++ b/framework/bigcommerce/wishlist/use-wishlist.tsx @@ -16,7 +16,7 @@ export interface UseWishlistOptions { } export interface UseWishlistInput extends UseWishlistOptions { - customerId?: Customer['id'] + customerId?: number } export const fetcher: HookFetcher = ( diff --git a/framework/commerce/wishlist/index.ts b/framework/commerce/wishlist/index.ts new file mode 100644 index 000000000..241af3c7e --- /dev/null +++ b/framework/commerce/wishlist/index.ts @@ -0,0 +1,3 @@ +export { default as useAddItem } from './use-add-item' +export { default as useWishlist } from './use-wishlist' +export { default as useRemoveItem } from './use-remove-item' diff --git a/framework/types.d.ts b/framework/types.d.ts index 881218ca8..8958a9a04 100644 --- a/framework/types.d.ts +++ b/framework/types.d.ts @@ -36,11 +36,14 @@ interface Wishlist { interface Order {} interface Customer { - id: string - name: string - email: string + id: string | number | undefined + [prop: string]: any } +type UseCustomerResponse = { + customer: Customer +} | null + interface Category { id: string name: string diff --git a/pages/wishlist.tsx b/pages/wishlist.tsx index b52c78d47..8f957280f 100644 --- a/pages/wishlist.tsx +++ b/pages/wishlist.tsx @@ -7,6 +7,7 @@ import { Heart } from '@components/icons' import { Text, Container } from '@components/ui' import { WishlistCard } from '@components/wishlist' import { defatultPageProps } from '@lib/defaults' +import { useCustomer } from '@framework/customer' export async function getStaticProps({ preview, @@ -20,7 +21,8 @@ export async function getStaticProps({ } export default function Wishlist() { - const { data, isEmpty } = useWishlist({ includeProducts: true }) + const { data: customer } = useCustomer() + const { data, isEmpty } = useWishlist() return ( From 92a2388bd11459fdb32faafafb4d8565ae531bf9 Mon Sep 17 00:00:00 2001 From: Belen Curcio Date: Sun, 10 Jan 2021 14:13:46 -0300 Subject: [PATCH 016/216] TS Issues --- .../common/HomeAllProductsGrid/HomeAllProductsGrid.tsx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/components/common/HomeAllProductsGrid/HomeAllProductsGrid.tsx b/components/common/HomeAllProductsGrid/HomeAllProductsGrid.tsx index f19e1586a..d292d0d6b 100644 --- a/components/common/HomeAllProductsGrid/HomeAllProductsGrid.tsx +++ b/components/common/HomeAllProductsGrid/HomeAllProductsGrid.tsx @@ -53,8 +53,10 @@ const Head: FC = ({ categories, brands, newestProducts }) => { key={node.path} product={node} variant="simple" - imgWidth={480} - imgHeight={480} + imgProps={{ + width: 480, + height: 480, + }} /> ))} From 0a05182f3b9445ef434aecc6016ce7b015532d0e Mon Sep 17 00:00:00 2001 From: Belen Curcio Date: Sun, 10 Jan 2021 15:55:11 -0300 Subject: [PATCH 017/216] Changes --- .../HomeAllProductsGrid.tsx | 10 ++-- .../product/ProductCard/ProductCard.tsx | 4 +- .../product/ProductView/ProductView.tsx | 47 +++++++++---------- .../api/operations/get-all-products.ts | 10 ++-- framework/types.d.ts | 7 +-- pages/index.tsx | 10 ++-- 6 files changed, 43 insertions(+), 45 deletions(-) diff --git a/components/common/HomeAllProductsGrid/HomeAllProductsGrid.tsx b/components/common/HomeAllProductsGrid/HomeAllProductsGrid.tsx index d292d0d6b..d55f51f7a 100644 --- a/components/common/HomeAllProductsGrid/HomeAllProductsGrid.tsx +++ b/components/common/HomeAllProductsGrid/HomeAllProductsGrid.tsx @@ -8,10 +8,10 @@ import { getCategoryPath, getDesignerPath } from '@lib/search' interface Props { categories?: any brands?: any - newestProducts?: any + products?: Product[] } -const Head: FC = ({ categories, brands, newestProducts }) => { +const Head: FC = ({ categories, brands, products = [] }) => { return (
@@ -48,10 +48,10 @@ const Head: FC = ({ categories, brands, newestProducts }) => {
- {newestProducts.map(({ node }: any) => ( + {products.map((product) => ( = ({ className, product, variant, imgProps }) => { {product.name} - {product.prices[0].value} + {product.price.value}   - {product.prices[0].currencyCode} + {product.price.currencyCode}
= ({ product }) => { const addItem = useAddItem() const { price } = usePrice({ - amount: product.prices?.price?.value, - baseAmount: product.prices?.retailPrice?.value, - currencyCode: product.prices?.price?.currencyCode!, + amount: product.price.value, + baseAmount: product.price.retailValue, + currencyCode: product.price.currencyCode!, }) const { openSidebar } = useUI() const options = getProductOptions(product) @@ -38,15 +38,15 @@ const ProductView: FC = ({ product }) => { size: null, color: null, }) - const variant = - getCurrentVariant(product, choices) || product.variants.edges?.[0] + + const variant = getCurrentVariant(product, choices) || product.variants[0] const addToCart = async () => { setLoading(true) try { await addItem({ - productId: product.entityId, - variantId: product.variants.edges?.[0]?.node.entityId!, + productId: Number(product.id), + variantId: Number(product.variants[0].id), }) openSidebar() setLoading(false) @@ -66,7 +66,7 @@ const ProductView: FC = ({ product }) => { description: product.description, images: [ { - url: product.images.edges?.[0]?.node.urlOriginal!, + url: product.images[0]?.url!, width: 800, height: 600, alt: product.name, @@ -81,18 +81,18 @@ const ProductView: FC = ({ product }) => {
{price} {` `} - {product.prices?.price.currencyCode} + {product.price?.currencyCode}
- - {product.images.edges?.map((image, i) => ( -
+ + {product.images.map((image, i) => ( +
{image?.node.altText = ({ product }) => {
-
diff --git a/framework/bigcommerce/api/operations/get-all-products.ts b/framework/bigcommerce/api/operations/get-all-products.ts index 036602639..7c91c4f1d 100644 --- a/framework/bigcommerce/api/operations/get-all-products.ts +++ b/framework/bigcommerce/api/operations/get-all-products.ts @@ -34,12 +34,10 @@ function productsNormalizer(arr: any[]): Product[] { ), variants: variants.edges.map(({ node }: any) => node), productOptions: productOptions.edges.map(({ node }: any) => node), - prices: [ - { - value: prices.price.value, - currencyCode: prices.price.currencyCode, - }, - ], + price: { + value: prices.price.value, + currencyCode: prices.price.currencyCode, + }, ...rest, }) ) diff --git a/framework/types.d.ts b/framework/types.d.ts index 8958a9a04..87347da7b 100644 --- a/framework/types.d.ts +++ b/framework/types.d.ts @@ -6,7 +6,7 @@ interface Product { path?: string images: ProductImage[] variants: ProductVariant[] - prices: ProductPrice[] + price: ProductPrice } interface ProductImage { url: string @@ -18,9 +18,10 @@ interface ProductVariant { } interface ProductPrice { - value: number | string + value: number currencyCode: 'USD' | 'ARS' - type?: 'price' | 'retail' | 'sale' | string + retailValue?: number + saleValue?: number } interface Cart { diff --git a/pages/index.tsx b/pages/index.tsx index e194366c4..4b76134c7 100644 --- a/pages/index.tsx +++ b/pages/index.tsx @@ -41,7 +41,7 @@ export default function Home({ categories, }: InferGetStaticPropsType) { return ( -
+ <> {products.slice(0, 3).map((product, i) => ( ))}
- {/* */} -
+ /> + ) } From ac58e4a35108b5312a133ec5404109453e32844e Mon Sep 17 00:00:00 2001 From: Belen Curcio Date: Sun, 10 Jan 2021 16:16:49 -0300 Subject: [PATCH 018/216] Normalizer --- .../api/operations/get-all-products.ts | 38 +------------------ .../bigcommerce/api/operations/get-product.ts | 6 ++- framework/bigcommerce/lib/normalize.ts | 33 ++++++++++++++++ framework/types.d.ts | 24 ++++++------ pages/product/[slug].tsx | 2 - 5 files changed, 52 insertions(+), 51 deletions(-) create mode 100644 framework/bigcommerce/lib/normalize.ts diff --git a/framework/bigcommerce/api/operations/get-all-products.ts b/framework/bigcommerce/api/operations/get-all-products.ts index 7c91c4f1d..599109a7d 100644 --- a/framework/bigcommerce/api/operations/get-all-products.ts +++ b/framework/bigcommerce/api/operations/get-all-products.ts @@ -7,41 +7,7 @@ import filterEdges from '../utils/filter-edges' import setProductLocaleMeta from '../utils/set-product-locale-meta' import { productConnectionFragment } from '../fragments/product' import { BigcommerceConfig, getConfig } from '..' - -function productsNormalizer(arr: any[]): Product[] { - // Normalizes products arr response and flattens node edges - return arr.map( - ({ - node: { - entityId: id, - images, - variants, - productOptions, - prices, - path, - ...rest - }, - }) => ({ - id, - path, - slug: path.slice(1, -1), - images: images.edges.map( - ({ node: { urlOriginal, altText, ...rest } }: any) => ({ - url: urlOriginal, - alt: altText, - ...rest, - }) - ), - variants: variants.edges.map(({ node }: any) => node), - productOptions: productOptions.edges.map(({ node }: any) => node), - price: { - value: prices.price.value, - currencyCode: prices.price.currencyCode, - }, - ...rest, - }) - ) -} +import { normalizeProduct } from '../../lib/normalize' export const getAllProductsQuery = /* GraphQL */ ` query getAllProducts( @@ -161,7 +127,7 @@ async function getAllProducts({ }) } - return { products: productsNormalizer(products) } + return { products: products.map(normalizeProduct) } } export default getAllProducts diff --git a/framework/bigcommerce/api/operations/get-product.ts b/framework/bigcommerce/api/operations/get-product.ts index e75e87607..50efb97aa 100644 --- a/framework/bigcommerce/api/operations/get-product.ts +++ b/framework/bigcommerce/api/operations/get-product.ts @@ -2,6 +2,7 @@ import type { GetProductQuery, GetProductQueryVariables } from '../../schema' import setProductLocaleMeta from '../utils/set-product-locale-meta' import { productInfoFragment } from '../fragments/product' import { BigcommerceConfig, getConfig } from '..' +import { normalizeProduct } from '@framework/lib/normalize' export const getProductQuery = /* GraphQL */ ` query getProduct( @@ -92,7 +93,7 @@ async function getProduct({ variables: ProductVariables config?: BigcommerceConfig preview?: boolean -}): Promise { +}): Promise { config = getConfig(config) const locale = vars.locale || config.locale @@ -109,7 +110,8 @@ async function getProduct({ if (locale && config.applyLocale) { setProductLocaleMeta(product) } - return { product } + + return { product: normalizeProduct(product as any) } } return {} diff --git a/framework/bigcommerce/lib/normalize.ts b/framework/bigcommerce/lib/normalize.ts new file mode 100644 index 000000000..f3a316319 --- /dev/null +++ b/framework/bigcommerce/lib/normalize.ts @@ -0,0 +1,33 @@ +import { ProductNode } from '@framework/api/operations/get-all-products' + +export function normalizeProduct(productNode: ProductNode | any): Product { + const { + entityId: id, + images, + variants, + productOptions, + prices, + path, + ...rest + } = productNode + + return { + id, + path, + slug: path.slice(1, -1), + images: images.edges?.map( + ({ node: { urlOriginal, altText, ...rest } }: any) => ({ + url: urlOriginal, + alt: altText, + ...rest, + }) + ), + variants: variants?.edges?.map(({ node }: any) => node), + productOptions: productOptions?.edges?.map(({ node }: any) => node), + price: { + value: prices?.price.value, + currencyCode: prices?.price.currencyCode, + }, + ...rest, + } +} diff --git a/framework/types.d.ts b/framework/types.d.ts index 87347da7b..6d4e573fc 100644 --- a/framework/types.d.ts +++ b/framework/types.d.ts @@ -1,11 +1,15 @@ -interface Product { +interface Entity { id: string | number + [prop: string]: any +} + +interface Product extends Entity { name: string description: string slug: string path?: string - images: ProductImage[] - variants: ProductVariant[] + images: ProductImage[] | any[] | undefined + variants: ProductVariant[] | any[] | undefined price: ProductPrice } interface ProductImage { @@ -19,25 +23,23 @@ interface ProductVariant { interface ProductPrice { value: number - currencyCode: 'USD' | 'ARS' + currencyCode: 'USD' | 'ARS' | string | undefined retailValue?: number saleValue?: number } -interface Cart { +interface Cart extends Entity { id: string products: Pick[] } -interface Wishlist { - id: string +interface Wishlist extends Entity { products: Pick[] } interface Order {} -interface Customer { - id: string | number | undefined +interface Customer extends Entity { [prop: string]: any } @@ -45,12 +47,12 @@ type UseCustomerResponse = { customer: Customer } | null -interface Category { +interface Category extends Entity { id: string name: string } -interface Brand { +interface Brand extends Entity { id: string name: string } diff --git a/pages/product/[slug].tsx b/pages/product/[slug].tsx index 008cd95d6..4f17dcbad 100644 --- a/pages/product/[slug].tsx +++ b/pages/product/[slug].tsx @@ -7,8 +7,6 @@ import { useRouter } from 'next/router' import { Layout } from '@components/common' import { ProductView } from '@components/product' -// Data - import { getConfig } from '@framework/api' import getProduct from '@framework/api/operations/get-product' import getAllPages from '@framework/api/operations/get-all-pages' From def1cf07787c64bd6e793d3b3daa947860ca2117 Mon Sep 17 00:00:00 2001 From: Belen Curcio Date: Sun, 10 Jan 2021 16:21:09 -0300 Subject: [PATCH 019/216] Normalizing more operations --- README.md | 2 ++ framework/bigcommerce/api/operations/get-product.ts | 2 +- framework/bigcommerce/product/index.ts | 2 ++ 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index e944c7569..8410f5641 100644 --- a/README.md +++ b/README.md @@ -106,6 +106,8 @@ Main folder and its exposed functions - `product` - usePrice - useSearch + - getProduct + - getAllProducts - `wishlist` - useWishlist - addWishlistItem diff --git a/framework/bigcommerce/api/operations/get-product.ts b/framework/bigcommerce/api/operations/get-product.ts index 50efb97aa..2476d1398 100644 --- a/framework/bigcommerce/api/operations/get-product.ts +++ b/framework/bigcommerce/api/operations/get-product.ts @@ -111,7 +111,7 @@ async function getProduct({ setProductLocaleMeta(product) } - return { product: normalizeProduct(product as any) } + return { product: normalizeProduct(product) } } return {} diff --git a/framework/bigcommerce/product/index.ts b/framework/bigcommerce/product/index.ts index 426a3edcd..83d507a2c 100644 --- a/framework/bigcommerce/product/index.ts +++ b/framework/bigcommerce/product/index.ts @@ -1,2 +1,4 @@ export { default as usePrice } from './use-price' export { default as useSearch } from './use-search' +export { default as getProduct } from '../api/operations/get-product' +export { default as getAllProducts } from '../api/operations/get-all-products' From 1742ae8ea617755b2ac553fd8cfa073dbbfcba32 Mon Sep 17 00:00:00 2001 From: Belen Curcio Date: Sun, 10 Jan 2021 16:25:25 -0300 Subject: [PATCH 020/216] Normalizing more operations --- components/product/ProductCard/ProductCard.tsx | 6 +++--- framework/types.d.ts | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/components/product/ProductCard/ProductCard.tsx b/components/product/ProductCard/ProductCard.tsx index 47c000032..d60f3e937 100644 --- a/components/product/ProductCard/ProductCard.tsx +++ b/components/product/ProductCard/ProductCard.tsx @@ -25,7 +25,7 @@ const ProductCard: FC = ({ className, product, variant, imgProps }) => { {product.name}
- {product.images[0] && ( + {product.images?[0] && ( {product.name} = ({ className, product, variant, imgProps }) => {
- {product.images[0] && ( + {product.images?[0] && ( {product.name} Date: Mon, 11 Jan 2021 12:12:51 -0300 Subject: [PATCH 021/216] changes --- .../product/ProductCard/ProductCard.tsx | 18 +- components/ui/Marquee/Marquee.tsx | 4 +- .../WishlistButton/WishlistButton.tsx | 2 +- framework/bigcommerce/lib/normalize.ts | 26 +- .../scripts/generate-definitions.js | 49 + package.json | 8 +- pages/index.tsx | 4 +- pages/{index copy.tsx => index2.tsx} | 0 yarn.lock | 1233 +++++++---------- 9 files changed, 570 insertions(+), 774 deletions(-) create mode 100644 framework/bigcommerce/scripts/generate-definitions.js rename pages/{index copy.tsx => index2.tsx} (100%) diff --git a/components/product/ProductCard/ProductCard.tsx b/components/product/ProductCard/ProductCard.tsx index d60f3e937..863a3b2b8 100644 --- a/components/product/ProductCard/ProductCard.tsx +++ b/components/product/ProductCard/ProductCard.tsx @@ -12,9 +12,15 @@ interface Props { imgProps?: Omit } -const ProductCard: FC = ({ className, product, variant, imgProps }) => { +const ProductCard: FC = ({ + className, + product, + variant, + imgProps, + ...props +}) => { return ( - + @@ -25,11 +31,11 @@ const ProductCard: FC = ({ className, product, variant, imgProps }) => { {product.name}
- {product.images?[0] && ( + {product?.images && ( {product.name} = ({ className, product, variant, imgProps }) => {
- {product.images?[0] && ( + {product?.images && ( {product.name} = ({ +const Marquee: FC = ({ className = '', children, variant = 'primary', @@ -32,4 +32,4 @@ const Maquee: FC = ({ ) } -export default Maquee +export default Marquee diff --git a/components/wishlist/WishlistButton/WishlistButton.tsx b/components/wishlist/WishlistButton/WishlistButton.tsx index db9ca4b67..aca0ad148 100644 --- a/components/wishlist/WishlistButton/WishlistButton.tsx +++ b/components/wishlist/WishlistButton/WishlistButton.tsx @@ -47,7 +47,7 @@ const WishlistButton: FC = ({ } else { await addItem({ productId, - variantId: variant?.id, + variantId: variant?.id!, }) } diff --git a/framework/bigcommerce/lib/normalize.ts b/framework/bigcommerce/lib/normalize.ts index f3a316319..7d938c643 100644 --- a/framework/bigcommerce/lib/normalize.ts +++ b/framework/bigcommerce/lib/normalize.ts @@ -1,21 +1,23 @@ -import { ProductNode } from '@framework/api/operations/get-all-products' +import { ProductEdge } from '@framework/schema' -export function normalizeProduct(productNode: ProductNode | any): Product { +export function normalizeProduct(productNode: ProductEdge): Product { + // console.log(productNode) const { - entityId: id, - images, - variants, - productOptions, - prices, - path, - ...rest + node: { + entityId: id, + images, + variants, + productOptions, + prices, + path, + ...rest + }, } = productNode return { - id, path, - slug: path.slice(1, -1), - images: images.edges?.map( + slug: path?.slice(1, -1), + images: images?.edges?.map( ({ node: { urlOriginal, altText, ...rest } }: any) => ({ url: urlOriginal, alt: altText, diff --git a/framework/bigcommerce/scripts/generate-definitions.js b/framework/bigcommerce/scripts/generate-definitions.js new file mode 100644 index 000000000..a2b830d3b --- /dev/null +++ b/framework/bigcommerce/scripts/generate-definitions.js @@ -0,0 +1,49 @@ +/** + * Generates definitions for REST API endpoints that are being + * used by ../api using https://github.com/drwpow/swagger-to-ts + */ +const { readFileSync, promises } = require('fs') +const path = require('path') +const fetch = require('node-fetch') +const swaggerToTS = require('@manifoldco/swagger-to-ts').default + +async function getSchema(filename) { + const url = `https://next-api.stoplight.io/projects/8433/files/${filename}` + const res = await fetch(url) + + if (!res.ok) { + throw new Error(`Request failed with ${res.status}: ${res.statusText}`) + } + + return res.json() +} + +const schemas = Object.entries({ + '../api/definitions/catalog.ts': + 'BigCommerce_Catalog_API.oas2.yml?ref=version%2F20.930', + '../api/definitions/store-content.ts': + 'BigCommerce_Store_Content_API.oas2.yml?ref=version%2F20.930', + '../api/definitions/wishlist.ts': + 'BigCommerce_Wishlist_API.oas2.yml?ref=version%2F20.930', + // swagger-to-ts is not working for the schema of the cart API + // '../api/definitions/cart.ts': + // 'BigCommerce_Server_to_Server_Cart_API.oas2.yml', +}) + +async function writeDefinitions() { + const ops = schemas.map(async ([dest, filename]) => { + const destination = path.join(__dirname, dest) + const schema = await getSchema(filename) + const definition = swaggerToTS(schema.content, { + prettierConfig: 'package.json', + }) + + await promises.writeFile(destination, definition) + + console.log(`✔️ Added definitions for: ${dest}`) + }) + + await Promise.all(ops) +} + +writeDefinitions() diff --git a/package.json b/package.json index 35e8d5cb5..dd78af9ba 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,7 @@ "analyze": "BUNDLE_ANALYZE=both yarn build", "find:unused": "next-unused", "generate": "graphql-codegen", - "generate:definitions": "node framework/bigcommerce/lib/generate-definitions.js" + "generate:definitions": "node framework/bigcommerce/scripts/generate-definitions.js" }, "prettier": { "semi": false, @@ -46,7 +46,9 @@ "dependencies": { "@reach/portal": "^0.11.2", "@tailwindcss/ui": "^0.6.2", + "@types/node-fetch": "2", "@vercel/fetch": "^6.1.0", + "@vercel/fetch-cached-dns": "^2.0.1", "body-scroll-lock": "^3.1.5", "bowser": "^2.11.0", "classnames": "^2.2.6", @@ -60,12 +62,14 @@ "next": "^10.0.5-canary.11", "next-seo": "^4.11.0", "next-themes": "^0.0.4", + "node-fetch": "^2.6.1", "postcss-nesting": "^7.0.1", "react": "^16.14.0", "react-dom": "^16.14.0", "react-merge-refs": "^1.1.0", "react-ticker": "^1.2.2", - "swr": "^0.3.11", + "swr": "^0.4.0", + "tabbable": "^5.1.5", "tailwindcss": "^1.9" }, "devDependencies": { diff --git a/pages/index.tsx b/pages/index.tsx index 4b76134c7..d3f3f6ba5 100644 --- a/pages/index.tsx +++ b/pages/index.tsx @@ -102,11 +102,11 @@ export default function Home({ /> ))}
- + /> */} ) } diff --git a/pages/index copy.tsx b/pages/index2.tsx similarity index 100% rename from pages/index copy.tsx rename to pages/index2.tsx diff --git a/yarn.lock b/yarn.lock index 2cd6e3ee4..29227fbb8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -88,7 +88,7 @@ semver "^5.4.1" source-map "^0.5.0" -"@babel/generator@^7.12.1", "@babel/generator@^7.12.10", "@babel/generator@^7.12.11", "@babel/generator@^7.5.0": +"@babel/generator@^7.12.10", "@babel/generator@^7.12.11", "@babel/generator@^7.5.0": version "7.12.11" resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.12.11.tgz#98a7df7b8c358c9a37ab07a24056853016aba3af" integrity sha512-Ggg6WPOJtSi8yYQvLVjG8F/TlpWDlKx0OpS4Kt+xMQPs5OaGYWy+v1A+1TvxI6sAMGZpKWWoAQ1DaeQbImlItA== @@ -212,12 +212,7 @@ dependencies: "@babel/types" "^7.12.11" -"@babel/helper-validator-identifier@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz#a78c7a7251e01f616512d31b10adcf52ada5e0d2" - integrity sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw== - -"@babel/helper-validator-identifier@^7.12.11": +"@babel/helper-validator-identifier@^7.10.4", "@babel/helper-validator-identifier@^7.12.11": version "7.12.11" resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz#c9a1f021917dcb5ccf0d4e453e399022981fc9ed" integrity sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw== @@ -240,17 +235,7 @@ chalk "^2.0.0" js-tokens "^4.0.0" -"@babel/parser@7.11.5": - version "7.11.5" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.11.5.tgz#c7ff6303df71080ec7a4f5b8c003c58f1cf51037" - integrity sha512-X9rD8qqm695vgmeaQ4fvz/o3+Wk4ZzQvSHkDBgpYKxpD4qTAUm88ZKtHkVqIOsYFFbIQ6wQYhC6q7pjqVK0E0Q== - -"@babel/parser@^7.0.0": - version "7.12.5" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.12.5.tgz#b4af32ddd473c0bfa643bd7ff0728b8e71b81ea0" - integrity sha512-FVM6RZQ0mn2KCf1VUED7KepYeUWoVShczewOCfm3nzoBybaih51h+sYVVGthW9M6lPByEPTQf+xm27PBdlpwmQ== - -"@babel/parser@^7.12.1", "@babel/parser@^7.12.10", "@babel/parser@^7.12.11", "@babel/parser@^7.12.7": +"@babel/parser@7.12.11", "@babel/parser@^7.0.0", "@babel/parser@^7.12.0", "@babel/parser@^7.12.10", "@babel/parser@^7.12.11", "@babel/parser@^7.12.7": version "7.12.11" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.12.11.tgz#9ce3595bcd74bc5c466905e86c535b8b25011e79" integrity sha512-N3UxG+uuF4CMYoNj8AhnbAcJF0PiuJ9KHuy1lQmkYsxTer/MAH9UBNHsBoAX/4s6NvlDD047No8mYVGGzLL4hg== @@ -474,22 +459,7 @@ "@babel/parser" "^7.12.7" "@babel/types" "^7.12.7" -"@babel/traverse@7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.12.1.tgz#941395e0c5cc86d5d3e75caa095d3924526f0c1e" - integrity sha512-MA3WPoRt1ZHo2ZmoGKNqi20YnPt0B1S0GTZEPhhd+hw2KGUzBlHuVunj6K4sNuK+reEvyiPwtp0cpaqLzJDmAw== - dependencies: - "@babel/code-frame" "^7.10.4" - "@babel/generator" "^7.12.1" - "@babel/helper-function-name" "^7.10.4" - "@babel/helper-split-export-declaration" "^7.11.0" - "@babel/parser" "^7.12.1" - "@babel/types" "^7.12.1" - debug "^4.1.0" - globals "^11.1.0" - lodash "^4.17.19" - -"@babel/traverse@^7.0.0", "@babel/traverse@^7.12.1", "@babel/traverse@^7.12.10", "@babel/traverse@^7.12.5": +"@babel/traverse@7.12.12", "@babel/traverse@^7.0.0", "@babel/traverse@^7.12.1", "@babel/traverse@^7.12.10", "@babel/traverse@^7.12.5": version "7.12.12" resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.12.12.tgz#d0cd87892704edd8da002d674bc811ce64743376" integrity sha512-s88i0X0lPy45RrLM8b9mz8RPH5FqO9G9p7ti59cToE44xFm1Q+Pjh5Gq4SXBbtb88X7Uy7pexeqRIQDDMNkL0w== @@ -504,12 +474,12 @@ globals "^11.1.0" lodash "^4.17.19" -"@babel/types@7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.12.1.tgz#e109d9ab99a8de735be287ee3d6a9947a190c4ae" - integrity sha512-BzSY3NJBKM4kyatSOWh3D/JJ2O3CVzBybHWxtgxnggaxEuaSTTDqeiSb/xk9lrkw2Tbqyivw5ZU4rT+EfznQsA== +"@babel/types@7.12.12", "@babel/types@^7.0.0", "@babel/types@^7.10.5", "@babel/types@^7.12.0", "@babel/types@^7.12.1", "@babel/types@^7.12.10", "@babel/types@^7.12.11", "@babel/types@^7.12.12", "@babel/types@^7.12.5", "@babel/types@^7.12.7": + version "7.12.12" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.12.12.tgz#4608a6ec313abbd87afa55004d373ad04a96c299" + integrity sha512-lnIX7piTxOH22xE7fDXDbSHg9MM1/6ORnafpJmov5rs0kX5g4BZxeXNJLXsMRiO0U5Rb8/FvMS6xlTnTHvxonQ== dependencies: - "@babel/helper-validator-identifier" "^7.10.4" + "@babel/helper-validator-identifier" "^7.12.11" lodash "^4.17.19" to-fast-properties "^2.0.0" @@ -522,15 +492,6 @@ lodash "^4.17.13" to-fast-properties "^2.0.0" -"@babel/types@^7.0.0", "@babel/types@^7.10.5", "@babel/types@^7.12.1", "@babel/types@^7.12.10", "@babel/types@^7.12.11", "@babel/types@^7.12.12", "@babel/types@^7.12.5", "@babel/types@^7.12.7": - version "7.12.12" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.12.12.tgz#4608a6ec313abbd87afa55004d373ad04a96c299" - integrity sha512-lnIX7piTxOH22xE7fDXDbSHg9MM1/6ORnafpJmov5rs0kX5g4BZxeXNJLXsMRiO0U5Rb8/FvMS6xlTnTHvxonQ== - dependencies: - "@babel/helper-validator-identifier" "^7.12.11" - lodash "^4.17.19" - to-fast-properties "^2.0.0" - "@csstools/convert-colors@^1.4.0": version "1.4.0" resolved "https://registry.yarnpkg.com/@csstools/convert-colors/-/convert-colors-1.4.0.tgz#ad495dc41b12e75d588c6db8b9834f08fa131eb7" @@ -653,19 +614,19 @@ tslib "~2.0.1" "@graphql-codegen/typescript@^1.18.1", "@graphql-codegen/typescript@^1.19.0": - version "1.19.0" - resolved "https://registry.yarnpkg.com/@graphql-codegen/typescript/-/typescript-1.19.0.tgz#05b1b4502b91dee53ec4f0ae39e9537eff004c5c" - integrity sha512-ThpMdtb6LmEKzLNxlotpk33eIMfX1i1aAlYDaqctIhFjZ2Rbvkgdb8q/5/my7yeH33BLnuqHDKrdkDsAAvCHcw== + version "1.20.0" + resolved "https://registry.yarnpkg.com/@graphql-codegen/typescript/-/typescript-1.20.0.tgz#f9a17b869e5691276965a56c7a1efe4eb938b6e7" + integrity sha512-7xW+n0USNpr6iZ4Et17ZbPzBLNe/LrSgrQ6V/8Mlgp1reQWAZtoVw13Oq4GnxHCzAYio8nFindLl+emW9ZBeew== dependencies: "@graphql-codegen/plugin-helpers" "^1.18.2" - "@graphql-codegen/visitor-plugin-common" "^1.17.21" + "@graphql-codegen/visitor-plugin-common" "^1.18.0" auto-bind "~4.0.0" tslib "~2.0.1" -"@graphql-codegen/visitor-plugin-common@^1.17.21", "@graphql-codegen/visitor-plugin-common@^1.17.22": - version "1.17.22" - resolved "https://registry.yarnpkg.com/@graphql-codegen/visitor-plugin-common/-/visitor-plugin-common-1.17.22.tgz#5321077ea54b423397b659406a2b60d1a3b44156" - integrity sha512-5+fkcET7ftqexyEkGWvmalL+RTi1ApfAt9k9FEmM2WdRXi/uYwwYb+qHwIoaMVD0pXKeUAB5+Qgs9+Md4VIM7Q== +"@graphql-codegen/visitor-plugin-common@^1.17.22", "@graphql-codegen/visitor-plugin-common@^1.18.0": + version "1.18.0" + resolved "https://registry.yarnpkg.com/@graphql-codegen/visitor-plugin-common/-/visitor-plugin-common-1.18.0.tgz#f4366ec1093c01e752e85f8bd30d09c58b1d6951" + integrity sha512-OR/Cm9nVaqMLe94Ski60UDhaAf/4+QeV/CQRYrCmxFzEsm03U41VplcNgJBXIAB3EgP/LEIZtgkRc1H4N9u9+Q== dependencies: "@graphql-codegen/plugin-helpers" "^1.18.2" "@graphql-tools/optimize" "^1.0.1" @@ -748,17 +709,17 @@ tslib "~2.0.1" "@graphql-tools/graphql-tag-pluck@^6.2.6": - version "6.3.0" - resolved "https://registry.yarnpkg.com/@graphql-tools/graphql-tag-pluck/-/graphql-tag-pluck-6.3.0.tgz#b1c178fe6e8c4823ca611cf1392f530ad0490dd9" - integrity sha512-wdXE6iKTD/ePvhPaukhXm6M8FcsiR9rrwFvkYN96sx2UjDjXzU6vS1QUniNuwjRPaQuSe635vqfaUSN9JuNHvA== + version "6.4.0" + resolved "https://registry.yarnpkg.com/@graphql-tools/graphql-tag-pluck/-/graphql-tag-pluck-6.4.0.tgz#f8303606f717174a1068501294805b3304417145" + integrity sha512-qBQ0ITgMkUzxz5QsZk9HsSeOQo6KlXd/Ex5cePzPuRT72odPEQXNL9hCsxaCvZO9r3in8bmG6OTWs4ms/GevXA== dependencies: - "@babel/parser" "7.11.5" - "@babel/traverse" "7.12.1" - "@babel/types" "7.12.1" + "@babel/parser" "7.12.11" + "@babel/traverse" "7.12.12" + "@babel/types" "7.12.12" "@graphql-tools/utils" "^7.0.0" - tslib "~2.0.1" + tslib "~2.1.0" optionalDependencies: - vue-template-compiler "^2.6.12" + "@vue/compiler-sfc" "^3.0.4" "@graphql-tools/import@^6.2.5": version "6.2.5" @@ -886,13 +847,13 @@ tslib "~2.0.1" "@graphql-tools/utils@^7.0.0", "@graphql-tools/utils@^7.1.0", "@graphql-tools/utils@^7.1.2", "@graphql-tools/utils@^7.1.5", "@graphql-tools/utils@^7.1.6", "@graphql-tools/utils@^7.2.1": - version "7.2.3" - resolved "https://registry.yarnpkg.com/@graphql-tools/utils/-/utils-7.2.3.tgz#4bb2ae0bef62df1f342f2a769434fbb105dd0d84" - integrity sha512-9MvSKeo+8DM72706FvrUP8figQjRzSwBswWrXviyWyt3wSkk6MU2cURQKfMpc0I6nswZvkDSqYoQQ/6mazoXxA== + version "7.2.4" + resolved "https://registry.yarnpkg.com/@graphql-tools/utils/-/utils-7.2.4.tgz#1164cf268988254f281b4cfbbc0e8f7ca24a8a41" + integrity sha512-EDSb98dTWX8FngvayWejip1DutOl0wGtNbXC7a3CZf5fiJS7bGHQ/8cSlMhe9XaHwpLJCbAk/Ijnp/dYbXk33w== dependencies: "@ardatan/aggregate-error" "0.0.6" camel-case "4.1.2" - tslib "~2.0.1" + tslib "~2.1.0" "@graphql-tools/wrap@^7.0.4": version "7.0.5" @@ -914,16 +875,16 @@ "@hapi/hoek" "9.x.x" "@hapi/boom@9.x.x": - version "9.1.0" - resolved "https://registry.yarnpkg.com/@hapi/boom/-/boom-9.1.0.tgz#0d9517657a56ff1e0b42d0aca9da1b37706fec56" - integrity sha512-4nZmpp4tXbm162LaZT45P7F7sgiem8dwAh2vHWT6XX24dozNjGMg6BvKCRvtCUcmcXqeMIUqWN8Rc5X8yKuROQ== + version "9.1.1" + resolved "https://registry.yarnpkg.com/@hapi/boom/-/boom-9.1.1.tgz#89e6f0e01637c2a4228da0d113e8157c93677b04" + integrity sha512-VNR8eDbBrOxBgbkddRYIe7+8DZ+vSbV6qlmaN2x7eWjsUjy2VmQgChkOKcVZIeupEZYj+I0dqNg430OhwzagjA== dependencies: "@hapi/hoek" "9.x.x" "@hapi/hoek@9.x.x": - version "9.1.0" - resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-9.1.0.tgz#6c9eafc78c1529248f8f4d92b0799a712b6052c6" - integrity sha512-i9YbZPN3QgfighY/1X1Pu118VUz2Fmmhd6b2n0/O8YVgGGfw0FbUYoA97k7FkpGJ+pLCFEDLUmAPPV4D1kpeFw== + version "9.1.1" + resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-9.1.1.tgz#9daf5745156fd84b8e9889a2dc721f0c58e894aa" + integrity sha512-CAEbWH7OIur6jEOzaai83jq3FmKmv4PmX1JYfs9IrYcGEVI/lyL1EXJGCj7eFVJ0bg5QR8LMxBlEtA+xKiLpFw== "@iarna/toml@^2.2.5": version "2.2.5" @@ -941,26 +902,26 @@ prettier "^2.0.5" "@next/bundle-analyzer@^10.0.1": - version "10.0.1" - resolved "https://registry.yarnpkg.com/@next/bundle-analyzer/-/bundle-analyzer-10.0.1.tgz#4bcb376c1163b9e6e2866e1112bc848194648dce" - integrity sha512-1UMWnaeZSm+HQTqkje5ToqzCO3kXh7tqeJQBRjWz4+bbTdZEWPO8JPB/JFNpckU3FzYcnG6oeeYmUzHufZp3sg== + version "10.0.5" + resolved "https://registry.yarnpkg.com/@next/bundle-analyzer/-/bundle-analyzer-10.0.5.tgz#02eda5d88bc1ee8efff03902083bcb2c537e787d" + integrity sha512-fDhursKrqycV7u6crESINKQKp5/Q17Xd9mI1n0BFhIvpfp8br/gSqLHeaN2DXfcOS/Rb0/FmY4pdIFjXnwdZbg== dependencies: - webpack-bundle-analyzer "3.6.1" + webpack-bundle-analyzer "4.3.0" -"@next/env@10.0.5-canary.11": - version "10.0.5-canary.11" - resolved "https://registry.yarnpkg.com/@next/env/-/env-10.0.5-canary.11.tgz#76daeda2bd0c9f040892f299864091c37c946bb9" - integrity sha512-afx6ECY9pqPLvVOteA1gi0pZ6CuLPSSx5QNyKX+m9v0sp+idEIjgFtghI+HU+hz7S9C7EP0kGw3wnY1/qdK0bw== +"@next/env@10.0.5": + version "10.0.5" + resolved "https://registry.yarnpkg.com/@next/env/-/env-10.0.5.tgz#446e59ee7a8d05061be784b24732c369653038ab" + integrity sha512-dw6Q7PALIo7nTFfaB4OnRDte3EikrApGtjX/4cRmYXLh+uudDI50aS39MaGeKKZ2mxPKoNiFcY6Slv1f6KIPOw== -"@next/polyfill-module@10.0.5-canary.11": - version "10.0.5-canary.11" - resolved "https://registry.yarnpkg.com/@next/polyfill-module/-/polyfill-module-10.0.5-canary.11.tgz#e6e53351b1bdd2ce619a4e29df191b1c8633d232" - integrity sha512-MWsioa2Kyx/p8kDsB0Y6fCley7/S8Z+vUG4ixUteR+OWibZSQrtqGs47lCJyfvdu69s75uzSlXNybbTWzcMguA== +"@next/polyfill-module@10.0.5": + version "10.0.5" + resolved "https://registry.yarnpkg.com/@next/polyfill-module/-/polyfill-module-10.0.5.tgz#f2de3deee8694cc75094fea4e91225724b3a21e1" + integrity sha512-R6ySTTIl6yqyO3Xft7h+QR9Z4e6epEw+AGO125CrwPmCDQ8ASLGltsHYvSHBP7Eae7xaorkXHW0jeI8NewLpew== -"@next/react-dev-overlay@10.0.5-canary.11": - version "10.0.5-canary.11" - resolved "https://registry.yarnpkg.com/@next/react-dev-overlay/-/react-dev-overlay-10.0.5-canary.11.tgz#c897d12eb0b1c8df065dc2a72ba7aeff5049b566" - integrity sha512-6Zt3wWhEVzGr9i8GUzCvDeY7qTb/u6Svnaan3uvY1cVtkghMa8qvGYqG45URecD8VhGBo9dI8Bnl9vYE4yj2wA== +"@next/react-dev-overlay@10.0.5": + version "10.0.5" + resolved "https://registry.yarnpkg.com/@next/react-dev-overlay/-/react-dev-overlay-10.0.5.tgz#f0006e56d8c8b4269f341ff22233e4a7e1176b52" + integrity sha512-olqIaaRvFezzi02V/AYwvmrGbShUNrJDvyZTGNahxXEkiYsuu67llY5IKFM5Oya93/eRqaCCKMn89vpvYtvDcw== dependencies: "@babel/code-frame" "7.12.11" anser "1.4.9" @@ -974,10 +935,10 @@ stacktrace-parser "0.1.10" strip-ansi "6.0.0" -"@next/react-refresh-utils@10.0.5-canary.11": - version "10.0.5-canary.11" - resolved "https://registry.yarnpkg.com/@next/react-refresh-utils/-/react-refresh-utils-10.0.5-canary.11.tgz#d3e885bfb0175f887adf4d927df0f6852a066a77" - integrity sha512-W/JNmDVnGeziaRkcCa94Oj0izOCWv4XGIKRNkTnQrtAWlZ1sIq5eijkJSJRphfBt9sShKUc90LOWCjtoEPpBwQ== +"@next/react-refresh-utils@10.0.5": + version "10.0.5" + resolved "https://registry.yarnpkg.com/@next/react-refresh-utils/-/react-refresh-utils-10.0.5.tgz#c1ca664c4ffe2f79d14383323d783368833d503b" + integrity sha512-Eo+nvW1ZhdkuxBWSsKHGDLNspUaJJQClld9R+H+EtiIuAQtTa8f2rhcQeyUOtvUNQoPyq7Em2PwUqOQD6LOOMA== "@nodelib/fs.scandir@2.1.4": version "2.1.4" @@ -1012,6 +973,11 @@ resolved "https://registry.yarnpkg.com/@opentelemetry/context-base/-/context-base-0.14.0.tgz#c67fc20a4d891447ca1a855d7d70fa79a3533001" integrity sha512-sDOAZcYwynHFTbLo6n8kIbLiVF3a3BLkrmehJUyEbT9F+Smbi47kLGS2gG2g0fjBLR/Lr1InPD7kXL7FaTqEkw== +"@polka/url@^1.0.0-next.9": + version "1.0.0-next.11" + resolved "https://registry.yarnpkg.com/@polka/url/-/url-1.0.0-next.11.tgz#aeb16f50649a91af79dbe36574b66d0f9e4d9f71" + integrity sha512-3NsZsJIA/22P3QUyrEDNA2D133H4j224twJrdipXN38dpnIOzAbUDtOwkcJ5pXmn75w7LSQDjA4tO9dm1XlqlA== + "@reach/portal@^0.11.2": version "0.11.2" resolved "https://registry.yarnpkg.com/@reach/portal/-/portal-0.11.2.tgz#19a671be9ff010a345892b81e710cb6e4d9f9762" @@ -1102,9 +1068,9 @@ "@types/node" "*" "@types/classnames@^2.2.10": - version "2.2.10" - resolved "https://registry.yarnpkg.com/@types/classnames/-/classnames-2.2.10.tgz#cc658ca319b6355399efc1f5b9e818f1a24bf999" - integrity sha512-1UzDldn9GfYYEsWWnn/P4wkTlkZDH7lDb0wBMGbtIQc9zXEQq7FlKBdZUn6OBqD8sKZZ2RQO2mAjGpXiDGoRmQ== + version "2.2.11" + resolved "https://registry.yarnpkg.com/@types/classnames/-/classnames-2.2.11.tgz#2521cc86f69d15c5b90664e4829d84566052c1cf" + integrity sha512-2koNhpWm3DgWRp5tpkiJ8JGc1xTn2q0l+jUNUE7oMKXUf5NpI9AIdC4kbjGNFBdHtcxBD18LAksoudAVhFKCjw== "@types/cookie@^0.4.0": version "0.4.0" @@ -1120,9 +1086,9 @@ "@types/estree" "*" "@types/eslint@*": - version "7.2.4" - resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-7.2.4.tgz#d12eeed7741d2491b69808576ac2d20c14f74c41" - integrity sha512-YCY4kzHMsHoyKspQH+nwSe+70Kep7Vjt2X+dZe5Vs2vkRudqtoFoUIv1RlJmZB8Hbp7McneupoZij4PadxsK5Q== + version "7.2.6" + resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-7.2.6.tgz#5e9aff555a975596c03a98b59ecd103decc70c3c" + integrity sha512-I+1sYH+NPQ3/tVqCeUSBwTE/0heyvtXqpIopUUArlBm0Kpocb8FbMa3AZ/ASKIFpN3rnEx932TTXDbt9OXsNDw== dependencies: "@types/estree" "*" "@types/json-schema" "*" @@ -1145,9 +1111,9 @@ integrity sha512-+oY0FDTO2GYKEV0YPvSshGq9t7YozVkgvXLty7zogQNuCxBhT9/3INX9Q7H1aRZ4SUDRXAKlJuA4EA5nTt7SNw== "@types/js-yaml@^3.12.5": - version "3.12.5" - resolved "https://registry.yarnpkg.com/@types/js-yaml/-/js-yaml-3.12.5.tgz#136d5e6a57a931e1cce6f9d8126aa98a9c92a6bb" - integrity sha512-JCcp6J0GV66Y4ZMDAQCXot4xprYB+Zfd3meK9+INSJeVZwJmHAW30BBEEkPzXswMXuiyReUGOP3GxrADc9wPww== + version "3.12.6" + resolved "https://registry.yarnpkg.com/@types/js-yaml/-/js-yaml-3.12.6.tgz#7f10c926aa41e189a2755c4c7fcf8e4573bd7ac1" + integrity sha512-cK4XqrLvP17X6c0C8n4iTbT59EixqyXL3Fk8/Rsk4dF3oX4dg70gYUXrXVUUHpnsGMPNlTQMqf+TVmNPX6FmSQ== "@types/json-schema@*", "@types/json-schema@^7.0.5", "@types/json-schema@^7.0.6": version "7.0.6" @@ -1188,9 +1154,9 @@ "@types/lodash" "*" "@types/lodash@*": - version "4.14.162" - resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.162.tgz#65d78c397e0d883f44afbf1f7ba9867022411470" - integrity sha512-alvcho1kRUnnD1Gcl4J+hK0eencvzq9rmzvFPRmP5rPHx9VVsJj6bKLTATPVf9ktgv4ujzh7T+XWKp+jhuODig== + version "4.14.167" + resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.167.tgz#ce7d78553e3c886d4ea643c37ec7edc20f16765e" + integrity sha512-w7tQPjARrvdeBkX/Rwg95S592JwxqOjmms3zWQ0XZgSyxSLdzWaYH3vErBhdVS/lRBX7F8aBYcYJYTr5TMGOzw== "@types/lru-cache@4.1.1": version "4.1.1" @@ -1202,6 +1168,14 @@ resolved "https://registry.yarnpkg.com/@types/minimist/-/minimist-1.2.1.tgz#283f669ff76d7b8260df8ab7a4262cc83d988256" integrity sha512-fZQQafSREFyuZcdWFAExYjBiCL7AUCdgsk80iO0q4yihYYdcIiH28CcuPTGFgLOCC8RlW49GSQxdHwZP+I7CNg== +"@types/node-fetch@2": + version "2.5.7" + resolved "https://registry.yarnpkg.com/@types/node-fetch/-/node-fetch-2.5.7.tgz#20a2afffa882ab04d44ca786449a276f9f6bbf3c" + integrity sha512-o2WVNf5UhWRkxlf6eq+jMZDu7kjgpgJfl4xVNlvryc95O/6F2ld8ztKX+qu+Rjyet93WAWm5LjeX9H5FGkODvw== + dependencies: + "@types/node" "*" + form-data "^3.0.0" + "@types/node-fetch@2.3.2": version "2.3.2" resolved "https://registry.yarnpkg.com/@types/node-fetch/-/node-fetch-2.3.2.tgz#e01893b176c6fa1367743726380d65bce5d6576b" @@ -1209,21 +1183,16 @@ dependencies: "@types/node" "*" -"@types/node@*": - version "14.14.2" - resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.2.tgz#d25295f9e4ca5989a2c610754dc02a9721235eeb" - integrity sha512-jeYJU2kl7hL9U5xuI/BhKPZ4vqGM/OmK6whiFAXVhlstzZhVamWhDSmHyGLIp+RVyuF9/d0dqr2P85aFj4BvJg== +"@types/node@*", "@types/node@^14.14.16": + version "14.14.20" + resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.20.tgz#f7974863edd21d1f8a494a73e8e2b3658615c340" + integrity sha512-Y93R97Ouif9JEOWPIUyU+eyIdyRqQR0I8Ez1dzku4hDx34NWh4HbtIc3WNzwB1Y9ULvNGeu5B8h8bVL5cAk4/A== "@types/node@10.12.18": version "10.12.18" resolved "https://registry.yarnpkg.com/@types/node/-/node-10.12.18.tgz#1d3ca764718915584fcd9f6344621b7672665c67" integrity sha512-fh+pAqt4xRzPfqA6eh3Z2y6fyZavRIumvjhaCL753+TVkGKGhpPeyrJG2JftD0T9q4GF00KjefsQ+PQNDdWQaQ== -"@types/node@^14.14.16": - version "14.14.16" - resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.16.tgz#3cc351f8d48101deadfed4c9e4f116048d437b4b" - integrity sha512-naXYePhweTi+BMv11TgioE2/FXU4fSl29HAH1ffxVciNsH3rYXjNP2yM8wqmSm7jS20gM8TIklKiTen+1iVncw== - "@types/normalize-package-data@^2.4.0": version "2.4.0" resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz#e486d0d97396d79beedd0a6e33f4534ff6b4973e" @@ -1299,6 +1268,60 @@ agentkeepalive "3.4.1" debug "3.1.0" +"@vue/compiler-core@3.0.5": + version "3.0.5" + resolved "https://registry.yarnpkg.com/@vue/compiler-core/-/compiler-core-3.0.5.tgz#a6e54cabe9536e74c6513acd2649f311af1d43ac" + integrity sha512-iFXwk2gmU/GGwN4hpBwDWWMLvpkIejf/AybcFtlQ5V1ur+5jwfBaV0Y1RXoR6ePfBPJixtKZ3PmN+M+HgMAtfQ== + dependencies: + "@babel/parser" "^7.12.0" + "@babel/types" "^7.12.0" + "@vue/shared" "3.0.5" + estree-walker "^2.0.1" + source-map "^0.6.1" + +"@vue/compiler-dom@3.0.5": + version "3.0.5" + resolved "https://registry.yarnpkg.com/@vue/compiler-dom/-/compiler-dom-3.0.5.tgz#7885a13e6d18f64dde8ebceec052ed2c102696c2" + integrity sha512-HSOSe2XSPuCkp20h4+HXSiPH9qkhz6YbW9z9ZtL5vef2T2PMugH7/osIFVSrRZP/Ul5twFZ7MIRlp8tPX6e4/g== + dependencies: + "@vue/compiler-core" "3.0.5" + "@vue/shared" "3.0.5" + +"@vue/compiler-sfc@^3.0.4": + version "3.0.5" + resolved "https://registry.yarnpkg.com/@vue/compiler-sfc/-/compiler-sfc-3.0.5.tgz#3ae08e60244a72faf9598361874fb7bdb5b1d37c" + integrity sha512-uOAC4X0Gx3SQ9YvDC7YMpbDvoCmPvP0afVhJoxRotDdJ+r8VO3q4hFf/2f7U62k4Vkdftp6DVni8QixrfYzs+w== + dependencies: + "@babel/parser" "^7.12.0" + "@babel/types" "^7.12.0" + "@vue/compiler-core" "3.0.5" + "@vue/compiler-dom" "3.0.5" + "@vue/compiler-ssr" "3.0.5" + "@vue/shared" "3.0.5" + consolidate "^0.16.0" + estree-walker "^2.0.1" + hash-sum "^2.0.0" + lru-cache "^5.1.1" + magic-string "^0.25.7" + merge-source-map "^1.1.0" + postcss "^7.0.32" + postcss-modules "^3.2.2" + postcss-selector-parser "^6.0.4" + source-map "^0.6.1" + +"@vue/compiler-ssr@3.0.5": + version "3.0.5" + resolved "https://registry.yarnpkg.com/@vue/compiler-ssr/-/compiler-ssr-3.0.5.tgz#7661ad891a0be948726c7f7ad1e425253c587b83" + integrity sha512-Wm//Kuxa1DpgjE4P9W0coZr8wklOfJ35Jtq61CbU+t601CpPTK4+FL2QDBItaG7aoUUDCWL5nnxMkuaOgzTBKg== + dependencies: + "@vue/compiler-dom" "3.0.5" + "@vue/shared" "3.0.5" + +"@vue/shared@3.0.5": + version "3.0.5" + resolved "https://registry.yarnpkg.com/@vue/shared/-/shared-3.0.5.tgz#c131d88bd6713cc4d93b3bb1372edb1983225ff0" + integrity sha512-gYsNoGkWejBxNO6SNRjOh/xKeZ0H0V+TFzaPzODfBjkAIb0aQgBuixC1brandC/CDJy1wYPwSoYrXpvul7m6yw== + "@webassemblyjs/ast@1.9.1": version "1.9.1" resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.9.1.tgz#76c6937716d68bf1484c15139f5ed30b9abc8bb4" @@ -1472,14 +1495,6 @@ abort-controller@3.0.0: dependencies: event-target-shim "^5.0.0" -accepts@~1.3.7: - version "1.3.7" - resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.7.tgz#531bc726517a3b2b41f850021c6cc15eaab507cd" - integrity sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA== - dependencies: - mime-types "~2.1.24" - negotiator "0.6.2" - acorn-node@^1.6.1: version "1.8.2" resolved "https://registry.yarnpkg.com/acorn-node/-/acorn-node-1.8.2.tgz#114c95d64539e53dede23de8b9d96df7c7ae2af8" @@ -1489,12 +1504,17 @@ acorn-node@^1.6.1: acorn-walk "^7.0.0" xtend "^4.0.2" -acorn-walk@^7.0.0, acorn-walk@^7.1.1: +acorn-walk@^7.0.0: version "7.2.0" resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-7.2.0.tgz#0de889a601203909b0fbe07b8938dc21d2e967bc" integrity sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA== -acorn@^7.0.0, acorn@^7.1.1: +acorn-walk@^8.0.0: + version "8.0.1" + resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.0.1.tgz#d265d35db6940a656c715806a448456ee4fa3b7f" + integrity sha512-zn/7dYtoTVkG4EoMU55QlQU4F+m+T7Kren6Vj3C2DapWPnakG/DL9Ns5aPAPW5Ixd3uxXrV/BoMKKVFIazPcdg== + +acorn@^7.0.0: version "7.4.1" resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== @@ -1640,11 +1660,6 @@ arity-n@^1.0.4: resolved "https://registry.yarnpkg.com/arity-n/-/arity-n-1.0.4.tgz#d9e76b11733e08569c0847ae7b39b2860b30b745" integrity sha1-2edrEXM+CFacCEeuezmyhgswt0U= -array-flatten@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" - integrity sha1-ml9pkFGx5wczKPKgCJaLZOopVdI= - array-flatten@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-3.0.0.tgz#6428ca2ee52c7b823192ec600fa3ed2f157cd541" @@ -1707,11 +1722,6 @@ ast-types@0.13.2: resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.13.2.tgz#df39b677a911a83f3a049644fb74fdded23cea48" integrity sha512-uWMHxJxtfj/1oZClOxDEV1sQ1HCDkA4MG8Gr69KKeBjEVH0R84WlejZ0y2DcwyBlpAEMltmVYkVgqfLFb2oyiA== -async-limiter@~1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.1.tgz#dd379e94f0db8310b08291f9d64c3209766617fd" - integrity sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ== - async-retry@1.2.3: version "1.2.3" resolved "https://registry.yarnpkg.com/async-retry/-/async-retry-1.2.3.tgz#a6521f338358d322b1a0012b79030c6f411d1ce0" @@ -1833,9 +1843,9 @@ balanced-match@^1.0.0: integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= base64-js@^1.0.2, base64-js@^1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.3.1.tgz#58ece8cb75dd07e71ed08c736abc5fac4dbf8df1" - integrity sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g== + version "1.5.1" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" + integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== bcrypt-pbkdf@^1.0.0: version "1.0.2" @@ -1844,25 +1854,15 @@ bcrypt-pbkdf@^1.0.0: dependencies: tweetnacl "^0.14.3" -bfj@^6.1.1: - version "6.1.2" - resolved "https://registry.yarnpkg.com/bfj/-/bfj-6.1.2.tgz#325c861a822bcb358a41c78a33b8e6e2086dde7f" - integrity sha512-BmBJa4Lip6BPRINSZ0BPEIfB1wUY/9rwbwvIHQA1KjX9om29B6id0wnWXq7m3bn5JrUVjeOTnVuhPT1FiHwPGw== - dependencies: - bluebird "^3.5.5" - check-types "^8.0.3" - hoopy "^0.1.4" - tryer "^1.0.1" - big.js@^5.2.2: version "5.2.2" resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328" integrity sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ== binary-extensions@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.1.0.tgz#30fa40c9e7fe07dbc895678cd287024dea241dd9" - integrity sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ== + version "2.2.0" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" + integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== bl@^4.0.3: version "4.0.3" @@ -1873,7 +1873,7 @@ bl@^4.0.3: inherits "^2.0.4" readable-stream "^3.4.0" -bluebird@^3.5.5, bluebird@^3.7.2: +bluebird@^3.7.2: version "3.7.2" resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== @@ -1883,27 +1883,11 @@ bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.4.0: resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.9.tgz#26d556829458f9d1e81fc48952493d0ba3507828" integrity sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw== -bn.js@^5.1.1: +bn.js@^5.0.0, bn.js@^5.1.1: version "5.1.3" resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.1.3.tgz#beca005408f642ebebea80b042b4d18d2ac0ee6b" integrity sha512-GkTiFpjFtUzU9CbMeJ5iazkCzGL3jrhzerzZIuqLABjbwRaFt33I9tUdSNryIptM+RxDet6OKm2WnLXzW51KsQ== -body-parser@1.19.0: - version "1.19.0" - resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.19.0.tgz#96b2709e57c9c4e09a6fd66a8fd979844f69f08a" - integrity sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw== - dependencies: - bytes "3.1.0" - content-type "~1.0.4" - debug "2.6.9" - depd "~1.1.2" - http-errors "1.7.2" - iconv-lite "0.4.24" - on-finished "~2.3.0" - qs "6.7.0" - raw-body "2.4.0" - type-is "~1.6.17" - body-scroll-lock@^3.1.5: version "3.1.5" resolved "https://registry.yarnpkg.com/body-scroll-lock/-/body-scroll-lock-3.1.5.tgz#c1392d9217ed2c3e237fee1e910f6cdd80b7aaec" @@ -1966,11 +1950,11 @@ browserify-des@^1.0.0: safe-buffer "^5.1.2" browserify-rsa@^4.0.0, browserify-rsa@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/browserify-rsa/-/browserify-rsa-4.0.1.tgz#21e0abfaf6f2029cf2fafb133567a701d4135524" - integrity sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ= + version "4.1.0" + resolved "https://registry.yarnpkg.com/browserify-rsa/-/browserify-rsa-4.1.0.tgz#b2fd06b5b75ae297f7ce2dc651f918f5be158c8d" + integrity sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog== dependencies: - bn.js "^4.1.0" + bn.js "^5.0.0" randombytes "^2.0.1" browserify-sign@^4.0.0: @@ -1999,14 +1983,15 @@ browserslist@4.14.6: node-releases "^1.1.65" browserslist@^4.12.0, browserslist@^4.14.5, browserslist@^4.6.4: - version "4.14.5" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.14.5.tgz#1c751461a102ddc60e40993639b709be7f2c4015" - integrity sha512-Z+vsCZIvCBvqLoYkBFTwEYH3v5MCQbsAjp50ERycpOjnPmolg1Gjy4+KaWWpm8QOJt9GHkhdqAl14NpCX73CWA== + version "4.16.1" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.16.1.tgz#bf757a2da376b3447b800a16f0f1c96358138766" + integrity sha512-UXhDrwqsNcpTYJBTZsbGATDxZbiVDsx6UjpmRUmtnP10pr8wAYr5LgFoEFw9ixriQH2mv/NX2SfGzE/o8GndLA== dependencies: - caniuse-lite "^1.0.30001135" - electron-to-chromium "^1.3.571" - escalade "^3.1.0" - node-releases "^1.1.61" + caniuse-lite "^1.0.30001173" + colorette "^1.2.1" + electron-to-chromium "^1.3.634" + escalade "^3.1.1" + node-releases "^1.1.69" bser@2.1.1: version "2.1.1" @@ -2038,15 +2023,7 @@ buffer@5.6.0: base64-js "^1.0.2" ieee754 "^1.1.4" -buffer@^5.5.0: - version "5.6.1" - resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.6.1.tgz#b99419405f4290a7a1f20b51037cee9f1fbd7f6a" - integrity sha512-2z15UUHpS9/3tk9mY/q+Rl3rydOi7yMp5XWNQnRvoz+mJwiv8brqYwp9a+nOCtma6dwuEIxljD8W3ysVBZ05Vg== - dependencies: - base64-js "^1.3.1" - ieee754 "^1.1.13" - -buffer@^5.7.0: +buffer@^5.5.0, buffer@^5.7.0: version "5.7.1" resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0" integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ== @@ -2060,9 +2037,9 @@ bunyan-prettystream@^0.1.3: integrity sha1-bDtxMmb2rTIAfHtqsemYokU0nZg= bunyan@^1.8.14: - version "1.8.14" - resolved "https://registry.yarnpkg.com/bunyan/-/bunyan-1.8.14.tgz#3d8c1afea7de158a5238c7cb8a66ab6b38dd45b4" - integrity sha512-LlahJUxXzZLuw/hetUQJmRgZ1LF6+cr5TPpRj6jf327AsiIq2jhYEH4oqUUkVKTor+9w2BT3oxVwhzE5lw9tcg== + version "1.8.15" + resolved "https://registry.yarnpkg.com/bunyan/-/bunyan-1.8.15.tgz#8ce34ca908a17d0776576ca1b2f6cbd916e93b46" + integrity sha512-0tECWShh6wUysgucJcBAoYegf3JJoZWibxdqhTm7OHPeT42qdjkZ29QCMcKwbgU1kiH+auSIasNRXMLWXafXig== optionalDependencies: dtrace-provider "~0.8" moment "^2.19.3" @@ -2095,12 +2072,12 @@ cacheable-request@^6.0.0: responselike "^1.0.2" call-bind@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.0.tgz#24127054bb3f9bdcb4b1fb82418186072f77b8ce" - integrity sha512-AEXsYIyyDY3MCzbwdhzG3Jx1R0J2wetQyUynn6dYHAO+bg8l1k7jwZtRv4ryryFs7EP+NDlikJlVe59jr0cM2w== + version "1.0.1" + resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.1.tgz#29aca9151f8ddcfd5b9b786898f005f425e88567" + integrity sha512-tvAvUwNcRikl3RVF20X9lsYmmepsovzTWeJiXjO0PkJp15uy/6xKFZOQtuiSULwYW+6ToZBprphCgWXC2dSgcQ== dependencies: function-bind "^1.1.1" - get-intrinsic "^1.0.0" + get-intrinsic "^1.0.2" callsites@^3.0.0: version "3.1.0" @@ -2143,19 +2120,14 @@ camelcase@5.3.1, camelcase@^5.0.0, camelcase@^5.3.1: integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== camelcase@^6.0.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.1.0.tgz#27dc176173725fb0adf8a48b647f4d7871944d78" - integrity sha512-WCMml9ivU60+8rEJgELlFp1gxFcEGxwYleE3bziHEDeqsqAWGHdimB7beBFGjLzVNgPGyDsfgXLQEYMpmIFnVQ== + version "6.2.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.2.0.tgz#924af881c9d525ac9d87f40d964e5cea982a1809" + integrity sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg== -caniuse-lite@^1.0.30000981, caniuse-lite@^1.0.30001093, caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001113, caniuse-lite@^1.0.30001135: - version "1.0.30001151" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001151.tgz#1ddfde5e6fff02aad7940b4edb7d3ac76b0cb00b" - integrity sha512-Zh3sHqskX6mHNrqUerh+fkf0N72cMxrmflzje/JyVImfpknscMnkeJrlFGJcqTmaa0iszdYptGpWMJCRQDkBVw== - -caniuse-lite@^1.0.30001154: - version "1.0.30001161" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001161.tgz#64f7ffe79ee780b8c92843ff34feb36cea4651e0" - integrity sha512-JharrCDxOqPLBULF9/SPa6yMcBRTjZARJ6sc3cuKrPfyIk64JN6kuMINWqA99Xc8uElMFcROliwtz0n9pYej+g== +caniuse-lite@^1.0.30000981, caniuse-lite@^1.0.30001093, caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001113, caniuse-lite@^1.0.30001154, caniuse-lite@^1.0.30001173: + version "1.0.30001174" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001174.tgz#0f2aca2153fd88ceb07a2bb982fc2acb787623c4" + integrity sha512-tqClL/4ThQq6cfFXH3oJL4rifFBeM6gTkphjao5kgwMaW9yn0tKgQLAEfKzDwj6HQWCB/aWo8kTFlSvIN8geEA== caseless@~0.12.0: version "0.12.0" @@ -2203,12 +2175,7 @@ chardet@^0.7.0: resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA== -check-types@^8.0.3: - version "8.0.3" - resolved "https://registry.yarnpkg.com/check-types/-/check-types-8.0.3.tgz#3356cca19c889544f2d7a95ed49ce508a0ecf552" - integrity sha512-YpeKZngUmG65rLudJ4taU7VLkOCTMhNl/u4ctNC56LQS/zJTyNH0Lrtwm1tfTsbLlwvlfsA2d1c8vCf/Kh2KwQ== - -chokidar@3.4.3, chokidar@^3.4.3: +chokidar@3.4.3: version "3.4.3" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.4.3.tgz#c1df38231448e45ca4ac588e6c79573ba6a57d5b" integrity sha512-DtM3g7juCXQxFVSNPNByEC2+NImtBuxQQvWlHunpJIS5Ocr0lG306cC7FCi7cEA0fzmybPUIl4txBIobk1gGOQ== @@ -2223,6 +2190,21 @@ chokidar@3.4.3, chokidar@^3.4.3: optionalDependencies: fsevents "~2.1.2" +chokidar@^3.4.3: + version "3.5.0" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.0.tgz#458a4816a415e9d3b3caa4faec2b96a6935a9e65" + integrity sha512-JgQM9JS92ZbFR4P90EvmzNpSGhpPBGBSj10PILeDyYFwp4h2/D9OM03wsJ4zW1fEp4ka2DGrnUeD7FuvQ2aZ2Q== + dependencies: + anymatch "~3.1.1" + braces "~3.0.2" + glob-parent "~5.1.0" + is-binary-path "~2.1.0" + is-glob "~4.0.1" + normalize-path "~3.0.0" + readdirp "~3.5.0" + optionalDependencies: + fsevents "~2.3.1" + chownr@^1.1.1: version "1.1.4" resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b" @@ -2262,7 +2244,7 @@ cli-cursor@^3.1.0: dependencies: restore-cursor "^3.1.0" -cli-spinners@^2.4.0: +cli-spinners@^2.5.0: version "2.5.0" resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.5.0.tgz#12763e47251bf951cb75c201dfa58ff1bcb2d047" integrity sha512-PC+AmIuK04E6aeSs/pUccSujsTzBhu4HzC2dL+CfJB/Jcc2qTRbEwZQDfIUpt2Xl8BodYBEq8w4fc0kU2I9DjQ== @@ -2367,7 +2349,7 @@ combined-stream@^1.0.6, combined-stream@^1.0.8, combined-stream@~1.0.6: dependencies: delayed-stream "~1.0.0" -commander@^2.13.0, commander@^2.16.0, commander@^2.18.0, commander@^2.20.0, commander@^2.20.3, commander@^2.8.1: +commander@^2.13.0, commander@^2.16.0, commander@^2.20.0, commander@^2.20.3, commander@^2.8.1: version "2.20.3" resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== @@ -2377,6 +2359,11 @@ commander@^5.0.0, commander@^5.1.0: resolved "https://registry.yarnpkg.com/commander/-/commander-5.1.0.tgz#46abbd1652f8e059bddaef99bbdcb2ad9cf179ae" integrity sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg== +commander@^6.2.0: + version "6.2.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-6.2.1.tgz#0792eb682dfbc325999bb2b84fddddba110ac73c" + integrity sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA== + common-tags@1.8.0, common-tags@^1.8.0: version "1.8.0" resolved "https://registry.yarnpkg.com/common-tags/-/common-tags-1.8.0.tgz#8e3153e542d4a39e9b10554434afaaf98956a937" @@ -2404,6 +2391,13 @@ console-control-strings@^1.0.0, console-control-strings@~1.1.0: resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" integrity sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4= +consolidate@^0.16.0: + version "0.16.0" + resolved "https://registry.yarnpkg.com/consolidate/-/consolidate-0.16.0.tgz#a11864768930f2f19431660a65906668f5fbdc16" + integrity sha512-Nhl1wzCslqXYTJVDyJCu3ODohy9OfBMB5uD2BiBTzd7w+QY0lBzafkR8y8755yMYHAaMD4NuzbAw03/xzfw+eQ== + dependencies: + bluebird "^3.7.2" + constant-case@3.0.3: version "3.0.3" resolved "https://registry.yarnpkg.com/constant-case/-/constant-case-3.0.3.tgz#ac910a99caf3926ac5112f352e3af599d8c5fc0a" @@ -2422,18 +2416,6 @@ constant-case@^3.0.3: tslib "^2.0.3" upper-case "^2.0.2" -content-disposition@0.5.3: - version "0.5.3" - resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.3.tgz#e130caf7e7279087c5616c2007d0485698984fbd" - integrity sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g== - dependencies: - safe-buffer "5.1.2" - -content-type@~1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" - integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA== - convert-source-map@1.7.0, convert-source-map@^1.7.0: version "1.7.0" resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.7.0.tgz#17a2cb882d7f77d3490585e2ce6c524424a3a442" @@ -2446,16 +2428,6 @@ convert-source-map@^0.3.3: resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-0.3.5.tgz#f1d802950af7dd2631a1febe0596550c86ab3190" integrity sha1-8dgClQr33SYxof6+BZZVDIarMZA= -cookie-signature@1.0.6: - version "1.0.6" - resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" - integrity sha1-4wOogrNCzD7oylE6eZmXNNqzriw= - -cookie@0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.0.tgz#beb437e7022b3b6d49019d088665303ebe9c14ba" - integrity sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg== - cookie@^0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.1.tgz#afd713fe26ebd21ba95ceb61f9a8116e50a537d1" @@ -2647,9 +2619,9 @@ cssnano-simple@1.2.1: postcss "^7.0.32" csstype@^3.0.2: - version "3.0.4" - resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.0.4.tgz#b156d7be03b84ff425c9a0a4b1e5f4da9c5ca888" - integrity sha512-xc8DUsCLmjvCfoD7LTGE0ou2MIWLx0K9RCZwSHMOdynqRsP4MtUcLeqh1HcQ2dInwDTqn+3CE0/FZh1et+p4jA== + version "3.0.6" + resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.0.6.tgz#865d0b5833d7d8d40f4e5b8a6d76aea3de4725ef" + integrity sha512-+ZAmfyWMT7TiIlzdqJgjMb7S4f1beorDbWbsocyK4RaiqA5RTX3K14bnBWmmA9QEM0gRdsjyyrEmcyga8Zsxmw== d@1, d@^1.0.1: version "1.0.1" @@ -2681,23 +2653,11 @@ date-fns@^1.27.2: resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-1.30.1.tgz#2e71bf0b119153dbb4cc4e88d9ea5acfb50dc05c" integrity sha512-hBSVCvSmWC+QypYObzwGOd9wqdDpOt+0wl0KbU+R+uuZBS1jN8VsD1ss3irQDknRj5NvxiTF6oj/nDRnN/UQNw== -de-indent@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/de-indent/-/de-indent-1.0.2.tgz#b2038e846dc33baa5796128d0804b455b8c1e21d" - integrity sha1-sgOOhG3DO6pXlhKNCAS0VbjB4h0= - debounce@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/debounce/-/debounce-1.2.0.tgz#44a540abc0ea9943018dc0eaa95cce87f65cd131" integrity sha512-mYtLl1xfZLi1m4RtQYlZgJUNQjl4ZxVnHzIR8nLLgi4q1YT8o/WM+MK/f8yfcc9s5Ir5zRaPZyZU6xs1Syoocg== -debug@2.6.9: - version "2.6.9" - resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" - integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== - dependencies: - ms "2.0.0" - debug@3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" @@ -2705,33 +2665,19 @@ debug@3.1.0: dependencies: ms "2.0.0" -debug@4, debug@^4.0.0, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1: - version "4.2.0" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.2.0.tgz#7f150f93920e94c58f5574c2fd01a3110effe7f1" - integrity sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg== - dependencies: - ms "2.1.2" - -debug@^3.1.0: - version "3.2.6" - resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" - integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ== - dependencies: - ms "^2.1.1" - -debug@^4.2.0: +debug@4, debug@^4.0.0, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.2.0, debug@^4.2.1: version "4.3.1" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.1.tgz#f0d229c505e0c6d8c49ac553d1b13dc183f6b2ee" integrity sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ== dependencies: ms "2.1.2" -debug@^4.2.1: - version "4.3.0" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.0.tgz#efa41cbf14fc9448075367fdaaddf82376da211e" - integrity sha512-jjO6JD2rKfiZQnBoRzhRTbXjHLGLfH+UtGkWLc/UXAh/rzZMyjbgn0NcfFpqT8nd1kTtFnDiJcrIFkq4UKeJVg== +debug@^3.1.0: + version "3.2.7" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" + integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== dependencies: - ms "2.1.2" + ms "^2.1.1" decamelize-keys@^1.1.0: version "1.1.0" @@ -2857,11 +2803,6 @@ des.js@^1.0.0: inherits "^2.0.1" minimalistic-assert "^1.0.0" -destroy@~1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" - integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA= - detect-indent@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-6.0.0.tgz#0abd0f549f69fc6659a254fe96786186b6f528fd" @@ -2986,7 +2927,7 @@ dir-glob@^3.0.1: dependencies: path-type "^4.0.0" -dom-serializer@1.1.0, dom-serializer@^1.0.1: +dom-serializer@1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-1.1.0.tgz#5f7c828f1bfc44887dc2a315ab5c45691d544b58" integrity sha512-ox7bvGXt2n+uLWtCRLybYx60IrOlWL/aCebWJk1T0d4m3y2tzf4U3ij9wBMUb6YJZpz06HCCYuyCDveE2xXmzQ== @@ -2995,12 +2936,16 @@ dom-serializer@1.1.0, dom-serializer@^1.0.1: domhandler "^3.0.0" entities "^2.0.0" -domelementtype@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.0.2.tgz#f3b6e549201e46f588b59463dd77187131fe6971" - integrity sha512-wFwTwCVebUrMgGeAwRL/NhZtHAUyT9n9yg4IMDwf10+6iCMxSkVq9MGCVEH+QZWo1nNidy8kNvwmv4zWHDTqvA== +dom-serializer@^1.0.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-1.2.0.tgz#3433d9136aeb3c627981daa385fc7f32d27c48f1" + integrity sha512-n6kZFH/KlCrqs/1GHMOd5i2fd/beQHuehKdWvNNffbGHTr/almdhuVvTVFb3V7fglz+nC50fFusu3lY33h12pA== + dependencies: + domelementtype "^2.0.1" + domhandler "^4.0.0" + entities "^2.0.0" -domelementtype@^2.1.0: +domelementtype@^2.0.1, domelementtype@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.1.0.tgz#a851c080a6d1c3d94344aed151d99f669edf585e" integrity sha512-LsTgx/L5VpD+Q8lmsXSHW2WpA+eBlZ9HPf3erD1IoPF00/3JKHZ3BknUVA2QGDNu69ZNmyFmCWBSO45XjYKC5w== @@ -3062,7 +3007,7 @@ duplexer3@^0.1.4: resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2" integrity sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI= -duplexer@^0.1.1: +duplexer@^0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.2.tgz#3abe43aef3835f8ae077d136ddce0f276b0400e6" integrity sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg== @@ -3082,25 +3027,10 @@ ecdsa-sig-formatter@1.0.11: dependencies: safe-buffer "^5.0.1" -ee-first@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" - integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= - -ejs@^2.6.1: - version "2.7.4" - resolved "https://registry.yarnpkg.com/ejs/-/ejs-2.7.4.tgz#48661287573dcc53e366c7a1ae52c3a120eec9ba" - integrity sha512-7vmuyh5+kuUyJKePhQfRQBhXV5Ce+RnaeeQArKu1EAMpL3WbgMt5WG6uQZpEVvYSSsxMXRKOewtDk9RaTKXRlA== - -electron-to-chromium@^1.3.571: - version "1.3.583" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.583.tgz#47a9fde74740b1205dba96db2e433132964ba3ee" - integrity sha512-L9BwLwJohjZW9mQESI79HRzhicPk1DFgM+8hOCfGgGCFEcA3Otpv7QK6SGtYoZvfQfE3wKLh0Hd5ptqUFv3gvQ== - -electron-to-chromium@^1.3.585: - version "1.3.607" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.607.tgz#1bff13f1cf89f2fee0d244b8c64a7138f80f3a3b" - integrity sha512-h2SYNaBnlplGS0YyXl8oJWokfcNxVjJANQfMCsQefG6OSuAuNIeW+A8yGT/ci+xRoBb3k2zq1FrOvkgoKBol8g== +electron-to-chromium@^1.3.585, electron-to-chromium@^1.3.634: + version "1.3.635" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.635.tgz#8d1591eeca6b257d380061a2c04f0b3cc6c9e33b" + integrity sha512-RRriZOLs9CpW6KTLmgBqyUdnY0QNqqWs0HOtuQGGEMizOTNNn1P7sGRBxARnUeLejOsgwjDyRqT3E/CSst02ZQ== elegant-spinner@^1.0.1: version "1.0.1" @@ -3140,11 +3070,6 @@ emojis-list@^3.0.0: resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-3.0.0.tgz#5570662046ad29e2e916e71aae260abdff4f6a78" integrity sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q== -encodeurl@~1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" - integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= - end-of-stream@^1.1.0, end-of-stream@^1.4.1: version "1.4.4" resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" @@ -3153,18 +3078,18 @@ end-of-stream@^1.1.0, end-of-stream@^1.4.1: once "^1.4.0" enhanced-resolve@^4.0.0, enhanced-resolve@^4.1.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-4.3.0.tgz#3b806f3bfafc1ec7de69551ef93cca46c1704126" - integrity sha512-3e87LvavsdxyoCfGusJnrZ5G8SLPOFeHSNpZI/ATL9a5leXo2k0w6MKnbqhdBad9qTobSfB20Ld7UmgoNbAZkQ== + version "4.5.0" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-4.5.0.tgz#2f3cfd84dbe3b487f18f2db2ef1e064a571ca5ec" + integrity sha512-Nv9m36S/vxpsI+Hc4/ZGRs0n9mXqSWGGq49zxb/cJfPAQMbUtttJAlNPS4AQzaBdw/pKskw5bMbekT/Y7W/Wlg== dependencies: graceful-fs "^4.1.2" memory-fs "^0.5.0" tapable "^1.0.0" enhanced-resolve@^5.3.1: - version "5.4.1" - resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.4.1.tgz#c89b0c34f17f931902ef2913a125d4b825b49b6f" - integrity sha512-4GbyIMzYktTFoRSmkbgZ1LU+RXwf4AQ8Z+rSuuh1dC8plp0PPeaWvx6+G4hh4KnUJ48VoxKbNyA1QQQIUpXjYA== + version "5.5.0" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.5.0.tgz#5f2ca7d511076541e2a30dc364a40c4f6c027bcd" + integrity sha512-b4a6BasBCoLzri4MdaeOlDMpls2oioI28CF17csMiav9dq46yvQaKPFNUrCHB6VqQokBDG2VIEEL81jMiQ6Wtw== dependencies: graceful-fs "^4.2.4" tapable "^2.2.0" @@ -3175,9 +3100,9 @@ entities@^2.0.0: integrity sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w== errno@^0.1.3: - version "0.1.7" - resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.7.tgz#4684d71779ad39af177e3f007996f7c67c852618" - integrity sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg== + version "0.1.8" + resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.8.tgz#8bb3e9c7d463be4976ff888f76b4809ebc2e811f" + integrity sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A== dependencies: prr "~1.0.1" @@ -3241,16 +3166,11 @@ es6-symbol@^3.1.1, es6-symbol@~3.1.3: d "^1.0.1" ext "^1.1.2" -escalade@^3.1.0, escalade@^3.1.1: +escalade@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== -escape-html@~1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" - integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg= - escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" @@ -3303,12 +3223,17 @@ estraverse@^5.2.0: resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.2.0.tgz#307df42547e6cc7324d3cf03c155d5cdb8c53880" integrity sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ== +estree-walker@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-2.0.2.tgz#52f010178c2a4c117a7757cfe942adb7d2da4cac" + integrity sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w== + esutils@^2.0.2: version "2.0.3" resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== -etag@1.8.1, etag@~1.8.1: +etag@1.8.1: version "1.8.1" resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc= @@ -3343,42 +3268,6 @@ expand-template@^2.0.3: resolved "https://registry.yarnpkg.com/expand-template/-/expand-template-2.0.3.tgz#6e14b3fcee0f3a6340ecb57d2e8918692052a47c" integrity sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg== -express@^4.16.3: - version "4.17.1" - resolved "https://registry.yarnpkg.com/express/-/express-4.17.1.tgz#4491fc38605cf51f8629d39c2b5d026f98a4c134" - integrity sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g== - dependencies: - accepts "~1.3.7" - array-flatten "1.1.1" - body-parser "1.19.0" - content-disposition "0.5.3" - content-type "~1.0.4" - cookie "0.4.0" - cookie-signature "1.0.6" - debug "2.6.9" - depd "~1.1.2" - encodeurl "~1.0.2" - escape-html "~1.0.3" - etag "~1.8.1" - finalhandler "~1.1.2" - fresh "0.5.2" - merge-descriptors "1.0.1" - methods "~1.1.2" - on-finished "~2.3.0" - parseurl "~1.3.3" - path-to-regexp "0.1.7" - proxy-addr "~2.0.5" - qs "6.7.0" - range-parser "~1.2.1" - safe-buffer "5.1.2" - send "0.17.1" - serve-static "1.14.1" - setprototypeof "1.1.1" - statuses "~1.5.0" - type-is "~1.6.18" - utils-merge "1.0.1" - vary "~1.1.2" - ext@^1.1.2: version "1.4.0" resolved "https://registry.yarnpkg.com/ext/-/ext-1.4.0.tgz#89ae7a07158f79d35517882904324077e4379244" @@ -3501,11 +3390,6 @@ file-exists-dazinatorfork@^1.0.2: resolved "https://registry.yarnpkg.com/file-exists-dazinatorfork/-/file-exists-dazinatorfork-1.0.2.tgz#cd8d0d85f63e39dc81eceb0b687c44a2cca95c47" integrity sha512-r70c72ln2YHzQINNfxDp02hAhbGkt1HffZ+Du8oetWDLjDtFja/Lm10lUaSh9e+wD+7VDvPee0b0C9SAy8pWZg== -filesize@^3.6.1: - version "3.6.1" - resolved "https://registry.yarnpkg.com/filesize/-/filesize-3.6.1.tgz#090bb3ee01b6f801a8a8be99d31710b3422bb317" - integrity sha512-7KjR1vv6qnicaPMi1iiTcI85CyYwRO/PSFCu6SvqL8jN2Wjt/NIYQTFtFs7fSDCYOstUkEWIQGFUg5YZQfjlcg== - filing-cabinet@^2.6.0: version "2.6.0" resolved "https://registry.yarnpkg.com/filing-cabinet/-/filing-cabinet-2.6.0.tgz#3d4d5093a98b6fae84cf282e8bded1b8ad5f9c0c" @@ -3532,19 +3416,6 @@ fill-range@^7.0.1: dependencies: to-regex-range "^5.0.1" -finalhandler@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.2.tgz#b7e7d000ffd11938d0fdb053506f6ebabe9f587d" - integrity sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA== - dependencies: - debug "2.6.9" - encodeurl "~1.0.2" - escape-html "~1.0.3" - on-finished "~2.3.0" - parseurl "~1.3.3" - statuses "~1.5.0" - unpipe "~1.0.0" - find-cache-dir@3.3.1: version "3.3.1" resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-3.3.1.tgz#89b33fad4a4670daa94f855f7fbe31d6d84fe880" @@ -3614,16 +3485,6 @@ form-data@~2.3.2: combined-stream "^1.0.6" mime-types "^2.1.12" -forwarded@~0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84" - integrity sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ= - -fresh@0.5.2: - version "0.5.2" - resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" - integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac= - fs-capacitor@^6.1.0: version "6.2.0" resolved "https://registry.yarnpkg.com/fs-capacitor/-/fs-capacitor-6.2.0.tgz#fa79ac6576629163cb84561995602d8999afb7f5" @@ -3653,6 +3514,11 @@ fsevents@~2.1.2: resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.1.3.tgz#fb738703ae8d2f9fe900c33836ddebee8b97f23e" integrity sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ== +fsevents@~2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.1.tgz#b209ab14c61012636c8863507edf7fb68cc54e9f" + integrity sha512-YR47Eg4hChJGAB1O3yEAOkGO+rlzutoICGqGo9EZ4lKWokzZRSyIW1QmTzqjtw8MJdj9srP869CuWw/hyzSiBw== + function-bind@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" @@ -3672,6 +3538,13 @@ gauge@~2.7.3: strip-ansi "^3.0.1" wide-align "^1.1.0" +generic-names@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/generic-names/-/generic-names-2.0.1.tgz#f8a378ead2ccaa7a34f0317b05554832ae41b872" + integrity sha512-kPCHWa1m9wGG/OwQpeweTwM/PYiQLrUIxXbt/P4Nic3LbGjCP0YwrALHW1uNLKZ0LIMg+RF+XRlj2ekT9ZlZAQ== + dependencies: + loader-utils "^1.1.0" + gensync@^1.0.0-beta.1: version "1.0.0-beta.2" resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" @@ -3690,7 +3563,7 @@ get-caller-file@^2.0.1, get-caller-file@^2.0.5: resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== -get-intrinsic@^1.0.0: +get-intrinsic@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.0.2.tgz#6820da226e50b24894e08859469dc68361545d49" integrity sha512-aeX0vrFm21ILl3+JpFFRNe9aUvp6VFZb2/CTbgLb8j75kOhvoNYjt9d8KA/tJG4gSo8nzEDedRl0h7vDmBYRVg== @@ -3871,13 +3744,12 @@ graphviz@0.0.9: dependencies: temp "~0.4.0" -gzip-size@^5.0.0: - version "5.1.1" - resolved "https://registry.yarnpkg.com/gzip-size/-/gzip-size-5.1.1.tgz#cb9bee692f87c0612b232840a873904e4c135274" - integrity sha512-FNHi6mmoHvs1mxZAds4PpdCS6QG8B4C1krxJsMutgxl5t3+GlRTzzI3NEkifXx2pVsOvJdOGSmIgDhQ55FwdPA== +gzip-size@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/gzip-size/-/gzip-size-6.0.0.tgz#065367fd50c239c0671cbcbad5be3e2eeb10e462" + integrity sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q== dependencies: - duplexer "^0.1.1" - pify "^4.0.1" + duplexer "^0.1.2" har-schema@^2.0.0: version "2.0.0" @@ -3940,6 +3812,11 @@ hash-base@^3.0.0: readable-stream "^3.6.0" safe-buffer "^5.2.0" +hash-sum@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/hash-sum/-/hash-sum-2.0.0.tgz#81d01bb5de8ea4a214ad5d6ead1b523460b0b45a" + integrity sha512-WdZTbAByD+pHfl/g9QSsBIIwy8IT+EsPiKDs0KNX+zSHhdDLFKdZu0BQHljvO+0QI/BasbMSUa8wYNCZTvhslg== + hash.js@^1.0.0, hash.js@^1.0.3: version "1.1.7" resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.7.tgz#0babca538e8d4ee4a0f8988d68866537a003cf42" @@ -3948,7 +3825,7 @@ hash.js@^1.0.0, hash.js@^1.0.3: inherits "^2.0.3" minimalistic-assert "^1.0.1" -he@1.2.0, he@^1.1.0: +he@1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== @@ -3967,11 +3844,6 @@ hmac-drbg@^1.0.0: minimalistic-assert "^1.0.0" minimalistic-crypto-utils "^1.0.1" -hoopy@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/hoopy/-/hoopy-0.1.4.tgz#609207d661100033a9a9402ad3dea677381c1b1d" - integrity sha512-HRcs+2mr52W0K+x8RzcLzuPPmVIKMSv97RGHy0Ea9y/mpcaK+xTrjICA04KAHi4GRzxliNqNJEFYWHghy3rSfQ== - hosted-git-info@^2.1.4: version "2.8.8" resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.8.tgz#7539bd4bc1e0e0a895815a2e0262420b12858488" @@ -3997,18 +3869,7 @@ http-cache-semantics@^4.0.0: resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz#49e91c5cbf36c9b94bcfcd71c23d5249ec74e390" integrity sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ== -http-errors@1.7.2: - version "1.7.2" - resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.2.tgz#4f5029cf13239f31036e5b2e55292bcfbcc85c8f" - integrity sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg== - dependencies: - depd "~1.1.2" - inherits "2.0.3" - setprototypeof "1.1.1" - statuses ">= 1.5.0 < 2" - toidentifier "1.0.0" - -http-errors@1.7.3, http-errors@~1.7.2: +http-errors@1.7.3: version "1.7.3" resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.3.tgz#6c619e4f9c60308c38519498c14fbb10aacebb06" integrity sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw== @@ -4070,6 +3931,11 @@ iconv-lite@0.4.24, iconv-lite@^0.4.24: dependencies: safer-buffer ">= 2.1.2 < 3" +icss-replace-symbols@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/icss-replace-symbols/-/icss-replace-symbols-1.1.0.tgz#06ea6f83679a7749e386cfe1fe812ae5db223ded" + integrity sha1-Bupvg2ead0njhs/h/oEq5dsiPe0= + icss-utils@^4.0.0, icss-utils@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/icss-utils/-/icss-utils-4.1.1.tgz#21170b53789ee27447c2f47dd683081403f9a467" @@ -4078,9 +3944,9 @@ icss-utils@^4.0.0, icss-utils@^4.1.1: postcss "^7.0.14" ieee754@^1.1.13, ieee754@^1.1.4: - version "1.1.13" - resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.13.tgz#ec168558e95aa181fd87d37f55c32bbcb6708b84" - integrity sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg== + version "1.2.1" + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" + integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== ignore@^5.1.4: version "5.1.8" @@ -4135,11 +4001,6 @@ inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, i resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== -inherits@2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" - integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= - ini@~1.3.0: version "1.3.8" resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c" @@ -4164,11 +4025,6 @@ inquirer@^7.3.3: strip-ansi "^6.0.0" through "^2.3.6" -ipaddr.js@1.9.1: - version "1.9.1" - resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" - integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== - is-absolute@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-absolute/-/is-absolute-1.0.0.tgz#395e1ae84b11f26ad1795e73c17378e48a301576" @@ -4199,13 +4055,6 @@ is-callable@^1.1.4, is-callable@^1.2.2: resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.2.tgz#c7c6715cd22d4ddb48d3e19970223aceabb080d9" integrity sha512-dnMqspv5nU3LoewK2N/y7KLtxtakvTuaCsU9FU50/QDmdbHNy/4/JuRtMHqRU22o3q+W89YQndQEeCVwK+3qrA== -is-core-module@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.0.0.tgz#58531b70aed1db7c0e8d4eb1a0a2d1ddd64bd12d" - integrity sha512-jq1AH6C8MuteOoBPwkxHafmByhL9j5q4OaPGdbuD+ZtQJVzH+i6E3BJDQcBA09k57i2Hh2yQbEG8yObZ0jdlWw== - dependencies: - has "^1.0.3" - is-core-module@^2.1.0: version "2.2.0" resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.2.0.tgz#97037ef3d52224d85163f5597b2b63d9afed981a" @@ -4397,10 +4246,10 @@ jest-worker@24.9.0: merge-stream "^2.0.0" supports-color "^6.1.0" -jest-worker@^26.6.1: - version "26.6.1" - resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-26.6.1.tgz#c2ae8cde6802cc14056043f997469ec170d9c32a" - integrity sha512-R5IE3qSGz+QynJx8y+ICEkdI2OJ3RJjRQVEyCcFAd3yVhQSEtquziPO29Mlzgn07LOVE8u8jhJ1FqcwegiXWOw== +jest-worker@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-26.6.2.tgz#7f72cbc4d643c365e27b9fd775f9d0eaa9c7a8ed" + integrity sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ== dependencies: "@types/node" "*" merge-stream "^2.0.0" @@ -4549,9 +4398,9 @@ jws@^3.2.2: safe-buffer "^5.0.1" keen-slider@^5.2.4: - version "5.2.4" - resolved "https://registry.yarnpkg.com/keen-slider/-/keen-slider-5.2.4.tgz#9e2a889c63c02a651c81caa438f3691e9a3bc0a8" - integrity sha512-z39afyASW63B+1FzWGzBkvXAnzJl3gAD8M+32TmhJAPJqjckCaKYm7YBjpSba04AoVMQw8y9U1LVcUucVVIQkQ== + version "5.3.5" + resolved "https://registry.yarnpkg.com/keen-slider/-/keen-slider-5.3.5.tgz#29ac24fd7dbf1f1435bd448e0e583cded36b4b91" + integrity sha512-3QYvrFK7HbtkiC98/G+RM44y9WBe9cpHDHtP9bI1J/Vrc54IHLuTjOjyX4E81ukRc5GwiGfijOwStxEhisFnPg== keyv@^3.0.0: version "3.1.0" @@ -4643,9 +4492,9 @@ listr@^0.14.3: rxjs "^6.3.3" loader-runner@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-4.1.0.tgz#f70bc0c29edbabdf2043e7ee73ccc3fe1c96b42d" - integrity sha512-oR4lB4WvwFoC70ocraKhn5nkKSs23t57h9udUgw8o0iH8hMXeEoRuUgfcvgUwAJ1ZpRqBvcou4N2SMvM1DwMrA== + version "4.2.0" + resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-4.2.0.tgz#d7022380d66d14c5fb1d496b89864ebcfd478384" + integrity sha512-92+huvxMvYlMzMt0iIOukcwYBFpkYJdpl2xsZ7LrlayO7E8SOv+JJUEK17B/dJIHAOLMfh2dZZ/Y18WgmGtYNw== loader-utils@1.2.3: version "1.2.3" @@ -4665,7 +4514,7 @@ loader-utils@2.0.0, loader-utils@^2.0.0: emojis-list "^3.0.0" json5 "^2.1.2" -loader-utils@^1.0.2: +loader-utils@^1.0.2, loader-utils@^1.1.0: version "1.4.0" resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.4.0.tgz#c579b5e34cb34b1a74edc6c1fb36bfa371d5a613" integrity sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA== @@ -4693,6 +4542,11 @@ lodash._reinterpolate@^3.0.0: resolved "https://registry.yarnpkg.com/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz#0ccf2d89166af03b3663c796538b75ac6e114d9d" integrity sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0= +lodash.camelcase@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6" + integrity sha1-soqmKIorn8ZRA1x3EfZathkDMaY= + lodash.debounce@^4.0.8: version "4.0.8" resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" @@ -4832,14 +4686,14 @@ lowercase-keys@^2.0.0: resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-2.0.0.tgz#2603e78b7b4b0006cbca2fbcc8a3202558ac9479" integrity sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA== -lru-cache@5.1.1: +lru-cache@5.1.1, lru-cache@^5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w== dependencies: yallist "^3.0.2" -lru-cache@6.0.0: +lru-cache@6.0.0, lru-cache@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== @@ -4874,6 +4728,13 @@ madge@^3.8.0: typescript "^3.9.5" walkdir "^0.4.1" +magic-string@^0.25.7: + version "0.25.7" + resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.25.7.tgz#3f497d6fd34c669c6798dcb821f2ef31f5445051" + integrity sha512-4CrMT5DOHTDk4HYDlzmwu4FVCcIYI8gauveasrdCu2IKIFOJ3f0v/8MDGJCDL9oD2ppz/Av1b0Nj345H9M+XIA== + dependencies: + sourcemap-codec "^1.4.4" + make-dir@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-2.1.0.tgz#5f0310e18b8be898cc07009295a30ae41e91e6f5" @@ -4918,11 +4779,6 @@ md5.js@^1.3.4: inherits "^2.0.1" safe-buffer "^5.1.2" -media-typer@0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" - integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g= - memory-fs@^0.5.0: version "0.5.0" resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.5.0.tgz#324c01288b88652966d161db77838720845a8e3c" @@ -4948,10 +4804,12 @@ meow@^7.0.0: type-fest "^0.13.1" yargs-parser "^18.1.3" -merge-descriptors@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" - integrity sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E= +merge-source-map@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/merge-source-map/-/merge-source-map-1.1.0.tgz#2fdde7e6020939f70906a68f2d7ae685e4c8c646" + integrity sha512-Qkcp7P2ygktpMPh2mCQZaf3jhN6D3Z/qVZHSdWvQ+2Ef5HgRAPBO57A77+ENm0CPx2+1Ce/MYKi3ymqdfuqibw== + dependencies: + source-map "^0.6.1" merge-stream@^2.0.0: version "2.0.0" @@ -4963,11 +4821,6 @@ merge2@^1.3.0: resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== -methods@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" - integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4= - micromatch@^4.0.0, micromatch@^4.0.2: version "4.0.2" resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.2.tgz#4fcb0999bf9fbc2fcbdd212f6d629b9a56c39259" @@ -4984,22 +4837,22 @@ miller-rabin@^4.0.0: bn.js "^4.0.0" brorand "^1.0.1" -mime-db@1.44.0: - version "1.44.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.44.0.tgz#fa11c5eb0aca1334b4233cb4d52f10c5a6272f92" - integrity sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg== +mime-db@1.45.0: + version "1.45.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.45.0.tgz#cceeda21ccd7c3a745eba2decd55d4b73e7879ea" + integrity sha512-CkqLUxUk15hofLoLyljJSrukZi8mAtgd+yE5uO4tqRZsdsAJKv0O+rFMhVDRJgozy+yG6md5KwuXhD4ocIoP+w== -mime-types@^2.1.12, mime-types@^2.1.27, mime-types@~2.1.19, mime-types@~2.1.24: - version "2.1.27" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.27.tgz#47949f98e279ea53119f5722e0f34e529bec009f" - integrity sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w== +mime-types@^2.1.12, mime-types@^2.1.27, mime-types@~2.1.19: + version "2.1.28" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.28.tgz#1160c4757eab2c5363888e005273ecf79d2a0ecd" + integrity sha512-0TO2yJ5YHYr7M2zzT7gDU1tbwHxEUWBCLt0lscSNpcdAfFyJOVEpRYNS7EXVcTLNj/25QO8gulHC5JtTzSE2UQ== dependencies: - mime-db "1.44.0" + mime-db "1.45.0" -mime@1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" - integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== +mime@^2.3.1: + version "2.4.7" + resolved "https://registry.yarnpkg.com/mime/-/mime-2.4.7.tgz#962aed9be0ed19c91fd7dc2ece5d7f4e89a90d74" + integrity sha512-dhNd1uA2u397uQk3Nv5LM4lm93WYDUXFn3Fu291FJerns4jyTudqhIWe4W04YLy7Uk1tm1Ore04NpjRvQp/NPA== mimic-fn@^1.0.0: version "1.2.0" @@ -5072,18 +4925,18 @@ mkdirp-classic@^0.5.2, mkdirp-classic@^0.5.3: resolved "https://registry.yarnpkg.com/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz#fa10c9115cc6d8865be221ba47ee9bed78601113" integrity sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A== -mkdirp@^0.5.1, mkdirp@~0.5.1: +mkdirp@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" + integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== + +mkdirp@~0.5.1: version "0.5.5" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== dependencies: minimist "^1.2.5" -mkdirp@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" - integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== - module-definition@^3.0.0, module-definition@^3.3.0: version "3.3.1" resolved "https://registry.yarnpkg.com/module-definition/-/module-definition-3.3.1.tgz#fedef71667713e36988b93d0626a4fe7b35aebfc" @@ -5114,16 +4967,16 @@ ms@2.0.0: resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= -ms@2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" - integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg== - -ms@2.1.2, ms@^2.0.0, ms@^2.1.1: +ms@2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== +ms@^2.0.0, ms@^2.1.1: + version "2.1.3" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" + integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== + mute-stream@0.0.8: version "0.0.8" resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d" @@ -5144,9 +4997,9 @@ nan@^2.14.0: integrity sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ== nanoid@^3.1.16: - version "3.1.18" - resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.18.tgz#0680db22ab01c372e89209f5d18283d98de3e96d" - integrity sha512-rndlDjbbHbcV3xi+R2fpJ+PbGMdfBxz5v1fATIQFq0DP64FsicQdwnKLy47K4kZHdRpmQXtz24eGsxQqamzYTA== + version "3.1.20" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.20.tgz#badc263c6b1dcf14b71efaa85f6ab4c1d6cfc788" + integrity sha512-a1cQNyczgKbLX9jwbS/+d7W8fX/RfgYR7lVWwWOGIPNgK2m0MWvrGF6/m4kk6U3QcFMnZf3RIhL0v2Jgh/0Uxw== napi-build-utils@^1.0.1: version "1.0.2" @@ -5165,20 +5018,15 @@ ncp@~2.0.0: resolved "https://registry.yarnpkg.com/ncp/-/ncp-2.0.0.tgz#195a21d6c46e361d2fb1281ba38b91e9df7bdbb3" integrity sha1-GVoh1sRuNh0vsSgbo4uR6d9727M= -negotiator@0.6.2: - version "0.6.2" - resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb" - integrity sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw== - neo-async@^2.6.2: version "2.6.2" resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== next-seo@^4.11.0: - version "4.14.0" - resolved "https://registry.yarnpkg.com/next-seo/-/next-seo-4.14.0.tgz#8a3243286f65606da81f6fdb0f8b1673ab5dd5a6" - integrity sha512-HHL82n2bx1Aj0z8kpy31LoJxzWpZwC/RlXleoO5zNNjJjEGtNS7uZ+wrvAbFGUqC4V54I1sZa4f0WZV+mpOx6w== + version "4.17.0" + resolved "https://registry.yarnpkg.com/next-seo/-/next-seo-4.17.0.tgz#fb3dbe0ed7414aa9d83872ef5d8510980a6dae7e" + integrity sha512-/hnb3oq7bhi8s7bup7+Lm6VzzgRucj+JrWtp+dJiYs/04H0N/NhmE9MpepixQ16fFj6G/39JLYxhzsO/QZG/Kw== next-themes@^0.0.4: version "0.0.4" @@ -5199,17 +5047,17 @@ next-unused@^0.0.3: ts-loader "^7.0.0" next@^10.0.5-canary.11: - version "10.0.5-canary.11" - resolved "https://registry.yarnpkg.com/next/-/next-10.0.5-canary.11.tgz#f6c32b451a8fe179f917f19c1b5315501584d47f" - integrity sha512-RryLV/az0m+SyD1plzeRsE8G66gec2wp8jJoyaOUJCUjQdQK6sHgjwJB26KJcJFZskdbtUqbFvr05rw4eY0SAQ== + version "10.0.5" + resolved "https://registry.yarnpkg.com/next/-/next-10.0.5.tgz#8071e0aa1883266c91943aa7c6b73deadb064793" + integrity sha512-yr7ap2TLugf0aMHz+3JoKFP9CCkFE+k6jCfdUymORhptjLYZbD3YGlTcUC1CRl+b5Phlbl7m/WUIPde0VcguiA== dependencies: "@ampproject/toolbox-optimizer" "2.7.1-alpha.0" "@babel/runtime" "7.12.5" "@hapi/accept" "5.0.1" - "@next/env" "10.0.5-canary.11" - "@next/polyfill-module" "10.0.5-canary.11" - "@next/react-dev-overlay" "10.0.5-canary.11" - "@next/react-refresh-utils" "10.0.5-canary.11" + "@next/env" "10.0.5" + "@next/polyfill-module" "10.0.5" + "@next/react-dev-overlay" "10.0.5" + "@next/react-refresh-utils" "10.0.5" "@opentelemetry/api" "0.14.0" ast-types "0.13.2" babel-plugin-transform-define "2.0.0" @@ -5261,16 +5109,16 @@ no-case@^3.0.3, no-case@^3.0.4: tslib "^2.0.3" node-abi@^2.7.0: - version "2.19.1" - resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-2.19.1.tgz#6aa32561d0a5e2fdb6810d8c25641b657a8cea85" - integrity sha512-HbtmIuByq44yhAzK7b9j/FelKlHYISKQn0mtvcBrU5QBkhoCMp5bu8Hv5AI34DcKfOAcJBcOEMwLlwO62FFu9A== + version "2.19.3" + resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-2.19.3.tgz#252f5dcab12dad1b5503b2d27eddd4733930282d" + integrity sha512-9xZrlyfvKhWme2EXFKQhZRp1yNWT/uI1luYPr3sFl+H4keYY4xR+1jO7mvTTijIsHf1M+QDe9uWuKeEpLInIlg== dependencies: semver "^5.4.1" node-addon-api@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-3.0.2.tgz#04bc7b83fd845ba785bb6eae25bc857e1ef75681" - integrity sha512-+D4s2HCnxPd5PjjI0STKwncjXTUKKqm74MDMz9OPXavjsGmjkvwgLtA5yoxJUdmpj52+2u+RrXgPipahKczMKg== + version "3.1.0" + resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-3.1.0.tgz#98b21931557466c6729e51cb77cd39c965f42239" + integrity sha512-flmrDNB06LIl5lywUz7YlNGZH/5p0M7W28k8hzd9Lshtdh1wshD2Y+U4h9LD6KObOy1f+fEVdgprPrEymjM5uw== node-emoji@^1.8.1: version "1.10.0" @@ -5296,15 +5144,10 @@ node-int64@^0.4.0: resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" integrity sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs= -node-releases@^1.1.61: - version "1.1.64" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.64.tgz#71b4ae988e9b1dd7c1ffce58dd9e561752dfebc5" - integrity sha512-Iec8O9166/x2HRMJyLLLWkd0sFFLrFNy+Xf+JQfSQsdBJzPcHpNl3JQ9gD4j+aJxmCa25jNsIbM4bmACtSbkSg== - -node-releases@^1.1.65: - version "1.1.67" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.67.tgz#28ebfcccd0baa6aad8e8d4d8fe4cbc49ae239c12" - integrity sha512-V5QF9noGFl3EymEwUYzO+3NTDpGfQB4ve6Qfnzf3UNydMhjQRVPR1DZTuvWiLzaFJYw2fmDwAfnRNEVb64hSIg== +node-releases@^1.1.65, node-releases@^1.1.69: + version "1.1.69" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.69.tgz#3149dbde53b781610cd8b486d62d86e26c3725f6" + integrity sha512-DGIjo79VDEyAnRlfSqYTsy+yoHd2IOjJiKUozD2MV2D85Vso6Bug56mb9tT/fY5Urt0iqk01H7x+llAruDR2zA== node-source-walk@^4.0.0, node-source-walk@^4.2.0: version "4.2.0" @@ -5396,9 +5239,9 @@ object-assign@^4.1.0, object-assign@^4.1.1: integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= object-hash@^2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/object-hash/-/object-hash-2.0.3.tgz#d12db044e03cd2ca3d77c0570d87225b02e1e6ea" - integrity sha512-JPKn0GMu+Fa3zt3Bmr66JhokJU5BaNBIh4ZeTlaCBzrBsOeXzwcKKAK1tbLiPKgvwmPXsDvvLHoWh5Bm7ofIYg== + version "2.1.1" + resolved "https://registry.yarnpkg.com/object-hash/-/object-hash-2.1.1.tgz#9447d0279b4fcf80cff3259bf66a1dc73afabe09" + integrity sha512-VOJmgmS+7wvXf8CjbQmimtCnEx3IAoLxI3fp2fbWehxrWBcAQFbk+vcwb6vzR0VZv/eNCJ/27j151ZTwqW/JeQ== object-inspect@^1.8.0: version "1.9.0" @@ -5425,13 +5268,6 @@ object.assign@^4.1.0, object.assign@^4.1.1: has-symbols "^1.0.1" object-keys "^1.1.1" -on-finished@~2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" - integrity sha1-IPEzZIGwg811M3mSoWlxqi2QaUc= - dependencies: - ee-first "1.1.1" - once@^1.3.0, once@^1.3.1, once@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" @@ -5453,7 +5289,7 @@ onetime@^5.1.0: dependencies: mimic-fn "^2.1.0" -opener@^1.5.1: +opener@^1.5.2: version "1.5.2" resolved "https://registry.yarnpkg.com/opener/-/opener-1.5.2.tgz#5d37e1f35077b9dcac4301372271afdeb2a13598" integrity sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A== @@ -5471,16 +5307,16 @@ optionator@^0.8.1: word-wrap "~1.2.3" ora@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/ora/-/ora-5.1.0.tgz#b188cf8cd2d4d9b13fd25383bc3e5cba352c94f8" - integrity sha512-9tXIMPvjZ7hPTbk8DFq1f7Kow/HU/pQYB60JbNq+QnGwcyhWVZaQ4hM9zQDEsPxw/muLpgiHSaumUZxCAmod/w== + version "5.2.0" + resolved "https://registry.yarnpkg.com/ora/-/ora-5.2.0.tgz#de10bfd2d15514384af45f3fa9d9b1aaf344fda1" + integrity sha512-+wG2v8TUU8EgzPHun1k/n45pXquQ9fHnbXVetl9rRgO6kjZszGGbraF3XPTIdgeA+s1lbRjSEftAnyT0w8ZMvQ== dependencies: + bl "^4.0.3" chalk "^4.1.0" cli-cursor "^3.1.0" - cli-spinners "^2.4.0" + cli-spinners "^2.5.0" is-interactive "^1.0.0" log-symbols "^4.0.0" - mute-stream "0.0.8" strip-ansi "^6.0.0" wcwidth "^1.0.1" @@ -5501,14 +5337,14 @@ p-cancelable@^1.0.0: resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-1.1.0.tgz#d078d15a3af409220c886f1d9a0ca2e441ab26cc" integrity sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw== -p-limit@3.0.2, p-limit@^3.0.2: +p-limit@3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.0.2.tgz#1664e010af3cadc681baafd3e2a437be7b0fb5fe" integrity sha512-iwqZSOoWIW+Ew4kAGUlN16J4M7OB3ysMLSZtnhmqx7njIHFPlxWBX8xo3lVTyFVq6mI/lL9qt2IsN1sHwaxJkg== dependencies: p-try "^2.0.0" -p-limit@3.1.0: +p-limit@3.1.0, p-limit@^3.0.2, p-limit@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== @@ -5606,11 +5442,6 @@ parse-ms@^2.1.0: resolved "https://registry.yarnpkg.com/parse-ms/-/parse-ms-2.1.0.tgz#348565a753d4391fa524029956b172cb7753097d" integrity sha512-kHt7kzLoS9VBZfUsiKjv43mr91ea+U05EyKkEtqp7vNbHxmaVuEqN7XxeEVnGrMtYOAxGrDElSi96K7EgO1zCA== -parseurl@~1.3.3: - version "1.3.3" - resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" - integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== - pascal-case@3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/pascal-case/-/pascal-case-3.1.1.tgz#5ac1975133ed619281e88920973d2cd1f279de5f" @@ -5659,11 +5490,6 @@ path-root@^0.1.1: dependencies: path-root-regex "^0.1.0" -path-to-regexp@0.1.7: - version "0.1.7" - resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" - integrity sha1-32BBeABfUi8V60SQ5yR6G/qmf4w= - path-type@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" @@ -5845,9 +5671,9 @@ postcss-focus-within@^3.0.0: postcss "^7.0.2" postcss-font-variant@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/postcss-font-variant/-/postcss-font-variant-4.0.0.tgz#71dd3c6c10a0d846c5eda07803439617bbbabacc" - integrity sha512-M8BFYKOvCrI2aITzDad7kWuXXTm0YhGdP9Q8HanmN4EF1Hmcgs1KK5rSHylt/lUJe8yLxiSwWAHdScoEiIxztg== + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-font-variant/-/postcss-font-variant-4.0.1.tgz#42d4c0ab30894f60f98b17561eb5c0321f502641" + integrity sha512-I3ADQSTNtLTTd8uxZhtSOrTCQ9G4qUVKPjHiDk0bV75QSxXjVWiJVJ2VLdspGUi9fbW9BcjKJoRvxAH1pckqmA== dependencies: postcss "^7.0.2" @@ -5922,7 +5748,7 @@ postcss-modules-extract-imports@^2.0.0: dependencies: postcss "^7.0.5" -postcss-modules-local-by-default@^3.0.3: +postcss-modules-local-by-default@^3.0.2, postcss-modules-local-by-default@^3.0.3: version "3.0.3" resolved "https://registry.yarnpkg.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-3.0.3.tgz#bb14e0cc78279d504dbdcbfd7e0ca28993ffbbb0" integrity sha512-e3xDq+LotiGesympRlKNgaJ0PCzoUIdpH0dj47iWAui/kyTgh3CiAr1qP54uodmJhl6p9rN6BoNcdEDVJx9RDw== @@ -5948,6 +5774,21 @@ postcss-modules-values@^3.0.0: icss-utils "^4.0.0" postcss "^7.0.6" +postcss-modules@^3.2.2: + version "3.2.2" + resolved "https://registry.yarnpkg.com/postcss-modules/-/postcss-modules-3.2.2.tgz#ee390de0f9f18e761e1778dfb9be26685c02c51f" + integrity sha512-JQ8IAqHELxC0N6tyCg2UF40pACY5oiL6UpiqqcIFRWqgDYO8B0jnxzoQ0EOpPrWXvcpu6BSbQU/3vSiq7w8Nhw== + dependencies: + generic-names "^2.0.1" + icss-replace-symbols "^1.1.0" + lodash.camelcase "^4.3.0" + postcss "^7.0.32" + postcss-modules-extract-imports "^2.0.0" + postcss-modules-local-by-default "^3.0.2" + postcss-modules-scope "^2.2.0" + postcss-modules-values "^3.0.0" + string-hash "^1.1.1" + postcss-nested@^4.1.1: version "4.2.3" resolved "https://registry.yarnpkg.com/postcss-nested/-/postcss-nested-4.2.3.tgz#c6f255b0a720549776d220d00c4b70cd244136f6" @@ -6059,9 +5900,9 @@ postcss-selector-matches@^4.0.0: postcss "^7.0.2" postcss-selector-not@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/postcss-selector-not/-/postcss-selector-not-4.0.0.tgz#c68ff7ba96527499e832724a2674d65603b645c0" - integrity sha512-W+bkBZRhqJaYN8XAnbbZPLWMvZD1wKTu0UxtFKdhtGjWYmxhkUneoeOhRJKdAE5V7ZTlnbHfCR+6bNwK9e1dTQ== + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-selector-not/-/postcss-selector-not-4.0.1.tgz#263016eef1cf219e0ade9a913780fc1f48204cbf" + integrity sha512-YolvBgInEK5/79C+bdFMyzqTg6pkYqDbzZIST/PDMqa/o3qtXenD05apBG2jLgT0/BQ77d4U2UK12jWpilqMAQ== dependencies: balanced-match "^1.0.0" postcss "^7.0.2" @@ -6075,7 +5916,7 @@ postcss-selector-parser@^5.0.0-rc.3, postcss-selector-parser@^5.0.0-rc.4: indexes-of "^1.0.1" uniq "^1.0.1" -postcss-selector-parser@^6.0.0, postcss-selector-parser@^6.0.2: +postcss-selector-parser@^6.0.0, postcss-selector-parser@^6.0.2, postcss-selector-parser@^6.0.4: version "6.0.4" resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.4.tgz#56075a1380a04604c38b063ea7767a129af5c2b3" integrity sha512-gjMeXBempyInaBqpp8gODmwZ52WaYsVOsfr4L4lDQ7n3ncD6mEyySiDtgzCT+NYC0mmeOLvtsF8iaEf0YT6dBw== @@ -6209,16 +6050,11 @@ prepend-http@^2.0.0: resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-2.0.0.tgz#e92434bfa5ea8c19f41cdfd401d741a3c819d897" integrity sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc= -prettier@^2.0.5: +prettier@^2.0.5, prettier@^2.1.2: version "2.2.1" resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.2.1.tgz#795a1a78dd52f073da0cd42b21f9c91381923ff5" integrity sha512-PqyhM2yCjg/oKkFPtTGUojv7gnZAoG80ttl45O6x2Ug/rMJw4wcc9k6aaf2hibP7BGVCCM33gZoGjyvt9mm16Q== -prettier@^2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.1.2.tgz#3050700dae2e4c8b67c4c3f666cdb8af405e1ce5" - integrity sha512-16c7K+x4qVlJg9rEbXl7HEGmQyZlG4R9AgP+oHKRMsMsuk8s+ATStlf1NpDqyBI1HpVyfjLOeMhH2LvuNvV5Vg== - pretty-hrtime@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz#b7e3ea42435a4c9b2759d99e0f201eb195802ee1" @@ -6257,14 +6093,6 @@ prop-types@15.7.2, prop-types@^15.6.2: object-assign "^4.1.1" react-is "^16.8.1" -proxy-addr@~2.0.5: - version "2.0.6" - resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.6.tgz#fdc2336505447d3f2f2c638ed272caf614bbb2bf" - integrity sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw== - dependencies: - forwarded "~0.1.2" - ipaddr.js "1.9.1" - prr@~1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476" @@ -6310,11 +6138,6 @@ purgecss@^2.3.0: postcss "7.0.32" postcss-selector-parser "^6.0.2" -qs@6.7.0: - version "6.7.0" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.7.0.tgz#41dc1a015e3d581f1621776be31afb2876a9b1bc" - integrity sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ== - qs@~6.5.2: version "6.5.2" resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" @@ -6350,21 +6173,6 @@ randomfill@^1.0.3: randombytes "^2.0.5" safe-buffer "^5.1.0" -range-parser@~1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" - integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== - -raw-body@2.4.0: - version "2.4.0" - resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.4.0.tgz#a1ce6fb9c9bc356ca52e89256ab59059e13d0332" - integrity sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q== - dependencies: - bytes "3.1.0" - http-errors "1.7.2" - iconv-lite "0.4.24" - unpipe "1.0.0" - raw-body@2.4.1: version "2.4.1" resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.4.1.tgz#30ac82f98bb5ae8c152e67149dac8d55153b168c" @@ -6481,9 +6289,9 @@ redent@^3.0.0: strip-indent "^3.0.0" reduce-css-calc@^2.1.6: - version "2.1.7" - resolved "https://registry.yarnpkg.com/reduce-css-calc/-/reduce-css-calc-2.1.7.tgz#1ace2e02c286d78abcd01fd92bfe8097ab0602c2" - integrity sha512-fDnlZ+AybAS3C7Q9xDq5y8A2z+lT63zLbynew/lur/IR24OQF5x98tfNwf79mzEdfywZ0a2wpM860FhFfMxZlA== + version "2.1.8" + resolved "https://registry.yarnpkg.com/reduce-css-calc/-/reduce-css-calc-2.1.8.tgz#7ef8761a28d614980dc0c982f772c93f7a99de03" + integrity sha512-8liAVezDmUcH+tdzoEGrhfbGcP7nOV4NkGE3a74+qqvE7nt9i4sKLGBuZNOnpI4WiGksiNPklZxva80061QiPg== dependencies: css-unit-converter "^1.1.1" postcss-value-parser "^3.3.0" @@ -6653,7 +6461,7 @@ resolve-url@^0.2.1: resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= -resolve@^1.10.0: +resolve@^1.10.0, resolve@^1.11.1, resolve@^1.14.2: version "1.19.0" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.19.0.tgz#1af5bf630409734a067cae29318aac7fa29a267c" integrity sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg== @@ -6661,14 +6469,6 @@ resolve@^1.10.0: is-core-module "^2.1.0" path-parse "^1.0.6" -resolve@^1.11.1, resolve@^1.14.2: - version "1.18.1" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.18.1.tgz#018fcb2c5b207d2a6424aee361c5a266da8f4130" - integrity sha512-lDfCPaMKfOJXjy0dPayzPdF1phampNWr3qFCjAu+rw/qbQmr5jWH5xN2hwh9QKfw9E5v4hwV7A+jrCmL8yjjqA== - dependencies: - is-core-module "^2.0.0" - path-parse "^1.0.6" - responselike@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/responselike/-/responselike-1.0.2.tgz#918720ef3b631c5642be068f15ade5a46f4ba1e7" @@ -6747,16 +6547,16 @@ rxjs@^6.3.3, rxjs@^6.6.0: dependencies: tslib "^1.9.0" -safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: - version "5.1.2" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" - integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== - safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@^5.2.0, safe-buffer@~5.2.0: version "5.2.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== +safe-buffer@~5.1.0, safe-buffer@~5.1.1: + version "5.1.2" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== + safe-json-stringify@~1: version "1.2.0" resolved "https://registry.yarnpkg.com/safe-json-stringify/-/safe-json-stringify-1.2.0.tgz#356e44bc98f1f93ce45df14bcd7c01cda86e0afd" @@ -6827,28 +6627,11 @@ semver@^6.0.0, semver@^6.2.0: integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== semver@^7.3.2: - version "7.3.2" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.2.tgz#604962b052b81ed0786aae84389ffba70ffd3938" - integrity sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ== - -send@0.17.1: - version "0.17.1" - resolved "https://registry.yarnpkg.com/send/-/send-0.17.1.tgz#c1d8b059f7900f7466dd4938bdc44e11ddb376c8" - integrity sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg== + version "7.3.4" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.4.tgz#27aaa7d2e4ca76452f98d3add093a72c943edc97" + integrity sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw== dependencies: - debug "2.6.9" - depd "~1.1.2" - destroy "~1.0.4" - encodeurl "~1.0.2" - escape-html "~1.0.3" - etag "~1.8.1" - fresh "0.5.2" - http-errors "~1.7.2" - mime "1.6.0" - ms "2.1.1" - on-finished "~2.3.0" - range-parser "~1.2.1" - statuses "~1.5.0" + lru-cache "^6.0.0" serialize-javascript@^5.0.1: version "5.0.1" @@ -6857,16 +6640,6 @@ serialize-javascript@^5.0.1: dependencies: randombytes "^2.1.0" -serve-static@1.14.1: - version "1.14.1" - resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.14.1.tgz#666e636dc4f010f7ef29970a88a674320898b2f9" - integrity sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg== - dependencies: - encodeurl "~1.0.2" - escape-html "~1.0.3" - parseurl "~1.3.3" - send "0.17.1" - set-blocking@^2.0.0, set-blocking@~2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" @@ -6956,6 +6729,15 @@ simple-swizzle@^0.2.2: dependencies: is-arrayish "^0.3.1" +sirv@^1.0.7: + version "1.0.10" + resolved "https://registry.yarnpkg.com/sirv/-/sirv-1.0.10.tgz#3e591f5a9ae2520f50d5830f5fae38d97e7be194" + integrity sha512-H5EZCoZaggEUQy8ocKsF7WAToGuZhjJlLvM3XOef46CbdIgbNeQ1p32N1PCuCjkVYwrAVOSMacN6CXXgIzuspg== + dependencies: + "@polka/url" "^1.0.0-next.9" + mime "^2.3.1" + totalist "^1.0.0" + slash@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" @@ -7017,6 +6799,11 @@ source-map@^0.5.0: resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= +sourcemap-codec@^1.4.4: + version "1.4.8" + resolved "https://registry.yarnpkg.com/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz#ea804bd94857402e6992d05a38ef1ae35a9ab4c4" + integrity sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA== + spdx-correct@^3.0.0: version "3.1.1" resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.1.tgz#dece81ac9c1e6713e5f7d1b6f17d468fa53d89a9" @@ -7075,7 +6862,7 @@ stacktrace-parser@0.1.10: dependencies: type-fest "^0.7.1" -"statuses@>= 1.5.0 < 2", statuses@~1.5.0: +"statuses@>= 1.5.0 < 2": version "1.5.0" resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= @@ -7098,7 +6885,7 @@ string-env-interpolation@1.0.1, string-env-interpolation@^1.0.1: resolved "https://registry.yarnpkg.com/string-env-interpolation/-/string-env-interpolation-1.0.1.tgz#ad4397ae4ac53fe6c91d1402ad6f6a52862c7152" integrity sha512-78lwMoCcn0nNu8LszbP1UA7g55OeE4v7rCeWnM5B453rnNr4aq+5it3FEYtZrSEiMvHZOZ9Jlqb0OD0M2VInqg== -string-hash@1.1.3: +string-hash@1.1.3, string-hash@^1.1.1: version "1.1.3" resolved "https://registry.yarnpkg.com/string-hash/-/string-hash-1.1.3.tgz#e8aafc0ac1855b4666929ed7dd1275df5d6c811b" integrity sha1-6Kr8CsGFW0Zmkp7X3RJ1311sgRs= @@ -7267,10 +7054,10 @@ supports-color@^7.0.0, supports-color@^7.1.0: dependencies: has-flag "^4.0.0" -swr@^0.3.11: - version "0.3.11" - resolved "https://registry.yarnpkg.com/swr/-/swr-0.3.11.tgz#f7f50ed26c06afea4249482cec504768a2272664" - integrity sha512-ya30LuRGK2R7eDlttnb7tU5EmJYJ+N6ytIOM2j0Hqs0qauJcDjVLDOGy7KmFeH5ivOwLHalFaIyYl2K+SGa7HQ== +swr@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/swr/-/swr-0.4.0.tgz#e76da9f981fe6dee0e133289e9b582fc80d9c41d" + integrity sha512-70qd1FHYHwIdYXW0jTpm5ktitzvPBCtyKz8ZzynWlY/rMqe4drYPgcl/H9Ipuh+Xv6ZW5viNx13ro8EKIWZcoQ== dependencies: dequal "2.0.2" @@ -7287,6 +7074,11 @@ sync-fetch@0.3.0: buffer "^5.7.0" node-fetch "^2.6.1" +tabbable@^5.1.5: + version "5.1.5" + resolved "https://registry.yarnpkg.com/tabbable/-/tabbable-5.1.5.tgz#efec48ede268d511c261e3b81facbb4782a35147" + integrity sha512-oVAPrWgLLqrbvQE8XqcU7CVBq6SQbaIbHkhOca3u7/jzuQvyZycrUKPCGr04qpEIUslmUlULbSeN+m3QrKEykA== + tailwindcss@^1.9: version "1.9.6" resolved "https://registry.yarnpkg.com/tailwindcss/-/tailwindcss-1.9.6.tgz#0c5089911d24e1e98e592a31bfdb3d8f34ecf1a0" @@ -7325,17 +7117,7 @@ tapable@^2.1.1, tapable@^2.2.0: resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.0.tgz#5c373d281d9c672848213d0e037d1c4165ab426b" integrity sha512-FBk4IesMV1rBxX2tfiK8RAmogtWn53puLOQlvO8XuwlgxcYbP4mVPS9Ph4aeamSyyVjOl24aYWAuc8U5kCVwMw== -tar-fs@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-2.1.0.tgz#d1cdd121ab465ee0eb9ccde2d35049d3f3daf0d5" - integrity sha512-9uW5iDvrIMCVpvasdFHW0wJPez0K4JnMZtsuIeDI7HyMGJNxmDZDOCQROr7lXyS+iL/QMpj07qcjGYTSdRFXUg== - dependencies: - chownr "^1.1.1" - mkdirp-classic "^0.5.2" - pump "^3.0.0" - tar-stream "^2.0.0" - -tar-fs@^2.1.1: +tar-fs@^2.0.0, tar-fs@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-2.1.1.tgz#489a15ab85f1f0befabb370b7de4f9eb5cbe8784" integrity sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng== @@ -7345,17 +7127,6 @@ tar-fs@^2.1.1: pump "^3.0.0" tar-stream "^2.1.4" -tar-stream@^2.0.0: - version "2.1.4" - resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-2.1.4.tgz#c4fb1a11eb0da29b893a5b25476397ba2d053bfa" - integrity sha512-o3pS2zlG4gxr67GmFYBLlq+dM8gyRGUOvsrHclSkvtVtQbjV0s/+ZE8OpICbaj8clrX3tjeHngYGP7rweaBnuw== - dependencies: - bl "^4.0.3" - end-of-stream "^1.4.1" - fs-constants "^1.0.0" - inherits "^2.0.3" - readable-stream "^3.1.1" - tar-stream@^2.1.4: version "2.2.0" resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-2.2.0.tgz#acad84c284136b060dc3faa64474aa9aebd77287" @@ -7373,18 +7144,18 @@ temp@~0.4.0: integrity sha1-ZxrWPVe+D+nXKUZks/xABjZnimA= terser-webpack-plugin@^5.0.3: - version "5.0.3" - resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.0.3.tgz#ec60542db2421f45735c719d2e17dabfbb2e3e42" - integrity sha512-zFdGk8Lh9ZJGPxxPE6jwysOlATWB8GMW8HcfGULWA/nPal+3VdATflQvSBSLQJRCmYZnfFJl6vkRTiwJGNgPiQ== + version "5.1.1" + resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.1.1.tgz#7effadee06f7ecfa093dbbd3e9ab23f5f3ed8673" + integrity sha512-5XNNXZiR8YO6X6KhSGXfY0QrGrCRlSwAEjIIrlRQR4W8nP69TaJUlh3bkuac6zzgspiGPfKEHcY295MMVExl5Q== dependencies: - jest-worker "^26.6.1" - p-limit "^3.0.2" + jest-worker "^26.6.2" + p-limit "^3.1.0" schema-utils "^3.0.0" serialize-javascript "^5.0.1" source-map "^0.6.1" - terser "^5.3.8" + terser "^5.5.1" -terser@5.5.1: +terser@5.5.1, terser@^5.5.1: version "5.5.1" resolved "https://registry.yarnpkg.com/terser/-/terser-5.5.1.tgz#540caa25139d6f496fdea056e414284886fb2289" integrity sha512-6VGWZNVP2KTUcltUQJ25TtNjx/XgdDsBDKGt8nN0MpydU36LmbPPcMBd2kmtZNNGVVDLg44k7GKeHHj+4zPIBQ== @@ -7393,15 +7164,6 @@ terser@5.5.1: source-map "~0.7.2" source-map-support "~0.5.19" -terser@^5.3.8: - version "5.3.8" - resolved "https://registry.yarnpkg.com/terser/-/terser-5.3.8.tgz#991ae8ba21a3d990579b54aa9af11586197a75dd" - integrity sha512-zVotuHoIfnYjtlurOouTazciEfL7V38QMAOhGqpXDEg6yT13cF4+fEP9b0rrCEQTn+tT46uxgFsTZzhygk+CzQ== - dependencies: - commander "^2.20.0" - source-map "~0.7.2" - source-map-support "~0.5.19" - through@^2.3.6: version "2.3.8" resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" @@ -7436,6 +7198,11 @@ toidentifier@1.0.0: resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553" integrity sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw== +totalist@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/totalist/-/totalist-1.1.0.tgz#a4d65a3e546517701e3e5c37a47a70ac97fe56df" + integrity sha512-gduQwd1rOdDMGxFG1gEvhV88Oirdo2p+KjoYFU7k2g+i7n6AFFbDQ5kMPUsW0pNbfQsB/cwXvT1i4Bue0s9g5g== + tough-cookie@~2.5.0: version "2.5.0" resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" @@ -7466,11 +7233,6 @@ trim-newlines@^3.0.0: resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-3.0.0.tgz#79726304a6a898aa8373427298d54c2ee8b1cb30" integrity sha512-C4+gOpvmxaSMKuEf9Qc134F1ZuOHVXKRbtEflf4NTtuuJDEIJ9p5PXsalL8SkeRw+qit1Mo+yuvMPAKwWg/1hA== -tryer@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/tryer/-/tryer-1.0.1.tgz#f2c85406800b9b0f74c9f7465b81eaad241252f8" - integrity sha512-c3zayb8/kWWpycWYg87P71E1S1ZL6b6IJxfb5fvsUgsf0S2MVGaDhDXXjDMpdCpfWXqptc+4mXwmiy1ypXqRAA== - ts-loader@^7.0.0: version "7.0.5" resolved "https://registry.yarnpkg.com/ts-loader/-/ts-loader-7.0.5.tgz#789338fb01cb5dc0a33c54e50558b34a73c9c4c5" @@ -7509,15 +7271,20 @@ tslib@^1.10.0, tslib@^1.8.1, tslib@^1.9.0: resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== -tslib@^2, tslib@^2.0.0, tslib@^2.0.3, tslib@~2.0.1: +tslib@^2, tslib@^2.0.0, tslib@^2.0.3, tslib@~2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.1.0.tgz#da60860f1c2ecaa5703ab7d39bc05b6bf988b97a" + integrity sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A== + +tslib@~2.0.1: version "2.0.3" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.0.3.tgz#8e0741ac45fc0c226e58a17bfc3e64b9bc6ca61c" integrity sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ== tsutils@^3.17.1: - version "3.17.1" - resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.17.1.tgz#ed719917f11ca0dee586272b2ac49e015a2dd759" - integrity sha512-kzeQ5B8H3w60nFY2g8cJIuH7JDpsALXySGtwGJ0p2LSjLgay3NdIpqq5SoOBe46bKDW2iq25irHCr8wjomUS2g== + version "3.19.1" + resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.19.1.tgz#d8566e0c51c82f32f9c25a4d367cd62409a547a9" + integrity sha512-GEdoBf5XI324lu7ycad7s6laADfnAqCw6wLGI+knxvw9vsIYBaJfYdmeCEG3FMMUiSm3OGgNb+m6utsWf5h9Vw== dependencies: tslib "^1.8.1" @@ -7565,14 +7332,6 @@ type-fest@^0.8.1: resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d" integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA== -type-is@~1.6.17, type-is@~1.6.18: - version "1.6.18" - resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" - integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== - dependencies: - media-typer "0.3.0" - mime-types "~2.1.24" - type@^1.0.1: version "1.2.0" resolved "https://registry.yarnpkg.com/type/-/type-1.2.0.tgz#848dd7698dafa3e54a6c479e759c4bc3f18847a0" @@ -7589,9 +7348,9 @@ typescript@^3.0.3, typescript@^3.8.3, typescript@^3.9.5, typescript@^3.9.7: integrity sha512-BLbiRkiBzAwsjut4x/dsibSTB6yWpwT5qWmC2OfuCg3GgVQCSgMs4vEctYPhsaGtd0AeuuHMkjZ2h2WG8MSzRw== typescript@^4.0.3: - version "4.0.3" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.0.3.tgz#153bbd468ef07725c1df9c77e8b453f8d36abba5" - integrity sha512-tEu6DGxGgRJPb/mVPIZ48e69xCn2yRmCgYmDugAVwmJ6o+0u1RI18eO7E7WBTLYLaEVVOhwQmcdhQHweux/WPg== + version "4.1.3" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.1.3.tgz#519d582bd94cba0cf8934c7d8e8467e473f53bb7" + integrity sha512-B3ZIOf1IKeH2ixgHhj6la6xdwR9QrLC5d1VKeCSY4tvkqhF2eqd9O7txNlS0PO3GrBAFIdr3L1ndNwteUbZLYg== ua-parser-js@^0.7.18: version "0.7.23" @@ -7620,7 +7379,7 @@ unixify@1.0.0: dependencies: normalize-path "^2.1.1" -unpipe@1.0.0, unpipe@~1.0.0: +unpipe@1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" integrity sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw= @@ -7640,9 +7399,9 @@ upper-case@^2.0.1, upper-case@^2.0.2: tslib "^2.0.3" uri-js@^4.2.2: - version "4.4.0" - resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.0.tgz#aa714261de793e8a82347a7bcc9ce74e86f28602" - integrity sha512-B0yRTzYdUCCn9n+F4+Gh4yIDtMQcaJsmYBDsTSG8g/OejKBodLQ2IHfN3bM7jUsRXndopT7OIXWdYqc1fjmV6g== + version "4.4.1" + resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" + integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== dependencies: punycode "^2.1.0" @@ -7678,11 +7437,6 @@ util-deprecate@^1.0.1, util-deprecate@^1.0.2, util-deprecate@~1.0.1: resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= -utils-merge@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" - integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM= - uuid@^3.3.2: version "3.4.0" resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" @@ -7701,11 +7455,6 @@ validate-npm-package-license@^3.0.1: spdx-correct "^3.0.0" spdx-expression-parse "^3.0.0" -vary@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" - integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw= - verror@1.10.0: version "1.10.0" resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" @@ -7720,14 +7469,6 @@ vm-browserify@1.1.2: resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.2.tgz#78641c488b8e6ca91a75f511e7a3b32a86e5dda0" integrity sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ== -vue-template-compiler@^2.6.12: - version "2.6.12" - resolved "https://registry.yarnpkg.com/vue-template-compiler/-/vue-template-compiler-2.6.12.tgz#947ed7196744c8a5285ebe1233fe960437fcc57e" - integrity sha512-OzzZ52zS41YUbkCBfdXShQTe69j1gQDZ9HIX8miuC9C3rBCk9wIRjLiZZLrmX9V+Ftq/YEyv1JaVr5Y/hNtByg== - dependencies: - de-indent "^1.0.2" - he "^1.1.0" - walkdir@^0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/walkdir/-/walkdir-0.4.1.tgz#dc119f83f4421df52e3061e514228a2db20afa39" @@ -7749,9 +7490,9 @@ watchpack@2.0.0-beta.13: graceful-fs "^4.1.2" watchpack@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.0.0.tgz#b12248f32f0fd4799b7be0802ad1f6573a45955c" - integrity sha512-xSdCxxYZWNk3VK13bZRYhsQpfa8Vg63zXG+3pyU8ouqSLRCv4IGXIp9Kr226q6GBkGRlZrST2wwKtjfKz2m7Cg== + version "2.1.0" + resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.1.0.tgz#e63194736bf3aa22026f7b191cd57907b0f9f696" + integrity sha512-UjgD1mqjkG99+3lgG36at4wPnUXNvis2v1utwTgQ43C22c4LD71LsYMExdWXh4HZ+RmW+B0t1Vrg2GpXAkTOQw== dependencies: glob-to-regexp "^0.4.1" graceful-fs "^4.1.2" @@ -7768,24 +7509,20 @@ webidl-conversions@^4.0.2: resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad" integrity sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg== -webpack-bundle-analyzer@3.6.1: - version "3.6.1" - resolved "https://registry.yarnpkg.com/webpack-bundle-analyzer/-/webpack-bundle-analyzer-3.6.1.tgz#bdb637c2304424f2fbff9a950c7be42a839ae73b" - integrity sha512-Nfd8HDwfSx1xBwC+P8QMGvHAOITxNBSvu/J/mCJvOwv+G4VWkU7zir9SSenTtyCi0LnVtmsc7G5SZo1uV+bxRw== +webpack-bundle-analyzer@4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/webpack-bundle-analyzer/-/webpack-bundle-analyzer-4.3.0.tgz#2f3c0ca9041d5ee47fa418693cf56b4a518b578b" + integrity sha512-J3TPm54bPARx6QG8z4cKBszahnUglcv70+N+8gUqv2I5KOFHJbzBiLx+pAp606so0X004fxM7hqRu10MLjJifA== dependencies: - acorn "^7.1.1" - acorn-walk "^7.1.1" - bfj "^6.1.1" - chalk "^2.4.1" - commander "^2.18.0" - ejs "^2.6.1" - express "^4.16.3" - filesize "^3.6.1" - gzip-size "^5.0.0" - lodash "^4.17.15" - mkdirp "^0.5.1" - opener "^1.5.1" - ws "^6.0.0" + acorn "^8.0.4" + acorn-walk "^8.0.0" + chalk "^4.1.0" + commander "^6.2.0" + gzip-size "^6.0.0" + lodash "^4.17.20" + opener "^1.5.2" + sirv "^1.0.7" + ws "^7.3.1" webpack-sources@1.4.3: version "1.4.3" @@ -7905,12 +7642,10 @@ ws@7.4.1: resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.1.tgz#a333be02696bd0e54cea0434e21dcc8a9ac294bb" integrity sha512-pTsP8UAfhy3sk1lSk/O/s4tjD0CRwvMnzvwr4OKGX7ZvqZtUyx4KIJB5JWbkykPoc55tixMGgTNoh3k4FkNGFQ== -ws@^6.0.0: - version "6.2.1" - resolved "https://registry.yarnpkg.com/ws/-/ws-6.2.1.tgz#442fdf0a47ed64f59b6a5d8ff130f4748ed524fb" - integrity sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA== - dependencies: - async-limiter "~1.0.0" +ws@^7.3.1: + version "7.4.2" + resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.2.tgz#782100048e54eb36fe9843363ab1c68672b261dd" + integrity sha512-T4tewALS3+qsrpGI/8dqNMLIVdq/g/85U98HPMa6F0m6xTbvhXU6RCQLqPH3+SlomNV/LdY6RXEbBpMH6EOJnA== xtend@^4.0.2: version "4.0.2" From 72b5fb0c1a5a04b8f1c9f3927c2e81dd3081d140 Mon Sep 17 00:00:00 2001 From: Belen Curcio Date: Mon, 11 Jan 2021 12:17:55 -0300 Subject: [PATCH 022/216] Merge Issues --- README.md | 26 ++++++-------------------- pages/wishlist.tsx | 6 +----- 2 files changed, 7 insertions(+), 25 deletions(-) diff --git a/README.md b/README.md index ebaf190d7..fbbbbf26b 100644 --- a/README.md +++ b/README.md @@ -22,18 +22,19 @@ This project is currently under development. - Dark Mode Support ## Work in progress + We're using Github Projects to keep track of issues in progress and todo's. Here is our [Board](https://github.com/vercel/commerce/projects/1) ## Integrations -Next.js Commerce integrates out-of-the-box with BigCommerce. We plan to support all major ecommerce backends. +Next.js Commerce integrates out-of-the-box with BigCommerce. We plan to support all major ecommerce backends. ## Goals -* **Next.js Commerce** should have a completely data **agnostic** UI -* **Aware of schema**: should ship with the right data schemas and types. -* All providers should return the right data types and schemas to blend correctly with Next.js Commerce. -* `@framework` will be the alias utilized in commerce and it will map to the ecommerce provider of preference- e.g BigCommerce, Shopify, Swell. All providers should expose the same standardized functions. _Note that the same applies for recipes using a CMS + an ecommerce provider._ +- **Next.js Commerce** should have a completely data **agnostic** UI +- **Aware of schema**: should ship with the right data schemas and types. +- All providers should return the right data types and schemas to blend correctly with Next.js Commerce. +- `@framework` will be the alias utilized in commerce and it will map to the ecommerce provider of preference- e.g BigCommerce, Shopify, Swell. All providers should expose the same standardized functions. _Note that the same applies for recipes using a CMS + an ecommerce provider._ There is a `framework` folder in the root folder that will contain multiple ecommerce providers. @@ -92,21 +93,6 @@ Our commitment to Open Source can be found [here](https://vercel.com/oss). 8. The development branch is `development` (this is the branch pull requests should be made against). On a release, `develop` branch is rebased into `master`. - -<<<<<<< HEAD -- **Next.js Commerce** should have a completely data **agnostic** UI -- **Aware of schema**: should ship with the right data schemas and types. -- All providers should return the right data types and schemas to blend correctly with Next.js Commerce. -- `@framework` will be the alias utilized in commerce and it will map to the ecommerce provider of preference- e.g BigCommerce, Shopify, Swell. All providers should expose the same standardized functions. _Note that the same applies for recipes using a CMS + an ecommerce provider._ - -There is a `framework` folder in the root folder that will contain multiple ecommerce providers. - -Additionally, we need to ensure feature parity (not all providers have e.g. wishlist) we will also have to build a feature API to disable/enable features in the UI. - -People actively working on this project: @okbel & @lfades. -======= ->>>>>>> master - ## Framework Framework is where the data comes from. It contains mostly hooks and functions. diff --git a/pages/wishlist.tsx b/pages/wishlist.tsx index 680848e35..b4410a58c 100644 --- a/pages/wishlist.tsx +++ b/pages/wishlist.tsx @@ -6,12 +6,8 @@ import { Layout } from '@components/common' import { Heart } from '@components/icons' import { Text, Container } from '@components/ui' import { WishlistCard } from '@components/wishlist' -<<<<<<< HEAD -import { defatultPageProps } from '@lib/defaults' -import { useCustomer } from '@framework/customer' -======= import { defaultPageProps } from '@lib/defaults' ->>>>>>> master +import { useCustomer } from '@framework/customer' export async function getStaticProps({ preview, From deadb1675b3f9c7496f075340e83af1159fe7ddd Mon Sep 17 00:00:00 2001 From: Belen Curcio Date: Mon, 11 Jan 2021 12:22:18 -0300 Subject: [PATCH 023/216] Cleanup --- components/auth/LoginView.tsx | 2 +- components/auth/SignUpView.tsx | 2 +- components/common/UserNav/DropdownMenu.tsx | 3 +- .../bigcommerce/lib/generate-definitions.js | 49 ------ package.json | 3 - pages/index2.tsx | 152 ------------------ tsconfig.json | 8 +- 7 files changed, 10 insertions(+), 209 deletions(-) delete mode 100644 framework/bigcommerce/lib/generate-definitions.js delete mode 100644 pages/index2.tsx diff --git a/components/auth/LoginView.tsx b/components/auth/LoginView.tsx index 89d5bf893..7b402e6d7 100644 --- a/components/auth/LoginView.tsx +++ b/components/auth/LoginView.tsx @@ -1,6 +1,6 @@ import { FC, useEffect, useState, useCallback } from 'react' import { Logo, Button, Input } from '@components/ui' -import useLogin from '@framework/auth/use-login' +import { useLogin } from '@framework/auth' import { useUI } from '@components/ui/context' import { validate } from 'email-validator' diff --git a/components/auth/SignUpView.tsx b/components/auth/SignUpView.tsx index 1b619828b..49351bfe9 100644 --- a/components/auth/SignUpView.tsx +++ b/components/auth/SignUpView.tsx @@ -3,7 +3,7 @@ import { validate } from 'email-validator' import { Info } from '@components/icons' import { useUI } from '@components/ui/context' import { Logo, Button, Input } from '@components/ui' -import useSignup from '@framework/auth/use-signup' +import { useSignup } from '@framework/auth' interface Props {} diff --git a/components/common/UserNav/DropdownMenu.tsx b/components/common/UserNav/DropdownMenu.tsx index a5bc5fd86..f8cedc332 100644 --- a/components/common/UserNav/DropdownMenu.tsx +++ b/components/common/UserNav/DropdownMenu.tsx @@ -8,6 +8,7 @@ import { Avatar } from '@components/common' import { Moon, Sun } from '@components/icons' import { useUI } from '@components/ui/context' import ClickOutside from '@lib/click-outside' +import { useLogout } from '@framework/auth' import { disableBodyScroll, @@ -15,8 +16,6 @@ import { clearAllBodyScrollLocks, } from 'body-scroll-lock' -import useLogout from '@framework/auth/use-logout' - interface DropdownMenuProps { open?: boolean } diff --git a/framework/bigcommerce/lib/generate-definitions.js b/framework/bigcommerce/lib/generate-definitions.js deleted file mode 100644 index a2b830d3b..000000000 --- a/framework/bigcommerce/lib/generate-definitions.js +++ /dev/null @@ -1,49 +0,0 @@ -/** - * Generates definitions for REST API endpoints that are being - * used by ../api using https://github.com/drwpow/swagger-to-ts - */ -const { readFileSync, promises } = require('fs') -const path = require('path') -const fetch = require('node-fetch') -const swaggerToTS = require('@manifoldco/swagger-to-ts').default - -async function getSchema(filename) { - const url = `https://next-api.stoplight.io/projects/8433/files/${filename}` - const res = await fetch(url) - - if (!res.ok) { - throw new Error(`Request failed with ${res.status}: ${res.statusText}`) - } - - return res.json() -} - -const schemas = Object.entries({ - '../api/definitions/catalog.ts': - 'BigCommerce_Catalog_API.oas2.yml?ref=version%2F20.930', - '../api/definitions/store-content.ts': - 'BigCommerce_Store_Content_API.oas2.yml?ref=version%2F20.930', - '../api/definitions/wishlist.ts': - 'BigCommerce_Wishlist_API.oas2.yml?ref=version%2F20.930', - // swagger-to-ts is not working for the schema of the cart API - // '../api/definitions/cart.ts': - // 'BigCommerce_Server_to_Server_Cart_API.oas2.yml', -}) - -async function writeDefinitions() { - const ops = schemas.map(async ([dest, filename]) => { - const destination = path.join(__dirname, dest) - const schema = await getSchema(filename) - const definition = swaggerToTS(schema.content, { - prettierConfig: 'package.json', - }) - - await promises.writeFile(destination, definition) - - console.log(`✔️ Added definitions for: ${dest}`) - }) - - await Promise.all(ops) -} - -writeDefinitions() diff --git a/package.json b/package.json index dd78af9ba..b90bf4cf8 100644 --- a/package.json +++ b/package.json @@ -46,9 +46,7 @@ "dependencies": { "@reach/portal": "^0.11.2", "@tailwindcss/ui": "^0.6.2", - "@types/node-fetch": "2", "@vercel/fetch": "^6.1.0", - "@vercel/fetch-cached-dns": "^2.0.1", "body-scroll-lock": "^3.1.5", "bowser": "^2.11.0", "classnames": "^2.2.6", @@ -62,7 +60,6 @@ "next": "^10.0.5-canary.11", "next-seo": "^4.11.0", "next-themes": "^0.0.4", - "node-fetch": "^2.6.1", "postcss-nesting": "^7.0.1", "react": "^16.14.0", "react-dom": "^16.14.0", diff --git a/pages/index2.tsx b/pages/index2.tsx deleted file mode 100644 index ef1c0a96e..000000000 --- a/pages/index2.tsx +++ /dev/null @@ -1,152 +0,0 @@ -import rangeMap from '@lib/range-map' -import { Layout } from '@components/common' -import { ProductCard } from '@components/product' -import { Grid, Marquee, Hero } from '@components/ui' -import HomeAllProductsGrid from '@components/common/HomeAllProductsGrid' -import type { GetStaticPropsContext, InferGetStaticPropsType } from 'next' - -import { getConfig } from '@framework/api' -import getAllProducts from '@framework/api/operations/get-all-products' -import getSiteInfo from '@framework/api/operations/get-site-info' -import getAllPages from '@framework/api/operations/get-all-pages' - -export async function getStaticProps({ - preview, - locale, -}: GetStaticPropsContext) { - const config = getConfig({ locale }) - - // Get Featured Products - const { products: featuredProducts } = await getAllProducts({ - variables: { field: 'featuredProducts', first: 6 }, - config, - preview, - }) - - // Get Best Selling Products - const { products: bestSellingProducts } = await getAllProducts({ - variables: { field: 'bestSellingProducts', first: 6 }, - config, - preview, - }) - - // Get Best Newest Products - const { products: newestProducts } = await getAllProducts({ - variables: { field: 'newestProducts', first: 12 }, - config, - preview, - }) - - const { categories, brands } = await getSiteInfo({ config, preview }) - const { pages } = await getAllPages({ config, preview }) - - // These are the products that are going to be displayed in the landing. - // We prefer to do the computation at buildtime/servertime - const { featured, bestSelling } = (() => { - // Create a copy of products that we can mutate - const products = [...newestProducts] - // If the lists of featured and best selling products don't have enough - // products, then fill them with products from the products list, this - // is useful for new commerce sites that don't have a lot of products - return { - featured: rangeMap(6, (i) => featuredProducts[i] ?? products.shift()) - .filter(nonNullable) - .sort((a, b) => a.node.prices.price.value - b.node.prices.price.value) - .reverse(), - bestSelling: rangeMap( - 6, - (i) => bestSellingProducts[i] ?? products.shift() - ).filter(nonNullable), - } - })() - - return { - props: { - featured, - bestSelling, - newestProducts, - categories, - brands, - pages, - }, - revalidate: 14400, - } -} - -const nonNullable = (v: any) => v - -export default function Home({ - featured, - bestSelling, - brands, - categories, - newestProducts, -}: InferGetStaticPropsType) { - return ( -
- - {featured.slice(0, 3).map(({ node }, i) => ( - - ))} - - - {bestSelling.slice(3, 6).map(({ node }) => ( - - ))} - - - - {featured.slice(3, 6).map(({ node }, i) => ( - - ))} - - - {bestSelling.slice(0, 3).map(({ node }) => ( - - ))} - - -
- ) -} - -Home.Layout = Layout diff --git a/tsconfig.json b/tsconfig.json index 43dfd2a27..480cc2cb4 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -26,6 +26,12 @@ "@framework": ["framework/bigcommerce"] } }, - "include": ["next-env.d.ts", "**/*.d.ts", "**/*.ts", "**/*.tsx", "**/*.js"], + "include": [ + "next-env.d.ts", + "framework/*.d.ts", + "**/*.ts", + "**/*.tsx", + "**/*.js" + ], "exclude": ["node_modules"] } From a3a2c15f70d238332afbeea34ac520cc457ff930 Mon Sep 17 00:00:00 2001 From: Belen Curcio Date: Mon, 11 Jan 2021 12:26:34 -0300 Subject: [PATCH 024/216] change --- framework/bigcommerce/lib/normalize.ts | 4 +- yarn.lock | 7728 ++++++++++++++++++++++++ 2 files changed, 7729 insertions(+), 3 deletions(-) create mode 100644 yarn.lock diff --git a/framework/bigcommerce/lib/normalize.ts b/framework/bigcommerce/lib/normalize.ts index 7d938c643..51b508edd 100644 --- a/framework/bigcommerce/lib/normalize.ts +++ b/framework/bigcommerce/lib/normalize.ts @@ -1,6 +1,4 @@ -import { ProductEdge } from '@framework/schema' - -export function normalizeProduct(productNode: ProductEdge): Product { +export function normalizeProduct(productNode: any): Product { // console.log(productNode) const { node: { diff --git a/yarn.lock b/yarn.lock new file mode 100644 index 000000000..8e9ded267 --- /dev/null +++ b/yarn.lock @@ -0,0 +1,7728 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@ampproject/toolbox-core@2.7.4", "@ampproject/toolbox-core@^2.7.1-alpha.0": + version "2.7.4" + resolved "https://registry.yarnpkg.com/@ampproject/toolbox-core/-/toolbox-core-2.7.4.tgz#8355136f16301458ce942acf6c55952c9a415627" + integrity sha512-qpBhcS4urB7IKc+jx2kksN7BuvvwCo7Y3IstapWo+EW+COY5EYAUwb2pil37v3TsaqHKgX//NloFP1SKzGZAnw== + dependencies: + cross-fetch "3.0.6" + lru-cache "6.0.0" + +"@ampproject/toolbox-optimizer@2.7.1-alpha.0": + version "2.7.1-alpha.0" + resolved "https://registry.yarnpkg.com/@ampproject/toolbox-optimizer/-/toolbox-optimizer-2.7.1-alpha.0.tgz#1571dcd02608223ff68f6b7223102a123e381197" + integrity sha512-WGPZKVQvHgNYJk1XVJCCmY+NVGTGJtvn0OALDyiegN4FJWOcilQUhCIcjMkZN59u1flz/u+sEKccM5qsROqVyg== + dependencies: + "@ampproject/toolbox-core" "^2.7.1-alpha.0" + "@ampproject/toolbox-runtime-version" "^2.7.1-alpha.0" + "@ampproject/toolbox-script-csp" "^2.5.4" + "@ampproject/toolbox-validator-rules" "^2.7.1-alpha.0" + abort-controller "3.0.0" + cross-fetch "3.0.6" + cssnano-simple "1.2.1" + dom-serializer "1.1.0" + domhandler "3.3.0" + domutils "2.4.2" + htmlparser2 "5.0.1" + https-proxy-agent "5.0.0" + lru-cache "6.0.0" + node-fetch "2.6.1" + normalize-html-whitespace "1.0.0" + postcss "7.0.32" + postcss-safe-parser "4.0.2" + terser "5.5.1" + +"@ampproject/toolbox-runtime-version@^2.7.1-alpha.0": + version "2.7.4" + resolved "https://registry.yarnpkg.com/@ampproject/toolbox-runtime-version/-/toolbox-runtime-version-2.7.4.tgz#f49da0dab122101ef75ed3caed3a0142487b73e1" + integrity sha512-SAdOUOERp42thVNWaBJlnFvFVvnacMVnz5z9LyUZHSnoL1EqrAW5Sz5jv+Ly+gkA8NYsEaUxAdSCBAzE9Uzb4Q== + dependencies: + "@ampproject/toolbox-core" "2.7.4" + +"@ampproject/toolbox-script-csp@^2.5.4": + version "2.5.4" + resolved "https://registry.yarnpkg.com/@ampproject/toolbox-script-csp/-/toolbox-script-csp-2.5.4.tgz#d8b7b91a678ae8f263cb36d9b74e441b7d633aad" + integrity sha512-+knTYetI5nWllRZ9wFcj7mYxelkiiFVRAAW/hl0ad8EnKHMH82tRlk40CapEnUHhp6Er5sCYkumQ8dngs3Q4zQ== + +"@ampproject/toolbox-validator-rules@^2.7.1-alpha.0": + version "2.7.4" + resolved "https://registry.yarnpkg.com/@ampproject/toolbox-validator-rules/-/toolbox-validator-rules-2.7.4.tgz#a58b5eca723f6c3557ac83b696de0247f5f03ce4" + integrity sha512-z3JRcpIZLLdVC9XVe7YTZuB3a/eR9s2SjElYB9AWRdyJyL5Jt7+pGNv4Uwh1uHVoBXsWEVQzNOWSNtrO3mSwZA== + dependencies: + cross-fetch "3.0.6" + +"@ardatan/aggregate-error@0.0.6": + version "0.0.6" + resolved "https://registry.yarnpkg.com/@ardatan/aggregate-error/-/aggregate-error-0.0.6.tgz#fe6924771ea40fc98dc7a7045c2e872dc8527609" + integrity sha512-vyrkEHG1jrukmzTPtyWB4NLPauUw5bQeg4uhn8f+1SSynmrOcyvlb1GKQjjgoBzElLdfXCRYX8UnBlhklOHYRQ== + dependencies: + tslib "~2.0.1" + +"@babel/code-frame@7.12.11", "@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4", "@babel/code-frame@^7.12.11": + version "7.12.11" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.12.11.tgz#f4ad435aa263db935b8f10f2c552d23fb716a63f" + integrity sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw== + dependencies: + "@babel/highlight" "^7.10.4" + +"@babel/core@^7.0.0": + version "7.12.10" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.12.10.tgz#b79a2e1b9f70ed3d84bbfb6d8c4ef825f606bccd" + integrity sha512-eTAlQKq65zHfkHZV0sIVODCPGVgoo1HdBlbSLi9CqOzuZanMv2ihzY+4paiKr1mH+XmYESMAmJ/dpZ68eN6d8w== + dependencies: + "@babel/code-frame" "^7.10.4" + "@babel/generator" "^7.12.10" + "@babel/helper-module-transforms" "^7.12.1" + "@babel/helpers" "^7.12.5" + "@babel/parser" "^7.12.10" + "@babel/template" "^7.12.7" + "@babel/traverse" "^7.12.10" + "@babel/types" "^7.12.10" + convert-source-map "^1.7.0" + debug "^4.1.0" + gensync "^1.0.0-beta.1" + json5 "^2.1.2" + lodash "^4.17.19" + semver "^5.4.1" + source-map "^0.5.0" + +"@babel/generator@^7.12.10", "@babel/generator@^7.12.11", "@babel/generator@^7.5.0": + version "7.12.11" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.12.11.tgz#98a7df7b8c358c9a37ab07a24056853016aba3af" + integrity sha512-Ggg6WPOJtSi8yYQvLVjG8F/TlpWDlKx0OpS4Kt+xMQPs5OaGYWy+v1A+1TvxI6sAMGZpKWWoAQ1DaeQbImlItA== + dependencies: + "@babel/types" "^7.12.11" + jsesc "^2.5.1" + source-map "^0.5.0" + +"@babel/helper-annotate-as-pure@^7.10.4", "@babel/helper-annotate-as-pure@^7.12.10": + version "7.12.10" + resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.12.10.tgz#54ab9b000e60a93644ce17b3f37d313aaf1d115d" + integrity sha512-XplmVbC1n+KY6jL8/fgLVXXUauDIB+lD5+GsQEh6F6GBF1dq1qy4DP4yXWzDKcoqXB3X58t61e85Fitoww4JVQ== + dependencies: + "@babel/types" "^7.12.10" + +"@babel/helper-create-class-features-plugin@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.12.1.tgz#3c45998f431edd4a9214c5f1d3ad1448a6137f6e" + integrity sha512-hkL++rWeta/OVOBTRJc9a5Azh5mt5WgZUGAKMD8JM141YsE08K//bp1unBBieO6rUKkIPyUE0USQ30jAy3Sk1w== + dependencies: + "@babel/helper-function-name" "^7.10.4" + "@babel/helper-member-expression-to-functions" "^7.12.1" + "@babel/helper-optimise-call-expression" "^7.10.4" + "@babel/helper-replace-supers" "^7.12.1" + "@babel/helper-split-export-declaration" "^7.10.4" + +"@babel/helper-define-map@^7.10.4": + version "7.10.5" + resolved "https://registry.yarnpkg.com/@babel/helper-define-map/-/helper-define-map-7.10.5.tgz#b53c10db78a640800152692b13393147acb9bb30" + integrity sha512-fMw4kgFB720aQFXSVaXr79pjjcW5puTCM16+rECJ/plGS+zByelE8l9nCpV1GibxTnFVmUuYG9U8wYfQHdzOEQ== + dependencies: + "@babel/helper-function-name" "^7.10.4" + "@babel/types" "^7.10.5" + lodash "^4.17.19" + +"@babel/helper-function-name@^7.10.4", "@babel/helper-function-name@^7.12.11": + version "7.12.11" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.12.11.tgz#1fd7738aee5dcf53c3ecff24f1da9c511ec47b42" + integrity sha512-AtQKjtYNolKNi6nNNVLQ27CP6D9oFR6bq/HPYSizlzbp7uC1M59XJe8L+0uXjbIaZaUJF99ruHqVGiKXU/7ybA== + dependencies: + "@babel/helper-get-function-arity" "^7.12.10" + "@babel/template" "^7.12.7" + "@babel/types" "^7.12.11" + +"@babel/helper-get-function-arity@^7.12.10": + version "7.12.10" + resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.10.tgz#b158817a3165b5faa2047825dfa61970ddcc16cf" + integrity sha512-mm0n5BPjR06wh9mPQaDdXWDoll/j5UpCAPl1x8fS71GHm7HA6Ua2V4ylG1Ju8lvcTOietbPNNPaSilKj+pj+Ag== + dependencies: + "@babel/types" "^7.12.10" + +"@babel/helper-member-expression-to-functions@^7.12.1", "@babel/helper-member-expression-to-functions@^7.12.7": + version "7.12.7" + resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.12.7.tgz#aa77bd0396ec8114e5e30787efa78599d874a855" + integrity sha512-DCsuPyeWxeHgh1Dus7APn7iza42i/qXqiFPWyBDdOFtvS581JQePsc1F/nD+fHrcswhLlRc2UpYS1NwERxZhHw== + dependencies: + "@babel/types" "^7.12.7" + +"@babel/helper-module-imports@^7.12.1", "@babel/helper-module-imports@^7.12.5": + version "7.12.5" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.12.5.tgz#1bfc0229f794988f76ed0a4d4e90860850b54dfb" + integrity sha512-SR713Ogqg6++uexFRORf/+nPXMmWIn80TALu0uaFb+iQIUoR7bOC7zBWyzBs5b3tBBJXuyD0cRu1F15GyzjOWA== + dependencies: + "@babel/types" "^7.12.5" + +"@babel/helper-module-transforms@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.12.1.tgz#7954fec71f5b32c48e4b303b437c34453fd7247c" + integrity sha512-QQzehgFAZ2bbISiCpmVGfiGux8YVFXQ0abBic2Envhej22DVXV9nCFaS5hIQbkyo1AdGb+gNME2TSh3hYJVV/w== + dependencies: + "@babel/helper-module-imports" "^7.12.1" + "@babel/helper-replace-supers" "^7.12.1" + "@babel/helper-simple-access" "^7.12.1" + "@babel/helper-split-export-declaration" "^7.11.0" + "@babel/helper-validator-identifier" "^7.10.4" + "@babel/template" "^7.10.4" + "@babel/traverse" "^7.12.1" + "@babel/types" "^7.12.1" + lodash "^4.17.19" + +"@babel/helper-optimise-call-expression@^7.10.4", "@babel/helper-optimise-call-expression@^7.12.10": + version "7.12.10" + resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.10.tgz#94ca4e306ee11a7dd6e9f42823e2ac6b49881e2d" + integrity sha512-4tpbU0SrSTjjt65UMWSrUOPZTsgvPgGG4S8QSTNHacKzpS51IVWGDj0yCwyeZND/i+LSN2g/O63jEXEWm49sYQ== + dependencies: + "@babel/types" "^7.12.10" + +"@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.8.0": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz#2f75a831269d4f677de49986dff59927533cf375" + integrity sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg== + +"@babel/helper-replace-supers@^7.12.1": + version "7.12.11" + resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.12.11.tgz#ea511658fc66c7908f923106dd88e08d1997d60d" + integrity sha512-q+w1cqmhL7R0FNzth/PLLp2N+scXEK/L2AHbXUyydxp828F4FEa5WcVoqui9vFRiHDQErj9Zof8azP32uGVTRA== + dependencies: + "@babel/helper-member-expression-to-functions" "^7.12.7" + "@babel/helper-optimise-call-expression" "^7.12.10" + "@babel/traverse" "^7.12.10" + "@babel/types" "^7.12.11" + +"@babel/helper-simple-access@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.12.1.tgz#32427e5aa61547d38eb1e6eaf5fd1426fdad9136" + integrity sha512-OxBp7pMrjVewSSC8fXDFrHrBcJATOOFssZwv16F3/6Xtc138GHybBfPbm9kfiqQHKhYQrlamWILwlDCeyMFEaA== + dependencies: + "@babel/types" "^7.12.1" + +"@babel/helper-skip-transparent-expression-wrappers@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.12.1.tgz#462dc63a7e435ade8468385c63d2b84cce4b3cbf" + integrity sha512-Mf5AUuhG1/OCChOJ/HcADmvcHM42WJockombn8ATJG3OnyiSxBK/Mm5x78BQWvmtXZKHgbjdGL2kin/HOLlZGA== + dependencies: + "@babel/types" "^7.12.1" + +"@babel/helper-split-export-declaration@^7.10.4", "@babel/helper-split-export-declaration@^7.11.0", "@babel/helper-split-export-declaration@^7.12.11": + version "7.12.11" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.11.tgz#1b4cc424458643c47d37022223da33d76ea4603a" + integrity sha512-LsIVN8j48gHgwzfocYUSkO/hjYAOJqlpJEc7tGXcIm4cubjVUf8LGW6eWRyxEu7gA25q02p0rQUWoCI33HNS5g== + dependencies: + "@babel/types" "^7.12.11" + +"@babel/helper-validator-identifier@^7.10.4", "@babel/helper-validator-identifier@^7.12.11": + version "7.12.11" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz#c9a1f021917dcb5ccf0d4e453e399022981fc9ed" + integrity sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw== + +"@babel/helpers@^7.12.5": + version "7.12.5" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.12.5.tgz#1a1ba4a768d9b58310eda516c449913fe647116e" + integrity sha512-lgKGMQlKqA8meJqKsW6rUnc4MdUk35Ln0ATDqdM1a/UpARODdI4j5Y5lVfUScnSNkJcdCRAaWkspykNoFg9sJA== + dependencies: + "@babel/template" "^7.10.4" + "@babel/traverse" "^7.12.5" + "@babel/types" "^7.12.5" + +"@babel/highlight@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.10.4.tgz#7d1bdfd65753538fabe6c38596cdb76d9ac60143" + integrity sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA== + dependencies: + "@babel/helper-validator-identifier" "^7.10.4" + chalk "^2.0.0" + js-tokens "^4.0.0" + +"@babel/parser@7.12.11", "@babel/parser@^7.0.0", "@babel/parser@^7.12.0", "@babel/parser@^7.12.10", "@babel/parser@^7.12.11", "@babel/parser@^7.12.7": + version "7.12.11" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.12.11.tgz#9ce3595bcd74bc5c466905e86c535b8b25011e79" + integrity sha512-N3UxG+uuF4CMYoNj8AhnbAcJF0PiuJ9KHuy1lQmkYsxTer/MAH9UBNHsBoAX/4s6NvlDD047No8mYVGGzLL4hg== + +"@babel/plugin-proposal-class-properties@^7.0.0": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.12.1.tgz#a082ff541f2a29a4821065b8add9346c0c16e5de" + integrity sha512-cKp3dlQsFsEs5CWKnN7BnSHOd0EOW8EKpEjkoz1pO2E5KzIDNV9Ros1b0CnmbVgAGXJubOYVBOGCT1OmJwOI7w== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.12.1" + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-proposal-object-rest-spread@^7.0.0": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.12.1.tgz#def9bd03cea0f9b72283dac0ec22d289c7691069" + integrity sha512-s6SowJIjzlhx8o7lsFx5zmY4At6CTtDvgNQDdPzkBQucle58A6b/TTeEBYtyDgmcXjUTM+vE8YOGHZzzbc/ioA== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-syntax-object-rest-spread" "^7.8.0" + "@babel/plugin-transform-parameters" "^7.12.1" + +"@babel/plugin-syntax-class-properties@^7.0.0": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.1.tgz#bcb297c5366e79bebadef509549cd93b04f19978" + integrity sha512-U40A76x5gTwmESz+qiqssqmeEsKvcSyvtgktrm0uzcARAmM9I1jR221f6Oq+GmHrcD+LvZDag1UTOTe2fL3TeA== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-syntax-flow@^7.0.0", "@babel/plugin-syntax-flow@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.12.1.tgz#a77670d9abe6d63e8acadf4c31bb1eb5a506bbdd" + integrity sha512-1lBLLmtxrwpm4VKmtVFselI/P3pX+G63fAtUUt6b2Nzgao77KNDwyuRt90Mj2/9pKobtt68FdvjfqohZjg/FCA== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-syntax-jsx@^7.0.0", "@babel/plugin-syntax-jsx@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.12.1.tgz#9d9d357cc818aa7ae7935917c1257f67677a0926" + integrity sha512-1yRi7yAtB0ETgxdY9ti/p2TivUxJkTdhu/ZbF9MshVGqOx1TdB3b7xCXs49Fupgg50N45KcAsRP/ZqWjs9SRjg== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-syntax-object-rest-spread@^7.0.0", "@babel/plugin-syntax-object-rest-spread@^7.8.0": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz#60e225edcbd98a640332a2e72dd3e66f1af55871" + integrity sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-transform-arrow-functions@^7.0.0": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.12.1.tgz#8083ffc86ac8e777fbe24b5967c4b2521f3cb2b3" + integrity sha512-5QB50qyN44fzzz4/qxDPQMBCTHgxg3n0xRBLJUmBlLoU/sFvxVWGZF/ZUfMVDQuJUKXaBhbupxIzIfZ6Fwk/0A== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-transform-block-scoped-functions@^7.0.0": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.12.1.tgz#f2a1a365bde2b7112e0a6ded9067fdd7c07905d9" + integrity sha512-5OpxfuYnSgPalRpo8EWGPzIYf0lHBWORCkj5M0oLBwHdlux9Ri36QqGW3/LR13RSVOAoUUMzoPI/jpE4ABcHoA== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-transform-block-scoping@^7.0.0": + version "7.12.12" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.12.12.tgz#d93a567a152c22aea3b1929bb118d1d0a175cdca" + integrity sha512-VOEPQ/ExOVqbukuP7BYJtI5ZxxsmegTwzZ04j1aF0dkSypGo9XpDHuOrABsJu+ie+penpSJheDJ11x1BEZNiyQ== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-transform-classes@^7.0.0": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.12.1.tgz#65e650fcaddd3d88ddce67c0f834a3d436a32db6" + integrity sha512-/74xkA7bVdzQTBeSUhLLJgYIcxw/dpEpCdRDiHgPJ3Mv6uC11UhjpOhl72CgqbBCmt1qtssCyB2xnJm1+PFjog== + dependencies: + "@babel/helper-annotate-as-pure" "^7.10.4" + "@babel/helper-define-map" "^7.10.4" + "@babel/helper-function-name" "^7.10.4" + "@babel/helper-optimise-call-expression" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-replace-supers" "^7.12.1" + "@babel/helper-split-export-declaration" "^7.10.4" + globals "^11.1.0" + +"@babel/plugin-transform-computed-properties@^7.0.0": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.12.1.tgz#d68cf6c9b7f838a8a4144badbe97541ea0904852" + integrity sha512-vVUOYpPWB7BkgUWPo4C44mUQHpTZXakEqFjbv8rQMg7TC6S6ZhGZ3otQcRH6u7+adSlE5i0sp63eMC/XGffrzg== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-transform-destructuring@^7.0.0": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.12.1.tgz#b9a570fe0d0a8d460116413cb4f97e8e08b2f847" + integrity sha512-fRMYFKuzi/rSiYb2uRLiUENJOKq4Gnl+6qOv5f8z0TZXg3llUwUhsNNwrwaT/6dUhJTzNpBr+CUvEWBtfNY1cw== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-transform-flow-strip-types@^7.0.0": + version "7.12.10" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.12.10.tgz#d85e30ecfa68093825773b7b857e5085bbd32c95" + integrity sha512-0ti12wLTLeUIzu9U7kjqIn4MyOL7+Wibc7avsHhj4o1l5C0ATs8p2IMHrVYjm9t9wzhfEO6S3kxax0Rpdo8LTg== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-syntax-flow" "^7.12.1" + +"@babel/plugin-transform-for-of@^7.0.0": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.12.1.tgz#07640f28867ed16f9511c99c888291f560921cfa" + integrity sha512-Zaeq10naAsuHo7heQvyV0ptj4dlZJwZgNAtBYBnu5nNKJoW62m0zKcIEyVECrUKErkUkg6ajMy4ZfnVZciSBhg== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-transform-function-name@^7.0.0": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.12.1.tgz#2ec76258c70fe08c6d7da154003a480620eba667" + integrity sha512-JF3UgJUILoFrFMEnOJLJkRHSk6LUSXLmEFsA23aR2O5CSLUxbeUX1IZ1YQ7Sn0aXb601Ncwjx73a+FVqgcljVw== + dependencies: + "@babel/helper-function-name" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-transform-literals@^7.0.0": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.12.1.tgz#d73b803a26b37017ddf9d3bb8f4dc58bfb806f57" + integrity sha512-+PxVGA+2Ag6uGgL0A5f+9rklOnnMccwEBzwYFL3EUaKuiyVnUipyXncFcfjSkbimLrODoqki1U9XxZzTvfN7IQ== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-transform-member-expression-literals@^7.0.0": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.12.1.tgz#496038602daf1514a64d43d8e17cbb2755e0c3ad" + integrity sha512-1sxePl6z9ad0gFMB9KqmYofk34flq62aqMt9NqliS/7hPEpURUCMbyHXrMPlo282iY7nAvUB1aQd5mg79UD9Jg== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-transform-modules-commonjs@^7.0.0": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.12.1.tgz#fa403124542636c786cf9b460a0ffbb48a86e648" + integrity sha512-dY789wq6l0uLY8py9c1B48V8mVL5gZh/+PQ5ZPrylPYsnAvnEMjqsUXkuoDVPeVK+0VyGar+D08107LzDQ6pag== + dependencies: + "@babel/helper-module-transforms" "^7.12.1" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-simple-access" "^7.12.1" + babel-plugin-dynamic-import-node "^2.3.3" + +"@babel/plugin-transform-object-super@^7.0.0": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.12.1.tgz#4ea08696b8d2e65841d0c7706482b048bed1066e" + integrity sha512-AvypiGJH9hsquNUn+RXVcBdeE3KHPZexWRdimhuV59cSoOt5kFBmqlByorAeUlGG2CJWd0U+4ZtNKga/TB0cAw== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-replace-supers" "^7.12.1" + +"@babel/plugin-transform-parameters@^7.0.0", "@babel/plugin-transform-parameters@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.12.1.tgz#d2e963b038771650c922eff593799c96d853255d" + integrity sha512-xq9C5EQhdPK23ZeCdMxl8bbRnAgHFrw5EOC3KJUsSylZqdkCaFEXxGSBuTSObOpiiHHNyb82es8M1QYgfQGfNg== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-transform-property-literals@^7.0.0": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.12.1.tgz#41bc81200d730abb4456ab8b3fbd5537b59adecd" + integrity sha512-6MTCR/mZ1MQS+AwZLplX4cEySjCpnIF26ToWo942nqn8hXSm7McaHQNeGx/pt7suI1TWOWMfa/NgBhiqSnX0cQ== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-transform-react-display-name@^7.0.0": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.12.1.tgz#1cbcd0c3b1d6648c55374a22fc9b6b7e5341c00d" + integrity sha512-cAzB+UzBIrekfYxyLlFqf/OagTvHLcVBb5vpouzkYkBclRPraiygVnafvAoipErZLI8ANv8Ecn6E/m5qPXD26w== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-transform-react-jsx@^7.0.0": + version "7.12.12" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.12.12.tgz#b0da51ffe5f34b9a900e9f1f5fb814f9e512d25e" + integrity sha512-JDWGuzGNWscYcq8oJVCtSE61a5+XAOos+V0HrxnDieUus4UMnBEosDnY1VJqU5iZ4pA04QY7l0+JvHL1hZEfsw== + dependencies: + "@babel/helper-annotate-as-pure" "^7.12.10" + "@babel/helper-module-imports" "^7.12.5" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-syntax-jsx" "^7.12.1" + "@babel/types" "^7.12.12" + +"@babel/plugin-transform-shorthand-properties@^7.0.0": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.12.1.tgz#0bf9cac5550fce0cfdf043420f661d645fdc75e3" + integrity sha512-GFZS3c/MhX1OusqB1MZ1ct2xRzX5ppQh2JU1h2Pnfk88HtFTM+TWQqJNfwkmxtPQtb/s1tk87oENfXJlx7rSDw== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-transform-spread@^7.0.0": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.12.1.tgz#527f9f311be4ec7fdc2b79bb89f7bf884b3e1e1e" + integrity sha512-vuLp8CP0BE18zVYjsEBZ5xoCecMK6LBMMxYzJnh01rxQRvhNhH1csMMmBfNo5tGpGO+NhdSNW2mzIvBu3K1fng== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-skip-transparent-expression-wrappers" "^7.12.1" + +"@babel/plugin-transform-template-literals@^7.0.0": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.12.1.tgz#b43ece6ed9a79c0c71119f576d299ef09d942843" + integrity sha512-b4Zx3KHi+taXB1dVRBhVJtEPi9h1THCeKmae2qP0YdUHIFhVjtpqqNfxeVAa1xeHVhAy4SbHxEwx5cltAu5apw== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/runtime@7.12.5", "@babel/runtime@^7.0.0": + version "7.12.5" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.12.5.tgz#410e7e487441e1b360c29be715d870d9b985882e" + integrity sha512-plcc+hbExy3McchJCEQG3knOsuh3HH+Prx1P6cLIkET/0dLuQDEnrT+s27Axgc9bqfsmNUNHfscgMUdBpC9xfg== + dependencies: + regenerator-runtime "^0.13.4" + +"@babel/template@^7.10.4", "@babel/template@^7.12.7": + version "7.12.7" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.12.7.tgz#c817233696018e39fbb6c491d2fb684e05ed43bc" + integrity sha512-GkDzmHS6GV7ZeXfJZ0tLRBhZcMcY0/Lnb+eEbXDBfCAcZCjrZKe6p3J4we/D24O9Y8enxWAg1cWwof59yLh2ow== + dependencies: + "@babel/code-frame" "^7.10.4" + "@babel/parser" "^7.12.7" + "@babel/types" "^7.12.7" + +"@babel/traverse@7.12.12", "@babel/traverse@^7.0.0", "@babel/traverse@^7.12.1", "@babel/traverse@^7.12.10", "@babel/traverse@^7.12.5": + version "7.12.12" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.12.12.tgz#d0cd87892704edd8da002d674bc811ce64743376" + integrity sha512-s88i0X0lPy45RrLM8b9mz8RPH5FqO9G9p7ti59cToE44xFm1Q+Pjh5Gq4SXBbtb88X7Uy7pexeqRIQDDMNkL0w== + dependencies: + "@babel/code-frame" "^7.12.11" + "@babel/generator" "^7.12.11" + "@babel/helper-function-name" "^7.12.11" + "@babel/helper-split-export-declaration" "^7.12.11" + "@babel/parser" "^7.12.11" + "@babel/types" "^7.12.12" + debug "^4.1.0" + globals "^11.1.0" + lodash "^4.17.19" + +"@babel/types@7.12.12", "@babel/types@^7.0.0", "@babel/types@^7.10.5", "@babel/types@^7.12.0", "@babel/types@^7.12.1", "@babel/types@^7.12.10", "@babel/types@^7.12.11", "@babel/types@^7.12.12", "@babel/types@^7.12.5", "@babel/types@^7.12.7": + version "7.12.12" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.12.12.tgz#4608a6ec313abbd87afa55004d373ad04a96c299" + integrity sha512-lnIX7piTxOH22xE7fDXDbSHg9MM1/6ORnafpJmov5rs0kX5g4BZxeXNJLXsMRiO0U5Rb8/FvMS6xlTnTHvxonQ== + dependencies: + "@babel/helper-validator-identifier" "^7.12.11" + lodash "^4.17.19" + to-fast-properties "^2.0.0" + +"@babel/types@7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.8.3.tgz#5a383dffa5416db1b73dedffd311ffd0788fb31c" + integrity sha512-jBD+G8+LWpMBBWvVcdr4QysjUE4mU/syrhN17o1u3gx0/WzJB1kwiVZAXRtWbsIPOwW8pF/YJV5+nmetPzepXg== + dependencies: + esutils "^2.0.2" + lodash "^4.17.13" + to-fast-properties "^2.0.0" + +"@csstools/convert-colors@^1.4.0": + version "1.4.0" + resolved "https://registry.yarnpkg.com/@csstools/convert-colors/-/convert-colors-1.4.0.tgz#ad495dc41b12e75d588c6db8b9834f08fa131eb7" + integrity sha512-5a6wqoJV/xEdbRNKVo6I4hO3VjyDq//8q2f9I6PBAvMesJHFauXDorcNCsr9RzvsZnaWi5NYCcfyqP1QeFHFbw== + +"@endemolshinegroup/cosmiconfig-typescript-loader@3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@endemolshinegroup/cosmiconfig-typescript-loader/-/cosmiconfig-typescript-loader-3.0.2.tgz#eea4635828dde372838b0909693ebd9aafeec22d" + integrity sha512-QRVtqJuS1mcT56oHpVegkKBlgtWjXw/gHNWO3eL9oyB5Sc7HBoc2OLG/nYpVfT/Jejvo3NUrD0Udk7XgoyDKkA== + dependencies: + lodash.get "^4" + make-error "^1" + ts-node "^9" + tslib "^2" + +"@fullhuman/postcss-purgecss@^2.1.2": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@fullhuman/postcss-purgecss/-/postcss-purgecss-2.3.0.tgz#50a954757ec78696615d3e118e3fee2d9291882e" + integrity sha512-qnKm5dIOyPGJ70kPZ5jiz0I9foVOic0j+cOzNDoo8KoCf6HjicIZ99UfO2OmE7vCYSKAAepEwJtNzpiiZAh9xw== + dependencies: + postcss "7.0.32" + purgecss "^2.3.0" + +"@graphql-codegen/cli@^1.20.0": + version "1.20.0" + resolved "https://registry.yarnpkg.com/@graphql-codegen/cli/-/cli-1.20.0.tgz#e1bb62fce07caaf1395ca6e94ffc0f2ba1f57938" + integrity sha512-5pLtZoaqEmEui6PR7IArmD23VLD3++UQby6iNe4NFG4eMcRai2raIM0E4a/MSn7SjyfSRguekYMMC5JKS1VgQw== + dependencies: + "@graphql-codegen/core" "1.17.9" + "@graphql-codegen/plugin-helpers" "^1.18.2" + "@graphql-tools/apollo-engine-loader" "^6" + "@graphql-tools/code-file-loader" "^6" + "@graphql-tools/git-loader" "^6" + "@graphql-tools/github-loader" "^6" + "@graphql-tools/graphql-file-loader" "^6" + "@graphql-tools/json-file-loader" "^6" + "@graphql-tools/load" "^6" + "@graphql-tools/prisma-loader" "^6" + "@graphql-tools/url-loader" "^6" + "@graphql-tools/utils" "^7.0.0" + ansi-escapes "^4.3.1" + camel-case "^4.1.2" + chalk "^4.1.0" + chokidar "^3.4.3" + common-tags "^1.8.0" + constant-case "^3.0.3" + cosmiconfig "^7.0.0" + debounce "^1.2.0" + dependency-graph "^0.9.0" + detect-indent "^6.0.0" + glob "^7.1.6" + graphql-config "^3.2.0" + indent-string "^4.0.0" + inquirer "^7.3.3" + is-glob "^4.0.1" + json-to-pretty-yaml "^1.2.2" + latest-version "5.1.0" + listr "^0.14.3" + listr-update-renderer "^0.5.0" + log-symbols "^4.0.0" + lower-case "^2.0.1" + minimatch "^3.0.4" + mkdirp "^1.0.4" + pascal-case "^3.1.1" + request "^2.88.2" + string-env-interpolation "^1.0.1" + ts-log "^2.2.3" + tslib "~2.0.1" + upper-case "^2.0.2" + valid-url "^1.0.9" + wrap-ansi "^7.0.0" + yaml "^1.10.0" + yargs "^16.1.1" + +"@graphql-codegen/core@1.17.9": + version "1.17.9" + resolved "https://registry.yarnpkg.com/@graphql-codegen/core/-/core-1.17.9.tgz#c03e71018ff04d26f5139a2d90a32b31d3bb2b43" + integrity sha512-7nwy+bMWqb0iYJ2DKxA9UiE16meeJ2Ch2XWS/N/ZnA0snTR+GZ20USI8z6YqP1Fuist7LvGO1MbitO2qBT8raA== + dependencies: + "@graphql-codegen/plugin-helpers" "^1.18.2" + "@graphql-tools/merge" "^6" + "@graphql-tools/utils" "^6" + tslib "~2.0.1" + +"@graphql-codegen/plugin-helpers@^1.18.2": + version "1.18.2" + resolved "https://registry.yarnpkg.com/@graphql-codegen/plugin-helpers/-/plugin-helpers-1.18.2.tgz#57011076cb8b8f5d04d37d226a5eda300c01be94" + integrity sha512-SvX+Ryq2naLcoD6jJNxtzc/moWTgHJ+X0KRfvhGWTa+xtFTS02i+PWOR89YYPcD8+LF6GmyFBjx2FmLCx4JwMg== + dependencies: + "@graphql-tools/utils" "^6" + camel-case "4.1.1" + common-tags "1.8.0" + constant-case "3.0.3" + import-from "3.0.0" + lodash "~4.17.20" + lower-case "2.0.1" + param-case "3.0.3" + pascal-case "3.1.1" + tslib "~2.0.1" + upper-case "2.0.1" + +"@graphql-codegen/schema-ast@^1.18.1": + version "1.18.1" + resolved "https://registry.yarnpkg.com/@graphql-codegen/schema-ast/-/schema-ast-1.18.1.tgz#4081741b940944f883eec26f031840283f877210" + integrity sha512-uBVPqDZVvV1i1mBTp+DQldBO5AO4PAetZrAJJhQk5gaYxvKlf7YZWRT2WFwRdH1GEdU35tRxUX8XKSkxaKct/w== + dependencies: + "@graphql-codegen/plugin-helpers" "^1.18.2" + "@graphql-tools/utils" "^6" + tslib "~2.0.1" + +"@graphql-codegen/typescript-operations@^1.17.13": + version "1.17.13" + resolved "https://registry.yarnpkg.com/@graphql-codegen/typescript-operations/-/typescript-operations-1.17.13.tgz#a5b08c1573b9507ca5a9e66e795aecc40ddc5305" + integrity sha512-Wm/S4pmPy+KPvFVpygNwC4pd9zKtGIwnS+2rlMUBZVSpv4fxjX2YDvYHP/gucck+SiS0RRxB7hW65bTwCns46g== + dependencies: + "@graphql-codegen/plugin-helpers" "^1.18.2" + "@graphql-codegen/typescript" "^1.18.1" + "@graphql-codegen/visitor-plugin-common" "^1.17.22" + auto-bind "~4.0.0" + tslib "~2.0.1" + +"@graphql-codegen/typescript@^1.18.1", "@graphql-codegen/typescript@^1.19.0": + version "1.20.0" + resolved "https://registry.yarnpkg.com/@graphql-codegen/typescript/-/typescript-1.20.0.tgz#f9a17b869e5691276965a56c7a1efe4eb938b6e7" + integrity sha512-7xW+n0USNpr6iZ4Et17ZbPzBLNe/LrSgrQ6V/8Mlgp1reQWAZtoVw13Oq4GnxHCzAYio8nFindLl+emW9ZBeew== + dependencies: + "@graphql-codegen/plugin-helpers" "^1.18.2" + "@graphql-codegen/visitor-plugin-common" "^1.18.0" + auto-bind "~4.0.0" + tslib "~2.0.1" + +"@graphql-codegen/visitor-plugin-common@^1.17.22", "@graphql-codegen/visitor-plugin-common@^1.18.0": + version "1.18.0" + resolved "https://registry.yarnpkg.com/@graphql-codegen/visitor-plugin-common/-/visitor-plugin-common-1.18.0.tgz#f4366ec1093c01e752e85f8bd30d09c58b1d6951" + integrity sha512-OR/Cm9nVaqMLe94Ski60UDhaAf/4+QeV/CQRYrCmxFzEsm03U41VplcNgJBXIAB3EgP/LEIZtgkRc1H4N9u9+Q== + dependencies: + "@graphql-codegen/plugin-helpers" "^1.18.2" + "@graphql-tools/optimize" "^1.0.1" + "@graphql-tools/relay-operation-optimizer" "^6" + array.prototype.flatmap "^1.2.4" + auto-bind "~4.0.0" + dependency-graph "^0.9.0" + graphql-tag "^2.11.0" + parse-filepath "^1.0.2" + pascal-case "^3.1.1" + tslib "~2.0.1" + +"@graphql-tools/apollo-engine-loader@^6": + version "6.2.5" + resolved "https://registry.yarnpkg.com/@graphql-tools/apollo-engine-loader/-/apollo-engine-loader-6.2.5.tgz#b9e65744f522bb9f6ca50651e5622820c4f059a8" + integrity sha512-CE4uef6PyxtSG+7OnLklIr2BZZDgjO89ZXK47EKdY7jQy/BQD/9o+8SxPsgiBc+2NsDJH2I6P/nqoaJMOEat6g== + dependencies: + "@graphql-tools/utils" "^7.0.0" + cross-fetch "3.0.6" + tslib "~2.0.1" + +"@graphql-tools/batch-execute@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@graphql-tools/batch-execute/-/batch-execute-7.0.0.tgz#e79d11bd5b39f29172f6ec2eafa71103c6a6c85b" + integrity sha512-+ywPfK6N2Ddna6oOa5Qb1Mv7EA8LOwRNOAPP9dL37FEhksJM9pYqPSceUcqMqg7S9b0+Cgr78s408rgvurV3/Q== + dependencies: + "@graphql-tools/utils" "^7.0.0" + dataloader "2.0.0" + is-promise "4.0.0" + tslib "~2.0.1" + +"@graphql-tools/code-file-loader@^6": + version "6.2.6" + resolved "https://registry.yarnpkg.com/@graphql-tools/code-file-loader/-/code-file-loader-6.2.6.tgz#f89ffb1a5ca48c67dcf2cff97e1a5d06eabc81c2" + integrity sha512-oDuMiXy1Rj1KszY7no+PFNzw2H25PVJKg9K/deK+IHL1631Q+VLK6/czBIw4TMEsbYhlKErgWDI+XBzK73VZSQ== + dependencies: + "@graphql-tools/graphql-tag-pluck" "^6.2.6" + "@graphql-tools/utils" "^7.0.0" + tslib "~2.0.1" + +"@graphql-tools/delegate@^7.0.1", "@graphql-tools/delegate@^7.0.7": + version "7.0.8" + resolved "https://registry.yarnpkg.com/@graphql-tools/delegate/-/delegate-7.0.8.tgz#72254c92d4254c4f8477a36f7e6c61b48265dcd5" + integrity sha512-pS1wci7ZxzdCITRrMI66UA+6/E0Z1Yczd3QxJBDb4Kp0nTGy1xy7enGa0+i55EmCvKvuwyx+tzXzwA1fNGRJzg== + dependencies: + "@ardatan/aggregate-error" "0.0.6" + "@graphql-tools/batch-execute" "^7.0.0" + "@graphql-tools/schema" "^7.0.0" + "@graphql-tools/utils" "^7.1.6" + dataloader "2.0.0" + is-promise "4.0.0" + tslib "~2.0.1" + +"@graphql-tools/git-loader@^6": + version "6.2.5" + resolved "https://registry.yarnpkg.com/@graphql-tools/git-loader/-/git-loader-6.2.5.tgz#a4b3e8826964e1752a3d3a5a33a44b70b9694353" + integrity sha512-WOQDSzazyPZMZUvymHBv5oZ80/mS7tc8XUNy2GmU5My8YRny5zu4fEgP4vQeFcD1trG3uoHUaJPGF7Mmvp6Yhg== + dependencies: + "@graphql-tools/graphql-tag-pluck" "^6.2.6" + "@graphql-tools/utils" "^7.0.0" + tslib "~2.0.1" + +"@graphql-tools/github-loader@^6": + version "6.2.5" + resolved "https://registry.yarnpkg.com/@graphql-tools/github-loader/-/github-loader-6.2.5.tgz#460dff6f5bbaa26957a5ea3be4f452b89cc6a44b" + integrity sha512-DLuQmYeNNdPo8oWus8EePxWCfCAyUXPZ/p1PWqjrX/NGPyH2ZObdqtDAfRHztljt0F/qkBHbGHCEk2TKbRZTRw== + dependencies: + "@graphql-tools/graphql-tag-pluck" "^6.2.6" + "@graphql-tools/utils" "^7.0.0" + cross-fetch "3.0.6" + tslib "~2.0.1" + +"@graphql-tools/graphql-file-loader@^6", "@graphql-tools/graphql-file-loader@^6.0.0": + version "6.2.6" + resolved "https://registry.yarnpkg.com/@graphql-tools/graphql-file-loader/-/graphql-file-loader-6.2.6.tgz#5b907d21b0f947df892ed837db74cd3f6d771c34" + integrity sha512-L+RdYl5C6+X0zdOTUotY0K5zwqvSGpqI/qcZpVvCDenoAcVTyaNLmnd/ViErwedhCaGqAAV0wI1nPtyKFPlMUg== + dependencies: + "@graphql-tools/import" "^6.2.5" + "@graphql-tools/utils" "^7.0.0" + tslib "~2.0.1" + +"@graphql-tools/graphql-tag-pluck@^6.2.6": + version "6.4.0" + resolved "https://registry.yarnpkg.com/@graphql-tools/graphql-tag-pluck/-/graphql-tag-pluck-6.4.0.tgz#f8303606f717174a1068501294805b3304417145" + integrity sha512-qBQ0ITgMkUzxz5QsZk9HsSeOQo6KlXd/Ex5cePzPuRT72odPEQXNL9hCsxaCvZO9r3in8bmG6OTWs4ms/GevXA== + dependencies: + "@babel/parser" "7.12.11" + "@babel/traverse" "7.12.12" + "@babel/types" "7.12.12" + "@graphql-tools/utils" "^7.0.0" + tslib "~2.1.0" + optionalDependencies: + "@vue/compiler-sfc" "^3.0.4" + +"@graphql-tools/import@^6.2.5": + version "6.2.5" + resolved "https://registry.yarnpkg.com/@graphql-tools/import/-/import-6.2.5.tgz#5f279815229320128a07cad188c4860be18cb422" + integrity sha512-ZGXT5tDod7m+LO38fc+o0JzR1LstL0RF35HKEWoUdxRIVaaeYH9VMuan9Gn+9M9RDME3RnzEa9aGzf9ATj8bTA== + dependencies: + resolve-from "5.0.0" + tslib "~2.0.1" + +"@graphql-tools/json-file-loader@^6", "@graphql-tools/json-file-loader@^6.0.0": + version "6.2.6" + resolved "https://registry.yarnpkg.com/@graphql-tools/json-file-loader/-/json-file-loader-6.2.6.tgz#830482cfd3721a0799cbf2fe5b09959d9332739a" + integrity sha512-CnfwBSY5926zyb6fkDBHnlTblHnHI4hoBALFYXnrg0Ev4yWU8B04DZl/pBRUc459VNgO2x8/mxGIZj2hPJG1EA== + dependencies: + "@graphql-tools/utils" "^7.0.0" + tslib "~2.0.1" + +"@graphql-tools/load@^6", "@graphql-tools/load@^6.0.0": + version "6.2.5" + resolved "https://registry.yarnpkg.com/@graphql-tools/load/-/load-6.2.5.tgz#7dd0d34c8ce2cfb24f61c6beba2817d9afdd7f2b" + integrity sha512-TpDgp+id0hhD1iMhdFSgWgWumdI/IpFWwouJeaEhEEAEBkdvH4W9gbBiJBSbPQwMPRNWx8/AZtry0cYKLW4lHg== + dependencies: + "@graphql-tools/merge" "^6.2.5" + "@graphql-tools/utils" "^7.0.0" + globby "11.0.1" + import-from "3.0.0" + is-glob "4.0.1" + p-limit "3.0.2" + tslib "~2.0.1" + unixify "1.0.0" + valid-url "1.0.9" + +"@graphql-tools/merge@^6", "@graphql-tools/merge@^6.0.0", "@graphql-tools/merge@^6.2.5": + version "6.2.6" + resolved "https://registry.yarnpkg.com/@graphql-tools/merge/-/merge-6.2.6.tgz#f10b8958523687440536ecf166f2959d2f094d0f" + integrity sha512-G6x0QlIzFHoJ3dyF9a4gxmBtaEYJ+EoAAGqXHsE/drRr58K1jscQdfKZdF1wZWZgxkgakHqgt1+oFMeQg/O6ug== + dependencies: + "@graphql-tools/schema" "^7.0.0" + "@graphql-tools/utils" "^7.0.0" + tslib "~2.0.1" + +"@graphql-tools/optimize@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@graphql-tools/optimize/-/optimize-1.0.1.tgz#9933fffc5a3c63f95102b1cb6076fb16ac7bb22d" + integrity sha512-cRlUNsbErYoBtzzS6zXahXeTBZGPVlPHXCpnEZ0XiK/KY/sQL96cyzak0fM/Gk6qEI9/l32MYEICjasiBQrl5w== + dependencies: + tslib "~2.0.1" + +"@graphql-tools/prisma-loader@^6": + version "6.2.7" + resolved "https://registry.yarnpkg.com/@graphql-tools/prisma-loader/-/prisma-loader-6.2.7.tgz#0a9aa8f40c79a926f2d4f157dc282478bccafaca" + integrity sha512-o0QHl767uaLZVjb9NlupZjCzjfC5Zo79G6QLnK0Rbi0Ldk5Lf05HDZIfMhiyd9tsw73d0GQY7yIPvQJFE2S5Tw== + dependencies: + "@graphql-tools/url-loader" "^6.3.1" + "@graphql-tools/utils" "^7.0.0" + "@types/http-proxy-agent" "^2.0.2" + "@types/js-yaml" "^3.12.5" + "@types/json-stable-stringify" "^1.0.32" + "@types/jsonwebtoken" "^8.5.0" + ajv "^6.12.6" + bluebird "^3.7.2" + chalk "^4.1.0" + debug "^4.2.0" + dotenv "^8.2.0" + graphql-request "^3.3.0" + http-proxy-agent "^4.0.1" + https-proxy-agent "^5.0.0" + isomorphic-fetch "^3.0.0" + js-yaml "^3.14.0" + json-stable-stringify "^1.0.1" + jsonwebtoken "^8.5.1" + lodash "^4.17.20" + replaceall "^0.1.6" + scuid "^1.1.0" + tslib "~2.0.1" + yaml-ast-parser "^0.0.43" + +"@graphql-tools/relay-operation-optimizer@^6": + version "6.3.0" + resolved "https://registry.yarnpkg.com/@graphql-tools/relay-operation-optimizer/-/relay-operation-optimizer-6.3.0.tgz#f8c7f6c8aa4a9cf50ab151fbc5db4f4282a79532" + integrity sha512-Or3UgRvkY9Fq1AAx7q38oPqFmTepLz7kp6wDHKyR0ceG7AvHv5En22R12mAeISInbhff4Rpwgf6cE8zHRu6bCw== + dependencies: + "@graphql-tools/utils" "^7.1.0" + relay-compiler "10.1.0" + tslib "~2.0.1" + +"@graphql-tools/schema@^7.0.0", "@graphql-tools/schema@^7.1.2": + version "7.1.2" + resolved "https://registry.yarnpkg.com/@graphql-tools/schema/-/schema-7.1.2.tgz#5084eaef893719ad01329f77673d102e7710542e" + integrity sha512-GabNT51ErVHE2riDH4EQdRusUsI+nMElT8LdFHyuP53v8gwtleAj+LePQ9jif4NYUe/JQVqO8V28vPcHrA7gfQ== + dependencies: + "@graphql-tools/utils" "^7.1.2" + tslib "~2.0.1" + +"@graphql-tools/url-loader@^6", "@graphql-tools/url-loader@^6.0.0", "@graphql-tools/url-loader@^6.3.1": + version "6.7.1" + resolved "https://registry.yarnpkg.com/@graphql-tools/url-loader/-/url-loader-6.7.1.tgz#ce4d2284b702a360d928e74e7f989d8579f0d9f6" + integrity sha512-7NJ1G5diJAuWYZszQf0mNwPipVMOjIIMteNkutdExBq4CgN0V1xa3/iC25CUrI7sZiq+D367zZNONmKf+3bA2Q== + dependencies: + "@graphql-tools/delegate" "^7.0.1" + "@graphql-tools/utils" "^7.1.5" + "@graphql-tools/wrap" "^7.0.4" + "@types/websocket" "1.0.1" + cross-fetch "3.0.6" + eventsource "1.0.7" + extract-files "9.0.0" + graphql-upload "^11.0.0" + graphql-ws "3.1.0" + is-promise "4.0.0" + isomorphic-form-data "2.0.0" + isomorphic-ws "4.0.1" + sse-z "0.3.0" + sync-fetch "0.3.0" + tslib "~2.0.1" + valid-url "1.0.9" + ws "7.4.1" + +"@graphql-tools/utils@^6", "@graphql-tools/utils@^6.0.0": + version "6.2.4" + resolved "https://registry.yarnpkg.com/@graphql-tools/utils/-/utils-6.2.4.tgz#38a2314d2e5e229ad4f78cca44e1199e18d55856" + integrity sha512-ybgZ9EIJE3JMOtTrTd2VcIpTXtDrn2q6eiYkeYMKRVh3K41+LZa6YnR2zKERTXqTWqhobROwLt4BZbw2O3Aeeg== + dependencies: + "@ardatan/aggregate-error" "0.0.6" + camel-case "4.1.1" + tslib "~2.0.1" + +"@graphql-tools/utils@^7.0.0", "@graphql-tools/utils@^7.1.0", "@graphql-tools/utils@^7.1.2", "@graphql-tools/utils@^7.1.5", "@graphql-tools/utils@^7.1.6", "@graphql-tools/utils@^7.2.1": + version "7.2.4" + resolved "https://registry.yarnpkg.com/@graphql-tools/utils/-/utils-7.2.4.tgz#1164cf268988254f281b4cfbbc0e8f7ca24a8a41" + integrity sha512-EDSb98dTWX8FngvayWejip1DutOl0wGtNbXC7a3CZf5fiJS7bGHQ/8cSlMhe9XaHwpLJCbAk/Ijnp/dYbXk33w== + dependencies: + "@ardatan/aggregate-error" "0.0.6" + camel-case "4.1.2" + tslib "~2.1.0" + +"@graphql-tools/wrap@^7.0.4": + version "7.0.5" + resolved "https://registry.yarnpkg.com/@graphql-tools/wrap/-/wrap-7.0.5.tgz#8659a119abef11754f712b0c202e41a484951e0b" + integrity sha512-KCWBXsDfvG46GNUawRltJL4j9BMGoOG7oo3WEyCQP+SByWXiTe5cBF45SLDVQgdjljGNZhZ4Lq/7avIkF7/zDQ== + dependencies: + "@graphql-tools/delegate" "^7.0.7" + "@graphql-tools/schema" "^7.1.2" + "@graphql-tools/utils" "^7.2.1" + is-promise "4.0.0" + tslib "~2.0.1" + +"@hapi/accept@5.0.1": + version "5.0.1" + resolved "https://registry.yarnpkg.com/@hapi/accept/-/accept-5.0.1.tgz#068553e867f0f63225a506ed74e899441af53e10" + integrity sha512-fMr4d7zLzsAXo28PRRQPXR1o2Wmu+6z+VY1UzDp0iFo13Twj8WePakwXBiqn3E1aAlTpSNzCXdnnQXFhst8h8Q== + dependencies: + "@hapi/boom" "9.x.x" + "@hapi/hoek" "9.x.x" + +"@hapi/boom@9.x.x": + version "9.1.1" + resolved "https://registry.yarnpkg.com/@hapi/boom/-/boom-9.1.1.tgz#89e6f0e01637c2a4228da0d113e8157c93677b04" + integrity sha512-VNR8eDbBrOxBgbkddRYIe7+8DZ+vSbV6qlmaN2x7eWjsUjy2VmQgChkOKcVZIeupEZYj+I0dqNg430OhwzagjA== + dependencies: + "@hapi/hoek" "9.x.x" + +"@hapi/hoek@9.x.x": + version "9.1.1" + resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-9.1.1.tgz#9daf5745156fd84b8e9889a2dc721f0c58e894aa" + integrity sha512-CAEbWH7OIur6jEOzaai83jq3FmKmv4PmX1JYfs9IrYcGEVI/lyL1EXJGCj7eFVJ0bg5QR8LMxBlEtA+xKiLpFw== + +"@iarna/toml@^2.2.5": + version "2.2.5" + resolved "https://registry.yarnpkg.com/@iarna/toml/-/toml-2.2.5.tgz#b32366c89b43c6f8cefbdefac778b9c828e3ba8c" + integrity sha512-trnsAYxU3xnS1gPHPyU961coFyLkh4gAD/0zQ5mymY4yOZ+CYvsPqUbOFSw0aDM4y0tV7tiFxL/1XfXPNC6IPg== + +"@manifoldco/swagger-to-ts@^2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@manifoldco/swagger-to-ts/-/swagger-to-ts-2.1.0.tgz#b52a429e5b4ab3627571d3e9ae7399cf5cd4c454" + integrity sha512-IH0FAHhwWHR3Gs3rnVHNEscZujGn+K6/2Zu5cWfZre3Vz2tx1SvvJKEbSM89MztfDDRjOpb+6pQD/vqdEoTBVg== + dependencies: + chalk "^4.0.0" + js-yaml "^3.13.1" + meow "^7.0.0" + prettier "^2.0.5" + +"@next/bundle-analyzer@^10.0.1": + version "10.0.5" + resolved "https://registry.yarnpkg.com/@next/bundle-analyzer/-/bundle-analyzer-10.0.5.tgz#02eda5d88bc1ee8efff03902083bcb2c537e787d" + integrity sha512-fDhursKrqycV7u6crESINKQKp5/Q17Xd9mI1n0BFhIvpfp8br/gSqLHeaN2DXfcOS/Rb0/FmY4pdIFjXnwdZbg== + dependencies: + webpack-bundle-analyzer "4.3.0" + +"@next/env@10.0.5": + version "10.0.5" + resolved "https://registry.yarnpkg.com/@next/env/-/env-10.0.5.tgz#446e59ee7a8d05061be784b24732c369653038ab" + integrity sha512-dw6Q7PALIo7nTFfaB4OnRDte3EikrApGtjX/4cRmYXLh+uudDI50aS39MaGeKKZ2mxPKoNiFcY6Slv1f6KIPOw== + +"@next/polyfill-module@10.0.5": + version "10.0.5" + resolved "https://registry.yarnpkg.com/@next/polyfill-module/-/polyfill-module-10.0.5.tgz#f2de3deee8694cc75094fea4e91225724b3a21e1" + integrity sha512-R6ySTTIl6yqyO3Xft7h+QR9Z4e6epEw+AGO125CrwPmCDQ8ASLGltsHYvSHBP7Eae7xaorkXHW0jeI8NewLpew== + +"@next/react-dev-overlay@10.0.5": + version "10.0.5" + resolved "https://registry.yarnpkg.com/@next/react-dev-overlay/-/react-dev-overlay-10.0.5.tgz#f0006e56d8c8b4269f341ff22233e4a7e1176b52" + integrity sha512-olqIaaRvFezzi02V/AYwvmrGbShUNrJDvyZTGNahxXEkiYsuu67llY5IKFM5Oya93/eRqaCCKMn89vpvYtvDcw== + dependencies: + "@babel/code-frame" "7.12.11" + anser "1.4.9" + chalk "4.0.0" + classnames "2.2.6" + css.escape "1.5.1" + data-uri-to-buffer "3.0.1" + platform "1.3.6" + shell-quote "1.7.2" + source-map "0.8.0-beta.0" + stacktrace-parser "0.1.10" + strip-ansi "6.0.0" + +"@next/react-refresh-utils@10.0.5": + version "10.0.5" + resolved "https://registry.yarnpkg.com/@next/react-refresh-utils/-/react-refresh-utils-10.0.5.tgz#c1ca664c4ffe2f79d14383323d783368833d503b" + integrity sha512-Eo+nvW1ZhdkuxBWSsKHGDLNspUaJJQClld9R+H+EtiIuAQtTa8f2rhcQeyUOtvUNQoPyq7Em2PwUqOQD6LOOMA== + +"@nodelib/fs.scandir@2.1.4": + version "2.1.4" + resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.4.tgz#d4b3549a5db5de2683e0c1071ab4f140904bbf69" + integrity sha512-33g3pMJk3bg5nXbL/+CY6I2eJDzZAni49PfJnL5fghPTggPvBd/pFNSgJsdAgWptuFu7qq/ERvOYFlhvsLTCKA== + dependencies: + "@nodelib/fs.stat" "2.0.4" + run-parallel "^1.1.9" + +"@nodelib/fs.stat@2.0.4", "@nodelib/fs.stat@^2.0.2": + version "2.0.4" + resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.4.tgz#a3f2dd61bab43b8db8fa108a121cfffe4c676655" + integrity sha512-IYlHJA0clt2+Vg7bccq+TzRdJvv19c2INqBSsoOLp1je7xjtr7J26+WXR72MCdvU9q1qTzIWDfhMf+DRvQJK4Q== + +"@nodelib/fs.walk@^1.2.3": + version "1.2.6" + resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.6.tgz#cce9396b30aa5afe9e3756608f5831adcb53d063" + integrity sha512-8Broas6vTtW4GIXTAHDoE32hnN2M5ykgCpWGbuXHQ15vEMqr23pB76e/GZcYsZCHALv50ktd24qhEyKr6wBtow== + dependencies: + "@nodelib/fs.scandir" "2.1.4" + fastq "^1.6.0" + +"@opentelemetry/api@0.14.0": + version "0.14.0" + resolved "https://registry.yarnpkg.com/@opentelemetry/api/-/api-0.14.0.tgz#4e17d8d2f1da72b19374efa7b6526aa001267cae" + integrity sha512-L7RMuZr5LzMmZiQSQDy9O1jo0q+DaLy6XpYJfIGfYSfoJA5qzYwUP3sP1uMIQ549DvxAgM3ng85EaPTM/hUHwQ== + dependencies: + "@opentelemetry/context-base" "^0.14.0" + +"@opentelemetry/context-base@^0.14.0": + version "0.14.0" + resolved "https://registry.yarnpkg.com/@opentelemetry/context-base/-/context-base-0.14.0.tgz#c67fc20a4d891447ca1a855d7d70fa79a3533001" + integrity sha512-sDOAZcYwynHFTbLo6n8kIbLiVF3a3BLkrmehJUyEbT9F+Smbi47kLGS2gG2g0fjBLR/Lr1InPD7kXL7FaTqEkw== + +"@polka/url@^1.0.0-next.9": + version "1.0.0-next.11" + resolved "https://registry.yarnpkg.com/@polka/url/-/url-1.0.0-next.11.tgz#aeb16f50649a91af79dbe36574b66d0f9e4d9f71" + integrity sha512-3NsZsJIA/22P3QUyrEDNA2D133H4j224twJrdipXN38dpnIOzAbUDtOwkcJ5pXmn75w7LSQDjA4tO9dm1XlqlA== + +"@reach/portal@^0.11.2": + version "0.11.2" + resolved "https://registry.yarnpkg.com/@reach/portal/-/portal-0.11.2.tgz#19a671be9ff010a345892b81e710cb6e4d9f9762" + integrity sha512-/53A/rY5oX2Y7D5TpvsP+V5cSd+4MPY6f21mAmVn4DCVwpkCFOlJ059ZL7ixS85M0Jz48YQnnvBJUqwkxqUG/g== + dependencies: + "@reach/utils" "0.11.2" + tslib "^2.0.0" + +"@reach/utils@0.11.2": + version "0.11.2" + resolved "https://registry.yarnpkg.com/@reach/utils/-/utils-0.11.2.tgz#be1f03650db56fd67a16d3fc70e5262cdb139cec" + integrity sha512-fBTolYj+rKTROXmf0zHO0rCWSvw7J0ALmYj5QxW4DmITMOH5uyRuWDWOfqohIGFbOtF/sum50WTB3tvx76d+Aw== + dependencies: + "@types/warning" "^3.0.0" + tslib "^2.0.0" + warning "^4.0.3" + +"@samverschueren/stream-to-observable@^0.3.0": + version "0.3.1" + resolved "https://registry.yarnpkg.com/@samverschueren/stream-to-observable/-/stream-to-observable-0.3.1.tgz#a21117b19ee9be70c379ec1877537ef2e1c63301" + integrity sha512-c/qwwcHyafOQuVQJj0IlBjf5yYgBI7YPJ77k4fOJYesb41jio65eaJODRUmfYKhTOFBrIZ66kgvGPlNbjuoRdQ== + dependencies: + any-observable "^0.3.0" + +"@sindresorhus/is@^0.14.0": + version "0.14.0" + resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.14.0.tgz#9fb3a3cf3132328151f353de4632e01e52102bea" + integrity sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ== + +"@szmarczak/http-timer@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-1.1.2.tgz#b1665e2c461a2cd92f4c1bbf50d5454de0d4b421" + integrity sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA== + dependencies: + defer-to-connect "^1.0.1" + +"@tailwindcss/custom-forms@^0.2.1": + version "0.2.1" + resolved "https://registry.yarnpkg.com/@tailwindcss/custom-forms/-/custom-forms-0.2.1.tgz#40e5ed1fff6d29d8ed1c508a0b2aaf8da96962e0" + integrity sha512-XdP5XY6kxo3x5o50mWUyoYWxOPV16baagLoZ5uM41gh6IhXzhz/vJYzqrTb/lN58maGIKlpkxgVsQUNSsbAS3Q== + dependencies: + lodash "^4.17.11" + mini-svg-data-uri "^1.0.3" + traverse "^0.6.6" + +"@tailwindcss/typography@^0.2.0": + version "0.2.0" + resolved "https://registry.yarnpkg.com/@tailwindcss/typography/-/typography-0.2.0.tgz#b597c83502e3c3c6641a8aaabda223cd494ab349" + integrity sha512-aPgMH+CjQiScLZculoDNOQUrrK2ktkbl3D6uCLYp1jgYRlNDrMONu9nMu8LfwAeetYNpVNeIGx7WzHSu0kvECg== + +"@tailwindcss/ui@^0.6.2": + version "0.6.2" + resolved "https://registry.yarnpkg.com/@tailwindcss/ui/-/ui-0.6.2.tgz#4144aba86543bf79fefe0ea14a78a12fb315810e" + integrity sha512-i0sWpAgnF4VitNqaf4JVDuiaQ3MmREwn7gmNYR6lvX29avYLLNOHf0DgzhVEfwfB+CJ6WjZvPoJuDYExZgWlwQ== + dependencies: + "@tailwindcss/custom-forms" "^0.2.1" + "@tailwindcss/typography" "^0.2.0" + hex-rgb "^4.1.0" + postcss-selector-parser "^6.0.2" + +"@tootallnate/once@1": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-1.1.2.tgz#ccb91445360179a04e7fe6aff78c00ffc1eeaf82" + integrity sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw== + +"@types/async-retry@1.2.1": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@types/async-retry/-/async-retry-1.2.1.tgz#fa9ac165907a8ee78f4924f4e393b656c65b5bb4" + integrity sha512-yMQ6CVgICWtyFNBqJT3zqOc+TnqqEPLo4nKJNPFwcialiylil38Ie6q1ENeFTjvaLOkVim9K5LisHgAKJWidGQ== + +"@types/body-scroll-lock@^2.6.1": + version "2.6.1" + resolved "https://registry.yarnpkg.com/@types/body-scroll-lock/-/body-scroll-lock-2.6.1.tgz#0dbd2b6ad2f4cfcece7102d6cf8630ce95508ee0" + integrity sha512-PPFm/2A6LfKmSpvMg58gHtSqwwMChbcKKGhSCRIhY4MyFzhY8moAN6HrTCpOeZQUqkFdTFfMqr7njeqGLKt72Q== + +"@types/bunyan-prettystream@^0.1.31": + version "0.1.31" + resolved "https://registry.yarnpkg.com/@types/bunyan-prettystream/-/bunyan-prettystream-0.1.31.tgz#3864836abb907ab151f7edf7c64c323c9609e1d1" + integrity sha512-NE7fq2ZcX7OSMK+VhTNJkVEHlo+hm0uVXpuLeH1ifGm52Qwuo/kLD2GHo7UcEXMFu3duKver/AFo8C4TME93zw== + dependencies: + "@types/node" "*" + +"@types/bunyan@^1.8.6": + version "1.8.6" + resolved "https://registry.yarnpkg.com/@types/bunyan/-/bunyan-1.8.6.tgz#6527641cca30bedec5feb9ab527b7803b8000582" + integrity sha512-YiozPOOsS6bIuz31ilYqR5SlLif4TBWsousN2aCWLi5233nZSX19tFbcQUPdR7xJ8ypPyxkCGNxg0CIV5n9qxQ== + dependencies: + "@types/node" "*" + +"@types/classnames@^2.2.10": + version "2.2.11" + resolved "https://registry.yarnpkg.com/@types/classnames/-/classnames-2.2.11.tgz#2521cc86f69d15c5b90664e4829d84566052c1cf" + integrity sha512-2koNhpWm3DgWRp5tpkiJ8JGc1xTn2q0l+jUNUE7oMKXUf5NpI9AIdC4kbjGNFBdHtcxBD18LAksoudAVhFKCjw== + +"@types/cookie@^0.4.0": + version "0.4.0" + resolved "https://registry.yarnpkg.com/@types/cookie/-/cookie-0.4.0.tgz#14f854c0f93d326e39da6e3b6f34f7d37513d108" + integrity sha512-y7mImlc/rNkvCRmg8gC3/lj87S7pTUIJ6QGjwHR9WQJcFs+ZMTOaoPrkdFA/YdbuqVEmEbb5RdhVxMkAcgOnpg== + +"@types/eslint-scope@^3.7.0": + version "3.7.0" + resolved "https://registry.yarnpkg.com/@types/eslint-scope/-/eslint-scope-3.7.0.tgz#4792816e31119ebd506902a482caec4951fabd86" + integrity sha512-O/ql2+rrCUe2W2rs7wMR+GqPRcgB6UiqN5RhrR5xruFlY7l9YLMn0ZkDzjoHLeiFkR8MCQZVudUuuvQ2BLC9Qw== + dependencies: + "@types/eslint" "*" + "@types/estree" "*" + +"@types/eslint@*": + version "7.2.6" + resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-7.2.6.tgz#5e9aff555a975596c03a98b59ecd103decc70c3c" + integrity sha512-I+1sYH+NPQ3/tVqCeUSBwTE/0heyvtXqpIopUUArlBm0Kpocb8FbMa3AZ/ASKIFpN3rnEx932TTXDbt9OXsNDw== + dependencies: + "@types/estree" "*" + "@types/json-schema" "*" + +"@types/estree@*", "@types/estree@^0.0.45": + version "0.0.45" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.45.tgz#e9387572998e5ecdac221950dab3e8c3b16af884" + integrity sha512-jnqIUKDUqJbDIUxm0Uj7bnlMnRm1T/eZ9N+AVMqhPgzrba2GhGG5o/jCTwmdPK709nEZsGoMzXEDUjcXHa3W0g== + +"@types/http-proxy-agent@^2.0.2": + version "2.0.2" + resolved "https://registry.yarnpkg.com/@types/http-proxy-agent/-/http-proxy-agent-2.0.2.tgz#942c1f35c7e1f0edd1b6ffae5d0f9051cfb32be1" + integrity sha512-2S6IuBRhqUnH1/AUx9k8KWtY3Esg4eqri946MnxTG5HwehF1S5mqLln8fcyMiuQkY72p2gH3W+rIPqp5li0LyQ== + dependencies: + "@types/node" "*" + +"@types/js-cookie@^2.2.6": + version "2.2.6" + resolved "https://registry.yarnpkg.com/@types/js-cookie/-/js-cookie-2.2.6.tgz#f1a1cb35aff47bc5cfb05cb0c441ca91e914c26f" + integrity sha512-+oY0FDTO2GYKEV0YPvSshGq9t7YozVkgvXLty7zogQNuCxBhT9/3INX9Q7H1aRZ4SUDRXAKlJuA4EA5nTt7SNw== + +"@types/js-yaml@^3.12.5": + version "3.12.6" + resolved "https://registry.yarnpkg.com/@types/js-yaml/-/js-yaml-3.12.6.tgz#7f10c926aa41e189a2755c4c7fcf8e4573bd7ac1" + integrity sha512-cK4XqrLvP17X6c0C8n4iTbT59EixqyXL3Fk8/Rsk4dF3oX4dg70gYUXrXVUUHpnsGMPNlTQMqf+TVmNPX6FmSQ== + +"@types/json-schema@*", "@types/json-schema@^7.0.5", "@types/json-schema@^7.0.6": + version "7.0.6" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.6.tgz#f4c7ec43e81b319a9815115031709f26987891f0" + integrity sha512-3c+yGKvVP5Y9TYBEibGNR+kLtijnj7mYrXRg+WpFb2X9xm04g/DXYkfg4hmzJQosc9snFNUPkbYIhu+KAm6jJw== + +"@types/json-stable-stringify@^1.0.32": + version "1.0.32" + resolved "https://registry.yarnpkg.com/@types/json-stable-stringify/-/json-stable-stringify-1.0.32.tgz#121f6917c4389db3923640b2e68de5fa64dda88e" + integrity sha512-q9Q6+eUEGwQkv4Sbst3J4PNgDOvpuVuKj79Hl/qnmBMEIPzB5QoFRUtjcgcg2xNUZyYUGXBk5wYIBKHt0A+Mxw== + +"@types/jsonwebtoken@^8.5.0": + version "8.5.0" + resolved "https://registry.yarnpkg.com/@types/jsonwebtoken/-/jsonwebtoken-8.5.0.tgz#2531d5e300803aa63279b232c014acf780c981c5" + integrity sha512-9bVao7LvyorRGZCw0VmH/dr7Og+NdjYSsKAxB43OQoComFbBgsEpoR9JW6+qSq/ogwVBg8GI2MfAlk4SYI4OLg== + dependencies: + "@types/node" "*" + +"@types/lodash.debounce@^4.0.6": + version "4.0.6" + resolved "https://registry.yarnpkg.com/@types/lodash.debounce/-/lodash.debounce-4.0.6.tgz#c5a2326cd3efc46566c47e4c0aa248dc0ee57d60" + integrity sha512-4WTmnnhCfDvvuLMaF3KV4Qfki93KebocUF45msxhYyjMttZDQYzHkO639ohhk8+oco2cluAFL3t5+Jn4mleylQ== + dependencies: + "@types/lodash" "*" + +"@types/lodash.random@^3.2.6": + version "3.2.6" + resolved "https://registry.yarnpkg.com/@types/lodash.random/-/lodash.random-3.2.6.tgz#64b08abad168dca39c778ed40cce75b2f9e168eb" + integrity sha512-RRr0pKm+3USvG/HTkuRKA8v2EqXu19VXC09j4VL2UQec8Yx8Fn6wYTPGjYdmX4UFd23ykS7SLFkiULS/rv8kTA== + dependencies: + "@types/lodash" "*" + +"@types/lodash.throttle@^4.1.6": + version "4.1.6" + resolved "https://registry.yarnpkg.com/@types/lodash.throttle/-/lodash.throttle-4.1.6.tgz#f5ba2c22244ee42ff6c2c49e614401a870c1009c" + integrity sha512-/UIH96i/sIRYGC60NoY72jGkCJtFN5KVPhEMMMTjol65effe1gPn0tycJqV5tlSwMTzX8FqzB5yAj0rfGHTPNg== + dependencies: + "@types/lodash" "*" + +"@types/lodash@*": + version "4.14.167" + resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.167.tgz#ce7d78553e3c886d4ea643c37ec7edc20f16765e" + integrity sha512-w7tQPjARrvdeBkX/Rwg95S592JwxqOjmms3zWQ0XZgSyxSLdzWaYH3vErBhdVS/lRBX7F8aBYcYJYTr5TMGOzw== + +"@types/lru-cache@4.1.1": + version "4.1.1" + resolved "https://registry.yarnpkg.com/@types/lru-cache/-/lru-cache-4.1.1.tgz#b2d87a5e3df8d4b18ca426c5105cd701c2306d40" + integrity sha512-8mNEUG6diOrI6pMqOHrHPDBB1JsrpedeMK9AWGzVCQ7StRRribiT9BRvUmF8aUws9iBbVlgVekOT5Sgzc1MTKw== + +"@types/minimist@^1.2.0": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@types/minimist/-/minimist-1.2.1.tgz#283f669ff76d7b8260df8ab7a4262cc83d988256" + integrity sha512-fZQQafSREFyuZcdWFAExYjBiCL7AUCdgsk80iO0q4yihYYdcIiH28CcuPTGFgLOCC8RlW49GSQxdHwZP+I7CNg== + +"@types/node-fetch@2.3.2": + version "2.3.2" + resolved "https://registry.yarnpkg.com/@types/node-fetch/-/node-fetch-2.3.2.tgz#e01893b176c6fa1367743726380d65bce5d6576b" + integrity sha512-yW0EOebSsQme9yKu09XbdDfle4/SmWZMK4dfteWcSLCYNQQcF+YOv0kIrvm+9pO11/ghA4E6A+RNQqvYj4Nr3A== + dependencies: + "@types/node" "*" + +"@types/node@*", "@types/node@^14.14.16": + version "14.14.20" + resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.20.tgz#f7974863edd21d1f8a494a73e8e2b3658615c340" + integrity sha512-Y93R97Ouif9JEOWPIUyU+eyIdyRqQR0I8Ez1dzku4hDx34NWh4HbtIc3WNzwB1Y9ULvNGeu5B8h8bVL5cAk4/A== + +"@types/node@10.12.18": + version "10.12.18" + resolved "https://registry.yarnpkg.com/@types/node/-/node-10.12.18.tgz#1d3ca764718915584fcd9f6344621b7672665c67" + integrity sha512-fh+pAqt4xRzPfqA6eh3Z2y6fyZavRIumvjhaCL753+TVkGKGhpPeyrJG2JftD0T9q4GF00KjefsQ+PQNDdWQaQ== + +"@types/normalize-package-data@^2.4.0": + version "2.4.0" + resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz#e486d0d97396d79beedd0a6e33f4534ff6b4973e" + integrity sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA== + +"@types/parse-json@^4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.0.tgz#2f8bb441434d163b35fb8ffdccd7138927ffb8c0" + integrity sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA== + +"@types/prop-types@*": + version "15.7.3" + resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.3.tgz#2ab0d5da2e5815f94b0b9d4b95d1e5f243ab2ca7" + integrity sha512-KfRL3PuHmqQLOG+2tGpRO26Ctg+Cq1E01D2DMriKEATHgWLfeNDmq9e29Q9WIky0dQ3NPkd1mzYH8Lm936Z9qw== + +"@types/react@^17.0.0": + version "17.0.0" + resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.0.tgz#5af3eb7fad2807092f0046a1302b7823e27919b8" + integrity sha512-aj/L7RIMsRlWML3YB6KZiXB3fV2t41+5RBGYF8z+tAKU43Px8C3cYUZsDvf1/+Bm4FK21QWBrDutu8ZJ/70qOw== + dependencies: + "@types/prop-types" "*" + csstype "^3.0.2" + +"@types/warning@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@types/warning/-/warning-3.0.0.tgz#0d2501268ad8f9962b740d387c4654f5f8e23e52" + integrity sha1-DSUBJorY+ZYrdA04fEZU9fjiPlI= + +"@types/websocket@1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@types/websocket/-/websocket-1.0.1.tgz#039272c196c2c0e4868a0d8a1a27bbb86e9e9138" + integrity sha512-f5WLMpezwVxCLm1xQe/kdPpQIOmL0TXYx2O15VYfYzc7hTIdxiOoOvez+McSIw3b7z/1zGovew9YSL7+h4h7/Q== + dependencies: + "@types/node" "*" + +"@typescript-eslint/typescript-estree@^2.29.0": + version "2.34.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-2.34.0.tgz#14aeb6353b39ef0732cc7f1b8285294937cf37d5" + integrity sha512-OMAr+nJWKdlVM9LOqCqh3pQQPwxHAN7Du8DR6dmwCrAmxtiXQnhHJ6tBNtf+cggqfo51SG/FCwnKhXCIM7hnVg== + dependencies: + debug "^4.1.1" + eslint-visitor-keys "^1.1.0" + glob "^7.1.6" + is-glob "^4.0.1" + lodash "^4.17.15" + semver "^7.3.2" + tsutils "^3.17.1" + +"@vercel/fetch-cached-dns@^2.0.1": + version "2.0.1" + resolved "https://registry.yarnpkg.com/@vercel/fetch-cached-dns/-/fetch-cached-dns-2.0.1.tgz#b929ba5b4b6f7108abf49adaf03309159047c134" + integrity sha512-4a2IoekfGUgV/dinAB7Tx5oqA+Pg9I/6x/t8n/yduHmdclP5EdWTN4gPrwOKVECKVn2pV1VxAT8q4toSzwa2Eg== + dependencies: + "@types/node-fetch" "2.3.2" + "@zeit/dns-cached-resolve" "2.1.0" + +"@vercel/fetch-retry@^5.0.2": + version "5.0.3" + resolved "https://registry.yarnpkg.com/@vercel/fetch-retry/-/fetch-retry-5.0.3.tgz#cce5d23f6e64f6f525c24e2ac7c78f65d6c5b1f4" + integrity sha512-DIIoBY92r+sQ6iHSf5WjKiYvkdsDIMPWKYATlE0KcUAj2RV6SZK9UWpUzBRKsofXqedOqpVjrI0IE6AWL7JRtg== + dependencies: + async-retry "^1.3.1" + debug "^3.1.0" + +"@vercel/fetch@^6.1.0": + version "6.1.0" + resolved "https://registry.yarnpkg.com/@vercel/fetch/-/fetch-6.1.0.tgz#4959cd264d25e811b46491818a9d9ca5d752a2a9" + integrity sha512-xR0GQggKhPvwEWrqcrobsQFjyR/bDDbX24BkSaRyLzW+8SydKhkBc/mBCUV8h4SBZSlJMJnqhrxjFCZ1uJcqNg== + dependencies: + "@types/async-retry" "1.2.1" + "@vercel/fetch-cached-dns" "^2.0.1" + "@vercel/fetch-retry" "^5.0.2" + agentkeepalive "3.4.1" + debug "3.1.0" + +"@vue/compiler-core@3.0.5": + version "3.0.5" + resolved "https://registry.yarnpkg.com/@vue/compiler-core/-/compiler-core-3.0.5.tgz#a6e54cabe9536e74c6513acd2649f311af1d43ac" + integrity sha512-iFXwk2gmU/GGwN4hpBwDWWMLvpkIejf/AybcFtlQ5V1ur+5jwfBaV0Y1RXoR6ePfBPJixtKZ3PmN+M+HgMAtfQ== + dependencies: + "@babel/parser" "^7.12.0" + "@babel/types" "^7.12.0" + "@vue/shared" "3.0.5" + estree-walker "^2.0.1" + source-map "^0.6.1" + +"@vue/compiler-dom@3.0.5": + version "3.0.5" + resolved "https://registry.yarnpkg.com/@vue/compiler-dom/-/compiler-dom-3.0.5.tgz#7885a13e6d18f64dde8ebceec052ed2c102696c2" + integrity sha512-HSOSe2XSPuCkp20h4+HXSiPH9qkhz6YbW9z9ZtL5vef2T2PMugH7/osIFVSrRZP/Ul5twFZ7MIRlp8tPX6e4/g== + dependencies: + "@vue/compiler-core" "3.0.5" + "@vue/shared" "3.0.5" + +"@vue/compiler-sfc@^3.0.4": + version "3.0.5" + resolved "https://registry.yarnpkg.com/@vue/compiler-sfc/-/compiler-sfc-3.0.5.tgz#3ae08e60244a72faf9598361874fb7bdb5b1d37c" + integrity sha512-uOAC4X0Gx3SQ9YvDC7YMpbDvoCmPvP0afVhJoxRotDdJ+r8VO3q4hFf/2f7U62k4Vkdftp6DVni8QixrfYzs+w== + dependencies: + "@babel/parser" "^7.12.0" + "@babel/types" "^7.12.0" + "@vue/compiler-core" "3.0.5" + "@vue/compiler-dom" "3.0.5" + "@vue/compiler-ssr" "3.0.5" + "@vue/shared" "3.0.5" + consolidate "^0.16.0" + estree-walker "^2.0.1" + hash-sum "^2.0.0" + lru-cache "^5.1.1" + magic-string "^0.25.7" + merge-source-map "^1.1.0" + postcss "^7.0.32" + postcss-modules "^3.2.2" + postcss-selector-parser "^6.0.4" + source-map "^0.6.1" + +"@vue/compiler-ssr@3.0.5": + version "3.0.5" + resolved "https://registry.yarnpkg.com/@vue/compiler-ssr/-/compiler-ssr-3.0.5.tgz#7661ad891a0be948726c7f7ad1e425253c587b83" + integrity sha512-Wm//Kuxa1DpgjE4P9W0coZr8wklOfJ35Jtq61CbU+t601CpPTK4+FL2QDBItaG7aoUUDCWL5nnxMkuaOgzTBKg== + dependencies: + "@vue/compiler-dom" "3.0.5" + "@vue/shared" "3.0.5" + +"@vue/shared@3.0.5": + version "3.0.5" + resolved "https://registry.yarnpkg.com/@vue/shared/-/shared-3.0.5.tgz#c131d88bd6713cc4d93b3bb1372edb1983225ff0" + integrity sha512-gYsNoGkWejBxNO6SNRjOh/xKeZ0H0V+TFzaPzODfBjkAIb0aQgBuixC1brandC/CDJy1wYPwSoYrXpvul7m6yw== + +"@webassemblyjs/ast@1.9.1": + version "1.9.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.9.1.tgz#76c6937716d68bf1484c15139f5ed30b9abc8bb4" + integrity sha512-uMu1nCWn2Wxyy126LlGqRVlhdTOsO/bsBRI4dNq3+6SiSuRKRQX6ejjKgh82LoGAPSq72lDUiQ4FWVaf0PecYw== + dependencies: + "@webassemblyjs/helper-module-context" "1.9.1" + "@webassemblyjs/helper-wasm-bytecode" "1.9.1" + "@webassemblyjs/wast-parser" "1.9.1" + +"@webassemblyjs/floating-point-hex-parser@1.9.1": + version "1.9.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.9.1.tgz#9eb0ff90a1cdeef51f36ba533ed9f06b5cdadd09" + integrity sha512-5VEKu024RySmLKTTBl9q1eO/2K5jk9ZS+2HXDBLA9s9p5IjkaXxWiDb/+b7wSQp6FRdLaH1IVGIfOex58Na2pg== + +"@webassemblyjs/helper-api-error@1.9.1": + version "1.9.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.9.1.tgz#ad89015c4246cd7f5ed0556700237f8b9c2c752f" + integrity sha512-y1lGmfm38djrScwpeL37rRR9f1D6sM8RhMpvM7CYLzOlHVboouZokXK/G88BpzW0NQBSvCCOnW5BFhten4FPfA== + +"@webassemblyjs/helper-buffer@1.9.1": + version "1.9.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.9.1.tgz#186e67ac25f9546ea7939759413987f157524133" + integrity sha512-uS6VSgieHbk/m4GSkMU5cqe/5TekdCzQso4revCIEQ3vpGZgqSSExi4jWpTWwDpAHOIAb1Jfrs0gUB9AA4n71w== + +"@webassemblyjs/helper-code-frame@1.9.1": + version "1.9.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.9.1.tgz#aab177b7cc87a318a8f8664ad68e2c3828ebc42b" + integrity sha512-ZQ2ZT6Evk4DPIfD+92AraGYaFIqGm4U20e7FpXwl7WUo2Pn1mZ1v8VGH8i+Y++IQpxPbQo/UyG0Khs7eInskzA== + dependencies: + "@webassemblyjs/wast-printer" "1.9.1" + +"@webassemblyjs/helper-fsm@1.9.1": + version "1.9.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-fsm/-/helper-fsm-1.9.1.tgz#527e91628e84d13d3573884b3dc4c53a81dcb911" + integrity sha512-J32HGpveEqqcKFS0YbgicB0zAlpfIxJa5MjxDxhu3i5ltPcVfY5EPvKQ1suRguFPehxiUs+/hfkwPEXom/l0lw== + +"@webassemblyjs/helper-module-context@1.9.1": + version "1.9.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-module-context/-/helper-module-context-1.9.1.tgz#778670b3d471f7cf093d1e7c0dde431b54310e16" + integrity sha512-IEH2cMmEQKt7fqelLWB5e/cMdZXf2rST1JIrzWmf4XBt3QTxGdnnLvV4DYoN8pJjOx0VYXsWg+yF16MmJtolZg== + dependencies: + "@webassemblyjs/ast" "1.9.1" + +"@webassemblyjs/helper-wasm-bytecode@1.9.1": + version "1.9.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.9.1.tgz#563f59bcf409ccf469edde168b9426961ffbf6df" + integrity sha512-i2rGTBqFUcSXxyjt2K4vm/3kkHwyzG6o427iCjcIKjOqpWH8SEem+xe82jUk1iydJO250/CvE5o7hzNAMZf0dQ== + +"@webassemblyjs/helper-wasm-section@1.9.1": + version "1.9.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.9.1.tgz#f7988f94c12b01b99a16120cb01dc099b00e4798" + integrity sha512-FetqzjtXZr2d57IECK+aId3D0IcGweeM0CbAnJHkYJkcRTHP+YcMb7Wmc0j21h5UWBpwYGb9dSkK/93SRCTrGg== + dependencies: + "@webassemblyjs/ast" "1.9.1" + "@webassemblyjs/helper-buffer" "1.9.1" + "@webassemblyjs/helper-wasm-bytecode" "1.9.1" + "@webassemblyjs/wasm-gen" "1.9.1" + +"@webassemblyjs/ieee754@1.9.1": + version "1.9.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.9.1.tgz#3b715871ca7d75784717cf9ceca9d7b81374b8af" + integrity sha512-EvTG9M78zP1MmkBpUjGQHZc26DzPGZSLIPxYHCjQsBMo60Qy2W34qf8z0exRDtxBbRIoiKa5dFyWer/7r1aaSQ== + dependencies: + "@xtuc/ieee754" "^1.2.0" + +"@webassemblyjs/leb128@1.9.1": + version "1.9.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.9.1.tgz#b2ecaa39f9e8277cc9c707c1ca8b2aa7b27d0b72" + integrity sha512-Oc04ub0vFfLnF+2/+ki3AE+anmW4sv9uNBqb+79fgTaPv6xJsOT0dhphNfL3FrME84CbX/D1T9XT8tjFo0IIiw== + dependencies: + "@xtuc/long" "4.2.2" + +"@webassemblyjs/utf8@1.9.1": + version "1.9.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.9.1.tgz#d02d9daab85cda3211e43caf31dca74c260a73b0" + integrity sha512-llkYtppagjCodFjo0alWOUhAkfOiQPQDIc5oA6C9sFAXz7vC9QhZf/f8ijQIX+A9ToM3c9Pq85X0EX7nx9gVhg== + +"@webassemblyjs/wasm-edit@1.9.1": + version "1.9.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.9.1.tgz#e27a6bdbf78e5c72fa812a2fc3cbaad7c3e37578" + integrity sha512-S2IaD6+x9B2Xi8BCT0eGsrXXd8UxAh2LVJpg1ZMtHXnrDcsTtIX2bDjHi40Hio6Lc62dWHmKdvksI+MClCYbbw== + dependencies: + "@webassemblyjs/ast" "1.9.1" + "@webassemblyjs/helper-buffer" "1.9.1" + "@webassemblyjs/helper-wasm-bytecode" "1.9.1" + "@webassemblyjs/helper-wasm-section" "1.9.1" + "@webassemblyjs/wasm-gen" "1.9.1" + "@webassemblyjs/wasm-opt" "1.9.1" + "@webassemblyjs/wasm-parser" "1.9.1" + "@webassemblyjs/wast-printer" "1.9.1" + +"@webassemblyjs/wasm-gen@1.9.1": + version "1.9.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.9.1.tgz#56a0787d1fa7994fdc7bea59004e5bec7189c5fc" + integrity sha512-bqWI0S4lBQsEN5FTZ35vYzfKUJvtjNnBobB1agCALH30xNk1LToZ7Z8eiaR/Z5iVECTlBndoRQV3F6mbEqE/fg== + dependencies: + "@webassemblyjs/ast" "1.9.1" + "@webassemblyjs/helper-wasm-bytecode" "1.9.1" + "@webassemblyjs/ieee754" "1.9.1" + "@webassemblyjs/leb128" "1.9.1" + "@webassemblyjs/utf8" "1.9.1" + +"@webassemblyjs/wasm-opt@1.9.1": + version "1.9.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.9.1.tgz#fbdf8943a825e6dcc4cd69c3e092289fa4aec96c" + integrity sha512-gSf7I7YWVXZ5c6XqTEqkZjVs8K1kc1k57vsB6KBQscSagDNbAdxt6MwuJoMjsE1yWY1tsuL+pga268A6u+Fdkg== + dependencies: + "@webassemblyjs/ast" "1.9.1" + "@webassemblyjs/helper-buffer" "1.9.1" + "@webassemblyjs/wasm-gen" "1.9.1" + "@webassemblyjs/wasm-parser" "1.9.1" + +"@webassemblyjs/wasm-parser@1.9.1": + version "1.9.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.9.1.tgz#5e8352a246d3f605312c8e414f7990de55aaedfa" + integrity sha512-ImM4N2T1MEIond0MyE3rXvStVxEmivQrDKf/ggfh5pP6EHu3lL/YTAoSrR7shrbKNPpeKpGesW1LIK/L4kqduw== + dependencies: + "@webassemblyjs/ast" "1.9.1" + "@webassemblyjs/helper-api-error" "1.9.1" + "@webassemblyjs/helper-wasm-bytecode" "1.9.1" + "@webassemblyjs/ieee754" "1.9.1" + "@webassemblyjs/leb128" "1.9.1" + "@webassemblyjs/utf8" "1.9.1" + +"@webassemblyjs/wast-parser@1.9.1": + version "1.9.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-parser/-/wast-parser-1.9.1.tgz#e25ef13585c060073c1db0d6bd94340fdeee7596" + integrity sha512-2xVxejXSvj3ls/o2TR/zI6p28qsGupjHhnHL6URULQRcXmryn3w7G83jQMcT7PHqUfyle65fZtWLukfdLdE7qw== + dependencies: + "@webassemblyjs/ast" "1.9.1" + "@webassemblyjs/floating-point-hex-parser" "1.9.1" + "@webassemblyjs/helper-api-error" "1.9.1" + "@webassemblyjs/helper-code-frame" "1.9.1" + "@webassemblyjs/helper-fsm" "1.9.1" + "@xtuc/long" "4.2.2" + +"@webassemblyjs/wast-printer@1.9.1": + version "1.9.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.9.1.tgz#b9f38e93652037d4f3f9c91584635af4191ed7c1" + integrity sha512-tDV8V15wm7mmbAH6XvQRU1X+oPGmeOzYsd6h7hlRLz6QpV4Ec/KKxM8OpLtFmQPLCreGxTp+HuxtH4pRIZyL9w== + dependencies: + "@webassemblyjs/ast" "1.9.1" + "@webassemblyjs/wast-parser" "1.9.1" + "@xtuc/long" "4.2.2" + +"@xtuc/ieee754@^1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@xtuc/ieee754/-/ieee754-1.2.0.tgz#eef014a3145ae477a1cbc00cd1e552336dceb790" + integrity sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA== + +"@xtuc/long@4.2.2": + version "4.2.2" + resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.2.tgz#d291c6a4e97989b5c61d9acf396ae4fe133a718d" + integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ== + +"@zeit/dns-cached-resolve@2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@zeit/dns-cached-resolve/-/dns-cached-resolve-2.1.0.tgz#78583010df1683fdb7b05949b75593c9a8641bc1" + integrity sha512-KD2zyRZEBNs9PJ3/ob7zx0CvR4wM0oV4G5s5gFfPwmM74GpFbUN2pAAivP2AXnUrJ14Nkh8NumNKOzOyc4LbFQ== + dependencies: + "@types/async-retry" "1.2.1" + "@types/lru-cache" "4.1.1" + "@types/node" "10.12.18" + async-retry "1.2.3" + lru-cache "5.1.1" + +abort-controller@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/abort-controller/-/abort-controller-3.0.0.tgz#eaf54d53b62bae4138e809ca225c8439a6efb392" + integrity sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg== + dependencies: + event-target-shim "^5.0.0" + +acorn-node@^1.6.1: + version "1.8.2" + resolved "https://registry.yarnpkg.com/acorn-node/-/acorn-node-1.8.2.tgz#114c95d64539e53dede23de8b9d96df7c7ae2af8" + integrity sha512-8mt+fslDufLYntIoPAaIMUe/lrbrehIiwmR3t2k9LljIzoigEPF27eLk2hy8zSGzmR/ogr7zbRKINMo1u0yh5A== + dependencies: + acorn "^7.0.0" + acorn-walk "^7.0.0" + xtend "^4.0.2" + +acorn-walk@^7.0.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-7.2.0.tgz#0de889a601203909b0fbe07b8938dc21d2e967bc" + integrity sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA== + +acorn-walk@^8.0.0: + version "8.0.1" + resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.0.1.tgz#d265d35db6940a656c715806a448456ee4fa3b7f" + integrity sha512-zn/7dYtoTVkG4EoMU55QlQU4F+m+T7Kren6Vj3C2DapWPnakG/DL9Ns5aPAPW5Ixd3uxXrV/BoMKKVFIazPcdg== + +acorn@^7.0.0: + version "7.4.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" + integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== + +acorn@^8.0.4: + version "8.0.4" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.0.4.tgz#7a3ae4191466a6984eee0fe3407a4f3aa9db8354" + integrity sha512-XNP0PqF1XD19ZlLKvB7cMmnZswW4C/03pRHgirB30uSJTaS3A3V1/P4sS3HPvFmjoriPCJQs+JDSbm4bL1TxGQ== + +adjust-sourcemap-loader@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/adjust-sourcemap-loader/-/adjust-sourcemap-loader-3.0.0.tgz#5ae12fb5b7b1c585e80bbb5a63ec163a1a45e61e" + integrity sha512-YBrGyT2/uVQ/c6Rr+t6ZJXniY03YtHGMJQYal368burRGYKqhx9qGTWqcBU5s1CwYY9E/ri63RYyG1IacMZtqw== + dependencies: + loader-utils "^2.0.0" + regex-parser "^2.2.11" + +agent-base@6: + version "6.0.2" + resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" + integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ== + dependencies: + debug "4" + +agentkeepalive@3.4.1: + version "3.4.1" + resolved "https://registry.yarnpkg.com/agentkeepalive/-/agentkeepalive-3.4.1.tgz#aa95aebc3a749bca5ed53e3880a09f5235b48f0c" + integrity sha512-MPIwsZU9PP9kOrZpyu2042kYA8Fdt/AedQYkYXucHgF9QoD9dXVp0ypuGnHXSR0hTstBxdt85Xkh4JolYfK5wg== + dependencies: + humanize-ms "^1.2.1" + +ajv-keywords@^3.5.2: + version "3.5.2" + resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz#31f29da5ab6e00d1c2d329acf7b5929614d5014d" + integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ== + +ajv@^6.12.3, ajv@^6.12.4, ajv@^6.12.5, ajv@^6.12.6: + version "6.12.6" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" + integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== + dependencies: + fast-deep-equal "^3.1.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" + +anser@1.4.9: + version "1.4.9" + resolved "https://registry.yarnpkg.com/anser/-/anser-1.4.9.tgz#1f85423a5dcf8da4631a341665ff675b96845760" + integrity sha512-AI+BjTeGt2+WFk4eWcqbQ7snZpDBt8SaLlj0RT2h5xfdWaiy51OjYvqwMrNzJLGy8iOAL6nKDITWO+rd4MkYEA== + +ansi-escapes@^3.0.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.2.0.tgz#8780b98ff9dbf5638152d1f1fe5c1d7b4442976b" + integrity sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ== + +ansi-escapes@^4.2.1, ansi-escapes@^4.3.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.1.tgz#a5c47cc43181f1f38ffd7076837700d395522a61" + integrity sha512-JWF7ocqNrp8u9oqpgV+wH5ftbt+cfvv+PTjOvKLT3AdYly/LmORARfEVT1iyjwN+4MqE5UmVKoAdIBqeoCHgLA== + dependencies: + type-fest "^0.11.0" + +ansi-regex@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" + integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8= + +ansi-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" + integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= + +ansi-regex@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.0.tgz#388539f55179bf39339c81af30a654d69f87cb75" + integrity sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg== + +ansi-styles@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" + integrity sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4= + +ansi-styles@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" + integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== + dependencies: + color-convert "^1.9.0" + +ansi-styles@^4.0.0, ansi-styles@^4.1.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" + integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== + dependencies: + color-convert "^2.0.1" + +any-observable@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/any-observable/-/any-observable-0.3.0.tgz#af933475e5806a67d0d7df090dd5e8bef65d119b" + integrity sha512-/FQM1EDkTsf63Ub2C6O7GuYFDsSXUwsaZDurV0np41ocwq0jthUAYCmhBX9f+KwlaCgIuWyr/4WlUQUBfKfZog== + +anymatch@~3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.1.tgz#c55ecf02185e2469259399310c173ce31233b142" + integrity sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg== + dependencies: + normalize-path "^3.0.0" + picomatch "^2.0.4" + +app-module-path@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/app-module-path/-/app-module-path-2.2.0.tgz#641aa55dfb7d6a6f0a8141c4b9c0aa50b6c24dd5" + integrity sha1-ZBqlXft9am8KgUHEucCqULbCTdU= + +aproba@^1.0.3: + version "1.2.0" + resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" + integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw== + +are-we-there-yet@~1.1.2: + version "1.1.5" + resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz#4b35c2944f062a8bfcda66410760350fe9ddfc21" + integrity sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w== + dependencies: + delegates "^1.0.0" + readable-stream "^2.0.6" + +arg@^4.1.0: + version "4.1.3" + resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089" + integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA== + +argparse@^1.0.7: + version "1.0.10" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" + integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== + dependencies: + sprintf-js "~1.0.2" + +arity-n@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/arity-n/-/arity-n-1.0.4.tgz#d9e76b11733e08569c0847ae7b39b2860b30b745" + integrity sha1-2edrEXM+CFacCEeuezmyhgswt0U= + +array-flatten@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-3.0.0.tgz#6428ca2ee52c7b823192ec600fa3ed2f157cd541" + integrity sha512-zPMVc3ZYlGLNk4mpK1NzP2wg0ml9t7fUgDsayR5Y5rSzxQilzR9FGu/EH2jQOcKSAeAfWeylyW8juy3OkWRvNA== + +array-union@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" + integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== + +array.prototype.flatmap@^1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/array.prototype.flatmap/-/array.prototype.flatmap-1.2.4.tgz#94cfd47cc1556ec0747d97f7c7738c58122004c9" + integrity sha512-r9Z0zYoxqHz60vvQbWEdXIEtCwHF0yxaWfno9qzXeNHvfyl3BZqygmGzb84dsubyaXLH4husF+NFgMSdpZhk2Q== + dependencies: + call-bind "^1.0.0" + define-properties "^1.1.3" + es-abstract "^1.18.0-next.1" + function-bind "^1.1.1" + +arrify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" + integrity sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0= + +asap@~2.0.3: + version "2.0.6" + resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" + integrity sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY= + +asn1.js@^5.2.0: + version "5.4.1" + resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-5.4.1.tgz#11a980b84ebb91781ce35b0fdc2ee294e3783f07" + integrity sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA== + dependencies: + bn.js "^4.0.0" + inherits "^2.0.1" + minimalistic-assert "^1.0.0" + safer-buffer "^2.1.0" + +asn1@~0.2.3: + version "0.2.4" + resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136" + integrity sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg== + dependencies: + safer-buffer "~2.1.0" + +assert-plus@1.0.0, assert-plus@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" + integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU= + +ast-module-types@^2.3.2, ast-module-types@^2.4.0, ast-module-types@^2.6.0, ast-module-types@^2.7.0, ast-module-types@^2.7.1: + version "2.7.1" + resolved "https://registry.yarnpkg.com/ast-module-types/-/ast-module-types-2.7.1.tgz#3f7989ef8dfa1fdb82dfe0ab02bdfc7c77a57dd3" + integrity sha512-Rnnx/4Dus6fn7fTqdeLEAn5vUll5w7/vts0RN608yFa6si/rDOUonlIIiwugHBFWjylHjxm9owoSZn71KwG4gw== + +ast-types@0.13.2: + version "0.13.2" + resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.13.2.tgz#df39b677a911a83f3a049644fb74fdded23cea48" + integrity sha512-uWMHxJxtfj/1oZClOxDEV1sQ1HCDkA4MG8Gr69KKeBjEVH0R84WlejZ0y2DcwyBlpAEMltmVYkVgqfLFb2oyiA== + +async-retry@1.2.3: + version "1.2.3" + resolved "https://registry.yarnpkg.com/async-retry/-/async-retry-1.2.3.tgz#a6521f338358d322b1a0012b79030c6f411d1ce0" + integrity sha512-tfDb02Th6CE6pJUF2gjW5ZVjsgwlucVXOEQMvEX9JgSJMs9gAX+Nz3xRuJBKuUYjTSYORqvDBORdAQ3LU59g7Q== + dependencies: + retry "0.12.0" + +async-retry@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/async-retry/-/async-retry-1.3.1.tgz#139f31f8ddce50c0870b0ba558a6079684aaed55" + integrity sha512-aiieFW/7h3hY0Bq5d+ktDBejxuwR78vRu9hDUdR8rNhSaQ29VzPL4AoIRG7D/c7tdenwOcKvgPM6tIxB3cB6HA== + dependencies: + retry "0.12.0" + +asynckit@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" + integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= + +atob@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" + integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== + +auto-bind@~4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/auto-bind/-/auto-bind-4.0.0.tgz#e3589fc6c2da8f7ca43ba9f84fa52a744fc997fb" + integrity sha512-Hdw8qdNiqdJ8LqT0iK0sVzkFbzg6fhnQqqfWhBDxcHZvU75+B+ayzTy8x+k5Ix0Y92XOhOUlx74ps+bA6BeYMQ== + +autoprefixer@^9.4.5, autoprefixer@^9.6.1: + version "9.8.6" + resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-9.8.6.tgz#3b73594ca1bf9266320c5acf1588d74dea74210f" + integrity sha512-XrvP4VVHdRBCdX1S3WXVD8+RyG9qeb1D5Sn1DeLiG2xfSpzellk5k54xbUERJ3M5DggQxes39UGOTP8CFrEGbg== + dependencies: + browserslist "^4.12.0" + caniuse-lite "^1.0.30001109" + colorette "^1.2.1" + normalize-range "^0.1.2" + num2fraction "^1.2.2" + postcss "^7.0.32" + postcss-value-parser "^4.1.0" + +aws-sign2@~0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" + integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg= + +aws4@^1.8.0: + version "1.11.0" + resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.11.0.tgz#d61f46d83b2519250e2784daf5b09479a8b41c59" + integrity sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA== + +babel-plugin-dynamic-import-node@^2.3.3: + version "2.3.3" + resolved "https://registry.yarnpkg.com/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz#84fda19c976ec5c6defef57f9427b3def66e17a3" + integrity sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ== + dependencies: + object.assign "^4.1.0" + +babel-plugin-syntax-jsx@6.18.0: + version "6.18.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz#0af32a9a6e13ca7a3fd5069e62d7b0f58d0d8946" + integrity sha1-CvMqmm4Tyno/1QaeYtew9Y0NiUY= + +babel-plugin-syntax-trailing-function-commas@^7.0.0-beta.0: + version "7.0.0-beta.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-7.0.0-beta.0.tgz#aa213c1435e2bffeb6fca842287ef534ad05d5cf" + integrity sha512-Xj9XuRuz3nTSbaTXWv3itLOcxyF4oPD8douBBmj7U9BBC6nEBYfyOJYQMf/8PJAFotC62UY5dFfIGEPr7WswzQ== + +babel-plugin-transform-define@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-define/-/babel-plugin-transform-define-2.0.0.tgz#79c3536635f899aabaf830b194b25519465675a4" + integrity sha512-0dv5RNRUlUKxGYIIErl01lpvi8b7W2R04Qcl1mCj70ahwZcgiklfXnFlh4FGnRh6aayCfSZKdhiMryVzcq5Dmg== + dependencies: + lodash "^4.17.11" + traverse "0.6.6" + +babel-plugin-transform-react-remove-prop-types@0.4.24: + version "0.4.24" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-remove-prop-types/-/babel-plugin-transform-react-remove-prop-types-0.4.24.tgz#f2edaf9b4c6a5fbe5c1d678bfb531078c1555f3a" + integrity sha512-eqj0hVcJUR57/Ug2zE1Yswsw4LhuqqHhD+8v120T1cl3kjg76QwtyBrdIk4WVwK+lAhBJVYCd/v+4nc4y+8JsA== + +babel-preset-fbjs@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/babel-preset-fbjs/-/babel-preset-fbjs-3.3.0.tgz#a6024764ea86c8e06a22d794ca8b69534d263541" + integrity sha512-7QTLTCd2gwB2qGoi5epSULMHugSVgpcVt5YAeiFO9ABLrutDQzKfGwzxgZHLpugq8qMdg/DhRZDZ5CLKxBkEbw== + dependencies: + "@babel/plugin-proposal-class-properties" "^7.0.0" + "@babel/plugin-proposal-object-rest-spread" "^7.0.0" + "@babel/plugin-syntax-class-properties" "^7.0.0" + "@babel/plugin-syntax-flow" "^7.0.0" + "@babel/plugin-syntax-jsx" "^7.0.0" + "@babel/plugin-syntax-object-rest-spread" "^7.0.0" + "@babel/plugin-transform-arrow-functions" "^7.0.0" + "@babel/plugin-transform-block-scoped-functions" "^7.0.0" + "@babel/plugin-transform-block-scoping" "^7.0.0" + "@babel/plugin-transform-classes" "^7.0.0" + "@babel/plugin-transform-computed-properties" "^7.0.0" + "@babel/plugin-transform-destructuring" "^7.0.0" + "@babel/plugin-transform-flow-strip-types" "^7.0.0" + "@babel/plugin-transform-for-of" "^7.0.0" + "@babel/plugin-transform-function-name" "^7.0.0" + "@babel/plugin-transform-literals" "^7.0.0" + "@babel/plugin-transform-member-expression-literals" "^7.0.0" + "@babel/plugin-transform-modules-commonjs" "^7.0.0" + "@babel/plugin-transform-object-super" "^7.0.0" + "@babel/plugin-transform-parameters" "^7.0.0" + "@babel/plugin-transform-property-literals" "^7.0.0" + "@babel/plugin-transform-react-display-name" "^7.0.0" + "@babel/plugin-transform-react-jsx" "^7.0.0" + "@babel/plugin-transform-shorthand-properties" "^7.0.0" + "@babel/plugin-transform-spread" "^7.0.0" + "@babel/plugin-transform-template-literals" "^7.0.0" + babel-plugin-syntax-trailing-function-commas "^7.0.0-beta.0" + +balanced-match@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" + integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= + +base64-js@^1.0.2, base64-js@^1.3.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" + integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== + +bcrypt-pbkdf@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" + integrity sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4= + dependencies: + tweetnacl "^0.14.3" + +big.js@^5.2.2: + version "5.2.2" + resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328" + integrity sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ== + +binary-extensions@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" + integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== + +bl@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/bl/-/bl-4.0.3.tgz#12d6287adc29080e22a705e5764b2a9522cdc489" + integrity sha512-fs4G6/Hu4/EE+F75J8DuN/0IpQqNjAdC7aEQv7Qt8MHGUH7Ckv2MwTEEeN9QehD0pfIDkMI1bkHYkKy7xHyKIg== + dependencies: + buffer "^5.5.0" + inherits "^2.0.4" + readable-stream "^3.4.0" + +bluebird@^3.7.2: + version "3.7.2" + resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" + integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== + +bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.4.0: + version "4.11.9" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.9.tgz#26d556829458f9d1e81fc48952493d0ba3507828" + integrity sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw== + +bn.js@^5.0.0, bn.js@^5.1.1: + version "5.1.3" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.1.3.tgz#beca005408f642ebebea80b042b4d18d2ac0ee6b" + integrity sha512-GkTiFpjFtUzU9CbMeJ5iazkCzGL3jrhzerzZIuqLABjbwRaFt33I9tUdSNryIptM+RxDet6OKm2WnLXzW51KsQ== + +body-scroll-lock@^3.1.5: + version "3.1.5" + resolved "https://registry.yarnpkg.com/body-scroll-lock/-/body-scroll-lock-3.1.5.tgz#c1392d9217ed2c3e237fee1e910f6cdd80b7aaec" + integrity sha512-Yi1Xaml0EvNA0OYWxXiYNqY24AfWkbA6w5vxE7GWxtKfzIbZM+Qw+aSmkgsbWzbHiy/RCSkUZBplVxTA+E4jJg== + +bowser@^2.11.0: + version "2.11.0" + resolved "https://registry.yarnpkg.com/bowser/-/bowser-2.11.0.tgz#5ca3c35757a7aa5771500c70a73a9f91ef420a8f" + integrity sha512-AlcaJBi/pqqJBIQ8U9Mcpc9i8Aqxn88Skv5d+xBX006BY5u8N3mGLHa5Lgppa7L/HfwgwLgZ6NYs+Ag6uUmJRA== + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +braces@^3.0.1, braces@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" + integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== + dependencies: + fill-range "^7.0.1" + +brorand@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" + integrity sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8= + +browserify-aes@^1.0.0, browserify-aes@^1.0.4: + version "1.2.0" + resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.2.0.tgz#326734642f403dabc3003209853bb70ad428ef48" + integrity sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA== + dependencies: + buffer-xor "^1.0.3" + cipher-base "^1.0.0" + create-hash "^1.1.0" + evp_bytestokey "^1.0.3" + inherits "^2.0.1" + safe-buffer "^5.0.1" + +browserify-cipher@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/browserify-cipher/-/browserify-cipher-1.0.1.tgz#8d6474c1b870bfdabcd3bcfcc1934a10e94f15f0" + integrity sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w== + dependencies: + browserify-aes "^1.0.4" + browserify-des "^1.0.0" + evp_bytestokey "^1.0.0" + +browserify-des@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/browserify-des/-/browserify-des-1.0.2.tgz#3af4f1f59839403572f1c66204375f7a7f703e9c" + integrity sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A== + dependencies: + cipher-base "^1.0.1" + des.js "^1.0.0" + inherits "^2.0.1" + safe-buffer "^5.1.2" + +browserify-rsa@^4.0.0, browserify-rsa@^4.0.1: + version "4.1.0" + resolved "https://registry.yarnpkg.com/browserify-rsa/-/browserify-rsa-4.1.0.tgz#b2fd06b5b75ae297f7ce2dc651f918f5be158c8d" + integrity sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog== + dependencies: + bn.js "^5.0.0" + randombytes "^2.0.1" + +browserify-sign@^4.0.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/browserify-sign/-/browserify-sign-4.2.1.tgz#eaf4add46dd54be3bb3b36c0cf15abbeba7956c3" + integrity sha512-/vrA5fguVAKKAVTNJjgSm1tRQDHUU6DbwO9IROu/0WAzC8PKhucDSh18J0RMvVeHAn5puMd+QHC2erPRNf8lmg== + dependencies: + bn.js "^5.1.1" + browserify-rsa "^4.0.1" + create-hash "^1.2.0" + create-hmac "^1.1.7" + elliptic "^6.5.3" + inherits "^2.0.4" + parse-asn1 "^5.1.5" + readable-stream "^3.6.0" + safe-buffer "^5.2.0" + +browserslist@4.14.6: + version "4.14.6" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.14.6.tgz#97702a9c212e0c6b6afefad913d3a1538e348457" + integrity sha512-zeFYcUo85ENhc/zxHbiIp0LGzzTrE2Pv2JhxvS7kpUb9Q9D38kUX6Bie7pGutJ/5iF5rOxE7CepAuWD56xJ33A== + dependencies: + caniuse-lite "^1.0.30001154" + electron-to-chromium "^1.3.585" + escalade "^3.1.1" + node-releases "^1.1.65" + +browserslist@^4.12.0, browserslist@^4.14.5, browserslist@^4.6.4: + version "4.16.1" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.16.1.tgz#bf757a2da376b3447b800a16f0f1c96358138766" + integrity sha512-UXhDrwqsNcpTYJBTZsbGATDxZbiVDsx6UjpmRUmtnP10pr8wAYr5LgFoEFw9ixriQH2mv/NX2SfGzE/o8GndLA== + dependencies: + caniuse-lite "^1.0.30001173" + colorette "^1.2.1" + electron-to-chromium "^1.3.634" + escalade "^3.1.1" + node-releases "^1.1.69" + +bser@2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/bser/-/bser-2.1.1.tgz#e6787da20ece9d07998533cfd9de6f5c38f4bc05" + integrity sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ== + dependencies: + node-int64 "^0.4.0" + +buffer-equal-constant-time@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz#f8e71132f7ffe6e01a5c9697a4c6f3e48d5cc819" + integrity sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk= + +buffer-from@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" + integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A== + +buffer-xor@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9" + integrity sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk= + +buffer@5.6.0: + version "5.6.0" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.6.0.tgz#a31749dc7d81d84db08abf937b6b8c4033f62786" + integrity sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw== + dependencies: + base64-js "^1.0.2" + ieee754 "^1.1.4" + +buffer@^5.5.0, buffer@^5.7.0: + version "5.7.1" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0" + integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ== + dependencies: + base64-js "^1.3.1" + ieee754 "^1.1.13" + +bunyan-prettystream@^0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/bunyan-prettystream/-/bunyan-prettystream-0.1.3.tgz#6c3b713266f6ad32007c7b6ab1e998a245349d98" + integrity sha1-bDtxMmb2rTIAfHtqsemYokU0nZg= + +bunyan@^1.8.14: + version "1.8.15" + resolved "https://registry.yarnpkg.com/bunyan/-/bunyan-1.8.15.tgz#8ce34ca908a17d0776576ca1b2f6cbd916e93b46" + integrity sha512-0tECWShh6wUysgucJcBAoYegf3JJoZWibxdqhTm7OHPeT42qdjkZ29QCMcKwbgU1kiH+auSIasNRXMLWXafXig== + optionalDependencies: + dtrace-provider "~0.8" + moment "^2.19.3" + mv "~2" + safe-json-stringify "~1" + +busboy@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/busboy/-/busboy-0.3.1.tgz#170899274c5bf38aae27d5c62b71268cd585fd1b" + integrity sha512-y7tTxhGKXcyBxRKAni+awqx8uqaJKrSFSNFSeRG5CsWNdmy2BIK+6VGWEW7TZnIO/533mtMEA4rOevQV815YJw== + dependencies: + dicer "0.3.0" + +bytes@3.1.0, bytes@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.0.tgz#f6cf7933a360e0588fa9fde85651cdc7f805d1f6" + integrity sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg== + +cacheable-request@^6.0.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-6.1.0.tgz#20ffb8bd162ba4be11e9567d823db651052ca912" + integrity sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg== + dependencies: + clone-response "^1.0.2" + get-stream "^5.1.0" + http-cache-semantics "^4.0.0" + keyv "^3.0.0" + lowercase-keys "^2.0.0" + normalize-url "^4.1.0" + responselike "^1.0.2" + +call-bind@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.1.tgz#29aca9151f8ddcfd5b9b786898f005f425e88567" + integrity sha512-tvAvUwNcRikl3RVF20X9lsYmmepsovzTWeJiXjO0PkJp15uy/6xKFZOQtuiSULwYW+6ToZBprphCgWXC2dSgcQ== + dependencies: + function-bind "^1.1.1" + get-intrinsic "^1.0.2" + +callsites@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" + integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== + +camel-case@4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/camel-case/-/camel-case-4.1.1.tgz#1fc41c854f00e2f7d0139dfeba1542d6896fe547" + integrity sha512-7fa2WcG4fYFkclIvEmxBbTvmibwF2/agfEBc6q3lOpVu0A13ltLsA+Hr/8Hp6kp5f+G7hKi6t8lys6XxP+1K6Q== + dependencies: + pascal-case "^3.1.1" + tslib "^1.10.0" + +camel-case@4.1.2, camel-case@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/camel-case/-/camel-case-4.1.2.tgz#9728072a954f805228225a6deea6b38461e1bd5a" + integrity sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw== + dependencies: + pascal-case "^3.1.2" + tslib "^2.0.3" + +camelcase-css@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/camelcase-css/-/camelcase-css-2.0.1.tgz#ee978f6947914cc30c6b44741b6ed1df7f043fd5" + integrity sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA== + +camelcase-keys@^6.2.2: + version "6.2.2" + resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-6.2.2.tgz#5e755d6ba51aa223ec7d3d52f25778210f9dc3c0" + integrity sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg== + dependencies: + camelcase "^5.3.1" + map-obj "^4.0.0" + quick-lru "^4.0.1" + +camelcase@5.3.1, camelcase@^5.0.0, camelcase@^5.3.1: + version "5.3.1" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" + integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== + +camelcase@^6.0.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.2.0.tgz#924af881c9d525ac9d87f40d964e5cea982a1809" + integrity sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg== + +caniuse-lite@^1.0.30000981, caniuse-lite@^1.0.30001093, caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001113, caniuse-lite@^1.0.30001154, caniuse-lite@^1.0.30001173: + version "1.0.30001174" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001174.tgz#0f2aca2153fd88ceb07a2bb982fc2acb787623c4" + integrity sha512-tqClL/4ThQq6cfFXH3oJL4rifFBeM6gTkphjao5kgwMaW9yn0tKgQLAEfKzDwj6HQWCB/aWo8kTFlSvIN8geEA== + +caseless@~0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" + integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= + +chalk@2.4.2, chalk@^2.0.0, chalk@^2.3.0, chalk@^2.4.1, chalk@^2.4.2: + version "2.4.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" + integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + +chalk@4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.0.0.tgz#6e98081ed2d17faab615eb52ac66ec1fe6209e72" + integrity sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + +chalk@^1.0.0, chalk@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" + integrity sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg= + dependencies: + ansi-styles "^2.2.1" + escape-string-regexp "^1.0.2" + has-ansi "^2.0.0" + strip-ansi "^3.0.0" + supports-color "^2.0.0" + +"chalk@^3.0.0 || ^4.0.0", chalk@^4.0.0, chalk@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.0.tgz#4e14870a618d9e2edd97dd8345fd9d9dc315646a" + integrity sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + +chardet@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" + integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA== + +chokidar@3.4.3: + version "3.4.3" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.4.3.tgz#c1df38231448e45ca4ac588e6c79573ba6a57d5b" + integrity sha512-DtM3g7juCXQxFVSNPNByEC2+NImtBuxQQvWlHunpJIS5Ocr0lG306cC7FCi7cEA0fzmybPUIl4txBIobk1gGOQ== + dependencies: + anymatch "~3.1.1" + braces "~3.0.2" + glob-parent "~5.1.0" + is-binary-path "~2.1.0" + is-glob "~4.0.1" + normalize-path "~3.0.0" + readdirp "~3.5.0" + optionalDependencies: + fsevents "~2.1.2" + +chokidar@^3.4.3: + version "3.5.0" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.0.tgz#458a4816a415e9d3b3caa4faec2b96a6935a9e65" + integrity sha512-JgQM9JS92ZbFR4P90EvmzNpSGhpPBGBSj10PILeDyYFwp4h2/D9OM03wsJ4zW1fEp4ka2DGrnUeD7FuvQ2aZ2Q== + dependencies: + anymatch "~3.1.1" + braces "~3.0.2" + glob-parent "~5.1.0" + is-binary-path "~2.1.0" + is-glob "~4.0.1" + normalize-path "~3.0.0" + readdirp "~3.5.0" + optionalDependencies: + fsevents "~2.3.1" + +chownr@^1.1.1: + version "1.1.4" + resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b" + integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg== + +chrome-trace-event@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz#234090ee97c7d4ad1a2c4beae27505deffc608a4" + integrity sha512-9e/zx1jw7B4CO+c/RXoCsfg/x1AfUBioy4owYH0bJprEYAx5hRFLRhWBqHAG57D0ZM4H7vxbP7bPe0VwhQRYDQ== + dependencies: + tslib "^1.9.0" + +cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de" + integrity sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q== + dependencies: + inherits "^2.0.1" + safe-buffer "^5.0.1" + +classnames@2.2.6, classnames@^2.2.6: + version "2.2.6" + resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.2.6.tgz#43935bffdd291f326dad0a205309b38d00f650ce" + integrity sha512-JR/iSQOSt+LQIWwrwEzJ9uk0xfN3mTVYMwt1Ir5mUcSN6pU+V4zQFFaJsclJbPuAUQH+yfWef6tm7l1quW3C8Q== + +cli-cursor@^2.0.0, cli-cursor@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5" + integrity sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU= + dependencies: + restore-cursor "^2.0.0" + +cli-cursor@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-3.1.0.tgz#264305a7ae490d1d03bf0c9ba7c925d1753af307" + integrity sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw== + dependencies: + restore-cursor "^3.1.0" + +cli-spinners@^2.5.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.5.0.tgz#12763e47251bf951cb75c201dfa58ff1bcb2d047" + integrity sha512-PC+AmIuK04E6aeSs/pUccSujsTzBhu4HzC2dL+CfJB/Jcc2qTRbEwZQDfIUpt2Xl8BodYBEq8w4fc0kU2I9DjQ== + +cli-truncate@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/cli-truncate/-/cli-truncate-0.2.1.tgz#9f15cfbb0705005369216c626ac7d05ab90dd574" + integrity sha1-nxXPuwcFAFNpIWxiasfQWrkN1XQ= + dependencies: + slice-ansi "0.0.4" + string-width "^1.0.1" + +cli-width@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-3.0.0.tgz#a2f48437a2caa9a22436e794bf071ec9e61cedf6" + integrity sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw== + +cliui@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-6.0.0.tgz#511d702c0c4e41ca156d7d0e96021f23e13225b1" + integrity sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ== + dependencies: + string-width "^4.2.0" + strip-ansi "^6.0.0" + wrap-ansi "^6.2.0" + +cliui@^7.0.2: + version "7.0.4" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" + integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ== + dependencies: + string-width "^4.2.0" + strip-ansi "^6.0.0" + wrap-ansi "^7.0.0" + +clone-response@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/clone-response/-/clone-response-1.0.2.tgz#d1dc973920314df67fbeb94223b4ee350239e96b" + integrity sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws= + dependencies: + mimic-response "^1.0.0" + +clone@^1.0.2: + version "1.0.4" + resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e" + integrity sha1-2jCcwmPfFZlMaIypAheco8fNfH4= + +code-point-at@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" + integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= + +color-convert@^1.9.0, color-convert@^1.9.1: + version "1.9.3" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" + integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== + dependencies: + color-name "1.1.3" + +color-convert@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" + integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== + dependencies: + color-name "~1.1.4" + +color-name@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" + integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= + +color-name@^1.0.0, color-name@~1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + +color-string@^1.5.4: + version "1.5.4" + resolved "https://registry.yarnpkg.com/color-string/-/color-string-1.5.4.tgz#dd51cd25cfee953d138fe4002372cc3d0e504cb6" + integrity sha512-57yF5yt8Xa3czSEW1jfQDE79Idk0+AkN/4KWad6tbdxUmAs3MvjxlWSWD4deYytcRfoZ9nhKyFl1kj5tBvidbw== + dependencies: + color-name "^1.0.0" + simple-swizzle "^0.2.2" + +color@^3.1.2, color@^3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/color/-/color-3.1.3.tgz#ca67fb4e7b97d611dcde39eceed422067d91596e" + integrity sha512-xgXAcTHa2HeFCGLE9Xs/R82hujGtu9Jd9x4NW3T34+OMs7VoPsjwzRczKHvTAHeJwWFwX5j15+MgAppE8ztObQ== + dependencies: + color-convert "^1.9.1" + color-string "^1.5.4" + +colorette@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.2.1.tgz#4d0b921325c14faf92633086a536db6e89564b1b" + integrity sha512-puCDz0CzydiSYOrnXpz/PKd69zRrribezjtE9yd4zvytoRc8+RY/KJPvtPFKZS3E3wP6neGyMe0vOTlHO5L3Pw== + +combined-stream@^1.0.6, combined-stream@^1.0.8, combined-stream@~1.0.6: + version "1.0.8" + resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" + integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== + dependencies: + delayed-stream "~1.0.0" + +commander@^2.13.0, commander@^2.16.0, commander@^2.20.0, commander@^2.20.3, commander@^2.8.1: + version "2.20.3" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" + integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== + +commander@^5.0.0, commander@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-5.1.0.tgz#46abbd1652f8e059bddaef99bbdcb2ad9cf179ae" + integrity sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg== + +commander@^6.2.0: + version "6.2.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-6.2.1.tgz#0792eb682dfbc325999bb2b84fddddba110ac73c" + integrity sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA== + +common-tags@1.8.0, common-tags@^1.8.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/common-tags/-/common-tags-1.8.0.tgz#8e3153e542d4a39e9b10554434afaaf98956a937" + integrity sha512-6P6g0uetGpW/sdyUy/iQQCbFF0kWVMSIVSyYz7Zgjcgh8mgw8PQzDNZeyZ5DQ2gM7LBoZPHmnjz8rUthkBG5tw== + +commondir@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" + integrity sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs= + +compose-function@3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/compose-function/-/compose-function-3.0.3.tgz#9ed675f13cc54501d30950a486ff6a7ba3ab185f" + integrity sha1-ntZ18TzFRQHTCVCkhv9qe6OrGF8= + dependencies: + arity-n "^1.0.4" + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= + +console-control-strings@^1.0.0, console-control-strings@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" + integrity sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4= + +consolidate@^0.16.0: + version "0.16.0" + resolved "https://registry.yarnpkg.com/consolidate/-/consolidate-0.16.0.tgz#a11864768930f2f19431660a65906668f5fbdc16" + integrity sha512-Nhl1wzCslqXYTJVDyJCu3ODohy9OfBMB5uD2BiBTzd7w+QY0lBzafkR8y8755yMYHAaMD4NuzbAw03/xzfw+eQ== + dependencies: + bluebird "^3.7.2" + +constant-case@3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/constant-case/-/constant-case-3.0.3.tgz#ac910a99caf3926ac5112f352e3af599d8c5fc0a" + integrity sha512-FXtsSnnrFYpzDmvwDGQW+l8XK3GV1coLyBN0eBz16ZUzGaZcT2ANVCJmLeuw2GQgxKHQIe9e0w2dzkSfaRlUmA== + dependencies: + no-case "^3.0.3" + tslib "^1.10.0" + upper-case "^2.0.1" + +constant-case@^3.0.3: + version "3.0.4" + resolved "https://registry.yarnpkg.com/constant-case/-/constant-case-3.0.4.tgz#3b84a9aeaf4cf31ec45e6bf5de91bdfb0589faf1" + integrity sha512-I2hSBi7Vvs7BEuJDr5dDHfzb/Ruj3FyvFyh7KLilAjNQw3Be+xgqUBA2W6scVEcL0hL1dwPRtIqEPVUCKkSsyQ== + dependencies: + no-case "^3.0.4" + tslib "^2.0.3" + upper-case "^2.0.2" + +convert-source-map@1.7.0, convert-source-map@^1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.7.0.tgz#17a2cb882d7f77d3490585e2ce6c524424a3a442" + integrity sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA== + dependencies: + safe-buffer "~5.1.1" + +convert-source-map@^0.3.3: + version "0.3.5" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-0.3.5.tgz#f1d802950af7dd2631a1febe0596550c86ab3190" + integrity sha1-8dgClQr33SYxof6+BZZVDIarMZA= + +cookie@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.1.tgz#afd713fe26ebd21ba95ceb61f9a8116e50a537d1" + integrity sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA== + +core-util-is@1.0.2, core-util-is@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" + integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= + +cosmiconfig-toml-loader@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/cosmiconfig-toml-loader/-/cosmiconfig-toml-loader-1.0.0.tgz#0681383651cceff918177debe9084c0d3769509b" + integrity sha512-H/2gurFWVi7xXvCyvsWRLCMekl4tITJcX0QEsDMpzxtuxDyM59xLatYNg4s/k9AA/HdtCYfj2su8mgA0GSDLDA== + dependencies: + "@iarna/toml" "^2.2.5" + +cosmiconfig@6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-6.0.0.tgz#da4fee853c52f6b1e6935f41c1a2fc50bd4a9982" + integrity sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg== + dependencies: + "@types/parse-json" "^4.0.0" + import-fresh "^3.1.0" + parse-json "^5.0.0" + path-type "^4.0.0" + yaml "^1.7.2" + +cosmiconfig@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-7.0.0.tgz#ef9b44d773959cae63ddecd122de23853b60f8d3" + integrity sha512-pondGvTuVYDk++upghXJabWzL6Kxu6f26ljFw64Swq9v6sQPUL3EUlVDV56diOjpCayKihL6hVe8exIACU4XcA== + dependencies: + "@types/parse-json" "^4.0.0" + import-fresh "^3.2.1" + parse-json "^5.0.0" + path-type "^4.0.0" + yaml "^1.10.0" + +create-ecdh@^4.0.0: + version "4.0.4" + resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.4.tgz#d6e7f4bffa66736085a0762fd3a632684dabcc4e" + integrity sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A== + dependencies: + bn.js "^4.1.0" + elliptic "^6.5.3" + +create-hash@^1.1.0, create-hash@^1.1.2, create-hash@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.2.0.tgz#889078af11a63756bcfb59bd221996be3a9ef196" + integrity sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg== + dependencies: + cipher-base "^1.0.1" + inherits "^2.0.1" + md5.js "^1.3.4" + ripemd160 "^2.0.1" + sha.js "^2.4.0" + +create-hmac@^1.1.0, create-hmac@^1.1.4, create-hmac@^1.1.7: + version "1.1.7" + resolved "https://registry.yarnpkg.com/create-hmac/-/create-hmac-1.1.7.tgz#69170c78b3ab957147b2b8b04572e47ead2243ff" + integrity sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg== + dependencies: + cipher-base "^1.0.3" + create-hash "^1.1.0" + inherits "^2.0.1" + ripemd160 "^2.0.0" + safe-buffer "^5.0.1" + sha.js "^2.4.8" + +create-require@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333" + integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ== + +cross-fetch@3.0.6, cross-fetch@^3.0.4, cross-fetch@^3.0.6: + version "3.0.6" + resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-3.0.6.tgz#3a4040bc8941e653e0e9cf17f29ebcd177d3365c" + integrity sha512-KBPUbqgFjzWlVcURG+Svp9TlhA5uliYtiNx/0r8nv0pdypeQCRJ9IaSIc3q/x3q8t3F75cHuwxVql1HFGHCNJQ== + dependencies: + node-fetch "2.6.1" + +crypto-browserify@3.12.0: + version "3.12.0" + resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.12.0.tgz#396cf9f3137f03e4b8e532c58f698254e00f80ec" + integrity sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg== + dependencies: + browserify-cipher "^1.0.0" + browserify-sign "^4.0.0" + create-ecdh "^4.0.0" + create-hash "^1.1.0" + create-hmac "^1.1.0" + diffie-hellman "^5.0.0" + inherits "^2.0.1" + pbkdf2 "^3.0.3" + public-encrypt "^4.0.0" + randombytes "^2.0.0" + randomfill "^1.0.3" + +css-blank-pseudo@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/css-blank-pseudo/-/css-blank-pseudo-0.1.4.tgz#dfdefd3254bf8a82027993674ccf35483bfcb3c5" + integrity sha512-LHz35Hr83dnFeipc7oqFDmsjHdljj3TQtxGGiNWSOsTLIAubSm4TEz8qCaKFpk7idaQ1GfWscF4E6mgpBysA1w== + dependencies: + postcss "^7.0.5" + +css-has-pseudo@^0.10.0: + version "0.10.0" + resolved "https://registry.yarnpkg.com/css-has-pseudo/-/css-has-pseudo-0.10.0.tgz#3c642ab34ca242c59c41a125df9105841f6966ee" + integrity sha512-Z8hnfsZu4o/kt+AuFzeGpLVhFOGO9mluyHBaA2bA8aCGTwah5sT3WV/fTHH8UNZUytOIImuGPrl/prlb4oX4qQ== + dependencies: + postcss "^7.0.6" + postcss-selector-parser "^5.0.0-rc.4" + +css-loader@4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-4.3.0.tgz#c888af64b2a5b2e85462c72c0f4a85c7e2e0821e" + integrity sha512-rdezjCjScIrsL8BSYszgT4s476IcNKt6yX69t0pHjJVnPUTDpn4WfIpDQTN3wCJvUvfsz/mFjuGOekf3PY3NUg== + dependencies: + camelcase "^6.0.0" + cssesc "^3.0.0" + icss-utils "^4.1.1" + loader-utils "^2.0.0" + postcss "^7.0.32" + postcss-modules-extract-imports "^2.0.0" + postcss-modules-local-by-default "^3.0.3" + postcss-modules-scope "^2.2.0" + postcss-modules-values "^3.0.0" + postcss-value-parser "^4.1.0" + schema-utils "^2.7.1" + semver "^7.3.2" + +css-prefers-color-scheme@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/css-prefers-color-scheme/-/css-prefers-color-scheme-3.1.1.tgz#6f830a2714199d4f0d0d0bb8a27916ed65cff1f4" + integrity sha512-MTu6+tMs9S3EUqzmqLXEcgNRbNkkD/TGFvowpeoWJn5Vfq7FMgsmRQs9X5NXAURiOBmOxm/lLjsDNXDE6k9bhg== + dependencies: + postcss "^7.0.5" + +css-unit-converter@^1.1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/css-unit-converter/-/css-unit-converter-1.1.2.tgz#4c77f5a1954e6dbff60695ecb214e3270436ab21" + integrity sha512-IiJwMC8rdZE0+xiEZHeru6YoONC4rfPMqGm2W85jMIbkFvv5nFTwJVFHam2eFrN6txmoUYFAFXiv8ICVeTO0MA== + +css.escape@1.5.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/css.escape/-/css.escape-1.5.1.tgz#42e27d4fa04ae32f931a4b4d4191fa9cddee97cb" + integrity sha1-QuJ9T6BK4y+TGktNQZH6nN3ul8s= + +css@^2.0.0: + version "2.2.4" + resolved "https://registry.yarnpkg.com/css/-/css-2.2.4.tgz#c646755c73971f2bba6a601e2cf2fd71b1298929" + integrity sha512-oUnjmWpy0niI3x/mPL8dVEI1l7MnG3+HHyRPHf+YFSbK+svOhXpmSOcDURUh2aOCgl2grzrOPt1nHLuCVFULLw== + dependencies: + inherits "^2.0.3" + source-map "^0.6.1" + source-map-resolve "^0.5.2" + urix "^0.1.0" + +cssdb@^4.4.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/cssdb/-/cssdb-4.4.0.tgz#3bf2f2a68c10f5c6a08abd92378331ee803cddb0" + integrity sha512-LsTAR1JPEM9TpGhl/0p3nQecC2LJ0kD8X5YARu1hk/9I1gril5vDtMZyNxcEpxxDj34YNck/ucjuoUd66K03oQ== + +cssesc@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-2.0.0.tgz#3b13bd1bb1cb36e1bcb5a4dcd27f54c5dcb35703" + integrity sha512-MsCAG1z9lPdoO/IUMLSBWBSVxVtJ1395VGIQ+Fc2gNdkQ1hNDnQdw3YhA71WJCBW1vdwA0cAnk/DnW6bqoEUYg== + +cssesc@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee" + integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg== + +cssnano-preset-simple@1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/cssnano-preset-simple/-/cssnano-preset-simple-1.2.1.tgz#8976013114b1fc4718253d30f21aaed1780fb80e" + integrity sha512-B2KahOIFTV6dw5Ioy9jHshTh/vAYNnUB2enyWRgnAEg3oJBjI/035ExpePaMqS2SwpbH7gCgvQqwpMBH6hTJSw== + dependencies: + caniuse-lite "^1.0.30001093" + postcss "^7.0.32" + +cssnano-simple@1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/cssnano-simple/-/cssnano-simple-1.2.1.tgz#6de5d9dd75774bc8f31767573410a952c7dd8a12" + integrity sha512-9vOyjw8Dj/T12kIOnXPZ5VnEIo6F3YMaIn0wqJXmn277R58cWpI3AvtdlCBtohX7VAUNYcyk2d0dKcXXkb5I6Q== + dependencies: + cssnano-preset-simple "1.2.1" + postcss "^7.0.32" + +csstype@^3.0.2: + version "3.0.6" + resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.0.6.tgz#865d0b5833d7d8d40f4e5b8a6d76aea3de4725ef" + integrity sha512-+ZAmfyWMT7TiIlzdqJgjMb7S4f1beorDbWbsocyK4RaiqA5RTX3K14bnBWmmA9QEM0gRdsjyyrEmcyga8Zsxmw== + +d@1, d@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/d/-/d-1.0.1.tgz#8698095372d58dbee346ffd0c7093f99f8f9eb5a" + integrity sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA== + dependencies: + es5-ext "^0.10.50" + type "^1.0.1" + +dashdash@^1.12.0: + version "1.14.1" + resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" + integrity sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA= + dependencies: + assert-plus "^1.0.0" + +data-uri-to-buffer@3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/data-uri-to-buffer/-/data-uri-to-buffer-3.0.1.tgz#594b8973938c5bc2c33046535785341abc4f3636" + integrity sha512-WboRycPNsVw3B3TL559F7kuBUM4d8CgMEvk6xEJlOp7OBPjt6G7z8WMWlD2rOFZLk6OYfFIUGsCOWzcQH9K2og== + +dataloader@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/dataloader/-/dataloader-2.0.0.tgz#41eaf123db115987e21ca93c005cd7753c55fe6f" + integrity sha512-YzhyDAwA4TaQIhM5go+vCLmU0UikghC/t9DTQYZR2M/UvZ1MdOhPezSDZcjj9uqQJOMqjLcpWtyW2iNINdlatQ== + +date-fns@^1.27.2: + version "1.30.1" + resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-1.30.1.tgz#2e71bf0b119153dbb4cc4e88d9ea5acfb50dc05c" + integrity sha512-hBSVCvSmWC+QypYObzwGOd9wqdDpOt+0wl0KbU+R+uuZBS1jN8VsD1ss3irQDknRj5NvxiTF6oj/nDRnN/UQNw== + +debounce@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/debounce/-/debounce-1.2.0.tgz#44a540abc0ea9943018dc0eaa95cce87f65cd131" + integrity sha512-mYtLl1xfZLi1m4RtQYlZgJUNQjl4ZxVnHzIR8nLLgi4q1YT8o/WM+MK/f8yfcc9s5Ir5zRaPZyZU6xs1Syoocg== + +debug@3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" + integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g== + dependencies: + ms "2.0.0" + +debug@4, debug@^4.0.0, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.2.0, debug@^4.2.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.1.tgz#f0d229c505e0c6d8c49ac553d1b13dc183f6b2ee" + integrity sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ== + dependencies: + ms "2.1.2" + +debug@^3.1.0: + version "3.2.7" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" + integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== + dependencies: + ms "^2.1.1" + +decamelize-keys@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/decamelize-keys/-/decamelize-keys-1.1.0.tgz#d171a87933252807eb3cb61dc1c1445d078df2d9" + integrity sha1-0XGoeTMlKAfrPLYdwcFEXQeN8tk= + dependencies: + decamelize "^1.1.0" + map-obj "^1.0.0" + +decamelize@^1.1.0, decamelize@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" + integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= + +decode-uri-component@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" + integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU= + +decomment@^0.9.2: + version "0.9.3" + resolved "https://registry.yarnpkg.com/decomment/-/decomment-0.9.3.tgz#b913f32e5fe1113848f516caa5c7afefa9544d38" + integrity sha512-5skH5BfUL3n09RDmMVaHS1QGCiZRnl2nArUwmsE9JRY93Ueh3tihYl5wIrDdAuXnoFhxVis/DmRWREO2c6DG3w== + dependencies: + esprima "4.0.1" + +decompress-response@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-3.3.0.tgz#80a4dd323748384bfa248083622aedec982adff3" + integrity sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M= + dependencies: + mimic-response "^1.0.0" + +decompress-response@^4.2.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-4.2.1.tgz#414023cc7a302da25ce2ec82d0d5238ccafd8986" + integrity sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw== + dependencies: + mimic-response "^2.0.0" + +decompress-response@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-6.0.0.tgz#ca387612ddb7e104bd16d85aab00d5ecf09c66fc" + integrity sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ== + dependencies: + mimic-response "^3.1.0" + +deep-extend@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" + integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== + +deep-is@~0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" + integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ= + +defaults@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/defaults/-/defaults-1.0.3.tgz#c656051e9817d9ff08ed881477f3fe4019f3ef7d" + integrity sha1-xlYFHpgX2f8I7YgUd/P+QBnz730= + dependencies: + clone "^1.0.2" + +defer-to-connect@^1.0.1: + version "1.1.3" + resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-1.1.3.tgz#331ae050c08dcf789f8c83a7b81f0ed94f4ac591" + integrity sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ== + +define-properties@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" + integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ== + dependencies: + object-keys "^1.0.12" + +defined@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/defined/-/defined-1.0.0.tgz#c98d9bcef75674188e110969151199e39b1fa693" + integrity sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM= + +delayed-stream@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" + integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= + +delegates@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" + integrity sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o= + +depd@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" + integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak= + +dependency-graph@^0.9.0: + version "0.9.0" + resolved "https://registry.yarnpkg.com/dependency-graph/-/dependency-graph-0.9.0.tgz#11aed7e203bc8b00f48356d92db27b265c445318" + integrity sha512-9YLIBURXj4DJMFALxXw9K3Y3rwb5Fk0X5/8ipCzaN84+gKxoHK43tVKRNakCQbiEx07E8Uwhuq21BpUagFhZ8w== + +dependency-tree@^7.2.2: + version "7.2.2" + resolved "https://registry.yarnpkg.com/dependency-tree/-/dependency-tree-7.2.2.tgz#2366c96c0a905adfc19e9ed8dcdbfcb93476dfb5" + integrity sha512-WWZJpNuMWqEM97CGykmyKLjjUWGVGkRRMSIEBWk5izmugxmivnItg4MMHkDzuvmB/7vglhudEoc5wyMp5ODD+Q== + dependencies: + commander "^2.20.3" + debug "^4.2.1" + filing-cabinet "^2.6.0" + precinct "^6.3.1" + typescript "^3.9.7" + +dequal@2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/dequal/-/dequal-2.0.2.tgz#85ca22025e3a87e65ef75a7a437b35284a7e319d" + integrity sha512-q9K8BlJVxK7hQYqa6XISGmBZbtQQWVXSrRrWreHC94rMt1QL/Impruc+7p2CYSYuVIUr+YCt6hjrs1kkdJRTug== + +des.js@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/des.js/-/des.js-1.0.1.tgz#5382142e1bdc53f85d86d53e5f4aa7deb91e0843" + integrity sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA== + dependencies: + inherits "^2.0.1" + minimalistic-assert "^1.0.0" + +detect-indent@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-6.0.0.tgz#0abd0f549f69fc6659a254fe96786186b6f528fd" + integrity sha512-oSyFlqaTHCItVRGK5RmrmjB+CmaMOW7IaNA/kdxqhoa6d17j/5ce9O9eWXmV/KEdRwqpQA+Vqe8a8Bsybu4YnA== + +detect-libc@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b" + integrity sha1-+hN8S9aY7fVc1c0CrFWfkaTEups= + +detective-amd@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/detective-amd/-/detective-amd-3.0.1.tgz#aca8eddb1f405821953faf4a893d9b9e0430b09e" + integrity sha512-vJgluSKkPyo+/McW9hzwmZwY1VPA3BS0VS1agdpPAWAhr65HwC1ox4Ig82rVfGYDYCa4GcKQON5JWBk++2Kf1Q== + dependencies: + ast-module-types "^2.7.0" + escodegen "^1.8.0" + get-amd-module-type "^3.0.0" + node-source-walk "^4.0.0" + +detective-cjs@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/detective-cjs/-/detective-cjs-3.1.1.tgz#18da3e39a002d2098a1123d45ce1de1b0d9045a0" + integrity sha512-JQtNTBgFY6h8uT6pgph5QpV3IyxDv+z3qPk/FZRDT9TlFfm5dnRtpH39WtQEr1khqsUxVqXzKjZHpdoQvQbllg== + dependencies: + ast-module-types "^2.4.0" + node-source-walk "^4.0.0" + +detective-es6@^2.1.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/detective-es6/-/detective-es6-2.2.0.tgz#8f2baba3f8cd90a5cfd748f5ac436f0158ed2585" + integrity sha512-fSpNY0SLER7/sVgQZ1NxJPwmc9uCTzNgdkQDhAaj8NPYwr7Qji9QBcmbNvtMCnuuOGMuKn3O7jv0An+/WRWJZQ== + dependencies: + node-source-walk "^4.0.0" + +detective-less@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/detective-less/-/detective-less-1.0.2.tgz#a68af9ca5f69d74b7d0aa190218b211d83b4f7e3" + integrity sha512-Rps1xDkEEBSq3kLdsdnHZL1x2S4NGDcbrjmd4q+PykK5aJwDdP5MBgrJw1Xo+kyUHuv3JEzPqxr+Dj9ryeDRTA== + dependencies: + debug "^4.0.0" + gonzales-pe "^4.2.3" + node-source-walk "^4.0.0" + +detective-postcss@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/detective-postcss/-/detective-postcss-3.0.1.tgz#511921951f66135e17d0ece2e7604c6e4966c9c6" + integrity sha512-tfTS2GdpUal5NY0aCqI4dpEy8Xfr88AehYKB0iBIZvo8y2g3UsrcDnrp9PR2FbzoW7xD5Rip3NJW7eCSvtqdUw== + dependencies: + debug "^4.1.1" + is-url "^1.2.4" + postcss "^7.0.2" + postcss-values-parser "^1.5.0" + +detective-sass@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/detective-sass/-/detective-sass-3.0.1.tgz#496b819efd1f5c4dd3f0e19b43a8634bdd6927c4" + integrity sha512-oSbrBozRjJ+QFF4WJFbjPQKeakoaY1GiR380NPqwdbWYd5wfl5cLWv0l6LsJVqrgWfFN1bjFqSeo32Nxza8Lbw== + dependencies: + debug "^4.1.1" + gonzales-pe "^4.2.3" + node-source-walk "^4.0.0" + +detective-scss@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/detective-scss/-/detective-scss-2.0.1.tgz#06f8c21ae6dedad1fccc26d544892d968083eaf8" + integrity sha512-VveyXW4WQE04s05KlJ8K0bG34jtHQVgTc9InspqoQxvnelj/rdgSAy7i2DXAazyQNFKlWSWbS+Ro2DWKFOKTPQ== + dependencies: + debug "^4.1.1" + gonzales-pe "^4.2.3" + node-source-walk "^4.0.0" + +detective-stylus@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/detective-stylus/-/detective-stylus-1.0.0.tgz#50aee7db8babb990381f010c63fabba5b58e54cd" + integrity sha1-UK7n24uruZA4HwEMY/q7pbWOVM0= + +detective-typescript@^5.8.0: + version "5.8.0" + resolved "https://registry.yarnpkg.com/detective-typescript/-/detective-typescript-5.8.0.tgz#c46776571e26bad6c9ada020cb3cb4e5625d1311" + integrity sha512-SrsUCfCaDTF64QVMHMidRal+kmkbIc5zP8cxxZPsomWx9vuEUjBlSJNhf7/ypE5cLdJJDI4qzKDmyzqQ+iz/xg== + dependencies: + "@typescript-eslint/typescript-estree" "^2.29.0" + ast-module-types "^2.6.0" + node-source-walk "^4.2.0" + typescript "^3.8.3" + +detective@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/detective/-/detective-5.2.0.tgz#feb2a77e85b904ecdea459ad897cc90a99bd2a7b" + integrity sha512-6SsIx+nUUbuK0EthKjv0zrdnajCCXVYGmbYYiYjFVpzcjwEs/JMDZ8tPRG29J/HhN56t3GJp2cGSWDRjjot8Pg== + dependencies: + acorn-node "^1.6.1" + defined "^1.0.0" + minimist "^1.1.1" + +dicer@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/dicer/-/dicer-0.3.0.tgz#eacd98b3bfbf92e8ab5c2fdb71aaac44bb06b872" + integrity sha512-MdceRRWqltEG2dZqO769g27N/3PXfcKl04VhYnBlo2YhH7zPi88VebsjTKclaOyiuMaGU72hTfw3VkUitGcVCA== + dependencies: + streamsearch "0.1.2" + +diff@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" + integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== + +diffie-hellman@^5.0.0: + version "5.0.3" + resolved "https://registry.yarnpkg.com/diffie-hellman/-/diffie-hellman-5.0.3.tgz#40e8ee98f55a2149607146921c63e1ae5f3d2875" + integrity sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg== + dependencies: + bn.js "^4.1.0" + miller-rabin "^4.0.0" + randombytes "^2.0.0" + +dir-glob@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" + integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== + dependencies: + path-type "^4.0.0" + +dom-serializer@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-1.1.0.tgz#5f7c828f1bfc44887dc2a315ab5c45691d544b58" + integrity sha512-ox7bvGXt2n+uLWtCRLybYx60IrOlWL/aCebWJk1T0d4m3y2tzf4U3ij9wBMUb6YJZpz06HCCYuyCDveE2xXmzQ== + dependencies: + domelementtype "^2.0.1" + domhandler "^3.0.0" + entities "^2.0.0" + +dom-serializer@^1.0.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-1.2.0.tgz#3433d9136aeb3c627981daa385fc7f32d27c48f1" + integrity sha512-n6kZFH/KlCrqs/1GHMOd5i2fd/beQHuehKdWvNNffbGHTr/almdhuVvTVFb3V7fglz+nC50fFusu3lY33h12pA== + dependencies: + domelementtype "^2.0.1" + domhandler "^4.0.0" + entities "^2.0.0" + +domelementtype@^2.0.1, domelementtype@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.1.0.tgz#a851c080a6d1c3d94344aed151d99f669edf585e" + integrity sha512-LsTgx/L5VpD+Q8lmsXSHW2WpA+eBlZ9HPf3erD1IoPF00/3JKHZ3BknUVA2QGDNu69ZNmyFmCWBSO45XjYKC5w== + +domhandler@3.3.0, domhandler@^3.0.0, domhandler@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-3.3.0.tgz#6db7ea46e4617eb15cf875df68b2b8524ce0037a" + integrity sha512-J1C5rIANUbuYK+FuFL98650rihynUOEzRLxW+90bKZRWB6A1X1Tf82GxR1qAWLyfNPRvjqfip3Q5tdYlmAa9lA== + dependencies: + domelementtype "^2.0.1" + +domhandler@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-4.0.0.tgz#01ea7821de996d85f69029e81fa873c21833098e" + integrity sha512-KPTbnGQ1JeEMQyO1iYXoagsI6so/C96HZiFyByU3T6iAzpXn8EGEvct6unm1ZGoed8ByO2oirxgwxBmqKF9haA== + dependencies: + domelementtype "^2.1.0" + +domutils@2.4.2: + version "2.4.2" + resolved "https://registry.yarnpkg.com/domutils/-/domutils-2.4.2.tgz#7ee5be261944e1ad487d9aa0616720010123922b" + integrity sha512-NKbgaM8ZJOecTZsIzW5gSuplsX2IWW2mIK7xVr8hTQF2v1CJWTmLZ1HOCh5sH+IzVPAGE5IucooOkvwBRAdowA== + dependencies: + dom-serializer "^1.0.1" + domelementtype "^2.0.1" + domhandler "^3.3.0" + +domutils@^2.4.2: + version "2.4.4" + resolved "https://registry.yarnpkg.com/domutils/-/domutils-2.4.4.tgz#282739c4b150d022d34699797369aad8d19bbbd3" + integrity sha512-jBC0vOsECI4OMdD0GC9mGn7NXPLb+Qt6KW1YDQzeQYRUFKmNG8lh7mO5HiELfr+lLQE7loDVI4QcAxV80HS+RA== + dependencies: + dom-serializer "^1.0.1" + domelementtype "^2.0.1" + domhandler "^4.0.0" + +dot-case@^3.0.3: + version "3.0.4" + resolved "https://registry.yarnpkg.com/dot-case/-/dot-case-3.0.4.tgz#9b2b670d00a431667a8a75ba29cd1b98809ce751" + integrity sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w== + dependencies: + no-case "^3.0.4" + tslib "^2.0.3" + +dotenv@^8.2.0: + version "8.2.0" + resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-8.2.0.tgz#97e619259ada750eea3e4ea3e26bceea5424b16a" + integrity sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw== + +dtrace-provider@~0.8: + version "0.8.8" + resolved "https://registry.yarnpkg.com/dtrace-provider/-/dtrace-provider-0.8.8.tgz#2996d5490c37e1347be263b423ed7b297fb0d97e" + integrity sha512-b7Z7cNtHPhH9EJhNNbbeqTcXB8LGFFZhq1PGgEvpeHlzd36bhbdTWoE/Ba/YguqpBSlAPKnARWhVlhunCMwfxg== + dependencies: + nan "^2.14.0" + +duplexer3@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2" + integrity sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI= + +duplexer@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.2.tgz#3abe43aef3835f8ae077d136ddce0f276b0400e6" + integrity sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg== + +ecc-jsbn@~0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" + integrity sha1-OoOpBOVDUyh4dMVkt1SThoSamMk= + dependencies: + jsbn "~0.1.0" + safer-buffer "^2.1.0" + +ecdsa-sig-formatter@1.0.11: + version "1.0.11" + resolved "https://registry.yarnpkg.com/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz#ae0f0fa2d85045ef14a817daa3ce9acd0489e5bf" + integrity sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ== + dependencies: + safe-buffer "^5.0.1" + +electron-to-chromium@^1.3.585, electron-to-chromium@^1.3.634: + version "1.3.635" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.635.tgz#8d1591eeca6b257d380061a2c04f0b3cc6c9e33b" + integrity sha512-RRriZOLs9CpW6KTLmgBqyUdnY0QNqqWs0HOtuQGGEMizOTNNn1P7sGRBxARnUeLejOsgwjDyRqT3E/CSst02ZQ== + +elegant-spinner@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/elegant-spinner/-/elegant-spinner-1.0.1.tgz#db043521c95d7e303fd8f345bedc3349cfb0729e" + integrity sha1-2wQ1IcldfjA/2PNFvtwzSc+wcp4= + +elliptic@^6.5.3: + version "6.5.3" + resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.3.tgz#cb59eb2efdaf73a0bd78ccd7015a62ad6e0f93d6" + integrity sha512-IMqzv5wNQf+E6aHeIqATs0tOLeOTwj1QKbRcS3jBbYkl5oLAserA8yJTT7/VyHUYG91PRmPyeQDObKLPpeS4dw== + dependencies: + bn.js "^4.4.0" + brorand "^1.0.1" + hash.js "^1.0.0" + hmac-drbg "^1.0.0" + inherits "^2.0.1" + minimalistic-assert "^1.0.0" + minimalistic-crypto-utils "^1.0.0" + +email-validator@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/email-validator/-/email-validator-2.0.4.tgz#b8dfaa5d0dae28f1b03c95881d904d4e40bfe7ed" + integrity sha512-gYCwo7kh5S3IDyZPLZf6hSS0MnZT8QmJFqYvbqlDZSbwdZlY6QZWxJ4i/6UhITOJ4XzyI647Bm2MXKCLqnJ4nQ== + +emoji-regex@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" + integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== + +emojis-list@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-2.1.0.tgz#4daa4d9db00f9819880c79fa457ae5b09a1fd389" + integrity sha1-TapNnbAPmBmIDHn6RXrlsJof04k= + +emojis-list@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-3.0.0.tgz#5570662046ad29e2e916e71aae260abdff4f6a78" + integrity sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q== + +end-of-stream@^1.1.0, end-of-stream@^1.4.1: + version "1.4.4" + resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" + integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== + dependencies: + once "^1.4.0" + +enhanced-resolve@^4.0.0, enhanced-resolve@^4.1.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-4.5.0.tgz#2f3cfd84dbe3b487f18f2db2ef1e064a571ca5ec" + integrity sha512-Nv9m36S/vxpsI+Hc4/ZGRs0n9mXqSWGGq49zxb/cJfPAQMbUtttJAlNPS4AQzaBdw/pKskw5bMbekT/Y7W/Wlg== + dependencies: + graceful-fs "^4.1.2" + memory-fs "^0.5.0" + tapable "^1.0.0" + +enhanced-resolve@^5.3.1: + version "5.5.0" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.5.0.tgz#5f2ca7d511076541e2a30dc364a40c4f6c027bcd" + integrity sha512-b4a6BasBCoLzri4MdaeOlDMpls2oioI28CF17csMiav9dq46yvQaKPFNUrCHB6VqQokBDG2VIEEL81jMiQ6Wtw== + dependencies: + graceful-fs "^4.2.4" + tapable "^2.2.0" + +entities@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/entities/-/entities-2.1.0.tgz#992d3129cf7df6870b96c57858c249a120f8b8b5" + integrity sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w== + +errno@^0.1.3: + version "0.1.8" + resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.8.tgz#8bb3e9c7d463be4976ff888f76b4809ebc2e811f" + integrity sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A== + dependencies: + prr "~1.0.1" + +error-ex@^1.3.1: + version "1.3.2" + resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" + integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== + dependencies: + is-arrayish "^0.2.1" + +es-abstract@^1.18.0-next.1: + version "1.18.0-next.1" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.18.0-next.1.tgz#6e3a0a4bda717e5023ab3b8e90bec36108d22c68" + integrity sha512-I4UGspA0wpZXWENrdA0uHbnhte683t3qT/1VFH9aX2dA5PPSf6QW5HHXf5HImaqPmjXaVeVk4RGWnaylmV7uAA== + dependencies: + es-to-primitive "^1.2.1" + function-bind "^1.1.1" + has "^1.0.3" + has-symbols "^1.0.1" + is-callable "^1.2.2" + is-negative-zero "^2.0.0" + is-regex "^1.1.1" + object-inspect "^1.8.0" + object-keys "^1.1.1" + object.assign "^4.1.1" + string.prototype.trimend "^1.0.1" + string.prototype.trimstart "^1.0.1" + +es-to-primitive@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a" + integrity sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA== + dependencies: + is-callable "^1.1.4" + is-date-object "^1.0.1" + is-symbol "^1.0.2" + +es5-ext@^0.10.35, es5-ext@^0.10.50: + version "0.10.53" + resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.53.tgz#93c5a3acfdbef275220ad72644ad02ee18368de1" + integrity sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q== + dependencies: + es6-iterator "~2.0.3" + es6-symbol "~3.1.3" + next-tick "~1.0.0" + +es6-iterator@2.0.3, es6-iterator@~2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.3.tgz#a7de889141a05a94b0854403b2d0a0fbfa98f3b7" + integrity sha1-p96IkUGgWpSwhUQDstCg+/qY87c= + dependencies: + d "1" + es5-ext "^0.10.35" + es6-symbol "^3.1.1" + +es6-symbol@^3.1.1, es6-symbol@~3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.3.tgz#bad5d3c1bcdac28269f4cb331e431c78ac705d18" + integrity sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA== + dependencies: + d "^1.0.1" + ext "^1.1.2" + +escalade@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" + integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== + +escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= + +escodegen@^1.8.0: + version "1.14.3" + resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.14.3.tgz#4e7b81fba61581dc97582ed78cab7f0e8d63f503" + integrity sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw== + dependencies: + esprima "^4.0.1" + estraverse "^4.2.0" + esutils "^2.0.2" + optionator "^0.8.1" + optionalDependencies: + source-map "~0.6.1" + +eslint-scope@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" + integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== + dependencies: + esrecurse "^4.3.0" + estraverse "^4.1.1" + +eslint-visitor-keys@^1.1.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz#30ebd1ef7c2fdff01c3a4f151044af25fab0523e" + integrity sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ== + +esprima@4.0.1, esprima@^4.0.0, esprima@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" + integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== + +esrecurse@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" + integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== + dependencies: + estraverse "^5.2.0" + +estraverse@^4.1.1, estraverse@^4.2.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" + integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== + +estraverse@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.2.0.tgz#307df42547e6cc7324d3cf03c155d5cdb8c53880" + integrity sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ== + +estree-walker@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-2.0.2.tgz#52f010178c2a4c117a7757cfe942adb7d2da4cac" + integrity sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w== + +esutils@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" + integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== + +etag@1.8.1: + version "1.8.1" + resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" + integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc= + +event-target-shim@^5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/event-target-shim/-/event-target-shim-5.0.1.tgz#5d4d3ebdf9583d63a5333ce2deb7480ab2b05789" + integrity sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ== + +events@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/events/-/events-3.2.0.tgz#93b87c18f8efcd4202a461aec4dfc0556b639379" + integrity sha512-/46HWwbfCX2xTawVfkKLGxMifJYQBWMwY1mjywRtb4c9x8l5NP3KoJtnIOiL1hfdRkIuYhETxQlo62IF8tcnlg== + +eventsource@1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/eventsource/-/eventsource-1.0.7.tgz#8fbc72c93fcd34088090bc0a4e64f4b5cee6d8d0" + integrity sha512-4Ln17+vVT0k8aWq+t/bF5arcS3EpT9gYtW66EPacdj/mAFevznsnyoHLPy2BA8gbIQeIHoPsvwmfBftfcG//BQ== + dependencies: + original "^1.0.0" + +evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz#7fcbdb198dc71959432efe13842684e0525acb02" + integrity sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA== + dependencies: + md5.js "^1.3.4" + safe-buffer "^5.1.1" + +expand-template@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/expand-template/-/expand-template-2.0.3.tgz#6e14b3fcee0f3a6340ecb57d2e8918692052a47c" + integrity sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg== + +ext@^1.1.2: + version "1.4.0" + resolved "https://registry.yarnpkg.com/ext/-/ext-1.4.0.tgz#89ae7a07158f79d35517882904324077e4379244" + integrity sha512-Key5NIsUxdqKg3vIsdw9dSuXpPCQ297y6wBjL30edxwPgt2E44WcWBZey/ZvUc6sERLTxKdyCu4gZFmUbk1Q7A== + dependencies: + type "^2.0.0" + +extend@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" + integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== + +external-editor@^3.0.3: + version "3.1.0" + resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.1.0.tgz#cb03f740befae03ea4d283caed2741a83f335495" + integrity sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew== + dependencies: + chardet "^0.7.0" + iconv-lite "^0.4.24" + tmp "^0.0.33" + +extract-files@9.0.0, extract-files@^9.0.0: + version "9.0.0" + resolved "https://registry.yarnpkg.com/extract-files/-/extract-files-9.0.0.tgz#8a7744f2437f81f5ed3250ed9f1550de902fe54a" + integrity sha512-CvdFfHkC95B4bBBk36hcEmvdR2awOdhhVUYH6S/zrVj3477zven/fJMYg7121h4T1xHZC+tetUpubpAhxwI7hQ== + +extsprintf@1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" + integrity sha1-lpGEQOMEGnpBT4xS48V06zw+HgU= + +extsprintf@^1.2.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f" + integrity sha1-4mifjzVvrWLMplo6kcXfX5VRaS8= + +fast-deep-equal@^3.1.1: + version "3.1.3" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" + integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== + +fast-glob@^3.1.1: + version "3.2.4" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.4.tgz#d20aefbf99579383e7f3cc66529158c9b98554d3" + integrity sha512-kr/Oo6PX51265qeuCYsyGypiO5uJFgBS0jksyG7FUeCyQzNwYnzrNIMR1NXfkZXsMYXYLRAHgISHBz8gQcxKHQ== + dependencies: + "@nodelib/fs.stat" "^2.0.2" + "@nodelib/fs.walk" "^1.2.3" + glob-parent "^5.1.0" + merge2 "^1.3.0" + micromatch "^4.0.2" + picomatch "^2.2.1" + +fast-json-stable-stringify@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" + integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== + +fast-levenshtein@~2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" + integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= + +fastq@^1.6.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.10.0.tgz#74dbefccade964932cdf500473ef302719c652bb" + integrity sha512-NL2Qc5L3iQEsyYzweq7qfgy5OtXCmGzGvhElGEd/SoFWEMOEczNh5s5ocaF01HDetxz+p8ecjNPA6cZxxIHmzA== + dependencies: + reusify "^1.0.4" + +fb-watchman@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/fb-watchman/-/fb-watchman-2.0.1.tgz#fc84fb39d2709cf3ff6d743706157bb5708a8a85" + integrity sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg== + dependencies: + bser "2.1.1" + +fbjs-css-vars@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/fbjs-css-vars/-/fbjs-css-vars-1.0.2.tgz#216551136ae02fe255932c3ec8775f18e2c078b8" + integrity sha512-b2XGFAFdWZWg0phtAWLHCk836A1Xann+I+Dgd3Gk64MHKZO44FfoD1KxyvbSh0qZsIoXQGGlVztIY+oitJPpRQ== + +fbjs@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-3.0.0.tgz#0907067fb3f57a78f45d95f1eacffcacd623c165" + integrity sha512-dJd4PiDOFuhe7vk4F80Mba83Vr2QuK86FoxtgPmzBqEJahncp+13YCmfoa53KHCo6OnlXLG7eeMWPfB5CrpVKg== + dependencies: + cross-fetch "^3.0.4" + fbjs-css-vars "^1.0.0" + loose-envify "^1.0.0" + object-assign "^4.1.0" + promise "^7.1.1" + setimmediate "^1.0.5" + ua-parser-js "^0.7.18" + +figures@^1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/figures/-/figures-1.7.0.tgz#cbe1e3affcf1cd44b80cadfed28dc793a9701d2e" + integrity sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4= + dependencies: + escape-string-regexp "^1.0.5" + object-assign "^4.1.0" + +figures@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/figures/-/figures-2.0.0.tgz#3ab1a2d2a62c8bfb431a0c94cb797a2fce27c962" + integrity sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI= + dependencies: + escape-string-regexp "^1.0.5" + +figures@^3.0.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/figures/-/figures-3.2.0.tgz#625c18bd293c604dc4a8ddb2febf0c88341746af" + integrity sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg== + dependencies: + escape-string-regexp "^1.0.5" + +file-exists-dazinatorfork@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/file-exists-dazinatorfork/-/file-exists-dazinatorfork-1.0.2.tgz#cd8d0d85f63e39dc81eceb0b687c44a2cca95c47" + integrity sha512-r70c72ln2YHzQINNfxDp02hAhbGkt1HffZ+Du8oetWDLjDtFja/Lm10lUaSh9e+wD+7VDvPee0b0C9SAy8pWZg== + +filing-cabinet@^2.6.0: + version "2.6.0" + resolved "https://registry.yarnpkg.com/filing-cabinet/-/filing-cabinet-2.6.0.tgz#3d4d5093a98b6fae84cf282e8bded1b8ad5f9c0c" + integrity sha512-7kSlTScEkxoYKXCix7tAQ52ZeIHcx7ZWWArEZgXY+eTMe6yDYFdDhHdkXm9rSmvrrpzdZeR1wiufS1rUt4OzMA== + dependencies: + app-module-path "^2.2.0" + commander "^2.13.0" + debug "^4.1.1" + decomment "^0.9.2" + enhanced-resolve "^4.1.0" + is-relative-path "^1.0.2" + module-definition "^3.0.0" + module-lookup-amd "^6.1.0" + resolve "^1.11.1" + resolve-dependency-path "^2.0.0" + sass-lookup "^3.0.0" + stylus-lookup "^3.0.1" + typescript "^3.0.3" + +fill-range@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" + integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== + dependencies: + to-regex-range "^5.0.1" + +find-cache-dir@3.3.1: + version "3.3.1" + resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-3.3.1.tgz#89b33fad4a4670daa94f855f7fbe31d6d84fe880" + integrity sha512-t2GDMt3oGC/v+BMwzmllWDuJF/xcDtE5j/fCGbqDD7OLuJkj0cfh1YSA5VKPvwMeLFLNDBkwOKZ2X85jGLVftQ== + dependencies: + commondir "^1.0.1" + make-dir "^3.0.2" + pkg-dir "^4.1.0" + +find-up@^4.0.0, find-up@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" + integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== + dependencies: + locate-path "^5.0.0" + path-exists "^4.0.0" + +find-up@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" + integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== + dependencies: + locate-path "^6.0.0" + path-exists "^4.0.0" + +find@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/find/-/find-0.3.0.tgz#4082e8fc8d8320f1a382b5e4f521b9bc50775cb8" + integrity sha512-iSd+O4OEYV/I36Zl8MdYJO0xD82wH528SaCieTVHhclgiYNe9y+yPKSwK+A7/WsmHL1EZ+pYUJBXWTL5qofksw== + dependencies: + traverse-chain "~0.1.0" + +flatten@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/flatten/-/flatten-1.0.3.tgz#c1283ac9f27b368abc1e36d1ff7b04501a30356b" + integrity sha512-dVsPA/UwQ8+2uoFe5GHtiBMu48dWLTdsuEd7CKGlZlD78r1TTWBvDuFaFGKCo/ZfEr95Uk56vZoX86OsHkUeIg== + +forever-agent@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" + integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= + +form-data@^2.3.2: + version "2.5.1" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.5.1.tgz#f2cbec57b5e59e23716e128fe44d4e5dd23895f4" + integrity sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.6" + mime-types "^2.1.12" + +form-data@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-3.0.0.tgz#31b7e39c85f1355b7139ee0c647cf0de7f83c682" + integrity sha512-CKMFDglpbMi6PyN+brwB9Q/GOw0eAnsrEZDgcsH5Krhz5Od/haKHAX0NmQfha2zPPz0JpWzA7GJHGSnvCRLWsg== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.8" + mime-types "^2.1.12" + +form-data@~2.3.2: + version "2.3.3" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" + integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.6" + mime-types "^2.1.12" + +fs-capacitor@^6.1.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/fs-capacitor/-/fs-capacitor-6.2.0.tgz#fa79ac6576629163cb84561995602d8999afb7f5" + integrity sha512-nKcE1UduoSKX27NSZlg879LdQc94OtbOsEmKMN2MBNudXREvijRKx2GEBsTMTfws+BrbkJoEuynbGSVRSpauvw== + +fs-constants@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad" + integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow== + +fs-extra@^8.0.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0" + integrity sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g== + dependencies: + graceful-fs "^4.2.0" + jsonfile "^4.0.0" + universalify "^0.1.0" + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= + +fsevents@~2.1.2: + version "2.1.3" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.1.3.tgz#fb738703ae8d2f9fe900c33836ddebee8b97f23e" + integrity sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ== + +fsevents@~2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.1.tgz#b209ab14c61012636c8863507edf7fb68cc54e9f" + integrity sha512-YR47Eg4hChJGAB1O3yEAOkGO+rlzutoICGqGo9EZ4lKWokzZRSyIW1QmTzqjtw8MJdj9srP869CuWw/hyzSiBw== + +function-bind@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" + integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== + +gauge@~2.7.3: + version "2.7.4" + resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" + integrity sha1-LANAXHU4w51+s3sxcCLjJfsBi/c= + dependencies: + aproba "^1.0.3" + console-control-strings "^1.0.0" + has-unicode "^2.0.0" + object-assign "^4.1.0" + signal-exit "^3.0.0" + string-width "^1.0.1" + strip-ansi "^3.0.1" + wide-align "^1.1.0" + +generic-names@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/generic-names/-/generic-names-2.0.1.tgz#f8a378ead2ccaa7a34f0317b05554832ae41b872" + integrity sha512-kPCHWa1m9wGG/OwQpeweTwM/PYiQLrUIxXbt/P4Nic3LbGjCP0YwrALHW1uNLKZ0LIMg+RF+XRlj2ekT9ZlZAQ== + dependencies: + loader-utils "^1.1.0" + +gensync@^1.0.0-beta.1: + version "1.0.0-beta.2" + resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" + integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg== + +get-amd-module-type@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/get-amd-module-type/-/get-amd-module-type-3.0.0.tgz#bb334662fa04427018c937774570de495845c288" + integrity sha512-99Q7COuACPfVt18zH9N4VAMyb81S6TUgJm2NgV6ERtkh9VIkAaByZkW530wl3lLN5KTtSrK9jVLxYsoP5hQKsw== + dependencies: + ast-module-types "^2.3.2" + node-source-walk "^4.0.0" + +get-caller-file@^2.0.1, get-caller-file@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" + integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== + +get-intrinsic@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.0.2.tgz#6820da226e50b24894e08859469dc68361545d49" + integrity sha512-aeX0vrFm21ILl3+JpFFRNe9aUvp6VFZb2/CTbgLb8j75kOhvoNYjt9d8KA/tJG4gSo8nzEDedRl0h7vDmBYRVg== + dependencies: + function-bind "^1.1.1" + has "^1.0.3" + has-symbols "^1.0.1" + +get-own-enumerable-property-symbols@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz#b5fde77f22cbe35f390b4e089922c50bce6ef664" + integrity sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g== + +get-stream@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5" + integrity sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w== + dependencies: + pump "^3.0.0" + +get-stream@^5.1.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.2.0.tgz#4966a1795ee5ace65e706c4b7beb71257d6e22d3" + integrity sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA== + dependencies: + pump "^3.0.0" + +getpass@^0.1.1: + version "0.1.7" + resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" + integrity sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo= + dependencies: + assert-plus "^1.0.0" + +github-from-package@0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/github-from-package/-/github-from-package-0.0.0.tgz#97fb5d96bfde8973313f20e8288ef9a167fa64ce" + integrity sha1-l/tdlr/eiXMxPyDoKI75oWf6ZM4= + +glob-parent@^5.1.0, glob-parent@~5.1.0: + version "5.1.1" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.1.tgz#b6c1ef417c4e5663ea498f1c45afac6916bbc229" + integrity sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ== + dependencies: + is-glob "^4.0.1" + +glob-to-regexp@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz#c75297087c851b9a578bd217dd59a92f59fe546e" + integrity sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw== + +glob@^6.0.1: + version "6.0.4" + resolved "https://registry.yarnpkg.com/glob/-/glob-6.0.4.tgz#0f08860f6a155127b2fadd4f9ce24b1aab6e4d22" + integrity sha1-DwiGD2oVUSey+t1PnOJLGqtuTSI= + dependencies: + inflight "^1.0.4" + inherits "2" + minimatch "2 || 3" + once "^1.3.0" + path-is-absolute "^1.0.0" + +glob@^7.0.0, glob@^7.1.1, glob@^7.1.2, glob@^7.1.6: + version "7.1.6" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" + integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +globals@^11.1.0: + version "11.12.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" + integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== + +globby@11.0.1: + version "11.0.1" + resolved "https://registry.yarnpkg.com/globby/-/globby-11.0.1.tgz#9a2bf107a068f3ffeabc49ad702c79ede8cfd357" + integrity sha512-iH9RmgwCmUJHi2z5o2l3eTtGBtXek1OYlHrbcxOYugyHLmAsZrPj43OtHThd62Buh/Vv6VyCBD2bdyWcGNQqoQ== + dependencies: + array-union "^2.1.0" + dir-glob "^3.0.1" + fast-glob "^3.1.1" + ignore "^5.1.4" + merge2 "^1.3.0" + slash "^3.0.0" + +gonzales-pe@^4.2.3: + version "4.3.0" + resolved "https://registry.yarnpkg.com/gonzales-pe/-/gonzales-pe-4.3.0.tgz#fe9dec5f3c557eead09ff868c65826be54d067b3" + integrity sha512-otgSPpUmdWJ43VXyiNgEYE4luzHCL2pz4wQ0OnDluC6Eg4Ko3Vexy/SrSynglw/eR+OhkzmqFCZa/OFa/RgAOQ== + dependencies: + minimist "^1.2.5" + +got@^9.6.0: + version "9.6.0" + resolved "https://registry.yarnpkg.com/got/-/got-9.6.0.tgz#edf45e7d67f99545705de1f7bbeeeb121765ed85" + integrity sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q== + dependencies: + "@sindresorhus/is" "^0.14.0" + "@szmarczak/http-timer" "^1.1.2" + cacheable-request "^6.0.0" + decompress-response "^3.3.0" + duplexer3 "^0.1.4" + get-stream "^4.1.0" + lowercase-keys "^1.0.1" + mimic-response "^1.0.1" + p-cancelable "^1.0.0" + to-readable-stream "^1.0.0" + url-parse-lax "^3.0.0" + +graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.4: + version "4.2.4" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.4.tgz#2256bde14d3632958c465ebc96dc467ca07a29fb" + integrity sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw== + +graphql-config@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/graphql-config/-/graphql-config-3.2.0.tgz#3ec3a7e319792086b80e54db4b37372ad4a79a32" + integrity sha512-ygEKDeQNZKpm4137560n2oY3bGM0D5zyRsQVaJntKkufWdgPg6sb9/4J1zJW2y/yC1ortAbhNho09qmeJeLa9g== + dependencies: + "@endemolshinegroup/cosmiconfig-typescript-loader" "3.0.2" + "@graphql-tools/graphql-file-loader" "^6.0.0" + "@graphql-tools/json-file-loader" "^6.0.0" + "@graphql-tools/load" "^6.0.0" + "@graphql-tools/merge" "^6.0.0" + "@graphql-tools/url-loader" "^6.0.0" + "@graphql-tools/utils" "^6.0.0" + cosmiconfig "6.0.0" + cosmiconfig-toml-loader "1.0.0" + minimatch "3.0.4" + string-env-interpolation "1.0.1" + tslib "^2.0.0" + +graphql-request@^3.3.0: + version "3.4.0" + resolved "https://registry.yarnpkg.com/graphql-request/-/graphql-request-3.4.0.tgz#3a400cd5511eb3c064b1873afb059196bbea9c2b" + integrity sha512-acrTzidSlwAj8wBNO7Q/UQHS8T+z5qRGquCQRv9J1InwR01BBWV9ObnoE+JS5nCCEj8wSGS0yrDXVDoRiKZuOg== + dependencies: + cross-fetch "^3.0.6" + extract-files "^9.0.0" + form-data "^3.0.0" + +graphql-tag@^2.11.0: + version "2.11.0" + resolved "https://registry.yarnpkg.com/graphql-tag/-/graphql-tag-2.11.0.tgz#1deb53a01c46a7eb401d6cb59dec86fa1cccbffd" + integrity sha512-VmsD5pJqWJnQZMUeRwrDhfgoyqcfwEkvtpANqcoUG8/tOLkwNgU9mzub/Mc78OJMhHjx7gfAMTxzdG43VGg3bA== + +graphql-upload@^11.0.0: + version "11.0.0" + resolved "https://registry.yarnpkg.com/graphql-upload/-/graphql-upload-11.0.0.tgz#24b245ff18f353bab6715e8a055db9fd73035e10" + integrity sha512-zsrDtu5gCbQFDWsNa5bMB4nf1LpKX9KDgh+f8oL1288ijV4RxeckhVozAjqjXAfRpxOHD1xOESsh6zq8SjdgjA== + dependencies: + busboy "^0.3.1" + fs-capacitor "^6.1.0" + http-errors "^1.7.3" + isobject "^4.0.0" + object-path "^0.11.4" + +graphql-ws@3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/graphql-ws/-/graphql-ws-3.1.0.tgz#cd09d385a21ab88af4c226da79c19351df9b27e8" + integrity sha512-zbex3FSiFz0iRgfkzDNWpOY/sYWoX+iZ5XUhakaDwOh99HSuk8rPt5suuxdXUVzEg5TGQ9rwzNaz/+mTPtS0yg== + +graphql@^15.4.0: + version "15.4.0" + resolved "https://registry.yarnpkg.com/graphql/-/graphql-15.4.0.tgz#e459dea1150da5a106486ba7276518b5295a4347" + integrity sha512-EB3zgGchcabbsU9cFe1j+yxdzKQKAbGUWRb13DsrsMN1yyfmmIq+2+L5MqVWcDCE4V89R5AyUOi7sMOGxdsYtA== + +graphviz@0.0.9: + version "0.0.9" + resolved "https://registry.yarnpkg.com/graphviz/-/graphviz-0.0.9.tgz#0bbf1df588c6a92259282da35323622528c4bbc4" + integrity sha512-SmoY2pOtcikmMCqCSy2NO1YsRfu9OO0wpTlOYW++giGjfX1a6gax/m1Fo8IdUd0/3H15cTOfR1SMKwohj4LKsg== + dependencies: + temp "~0.4.0" + +gzip-size@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/gzip-size/-/gzip-size-6.0.0.tgz#065367fd50c239c0671cbcbad5be3e2eeb10e462" + integrity sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q== + dependencies: + duplexer "^0.1.2" + +har-schema@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" + integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI= + +har-validator@~5.1.3: + version "5.1.5" + resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.5.tgz#1f0803b9f8cb20c0fa13822df1ecddb36bde1efd" + integrity sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w== + dependencies: + ajv "^6.12.3" + har-schema "^2.0.0" + +hard-rejection@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/hard-rejection/-/hard-rejection-2.1.0.tgz#1c6eda5c1685c63942766d79bb40ae773cecd883" + integrity sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA== + +has-ansi@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" + integrity sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE= + dependencies: + ansi-regex "^2.0.0" + +has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= + +has-flag@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" + integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== + +has-symbols@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.1.tgz#9f5214758a44196c406d9bd76cebf81ec2dd31e8" + integrity sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg== + +has-unicode@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" + integrity sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk= + +has@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" + integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== + dependencies: + function-bind "^1.1.1" + +hash-base@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.1.0.tgz#55c381d9e06e1d2997a883b4a3fddfe7f0d3af33" + integrity sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA== + dependencies: + inherits "^2.0.4" + readable-stream "^3.6.0" + safe-buffer "^5.2.0" + +hash-sum@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/hash-sum/-/hash-sum-2.0.0.tgz#81d01bb5de8ea4a214ad5d6ead1b523460b0b45a" + integrity sha512-WdZTbAByD+pHfl/g9QSsBIIwy8IT+EsPiKDs0KNX+zSHhdDLFKdZu0BQHljvO+0QI/BasbMSUa8wYNCZTvhslg== + +hash.js@^1.0.0, hash.js@^1.0.3: + version "1.1.7" + resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.7.tgz#0babca538e8d4ee4a0f8988d68866537a003cf42" + integrity sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA== + dependencies: + inherits "^2.0.3" + minimalistic-assert "^1.0.1" + +he@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" + integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== + +hex-rgb@^4.1.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/hex-rgb/-/hex-rgb-4.2.0.tgz#fb377f2e5658fc924f1efa189685922e56ecaf0f" + integrity sha512-I7DkKeQ2kR2uyqgbxPgNgClH/rfs1ioKZhZW8VTIAirsxCR5EyhYeywgZbhMScgUbKCkgo6bb6JwA0CLTn9beA== + +hmac-drbg@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" + integrity sha1-0nRXAQJabHdabFRXk+1QL8DGSaE= + dependencies: + hash.js "^1.0.3" + minimalistic-assert "^1.0.0" + minimalistic-crypto-utils "^1.0.1" + +hosted-git-info@^2.1.4: + version "2.8.8" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.8.tgz#7539bd4bc1e0e0a895815a2e0262420b12858488" + integrity sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg== + +html-tags@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/html-tags/-/html-tags-3.1.0.tgz#7b5e6f7e665e9fb41f30007ed9e0d41e97fb2140" + integrity sha512-1qYz89hW3lFDEazhjW0yVAV87lw8lVkrJocr72XmBkMKsoSVJCQx3W8BXsC7hO2qAt8BoVjYjtAcZ9perqGnNg== + +htmlparser2@5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-5.0.1.tgz#7daa6fc3e35d6107ac95a4fc08781f091664f6e7" + integrity sha512-vKZZra6CSe9qsJzh0BjBGXo8dvzNsq/oGvsjfRdOrrryfeD9UOBEEQdeoqCRmKZchF5h2zOBMQ6YuQ0uRUmdbQ== + dependencies: + domelementtype "^2.0.1" + domhandler "^3.3.0" + domutils "^2.4.2" + entities "^2.0.0" + +http-cache-semantics@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz#49e91c5cbf36c9b94bcfcd71c23d5249ec74e390" + integrity sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ== + +http-errors@1.7.3: + version "1.7.3" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.3.tgz#6c619e4f9c60308c38519498c14fbb10aacebb06" + integrity sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw== + dependencies: + depd "~1.1.2" + inherits "2.0.4" + setprototypeof "1.1.1" + statuses ">= 1.5.0 < 2" + toidentifier "1.0.0" + +http-errors@^1.7.3: + version "1.8.0" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.8.0.tgz#75d1bbe497e1044f51e4ee9e704a62f28d336507" + integrity sha512-4I8r0C5JDhT5VkvI47QktDW75rNlGVsUf/8hzjCC/wkWI/jdTRmBb9aI7erSG82r1bjKY3F6k28WnsVxB1C73A== + dependencies: + depd "~1.1.2" + inherits "2.0.4" + setprototypeof "1.2.0" + statuses ">= 1.5.0 < 2" + toidentifier "1.0.0" + +http-proxy-agent@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz#8a8c8ef7f5932ccf953c296ca8291b95aa74aa3a" + integrity sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg== + dependencies: + "@tootallnate/once" "1" + agent-base "6" + debug "4" + +http-signature@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" + integrity sha1-muzZJRFHcvPZW2WmCruPfBj7rOE= + dependencies: + assert-plus "^1.0.0" + jsprim "^1.2.2" + sshpk "^1.7.0" + +https-proxy-agent@5.0.0, https-proxy-agent@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz#e2a90542abb68a762e0a0850f6c9edadfd8506b2" + integrity sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA== + dependencies: + agent-base "6" + debug "4" + +humanize-ms@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/humanize-ms/-/humanize-ms-1.2.1.tgz#c46e3159a293f6b896da29316d8b6fe8bb79bbed" + integrity sha1-xG4xWaKT9riW2ikxbYtv6Lt5u+0= + dependencies: + ms "^2.0.0" + +iconv-lite@0.4.24, iconv-lite@^0.4.24: + version "0.4.24" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" + integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== + dependencies: + safer-buffer ">= 2.1.2 < 3" + +icss-replace-symbols@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/icss-replace-symbols/-/icss-replace-symbols-1.1.0.tgz#06ea6f83679a7749e386cfe1fe812ae5db223ded" + integrity sha1-Bupvg2ead0njhs/h/oEq5dsiPe0= + +icss-utils@^4.0.0, icss-utils@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/icss-utils/-/icss-utils-4.1.1.tgz#21170b53789ee27447c2f47dd683081403f9a467" + integrity sha512-4aFq7wvWyMHKgxsH8QQtGpvbASCf+eM3wPRLI6R+MgAnTCZ6STYsRvttLvRWK0Nfif5piF394St3HeJDaljGPA== + dependencies: + postcss "^7.0.14" + +ieee754@^1.1.13, ieee754@^1.1.4: + version "1.2.1" + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" + integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== + +ignore@^5.1.4: + version "5.1.8" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.8.tgz#f150a8b50a34289b33e22f5889abd4d8016f0e57" + integrity sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw== + +immutable@~3.7.6: + version "3.7.6" + resolved "https://registry.yarnpkg.com/immutable/-/immutable-3.7.6.tgz#13b4d3cb12befa15482a26fe1b2ebae640071e4b" + integrity sha1-E7TTyxK++hVIKib+Gy665kAHHks= + +import-fresh@^3.1.0, import-fresh@^3.2.1: + version "3.3.0" + resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" + integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== + dependencies: + parent-module "^1.0.0" + resolve-from "^4.0.0" + +import-from@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/import-from/-/import-from-3.0.0.tgz#055cfec38cd5a27d8057ca51376d7d3bf0891966" + integrity sha512-CiuXOFFSzkU5x/CR0+z7T91Iht4CXgfCxVOFRhh2Zyhg5wOpWvvDLQUsWl+gcN+QscYBjez8hDCt85O7RLDttQ== + dependencies: + resolve-from "^5.0.0" + +indent-string@^3.0.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-3.2.0.tgz#4a5fd6d27cc332f37e5419a504dbb837105c9289" + integrity sha1-Sl/W0nzDMvN+VBmlBNu4NxBckok= + +indent-string@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251" + integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg== + +indexes-of@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/indexes-of/-/indexes-of-1.0.1.tgz#f30f716c8e2bd346c7b67d3df3915566a7c05607" + integrity sha1-8w9xbI4r00bHtn0985FVZqfAVgc= + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.3, inherits@~2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +ini@~1.3.0: + version "1.3.8" + resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c" + integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== + +inquirer@^7.3.3: + version "7.3.3" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-7.3.3.tgz#04d176b2af04afc157a83fd7c100e98ee0aad003" + integrity sha512-JG3eIAj5V9CwcGvuOmoo6LB9kbAYT8HXffUl6memuszlwDC/qvFAJw49XJ5NROSFNPxp3iQg1GqkFhaY/CR0IA== + dependencies: + ansi-escapes "^4.2.1" + chalk "^4.1.0" + cli-cursor "^3.1.0" + cli-width "^3.0.0" + external-editor "^3.0.3" + figures "^3.0.0" + lodash "^4.17.19" + mute-stream "0.0.8" + run-async "^2.4.0" + rxjs "^6.6.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + through "^2.3.6" + +is-absolute@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-absolute/-/is-absolute-1.0.0.tgz#395e1ae84b11f26ad1795e73c17378e48a301576" + integrity sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA== + dependencies: + is-relative "^1.0.0" + is-windows "^1.0.1" + +is-arrayish@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" + integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0= + +is-arrayish@^0.3.1: + version "0.3.2" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.3.2.tgz#4574a2ae56f7ab206896fb431eaeed066fdf8f03" + integrity sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ== + +is-binary-path@~2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" + integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== + dependencies: + binary-extensions "^2.0.0" + +is-callable@^1.1.4, is-callable@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.2.tgz#c7c6715cd22d4ddb48d3e19970223aceabb080d9" + integrity sha512-dnMqspv5nU3LoewK2N/y7KLtxtakvTuaCsU9FU50/QDmdbHNy/4/JuRtMHqRU22o3q+W89YQndQEeCVwK+3qrA== + +is-core-module@^2.1.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.2.0.tgz#97037ef3d52224d85163f5597b2b63d9afed981a" + integrity sha512-XRAfAdyyY5F5cOXn7hYQDqh2Xmii+DEfIcQGxK/uNwMHhIkPWO0g8msXcbzLe+MpGoR951MlqM/2iIlU4vKDdQ== + dependencies: + has "^1.0.3" + +is-date-object@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.2.tgz#bda736f2cd8fd06d32844e7743bfa7494c3bfd7e" + integrity sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g== + +is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= + +is-fullwidth-code-point@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" + integrity sha1-754xOG8DGn8NZDr4L95QxFfvAMs= + dependencies: + number-is-nan "^1.0.0" + +is-fullwidth-code-point@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" + integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= + +is-fullwidth-code-point@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" + integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== + +is-glob@4.0.1, is-glob@^4.0.1, is-glob@~4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc" + integrity sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg== + dependencies: + is-extglob "^2.1.1" + +is-interactive@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-interactive/-/is-interactive-1.0.0.tgz#cea6e6ae5c870a7b0a0004070b7b587e0252912e" + integrity sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w== + +is-negative-zero@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.1.tgz#3de746c18dda2319241a53675908d8f766f11c24" + integrity sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w== + +is-number@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" + integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== + +is-obj@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" + integrity sha1-PkcprB9f3gJc19g6iW2rn09n2w8= + +is-observable@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-observable/-/is-observable-1.1.0.tgz#b3e986c8f44de950867cab5403f5a3465005975e" + integrity sha512-NqCa4Sa2d+u7BWc6CukaObG3Fh+CU9bvixbpcXYhy2VvYS7vVGIdAgnIS5Ks3A/cqk4rebLJ9s8zBstT2aKnIA== + dependencies: + symbol-observable "^1.1.0" + +is-plain-obj@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" + integrity sha1-caUMhCnfync8kqOQpKA7OfzVHT4= + +is-promise@4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-4.0.0.tgz#42ff9f84206c1991d26debf520dd5c01042dd2f3" + integrity sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ== + +is-promise@^2.1.0: + version "2.2.2" + resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.2.2.tgz#39ab959ccbf9a774cf079f7b40c7a26f763135f1" + integrity sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ== + +is-regex@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.1.tgz#c6f98aacc546f6cec5468a07b7b153ab564a57b9" + integrity sha512-1+QkEcxiLlB7VEyFtyBg94e08OAsvq7FUBgApTq/w2ymCLyKJgDPsybBENVtA7XCQEgEXxKPonG+mvYRxh/LIg== + dependencies: + has-symbols "^1.0.1" + +is-regexp@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-regexp/-/is-regexp-1.0.0.tgz#fd2d883545c46bac5a633e7b9a09e87fa2cb5069" + integrity sha1-/S2INUXEa6xaYz57mgnof6LLUGk= + +is-relative-path@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-relative-path/-/is-relative-path-1.0.2.tgz#091b46a0d67c1ed0fe85f1f8cfdde006bb251d46" + integrity sha1-CRtGoNZ8HtD+hfH4z93gBrslHUY= + +is-relative@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-relative/-/is-relative-1.0.0.tgz#a1bb6935ce8c5dba1e8b9754b9b2dcc020e2260d" + integrity sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA== + dependencies: + is-unc-path "^1.0.0" + +is-stream@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" + integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ= + +is-symbol@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.3.tgz#38e1014b9e6329be0de9d24a414fd7441ec61937" + integrity sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ== + dependencies: + has-symbols "^1.0.1" + +is-typedarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" + integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= + +is-unc-path@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-unc-path/-/is-unc-path-1.0.0.tgz#d731e8898ed090a12c352ad2eaed5095ad322c9d" + integrity sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ== + dependencies: + unc-path-regex "^0.1.2" + +is-url@^1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/is-url/-/is-url-1.2.4.tgz#04a4df46d28c4cff3d73d01ff06abeb318a1aa52" + integrity sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww== + +is-windows@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" + integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA== + +isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= + +isobject@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" + integrity sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk= + dependencies: + isarray "1.0.0" + +isobject@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-4.0.0.tgz#3f1c9155e73b192022a80819bacd0343711697b0" + integrity sha512-S/2fF5wH8SJA/kmwr6HYhK/RI/OkhD84k8ntalo0iJjZikgq1XFvR5M8NPT1x5F7fBwCG3qHfnzeP/Vh/ZxCUA== + +isomorphic-fetch@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/isomorphic-fetch/-/isomorphic-fetch-3.0.0.tgz#0267b005049046d2421207215d45d6a262b8b8b4" + integrity sha512-qvUtwJ3j6qwsF3jLxkZ72qCgjMysPzDfeV240JHiGZsANBYd+EEuu35v7dfrJ9Up0Ak07D7GGSkGhCHTqg/5wA== + dependencies: + node-fetch "^2.6.1" + whatwg-fetch "^3.4.1" + +isomorphic-form-data@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isomorphic-form-data/-/isomorphic-form-data-2.0.0.tgz#9f6adf1c4c61ae3aefd8f110ab60fb9b143d6cec" + integrity sha512-TYgVnXWeESVmQSg4GLVbalmQ+B4NPi/H4eWxqALKj63KsUrcu301YDjBqaOw3h+cbak7Na4Xyps3BiptHtxTfg== + dependencies: + form-data "^2.3.2" + +isomorphic-ws@4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz#55fd4cd6c5e6491e76dc125938dd863f5cd4f2dc" + integrity sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w== + +isstream@~0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" + integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo= + +jest-worker@24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-24.9.0.tgz#5dbfdb5b2d322e98567898238a9697bcce67b3e5" + integrity sha512-51PE4haMSXcHohnSMdM42anbvZANYTqMrr52tVKPqqsPJMzoP6FYYDVqahX/HrAoKEKz3uUPzSvKs9A3qR4iVw== + dependencies: + merge-stream "^2.0.0" + supports-color "^6.1.0" + +jest-worker@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-26.6.2.tgz#7f72cbc4d643c365e27b9fd775f9d0eaa9c7a8ed" + integrity sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ== + dependencies: + "@types/node" "*" + merge-stream "^2.0.0" + supports-color "^7.0.0" + +js-cookie@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/js-cookie/-/js-cookie-2.2.1.tgz#69e106dc5d5806894562902aa5baec3744e9b2b8" + integrity sha512-HvdH2LzI/EAZcUwA8+0nKNtWHqS+ZmijLA30RwZA0bo7ToCckjK5MkGhjED9KoRcXO6BaGI3I9UIzSA1FKFPOQ== + +"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" + integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== + +js-yaml@^3.13.1, js-yaml@^3.14.0: + version "3.14.1" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537" + integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g== + dependencies: + argparse "^1.0.7" + esprima "^4.0.0" + +jsbn@~0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" + integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM= + +jsesc@^2.5.1: + version "2.5.2" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" + integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== + +json-buffer@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.0.tgz#5b1f397afc75d677bde8bcfc0e47e1f9a3d9a898" + integrity sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg= + +json-parse-better-errors@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" + integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw== + +json-parse-even-better-errors@^2.3.0: + version "2.3.1" + resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" + integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== + +json-schema-traverse@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" + integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== + +json-schema@0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" + integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM= + +json-stable-stringify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz#9a759d39c5f2ff503fd5300646ed445f88c4f9af" + integrity sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8= + dependencies: + jsonify "~0.0.0" + +json-stringify-safe@~5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" + integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= + +json-to-pretty-yaml@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/json-to-pretty-yaml/-/json-to-pretty-yaml-1.2.2.tgz#f4cd0bd0a5e8fe1df25aaf5ba118b099fd992d5b" + integrity sha1-9M0L0KXo/h3yWq9boRiwmf2ZLVs= + dependencies: + remedial "^1.0.7" + remove-trailing-spaces "^1.0.6" + +json5@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.1.tgz#779fb0018604fa854eacbf6252180d83543e3dbe" + integrity sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow== + dependencies: + minimist "^1.2.0" + +json5@^2.1.2: + version "2.1.3" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.1.3.tgz#c9b0f7fa9233bfe5807fe66fcf3a5617ed597d43" + integrity sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA== + dependencies: + minimist "^1.2.5" + +jsonfile@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" + integrity sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss= + optionalDependencies: + graceful-fs "^4.1.6" + +jsonify@~0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73" + integrity sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM= + +jsonwebtoken@^8.5.1: + version "8.5.1" + resolved "https://registry.yarnpkg.com/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz#00e71e0b8df54c2121a1f26137df2280673bcc0d" + integrity sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w== + dependencies: + jws "^3.2.2" + lodash.includes "^4.3.0" + lodash.isboolean "^3.0.3" + lodash.isinteger "^4.0.4" + lodash.isnumber "^3.0.3" + lodash.isplainobject "^4.0.6" + lodash.isstring "^4.0.1" + lodash.once "^4.0.0" + ms "^2.1.1" + semver "^5.6.0" + +jsprim@^1.2.2: + version "1.4.1" + resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" + integrity sha1-MT5mvB5cwG5Di8G3SZwuXFastqI= + dependencies: + assert-plus "1.0.0" + extsprintf "1.3.0" + json-schema "0.2.3" + verror "1.10.0" + +jwa@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/jwa/-/jwa-1.4.1.tgz#743c32985cb9e98655530d53641b66c8645b039a" + integrity sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA== + dependencies: + buffer-equal-constant-time "1.0.1" + ecdsa-sig-formatter "1.0.11" + safe-buffer "^5.0.1" + +jws@^3.2.2: + version "3.2.2" + resolved "https://registry.yarnpkg.com/jws/-/jws-3.2.2.tgz#001099f3639468c9414000e99995fa52fb478304" + integrity sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA== + dependencies: + jwa "^1.4.1" + safe-buffer "^5.0.1" + +keen-slider@^5.2.4: + version "5.3.5" + resolved "https://registry.yarnpkg.com/keen-slider/-/keen-slider-5.3.5.tgz#29ac24fd7dbf1f1435bd448e0e583cded36b4b91" + integrity sha512-3QYvrFK7HbtkiC98/G+RM44y9WBe9cpHDHtP9bI1J/Vrc54IHLuTjOjyX4E81ukRc5GwiGfijOwStxEhisFnPg== + +keyv@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/keyv/-/keyv-3.1.0.tgz#ecc228486f69991e49e9476485a5be1e8fc5c4d9" + integrity sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA== + dependencies: + json-buffer "3.0.0" + +kind-of@^6.0.3: + version "6.0.3" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" + integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== + +klona@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/klona/-/klona-2.0.4.tgz#7bb1e3affb0cb8624547ef7e8f6708ea2e39dfc0" + integrity sha512-ZRbnvdg/NxqzC7L9Uyqzf4psi1OM4Cuc+sJAkQPjO6XkQIJTNbfK2Rsmbw8fx1p2mkZdp2FZYo2+LwXYY/uwIA== + +latest-version@5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/latest-version/-/latest-version-5.1.0.tgz#119dfe908fe38d15dfa43ecd13fa12ec8832face" + integrity sha512-weT+r0kTkRQdCdYCNtkMwWXQTMEswKrFBkm4ckQOMVhhqhIMI1UT2hMj+1iigIhgSZm5gTmrRXBNoGUgaTY1xA== + dependencies: + package-json "^6.3.0" + +levn@~0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" + integrity sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4= + dependencies: + prelude-ls "~1.1.2" + type-check "~0.3.2" + +line-column@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/line-column/-/line-column-1.0.2.tgz#d25af2936b6f4849172b312e4792d1d987bc34a2" + integrity sha1-0lryk2tvSEkXKzEuR5LR2Ye8NKI= + dependencies: + isarray "^1.0.0" + isobject "^2.0.0" + +lines-and-columns@^1.1.6: + version "1.1.6" + resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.1.6.tgz#1c00c743b433cd0a4e80758f7b64a57440d9ff00" + integrity sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA= + +listr-silent-renderer@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/listr-silent-renderer/-/listr-silent-renderer-1.1.1.tgz#924b5a3757153770bf1a8e3fbf74b8bbf3f9242e" + integrity sha1-kktaN1cVN3C/Go4/v3S4u/P5JC4= + +listr-update-renderer@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/listr-update-renderer/-/listr-update-renderer-0.5.0.tgz#4ea8368548a7b8aecb7e06d8c95cb45ae2ede6a2" + integrity sha512-tKRsZpKz8GSGqoI/+caPmfrypiaq+OQCbd+CovEC24uk1h952lVj5sC7SqyFUm+OaJ5HN/a1YLt5cit2FMNsFA== + dependencies: + chalk "^1.1.3" + cli-truncate "^0.2.1" + elegant-spinner "^1.0.1" + figures "^1.7.0" + indent-string "^3.0.0" + log-symbols "^1.0.2" + log-update "^2.3.0" + strip-ansi "^3.0.1" + +listr-verbose-renderer@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/listr-verbose-renderer/-/listr-verbose-renderer-0.5.0.tgz#f1132167535ea4c1261102b9f28dac7cba1e03db" + integrity sha512-04PDPqSlsqIOaaaGZ+41vq5FejI9auqTInicFRndCBgE3bXG8D6W1I+mWhk+1nqbHmyhla/6BUrd5OSiHwKRXw== + dependencies: + chalk "^2.4.1" + cli-cursor "^2.1.0" + date-fns "^1.27.2" + figures "^2.0.0" + +listr@^0.14.3: + version "0.14.3" + resolved "https://registry.yarnpkg.com/listr/-/listr-0.14.3.tgz#2fea909604e434be464c50bddba0d496928fa586" + integrity sha512-RmAl7su35BFd/xoMamRjpIE4j3v+L28o8CT5YhAXQJm1fD+1l9ngXY8JAQRJ+tFK2i5njvi0iRUKV09vPwA0iA== + dependencies: + "@samverschueren/stream-to-observable" "^0.3.0" + is-observable "^1.1.0" + is-promise "^2.1.0" + is-stream "^1.1.0" + listr-silent-renderer "^1.1.1" + listr-update-renderer "^0.5.0" + listr-verbose-renderer "^0.5.0" + p-map "^2.0.0" + rxjs "^6.3.3" + +loader-runner@^4.1.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-4.2.0.tgz#d7022380d66d14c5fb1d496b89864ebcfd478384" + integrity sha512-92+huvxMvYlMzMt0iIOukcwYBFpkYJdpl2xsZ7LrlayO7E8SOv+JJUEK17B/dJIHAOLMfh2dZZ/Y18WgmGtYNw== + +loader-utils@1.2.3: + version "1.2.3" + resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.2.3.tgz#1ff5dc6911c9f0a062531a4c04b609406108c2c7" + integrity sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA== + dependencies: + big.js "^5.2.2" + emojis-list "^2.0.0" + json5 "^1.0.1" + +loader-utils@2.0.0, loader-utils@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-2.0.0.tgz#e4cace5b816d425a166b5f097e10cd12b36064b0" + integrity sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ== + dependencies: + big.js "^5.2.2" + emojis-list "^3.0.0" + json5 "^2.1.2" + +loader-utils@^1.0.2, loader-utils@^1.1.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.4.0.tgz#c579b5e34cb34b1a74edc6c1fb36bfa371d5a613" + integrity sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA== + dependencies: + big.js "^5.2.2" + emojis-list "^3.0.0" + json5 "^1.0.1" + +locate-path@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" + integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g== + dependencies: + p-locate "^4.1.0" + +locate-path@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" + integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== + dependencies: + p-locate "^5.0.0" + +lodash._reinterpolate@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz#0ccf2d89166af03b3663c796538b75ac6e114d9d" + integrity sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0= + +lodash.camelcase@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6" + integrity sha1-soqmKIorn8ZRA1x3EfZathkDMaY= + +lodash.debounce@^4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" + integrity sha1-gteb/zCmfEAF/9XiUVMArZyk168= + +lodash.get@^4: + version "4.4.2" + resolved "https://registry.yarnpkg.com/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99" + integrity sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk= + +lodash.includes@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/lodash.includes/-/lodash.includes-4.3.0.tgz#60bb98a87cb923c68ca1e51325483314849f553f" + integrity sha1-YLuYqHy5I8aMoeUTJUgzFISfVT8= + +lodash.isboolean@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz#6c2e171db2a257cd96802fd43b01b20d5f5870f6" + integrity sha1-bC4XHbKiV82WgC/UOwGyDV9YcPY= + +lodash.isinteger@^4.0.4: + version "4.0.4" + resolved "https://registry.yarnpkg.com/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz#619c0af3d03f8b04c31f5882840b77b11cd68343" + integrity sha1-YZwK89A/iwTDH1iChAt3sRzWg0M= + +lodash.isnumber@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz#3ce76810c5928d03352301ac287317f11c0b1ffc" + integrity sha1-POdoEMWSjQM1IwGsKHMX8RwLH/w= + +lodash.isplainobject@^4.0.6: + version "4.0.6" + resolved "https://registry.yarnpkg.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb" + integrity sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs= + +lodash.isstring@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/lodash.isstring/-/lodash.isstring-4.0.1.tgz#d527dfb5456eca7cc9bb95d5daeaf88ba54a5451" + integrity sha1-1SfftUVuynzJu5XV2ur4i6VKVFE= + +lodash.once@^4.0.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac" + integrity sha1-DdOXEhPHxW34gJd9UEyI+0cal6w= + +lodash.random@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/lodash.random/-/lodash.random-3.2.0.tgz#96e24e763333199130d2c9e2fd57f91703cc262d" + integrity sha1-luJOdjMzGZEw0sni/Vf5FwPMJi0= + +lodash.sortby@^4.7.0: + version "4.7.0" + resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438" + integrity sha1-7dFMgk4sycHgsKG0K7UhBRakJDg= + +lodash.template@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.template/-/lodash.template-4.5.0.tgz#f976195cf3f347d0d5f52483569fe8031ccce8ab" + integrity sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A== + dependencies: + lodash._reinterpolate "^3.0.0" + lodash.templatesettings "^4.0.0" + +lodash.templatesettings@^4.0.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/lodash.templatesettings/-/lodash.templatesettings-4.2.0.tgz#e481310f049d3cf6d47e912ad09313b154f0fb33" + integrity sha512-stgLz+i3Aa9mZgnjr/O+v9ruKZsPsndy7qPZOchbqk2cnTU1ZaldKK+v7m54WoKIyxiuMZTKT2H81F8BeAc3ZQ== + dependencies: + lodash._reinterpolate "^3.0.0" + +lodash.throttle@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/lodash.throttle/-/lodash.throttle-4.1.1.tgz#c23e91b710242ac70c37f1e1cda9274cc39bf2f4" + integrity sha1-wj6RtxAkKscMN/HhzaknTMOb8vQ= + +lodash.toarray@^4.4.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/lodash.toarray/-/lodash.toarray-4.4.0.tgz#24c4bfcd6b2fba38bfd0594db1179d8e9b656561" + integrity sha1-JMS/zWsvuji/0FlNsRedjptlZWE= + +lodash@^4.17.11, lodash@^4.17.13, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20, lodash@~4.17.20: + version "4.17.20" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.20.tgz#b44a9b6297bcb698f1c51a3545a2b3b368d59c52" + integrity sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA== + +log-symbols@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-1.0.2.tgz#376ff7b58ea3086a0f09facc74617eca501e1a18" + integrity sha1-N2/3tY6jCGoPCfrMdGF+ylAeGhg= + dependencies: + chalk "^1.0.0" + +log-symbols@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.0.0.tgz#69b3cc46d20f448eccdb75ea1fa733d9e821c920" + integrity sha512-FN8JBzLx6CzeMrB0tg6pqlGU1wCrXW+ZXGH481kfsBqer0hToTIiHdjH4Mq8xJUbvATujKCvaREGWpGUionraA== + dependencies: + chalk "^4.0.0" + +log-update@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/log-update/-/log-update-2.3.0.tgz#88328fd7d1ce7938b29283746f0b1bc126b24708" + integrity sha1-iDKP19HOeTiykoN0bwsbwSayRwg= + dependencies: + ansi-escapes "^3.0.0" + cli-cursor "^2.0.0" + wrap-ansi "^3.0.1" + +loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" + integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== + dependencies: + js-tokens "^3.0.0 || ^4.0.0" + +lower-case@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-2.0.1.tgz#39eeb36e396115cc05e29422eaea9e692c9408c7" + integrity sha512-LiWgfDLLb1dwbFQZsSglpRj+1ctGnayXz3Uv0/WO8n558JycT5fg6zkNcnW0G68Nn0aEldTFeEfmjCfmqry/rQ== + dependencies: + tslib "^1.10.0" + +lower-case@^2.0.1, lower-case@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-2.0.2.tgz#6fa237c63dbdc4a82ca0fd882e4722dc5e634e28" + integrity sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg== + dependencies: + tslib "^2.0.3" + +lowercase-keys@^1.0.0, lowercase-keys@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.1.tgz#6f9e30b47084d971a7c820ff15a6c5167b74c26f" + integrity sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA== + +lowercase-keys@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-2.0.0.tgz#2603e78b7b4b0006cbca2fbcc8a3202558ac9479" + integrity sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA== + +lru-cache@5.1.1, lru-cache@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" + integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w== + dependencies: + yallist "^3.0.2" + +lru-cache@6.0.0, lru-cache@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" + integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== + dependencies: + yallist "^4.0.0" + +madge@^3.8.0: + version "3.12.0" + resolved "https://registry.yarnpkg.com/madge/-/madge-3.12.0.tgz#727c1ebb268150d52e6d0c3ccd382b4c7bd0bf19" + integrity sha512-9kA2W5RIbvH25CWc8tzPNn1X47AOcHEEwZJxWAMxhEOKEziVR1iMCbGCFUea5tWXs/A+xgJF59o/oSbNkOXpeg== + dependencies: + chalk "^4.1.0" + commander "^5.1.0" + commondir "^1.0.1" + debug "^4.0.1" + dependency-tree "^7.2.2" + detective-amd "^3.0.0" + detective-cjs "^3.1.1" + detective-es6 "^2.1.0" + detective-less "^1.0.2" + detective-postcss "^3.0.1" + detective-sass "^3.0.1" + detective-scss "^2.0.1" + detective-stylus "^1.0.0" + detective-typescript "^5.8.0" + graphviz "0.0.9" + ora "^5.1.0" + pluralize "^8.0.0" + precinct "^6.3.1" + pretty-ms "^7.0.0" + rc "^1.2.7" + typescript "^3.9.5" + walkdir "^0.4.1" + +magic-string@^0.25.7: + version "0.25.7" + resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.25.7.tgz#3f497d6fd34c669c6798dcb821f2ef31f5445051" + integrity sha512-4CrMT5DOHTDk4HYDlzmwu4FVCcIYI8gauveasrdCu2IKIFOJ3f0v/8MDGJCDL9oD2ppz/Av1b0Nj345H9M+XIA== + dependencies: + sourcemap-codec "^1.4.4" + +make-dir@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-2.1.0.tgz#5f0310e18b8be898cc07009295a30ae41e91e6f5" + integrity sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA== + dependencies: + pify "^4.0.1" + semver "^5.6.0" + +make-dir@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" + integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw== + dependencies: + semver "^6.0.0" + +make-error@^1, make-error@^1.1.1: + version "1.3.6" + resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" + integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== + +map-cache@^0.2.0: + version "0.2.2" + resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" + integrity sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8= + +map-obj@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-1.0.1.tgz#d933ceb9205d82bdcf4886f6742bdc2b4dea146d" + integrity sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0= + +map-obj@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-4.1.0.tgz#b91221b542734b9f14256c0132c897c5d7256fd5" + integrity sha512-glc9y00wgtwcDmp7GaE/0b0OnxpNJsVf3ael/An6Fe2Q51LLwN1er6sdomLRzz5h0+yMpiYLhWYF5R7HeqVd4g== + +md5.js@^1.3.4: + version "1.3.5" + resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f" + integrity sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg== + dependencies: + hash-base "^3.0.0" + inherits "^2.0.1" + safe-buffer "^5.1.2" + +memory-fs@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.5.0.tgz#324c01288b88652966d161db77838720845a8e3c" + integrity sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA== + dependencies: + errno "^0.1.3" + readable-stream "^2.0.1" + +meow@^7.0.0: + version "7.1.1" + resolved "https://registry.yarnpkg.com/meow/-/meow-7.1.1.tgz#7c01595e3d337fcb0ec4e8eed1666ea95903d306" + integrity sha512-GWHvA5QOcS412WCo8vwKDlTelGLsCGBVevQB5Kva961rmNfun0PCbv5+xta2kUMFJyR8/oWnn7ddeKdosbAPbA== + dependencies: + "@types/minimist" "^1.2.0" + camelcase-keys "^6.2.2" + decamelize-keys "^1.1.0" + hard-rejection "^2.1.0" + minimist-options "4.1.0" + normalize-package-data "^2.5.0" + read-pkg-up "^7.0.1" + redent "^3.0.0" + trim-newlines "^3.0.0" + type-fest "^0.13.1" + yargs-parser "^18.1.3" + +merge-source-map@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/merge-source-map/-/merge-source-map-1.1.0.tgz#2fdde7e6020939f70906a68f2d7ae685e4c8c646" + integrity sha512-Qkcp7P2ygktpMPh2mCQZaf3jhN6D3Z/qVZHSdWvQ+2Ef5HgRAPBO57A77+ENm0CPx2+1Ce/MYKi3ymqdfuqibw== + dependencies: + source-map "^0.6.1" + +merge-stream@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" + integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== + +merge2@^1.3.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" + integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== + +micromatch@^4.0.0, micromatch@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.2.tgz#4fcb0999bf9fbc2fcbdd212f6d629b9a56c39259" + integrity sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q== + dependencies: + braces "^3.0.1" + picomatch "^2.0.5" + +miller-rabin@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/miller-rabin/-/miller-rabin-4.0.1.tgz#f080351c865b0dc562a8462966daa53543c78a4d" + integrity sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA== + dependencies: + bn.js "^4.0.0" + brorand "^1.0.1" + +mime-db@1.45.0: + version "1.45.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.45.0.tgz#cceeda21ccd7c3a745eba2decd55d4b73e7879ea" + integrity sha512-CkqLUxUk15hofLoLyljJSrukZi8mAtgd+yE5uO4tqRZsdsAJKv0O+rFMhVDRJgozy+yG6md5KwuXhD4ocIoP+w== + +mime-types@^2.1.12, mime-types@^2.1.27, mime-types@~2.1.19: + version "2.1.28" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.28.tgz#1160c4757eab2c5363888e005273ecf79d2a0ecd" + integrity sha512-0TO2yJ5YHYr7M2zzT7gDU1tbwHxEUWBCLt0lscSNpcdAfFyJOVEpRYNS7EXVcTLNj/25QO8gulHC5JtTzSE2UQ== + dependencies: + mime-db "1.45.0" + +mime@^2.3.1: + version "2.4.7" + resolved "https://registry.yarnpkg.com/mime/-/mime-2.4.7.tgz#962aed9be0ed19c91fd7dc2ece5d7f4e89a90d74" + integrity sha512-dhNd1uA2u397uQk3Nv5LM4lm93WYDUXFn3Fu291FJerns4jyTudqhIWe4W04YLy7Uk1tm1Ore04NpjRvQp/NPA== + +mimic-fn@^1.0.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022" + integrity sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ== + +mimic-fn@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" + integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== + +mimic-response@^1.0.0, mimic-response@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b" + integrity sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ== + +mimic-response@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-2.1.0.tgz#d13763d35f613d09ec37ebb30bac0469c0ee8f43" + integrity sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA== + +mimic-response@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-3.1.0.tgz#2d1d59af9c1b129815accc2c46a022a5ce1fa3c9" + integrity sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ== + +min-indent@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/min-indent/-/min-indent-1.0.1.tgz#a63f681673b30571fbe8bc25686ae746eefa9869" + integrity sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg== + +mini-svg-data-uri@^1.0.3: + version "1.2.3" + resolved "https://registry.yarnpkg.com/mini-svg-data-uri/-/mini-svg-data-uri-1.2.3.tgz#e16baa92ad55ddaa1c2c135759129f41910bc39f" + integrity sha512-zd6KCAyXgmq6FV1mR10oKXYtvmA9vRoB6xPSTUJTbFApCtkefDnYueVR1gkof3KcdLZo1Y8mjF2DFmQMIxsHNQ== + +minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" + integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== + +minimalistic-crypto-utils@^1.0.0, minimalistic-crypto-utils@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" + integrity sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo= + +"minimatch@2 || 3", minimatch@3.0.4, minimatch@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" + integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== + dependencies: + brace-expansion "^1.1.7" + +minimist-options@4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/minimist-options/-/minimist-options-4.1.0.tgz#c0655713c53a8a2ebd77ffa247d342c40f010619" + integrity sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A== + dependencies: + arrify "^1.0.1" + is-plain-obj "^1.1.0" + kind-of "^6.0.3" + +minimist@^1.1.1, minimist@^1.2.0, minimist@^1.2.3, minimist@^1.2.5: + version "1.2.5" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" + integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== + +mkdirp-classic@^0.5.2, mkdirp-classic@^0.5.3: + version "0.5.3" + resolved "https://registry.yarnpkg.com/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz#fa10c9115cc6d8865be221ba47ee9bed78601113" + integrity sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A== + +mkdirp@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" + integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== + +mkdirp@~0.5.1: + version "0.5.5" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" + integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== + dependencies: + minimist "^1.2.5" + +module-definition@^3.0.0, module-definition@^3.3.0: + version "3.3.1" + resolved "https://registry.yarnpkg.com/module-definition/-/module-definition-3.3.1.tgz#fedef71667713e36988b93d0626a4fe7b35aebfc" + integrity sha512-kLidGPwQ2yq484nSD+D3JoJp4Etc0Ox9P0L34Pu/cU4X4HcG7k7p62XI5BBuvURWMRX3RPyuhOcBHbKus+UH4A== + dependencies: + ast-module-types "^2.7.1" + node-source-walk "^4.0.0" + +module-lookup-amd@^6.1.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/module-lookup-amd/-/module-lookup-amd-6.2.0.tgz#70600008b3f26630fde9ef9ae6165ac69de6ecbb" + integrity sha512-uxHCj5Pw9psZiC1znjU2qPsubt6haCSsN9m7xmIdoTciEgfxUkE1vhtDvjHPuOXEZrVJhjKgkmkP+w73rRuelQ== + dependencies: + commander "^2.8.1" + debug "^4.1.0" + file-exists-dazinatorfork "^1.0.2" + find "^0.3.0" + requirejs "^2.3.5" + requirejs-config-file "^3.1.1" + +moment@^2.19.3: + version "2.29.1" + resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.1.tgz#b2be769fa31940be9eeea6469c075e35006fa3d3" + integrity sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ== + +ms@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= + +ms@2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" + integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== + +ms@^2.0.0, ms@^2.1.1: + version "2.1.3" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" + integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== + +mute-stream@0.0.8: + version "0.0.8" + resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d" + integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA== + +mv@~2: + version "2.1.1" + resolved "https://registry.yarnpkg.com/mv/-/mv-2.1.1.tgz#ae6ce0d6f6d5e0a4f7d893798d03c1ea9559b6a2" + integrity sha1-rmzg1vbV4KT32JN5jQPB6pVZtqI= + dependencies: + mkdirp "~0.5.1" + ncp "~2.0.0" + rimraf "~2.4.0" + +nan@^2.14.0: + version "2.14.2" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.2.tgz#f5376400695168f4cc694ac9393d0c9585eeea19" + integrity sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ== + +nanoid@^3.1.16: + version "3.1.20" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.20.tgz#badc263c6b1dcf14b71efaa85f6ab4c1d6cfc788" + integrity sha512-a1cQNyczgKbLX9jwbS/+d7W8fX/RfgYR7lVWwWOGIPNgK2m0MWvrGF6/m4kk6U3QcFMnZf3RIhL0v2Jgh/0Uxw== + +napi-build-utils@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/napi-build-utils/-/napi-build-utils-1.0.2.tgz#b1fddc0b2c46e380a0b7a76f984dd47c41a13806" + integrity sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg== + +native-url@0.3.4: + version "0.3.4" + resolved "https://registry.yarnpkg.com/native-url/-/native-url-0.3.4.tgz#29c943172aed86c63cee62c8c04db7f5756661f8" + integrity sha512-6iM8R99ze45ivyH8vybJ7X0yekIcPf5GgLV5K0ENCbmRcaRIDoj37BC8iLEmaaBfqqb8enuZ5p0uhY+lVAbAcA== + dependencies: + querystring "^0.2.0" + +ncp@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ncp/-/ncp-2.0.0.tgz#195a21d6c46e361d2fb1281ba38b91e9df7bdbb3" + integrity sha1-GVoh1sRuNh0vsSgbo4uR6d9727M= + +neo-async@^2.6.2: + version "2.6.2" + resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" + integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== + +next-seo@^4.11.0: + version "4.17.0" + resolved "https://registry.yarnpkg.com/next-seo/-/next-seo-4.17.0.tgz#fb3dbe0ed7414aa9d83872ef5d8510980a6dae7e" + integrity sha512-/hnb3oq7bhi8s7bup7+Lm6VzzgRucj+JrWtp+dJiYs/04H0N/NhmE9MpepixQ16fFj6G/39JLYxhzsO/QZG/Kw== + +next-themes@^0.0.4: + version "0.0.4" + resolved "https://registry.yarnpkg.com/next-themes/-/next-themes-0.0.4.tgz#fb06a9d03887201dd8fdd75fc1c84f406988f61e" + integrity sha512-j0bJJ6INanFsniCL31j1ZhjNaoqIFOaTeiUakbGpGxDz4+318Zp2ZfaorSjpUhzDWbXBKA3ZDE0DSUVWJ/8EsA== + +next-tick@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.0.0.tgz#ca86d1fe8828169b0120208e3dc8424b9db8342c" + integrity sha1-yobR/ogoFpsBICCOPchCS524NCw= + +next-unused@^0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/next-unused/-/next-unused-0.0.3.tgz#e7560b30c64b91a4143450eee1cdb535eb85e51b" + integrity sha512-LrjyGL6gq3v7eOL2KNkmciDZCpJjt9QjEftQEr4oZ8o5zwoEvLqfn7mgv+9Qv+i39fDrEYlF436zfwpBHp7ahg== + dependencies: + madge "^3.8.0" + ts-loader "^7.0.0" + +next@^10.0.5-canary.11: + version "10.0.5" + resolved "https://registry.yarnpkg.com/next/-/next-10.0.5.tgz#8071e0aa1883266c91943aa7c6b73deadb064793" + integrity sha512-yr7ap2TLugf0aMHz+3JoKFP9CCkFE+k6jCfdUymORhptjLYZbD3YGlTcUC1CRl+b5Phlbl7m/WUIPde0VcguiA== + dependencies: + "@ampproject/toolbox-optimizer" "2.7.1-alpha.0" + "@babel/runtime" "7.12.5" + "@hapi/accept" "5.0.1" + "@next/env" "10.0.5" + "@next/polyfill-module" "10.0.5" + "@next/react-dev-overlay" "10.0.5" + "@next/react-refresh-utils" "10.0.5" + "@opentelemetry/api" "0.14.0" + ast-types "0.13.2" + babel-plugin-transform-define "2.0.0" + babel-plugin-transform-react-remove-prop-types "0.4.24" + browserslist "4.14.6" + buffer "5.6.0" + caniuse-lite "^1.0.30001113" + chalk "2.4.2" + chokidar "3.4.3" + crypto-browserify "3.12.0" + css-loader "4.3.0" + cssnano-simple "1.2.1" + etag "1.8.1" + find-cache-dir "3.3.1" + jest-worker "24.9.0" + loader-utils "2.0.0" + native-url "0.3.4" + node-fetch "2.6.1" + node-html-parser "1.4.9" + p-limit "3.1.0" + path-browserify "1.0.1" + pnp-webpack-plugin "1.6.4" + postcss "8.1.7" + process "0.11.10" + prop-types "15.7.2" + raw-body "2.4.1" + react-is "16.13.1" + react-refresh "0.8.3" + resolve-url-loader "3.1.2" + sass-loader "10.0.5" + schema-utils "2.7.1" + stream-browserify "3.0.0" + style-loader "1.2.1" + styled-jsx "3.3.2" + use-subscription "1.5.1" + vm-browserify "1.1.2" + watchpack "2.0.0-beta.13" + webpack "4.44.1" + webpack-sources "1.4.3" + optionalDependencies: + sharp "0.26.3" + +no-case@^3.0.3, no-case@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/no-case/-/no-case-3.0.4.tgz#d361fd5c9800f558551a8369fc0dcd4662b6124d" + integrity sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg== + dependencies: + lower-case "^2.0.2" + tslib "^2.0.3" + +node-abi@^2.7.0: + version "2.19.3" + resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-2.19.3.tgz#252f5dcab12dad1b5503b2d27eddd4733930282d" + integrity sha512-9xZrlyfvKhWme2EXFKQhZRp1yNWT/uI1luYPr3sFl+H4keYY4xR+1jO7mvTTijIsHf1M+QDe9uWuKeEpLInIlg== + dependencies: + semver "^5.4.1" + +node-addon-api@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-3.1.0.tgz#98b21931557466c6729e51cb77cd39c965f42239" + integrity sha512-flmrDNB06LIl5lywUz7YlNGZH/5p0M7W28k8hzd9Lshtdh1wshD2Y+U4h9LD6KObOy1f+fEVdgprPrEymjM5uw== + +node-emoji@^1.8.1: + version "1.10.0" + resolved "https://registry.yarnpkg.com/node-emoji/-/node-emoji-1.10.0.tgz#8886abd25d9c7bb61802a658523d1f8d2a89b2da" + integrity sha512-Yt3384If5H6BYGVHiHwTL+99OzJKHhgp82S8/dktEK73T26BazdgZ4JZh92xSVtGNJvz9UbXdNAc5hcrXV42vw== + dependencies: + lodash.toarray "^4.4.0" + +node-fetch@2.6.1, node-fetch@^2.6.1: + version "2.6.1" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052" + integrity sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw== + +node-html-parser@1.4.9: + version "1.4.9" + resolved "https://registry.yarnpkg.com/node-html-parser/-/node-html-parser-1.4.9.tgz#3c8f6cac46479fae5800725edb532e9ae8fd816c" + integrity sha512-UVcirFD1Bn0O+TSmloHeHqZZCxHjvtIeGdVdGMhyZ8/PWlEiZaZ5iJzR189yKZr8p0FXN58BUeC7RHRkf/KYGw== + dependencies: + he "1.2.0" + +node-int64@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" + integrity sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs= + +node-releases@^1.1.65, node-releases@^1.1.69: + version "1.1.69" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.69.tgz#3149dbde53b781610cd8b486d62d86e26c3725f6" + integrity sha512-DGIjo79VDEyAnRlfSqYTsy+yoHd2IOjJiKUozD2MV2D85Vso6Bug56mb9tT/fY5Urt0iqk01H7x+llAruDR2zA== + +node-source-walk@^4.0.0, node-source-walk@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/node-source-walk/-/node-source-walk-4.2.0.tgz#c2efe731ea8ba9c03c562aa0a9d984e54f27bc2c" + integrity sha512-hPs/QMe6zS94f5+jG3kk9E7TNm4P2SulrKiLWMzKszBfNZvL/V6wseHlTd7IvfW0NZWqPtK3+9yYNr+3USGteA== + dependencies: + "@babel/parser" "^7.0.0" + +noop-logger@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/noop-logger/-/noop-logger-0.1.1.tgz#94a2b1633c4f1317553007d8966fd0e841b6a4c2" + integrity sha1-lKKxYzxPExdVMAfYlm/Q6EG2pMI= + +normalize-html-whitespace@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/normalize-html-whitespace/-/normalize-html-whitespace-1.0.0.tgz#5e3c8e192f1b06c3b9eee4b7e7f28854c7601e34" + integrity sha512-9ui7CGtOOlehQu0t/OhhlmDyc71mKVlv+4vF+me4iZLPrNtRL2xoquEdfZxasC/bdQi/Hr3iTrpyRKIG+ocabA== + +normalize-package-data@^2.5.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" + integrity sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA== + dependencies: + hosted-git-info "^2.1.4" + resolve "^1.10.0" + semver "2 || 3 || 4 || 5" + validate-npm-package-license "^3.0.1" + +normalize-path@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" + integrity sha1-GrKLVW4Zg2Oowab35vogE3/mrtk= + dependencies: + remove-trailing-separator "^1.0.1" + +normalize-path@^3.0.0, normalize-path@~3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" + integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== + +normalize-range@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/normalize-range/-/normalize-range-0.1.2.tgz#2d10c06bdfd312ea9777695a4d28439456b75942" + integrity sha1-LRDAa9/TEuqXd2laTShDlFa3WUI= + +normalize-url@^4.1.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-4.5.0.tgz#453354087e6ca96957bd8f5baf753f5982142129" + integrity sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ== + +normalize.css@^8.0.1: + version "8.0.1" + resolved "https://registry.yarnpkg.com/normalize.css/-/normalize.css-8.0.1.tgz#9b98a208738b9cc2634caacbc42d131c97487bf3" + integrity sha512-qizSNPO93t1YUuUhP22btGOo3chcvDFqFaj2TRybP0DMxkHOCTYwp3n34fel4a31ORXy4m1Xq0Gyqpb5m33qIg== + +npmlog@^4.0.1, npmlog@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" + integrity sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg== + dependencies: + are-we-there-yet "~1.1.2" + console-control-strings "~1.1.0" + gauge "~2.7.3" + set-blocking "~2.0.0" + +nullthrows@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/nullthrows/-/nullthrows-1.1.1.tgz#7818258843856ae971eae4208ad7d7eb19a431b1" + integrity sha512-2vPPEi+Z7WqML2jZYddDIfy5Dqb0r2fze2zTxNNknZaFpVHU3mFB3R+DWeJWGVx0ecvttSGlJTI+WG+8Z4cDWw== + +num2fraction@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/num2fraction/-/num2fraction-1.2.2.tgz#6f682b6a027a4e9ddfa4564cd2589d1d4e669ede" + integrity sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4= + +number-is-nan@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" + integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0= + +oauth-sign@~0.9.0: + version "0.9.0" + resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" + integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== + +object-assign@^4.1.0, object-assign@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= + +object-hash@^2.0.3: + version "2.1.1" + resolved "https://registry.yarnpkg.com/object-hash/-/object-hash-2.1.1.tgz#9447d0279b4fcf80cff3259bf66a1dc73afabe09" + integrity sha512-VOJmgmS+7wvXf8CjbQmimtCnEx3IAoLxI3fp2fbWehxrWBcAQFbk+vcwb6vzR0VZv/eNCJ/27j151ZTwqW/JeQ== + +object-inspect@^1.8.0: + version "1.9.0" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.9.0.tgz#c90521d74e1127b67266ded3394ad6116986533a" + integrity sha512-i3Bp9iTqwhaLZBxGkRfo5ZbE07BQRT7MGu8+nNgwW9ItGp1TzCTw2DLEoWwjClxBjOFI/hWljTAmYGCEwmtnOw== + +object-keys@^1.0.12, object-keys@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" + integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== + +object-path@^0.11.4: + version "0.11.5" + resolved "https://registry.yarnpkg.com/object-path/-/object-path-0.11.5.tgz#d4e3cf19601a5140a55a16ad712019a9c50b577a" + integrity sha512-jgSbThcoR/s+XumvGMTMf81QVBmah+/Q7K7YduKeKVWL7N111unR2d6pZZarSk6kY/caeNxUDyxOvMWyzoU2eg== + +object.assign@^4.1.0, object.assign@^4.1.1: + version "4.1.2" + resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.2.tgz#0ed54a342eceb37b38ff76eb831a0e788cb63940" + integrity sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ== + dependencies: + call-bind "^1.0.0" + define-properties "^1.1.3" + has-symbols "^1.0.1" + object-keys "^1.1.1" + +once@^1.3.0, once@^1.3.1, once@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= + dependencies: + wrappy "1" + +onetime@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-2.0.1.tgz#067428230fd67443b2794b22bba528b6867962d4" + integrity sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ= + dependencies: + mimic-fn "^1.0.0" + +onetime@^5.1.0: + version "5.1.2" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" + integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== + dependencies: + mimic-fn "^2.1.0" + +opener@^1.5.2: + version "1.5.2" + resolved "https://registry.yarnpkg.com/opener/-/opener-1.5.2.tgz#5d37e1f35077b9dcac4301372271afdeb2a13598" + integrity sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A== + +optionator@^0.8.1: + version "0.8.3" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.3.tgz#84fa1d036fe9d3c7e21d99884b601167ec8fb495" + integrity sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA== + dependencies: + deep-is "~0.1.3" + fast-levenshtein "~2.0.6" + levn "~0.3.0" + prelude-ls "~1.1.2" + type-check "~0.3.2" + word-wrap "~1.2.3" + +ora@^5.1.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/ora/-/ora-5.2.0.tgz#de10bfd2d15514384af45f3fa9d9b1aaf344fda1" + integrity sha512-+wG2v8TUU8EgzPHun1k/n45pXquQ9fHnbXVetl9rRgO6kjZszGGbraF3XPTIdgeA+s1lbRjSEftAnyT0w8ZMvQ== + dependencies: + bl "^4.0.3" + chalk "^4.1.0" + cli-cursor "^3.1.0" + cli-spinners "^2.5.0" + is-interactive "^1.0.0" + log-symbols "^4.0.0" + strip-ansi "^6.0.0" + wcwidth "^1.0.1" + +original@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/original/-/original-1.0.2.tgz#e442a61cffe1c5fd20a65f3261c26663b303f25f" + integrity sha512-hyBVl6iqqUOJ8FqRe+l/gS8H+kKYjrEndd5Pm1MfBtsEKA038HkkdbAl/72EAXGyonD/PFsvmVG+EvcIpliMBg== + dependencies: + url-parse "^1.4.3" + +os-tmpdir@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" + integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= + +p-cancelable@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-1.1.0.tgz#d078d15a3af409220c886f1d9a0ca2e441ab26cc" + integrity sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw== + +p-limit@3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.0.2.tgz#1664e010af3cadc681baafd3e2a437be7b0fb5fe" + integrity sha512-iwqZSOoWIW+Ew4kAGUlN16J4M7OB3ysMLSZtnhmqx7njIHFPlxWBX8xo3lVTyFVq6mI/lL9qt2IsN1sHwaxJkg== + dependencies: + p-try "^2.0.0" + +p-limit@3.1.0, p-limit@^3.0.2, p-limit@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" + integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== + dependencies: + yocto-queue "^0.1.0" + +p-limit@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" + integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== + dependencies: + p-try "^2.0.0" + +p-locate@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07" + integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A== + dependencies: + p-limit "^2.2.0" + +p-locate@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" + integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== + dependencies: + p-limit "^3.0.2" + +p-map@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/p-map/-/p-map-2.1.0.tgz#310928feef9c9ecc65b68b17693018a665cea175" + integrity sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw== + +p-try@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" + integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== + +package-json@^6.3.0: + version "6.5.0" + resolved "https://registry.yarnpkg.com/package-json/-/package-json-6.5.0.tgz#6feedaca35e75725876d0b0e64974697fed145b0" + integrity sha512-k3bdm2n25tkyxcjSKzB5x8kfVxlMdgsbPr0GkZcwHsLpba6cBjqCt1KlcChKEvxHIcTB1FVMuwoijZ26xex5MQ== + dependencies: + got "^9.6.0" + registry-auth-token "^4.0.0" + registry-url "^5.0.0" + semver "^6.2.0" + +param-case@3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/param-case/-/param-case-3.0.3.tgz#4be41f8399eff621c56eebb829a5e451d9801238" + integrity sha512-VWBVyimc1+QrzappRs7waeN2YmoZFCGXWASRYX1/rGHtXqEcrGEIDm+jqIwFa2fRXNgQEwrxaYuIrX0WcAguTA== + dependencies: + dot-case "^3.0.3" + tslib "^1.10.0" + +parent-module@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" + integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== + dependencies: + callsites "^3.0.0" + +parse-asn1@^5.0.0, parse-asn1@^5.1.5: + version "5.1.6" + resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.1.6.tgz#385080a3ec13cb62a62d39409cb3e88844cdaed4" + integrity sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw== + dependencies: + asn1.js "^5.2.0" + browserify-aes "^1.0.0" + evp_bytestokey "^1.0.0" + pbkdf2 "^3.0.3" + safe-buffer "^5.1.1" + +parse-filepath@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/parse-filepath/-/parse-filepath-1.0.2.tgz#a632127f53aaf3d15876f5872f3ffac763d6c891" + integrity sha1-pjISf1Oq89FYdvWHLz/6x2PWyJE= + dependencies: + is-absolute "^1.0.0" + map-cache "^0.2.0" + path-root "^0.1.1" + +parse-json@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.1.0.tgz#f96088cdf24a8faa9aea9a009f2d9d942c999646" + integrity sha512-+mi/lmVVNKFNVyLXV31ERiy2CY5E1/F6QtJFEzoChPRwwngMNXRDQ9GJ5WdE2Z2P4AujsOi0/+2qHID68KwfIQ== + dependencies: + "@babel/code-frame" "^7.0.0" + error-ex "^1.3.1" + json-parse-even-better-errors "^2.3.0" + lines-and-columns "^1.1.6" + +parse-ms@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/parse-ms/-/parse-ms-2.1.0.tgz#348565a753d4391fa524029956b172cb7753097d" + integrity sha512-kHt7kzLoS9VBZfUsiKjv43mr91ea+U05EyKkEtqp7vNbHxmaVuEqN7XxeEVnGrMtYOAxGrDElSi96K7EgO1zCA== + +pascal-case@3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/pascal-case/-/pascal-case-3.1.1.tgz#5ac1975133ed619281e88920973d2cd1f279de5f" + integrity sha512-XIeHKqIrsquVTQL2crjq3NfJUxmdLasn3TYOU0VBM+UX2a6ztAWBlJQBePLGY7VHW8+2dRadeIPK5+KImwTxQA== + dependencies: + no-case "^3.0.3" + tslib "^1.10.0" + +pascal-case@^3.1.1, pascal-case@^3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/pascal-case/-/pascal-case-3.1.2.tgz#b48e0ef2b98e205e7c1dae747d0b1508237660eb" + integrity sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g== + dependencies: + no-case "^3.0.4" + tslib "^2.0.3" + +path-browserify@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-1.0.1.tgz#d98454a9c3753d5790860f16f68867b9e46be1fd" + integrity sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g== + +path-exists@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" + integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= + +path-parse@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c" + integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw== + +path-root-regex@^0.1.0: + version "0.1.2" + resolved "https://registry.yarnpkg.com/path-root-regex/-/path-root-regex-0.1.2.tgz#bfccdc8df5b12dc52c8b43ec38d18d72c04ba96d" + integrity sha1-v8zcjfWxLcUsi0PsONGNcsBLqW0= + +path-root@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/path-root/-/path-root-0.1.1.tgz#9a4a6814cac1c0cd73360a95f32083c8ea4745b7" + integrity sha1-mkpoFMrBwM1zNgqV8yCDyOpHRbc= + dependencies: + path-root-regex "^0.1.0" + +path-type@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" + integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== + +pbkdf2@^3.0.3: + version "3.1.1" + resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.1.1.tgz#cb8724b0fada984596856d1a6ebafd3584654b94" + integrity sha512-4Ejy1OPxi9f2tt1rRV7Go7zmfDQ+ZectEQz3VGUQhgq62HtIRPDyG/JtnwIxs6x3uNMwo2V7q1fMvKjb+Tnpqg== + dependencies: + create-hash "^1.1.2" + create-hmac "^1.1.4" + ripemd160 "^2.0.1" + safe-buffer "^5.0.1" + sha.js "^2.4.8" + +performance-now@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" + integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= + +picomatch@^2.0.4, picomatch@^2.0.5, picomatch@^2.2.1: + version "2.2.2" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.2.tgz#21f333e9b6b8eaff02468f5146ea406d345f4dad" + integrity sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg== + +pify@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231" + integrity sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g== + +pkg-dir@^4.1.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3" + integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ== + dependencies: + find-up "^4.0.0" + +pkg-dir@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-5.0.0.tgz#a02d6aebe6ba133a928f74aec20bafdfe6b8e760" + integrity sha512-NPE8TDbzl/3YQYY7CSS228s3g2ollTFnc+Qi3tqmqJp9Vg2ovUpixcJEo2HJScN2Ez+kEaal6y70c0ehqJBJeA== + dependencies: + find-up "^5.0.0" + +platform@1.3.6: + version "1.3.6" + resolved "https://registry.yarnpkg.com/platform/-/platform-1.3.6.tgz#48b4ce983164b209c2d45a107adb31f473a6e7a7" + integrity sha512-fnWVljUchTro6RiCFvCXBbNhJc2NijN7oIQxbwsyL0buWJPG85v81ehlHI9fXrJsMNgTofEoWIQeClKpgxFLrg== + +pluralize@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-8.0.0.tgz#1a6fa16a38d12a1901e0320fa017051c539ce3b1" + integrity sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA== + +pnp-webpack-plugin@1.6.4: + version "1.6.4" + resolved "https://registry.yarnpkg.com/pnp-webpack-plugin/-/pnp-webpack-plugin-1.6.4.tgz#c9711ac4dc48a685dabafc86f8b6dd9f8df84149" + integrity sha512-7Wjy+9E3WwLOEL30D+m8TSTF7qJJUJLONBnwQp0518siuMxUQUbgZwssaFX+QKlZkjHZcw/IpZCt/H0srrntSg== + dependencies: + ts-pnp "^1.1.6" + +postcss-attribute-case-insensitive@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-attribute-case-insensitive/-/postcss-attribute-case-insensitive-4.0.2.tgz#d93e46b504589e94ac7277b0463226c68041a880" + integrity sha512-clkFxk/9pcdb4Vkn0hAHq3YnxBQ2p0CGD1dy24jN+reBck+EWxMbxSUqN4Yj7t0w8csl87K6p0gxBe1utkJsYA== + dependencies: + postcss "^7.0.2" + postcss-selector-parser "^6.0.2" + +postcss-color-functional-notation@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/postcss-color-functional-notation/-/postcss-color-functional-notation-2.0.1.tgz#5efd37a88fbabeb00a2966d1e53d98ced93f74e0" + integrity sha512-ZBARCypjEDofW4P6IdPVTLhDNXPRn8T2s1zHbZidW6rPaaZvcnCS2soYFIQJrMZSxiePJ2XIYTlcb2ztr/eT2g== + dependencies: + postcss "^7.0.2" + postcss-values-parser "^2.0.0" + +postcss-color-gray@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/postcss-color-gray/-/postcss-color-gray-5.0.0.tgz#532a31eb909f8da898ceffe296fdc1f864be8547" + integrity sha512-q6BuRnAGKM/ZRpfDascZlIZPjvwsRye7UDNalqVz3s7GDxMtqPY6+Q871liNxsonUw8oC61OG+PSaysYpl1bnw== + dependencies: + "@csstools/convert-colors" "^1.4.0" + postcss "^7.0.5" + postcss-values-parser "^2.0.0" + +postcss-color-hex-alpha@^5.0.3: + version "5.0.3" + resolved "https://registry.yarnpkg.com/postcss-color-hex-alpha/-/postcss-color-hex-alpha-5.0.3.tgz#a8d9ca4c39d497c9661e374b9c51899ef0f87388" + integrity sha512-PF4GDel8q3kkreVXKLAGNpHKilXsZ6xuu+mOQMHWHLPNyjiUBOr75sp5ZKJfmv1MCus5/DWUGcK9hm6qHEnXYw== + dependencies: + postcss "^7.0.14" + postcss-values-parser "^2.0.1" + +postcss-color-mod-function@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/postcss-color-mod-function/-/postcss-color-mod-function-3.0.3.tgz#816ba145ac11cc3cb6baa905a75a49f903e4d31d" + integrity sha512-YP4VG+xufxaVtzV6ZmhEtc+/aTXH3d0JLpnYfxqTvwZPbJhWqp8bSY3nfNzNRFLgB4XSaBA82OE4VjOOKpCdVQ== + dependencies: + "@csstools/convert-colors" "^1.4.0" + postcss "^7.0.2" + postcss-values-parser "^2.0.0" + +postcss-color-rebeccapurple@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-color-rebeccapurple/-/postcss-color-rebeccapurple-4.0.1.tgz#c7a89be872bb74e45b1e3022bfe5748823e6de77" + integrity sha512-aAe3OhkS6qJXBbqzvZth2Au4V3KieR5sRQ4ptb2b2O8wgvB3SJBsdG+jsn2BZbbwekDG8nTfcCNKcSfe/lEy8g== + dependencies: + postcss "^7.0.2" + postcss-values-parser "^2.0.0" + +postcss-custom-media@^7.0.8: + version "7.0.8" + resolved "https://registry.yarnpkg.com/postcss-custom-media/-/postcss-custom-media-7.0.8.tgz#fffd13ffeffad73621be5f387076a28b00294e0c" + integrity sha512-c9s5iX0Ge15o00HKbuRuTqNndsJUbaXdiNsksnVH8H4gdc+zbLzr/UasOwNG6CTDpLFekVY4672eWdiiWu2GUg== + dependencies: + postcss "^7.0.14" + +postcss-custom-properties@^8.0.11: + version "8.0.11" + resolved "https://registry.yarnpkg.com/postcss-custom-properties/-/postcss-custom-properties-8.0.11.tgz#2d61772d6e92f22f5e0d52602df8fae46fa30d97" + integrity sha512-nm+o0eLdYqdnJ5abAJeXp4CEU1c1k+eB2yMCvhgzsds/e0umabFrN6HoTy/8Q4K5ilxERdl/JD1LO5ANoYBeMA== + dependencies: + postcss "^7.0.17" + postcss-values-parser "^2.0.1" + +postcss-custom-selectors@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/postcss-custom-selectors/-/postcss-custom-selectors-5.1.2.tgz#64858c6eb2ecff2fb41d0b28c9dd7b3db4de7fba" + integrity sha512-DSGDhqinCqXqlS4R7KGxL1OSycd1lydugJ1ky4iRXPHdBRiozyMHrdu0H3o7qNOCiZwySZTUI5MV0T8QhCLu+w== + dependencies: + postcss "^7.0.2" + postcss-selector-parser "^5.0.0-rc.3" + +postcss-dir-pseudo-class@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/postcss-dir-pseudo-class/-/postcss-dir-pseudo-class-5.0.0.tgz#6e3a4177d0edb3abcc85fdb6fbb1c26dabaeaba2" + integrity sha512-3pm4oq8HYWMZePJY+5ANriPs3P07q+LW6FAdTlkFH2XqDdP4HeeJYMOzn0HYLhRSjBO3fhiqSwwU9xEULSrPgw== + dependencies: + postcss "^7.0.2" + postcss-selector-parser "^5.0.0-rc.3" + +postcss-double-position-gradients@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/postcss-double-position-gradients/-/postcss-double-position-gradients-1.0.0.tgz#fc927d52fddc896cb3a2812ebc5df147e110522e" + integrity sha512-G+nV8EnQq25fOI8CH/B6krEohGWnF5+3A6H/+JEpOncu5dCnkS1QQ6+ct3Jkaepw1NGVqqOZH6lqrm244mCftA== + dependencies: + postcss "^7.0.5" + postcss-values-parser "^2.0.0" + +postcss-env-function@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/postcss-env-function/-/postcss-env-function-2.0.2.tgz#0f3e3d3c57f094a92c2baf4b6241f0b0da5365d7" + integrity sha512-rwac4BuZlITeUbiBq60h/xbLzXY43qOsIErngWa4l7Mt+RaSkT7QBjXVGTcBHupykkblHMDrBFh30zchYPaOUw== + dependencies: + postcss "^7.0.2" + postcss-values-parser "^2.0.0" + +postcss-flexbugs-fixes@^4.2.1: + version "4.2.1" + resolved "https://registry.yarnpkg.com/postcss-flexbugs-fixes/-/postcss-flexbugs-fixes-4.2.1.tgz#9218a65249f30897deab1033aced8578562a6690" + integrity sha512-9SiofaZ9CWpQWxOwRh1b/r85KD5y7GgvsNt1056k6OYLvWUun0czCvogfJgylC22uJTwW1KzY3Gz65NZRlvoiQ== + dependencies: + postcss "^7.0.26" + +postcss-focus-visible@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/postcss-focus-visible/-/postcss-focus-visible-4.0.0.tgz#477d107113ade6024b14128317ade2bd1e17046e" + integrity sha512-Z5CkWBw0+idJHSV6+Bgf2peDOFf/x4o+vX/pwcNYrWpXFrSfTkQ3JQ1ojrq9yS+upnAlNRHeg8uEwFTgorjI8g== + dependencies: + postcss "^7.0.2" + +postcss-focus-within@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/postcss-focus-within/-/postcss-focus-within-3.0.0.tgz#763b8788596cee9b874c999201cdde80659ef680" + integrity sha512-W0APui8jQeBKbCGZudW37EeMCjDeVxKgiYfIIEo8Bdh5SpB9sxds/Iq8SEuzS0Q4YFOlG7EPFulbbxujpkrV2w== + dependencies: + postcss "^7.0.2" + +postcss-font-variant@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-font-variant/-/postcss-font-variant-4.0.1.tgz#42d4c0ab30894f60f98b17561eb5c0321f502641" + integrity sha512-I3ADQSTNtLTTd8uxZhtSOrTCQ9G4qUVKPjHiDk0bV75QSxXjVWiJVJ2VLdspGUi9fbW9BcjKJoRvxAH1pckqmA== + dependencies: + postcss "^7.0.2" + +postcss-functions@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/postcss-functions/-/postcss-functions-3.0.0.tgz#0e94d01444700a481de20de4d55fb2640564250e" + integrity sha1-DpTQFERwCkgd4g3k1V+yZAVkJQ4= + dependencies: + glob "^7.1.2" + object-assign "^4.1.1" + postcss "^6.0.9" + postcss-value-parser "^3.3.0" + +postcss-gap-properties@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/postcss-gap-properties/-/postcss-gap-properties-2.0.0.tgz#431c192ab3ed96a3c3d09f2ff615960f902c1715" + integrity sha512-QZSqDaMgXCHuHTEzMsS2KfVDOq7ZFiknSpkrPJY6jmxbugUPTuSzs/vuE5I3zv0WAS+3vhrlqhijiprnuQfzmg== + dependencies: + postcss "^7.0.2" + +postcss-image-set-function@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/postcss-image-set-function/-/postcss-image-set-function-3.0.1.tgz#28920a2f29945bed4c3198d7df6496d410d3f288" + integrity sha512-oPTcFFip5LZy8Y/whto91L9xdRHCWEMs3e1MdJxhgt4jy2WYXfhkng59fH5qLXSCPN8k4n94p1Czrfe5IOkKUw== + dependencies: + postcss "^7.0.2" + postcss-values-parser "^2.0.0" + +postcss-initial@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/postcss-initial/-/postcss-initial-3.0.2.tgz#f018563694b3c16ae8eaabe3c585ac6319637b2d" + integrity sha512-ugA2wKonC0xeNHgirR4D3VWHs2JcU08WAi1KFLVcnb7IN89phID6Qtg2RIctWbnvp1TM2BOmDtX8GGLCKdR8YA== + dependencies: + lodash.template "^4.5.0" + postcss "^7.0.2" + +postcss-js@^2.0.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/postcss-js/-/postcss-js-2.0.3.tgz#a96f0f23ff3d08cec7dc5b11bf11c5f8077cdab9" + integrity sha512-zS59pAk3deu6dVHyrGqmC3oDXBdNdajk4k1RyxeVXCrcEDBUBHoIhE4QTsmhxgzXxsaqFDAkUZfmMa5f/N/79w== + dependencies: + camelcase-css "^2.0.1" + postcss "^7.0.18" + +postcss-lab-function@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/postcss-lab-function/-/postcss-lab-function-2.0.1.tgz#bb51a6856cd12289ab4ae20db1e3821ef13d7d2e" + integrity sha512-whLy1IeZKY+3fYdqQFuDBf8Auw+qFuVnChWjmxm/UhHWqNHZx+B99EwxTvGYmUBqe3Fjxs4L1BoZTJmPu6usVg== + dependencies: + "@csstools/convert-colors" "^1.4.0" + postcss "^7.0.2" + postcss-values-parser "^2.0.0" + +postcss-logical@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/postcss-logical/-/postcss-logical-3.0.0.tgz#2495d0f8b82e9f262725f75f9401b34e7b45d5b5" + integrity sha512-1SUKdJc2vuMOmeItqGuNaC+N8MzBWFWEkAnRnLpFYj1tGGa7NqyVBujfRtgNa2gXR+6RkGUiB2O5Vmh7E2RmiA== + dependencies: + postcss "^7.0.2" + +postcss-media-minmax@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/postcss-media-minmax/-/postcss-media-minmax-4.0.0.tgz#b75bb6cbc217c8ac49433e12f22048814a4f5ed5" + integrity sha512-fo9moya6qyxsjbFAYl97qKO9gyre3qvbMnkOZeZwlsW6XYFsvs2DMGDlchVLfAd8LHPZDxivu/+qW2SMQeTHBw== + dependencies: + postcss "^7.0.2" + +postcss-modules-extract-imports@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-2.0.0.tgz#818719a1ae1da325f9832446b01136eeb493cd7e" + integrity sha512-LaYLDNS4SG8Q5WAWqIJgdHPJrDDr/Lv775rMBFUbgjTz6j34lUznACHcdRWroPvXANP2Vj7yNK57vp9eFqzLWQ== + dependencies: + postcss "^7.0.5" + +postcss-modules-local-by-default@^3.0.2, postcss-modules-local-by-default@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-3.0.3.tgz#bb14e0cc78279d504dbdcbfd7e0ca28993ffbbb0" + integrity sha512-e3xDq+LotiGesympRlKNgaJ0PCzoUIdpH0dj47iWAui/kyTgh3CiAr1qP54uodmJhl6p9rN6BoNcdEDVJx9RDw== + dependencies: + icss-utils "^4.1.1" + postcss "^7.0.32" + postcss-selector-parser "^6.0.2" + postcss-value-parser "^4.1.0" + +postcss-modules-scope@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/postcss-modules-scope/-/postcss-modules-scope-2.2.0.tgz#385cae013cc7743f5a7d7602d1073a89eaae62ee" + integrity sha512-YyEgsTMRpNd+HmyC7H/mh3y+MeFWevy7V1evVhJWewmMbjDHIbZbOXICC2y+m1xI1UVfIT1HMW/O04Hxyu9oXQ== + dependencies: + postcss "^7.0.6" + postcss-selector-parser "^6.0.0" + +postcss-modules-values@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/postcss-modules-values/-/postcss-modules-values-3.0.0.tgz#5b5000d6ebae29b4255301b4a3a54574423e7f10" + integrity sha512-1//E5jCBrZ9DmRX+zCtmQtRSV6PV42Ix7Bzj9GbwJceduuf7IqP8MgeTXuRDHOWj2m0VzZD5+roFWDuU8RQjcg== + dependencies: + icss-utils "^4.0.0" + postcss "^7.0.6" + +postcss-modules@^3.2.2: + version "3.2.2" + resolved "https://registry.yarnpkg.com/postcss-modules/-/postcss-modules-3.2.2.tgz#ee390de0f9f18e761e1778dfb9be26685c02c51f" + integrity sha512-JQ8IAqHELxC0N6tyCg2UF40pACY5oiL6UpiqqcIFRWqgDYO8B0jnxzoQ0EOpPrWXvcpu6BSbQU/3vSiq7w8Nhw== + dependencies: + generic-names "^2.0.1" + icss-replace-symbols "^1.1.0" + lodash.camelcase "^4.3.0" + postcss "^7.0.32" + postcss-modules-extract-imports "^2.0.0" + postcss-modules-local-by-default "^3.0.2" + postcss-modules-scope "^2.2.0" + postcss-modules-values "^3.0.0" + string-hash "^1.1.1" + +postcss-nested@^4.1.1: + version "4.2.3" + resolved "https://registry.yarnpkg.com/postcss-nested/-/postcss-nested-4.2.3.tgz#c6f255b0a720549776d220d00c4b70cd244136f6" + integrity sha512-rOv0W1HquRCamWy2kFl3QazJMMe1ku6rCFoAAH+9AcxdbpDeBr6k968MLWuLjvjMcGEip01ak09hKOEgpK9hvw== + dependencies: + postcss "^7.0.32" + postcss-selector-parser "^6.0.2" + +postcss-nesting@^7.0.0, postcss-nesting@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/postcss-nesting/-/postcss-nesting-7.0.1.tgz#b50ad7b7f0173e5b5e3880c3501344703e04c052" + integrity sha512-FrorPb0H3nuVq0Sff7W2rnc3SmIcruVC6YwpcS+k687VxyxO33iE1amna7wHuRVzM8vfiYofXSBHNAZ3QhLvYg== + dependencies: + postcss "^7.0.2" + +postcss-overflow-shorthand@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/postcss-overflow-shorthand/-/postcss-overflow-shorthand-2.0.0.tgz#31ecf350e9c6f6ddc250a78f0c3e111f32dd4c30" + integrity sha512-aK0fHc9CBNx8jbzMYhshZcEv8LtYnBIRYQD5i7w/K/wS9c2+0NSR6B3OVMu5y0hBHYLcMGjfU+dmWYNKH0I85g== + dependencies: + postcss "^7.0.2" + +postcss-page-break@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/postcss-page-break/-/postcss-page-break-2.0.0.tgz#add52d0e0a528cabe6afee8b46e2abb277df46bf" + integrity sha512-tkpTSrLpfLfD9HvgOlJuigLuk39wVTbbd8RKcy8/ugV2bNBUW3xU+AIqyxhDrQr1VUj1RmyJrBn1YWrqUm9zAQ== + dependencies: + postcss "^7.0.2" + +postcss-place@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-place/-/postcss-place-4.0.1.tgz#e9f39d33d2dc584e46ee1db45adb77ca9d1dcc62" + integrity sha512-Zb6byCSLkgRKLODj/5mQugyuj9bvAAw9LqJJjgwz5cYryGeXfFZfSXoP1UfveccFmeq0b/2xxwcTEVScnqGxBg== + dependencies: + postcss "^7.0.2" + postcss-values-parser "^2.0.0" + +postcss-preset-env@^6.7.0: + version "6.7.0" + resolved "https://registry.yarnpkg.com/postcss-preset-env/-/postcss-preset-env-6.7.0.tgz#c34ddacf8f902383b35ad1e030f178f4cdf118a5" + integrity sha512-eU4/K5xzSFwUFJ8hTdTQzo2RBLbDVt83QZrAvI07TULOkmyQlnYlpwep+2yIK+K+0KlZO4BvFcleOCCcUtwchg== + dependencies: + autoprefixer "^9.6.1" + browserslist "^4.6.4" + caniuse-lite "^1.0.30000981" + css-blank-pseudo "^0.1.4" + css-has-pseudo "^0.10.0" + css-prefers-color-scheme "^3.1.1" + cssdb "^4.4.0" + postcss "^7.0.17" + postcss-attribute-case-insensitive "^4.0.1" + postcss-color-functional-notation "^2.0.1" + postcss-color-gray "^5.0.0" + postcss-color-hex-alpha "^5.0.3" + postcss-color-mod-function "^3.0.3" + postcss-color-rebeccapurple "^4.0.1" + postcss-custom-media "^7.0.8" + postcss-custom-properties "^8.0.11" + postcss-custom-selectors "^5.1.2" + postcss-dir-pseudo-class "^5.0.0" + postcss-double-position-gradients "^1.0.0" + postcss-env-function "^2.0.2" + postcss-focus-visible "^4.0.0" + postcss-focus-within "^3.0.0" + postcss-font-variant "^4.0.0" + postcss-gap-properties "^2.0.0" + postcss-image-set-function "^3.0.1" + postcss-initial "^3.0.0" + postcss-lab-function "^2.0.1" + postcss-logical "^3.0.0" + postcss-media-minmax "^4.0.0" + postcss-nesting "^7.0.0" + postcss-overflow-shorthand "^2.0.0" + postcss-page-break "^2.0.0" + postcss-place "^4.0.1" + postcss-pseudo-class-any-link "^6.0.0" + postcss-replace-overflow-wrap "^3.0.0" + postcss-selector-matches "^4.0.0" + postcss-selector-not "^4.0.0" + +postcss-pseudo-class-any-link@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/postcss-pseudo-class-any-link/-/postcss-pseudo-class-any-link-6.0.0.tgz#2ed3eed393b3702879dec4a87032b210daeb04d1" + integrity sha512-lgXW9sYJdLqtmw23otOzrtbDXofUdfYzNm4PIpNE322/swES3VU9XlXHeJS46zT2onFO7V1QFdD4Q9LiZj8mew== + dependencies: + postcss "^7.0.2" + postcss-selector-parser "^5.0.0-rc.3" + +postcss-replace-overflow-wrap@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/postcss-replace-overflow-wrap/-/postcss-replace-overflow-wrap-3.0.0.tgz#61b360ffdaedca84c7c918d2b0f0d0ea559ab01c" + integrity sha512-2T5hcEHArDT6X9+9dVSPQdo7QHzG4XKclFT8rU5TzJPDN7RIRTbO9c4drUISOVemLj03aezStHCR2AIcr8XLpw== + dependencies: + postcss "^7.0.2" + +postcss-safe-parser@4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-safe-parser/-/postcss-safe-parser-4.0.2.tgz#a6d4e48f0f37d9f7c11b2a581bf00f8ba4870b96" + integrity sha512-Uw6ekxSWNLCPesSv/cmqf2bY/77z11O7jZGPax3ycZMFU/oi2DMH9i89AdHc1tRwFg/arFoEwX0IS3LCUxJh1g== + dependencies: + postcss "^7.0.26" + +postcss-selector-matches@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/postcss-selector-matches/-/postcss-selector-matches-4.0.0.tgz#71c8248f917ba2cc93037c9637ee09c64436fcff" + integrity sha512-LgsHwQR/EsRYSqlwdGzeaPKVT0Ml7LAT6E75T8W8xLJY62CE4S/l03BWIt3jT8Taq22kXP08s2SfTSzaraoPww== + dependencies: + balanced-match "^1.0.0" + postcss "^7.0.2" + +postcss-selector-not@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-selector-not/-/postcss-selector-not-4.0.1.tgz#263016eef1cf219e0ade9a913780fc1f48204cbf" + integrity sha512-YolvBgInEK5/79C+bdFMyzqTg6pkYqDbzZIST/PDMqa/o3qtXenD05apBG2jLgT0/BQ77d4U2UK12jWpilqMAQ== + dependencies: + balanced-match "^1.0.0" + postcss "^7.0.2" + +postcss-selector-parser@^5.0.0-rc.3, postcss-selector-parser@^5.0.0-rc.4: + version "5.0.0" + resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-5.0.0.tgz#249044356697b33b64f1a8f7c80922dddee7195c" + integrity sha512-w+zLE5Jhg6Liz8+rQOWEAwtwkyqpfnmsinXjXg6cY7YIONZZtgvE0v2O0uhQBs0peNomOJwWRKt6JBfTdTd3OQ== + dependencies: + cssesc "^2.0.0" + indexes-of "^1.0.1" + uniq "^1.0.1" + +postcss-selector-parser@^6.0.0, postcss-selector-parser@^6.0.2, postcss-selector-parser@^6.0.4: + version "6.0.4" + resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.4.tgz#56075a1380a04604c38b063ea7767a129af5c2b3" + integrity sha512-gjMeXBempyInaBqpp8gODmwZ52WaYsVOsfr4L4lDQ7n3ncD6mEyySiDtgzCT+NYC0mmeOLvtsF8iaEf0YT6dBw== + dependencies: + cssesc "^3.0.0" + indexes-of "^1.0.1" + uniq "^1.0.1" + util-deprecate "^1.0.2" + +postcss-value-parser@^3.3.0: + version "3.3.1" + resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz#9ff822547e2893213cf1c30efa51ac5fd1ba8281" + integrity sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ== + +postcss-value-parser@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz#443f6a20ced6481a2bda4fa8532a6e55d789a2cb" + integrity sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ== + +postcss-values-parser@^1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/postcss-values-parser/-/postcss-values-parser-1.5.0.tgz#5d9fa63e2bcb0179ce48f3235303765eb89f3047" + integrity sha512-3M3p+2gMp0AH3da530TlX8kiO1nxdTnc3C6vr8dMxRLIlh8UYkz0/wcwptSXjhtx2Fr0TySI7a+BHDQ8NL7LaQ== + dependencies: + flatten "^1.0.2" + indexes-of "^1.0.1" + uniq "^1.0.1" + +postcss-values-parser@^2.0.0, postcss-values-parser@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/postcss-values-parser/-/postcss-values-parser-2.0.1.tgz#da8b472d901da1e205b47bdc98637b9e9e550e5f" + integrity sha512-2tLuBsA6P4rYTNKCXYG/71C7j1pU6pK503suYOmn4xYrQIzW+opD+7FAFNuGSdZC/3Qfy334QbeMu7MEb8gOxg== + dependencies: + flatten "^1.0.2" + indexes-of "^1.0.1" + uniq "^1.0.1" + +postcss@7.0.21: + version "7.0.21" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.21.tgz#06bb07824c19c2021c5d056d5b10c35b989f7e17" + integrity sha512-uIFtJElxJo29QC753JzhidoAhvp/e/Exezkdhfmt8AymWT6/5B7W1WmponYWkHk2eg6sONyTch0A3nkMPun3SQ== + dependencies: + chalk "^2.4.2" + source-map "^0.6.1" + supports-color "^6.1.0" + +postcss@7.0.32: + version "7.0.32" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.32.tgz#4310d6ee347053da3433db2be492883d62cec59d" + integrity sha512-03eXong5NLnNCD05xscnGKGDZ98CyzoqPSMjOe6SuoQY7Z2hIj0Ld1g/O/UQRuOle2aRtiIRDg9tDcTGAkLfKw== + dependencies: + chalk "^2.4.2" + source-map "^0.6.1" + supports-color "^6.1.0" + +postcss@8.1.7: + version "8.1.7" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.1.7.tgz#ff6a82691bd861f3354fd9b17b2332f88171233f" + integrity sha512-llCQW1Pz4MOPwbZLmOddGM9eIJ8Bh7SZ2Oj5sxZva77uVaotYDsYTch1WBTNu7fUY0fpWp0fdt7uW40D4sRiiQ== + dependencies: + colorette "^1.2.1" + line-column "^1.0.2" + nanoid "^3.1.16" + source-map "^0.6.1" + +postcss@^6.0.9: + version "6.0.23" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-6.0.23.tgz#61c82cc328ac60e677645f979054eb98bc0e3324" + integrity sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag== + dependencies: + chalk "^2.4.1" + source-map "^0.6.1" + supports-color "^5.4.0" + +postcss@^7.0.11, postcss@^7.0.14, postcss@^7.0.17, postcss@^7.0.18, postcss@^7.0.2, postcss@^7.0.26, postcss@^7.0.32, postcss@^7.0.5, postcss@^7.0.6: + version "7.0.35" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.35.tgz#d2be00b998f7f211d8a276974079f2e92b970e24" + integrity sha512-3QT8bBJeX/S5zKTTjTCIjRF3If4avAT6kqxcASlTWEtAFCb9NH0OUxNDfgZSWdP5fJnBYCMEWkIFfWeugjzYMg== + dependencies: + chalk "^2.4.2" + source-map "^0.6.1" + supports-color "^6.1.0" + +prebuild-install@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/prebuild-install/-/prebuild-install-6.0.0.tgz#669022bcde57c710a869e39c5ca6bf9cd207f316" + integrity sha512-h2ZJ1PXHKWZpp1caLw0oX9sagVpL2YTk+ZwInQbQ3QqNd4J03O6MpFNmMTJlkfgPENWqe5kP0WjQLqz5OjLfsw== + dependencies: + detect-libc "^1.0.3" + expand-template "^2.0.3" + github-from-package "0.0.0" + minimist "^1.2.3" + mkdirp-classic "^0.5.3" + napi-build-utils "^1.0.1" + node-abi "^2.7.0" + noop-logger "^0.1.1" + npmlog "^4.0.1" + pump "^3.0.0" + rc "^1.2.7" + simple-get "^3.0.3" + tar-fs "^2.0.0" + tunnel-agent "^0.6.0" + which-pm-runs "^1.0.0" + +precinct@^6.3.1: + version "6.3.1" + resolved "https://registry.yarnpkg.com/precinct/-/precinct-6.3.1.tgz#8ad735a8afdfc48b56ed39c9ad3bf999b6b928dc" + integrity sha512-JAwyLCgTylWminoD7V0VJwMElWmwrVSR6r9HaPWCoswkB4iFzX7aNtO7VBfAVPy+NhmjKb8IF8UmlWJXzUkOIQ== + dependencies: + commander "^2.20.3" + debug "^4.1.1" + detective-amd "^3.0.0" + detective-cjs "^3.1.1" + detective-es6 "^2.1.0" + detective-less "^1.0.2" + detective-postcss "^3.0.1" + detective-sass "^3.0.1" + detective-scss "^2.0.1" + detective-stylus "^1.0.0" + detective-typescript "^5.8.0" + module-definition "^3.3.0" + node-source-walk "^4.2.0" + +prelude-ls@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" + integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ= + +prepend-http@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-2.0.0.tgz#e92434bfa5ea8c19f41cdfd401d741a3c819d897" + integrity sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc= + +prettier@^2.0.5, prettier@^2.1.2: + version "2.2.1" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.2.1.tgz#795a1a78dd52f073da0cd42b21f9c91381923ff5" + integrity sha512-PqyhM2yCjg/oKkFPtTGUojv7gnZAoG80ttl45O6x2Ug/rMJw4wcc9k6aaf2hibP7BGVCCM33gZoGjyvt9mm16Q== + +pretty-hrtime@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz#b7e3ea42435a4c9b2759d99e0f201eb195802ee1" + integrity sha1-t+PqQkNaTJsnWdmeDyAesZWALuE= + +pretty-ms@^7.0.0: + version "7.0.1" + resolved "https://registry.yarnpkg.com/pretty-ms/-/pretty-ms-7.0.1.tgz#7d903eaab281f7d8e03c66f867e239dc32fb73e8" + integrity sha512-973driJZvxiGOQ5ONsFhOF/DtzPMOMtgC11kCpUrPGMTgqp2q/1gwzCquocrN33is0VZ5GFHXZYMM9l6h67v2Q== + dependencies: + parse-ms "^2.1.0" + +process-nextick-args@~2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" + integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== + +process@0.11.10: + version "0.11.10" + resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" + integrity sha1-czIwDoQBYb2j5podHZGn1LwW8YI= + +promise@^7.1.1: + version "7.3.1" + resolved "https://registry.yarnpkg.com/promise/-/promise-7.3.1.tgz#064b72602b18f90f29192b8b1bc418ffd1ebd3bf" + integrity sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg== + dependencies: + asap "~2.0.3" + +prop-types@15.7.2, prop-types@^15.6.2: + version "15.7.2" + resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5" + integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ== + dependencies: + loose-envify "^1.4.0" + object-assign "^4.1.1" + react-is "^16.8.1" + +prr@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476" + integrity sha1-0/wRS6BplaRexok/SEzrHXj19HY= + +psl@^1.1.28: + version "1.8.0" + resolved "https://registry.yarnpkg.com/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24" + integrity sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ== + +public-encrypt@^4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/public-encrypt/-/public-encrypt-4.0.3.tgz#4fcc9d77a07e48ba7527e7cbe0de33d0701331e0" + integrity sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q== + dependencies: + bn.js "^4.1.0" + browserify-rsa "^4.0.0" + create-hash "^1.1.0" + parse-asn1 "^5.0.0" + randombytes "^2.0.1" + safe-buffer "^5.1.2" + +pump@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" + integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + +punycode@^2.1.0, punycode@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" + integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== + +purgecss@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/purgecss/-/purgecss-2.3.0.tgz#5327587abf5795e6541517af8b190a6fb5488bb3" + integrity sha512-BE5CROfVGsx2XIhxGuZAT7rTH9lLeQx/6M0P7DTXQH4IUc3BBzs9JUzt4yzGf3JrH9enkeq6YJBe9CTtkm1WmQ== + dependencies: + commander "^5.0.0" + glob "^7.0.0" + postcss "7.0.32" + postcss-selector-parser "^6.0.2" + +qs@~6.5.2: + version "6.5.2" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" + integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA== + +querystring@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" + integrity sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA= + +querystringify@^2.1.1: + version "2.2.0" + resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-2.2.0.tgz#3345941b4153cb9d082d8eee4cda2016a9aef7f6" + integrity sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ== + +quick-lru@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-4.0.1.tgz#5b8878f113a58217848c6482026c73e1ba57727f" + integrity sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g== + +randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5, randombytes@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" + integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== + dependencies: + safe-buffer "^5.1.0" + +randomfill@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/randomfill/-/randomfill-1.0.4.tgz#c92196fc86ab42be983f1bf31778224931d61458" + integrity sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw== + dependencies: + randombytes "^2.0.5" + safe-buffer "^5.1.0" + +raw-body@2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.4.1.tgz#30ac82f98bb5ae8c152e67149dac8d55153b168c" + integrity sha512-9WmIKF6mkvA0SLmA2Knm9+qj89e+j1zqgyn8aXGd7+nAduPoqgI9lO57SAZNn/Byzo5P7JhXTyg9PzaJbH73bA== + dependencies: + bytes "3.1.0" + http-errors "1.7.3" + iconv-lite "0.4.24" + unpipe "1.0.0" + +rc@^1.2.7, rc@^1.2.8: + version "1.2.8" + resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" + integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw== + dependencies: + deep-extend "^0.6.0" + ini "~1.3.0" + minimist "^1.2.0" + strip-json-comments "~2.0.1" + +react-dom@^16.14.0: + version "16.14.0" + resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.14.0.tgz#7ad838ec29a777fb3c75c3a190f661cf92ab8b89" + integrity sha512-1gCeQXDLoIqMgqD3IO2Ah9bnf0w9kzhwN5q4FGnHZ67hBm9yePzB5JJAIQCc8x3pFnNlwFq4RidZggNAAkzWWw== + dependencies: + loose-envify "^1.1.0" + object-assign "^4.1.1" + prop-types "^15.6.2" + scheduler "^0.19.1" + +react-is@16.13.1, react-is@^16.8.1: + version "16.13.1" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" + integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== + +react-merge-refs@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/react-merge-refs/-/react-merge-refs-1.1.0.tgz#73d88b892c6c68cbb7a66e0800faa374f4c38b06" + integrity sha512-alTKsjEL0dKH/ru1Iyn7vliS2QRcBp9zZPGoWxUOvRGWPUYgjo+V01is7p04It6KhgrzhJGnIj9GgX8W4bZoCQ== + +react-refresh@0.8.3: + version "0.8.3" + resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.8.3.tgz#721d4657672d400c5e3c75d063c4a85fb2d5d68f" + integrity sha512-X8jZHc7nCMjaCqoU+V2I0cOhNW+QMBwSUkeXnTi8IPe6zaRWfn60ZzvFDZqWPfmSJfjub7dDW1SP0jaHWLu/hg== + +react-ticker@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/react-ticker/-/react-ticker-1.2.2.tgz#12cda5ff8266c6fe90ffcd8c58e12ba1596ddf24" + integrity sha512-PXUujoPJvajxwOfosuuujlrBUrjgGp4FB4haWFOI25ujhMppW4SuLkiOdQ9AylrWN3yTHWdk2kbQWe3n9SjFGA== + +react@^16.14.0: + version "16.14.0" + resolved "https://registry.yarnpkg.com/react/-/react-16.14.0.tgz#94d776ddd0aaa37da3eda8fc5b6b18a4c9a3114d" + integrity sha512-0X2CImDkJGApiAlcf0ODKIneSwBPhqJawOa5wCtKbu7ZECrmS26NvtSILynQ66cgkT/RJ4LidJOc3bUESwmU8g== + dependencies: + loose-envify "^1.1.0" + object-assign "^4.1.1" + prop-types "^15.6.2" + +read-pkg-up@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-7.0.1.tgz#f3a6135758459733ae2b95638056e1854e7ef507" + integrity sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg== + dependencies: + find-up "^4.1.0" + read-pkg "^5.2.0" + type-fest "^0.8.1" + +read-pkg@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-5.2.0.tgz#7bf295438ca5a33e56cd30e053b34ee7250c93cc" + integrity sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg== + dependencies: + "@types/normalize-package-data" "^2.4.0" + normalize-package-data "^2.5.0" + parse-json "^5.0.0" + type-fest "^0.6.0" + +readable-stream@^2.0.1, readable-stream@^2.0.6: + version "2.3.7" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" + integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.3" + isarray "~1.0.0" + process-nextick-args "~2.0.0" + safe-buffer "~5.1.1" + string_decoder "~1.1.1" + util-deprecate "~1.0.1" + +readable-stream@^3.1.1, readable-stream@^3.4.0, readable-stream@^3.5.0, readable-stream@^3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" + integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== + dependencies: + inherits "^2.0.3" + string_decoder "^1.1.1" + util-deprecate "^1.0.1" + +readdirp@~3.5.0: + version "3.5.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.5.0.tgz#9ba74c019b15d365278d2e91bb8c48d7b4d42c9e" + integrity sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ== + dependencies: + picomatch "^2.2.1" + +redent@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/redent/-/redent-3.0.0.tgz#e557b7998316bb53c9f1f56fa626352c6963059f" + integrity sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg== + dependencies: + indent-string "^4.0.0" + strip-indent "^3.0.0" + +reduce-css-calc@^2.1.6: + version "2.1.8" + resolved "https://registry.yarnpkg.com/reduce-css-calc/-/reduce-css-calc-2.1.8.tgz#7ef8761a28d614980dc0c982f772c93f7a99de03" + integrity sha512-8liAVezDmUcH+tdzoEGrhfbGcP7nOV4NkGE3a74+qqvE7nt9i4sKLGBuZNOnpI4WiGksiNPklZxva80061QiPg== + dependencies: + css-unit-converter "^1.1.1" + postcss-value-parser "^3.3.0" + +regenerator-runtime@^0.13.4: + version "0.13.7" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz#cac2dacc8a1ea675feaabaeb8ae833898ae46f55" + integrity sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew== + +regex-parser@^2.2.11: + version "2.2.11" + resolved "https://registry.yarnpkg.com/regex-parser/-/regex-parser-2.2.11.tgz#3b37ec9049e19479806e878cabe7c1ca83ccfe58" + integrity sha512-jbD/FT0+9MBU2XAZluI7w2OBs1RBi6p9M83nkoZayQXXU9e8Robt69FcZc7wU4eJD/YFTjn1JdCk3rbMJajz8Q== + +registry-auth-token@^4.0.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/registry-auth-token/-/registry-auth-token-4.2.1.tgz#6d7b4006441918972ccd5fedcd41dc322c79b250" + integrity sha512-6gkSb4U6aWJB4SF2ZvLb76yCBjcvufXBqvvEx1HbmKPkutswjW1xNVRY0+daljIYRbogN7O0etYSlbiaEQyMyw== + dependencies: + rc "^1.2.8" + +registry-url@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/registry-url/-/registry-url-5.1.0.tgz#e98334b50d5434b81136b44ec638d9c2009c5009" + integrity sha512-8acYXXTI0AkQv6RAOjE3vOaIXZkT9wo4LOFbBKYQEEnnMNBpKqdUrI6S4NT0KPIo/WVvJ5tE/X5LF/TQUf0ekw== + dependencies: + rc "^1.2.8" + +relay-compiler@10.1.0: + version "10.1.0" + resolved "https://registry.yarnpkg.com/relay-compiler/-/relay-compiler-10.1.0.tgz#fb4672cdbe9b54869a3a79759edd8c2d91609cbe" + integrity sha512-HPqc3N3tNgEgUH5+lTr5lnLbgnsZMt+MRiyS0uAVNhuPY2It0X1ZJG+9qdA3L9IqKFUNwVn6zTO7RArjMZbARQ== + dependencies: + "@babel/core" "^7.0.0" + "@babel/generator" "^7.5.0" + "@babel/parser" "^7.0.0" + "@babel/runtime" "^7.0.0" + "@babel/traverse" "^7.0.0" + "@babel/types" "^7.0.0" + babel-preset-fbjs "^3.3.0" + chalk "^4.0.0" + fb-watchman "^2.0.0" + fbjs "^3.0.0" + glob "^7.1.1" + immutable "~3.7.6" + nullthrows "^1.1.1" + relay-runtime "10.1.0" + signedsource "^1.0.0" + yargs "^15.3.1" + +relay-runtime@10.1.0: + version "10.1.0" + resolved "https://registry.yarnpkg.com/relay-runtime/-/relay-runtime-10.1.0.tgz#4753bf36e95e8d862cef33608e3d98b4ed730d16" + integrity sha512-bxznLnQ1ST6APN/cFi7l0FpjbZVchWQjjhj9mAuJBuUqNNCh9uV+UTRhpQF7Q8ycsPp19LHTpVyGhYb0ustuRQ== + dependencies: + "@babel/runtime" "^7.0.0" + fbjs "^3.0.0" + +remedial@^1.0.7: + version "1.0.8" + resolved "https://registry.yarnpkg.com/remedial/-/remedial-1.0.8.tgz#a5e4fd52a0e4956adbaf62da63a5a46a78c578a0" + integrity sha512-/62tYiOe6DzS5BqVsNpH/nkGlX45C/Sp6V+NtiN6JQNS1Viay7cWkazmRkrQrdFj2eshDe96SIQNIoMxqhzBOg== + +remove-trailing-separator@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" + integrity sha1-wkvOKig62tW8P1jg1IJJuSN52O8= + +remove-trailing-spaces@^1.0.6: + version "1.0.8" + resolved "https://registry.yarnpkg.com/remove-trailing-spaces/-/remove-trailing-spaces-1.0.8.tgz#4354d22f3236374702f58ee373168f6d6887ada7" + integrity sha512-O3vsMYfWighyFbTd8hk8VaSj9UAGENxAtX+//ugIst2RMk5e03h6RoIS+0ylsFxY1gvmPuAY/PO4It+gPEeySA== + +replaceall@^0.1.6: + version "0.1.6" + resolved "https://registry.yarnpkg.com/replaceall/-/replaceall-0.1.6.tgz#81d81ac7aeb72d7f5c4942adf2697a3220688d8e" + integrity sha1-gdgax663LX9cSUKt8ml6MiBojY4= + +request@^2.88.2: + version "2.88.2" + resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3" + integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw== + dependencies: + aws-sign2 "~0.7.0" + aws4 "^1.8.0" + caseless "~0.12.0" + combined-stream "~1.0.6" + extend "~3.0.2" + forever-agent "~0.6.1" + form-data "~2.3.2" + har-validator "~5.1.3" + http-signature "~1.2.0" + is-typedarray "~1.0.0" + isstream "~0.1.2" + json-stringify-safe "~5.0.1" + mime-types "~2.1.19" + oauth-sign "~0.9.0" + performance-now "^2.1.0" + qs "~6.5.2" + safe-buffer "^5.1.2" + tough-cookie "~2.5.0" + tunnel-agent "^0.6.0" + uuid "^3.3.2" + +require-directory@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" + integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= + +require-main-filename@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b" + integrity sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg== + +requirejs-config-file@^3.1.1: + version "3.1.2" + resolved "https://registry.yarnpkg.com/requirejs-config-file/-/requirejs-config-file-3.1.2.tgz#de8c0b3eebdf243511c994a8a24b006f8b825997" + integrity sha512-sdLWywcDuNz7EIOhenSbRfT4YF84nItDv90coN2htbokjmU2QeyQuSBZILQUKNksepl8UPVU+hgYySFaDxbJPQ== + dependencies: + esprima "^4.0.0" + make-dir "^2.1.0" + stringify-object "^3.2.1" + +requirejs@^2.3.5: + version "2.3.6" + resolved "https://registry.yarnpkg.com/requirejs/-/requirejs-2.3.6.tgz#e5093d9601c2829251258c0b9445d4d19fa9e7c9" + integrity sha512-ipEzlWQe6RK3jkzikgCupiTbTvm4S0/CAU5GlgptkN5SO6F3u0UD0K18wy6ErDqiCyP4J4YYe1HuAShvsxePLg== + +requires-port@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" + integrity sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8= + +resolve-dependency-path@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/resolve-dependency-path/-/resolve-dependency-path-2.0.0.tgz#11700e340717b865d216c66cabeb4a2a3c696736" + integrity sha512-DIgu+0Dv+6v2XwRaNWnumKu7GPufBBOr5I1gRPJHkvghrfCGOooJODFvgFimX/KRxk9j0whD2MnKHzM1jYvk9w== + +resolve-from@5.0.0, resolve-from@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" + integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== + +resolve-from@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" + integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== + +resolve-url-loader@3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/resolve-url-loader/-/resolve-url-loader-3.1.2.tgz#235e2c28e22e3e432ba7a5d4e305c59a58edfc08" + integrity sha512-QEb4A76c8Mi7I3xNKXlRKQSlLBwjUV/ULFMP+G7n3/7tJZ8MG5wsZ3ucxP1Jz8Vevn6fnJsxDx9cIls+utGzPQ== + dependencies: + adjust-sourcemap-loader "3.0.0" + camelcase "5.3.1" + compose-function "3.0.3" + convert-source-map "1.7.0" + es6-iterator "2.0.3" + loader-utils "1.2.3" + postcss "7.0.21" + rework "1.0.1" + rework-visit "1.0.0" + source-map "0.6.1" + +resolve-url@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" + integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= + +resolve@^1.10.0, resolve@^1.11.1, resolve@^1.14.2: + version "1.19.0" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.19.0.tgz#1af5bf630409734a067cae29318aac7fa29a267c" + integrity sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg== + dependencies: + is-core-module "^2.1.0" + path-parse "^1.0.6" + +responselike@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/responselike/-/responselike-1.0.2.tgz#918720ef3b631c5642be068f15ade5a46f4ba1e7" + integrity sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec= + dependencies: + lowercase-keys "^1.0.0" + +restore-cursor@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf" + integrity sha1-n37ih/gv0ybU/RYpI9YhKe7g368= + dependencies: + onetime "^2.0.0" + signal-exit "^3.0.2" + +restore-cursor@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-3.1.0.tgz#39f67c54b3a7a58cea5236d95cf0034239631f7e" + integrity sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA== + dependencies: + onetime "^5.1.0" + signal-exit "^3.0.2" + +retry@0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/retry/-/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b" + integrity sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs= + +reusify@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" + integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== + +rework-visit@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/rework-visit/-/rework-visit-1.0.0.tgz#9945b2803f219e2f7aca00adb8bc9f640f842c9a" + integrity sha1-mUWygD8hni96ygCtuLyfZA+ELJo= + +rework@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/rework/-/rework-1.0.1.tgz#30806a841342b54510aa4110850cd48534144aa7" + integrity sha1-MIBqhBNCtUUQqkEQhQzUhTQUSqc= + dependencies: + convert-source-map "^0.3.3" + css "^2.0.0" + +rimraf@~2.4.0: + version "2.4.5" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.4.5.tgz#ee710ce5d93a8fdb856fb5ea8ff0e2d75934b2da" + integrity sha1-7nEM5dk6j9uFb7Xqj/Di11k0sto= + dependencies: + glob "^6.0.1" + +ripemd160@^2.0.0, ripemd160@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c" + integrity sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA== + dependencies: + hash-base "^3.0.0" + inherits "^2.0.1" + +run-async@^2.4.0: + version "2.4.1" + resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.4.1.tgz#8440eccf99ea3e70bd409d49aab88e10c189a455" + integrity sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ== + +run-parallel@^1.1.9: + version "1.1.10" + resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.1.10.tgz#60a51b2ae836636c81377df16cb107351bcd13ef" + integrity sha512-zb/1OuZ6flOlH6tQyMPUrE3x3Ulxjlo9WIVXR4yVYi4H9UXQaeIsPbLn2R3O3vQCnDKkAl2qHiuocKKX4Tz/Sw== + +rxjs@^6.3.3, rxjs@^6.6.0: + version "6.6.3" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.6.3.tgz#8ca84635c4daa900c0d3967a6ee7ac60271ee552" + integrity sha512-trsQc+xYYXZ3urjOiJOuCOa5N3jAZ3eiSpQB5hIT8zGlL2QfnHLJ2r7GMkBGuIausdJN1OneaI6gQlsqNHHmZQ== + dependencies: + tslib "^1.9.0" + +safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@^5.2.0, safe-buffer@~5.2.0: + version "5.2.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" + integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== + +safe-buffer@~5.1.0, safe-buffer@~5.1.1: + version "5.1.2" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== + +safe-json-stringify@~1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/safe-json-stringify/-/safe-json-stringify-1.2.0.tgz#356e44bc98f1f93ce45df14bcd7c01cda86e0afd" + integrity sha512-gH8eh2nZudPQO6TytOvbxnuhYBOvDBBLW52tz5q6X58lJcd/tkmqFR+5Z9adS8aJtURSXWThWy/xJtJwixErvg== + +"safer-buffer@>= 2.1.2 < 3", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: + version "2.1.2" + resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== + +sass-loader@10.0.5: + version "10.0.5" + resolved "https://registry.yarnpkg.com/sass-loader/-/sass-loader-10.0.5.tgz#f53505b5ddbedf43797470ceb34066ded82bb769" + integrity sha512-2LqoNPtKkZq/XbXNQ4C64GFEleSEHKv6NPSI+bMC/l+jpEXGJhiRYkAQToO24MR7NU4JRY2RpLpJ/gjo2Uf13w== + dependencies: + klona "^2.0.4" + loader-utils "^2.0.0" + neo-async "^2.6.2" + schema-utils "^3.0.0" + semver "^7.3.2" + +sass-lookup@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/sass-lookup/-/sass-lookup-3.0.0.tgz#3b395fa40569738ce857bc258e04df2617c48cac" + integrity sha512-TTsus8CfFRn1N44bvdEai1no6PqdmDiQUiqW5DlpmtT+tYnIt1tXtDIph5KA1efC+LmioJXSnCtUVpcK9gaKIg== + dependencies: + commander "^2.16.0" + +scheduler@^0.19.1: + version "0.19.1" + resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.19.1.tgz#4f3e2ed2c1a7d65681f4c854fa8c5a1ccb40f196" + integrity sha512-n/zwRWRYSUj0/3g/otKDRPMh6qv2SYMWNq85IEa8iZyAv8od9zDYpGSnpBEjNgcMNq6Scbu5KfIPxNF72R/2EA== + dependencies: + loose-envify "^1.1.0" + object-assign "^4.1.1" + +schema-utils@2.7.1, schema-utils@^2.6.6, schema-utils@^2.7.1: + version "2.7.1" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-2.7.1.tgz#1ca4f32d1b24c590c203b8e7a50bf0ea4cd394d7" + integrity sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg== + dependencies: + "@types/json-schema" "^7.0.5" + ajv "^6.12.4" + ajv-keywords "^3.5.2" + +schema-utils@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-3.0.0.tgz#67502f6aa2b66a2d4032b4279a2944978a0913ef" + integrity sha512-6D82/xSzO094ajanoOSbe4YvXWMfn2A//8Y1+MUqFAJul5Bs+yn36xbK9OtNDcRVSBJ9jjeoXftM6CfztsjOAA== + dependencies: + "@types/json-schema" "^7.0.6" + ajv "^6.12.5" + ajv-keywords "^3.5.2" + +scuid@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/scuid/-/scuid-1.1.0.tgz#d3f9f920956e737a60f72d0e4ad280bf324d5dab" + integrity sha512-MuCAyrGZcTLfQoH2XoBlQ8C6bzwN88XT/0slOGz0pn8+gIP85BOAfYa44ZXQUTOwRwPU0QvgU+V+OSajl/59Xg== + +"semver@2 || 3 || 4 || 5", semver@^5.4.1, semver@^5.6.0: + version "5.7.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" + integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== + +semver@^6.0.0, semver@^6.2.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" + integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== + +semver@^7.3.2: + version "7.3.4" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.4.tgz#27aaa7d2e4ca76452f98d3add093a72c943edc97" + integrity sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw== + dependencies: + lru-cache "^6.0.0" + +serialize-javascript@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-5.0.1.tgz#7886ec848049a462467a97d3d918ebb2aaf934f4" + integrity sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA== + dependencies: + randombytes "^2.1.0" + +set-blocking@^2.0.0, set-blocking@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" + integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= + +setimmediate@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" + integrity sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU= + +setprototypeof@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.1.tgz#7e95acb24aa92f5885e0abef5ba131330d4ae683" + integrity sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw== + +setprototypeof@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424" + integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== + +sha.js@^2.4.0, sha.js@^2.4.8: + version "2.4.11" + resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.11.tgz#37a5cf0b81ecbc6943de109ba2960d1b26584ae7" + integrity sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ== + dependencies: + inherits "^2.0.1" + safe-buffer "^5.0.1" + +sharp@0.26.3: + version "0.26.3" + resolved "https://registry.yarnpkg.com/sharp/-/sharp-0.26.3.tgz#9de8577a986b22538e6e12ced1f7e8a53f9728de" + integrity sha512-NdEJ9S6AMr8Px0zgtFo1TJjMK/ROMU92MkDtYn2BBrDjIx3YfH9TUyGdzPC+I/L619GeYQc690Vbaxc5FPCCWg== + dependencies: + array-flatten "^3.0.0" + color "^3.1.3" + detect-libc "^1.0.3" + node-addon-api "^3.0.2" + npmlog "^4.1.2" + prebuild-install "^6.0.0" + semver "^7.3.2" + simple-get "^4.0.0" + tar-fs "^2.1.1" + tunnel-agent "^0.6.0" + +shell-quote@1.7.2: + version "1.7.2" + resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.7.2.tgz#67a7d02c76c9da24f99d20808fcaded0e0e04be2" + integrity sha512-mRz/m/JVscCrkMyPqHc/bczi3OQHkLTqXHEFu0zDhK/qfv3UcOA4SVmRCLmos4bhjr9ekVQubj/R7waKapmiQg== + +signal-exit@^3.0.0, signal-exit@^3.0.2: + version "3.0.3" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c" + integrity sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA== + +signedsource@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/signedsource/-/signedsource-1.0.0.tgz#1ddace4981798f93bd833973803d80d52e93ad6a" + integrity sha1-HdrOSYF5j5O9gzlzgD2A1S6TrWo= + +simple-concat@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/simple-concat/-/simple-concat-1.0.1.tgz#f46976082ba35c2263f1c8ab5edfe26c41c9552f" + integrity sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q== + +simple-get@^3.0.3: + version "3.1.0" + resolved "https://registry.yarnpkg.com/simple-get/-/simple-get-3.1.0.tgz#b45be062435e50d159540b576202ceec40b9c6b3" + integrity sha512-bCR6cP+aTdScaQCnQKbPKtJOKDp/hj9EDLJo3Nw4y1QksqaovlW/bnptB6/c1e+qmNIDHRK+oXFDdEqBT8WzUA== + dependencies: + decompress-response "^4.2.0" + once "^1.3.1" + simple-concat "^1.0.0" + +simple-get@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/simple-get/-/simple-get-4.0.0.tgz#73fa628278d21de83dadd5512d2cc1f4872bd675" + integrity sha512-ZalZGexYr3TA0SwySsr5HlgOOinS4Jsa8YB2GJ6lUNAazyAu4KG/VmzMTwAt2YVXzzVj8QmefmAonZIK2BSGcQ== + dependencies: + decompress-response "^6.0.0" + once "^1.3.1" + simple-concat "^1.0.0" + +simple-swizzle@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/simple-swizzle/-/simple-swizzle-0.2.2.tgz#a4da6b635ffcccca33f70d17cb92592de95e557a" + integrity sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo= + dependencies: + is-arrayish "^0.3.1" + +sirv@^1.0.7: + version "1.0.10" + resolved "https://registry.yarnpkg.com/sirv/-/sirv-1.0.10.tgz#3e591f5a9ae2520f50d5830f5fae38d97e7be194" + integrity sha512-H5EZCoZaggEUQy8ocKsF7WAToGuZhjJlLvM3XOef46CbdIgbNeQ1p32N1PCuCjkVYwrAVOSMacN6CXXgIzuspg== + dependencies: + "@polka/url" "^1.0.0-next.9" + mime "^2.3.1" + totalist "^1.0.0" + +slash@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" + integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== + +slice-ansi@0.0.4: + version "0.0.4" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-0.0.4.tgz#edbf8903f66f7ce2f8eafd6ceed65e264c831b35" + integrity sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU= + +source-list-map@^2.0.0, source-list-map@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.1.tgz#3993bd873bfc48479cca9ea3a547835c7c154b34" + integrity sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw== + +source-map-resolve@^0.5.2: + version "0.5.3" + resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.3.tgz#190866bece7553e1f8f267a2ee82c606b5509a1a" + integrity sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw== + dependencies: + atob "^2.1.2" + decode-uri-component "^0.2.0" + resolve-url "^0.2.1" + source-map-url "^0.4.0" + urix "^0.1.0" + +source-map-support@^0.5.17, source-map-support@~0.5.19: + version "0.5.19" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.19.tgz#a98b62f86dcaf4f67399648c085291ab9e8fed61" + integrity sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + +source-map-url@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3" + integrity sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM= + +source-map@0.6.1, source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== + +source-map@0.7.3, source-map@~0.7.2: + version "0.7.3" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383" + integrity sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ== + +source-map@0.8.0-beta.0: + version "0.8.0-beta.0" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.8.0-beta.0.tgz#d4c1bb42c3f7ee925f005927ba10709e0d1d1f11" + integrity sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA== + dependencies: + whatwg-url "^7.0.0" + +source-map@^0.5.0: + version "0.5.7" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" + integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= + +sourcemap-codec@^1.4.4: + version "1.4.8" + resolved "https://registry.yarnpkg.com/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz#ea804bd94857402e6992d05a38ef1ae35a9ab4c4" + integrity sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA== + +spdx-correct@^3.0.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.1.tgz#dece81ac9c1e6713e5f7d1b6f17d468fa53d89a9" + integrity sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w== + dependencies: + spdx-expression-parse "^3.0.0" + spdx-license-ids "^3.0.0" + +spdx-exceptions@^2.1.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz#3f28ce1a77a00372683eade4a433183527a2163d" + integrity sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A== + +spdx-expression-parse@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz#cf70f50482eefdc98e3ce0a6833e4a53ceeba679" + integrity sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q== + dependencies: + spdx-exceptions "^2.1.0" + spdx-license-ids "^3.0.0" + +spdx-license-ids@^3.0.0: + version "3.0.7" + resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.7.tgz#e9c18a410e5ed7e12442a549fbd8afa767038d65" + integrity sha512-U+MTEOO0AiDzxwFvoa4JVnMV6mZlJKk2sBLt90s7G0Gd0Mlknc7kxEn3nuDPNZRta7O2uy8oLcZLVT+4sqNZHQ== + +sprintf-js@~1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" + integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= + +sse-z@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/sse-z/-/sse-z-0.3.0.tgz#e215db7c303d6c4a4199d80cb63811cc28fa55b9" + integrity sha512-jfcXynl9oAOS9YJ7iqS2JMUEHOlvrRAD+54CENiWnc4xsuVLQVSgmwf7cwOTcBd/uq3XkQKBGojgvEtVXcJ/8w== + +sshpk@^1.7.0: + version "1.16.1" + resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.16.1.tgz#fb661c0bef29b39db40769ee39fa70093d6f6877" + integrity sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg== + dependencies: + asn1 "~0.2.3" + assert-plus "^1.0.0" + bcrypt-pbkdf "^1.0.0" + dashdash "^1.12.0" + ecc-jsbn "~0.1.1" + getpass "^0.1.1" + jsbn "~0.1.0" + safer-buffer "^2.0.2" + tweetnacl "~0.14.0" + +stacktrace-parser@0.1.10: + version "0.1.10" + resolved "https://registry.yarnpkg.com/stacktrace-parser/-/stacktrace-parser-0.1.10.tgz#29fb0cae4e0d0b85155879402857a1639eb6051a" + integrity sha512-KJP1OCML99+8fhOHxwwzyWrlUuVX5GQ0ZpJTd1DFXhdkrvg1szxfHhawXUZ3g9TkXORQd4/WG68jMlQZ2p8wlg== + dependencies: + type-fest "^0.7.1" + +"statuses@>= 1.5.0 < 2": + version "1.5.0" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" + integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= + +stream-browserify@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/stream-browserify/-/stream-browserify-3.0.0.tgz#22b0a2850cdf6503e73085da1fc7b7d0c2122f2f" + integrity sha512-H73RAHsVBapbim0tU2JwwOiXUj+fikfiaoYAKHF3VJfA0pe2BCzkhAHBlLG6REzE+2WNZcxOXjK7lkso+9euLA== + dependencies: + inherits "~2.0.4" + readable-stream "^3.5.0" + +streamsearch@0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/streamsearch/-/streamsearch-0.1.2.tgz#808b9d0e56fc273d809ba57338e929919a1a9f1a" + integrity sha1-gIudDlb8Jz2Am6VzOOkpkZoanxo= + +string-env-interpolation@1.0.1, string-env-interpolation@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/string-env-interpolation/-/string-env-interpolation-1.0.1.tgz#ad4397ae4ac53fe6c91d1402ad6f6a52862c7152" + integrity sha512-78lwMoCcn0nNu8LszbP1UA7g55OeE4v7rCeWnM5B453rnNr4aq+5it3FEYtZrSEiMvHZOZ9Jlqb0OD0M2VInqg== + +string-hash@1.1.3, string-hash@^1.1.1: + version "1.1.3" + resolved "https://registry.yarnpkg.com/string-hash/-/string-hash-1.1.3.tgz#e8aafc0ac1855b4666929ed7dd1275df5d6c811b" + integrity sha1-6Kr8CsGFW0Zmkp7X3RJ1311sgRs= + +string-width@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" + integrity sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M= + dependencies: + code-point-at "^1.0.0" + is-fullwidth-code-point "^1.0.0" + strip-ansi "^3.0.0" + +"string-width@^1.0.2 || 2", string-width@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" + integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== + dependencies: + is-fullwidth-code-point "^2.0.0" + strip-ansi "^4.0.0" + +string-width@^4.1.0, string-width@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.0.tgz#952182c46cc7b2c313d1596e623992bd163b72b5" + integrity sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.0" + +string.prototype.trimend@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.3.tgz#a22bd53cca5c7cf44d7c9d5c732118873d6cd18b" + integrity sha512-ayH0pB+uf0U28CtjlLvL7NaohvR1amUvVZk+y3DYb0Ey2PUV5zPkkKy9+U1ndVEIXO8hNg18eIv9Jntbii+dKw== + dependencies: + call-bind "^1.0.0" + define-properties "^1.1.3" + +string.prototype.trimstart@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.3.tgz#9b4cb590e123bb36564401d59824298de50fd5aa" + integrity sha512-oBIBUy5lea5tt0ovtOFiEQaBkoBBkyJhZXzJYrSmDo5IUUqbOPvVezuRs/agBIdZ2p2Eo1FD6bD9USyBLfl3xg== + dependencies: + call-bind "^1.0.0" + define-properties "^1.1.3" + +string_decoder@^1.1.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" + integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== + dependencies: + safe-buffer "~5.2.0" + +string_decoder@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" + integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== + dependencies: + safe-buffer "~5.1.0" + +stringify-object@^3.2.1: + version "3.3.0" + resolved "https://registry.yarnpkg.com/stringify-object/-/stringify-object-3.3.0.tgz#703065aefca19300d3ce88af4f5b3956d7556629" + integrity sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw== + dependencies: + get-own-enumerable-property-symbols "^3.0.0" + is-obj "^1.0.1" + is-regexp "^1.0.0" + +strip-ansi@6.0.0, strip-ansi@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.0.tgz#0b1571dd7669ccd4f3e06e14ef1eed26225ae532" + integrity sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w== + dependencies: + ansi-regex "^5.0.0" + +strip-ansi@^3.0.0, strip-ansi@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" + integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8= + dependencies: + ansi-regex "^2.0.0" + +strip-ansi@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" + integrity sha1-qEeQIusaw2iocTibY1JixQXuNo8= + dependencies: + ansi-regex "^3.0.0" + +strip-indent@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-3.0.0.tgz#c32e1cee940b6b3432c771bc2c54bcce73cd3001" + integrity sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ== + dependencies: + min-indent "^1.0.0" + +strip-json-comments@~2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" + integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= + +style-loader@1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-1.2.1.tgz#c5cbbfbf1170d076cfdd86e0109c5bba114baa1a" + integrity sha512-ByHSTQvHLkWE9Ir5+lGbVOXhxX10fbprhLvdg96wedFZb4NDekDPxVKv5Fwmio+QcMlkkNfuK+5W1peQ5CUhZg== + dependencies: + loader-utils "^2.0.0" + schema-utils "^2.6.6" + +styled-jsx@3.3.2: + version "3.3.2" + resolved "https://registry.yarnpkg.com/styled-jsx/-/styled-jsx-3.3.2.tgz#2474601a26670a6049fb4d3f94bd91695b3ce018" + integrity sha512-daAkGd5mqhbBhLd6jYAjYBa9LpxYCzsgo/f6qzPdFxVB8yoGbhxvzQgkC0pfmCVvW3JuAEBn0UzFLBfkHVZG1g== + dependencies: + "@babel/types" "7.8.3" + babel-plugin-syntax-jsx "6.18.0" + convert-source-map "1.7.0" + loader-utils "1.2.3" + source-map "0.7.3" + string-hash "1.1.3" + stylis "3.5.4" + stylis-rule-sheet "0.0.10" + +stylis-rule-sheet@0.0.10: + version "0.0.10" + resolved "https://registry.yarnpkg.com/stylis-rule-sheet/-/stylis-rule-sheet-0.0.10.tgz#44e64a2b076643f4b52e5ff71efc04d8c3c4a430" + integrity sha512-nTbZoaqoBnmK+ptANthb10ZRZOGC+EmTLLUxeYIuHNkEKcmKgXX1XWKkUBT2Ac4es3NybooPe0SmvKdhKJZAuw== + +stylis@3.5.4: + version "3.5.4" + resolved "https://registry.yarnpkg.com/stylis/-/stylis-3.5.4.tgz#f665f25f5e299cf3d64654ab949a57c768b73fbe" + integrity sha512-8/3pSmthWM7lsPBKv7NXkzn2Uc9W7NotcwGNpJaa3k7WMM1XDCA4MgT5k/8BIexd5ydZdboXtU90XH9Ec4Bv/Q== + +stylus-lookup@^3.0.1: + version "3.0.2" + resolved "https://registry.yarnpkg.com/stylus-lookup/-/stylus-lookup-3.0.2.tgz#c9eca3ff799691020f30b382260a67355fefdddd" + integrity sha512-oEQGHSjg/AMaWlKe7gqsnYzan8DLcGIHe0dUaFkucZZ14z4zjENRlQMCHT4FNsiWnJf17YN9OvrCfCoi7VvOyg== + dependencies: + commander "^2.8.1" + debug "^4.1.0" + +supports-color@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" + integrity sha1-U10EXOa2Nj+kARcIRimZXp3zJMc= + +supports-color@^5.3.0, supports-color@^5.4.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" + integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== + dependencies: + has-flag "^3.0.0" + +supports-color@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-6.1.0.tgz#0764abc69c63d5ac842dd4867e8d025e880df8f3" + integrity sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ== + dependencies: + has-flag "^3.0.0" + +supports-color@^7.0.0, supports-color@^7.1.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" + integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== + dependencies: + has-flag "^4.0.0" + +swr@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/swr/-/swr-0.4.0.tgz#e76da9f981fe6dee0e133289e9b582fc80d9c41d" + integrity sha512-70qd1FHYHwIdYXW0jTpm5ktitzvPBCtyKz8ZzynWlY/rMqe4drYPgcl/H9Ipuh+Xv6ZW5viNx13ro8EKIWZcoQ== + dependencies: + dequal "2.0.2" + +symbol-observable@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.2.0.tgz#c22688aed4eab3cdc2dfeacbb561660560a00804" + integrity sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ== + +sync-fetch@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/sync-fetch/-/sync-fetch-0.3.0.tgz#77246da949389310ad978ab26790bb05f88d1335" + integrity sha512-dJp4qg+x4JwSEW1HibAuMi0IIrBI3wuQr2GimmqB7OXR50wmwzfdusG+p39R9w3R6aFtZ2mzvxvWKQ3Bd/vx3g== + dependencies: + buffer "^5.7.0" + node-fetch "^2.6.1" + +tabbable@^5.1.5: + version "5.1.5" + resolved "https://registry.yarnpkg.com/tabbable/-/tabbable-5.1.5.tgz#efec48ede268d511c261e3b81facbb4782a35147" + integrity sha512-oVAPrWgLLqrbvQE8XqcU7CVBq6SQbaIbHkhOca3u7/jzuQvyZycrUKPCGr04qpEIUslmUlULbSeN+m3QrKEykA== + +tailwindcss@^1.9: + version "1.9.6" + resolved "https://registry.yarnpkg.com/tailwindcss/-/tailwindcss-1.9.6.tgz#0c5089911d24e1e98e592a31bfdb3d8f34ecf1a0" + integrity sha512-nY8WYM/RLPqGsPEGEV2z63riyQPcHYZUJpAwdyBzVpxQHOHqHE+F/fvbCeXhdF1+TA5l72vSkZrtYCB9hRcwkQ== + dependencies: + "@fullhuman/postcss-purgecss" "^2.1.2" + autoprefixer "^9.4.5" + browserslist "^4.12.0" + bytes "^3.0.0" + chalk "^3.0.0 || ^4.0.0" + color "^3.1.2" + detective "^5.2.0" + fs-extra "^8.0.0" + html-tags "^3.1.0" + lodash "^4.17.20" + node-emoji "^1.8.1" + normalize.css "^8.0.1" + object-hash "^2.0.3" + postcss "^7.0.11" + postcss-functions "^3.0.0" + postcss-js "^2.0.0" + postcss-nested "^4.1.1" + postcss-selector-parser "^6.0.0" + postcss-value-parser "^4.1.0" + pretty-hrtime "^1.0.3" + reduce-css-calc "^2.1.6" + resolve "^1.14.2" + +tapable@^1.0.0: + version "1.1.3" + resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.1.3.tgz#a1fccc06b58db61fd7a45da2da44f5f3a3e67ba2" + integrity sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA== + +tapable@^2.1.1, tapable@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.0.tgz#5c373d281d9c672848213d0e037d1c4165ab426b" + integrity sha512-FBk4IesMV1rBxX2tfiK8RAmogtWn53puLOQlvO8XuwlgxcYbP4mVPS9Ph4aeamSyyVjOl24aYWAuc8U5kCVwMw== + +tar-fs@^2.0.0, tar-fs@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-2.1.1.tgz#489a15ab85f1f0befabb370b7de4f9eb5cbe8784" + integrity sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng== + dependencies: + chownr "^1.1.1" + mkdirp-classic "^0.5.2" + pump "^3.0.0" + tar-stream "^2.1.4" + +tar-stream@^2.1.4: + version "2.2.0" + resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-2.2.0.tgz#acad84c284136b060dc3faa64474aa9aebd77287" + integrity sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ== + dependencies: + bl "^4.0.3" + end-of-stream "^1.4.1" + fs-constants "^1.0.0" + inherits "^2.0.3" + readable-stream "^3.1.1" + +temp@~0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/temp/-/temp-0.4.0.tgz#671ad63d57be0fe9d7294664b3fc400636678a60" + integrity sha1-ZxrWPVe+D+nXKUZks/xABjZnimA= + +terser-webpack-plugin@^5.0.3: + version "5.1.1" + resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.1.1.tgz#7effadee06f7ecfa093dbbd3e9ab23f5f3ed8673" + integrity sha512-5XNNXZiR8YO6X6KhSGXfY0QrGrCRlSwAEjIIrlRQR4W8nP69TaJUlh3bkuac6zzgspiGPfKEHcY295MMVExl5Q== + dependencies: + jest-worker "^26.6.2" + p-limit "^3.1.0" + schema-utils "^3.0.0" + serialize-javascript "^5.0.1" + source-map "^0.6.1" + terser "^5.5.1" + +terser@5.5.1, terser@^5.5.1: + version "5.5.1" + resolved "https://registry.yarnpkg.com/terser/-/terser-5.5.1.tgz#540caa25139d6f496fdea056e414284886fb2289" + integrity sha512-6VGWZNVP2KTUcltUQJ25TtNjx/XgdDsBDKGt8nN0MpydU36LmbPPcMBd2kmtZNNGVVDLg44k7GKeHHj+4zPIBQ== + dependencies: + commander "^2.20.0" + source-map "~0.7.2" + source-map-support "~0.5.19" + +through@^2.3.6: + version "2.3.8" + resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" + integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= + +tmp@^0.0.33: + version "0.0.33" + resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" + integrity sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw== + dependencies: + os-tmpdir "~1.0.2" + +to-fast-properties@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" + integrity sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4= + +to-readable-stream@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/to-readable-stream/-/to-readable-stream-1.0.0.tgz#ce0aa0c2f3df6adf852efb404a783e77c0475771" + integrity sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q== + +to-regex-range@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" + integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== + dependencies: + is-number "^7.0.0" + +toidentifier@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553" + integrity sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw== + +totalist@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/totalist/-/totalist-1.1.0.tgz#a4d65a3e546517701e3e5c37a47a70ac97fe56df" + integrity sha512-gduQwd1rOdDMGxFG1gEvhV88Oirdo2p+KjoYFU7k2g+i7n6AFFbDQ5kMPUsW0pNbfQsB/cwXvT1i4Bue0s9g5g== + +tough-cookie@~2.5.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" + integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g== + dependencies: + psl "^1.1.28" + punycode "^2.1.1" + +tr46@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-1.0.1.tgz#a8b13fd6bfd2489519674ccde55ba3693b706d09" + integrity sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk= + dependencies: + punycode "^2.1.0" + +traverse-chain@~0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/traverse-chain/-/traverse-chain-0.1.0.tgz#61dbc2d53b69ff6091a12a168fd7d433107e40f1" + integrity sha1-YdvC1Ttp/2CRoSoWj9fUMxB+QPE= + +traverse@0.6.6, traverse@^0.6.6: + version "0.6.6" + resolved "https://registry.yarnpkg.com/traverse/-/traverse-0.6.6.tgz#cbdf560fd7b9af632502fed40f918c157ea97137" + integrity sha1-y99WD9e5r2MlAv7UD5GMFX6pcTc= + +trim-newlines@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-3.0.0.tgz#79726304a6a898aa8373427298d54c2ee8b1cb30" + integrity sha512-C4+gOpvmxaSMKuEf9Qc134F1ZuOHVXKRbtEflf4NTtuuJDEIJ9p5PXsalL8SkeRw+qit1Mo+yuvMPAKwWg/1hA== + +ts-loader@^7.0.0: + version "7.0.5" + resolved "https://registry.yarnpkg.com/ts-loader/-/ts-loader-7.0.5.tgz#789338fb01cb5dc0a33c54e50558b34a73c9c4c5" + integrity sha512-zXypEIT6k3oTc+OZNx/cqElrsbBtYqDknf48OZos0NQ3RTt045fBIU8RRSu+suObBzYB355aIPGOe/3kj9h7Ig== + dependencies: + chalk "^2.3.0" + enhanced-resolve "^4.0.0" + loader-utils "^1.0.2" + micromatch "^4.0.0" + semver "^6.0.0" + +ts-log@^2.2.3: + version "2.2.3" + resolved "https://registry.yarnpkg.com/ts-log/-/ts-log-2.2.3.tgz#4da5640fe25a9fb52642cd32391c886721318efb" + integrity sha512-XvB+OdKSJ708Dmf9ore4Uf/q62AYDTzFcAdxc8KNML1mmAWywRFVt/dn1KYJH8Agt5UJNujfM3znU5PxgAzA2w== + +ts-node@^9: + version "9.1.1" + resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-9.1.1.tgz#51a9a450a3e959401bda5f004a72d54b936d376d" + integrity sha512-hPlt7ZACERQGf03M253ytLY3dHbGNGrAq9qIHWUY9XHYl1z7wYngSr3OQ5xmui8o2AaxsONxIzjafLUiWBo1Fg== + dependencies: + arg "^4.1.0" + create-require "^1.1.0" + diff "^4.0.1" + make-error "^1.1.1" + source-map-support "^0.5.17" + yn "3.1.1" + +ts-pnp@^1.1.6: + version "1.2.0" + resolved "https://registry.yarnpkg.com/ts-pnp/-/ts-pnp-1.2.0.tgz#a500ad084b0798f1c3071af391e65912c86bca92" + integrity sha512-csd+vJOb/gkzvcCHgTGSChYpy5f1/XKNsmvBGO4JXS+z1v2HobugDz4s1IeFXM3wZB44uczs+eazB5Q/ccdhQw== + +tslib@^1.10.0, tslib@^1.8.1, tslib@^1.9.0: + version "1.14.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" + integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== + +tslib@^2, tslib@^2.0.0, tslib@^2.0.3, tslib@~2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.1.0.tgz#da60860f1c2ecaa5703ab7d39bc05b6bf988b97a" + integrity sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A== + +tslib@~2.0.1: + version "2.0.3" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.0.3.tgz#8e0741ac45fc0c226e58a17bfc3e64b9bc6ca61c" + integrity sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ== + +tsutils@^3.17.1: + version "3.19.1" + resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.19.1.tgz#d8566e0c51c82f32f9c25a4d367cd62409a547a9" + integrity sha512-GEdoBf5XI324lu7ycad7s6laADfnAqCw6wLGI+knxvw9vsIYBaJfYdmeCEG3FMMUiSm3OGgNb+m6utsWf5h9Vw== + dependencies: + tslib "^1.8.1" + +tunnel-agent@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" + integrity sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0= + dependencies: + safe-buffer "^5.0.1" + +tweetnacl@^0.14.3, tweetnacl@~0.14.0: + version "0.14.5" + resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" + integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q= + +type-check@~0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" + integrity sha1-WITKtRLPHTVeP7eE8wgEsrUg23I= + dependencies: + prelude-ls "~1.1.2" + +type-fest@^0.11.0: + version "0.11.0" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.11.0.tgz#97abf0872310fed88a5c466b25681576145e33f1" + integrity sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ== + +type-fest@^0.13.1: + version "0.13.1" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.13.1.tgz#0172cb5bce80b0bd542ea348db50c7e21834d934" + integrity sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg== + +type-fest@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.6.0.tgz#8d2a2370d3df886eb5c90ada1c5bf6188acf838b" + integrity sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg== + +type-fest@^0.7.1: + version "0.7.1" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.7.1.tgz#8dda65feaf03ed78f0a3f9678f1869147f7c5c48" + integrity sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg== + +type-fest@^0.8.1: + version "0.8.1" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d" + integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA== + +type@^1.0.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/type/-/type-1.2.0.tgz#848dd7698dafa3e54a6c479e759c4bc3f18847a0" + integrity sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg== + +type@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/type/-/type-2.1.0.tgz#9bdc22c648cf8cf86dd23d32336a41cfb6475e3f" + integrity sha512-G9absDWvhAWCV2gmF1zKud3OyC61nZDwWvBL2DApaVFogI07CprggiQAOOjvp2NRjYWFzPyu7vwtDrQFq8jeSA== + +typescript@^3.0.3, typescript@^3.8.3, typescript@^3.9.5, typescript@^3.9.7: + version "3.9.7" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.9.7.tgz#98d600a5ebdc38f40cb277522f12dc800e9e25fa" + integrity sha512-BLbiRkiBzAwsjut4x/dsibSTB6yWpwT5qWmC2OfuCg3GgVQCSgMs4vEctYPhsaGtd0AeuuHMkjZ2h2WG8MSzRw== + +typescript@^4.0.3: + version "4.1.3" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.1.3.tgz#519d582bd94cba0cf8934c7d8e8467e473f53bb7" + integrity sha512-B3ZIOf1IKeH2ixgHhj6la6xdwR9QrLC5d1VKeCSY4tvkqhF2eqd9O7txNlS0PO3GrBAFIdr3L1ndNwteUbZLYg== + +ua-parser-js@^0.7.18: + version "0.7.23" + resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.23.tgz#704d67f951e13195fbcd3d78818577f5bc1d547b" + integrity sha512-m4hvMLxgGHXG3O3fQVAyyAQpZzDOvwnhOTjYz5Xmr7r/+LpkNy3vJXdVRWgd1TkAb7NGROZuSy96CrlNVjA7KA== + +unc-path-regex@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/unc-path-regex/-/unc-path-regex-0.1.2.tgz#e73dd3d7b0d7c5ed86fbac6b0ae7d8c6a69d50fa" + integrity sha1-5z3T17DXxe2G+6xrCufYxqadUPo= + +uniq@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/uniq/-/uniq-1.0.1.tgz#b31c5ae8254844a3a8281541ce2b04b865a734ff" + integrity sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8= + +universalify@^0.1.0: + version "0.1.2" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" + integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== + +unixify@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unixify/-/unixify-1.0.0.tgz#3a641c8c2ffbce4da683a5c70f03a462940c2090" + integrity sha1-OmQcjC/7zk2mg6XHDwOkYpQMIJA= + dependencies: + normalize-path "^2.1.1" + +unpipe@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" + integrity sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw= + +upper-case@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/upper-case/-/upper-case-2.0.1.tgz#6214d05e235dc817822464ccbae85822b3d8665f" + integrity sha512-laAsbea9SY5osxrv7S99vH9xAaJKrw5Qpdh4ENRLcaxipjKsiaBwiAsxfa8X5mObKNTQPsupSq0J/VIxsSJe3A== + dependencies: + tslib "^1.10.0" + +upper-case@^2.0.1, upper-case@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/upper-case/-/upper-case-2.0.2.tgz#d89810823faab1df1549b7d97a76f8662bae6f7a" + integrity sha512-KgdgDGJt2TpuwBUIjgG6lzw2GWFRCW9Qkfkiv0DxqHHLYJHmtmdUIKcZd8rHgFSjopVTlw6ggzCm1b8MFQwikg== + dependencies: + tslib "^2.0.3" + +uri-js@^4.2.2: + version "4.4.1" + resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" + integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== + dependencies: + punycode "^2.1.0" + +urix@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" + integrity sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI= + +url-parse-lax@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-3.0.0.tgz#16b5cafc07dbe3676c1b1999177823d6503acb0c" + integrity sha1-FrXK/Afb42dsGxmZF3gj1lA6yww= + dependencies: + prepend-http "^2.0.0" + +url-parse@^1.4.3: + version "1.4.7" + resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.4.7.tgz#a8a83535e8c00a316e403a5db4ac1b9b853ae278" + integrity sha512-d3uaVyzDB9tQoSXFvuSUNFibTd9zxd2bkVrDRvF5TmvWWQwqE4lgYJ5m+x1DbecWkw+LK4RNl2CU1hHuOKPVlg== + dependencies: + querystringify "^2.1.1" + requires-port "^1.0.0" + +use-subscription@1.5.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/use-subscription/-/use-subscription-1.5.1.tgz#73501107f02fad84c6dd57965beb0b75c68c42d1" + integrity sha512-Xv2a1P/yReAjAbhylMfFplFKj9GssgTwN7RlcTxBujFQcloStWNDQdc4g4NRWH9xS4i/FDk04vQBptAXoF3VcA== + dependencies: + object-assign "^4.1.1" + +util-deprecate@^1.0.1, util-deprecate@^1.0.2, util-deprecate@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= + +uuid@^3.3.2: + version "3.4.0" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" + integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== + +valid-url@1.0.9, valid-url@^1.0.9: + version "1.0.9" + resolved "https://registry.yarnpkg.com/valid-url/-/valid-url-1.0.9.tgz#1c14479b40f1397a75782f115e4086447433a200" + integrity sha1-HBRHm0DxOXp1eC8RXkCGRHQzogA= + +validate-npm-package-license@^3.0.1: + version "3.0.4" + resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" + integrity sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew== + dependencies: + spdx-correct "^3.0.0" + spdx-expression-parse "^3.0.0" + +verror@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" + integrity sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA= + dependencies: + assert-plus "^1.0.0" + core-util-is "1.0.2" + extsprintf "^1.2.0" + +vm-browserify@1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.2.tgz#78641c488b8e6ca91a75f511e7a3b32a86e5dda0" + integrity sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ== + +walkdir@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/walkdir/-/walkdir-0.4.1.tgz#dc119f83f4421df52e3061e514228a2db20afa39" + integrity sha512-3eBwRyEln6E1MSzcxcVpQIhRG8Q1jLvEqRmCZqS3dsfXEDR/AhOF4d+jHg1qvDCpYaVRZjENPQyrVxAkQqxPgQ== + +warning@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/warning/-/warning-4.0.3.tgz#16e9e077eb8a86d6af7d64aa1e05fd85b4678ca3" + integrity sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w== + dependencies: + loose-envify "^1.0.0" + +watchpack@2.0.0-beta.13: + version "2.0.0-beta.13" + resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.0.0-beta.13.tgz#9d9b0c094b8402139333e04eb6194643c8384f55" + integrity sha512-ZEFq2mx/k5qgQwgi6NOm+2ImICb8ngAkA/rZ6oyXZ7SgPn3pncf+nfhYTCrs3lmHwOxnPtGLTOuFLfpSMh1VMA== + dependencies: + glob-to-regexp "^0.4.1" + graceful-fs "^4.1.2" + +watchpack@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.1.0.tgz#e63194736bf3aa22026f7b191cd57907b0f9f696" + integrity sha512-UjgD1mqjkG99+3lgG36at4wPnUXNvis2v1utwTgQ43C22c4LD71LsYMExdWXh4HZ+RmW+B0t1Vrg2GpXAkTOQw== + dependencies: + glob-to-regexp "^0.4.1" + graceful-fs "^4.1.2" + +wcwidth@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/wcwidth/-/wcwidth-1.0.1.tgz#f0b0dcf915bc5ff1528afadb2c0e17b532da2fe8" + integrity sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g= + dependencies: + defaults "^1.0.3" + +webidl-conversions@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad" + integrity sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg== + +webpack-bundle-analyzer@4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/webpack-bundle-analyzer/-/webpack-bundle-analyzer-4.3.0.tgz#2f3c0ca9041d5ee47fa418693cf56b4a518b578b" + integrity sha512-J3TPm54bPARx6QG8z4cKBszahnUglcv70+N+8gUqv2I5KOFHJbzBiLx+pAp606so0X004fxM7hqRu10MLjJifA== + dependencies: + acorn "^8.0.4" + acorn-walk "^8.0.0" + chalk "^4.1.0" + commander "^6.2.0" + gzip-size "^6.0.0" + lodash "^4.17.20" + opener "^1.5.2" + sirv "^1.0.7" + ws "^7.3.1" + +webpack-sources@1.4.3: + version "1.4.3" + resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.4.3.tgz#eedd8ec0b928fbf1cbfe994e22d2d890f330a933" + integrity sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ== + dependencies: + source-list-map "^2.0.0" + source-map "~0.6.1" + +webpack-sources@^2.1.1: + version "2.2.0" + resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-2.2.0.tgz#058926f39e3d443193b6c31547229806ffd02bac" + integrity sha512-bQsA24JLwcnWGArOKUxYKhX3Mz/nK1Xf6hxullKERyktjNMC4x8koOeaDNTA2fEJ09BdWLbM/iTW0ithREUP0w== + dependencies: + source-list-map "^2.0.1" + source-map "^0.6.1" + +webpack@4.44.1, webpack@5.11.1: + version "5.11.1" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.11.1.tgz#39b2b9daeb5c6c620e03b7556ec674eaed4016b4" + integrity sha512-tNUIdAmYJv+nupRs/U/gqmADm6fgrf5xE+rSlSsf2PgsGO7j2WG7ccU6AWNlOJlHFl+HnmXlBmHIkiLf+XA9mQ== + dependencies: + "@types/eslint-scope" "^3.7.0" + "@types/estree" "^0.0.45" + "@webassemblyjs/ast" "1.9.1" + "@webassemblyjs/helper-module-context" "1.9.1" + "@webassemblyjs/wasm-edit" "1.9.1" + "@webassemblyjs/wasm-parser" "1.9.1" + acorn "^8.0.4" + browserslist "^4.14.5" + chrome-trace-event "^1.0.2" + enhanced-resolve "^5.3.1" + eslint-scope "^5.1.1" + events "^3.2.0" + glob-to-regexp "^0.4.1" + graceful-fs "^4.2.4" + json-parse-better-errors "^1.0.2" + loader-runner "^4.1.0" + mime-types "^2.1.27" + neo-async "^2.6.2" + pkg-dir "^5.0.0" + schema-utils "^3.0.0" + tapable "^2.1.1" + terser-webpack-plugin "^5.0.3" + watchpack "^2.0.0" + webpack-sources "^2.1.1" + +whatwg-fetch@^3.4.1: + version "3.5.0" + resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-3.5.0.tgz#605a2cd0a7146e5db141e29d1c62ab84c0c4c868" + integrity sha512-jXkLtsR42xhXg7akoDKvKWE40eJeI+2KZqcp2h3NsOrRnDvtWX36KcKl30dy+hxECivdk2BVUHVNrPtoMBUx6A== + +whatwg-url@^7.0.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-7.1.0.tgz#c2c492f1eca612988efd3d2266be1b9fc6170d06" + integrity sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg== + dependencies: + lodash.sortby "^4.7.0" + tr46 "^1.0.1" + webidl-conversions "^4.0.2" + +which-module@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" + integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= + +which-pm-runs@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/which-pm-runs/-/which-pm-runs-1.0.0.tgz#670b3afbc552e0b55df6b7780ca74615f23ad1cb" + integrity sha1-Zws6+8VS4LVd9rd4DKdGFfI60cs= + +wide-align@^1.1.0: + version "1.1.3" + resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457" + integrity sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA== + dependencies: + string-width "^1.0.2 || 2" + +word-wrap@~1.2.3: + version "1.2.3" + resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" + integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== + +wrap-ansi@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-3.0.1.tgz#288a04d87eda5c286e060dfe8f135ce8d007f8ba" + integrity sha1-KIoE2H7aXChuBg3+jxNc6NAH+Lo= + dependencies: + string-width "^2.1.1" + strip-ansi "^4.0.0" + +wrap-ansi@^6.2.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-6.2.0.tgz#e9393ba07102e6c91a3b221478f0257cd2856e53" + integrity sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + +wrap-ansi@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= + +ws@7.4.1: + version "7.4.1" + resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.1.tgz#a333be02696bd0e54cea0434e21dcc8a9ac294bb" + integrity sha512-pTsP8UAfhy3sk1lSk/O/s4tjD0CRwvMnzvwr4OKGX7ZvqZtUyx4KIJB5JWbkykPoc55tixMGgTNoh3k4FkNGFQ== + +ws@^7.3.1: + version "7.4.2" + resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.2.tgz#782100048e54eb36fe9843363ab1c68672b261dd" + integrity sha512-T4tewALS3+qsrpGI/8dqNMLIVdq/g/85U98HPMa6F0m6xTbvhXU6RCQLqPH3+SlomNV/LdY6RXEbBpMH6EOJnA== + +xtend@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" + integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== + +y18n@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.1.tgz#8db2b83c31c5d75099bb890b23f3094891e247d4" + integrity sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ== + +y18n@^5.0.5: + version "5.0.5" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.5.tgz#8769ec08d03b1ea2df2500acef561743bbb9ab18" + integrity sha512-hsRUr4FFrvhhRH12wOdfs38Gy7k2FFzB9qgN9v3aLykRq0dRcdcpz5C9FxdS2NuhOrI/628b/KSTJ3rwHysYSg== + +yallist@^3.0.2: + version "3.1.1" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" + integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== + +yallist@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" + integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== + +yaml-ast-parser@^0.0.43: + version "0.0.43" + resolved "https://registry.yarnpkg.com/yaml-ast-parser/-/yaml-ast-parser-0.0.43.tgz#e8a23e6fb4c38076ab92995c5dca33f3d3d7c9bb" + integrity sha512-2PTINUwsRqSd+s8XxKaJWQlUuEMHJQyEuh2edBbW8KNJz0SJPwUSD2zRWqezFEdN7IzAgeuYHFUCF7o8zRdZ0A== + +yaml@^1.10.0, yaml@^1.7.2: + version "1.10.0" + resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.0.tgz#3b593add944876077d4d683fee01081bd9fff31e" + integrity sha512-yr2icI4glYaNG+KWONODapy2/jDdMSDnrONSjblABjD9B4Z5LgiircSt8m8sRZFNi08kG9Sm0uSHtEmP3zaEGg== + +yargs-parser@^18.1.2, yargs-parser@^18.1.3: + version "18.1.3" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-18.1.3.tgz#be68c4975c6b2abf469236b0c870362fab09a7b0" + integrity sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ== + dependencies: + camelcase "^5.0.0" + decamelize "^1.2.0" + +yargs-parser@^20.2.2: + version "20.2.4" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.4.tgz#b42890f14566796f85ae8e3a25290d205f154a54" + integrity sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA== + +yargs@^15.3.1: + version "15.4.1" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-15.4.1.tgz#0d87a16de01aee9d8bec2bfbf74f67851730f4f8" + integrity sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A== + dependencies: + cliui "^6.0.0" + decamelize "^1.2.0" + find-up "^4.1.0" + get-caller-file "^2.0.1" + require-directory "^2.1.1" + require-main-filename "^2.0.0" + set-blocking "^2.0.0" + string-width "^4.2.0" + which-module "^2.0.0" + y18n "^4.0.0" + yargs-parser "^18.1.2" + +yargs@^16.1.1: + version "16.2.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66" + integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw== + dependencies: + cliui "^7.0.2" + escalade "^3.1.1" + get-caller-file "^2.0.5" + require-directory "^2.1.1" + string-width "^4.2.0" + y18n "^5.0.5" + yargs-parser "^20.2.2" + +yn@3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50" + integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q== + +yocto-queue@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" + integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== From 28b244760afb5fee9ba71779a9f1f5c38ec99fc7 Mon Sep 17 00:00:00 2001 From: Belen Curcio Date: Mon, 11 Jan 2021 13:25:25 -0300 Subject: [PATCH 025/216] changes --- framework/bigcommerce/api/operations/get-all-products.ts | 4 ++-- framework/bigcommerce/api/operations/get-product.ts | 4 ++-- package.json | 2 +- pages/index2.tsx | 7 +++++++ yarn.lock | 2 +- 5 files changed, 13 insertions(+), 6 deletions(-) create mode 100644 pages/index2.tsx diff --git a/framework/bigcommerce/api/operations/get-all-products.ts b/framework/bigcommerce/api/operations/get-all-products.ts index 599109a7d..534c20bfb 100644 --- a/framework/bigcommerce/api/operations/get-all-products.ts +++ b/framework/bigcommerce/api/operations/get-all-products.ts @@ -94,7 +94,7 @@ async function getAllProducts({ variables?: ProductVariables config?: BigcommerceConfig preview?: boolean -} = {}): Promise<{ products: Product[] }> { +} = {}): Promise<{ products: Product[] | any[] }> { config = getConfig(config) const locale = vars.locale || config.locale @@ -127,7 +127,7 @@ async function getAllProducts({ }) } - return { products: products.map(normalizeProduct) } + return { products } } export default getAllProducts diff --git a/framework/bigcommerce/api/operations/get-product.ts b/framework/bigcommerce/api/operations/get-product.ts index 2476d1398..403208264 100644 --- a/framework/bigcommerce/api/operations/get-product.ts +++ b/framework/bigcommerce/api/operations/get-product.ts @@ -93,7 +93,7 @@ async function getProduct({ variables: ProductVariables config?: BigcommerceConfig preview?: boolean -}): Promise { +}): Promise { config = getConfig(config) const locale = vars.locale || config.locale @@ -111,7 +111,7 @@ async function getProduct({ setProductLocaleMeta(product) } - return { product: normalizeProduct(product) } + return { product } } return {} diff --git a/package.json b/package.json index b90bf4cf8..d1f669a36 100644 --- a/package.json +++ b/package.json @@ -57,7 +57,7 @@ "lodash.debounce": "^4.0.8", "lodash.random": "^3.2.0", "lodash.throttle": "^4.1.1", - "next": "^10.0.5-canary.11", + "next": "^10.0.5", "next-seo": "^4.11.0", "next-themes": "^0.0.4", "postcss-nesting": "^7.0.1", diff --git a/pages/index2.tsx b/pages/index2.tsx new file mode 100644 index 000000000..9b94444e1 --- /dev/null +++ b/pages/index2.tsx @@ -0,0 +1,7 @@ +import { Layout } from '@components/common' + +export default function Home() { + return <>Hello +} + +Home.Layout = Layout diff --git a/yarn.lock b/yarn.lock index 8e9ded267..769c2e077 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5038,7 +5038,7 @@ next-unused@^0.0.3: madge "^3.8.0" ts-loader "^7.0.0" -next@^10.0.5-canary.11: +next@^10.0.5: version "10.0.5" resolved "https://registry.yarnpkg.com/next/-/next-10.0.5.tgz#8071e0aa1883266c91943aa7c6b73deadb064793" integrity sha512-yr7ap2TLugf0aMHz+3JoKFP9CCkFE+k6jCfdUymORhptjLYZbD3YGlTcUC1CRl+b5Phlbl7m/WUIPde0VcguiA== From 8f9bbe19cae4af57815850c46fd450941c9667fa Mon Sep 17 00:00:00 2001 From: Belen Curcio Date: Mon, 11 Jan 2021 13:55:45 -0300 Subject: [PATCH 026/216] index.ts broke my tree shaking --- components/auth/LoginView.tsx | 2 +- components/auth/SignUpView.tsx | 2 +- components/common/UserNav/DropdownMenu.tsx | 2 +- .../product/ProductCard/ProductCard.tsx | 4 ++-- .../product/ProductView/ProductView.tsx | 2 +- .../WishlistButton/WishlistButton.tsx | 6 ++++-- .../api/operations/get-all-products.ts | 2 +- .../bigcommerce/api/operations/get-product.ts | 2 +- framework/bigcommerce/lib/normalize.ts | 21 +++++++++---------- next.config.js | 8 ++----- package.json | 3 +++ tsconfig.json | 8 +------ 12 files changed, 28 insertions(+), 34 deletions(-) diff --git a/components/auth/LoginView.tsx b/components/auth/LoginView.tsx index 7b402e6d7..89d5bf893 100644 --- a/components/auth/LoginView.tsx +++ b/components/auth/LoginView.tsx @@ -1,6 +1,6 @@ import { FC, useEffect, useState, useCallback } from 'react' import { Logo, Button, Input } from '@components/ui' -import { useLogin } from '@framework/auth' +import useLogin from '@framework/auth/use-login' import { useUI } from '@components/ui/context' import { validate } from 'email-validator' diff --git a/components/auth/SignUpView.tsx b/components/auth/SignUpView.tsx index 49351bfe9..1b619828b 100644 --- a/components/auth/SignUpView.tsx +++ b/components/auth/SignUpView.tsx @@ -3,7 +3,7 @@ import { validate } from 'email-validator' import { Info } from '@components/icons' import { useUI } from '@components/ui/context' import { Logo, Button, Input } from '@components/ui' -import { useSignup } from '@framework/auth' +import useSignup from '@framework/auth/use-signup' interface Props {} diff --git a/components/common/UserNav/DropdownMenu.tsx b/components/common/UserNav/DropdownMenu.tsx index f8cedc332..43f842009 100644 --- a/components/common/UserNav/DropdownMenu.tsx +++ b/components/common/UserNav/DropdownMenu.tsx @@ -8,7 +8,7 @@ import { Avatar } from '@components/common' import { Moon, Sun } from '@components/icons' import { useUI } from '@components/ui/context' import ClickOutside from '@lib/click-outside' -import { useLogout } from '@framework/auth' +import useLogout from '@framework/auth/use-logout' import { disableBodyScroll, diff --git a/components/product/ProductCard/ProductCard.tsx b/components/product/ProductCard/ProductCard.tsx index 863a3b2b8..b3c061a5c 100644 --- a/components/product/ProductCard/ProductCard.tsx +++ b/components/product/ProductCard/ProductCard.tsx @@ -57,11 +57,11 @@ const ProductCard: FC = ({ {product.price.currencyCode}
- + /> */}
{product?.images && ( diff --git a/components/product/ProductView/ProductView.tsx b/components/product/ProductView/ProductView.tsx index 34bae1f69..b5aafd0b1 100644 --- a/components/product/ProductView/ProductView.tsx +++ b/components/product/ProductView/ProductView.tsx @@ -8,7 +8,7 @@ import { useUI } from '@components/ui' import { Swatch, ProductSlider } from '@components/product' import { Button, Container, Text } from '@components/ui' -import { usePrice } from '@framework/product' +import usePrice from '@framework/product/use-price' import { useAddItem } from '@framework/cart' import { diff --git a/components/wishlist/WishlistButton/WishlistButton.tsx b/components/wishlist/WishlistButton/WishlistButton.tsx index aca0ad148..dced18a89 100644 --- a/components/wishlist/WishlistButton/WishlistButton.tsx +++ b/components/wishlist/WishlistButton/WishlistButton.tsx @@ -3,8 +3,10 @@ import cn from 'classnames' import { Heart } from '@components/icons' import { useUI } from '@components/ui' -import { useCustomer } from '@framework/customer' -import { useAddItem, useWishlist, useRemoveItem } from '@framework/wishlist' +import useCustomer from '@framework/customer/use-customer' +import useAddItem from '@framework/wishlist/use-add-item' +import useRemoveItem from '@framework/wishlist/use-remove-item' +import useWishlist from '@framework/wishlist/use-add-item' type Props = { productId: Product['id'] diff --git a/framework/bigcommerce/api/operations/get-all-products.ts b/framework/bigcommerce/api/operations/get-all-products.ts index 534c20bfb..60aa197cc 100644 --- a/framework/bigcommerce/api/operations/get-all-products.ts +++ b/framework/bigcommerce/api/operations/get-all-products.ts @@ -127,7 +127,7 @@ async function getAllProducts({ }) } - return { products } + return { products: products.map(({ node }) => normalizeProduct(node)) } } export default getAllProducts diff --git a/framework/bigcommerce/api/operations/get-product.ts b/framework/bigcommerce/api/operations/get-product.ts index 403208264..aa480ac5e 100644 --- a/framework/bigcommerce/api/operations/get-product.ts +++ b/framework/bigcommerce/api/operations/get-product.ts @@ -111,7 +111,7 @@ async function getProduct({ setProductLocaleMeta(product) } - return { product } + return { product: normalizeProduct(product) } } return {} diff --git a/framework/bigcommerce/lib/normalize.ts b/framework/bigcommerce/lib/normalize.ts index 51b508edd..0e3dbc128 100644 --- a/framework/bigcommerce/lib/normalize.ts +++ b/framework/bigcommerce/lib/normalize.ts @@ -1,15 +1,14 @@ -export function normalizeProduct(productNode: any): Product { - // console.log(productNode) +import { Product as BCProduct } from '@framework/schema' + +export function normalizeProduct(productNode: BCProduct): Product { const { - node: { - entityId: id, - images, - variants, - productOptions, - prices, - path, - ...rest - }, + entityId: id, + images, + variants, + productOptions, + prices, + path, + ...rest } = productNode return { diff --git a/next.config.js b/next.config.js index ee2db68bc..e732ef78a 100644 --- a/next.config.js +++ b/next.config.js @@ -1,8 +1,4 @@ -const bundleAnalyzer = require('@next/bundle-analyzer')({ - enabled: !!process.env.BUNDLE_ANALYZE, -}) - -module.exports = bundleAnalyzer({ +module.exports = { images: { domains: ['cdn11.bigcommerce.com'], }, @@ -38,4 +34,4 @@ module.exports = bundleAnalyzer({ }, ] }, -}) +} diff --git a/package.json b/package.json index d1f669a36..a30af5b97 100644 --- a/package.json +++ b/package.json @@ -99,5 +99,8 @@ "resolutions": { "webpack": "5.11.1" }, + "node": { + "net": "empty" + }, "license": "MIT" } diff --git a/tsconfig.json b/tsconfig.json index 480cc2cb4..98639f61e 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -26,12 +26,6 @@ "@framework": ["framework/bigcommerce"] } }, - "include": [ - "next-env.d.ts", - "framework/*.d.ts", - "**/*.ts", - "**/*.tsx", - "**/*.js" - ], + "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", "**/*.js"], "exclude": ["node_modules"] } From dccc5ef430b4191aee9ce6cd55289e9264b37d64 Mon Sep 17 00:00:00 2001 From: Belen Curcio Date: Mon, 11 Jan 2021 14:13:29 -0300 Subject: [PATCH 027/216] slug --- .../product/ProductCard/ProductCard.tsx | 6 ++-- .../product/ProductView/ProductView.tsx | 15 ++++++---- framework/bigcommerce/lib/normalize.ts | 29 ++++++++++++------- framework/types.d.ts | 4 +-- 4 files changed, 34 insertions(+), 20 deletions(-) diff --git a/components/product/ProductCard/ProductCard.tsx b/components/product/ProductCard/ProductCard.tsx index b3c061a5c..658476e7d 100644 --- a/components/product/ProductCard/ProductCard.tsx +++ b/components/product/ProductCard/ProductCard.tsx @@ -57,11 +57,11 @@ const ProductCard: FC = ({ {product.price.currencyCode}
- {/* */} + variant={product.variants[0]} + />
{product?.images && ( diff --git a/components/product/ProductView/ProductView.tsx b/components/product/ProductView/ProductView.tsx index b5aafd0b1..4f9844fcc 100644 --- a/components/product/ProductView/ProductView.tsx +++ b/components/product/ProductView/ProductView.tsx @@ -25,21 +25,26 @@ interface Props { } const ProductView: FC = ({ product }) => { + console.log(product) + const addItem = useAddItem() const { price } = usePrice({ amount: product.price.value, baseAmount: product.price.retailValue, currencyCode: product.price.currencyCode!, }) + const { openSidebar } = useUI() - const options = getProductOptions(product) + + // const options = getProductOptions(product) + const [loading, setLoading] = useState(false) const [choices, setChoices] = useState({ size: null, color: null, }) - const variant = getCurrentVariant(product, choices) || product.variants[0] + // const variant = getCurrentVariant(product, choices) || product.variants[0] const addToCart = async () => { setLoading(true) @@ -106,7 +111,7 @@ const ProductView: FC = ({ product }) => {
- {options?.map((opt: any) => ( + {/* {options?.map((opt: any) => (

{opt.displayName}

@@ -133,7 +138,7 @@ const ProductView: FC = ({ product }) => { })}
- ))} + ))} */}
@@ -146,7 +151,7 @@ const ProductView: FC = ({ product }) => { className={s.button} onClick={addToCart} loading={loading} - disabled={!variant} + // disabled={!variant} > Add to Cart diff --git a/framework/bigcommerce/lib/normalize.ts b/framework/bigcommerce/lib/normalize.ts index 0e3dbc128..73c477d9a 100644 --- a/framework/bigcommerce/lib/normalize.ts +++ b/framework/bigcommerce/lib/normalize.ts @@ -13,16 +13,25 @@ export function normalizeProduct(productNode: BCProduct): Product { return { path, - slug: path?.slice(1, -1), - images: images?.edges?.map( - ({ node: { urlOriginal, altText, ...rest } }: any) => ({ - url: urlOriginal, - alt: altText, - ...rest, - }) - ), - variants: variants?.edges?.map(({ node }: any) => node), - productOptions: productOptions?.edges?.map(({ node }: any) => node), + slug: path?.replace(/^\/+|\/+$/g, ''), + images: images.edges + ? images.edges.map( + ({ node: { urlOriginal, altText, ...rest } }: any) => ({ + url: urlOriginal, + alt: altText, + ...rest, + }) + ) + : [], + variants: variants.edges + ? variants.edges.map(({ node: { entityId, ...rest } }: any) => ({ + id: entityId, + ...rest, + })) + : [], + productOptions: productOptions.edges + ? productOptions.edges.map(({ node }: any) => node) + : [], price: { value: prices?.price.value, currencyCode: prices?.price.currencyCode, diff --git a/framework/types.d.ts b/framework/types.d.ts index 1342071dd..b189d26b6 100644 --- a/framework/types.d.ts +++ b/framework/types.d.ts @@ -8,8 +8,8 @@ interface Product extends Entity { description: string slug: string path?: string - images: ProductImage[] | any[] | undefined - variants: ProductVariant[] | any[] | null | undefined + images: ProductImage[] + variants: ProductVariant[] price: ProductPrice } interface ProductImage { From 4fdaae2197238b695ab5627dca6694c5d2d3618c Mon Sep 17 00:00:00 2001 From: Belen Curcio Date: Mon, 11 Jan 2021 14:54:05 -0300 Subject: [PATCH 028/216] Normalized Options and Swatches --- components/product/ProductView/ProductView.tsx | 12 ++++-------- framework/bigcommerce/lib/normalize.ts | 17 +++++++++++++++-- framework/types.d.ts | 12 ++++++++++++ tsconfig.json | 8 +++++++- 4 files changed, 38 insertions(+), 11 deletions(-) diff --git a/components/product/ProductView/ProductView.tsx b/components/product/ProductView/ProductView.tsx index 4f9844fcc..290af8b68 100644 --- a/components/product/ProductView/ProductView.tsx +++ b/components/product/ProductView/ProductView.tsx @@ -25,8 +25,6 @@ interface Props { } const ProductView: FC = ({ product }) => { - console.log(product) - const addItem = useAddItem() const { price } = usePrice({ amount: product.price.value, @@ -36,8 +34,6 @@ const ProductView: FC = ({ product }) => { const { openSidebar } = useUI() - // const options = getProductOptions(product) - const [loading, setLoading] = useState(false) const [choices, setChoices] = useState({ size: null, @@ -111,16 +107,16 @@ const ProductView: FC = ({ product }) => {
- {/* {options?.map((opt: any) => ( + {product.options?.map((opt) => (

{opt.displayName}

- {opt.values.map((v: any, i: number) => { + {opt.values.map((v, i: number) => { const active = (choices as any)[opt.displayName] return ( = ({ product }) => { })}
- ))} */} + ))}
diff --git a/framework/bigcommerce/lib/normalize.ts b/framework/bigcommerce/lib/normalize.ts index 73c477d9a..a2be86478 100644 --- a/framework/bigcommerce/lib/normalize.ts +++ b/framework/bigcommerce/lib/normalize.ts @@ -8,6 +8,7 @@ export function normalizeProduct(productNode: BCProduct): Product { productOptions, prices, path, + options: _, ...rest } = productNode @@ -29,8 +30,20 @@ export function normalizeProduct(productNode: BCProduct): Product { ...rest, })) : [], - productOptions: productOptions.edges - ? productOptions.edges.map(({ node }: any) => node) + options: productOptions.edges + ? productOptions.edges.map( + ({ + node: { + entityId, + values: { edges }, + ...rest + }, + }: any) => ({ + id: entityId, + values: edges.map(({ node }: any) => node), + ...rest, + }) + ) : [], price: { value: prices?.price.value, diff --git a/framework/types.d.ts b/framework/types.d.ts index b189d26b6..e44f23bbb 100644 --- a/framework/types.d.ts +++ b/framework/types.d.ts @@ -11,7 +11,19 @@ interface Product extends Entity { images: ProductImage[] variants: ProductVariant[] price: ProductPrice + options: ProductOption[] } + +interface ProductOption extends Entity { + displayName: string + values: ProductOptionValues[] +} + +interface ProductOptionValues { + label: string + hexColors?: string[] +} + interface ProductImage { url: string alt?: string diff --git a/tsconfig.json b/tsconfig.json index 98639f61e..c45e16c4d 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -26,6 +26,12 @@ "@framework": ["framework/bigcommerce"] } }, - "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", "**/*.js"], + "include": [ + "next-env.d.ts", + "./framework/types.d.ts", + "**/*.ts", + "**/*.tsx", + "**/*.js" + ], "exclude": ["node_modules"] } From 9bbd7feed083d5bd7a055dd665a78f4c905f9000 Mon Sep 17 00:00:00 2001 From: Belen Curcio Date: Mon, 11 Jan 2021 15:03:04 -0300 Subject: [PATCH 029/216] Restored Add to cart --- components/product/ProductView/ProductView.tsx | 12 +++--------- components/product/Swatch/Swatch.tsx | 2 +- framework/bigcommerce/lib/normalize.ts | 4 +++- 3 files changed, 7 insertions(+), 11 deletions(-) diff --git a/components/product/ProductView/ProductView.tsx b/components/product/ProductView/ProductView.tsx index 290af8b68..2c8a456d9 100644 --- a/components/product/ProductView/ProductView.tsx +++ b/components/product/ProductView/ProductView.tsx @@ -11,11 +11,7 @@ import { Button, Container, Text } from '@components/ui' import usePrice from '@framework/product/use-price' import { useAddItem } from '@framework/cart' -import { - getCurrentVariant, - getProductOptions, - SelectedOptions, -} from '../helpers' +import { getCurrentVariant, SelectedOptions } from '../helpers' import WishlistButton from '@components/wishlist/WishlistButton' interface Props { @@ -41,13 +37,13 @@ const ProductView: FC = ({ product }) => { }) // const variant = getCurrentVariant(product, choices) || product.variants[0] - + console.log('PRODUCT VIEW', product) const addToCart = async () => { setLoading(true) try { await addItem({ productId: Number(product.id), - variantId: Number(product.variants[0].id), + variantId: Number(product.variants[0].id), // TODO(bc) send the correct variant }) openSidebar() setLoading(false) @@ -113,7 +109,6 @@ const ProductView: FC = ({ product }) => {
{opt.values.map((v, i: number) => { const active = (choices as any)[opt.displayName] - return ( = ({ product }) => { className={s.button} onClick={addToCart} loading={loading} - // disabled={!variant} > Add to Cart diff --git a/components/product/Swatch/Swatch.tsx b/components/product/Swatch/Swatch.tsx index 30c9be7c3..34244321f 100644 --- a/components/product/Swatch/Swatch.tsx +++ b/components/product/Swatch/Swatch.tsx @@ -13,7 +13,7 @@ interface Props { color?: string } -const Swatch: FC = ({ +const Swatch: FC & Props> = ({ className, color = '', label, diff --git a/framework/bigcommerce/lib/normalize.ts b/framework/bigcommerce/lib/normalize.ts index a2be86478..ad6302c2e 100644 --- a/framework/bigcommerce/lib/normalize.ts +++ b/framework/bigcommerce/lib/normalize.ts @@ -8,11 +8,13 @@ export function normalizeProduct(productNode: BCProduct): Product { productOptions, prices, path, - options: _, + id: _, + options: _0, ...rest } = productNode return { + id, path, slug: path?.replace(/^\/+|\/+$/g, ''), images: images.edges From 287e6904954e6ea8c8b501d1c04f8f38d57332ab Mon Sep 17 00:00:00 2001 From: Belen Curcio Date: Mon, 11 Jan 2021 16:16:00 -0300 Subject: [PATCH 030/216] Correct Variant Added to Cart --- .../product/ProductView/ProductView.tsx | 23 ++++++----- components/product/helpers.ts | 38 +++--------------- .../wishlist/WishlistCard/WishlistCard.tsx | 29 +++++++------- framework/bigcommerce/api/catalog/products.ts | 2 +- framework/bigcommerce/lib/normalize.ts | 40 ++++++++++++------- .../bigcommerce/wishlist/use-wishlist.tsx | 2 +- framework/types.d.ts | 7 +--- 7 files changed, 63 insertions(+), 78 deletions(-) diff --git a/components/product/ProductView/ProductView.tsx b/components/product/ProductView/ProductView.tsx index 2c8a456d9..7151208ac 100644 --- a/components/product/ProductView/ProductView.tsx +++ b/components/product/ProductView/ProductView.tsx @@ -11,7 +11,7 @@ import { Button, Container, Text } from '@components/ui' import usePrice from '@framework/product/use-price' import { useAddItem } from '@framework/cart' -import { getCurrentVariant, SelectedOptions } from '../helpers' +import { getVariant, SelectedOptions } from '../helpers' import WishlistButton from '@components/wishlist/WishlistButton' interface Props { @@ -27,23 +27,24 @@ const ProductView: FC = ({ product }) => { baseAmount: product.price.retailValue, currencyCode: product.price.currencyCode!, }) - const { openSidebar } = useUI() - const [loading, setLoading] = useState(false) const [choices, setChoices] = useState({ size: null, color: null, }) - // const variant = getCurrentVariant(product, choices) || product.variants[0] - console.log('PRODUCT VIEW', product) + // Select the correct variant based on choices + const variant = getVariant(product, choices) + const addToCart = async () => { setLoading(true) try { await addItem({ productId: Number(product.id), - variantId: Number(product.variants[0].id), // TODO(bc) send the correct variant + variantId: variant + ? Number(variant.id) + : Number(product.variants[0].id), }) openSidebar() setLoading(false) @@ -108,11 +109,14 @@ const ProductView: FC = ({ product }) => {

{opt.displayName}

{opt.values.map((v, i: number) => { - const active = (choices as any)[opt.displayName] + const active = (choices as any)[ + opt.displayName.toLowerCase() + ] + return ( = ({ product }) => { setChoices((choices) => { return { ...choices, - [opt.displayName]: v.label, + [opt.displayName.toLowerCase()]: v.label.toLowerCase(), } }) }} @@ -142,6 +146,7 @@ const ProductView: FC = ({ product }) => { className={s.button} onClick={addToCart} loading={loading} + disabled={!variant} > Add to Cart diff --git a/components/product/helpers.ts b/components/product/helpers.ts index eda8d434a..57c37dbc8 100644 --- a/components/product/helpers.ts +++ b/components/product/helpers.ts @@ -1,5 +1,3 @@ -import type { ProductNode } from '@framework/api/operations/get-product' - export type SelectedOptions = { size: string | null color: string | null @@ -10,42 +8,18 @@ export type ProductOption = { values: any } -// Returns the available options of a product -export function getProductOptions(product: ProductNode) { - const options = product.productOptions.edges?.reduce( - (arr, edge) => { - if (edge?.node.__typename === 'MultipleChoiceOption') { - arr.push({ - displayName: edge.node.displayName.toLowerCase(), - values: edge.node.values.edges?.map((edge) => edge?.node), - }) - } - return arr - }, - [] - ) - - return options -} - -// Finds a variant in the product that matches the selected options -export function getCurrentVariant(product: ProductNode, opts: SelectedOptions) { - const variant = product.variants.edges?.find((edge) => { - const { node } = edge ?? {} - +export function getVariant(product: Product, opts: SelectedOptions) { + const variant = product.variants.find((variant) => { return Object.entries(opts).every(([key, value]) => - node?.productOptions.edges?.find((edge) => { + variant.options.find((option) => { if ( - edge?.node.__typename === 'MultipleChoiceOption' && - edge.node.displayName.toLowerCase() === key + option.__typename === 'MultipleChoiceOption' && + option.displayName.toLowerCase() === key.toLowerCase() ) { - return edge.node.values.edges?.find( - (valueEdge) => valueEdge?.node.label === value - ) + return option.values.find((v) => v.label.toLowerCase() === value) } }) ) }) - return variant } diff --git a/components/wishlist/WishlistCard/WishlistCard.tsx b/components/wishlist/WishlistCard/WishlistCard.tsx index b9b1a2f3e..82147f575 100644 --- a/components/wishlist/WishlistCard/WishlistCard.tsx +++ b/components/wishlist/WishlistCard/WishlistCard.tsx @@ -2,21 +2,20 @@ import { FC, useState } from 'react' import cn from 'classnames' import Link from 'next/link' import Image from 'next/image' -import type { WishlistItem } from '@framework/api/wishlist' -import usePrice from '@framework/product/use-price' -import useRemoveItem from '@framework/wishlist/use-remove-item' -import useAddItem from '@framework/cart/use-add-item' -import { useUI } from '@components/ui/context' -import { Button, Text } from '@components/ui' -import { Trash } from '@components/icons' import s from './WishlistCard.module.css' +import { Trash } from '@components/icons' +import { Button, Text } from '@components/ui' + +import { useUI } from '@components/ui/context' +import usePrice from '@framework/product/use-price' +import useAddItem from '@framework/cart/use-add-item' +import useRemoveItem from '@framework/wishlist/use-remove-item' interface Props { - item: WishlistItem + product: Product } -const WishlistCard: FC = ({ item }) => { - const product = item.product! +const WishlistCard: FC = ({ product }) => { const { price } = usePrice({ amount: product.prices?.price?.value, baseAmount: product.prices?.retailPrice?.value, @@ -34,7 +33,7 @@ const WishlistCard: FC = ({ item }) => { try { // If this action succeeds then there's no need to do `setRemoving(true)` // because the component will be removed from the view - await removeItem({ id: item.id! }) + await removeItem({ id: product.id! }) } catch (error) { setRemoving(false) } @@ -43,8 +42,8 @@ const WishlistCard: FC = ({ item }) => { setLoading(true) try { await addItem({ - productId: product.entityId, - variantId: product.variants.edges?.[0]?.node.entityId!, + productId: Number(product.id), + variantId: Number(product.variants[0].id), }) openSidebar() setLoading(false) @@ -57,10 +56,10 @@ const WishlistCard: FC = ({ item }) => {
{product.images.edges?.[0]?.node.altText
diff --git a/framework/bigcommerce/api/catalog/products.ts b/framework/bigcommerce/api/catalog/products.ts index 0e3690e55..7456fc3ac 100644 --- a/framework/bigcommerce/api/catalog/products.ts +++ b/framework/bigcommerce/api/catalog/products.ts @@ -21,7 +21,7 @@ export type ProductsHandlers = { const METHODS = ['GET'] -// TODO: a complete implementation should have schema validation for `req.body` +// TODO(lf): a complete implementation should have schema validation for `req.body` const productsApi: BigcommerceApiHandler< SearchProductsData, ProductsHandlers diff --git a/framework/bigcommerce/lib/normalize.ts b/framework/bigcommerce/lib/normalize.ts index ad6302c2e..5e3992d4b 100644 --- a/framework/bigcommerce/lib/normalize.ts +++ b/framework/bigcommerce/lib/normalize.ts @@ -1,5 +1,19 @@ import { Product as BCProduct } from '@framework/schema' +function productOptionNormalize({ + node: { + entityId, + values: { edges }, + ...rest + }, +}: any) { + return { + id: entityId, + values: edges.map(({ node }: any) => node), + ...rest, + } +} + export function normalizeProduct(productNode: BCProduct): Product { const { entityId: id, @@ -10,6 +24,7 @@ export function normalizeProduct(productNode: BCProduct): Product { path, id: _, options: _0, + brand, ...rest } = productNode @@ -27,26 +42,21 @@ export function normalizeProduct(productNode: BCProduct): Product { ) : [], variants: variants.edges - ? variants.edges.map(({ node: { entityId, ...rest } }: any) => ({ - id: entityId, - ...rest, - })) - : [], - options: productOptions.edges - ? productOptions.edges.map( - ({ - node: { - entityId, - values: { edges }, - ...rest - }, - }: any) => ({ + ? variants.edges.map( + ({ node: { entityId, productOptions, ...rest } }: any) => ({ id: entityId, - values: edges.map(({ node }: any) => node), + options: productOptions.edges.map(productOptionNormalize), ...rest, }) ) : [], + options: productOptions.edges + ? productOptions.edges.map(productOptionNormalize) + : [], + brand: { + id: brand?.entityId, + ...brand, + }, price: { value: prices?.price.value, currencyCode: prices?.price.currencyCode, diff --git a/framework/bigcommerce/wishlist/use-wishlist.tsx b/framework/bigcommerce/wishlist/use-wishlist.tsx index 6ebc8459d..0e1671039 100644 --- a/framework/bigcommerce/wishlist/use-wishlist.tsx +++ b/framework/bigcommerce/wishlist/use-wishlist.tsx @@ -46,7 +46,7 @@ export function extendHook( const response = useCommerceWishlist( defaultOpts, [ - ['customerId', customer?.entityId], + ['customerId', customer?.id], ['includeProducts', includeProducts], ], customFetcher, diff --git a/framework/types.d.ts b/framework/types.d.ts index e44f23bbb..e020ba893 100644 --- a/framework/types.d.ts +++ b/framework/types.d.ts @@ -31,6 +31,7 @@ interface ProductImage { interface ProductVariant { id: string | number + options: ProductOption[] } interface ProductPrice { @@ -51,21 +52,17 @@ interface Wishlist extends Entity { interface Order {} -interface Customer extends Entity { - [prop: string]: any -} +interface Customer extends Entity {} type UseCustomerResponse = { customer: Customer } | null interface Category extends Entity { - id: string name: string } interface Brand extends Entity { - id: string name: string } From fc34856e506a4d8186e792b6845617968e34f4c6 Mon Sep 17 00:00:00 2001 From: Belen Curcio Date: Tue, 12 Jan 2021 16:59:07 -0300 Subject: [PATCH 031/216] Normalizing Cart Responses --- .../cart/CartSidebarView/CartSidebarView.tsx | 1 + components/common/Layout/Layout.tsx | 5 ++- components/product/helpers.ts | 5 --- framework/bigcommerce/cart/use-cart.tsx | 3 +- framework/bigcommerce/lib/normalize.ts | 22 +++++++--- framework/commerce/cart/use-cart.tsx | 2 +- framework/types.d.ts | 5 ++- pages/cart.tsx | 41 ++++++++++++------- 8 files changed, 54 insertions(+), 30 deletions(-) diff --git a/components/cart/CartSidebarView/CartSidebarView.tsx b/components/cart/CartSidebarView/CartSidebarView.tsx index ca73a6ec3..466ef15b6 100644 --- a/components/cart/CartSidebarView/CartSidebarView.tsx +++ b/components/cart/CartSidebarView/CartSidebarView.tsx @@ -12,6 +12,7 @@ import s from './CartSidebarView.module.css' const CartSidebarView: FC = () => { const { closeSidebar } = useUI() const { data, isEmpty } = useCart() + const { price: subTotal } = usePrice( data && { amount: data.base_amount, diff --git a/components/common/Layout/Layout.tsx b/components/common/Layout/Layout.tsx index ff8467a23..f4dac69ac 100644 --- a/components/common/Layout/Layout.tsx +++ b/components/common/Layout/Layout.tsx @@ -7,13 +7,12 @@ import { useUI } from '@components/ui/context' import { Navbar, Footer } from '@components/common' import { useAcceptCookies } from '@lib/hooks/useAcceptCookies' import { Sidebar, Button, Modal, LoadingDots } from '@components/ui' -import { CartSidebarView } from '@components/cart' +import CartSidebarView from '@components/cart/CartSidebarView' import LoginView from '@components/auth/LoginView' import { CommerceProvider } from '@framework' import type { Page } from '@framework/api/operations/get-all-pages' - const Loading = () => (
@@ -28,10 +27,12 @@ const SignUpView = dynamic( () => import('@components/auth/SignUpView'), dynamicProps ) + const ForgotPassword = dynamic( () => import('@components/auth/ForgotPassword'), dynamicProps ) + const FeatureBar = dynamic( () => import('@components/common/FeatureBar'), dynamicProps diff --git a/components/product/helpers.ts b/components/product/helpers.ts index 57c37dbc8..ae0c43530 100644 --- a/components/product/helpers.ts +++ b/components/product/helpers.ts @@ -3,11 +3,6 @@ export type SelectedOptions = { color: string | null } -export type ProductOption = { - displayName: string - values: any -} - export function getVariant(product: Product, opts: SelectedOptions) { const variant = product.variants.find((variant) => { return Object.entries(opts).every(([key, value]) => diff --git a/framework/bigcommerce/cart/use-cart.tsx b/framework/bigcommerce/cart/use-cart.tsx index 83743096e..54582372f 100644 --- a/framework/bigcommerce/cart/use-cart.tsx +++ b/framework/bigcommerce/cart/use-cart.tsx @@ -2,6 +2,7 @@ import type { HookFetcher } from '@commerce/utils/types' import type { SwrOptions } from '@commerce/utils/use-data' import useCommerceCart, { CartInput } from '@commerce/cart/use-cart' import type { Cart } from '../api/cart' +import { normalizeCart } from '../lib/normalize' const defaultOpts = { url: '/api/bigcommerce/cart', @@ -39,7 +40,7 @@ export function extendHook( set: (x) => x, }) - return response + return normalizeCart(response) } useCart.extend = extendHook diff --git a/framework/bigcommerce/lib/normalize.ts b/framework/bigcommerce/lib/normalize.ts index 5e3992d4b..686581b9f 100644 --- a/framework/bigcommerce/lib/normalize.ts +++ b/framework/bigcommerce/lib/normalize.ts @@ -1,6 +1,6 @@ import { Product as BCProduct } from '@framework/schema' -function productOptionNormalize({ +function normalizeProductOption({ node: { entityId, values: { edges }, @@ -9,7 +9,7 @@ function productOptionNormalize({ }: any) { return { id: entityId, - values: edges.map(({ node }: any) => node), + values: edges?.map(({ node }: any) => node), ...rest, } } @@ -45,16 +45,18 @@ export function normalizeProduct(productNode: BCProduct): Product { ? variants.edges.map( ({ node: { entityId, productOptions, ...rest } }: any) => ({ id: entityId, - options: productOptions.edges.map(productOptionNormalize), + options: productOptions?.edges + ? productOptions.edges.map(normalizeProductOption) + : [], ...rest, }) ) : [], options: productOptions.edges - ? productOptions.edges.map(productOptionNormalize) + ? productOptions?.edges.map(normalizeProductOption) : [], brand: { - id: brand?.entityId, + id: brand?.entityId ? brand?.entityId : null, ...brand, }, price: { @@ -64,3 +66,13 @@ export function normalizeProduct(productNode: BCProduct): Product { ...rest, } } + +export function normalizeCart({ data, ...rest }: any) { + return { + ...rest, + data: { + products: data?.line_items?.physical_items ?? [], + ...data, + }, + } +} diff --git a/framework/commerce/cart/use-cart.tsx b/framework/commerce/cart/use-cart.tsx index 8aefc3e68..f280923a6 100644 --- a/framework/commerce/cart/use-cart.tsx +++ b/framework/commerce/cart/use-cart.tsx @@ -9,7 +9,7 @@ export type CartResponse = responseInterface & { } export type CartInput = { - cartId: string | undefined + cartId: Cart['id'] } export default function useCart( diff --git a/framework/types.d.ts b/framework/types.d.ts index e020ba893..7d79b6c80 100644 --- a/framework/types.d.ts +++ b/framework/types.d.ts @@ -42,7 +42,10 @@ interface ProductPrice { } interface Cart extends Entity { - id: string + id: string | undefined + currency: { code: string } + taxIncluded?: boolean + totalAmmount: number | string products: Pick[] } diff --git a/pages/cart.tsx b/pages/cart.tsx index fc06c4ced..a9e24edf2 100644 --- a/pages/cart.tsx +++ b/pages/cart.tsx @@ -22,23 +22,34 @@ export async function getStaticProps({ export default function Cart() { const { data, isEmpty } = useCart() - const { price: subTotal } = usePrice( - data && { - amount: data.base_amount, - currencyCode: data.currency.code, - } - ) - const { price: total } = usePrice( - data && { - amount: data.cart_amount, - currencyCode: data.currency.code, - } - ) + const loading = !data - const items = data?.line_items.physical_items ?? [] + if (loading) { + // Load skeleton + return
Loading
+ } - const error = null - const success = null + console.log('Cart Data', data) + + // const { price: subTotal } = usePrice( + // data && { + // amount: data.base_amount, + // currencyCode: data.currency.code, + // } + // ) + // const { price: total } = usePrice( + // data && { + // amount: data.cart_amount, + // currencyCode: data.currency.code, + // } + // ) + + // const items = data?.line_items.physical_items ?? [] + + // const error = null + // const success = null + + return
hola
return (
From 7f70cfd868c6224e293061e8ba4158d9bd92fe28 Mon Sep 17 00:00:00 2001 From: Belen Curcio Date: Thu, 14 Jan 2021 12:58:41 -0300 Subject: [PATCH 032/216] Changes --- components/cart/CartItem/CartItem.tsx | 15 ++++--- .../cart/CartSidebarView/CartSidebarView.tsx | 8 ++-- .../product/ProductView/ProductView.tsx | 2 +- .../api/catalog/handlers/get-products.ts | 12 +++-- framework/bigcommerce/api/catalog/products.ts | 4 +- .../api/operations/get-all-products.ts | 2 +- .../bigcommerce/api/operations/get-product.ts | 2 +- framework/bigcommerce/lib/normalize.ts | 44 +++++++++++++++++-- framework/types.d.ts | 19 ++++++-- package.json | 1 + pages/cart.tsx | 26 +++++------ pages/index2.tsx | 7 --- pages/search.tsx | 42 ++++++++++-------- tsconfig.json | 2 +- yarn.lock | 5 +++ 15 files changed, 124 insertions(+), 67 deletions(-) delete mode 100644 pages/index2.tsx diff --git a/components/cart/CartItem/CartItem.tsx b/components/cart/CartItem/CartItem.tsx index ac78d1849..2337c871c 100644 --- a/components/cart/CartItem/CartItem.tsx +++ b/components/cart/CartItem/CartItem.tsx @@ -12,7 +12,7 @@ const CartItem = ({ item, currencyCode, }: { - item: any + item: CartItem currencyCode: string }) => { const { price } = usePrice({ @@ -55,7 +55,7 @@ const CartItem = ({ try { // If this action succeeds then there's no need to do `setRemoving(true)` // because the component will be removed from the view - await removeItem({ id: item.id }) + await removeItem({ id: String(item.id) }) } catch (error) { setRemoving(false) } @@ -77,16 +77,14 @@ const CartItem = ({
Product Image
- {/** TODO: Replace this. No `path` found at Cart */} {item.name} @@ -115,7 +113,10 @@ const CartItem = ({
{price} -
diff --git a/components/cart/CartSidebarView/CartSidebarView.tsx b/components/cart/CartSidebarView/CartSidebarView.tsx index 466ef15b6..19c6964d7 100644 --- a/components/cart/CartSidebarView/CartSidebarView.tsx +++ b/components/cart/CartSidebarView/CartSidebarView.tsx @@ -16,19 +16,17 @@ const CartSidebarView: FC = () => { const { price: subTotal } = usePrice( data && { amount: data.base_amount, - currencyCode: data.currency.code, + currencyCode: data.currency?.code || 'USD', } ) const { price: total } = usePrice( data && { amount: data.cart_amount, - currencyCode: data.currency.code, + currencyCode: data.currency?.code || 'USD', } ) const handleClose = () => closeSidebar() - const items = data?.line_items.physical_items ?? [] - const error = null const success = null @@ -95,7 +93,7 @@ const CartSidebarView: FC = () => { My Cart
    - {items.map((item: any) => ( + {data.products.map((item: any) => ( = ({ product }) => { className={s.button} onClick={addToCart} loading={loading} - disabled={!variant} + disabled={!variant && product.options.length > 0} > Add to Cart diff --git a/framework/bigcommerce/api/catalog/handlers/get-products.ts b/framework/bigcommerce/api/catalog/handlers/get-products.ts index b05548e40..f99d82729 100644 --- a/framework/bigcommerce/api/catalog/handlers/get-products.ts +++ b/framework/bigcommerce/api/catalog/handlers/get-products.ts @@ -1,3 +1,4 @@ +import { Product } from 'framework/types' import getAllProducts, { ProductEdge } from '../../operations/get-all-products' import type { ProductsHandlers } from '../products' @@ -6,6 +7,7 @@ const SORT: { [key: string]: string | undefined } = { trending: 'total_sold', price: 'price', } + const LIMIT = 12 // Return current cart info @@ -44,21 +46,25 @@ const getProducts: ProductsHandlers['getProducts'] = async ({ const { data } = await config.storeApiFetch<{ data: { id: number }[] }>( url.pathname + url.search ) + const entityIds = data.map((p) => p.id) const found = entityIds.length > 0 + // We want the GraphQL version of each product const graphqlData = await getAllProducts({ variables: { first: LIMIT, entityIds }, config, }) + // Put the products in an object that we can use to get them by id const productsById = graphqlData.products.reduce<{ - [k: number]: ProductEdge + [k: number]: Product }>((prods, p) => { - prods[p.node.entityId] = p + prods[p.id] = p return prods }, {}) - const products: ProductEdge[] = found ? [] : graphqlData.products + + const products: Product[] = found ? [] : graphqlData.products // Populate the products array with the graphql products, in the order // assigned by the list of entity ids diff --git a/framework/bigcommerce/api/catalog/products.ts b/framework/bigcommerce/api/catalog/products.ts index 7456fc3ac..fe5b807c6 100644 --- a/framework/bigcommerce/api/catalog/products.ts +++ b/framework/bigcommerce/api/catalog/products.ts @@ -4,11 +4,11 @@ import createApiHandler, { BigcommerceHandler, } from '../utils/create-api-handler' import { BigcommerceApiError } from '../utils/errors' -import type { ProductEdge } from '../operations/get-all-products' import getProducts from './handlers/get-products' +import { Product } from 'framework/types' export type SearchProductsData = { - products: ProductEdge[] + products: Product[] found: boolean } diff --git a/framework/bigcommerce/api/operations/get-all-products.ts b/framework/bigcommerce/api/operations/get-all-products.ts index 60aa197cc..3cfb77b7c 100644 --- a/framework/bigcommerce/api/operations/get-all-products.ts +++ b/framework/bigcommerce/api/operations/get-all-products.ts @@ -127,7 +127,7 @@ async function getAllProducts({ }) } - return { products: products.map(({ node }) => normalizeProduct(node)) } + return { products: products.map(({ node }) => normalizeProduct(node as any)) } } export default getAllProducts diff --git a/framework/bigcommerce/api/operations/get-product.ts b/framework/bigcommerce/api/operations/get-product.ts index aa480ac5e..4d34d86a0 100644 --- a/framework/bigcommerce/api/operations/get-product.ts +++ b/framework/bigcommerce/api/operations/get-product.ts @@ -111,7 +111,7 @@ async function getProduct({ setProductLocaleMeta(product) } - return { product: normalizeProduct(product) } + return { product: normalizeProduct(product as any) } } return {} diff --git a/framework/bigcommerce/lib/normalize.ts b/framework/bigcommerce/lib/normalize.ts index 686581b9f..950177e73 100644 --- a/framework/bigcommerce/lib/normalize.ts +++ b/framework/bigcommerce/lib/normalize.ts @@ -1,4 +1,5 @@ -import { Product as BCProduct } from '@framework/schema' +import { Cart, CartItem, Product } from '../../types' +import { Product as BigCommerceProduct } from '@framework/schema' function normalizeProductOption({ node: { @@ -14,7 +15,7 @@ function normalizeProductOption({ } } -export function normalizeProduct(productNode: BCProduct): Product { +export function normalizeProduct(productNode: BigCommerceProduct): Product { const { entityId: id, images, @@ -67,12 +68,47 @@ export function normalizeProduct(productNode: BCProduct): Product { } } -export function normalizeCart({ data, ...rest }: any) { +export function normalizeCart({ data, ...rest }: any): Cart { return { ...rest, data: { - products: data?.line_items?.physical_items ?? [], + products: data?.line_items?.physical_items.map(itemsToProducts) ?? [], ...data, }, } } + +function itemsToProducts({ + id, + name, + quantity, + product_id, + variant_id, + image_url, + list_price, + sale_price, + extended_list_price, + extended_sale_price, + ...rest +}: any): CartItem { + return { + id, + name, + prices: { + listPrice: list_price, + salePrice: sale_price, + extendedListPrice: extended_list_price, + extendedSalePrice: extended_sale_price, + }, + images: [ + { + alt: name, + url: image_url, + }, + ], + productId: product_id, + variantId: variant_id, + quantity, + ...rest, + } +} diff --git a/framework/types.d.ts b/framework/types.d.ts index 7d79b6c80..7a4c45359 100644 --- a/framework/types.d.ts +++ b/framework/types.d.ts @@ -1,3 +1,5 @@ +import { CartItem } from '@components/cart' + interface Entity { id: string | number [prop: string]: any @@ -12,6 +14,7 @@ interface Product extends Entity { variants: ProductVariant[] price: ProductPrice options: ProductOption[] + sku?: string } interface ProductOption extends Entity { @@ -37,8 +40,11 @@ interface ProductVariant { interface ProductPrice { value: number currencyCode: 'USD' | 'ARS' | string | undefined - retailValue?: number - saleValue?: number + retailPrice?: number + salePrice?: number + listPrice?: number + extendedSalePrice?: number + extendedListPrice?: number } interface Cart extends Entity { @@ -46,7 +52,14 @@ interface Cart extends Entity { currency: { code: string } taxIncluded?: boolean totalAmmount: number | string - products: Pick[] + products: Pick & CartItem[] +} + +interface CartItem extends Entity { + quantity: number + productId: Product['id'] + variantId: ProductVariant['id'] + images: ProductImage[] } interface Wishlist extends Entity { diff --git a/package.json b/package.json index a30af5b97..edabd234f 100644 --- a/package.json +++ b/package.json @@ -60,6 +60,7 @@ "next": "^10.0.5", "next-seo": "^4.11.0", "next-themes": "^0.0.4", + "normalizr": "^3.6.1", "postcss-nesting": "^7.0.1", "react": "^16.14.0", "react-dom": "^16.14.0", diff --git a/pages/cart.tsx b/pages/cart.tsx index a9e24edf2..57b92db27 100644 --- a/pages/cart.tsx +++ b/pages/cart.tsx @@ -29,20 +29,18 @@ export default function Cart() { return
    Loading
    } - console.log('Cart Data', data) - - // const { price: subTotal } = usePrice( - // data && { - // amount: data.base_amount, - // currencyCode: data.currency.code, - // } - // ) - // const { price: total } = usePrice( - // data && { - // amount: data.cart_amount, - // currencyCode: data.currency.code, - // } - // ) + const { price: subTotal } = usePrice( + data && { + amount: data.base_amount, + currencyCode: data.currency.code, + } + ) + const { price: total } = usePrice( + data && { + amount: data.cart_amount, + currencyCode: data.currency.code, + } + ) // const items = data?.line_items.physical_items ?? [] diff --git a/pages/index2.tsx b/pages/index2.tsx deleted file mode 100644 index 9b94444e1..000000000 --- a/pages/index2.tsx +++ /dev/null @@ -1,7 +0,0 @@ -import { Layout } from '@components/common' - -export default function Home() { - return <>Hello -} - -Home.Layout = Layout diff --git a/pages/search.tsx b/pages/search.tsx index 18b0d9c1a..d9367239f 100644 --- a/pages/search.tsx +++ b/pages/search.tsx @@ -3,16 +3,29 @@ import type { GetStaticPropsContext, InferGetStaticPropsType } from 'next' import Link from 'next/link' import { useState } from 'react' import { useRouter } from 'next/router' -import { getConfig } from '@framework/api' -import getAllPages from '@framework/api/operations/get-all-pages' -import getSiteInfo from '@framework/api/operations/get-site-info' -import useSearch from '@framework/product/use-search' + import { Layout } from '@components/common' import { ProductCard } from '@components/product' import { Container, Grid, Skeleton } from '@components/ui' +import { getConfig } from '@framework/api' +import getAllPages from '@framework/api/operations/get-all-pages' +import getSiteInfo from '@framework/api/operations/get-site-info' +import useSearch from '@framework/product/use-search' + import rangeMap from '@lib/range-map' + +// TODO(bc) Remove this. This should come from the API import getSlug from '@lib/get-slug' + +// TODO (bc) : Remove or standarize this. +const SORT = Object.entries({ + 'latest-desc': 'Latest arrivals', + 'trending-desc': 'Trending', + 'price-asc': 'Price: Low to high', + 'price-desc': 'Price: High to low', +}) + import { filterQuery, getCategoryPath, @@ -27,19 +40,11 @@ export async function getStaticProps({ const config = getConfig({ locale }) const { pages } = await getAllPages({ config, preview }) const { categories, brands } = await getSiteInfo({ config, preview }) - return { props: { pages, categories, brands }, } } -const SORT = Object.entries({ - 'latest-desc': 'Latest arrivals', - 'trending-desc': 'Trending', - 'price-asc': 'Price: Low to high', - 'price-desc': 'Price: High to low', -}) - export default function Search({ categories, brands, @@ -76,7 +81,6 @@ export default function Search({ } else { setToggleFilter(!toggleFilter) } - setActiveFilter(filter) } @@ -333,14 +337,16 @@ export default function Search({ {data ? ( - {data.products.map(({ node }) => ( + {data.products.map((product) => ( ))} diff --git a/tsconfig.json b/tsconfig.json index c45e16c4d..d80fe8ba8 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -28,7 +28,7 @@ }, "include": [ "next-env.d.ts", - "./framework/types.d.ts", + "framework/types.d.ts", "**/*.ts", "**/*.tsx", "**/*.js" diff --git a/yarn.lock b/yarn.lock index 769c2e077..4db1aba12 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5195,6 +5195,11 @@ normalize.css@^8.0.1: resolved "https://registry.yarnpkg.com/normalize.css/-/normalize.css-8.0.1.tgz#9b98a208738b9cc2634caacbc42d131c97487bf3" integrity sha512-qizSNPO93t1YUuUhP22btGOo3chcvDFqFaj2TRybP0DMxkHOCTYwp3n34fel4a31ORXy4m1Xq0Gyqpb5m33qIg== +normalizr@^3.6.1: + version "3.6.1" + resolved "https://registry.yarnpkg.com/normalizr/-/normalizr-3.6.1.tgz#d367ab840e031ff382141b8d81ce279292ff69fe" + integrity sha512-8iEmqXmPtll8PwbEFrbPoDxVw7MKnNvt3PZzR2Xvq9nggEEOgBlNICPXYzyZ4w4AkHUzCU998mdatER3n2VaMA== + npmlog@^4.0.1, npmlog@^4.1.2: version "4.1.2" resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" From de0ba8cee8108794521a58c3579fc56b7a7663d3 Mon Sep 17 00:00:00 2001 From: Belen Curcio Date: Sun, 17 Jan 2021 12:53:34 -0300 Subject: [PATCH 033/216] changes breaking --- components/cart/CartItem/CartItem.tsx | 9 +++++---- components/common/Footer/Footer.tsx | 2 +- components/common/Layout/Layout.tsx | 2 +- .../api/catalog/handlers/get-products.ts | 2 +- .../bigcommerce/api/customers/handlers/login.ts | 2 +- .../bigcommerce/api/customers/handlers/signup.ts | 2 +- .../api/utils/set-product-locale-meta.ts | 2 +- .../bigcommerce/api/wishlist/handlers/add-item.ts | 4 ++-- .../api/wishlist/handlers/get-wishlist.ts | 4 ++-- .../api/wishlist/handlers/remove-item.ts | 4 ++-- framework/bigcommerce/api/wishlist/index.ts | 2 +- .../bigcommerce/{api/operations => auth}/login.ts | 8 ++++---- .../{api/operations => common}/get-all-pages.ts | 6 +++--- .../{api/operations => common}/get-page.ts | 6 +++--- .../{api/operations => common}/get-site-info.ts | 10 +++++----- .../operations => customer}/get-customer-id.ts | 4 ++-- .../get-customer-wishlist.ts | 8 ++++---- .../get-all-product-paths.ts | 8 ++++---- .../operations => product}/get-all-products.ts | 14 +++++++------- .../{api/operations => product}/get-product.ts | 8 ++++---- framework/bigcommerce/product/index.ts | 4 ++-- package.json | 5 +++-- pages/[...pages].tsx | 4 ++-- pages/blog.tsx | 2 +- pages/cart.tsx | 2 +- pages/index.tsx | 6 +++--- pages/orders.tsx | 2 +- pages/product/[slug].tsx | 6 +++--- pages/profile.tsx | 2 +- pages/search.tsx | 4 ++-- pages/wishlist.tsx | 2 +- tsconfig.json | 2 +- yarn.lock | 15 ++++++++++++++- 33 files changed, 89 insertions(+), 74 deletions(-) rename framework/bigcommerce/{api/operations => auth}/login.ts (88%) rename framework/bigcommerce/{api/operations => common}/get-all-pages.ts (83%) rename framework/bigcommerce/{api/operations => common}/get-page.ts (85%) rename framework/bigcommerce/{api/operations => common}/get-site-info.ts (89%) rename framework/bigcommerce/{api/operations => customer}/get-customer-id.ts (84%) rename framework/bigcommerce/{api/operations => customer}/get-customer-wishlist.ts (89%) rename framework/bigcommerce/{api/operations => product}/get-all-product-paths.ts (89%) rename framework/bigcommerce/{api/operations => product}/get-all-products.ts (88%) rename framework/bigcommerce/{api/operations => product}/get-product.ts (93%) diff --git a/components/cart/CartItem/CartItem.tsx b/components/cart/CartItem/CartItem.tsx index 2337c871c..c5a48c8e6 100644 --- a/components/cart/CartItem/CartItem.tsx +++ b/components/cart/CartItem/CartItem.tsx @@ -2,13 +2,14 @@ import { ChangeEvent, useEffect, useState } from 'react' import cn from 'classnames' import Image from 'next/image' import Link from 'next/link' +import s from './CartItem.module.css' import { Trash, Plus, Minus } from '@components/icons' import usePrice from '@framework/product/use-price' import useUpdateItem from '@framework/cart/use-update-item' import useRemoveItem from '@framework/cart/use-remove-item' -import s from './CartItem.module.css' +import { CartItem } from 'framework/types' -const CartItem = ({ +const Item = ({ item, currencyCode, }: { @@ -31,7 +32,7 @@ const CartItem = ({ const val = Number(e.target.value) if (Number.isInteger(val) && val >= 0) { - setQuantity(e.target.value) + setQuantity(Number(e.target.value)) } } const handleBlur = () => { @@ -124,4 +125,4 @@ const CartItem = ({ ) } -export default CartItem +export default Item diff --git a/components/common/Footer/Footer.tsx b/components/common/Footer/Footer.tsx index c90b4886f..75b2806ef 100644 --- a/components/common/Footer/Footer.tsx +++ b/components/common/Footer/Footer.tsx @@ -2,7 +2,7 @@ import { FC } from 'react' import cn from 'classnames' import Link from 'next/link' import { useRouter } from 'next/router' -import type { Page } from '@framework/api/operations/get-all-pages' +import type { Page } from '@framework/common/get-all-pages' import getSlug from '@lib/get-slug' import { Github, Vercel } from '@components/icons' import { Logo, Container } from '@components/ui' diff --git a/components/common/Layout/Layout.tsx b/components/common/Layout/Layout.tsx index f4dac69ac..0490dbb19 100644 --- a/components/common/Layout/Layout.tsx +++ b/components/common/Layout/Layout.tsx @@ -11,7 +11,7 @@ import CartSidebarView from '@components/cart/CartSidebarView' import LoginView from '@components/auth/LoginView' import { CommerceProvider } from '@framework' -import type { Page } from '@framework/api/operations/get-all-pages' +import type { Page } from '@framework/common/get-all-pages' const Loading = () => (
    diff --git a/framework/bigcommerce/api/catalog/handlers/get-products.ts b/framework/bigcommerce/api/catalog/handlers/get-products.ts index f99d82729..894dc5cf3 100644 --- a/framework/bigcommerce/api/catalog/handlers/get-products.ts +++ b/framework/bigcommerce/api/catalog/handlers/get-products.ts @@ -1,5 +1,5 @@ import { Product } from 'framework/types' -import getAllProducts, { ProductEdge } from '../../operations/get-all-products' +import getAllProducts, { ProductEdge } from '../../../product/get-all-products' import type { ProductsHandlers } from '../products' const SORT: { [key: string]: string | undefined } = { diff --git a/framework/bigcommerce/api/customers/handlers/login.ts b/framework/bigcommerce/api/customers/handlers/login.ts index c4062f6cc..9e019f3a0 100644 --- a/framework/bigcommerce/api/customers/handlers/login.ts +++ b/framework/bigcommerce/api/customers/handlers/login.ts @@ -1,5 +1,5 @@ import { FetcherError } from '@commerce/utils/errors' -import login from '../../operations/login' +import login from '../../../auth/login' import type { LoginHandlers } from '../login' const invalidCredentials = /invalid credentials/i diff --git a/framework/bigcommerce/api/customers/handlers/signup.ts b/framework/bigcommerce/api/customers/handlers/signup.ts index ff45adadb..1b24db0cc 100644 --- a/framework/bigcommerce/api/customers/handlers/signup.ts +++ b/framework/bigcommerce/api/customers/handlers/signup.ts @@ -1,5 +1,5 @@ import { BigcommerceApiError } from '../../utils/errors' -import login from '../../operations/login' +import login from '../../../auth/login' import { SignupHandlers } from '../signup' const signup: SignupHandlers['signup'] = async ({ diff --git a/framework/bigcommerce/api/utils/set-product-locale-meta.ts b/framework/bigcommerce/api/utils/set-product-locale-meta.ts index 767286477..974a197bd 100644 --- a/framework/bigcommerce/api/utils/set-product-locale-meta.ts +++ b/framework/bigcommerce/api/utils/set-product-locale-meta.ts @@ -1,4 +1,4 @@ -import type { ProductNode } from '../operations/get-all-products' +import type { ProductNode } from '../../product/get-all-products' import type { RecursivePartial } from './types' export default function setProductLocaleMeta( diff --git a/framework/bigcommerce/api/wishlist/handlers/add-item.ts b/framework/bigcommerce/api/wishlist/handlers/add-item.ts index a02ef4434..00d7b06bd 100644 --- a/framework/bigcommerce/api/wishlist/handlers/add-item.ts +++ b/framework/bigcommerce/api/wishlist/handlers/add-item.ts @@ -1,6 +1,6 @@ import type { WishlistHandlers } from '..' -import getCustomerId from '../../operations/get-customer-id' -import getCustomerWishlist from '../../operations/get-customer-wishlist' +import getCustomerId from '../../../customer/get-customer-id' +import getCustomerWishlist from '../../../customer/get-customer-wishlist' import { parseWishlistItem } from '../../utils/parse-item' // Returns the wishlist of the signed customer diff --git a/framework/bigcommerce/api/wishlist/handlers/get-wishlist.ts b/framework/bigcommerce/api/wishlist/handlers/get-wishlist.ts index 3eb3000cc..3737c033a 100644 --- a/framework/bigcommerce/api/wishlist/handlers/get-wishlist.ts +++ b/framework/bigcommerce/api/wishlist/handlers/get-wishlist.ts @@ -1,5 +1,5 @@ -import getCustomerId from '../../operations/get-customer-id' -import getCustomerWishlist from '../../operations/get-customer-wishlist' +import getCustomerId from '../../../customer/get-customer-id' +import getCustomerWishlist from '../../../customer/get-customer-wishlist' import type { Wishlist, WishlistHandlers } from '..' // Return wishlist info diff --git a/framework/bigcommerce/api/wishlist/handlers/remove-item.ts b/framework/bigcommerce/api/wishlist/handlers/remove-item.ts index 29b6eff60..a9cfd9db5 100644 --- a/framework/bigcommerce/api/wishlist/handlers/remove-item.ts +++ b/framework/bigcommerce/api/wishlist/handlers/remove-item.ts @@ -1,7 +1,7 @@ -import getCustomerId from '../../operations/get-customer-id' +import getCustomerId from '../../../customer/get-customer-id' import getCustomerWishlist, { Wishlist, -} from '../../operations/get-customer-wishlist' +} from '../../../customer/get-customer-wishlist' import type { WishlistHandlers } from '..' // Return current wishlist info diff --git a/framework/bigcommerce/api/wishlist/index.ts b/framework/bigcommerce/api/wishlist/index.ts index b50c5e97f..e892d2e78 100644 --- a/framework/bigcommerce/api/wishlist/index.ts +++ b/framework/bigcommerce/api/wishlist/index.ts @@ -7,7 +7,7 @@ import { BigcommerceApiError } from '../utils/errors' import type { Wishlist, WishlistItem, -} from '../operations/get-customer-wishlist' +} from '../../customer/get-customer-wishlist' import getWishlist from './handlers/get-wishlist' import addItem from './handlers/add-item' import removeItem from './handlers/remove-item' diff --git a/framework/bigcommerce/api/operations/login.ts b/framework/bigcommerce/auth/login.ts similarity index 88% rename from framework/bigcommerce/api/operations/login.ts rename to framework/bigcommerce/auth/login.ts index 8a8502705..adfa2d467 100644 --- a/framework/bigcommerce/api/operations/login.ts +++ b/framework/bigcommerce/auth/login.ts @@ -1,8 +1,8 @@ import type { ServerResponse } from 'http' -import type { LoginMutation, LoginMutationVariables } from '../../schema' -import type { RecursivePartial } from '../utils/types' -import concatHeader from '../utils/concat-cookie' -import { BigcommerceConfig, getConfig } from '..' +import type { LoginMutation, LoginMutationVariables } from '../schema' +import type { RecursivePartial } from '../api/utils/types' +import concatHeader from '../api/utils/concat-cookie' +import { BigcommerceConfig, getConfig } from '../api' export const loginMutation = /* GraphQL */ ` mutation login($email: String!, $password: String!) { diff --git a/framework/bigcommerce/api/operations/get-all-pages.ts b/framework/bigcommerce/common/get-all-pages.ts similarity index 83% rename from framework/bigcommerce/api/operations/get-all-pages.ts rename to framework/bigcommerce/common/get-all-pages.ts index 9fe83f2a1..dc5eb15a5 100644 --- a/framework/bigcommerce/api/operations/get-all-pages.ts +++ b/framework/bigcommerce/common/get-all-pages.ts @@ -1,6 +1,6 @@ -import type { RecursivePartial, RecursiveRequired } from '../utils/types' -import { BigcommerceConfig, getConfig } from '..' -import { definitions } from '../definitions/store-content' +import type { RecursivePartial, RecursiveRequired } from '../api/utils/types' +import { BigcommerceConfig, getConfig } from '../api' +import { definitions } from '../api/definitions/store-content' export type Page = definitions['page_Full'] diff --git a/framework/bigcommerce/api/operations/get-page.ts b/framework/bigcommerce/common/get-page.ts similarity index 85% rename from framework/bigcommerce/api/operations/get-page.ts rename to framework/bigcommerce/common/get-page.ts index 3010dd34c..b65e340e1 100644 --- a/framework/bigcommerce/api/operations/get-page.ts +++ b/framework/bigcommerce/common/get-page.ts @@ -1,6 +1,6 @@ -import type { RecursivePartial, RecursiveRequired } from '../utils/types' -import { BigcommerceConfig, getConfig } from '..' -import { definitions } from '../definitions/store-content' +import type { RecursivePartial, RecursiveRequired } from '../api/utils/types' +import { BigcommerceConfig, getConfig } from '../api' +import { definitions } from '../api/definitions/store-content' export type Page = definitions['page_Full'] diff --git a/framework/bigcommerce/api/operations/get-site-info.ts b/framework/bigcommerce/common/get-site-info.ts similarity index 89% rename from framework/bigcommerce/api/operations/get-site-info.ts rename to framework/bigcommerce/common/get-site-info.ts index 44c0cfeb5..80cde8d82 100644 --- a/framework/bigcommerce/api/operations/get-site-info.ts +++ b/framework/bigcommerce/common/get-site-info.ts @@ -1,8 +1,8 @@ -import type { GetSiteInfoQuery, GetSiteInfoQueryVariables } from '../../schema' -import type { RecursivePartial, RecursiveRequired } from '../utils/types' -import filterEdges from '../utils/filter-edges' -import { BigcommerceConfig, getConfig } from '..' -import { categoryTreeItemFragment } from '../fragments/category-tree' +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 */ ` diff --git a/framework/bigcommerce/api/operations/get-customer-id.ts b/framework/bigcommerce/customer/get-customer-id.ts similarity index 84% rename from framework/bigcommerce/api/operations/get-customer-id.ts rename to framework/bigcommerce/customer/get-customer-id.ts index 7fe84093e..65ce5a6a8 100644 --- a/framework/bigcommerce/api/operations/get-customer-id.ts +++ b/framework/bigcommerce/customer/get-customer-id.ts @@ -1,5 +1,5 @@ -import { GetCustomerIdQuery } from '../../schema' -import { BigcommerceConfig, getConfig } from '..' +import { GetCustomerIdQuery } from '../schema' +import { BigcommerceConfig, getConfig } from '../api' export const getCustomerIdQuery = /* GraphQL */ ` query getCustomerId { diff --git a/framework/bigcommerce/api/operations/get-customer-wishlist.ts b/framework/bigcommerce/customer/get-customer-wishlist.ts similarity index 89% rename from framework/bigcommerce/api/operations/get-customer-wishlist.ts rename to framework/bigcommerce/customer/get-customer-wishlist.ts index 2c1299b46..a3c7413cc 100644 --- a/framework/bigcommerce/api/operations/get-customer-wishlist.ts +++ b/framework/bigcommerce/customer/get-customer-wishlist.ts @@ -1,7 +1,7 @@ -import type { RecursivePartial, RecursiveRequired } from '../utils/types' -import { definitions } from '../definitions/wishlist' -import { BigcommerceConfig, getConfig } from '..' -import getAllProducts, { ProductEdge } from './get-all-products' +import type { RecursivePartial, RecursiveRequired } from '../api/utils/types' +import { definitions } from '../api/definitions/wishlist' +import { BigcommerceConfig, getConfig } from '../api' +import getAllProducts, { ProductEdge } from '../product/get-all-products' export type Wishlist = Omit & { items?: WishlistItem[] diff --git a/framework/bigcommerce/api/operations/get-all-product-paths.ts b/framework/bigcommerce/product/get-all-product-paths.ts similarity index 89% rename from framework/bigcommerce/api/operations/get-all-product-paths.ts rename to framework/bigcommerce/product/get-all-product-paths.ts index 71522be35..c1b23b38d 100644 --- a/framework/bigcommerce/api/operations/get-all-product-paths.ts +++ b/framework/bigcommerce/product/get-all-product-paths.ts @@ -1,10 +1,10 @@ import type { GetAllProductPathsQuery, GetAllProductPathsQueryVariables, -} from '../../schema' -import type { RecursivePartial, RecursiveRequired } from '../utils/types' -import filterEdges from '../utils/filter-edges' -import { BigcommerceConfig, getConfig } from '..' +} from '../schema' +import type { RecursivePartial, RecursiveRequired } from '../api/utils/types' +import filterEdges from '../api/utils/filter-edges' +import { BigcommerceConfig, getConfig } from '../api' export const getAllProductPathsQuery = /* GraphQL */ ` query getAllProductPaths($first: Int = 100) { diff --git a/framework/bigcommerce/api/operations/get-all-products.ts b/framework/bigcommerce/product/get-all-products.ts similarity index 88% rename from framework/bigcommerce/api/operations/get-all-products.ts rename to framework/bigcommerce/product/get-all-products.ts index 3cfb77b7c..b7d728c4a 100644 --- a/framework/bigcommerce/api/operations/get-all-products.ts +++ b/framework/bigcommerce/product/get-all-products.ts @@ -1,13 +1,13 @@ import type { GetAllProductsQuery, GetAllProductsQueryVariables, -} from '../../schema' -import type { RecursivePartial, RecursiveRequired } from '../utils/types' -import filterEdges from '../utils/filter-edges' -import setProductLocaleMeta from '../utils/set-product-locale-meta' -import { productConnectionFragment } from '../fragments/product' -import { BigcommerceConfig, getConfig } from '..' -import { normalizeProduct } from '../../lib/normalize' +} from '../schema' +import type { RecursivePartial, RecursiveRequired } from '../api/utils/types' +import filterEdges from '../api/utils/filter-edges' +import setProductLocaleMeta from '../api/utils/set-product-locale-meta' +import { productConnectionFragment } from '../api/fragments/product' +import { BigcommerceConfig, getConfig } from '../api' +import { normalizeProduct } from '../lib/normalize' export const getAllProductsQuery = /* GraphQL */ ` query getAllProducts( diff --git a/framework/bigcommerce/api/operations/get-product.ts b/framework/bigcommerce/product/get-product.ts similarity index 93% rename from framework/bigcommerce/api/operations/get-product.ts rename to framework/bigcommerce/product/get-product.ts index 4d34d86a0..3624a9cca 100644 --- a/framework/bigcommerce/api/operations/get-product.ts +++ b/framework/bigcommerce/product/get-product.ts @@ -1,7 +1,7 @@ -import type { GetProductQuery, GetProductQueryVariables } from '../../schema' -import setProductLocaleMeta from '../utils/set-product-locale-meta' -import { productInfoFragment } from '../fragments/product' -import { BigcommerceConfig, getConfig } from '..' +import type { GetProductQuery, GetProductQueryVariables } from '../schema' +import setProductLocaleMeta from '../api/utils/set-product-locale-meta' +import { productInfoFragment } from '../api/fragments/product' +import { BigcommerceConfig, getConfig } from '../api' import { normalizeProduct } from '@framework/lib/normalize' export const getProductQuery = /* GraphQL */ ` diff --git a/framework/bigcommerce/product/index.ts b/framework/bigcommerce/product/index.ts index 83d507a2c..b290c189f 100644 --- a/framework/bigcommerce/product/index.ts +++ b/framework/bigcommerce/product/index.ts @@ -1,4 +1,4 @@ export { default as usePrice } from './use-price' export { default as useSearch } from './use-search' -export { default as getProduct } from '../api/operations/get-product' -export { default as getAllProducts } from '../api/operations/get-all-products' +export { default as getProduct } from './get-product' +export { default as getAllProducts } from './get-all-products' diff --git a/package.json b/package.json index edabd234f..aba8b4b5d 100644 --- a/package.json +++ b/package.json @@ -51,6 +51,7 @@ "bowser": "^2.11.0", "classnames": "^2.2.6", "cookie": "^0.4.1", + "dot-object": "^2.1.4", "email-validator": "^2.0.4", "js-cookie": "^2.2.1", "keen-slider": "^5.2.4", @@ -100,8 +101,8 @@ "resolutions": { "webpack": "5.11.1" }, - "node": { - "net": "empty" + "engines": { + "node": ">=14" }, "license": "MIT" } diff --git a/pages/[...pages].tsx b/pages/[...pages].tsx index 6caac1720..98d7697cd 100644 --- a/pages/[...pages].tsx +++ b/pages/[...pages].tsx @@ -8,8 +8,8 @@ import { Layout } from '@components/common' import getSlug from '@lib/get-slug' import { missingLocaleInPages } from '@lib/usage-warns' import { getConfig } from '@framework/api' -import getPage from '@framework/api/operations/get-page' -import getAllPages from '@framework/api/operations/get-all-pages' +import getPage from '@framework/common/get-page' +import getAllPages from '@framework/common/get-all-pages' import { defaultPageProps } from '@lib/defaults' export async function getStaticProps({ diff --git a/pages/blog.tsx b/pages/blog.tsx index a3a020bca..eca3b2295 100644 --- a/pages/blog.tsx +++ b/pages/blog.tsx @@ -1,6 +1,6 @@ import type { GetStaticPropsContext } from 'next' import { getConfig } from '@framework/api' -import getAllPages from '@framework/api/operations/get-all-pages' +import getAllPages from '@framework/common/get-all-pages' import { Layout } from '@components/common' import { Container } from '@components/ui' diff --git a/pages/cart.tsx b/pages/cart.tsx index 57b92db27..e78beed57 100644 --- a/pages/cart.tsx +++ b/pages/cart.tsx @@ -1,6 +1,6 @@ import type { GetStaticPropsContext } from 'next' import { getConfig } from '@framework/api' -import getAllPages from '@framework/api/operations/get-all-pages' +import getAllPages from '@framework/common/get-all-pages' import useCart from '@framework/cart/use-cart' import usePrice from '@framework/product/use-price' import { Layout } from '@components/common' diff --git a/pages/index.tsx b/pages/index.tsx index d3f3f6ba5..811472674 100644 --- a/pages/index.tsx +++ b/pages/index.tsx @@ -5,9 +5,9 @@ import HomeAllProductsGrid from '@components/common/HomeAllProductsGrid' import type { GetStaticPropsContext, InferGetStaticPropsType } from 'next' import { getConfig } from '@framework/api' -import getAllProducts from '@framework/api/operations/get-all-products' -import getSiteInfo from '@framework/api/operations/get-site-info' -import getAllPages from '@framework/api/operations/get-all-pages' +import getAllProducts from '@framework/product/get-all-products' +import getSiteInfo from '@framework/common/get-site-info' +import getAllPages from '@framework/common/get-all-pages' export async function getStaticProps({ preview, diff --git a/pages/orders.tsx b/pages/orders.tsx index 973a021eb..08e32c2b2 100644 --- a/pages/orders.tsx +++ b/pages/orders.tsx @@ -1,6 +1,6 @@ import type { GetStaticPropsContext } from 'next' import { getConfig } from '@framework/api' -import getAllPages from '@framework/api/operations/get-all-pages' +import getAllPages from '@framework/common/get-all-pages' import { Layout } from '@components/common' import { Container, Text } from '@components/ui' import { Bag } from '@components/icons' diff --git a/pages/product/[slug].tsx b/pages/product/[slug].tsx index 4f17dcbad..3d2971eed 100644 --- a/pages/product/[slug].tsx +++ b/pages/product/[slug].tsx @@ -8,9 +8,9 @@ import { Layout } from '@components/common' import { ProductView } from '@components/product' import { getConfig } from '@framework/api' -import getProduct from '@framework/api/operations/get-product' -import getAllPages from '@framework/api/operations/get-all-pages' -import getAllProductPaths from '@framework/api/operations/get-all-product-paths' +import getProduct from '@framework/product/get-product' +import getAllPages from '@framework/common/get-all-pages' +import getAllProductPaths from '@framework/product/get-all-product-paths' export async function getStaticProps({ params, diff --git a/pages/profile.tsx b/pages/profile.tsx index 8b8c1a3b1..ec845c879 100644 --- a/pages/profile.tsx +++ b/pages/profile.tsx @@ -1,6 +1,6 @@ import type { GetStaticPropsContext } from 'next' import { getConfig } from '@framework/api' -import getAllPages from '@framework/api/operations/get-all-pages' +import getAllPages from '@framework/common/get-all-pages' import useCustomer from '@framework/customer/use-customer' import { Layout } from '@components/common' import { Container, Text } from '@components/ui' diff --git a/pages/search.tsx b/pages/search.tsx index d9367239f..e84569db3 100644 --- a/pages/search.tsx +++ b/pages/search.tsx @@ -9,9 +9,9 @@ import { ProductCard } from '@components/product' import { Container, Grid, Skeleton } from '@components/ui' import { getConfig } from '@framework/api' -import getAllPages from '@framework/api/operations/get-all-pages' -import getSiteInfo from '@framework/api/operations/get-site-info' import useSearch from '@framework/product/use-search' +import getAllPages from '@framework/common/get-all-pages' +import getSiteInfo from '@framework/common/get-site-info' import rangeMap from '@lib/range-map' diff --git a/pages/wishlist.tsx b/pages/wishlist.tsx index b4410a58c..9df111dc6 100644 --- a/pages/wishlist.tsx +++ b/pages/wishlist.tsx @@ -1,6 +1,6 @@ import type { GetStaticPropsContext } from 'next' import { getConfig } from '@framework/api' -import getAllPages from '@framework/api/operations/get-all-pages' +import getAllPages from '@framework/common/get-all-pages' import useWishlist from '@framework/wishlist/use-wishlist' import { Layout } from '@components/common' import { Heart } from '@components/icons' diff --git a/tsconfig.json b/tsconfig.json index d80fe8ba8..e6201f640 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -27,8 +27,8 @@ } }, "include": [ + "/framework/types.d.ts", "next-env.d.ts", - "framework/types.d.ts", "**/*.ts", "**/*.tsx", "**/*.js" diff --git a/yarn.lock b/yarn.lock index 4db1aba12..441f924fc 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2346,6 +2346,11 @@ commander@^2.13.0, commander@^2.16.0, commander@^2.20.0, commander@^2.20.3, comm resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== +commander@^4.0.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-4.1.1.tgz#9fd602bd936294e9e9ef46a3f4d6964044b18068" + integrity sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA== + commander@^5.0.0, commander@^5.1.0: version "5.1.0" resolved "https://registry.yarnpkg.com/commander/-/commander-5.1.0.tgz#46abbd1652f8e059bddaef99bbdcb2ad9cf179ae" @@ -2982,6 +2987,14 @@ dot-case@^3.0.3: no-case "^3.0.4" tslib "^2.0.3" +dot-object@^2.1.4: + version "2.1.4" + resolved "https://registry.yarnpkg.com/dot-object/-/dot-object-2.1.4.tgz#c6c54e9fca510b4d0ea4d65acf33726963843b5f" + integrity sha512-7FXnyyCLFawNYJ+NhkqyP9Wd2yzuo+7n9pGiYpkmXCTYa8Ci2U0eUNDVg5OuO5Pm6aFXI2SWN8/N/w7SJWu1WA== + dependencies: + commander "^4.0.0" + glob "^7.1.5" + dotenv@^8.2.0: version "8.2.0" resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-8.2.0.tgz#97e619259ada750eea3e4ea3e26bceea5424b16a" @@ -3618,7 +3631,7 @@ glob@^6.0.1: once "^1.3.0" path-is-absolute "^1.0.0" -glob@^7.0.0, glob@^7.1.1, glob@^7.1.2, glob@^7.1.6: +glob@^7.0.0, glob@^7.1.1, glob@^7.1.2, glob@^7.1.5, glob@^7.1.6: version "7.1.6" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== From 64b25ef70bfa98ad6bd2d10deab330d98cd59533 Mon Sep 17 00:00:00 2001 From: bc Date: Mon, 18 Jan 2021 13:23:37 -0300 Subject: [PATCH 034/216] Adding immutable normalizer for Product --- framework/bigcommerce/lib/normalize.ts | 93 +++++++++++++------------- framework/types.d.ts | 2 +- package.json | 1 + yarn.lock | 5 ++ 4 files changed, 54 insertions(+), 47 deletions(-) diff --git a/framework/bigcommerce/lib/normalize.ts b/framework/bigcommerce/lib/normalize.ts index 950177e73..d9e0274c7 100644 --- a/framework/bigcommerce/lib/normalize.ts +++ b/framework/bigcommerce/lib/normalize.ts @@ -1,13 +1,16 @@ import { Cart, CartItem, Product } from '../../types' import { Product as BigCommerceProduct } from '@framework/schema' +import update from "immutability-helper" + +function normalizeProductOption(productOption:any) { + const { + node: { + entityId, + values: { edges }, + ...rest + }, + } = productOption; -function normalizeProductOption({ - node: { - entityId, - values: { edges }, - ...rest - }, -}: any) { return { id: entityId, values: edges?.map(({ node }: any) => node), @@ -15,57 +18,55 @@ function normalizeProductOption({ } } -export function normalizeProduct(productNode: BigCommerceProduct): Product { +export function normalizeProduct(productNode: any): Product { const { entityId: id, - images, - variants, productOptions, prices, path, id: _, options: _0, - brand, - ...rest } = productNode - return { - id, - path, - slug: path?.replace(/^\/+|\/+$/g, ''), - images: images.edges - ? images.edges.map( - ({ node: { urlOriginal, altText, ...rest } }: any) => ({ - url: urlOriginal, - alt: altText, - ...rest, - }) - ) - : [], - variants: variants.edges - ? variants.edges.map( - ({ node: { entityId, productOptions, ...rest } }: any) => ({ - id: entityId, - options: productOptions?.edges - ? productOptions.edges.map(normalizeProductOption) - : [], - ...rest, - }) - ) - : [], - options: productOptions.edges - ? productOptions?.edges.map(normalizeProductOption) - : [], + return update(productNode, { + id: { $set: String(id) }, + images: { + $apply: ({edges} : any) => edges?.map( + ({ node: { urlOriginal, altText, ...rest } }: any) => ({ + url: urlOriginal, + alt: altText, + ...rest, + }) + ) + }, + variants: { + $apply: ({edges} : any) => edges?.map( + ({ node: { entityId, productOptions, ...rest } }: any) => ({ + id: entityId, + options: productOptions?.edges + ? productOptions.edges.map(normalizeProductOption) + : [], + ...rest, + }) + ) + }, + options: { + $set: productOptions.edges ? productOptions?.edges.map(normalizeProductOption) : [] + }, brand: { - id: brand?.entityId ? brand?.entityId : null, - ...brand, + $apply:(brand : any) => brand?.entityId ? brand?.entityId : null, + }, + slug: { + $set: path?.replace(/^\/+|\/+$/g, '') }, price: { - value: prices?.price.value, - currencyCode: prices?.price.currencyCode, - }, - ...rest, - } + $set: { + value: prices?.price.value, + currencyCode: prices?.price.currencyCode, + } + }, + $unset: ['entityId'] + }) } export function normalizeCart({ data, ...rest }: any): Cart { diff --git a/framework/types.d.ts b/framework/types.d.ts index 7a4c45359..e68b6fd17 100644 --- a/framework/types.d.ts +++ b/framework/types.d.ts @@ -8,7 +8,7 @@ interface Entity { interface Product extends Entity { name: string description: string - slug: string + slug?: string path?: string images: ProductImage[] variants: ProductVariant[] diff --git a/package.json b/package.json index aba8b4b5d..d8229071d 100644 --- a/package.json +++ b/package.json @@ -53,6 +53,7 @@ "cookie": "^0.4.1", "dot-object": "^2.1.4", "email-validator": "^2.0.4", + "immutability-helper": "^3.1.1", "js-cookie": "^2.2.1", "keen-slider": "^5.2.4", "lodash.debounce": "^4.0.8", diff --git a/yarn.lock b/yarn.lock index 441f924fc..bc77775f6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3958,6 +3958,11 @@ ignore@^5.1.4: resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.8.tgz#f150a8b50a34289b33e22f5889abd4d8016f0e57" integrity sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw== +immutability-helper@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/immutability-helper/-/immutability-helper-3.1.1.tgz#2b86b2286ed3b1241c9e23b7b21e0444f52f77b7" + integrity sha512-Q0QaXjPjwIju/28TsugCHNEASwoCcJSyJV3uO1sOIQGI0jKgm9f41Lvz0DZj3n46cNCyAZTsEYoY4C2bVRUzyQ== + immutable@~3.7.6: version "3.7.6" resolved "https://registry.yarnpkg.com/immutable/-/immutable-3.7.6.tgz#13b4d3cb12befa15482a26fe1b2ebae640071e4b" From d03df631cef305ef3400ee948a3c535721a62803 Mon Sep 17 00:00:00 2001 From: okbel Date: Mon, 18 Jan 2021 16:24:22 -0300 Subject: [PATCH 035/216] Cart Normalized --- CHANGELOG.md | 4 ++ components/cart/CartItem/CartItem.tsx | 8 ++- framework/bigcommerce/cart/use-cart.tsx | 5 +- framework/bigcommerce/lib/normalize.ts | 83 +++++++++++++------------ framework/types.d.ts | 2 - tsconfig.json | 2 +- 6 files changed, 60 insertions(+), 44 deletions(-) create mode 100644 CHANGELOG.md diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 000000000..b2d1092e3 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,4 @@ +## Changelog + +- Select Variants Working +- Click on cart item title, closes the sidebar \ No newline at end of file diff --git a/components/cart/CartItem/CartItem.tsx b/components/cart/CartItem/CartItem.tsx index c5a48c8e6..47389aee4 100644 --- a/components/cart/CartItem/CartItem.tsx +++ b/components/cart/CartItem/CartItem.tsx @@ -4,6 +4,7 @@ import Image from 'next/image' import Link from 'next/link' import s from './CartItem.module.css' import { Trash, Plus, Minus } from '@components/icons' +import {useUI} from '@components/ui/context' import usePrice from '@framework/product/use-price' import useUpdateItem from '@framework/cart/use-update-item' import useRemoveItem from '@framework/cart/use-remove-item' @@ -16,18 +17,23 @@ const Item = ({ item: CartItem currencyCode: string }) => { + const { closeSidebarIfPresent } = useUI() + const { price } = usePrice({ amount: item.extended_sale_price, baseAmount: item.extended_list_price, currencyCode, }) + const updateItem = useUpdateItem(item) const removeItem = useRemoveItem() const [quantity, setQuantity] = useState(item.quantity) const [removing, setRemoving] = useState(false) + const updateQuantity = async (val: number) => { await updateItem({ quantity: val }) } + const handleQuantity = (e: ChangeEvent) => { const val = Number(e.target.value) @@ -87,7 +93,7 @@ const Item = ({
    - + closeSidebarIfPresent()}> {item.name} diff --git a/framework/bigcommerce/cart/use-cart.tsx b/framework/bigcommerce/cart/use-cart.tsx index 54582372f..a1ace483d 100644 --- a/framework/bigcommerce/cart/use-cart.tsx +++ b/framework/bigcommerce/cart/use-cart.tsx @@ -3,6 +3,7 @@ import type { SwrOptions } from '@commerce/utils/use-data' import useCommerceCart, { CartInput } from '@commerce/cart/use-cart' import type { Cart } from '../api/cart' import { normalizeCart } from '../lib/normalize' +import update from 'immutability-helper' const defaultOpts = { url: '/api/bigcommerce/cart', @@ -40,7 +41,9 @@ export function extendHook( set: (x) => x, }) - return normalizeCart(response) + return update(response, { + data: { $set: normalizeCart(response.data) } + }) } useCart.extend = extendHook diff --git a/framework/bigcommerce/lib/normalize.ts b/framework/bigcommerce/lib/normalize.ts index d9e0274c7..cd7763c6e 100644 --- a/framework/bigcommerce/lib/normalize.ts +++ b/framework/bigcommerce/lib/normalize.ts @@ -1,6 +1,12 @@ import { Cart, CartItem, Product } from '../../types' -import { Product as BigCommerceProduct } from '@framework/schema' -import update from "immutability-helper" +import update, { extend } from "immutability-helper" + +// Allows auto creation when needed +extend('$auto', function(value, object) { + return object ? + update(object, value): + update({}, value); +}); function normalizeProductOption(productOption:any) { const { @@ -69,47 +75,46 @@ export function normalizeProduct(productNode: any): Product { }) } -export function normalizeCart({ data, ...rest }: any): Cart { - return { - ...rest, - data: { - products: data?.line_items?.physical_items.map(itemsToProducts) ?? [], - ...data, +export function normalizeCart(cart: any): Cart { + return update(cart, { + $auto: { + products: { $set: cart?.line_items?.physical_items?.map(itemsToProducts)} }, - } + $unset: ['created_time', 'coupons', 'line_items'] + }) } -function itemsToProducts({ - id, - name, - quantity, - product_id, - variant_id, - image_url, - list_price, - sale_price, - extended_list_price, - extended_sale_price, - ...rest -}: any): CartItem { - return { +function itemsToProducts(item: any): CartItem { + const { id, name, - prices: { - listPrice: list_price, - salePrice: sale_price, - extendedListPrice: extended_list_price, - extendedSalePrice: extended_sale_price, - }, - images: [ - { - alt: name, - url: image_url, - }, - ], - productId: product_id, - variantId: variant_id, quantity, - ...rest, - } + product_id, + variant_id, + image_url, + list_price, + sale_price, + extended_list_price, + extended_sale_price, + ...rest + } = item; + + return update(item, { + $auto: { + prices: { + $auto: { + listPrice: { $set: list_price }, + salePrice: { $set: sale_price } , + extendedListPrice: { $set: extended_list_price }, + extendedSalePrice: { $set: extended_sale_price }, + } + }, + images: { $set: [{ + alt: name, + url: image_url + }]}, + productId: { $set: product_id }, + variantId: { $set: variant_id } + } + }) } diff --git a/framework/types.d.ts b/framework/types.d.ts index e68b6fd17..9ee622c4b 100644 --- a/framework/types.d.ts +++ b/framework/types.d.ts @@ -1,5 +1,3 @@ -import { CartItem } from '@components/cart' - interface Entity { id: string | number [prop: string]: any diff --git a/tsconfig.json b/tsconfig.json index e6201f640..856ebbff5 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -27,7 +27,7 @@ } }, "include": [ - "/framework/types.d.ts", + "framework/types.d.ts", "next-env.d.ts", "**/*.ts", "**/*.tsx", From 49b9efa395de7a5330e963fd5363cbf4eee2802e Mon Sep 17 00:00:00 2001 From: Bel Curcio Date: Mon, 18 Jan 2021 20:17:10 -0300 Subject: [PATCH 036/216] changes --- components/cart/CartItem/CartItem.tsx | 8 +++++--- components/cart/CartSidebarView/CartSidebarView.tsx | 2 +- components/product/ProductCard/ProductCard.tsx | 6 +++--- components/product/ProductView/ProductView.tsx | 8 ++++---- components/wishlist/WishlistButton/index.ts | 1 - package.json | 2 +- tsconfig.json | 2 +- 7 files changed, 15 insertions(+), 14 deletions(-) delete mode 100644 components/wishlist/WishlistButton/index.ts diff --git a/components/cart/CartItem/CartItem.tsx b/components/cart/CartItem/CartItem.tsx index 47389aee4..14bd10c94 100644 --- a/components/cart/CartItem/CartItem.tsx +++ b/components/cart/CartItem/CartItem.tsx @@ -4,11 +4,10 @@ import Image from 'next/image' import Link from 'next/link' import s from './CartItem.module.css' import { Trash, Plus, Minus } from '@components/icons' -import {useUI} from '@components/ui/context' +import { useUI } from '@components/ui/context' import usePrice from '@framework/product/use-price' import useUpdateItem from '@framework/cart/use-update-item' import useRemoveItem from '@framework/cart/use-remove-item' -import { CartItem } from 'framework/types' const Item = ({ item, @@ -93,7 +92,10 @@ const Item = ({
    - closeSidebarIfPresent()}> + closeSidebarIfPresent()} + > {item.name} diff --git a/components/cart/CartSidebarView/CartSidebarView.tsx b/components/cart/CartSidebarView/CartSidebarView.tsx index 19c6964d7..ed4ce915a 100644 --- a/components/cart/CartSidebarView/CartSidebarView.tsx +++ b/components/cart/CartSidebarView/CartSidebarView.tsx @@ -93,7 +93,7 @@ const CartSidebarView: FC = () => { My Cart
      - {data.products.map((item: any) => ( + {data?.products?.map((item) => ( = ({ {product.price.currencyCode}
    - + /> */}
{product?.images && ( diff --git a/components/product/ProductView/ProductView.tsx b/components/product/ProductView/ProductView.tsx index d55e52611..d3d11ea16 100644 --- a/components/product/ProductView/ProductView.tsx +++ b/components/product/ProductView/ProductView.tsx @@ -12,7 +12,7 @@ import usePrice from '@framework/product/use-price' import { useAddItem } from '@framework/cart' import { getVariant, SelectedOptions } from '../helpers' -import WishlistButton from '@components/wishlist/WishlistButton' +// import WishlistButton from '@components/wishlist/WishlistButton' interface Props { className?: string @@ -24,7 +24,7 @@ const ProductView: FC = ({ product }) => { const addItem = useAddItem() const { price } = usePrice({ amount: product.price.value, - baseAmount: product.price.retailValue, + baseAmount: product.price.retailPrice, currencyCode: product.price.currencyCode!, }) const { openSidebar } = useUI() @@ -152,11 +152,11 @@ const ProductView: FC = ({ product }) => {
- + /> */}
) diff --git a/components/wishlist/WishlistButton/index.ts b/components/wishlist/WishlistButton/index.ts deleted file mode 100644 index 66e88074b..000000000 --- a/components/wishlist/WishlistButton/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { default } from './WishlistButton' diff --git a/package.json b/package.json index d8229071d..9848a4674 100644 --- a/package.json +++ b/package.json @@ -103,7 +103,7 @@ "webpack": "5.11.1" }, "engines": { - "node": ">=14" + "node": "12.x" }, "license": "MIT" } diff --git a/tsconfig.json b/tsconfig.json index 856ebbff5..0992a8cd6 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -33,5 +33,5 @@ "**/*.tsx", "**/*.js" ], - "exclude": ["node_modules"] + "exclude": ["node_modules", "components/wishlist"] } From 017218c155896898d0ddcd6803c1bffccb2ae1af Mon Sep 17 00:00:00 2001 From: okbel Date: Tue, 19 Jan 2021 11:07:40 -0300 Subject: [PATCH 037/216] Progress --- components/cart/CartSidebarView/CartSidebarView.tsx | 5 +++-- framework/bigcommerce/lib/normalize.ts | 8 +++++--- framework/types.d.ts | 3 ++- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/components/cart/CartSidebarView/CartSidebarView.tsx b/components/cart/CartSidebarView/CartSidebarView.tsx index 19c6964d7..dd3b62f29 100644 --- a/components/cart/CartSidebarView/CartSidebarView.tsx +++ b/components/cart/CartSidebarView/CartSidebarView.tsx @@ -15,13 +15,14 @@ const CartSidebarView: FC = () => { const { price: subTotal } = usePrice( data && { - amount: data.base_amount, + amount: data.subTotal, currencyCode: data.currency?.code || 'USD', } ) + const { price: total } = usePrice( data && { - amount: data.cart_amount, + amount: data.total, currencyCode: data.currency?.code || 'USD', } ) diff --git a/framework/bigcommerce/lib/normalize.ts b/framework/bigcommerce/lib/normalize.ts index cd7763c6e..35c8d48b2 100644 --- a/framework/bigcommerce/lib/normalize.ts +++ b/framework/bigcommerce/lib/normalize.ts @@ -75,10 +75,12 @@ export function normalizeProduct(productNode: any): Product { }) } -export function normalizeCart(cart: any): Cart { - return update(cart, { +export function normalizeCart(data: any): Cart { + return update(data, { $auto: { - products: { $set: cart?.line_items?.physical_items?.map(itemsToProducts)} + products: { $set: data?.line_items?.physical_items?.map(itemsToProducts)}, + subTotal: { $set: data.base_amount }, + total: { $set: data.cart_amount } }, $unset: ['created_time', 'coupons', 'line_items'] }) diff --git a/framework/types.d.ts b/framework/types.d.ts index 9ee622c4b..31d5aedf3 100644 --- a/framework/types.d.ts +++ b/framework/types.d.ts @@ -49,8 +49,9 @@ interface Cart extends Entity { id: string | undefined currency: { code: string } taxIncluded?: boolean - totalAmmount: number | string products: Pick & CartItem[] + subTotal: number | string + total: number | string } interface CartItem extends Entity { From 48b484011dc1bf406f8239ecf53749ff9a939928 Mon Sep 17 00:00:00 2001 From: okbel Date: Tue, 19 Jan 2021 12:33:50 -0300 Subject: [PATCH 038/216] More updates --- components/cart/CartItem/CartItem.tsx | 2 ++ .../cart/CartSidebarView/CartSidebarView.tsx | 6 ++--- .../product/ProductCard/ProductCard.tsx | 2 +- framework/bigcommerce/cart/use-cart.tsx | 21 ++++++++------- framework/bigcommerce/lib/immutability.ts | 18 +++++++++++++ framework/bigcommerce/lib/normalize.ts | 17 ++++-------- framework/types.d.ts | 3 ++- pages/cart.tsx | 26 ++++++------------- pages/search.tsx | 12 ++++----- 9 files changed, 57 insertions(+), 50 deletions(-) create mode 100644 framework/bigcommerce/lib/immutability.ts diff --git a/components/cart/CartItem/CartItem.tsx b/components/cart/CartItem/CartItem.tsx index 14bd10c94..91a70af0b 100644 --- a/components/cart/CartItem/CartItem.tsx +++ b/components/cart/CartItem/CartItem.tsx @@ -12,6 +12,7 @@ import useRemoveItem from '@framework/cart/use-remove-item' const Item = ({ item, currencyCode, + ...rest }: { item: CartItem currencyCode: string @@ -79,6 +80,7 @@ const Item = ({ className={cn('flex flex-row space-x-8 py-8', { 'opacity-75 pointer-events-none': removing, })} + {...rest} >
{ const { price: subTotal } = usePrice( data && { - amount: data.subTotal, + amount: Number(data.subTotal), currencyCode: data.currency?.code || 'USD', } ) const { price: total } = usePrice( data && { - amount: data.total, + amount: Number(data.total), currencyCode: data.currency?.code || 'USD', } ) @@ -94,7 +94,7 @@ const CartSidebarView: FC = () => { My Cart
diff --git a/components/common/HomeAllProductsGrid/HomeAllProductsGrid.tsx b/components/common/HomeAllProductsGrid/HomeAllProductsGrid.tsx index 4b838e1a4..423048f75 100644 --- a/components/common/HomeAllProductsGrid/HomeAllProductsGrid.tsx +++ b/components/common/HomeAllProductsGrid/HomeAllProductsGrid.tsx @@ -5,20 +5,17 @@ import { Grid } from '@components/ui' import { ProductCard } from '@components/product' import s from './HomeAllProductsGrid.module.css' import { getCategoryPath, getDesignerPath } from '@lib/search' -import wishlist from '@framework/api/wishlist' interface Props { categories?: any brands?: any products?: Product[] - wishlist?: boolean } const HomeAllProductsGrid: FC = ({ categories, brands, products = [], - wishlist = false, }) => { return (
@@ -65,7 +62,6 @@ const HomeAllProductsGrid: FC = ({ width: 480, height: 480, }} - wishlist={wishlist} /> ))} diff --git a/components/common/Layout/Layout.tsx b/components/common/Layout/Layout.tsx index 82e045474..54749c46b 100644 --- a/components/common/Layout/Layout.tsx +++ b/components/common/Layout/Layout.tsx @@ -61,7 +61,7 @@ const Layout: FC = ({ return (
- +
{children}
@@ -72,7 +72,7 @@ const Layout: FC = ({ - + = ({ wishlist }) => ( +const Navbar: FC = () => (
@@ -33,7 +33,7 @@ const Navbar: FC<{ wishlist?: boolean }> = ({ wishlist }) => (
- +
diff --git a/components/common/UserNav/UserNav.tsx b/components/common/UserNav/UserNav.tsx index 5d9d58fff..d2dfc11dd 100644 --- a/components/common/UserNav/UserNav.tsx +++ b/components/common/UserNav/UserNav.tsx @@ -12,12 +12,11 @@ import { Avatar } from '@components/common' interface Props { className?: string - wishlist?: boolean } const countItem = (count: number, item: LineItem) => count + item.quantity -const UserNav: FC = ({ className, wishlist = false }) => { +const UserNav: FC = ({ className }) => { const { data } = useCart() const { data: customer } = useCustomer() const { toggleSidebar, closeSidebarIfPresent, openModal } = useUI() @@ -31,7 +30,7 @@ const UserNav: FC = ({ className, wishlist = false }) => { {itemsCount > 0 && {itemsCount}} - {wishlist && ( + {process.env.WISHLIST_ENABLED && (
  • From b931bc47afe20c923381316d36c6e3b4a4358bc7 Mon Sep 17 00:00:00 2001 From: Luis Alvarez Date: Tue, 23 Feb 2021 13:59:11 -0500 Subject: [PATCH 162/216] Disable wishlist --- next.config.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/next.config.js b/next.config.js index fe4441dda..939031884 100644 --- a/next.config.js +++ b/next.config.js @@ -7,7 +7,7 @@ module.exports = { defaultLocale: 'en-US', }, env: { - WISHLIST_ENABLED: true, + WISHLIST_ENABLED: false, }, rewrites() { return [ From 9b251a10c6b844af7c2078b08bddc66fd1019e34 Mon Sep 17 00:00:00 2001 From: Luis Alvarez Date: Tue, 23 Feb 2021 23:03:23 -0500 Subject: [PATCH 163/216] Removed useWishlistActions --- framework/bigcommerce/wishlist/index.ts | 1 - .../bigcommerce/wishlist/use-wishlist-actions.tsx | 11 ----------- 2 files changed, 12 deletions(-) delete mode 100644 framework/bigcommerce/wishlist/use-wishlist-actions.tsx diff --git a/framework/bigcommerce/wishlist/index.ts b/framework/bigcommerce/wishlist/index.ts index 9ea28291c..241af3c7e 100644 --- a/framework/bigcommerce/wishlist/index.ts +++ b/framework/bigcommerce/wishlist/index.ts @@ -1,4 +1,3 @@ export { default as useAddItem } from './use-add-item' export { default as useWishlist } from './use-wishlist' export { default as useRemoveItem } from './use-remove-item' -export { default as useWishlistActions } from './use-wishlist-actions' diff --git a/framework/bigcommerce/wishlist/use-wishlist-actions.tsx b/framework/bigcommerce/wishlist/use-wishlist-actions.tsx deleted file mode 100644 index 711d00516..000000000 --- a/framework/bigcommerce/wishlist/use-wishlist-actions.tsx +++ /dev/null @@ -1,11 +0,0 @@ -import useAddItem from './use-add-item' -import useRemoveItem from './use-remove-item' - -// This hook is probably not going to be used, but it's here -// to show how a commerce should be structuring it -export default function useWishlistActions() { - const addItem = useAddItem() - const removeItem = useRemoveItem() - - return { addItem, removeItem } -} From bbfca29217540df58ff34f604970e2bb16e856d4 Mon Sep 17 00:00:00 2001 From: Luis Alvarez Date: Tue, 23 Feb 2021 23:07:49 -0500 Subject: [PATCH 164/216] Updated readme --- README.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index ea6248c51..9d2108cfe 100644 --- a/README.md +++ b/README.md @@ -57,18 +57,21 @@ Main folder and its exposed functions - getAllProducts - `wishlist` - useWishlist - - addWishlistItem - - removeWishlistItem + - useAddItem + - useRemoveItem - `auth` - useLogin - useLogout - useSignup +- `customer` + - useCustomer + - getCustomerId + - getCustomerWistlist - `cart` - useCart - useAddItem - useRemoveItem - - useCartActions - useUpdateItem - `config.json` From bcd1d46e30d0cfc7078544afcf82532d03b586d6 Mon Sep 17 00:00:00 2001 From: okbel Date: Wed, 24 Feb 2021 14:37:25 -0300 Subject: [PATCH 165/216] updates --- .vscode/extensions.json | 3 ++ components/common/UserNav/UserNav.tsx | 2 +- .../product/ProductCard/ProductCard.tsx | 2 +- .../product/ProductView/ProductView.tsx | 2 +- framework/bigcommerce/auth/use-login.tsx | 2 +- framework/bigcommerce/auth/use-logout.tsx | 2 +- framework/bigcommerce/auth/use-signup.tsx | 2 +- framework/bigcommerce/next.config.js | 37 +++++++++++++++ framework/bigcommerce/product/use-price.tsx | 4 +- framework/commerce/{ => auth}/use-login.tsx | 8 ++-- framework/commerce/{ => auth}/use-logout.tsx | 8 ++-- framework/commerce/{ => auth}/use-signup.tsx | 8 ++-- framework/commerce/config.json | 5 -- .../commerce/{ => product}/use-price.tsx | 2 +- framework/commerce/types.ts | 4 +- framework/commerce/utils/bootstrap.js | 11 +++++ framework/commerce/utils/features.ts | 10 ++++ next.config.js | 46 +++---------------- package.json | 1 + pages/wishlist.tsx | 2 +- yarn.lock | 5 ++ 21 files changed, 98 insertions(+), 68 deletions(-) create mode 100644 .vscode/extensions.json create mode 100644 framework/bigcommerce/next.config.js rename framework/commerce/{ => auth}/use-login.tsx (64%) rename framework/commerce/{ => auth}/use-logout.tsx (64%) rename framework/commerce/{ => auth}/use-signup.tsx (64%) delete mode 100644 framework/commerce/config.json rename framework/commerce/{ => product}/use-price.tsx (97%) create mode 100644 framework/commerce/utils/bootstrap.js diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 000000000..c83e26348 --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,3 @@ +{ + "recommendations": ["esbenp.prettier-vscode"] +} diff --git a/components/common/UserNav/UserNav.tsx b/components/common/UserNav/UserNav.tsx index d2dfc11dd..9d143a572 100644 --- a/components/common/UserNav/UserNav.tsx +++ b/components/common/UserNav/UserNav.tsx @@ -30,7 +30,7 @@ const UserNav: FC = ({ className }) => { {itemsCount > 0 && {itemsCount}}
  • - {process.env.WISHLIST_ENABLED && ( + {process.env.COMMERCE_WISHLIST_ENABLED && (
  • diff --git a/components/product/ProductCard/ProductCard.tsx b/components/product/ProductCard/ProductCard.tsx index 3c28e6663..ade53380c 100644 --- a/components/product/ProductCard/ProductCard.tsx +++ b/components/product/ProductCard/ProductCard.tsx @@ -57,7 +57,7 @@ const ProductCard: FC = ({ {product.price.currencyCode}
  • - {process.env.WISHLIST_ENABLED && ( + {process.env.COMMERCE_WISHLIST_ENABLED && ( = ({ product }) => {
    - {process.env.WISHLIST_ENABLED && ( + {process.env.COMMERCE_WISHLIST_ENABLED && ( diff --git a/framework/bigcommerce/auth/use-signup.tsx b/framework/bigcommerce/auth/use-signup.tsx index 23b7ce9c6..28f7024ef 100644 --- a/framework/bigcommerce/auth/use-signup.tsx +++ b/framework/bigcommerce/auth/use-signup.tsx @@ -1,7 +1,7 @@ import { useCallback } from 'react' import type { MutationHook } from '@commerce/utils/types' import { CommerceError } from '@commerce/utils/errors' -import useSignup, { UseSignup } from '@commerce/use-signup' +import useSignup, { UseSignup } from '@commerce/auth/use-signup' import type { SignupBody } from '../api/customers/signup' import useCustomer from '../customer/use-customer' diff --git a/framework/bigcommerce/next.config.js b/framework/bigcommerce/next.config.js new file mode 100644 index 000000000..e732ef78a --- /dev/null +++ b/framework/bigcommerce/next.config.js @@ -0,0 +1,37 @@ +module.exports = { + images: { + domains: ['cdn11.bigcommerce.com'], + }, + i18n: { + locales: ['en-US', 'es'], + defaultLocale: 'en-US', + }, + rewrites() { + return [ + { + source: '/checkout', + destination: '/api/bigcommerce/checkout', + }, + // The logout is also an action so this route is not required, but it's also another way + // you can allow a logout! + { + source: '/logout', + destination: '/api/bigcommerce/customers/logout?redirect_to=/', + }, + // Rewrites for /search + { + source: '/search/designers/:name', + destination: '/search', + }, + { + source: '/search/designers/:name/:category', + destination: '/search', + }, + { + // This rewrite will also handle `/search/designers` + source: '/search/:category', + destination: '/search', + }, + ] + }, +} diff --git a/framework/bigcommerce/product/use-price.tsx b/framework/bigcommerce/product/use-price.tsx index a79940a76..0174faf5e 100644 --- a/framework/bigcommerce/product/use-price.tsx +++ b/framework/bigcommerce/product/use-price.tsx @@ -1,2 +1,2 @@ -export * from '@commerce/use-price' -export { default } from '@commerce/use-price' +export * from '@commerce/product/use-price' +export { default } from '@commerce/product/use-price' diff --git a/framework/commerce/use-login.tsx b/framework/commerce/auth/use-login.tsx similarity index 64% rename from framework/commerce/use-login.tsx rename to framework/commerce/auth/use-login.tsx index 755e10fd9..cc4cf6a73 100644 --- a/framework/commerce/use-login.tsx +++ b/framework/commerce/auth/use-login.tsx @@ -1,7 +1,7 @@ -import { useHook, useMutationHook } from './utils/use-hook' -import { mutationFetcher } from './utils/default-fetcher' -import type { MutationHook, HookFetcherFn } from './utils/types' -import type { Provider } from '.' +import { useHook, useMutationHook } from '../utils/use-hook' +import { mutationFetcher } from '../utils/default-fetcher' +import type { MutationHook, HookFetcherFn } from '../utils/types' +import type { Provider } from '..' export type UseLogin< H extends MutationHook = MutationHook diff --git a/framework/commerce/use-logout.tsx b/framework/commerce/auth/use-logout.tsx similarity index 64% rename from framework/commerce/use-logout.tsx rename to framework/commerce/auth/use-logout.tsx index 0a80c318b..d0f7e3ae0 100644 --- a/framework/commerce/use-logout.tsx +++ b/framework/commerce/auth/use-logout.tsx @@ -1,7 +1,7 @@ -import { useHook, useMutationHook } from './utils/use-hook' -import { mutationFetcher } from './utils/default-fetcher' -import type { HookFetcherFn, MutationHook } from './utils/types' -import type { Provider } from '.' +import { useHook, useMutationHook } from '../utils/use-hook' +import { mutationFetcher } from '../utils/default-fetcher' +import type { HookFetcherFn, MutationHook } from '../utils/types' +import type { Provider } from '..' export type UseLogout< H extends MutationHook = MutationHook diff --git a/framework/commerce/use-signup.tsx b/framework/commerce/auth/use-signup.tsx similarity index 64% rename from framework/commerce/use-signup.tsx rename to framework/commerce/auth/use-signup.tsx index be3c32000..72e242209 100644 --- a/framework/commerce/use-signup.tsx +++ b/framework/commerce/auth/use-signup.tsx @@ -1,7 +1,7 @@ -import { useHook, useMutationHook } from './utils/use-hook' -import { mutationFetcher } from './utils/default-fetcher' -import type { HookFetcherFn, MutationHook } from './utils/types' -import type { Provider } from '.' +import { useHook, useMutationHook } from '../utils/use-hook' +import { mutationFetcher } from '../utils/default-fetcher' +import type { HookFetcherFn, MutationHook } from '../utils/types' +import type { Provider } from '..' export type UseSignup< H extends MutationHook = MutationHook diff --git a/framework/commerce/config.json b/framework/commerce/config.json deleted file mode 100644 index a0e7afc5d..000000000 --- a/framework/commerce/config.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "features": { - "wishlist": true - } -} diff --git a/framework/commerce/use-price.tsx b/framework/commerce/product/use-price.tsx similarity index 97% rename from framework/commerce/use-price.tsx rename to framework/commerce/product/use-price.tsx index 9a3fc4b6e..9c09e3487 100644 --- a/framework/commerce/use-price.tsx +++ b/framework/commerce/product/use-price.tsx @@ -1,5 +1,5 @@ import { useMemo } from 'react' -import { useCommerce } from '.' +import { useCommerce } from '..' export function formatPrice({ amount, diff --git a/framework/commerce/types.ts b/framework/commerce/types.ts index 0ae766095..57e707f35 100644 --- a/framework/commerce/types.ts +++ b/framework/commerce/types.ts @@ -2,8 +2,10 @@ import type { Wishlist as BCWishlist } from '@framework/api/wishlist' import type { Customer as BCCustomer } from '@framework/api/customers' import type { SearchProductsData as BCSearchProductsData } from '@framework/api/catalog/products' +export type Features = 'wishlist' | 'checkout' | string + export type CommerceProviderConfig = { - features: Record + features: Record } export type Discount = { diff --git a/framework/commerce/utils/bootstrap.js b/framework/commerce/utils/bootstrap.js new file mode 100644 index 000000000..6a604b7dd --- /dev/null +++ b/framework/commerce/utils/bootstrap.js @@ -0,0 +1,11 @@ +module.exports = ({ features }) => { + let output = { + env: {}, + } + if (!!Object.keys(features).length) { + Object.keys(features).map( + (r) => (output.env[`COMMERCE_${r.toUpperCase()}_ENABLED`] = features[r]) + ) + } + return output +} diff --git a/framework/commerce/utils/features.ts b/framework/commerce/utils/features.ts index 98a53ed54..72ed0d7f5 100644 --- a/framework/commerce/utils/features.ts +++ b/framework/commerce/utils/features.ts @@ -14,6 +14,16 @@ function isFeatureEnabled(config: CommerceProviderConfig) { .includes(desideredFeature) } +export function toEnvConfig( + configMap: CommerceProviderConfig['features'] +): Map { + let toEnvConfigMap = new Map() + Object.keys(configMap).map((r) => + toEnvConfigMap.set(`${r.toUpperCase()}_ENABLED`, configMap[r]) + ) + return toEnvConfigMap +} + function boostrap(): FeaturesAPI { const basis = { isEnabled: () => false, diff --git a/next.config.js b/next.config.js index 939031884..749fd1b0a 100644 --- a/next.config.js +++ b/next.config.js @@ -1,40 +1,6 @@ -module.exports = { - images: { - domains: ['cdn11.bigcommerce.com'], - }, - i18n: { - locales: ['en-US', 'es'], - defaultLocale: 'en-US', - }, - env: { - WISHLIST_ENABLED: false, - }, - rewrites() { - return [ - { - source: '/checkout', - destination: '/api/bigcommerce/checkout', - }, - // The logout is also an action so this route is not required, but it's also another way - // you can allow a logout! - { - source: '/logout', - destination: '/api/bigcommerce/customers/logout?redirect_to=/', - }, - // Rewrites for /search - { - source: '/search/designers/:name', - destination: '/search', - }, - { - source: '/search/designers/:name/:category', - destination: '/search', - }, - { - // This rewrite will also handle `/search/designers` - source: '/search/:category', - destination: '/search', - }, - ] - }, -} +const providerConfig = require('./framework/bigcommerce/config.json') +const providerNextConfig = require('./framework/bigcommerce/next.config') +const bootstrap = require('./framework/commerce/utils/bootstrap') +const d = require('deepmerge') + +module.exports = d(providerNextConfig, bootstrap(providerConfig)) diff --git a/package.json b/package.json index d1bfbb574..8a7d64e6a 100644 --- a/package.json +++ b/package.json @@ -66,6 +66,7 @@ "@types/lodash.throttle": "^4.1.6", "@types/node": "^14.14.16", "@types/react": "^17.0.0", + "deepmerge": "^4.2.2", "graphql": "^15.4.0", "husky": "^4.3.8", "lint-staged": "^10.5.3", diff --git a/pages/wishlist.tsx b/pages/wishlist.tsx index dcda912c6..ce97532b0 100644 --- a/pages/wishlist.tsx +++ b/pages/wishlist.tsx @@ -17,7 +17,7 @@ export async function getStaticProps({ locale, }: GetStaticPropsContext) { // Disabling page if Feature is not available - if (!process.env.WISHLIST_ENABLED) { + if (!process.env.COMMERCE_WISHLIST_ENABLED) { return { notFound: true, } diff --git a/yarn.lock b/yarn.lock index e7cd08438..3497602b9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2532,6 +2532,11 @@ deep-is@~0.1.3: resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ= +deepmerge@^4.2.2: + version "4.2.2" + resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.2.2.tgz#44d2ea3679b8f4d4ffba33f03d865fc1e7bf4955" + integrity sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg== + defaults@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/defaults/-/defaults-1.0.3.tgz#c656051e9817d9ff08ed881477f3fe4019f3ef7d" From 4de9b906f4f15db74a792cd1fa743f56ea92767b Mon Sep 17 00:00:00 2001 From: okbel Date: Wed, 24 Feb 2021 19:32:03 -0300 Subject: [PATCH 166/216] typos --- framework/bigcommerce/config.json | 2 +- framework/shopify/api/index.ts | 2 +- framework/shopify/customer/use-customer.tsx | 2 +- framework/shopify/product/use-search.tsx | 2 +- package.json | 1 + yarn.lock | 5 +++++ 6 files changed, 10 insertions(+), 4 deletions(-) diff --git a/framework/bigcommerce/config.json b/framework/bigcommerce/config.json index 17ef37e25..a0e7afc5d 100644 --- a/framework/bigcommerce/config.json +++ b/framework/bigcommerce/config.json @@ -1,5 +1,5 @@ { "features": { - "wishlist": false + "wishlist": true } } diff --git a/framework/shopify/api/index.ts b/framework/shopify/api/index.ts index dcb0fc2ba..0402cfccc 100644 --- a/framework/shopify/api/index.ts +++ b/framework/shopify/api/index.ts @@ -3,7 +3,7 @@ import fetchGraphqlApi from './utils/fetch-graphql-api' export interface ShopifyConfig extends CommerceAPIConfig {} -// No I don't like this - will fix it later +// TODO(bc) const API_URL = process.env.SHOPIFY_STORE_DOMAIN || process.env.NEXT_PUBLIC_SHOPIFY_STORE_DOMAIN diff --git a/framework/shopify/customer/use-customer.tsx b/framework/shopify/customer/use-customer.tsx index a909443ff..7ea2ae679 100644 --- a/framework/shopify/customer/use-customer.tsx +++ b/framework/shopify/customer/use-customer.tsx @@ -1,6 +1,6 @@ import type { HookFetcher } from '@commerce/utils/types' import type { SwrOptions } from '@commerce/utils/use-data' -import useCommerceCustomer from '@commerce/use-customer' +import useCommerceCustomer from '@commerce/customer/use-customer' const defaultOpts = {} diff --git a/framework/shopify/product/use-search.tsx b/framework/shopify/product/use-search.tsx index a2c32c896..04f6a3536 100644 --- a/framework/shopify/product/use-search.tsx +++ b/framework/shopify/product/use-search.tsx @@ -1,6 +1,6 @@ import type { HookFetcher } from '@commerce/utils/types' import type { SwrOptions } from '@commerce/utils/use-data' -import useCommerceSearch from '@commerce/products/use-search' +import useCommerceSearch from '@commerce/product/use-search' import { ProductEdge } from '../types' const defaultOpts = {} diff --git a/package.json b/package.json index 8a7d64e6a..85bd9c063 100644 --- a/package.json +++ b/package.json @@ -46,6 +46,7 @@ "react-dom": "^17.0.1", "react-merge-refs": "^1.1.0", "react-ticker": "^1.2.2", + "shopify-buy": "^2.11.0", "swr": "^0.4.0", "tabbable": "^5.1.5", "tailwindcss": "^2.0.2" diff --git a/yarn.lock b/yarn.lock index 3497602b9..1255b9d62 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6226,6 +6226,11 @@ shell-quote@1.7.2: resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.7.2.tgz#67a7d02c76c9da24f99d20808fcaded0e0e04be2" integrity sha512-mRz/m/JVscCrkMyPqHc/bczi3OQHkLTqXHEFu0zDhK/qfv3UcOA4SVmRCLmos4bhjr9ekVQubj/R7waKapmiQg== +shopify-buy@^2.11.0: + version "2.11.0" + resolved "https://registry.yarnpkg.com/shopify-buy/-/shopify-buy-2.11.0.tgz#0f7cb52741395e4ae778c336f32ddf3fe67c2f35" + integrity sha512-bGjS1b/VCPvCjazSstlKwgLtK1WBotWom06/12loja8yfo/cWkLuJsakBbQe1uEIDiOLhKaR0M0CAXZFheYDug== + signal-exit@^3.0.0, signal-exit@^3.0.2: version "3.0.3" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c" From 0cc443db06c3293b1a3697eee7175d9b14bf0784 Mon Sep 17 00:00:00 2001 From: Luis Alvarez Date: Wed, 24 Feb 2021 21:55:45 -0500 Subject: [PATCH 167/216] Updated the way the provider config is set --- .env.template | 3 +- README.md | 5 +-- framework/bigcommerce/README.md | 1 + framework/bigcommerce/next.config.js | 38 ++++---------------- framework/commerce/with-config.js | 40 +++++++++++++++++++++ next.config.js | 53 +++++++++++++++++++++++++--- 6 files changed, 100 insertions(+), 40 deletions(-) create mode 100644 framework/commerce/with-config.js diff --git a/.env.template b/.env.template index 73a8a6e3b..83e7dd403 100644 --- a/.env.template +++ b/.env.template @@ -2,4 +2,5 @@ BIGCOMMERCE_STOREFRONT_API_URL= BIGCOMMERCE_STOREFRONT_API_TOKEN= BIGCOMMERCE_STORE_API_URL= BIGCOMMERCE_STORE_API_TOKEN= -BIGCOMMERCE_STORE_API_CLIENT_ID= \ No newline at end of file +BIGCOMMERCE_STORE_API_CLIENT_ID= +BIGCOMMERCE_CHANNEL_ID= \ No newline at end of file diff --git a/README.md b/README.md index 9d2108cfe..f254b1b07 100644 --- a/README.md +++ b/README.md @@ -77,12 +77,12 @@ Main folder and its exposed functions - `config.json` - README.md -#### Example of correct usage of Commece Framework +#### Example of correct usage of Commerce Framework ```js import { useUI } from '@components/ui' import { useCustomer } from '@framework/customer' -import { useAddItem, useWishlist, useRemoveItem } from '@framework/wishlist' +import { useWishlist, useAddItem, useRemoveItem } from '@framework/wishlist' ``` ## Config @@ -131,6 +131,7 @@ BIGCOMMERCE_STOREFRONT_API_TOKEN=<> BIGCOMMERCE_STORE_API_URL=<> BIGCOMMERCE_STORE_API_TOKEN=<> BIGCOMMERCE_STORE_API_CLIENT_ID=<> +BIGCOMMERCE_CHANNEL_ID=<> ``` If your project was started with a "Deploy with Vercel" button, you can use Vercel's CLI to retrieve these credentials. diff --git a/framework/bigcommerce/README.md b/framework/bigcommerce/README.md index 86fbac91d..2609b1544 100644 --- a/framework/bigcommerce/README.md +++ b/framework/bigcommerce/README.md @@ -47,6 +47,7 @@ BIGCOMMERCE_STOREFRONT_API_TOKEN=<> BIGCOMMERCE_STORE_API_URL=<> BIGCOMMERCE_STORE_API_TOKEN=<> BIGCOMMERCE_STORE_API_CLIENT_ID=<> +BIGCOMMERCE_CHANNEL_ID=<> ``` ## General Usage diff --git a/framework/bigcommerce/next.config.js b/framework/bigcommerce/next.config.js index e732ef78a..5703f2343 100644 --- a/framework/bigcommerce/next.config.js +++ b/framework/bigcommerce/next.config.js @@ -1,37 +1,11 @@ +const providerConfig = require('./config.json') + module.exports = { + commerce: { + provider: 'bigcommerce', + ...providerConfig, + }, images: { domains: ['cdn11.bigcommerce.com'], }, - i18n: { - locales: ['en-US', 'es'], - defaultLocale: 'en-US', - }, - rewrites() { - return [ - { - source: '/checkout', - destination: '/api/bigcommerce/checkout', - }, - // The logout is also an action so this route is not required, but it's also another way - // you can allow a logout! - { - source: '/logout', - destination: '/api/bigcommerce/customers/logout?redirect_to=/', - }, - // Rewrites for /search - { - source: '/search/designers/:name', - destination: '/search', - }, - { - source: '/search/designers/:name/:category', - destination: '/search', - }, - { - // This rewrite will also handle `/search/designers` - source: '/search/:category', - destination: '/search', - }, - ] - }, } diff --git a/framework/commerce/with-config.js b/framework/commerce/with-config.js new file mode 100644 index 000000000..6dcf08986 --- /dev/null +++ b/framework/commerce/with-config.js @@ -0,0 +1,40 @@ +/** + * This file is expected to be used in next.config.js only + */ + +const merge = require('deepmerge') + +const PROVIDERS = ['bigcommerce'] + +function getProviderName() { + return process.env.BIGCOMMERCE_STOREFRONT_API_URL ? 'bigcommerce' : null +} + +module.exports = (nextConfig = {}) => { + const commerce = nextConfig.commerce || {} + const name = commerce.provider || getProviderName() + + if (!name) { + throw new Error( + `The commerce provider is missing, please add a valid provider name or its environment variables` + ) + } + if (!PROVIDERS.includes(name)) { + throw new Error( + `The commerce provider "${name}" can't be found, please use one of "${PROVIDERS.join( + ', ' + )}"` + ) + } + + const commerceNextConfig = require(`../${name}/next.config`) + const config = merge(commerceNextConfig, nextConfig) + + config.env = config.env || {} + + Object.entries(config.commerce.features).forEach(([k, v]) => { + if (v) config.env[`COMMERCE_${k.toUpperCase()}_ENABLED`] = true + }) + + return config +} diff --git a/next.config.js b/next.config.js index 749fd1b0a..74be36a5d 100644 --- a/next.config.js +++ b/next.config.js @@ -1,6 +1,49 @@ -const providerConfig = require('./framework/bigcommerce/config.json') -const providerNextConfig = require('./framework/bigcommerce/next.config') -const bootstrap = require('./framework/commerce/utils/bootstrap') -const d = require('deepmerge') +// const providerConfig = require('./framework/bigcommerce/config.json') +// const providerNextConfig = require('./framework/bigcommerce/next.config') +// const bootstrap = require('./framework/commerce/utils/bootstrap') +// const d = require('deepmerge') -module.exports = d(providerNextConfig, bootstrap(providerConfig)) +// module.exports = d(providerNextConfig, bootstrap(providerConfig)) + +const withCommerceConfig = require('./framework/commerce/with-config') + +const commerce = { provider: 'bigcommerce' } +const isBC = commerce.provider === 'bigcommerce' + +module.exports = withCommerceConfig({ + commerce, + i18n: { + locales: ['en-US', 'es'], + defaultLocale: 'en-US', + }, + rewrites() { + return [ + isBC && { + source: '/checkout', + destination: '/api/bigcommerce/checkout', + }, + // The logout is also an action so this route is not required, but it's also another way + // you can allow a logout! + isBC && { + source: '/logout', + destination: '/api/bigcommerce/customers/logout?redirect_to=/', + }, + // Rewrites for /search + { + source: '/search/designers/:name', + destination: '/search', + }, + { + source: '/search/designers/:name/:category', + destination: '/search', + }, + { + // This rewrite will also handle `/search/designers` + source: '/search/:category', + destination: '/search', + }, + ].filter((x) => x) + }, +}) + +console.log('RESULT', module.exports) From 4c156422a6b60242b86bb32401ee01a0df94872b Mon Sep 17 00:00:00 2001 From: Luis Alvarez Date: Wed, 24 Feb 2021 21:57:38 -0500 Subject: [PATCH 168/216] Removed features.ts --- framework/commerce/types.ts | 6 ---- framework/commerce/utils/features.ts | 47 ---------------------------- package.json | 2 -- yarn.lock | 12 ------- 4 files changed, 67 deletions(-) delete mode 100644 framework/commerce/utils/features.ts diff --git a/framework/commerce/types.ts b/framework/commerce/types.ts index 57e707f35..bf635c9dc 100644 --- a/framework/commerce/types.ts +++ b/framework/commerce/types.ts @@ -2,12 +2,6 @@ import type { Wishlist as BCWishlist } from '@framework/api/wishlist' import type { Customer as BCCustomer } from '@framework/api/customers' import type { SearchProductsData as BCSearchProductsData } from '@framework/api/catalog/products' -export type Features = 'wishlist' | 'checkout' | string - -export type CommerceProviderConfig = { - features: Record -} - export type Discount = { // The value of the discount, can be an amount or percentage value: number diff --git a/framework/commerce/utils/features.ts b/framework/commerce/utils/features.ts deleted file mode 100644 index 72ed0d7f5..000000000 --- a/framework/commerce/utils/features.ts +++ /dev/null @@ -1,47 +0,0 @@ -import commerceProviderConfig from '../config.json' -import type { CommerceProviderConfig } from '../types' -import memo from 'lodash.memoize' - -type FeaturesAPI = { - isEnabled: (desideredFeature: string) => boolean -} - -function isFeatureEnabled(config: CommerceProviderConfig) { - const features = config.features - return (desideredFeature: string) => - Object.keys(features) - .filter((k) => features[k]) - .includes(desideredFeature) -} - -export function toEnvConfig( - configMap: CommerceProviderConfig['features'] -): Map { - let toEnvConfigMap = new Map() - Object.keys(configMap).map((r) => - toEnvConfigMap.set(`${r.toUpperCase()}_ENABLED`, configMap[r]) - ) - return toEnvConfigMap -} - -function boostrap(): FeaturesAPI { - const basis = { - isEnabled: () => false, - } - - if (!commerceProviderConfig) { - console.log('No config.json found - Please add a config.json') - return basis - } - - if (commerceProviderConfig.features) { - return { - ...basis, - isEnabled: memo(isFeatureEnabled(commerceProviderConfig)), - } - } - - return basis -} - -export default boostrap() diff --git a/package.json b/package.json index 8a7d64e6a..a8a698112 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,6 @@ }, "dependencies": { "@reach/portal": "^0.11.2", - "@types/lodash.memoize": "^4.1.6", "@vercel/fetch": "^6.1.0", "body-scroll-lock": "^3.1.5", "bowser": "^2.11.0", @@ -34,7 +33,6 @@ "js-cookie": "^2.2.1", "keen-slider": "^5.2.4", "lodash.debounce": "^4.0.8", - "lodash.memoize": "^4.1.2", "lodash.random": "^3.2.0", "lodash.throttle": "^4.1.1", "next": "^10.0.7-canary.3", diff --git a/yarn.lock b/yarn.lock index 3497602b9..47c5781fb 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1060,13 +1060,6 @@ dependencies: "@types/lodash" "*" -"@types/lodash.memoize@^4.1.6": - version "4.1.6" - resolved "https://registry.yarnpkg.com/@types/lodash.memoize/-/lodash.memoize-4.1.6.tgz#3221f981790a415cab1a239f25c17efd8b604c23" - integrity sha512-mYxjKiKzRadRJVClLKxS4wb3Iy9kzwJ1CkbyKiadVxejnswnRByyofmPMscFKscmYpl36BEEhCMPuWhA1R/1ZQ== - dependencies: - "@types/lodash" "*" - "@types/lodash.random@^3.2.6": version "3.2.6" resolved "https://registry.yarnpkg.com/@types/lodash.random/-/lodash.random-3.2.6.tgz#64b08abad168dca39c778ed40cce75b2f9e168eb" @@ -4244,11 +4237,6 @@ lodash.isstring@^4.0.1: resolved "https://registry.yarnpkg.com/lodash.isstring/-/lodash.isstring-4.0.1.tgz#d527dfb5456eca7cc9bb95d5daeaf88ba54a5451" integrity sha1-1SfftUVuynzJu5XV2ur4i6VKVFE= -lodash.memoize@^4.1.2: - version "4.1.2" - resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" - integrity sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4= - lodash.once@^4.0.0: version "4.1.1" resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac" From 764e0db322696f5c3851dbf3dc7ae48c271d3d3d Mon Sep 17 00:00:00 2001 From: Luis Alvarez Date: Wed, 24 Feb 2021 21:58:39 -0500 Subject: [PATCH 169/216] Removed bootstrap.js --- framework/commerce/utils/bootstrap.js | 11 ----------- next.config.js | 9 --------- 2 files changed, 20 deletions(-) delete mode 100644 framework/commerce/utils/bootstrap.js diff --git a/framework/commerce/utils/bootstrap.js b/framework/commerce/utils/bootstrap.js deleted file mode 100644 index 6a604b7dd..000000000 --- a/framework/commerce/utils/bootstrap.js +++ /dev/null @@ -1,11 +0,0 @@ -module.exports = ({ features }) => { - let output = { - env: {}, - } - if (!!Object.keys(features).length) { - Object.keys(features).map( - (r) => (output.env[`COMMERCE_${r.toUpperCase()}_ENABLED`] = features[r]) - ) - } - return output -} diff --git a/next.config.js b/next.config.js index 74be36a5d..725024066 100644 --- a/next.config.js +++ b/next.config.js @@ -1,10 +1,3 @@ -// const providerConfig = require('./framework/bigcommerce/config.json') -// const providerNextConfig = require('./framework/bigcommerce/next.config') -// const bootstrap = require('./framework/commerce/utils/bootstrap') -// const d = require('deepmerge') - -// module.exports = d(providerNextConfig, bootstrap(providerConfig)) - const withCommerceConfig = require('./framework/commerce/with-config') const commerce = { provider: 'bigcommerce' } @@ -45,5 +38,3 @@ module.exports = withCommerceConfig({ ].filter((x) => x) }, }) - -console.log('RESULT', module.exports) From f242f3c58859caee30ebbecbb0e8387c197d26d6 Mon Sep 17 00:00:00 2001 From: cond0r Date: Thu, 25 Feb 2021 09:55:02 +0200 Subject: [PATCH 170/216] Aligned with upstream changes --- .../cart/CartSidebarView/CartSidebarView.tsx | 3 ++- framework/commerce/with-config.js | 2 +- framework/shopify/api/checkout/index.ts | 21 +++++++++++-------- framework/shopify/auth/use-login.tsx | 4 +--- framework/shopify/auth/use-logout.tsx | 2 +- framework/shopify/auth/use-signup.tsx | 2 +- framework/shopify/common/get-all-pages.ts | 21 ++++++++++++++----- framework/shopify/common/get-page.ts | 13 ++++++------ framework/shopify/next.config.js | 11 ++++++++++ .../shopify/product/get-all-product-paths.ts | 11 +++++++++- framework/shopify/product/get-all-products.ts | 14 ++++++------- framework/shopify/product/use-price.tsx | 4 ++-- framework/shopify/utils/normalize.ts | 2 +- .../utils/queries/get-all-pages-query.ts | 3 --- .../shopify/utils/queries/get-page-query.ts | 1 - next.config.js | 5 +++-- tsconfig.json | 5 +++-- 17 files changed, 77 insertions(+), 47 deletions(-) create mode 100644 framework/shopify/next.config.js diff --git a/components/cart/CartSidebarView/CartSidebarView.tsx b/components/cart/CartSidebarView/CartSidebarView.tsx index 3ceda44fe..cb932247f 100644 --- a/components/cart/CartSidebarView/CartSidebarView.tsx +++ b/components/cart/CartSidebarView/CartSidebarView.tsx @@ -8,6 +8,7 @@ import useCart from '@framework/cart/use-cart' import usePrice from '@framework/product/use-price' import CartItem from '../CartItem' import s from './CartSidebarView.module.css' +import { LineItem } from '@commerce/types' const CartSidebarView: FC = () => { const { closeSidebar } = useUI() @@ -91,7 +92,7 @@ const CartSidebarView: FC = () => { My Cart
    diff --git a/framework/shopify/api/checkout/index.ts b/framework/shopify/api/checkout/index.ts index ea9b101e1..d5d6d7f6e 100644 --- a/framework/shopify/api/checkout/index.ts +++ b/framework/shopify/api/checkout/index.ts @@ -1 +1,46 @@ -export default function () {} +import isAllowedMethod from '../utils/is-allowed-method' +import createApiHandler, { + ShopifyApiHandler, +} from '../utils/create-api-handler' + +import { + SHOPIFY_CHECKOUT_ID_COOKIE, + SHOPIFY_CHECKOUT_URL_COOKIE, + SHOPIFY_CUSTOMER_TOKEN_COOKIE, +} from '@framework/const' + +import { getConfig } from '..' +import associateCustomerWithCheckoutMutation from '@framework/utils/mutations/associate-customer-with-checkout' + +const METHODS = ['GET'] + +const checkoutApi: ShopifyApiHandler = async (req, res, config) => { + if (!isAllowedMethod(req, res, METHODS)) return + + config = getConfig() + + const { cookies } = req + const checkoutUrl = cookies[SHOPIFY_CHECKOUT_URL_COOKIE] + const customerCookie = cookies[SHOPIFY_CUSTOMER_TOKEN_COOKIE] + + if (customerCookie) { + try { + await config.fetch(associateCustomerWithCheckoutMutation, { + variables: { + checkoutId: cookies[SHOPIFY_CHECKOUT_ID_COOKIE], + customerAccessToken: cookies[SHOPIFY_CUSTOMER_TOKEN_COOKIE], + }, + }) + } catch (error) { + console.error(error) + } + } + + if (checkoutUrl) { + res.redirect(checkoutUrl) + } else { + res.redirect('/cart') + } +} + +export default createApiHandler(checkoutApi, {}, {}) diff --git a/framework/shopify/api/customer.ts b/framework/shopify/api/customer.ts new file mode 100644 index 000000000..ea9b101e1 --- /dev/null +++ b/framework/shopify/api/customer.ts @@ -0,0 +1 @@ +export default function () {} diff --git a/framework/shopify/api/index.ts b/framework/shopify/api/index.ts index 8646d0136..184d03748 100644 --- a/framework/shopify/api/index.ts +++ b/framework/shopify/api/index.ts @@ -1,24 +1,29 @@ import type { CommerceAPIConfig } from '@commerce/api' -import fetchGraphqlApi from './utils/fetch-graphql-api' -export interface ShopifyConfig extends CommerceAPIConfig {} - -const API_URL = process.env.SHOPIFY_STORE_DOMAIN -const API_TOKEN = process.env.SHOPIFY_STOREFRONT_ACCESS_TOKEN +import { + API_URL, + API_TOKEN, + SHOPIFY_CHECKOUT_ID_COOKIE, + SHOPIFY_CUSTOMER_TOKEN_COOKIE, +} from '@framework/const' if (!API_URL) { console.log(process.env) throw new Error( - `The environment variable SHOPIFY_STORE_DOMAIN is missing and it's required to access your store` + `The environment variable NEXT_PUBLIC_SHOPIFY_STORE_DOMAIN is missing and it's required to access your store` ) } if (!API_TOKEN) { throw new Error( - `The environment variable SHOPIFY_STOREFRONT_ACCESS_TOKEN is missing and it's required to access your store` + `The environment variable NEXT_PUBLIC_SHOPIFY_STOREFRONT_ACCESS_TOKEN is missing and it's required to access your store` ) } +import fetchGraphqlApi from './utils/fetch-graphql-api' + +export interface ShopifyConfig extends CommerceAPIConfig {} + export class Config { private config: ShopifyConfig @@ -40,11 +45,11 @@ export class Config { const config = new Config({ commerceUrl: API_URL, - apiToken: API_TOKEN, - // TODO - // @ts-ignore + apiToken: API_TOKEN!, + cartCookie: SHOPIFY_CHECKOUT_ID_COOKIE, + cartCookieMaxAge: 60 * 60 * 24 * 30, fetch: fetchGraphqlApi, - customerCookie: 'SHOP_TOKEN', + customerCookie: SHOPIFY_CUSTOMER_TOKEN_COOKIE, }) export function getConfig(userConfig?: Partial) { diff --git a/framework/shopify/api/utils/create-api-handler.ts b/framework/shopify/api/utils/create-api-handler.ts new file mode 100644 index 000000000..8820aeabc --- /dev/null +++ b/framework/shopify/api/utils/create-api-handler.ts @@ -0,0 +1,58 @@ +import type { NextApiHandler, NextApiRequest, NextApiResponse } from 'next' +import { ShopifyConfig, getConfig } from '..' + +export type ShopifyApiHandler< + T = any, + H extends ShopifyHandlers = {}, + Options extends {} = {} +> = ( + req: NextApiRequest, + res: NextApiResponse>, + config: ShopifyConfig, + handlers: H, + // Custom configs that may be used by a particular handler + options: Options +) => void | Promise + +export type ShopifyHandler = (options: { + req: NextApiRequest + res: NextApiResponse> + config: ShopifyConfig + body: Body +}) => void | Promise + +export type ShopifyHandlers = { + [k: string]: ShopifyHandler +} + +export type ShopifyApiResponse = { + data: T | null + errors?: { message: string; code?: string }[] +} + +export default function createApiHandler< + T = any, + H extends ShopifyHandlers = {}, + Options extends {} = {} +>( + handler: ShopifyApiHandler, + handlers: H, + defaultOptions: Options +) { + return function getApiHandler({ + config, + operations, + options, + }: { + config?: ShopifyConfig + operations?: Partial + options?: Options extends {} ? Partial : never + } = {}): NextApiHandler { + const ops = { ...operations, ...handlers } + const opts = { ...defaultOptions, ...options } + + return function apiHandler(req, res) { + return handler(req, res, getConfig(config), ops, opts) + } + } +} diff --git a/framework/shopify/api/utils/fetch-all-products.ts b/framework/shopify/api/utils/fetch-all-products.ts new file mode 100644 index 000000000..efeb809f1 --- /dev/null +++ b/framework/shopify/api/utils/fetch-all-products.ts @@ -0,0 +1,41 @@ +import { ProductEdge } from '@framework/schema' +import { ShopifyConfig } from '..' + +const fetchAllProducts = async ({ + config, + query, + variables, + acc = [], + cursor, +}: { + config: ShopifyConfig + query: string + acc?: ProductEdge[] + variables?: any + cursor?: string +}): Promise => { + const { data } = await config.fetch(query, { + variables: { ...variables, cursor }, + }) + + const edges: ProductEdge[] = data.products?.edges ?? [] + const hasNextPage = data.products?.pageInfo?.hasNextPage + acc = acc.concat(edges) + + if (hasNextPage) { + const cursor = edges.pop()?.cursor + if (cursor) { + return fetchAllProducts({ + config, + query, + variables, + acc, + cursor, + }) + } + } + + return acc +} + +export default fetchAllProducts diff --git a/framework/shopify/api/utils/fetch-graphql-api.ts b/framework/shopify/api/utils/fetch-graphql-api.ts index f3f8b9a17..92d4f2cf6 100644 --- a/framework/shopify/api/utils/fetch-graphql-api.ts +++ b/framework/shopify/api/utils/fetch-graphql-api.ts @@ -1,33 +1,19 @@ -import { CommerceAPIFetchOptions } from '@commerce/api' -import { FetcherError } from '@commerce/utils/errors' -import { getConfig } from '../index' +import type { GraphQLFetcher } from '@commerce/api' +import fetch from './fetch' -export interface GraphQLFetcherResult { - data: Data - res: Response -} -export type GraphQLFetcher< - Data extends GraphQLFetcherResult = GraphQLFetcherResult, - Variables = any -> = ( - query: string, - queryData?: CommerceAPIFetchOptions, - fetchOptions?: RequestInit -) => Promise +import { API_URL, API_TOKEN } from '../../const' +import { getError } from '@framework/utils/handle-fetch-response' const fetchGraphqlApi: GraphQLFetcher = async ( query: string, { variables } = {}, fetchOptions ) => { - const config = getConfig() - const url = `https://${config.commerceUrl}/api/2021-01/graphql.json` - - const res = await fetch(url, { + const res = await fetch(API_URL, { ...fetchOptions, method: 'POST', headers: { - 'X-Shopify-Storefront-Access-Token': config.apiToken, + 'X-Shopify-Storefront-Access-Token': API_TOKEN!, ...fetchOptions?.headers, 'Content-Type': 'application/json', }, @@ -37,15 +23,12 @@ const fetchGraphqlApi: GraphQLFetcher = async ( }), }) - const json = await res.json() - if (json.errors) { - throw new FetcherError({ - errors: json.errors ?? [{ message: 'Failed to fetch Shopify API' }], - status: res.status, - }) + const { data, errors, status } = await res.json() + + if (errors) { + throw getError(errors, status) } - return { data: json.data, res } + return { data, res } } - export default fetchGraphqlApi diff --git a/framework/shopify/api/utils/fetch.ts b/framework/shopify/api/utils/fetch.ts new file mode 100644 index 000000000..0b8367102 --- /dev/null +++ b/framework/shopify/api/utils/fetch.ts @@ -0,0 +1,2 @@ +import zeitFetch from '@vercel/fetch' +export default zeitFetch() diff --git a/framework/shopify/api/utils/is-allowed-method.ts b/framework/shopify/api/utils/is-allowed-method.ts new file mode 100644 index 000000000..78bbba568 --- /dev/null +++ b/framework/shopify/api/utils/is-allowed-method.ts @@ -0,0 +1,28 @@ +import type { NextApiRequest, NextApiResponse } from 'next' + +export default function isAllowedMethod( + req: NextApiRequest, + res: NextApiResponse, + allowedMethods: string[] +) { + const methods = allowedMethods.includes('OPTIONS') + ? allowedMethods + : [...allowedMethods, 'OPTIONS'] + + if (!req.method || !methods.includes(req.method)) { + res.status(405) + res.setHeader('Allow', methods.join(', ')) + res.end() + return false + } + + if (req.method === 'OPTIONS') { + res.status(200) + res.setHeader('Allow', methods.join(', ')) + res.setHeader('Content-Length', '0') + res.end() + return false + } + + return true +} diff --git a/framework/shopify/auth/use-login.tsx b/framework/shopify/auth/use-login.tsx index 75f067c3a..32dd91920 100644 --- a/framework/shopify/auth/use-login.tsx +++ b/framework/shopify/auth/use-login.tsx @@ -1,13 +1,76 @@ import { useCallback } from 'react' +import type { MutationHook } from '@commerce/utils/types' +import { CommerceError, ValidationError } from '@commerce/utils/errors' +import useCustomer from '../customer/use-customer' +import createCustomerAccessTokenMutation from '../utils/mutations/customer-access-token-create' +import { + CustomerAccessTokenCreateInput, + CustomerUserError, + Mutation, + MutationCheckoutCreateArgs, +} from '@framework/schema' +import useLogin, { UseLogin } from '@commerce/auth/use-login' +import { setCustomerToken } from '@framework/utils' -export function emptyHook() { - const useEmptyHook = async (options = {}) => { - return useCallback(async function () { - return Promise.resolve() - }, []) +export default useLogin as UseLogin + +const getErrorMessage = ({ code, message }: CustomerUserError) => { + switch (code) { + case 'UNIDENTIFIED_CUSTOMER': + message = 'Cannot find an account that matches the provided credentials' + break } - - return useEmptyHook + return message } -export default emptyHook +export const handler: MutationHook = { + fetchOptions: { + query: createCustomerAccessTokenMutation, + }, + async fetcher({ input: { email, password }, options, fetch }) { + if (!(email && password)) { + throw new CommerceError({ + message: + 'A first name, last name, email and password are required to login', + }) + } + + const { customerAccessTokenCreate } = await fetch< + Mutation, + MutationCheckoutCreateArgs + >({ + ...options, + variables: { + input: { email, password }, + }, + }) + + const errors = customerAccessTokenCreate?.customerUserErrors + + if (errors && errors.length) { + throw new ValidationError({ + message: getErrorMessage(errors[0]), + }) + } + const customerAccessToken = customerAccessTokenCreate?.customerAccessToken + const accessToken = customerAccessToken?.accessToken + + if (accessToken) { + setCustomerToken(accessToken) + } + + return null + }, + useHook: ({ fetch }) => () => { + const { revalidate } = useCustomer() + + return useCallback( + async function login(input) { + const data = await fetch({ input }) + await revalidate() + return data + }, + [fetch, revalidate] + ) + }, +} diff --git a/framework/shopify/auth/use-logout.tsx b/framework/shopify/auth/use-logout.tsx index 75f067c3a..ccbeb8166 100644 --- a/framework/shopify/auth/use-logout.tsx +++ b/framework/shopify/auth/use-logout.tsx @@ -1,13 +1,39 @@ import { useCallback } from 'react' +import type { MutationHook } from '@commerce/utils/types' +import useLogout, { UseLogout } from '@commerce/auth/use-logout' +import useCustomer from '../customer/use-customer' +import customerAccessTokenDeleteMutation from '@framework/utils/mutations/customer-access-token-delete' +import { + getCustomerToken, + setCustomerToken, +} from '@framework/utils/customer-token' -export function emptyHook() { - const useEmptyHook = async (options = {}) => { - return useCallback(async function () { - return Promise.resolve() - }, []) - } +export default useLogout as UseLogout - return useEmptyHook +export const handler: MutationHook = { + fetchOptions: { + query: customerAccessTokenDeleteMutation, + }, + async fetcher({ options, fetch }) { + await fetch({ + ...options, + variables: { + customerAccessToken: getCustomerToken(), + }, + }) + setCustomerToken(null) + return null + }, + useHook: ({ fetch }) => () => { + const { mutate } = useCustomer() + + return useCallback( + async function logout() { + const data = await fetch() + await mutate(null, false) + return data + }, + [fetch, mutate] + ) + }, } - -export default emptyHook diff --git a/framework/shopify/auth/use-signup.tsx b/framework/shopify/auth/use-signup.tsx index 75f067c3a..f072f1925 100644 --- a/framework/shopify/auth/use-signup.tsx +++ b/framework/shopify/auth/use-signup.tsx @@ -1,13 +1,74 @@ import { useCallback } from 'react' +import type { MutationHook } from '@commerce/utils/types' +import { CommerceError } from '@commerce/utils/errors' +import useSignup, { UseSignup } from '@commerce/auth/use-signup' +import useCustomer from '../customer/use-customer' +import { CustomerCreateInput } from '@framework/schema' -export function emptyHook() { - const useEmptyHook = async (options = {}) => { - return useCallback(async function () { - return Promise.resolve() - }, []) - } +import { + customerCreateMutation, + customerAccessTokenCreateMutation, +} from '@framework/utils/mutations' +import handleLogin from '@framework/utils/handle-login' - return useEmptyHook +export default useSignup as UseSignup + +export const handler: MutationHook< + null, + {}, + CustomerCreateInput, + CustomerCreateInput +> = { + fetchOptions: { + query: customerCreateMutation, + }, + async fetcher({ + input: { firstName, lastName, email, password }, + options, + fetch, + }) { + if (!(firstName && lastName && email && password)) { + throw new CommerceError({ + message: + 'A first name, last name, email and password are required to signup', + }) + } + const data = await fetch({ + ...options, + variables: { + input: { + firstName, + lastName, + email, + password, + }, + }, + }) + + try { + const loginData = await fetch({ + query: customerAccessTokenCreateMutation, + variables: { + input: { + email, + password, + }, + }, + }) + handleLogin(loginData) + } catch (error) {} + return data + }, + useHook: ({ fetch }) => () => { + const { revalidate } = useCustomer() + + return useCallback( + async function signup(input) { + const data = await fetch({ input }) + await revalidate() + return data + }, + [fetch, revalidate] + ) + }, } - -export default emptyHook diff --git a/framework/shopify/cart/index.ts b/framework/shopify/cart/index.ts index e1c6ef823..3d288b1df 100644 --- a/framework/shopify/cart/index.ts +++ b/framework/shopify/cart/index.ts @@ -1,5 +1,3 @@ export { default as useCart } from './use-cart' export { default as useAddItem } from './use-add-item' export { default as useRemoveItem } from './use-remove-item' -// export { default as useWishlistActions } from './use-cart-actions' -// export { default as useUpdateItem } from './use-cart-actions' diff --git a/framework/shopify/cart/use-add-item.tsx b/framework/shopify/cart/use-add-item.tsx index 276d66e30..36f02847b 100644 --- a/framework/shopify/cart/use-add-item.tsx +++ b/framework/shopify/cart/use-add-item.tsx @@ -1,30 +1,57 @@ +import type { MutationHook } from '@commerce/utils/types' +import { CommerceError } from '@commerce/utils/errors' +import useAddItem, { UseAddItem } from '@commerce/cart/use-add-item' +import useCart from './use-cart' +import { Cart, CartItemBody } from '../types' +import { checkoutLineItemAddMutation, getCheckoutId } from '../utils' +import { checkoutToCart } from './utils' +import { Mutation, MutationCheckoutLineItemsAddArgs } from '../schema' import { useCallback } from 'react' -import { LineItemToAdd } from 'shopify-buy' -import { useCommerce } from '../index' -type Options = { - productId: number - variantId: string | number +export default useAddItem as UseAddItem + +export const handler: MutationHook = { + fetchOptions: { + query: checkoutLineItemAddMutation, + }, + async fetcher({ input: item, options, fetch }) { + if ( + item.quantity && + (!Number.isInteger(item.quantity) || item.quantity! < 1) + ) { + throw new CommerceError({ + message: 'The item quantity has to be a valid integer greater than 0', + }) + } + + const { checkoutLineItemsAdd } = await fetch< + Mutation, + MutationCheckoutLineItemsAddArgs + >({ + ...options, + variables: { + checkoutId: getCheckoutId(), + lineItems: [ + { + variantId: item.variantId, + quantity: item.quantity ?? 1, + }, + ], + }, + }) + + return checkoutToCart(checkoutLineItemsAdd) + }, + useHook: ({ fetch }) => () => { + const { mutate } = useCart() + + return useCallback( + async function addItem(input) { + const data = await fetch({ input }) + await mutate(data, false) + return data + }, + [fetch, mutate] + ) + }, } - -const useAddItem = () => { - const { checkout, client, updateCheckout } = useCommerce() - - return useCallback( - async function addItem(options: Options) { - const lineItems: LineItemToAdd[] = [ - { - variantId: `${options.variantId}`, - quantity: 1, - }, - ] - - const cart = await client?.checkout.addLineItems(checkout.id, lineItems) - updateCheckout(cart) - return cart - }, - [checkout, client] - ) -} - -export default useAddItem diff --git a/framework/shopify/cart/use-cart.tsx b/framework/shopify/cart/use-cart.tsx index e69afda0c..2cf3a3e95 100644 --- a/framework/shopify/cart/use-cart.tsx +++ b/framework/shopify/cart/use-cart.tsx @@ -1,47 +1,60 @@ -import { useCommerce } from '../index' -import useCart, { UseCart, FetchCartInput } from '@commerce/cart/use-cart' -import type { Cart } from '../types' +import { useMemo } from 'react' +import type { ShopifyProvider } from '..' -// export default useCart as UseCart -export default useCart as UseCart +import useCommerceCart, { + FetchCartInput, + UseCart, +} from '@commerce/cart/use-cart' -export const handler = () => { - const { checkout } = useCommerce() - const { lineItems, totalPriceV2 } = checkout || {} +import { Cart } from '@commerce/types' +import { SWRHook } from '@commerce/utils/types' +import { checkoutCreate, checkoutToCart } from './utils' +import getCheckoutQuery from '../utils/queries/get-checkout-query' - console.log(checkout) +export default useCommerceCart as UseCart - return { - data: { - subTotal: totalPriceV2?.amount || 0, - total: totalPriceV2?.amount || 0, - currency: { - code: '', - }, - line_items: - lineItems?.map((item) => { - return [ - { - id: item.id, - name: item.title, - quantity: item.quantity, +export const handler: SWRHook< + Cart | null, + {}, + FetchCartInput, + { isEmpty?: boolean } +> = { + fetchOptions: { + query: getCheckoutQuery, + }, + async fetcher({ input: { cartId: checkoutId }, options, fetch }) { + let checkout + if (checkoutId) { + const data = await fetch({ + ...options, + variables: { + checkoutId, + }, + }) + checkout = data.node + } + + if (checkout?.completedAt || !checkoutId) { + checkout = await checkoutCreate(fetch) + } + + return checkoutToCart({ checkout }) + }, + useHook: ({ useData }) => (input) => { + const response = useData({ + swrOptions: { revalidateOnFocus: false, ...input?.swrOptions }, + }) + return useMemo( + () => + Object.create(response, { + isEmpty: { + get() { + return (response.data?.lineItems.length ?? 0) <= 0 }, - ] - }) || [], - items: - lineItems?.map((item) => { - return { - id: item.id, - name: item.title, - images: [{ url: '/jacket.png' }], - url: '/', - quantity: item.quantity, - productId: item.id, - variantId: item.id, - } - }) || [], - }, - isEmpty: false, - isLoading: false, - } + enumerable: true, + }, + }), + [response] + ) + }, } diff --git a/framework/shopify/cart/use-remove-item.tsx b/framework/shopify/cart/use-remove-item.tsx index c0ce93bd5..1963176c8 100644 --- a/framework/shopify/cart/use-remove-item.tsx +++ b/framework/shopify/cart/use-remove-item.tsx @@ -1,17 +1,75 @@ import { useCallback } from 'react' -import { useCommerce } from '../index' -const useRemoveItem = () => { - const { checkout, client, updateCheckout } = useCommerce() +import type { + MutationHookContext, + HookFetcherContext, +} from '@commerce/utils/types' - return useCallback( - async function removeItem({ id }: { id: string }) { - const cart = await client?.checkout.removeLineItems(checkout.id, [id]) - updateCheckout(cart) - return cart - }, - [checkout, client] - ) +import { ValidationError } from '@commerce/utils/errors' + +import useRemoveItem, { + RemoveItemInput as RemoveItemInputBase, + UseRemoveItem, +} from '@commerce/cart/use-remove-item' + +import useCart from './use-cart' +import { checkoutLineItemRemoveMutation, getCheckoutId } from '@framework/utils' +import { checkoutToCart } from './utils' +import { Cart, LineItem } from '@framework/types' +import { + Mutation, + MutationCheckoutLineItemsRemoveArgs, +} from '@framework/schema' +import { RemoveCartItemBody } from '@commerce/types' + +export type RemoveItemFn = T extends LineItem + ? (input?: RemoveItemInput) => Promise + : (input: RemoveItemInput) => Promise + +export type RemoveItemInput = T extends LineItem + ? Partial + : RemoveItemInputBase + +export default useRemoveItem as UseRemoveItem + +export const handler = { + fetchOptions: { + query: checkoutLineItemRemoveMutation, + }, + async fetcher({ + input: { itemId }, + options, + fetch, + }: HookFetcherContext) { + const data = await fetch({ + ...options, + variables: { checkoutId: getCheckoutId(), lineItemIds: [itemId] }, + }) + return checkoutToCart(data.checkoutLineItemsRemove) + }, + useHook: ({ + fetch, + }: MutationHookContext) => < + T extends LineItem | undefined = undefined + >( + ctx: { item?: T } = {} + ) => { + const { item } = ctx + const { mutate } = useCart() + const removeItem: RemoveItemFn = async (input) => { + const itemId = input?.id ?? item?.id + + if (!itemId) { + throw new ValidationError({ + message: 'Invalid input used for this operation', + }) + } + + const data = await fetch({ input: { itemId } }) + await mutate(data, false) + return data + } + + return useCallback(removeItem as RemoveItemFn, [fetch, mutate]) + }, } - -export default useRemoveItem diff --git a/framework/shopify/cart/use-update-item.tsx b/framework/shopify/cart/use-update-item.tsx index 05118a65b..9e89d0aca 100644 --- a/framework/shopify/cart/use-update-item.tsx +++ b/framework/shopify/cart/use-update-item.tsx @@ -1,24 +1,110 @@ import { useCallback } from 'react' -import { useCommerce } from '../index' +import debounce from 'lodash.debounce' +import type { + HookFetcherContext, + MutationHookContext, +} from '@commerce/utils/types' +import { ValidationError } from '@commerce/utils/errors' +import useUpdateItem, { + UpdateItemInput as UpdateItemInputBase, + UseUpdateItem, +} from '@commerce/cart/use-update-item' -const useUpdateItem = (item: CartItem) => { - const { checkout, client, updateCheckout } = useCommerce() +import useCart from './use-cart' +import { handler as removeItemHandler } from './use-remove-item' +import type { Cart, LineItem, UpdateCartItemBody } from '../types' +import { checkoutToCart } from './utils' +import { getCheckoutId, checkoutLineItemUpdateMutation } from '../utils' +import { + Mutation, + MutationCheckoutLineItemsUpdateArgs, +} from '@framework/schema' - return useCallback( - async function updateItem({ quantity }: { quantity: number }) { - const lineItemsToUpdate = [{ id: item.id, quantity }] +export type UpdateItemInput = T extends LineItem + ? Partial> + : UpdateItemInputBase - const cart = await client?.checkout.updateLineItems( - checkout.id, - lineItemsToUpdate - ) +export default useUpdateItem as UseUpdateItem - updateCheckout(cart) +export const handler = { + fetchOptions: { + query: checkoutLineItemUpdateMutation, + }, + async fetcher({ + input: { itemId, item }, + options, + fetch, + }: HookFetcherContext) { + if (Number.isInteger(item.quantity)) { + // Also allow the update hook to remove an item if the quantity is lower than 1 + if (item.quantity! < 1) { + return removeItemHandler.fetcher({ + options: removeItemHandler.fetchOptions, + input: { itemId }, + fetch, + }) + } + } else if (item.quantity) { + throw new ValidationError({ + message: 'The item quantity has to be a valid integer', + }) + } + const { checkoutLineItemsUpdate } = await fetch< + Mutation, + MutationCheckoutLineItemsUpdateArgs + >({ + ...options, + variables: { + checkoutId: getCheckoutId(), + lineItems: [ + { + id: itemId, + quantity: item.quantity, + }, + ], + }, + }) - return cart - }, - [checkout, client] - ) + return checkoutToCart(checkoutLineItemsUpdate) + }, + useHook: ({ + fetch, + }: MutationHookContext) => < + T extends LineItem | undefined = undefined + >( + ctx: { + item?: T + wait?: number + } = {} + ) => { + const { item } = ctx + const { mutate } = useCart() as any + + return useCallback( + debounce(async (input: UpdateItemInput) => { + const itemId = input.id ?? item?.id + const productId = input.productId ?? item?.productId + const variantId = input.productId ?? item?.variantId + if (!itemId || !productId || !variantId) { + throw new ValidationError({ + message: 'Invalid input used for this operation', + }) + } + + const data = await fetch({ + input: { + item: { + productId, + variantId, + quantity: input.quantity, + }, + itemId, + }, + }) + await mutate(data, false) + return data + }, ctx.wait ?? 500), + [fetch, mutate] + ) + }, } - -export default useUpdateItem diff --git a/framework/shopify/cart/utils/checkout-create.ts b/framework/shopify/cart/utils/checkout-create.ts new file mode 100644 index 000000000..0e71be62f --- /dev/null +++ b/framework/shopify/cart/utils/checkout-create.ts @@ -0,0 +1,25 @@ +import { + SHOPIFY_CHECKOUT_ID_COOKIE, + SHOPIFY_CHECKOUT_URL_COOKIE, +} from '@framework/const' + +import checkoutCreateMutation from '@framework/utils/mutations/checkout-create' +import Cookies from 'js-cookie' + +export const checkoutCreate = async (fetch: any) => { + const data = await fetch({ + query: checkoutCreateMutation, + }) + + const checkout = data.checkoutCreate?.checkout + const checkoutId = checkout?.id + + if (checkoutId) { + Cookies.set(SHOPIFY_CHECKOUT_ID_COOKIE, checkoutId) + Cookies.set(SHOPIFY_CHECKOUT_URL_COOKIE, checkout?.webUrl) + } + + return checkout +} + +export default checkoutCreate diff --git a/framework/shopify/cart/utils/checkout-to-cart.ts b/framework/shopify/cart/utils/checkout-to-cart.ts new file mode 100644 index 000000000..662db1c45 --- /dev/null +++ b/framework/shopify/cart/utils/checkout-to-cart.ts @@ -0,0 +1,42 @@ +import { Cart } from '@commerce/types' +import { CommerceError, ValidationError } from '@commerce/utils/errors' + +import { + CheckoutLineItemsAddPayload, + CheckoutLineItemsRemovePayload, + CheckoutLineItemsUpdatePayload, + Maybe, +} from '@framework/schema' +import { normalizeCart } from '@framework/utils' + +export type CheckoutPayload = + | CheckoutLineItemsAddPayload + | CheckoutLineItemsUpdatePayload + | CheckoutLineItemsRemovePayload + +const checkoutToCart = (checkoutPayload?: Maybe): Cart => { + if (!checkoutPayload) { + throw new CommerceError({ + message: 'Invalid response from Shopify', + }) + } + + const checkout = checkoutPayload?.checkout + const userErrors = checkoutPayload?.userErrors + + if (userErrors && userErrors.length) { + throw new ValidationError({ + message: userErrors[0].message, + }) + } + + if (!checkout) { + throw new CommerceError({ + message: 'Invalid response from Shopify', + }) + } + + return normalizeCart(checkout) +} + +export default checkoutToCart diff --git a/framework/shopify/cart/utils/fetcher.ts b/framework/shopify/cart/utils/fetcher.ts new file mode 100644 index 000000000..a69492f0d --- /dev/null +++ b/framework/shopify/cart/utils/fetcher.ts @@ -0,0 +1,30 @@ +import { HookFetcherFn } from '@commerce/utils/types' +import { Cart } from '@commerce/types' +import { checkoutCreate, checkoutToCart } from '.' +import { FetchCartInput } from '@commerce/cart/use-cart' + +const fetcher: HookFetcherFn = async ({ + options, + input: { cartId: checkoutId }, + fetch, +}) => { + let checkout + + if (checkoutId) { + const data = await fetch({ + ...options, + variables: { + checkoutId, + }, + }) + checkout = data.node + } + + if (checkout?.completedAt || !checkoutId) { + checkout = await checkoutCreate(fetch) + } + + return checkoutToCart({ checkout }) +} + +export default fetcher diff --git a/framework/shopify/cart/utils/index.ts b/framework/shopify/cart/utils/index.ts new file mode 100644 index 000000000..20d04955d --- /dev/null +++ b/framework/shopify/cart/utils/index.ts @@ -0,0 +1,2 @@ +export { default as checkoutToCart } from './checkout-to-cart' +export { default as checkoutCreate } from './checkout-create' diff --git a/framework/shopify/common/get-all-pages.ts b/framework/shopify/common/get-all-pages.ts index 02db3fdc3..6f06185e2 100644 --- a/framework/shopify/common/get-all-pages.ts +++ b/framework/shopify/common/get-all-pages.ts @@ -1,53 +1,39 @@ import { getConfig, ShopifyConfig } from '../api' -import { Page as PageType, PageEdge } from '../types' - -export type Page = PageType - -export const getAllPagesQuery = /* GraphQL */ ` - query($first: Int!) { - pages(first: $first) { - edges { - node { - id - title - handle - body - bodySummary - url - } - } - } - } -` +import { PageEdge } from '../schema' +import { getAllPagesQuery } from '../utils/queries' type Variables = { first?: number } -type Options = { - variables?: Variables - config: ShopifyConfig - preview?: boolean -} - type ReturnType = { pages: Page[] } -const getAllPages = async (options?: Options): Promise => { - let { config, variables = { first: 250 } } = options || {} +export type Page = { + id: string + name: string + url: string + sort_order?: number + body: string +} +const getAllPages = async (options?: { + variables?: Variables + config: ShopifyConfig + preview?: boolean +}): Promise => { + let { config, variables = { first: 250 } } = options ?? {} config = getConfig(config) - const { data } = await config.fetch(getAllPagesQuery, { variables }) - const pages = data.pages.edges.map(({ node }: PageEdge) => { - return { + const pages = data.pages?.edges?.map( + ({ node: { title: name, handle, ...node } }: PageEdge) => ({ ...node, - name: node.handle, - url: `${config!.locale}/${node.handle}`, - } - }) + url: `/${handle}`, + name, + }) + ) return { pages } } diff --git a/framework/shopify/common/get-page.ts b/framework/shopify/common/get-page.ts new file mode 100644 index 000000000..6016c8c9a --- /dev/null +++ b/framework/shopify/common/get-page.ts @@ -0,0 +1,38 @@ +import { getConfig, ShopifyConfig } from '../api' +import getPageQuery from '../utils/queries/get-page-query' +import { Page } from './get-all-pages' + +type Variables = { + slug: string +} + +type ReturnType = { + page: Page +} + +const getPage = async (options: { + variables: Variables + config: ShopifyConfig + preview?: boolean +}): Promise => { + let { config, variables } = options ?? {} + config = getConfig(config) + + const { data } = await config.fetch(getPageQuery, { + variables, + }) + + const { pageByHandle: page } = data + + return { + page: page + ? { + ...page, + name: page.title, + url: page?.handle, + } + : null, + } +} + +export default getPage diff --git a/framework/shopify/common/get-site-info.ts b/framework/shopify/common/get-site-info.ts index c08ae2b92..f6cdaad85 100644 --- a/framework/shopify/common/get-site-info.ts +++ b/framework/shopify/common/get-site-info.ts @@ -1,29 +1,30 @@ -import { ShopifyConfig } from '../index' +import getCategories, { Category } from '@framework/utils/get-categories' +import getVendors, { Brands } from '@framework/utils/get-vendors' -type Options = { +import { getConfig, ShopifyConfig } from '../api' + +export type GetSiteInfoResult< + T extends { categories: any[]; brands: any[] } = { + categories: Category[] + brands: Brands + } +> = T + +const getSiteInfo = async (options?: { + variables?: any config: ShopifyConfig preview?: boolean -} +}): Promise => { + let { config } = options ?? {} + + config = getConfig(config) + + const categories = await getCategories(config) + const brands = await getVendors(config) -const getSiteInfo = async (options: Options) => { - // TODO return { - categories: [ - { - path: '', - name: '', - entityId: 0, - }, - ], - brands: [ - { - node: { - path: '', - name: '', - entityId: 0, - }, - }, - ], + categories, + brands, } } diff --git a/framework/shopify/const.ts b/framework/shopify/const.ts new file mode 100644 index 000000000..a6e9e8d90 --- /dev/null +++ b/framework/shopify/const.ts @@ -0,0 +1,11 @@ +export const SHOPIFY_CHECKOUT_ID_COOKIE = 'shopify_checkoutId' + +export const SHOPIFY_CHECKOUT_URL_COOKIE = 'shopify_checkoutUrl' + +export const SHOPIFY_CUSTOMER_TOKEN_COOKIE = 'shopify_customerToken' + +export const STORE_DOMAIN = process.env.NEXT_PUBLIC_SHOPIFY_STORE_DOMAIN + +export const API_URL = `https://${STORE_DOMAIN}/api/2021-01/graphql.json` + +export const API_TOKEN = process.env.NEXT_PUBLIC_SHOPIFY_STOREFRONT_ACCESS_TOKEN diff --git a/framework/shopify/customer/get-customer-id.ts b/framework/shopify/customer/get-customer-id.ts new file mode 100644 index 000000000..78309a8ec --- /dev/null +++ b/framework/shopify/customer/get-customer-id.ts @@ -0,0 +1,24 @@ +import { getConfig, ShopifyConfig } from '@framework/api' +import getCustomerIdQuery from '@framework/utils/queries/get-customer-id-query' +import Cookies from 'js-cookie' + +async function getCustomerId({ + customerToken: customerAccesToken, + config, +}: { + customerToken: string + config?: ShopifyConfig +}): Promise { + config = getConfig(config) + + const { data } = await config.fetch(getCustomerIdQuery, { + variables: { + customerAccesToken: + customerAccesToken || Cookies.get(config.customerCookie), + }, + }) + + return data.customer?.id +} + +export default getCustomerId diff --git a/framework/shopify/customer/index.ts b/framework/shopify/customer/index.ts new file mode 100644 index 000000000..6c903ecc5 --- /dev/null +++ b/framework/shopify/customer/index.ts @@ -0,0 +1 @@ +export { default as useCustomer } from './use-customer' diff --git a/framework/shopify/customer/use-customer.tsx b/framework/shopify/customer/use-customer.tsx index 7ea2ae679..91b7281af 100644 --- a/framework/shopify/customer/use-customer.tsx +++ b/framework/shopify/customer/use-customer.tsx @@ -1,32 +1,27 @@ -import type { HookFetcher } from '@commerce/utils/types' -import type { SwrOptions } from '@commerce/utils/use-data' -import useCommerceCustomer from '@commerce/customer/use-customer' +import useCustomer, { UseCustomer } from '@commerce/customer/use-customer' +import { Customer } from '@commerce/types' +import { SWRHook } from '@commerce/utils/types' +import { getCustomerQuery, getCustomerToken } from '../utils' +import type { ShopifyProvider } from '..' -const defaultOpts = {} - -export type Customer = { - entityId: number - firstName: string - lastName: string - email: string +export default useCustomer as UseCustomer +export const handler: SWRHook = { + fetchOptions: { + query: getCustomerQuery, + }, + async fetcher({ options, fetch }) { + const data = await fetch({ + ...options, + variables: { customerAccessToken: getCustomerToken() }, + }) + return data.customer ?? null + }, + useHook: ({ useData }) => (input) => { + return useData({ + swrOptions: { + revalidateOnFocus: false, + ...input?.swrOptions, + }, + }) + }, } -export type CustomerData = {} - -export const fetcher: HookFetcher = async () => { - return null -} - -export function extendHook( - customFetcher: typeof fetcher, - swrOptions?: SwrOptions -) { - const useCustomer = () => { - return { data: { firstName: null, lastName: null, email: null } } - } - - useCustomer.extend = extendHook - - return useCustomer -} - -export default extendHook(fetcher) diff --git a/framework/shopify/fetcher.ts b/framework/shopify/fetcher.ts index 73500ee93..9c4fe9a9e 100644 --- a/framework/shopify/fetcher.ts +++ b/framework/shopify/fetcher.ts @@ -1,51 +1,18 @@ -import { FetcherError } from '@commerce/utils/errors' -import type { Fetcher } from '@commerce/utils/types' +import { Fetcher } from '@commerce/utils/types' +import { API_TOKEN, API_URL } from './const' +import { handleFetchResponse } from './utils' -async function getText(res: Response) { - try { - return (await res.text()) || res.statusText - } catch (error) { - return res.statusText - } -} - -async function getError(res: Response) { - if (res.headers.get('Content-Type')?.includes('application/json')) { - const data = await res.json() - return new FetcherError({ errors: data.errors, status: res.status }) - } - return new FetcherError({ message: await getText(res), status: res.status }) -} - -const fetcher: Fetcher = async ({ - url, - query, - method = 'POST', - variables, - body: bodyObj, -}) => { - // const config = getConfig() - // url = `https://${process.env.SHOPIFY_STORE_DOMAIN}/api/2021-01/graphql.json` - - const hasBody = Boolean(variables || bodyObj) - const body = hasBody - ? JSON.stringify(variables ? { query, variables } : bodyObj) - : undefined - const headers = hasBody - ? { - 'X-Shopify-Storefront-Access-Token': config.apiToken, +const fetcher: Fetcher = async ({ method = 'POST', variables, query }) => { + return handleFetchResponse( + await fetch(API_URL, { + method, + body: JSON.stringify({ query, variables }), + headers: { + 'X-Shopify-Storefront-Access-Token': API_TOKEN!, 'Content-Type': 'application/json', - } - : undefined - - const res = await fetch(url!, { method, body, headers }) - - if (res.ok) { - const { data } = await res.json() - return data - } - - throw await getError(res) + }, + }) + ) } export default fetcher diff --git a/framework/shopify/index.tsx b/framework/shopify/index.tsx index 5fd08e0d9..5b25d6b21 100644 --- a/framework/shopify/index.tsx +++ b/framework/shopify/index.tsx @@ -1,109 +1,39 @@ -import React, { - ReactNode, - createContext, - useContext, - useMemo, - useState, - useEffect, -} from 'react' -import Client from 'shopify-buy' -import { Shop, Cart, Client as ClientType } from './types' +import * as React from 'react' +import { ReactNode } from 'react' + import { - getCheckoutIdFromStorage, - setCheckoutIdInStorage, -} from './utils/storage' -import { getConfig } from '@framework/api' + CommerceConfig, + CommerceProvider as CoreCommerceProvider, + useCommerce as useCoreCommerce, +} from '@commerce' -const Commerce = createContext({}) +import { shopifyProvider, ShopifyProvider } from './provider' +import { SHOPIFY_CHECKOUT_ID_COOKIE } from './const' -type CommerceProps = { +export { shopifyProvider } +export type { ShopifyProvider } + +export const shopifyConfig: CommerceConfig = { + locale: 'en-us', + cartCookie: SHOPIFY_CHECKOUT_ID_COOKIE, +} + +export type ShopifyConfig = Partial + +export type ShopifyProps = { children?: ReactNode locale: string -} +} & ShopifyConfig -type CommerceContextValue = { - client: ClientType - shop: Shop - checkout: Cart - updateCheckout: (cart: Cart | undefined) => void - currencyCode: string - locale: string - sessionToken: string -} - -export function CommerceProvider({ - children, - locale = 'en-US', -}: CommerceProps) { - const sessionToken = 'nextjs-commerce-shopify-token' - - const config = getConfig() - - const client = Client.buildClient({ - storefrontAccessToken: config.apiToken, - domain: config.commerceUrl, - language: locale, - }) as ClientType - - const [shop, setShop] = useState() - const [checkout, setCheckout] = useState() - - const fetchShopify = async () => { - const shopInfo: Shop = await client.shop.fetchInfo() - let checkoutResource: Cart - - const checkoutOptions = { - presentmentCurrencyCode: - /*config.currencyCode ||*/ shopInfo?.currencyCode, - } - - let checkoutId = getCheckoutIdFromStorage(sessionToken) - - // we could have a cart id stored in session storage - // user could be refreshing or navigating back and forth - if (checkoutId) { - checkoutResource = await client.checkout.fetch(checkoutId) - - // could be expired order - we will create a new order - if (checkoutResource.completedAt) { - checkoutResource = await client.checkout.create(checkoutOptions) - } - } else { - checkoutResource = await client.checkout.create(checkoutOptions) - } - - setCheckoutIdInStorage(sessionToken, checkoutResource.id) - - setShop(shopInfo) - setCheckout(checkoutResource) - } - - useEffect(() => { - fetchShopify() - }, []) - - const updateCheckout = (newCheckout: Cart) => { - setCheckout(newCheckout) - } - - // Because the config is an object, if the parent re-renders this provider - // will re-render every consumer unless we memoize the config - const cfg = useMemo( - () => ({ - client, - checkout, - shop, - updateCheckout: updateCheckout, - currencyCode: /*config.currencyCode ||*/ checkout?.currencyCode, - locale, - sessionToken, - }), - [client] +export function CommerceProvider({ children, ...config }: ShopifyProps) { + return ( + + {children} + ) - - return {children} } -export function useCommerce() { - return useContext(Commerce) as T -} +export const useCommerce = () => useCoreCommerce() diff --git a/framework/shopify/product/get-all-collections.ts b/framework/shopify/product/get-all-collections.ts new file mode 100644 index 000000000..bf3fee392 --- /dev/null +++ b/framework/shopify/product/get-all-collections.ts @@ -0,0 +1,29 @@ +import { CollectionEdge } from '@framework/schema' +import { getConfig, ShopifyConfig } from '../api' +import getAllCollectionsQuery from '../utils/queries/get-all-collections-query' + +const getAllCollections = async (options?: { + variables?: any + config: ShopifyConfig + preview?: boolean +}) => { + let { config, variables = { first: 250 } } = options ?? {} + config = getConfig(config) + + const { data } = await config.fetch(getAllCollectionsQuery, { variables }) + const edges = data.collections?.edges ?? [] + + const categories = edges.map( + ({ node: { id: entityId, title: name, handle } }: CollectionEdge) => ({ + entityId, + name, + path: `/${handle}`, + }) + ) + + return { + categories, + } +} + +export default getAllCollections diff --git a/framework/shopify/product/get-all-product-paths.ts b/framework/shopify/product/get-all-product-paths.ts index 3d4f0ef7a..4431d1e53 100644 --- a/framework/shopify/product/get-all-product-paths.ts +++ b/framework/shopify/product/get-all-product-paths.ts @@ -1,30 +1,41 @@ -import Client from 'shopify-buy' -import { getConfig } from '../api' -import { Product } from '../types' -import toCommerceProducts from '../utils/to-commerce-products' +import { Product } from '@commerce/types' +import { getConfig, ShopifyConfig } from '../api' +import fetchAllProducts from '../api/utils/fetch-all-products' +import { ProductEdge } from '../schema' +import getAllProductsPathsQuery from '../utils/queries/get-all-products-paths-query' -type ReturnType = { - products: any[] +type ProductPath = { + path: string } -const getAllProductPaths = async (): Promise => { - const config = getConfig() +export type ProductPathNode = { + node: ProductPath +} - const client = Client.buildClient({ - storefrontAccessToken: config.apiToken, - domain: config.commerceUrl, +type ReturnType = { + products: ProductPathNode[] +} + +const getAllProductPaths = async (options?: { + variables?: any + config?: ShopifyConfig + preview?: boolean +}): Promise => { + let { config, variables = { first: 250 } } = options ?? {} + config = getConfig(config) + + const products = await fetchAllProducts({ + config, + query: getAllProductsPathsQuery, + variables, }) - const res = (await client.product.fetchAll()) as Product[] - - const products = toCommerceProducts(res) - return { - products: products.map((product) => { - return { - node: { ...product }, - } - }), + products: products?.map(({ node: { handle } }: ProductEdge) => ({ + node: { + path: `/${handle}`, + }, + })), } } diff --git a/framework/shopify/product/get-all-products.ts b/framework/shopify/product/get-all-products.ts index 6e4881e99..e1eb96aac 100644 --- a/framework/shopify/product/get-all-products.ts +++ b/framework/shopify/product/get-all-products.ts @@ -1,36 +1,36 @@ -import Client from 'shopify-buy' -import { ShopifyConfig } from '../api' -import { Product } from '../types' -import toCommerceProducts from '../utils/to-commerce-products' - -export type ProductNode = Product +import { GraphQLFetcherResult } from '@commerce/api' +import { getConfig, ShopifyConfig } from '../api' +import { ProductEdge } from '../schema' +import { getAllProductsQuery } from '../utils/queries' +import { normalizeProduct } from '@framework/utils/normalize' +import { Product } from '@commerce/types' type Variables = { first?: number field?: string } -type Options = { - variables: Variables - config: ShopifyConfig - preview?: boolean -} - type ReturnType = { - products: any[] + products: Product[] } -const getAllProducts = async (options: Options): Promise => { - const { config } = options +const getAllProducts = async (options: { + variables?: Variables + config?: ShopifyConfig + preview?: boolean +}): Promise => { + let { config, variables = { first: 250 } } = options ?? {} + config = getConfig(config) - const client = Client.buildClient({ - storefrontAccessToken: config.apiToken, - domain: config.commerceUrl, - }) + const { data }: GraphQLFetcherResult = await config.fetch( + getAllProductsQuery, + { variables } + ) - const res = (await client.product.fetchAll()) as Product[] - - const products = toCommerceProducts(res) + const products = + data.products?.edges?.map(({ node: p }: ProductEdge) => + normalizeProduct(p) + ) ?? [] return { products, diff --git a/framework/shopify/product/get-product.ts b/framework/shopify/product/get-product.ts index f71aa0213..1f00288c7 100644 --- a/framework/shopify/product/get-product.ts +++ b/framework/shopify/product/get-product.ts @@ -1,36 +1,31 @@ -import Client from 'shopify-buy' -import { ShopifyConfig } from '../api' -import { Product } from '../types' -import toCommerceProducts from '../utils/to-commerce-products' - -export type ProductNode = Product +import { GraphQLFetcherResult } from '@commerce/api' +import { getConfig, ShopifyConfig } from '../api' +import { normalizeProduct, getProductQuery } from '../utils' type Variables = { slug: string } -type Options = { - variables: Variables - config: ShopifyConfig - preview?: boolean -} - type ReturnType = { product: any } -const getProduct = async (options: Options): Promise => { - const { variables, config } = options +const getProduct = async (options: { + variables: Variables + config: ShopifyConfig + preview?: boolean +}): Promise => { + let { config, variables } = options ?? {} + config = getConfig(config) - const client = Client.buildClient({ - storefrontAccessToken: config.apiToken, - domain: config.commerceUrl, + const { data }: GraphQLFetcherResult = await config.fetch(getProductQuery, { + variables, }) - const res = (await client.product.fetchByHandle(variables.slug)) as Product + const { productByHandle: product } = data return { - product: toCommerceProducts([res])[0], + product: product ? normalizeProduct(product) : null, } } diff --git a/framework/shopify/product/use-search.tsx b/framework/shopify/product/use-search.tsx index 04f6a3536..7ca37916b 100644 --- a/framework/shopify/product/use-search.tsx +++ b/framework/shopify/product/use-search.tsx @@ -1,9 +1,17 @@ -import type { HookFetcher } from '@commerce/utils/types' -import type { SwrOptions } from '@commerce/utils/use-data' -import useCommerceSearch from '@commerce/product/use-search' -import { ProductEdge } from '../types' +import { SWRHook } from '@commerce/utils/types' +import useSearch, { UseSearch } from '@commerce/product/use-search' -const defaultOpts = {} +import { ProductEdge } from '@framework/schema' +import { + getAllProductsQuery, + getSearchVariables, + normalizeProduct, +} from '@framework/utils' +import type { ShopifyProvider } from '..' + +import { Product } from '@commerce/types' + +export default useSearch as UseSearch export type SearchProductsInput = { search?: string @@ -13,29 +21,41 @@ export type SearchProductsInput = { } export type SearchProductsData = { - products: ProductEdge[] + products: Product[] found: boolean } - -export const fetcher: HookFetcher = ( - options, - { search, categoryId, brandId, sort }, - fetch -) => { - return { found: false, products: [] } +export const handler: SWRHook< + SearchProductsData, + SearchProductsInput, + SearchProductsInput +> = { + fetchOptions: { + query: getAllProductsQuery, + }, + async fetcher({ input, options, fetch }) { + const resp = await fetch({ + query: options?.query, + method: options?.method, + variables: getSearchVariables(input), + }) + const edges = resp.products?.edges + return { + products: edges?.map(({ node: p }: ProductEdge) => normalizeProduct(p)), + found: !!edges?.length, + } + }, + useHook: ({ useData }) => (input = {}) => { + return useData({ + input: [ + ['search', input.search], + ['categoryId', input.categoryId], + ['brandId', input.brandId], + ['sort', input.sort], + ], + swrOptions: { + revalidateOnFocus: false, + ...input.swrOptions, + }, + }) + }, } - -export function extendHook( - customFetcher: typeof fetcher, - swrOptions?: SwrOptions -) { - const useSearch = (input: SearchProductsInput = {}) => { - return {} - } - - useSearch.extend = extendHook - - return useSearch -} - -export default extendHook(fetcher) diff --git a/framework/shopify/provider.ts b/framework/shopify/provider.ts index 31b958a21..383822baa 100644 --- a/framework/shopify/provider.ts +++ b/framework/shopify/provider.ts @@ -1,12 +1,10 @@ +import { SHOPIFY_CHECKOUT_ID_COOKIE, STORE_DOMAIN } from './const' + import { handler as useCart } from './cart/use-cart' import { handler as useAddItem } from './cart/use-add-item' import { handler as useUpdateItem } from './cart/use-update-item' import { handler as useRemoveItem } from './cart/use-remove-item' -import { handler as useWishlist } from './wishlist/use-wishlist' -import { handler as useWishlistAddItem } from './wishlist/use-add-item' -import { handler as useWishlistRemoveItem } from './wishlist/use-remove-item' - import { handler as useCustomer } from './customer/use-customer' import { handler as useSearch } from './product/use-search' @@ -18,17 +16,16 @@ import fetcher from './fetcher' export const shopifyProvider = { locale: 'en-us', - cartCookie: 'sp_cartId', + cartCookie: SHOPIFY_CHECKOUT_ID_COOKIE, + storeDomain: STORE_DOMAIN, fetcher, cart: { useCart, useAddItem, useUpdateItem, useRemoveItem }, - wishlist: { - useWishlist, - useAddItem: useWishlistAddItem, - useRemoveItem: useWishlistRemoveItem, - }, customer: { useCustomer }, products: { useSearch }, auth: { useLogin, useLogout, useSignup }, + features: { + wishlist: false, + }, } export type ShopifyProvider = typeof shopifyProvider diff --git a/framework/shopify/schema.d.ts b/framework/shopify/schema.d.ts new file mode 100644 index 000000000..b1b23a3e5 --- /dev/null +++ b/framework/shopify/schema.d.ts @@ -0,0 +1,4985 @@ +export type Maybe = T | null +export type Exact = { + [K in keyof T]: T[K] +} +export type MakeOptional = Omit & + { [SubKey in K]?: Maybe } +export type MakeMaybe = Omit & + { [SubKey in K]: Maybe } +/** All built-in and custom scalars, mapped to their actual values */ +export type Scalars = { + ID: string + String: string + Boolean: boolean + Int: number + Float: number + /** An ISO-8601 encoded UTC date time string. Example value: `"2019-07-03T20:47:55Z"`. */ + DateTime: any + /** A signed decimal number, which supports arbitrary precision and is serialized as a string. Example value: `"29.99"`. */ + Decimal: any + /** A string containing HTML code. Example value: `"

    Grey cotton knit sweater.

    "`. */ + HTML: any + /** A monetary value string. Example value: `"100.57"`. */ + Money: any + /** + * An RFC 3986 and RFC 3987 compliant URI string. + * + * Example value: `"https://johns-apparel.myshopify.com"`. + * + */ + URL: any +} + +/** A version of the API. */ +export type ApiVersion = { + __typename?: 'ApiVersion' + /** The human-readable name of the version. */ + displayName: Scalars['String'] + /** The unique identifier of an ApiVersion. All supported API versions have a date-based (YYYY-MM) or `unstable` handle. */ + handle: Scalars['String'] + /** Whether the version is supported by Shopify. */ + supported: Scalars['Boolean'] +} + +/** Details about the gift card used on the checkout. */ +export type AppliedGiftCard = Node & { + __typename?: 'AppliedGiftCard' + /** + * The amount that was taken from the gift card by applying it. + * @deprecated Use `amountUsedV2` instead + */ + amountUsed: Scalars['Money'] + /** The amount that was taken from the gift card by applying it. */ + amountUsedV2: MoneyV2 + /** + * The amount left on the gift card. + * @deprecated Use `balanceV2` instead + */ + balance: Scalars['Money'] + /** The amount left on the gift card. */ + balanceV2: MoneyV2 + /** Globally unique identifier. */ + id: Scalars['ID'] + /** The last characters of the gift card. */ + lastCharacters: Scalars['String'] + /** The amount that was applied to the checkout in its currency. */ + presentmentAmountUsed: MoneyV2 +} + +/** An article in an online store blog. */ +export type Article = Node & { + __typename?: 'Article' + /** + * The article's author. + * @deprecated Use `authorV2` instead + */ + author: ArticleAuthor + /** The article's author. */ + authorV2?: Maybe + /** The blog that the article belongs to. */ + blog: Blog + /** List of comments posted on the article. */ + comments: CommentConnection + /** Stripped content of the article, single line with HTML tags removed. */ + content: Scalars['String'] + /** The content of the article, complete with HTML formatting. */ + contentHtml: Scalars['HTML'] + /** Stripped excerpt of the article, single line with HTML tags removed. */ + excerpt?: Maybe + /** The excerpt of the article, complete with HTML formatting. */ + excerptHtml?: Maybe + /** A human-friendly unique string for the Article automatically generated from its title. */ + handle: Scalars['String'] + /** Globally unique identifier. */ + id: Scalars['ID'] + /** The image associated with the article. */ + image?: Maybe + /** The date and time when the article was published. */ + publishedAt: Scalars['DateTime'] + /** The article’s SEO information. */ + seo?: Maybe + /** A categorization that a article can be tagged with. */ + tags: Array + /** The article’s name. */ + title: Scalars['String'] + /** The url pointing to the article accessible from the web. */ + url: Scalars['URL'] +} + +/** An article in an online store blog. */ +export type ArticleCommentsArgs = { + first?: Maybe + after?: Maybe + last?: Maybe + before?: Maybe + reverse?: Maybe +} + +/** An article in an online store blog. */ +export type ArticleContentArgs = { + truncateAt?: Maybe +} + +/** An article in an online store blog. */ +export type ArticleExcerptArgs = { + truncateAt?: Maybe +} + +/** An article in an online store blog. */ +export type ArticleImageArgs = { + maxWidth?: Maybe + maxHeight?: Maybe + crop?: Maybe + scale?: Maybe +} + +/** The author of an article. */ +export type ArticleAuthor = { + __typename?: 'ArticleAuthor' + /** The author's bio. */ + bio?: Maybe + /** The author’s email. */ + email: Scalars['String'] + /** The author's first name. */ + firstName: Scalars['String'] + /** The author's last name. */ + lastName: Scalars['String'] + /** The author's full name. */ + name: Scalars['String'] +} + +/** An auto-generated type for paginating through multiple Articles. */ +export type ArticleConnection = { + __typename?: 'ArticleConnection' + /** A list of edges. */ + edges: Array + /** Information to aid in pagination. */ + pageInfo: PageInfo +} + +/** An auto-generated type which holds one Article and a cursor during pagination. */ +export type ArticleEdge = { + __typename?: 'ArticleEdge' + /** A cursor for use in pagination. */ + cursor: Scalars['String'] + /** The item at the end of ArticleEdge. */ + node: Article +} + +/** The set of valid sort keys for the Article query. */ +export enum ArticleSortKeys { + /** Sort by the `title` value. */ + Title = 'TITLE', + /** Sort by the `blog_title` value. */ + BlogTitle = 'BLOG_TITLE', + /** Sort by the `author` value. */ + Author = 'AUTHOR', + /** Sort by the `updated_at` value. */ + UpdatedAt = 'UPDATED_AT', + /** Sort by the `published_at` value. */ + PublishedAt = 'PUBLISHED_AT', + /** Sort by the `id` value. */ + Id = 'ID', + /** + * During a search (i.e. when the `query` parameter has been specified on the connection) this sorts the + * results by relevance to the search term(s). When no search query is specified, this sort key is not + * deterministic and should not be used. + */ + Relevance = 'RELEVANCE', +} + +/** Represents a generic custom attribute. */ +export type Attribute = { + __typename?: 'Attribute' + /** Key or name of the attribute. */ + key: Scalars['String'] + /** Value of the attribute. */ + value?: Maybe +} + +/** Specifies the input fields required for an attribute. */ +export type AttributeInput = { + /** Key or name of the attribute. */ + key: Scalars['String'] + /** Value of the attribute. */ + value: Scalars['String'] +} + +/** Automatic discount applications capture the intentions of a discount that was automatically applied. */ +export type AutomaticDiscountApplication = DiscountApplication & { + __typename?: 'AutomaticDiscountApplication' + /** The method by which the discount's value is allocated to its entitled items. */ + allocationMethod: DiscountApplicationAllocationMethod + /** Which lines of targetType that the discount is allocated over. */ + targetSelection: DiscountApplicationTargetSelection + /** The type of line that the discount is applicable towards. */ + targetType: DiscountApplicationTargetType + /** The title of the application. */ + title: Scalars['String'] + /** The value of the discount application. */ + value: PricingValue +} + +/** A collection of available shipping rates for a checkout. */ +export type AvailableShippingRates = { + __typename?: 'AvailableShippingRates' + /** + * Whether or not the shipping rates are ready. + * The `shippingRates` field is `null` when this value is `false`. + * This field should be polled until its value becomes `true`. + */ + ready: Scalars['Boolean'] + /** The fetched shipping rates. `null` until the `ready` field is `true`. */ + shippingRates?: Maybe> +} + +/** An online store blog. */ +export type Blog = Node & { + __typename?: 'Blog' + /** Find an article by its handle. */ + articleByHandle?: Maybe
    + /** List of the blog's articles. */ + articles: ArticleConnection + /** The authors who have contributed to the blog. */ + authors: Array + /** A human-friendly unique string for the Blog automatically generated from its title. */ + handle: Scalars['String'] + /** Globally unique identifier. */ + id: Scalars['ID'] + /** The blog's SEO information. */ + seo?: Maybe + /** The blogs’s title. */ + title: Scalars['String'] + /** The url pointing to the blog accessible from the web. */ + url: Scalars['URL'] +} + +/** An online store blog. */ +export type BlogArticleByHandleArgs = { + handle: Scalars['String'] +} + +/** An online store blog. */ +export type BlogArticlesArgs = { + first?: Maybe + after?: Maybe + last?: Maybe + before?: Maybe + reverse?: Maybe + sortKey?: Maybe + query?: Maybe +} + +/** An auto-generated type for paginating through multiple Blogs. */ +export type BlogConnection = { + __typename?: 'BlogConnection' + /** A list of edges. */ + edges: Array + /** Information to aid in pagination. */ + pageInfo: PageInfo +} + +/** An auto-generated type which holds one Blog and a cursor during pagination. */ +export type BlogEdge = { + __typename?: 'BlogEdge' + /** A cursor for use in pagination. */ + cursor: Scalars['String'] + /** The item at the end of BlogEdge. */ + node: Blog +} + +/** The set of valid sort keys for the Blog query. */ +export enum BlogSortKeys { + /** Sort by the `handle` value. */ + Handle = 'HANDLE', + /** Sort by the `title` value. */ + Title = 'TITLE', + /** Sort by the `id` value. */ + Id = 'ID', + /** + * During a search (i.e. when the `query` parameter has been specified on the connection) this sorts the + * results by relevance to the search term(s). When no search query is specified, this sort key is not + * deterministic and should not be used. + */ + Relevance = 'RELEVANCE', +} + +/** Card brand, such as Visa or Mastercard, which can be used for payments. */ +export enum CardBrand { + /** Visa */ + Visa = 'VISA', + /** Mastercard */ + Mastercard = 'MASTERCARD', + /** Discover */ + Discover = 'DISCOVER', + /** American Express */ + AmericanExpress = 'AMERICAN_EXPRESS', + /** Diners Club */ + DinersClub = 'DINERS_CLUB', + /** JCB */ + Jcb = 'JCB', +} + +/** A container for all the information required to checkout items and pay. */ +export type Checkout = Node & { + __typename?: 'Checkout' + /** The gift cards used on the checkout. */ + appliedGiftCards: Array + /** + * The available shipping rates for this Checkout. + * Should only be used when checkout `requiresShipping` is `true` and + * the shipping address is valid. + */ + availableShippingRates?: Maybe + /** The date and time when the checkout was completed. */ + completedAt?: Maybe + /** The date and time when the checkout was created. */ + createdAt: Scalars['DateTime'] + /** The currency code for the Checkout. */ + currencyCode: CurrencyCode + /** A list of extra information that is added to the checkout. */ + customAttributes: Array + /** + * The customer associated with the checkout. + * @deprecated This field will always return null. If you have an authentication token for the customer, you can use the `customer` field on the query root to retrieve it. + */ + customer?: Maybe + /** Discounts that have been applied on the checkout. */ + discountApplications: DiscountApplicationConnection + /** The email attached to this checkout. */ + email?: Maybe + /** Globally unique identifier. */ + id: Scalars['ID'] + /** A list of line item objects, each one containing information about an item in the checkout. */ + lineItems: CheckoutLineItemConnection + /** The sum of all the prices of all the items in the checkout. Duties, taxes, shipping and discounts excluded. */ + lineItemsSubtotalPrice: MoneyV2 + /** The note associated with the checkout. */ + note?: Maybe + /** The resulting order from a paid checkout. */ + order?: Maybe + /** The Order Status Page for this Checkout, null when checkout is not completed. */ + orderStatusUrl?: Maybe + /** + * The amount left to be paid. This is equal to the cost of the line items, taxes and shipping minus discounts and gift cards. + * @deprecated Use `paymentDueV2` instead + */ + paymentDue: Scalars['Money'] + /** The amount left to be paid. This is equal to the cost of the line items, duties, taxes and shipping minus discounts and gift cards. */ + paymentDueV2: MoneyV2 + /** + * Whether or not the Checkout is ready and can be completed. Checkouts may + * have asynchronous operations that can take time to finish. If you want + * to complete a checkout or ensure all the fields are populated and up to + * date, polling is required until the value is true. + */ + ready: Scalars['Boolean'] + /** States whether or not the fulfillment requires shipping. */ + requiresShipping: Scalars['Boolean'] + /** The shipping address to where the line items will be shipped. */ + shippingAddress?: Maybe + /** The discounts that have been allocated onto the shipping line by discount applications. */ + shippingDiscountAllocations: Array + /** Once a shipping rate is selected by the customer it is transitioned to a `shipping_line` object. */ + shippingLine?: Maybe + /** + * Price of the checkout before shipping and taxes. + * @deprecated Use `subtotalPriceV2` instead + */ + subtotalPrice: Scalars['Money'] + /** Price of the checkout before duties, shipping and taxes. */ + subtotalPriceV2: MoneyV2 + /** Specifies if the Checkout is tax exempt. */ + taxExempt: Scalars['Boolean'] + /** Specifies if taxes are included in the line item and shipping line prices. */ + taxesIncluded: Scalars['Boolean'] + /** + * The sum of all the prices of all the items in the checkout, taxes and discounts included. + * @deprecated Use `totalPriceV2` instead + */ + totalPrice: Scalars['Money'] + /** The sum of all the prices of all the items in the checkout, duties, taxes and discounts included. */ + totalPriceV2: MoneyV2 + /** + * The sum of all the taxes applied to the line items and shipping lines in the checkout. + * @deprecated Use `totalTaxV2` instead + */ + totalTax: Scalars['Money'] + /** The sum of all the taxes applied to the line items and shipping lines in the checkout. */ + totalTaxV2: MoneyV2 + /** The date and time when the checkout was last updated. */ + updatedAt: Scalars['DateTime'] + /** The url pointing to the checkout accessible from the web. */ + webUrl: Scalars['URL'] +} + +/** A container for all the information required to checkout items and pay. */ +export type CheckoutDiscountApplicationsArgs = { + first?: Maybe + after?: Maybe + last?: Maybe + before?: Maybe + reverse?: Maybe +} + +/** A container for all the information required to checkout items and pay. */ +export type CheckoutLineItemsArgs = { + first?: Maybe + after?: Maybe + last?: Maybe + before?: Maybe + reverse?: Maybe +} + +/** Specifies the fields required to update a checkout's attributes. */ +export type CheckoutAttributesUpdateInput = { + /** The text of an optional note that a shop owner can attach to the checkout. */ + note?: Maybe + /** A list of extra information that is added to the checkout. */ + customAttributes?: Maybe> + /** + * Allows setting partial addresses on a Checkout, skipping the full validation of attributes. + * The required attributes are city, province, and country. + * Full validation of the addresses is still done at complete time. + */ + allowPartialAddresses?: Maybe +} + +/** Return type for `checkoutAttributesUpdate` mutation. */ +export type CheckoutAttributesUpdatePayload = { + __typename?: 'CheckoutAttributesUpdatePayload' + /** The updated checkout object. */ + checkout: Checkout + /** List of errors that occurred executing the mutation. */ + checkoutUserErrors: Array + /** + * List of errors that occurred executing the mutation. + * @deprecated Use `checkoutUserErrors` instead + */ + userErrors: Array +} + +/** Specifies the fields required to update a checkout's attributes. */ +export type CheckoutAttributesUpdateV2Input = { + /** The text of an optional note that a shop owner can attach to the checkout. */ + note?: Maybe + /** A list of extra information that is added to the checkout. */ + customAttributes?: Maybe> + /** + * Allows setting partial addresses on a Checkout, skipping the full validation of attributes. + * The required attributes are city, province, and country. + * Full validation of the addresses is still done at complete time. + */ + allowPartialAddresses?: Maybe +} + +/** Return type for `checkoutAttributesUpdateV2` mutation. */ +export type CheckoutAttributesUpdateV2Payload = { + __typename?: 'CheckoutAttributesUpdateV2Payload' + /** The updated checkout object. */ + checkout?: Maybe + /** List of errors that occurred executing the mutation. */ + checkoutUserErrors: Array + /** + * List of errors that occurred executing the mutation. + * @deprecated Use `checkoutUserErrors` instead + */ + userErrors: Array +} + +/** Return type for `checkoutCompleteFree` mutation. */ +export type CheckoutCompleteFreePayload = { + __typename?: 'CheckoutCompleteFreePayload' + /** The updated checkout object. */ + checkout?: Maybe + /** List of errors that occurred executing the mutation. */ + checkoutUserErrors: Array + /** + * List of errors that occurred executing the mutation. + * @deprecated Use `checkoutUserErrors` instead + */ + userErrors: Array +} + +/** Return type for `checkoutCompleteWithCreditCard` mutation. */ +export type CheckoutCompleteWithCreditCardPayload = { + __typename?: 'CheckoutCompleteWithCreditCardPayload' + /** The checkout on which the payment was applied. */ + checkout: Checkout + /** List of errors that occurred executing the mutation. */ + checkoutUserErrors: Array + /** A representation of the attempted payment. */ + payment?: Maybe + /** + * List of errors that occurred executing the mutation. + * @deprecated Use `checkoutUserErrors` instead + */ + userErrors: Array +} + +/** Return type for `checkoutCompleteWithCreditCardV2` mutation. */ +export type CheckoutCompleteWithCreditCardV2Payload = { + __typename?: 'CheckoutCompleteWithCreditCardV2Payload' + /** The checkout on which the payment was applied. */ + checkout?: Maybe + /** List of errors that occurred executing the mutation. */ + checkoutUserErrors: Array + /** A representation of the attempted payment. */ + payment?: Maybe + /** + * List of errors that occurred executing the mutation. + * @deprecated Use `checkoutUserErrors` instead + */ + userErrors: Array +} + +/** Return type for `checkoutCompleteWithTokenizedPayment` mutation. */ +export type CheckoutCompleteWithTokenizedPaymentPayload = { + __typename?: 'CheckoutCompleteWithTokenizedPaymentPayload' + /** The checkout on which the payment was applied. */ + checkout: Checkout + /** List of errors that occurred executing the mutation. */ + checkoutUserErrors: Array + /** A representation of the attempted payment. */ + payment?: Maybe + /** + * List of errors that occurred executing the mutation. + * @deprecated Use `checkoutUserErrors` instead + */ + userErrors: Array +} + +/** Return type for `checkoutCompleteWithTokenizedPaymentV2` mutation. */ +export type CheckoutCompleteWithTokenizedPaymentV2Payload = { + __typename?: 'CheckoutCompleteWithTokenizedPaymentV2Payload' + /** The checkout on which the payment was applied. */ + checkout?: Maybe + /** List of errors that occurred executing the mutation. */ + checkoutUserErrors: Array + /** A representation of the attempted payment. */ + payment?: Maybe + /** + * List of errors that occurred executing the mutation. + * @deprecated Use `checkoutUserErrors` instead + */ + userErrors: Array +} + +/** Return type for `checkoutCompleteWithTokenizedPaymentV3` mutation. */ +export type CheckoutCompleteWithTokenizedPaymentV3Payload = { + __typename?: 'CheckoutCompleteWithTokenizedPaymentV3Payload' + /** The checkout on which the payment was applied. */ + checkout?: Maybe + /** List of errors that occurred executing the mutation. */ + checkoutUserErrors: Array + /** A representation of the attempted payment. */ + payment?: Maybe + /** + * List of errors that occurred executing the mutation. + * @deprecated Use `checkoutUserErrors` instead + */ + userErrors: Array +} + +/** Specifies the fields required to create a checkout. */ +export type CheckoutCreateInput = { + /** The email with which the customer wants to checkout. */ + email?: Maybe + /** A list of line item objects, each one containing information about an item in the checkout. */ + lineItems?: Maybe> + /** The shipping address to where the line items will be shipped. */ + shippingAddress?: Maybe + /** The text of an optional note that a shop owner can attach to the checkout. */ + note?: Maybe + /** A list of extra information that is added to the checkout. */ + customAttributes?: Maybe> + /** + * Allows setting partial addresses on a Checkout, skipping the full validation of attributes. + * The required attributes are city, province, and country. + * Full validation of addresses is still done at complete time. + */ + allowPartialAddresses?: Maybe + /** + * The three-letter currency code of one of the shop's enabled presentment currencies. + * Including this field creates a checkout in the specified currency. By default, new + * checkouts are created in the shop's primary currency. + */ + presentmentCurrencyCode?: Maybe +} + +/** Return type for `checkoutCreate` mutation. */ +export type CheckoutCreatePayload = { + __typename?: 'CheckoutCreatePayload' + /** The new checkout object. */ + checkout?: Maybe + /** List of errors that occurred executing the mutation. */ + checkoutUserErrors: Array + /** + * List of errors that occurred executing the mutation. + * @deprecated Use `checkoutUserErrors` instead + */ + userErrors: Array +} + +/** Return type for `checkoutCustomerAssociate` mutation. */ +export type CheckoutCustomerAssociatePayload = { + __typename?: 'CheckoutCustomerAssociatePayload' + /** The updated checkout object. */ + checkout: Checkout + /** The associated customer object. */ + customer?: Maybe + /** List of errors that occurred executing the mutation. */ + userErrors: Array +} + +/** Return type for `checkoutCustomerAssociateV2` mutation. */ +export type CheckoutCustomerAssociateV2Payload = { + __typename?: 'CheckoutCustomerAssociateV2Payload' + /** The updated checkout object. */ + checkout?: Maybe + /** List of errors that occurred executing the mutation. */ + checkoutUserErrors: Array + /** The associated customer object. */ + customer?: Maybe + /** + * List of errors that occurred executing the mutation. + * @deprecated Use `checkoutUserErrors` instead + */ + userErrors: Array +} + +/** Return type for `checkoutCustomerDisassociate` mutation. */ +export type CheckoutCustomerDisassociatePayload = { + __typename?: 'CheckoutCustomerDisassociatePayload' + /** The updated checkout object. */ + checkout: Checkout + /** List of errors that occurred executing the mutation. */ + checkoutUserErrors: Array + /** + * List of errors that occurred executing the mutation. + * @deprecated Use `checkoutUserErrors` instead + */ + userErrors: Array +} + +/** Return type for `checkoutCustomerDisassociateV2` mutation. */ +export type CheckoutCustomerDisassociateV2Payload = { + __typename?: 'CheckoutCustomerDisassociateV2Payload' + /** The updated checkout object. */ + checkout?: Maybe + /** List of errors that occurred executing the mutation. */ + checkoutUserErrors: Array + /** + * List of errors that occurred executing the mutation. + * @deprecated Use `checkoutUserErrors` instead + */ + userErrors: Array +} + +/** Return type for `checkoutDiscountCodeApply` mutation. */ +export type CheckoutDiscountCodeApplyPayload = { + __typename?: 'CheckoutDiscountCodeApplyPayload' + /** The updated checkout object. */ + checkout: Checkout + /** List of errors that occurred executing the mutation. */ + checkoutUserErrors: Array + /** + * List of errors that occurred executing the mutation. + * @deprecated Use `checkoutUserErrors` instead + */ + userErrors: Array +} + +/** Return type for `checkoutDiscountCodeApplyV2` mutation. */ +export type CheckoutDiscountCodeApplyV2Payload = { + __typename?: 'CheckoutDiscountCodeApplyV2Payload' + /** The updated checkout object. */ + checkout?: Maybe + /** List of errors that occurred executing the mutation. */ + checkoutUserErrors: Array + /** + * List of errors that occurred executing the mutation. + * @deprecated Use `checkoutUserErrors` instead + */ + userErrors: Array +} + +/** Return type for `checkoutDiscountCodeRemove` mutation. */ +export type CheckoutDiscountCodeRemovePayload = { + __typename?: 'CheckoutDiscountCodeRemovePayload' + /** The updated checkout object. */ + checkout?: Maybe + /** List of errors that occurred executing the mutation. */ + checkoutUserErrors: Array + /** + * List of errors that occurred executing the mutation. + * @deprecated Use `checkoutUserErrors` instead + */ + userErrors: Array +} + +/** Return type for `checkoutEmailUpdate` mutation. */ +export type CheckoutEmailUpdatePayload = { + __typename?: 'CheckoutEmailUpdatePayload' + /** The checkout object with the updated email. */ + checkout: Checkout + /** List of errors that occurred executing the mutation. */ + checkoutUserErrors: Array + /** + * List of errors that occurred executing the mutation. + * @deprecated Use `checkoutUserErrors` instead + */ + userErrors: Array +} + +/** Return type for `checkoutEmailUpdateV2` mutation. */ +export type CheckoutEmailUpdateV2Payload = { + __typename?: 'CheckoutEmailUpdateV2Payload' + /** The checkout object with the updated email. */ + checkout?: Maybe + /** List of errors that occurred executing the mutation. */ + checkoutUserErrors: Array + /** + * List of errors that occurred executing the mutation. + * @deprecated Use `checkoutUserErrors` instead + */ + userErrors: Array +} + +/** Possible error codes that could be returned by CheckoutUserError. */ +export enum CheckoutErrorCode { + /** Input value is blank. */ + Blank = 'BLANK', + /** Input value is invalid. */ + Invalid = 'INVALID', + /** Input value is too long. */ + TooLong = 'TOO_LONG', + /** Input value is not present. */ + Present = 'PRESENT', + /** Input value should be less than maximum allowed value. */ + LessThan = 'LESS_THAN', + /** Input value should be greater than or equal to minimum allowed value. */ + GreaterThanOrEqualTo = 'GREATER_THAN_OR_EQUAL_TO', + /** Input value should be less or equal to maximum allowed value. */ + LessThanOrEqualTo = 'LESS_THAN_OR_EQUAL_TO', + /** Checkout is already completed. */ + AlreadyCompleted = 'ALREADY_COMPLETED', + /** Checkout is locked. */ + Locked = 'LOCKED', + /** Input value is not supported. */ + NotSupported = 'NOT_SUPPORTED', + /** Input email contains an invalid domain name. */ + BadDomain = 'BAD_DOMAIN', + /** Input Zip is invalid for country provided. */ + InvalidForCountry = 'INVALID_FOR_COUNTRY', + /** Input Zip is invalid for country and province provided. */ + InvalidForCountryAndProvince = 'INVALID_FOR_COUNTRY_AND_PROVINCE', + /** Invalid state in country. */ + InvalidStateInCountry = 'INVALID_STATE_IN_COUNTRY', + /** Invalid province in country. */ + InvalidProvinceInCountry = 'INVALID_PROVINCE_IN_COUNTRY', + /** Invalid region in country. */ + InvalidRegionInCountry = 'INVALID_REGION_IN_COUNTRY', + /** Shipping rate expired. */ + ShippingRateExpired = 'SHIPPING_RATE_EXPIRED', + /** Gift card cannot be applied to a checkout that contains a gift card. */ + GiftCardUnusable = 'GIFT_CARD_UNUSABLE', + /** Gift card is disabled. */ + GiftCardDisabled = 'GIFT_CARD_DISABLED', + /** Gift card code is invalid. */ + GiftCardCodeInvalid = 'GIFT_CARD_CODE_INVALID', + /** Gift card has already been applied. */ + GiftCardAlreadyApplied = 'GIFT_CARD_ALREADY_APPLIED', + /** Gift card currency does not match checkout currency. */ + GiftCardCurrencyMismatch = 'GIFT_CARD_CURRENCY_MISMATCH', + /** Gift card is expired. */ + GiftCardExpired = 'GIFT_CARD_EXPIRED', + /** Gift card has no funds left. */ + GiftCardDepleted = 'GIFT_CARD_DEPLETED', + /** Gift card was not found. */ + GiftCardNotFound = 'GIFT_CARD_NOT_FOUND', + /** Cart does not meet discount requirements notice. */ + CartDoesNotMeetDiscountRequirementsNotice = 'CART_DOES_NOT_MEET_DISCOUNT_REQUIREMENTS_NOTICE', + /** Discount expired. */ + DiscountExpired = 'DISCOUNT_EXPIRED', + /** Discount disabled. */ + DiscountDisabled = 'DISCOUNT_DISABLED', + /** Discount limit reached. */ + DiscountLimitReached = 'DISCOUNT_LIMIT_REACHED', + /** Discount not found. */ + DiscountNotFound = 'DISCOUNT_NOT_FOUND', + /** Customer already used once per customer discount notice. */ + CustomerAlreadyUsedOncePerCustomerDiscountNotice = 'CUSTOMER_ALREADY_USED_ONCE_PER_CUSTOMER_DISCOUNT_NOTICE', + /** Checkout is already completed. */ + Empty = 'EMPTY', + /** Not enough in stock. */ + NotEnoughInStock = 'NOT_ENOUGH_IN_STOCK', + /** Missing payment input. */ + MissingPaymentInput = 'MISSING_PAYMENT_INPUT', + /** The amount of the payment does not match the value to be paid. */ + TotalPriceMismatch = 'TOTAL_PRICE_MISMATCH', + /** Line item was not found in checkout. */ + LineItemNotFound = 'LINE_ITEM_NOT_FOUND', + /** Unable to apply discount. */ + UnableToApply = 'UNABLE_TO_APPLY', + /** Discount already applied. */ + DiscountAlreadyApplied = 'DISCOUNT_ALREADY_APPLIED', +} + +/** Return type for `checkoutGiftCardApply` mutation. */ +export type CheckoutGiftCardApplyPayload = { + __typename?: 'CheckoutGiftCardApplyPayload' + /** The updated checkout object. */ + checkout: Checkout + /** List of errors that occurred executing the mutation. */ + checkoutUserErrors: Array + /** + * List of errors that occurred executing the mutation. + * @deprecated Use `checkoutUserErrors` instead + */ + userErrors: Array +} + +/** Return type for `checkoutGiftCardRemove` mutation. */ +export type CheckoutGiftCardRemovePayload = { + __typename?: 'CheckoutGiftCardRemovePayload' + /** The updated checkout object. */ + checkout: Checkout + /** List of errors that occurred executing the mutation. */ + checkoutUserErrors: Array + /** + * List of errors that occurred executing the mutation. + * @deprecated Use `checkoutUserErrors` instead + */ + userErrors: Array +} + +/** Return type for `checkoutGiftCardRemoveV2` mutation. */ +export type CheckoutGiftCardRemoveV2Payload = { + __typename?: 'CheckoutGiftCardRemoveV2Payload' + /** The updated checkout object. */ + checkout?: Maybe + /** List of errors that occurred executing the mutation. */ + checkoutUserErrors: Array + /** + * List of errors that occurred executing the mutation. + * @deprecated Use `checkoutUserErrors` instead + */ + userErrors: Array +} + +/** Return type for `checkoutGiftCardsAppend` mutation. */ +export type CheckoutGiftCardsAppendPayload = { + __typename?: 'CheckoutGiftCardsAppendPayload' + /** The updated checkout object. */ + checkout?: Maybe + /** List of errors that occurred executing the mutation. */ + checkoutUserErrors: Array + /** + * List of errors that occurred executing the mutation. + * @deprecated Use `checkoutUserErrors` instead + */ + userErrors: Array +} + +/** A single line item in the checkout, grouped by variant and attributes. */ +export type CheckoutLineItem = Node & { + __typename?: 'CheckoutLineItem' + /** Extra information in the form of an array of Key-Value pairs about the line item. */ + customAttributes: Array + /** The discounts that have been allocated onto the checkout line item by discount applications. */ + discountAllocations: Array + /** Globally unique identifier. */ + id: Scalars['ID'] + /** The quantity of the line item. */ + quantity: Scalars['Int'] + /** Title of the line item. Defaults to the product's title. */ + title: Scalars['String'] + /** Unit price of the line item. */ + unitPrice?: Maybe + /** Product variant of the line item. */ + variant?: Maybe +} + +/** An auto-generated type for paginating through multiple CheckoutLineItems. */ +export type CheckoutLineItemConnection = { + __typename?: 'CheckoutLineItemConnection' + /** A list of edges. */ + edges: Array + /** Information to aid in pagination. */ + pageInfo: PageInfo +} + +/** An auto-generated type which holds one CheckoutLineItem and a cursor during pagination. */ +export type CheckoutLineItemEdge = { + __typename?: 'CheckoutLineItemEdge' + /** A cursor for use in pagination. */ + cursor: Scalars['String'] + /** The item at the end of CheckoutLineItemEdge. */ + node: CheckoutLineItem +} + +/** Specifies the input fields to create a line item on a checkout. */ +export type CheckoutLineItemInput = { + /** Extra information in the form of an array of Key-Value pairs about the line item. */ + customAttributes?: Maybe> + /** The quantity of the line item. */ + quantity: Scalars['Int'] + /** The identifier of the product variant for the line item. */ + variantId: Scalars['ID'] +} + +/** Specifies the input fields to update a line item on the checkout. */ +export type CheckoutLineItemUpdateInput = { + /** The identifier of the line item. */ + id?: Maybe + /** The variant identifier of the line item. */ + variantId?: Maybe + /** The quantity of the line item. */ + quantity?: Maybe + /** Extra information in the form of an array of Key-Value pairs about the line item. */ + customAttributes?: Maybe> +} + +/** Return type for `checkoutLineItemsAdd` mutation. */ +export type CheckoutLineItemsAddPayload = { + __typename?: 'CheckoutLineItemsAddPayload' + /** The updated checkout object. */ + checkout?: Maybe + /** List of errors that occurred executing the mutation. */ + checkoutUserErrors: Array + /** + * List of errors that occurred executing the mutation. + * @deprecated Use `checkoutUserErrors` instead + */ + userErrors: Array +} + +/** Return type for `checkoutLineItemsRemove` mutation. */ +export type CheckoutLineItemsRemovePayload = { + __typename?: 'CheckoutLineItemsRemovePayload' + /** The updated checkout object. */ + checkout?: Maybe + /** List of errors that occurred executing the mutation. */ + checkoutUserErrors: Array + /** + * List of errors that occurred executing the mutation. + * @deprecated Use `checkoutUserErrors` instead + */ + userErrors: Array +} + +/** Return type for `checkoutLineItemsReplace` mutation. */ +export type CheckoutLineItemsReplacePayload = { + __typename?: 'CheckoutLineItemsReplacePayload' + /** The updated checkout object. */ + checkout?: Maybe + /** List of errors that occurred executing the mutation. */ + userErrors: Array +} + +/** Return type for `checkoutLineItemsUpdate` mutation. */ +export type CheckoutLineItemsUpdatePayload = { + __typename?: 'CheckoutLineItemsUpdatePayload' + /** The updated checkout object. */ + checkout?: Maybe + /** List of errors that occurred executing the mutation. */ + checkoutUserErrors: Array + /** + * List of errors that occurred executing the mutation. + * @deprecated Use `checkoutUserErrors` instead + */ + userErrors: Array +} + +/** Return type for `checkoutShippingAddressUpdate` mutation. */ +export type CheckoutShippingAddressUpdatePayload = { + __typename?: 'CheckoutShippingAddressUpdatePayload' + /** The updated checkout object. */ + checkout: Checkout + /** List of errors that occurred executing the mutation. */ + checkoutUserErrors: Array + /** + * List of errors that occurred executing the mutation. + * @deprecated Use `checkoutUserErrors` instead + */ + userErrors: Array +} + +/** Return type for `checkoutShippingAddressUpdateV2` mutation. */ +export type CheckoutShippingAddressUpdateV2Payload = { + __typename?: 'CheckoutShippingAddressUpdateV2Payload' + /** The updated checkout object. */ + checkout?: Maybe + /** List of errors that occurred executing the mutation. */ + checkoutUserErrors: Array + /** + * List of errors that occurred executing the mutation. + * @deprecated Use `checkoutUserErrors` instead + */ + userErrors: Array +} + +/** Return type for `checkoutShippingLineUpdate` mutation. */ +export type CheckoutShippingLineUpdatePayload = { + __typename?: 'CheckoutShippingLineUpdatePayload' + /** The updated checkout object. */ + checkout?: Maybe + /** List of errors that occurred executing the mutation. */ + checkoutUserErrors: Array + /** + * List of errors that occurred executing the mutation. + * @deprecated Use `checkoutUserErrors` instead + */ + userErrors: Array +} + +/** Represents an error that happens during execution of a checkout mutation. */ +export type CheckoutUserError = DisplayableError & { + __typename?: 'CheckoutUserError' + /** Error code to uniquely identify the error. */ + code?: Maybe + /** Path to the input field which caused the error. */ + field?: Maybe> + /** The error message. */ + message: Scalars['String'] +} + +/** A collection represents a grouping of products that a shop owner can create to organize them or make their shops easier to browse. */ +export type Collection = Node & { + __typename?: 'Collection' + /** Stripped description of the collection, single line with HTML tags removed. */ + description: Scalars['String'] + /** The description of the collection, complete with HTML formatting. */ + descriptionHtml: Scalars['HTML'] + /** + * A human-friendly unique string for the collection automatically generated from its title. + * Limit of 255 characters. + */ + handle: Scalars['String'] + /** Globally unique identifier. */ + id: Scalars['ID'] + /** Image associated with the collection. */ + image?: Maybe + /** List of products in the collection. */ + products: ProductConnection + /** The collection’s name. Limit of 255 characters. */ + title: Scalars['String'] + /** The date and time when the collection was last modified. */ + updatedAt: Scalars['DateTime'] +} + +/** A collection represents a grouping of products that a shop owner can create to organize them or make their shops easier to browse. */ +export type CollectionDescriptionArgs = { + truncateAt?: Maybe +} + +/** A collection represents a grouping of products that a shop owner can create to organize them or make their shops easier to browse. */ +export type CollectionImageArgs = { + maxWidth?: Maybe + maxHeight?: Maybe + crop?: Maybe + scale?: Maybe +} + +/** A collection represents a grouping of products that a shop owner can create to organize them or make their shops easier to browse. */ +export type CollectionProductsArgs = { + first?: Maybe + after?: Maybe + last?: Maybe + before?: Maybe + reverse?: Maybe + sortKey?: Maybe +} + +/** An auto-generated type for paginating through multiple Collections. */ +export type CollectionConnection = { + __typename?: 'CollectionConnection' + /** A list of edges. */ + edges: Array + /** Information to aid in pagination. */ + pageInfo: PageInfo +} + +/** An auto-generated type which holds one Collection and a cursor during pagination. */ +export type CollectionEdge = { + __typename?: 'CollectionEdge' + /** A cursor for use in pagination. */ + cursor: Scalars['String'] + /** The item at the end of CollectionEdge. */ + node: Collection +} + +/** The set of valid sort keys for the Collection query. */ +export enum CollectionSortKeys { + /** Sort by the `title` value. */ + Title = 'TITLE', + /** Sort by the `updated_at` value. */ + UpdatedAt = 'UPDATED_AT', + /** Sort by the `id` value. */ + Id = 'ID', + /** + * During a search (i.e. when the `query` parameter has been specified on the connection) this sorts the + * results by relevance to the search term(s). When no search query is specified, this sort key is not + * deterministic and should not be used. + */ + Relevance = 'RELEVANCE', +} + +/** A comment on an article. */ +export type Comment = Node & { + __typename?: 'Comment' + /** The comment’s author. */ + author: CommentAuthor + /** Stripped content of the comment, single line with HTML tags removed. */ + content: Scalars['String'] + /** The content of the comment, complete with HTML formatting. */ + contentHtml: Scalars['HTML'] + /** Globally unique identifier. */ + id: Scalars['ID'] +} + +/** A comment on an article. */ +export type CommentContentArgs = { + truncateAt?: Maybe +} + +/** The author of a comment. */ +export type CommentAuthor = { + __typename?: 'CommentAuthor' + /** The author's email. */ + email: Scalars['String'] + /** The author’s name. */ + name: Scalars['String'] +} + +/** An auto-generated type for paginating through multiple Comments. */ +export type CommentConnection = { + __typename?: 'CommentConnection' + /** A list of edges. */ + edges: Array + /** Information to aid in pagination. */ + pageInfo: PageInfo +} + +/** An auto-generated type which holds one Comment and a cursor during pagination. */ +export type CommentEdge = { + __typename?: 'CommentEdge' + /** A cursor for use in pagination. */ + cursor: Scalars['String'] + /** The item at the end of CommentEdge. */ + node: Comment +} + +/** ISO 3166-1 alpha-2 country codes with some differences. */ +export enum CountryCode { + /** Afghanistan. */ + Af = 'AF', + /** Åland Islands. */ + Ax = 'AX', + /** Albania. */ + Al = 'AL', + /** Algeria. */ + Dz = 'DZ', + /** Andorra. */ + Ad = 'AD', + /** Angola. */ + Ao = 'AO', + /** Anguilla. */ + Ai = 'AI', + /** Antigua & Barbuda. */ + Ag = 'AG', + /** Argentina. */ + Ar = 'AR', + /** Armenia. */ + Am = 'AM', + /** Aruba. */ + Aw = 'AW', + /** Australia. */ + Au = 'AU', + /** Austria. */ + At = 'AT', + /** Azerbaijan. */ + Az = 'AZ', + /** Bahamas. */ + Bs = 'BS', + /** Bahrain. */ + Bh = 'BH', + /** Bangladesh. */ + Bd = 'BD', + /** Barbados. */ + Bb = 'BB', + /** Belarus. */ + By = 'BY', + /** Belgium. */ + Be = 'BE', + /** Belize. */ + Bz = 'BZ', + /** Benin. */ + Bj = 'BJ', + /** Bermuda. */ + Bm = 'BM', + /** Bhutan. */ + Bt = 'BT', + /** Bolivia. */ + Bo = 'BO', + /** Bosnia & Herzegovina. */ + Ba = 'BA', + /** Botswana. */ + Bw = 'BW', + /** Bouvet Island. */ + Bv = 'BV', + /** Brazil. */ + Br = 'BR', + /** British Indian Ocean Territory. */ + Io = 'IO', + /** Brunei. */ + Bn = 'BN', + /** Bulgaria. */ + Bg = 'BG', + /** Burkina Faso. */ + Bf = 'BF', + /** Burundi. */ + Bi = 'BI', + /** Cambodia. */ + Kh = 'KH', + /** Canada. */ + Ca = 'CA', + /** Cape Verde. */ + Cv = 'CV', + /** Caribbean Netherlands. */ + Bq = 'BQ', + /** Cayman Islands. */ + Ky = 'KY', + /** Central African Republic. */ + Cf = 'CF', + /** Chad. */ + Td = 'TD', + /** Chile. */ + Cl = 'CL', + /** China. */ + Cn = 'CN', + /** Christmas Island. */ + Cx = 'CX', + /** Cocos (Keeling) Islands. */ + Cc = 'CC', + /** Colombia. */ + Co = 'CO', + /** Comoros. */ + Km = 'KM', + /** Congo - Brazzaville. */ + Cg = 'CG', + /** Congo - Kinshasa. */ + Cd = 'CD', + /** Cook Islands. */ + Ck = 'CK', + /** Costa Rica. */ + Cr = 'CR', + /** Croatia. */ + Hr = 'HR', + /** Cuba. */ + Cu = 'CU', + /** Curaçao. */ + Cw = 'CW', + /** Cyprus. */ + Cy = 'CY', + /** Czechia. */ + Cz = 'CZ', + /** Côte d’Ivoire. */ + Ci = 'CI', + /** Denmark. */ + Dk = 'DK', + /** Djibouti. */ + Dj = 'DJ', + /** Dominica. */ + Dm = 'DM', + /** Dominican Republic. */ + Do = 'DO', + /** Ecuador. */ + Ec = 'EC', + /** Egypt. */ + Eg = 'EG', + /** El Salvador. */ + Sv = 'SV', + /** Equatorial Guinea. */ + Gq = 'GQ', + /** Eritrea. */ + Er = 'ER', + /** Estonia. */ + Ee = 'EE', + /** Eswatini. */ + Sz = 'SZ', + /** Ethiopia. */ + Et = 'ET', + /** Falkland Islands. */ + Fk = 'FK', + /** Faroe Islands. */ + Fo = 'FO', + /** Fiji. */ + Fj = 'FJ', + /** Finland. */ + Fi = 'FI', + /** France. */ + Fr = 'FR', + /** French Guiana. */ + Gf = 'GF', + /** French Polynesia. */ + Pf = 'PF', + /** French Southern Territories. */ + Tf = 'TF', + /** Gabon. */ + Ga = 'GA', + /** Gambia. */ + Gm = 'GM', + /** Georgia. */ + Ge = 'GE', + /** Germany. */ + De = 'DE', + /** Ghana. */ + Gh = 'GH', + /** Gibraltar. */ + Gi = 'GI', + /** Greece. */ + Gr = 'GR', + /** Greenland. */ + Gl = 'GL', + /** Grenada. */ + Gd = 'GD', + /** Guadeloupe. */ + Gp = 'GP', + /** Guatemala. */ + Gt = 'GT', + /** Guernsey. */ + Gg = 'GG', + /** Guinea. */ + Gn = 'GN', + /** Guinea-Bissau. */ + Gw = 'GW', + /** Guyana. */ + Gy = 'GY', + /** Haiti. */ + Ht = 'HT', + /** Heard & McDonald Islands. */ + Hm = 'HM', + /** Vatican City. */ + Va = 'VA', + /** Honduras. */ + Hn = 'HN', + /** Hong Kong SAR. */ + Hk = 'HK', + /** Hungary. */ + Hu = 'HU', + /** Iceland. */ + Is = 'IS', + /** India. */ + In = 'IN', + /** Indonesia. */ + Id = 'ID', + /** Iran. */ + Ir = 'IR', + /** Iraq. */ + Iq = 'IQ', + /** Ireland. */ + Ie = 'IE', + /** Isle of Man. */ + Im = 'IM', + /** Israel. */ + Il = 'IL', + /** Italy. */ + It = 'IT', + /** Jamaica. */ + Jm = 'JM', + /** Japan. */ + Jp = 'JP', + /** Jersey. */ + Je = 'JE', + /** Jordan. */ + Jo = 'JO', + /** Kazakhstan. */ + Kz = 'KZ', + /** Kenya. */ + Ke = 'KE', + /** Kiribati. */ + Ki = 'KI', + /** North Korea. */ + Kp = 'KP', + /** Kosovo. */ + Xk = 'XK', + /** Kuwait. */ + Kw = 'KW', + /** Kyrgyzstan. */ + Kg = 'KG', + /** Laos. */ + La = 'LA', + /** Latvia. */ + Lv = 'LV', + /** Lebanon. */ + Lb = 'LB', + /** Lesotho. */ + Ls = 'LS', + /** Liberia. */ + Lr = 'LR', + /** Libya. */ + Ly = 'LY', + /** Liechtenstein. */ + Li = 'LI', + /** Lithuania. */ + Lt = 'LT', + /** Luxembourg. */ + Lu = 'LU', + /** Macao SAR. */ + Mo = 'MO', + /** Madagascar. */ + Mg = 'MG', + /** Malawi. */ + Mw = 'MW', + /** Malaysia. */ + My = 'MY', + /** Maldives. */ + Mv = 'MV', + /** Mali. */ + Ml = 'ML', + /** Malta. */ + Mt = 'MT', + /** Martinique. */ + Mq = 'MQ', + /** Mauritania. */ + Mr = 'MR', + /** Mauritius. */ + Mu = 'MU', + /** Mayotte. */ + Yt = 'YT', + /** Mexico. */ + Mx = 'MX', + /** Moldova. */ + Md = 'MD', + /** Monaco. */ + Mc = 'MC', + /** Mongolia. */ + Mn = 'MN', + /** Montenegro. */ + Me = 'ME', + /** Montserrat. */ + Ms = 'MS', + /** Morocco. */ + Ma = 'MA', + /** Mozambique. */ + Mz = 'MZ', + /** Myanmar (Burma). */ + Mm = 'MM', + /** Namibia. */ + Na = 'NA', + /** Nauru. */ + Nr = 'NR', + /** Nepal. */ + Np = 'NP', + /** Netherlands. */ + Nl = 'NL', + /** Netherlands Antilles. */ + An = 'AN', + /** New Caledonia. */ + Nc = 'NC', + /** New Zealand. */ + Nz = 'NZ', + /** Nicaragua. */ + Ni = 'NI', + /** Niger. */ + Ne = 'NE', + /** Nigeria. */ + Ng = 'NG', + /** Niue. */ + Nu = 'NU', + /** Norfolk Island. */ + Nf = 'NF', + /** North Macedonia. */ + Mk = 'MK', + /** Norway. */ + No = 'NO', + /** Oman. */ + Om = 'OM', + /** Pakistan. */ + Pk = 'PK', + /** Palestinian Territories. */ + Ps = 'PS', + /** Panama. */ + Pa = 'PA', + /** Papua New Guinea. */ + Pg = 'PG', + /** Paraguay. */ + Py = 'PY', + /** Peru. */ + Pe = 'PE', + /** Philippines. */ + Ph = 'PH', + /** Pitcairn Islands. */ + Pn = 'PN', + /** Poland. */ + Pl = 'PL', + /** Portugal. */ + Pt = 'PT', + /** Qatar. */ + Qa = 'QA', + /** Cameroon. */ + Cm = 'CM', + /** Réunion. */ + Re = 'RE', + /** Romania. */ + Ro = 'RO', + /** Russia. */ + Ru = 'RU', + /** Rwanda. */ + Rw = 'RW', + /** St. Barthélemy. */ + Bl = 'BL', + /** St. Helena. */ + Sh = 'SH', + /** St. Kitts & Nevis. */ + Kn = 'KN', + /** St. Lucia. */ + Lc = 'LC', + /** St. Martin. */ + Mf = 'MF', + /** St. Pierre & Miquelon. */ + Pm = 'PM', + /** Samoa. */ + Ws = 'WS', + /** San Marino. */ + Sm = 'SM', + /** São Tomé & Príncipe. */ + St = 'ST', + /** Saudi Arabia. */ + Sa = 'SA', + /** Senegal. */ + Sn = 'SN', + /** Serbia. */ + Rs = 'RS', + /** Seychelles. */ + Sc = 'SC', + /** Sierra Leone. */ + Sl = 'SL', + /** Singapore. */ + Sg = 'SG', + /** Sint Maarten. */ + Sx = 'SX', + /** Slovakia. */ + Sk = 'SK', + /** Slovenia. */ + Si = 'SI', + /** Solomon Islands. */ + Sb = 'SB', + /** Somalia. */ + So = 'SO', + /** South Africa. */ + Za = 'ZA', + /** South Georgia & South Sandwich Islands. */ + Gs = 'GS', + /** South Korea. */ + Kr = 'KR', + /** South Sudan. */ + Ss = 'SS', + /** Spain. */ + Es = 'ES', + /** Sri Lanka. */ + Lk = 'LK', + /** St. Vincent & Grenadines. */ + Vc = 'VC', + /** Sudan. */ + Sd = 'SD', + /** Suriname. */ + Sr = 'SR', + /** Svalbard & Jan Mayen. */ + Sj = 'SJ', + /** Sweden. */ + Se = 'SE', + /** Switzerland. */ + Ch = 'CH', + /** Syria. */ + Sy = 'SY', + /** Taiwan. */ + Tw = 'TW', + /** Tajikistan. */ + Tj = 'TJ', + /** Tanzania. */ + Tz = 'TZ', + /** Thailand. */ + Th = 'TH', + /** Timor-Leste. */ + Tl = 'TL', + /** Togo. */ + Tg = 'TG', + /** Tokelau. */ + Tk = 'TK', + /** Tonga. */ + To = 'TO', + /** Trinidad & Tobago. */ + Tt = 'TT', + /** Tunisia. */ + Tn = 'TN', + /** Turkey. */ + Tr = 'TR', + /** Turkmenistan. */ + Tm = 'TM', + /** Turks & Caicos Islands. */ + Tc = 'TC', + /** Tuvalu. */ + Tv = 'TV', + /** Uganda. */ + Ug = 'UG', + /** Ukraine. */ + Ua = 'UA', + /** United Arab Emirates. */ + Ae = 'AE', + /** United Kingdom. */ + Gb = 'GB', + /** United States. */ + Us = 'US', + /** U.S. Outlying Islands. */ + Um = 'UM', + /** Uruguay. */ + Uy = 'UY', + /** Uzbekistan. */ + Uz = 'UZ', + /** Vanuatu. */ + Vu = 'VU', + /** Venezuela. */ + Ve = 'VE', + /** Vietnam. */ + Vn = 'VN', + /** British Virgin Islands. */ + Vg = 'VG', + /** Wallis & Futuna. */ + Wf = 'WF', + /** Western Sahara. */ + Eh = 'EH', + /** Yemen. */ + Ye = 'YE', + /** Zambia. */ + Zm = 'ZM', + /** Zimbabwe. */ + Zw = 'ZW', +} + +/** Credit card information used for a payment. */ +export type CreditCard = { + __typename?: 'CreditCard' + /** The brand of the credit card. */ + brand?: Maybe + /** The expiry month of the credit card. */ + expiryMonth?: Maybe + /** The expiry year of the credit card. */ + expiryYear?: Maybe + /** The credit card's BIN number. */ + firstDigits?: Maybe + /** The first name of the card holder. */ + firstName?: Maybe + /** The last 4 digits of the credit card. */ + lastDigits?: Maybe + /** The last name of the card holder. */ + lastName?: Maybe + /** The masked credit card number with only the last 4 digits displayed. */ + maskedNumber?: Maybe +} + +/** + * Specifies the fields required to complete a checkout with + * a Shopify vaulted credit card payment. + */ +export type CreditCardPaymentInput = { + /** The amount of the payment. */ + amount: Scalars['Money'] + /** A unique client generated key used to avoid duplicate charges. When a duplicate payment is found, the original is returned instead of creating a new one. */ + idempotencyKey: Scalars['String'] + /** The billing address for the payment. */ + billingAddress: MailingAddressInput + /** The ID returned by Shopify's Card Vault. */ + vaultId: Scalars['String'] + /** Executes the payment in test mode if possible. Defaults to `false`. */ + test?: Maybe +} + +/** + * Specifies the fields required to complete a checkout with + * a Shopify vaulted credit card payment. + */ +export type CreditCardPaymentInputV2 = { + /** The amount and currency of the payment. */ + paymentAmount: MoneyInput + /** A unique client generated key used to avoid duplicate charges. When a duplicate payment is found, the original is returned instead of creating a new one. */ + idempotencyKey: Scalars['String'] + /** The billing address for the payment. */ + billingAddress: MailingAddressInput + /** The ID returned by Shopify's Card Vault. */ + vaultId: Scalars['String'] + /** Executes the payment in test mode if possible. Defaults to `false`. */ + test?: Maybe +} + +/** The part of the image that should remain after cropping. */ +export enum CropRegion { + /** Keep the center of the image. */ + Center = 'CENTER', + /** Keep the top of the image. */ + Top = 'TOP', + /** Keep the bottom of the image. */ + Bottom = 'BOTTOM', + /** Keep the left of the image. */ + Left = 'LEFT', + /** Keep the right of the image. */ + Right = 'RIGHT', +} + +/** Currency codes. */ +export enum CurrencyCode { + /** United States Dollars (USD). */ + Usd = 'USD', + /** Euro (EUR). */ + Eur = 'EUR', + /** United Kingdom Pounds (GBP). */ + Gbp = 'GBP', + /** Canadian Dollars (CAD). */ + Cad = 'CAD', + /** Afghan Afghani (AFN). */ + Afn = 'AFN', + /** Albanian Lek (ALL). */ + All = 'ALL', + /** Algerian Dinar (DZD). */ + Dzd = 'DZD', + /** Angolan Kwanza (AOA). */ + Aoa = 'AOA', + /** Argentine Pesos (ARS). */ + Ars = 'ARS', + /** Armenian Dram (AMD). */ + Amd = 'AMD', + /** Aruban Florin (AWG). */ + Awg = 'AWG', + /** Australian Dollars (AUD). */ + Aud = 'AUD', + /** Barbadian Dollar (BBD). */ + Bbd = 'BBD', + /** Azerbaijani Manat (AZN). */ + Azn = 'AZN', + /** Bangladesh Taka (BDT). */ + Bdt = 'BDT', + /** Bahamian Dollar (BSD). */ + Bsd = 'BSD', + /** Bahraini Dinar (BHD). */ + Bhd = 'BHD', + /** Burundian Franc (BIF). */ + Bif = 'BIF', + /** Belarusian Ruble (BYN). */ + Byn = 'BYN', + /** Belarusian Ruble (BYR). */ + Byr = 'BYR', + /** Belize Dollar (BZD). */ + Bzd = 'BZD', + /** Bermudian Dollar (BMD). */ + Bmd = 'BMD', + /** Bhutanese Ngultrum (BTN). */ + Btn = 'BTN', + /** Bosnia and Herzegovina Convertible Mark (BAM). */ + Bam = 'BAM', + /** Brazilian Real (BRL). */ + Brl = 'BRL', + /** Bolivian Boliviano (BOB). */ + Bob = 'BOB', + /** Botswana Pula (BWP). */ + Bwp = 'BWP', + /** Brunei Dollar (BND). */ + Bnd = 'BND', + /** Bulgarian Lev (BGN). */ + Bgn = 'BGN', + /** Burmese Kyat (MMK). */ + Mmk = 'MMK', + /** Cambodian Riel. */ + Khr = 'KHR', + /** Cape Verdean escudo (CVE). */ + Cve = 'CVE', + /** Cayman Dollars (KYD). */ + Kyd = 'KYD', + /** Central African CFA Franc (XAF). */ + Xaf = 'XAF', + /** Chilean Peso (CLP). */ + Clp = 'CLP', + /** Chinese Yuan Renminbi (CNY). */ + Cny = 'CNY', + /** Colombian Peso (COP). */ + Cop = 'COP', + /** Comorian Franc (KMF). */ + Kmf = 'KMF', + /** Congolese franc (CDF). */ + Cdf = 'CDF', + /** Costa Rican Colones (CRC). */ + Crc = 'CRC', + /** Croatian Kuna (HRK). */ + Hrk = 'HRK', + /** Czech Koruny (CZK). */ + Czk = 'CZK', + /** Danish Kroner (DKK). */ + Dkk = 'DKK', + /** Djiboutian Franc (DJF). */ + Djf = 'DJF', + /** Dominican Peso (DOP). */ + Dop = 'DOP', + /** East Caribbean Dollar (XCD). */ + Xcd = 'XCD', + /** Egyptian Pound (EGP). */ + Egp = 'EGP', + /** Eritrean Nakfa (ERN). */ + Ern = 'ERN', + /** Ethiopian Birr (ETB). */ + Etb = 'ETB', + /** Falkland Islands Pounds (FKP). */ + Fkp = 'FKP', + /** CFP Franc (XPF). */ + Xpf = 'XPF', + /** Fijian Dollars (FJD). */ + Fjd = 'FJD', + /** Gibraltar Pounds (GIP). */ + Gip = 'GIP', + /** Gambian Dalasi (GMD). */ + Gmd = 'GMD', + /** Ghanaian Cedi (GHS). */ + Ghs = 'GHS', + /** Guatemalan Quetzal (GTQ). */ + Gtq = 'GTQ', + /** Guyanese Dollar (GYD). */ + Gyd = 'GYD', + /** Georgian Lari (GEL). */ + Gel = 'GEL', + /** Guinean Franc (GNF). */ + Gnf = 'GNF', + /** Haitian Gourde (HTG). */ + Htg = 'HTG', + /** Honduran Lempira (HNL). */ + Hnl = 'HNL', + /** Hong Kong Dollars (HKD). */ + Hkd = 'HKD', + /** Hungarian Forint (HUF). */ + Huf = 'HUF', + /** Icelandic Kronur (ISK). */ + Isk = 'ISK', + /** Indian Rupees (INR). */ + Inr = 'INR', + /** Indonesian Rupiah (IDR). */ + Idr = 'IDR', + /** Israeli New Shekel (NIS). */ + Ils = 'ILS', + /** Iranian Rial (IRR). */ + Irr = 'IRR', + /** Iraqi Dinar (IQD). */ + Iqd = 'IQD', + /** Jamaican Dollars (JMD). */ + Jmd = 'JMD', + /** Japanese Yen (JPY). */ + Jpy = 'JPY', + /** Jersey Pound. */ + Jep = 'JEP', + /** Jordanian Dinar (JOD). */ + Jod = 'JOD', + /** Kazakhstani Tenge (KZT). */ + Kzt = 'KZT', + /** Kenyan Shilling (KES). */ + Kes = 'KES', + /** Kiribati Dollar (KID). */ + Kid = 'KID', + /** Kuwaiti Dinar (KWD). */ + Kwd = 'KWD', + /** Kyrgyzstani Som (KGS). */ + Kgs = 'KGS', + /** Laotian Kip (LAK). */ + Lak = 'LAK', + /** Latvian Lati (LVL). */ + Lvl = 'LVL', + /** Lebanese Pounds (LBP). */ + Lbp = 'LBP', + /** Lesotho Loti (LSL). */ + Lsl = 'LSL', + /** Liberian Dollar (LRD). */ + Lrd = 'LRD', + /** Libyan Dinar (LYD). */ + Lyd = 'LYD', + /** Lithuanian Litai (LTL). */ + Ltl = 'LTL', + /** Malagasy Ariary (MGA). */ + Mga = 'MGA', + /** Macedonia Denar (MKD). */ + Mkd = 'MKD', + /** Macanese Pataca (MOP). */ + Mop = 'MOP', + /** Malawian Kwacha (MWK). */ + Mwk = 'MWK', + /** Maldivian Rufiyaa (MVR). */ + Mvr = 'MVR', + /** Mauritanian Ouguiya (MRU). */ + Mru = 'MRU', + /** Mexican Pesos (MXN). */ + Mxn = 'MXN', + /** Malaysian Ringgits (MYR). */ + Myr = 'MYR', + /** Mauritian Rupee (MUR). */ + Mur = 'MUR', + /** Moldovan Leu (MDL). */ + Mdl = 'MDL', + /** Moroccan Dirham. */ + Mad = 'MAD', + /** Mongolian Tugrik. */ + Mnt = 'MNT', + /** Mozambican Metical. */ + Mzn = 'MZN', + /** Namibian Dollar. */ + Nad = 'NAD', + /** Nepalese Rupee (NPR). */ + Npr = 'NPR', + /** Netherlands Antillean Guilder. */ + Ang = 'ANG', + /** New Zealand Dollars (NZD). */ + Nzd = 'NZD', + /** Nicaraguan Córdoba (NIO). */ + Nio = 'NIO', + /** Nigerian Naira (NGN). */ + Ngn = 'NGN', + /** Norwegian Kroner (NOK). */ + Nok = 'NOK', + /** Omani Rial (OMR). */ + Omr = 'OMR', + /** Panamian Balboa (PAB). */ + Pab = 'PAB', + /** Pakistani Rupee (PKR). */ + Pkr = 'PKR', + /** Papua New Guinean Kina (PGK). */ + Pgk = 'PGK', + /** Paraguayan Guarani (PYG). */ + Pyg = 'PYG', + /** Peruvian Nuevo Sol (PEN). */ + Pen = 'PEN', + /** Philippine Peso (PHP). */ + Php = 'PHP', + /** Polish Zlotych (PLN). */ + Pln = 'PLN', + /** Qatari Rial (QAR). */ + Qar = 'QAR', + /** Romanian Lei (RON). */ + Ron = 'RON', + /** Russian Rubles (RUB). */ + Rub = 'RUB', + /** Rwandan Franc (RWF). */ + Rwf = 'RWF', + /** Samoan Tala (WST). */ + Wst = 'WST', + /** Saint Helena Pounds (SHP). */ + Shp = 'SHP', + /** Saudi Riyal (SAR). */ + Sar = 'SAR', + /** Sao Tome And Principe Dobra (STD). */ + Std = 'STD', + /** Serbian dinar (RSD). */ + Rsd = 'RSD', + /** Seychellois Rupee (SCR). */ + Scr = 'SCR', + /** Sierra Leonean Leone (SLL). */ + Sll = 'SLL', + /** Singapore Dollars (SGD). */ + Sgd = 'SGD', + /** Sudanese Pound (SDG). */ + Sdg = 'SDG', + /** Somali Shilling (SOS). */ + Sos = 'SOS', + /** Syrian Pound (SYP). */ + Syp = 'SYP', + /** South African Rand (ZAR). */ + Zar = 'ZAR', + /** South Korean Won (KRW). */ + Krw = 'KRW', + /** South Sudanese Pound (SSP). */ + Ssp = 'SSP', + /** Solomon Islands Dollar (SBD). */ + Sbd = 'SBD', + /** Sri Lankan Rupees (LKR). */ + Lkr = 'LKR', + /** Surinamese Dollar (SRD). */ + Srd = 'SRD', + /** Swazi Lilangeni (SZL). */ + Szl = 'SZL', + /** Swedish Kronor (SEK). */ + Sek = 'SEK', + /** Swiss Francs (CHF). */ + Chf = 'CHF', + /** Taiwan Dollars (TWD). */ + Twd = 'TWD', + /** Thai baht (THB). */ + Thb = 'THB', + /** Tajikistani Somoni (TJS). */ + Tjs = 'TJS', + /** Tanzanian Shilling (TZS). */ + Tzs = 'TZS', + /** Tongan Pa'anga (TOP). */ + Top = 'TOP', + /** Trinidad and Tobago Dollars (TTD). */ + Ttd = 'TTD', + /** Tunisian Dinar (TND). */ + Tnd = 'TND', + /** Turkish Lira (TRY). */ + Try = 'TRY', + /** Turkmenistani Manat (TMT). */ + Tmt = 'TMT', + /** Ugandan Shilling (UGX). */ + Ugx = 'UGX', + /** Ukrainian Hryvnia (UAH). */ + Uah = 'UAH', + /** United Arab Emirates Dirham (AED). */ + Aed = 'AED', + /** Uruguayan Pesos (UYU). */ + Uyu = 'UYU', + /** Uzbekistan som (UZS). */ + Uzs = 'UZS', + /** Vanuatu Vatu (VUV). */ + Vuv = 'VUV', + /** Venezuelan Bolivares (VEF). */ + Vef = 'VEF', + /** Venezuelan Bolivares (VES). */ + Ves = 'VES', + /** Vietnamese đồng (VND). */ + Vnd = 'VND', + /** West African CFA franc (XOF). */ + Xof = 'XOF', + /** Yemeni Rial (YER). */ + Yer = 'YER', + /** Zambian Kwacha (ZMW). */ + Zmw = 'ZMW', +} + +/** A customer represents a customer account with the shop. Customer accounts store contact information for the customer, saving logged-in customers the trouble of having to provide it at every checkout. */ +export type Customer = { + __typename?: 'Customer' + /** Indicates whether the customer has consented to be sent marketing material via email. */ + acceptsMarketing: Scalars['Boolean'] + /** A list of addresses for the customer. */ + addresses: MailingAddressConnection + /** The date and time when the customer was created. */ + createdAt: Scalars['DateTime'] + /** The customer’s default address. */ + defaultAddress?: Maybe + /** The customer’s name, email or phone number. */ + displayName: Scalars['String'] + /** The customer’s email address. */ + email?: Maybe + /** The customer’s first name. */ + firstName?: Maybe + /** A unique identifier for the customer. */ + id: Scalars['ID'] + /** The customer's most recently updated, incomplete checkout. */ + lastIncompleteCheckout?: Maybe + /** The customer’s last name. */ + lastName?: Maybe + /** The orders associated with the customer. */ + orders: OrderConnection + /** The customer’s phone number. */ + phone?: Maybe + /** + * A comma separated list of tags that have been added to the customer. + * Additional access scope required: unauthenticated_read_customer_tags. + */ + tags: Array + /** The date and time when the customer information was updated. */ + updatedAt: Scalars['DateTime'] +} + +/** A customer represents a customer account with the shop. Customer accounts store contact information for the customer, saving logged-in customers the trouble of having to provide it at every checkout. */ +export type CustomerAddressesArgs = { + first?: Maybe + after?: Maybe + last?: Maybe + before?: Maybe + reverse?: Maybe +} + +/** A customer represents a customer account with the shop. Customer accounts store contact information for the customer, saving logged-in customers the trouble of having to provide it at every checkout. */ +export type CustomerOrdersArgs = { + first?: Maybe + after?: Maybe + last?: Maybe + before?: Maybe + reverse?: Maybe + sortKey?: Maybe + query?: Maybe +} + +/** A CustomerAccessToken represents the unique token required to make modifications to the customer object. */ +export type CustomerAccessToken = { + __typename?: 'CustomerAccessToken' + /** The customer’s access token. */ + accessToken: Scalars['String'] + /** The date and time when the customer access token expires. */ + expiresAt: Scalars['DateTime'] +} + +/** Specifies the input fields required to create a customer access token. */ +export type CustomerAccessTokenCreateInput = { + /** The email associated to the customer. */ + email: Scalars['String'] + /** The login password to be used by the customer. */ + password: Scalars['String'] +} + +/** Return type for `customerAccessTokenCreate` mutation. */ +export type CustomerAccessTokenCreatePayload = { + __typename?: 'CustomerAccessTokenCreatePayload' + /** The newly created customer access token object. */ + customerAccessToken?: Maybe + /** List of errors that occurred executing the mutation. */ + customerUserErrors: Array + /** + * List of errors that occurred executing the mutation. + * @deprecated Use `customerUserErrors` instead + */ + userErrors: Array +} + +/** Return type for `customerAccessTokenCreateWithMultipass` mutation. */ +export type CustomerAccessTokenCreateWithMultipassPayload = { + __typename?: 'CustomerAccessTokenCreateWithMultipassPayload' + /** An access token object associated with the customer. */ + customerAccessToken?: Maybe + /** List of errors that occurred executing the mutation. */ + customerUserErrors: Array +} + +/** Return type for `customerAccessTokenDelete` mutation. */ +export type CustomerAccessTokenDeletePayload = { + __typename?: 'CustomerAccessTokenDeletePayload' + /** The destroyed access token. */ + deletedAccessToken?: Maybe + /** ID of the destroyed customer access token. */ + deletedCustomerAccessTokenId?: Maybe + /** List of errors that occurred executing the mutation. */ + userErrors: Array +} + +/** Return type for `customerAccessTokenRenew` mutation. */ +export type CustomerAccessTokenRenewPayload = { + __typename?: 'CustomerAccessTokenRenewPayload' + /** The renewed customer access token object. */ + customerAccessToken?: Maybe + /** List of errors that occurred executing the mutation. */ + userErrors: Array +} + +/** Return type for `customerActivateByUrl` mutation. */ +export type CustomerActivateByUrlPayload = { + __typename?: 'CustomerActivateByUrlPayload' + /** The customer that was activated. */ + customer?: Maybe + /** A new customer access token for the customer. */ + customerAccessToken?: Maybe + /** List of errors that occurred executing the mutation. */ + customerUserErrors: Array +} + +/** Specifies the input fields required to activate a customer. */ +export type CustomerActivateInput = { + /** The activation token required to activate the customer. */ + activationToken: Scalars['String'] + /** New password that will be set during activation. */ + password: Scalars['String'] +} + +/** Return type for `customerActivate` mutation. */ +export type CustomerActivatePayload = { + __typename?: 'CustomerActivatePayload' + /** The customer object. */ + customer?: Maybe + /** A newly created customer access token object for the customer. */ + customerAccessToken?: Maybe + /** List of errors that occurred executing the mutation. */ + customerUserErrors: Array + /** + * List of errors that occurred executing the mutation. + * @deprecated Use `customerUserErrors` instead + */ + userErrors: Array +} + +/** Return type for `customerAddressCreate` mutation. */ +export type CustomerAddressCreatePayload = { + __typename?: 'CustomerAddressCreatePayload' + /** The new customer address object. */ + customerAddress?: Maybe + /** List of errors that occurred executing the mutation. */ + customerUserErrors: Array + /** + * List of errors that occurred executing the mutation. + * @deprecated Use `customerUserErrors` instead + */ + userErrors: Array +} + +/** Return type for `customerAddressDelete` mutation. */ +export type CustomerAddressDeletePayload = { + __typename?: 'CustomerAddressDeletePayload' + /** List of errors that occurred executing the mutation. */ + customerUserErrors: Array + /** ID of the deleted customer address. */ + deletedCustomerAddressId?: Maybe + /** + * List of errors that occurred executing the mutation. + * @deprecated Use `customerUserErrors` instead + */ + userErrors: Array +} + +/** Return type for `customerAddressUpdate` mutation. */ +export type CustomerAddressUpdatePayload = { + __typename?: 'CustomerAddressUpdatePayload' + /** The customer’s updated mailing address. */ + customerAddress?: Maybe + /** List of errors that occurred executing the mutation. */ + customerUserErrors: Array + /** + * List of errors that occurred executing the mutation. + * @deprecated Use `customerUserErrors` instead + */ + userErrors: Array +} + +/** Specifies the fields required to create a new customer. */ +export type CustomerCreateInput = { + /** The customer’s first name. */ + firstName?: Maybe + /** The customer’s last name. */ + lastName?: Maybe + /** The customer’s email. */ + email: Scalars['String'] + /** + * A unique phone number for the customer. + * + * Formatted using E.164 standard. For example, _+16135551111_. + */ + phone?: Maybe + /** The login password used by the customer. */ + password: Scalars['String'] + /** Indicates whether the customer has consented to be sent marketing material via email. */ + acceptsMarketing?: Maybe +} + +/** Return type for `customerCreate` mutation. */ +export type CustomerCreatePayload = { + __typename?: 'CustomerCreatePayload' + /** The created customer object. */ + customer?: Maybe + /** List of errors that occurred executing the mutation. */ + customerUserErrors: Array + /** + * List of errors that occurred executing the mutation. + * @deprecated Use `customerUserErrors` instead + */ + userErrors: Array +} + +/** Return type for `customerDefaultAddressUpdate` mutation. */ +export type CustomerDefaultAddressUpdatePayload = { + __typename?: 'CustomerDefaultAddressUpdatePayload' + /** The updated customer object. */ + customer?: Maybe + /** List of errors that occurred executing the mutation. */ + customerUserErrors: Array + /** + * List of errors that occurred executing the mutation. + * @deprecated Use `customerUserErrors` instead + */ + userErrors: Array +} + +/** Possible error codes that could be returned by CustomerUserError. */ +export enum CustomerErrorCode { + /** Input value is blank. */ + Blank = 'BLANK', + /** Input value is invalid. */ + Invalid = 'INVALID', + /** Input value is already taken. */ + Taken = 'TAKEN', + /** Input value is too long. */ + TooLong = 'TOO_LONG', + /** Input value is too short. */ + TooShort = 'TOO_SHORT', + /** Unidentified customer. */ + UnidentifiedCustomer = 'UNIDENTIFIED_CUSTOMER', + /** Customer is disabled. */ + CustomerDisabled = 'CUSTOMER_DISABLED', + /** Input password starts or ends with whitespace. */ + PasswordStartsOrEndsWithWhitespace = 'PASSWORD_STARTS_OR_ENDS_WITH_WHITESPACE', + /** Input contains HTML tags. */ + ContainsHtmlTags = 'CONTAINS_HTML_TAGS', + /** Input contains URL. */ + ContainsUrl = 'CONTAINS_URL', + /** Invalid activation token. */ + TokenInvalid = 'TOKEN_INVALID', + /** Customer already enabled. */ + AlreadyEnabled = 'ALREADY_ENABLED', + /** Address does not exist. */ + NotFound = 'NOT_FOUND', + /** Input email contains an invalid domain name. */ + BadDomain = 'BAD_DOMAIN', + /** Multipass token is not valid. */ + InvalidMultipassRequest = 'INVALID_MULTIPASS_REQUEST', +} + +/** Return type for `customerRecover` mutation. */ +export type CustomerRecoverPayload = { + __typename?: 'CustomerRecoverPayload' + /** List of errors that occurred executing the mutation. */ + customerUserErrors: Array + /** + * List of errors that occurred executing the mutation. + * @deprecated Use `customerUserErrors` instead + */ + userErrors: Array +} + +/** Return type for `customerResetByUrl` mutation. */ +export type CustomerResetByUrlPayload = { + __typename?: 'CustomerResetByUrlPayload' + /** The customer object which was reset. */ + customer?: Maybe + /** A newly created customer access token object for the customer. */ + customerAccessToken?: Maybe + /** List of errors that occurred executing the mutation. */ + customerUserErrors: Array + /** + * List of errors that occurred executing the mutation. + * @deprecated Use `customerUserErrors` instead + */ + userErrors: Array +} + +/** Specifies the fields required to reset a customer’s password. */ +export type CustomerResetInput = { + /** The reset token required to reset the customer’s password. */ + resetToken: Scalars['String'] + /** New password that will be set as part of the reset password process. */ + password: Scalars['String'] +} + +/** Return type for `customerReset` mutation. */ +export type CustomerResetPayload = { + __typename?: 'CustomerResetPayload' + /** The customer object which was reset. */ + customer?: Maybe + /** A newly created customer access token object for the customer. */ + customerAccessToken?: Maybe + /** List of errors that occurred executing the mutation. */ + customerUserErrors: Array + /** + * List of errors that occurred executing the mutation. + * @deprecated Use `customerUserErrors` instead + */ + userErrors: Array +} + +/** Specifies the fields required to update the Customer information. */ +export type CustomerUpdateInput = { + /** The customer’s first name. */ + firstName?: Maybe + /** The customer’s last name. */ + lastName?: Maybe + /** The customer’s email. */ + email?: Maybe + /** + * A unique phone number for the customer. + * + * Formatted using E.164 standard. For example, _+16135551111_. To remove the phone number, specify `null`. + */ + phone?: Maybe + /** The login password used by the customer. */ + password?: Maybe + /** Indicates whether the customer has consented to be sent marketing material via email. */ + acceptsMarketing?: Maybe +} + +/** Return type for `customerUpdate` mutation. */ +export type CustomerUpdatePayload = { + __typename?: 'CustomerUpdatePayload' + /** The updated customer object. */ + customer?: Maybe + /** + * The newly created customer access token. If the customer's password is updated, all previous access tokens + * (including the one used to perform this mutation) become invalid, and a new token is generated. + */ + customerAccessToken?: Maybe + /** List of errors that occurred executing the mutation. */ + customerUserErrors: Array + /** + * List of errors that occurred executing the mutation. + * @deprecated Use `customerUserErrors` instead + */ + userErrors: Array +} + +/** Represents an error that happens during execution of a customer mutation. */ +export type CustomerUserError = DisplayableError & { + __typename?: 'CustomerUserError' + /** Error code to uniquely identify the error. */ + code?: Maybe + /** Path to the input field which caused the error. */ + field?: Maybe> + /** The error message. */ + message: Scalars['String'] +} + +/** Digital wallet, such as Apple Pay, which can be used for accelerated checkouts. */ +export enum DigitalWallet { + /** Apple Pay. */ + ApplePay = 'APPLE_PAY', + /** Android Pay. */ + AndroidPay = 'ANDROID_PAY', + /** Google Pay. */ + GooglePay = 'GOOGLE_PAY', + /** Shopify Pay. */ + ShopifyPay = 'SHOPIFY_PAY', +} + +/** An amount discounting the line that has been allocated by a discount. */ +export type DiscountAllocation = { + __typename?: 'DiscountAllocation' + /** Amount of discount allocated. */ + allocatedAmount: MoneyV2 + /** The discount this allocated amount originated from. */ + discountApplication: DiscountApplication +} + +/** + * Discount applications capture the intentions of a discount source at + * the time of application. + */ +export type DiscountApplication = { + /** The method by which the discount's value is allocated to its entitled items. */ + allocationMethod: DiscountApplicationAllocationMethod + /** Which lines of targetType that the discount is allocated over. */ + targetSelection: DiscountApplicationTargetSelection + /** The type of line that the discount is applicable towards. */ + targetType: DiscountApplicationTargetType + /** The value of the discount application. */ + value: PricingValue +} + +/** The method by which the discount's value is allocated onto its entitled lines. */ +export enum DiscountApplicationAllocationMethod { + /** The value is spread across all entitled lines. */ + Across = 'ACROSS', + /** The value is applied onto every entitled line. */ + Each = 'EACH', + /** The value is specifically applied onto a particular line. */ + One = 'ONE', +} + +/** An auto-generated type for paginating through multiple DiscountApplications. */ +export type DiscountApplicationConnection = { + __typename?: 'DiscountApplicationConnection' + /** A list of edges. */ + edges: Array + /** Information to aid in pagination. */ + pageInfo: PageInfo +} + +/** An auto-generated type which holds one DiscountApplication and a cursor during pagination. */ +export type DiscountApplicationEdge = { + __typename?: 'DiscountApplicationEdge' + /** A cursor for use in pagination. */ + cursor: Scalars['String'] + /** The item at the end of DiscountApplicationEdge. */ + node: DiscountApplication +} + +/** + * Which lines on the order that the discount is allocated over, of the type + * defined by the Discount Application's target_type. + */ +export enum DiscountApplicationTargetSelection { + /** The discount is allocated onto all the lines. */ + All = 'ALL', + /** The discount is allocated onto only the lines it is entitled for. */ + Entitled = 'ENTITLED', + /** The discount is allocated onto explicitly chosen lines. */ + Explicit = 'EXPLICIT', +} + +/** The type of line (i.e. line item or shipping line) on an order that the discount is applicable towards. */ +export enum DiscountApplicationTargetType { + /** The discount applies onto line items. */ + LineItem = 'LINE_ITEM', + /** The discount applies onto shipping lines. */ + ShippingLine = 'SHIPPING_LINE', +} + +/** + * Discount code applications capture the intentions of a discount code at + * the time that it is applied. + */ +export type DiscountCodeApplication = DiscountApplication & { + __typename?: 'DiscountCodeApplication' + /** The method by which the discount's value is allocated to its entitled items. */ + allocationMethod: DiscountApplicationAllocationMethod + /** Specifies whether the discount code was applied successfully. */ + applicable: Scalars['Boolean'] + /** The string identifying the discount code that was used at the time of application. */ + code: Scalars['String'] + /** Which lines of targetType that the discount is allocated over. */ + targetSelection: DiscountApplicationTargetSelection + /** The type of line that the discount is applicable towards. */ + targetType: DiscountApplicationTargetType + /** The value of the discount application. */ + value: PricingValue +} + +/** Represents an error in the input of a mutation. */ +export type DisplayableError = { + /** Path to the input field which caused the error. */ + field?: Maybe> + /** The error message. */ + message: Scalars['String'] +} + +/** Represents a web address. */ +export type Domain = { + __typename?: 'Domain' + /** The host name of the domain (eg: `example.com`). */ + host: Scalars['String'] + /** Whether SSL is enabled or not. */ + sslEnabled: Scalars['Boolean'] + /** The URL of the domain (eg: `https://example.com`). */ + url: Scalars['URL'] +} + +/** Represents a video hosted outside of Shopify. */ +export type ExternalVideo = Node & + Media & { + __typename?: 'ExternalVideo' + /** A word or phrase to share the nature or contents of a media. */ + alt?: Maybe + /** The URL. */ + embeddedUrl: Scalars['URL'] + /** Globally unique identifier. */ + id: Scalars['ID'] + /** The media content type. */ + mediaContentType: MediaContentType + /** The preview image for the media. */ + previewImage?: Maybe + } + +/** Represents a single fulfillment in an order. */ +export type Fulfillment = { + __typename?: 'Fulfillment' + /** List of the fulfillment's line items. */ + fulfillmentLineItems: FulfillmentLineItemConnection + /** The name of the tracking company. */ + trackingCompany?: Maybe + /** + * Tracking information associated with the fulfillment, + * such as the tracking number and tracking URL. + */ + trackingInfo: Array +} + +/** Represents a single fulfillment in an order. */ +export type FulfillmentFulfillmentLineItemsArgs = { + first?: Maybe + after?: Maybe + last?: Maybe + before?: Maybe + reverse?: Maybe +} + +/** Represents a single fulfillment in an order. */ +export type FulfillmentTrackingInfoArgs = { + first?: Maybe +} + +/** Represents a single line item in a fulfillment. There is at most one fulfillment line item for each order line item. */ +export type FulfillmentLineItem = { + __typename?: 'FulfillmentLineItem' + /** The associated order's line item. */ + lineItem: OrderLineItem + /** The amount fulfilled in this fulfillment. */ + quantity: Scalars['Int'] +} + +/** An auto-generated type for paginating through multiple FulfillmentLineItems. */ +export type FulfillmentLineItemConnection = { + __typename?: 'FulfillmentLineItemConnection' + /** A list of edges. */ + edges: Array + /** Information to aid in pagination. */ + pageInfo: PageInfo +} + +/** An auto-generated type which holds one FulfillmentLineItem and a cursor during pagination. */ +export type FulfillmentLineItemEdge = { + __typename?: 'FulfillmentLineItemEdge' + /** A cursor for use in pagination. */ + cursor: Scalars['String'] + /** The item at the end of FulfillmentLineItemEdge. */ + node: FulfillmentLineItem +} + +/** Tracking information associated with the fulfillment. */ +export type FulfillmentTrackingInfo = { + __typename?: 'FulfillmentTrackingInfo' + /** The tracking number of the fulfillment. */ + number?: Maybe + /** The URL to track the fulfillment. */ + url?: Maybe +} + +/** Represents information about the metafields associated to the specified resource. */ +export type HasMetafields = { + /** The metafield associated with the resource. */ + metafield?: Maybe + /** A paginated list of metafields associated with the resource. */ + metafields: MetafieldConnection +} + +/** Represents information about the metafields associated to the specified resource. */ +export type HasMetafieldsMetafieldArgs = { + namespace: Scalars['String'] + key: Scalars['String'] +} + +/** Represents information about the metafields associated to the specified resource. */ +export type HasMetafieldsMetafieldsArgs = { + namespace?: Maybe + first?: Maybe + after?: Maybe + last?: Maybe + before?: Maybe + reverse?: Maybe +} + +/** Represents an image resource. */ +export type Image = { + __typename?: 'Image' + /** A word or phrase to share the nature or contents of an image. */ + altText?: Maybe + /** The original height of the image in pixels. Returns `null` if the image is not hosted by Shopify. */ + height?: Maybe + /** A unique identifier for the image. */ + id?: Maybe + /** + * The location of the original image as a URL. + * + * If there are any existing transformations in the original source URL, they will remain and not be stripped. + */ + originalSrc: Scalars['URL'] + /** + * The location of the image as a URL. + * @deprecated Previously an image had a single `src` field. This could either return the original image + * location or a URL that contained transformations such as sizing or scale. + * + * These transformations were specified by arguments on the parent field. + * + * Now an image has two distinct URL fields: `originalSrc` and `transformedSrc`. + * + * * `originalSrc` - the original unmodified image URL + * * `transformedSrc` - the image URL with the specified transformations included + * + * To migrate to the new fields, image transformations should be moved from the parent field to `transformedSrc`. + * + * Before: + * ```graphql + * { + * shop { + * productImages(maxWidth: 200, scale: 2) { + * edges { + * node { + * src + * } + * } + * } + * } + * } + * ``` + * + * After: + * ```graphql + * { + * shop { + * productImages { + * edges { + * node { + * transformedSrc(maxWidth: 200, scale: 2) + * } + * } + * } + * } + * } + * ``` + * + */ + src: Scalars['URL'] + /** + * The location of the transformed image as a URL. + * + * All transformation arguments are considered "best-effort". If they can be applied to an image, they will be. + * Otherwise any transformations which an image type does not support will be ignored. + */ + transformedSrc: Scalars['URL'] + /** The original width of the image in pixels. Returns `null` if the image is not hosted by Shopify. */ + width?: Maybe +} + +/** Represents an image resource. */ +export type ImageTransformedSrcArgs = { + maxWidth?: Maybe + maxHeight?: Maybe + crop?: Maybe + scale?: Maybe + preferredContentType?: Maybe +} + +/** An auto-generated type for paginating through multiple Images. */ +export type ImageConnection = { + __typename?: 'ImageConnection' + /** A list of edges. */ + edges: Array + /** Information to aid in pagination. */ + pageInfo: PageInfo +} + +/** List of supported image content types. */ +export enum ImageContentType { + /** A PNG image. */ + Png = 'PNG', + /** A JPG image. */ + Jpg = 'JPG', + /** A WEBP image. */ + Webp = 'WEBP', +} + +/** An auto-generated type which holds one Image and a cursor during pagination. */ +export type ImageEdge = { + __typename?: 'ImageEdge' + /** A cursor for use in pagination. */ + cursor: Scalars['String'] + /** The item at the end of ImageEdge. */ + node: Image +} + +/** Represents a mailing address for customers and shipping. */ +export type MailingAddress = Node & { + __typename?: 'MailingAddress' + /** The first line of the address. Typically the street address or PO Box number. */ + address1?: Maybe + /** The second line of the address. Typically the number of the apartment, suite, or unit. */ + address2?: Maybe + /** The name of the city, district, village, or town. */ + city?: Maybe + /** The name of the customer's company or organization. */ + company?: Maybe + /** The name of the country. */ + country?: Maybe + /** + * The two-letter code for the country of the address. + * + * For example, US. + * @deprecated Use `countryCodeV2` instead + */ + countryCode?: Maybe + /** + * The two-letter code for the country of the address. + * + * For example, US. + */ + countryCodeV2?: Maybe + /** The first name of the customer. */ + firstName?: Maybe + /** A formatted version of the address, customized by the provided arguments. */ + formatted: Array + /** A comma-separated list of the values for city, province, and country. */ + formattedArea?: Maybe + /** Globally unique identifier. */ + id: Scalars['ID'] + /** The last name of the customer. */ + lastName?: Maybe + /** The latitude coordinate of the customer address. */ + latitude?: Maybe + /** The longitude coordinate of the customer address. */ + longitude?: Maybe + /** The full name of the customer, based on firstName and lastName. */ + name?: Maybe + /** + * A unique phone number for the customer. + * + * Formatted using E.164 standard. For example, _+16135551111_. + */ + phone?: Maybe + /** The region of the address, such as the province, state, or district. */ + province?: Maybe + /** + * The two-letter code for the region. + * + * For example, ON. + */ + provinceCode?: Maybe + /** The zip or postal code of the address. */ + zip?: Maybe +} + +/** Represents a mailing address for customers and shipping. */ +export type MailingAddressFormattedArgs = { + withName?: Maybe + withCompany?: Maybe +} + +/** An auto-generated type for paginating through multiple MailingAddresses. */ +export type MailingAddressConnection = { + __typename?: 'MailingAddressConnection' + /** A list of edges. */ + edges: Array + /** Information to aid in pagination. */ + pageInfo: PageInfo +} + +/** An auto-generated type which holds one MailingAddress and a cursor during pagination. */ +export type MailingAddressEdge = { + __typename?: 'MailingAddressEdge' + /** A cursor for use in pagination. */ + cursor: Scalars['String'] + /** The item at the end of MailingAddressEdge. */ + node: MailingAddress +} + +/** Specifies the fields accepted to create or update a mailing address. */ +export type MailingAddressInput = { + /** The first line of the address. Typically the street address or PO Box number. */ + address1?: Maybe + /** The second line of the address. Typically the number of the apartment, suite, or unit. */ + address2?: Maybe + /** The name of the city, district, village, or town. */ + city?: Maybe + /** The name of the customer's company or organization. */ + company?: Maybe + /** The name of the country. */ + country?: Maybe + /** The first name of the customer. */ + firstName?: Maybe + /** The last name of the customer. */ + lastName?: Maybe + /** + * A unique phone number for the customer. + * + * Formatted using E.164 standard. For example, _+16135551111_. + */ + phone?: Maybe + /** The region of the address, such as the province, state, or district. */ + province?: Maybe + /** The zip or postal code of the address. */ + zip?: Maybe +} + +/** Manual discount applications capture the intentions of a discount that was manually created. */ +export type ManualDiscountApplication = DiscountApplication & { + __typename?: 'ManualDiscountApplication' + /** The method by which the discount's value is allocated to its entitled items. */ + allocationMethod: DiscountApplicationAllocationMethod + /** The description of the application. */ + description?: Maybe + /** Which lines of targetType that the discount is allocated over. */ + targetSelection: DiscountApplicationTargetSelection + /** The type of line that the discount is applicable towards. */ + targetType: DiscountApplicationTargetType + /** The title of the application. */ + title: Scalars['String'] + /** The value of the discount application. */ + value: PricingValue +} + +/** Represents a media interface. */ +export type Media = { + /** A word or phrase to share the nature or contents of a media. */ + alt?: Maybe + /** The media content type. */ + mediaContentType: MediaContentType + /** The preview image for the media. */ + previewImage?: Maybe +} + +/** An auto-generated type for paginating through multiple Media. */ +export type MediaConnection = { + __typename?: 'MediaConnection' + /** A list of edges. */ + edges: Array + /** Information to aid in pagination. */ + pageInfo: PageInfo +} + +/** The possible content types for a media object. */ +export enum MediaContentType { + /** An externally hosted video. */ + ExternalVideo = 'EXTERNAL_VIDEO', + /** A Shopify hosted image. */ + Image = 'IMAGE', + /** A 3d model. */ + Model_3D = 'MODEL_3D', + /** A Shopify hosted video. */ + Video = 'VIDEO', +} + +/** An auto-generated type which holds one Media and a cursor during pagination. */ +export type MediaEdge = { + __typename?: 'MediaEdge' + /** A cursor for use in pagination. */ + cursor: Scalars['String'] + /** The item at the end of MediaEdge. */ + node: Media +} + +/** Represents a Shopify hosted image. */ +export type MediaImage = Node & + Media & { + __typename?: 'MediaImage' + /** A word or phrase to share the nature or contents of a media. */ + alt?: Maybe + /** Globally unique identifier. */ + id: Scalars['ID'] + /** The image for the media. */ + image?: Maybe + /** The media content type. */ + mediaContentType: MediaContentType + /** The preview image for the media. */ + previewImage?: Maybe + } + +/** + * Metafields represent custom metadata attached to a resource. Metafields can be sorted into namespaces and are + * comprised of keys, values, and value types. + */ +export type Metafield = Node & { + __typename?: 'Metafield' + /** The date and time when the storefront metafield was created. */ + createdAt: Scalars['DateTime'] + /** The description of a metafield. */ + description?: Maybe + /** Globally unique identifier. */ + id: Scalars['ID'] + /** The key name for a metafield. */ + key: Scalars['String'] + /** The namespace for a metafield. */ + namespace: Scalars['String'] + /** The parent object that the metafield belongs to. */ + parentResource: MetafieldParentResource + /** The date and time when the storefront metafield was updated. */ + updatedAt: Scalars['DateTime'] + /** The value of a metafield. */ + value: Scalars['String'] + /** Represents the metafield value type. */ + valueType: MetafieldValueType +} + +/** An auto-generated type for paginating through multiple Metafields. */ +export type MetafieldConnection = { + __typename?: 'MetafieldConnection' + /** A list of edges. */ + edges: Array + /** Information to aid in pagination. */ + pageInfo: PageInfo +} + +/** An auto-generated type which holds one Metafield and a cursor during pagination. */ +export type MetafieldEdge = { + __typename?: 'MetafieldEdge' + /** A cursor for use in pagination. */ + cursor: Scalars['String'] + /** The item at the end of MetafieldEdge. */ + node: Metafield +} + +/** A resource that the metafield belongs to. */ +export type MetafieldParentResource = Product | ProductVariant + +/** Metafield value types. */ +export enum MetafieldValueType { + /** A string metafield. */ + String = 'STRING', + /** An integer metafield. */ + Integer = 'INTEGER', + /** A json string metafield. */ + JsonString = 'JSON_STRING', +} + +/** Represents a Shopify hosted 3D model. */ +export type Model3d = Node & + Media & { + __typename?: 'Model3d' + /** A word or phrase to share the nature or contents of a media. */ + alt?: Maybe + /** Globally unique identifier. */ + id: Scalars['ID'] + /** The media content type. */ + mediaContentType: MediaContentType + /** The preview image for the media. */ + previewImage?: Maybe + /** The sources for a 3d model. */ + sources: Array + } + +/** Represents a source for a Shopify hosted 3d model. */ +export type Model3dSource = { + __typename?: 'Model3dSource' + /** The filesize of the 3d model. */ + filesize: Scalars['Int'] + /** The format of the 3d model. */ + format: Scalars['String'] + /** The MIME type of the 3d model. */ + mimeType: Scalars['String'] + /** The URL of the 3d model. */ + url: Scalars['String'] +} + +/** Specifies the fields for a monetary value with currency. */ +export type MoneyInput = { + /** Decimal money amount. */ + amount: Scalars['Decimal'] + /** Currency of the money. */ + currencyCode: CurrencyCode +} + +/** + * A monetary value with currency. + * + * To format currencies, combine this type's amount and currencyCode fields with your client's locale. + * + * For example, in JavaScript you could use Intl.NumberFormat: + * + * ```js + * new Intl.NumberFormat(locale, { + * style: 'currency', + * currency: currencyCode + * }).format(amount); + * ``` + * + * Other formatting libraries include: + * + * * iOS - [NumberFormatter](https://developer.apple.com/documentation/foundation/numberformatter) + * * Android - [NumberFormat](https://developer.android.com/reference/java/text/NumberFormat.html) + * * PHP - [NumberFormatter](http://php.net/manual/en/class.numberformatter.php) + * + * For a more general solution, the [Unicode CLDR number formatting database] is available with many implementations + * (such as [TwitterCldr](https://github.com/twitter/twitter-cldr-rb)). + */ +export type MoneyV2 = { + __typename?: 'MoneyV2' + /** Decimal money amount. */ + amount: Scalars['Decimal'] + /** Currency of the money. */ + currencyCode: CurrencyCode +} + +/** An auto-generated type for paginating through multiple MoneyV2s. */ +export type MoneyV2Connection = { + __typename?: 'MoneyV2Connection' + /** A list of edges. */ + edges: Array + /** Information to aid in pagination. */ + pageInfo: PageInfo +} + +/** An auto-generated type which holds one MoneyV2 and a cursor during pagination. */ +export type MoneyV2Edge = { + __typename?: 'MoneyV2Edge' + /** A cursor for use in pagination. */ + cursor: Scalars['String'] + /** The item at the end of MoneyV2Edge. */ + node: MoneyV2 +} + +/** The schema’s entry-point for mutations. This acts as the public, top-level API from which all mutation queries must start. */ +export type Mutation = { + __typename?: 'Mutation' + /** + * Updates the attributes of a checkout. + * @deprecated Use `checkoutAttributesUpdateV2` instead + */ + checkoutAttributesUpdate?: Maybe + /** Updates the attributes of a checkout. */ + checkoutAttributesUpdateV2?: Maybe + /** Completes a checkout without providing payment information. You can use this mutation for free items or items whose purchase price is covered by a gift card. */ + checkoutCompleteFree?: Maybe + /** + * Completes a checkout using a credit card token from Shopify's Vault. + * @deprecated Use `checkoutCompleteWithCreditCardV2` instead + */ + checkoutCompleteWithCreditCard?: Maybe + /** Completes a checkout using a credit card token from Shopify's card vault. Before you can complete checkouts using CheckoutCompleteWithCreditCardV2, you need to [_request payment processing_](https://help.shopify.com/api/guides/sales-channel-sdk/getting-started#request-payment-processing). */ + checkoutCompleteWithCreditCardV2?: Maybe + /** + * Completes a checkout with a tokenized payment. + * @deprecated Use `checkoutCompleteWithTokenizedPaymentV2` instead + */ + checkoutCompleteWithTokenizedPayment?: Maybe + /** + * Completes a checkout with a tokenized payment. + * @deprecated Use `checkoutCompleteWithTokenizedPaymentV3` instead + */ + checkoutCompleteWithTokenizedPaymentV2?: Maybe + /** Completes a checkout with a tokenized payment. */ + checkoutCompleteWithTokenizedPaymentV3?: Maybe + /** Creates a new checkout. */ + checkoutCreate?: Maybe + /** + * Associates a customer to the checkout. + * @deprecated Use `checkoutCustomerAssociateV2` instead + */ + checkoutCustomerAssociate?: Maybe + /** Associates a customer to the checkout. */ + checkoutCustomerAssociateV2?: Maybe + /** + * Disassociates the current checkout customer from the checkout. + * @deprecated Use `checkoutCustomerDisassociateV2` instead + */ + checkoutCustomerDisassociate?: Maybe + /** Disassociates the current checkout customer from the checkout. */ + checkoutCustomerDisassociateV2?: Maybe + /** + * Applies a discount to an existing checkout using a discount code. + * @deprecated Use `checkoutDiscountCodeApplyV2` instead + */ + checkoutDiscountCodeApply?: Maybe + /** Applies a discount to an existing checkout using a discount code. */ + checkoutDiscountCodeApplyV2?: Maybe + /** Removes the applied discount from an existing checkout. */ + checkoutDiscountCodeRemove?: Maybe + /** + * Updates the email on an existing checkout. + * @deprecated Use `checkoutEmailUpdateV2` instead + */ + checkoutEmailUpdate?: Maybe + /** Updates the email on an existing checkout. */ + checkoutEmailUpdateV2?: Maybe + /** + * Applies a gift card to an existing checkout using a gift card code. This will replace all currently applied gift cards. + * @deprecated Use `checkoutGiftCardsAppend` instead + */ + checkoutGiftCardApply?: Maybe + /** + * Removes an applied gift card from the checkout. + * @deprecated Use `checkoutGiftCardRemoveV2` instead + */ + checkoutGiftCardRemove?: Maybe + /** Removes an applied gift card from the checkout. */ + checkoutGiftCardRemoveV2?: Maybe + /** Appends gift cards to an existing checkout. */ + checkoutGiftCardsAppend?: Maybe + /** Adds a list of line items to a checkout. */ + checkoutLineItemsAdd?: Maybe + /** Removes line items from an existing checkout. */ + checkoutLineItemsRemove?: Maybe + /** Sets a list of line items to a checkout. */ + checkoutLineItemsReplace?: Maybe + /** Updates line items on a checkout. */ + checkoutLineItemsUpdate?: Maybe + /** + * Updates the shipping address of an existing checkout. + * @deprecated Use `checkoutShippingAddressUpdateV2` instead + */ + checkoutShippingAddressUpdate?: Maybe + /** Updates the shipping address of an existing checkout. */ + checkoutShippingAddressUpdateV2?: Maybe + /** Updates the shipping lines on an existing checkout. */ + checkoutShippingLineUpdate?: Maybe + /** + * Creates a customer access token. + * The customer access token is required to modify the customer object in any way. + */ + customerAccessTokenCreate?: Maybe + /** + * Creates a customer access token using a multipass token instead of email and password. + * A customer record is created if customer does not exist. If a customer record already + * exists but the record is disabled, then it's enabled. + */ + customerAccessTokenCreateWithMultipass?: Maybe + /** Permanently destroys a customer access token. */ + customerAccessTokenDelete?: Maybe + /** + * Renews a customer access token. + * + * Access token renewal must happen *before* a token expires. + * If a token has already expired, a new one should be created instead via `customerAccessTokenCreate`. + */ + customerAccessTokenRenew?: Maybe + /** Activates a customer. */ + customerActivate?: Maybe + /** Activates a customer with the activation url received from `customerCreate`. */ + customerActivateByUrl?: Maybe + /** Creates a new address for a customer. */ + customerAddressCreate?: Maybe + /** Permanently deletes the address of an existing customer. */ + customerAddressDelete?: Maybe + /** Updates the address of an existing customer. */ + customerAddressUpdate?: Maybe + /** Creates a new customer. */ + customerCreate?: Maybe + /** Updates the default address of an existing customer. */ + customerDefaultAddressUpdate?: Maybe + /** Sends a reset password email to the customer, as the first step in the reset password process. */ + customerRecover?: Maybe + /** Resets a customer’s password with a token received from `CustomerRecover`. */ + customerReset?: Maybe + /** Resets a customer’s password with the reset password url received from `CustomerRecover`. */ + customerResetByUrl?: Maybe + /** Updates an existing customer. */ + customerUpdate?: Maybe +} + +/** The schema’s entry-point for mutations. This acts as the public, top-level API from which all mutation queries must start. */ +export type MutationCheckoutAttributesUpdateArgs = { + checkoutId: Scalars['ID'] + input: CheckoutAttributesUpdateInput +} + +/** The schema’s entry-point for mutations. This acts as the public, top-level API from which all mutation queries must start. */ +export type MutationCheckoutAttributesUpdateV2Args = { + checkoutId: Scalars['ID'] + input: CheckoutAttributesUpdateV2Input +} + +/** The schema’s entry-point for mutations. This acts as the public, top-level API from which all mutation queries must start. */ +export type MutationCheckoutCompleteFreeArgs = { + checkoutId: Scalars['ID'] +} + +/** The schema’s entry-point for mutations. This acts as the public, top-level API from which all mutation queries must start. */ +export type MutationCheckoutCompleteWithCreditCardArgs = { + checkoutId: Scalars['ID'] + payment: CreditCardPaymentInput +} + +/** The schema’s entry-point for mutations. This acts as the public, top-level API from which all mutation queries must start. */ +export type MutationCheckoutCompleteWithCreditCardV2Args = { + checkoutId: Scalars['ID'] + payment: CreditCardPaymentInputV2 +} + +/** The schema’s entry-point for mutations. This acts as the public, top-level API from which all mutation queries must start. */ +export type MutationCheckoutCompleteWithTokenizedPaymentArgs = { + checkoutId: Scalars['ID'] + payment: TokenizedPaymentInput +} + +/** The schema’s entry-point for mutations. This acts as the public, top-level API from which all mutation queries must start. */ +export type MutationCheckoutCompleteWithTokenizedPaymentV2Args = { + checkoutId: Scalars['ID'] + payment: TokenizedPaymentInputV2 +} + +/** The schema’s entry-point for mutations. This acts as the public, top-level API from which all mutation queries must start. */ +export type MutationCheckoutCompleteWithTokenizedPaymentV3Args = { + checkoutId: Scalars['ID'] + payment: TokenizedPaymentInputV3 +} + +/** The schema’s entry-point for mutations. This acts as the public, top-level API from which all mutation queries must start. */ +export type MutationCheckoutCreateArgs = { + input: CheckoutCreateInput +} + +/** The schema’s entry-point for mutations. This acts as the public, top-level API from which all mutation queries must start. */ +export type MutationCheckoutCustomerAssociateArgs = { + checkoutId: Scalars['ID'] + customerAccessToken: Scalars['String'] +} + +/** The schema’s entry-point for mutations. This acts as the public, top-level API from which all mutation queries must start. */ +export type MutationCheckoutCustomerAssociateV2Args = { + checkoutId: Scalars['ID'] + customerAccessToken: Scalars['String'] +} + +/** The schema’s entry-point for mutations. This acts as the public, top-level API from which all mutation queries must start. */ +export type MutationCheckoutCustomerDisassociateArgs = { + checkoutId: Scalars['ID'] +} + +/** The schema’s entry-point for mutations. This acts as the public, top-level API from which all mutation queries must start. */ +export type MutationCheckoutCustomerDisassociateV2Args = { + checkoutId: Scalars['ID'] +} + +/** The schema’s entry-point for mutations. This acts as the public, top-level API from which all mutation queries must start. */ +export type MutationCheckoutDiscountCodeApplyArgs = { + discountCode: Scalars['String'] + checkoutId: Scalars['ID'] +} + +/** The schema’s entry-point for mutations. This acts as the public, top-level API from which all mutation queries must start. */ +export type MutationCheckoutDiscountCodeApplyV2Args = { + discountCode: Scalars['String'] + checkoutId: Scalars['ID'] +} + +/** The schema’s entry-point for mutations. This acts as the public, top-level API from which all mutation queries must start. */ +export type MutationCheckoutDiscountCodeRemoveArgs = { + checkoutId: Scalars['ID'] +} + +/** The schema’s entry-point for mutations. This acts as the public, top-level API from which all mutation queries must start. */ +export type MutationCheckoutEmailUpdateArgs = { + checkoutId: Scalars['ID'] + email: Scalars['String'] +} + +/** The schema’s entry-point for mutations. This acts as the public, top-level API from which all mutation queries must start. */ +export type MutationCheckoutEmailUpdateV2Args = { + checkoutId: Scalars['ID'] + email: Scalars['String'] +} + +/** The schema’s entry-point for mutations. This acts as the public, top-level API from which all mutation queries must start. */ +export type MutationCheckoutGiftCardApplyArgs = { + giftCardCode: Scalars['String'] + checkoutId: Scalars['ID'] +} + +/** The schema’s entry-point for mutations. This acts as the public, top-level API from which all mutation queries must start. */ +export type MutationCheckoutGiftCardRemoveArgs = { + appliedGiftCardId: Scalars['ID'] + checkoutId: Scalars['ID'] +} + +/** The schema’s entry-point for mutations. This acts as the public, top-level API from which all mutation queries must start. */ +export type MutationCheckoutGiftCardRemoveV2Args = { + appliedGiftCardId: Scalars['ID'] + checkoutId: Scalars['ID'] +} + +/** The schema’s entry-point for mutations. This acts as the public, top-level API from which all mutation queries must start. */ +export type MutationCheckoutGiftCardsAppendArgs = { + giftCardCodes: Array + checkoutId: Scalars['ID'] +} + +/** The schema’s entry-point for mutations. This acts as the public, top-level API from which all mutation queries must start. */ +export type MutationCheckoutLineItemsAddArgs = { + lineItems: Array + checkoutId: Scalars['ID'] +} + +/** The schema’s entry-point for mutations. This acts as the public, top-level API from which all mutation queries must start. */ +export type MutationCheckoutLineItemsRemoveArgs = { + checkoutId: Scalars['ID'] + lineItemIds: Array +} + +/** The schema’s entry-point for mutations. This acts as the public, top-level API from which all mutation queries must start. */ +export type MutationCheckoutLineItemsReplaceArgs = { + lineItems: Array + checkoutId: Scalars['ID'] +} + +/** The schema’s entry-point for mutations. This acts as the public, top-level API from which all mutation queries must start. */ +export type MutationCheckoutLineItemsUpdateArgs = { + checkoutId: Scalars['ID'] + lineItems: Array +} + +/** The schema’s entry-point for mutations. This acts as the public, top-level API from which all mutation queries must start. */ +export type MutationCheckoutShippingAddressUpdateArgs = { + shippingAddress: MailingAddressInput + checkoutId: Scalars['ID'] +} + +/** The schema’s entry-point for mutations. This acts as the public, top-level API from which all mutation queries must start. */ +export type MutationCheckoutShippingAddressUpdateV2Args = { + shippingAddress: MailingAddressInput + checkoutId: Scalars['ID'] +} + +/** The schema’s entry-point for mutations. This acts as the public, top-level API from which all mutation queries must start. */ +export type MutationCheckoutShippingLineUpdateArgs = { + checkoutId: Scalars['ID'] + shippingRateHandle: Scalars['String'] +} + +/** The schema’s entry-point for mutations. This acts as the public, top-level API from which all mutation queries must start. */ +export type MutationCustomerAccessTokenCreateArgs = { + input: CustomerAccessTokenCreateInput +} + +/** The schema’s entry-point for mutations. This acts as the public, top-level API from which all mutation queries must start. */ +export type MutationCustomerAccessTokenCreateWithMultipassArgs = { + multipassToken: Scalars['String'] +} + +/** The schema’s entry-point for mutations. This acts as the public, top-level API from which all mutation queries must start. */ +export type MutationCustomerAccessTokenDeleteArgs = { + customerAccessToken: Scalars['String'] +} + +/** The schema’s entry-point for mutations. This acts as the public, top-level API from which all mutation queries must start. */ +export type MutationCustomerAccessTokenRenewArgs = { + customerAccessToken: Scalars['String'] +} + +/** The schema’s entry-point for mutations. This acts as the public, top-level API from which all mutation queries must start. */ +export type MutationCustomerActivateArgs = { + id: Scalars['ID'] + input: CustomerActivateInput +} + +/** The schema’s entry-point for mutations. This acts as the public, top-level API from which all mutation queries must start. */ +export type MutationCustomerActivateByUrlArgs = { + activationUrl: Scalars['URL'] + password: Scalars['String'] +} + +/** The schema’s entry-point for mutations. This acts as the public, top-level API from which all mutation queries must start. */ +export type MutationCustomerAddressCreateArgs = { + customerAccessToken: Scalars['String'] + address: MailingAddressInput +} + +/** The schema’s entry-point for mutations. This acts as the public, top-level API from which all mutation queries must start. */ +export type MutationCustomerAddressDeleteArgs = { + id: Scalars['ID'] + customerAccessToken: Scalars['String'] +} + +/** The schema’s entry-point for mutations. This acts as the public, top-level API from which all mutation queries must start. */ +export type MutationCustomerAddressUpdateArgs = { + customerAccessToken: Scalars['String'] + id: Scalars['ID'] + address: MailingAddressInput +} + +/** The schema’s entry-point for mutations. This acts as the public, top-level API from which all mutation queries must start. */ +export type MutationCustomerCreateArgs = { + input: CustomerCreateInput +} + +/** The schema’s entry-point for mutations. This acts as the public, top-level API from which all mutation queries must start. */ +export type MutationCustomerDefaultAddressUpdateArgs = { + customerAccessToken: Scalars['String'] + addressId: Scalars['ID'] +} + +/** The schema’s entry-point for mutations. This acts as the public, top-level API from which all mutation queries must start. */ +export type MutationCustomerRecoverArgs = { + email: Scalars['String'] +} + +/** The schema’s entry-point for mutations. This acts as the public, top-level API from which all mutation queries must start. */ +export type MutationCustomerResetArgs = { + id: Scalars['ID'] + input: CustomerResetInput +} + +/** The schema’s entry-point for mutations. This acts as the public, top-level API from which all mutation queries must start. */ +export type MutationCustomerResetByUrlArgs = { + resetUrl: Scalars['URL'] + password: Scalars['String'] +} + +/** The schema’s entry-point for mutations. This acts as the public, top-level API from which all mutation queries must start. */ +export type MutationCustomerUpdateArgs = { + customerAccessToken: Scalars['String'] + customer: CustomerUpdateInput +} + +/** An object with an ID to support global identification. */ +export type Node = { + /** Globally unique identifier. */ + id: Scalars['ID'] +} + +/** An order is a customer’s completed request to purchase one or more products from a shop. An order is created when a customer completes the checkout process, during which time they provides an email address, billing address and payment information. */ +export type Order = Node & { + __typename?: 'Order' + /** The reason for the order's cancellation. Returns `null` if the order wasn't canceled. */ + cancelReason?: Maybe + /** The date and time when the order was canceled. Returns null if the order wasn't canceled. */ + canceledAt?: Maybe + /** The code of the currency used for the payment. */ + currencyCode: CurrencyCode + /** The subtotal of line items and their discounts, excluding line items that have been removed. Does not contain order-level discounts, duties, shipping costs, or shipping discounts. Taxes are not included unless the order is a taxes-included order. */ + currentSubtotalPrice: MoneyV2 + /** The total amount of the order, including duties, taxes and discounts, minus amounts for line items that have been removed. */ + currentTotalPrice: MoneyV2 + /** The total of all taxes applied to the order, excluding taxes for returned line items. */ + currentTotalTax: MoneyV2 + /** The locale code in which this specific order happened. */ + customerLocale?: Maybe + /** The unique URL that the customer can use to access the order. */ + customerUrl?: Maybe + /** Discounts that have been applied on the order. */ + discountApplications: DiscountApplicationConnection + /** Whether the order has had any edits applied or not. */ + edited: Scalars['Boolean'] + /** The customer's email address. */ + email?: Maybe + /** The financial status of the order. */ + financialStatus?: Maybe + /** The fulfillment status for the order. */ + fulfillmentStatus: OrderFulfillmentStatus + /** Globally unique identifier. */ + id: Scalars['ID'] + /** List of the order’s line items. */ + lineItems: OrderLineItemConnection + /** + * Unique identifier for the order that appears on the order. + * For example, _#1000_ or _Store1001. + */ + name: Scalars['String'] + /** A unique numeric identifier for the order for use by shop owner and customer. */ + orderNumber: Scalars['Int'] + /** The total price of the order before any applied edits. */ + originalTotalPrice: MoneyV2 + /** The customer's phone number for receiving SMS notifications. */ + phone?: Maybe + /** + * The date and time when the order was imported. + * This value can be set to dates in the past when importing from other systems. + * If no value is provided, it will be auto-generated based on current date and time. + */ + processedAt: Scalars['DateTime'] + /** The address to where the order will be shipped. */ + shippingAddress?: Maybe + /** The discounts that have been allocated onto the shipping line by discount applications. */ + shippingDiscountAllocations: Array + /** The unique URL for the order's status page. */ + statusUrl: Scalars['URL'] + /** + * Price of the order before shipping and taxes. + * @deprecated Use `subtotalPriceV2` instead + */ + subtotalPrice?: Maybe + /** Price of the order before duties, shipping and taxes. */ + subtotalPriceV2?: Maybe + /** List of the order’s successful fulfillments. */ + successfulFulfillments?: Maybe> + /** + * The sum of all the prices of all the items in the order, taxes and discounts included (must be positive). + * @deprecated Use `totalPriceV2` instead + */ + totalPrice: Scalars['Money'] + /** The sum of all the prices of all the items in the order, duties, taxes and discounts included (must be positive). */ + totalPriceV2: MoneyV2 + /** + * The total amount that has been refunded. + * @deprecated Use `totalRefundedV2` instead + */ + totalRefunded: Scalars['Money'] + /** The total amount that has been refunded. */ + totalRefundedV2: MoneyV2 + /** + * The total cost of shipping. + * @deprecated Use `totalShippingPriceV2` instead + */ + totalShippingPrice: Scalars['Money'] + /** The total cost of shipping. */ + totalShippingPriceV2: MoneyV2 + /** + * The total cost of taxes. + * @deprecated Use `totalTaxV2` instead + */ + totalTax?: Maybe + /** The total cost of taxes. */ + totalTaxV2?: Maybe +} + +/** An order is a customer’s completed request to purchase one or more products from a shop. An order is created when a customer completes the checkout process, during which time they provides an email address, billing address and payment information. */ +export type OrderDiscountApplicationsArgs = { + first?: Maybe + after?: Maybe + last?: Maybe + before?: Maybe + reverse?: Maybe +} + +/** An order is a customer’s completed request to purchase one or more products from a shop. An order is created when a customer completes the checkout process, during which time they provides an email address, billing address and payment information. */ +export type OrderLineItemsArgs = { + first?: Maybe + after?: Maybe + last?: Maybe + before?: Maybe + reverse?: Maybe +} + +/** An order is a customer’s completed request to purchase one or more products from a shop. An order is created when a customer completes the checkout process, during which time they provides an email address, billing address and payment information. */ +export type OrderSuccessfulFulfillmentsArgs = { + first?: Maybe +} + +/** Represents the reason for the order's cancellation. */ +export enum OrderCancelReason { + /** The customer wanted to cancel the order. */ + Customer = 'CUSTOMER', + /** The order was fraudulent. */ + Fraud = 'FRAUD', + /** There was insufficient inventory. */ + Inventory = 'INVENTORY', + /** Payment was declined. */ + Declined = 'DECLINED', + /** The order was canceled for an unlisted reason. */ + Other = 'OTHER', +} + +/** An auto-generated type for paginating through multiple Orders. */ +export type OrderConnection = { + __typename?: 'OrderConnection' + /** A list of edges. */ + edges: Array + /** Information to aid in pagination. */ + pageInfo: PageInfo +} + +/** An auto-generated type which holds one Order and a cursor during pagination. */ +export type OrderEdge = { + __typename?: 'OrderEdge' + /** A cursor for use in pagination. */ + cursor: Scalars['String'] + /** The item at the end of OrderEdge. */ + node: Order +} + +/** Represents the order's current financial status. */ +export enum OrderFinancialStatus { + /** Displayed as **Pending**. */ + Pending = 'PENDING', + /** Displayed as **Authorized**. */ + Authorized = 'AUTHORIZED', + /** Displayed as **Partially paid**. */ + PartiallyPaid = 'PARTIALLY_PAID', + /** Displayed as **Partially refunded**. */ + PartiallyRefunded = 'PARTIALLY_REFUNDED', + /** Displayed as **Voided**. */ + Voided = 'VOIDED', + /** Displayed as **Paid**. */ + Paid = 'PAID', + /** Displayed as **Refunded**. */ + Refunded = 'REFUNDED', +} + +/** Represents the order's current fulfillment status. */ +export enum OrderFulfillmentStatus { + /** Displayed as **Unfulfilled**. */ + Unfulfilled = 'UNFULFILLED', + /** Displayed as **Partially fulfilled**. */ + PartiallyFulfilled = 'PARTIALLY_FULFILLED', + /** Displayed as **Fulfilled**. */ + Fulfilled = 'FULFILLED', + /** Displayed as **Restocked**. */ + Restocked = 'RESTOCKED', + /** Displayed as **Pending fulfillment**. */ + PendingFulfillment = 'PENDING_FULFILLMENT', + /** Displayed as **Open**. */ + Open = 'OPEN', + /** Displayed as **In progress**. */ + InProgress = 'IN_PROGRESS', + /** Displayed as **Scheduled**. */ + Scheduled = 'SCHEDULED', +} + +/** Represents a single line in an order. There is one line item for each distinct product variant. */ +export type OrderLineItem = { + __typename?: 'OrderLineItem' + /** The number of entries associated to the line item minus the items that have been removed. */ + currentQuantity: Scalars['Int'] + /** List of custom attributes associated to the line item. */ + customAttributes: Array + /** The discounts that have been allocated onto the order line item by discount applications. */ + discountAllocations: Array + /** The total price of the line item, including discounts, and displayed in the presentment currency. */ + discountedTotalPrice: MoneyV2 + /** The total price of the line item, not including any discounts. The total price is calculated using the original unit price multiplied by the quantity, and it is displayed in the presentment currency. */ + originalTotalPrice: MoneyV2 + /** The number of products variants associated to the line item. */ + quantity: Scalars['Int'] + /** The title of the product combined with title of the variant. */ + title: Scalars['String'] + /** The product variant object associated to the line item. */ + variant?: Maybe +} + +/** An auto-generated type for paginating through multiple OrderLineItems. */ +export type OrderLineItemConnection = { + __typename?: 'OrderLineItemConnection' + /** A list of edges. */ + edges: Array + /** Information to aid in pagination. */ + pageInfo: PageInfo +} + +/** An auto-generated type which holds one OrderLineItem and a cursor during pagination. */ +export type OrderLineItemEdge = { + __typename?: 'OrderLineItemEdge' + /** A cursor for use in pagination. */ + cursor: Scalars['String'] + /** The item at the end of OrderLineItemEdge. */ + node: OrderLineItem +} + +/** The set of valid sort keys for the Order query. */ +export enum OrderSortKeys { + /** Sort by the `processed_at` value. */ + ProcessedAt = 'PROCESSED_AT', + /** Sort by the `total_price` value. */ + TotalPrice = 'TOTAL_PRICE', + /** Sort by the `id` value. */ + Id = 'ID', + /** + * During a search (i.e. when the `query` parameter has been specified on the connection) this sorts the + * results by relevance to the search term(s). When no search query is specified, this sort key is not + * deterministic and should not be used. + */ + Relevance = 'RELEVANCE', +} + +/** Shopify merchants can create pages to hold static HTML content. Each Page object represents a custom page on the online store. */ +export type Page = Node & { + __typename?: 'Page' + /** The description of the page, complete with HTML formatting. */ + body: Scalars['HTML'] + /** Summary of the page body. */ + bodySummary: Scalars['String'] + /** The timestamp of the page creation. */ + createdAt: Scalars['DateTime'] + /** A human-friendly unique string for the page automatically generated from its title. */ + handle: Scalars['String'] + /** Globally unique identifier. */ + id: Scalars['ID'] + /** The page's SEO information. */ + seo?: Maybe + /** The title of the page. */ + title: Scalars['String'] + /** The timestamp of the latest page update. */ + updatedAt: Scalars['DateTime'] + /** The url pointing to the page accessible from the web. */ + url: Scalars['URL'] +} + +/** An auto-generated type for paginating through multiple Pages. */ +export type PageConnection = { + __typename?: 'PageConnection' + /** A list of edges. */ + edges: Array + /** Information to aid in pagination. */ + pageInfo: PageInfo +} + +/** An auto-generated type which holds one Page and a cursor during pagination. */ +export type PageEdge = { + __typename?: 'PageEdge' + /** A cursor for use in pagination. */ + cursor: Scalars['String'] + /** The item at the end of PageEdge. */ + node: Page +} + +/** Information about pagination in a connection. */ +export type PageInfo = { + __typename?: 'PageInfo' + /** Indicates if there are more pages to fetch. */ + hasNextPage: Scalars['Boolean'] + /** Indicates if there are any pages prior to the current page. */ + hasPreviousPage: Scalars['Boolean'] +} + +/** The set of valid sort keys for the Page query. */ +export enum PageSortKeys { + /** Sort by the `title` value. */ + Title = 'TITLE', + /** Sort by the `updated_at` value. */ + UpdatedAt = 'UPDATED_AT', + /** Sort by the `id` value. */ + Id = 'ID', + /** + * During a search (i.e. when the `query` parameter has been specified on the connection) this sorts the + * results by relevance to the search term(s). When no search query is specified, this sort key is not + * deterministic and should not be used. + */ + Relevance = 'RELEVANCE', +} + +/** A payment applied to a checkout. */ +export type Payment = Node & { + __typename?: 'Payment' + /** + * The amount of the payment. + * @deprecated Use `amountV2` instead + */ + amount: Scalars['Money'] + /** The amount of the payment. */ + amountV2: MoneyV2 + /** The billing address for the payment. */ + billingAddress?: Maybe + /** The checkout to which the payment belongs. */ + checkout: Checkout + /** The credit card used for the payment in the case of direct payments. */ + creditCard?: Maybe + /** A message describing a processing error during asynchronous processing. */ + errorMessage?: Maybe + /** Globally unique identifier. */ + id: Scalars['ID'] + /** A client-side generated token to identify a payment and perform idempotent operations. */ + idempotencyKey?: Maybe + /** The URL where the customer needs to be redirected so they can complete the 3D Secure payment flow. */ + nextActionUrl?: Maybe + /** Whether or not the payment is still processing asynchronously. */ + ready: Scalars['Boolean'] + /** A flag to indicate if the payment is to be done in test mode for gateways that support it. */ + test: Scalars['Boolean'] + /** The actual transaction recorded by Shopify after having processed the payment with the gateway. */ + transaction?: Maybe +} + +/** Settings related to payments. */ +export type PaymentSettings = { + __typename?: 'PaymentSettings' + /** List of the card brands which the shop accepts. */ + acceptedCardBrands: Array + /** The url pointing to the endpoint to vault credit cards. */ + cardVaultUrl: Scalars['URL'] + /** The country where the shop is located. */ + countryCode: CountryCode + /** The three-letter code for the shop's primary currency. */ + currencyCode: CurrencyCode + /** A list of enabled currencies (ISO 4217 format) that the shop accepts. Merchants can enable currencies from their Shopify Payments settings in the Shopify admin. */ + enabledPresentmentCurrencies: Array + /** The shop’s Shopify Payments account id. */ + shopifyPaymentsAccountId?: Maybe + /** List of the digital wallets which the shop supports. */ + supportedDigitalWallets: Array +} + +/** The valid values for the types of payment token. */ +export enum PaymentTokenType { + /** Apple Pay token type. */ + ApplePay = 'APPLE_PAY', + /** Vault payment token type. */ + Vault = 'VAULT', + /** Shopify Pay token type. */ + ShopifyPay = 'SHOPIFY_PAY', + /** Google Pay token type. */ + GooglePay = 'GOOGLE_PAY', +} + +/** The value of the percentage pricing object. */ +export type PricingPercentageValue = { + __typename?: 'PricingPercentageValue' + /** The percentage value of the object. */ + percentage: Scalars['Float'] +} + +/** The price value (fixed or percentage) for a discount application. */ +export type PricingValue = MoneyV2 | PricingPercentageValue + +/** + * A product represents an individual item for sale in a Shopify store. Products are often physical, but they don't have to be. + * For example, a digital download (such as a movie, music or ebook file) also qualifies as a product, as do services (such as equipment rental, work for hire, customization of another product or an extended warranty). + */ +export type Product = Node & + HasMetafields & { + __typename?: 'Product' + /** Indicates if at least one product variant is available for sale. */ + availableForSale: Scalars['Boolean'] + /** List of collections a product belongs to. */ + collections: CollectionConnection + /** The compare at price of the product across all variants. */ + compareAtPriceRange: ProductPriceRange + /** The date and time when the product was created. */ + createdAt: Scalars['DateTime'] + /** Stripped description of the product, single line with HTML tags removed. */ + description: Scalars['String'] + /** The description of the product, complete with HTML formatting. */ + descriptionHtml: Scalars['HTML'] + /** + * A human-friendly unique string for the Product automatically generated from its title. + * They are used by the Liquid templating language to refer to objects. + */ + handle: Scalars['String'] + /** Globally unique identifier. */ + id: Scalars['ID'] + /** List of images associated with the product. */ + images: ImageConnection + /** The media associated with the product. */ + media: MediaConnection + /** The metafield associated with the resource. */ + metafield?: Maybe + /** A paginated list of metafields associated with the resource. */ + metafields: MetafieldConnection + /** + * The online store URL for the product. + * A value of `null` indicates that the product is not published to the Online Store sales channel. + */ + onlineStoreUrl?: Maybe + /** List of product options. */ + options: Array + /** List of price ranges in the presentment currencies for this shop. */ + presentmentPriceRanges: ProductPriceRangeConnection + /** The price range. */ + priceRange: ProductPriceRange + /** A categorization that a product can be tagged with, commonly used for filtering and searching. */ + productType: Scalars['String'] + /** The date and time when the product was published to the channel. */ + publishedAt: Scalars['DateTime'] + /** The product's SEO information. */ + seo: Seo + /** + * A comma separated list of tags that have been added to the product. + * Additional access scope required for private apps: unauthenticated_read_product_tags. + */ + tags: Array + /** The product’s title. */ + title: Scalars['String'] + /** The total quantity of inventory in stock for this Product. */ + totalInventory?: Maybe + /** + * The date and time when the product was last modified. + * A product's `updatedAt` value can change for different reasons. For example, if an order + * is placed for a product that has inventory tracking set up, then the inventory adjustment + * is counted as an update. + */ + updatedAt: Scalars['DateTime'] + /** + * Find a product’s variant based on its selected options. + * This is useful for converting a user’s selection of product options into a single matching variant. + * If there is not a variant for the selected options, `null` will be returned. + */ + variantBySelectedOptions?: Maybe + /** List of the product’s variants. */ + variants: ProductVariantConnection + /** The product’s vendor name. */ + vendor: Scalars['String'] + } + +/** + * A product represents an individual item for sale in a Shopify store. Products are often physical, but they don't have to be. + * For example, a digital download (such as a movie, music or ebook file) also qualifies as a product, as do services (such as equipment rental, work for hire, customization of another product or an extended warranty). + */ +export type ProductCollectionsArgs = { + first?: Maybe + after?: Maybe + last?: Maybe + before?: Maybe + reverse?: Maybe +} + +/** + * A product represents an individual item for sale in a Shopify store. Products are often physical, but they don't have to be. + * For example, a digital download (such as a movie, music or ebook file) also qualifies as a product, as do services (such as equipment rental, work for hire, customization of another product or an extended warranty). + */ +export type ProductDescriptionArgs = { + truncateAt?: Maybe +} + +/** + * A product represents an individual item for sale in a Shopify store. Products are often physical, but they don't have to be. + * For example, a digital download (such as a movie, music or ebook file) also qualifies as a product, as do services (such as equipment rental, work for hire, customization of another product or an extended warranty). + */ +export type ProductImagesArgs = { + first?: Maybe + after?: Maybe + last?: Maybe + before?: Maybe + reverse?: Maybe + sortKey?: Maybe + maxWidth?: Maybe + maxHeight?: Maybe + crop?: Maybe + scale?: Maybe +} + +/** + * A product represents an individual item for sale in a Shopify store. Products are often physical, but they don't have to be. + * For example, a digital download (such as a movie, music or ebook file) also qualifies as a product, as do services (such as equipment rental, work for hire, customization of another product or an extended warranty). + */ +export type ProductMediaArgs = { + first?: Maybe + after?: Maybe + last?: Maybe + before?: Maybe + reverse?: Maybe + sortKey?: Maybe +} + +/** + * A product represents an individual item for sale in a Shopify store. Products are often physical, but they don't have to be. + * For example, a digital download (such as a movie, music or ebook file) also qualifies as a product, as do services (such as equipment rental, work for hire, customization of another product or an extended warranty). + */ +export type ProductMetafieldArgs = { + namespace: Scalars['String'] + key: Scalars['String'] +} + +/** + * A product represents an individual item for sale in a Shopify store. Products are often physical, but they don't have to be. + * For example, a digital download (such as a movie, music or ebook file) also qualifies as a product, as do services (such as equipment rental, work for hire, customization of another product or an extended warranty). + */ +export type ProductMetafieldsArgs = { + namespace?: Maybe + first?: Maybe + after?: Maybe + last?: Maybe + before?: Maybe + reverse?: Maybe +} + +/** + * A product represents an individual item for sale in a Shopify store. Products are often physical, but they don't have to be. + * For example, a digital download (such as a movie, music or ebook file) also qualifies as a product, as do services (such as equipment rental, work for hire, customization of another product or an extended warranty). + */ +export type ProductOptionsArgs = { + first?: Maybe +} + +/** + * A product represents an individual item for sale in a Shopify store. Products are often physical, but they don't have to be. + * For example, a digital download (such as a movie, music or ebook file) also qualifies as a product, as do services (such as equipment rental, work for hire, customization of another product or an extended warranty). + */ +export type ProductPresentmentPriceRangesArgs = { + presentmentCurrencies?: Maybe> + first?: Maybe + after?: Maybe + last?: Maybe + before?: Maybe + reverse?: Maybe +} + +/** + * A product represents an individual item for sale in a Shopify store. Products are often physical, but they don't have to be. + * For example, a digital download (such as a movie, music or ebook file) also qualifies as a product, as do services (such as equipment rental, work for hire, customization of another product or an extended warranty). + */ +export type ProductVariantBySelectedOptionsArgs = { + selectedOptions: Array +} + +/** + * A product represents an individual item for sale in a Shopify store. Products are often physical, but they don't have to be. + * For example, a digital download (such as a movie, music or ebook file) also qualifies as a product, as do services (such as equipment rental, work for hire, customization of another product or an extended warranty). + */ +export type ProductVariantsArgs = { + first?: Maybe + after?: Maybe + last?: Maybe + before?: Maybe + reverse?: Maybe + sortKey?: Maybe +} + +/** The set of valid sort keys for the ProductCollection query. */ +export enum ProductCollectionSortKeys { + /** Sort by the `title` value. */ + Title = 'TITLE', + /** Sort by the `price` value. */ + Price = 'PRICE', + /** Sort by the `best-selling` value. */ + BestSelling = 'BEST_SELLING', + /** Sort by the `created` value. */ + Created = 'CREATED', + /** Sort by the `id` value. */ + Id = 'ID', + /** Sort by the `manual` value. */ + Manual = 'MANUAL', + /** Sort by the `collection-default` value. */ + CollectionDefault = 'COLLECTION_DEFAULT', + /** + * During a search (i.e. when the `query` parameter has been specified on the connection) this sorts the + * results by relevance to the search term(s). When no search query is specified, this sort key is not + * deterministic and should not be used. + */ + Relevance = 'RELEVANCE', +} + +/** An auto-generated type for paginating through multiple Products. */ +export type ProductConnection = { + __typename?: 'ProductConnection' + /** A list of edges. */ + edges: Array + /** Information to aid in pagination. */ + pageInfo: PageInfo +} + +/** An auto-generated type which holds one Product and a cursor during pagination. */ +export type ProductEdge = { + __typename?: 'ProductEdge' + /** A cursor for use in pagination. */ + cursor: Scalars['String'] + /** The item at the end of ProductEdge. */ + node: Product +} + +/** The set of valid sort keys for the ProductImage query. */ +export enum ProductImageSortKeys { + /** Sort by the `created_at` value. */ + CreatedAt = 'CREATED_AT', + /** Sort by the `position` value. */ + Position = 'POSITION', + /** Sort by the `id` value. */ + Id = 'ID', + /** + * During a search (i.e. when the `query` parameter has been specified on the connection) this sorts the + * results by relevance to the search term(s). When no search query is specified, this sort key is not + * deterministic and should not be used. + */ + Relevance = 'RELEVANCE', +} + +/** The set of valid sort keys for the ProductMedia query. */ +export enum ProductMediaSortKeys { + /** Sort by the `position` value. */ + Position = 'POSITION', + /** Sort by the `id` value. */ + Id = 'ID', + /** + * During a search (i.e. when the `query` parameter has been specified on the connection) this sorts the + * results by relevance to the search term(s). When no search query is specified, this sort key is not + * deterministic and should not be used. + */ + Relevance = 'RELEVANCE', +} + +/** + * Product property names like "Size", "Color", and "Material" that the customers can select. + * Variants are selected based on permutations of these options. + * 255 characters limit each. + */ +export type ProductOption = Node & { + __typename?: 'ProductOption' + /** Globally unique identifier. */ + id: Scalars['ID'] + /** The product option’s name. */ + name: Scalars['String'] + /** The corresponding value to the product option name. */ + values: Array +} + +/** The price range of the product. */ +export type ProductPriceRange = { + __typename?: 'ProductPriceRange' + /** The highest variant's price. */ + maxVariantPrice: MoneyV2 + /** The lowest variant's price. */ + minVariantPrice: MoneyV2 +} + +/** An auto-generated type for paginating through multiple ProductPriceRanges. */ +export type ProductPriceRangeConnection = { + __typename?: 'ProductPriceRangeConnection' + /** A list of edges. */ + edges: Array + /** Information to aid in pagination. */ + pageInfo: PageInfo +} + +/** An auto-generated type which holds one ProductPriceRange and a cursor during pagination. */ +export type ProductPriceRangeEdge = { + __typename?: 'ProductPriceRangeEdge' + /** A cursor for use in pagination. */ + cursor: Scalars['String'] + /** The item at the end of ProductPriceRangeEdge. */ + node: ProductPriceRange +} + +/** The set of valid sort keys for the Product query. */ +export enum ProductSortKeys { + /** Sort by the `title` value. */ + Title = 'TITLE', + /** Sort by the `product_type` value. */ + ProductType = 'PRODUCT_TYPE', + /** Sort by the `vendor` value. */ + Vendor = 'VENDOR', + /** Sort by the `updated_at` value. */ + UpdatedAt = 'UPDATED_AT', + /** Sort by the `created_at` value. */ + CreatedAt = 'CREATED_AT', + /** Sort by the `best_selling` value. */ + BestSelling = 'BEST_SELLING', + /** Sort by the `price` value. */ + Price = 'PRICE', + /** Sort by the `id` value. */ + Id = 'ID', + /** + * During a search (i.e. when the `query` parameter has been specified on the connection) this sorts the + * results by relevance to the search term(s). When no search query is specified, this sort key is not + * deterministic and should not be used. + */ + Relevance = 'RELEVANCE', +} + +/** A product variant represents a different version of a product, such as differing sizes or differing colors. */ +export type ProductVariant = Node & + HasMetafields & { + __typename?: 'ProductVariant' + /** + * Indicates if the product variant is in stock. + * @deprecated Use `availableForSale` instead + */ + available?: Maybe + /** Indicates if the product variant is available for sale. */ + availableForSale: Scalars['Boolean'] + /** + * The compare at price of the variant. This can be used to mark a variant as on sale, when `compareAtPrice` is higher than `price`. + * @deprecated Use `compareAtPriceV2` instead + */ + compareAtPrice?: Maybe + /** The compare at price of the variant. This can be used to mark a variant as on sale, when `compareAtPriceV2` is higher than `priceV2`. */ + compareAtPriceV2?: Maybe + /** Whether a product is out of stock but still available for purchase (used for backorders). */ + currentlyNotInStock: Scalars['Boolean'] + /** Globally unique identifier. */ + id: Scalars['ID'] + /** Image associated with the product variant. This field falls back to the product image if no image is available. */ + image?: Maybe + /** The metafield associated with the resource. */ + metafield?: Maybe + /** A paginated list of metafields associated with the resource. */ + metafields: MetafieldConnection + /** List of prices and compare-at prices in the presentment currencies for this shop. */ + presentmentPrices: ProductVariantPricePairConnection + /** List of unit prices in the presentment currencies for this shop. */ + presentmentUnitPrices: MoneyV2Connection + /** + * The product variant’s price. + * @deprecated Use `priceV2` instead + */ + price: Scalars['Money'] + /** The product variant’s price. */ + priceV2: MoneyV2 + /** The product object that the product variant belongs to. */ + product: Product + /** The total sellable quantity of the variant for online sales channels. */ + quantityAvailable?: Maybe + /** Whether a customer needs to provide a shipping address when placing an order for the product variant. */ + requiresShipping: Scalars['Boolean'] + /** List of product options applied to the variant. */ + selectedOptions: Array + /** The SKU (stock keeping unit) associated with the variant. */ + sku?: Maybe + /** The product variant’s title. */ + title: Scalars['String'] + /** The unit price value for the variant based on the variant's measurement. */ + unitPrice?: Maybe + /** The unit price measurement for the variant. */ + unitPriceMeasurement?: Maybe + /** The weight of the product variant in the unit system specified with `weight_unit`. */ + weight?: Maybe + /** Unit of measurement for weight. */ + weightUnit: WeightUnit + } + +/** A product variant represents a different version of a product, such as differing sizes or differing colors. */ +export type ProductVariantImageArgs = { + maxWidth?: Maybe + maxHeight?: Maybe + crop?: Maybe + scale?: Maybe +} + +/** A product variant represents a different version of a product, such as differing sizes or differing colors. */ +export type ProductVariantMetafieldArgs = { + namespace: Scalars['String'] + key: Scalars['String'] +} + +/** A product variant represents a different version of a product, such as differing sizes or differing colors. */ +export type ProductVariantMetafieldsArgs = { + namespace?: Maybe + first?: Maybe + after?: Maybe + last?: Maybe + before?: Maybe + reverse?: Maybe +} + +/** A product variant represents a different version of a product, such as differing sizes or differing colors. */ +export type ProductVariantPresentmentPricesArgs = { + presentmentCurrencies?: Maybe> + first?: Maybe + after?: Maybe + last?: Maybe + before?: Maybe + reverse?: Maybe +} + +/** A product variant represents a different version of a product, such as differing sizes or differing colors. */ +export type ProductVariantPresentmentUnitPricesArgs = { + presentmentCurrencies?: Maybe> + first?: Maybe + after?: Maybe + last?: Maybe + before?: Maybe + reverse?: Maybe +} + +/** An auto-generated type for paginating through multiple ProductVariants. */ +export type ProductVariantConnection = { + __typename?: 'ProductVariantConnection' + /** A list of edges. */ + edges: Array + /** Information to aid in pagination. */ + pageInfo: PageInfo +} + +/** An auto-generated type which holds one ProductVariant and a cursor during pagination. */ +export type ProductVariantEdge = { + __typename?: 'ProductVariantEdge' + /** A cursor for use in pagination. */ + cursor: Scalars['String'] + /** The item at the end of ProductVariantEdge. */ + node: ProductVariant +} + +/** The compare-at price and price of a variant sharing a currency. */ +export type ProductVariantPricePair = { + __typename?: 'ProductVariantPricePair' + /** The compare-at price of the variant with associated currency. */ + compareAtPrice?: Maybe + /** The price of the variant with associated currency. */ + price: MoneyV2 +} + +/** An auto-generated type for paginating through multiple ProductVariantPricePairs. */ +export type ProductVariantPricePairConnection = { + __typename?: 'ProductVariantPricePairConnection' + /** A list of edges. */ + edges: Array + /** Information to aid in pagination. */ + pageInfo: PageInfo +} + +/** An auto-generated type which holds one ProductVariantPricePair and a cursor during pagination. */ +export type ProductVariantPricePairEdge = { + __typename?: 'ProductVariantPricePairEdge' + /** A cursor for use in pagination. */ + cursor: Scalars['String'] + /** The item at the end of ProductVariantPricePairEdge. */ + node: ProductVariantPricePair +} + +/** The set of valid sort keys for the ProductVariant query. */ +export enum ProductVariantSortKeys { + /** Sort by the `title` value. */ + Title = 'TITLE', + /** Sort by the `sku` value. */ + Sku = 'SKU', + /** Sort by the `position` value. */ + Position = 'POSITION', + /** Sort by the `id` value. */ + Id = 'ID', + /** + * During a search (i.e. when the `query` parameter has been specified on the connection) this sorts the + * results by relevance to the search term(s). When no search query is specified, this sort key is not + * deterministic and should not be used. + */ + Relevance = 'RELEVANCE', +} + +/** The schema’s entry-point for queries. This acts as the public, top-level API from which all queries must start. */ +export type QueryRoot = { + __typename?: 'QueryRoot' + /** List of the shop's articles. */ + articles: ArticleConnection + /** Find a blog by its handle. */ + blogByHandle?: Maybe + /** List of the shop's blogs. */ + blogs: BlogConnection + /** Find a collection by its handle. */ + collectionByHandle?: Maybe + /** List of the shop’s collections. */ + collections: CollectionConnection + /** Find a customer by its access token. */ + customer?: Maybe + node?: Maybe + nodes: Array> + /** Find a page by its handle. */ + pageByHandle?: Maybe + /** List of the shop's pages. */ + pages: PageConnection + /** Find a product by its handle. */ + productByHandle?: Maybe + /** + * Find recommended products related to a given `product_id`. + * To learn more about how recommendations are generated, see + * [*Showing product recommendations on product pages*](https://help.shopify.com/themes/development/recommended-products). + */ + productRecommendations?: Maybe> + /** + * Tags added to products. + * Additional access scope required: unauthenticated_read_product_tags. + */ + productTags: StringConnection + /** List of product types for the shop's products that are published to your app. */ + productTypes: StringConnection + /** List of the shop’s products. */ + products: ProductConnection + /** The list of public Storefront API versions, including supported, release candidate and unstable versions. */ + publicApiVersions: Array + /** The shop associated with the storefront access token. */ + shop: Shop +} + +/** The schema’s entry-point for queries. This acts as the public, top-level API from which all queries must start. */ +export type QueryRootArticlesArgs = { + first?: Maybe + after?: Maybe + last?: Maybe + before?: Maybe + reverse?: Maybe + sortKey?: Maybe + query?: Maybe +} + +/** The schema’s entry-point for queries. This acts as the public, top-level API from which all queries must start. */ +export type QueryRootBlogByHandleArgs = { + handle: Scalars['String'] +} + +/** The schema’s entry-point for queries. This acts as the public, top-level API from which all queries must start. */ +export type QueryRootBlogsArgs = { + first?: Maybe + after?: Maybe + last?: Maybe + before?: Maybe + reverse?: Maybe + sortKey?: Maybe + query?: Maybe +} + +/** The schema’s entry-point for queries. This acts as the public, top-level API from which all queries must start. */ +export type QueryRootCollectionByHandleArgs = { + handle: Scalars['String'] +} + +/** The schema’s entry-point for queries. This acts as the public, top-level API from which all queries must start. */ +export type QueryRootCollectionsArgs = { + first?: Maybe + after?: Maybe + last?: Maybe + before?: Maybe + reverse?: Maybe + sortKey?: Maybe + query?: Maybe +} + +/** The schema’s entry-point for queries. This acts as the public, top-level API from which all queries must start. */ +export type QueryRootCustomerArgs = { + customerAccessToken: Scalars['String'] +} + +/** The schema’s entry-point for queries. This acts as the public, top-level API from which all queries must start. */ +export type QueryRootNodeArgs = { + id: Scalars['ID'] +} + +/** The schema’s entry-point for queries. This acts as the public, top-level API from which all queries must start. */ +export type QueryRootNodesArgs = { + ids: Array +} + +/** The schema’s entry-point for queries. This acts as the public, top-level API from which all queries must start. */ +export type QueryRootPageByHandleArgs = { + handle: Scalars['String'] +} + +/** The schema’s entry-point for queries. This acts as the public, top-level API from which all queries must start. */ +export type QueryRootPagesArgs = { + first?: Maybe + after?: Maybe + last?: Maybe + before?: Maybe + reverse?: Maybe + sortKey?: Maybe + query?: Maybe +} + +/** The schema’s entry-point for queries. This acts as the public, top-level API from which all queries must start. */ +export type QueryRootProductByHandleArgs = { + handle: Scalars['String'] +} + +/** The schema’s entry-point for queries. This acts as the public, top-level API from which all queries must start. */ +export type QueryRootProductRecommendationsArgs = { + productId: Scalars['ID'] +} + +/** The schema’s entry-point for queries. This acts as the public, top-level API from which all queries must start. */ +export type QueryRootProductTagsArgs = { + first: Scalars['Int'] +} + +/** The schema’s entry-point for queries. This acts as the public, top-level API from which all queries must start. */ +export type QueryRootProductTypesArgs = { + first: Scalars['Int'] +} + +/** The schema’s entry-point for queries. This acts as the public, top-level API from which all queries must start. */ +export type QueryRootProductsArgs = { + first?: Maybe + after?: Maybe + last?: Maybe + before?: Maybe + reverse?: Maybe + sortKey?: Maybe + query?: Maybe +} + +/** SEO information. */ +export type Seo = { + __typename?: 'SEO' + /** The meta description. */ + description?: Maybe + /** The SEO title. */ + title?: Maybe +} + +/** + * Script discount applications capture the intentions of a discount that + * was created by a Shopify Script. + */ +export type ScriptDiscountApplication = DiscountApplication & { + __typename?: 'ScriptDiscountApplication' + /** The method by which the discount's value is allocated to its entitled items. */ + allocationMethod: DiscountApplicationAllocationMethod + /** + * The description of the application as defined by the Script. + * @deprecated Use `title` instead + */ + description: Scalars['String'] + /** Which lines of targetType that the discount is allocated over. */ + targetSelection: DiscountApplicationTargetSelection + /** The type of line that the discount is applicable towards. */ + targetType: DiscountApplicationTargetType + /** The title of the application as defined by the Script. */ + title: Scalars['String'] + /** The value of the discount application. */ + value: PricingValue +} + +/** + * Properties used by customers to select a product variant. + * Products can have multiple options, like different sizes or colors. + */ +export type SelectedOption = { + __typename?: 'SelectedOption' + /** The product option’s name. */ + name: Scalars['String'] + /** The product option’s value. */ + value: Scalars['String'] +} + +/** Specifies the input fields required for a selected option. */ +export type SelectedOptionInput = { + /** The product option’s name. */ + name: Scalars['String'] + /** The product option’s value. */ + value: Scalars['String'] +} + +/** A shipping rate to be applied to a checkout. */ +export type ShippingRate = { + __typename?: 'ShippingRate' + /** Human-readable unique identifier for this shipping rate. */ + handle: Scalars['String'] + /** + * Price of this shipping rate. + * @deprecated Use `priceV2` instead + */ + price: Scalars['Money'] + /** Price of this shipping rate. */ + priceV2: MoneyV2 + /** Title of this shipping rate. */ + title: Scalars['String'] +} + +/** Shop represents a collection of the general settings and information about the shop. */ +export type Shop = { + __typename?: 'Shop' + /** + * List of the shop' articles. + * @deprecated Use `QueryRoot.articles` instead. + */ + articles: ArticleConnection + /** + * List of the shop' blogs. + * @deprecated Use `QueryRoot.blogs` instead. + */ + blogs: BlogConnection + /** + * Find a collection by its handle. + * @deprecated Use `QueryRoot.collectionByHandle` instead. + */ + collectionByHandle?: Maybe + /** + * List of the shop’s collections. + * @deprecated Use `QueryRoot.collections` instead. + */ + collections: CollectionConnection + /** + * The three-letter code for the currency that the shop accepts. + * @deprecated Use `paymentSettings` instead + */ + currencyCode: CurrencyCode + /** A description of the shop. */ + description?: Maybe + /** A string representing the way currency is formatted when the currency isn’t specified. */ + moneyFormat: Scalars['String'] + /** The shop’s name. */ + name: Scalars['String'] + /** Settings related to payments. */ + paymentSettings: PaymentSettings + /** The shop’s primary domain. */ + primaryDomain: Domain + /** The shop’s privacy policy. */ + privacyPolicy?: Maybe + /** + * Find a product by its handle. + * @deprecated Use `QueryRoot.productByHandle` instead. + */ + productByHandle?: Maybe + /** + * A list of tags that have been added to products. + * Additional access scope required: unauthenticated_read_product_tags. + * @deprecated Use `QueryRoot.productTags` instead. + */ + productTags: StringConnection + /** + * List of the shop’s product types. + * @deprecated Use `QueryRoot.productTypes` instead. + */ + productTypes: StringConnection + /** + * List of the shop’s products. + * @deprecated Use `QueryRoot.products` instead. + */ + products: ProductConnection + /** The shop’s refund policy. */ + refundPolicy?: Maybe + /** The shop’s shipping policy. */ + shippingPolicy?: Maybe + /** Countries that the shop ships to. */ + shipsToCountries: Array + /** + * The shop’s Shopify Payments account id. + * @deprecated Use `paymentSettings` instead + */ + shopifyPaymentsAccountId?: Maybe + /** The shop’s terms of service. */ + termsOfService?: Maybe +} + +/** Shop represents a collection of the general settings and information about the shop. */ +export type ShopArticlesArgs = { + first?: Maybe + after?: Maybe + last?: Maybe + before?: Maybe + reverse?: Maybe + sortKey?: Maybe + query?: Maybe +} + +/** Shop represents a collection of the general settings and information about the shop. */ +export type ShopBlogsArgs = { + first?: Maybe + after?: Maybe + last?: Maybe + before?: Maybe + reverse?: Maybe + sortKey?: Maybe + query?: Maybe +} + +/** Shop represents a collection of the general settings and information about the shop. */ +export type ShopCollectionByHandleArgs = { + handle: Scalars['String'] +} + +/** Shop represents a collection of the general settings and information about the shop. */ +export type ShopCollectionsArgs = { + first?: Maybe + after?: Maybe + last?: Maybe + before?: Maybe + reverse?: Maybe + sortKey?: Maybe + query?: Maybe +} + +/** Shop represents a collection of the general settings and information about the shop. */ +export type ShopProductByHandleArgs = { + handle: Scalars['String'] +} + +/** Shop represents a collection of the general settings and information about the shop. */ +export type ShopProductTagsArgs = { + first: Scalars['Int'] +} + +/** Shop represents a collection of the general settings and information about the shop. */ +export type ShopProductTypesArgs = { + first: Scalars['Int'] +} + +/** Shop represents a collection of the general settings and information about the shop. */ +export type ShopProductsArgs = { + first?: Maybe + after?: Maybe + last?: Maybe + before?: Maybe + reverse?: Maybe + sortKey?: Maybe + query?: Maybe +} + +/** Policy that a merchant has configured for their store, such as their refund or privacy policy. */ +export type ShopPolicy = Node & { + __typename?: 'ShopPolicy' + /** Policy text, maximum size of 64kb. */ + body: Scalars['String'] + /** Policy’s handle. */ + handle: Scalars['String'] + /** Globally unique identifier. */ + id: Scalars['ID'] + /** Policy’s title. */ + title: Scalars['String'] + /** Public URL to the policy. */ + url: Scalars['URL'] +} + +/** An auto-generated type for paginating through multiple Strings. */ +export type StringConnection = { + __typename?: 'StringConnection' + /** A list of edges. */ + edges: Array + /** Information to aid in pagination. */ + pageInfo: PageInfo +} + +/** An auto-generated type which holds one String and a cursor during pagination. */ +export type StringEdge = { + __typename?: 'StringEdge' + /** A cursor for use in pagination. */ + cursor: Scalars['String'] + /** The item at the end of StringEdge. */ + node: Scalars['String'] +} + +/** + * Specifies the fields required to complete a checkout with + * a tokenized payment. + */ +export type TokenizedPaymentInput = { + /** The amount of the payment. */ + amount: Scalars['Money'] + /** A unique client generated key used to avoid duplicate charges. When a duplicate payment is found, the original is returned instead of creating a new one. */ + idempotencyKey: Scalars['String'] + /** The billing address for the payment. */ + billingAddress: MailingAddressInput + /** The type of payment token. */ + type: Scalars['String'] + /** A simple string or JSON containing the required payment data for the tokenized payment. */ + paymentData: Scalars['String'] + /** Executes the payment in test mode if possible. Defaults to `false`. */ + test?: Maybe + /** Public Hash Key used for AndroidPay payments only. */ + identifier?: Maybe +} + +/** + * Specifies the fields required to complete a checkout with + * a tokenized payment. + */ +export type TokenizedPaymentInputV2 = { + /** The amount and currency of the payment. */ + paymentAmount: MoneyInput + /** A unique client generated key used to avoid duplicate charges. When a duplicate payment is found, the original is returned instead of creating a new one. */ + idempotencyKey: Scalars['String'] + /** The billing address for the payment. */ + billingAddress: MailingAddressInput + /** A simple string or JSON containing the required payment data for the tokenized payment. */ + paymentData: Scalars['String'] + /** Whether to execute the payment in test mode, if possible. Test mode is not supported in production stores. Defaults to `false`. */ + test?: Maybe + /** Public Hash Key used for AndroidPay payments only. */ + identifier?: Maybe + /** The type of payment token. */ + type: Scalars['String'] +} + +/** + * Specifies the fields required to complete a checkout with + * a tokenized payment. + */ +export type TokenizedPaymentInputV3 = { + /** The amount and currency of the payment. */ + paymentAmount: MoneyInput + /** A unique client generated key used to avoid duplicate charges. When a duplicate payment is found, the original is returned instead of creating a new one. */ + idempotencyKey: Scalars['String'] + /** The billing address for the payment. */ + billingAddress: MailingAddressInput + /** A simple string or JSON containing the required payment data for the tokenized payment. */ + paymentData: Scalars['String'] + /** Whether to execute the payment in test mode, if possible. Test mode is not supported in production stores. Defaults to `false`. */ + test?: Maybe + /** Public Hash Key used for AndroidPay payments only. */ + identifier?: Maybe + /** The type of payment token. */ + type: PaymentTokenType +} + +/** An object representing exchange of money for a product or service. */ +export type Transaction = { + __typename?: 'Transaction' + /** + * The amount of money that the transaction was for. + * @deprecated Use `amountV2` instead + */ + amount: Scalars['Money'] + /** The amount of money that the transaction was for. */ + amountV2: MoneyV2 + /** The kind of the transaction. */ + kind: TransactionKind + /** + * The status of the transaction. + * @deprecated Use `statusV2` instead + */ + status: TransactionStatus + /** The status of the transaction. */ + statusV2?: Maybe + /** Whether the transaction was done in test mode or not. */ + test: Scalars['Boolean'] +} + +export enum TransactionKind { + Sale = 'SALE', + Capture = 'CAPTURE', + Authorization = 'AUTHORIZATION', + EmvAuthorization = 'EMV_AUTHORIZATION', + Change = 'CHANGE', +} + +export enum TransactionStatus { + Pending = 'PENDING', + Success = 'SUCCESS', + Failure = 'FAILURE', + Error = 'ERROR', +} + +/** The measurement used to calculate a unit price for a product variant (e.g. $9.99 / 100ml). */ +export type UnitPriceMeasurement = { + __typename?: 'UnitPriceMeasurement' + /** The type of unit of measurement for the unit price measurement. */ + measuredType?: Maybe + /** The quantity unit for the unit price measurement. */ + quantityUnit?: Maybe + /** The quantity value for the unit price measurement. */ + quantityValue: Scalars['Float'] + /** The reference unit for the unit price measurement. */ + referenceUnit?: Maybe + /** The reference value for the unit price measurement. */ + referenceValue: Scalars['Int'] +} + +/** The accepted types of unit of measurement. */ +export enum UnitPriceMeasurementMeasuredType { + /** Unit of measurements representing volumes. */ + Volume = 'VOLUME', + /** Unit of measurements representing weights. */ + Weight = 'WEIGHT', + /** Unit of measurements representing lengths. */ + Length = 'LENGTH', + /** Unit of measurements representing areas. */ + Area = 'AREA', +} + +/** The valid units of measurement for a unit price measurement. */ +export enum UnitPriceMeasurementMeasuredUnit { + /** 1000 milliliters equals 1 liter. */ + Ml = 'ML', + /** 100 centiliters equals 1 liter. */ + Cl = 'CL', + /** Metric system unit of volume. */ + L = 'L', + /** 1 cubic meter equals 1000 liters. */ + M3 = 'M3', + /** 1000 milligrams equals 1 gram. */ + Mg = 'MG', + /** Metric system unit of weight. */ + G = 'G', + /** 1 kilogram equals 1000 grams. */ + Kg = 'KG', + /** 1000 millimeters equals 1 meter. */ + Mm = 'MM', + /** 100 centimeters equals 1 meter. */ + Cm = 'CM', + /** Metric system unit of length. */ + M = 'M', + /** Metric system unit of area. */ + M2 = 'M2', +} + +/** Represents an error in the input of a mutation. */ +export type UserError = DisplayableError & { + __typename?: 'UserError' + /** Path to the input field which caused the error. */ + field?: Maybe> + /** The error message. */ + message: Scalars['String'] +} + +/** Represents a Shopify hosted video. */ +export type Video = Node & + Media & { + __typename?: 'Video' + /** A word or phrase to share the nature or contents of a media. */ + alt?: Maybe + /** Globally unique identifier. */ + id: Scalars['ID'] + /** The media content type. */ + mediaContentType: MediaContentType + /** The preview image for the media. */ + previewImage?: Maybe + /** The sources for a video. */ + sources: Array + } + +/** Represents a source for a Shopify hosted video. */ +export type VideoSource = { + __typename?: 'VideoSource' + /** The format of the video source. */ + format: Scalars['String'] + /** The height of the video. */ + height: Scalars['Int'] + /** The video MIME type. */ + mimeType: Scalars['String'] + /** The URL of the video. */ + url: Scalars['String'] + /** The width of the video. */ + width: Scalars['Int'] +} + +/** Units of measurement for weight. */ +export enum WeightUnit { + /** 1 kilogram equals 1000 grams. */ + Kilograms = 'KILOGRAMS', + /** Metric system unit of mass. */ + Grams = 'GRAMS', + /** 1 pound equals 16 ounces. */ + Pounds = 'POUNDS', + /** Imperial system unit of mass. */ + Ounces = 'OUNCES', +} + +export type Unnamed_1_QueryVariables = Exact<{ + first: Scalars['Int'] +}> + +export type Unnamed_1_Query = { __typename?: 'QueryRoot' } & { + pages: { __typename?: 'PageConnection' } & { + edges: Array< + { __typename?: 'PageEdge' } & { + node: { __typename?: 'Page' } & Pick< + Page, + 'id' | 'title' | 'handle' | 'body' | 'bodySummary' | 'url' + > + } + > + } +} diff --git a/framework/shopify/schema.graphql b/framework/shopify/schema.graphql new file mode 100644 index 000000000..822e6007e --- /dev/null +++ b/framework/shopify/schema.graphql @@ -0,0 +1,9631 @@ +schema { + query: QueryRoot + mutation: Mutation +} + +""" +Marks an element of a GraphQL schema as having restricted access. +""" +directive @accessRestricted( + """ + Explains the reason around this restriction + """ + reason: String = null +) on FIELD_DEFINITION | OBJECT + +""" +A version of the API. +""" +type ApiVersion { + """ + The human-readable name of the version. + """ + displayName: String! + + """ + The unique identifier of an ApiVersion. All supported API versions have a date-based (YYYY-MM) or `unstable` handle. + """ + handle: String! + + """ + Whether the version is supported by Shopify. + """ + supported: Boolean! +} + +""" +Details about the gift card used on the checkout. +""" +type AppliedGiftCard implements Node { + """ + The amount that was taken from the gift card by applying it. + """ + amountUsed: Money! @deprecated(reason: "Use `amountUsedV2` instead") + + """ + The amount that was taken from the gift card by applying it. + """ + amountUsedV2: MoneyV2! + + """ + The amount left on the gift card. + """ + balance: Money! @deprecated(reason: "Use `balanceV2` instead") + + """ + The amount left on the gift card. + """ + balanceV2: MoneyV2! + + """ + Globally unique identifier. + """ + id: ID! + + """ + The last characters of the gift card. + """ + lastCharacters: String! + + """ + The amount that was applied to the checkout in its currency. + """ + presentmentAmountUsed: MoneyV2! +} + +""" +An article in an online store blog. +""" +type Article implements Node { + """ + The article's author. + """ + author: ArticleAuthor! @deprecated(reason: "Use `authorV2` instead") + + """ + The article's author. + """ + authorV2: ArticleAuthor + + """ + The blog that the article belongs to. + """ + blog: Blog! + + """ + List of comments posted on the article. + """ + comments( + """ + Returns up to the first `n` elements from the list. + """ + first: Int + + """ + Returns the elements that come after the specified cursor. + """ + after: String + + """ + Returns up to the last `n` elements from the list. + """ + last: Int + + """ + Returns the elements that come before the specified cursor. + """ + before: String + + """ + Reverse the order of the underlying list. + """ + reverse: Boolean = false + ): CommentConnection! + + """ + Stripped content of the article, single line with HTML tags removed. + """ + content( + """ + Truncates string after the given length. + """ + truncateAt: Int + ): String! + + """ + The content of the article, complete with HTML formatting. + """ + contentHtml: HTML! + + """ + Stripped excerpt of the article, single line with HTML tags removed. + """ + excerpt( + """ + Truncates string after the given length. + """ + truncateAt: Int + ): String + + """ + The excerpt of the article, complete with HTML formatting. + """ + excerptHtml: HTML + + """ + A human-friendly unique string for the Article automatically generated from its title. + """ + handle: String! + + """ + Globally unique identifier. + """ + id: ID! + + """ + The image associated with the article. + """ + image( + """ + Image width in pixels between 1 and 2048. This argument is deprecated: Use `maxWidth` on `Image.transformedSrc` instead. + """ + maxWidth: Int + + """ + Image height in pixels between 1 and 2048. This argument is deprecated: Use `maxHeight` on `Image.transformedSrc` instead. + """ + maxHeight: Int + + """ + Crops the image according to the specified region. This argument is deprecated: Use `crop` on `Image.transformedSrc` instead. + """ + crop: CropRegion + + """ + Image size multiplier for high-resolution retina displays. Must be between 1 and 3. This argument is deprecated: Use `scale` on `Image.transformedSrc` instead. + """ + scale: Int = 1 + ): Image + + """ + The date and time when the article was published. + """ + publishedAt: DateTime! + + """ + The article’s SEO information. + """ + seo: SEO + + """ + A categorization that a article can be tagged with. + """ + tags: [String!]! + + """ + The article’s name. + """ + title: String! + + """ + The url pointing to the article accessible from the web. + """ + url: URL! +} + +""" +The author of an article. +""" +type ArticleAuthor { + """ + The author's bio. + """ + bio: String + + """ + The author’s email. + """ + email: String! + + """ + The author's first name. + """ + firstName: String! + + """ + The author's last name. + """ + lastName: String! + + """ + The author's full name. + """ + name: String! +} + +""" +An auto-generated type for paginating through multiple Articles. +""" +type ArticleConnection { + """ + A list of edges. + """ + edges: [ArticleEdge!]! + + """ + Information to aid in pagination. + """ + pageInfo: PageInfo! +} + +""" +An auto-generated type which holds one Article and a cursor during pagination. +""" +type ArticleEdge { + """ + A cursor for use in pagination. + """ + cursor: String! + + """ + The item at the end of ArticleEdge. + """ + node: Article! +} + +""" +The set of valid sort keys for the Article query. +""" +enum ArticleSortKeys { + """ + Sort by the `title` value. + """ + TITLE + + """ + Sort by the `blog_title` value. + """ + BLOG_TITLE + + """ + Sort by the `author` value. + """ + AUTHOR + + """ + Sort by the `updated_at` value. + """ + UPDATED_AT + + """ + Sort by the `published_at` value. + """ + PUBLISHED_AT + + """ + Sort by the `id` value. + """ + ID + + """ + During a search (i.e. when the `query` parameter has been specified on the connection) this sorts the + results by relevance to the search term(s). When no search query is specified, this sort key is not + deterministic and should not be used. + """ + RELEVANCE +} + +""" +Represents a generic custom attribute. +""" +type Attribute { + """ + Key or name of the attribute. + """ + key: String! + + """ + Value of the attribute. + """ + value: String +} + +""" +Specifies the input fields required for an attribute. +""" +input AttributeInput { + """ + Key or name of the attribute. + """ + key: String! + + """ + Value of the attribute. + """ + value: String! +} + +""" +Automatic discount applications capture the intentions of a discount that was automatically applied. +""" +type AutomaticDiscountApplication implements DiscountApplication { + """ + The method by which the discount's value is allocated to its entitled items. + """ + allocationMethod: DiscountApplicationAllocationMethod! + + """ + Which lines of targetType that the discount is allocated over. + """ + targetSelection: DiscountApplicationTargetSelection! + + """ + The type of line that the discount is applicable towards. + """ + targetType: DiscountApplicationTargetType! + + """ + The title of the application. + """ + title: String! + + """ + The value of the discount application. + """ + value: PricingValue! +} + +""" +A collection of available shipping rates for a checkout. +""" +type AvailableShippingRates { + """ + Whether or not the shipping rates are ready. + The `shippingRates` field is `null` when this value is `false`. + This field should be polled until its value becomes `true`. + """ + ready: Boolean! + + """ + The fetched shipping rates. `null` until the `ready` field is `true`. + """ + shippingRates: [ShippingRate!] +} + +""" +An online store blog. +""" +type Blog implements Node { + """ + Find an article by its handle. + """ + articleByHandle( + """ + The handle of the article. + """ + handle: String! + ): Article + + """ + List of the blog's articles. + """ + articles( + """ + Returns up to the first `n` elements from the list. + """ + first: Int + + """ + Returns the elements that come after the specified cursor. + """ + after: String + + """ + Returns up to the last `n` elements from the list. + """ + last: Int + + """ + Returns the elements that come before the specified cursor. + """ + before: String + + """ + Reverse the order of the underlying list. + """ + reverse: Boolean = false + + """ + Sort the underlying list by the given key. + """ + sortKey: ArticleSortKeys = ID + + """ + Supported filter parameters: + - `author` + - `blog_title` + - `created_at` + - `tag` + - `updated_at` + + See the detailed [search syntax](https://help.shopify.com/api/getting-started/search-syntax) + for more information about using filters. + """ + query: String + ): ArticleConnection! + + """ + The authors who have contributed to the blog. + """ + authors: [ArticleAuthor!]! + + """ + A human-friendly unique string for the Blog automatically generated from its title. + """ + handle: String! + + """ + Globally unique identifier. + """ + id: ID! + + """ + The blog's SEO information. + """ + seo: SEO + + """ + The blogs’s title. + """ + title: String! + + """ + The url pointing to the blog accessible from the web. + """ + url: URL! +} + +""" +An auto-generated type for paginating through multiple Blogs. +""" +type BlogConnection { + """ + A list of edges. + """ + edges: [BlogEdge!]! + + """ + Information to aid in pagination. + """ + pageInfo: PageInfo! +} + +""" +An auto-generated type which holds one Blog and a cursor during pagination. +""" +type BlogEdge { + """ + A cursor for use in pagination. + """ + cursor: String! + + """ + The item at the end of BlogEdge. + """ + node: Blog! +} + +""" +The set of valid sort keys for the Blog query. +""" +enum BlogSortKeys { + """ + Sort by the `handle` value. + """ + HANDLE + + """ + Sort by the `title` value. + """ + TITLE + + """ + Sort by the `id` value. + """ + ID + + """ + During a search (i.e. when the `query` parameter has been specified on the connection) this sorts the + results by relevance to the search term(s). When no search query is specified, this sort key is not + deterministic and should not be used. + """ + RELEVANCE +} + +""" +Card brand, such as Visa or Mastercard, which can be used for payments. +""" +enum CardBrand { + """ + Visa + """ + VISA + + """ + Mastercard + """ + MASTERCARD + + """ + Discover + """ + DISCOVER + + """ + American Express + """ + AMERICAN_EXPRESS + + """ + Diners Club + """ + DINERS_CLUB + + """ + JCB + """ + JCB +} + +""" +A container for all the information required to checkout items and pay. +""" +type Checkout implements Node { + """ + The gift cards used on the checkout. + """ + appliedGiftCards: [AppliedGiftCard!]! + + """ + The available shipping rates for this Checkout. + Should only be used when checkout `requiresShipping` is `true` and + the shipping address is valid. + """ + availableShippingRates: AvailableShippingRates + + """ + The date and time when the checkout was completed. + """ + completedAt: DateTime + + """ + The date and time when the checkout was created. + """ + createdAt: DateTime! + + """ + The currency code for the Checkout. + """ + currencyCode: CurrencyCode! + + """ + A list of extra information that is added to the checkout. + """ + customAttributes: [Attribute!]! + + """ + The customer associated with the checkout. + """ + customer: Customer + @deprecated( + reason: "This field will always return null. If you have an authentication token for the customer, you can use the `customer` field on the query root to retrieve it." + ) + + """ + Discounts that have been applied on the checkout. + """ + discountApplications( + """ + Returns up to the first `n` elements from the list. + """ + first: Int + + """ + Returns the elements that come after the specified cursor. + """ + after: String + + """ + Returns up to the last `n` elements from the list. + """ + last: Int + + """ + Returns the elements that come before the specified cursor. + """ + before: String + + """ + Reverse the order of the underlying list. + """ + reverse: Boolean = false + ): DiscountApplicationConnection! + + """ + The email attached to this checkout. + """ + email: String + + """ + Globally unique identifier. + """ + id: ID! + + """ + A list of line item objects, each one containing information about an item in the checkout. + """ + lineItems( + """ + Returns up to the first `n` elements from the list. + """ + first: Int + + """ + Returns the elements that come after the specified cursor. + """ + after: String + + """ + Returns up to the last `n` elements from the list. + """ + last: Int + + """ + Returns the elements that come before the specified cursor. + """ + before: String + + """ + Reverse the order of the underlying list. + """ + reverse: Boolean = false + ): CheckoutLineItemConnection! + + """ + The sum of all the prices of all the items in the checkout. Duties, taxes, shipping and discounts excluded. + """ + lineItemsSubtotalPrice: MoneyV2! + + """ + The note associated with the checkout. + """ + note: String + + """ + The resulting order from a paid checkout. + """ + order: Order + + """ + The Order Status Page for this Checkout, null when checkout is not completed. + """ + orderStatusUrl: URL + + """ + The amount left to be paid. This is equal to the cost of the line items, taxes and shipping minus discounts and gift cards. + """ + paymentDue: Money! @deprecated(reason: "Use `paymentDueV2` instead") + + """ + The amount left to be paid. This is equal to the cost of the line items, duties, taxes and shipping minus discounts and gift cards. + """ + paymentDueV2: MoneyV2! + + """ + Whether or not the Checkout is ready and can be completed. Checkouts may + have asynchronous operations that can take time to finish. If you want + to complete a checkout or ensure all the fields are populated and up to + date, polling is required until the value is true. + """ + ready: Boolean! + + """ + States whether or not the fulfillment requires shipping. + """ + requiresShipping: Boolean! + + """ + The shipping address to where the line items will be shipped. + """ + shippingAddress: MailingAddress + + """ + The discounts that have been allocated onto the shipping line by discount applications. + """ + shippingDiscountAllocations: [DiscountAllocation!]! + + """ + Once a shipping rate is selected by the customer it is transitioned to a `shipping_line` object. + """ + shippingLine: ShippingRate + + """ + Price of the checkout before shipping and taxes. + """ + subtotalPrice: Money! @deprecated(reason: "Use `subtotalPriceV2` instead") + + """ + Price of the checkout before duties, shipping and taxes. + """ + subtotalPriceV2: MoneyV2! + + """ + Specifies if the Checkout is tax exempt. + """ + taxExempt: Boolean! + + """ + Specifies if taxes are included in the line item and shipping line prices. + """ + taxesIncluded: Boolean! + + """ + The sum of all the prices of all the items in the checkout, taxes and discounts included. + """ + totalPrice: Money! @deprecated(reason: "Use `totalPriceV2` instead") + + """ + The sum of all the prices of all the items in the checkout, duties, taxes and discounts included. + """ + totalPriceV2: MoneyV2! + + """ + The sum of all the taxes applied to the line items and shipping lines in the checkout. + """ + totalTax: Money! @deprecated(reason: "Use `totalTaxV2` instead") + + """ + The sum of all the taxes applied to the line items and shipping lines in the checkout. + """ + totalTaxV2: MoneyV2! + + """ + The date and time when the checkout was last updated. + """ + updatedAt: DateTime! + + """ + The url pointing to the checkout accessible from the web. + """ + webUrl: URL! +} + +""" +Specifies the fields required to update a checkout's attributes. +""" +input CheckoutAttributesUpdateInput { + """ + The text of an optional note that a shop owner can attach to the checkout. + """ + note: String + + """ + A list of extra information that is added to the checkout. + """ + customAttributes: [AttributeInput!] + + """ + Allows setting partial addresses on a Checkout, skipping the full validation of attributes. + The required attributes are city, province, and country. + Full validation of the addresses is still done at complete time. + """ + allowPartialAddresses: Boolean +} + +""" +Return type for `checkoutAttributesUpdate` mutation. +""" +type CheckoutAttributesUpdatePayload { + """ + The updated checkout object. + """ + checkout: Checkout! + + """ + List of errors that occurred executing the mutation. + """ + checkoutUserErrors: [CheckoutUserError!]! + + """ + List of errors that occurred executing the mutation. + """ + userErrors: [UserError!]! + @deprecated(reason: "Use `checkoutUserErrors` instead") +} + +""" +Specifies the fields required to update a checkout's attributes. +""" +input CheckoutAttributesUpdateV2Input { + """ + The text of an optional note that a shop owner can attach to the checkout. + """ + note: String + + """ + A list of extra information that is added to the checkout. + """ + customAttributes: [AttributeInput!] + + """ + Allows setting partial addresses on a Checkout, skipping the full validation of attributes. + The required attributes are city, province, and country. + Full validation of the addresses is still done at complete time. + """ + allowPartialAddresses: Boolean +} + +""" +Return type for `checkoutAttributesUpdateV2` mutation. +""" +type CheckoutAttributesUpdateV2Payload { + """ + The updated checkout object. + """ + checkout: Checkout + + """ + List of errors that occurred executing the mutation. + """ + checkoutUserErrors: [CheckoutUserError!]! + + """ + List of errors that occurred executing the mutation. + """ + userErrors: [UserError!]! + @deprecated(reason: "Use `checkoutUserErrors` instead") +} + +""" +Return type for `checkoutCompleteFree` mutation. +""" +type CheckoutCompleteFreePayload { + """ + The updated checkout object. + """ + checkout: Checkout + + """ + List of errors that occurred executing the mutation. + """ + checkoutUserErrors: [CheckoutUserError!]! + + """ + List of errors that occurred executing the mutation. + """ + userErrors: [UserError!]! + @deprecated(reason: "Use `checkoutUserErrors` instead") +} + +""" +Return type for `checkoutCompleteWithCreditCard` mutation. +""" +type CheckoutCompleteWithCreditCardPayload { + """ + The checkout on which the payment was applied. + """ + checkout: Checkout! + + """ + List of errors that occurred executing the mutation. + """ + checkoutUserErrors: [CheckoutUserError!]! + + """ + A representation of the attempted payment. + """ + payment: Payment + + """ + List of errors that occurred executing the mutation. + """ + userErrors: [UserError!]! + @deprecated(reason: "Use `checkoutUserErrors` instead") +} + +""" +Return type for `checkoutCompleteWithCreditCardV2` mutation. +""" +type CheckoutCompleteWithCreditCardV2Payload { + """ + The checkout on which the payment was applied. + """ + checkout: Checkout + + """ + List of errors that occurred executing the mutation. + """ + checkoutUserErrors: [CheckoutUserError!]! + + """ + A representation of the attempted payment. + """ + payment: Payment + + """ + List of errors that occurred executing the mutation. + """ + userErrors: [UserError!]! + @deprecated(reason: "Use `checkoutUserErrors` instead") +} + +""" +Return type for `checkoutCompleteWithTokenizedPayment` mutation. +""" +type CheckoutCompleteWithTokenizedPaymentPayload { + """ + The checkout on which the payment was applied. + """ + checkout: Checkout! + + """ + List of errors that occurred executing the mutation. + """ + checkoutUserErrors: [CheckoutUserError!]! + + """ + A representation of the attempted payment. + """ + payment: Payment + + """ + List of errors that occurred executing the mutation. + """ + userErrors: [UserError!]! + @deprecated(reason: "Use `checkoutUserErrors` instead") +} + +""" +Return type for `checkoutCompleteWithTokenizedPaymentV2` mutation. +""" +type CheckoutCompleteWithTokenizedPaymentV2Payload { + """ + The checkout on which the payment was applied. + """ + checkout: Checkout + + """ + List of errors that occurred executing the mutation. + """ + checkoutUserErrors: [CheckoutUserError!]! + + """ + A representation of the attempted payment. + """ + payment: Payment + + """ + List of errors that occurred executing the mutation. + """ + userErrors: [UserError!]! + @deprecated(reason: "Use `checkoutUserErrors` instead") +} + +""" +Return type for `checkoutCompleteWithTokenizedPaymentV3` mutation. +""" +type CheckoutCompleteWithTokenizedPaymentV3Payload { + """ + The checkout on which the payment was applied. + """ + checkout: Checkout + + """ + List of errors that occurred executing the mutation. + """ + checkoutUserErrors: [CheckoutUserError!]! + + """ + A representation of the attempted payment. + """ + payment: Payment + + """ + List of errors that occurred executing the mutation. + """ + userErrors: [UserError!]! + @deprecated(reason: "Use `checkoutUserErrors` instead") +} + +""" +Specifies the fields required to create a checkout. +""" +input CheckoutCreateInput { + """ + The email with which the customer wants to checkout. + """ + email: String + + """ + A list of line item objects, each one containing information about an item in the checkout. + """ + lineItems: [CheckoutLineItemInput!] + + """ + The shipping address to where the line items will be shipped. + """ + shippingAddress: MailingAddressInput + + """ + The text of an optional note that a shop owner can attach to the checkout. + """ + note: String + + """ + A list of extra information that is added to the checkout. + """ + customAttributes: [AttributeInput!] + + """ + Allows setting partial addresses on a Checkout, skipping the full validation of attributes. + The required attributes are city, province, and country. + Full validation of addresses is still done at complete time. + """ + allowPartialAddresses: Boolean + + """ + The three-letter currency code of one of the shop's enabled presentment currencies. + Including this field creates a checkout in the specified currency. By default, new + checkouts are created in the shop's primary currency. + """ + presentmentCurrencyCode: CurrencyCode +} + +""" +Return type for `checkoutCreate` mutation. +""" +type CheckoutCreatePayload { + """ + The new checkout object. + """ + checkout: Checkout + + """ + List of errors that occurred executing the mutation. + """ + checkoutUserErrors: [CheckoutUserError!]! + + """ + List of errors that occurred executing the mutation. + """ + userErrors: [UserError!]! + @deprecated(reason: "Use `checkoutUserErrors` instead") +} + +""" +Return type for `checkoutCustomerAssociate` mutation. +""" +type CheckoutCustomerAssociatePayload { + """ + The updated checkout object. + """ + checkout: Checkout! + + """ + The associated customer object. + """ + customer: Customer + + """ + List of errors that occurred executing the mutation. + """ + userErrors: [UserError!]! +} + +""" +Return type for `checkoutCustomerAssociateV2` mutation. +""" +type CheckoutCustomerAssociateV2Payload { + """ + The updated checkout object. + """ + checkout: Checkout + + """ + List of errors that occurred executing the mutation. + """ + checkoutUserErrors: [CheckoutUserError!]! + + """ + The associated customer object. + """ + customer: Customer + + """ + List of errors that occurred executing the mutation. + """ + userErrors: [UserError!]! + @deprecated(reason: "Use `checkoutUserErrors` instead") +} + +""" +Return type for `checkoutCustomerDisassociate` mutation. +""" +type CheckoutCustomerDisassociatePayload { + """ + The updated checkout object. + """ + checkout: Checkout! + + """ + List of errors that occurred executing the mutation. + """ + checkoutUserErrors: [CheckoutUserError!]! + + """ + List of errors that occurred executing the mutation. + """ + userErrors: [UserError!]! + @deprecated(reason: "Use `checkoutUserErrors` instead") +} + +""" +Return type for `checkoutCustomerDisassociateV2` mutation. +""" +type CheckoutCustomerDisassociateV2Payload { + """ + The updated checkout object. + """ + checkout: Checkout + + """ + List of errors that occurred executing the mutation. + """ + checkoutUserErrors: [CheckoutUserError!]! + + """ + List of errors that occurred executing the mutation. + """ + userErrors: [UserError!]! + @deprecated(reason: "Use `checkoutUserErrors` instead") +} + +""" +Return type for `checkoutDiscountCodeApply` mutation. +""" +type CheckoutDiscountCodeApplyPayload { + """ + The updated checkout object. + """ + checkout: Checkout! + + """ + List of errors that occurred executing the mutation. + """ + checkoutUserErrors: [CheckoutUserError!]! + + """ + List of errors that occurred executing the mutation. + """ + userErrors: [UserError!]! + @deprecated(reason: "Use `checkoutUserErrors` instead") +} + +""" +Return type for `checkoutDiscountCodeApplyV2` mutation. +""" +type CheckoutDiscountCodeApplyV2Payload { + """ + The updated checkout object. + """ + checkout: Checkout + + """ + List of errors that occurred executing the mutation. + """ + checkoutUserErrors: [CheckoutUserError!]! + + """ + List of errors that occurred executing the mutation. + """ + userErrors: [UserError!]! + @deprecated(reason: "Use `checkoutUserErrors` instead") +} + +""" +Return type for `checkoutDiscountCodeRemove` mutation. +""" +type CheckoutDiscountCodeRemovePayload { + """ + The updated checkout object. + """ + checkout: Checkout + + """ + List of errors that occurred executing the mutation. + """ + checkoutUserErrors: [CheckoutUserError!]! + + """ + List of errors that occurred executing the mutation. + """ + userErrors: [UserError!]! + @deprecated(reason: "Use `checkoutUserErrors` instead") +} + +""" +Return type for `checkoutEmailUpdate` mutation. +""" +type CheckoutEmailUpdatePayload { + """ + The checkout object with the updated email. + """ + checkout: Checkout! + + """ + List of errors that occurred executing the mutation. + """ + checkoutUserErrors: [CheckoutUserError!]! + + """ + List of errors that occurred executing the mutation. + """ + userErrors: [UserError!]! + @deprecated(reason: "Use `checkoutUserErrors` instead") +} + +""" +Return type for `checkoutEmailUpdateV2` mutation. +""" +type CheckoutEmailUpdateV2Payload { + """ + The checkout object with the updated email. + """ + checkout: Checkout + + """ + List of errors that occurred executing the mutation. + """ + checkoutUserErrors: [CheckoutUserError!]! + + """ + List of errors that occurred executing the mutation. + """ + userErrors: [UserError!]! + @deprecated(reason: "Use `checkoutUserErrors` instead") +} + +""" +Possible error codes that could be returned by CheckoutUserError. +""" +enum CheckoutErrorCode { + """ + Input value is blank. + """ + BLANK + + """ + Input value is invalid. + """ + INVALID + + """ + Input value is too long. + """ + TOO_LONG + + """ + Input value is not present. + """ + PRESENT + + """ + Input value should be less than maximum allowed value. + """ + LESS_THAN + + """ + Input value should be greater than or equal to minimum allowed value. + """ + GREATER_THAN_OR_EQUAL_TO + + """ + Input value should be less or equal to maximum allowed value. + """ + LESS_THAN_OR_EQUAL_TO + + """ + Checkout is already completed. + """ + ALREADY_COMPLETED + + """ + Checkout is locked. + """ + LOCKED + + """ + Input value is not supported. + """ + NOT_SUPPORTED + + """ + Input email contains an invalid domain name. + """ + BAD_DOMAIN + + """ + Input Zip is invalid for country provided. + """ + INVALID_FOR_COUNTRY + + """ + Input Zip is invalid for country and province provided. + """ + INVALID_FOR_COUNTRY_AND_PROVINCE + + """ + Invalid state in country. + """ + INVALID_STATE_IN_COUNTRY + + """ + Invalid province in country. + """ + INVALID_PROVINCE_IN_COUNTRY + + """ + Invalid region in country. + """ + INVALID_REGION_IN_COUNTRY + + """ + Shipping rate expired. + """ + SHIPPING_RATE_EXPIRED + + """ + Gift card cannot be applied to a checkout that contains a gift card. + """ + GIFT_CARD_UNUSABLE + + """ + Gift card is disabled. + """ + GIFT_CARD_DISABLED + + """ + Gift card code is invalid. + """ + GIFT_CARD_CODE_INVALID + + """ + Gift card has already been applied. + """ + GIFT_CARD_ALREADY_APPLIED + + """ + Gift card currency does not match checkout currency. + """ + GIFT_CARD_CURRENCY_MISMATCH + + """ + Gift card is expired. + """ + GIFT_CARD_EXPIRED + + """ + Gift card has no funds left. + """ + GIFT_CARD_DEPLETED + + """ + Gift card was not found. + """ + GIFT_CARD_NOT_FOUND + + """ + Cart does not meet discount requirements notice. + """ + CART_DOES_NOT_MEET_DISCOUNT_REQUIREMENTS_NOTICE + + """ + Discount expired. + """ + DISCOUNT_EXPIRED + + """ + Discount disabled. + """ + DISCOUNT_DISABLED + + """ + Discount limit reached. + """ + DISCOUNT_LIMIT_REACHED + + """ + Discount not found. + """ + DISCOUNT_NOT_FOUND + + """ + Customer already used once per customer discount notice. + """ + CUSTOMER_ALREADY_USED_ONCE_PER_CUSTOMER_DISCOUNT_NOTICE + + """ + Checkout is already completed. + """ + EMPTY + + """ + Not enough in stock. + """ + NOT_ENOUGH_IN_STOCK + + """ + Missing payment input. + """ + MISSING_PAYMENT_INPUT + + """ + The amount of the payment does not match the value to be paid. + """ + TOTAL_PRICE_MISMATCH + + """ + Line item was not found in checkout. + """ + LINE_ITEM_NOT_FOUND + + """ + Unable to apply discount. + """ + UNABLE_TO_APPLY + + """ + Discount already applied. + """ + DISCOUNT_ALREADY_APPLIED +} + +""" +Return type for `checkoutGiftCardApply` mutation. +""" +type CheckoutGiftCardApplyPayload { + """ + The updated checkout object. + """ + checkout: Checkout! + + """ + List of errors that occurred executing the mutation. + """ + checkoutUserErrors: [CheckoutUserError!]! + + """ + List of errors that occurred executing the mutation. + """ + userErrors: [UserError!]! + @deprecated(reason: "Use `checkoutUserErrors` instead") +} + +""" +Return type for `checkoutGiftCardRemove` mutation. +""" +type CheckoutGiftCardRemovePayload { + """ + The updated checkout object. + """ + checkout: Checkout! + + """ + List of errors that occurred executing the mutation. + """ + checkoutUserErrors: [CheckoutUserError!]! + + """ + List of errors that occurred executing the mutation. + """ + userErrors: [UserError!]! + @deprecated(reason: "Use `checkoutUserErrors` instead") +} + +""" +Return type for `checkoutGiftCardRemoveV2` mutation. +""" +type CheckoutGiftCardRemoveV2Payload { + """ + The updated checkout object. + """ + checkout: Checkout + + """ + List of errors that occurred executing the mutation. + """ + checkoutUserErrors: [CheckoutUserError!]! + + """ + List of errors that occurred executing the mutation. + """ + userErrors: [UserError!]! + @deprecated(reason: "Use `checkoutUserErrors` instead") +} + +""" +Return type for `checkoutGiftCardsAppend` mutation. +""" +type CheckoutGiftCardsAppendPayload { + """ + The updated checkout object. + """ + checkout: Checkout + + """ + List of errors that occurred executing the mutation. + """ + checkoutUserErrors: [CheckoutUserError!]! + + """ + List of errors that occurred executing the mutation. + """ + userErrors: [UserError!]! + @deprecated(reason: "Use `checkoutUserErrors` instead") +} + +""" +A single line item in the checkout, grouped by variant and attributes. +""" +type CheckoutLineItem implements Node { + """ + Extra information in the form of an array of Key-Value pairs about the line item. + """ + customAttributes: [Attribute!]! + + """ + The discounts that have been allocated onto the checkout line item by discount applications. + """ + discountAllocations: [DiscountAllocation!]! + + """ + Globally unique identifier. + """ + id: ID! + + """ + The quantity of the line item. + """ + quantity: Int! + + """ + Title of the line item. Defaults to the product's title. + """ + title: String! + + """ + Unit price of the line item. + """ + unitPrice: MoneyV2 + + """ + Product variant of the line item. + """ + variant: ProductVariant +} + +""" +An auto-generated type for paginating through multiple CheckoutLineItems. +""" +type CheckoutLineItemConnection { + """ + A list of edges. + """ + edges: [CheckoutLineItemEdge!]! + + """ + Information to aid in pagination. + """ + pageInfo: PageInfo! +} + +""" +An auto-generated type which holds one CheckoutLineItem and a cursor during pagination. +""" +type CheckoutLineItemEdge { + """ + A cursor for use in pagination. + """ + cursor: String! + + """ + The item at the end of CheckoutLineItemEdge. + """ + node: CheckoutLineItem! +} + +""" +Specifies the input fields to create a line item on a checkout. +""" +input CheckoutLineItemInput { + """ + Extra information in the form of an array of Key-Value pairs about the line item. + """ + customAttributes: [AttributeInput!] + + """ + The quantity of the line item. + """ + quantity: Int! + + """ + The identifier of the product variant for the line item. + """ + variantId: ID! +} + +""" +Specifies the input fields to update a line item on the checkout. +""" +input CheckoutLineItemUpdateInput { + """ + The identifier of the line item. + """ + id: ID + + """ + The variant identifier of the line item. + """ + variantId: ID + + """ + The quantity of the line item. + """ + quantity: Int + + """ + Extra information in the form of an array of Key-Value pairs about the line item. + """ + customAttributes: [AttributeInput!] +} + +""" +Return type for `checkoutLineItemsAdd` mutation. +""" +type CheckoutLineItemsAddPayload { + """ + The updated checkout object. + """ + checkout: Checkout + + """ + List of errors that occurred executing the mutation. + """ + checkoutUserErrors: [CheckoutUserError!]! + + """ + List of errors that occurred executing the mutation. + """ + userErrors: [UserError!]! + @deprecated(reason: "Use `checkoutUserErrors` instead") +} + +""" +Return type for `checkoutLineItemsRemove` mutation. +""" +type CheckoutLineItemsRemovePayload { + """ + The updated checkout object. + """ + checkout: Checkout + + """ + List of errors that occurred executing the mutation. + """ + checkoutUserErrors: [CheckoutUserError!]! + + """ + List of errors that occurred executing the mutation. + """ + userErrors: [UserError!]! + @deprecated(reason: "Use `checkoutUserErrors` instead") +} + +""" +Return type for `checkoutLineItemsReplace` mutation. +""" +type CheckoutLineItemsReplacePayload { + """ + The updated checkout object. + """ + checkout: Checkout + + """ + List of errors that occurred executing the mutation. + """ + userErrors: [CheckoutUserError!]! +} + +""" +Return type for `checkoutLineItemsUpdate` mutation. +""" +type CheckoutLineItemsUpdatePayload { + """ + The updated checkout object. + """ + checkout: Checkout + + """ + List of errors that occurred executing the mutation. + """ + checkoutUserErrors: [CheckoutUserError!]! + + """ + List of errors that occurred executing the mutation. + """ + userErrors: [UserError!]! + @deprecated(reason: "Use `checkoutUserErrors` instead") +} + +""" +Return type for `checkoutShippingAddressUpdate` mutation. +""" +type CheckoutShippingAddressUpdatePayload { + """ + The updated checkout object. + """ + checkout: Checkout! + + """ + List of errors that occurred executing the mutation. + """ + checkoutUserErrors: [CheckoutUserError!]! + + """ + List of errors that occurred executing the mutation. + """ + userErrors: [UserError!]! + @deprecated(reason: "Use `checkoutUserErrors` instead") +} + +""" +Return type for `checkoutShippingAddressUpdateV2` mutation. +""" +type CheckoutShippingAddressUpdateV2Payload { + """ + The updated checkout object. + """ + checkout: Checkout + + """ + List of errors that occurred executing the mutation. + """ + checkoutUserErrors: [CheckoutUserError!]! + + """ + List of errors that occurred executing the mutation. + """ + userErrors: [UserError!]! + @deprecated(reason: "Use `checkoutUserErrors` instead") +} + +""" +Return type for `checkoutShippingLineUpdate` mutation. +""" +type CheckoutShippingLineUpdatePayload { + """ + The updated checkout object. + """ + checkout: Checkout + + """ + List of errors that occurred executing the mutation. + """ + checkoutUserErrors: [CheckoutUserError!]! + + """ + List of errors that occurred executing the mutation. + """ + userErrors: [UserError!]! + @deprecated(reason: "Use `checkoutUserErrors` instead") +} + +""" +Represents an error that happens during execution of a checkout mutation. +""" +type CheckoutUserError implements DisplayableError { + """ + Error code to uniquely identify the error. + """ + code: CheckoutErrorCode + + """ + Path to the input field which caused the error. + """ + field: [String!] + + """ + The error message. + """ + message: String! +} + +""" +A collection represents a grouping of products that a shop owner can create to organize them or make their shops easier to browse. +""" +type Collection implements Node { + """ + Stripped description of the collection, single line with HTML tags removed. + """ + description( + """ + Truncates string after the given length. + """ + truncateAt: Int + ): String! + + """ + The description of the collection, complete with HTML formatting. + """ + descriptionHtml: HTML! + + """ + A human-friendly unique string for the collection automatically generated from its title. + Limit of 255 characters. + """ + handle: String! + + """ + Globally unique identifier. + """ + id: ID! + + """ + Image associated with the collection. + """ + image( + """ + Image width in pixels between 1 and 2048. This argument is deprecated: Use `maxWidth` on `Image.transformedSrc` instead. + """ + maxWidth: Int + + """ + Image height in pixels between 1 and 2048. This argument is deprecated: Use `maxHeight` on `Image.transformedSrc` instead. + """ + maxHeight: Int + + """ + Crops the image according to the specified region. This argument is deprecated: Use `crop` on `Image.transformedSrc` instead. + """ + crop: CropRegion + + """ + Image size multiplier for high-resolution retina displays. Must be between 1 and 3. This argument is deprecated: Use `scale` on `Image.transformedSrc` instead. + """ + scale: Int = 1 + ): Image + + """ + List of products in the collection. + """ + products( + """ + Returns up to the first `n` elements from the list. + """ + first: Int + + """ + Returns the elements that come after the specified cursor. + """ + after: String + + """ + Returns up to the last `n` elements from the list. + """ + last: Int + + """ + Returns the elements that come before the specified cursor. + """ + before: String + + """ + Reverse the order of the underlying list. + """ + reverse: Boolean = false + + """ + Sort the underlying list by the given key. + """ + sortKey: ProductCollectionSortKeys = COLLECTION_DEFAULT + ): ProductConnection! + + """ + The collection’s name. Limit of 255 characters. + """ + title: String! + + """ + The date and time when the collection was last modified. + """ + updatedAt: DateTime! +} + +""" +An auto-generated type for paginating through multiple Collections. +""" +type CollectionConnection { + """ + A list of edges. + """ + edges: [CollectionEdge!]! + + """ + Information to aid in pagination. + """ + pageInfo: PageInfo! +} + +""" +An auto-generated type which holds one Collection and a cursor during pagination. +""" +type CollectionEdge { + """ + A cursor for use in pagination. + """ + cursor: String! + + """ + The item at the end of CollectionEdge. + """ + node: Collection! +} + +""" +The set of valid sort keys for the Collection query. +""" +enum CollectionSortKeys { + """ + Sort by the `title` value. + """ + TITLE + + """ + Sort by the `updated_at` value. + """ + UPDATED_AT + + """ + Sort by the `id` value. + """ + ID + + """ + During a search (i.e. when the `query` parameter has been specified on the connection) this sorts the + results by relevance to the search term(s). When no search query is specified, this sort key is not + deterministic and should not be used. + """ + RELEVANCE +} + +""" +A comment on an article. +""" +type Comment implements Node { + """ + The comment’s author. + """ + author: CommentAuthor! + + """ + Stripped content of the comment, single line with HTML tags removed. + """ + content( + """ + Truncates string after the given length. + """ + truncateAt: Int + ): String! + + """ + The content of the comment, complete with HTML formatting. + """ + contentHtml: HTML! + + """ + Globally unique identifier. + """ + id: ID! +} + +""" +The author of a comment. +""" +type CommentAuthor { + """ + The author's email. + """ + email: String! + + """ + The author’s name. + """ + name: String! +} + +""" +An auto-generated type for paginating through multiple Comments. +""" +type CommentConnection { + """ + A list of edges. + """ + edges: [CommentEdge!]! + + """ + Information to aid in pagination. + """ + pageInfo: PageInfo! +} + +""" +An auto-generated type which holds one Comment and a cursor during pagination. +""" +type CommentEdge { + """ + A cursor for use in pagination. + """ + cursor: String! + + """ + The item at the end of CommentEdge. + """ + node: Comment! +} + +""" +ISO 3166-1 alpha-2 country codes with some differences. +""" +enum CountryCode { + """ + Afghanistan. + """ + AF + + """ + Åland Islands. + """ + AX + + """ + Albania. + """ + AL + + """ + Algeria. + """ + DZ + + """ + Andorra. + """ + AD + + """ + Angola. + """ + AO + + """ + Anguilla. + """ + AI + + """ + Antigua & Barbuda. + """ + AG + + """ + Argentina. + """ + AR + + """ + Armenia. + """ + AM + + """ + Aruba. + """ + AW + + """ + Australia. + """ + AU + + """ + Austria. + """ + AT + + """ + Azerbaijan. + """ + AZ + + """ + Bahamas. + """ + BS + + """ + Bahrain. + """ + BH + + """ + Bangladesh. + """ + BD + + """ + Barbados. + """ + BB + + """ + Belarus. + """ + BY + + """ + Belgium. + """ + BE + + """ + Belize. + """ + BZ + + """ + Benin. + """ + BJ + + """ + Bermuda. + """ + BM + + """ + Bhutan. + """ + BT + + """ + Bolivia. + """ + BO + + """ + Bosnia & Herzegovina. + """ + BA + + """ + Botswana. + """ + BW + + """ + Bouvet Island. + """ + BV + + """ + Brazil. + """ + BR + + """ + British Indian Ocean Territory. + """ + IO + + """ + Brunei. + """ + BN + + """ + Bulgaria. + """ + BG + + """ + Burkina Faso. + """ + BF + + """ + Burundi. + """ + BI + + """ + Cambodia. + """ + KH + + """ + Canada. + """ + CA + + """ + Cape Verde. + """ + CV + + """ + Caribbean Netherlands. + """ + BQ + + """ + Cayman Islands. + """ + KY + + """ + Central African Republic. + """ + CF + + """ + Chad. + """ + TD + + """ + Chile. + """ + CL + + """ + China. + """ + CN + + """ + Christmas Island. + """ + CX + + """ + Cocos (Keeling) Islands. + """ + CC + + """ + Colombia. + """ + CO + + """ + Comoros. + """ + KM + + """ + Congo - Brazzaville. + """ + CG + + """ + Congo - Kinshasa. + """ + CD + + """ + Cook Islands. + """ + CK + + """ + Costa Rica. + """ + CR + + """ + Croatia. + """ + HR + + """ + Cuba. + """ + CU + + """ + Curaçao. + """ + CW + + """ + Cyprus. + """ + CY + + """ + Czechia. + """ + CZ + + """ + Côte d’Ivoire. + """ + CI + + """ + Denmark. + """ + DK + + """ + Djibouti. + """ + DJ + + """ + Dominica. + """ + DM + + """ + Dominican Republic. + """ + DO + + """ + Ecuador. + """ + EC + + """ + Egypt. + """ + EG + + """ + El Salvador. + """ + SV + + """ + Equatorial Guinea. + """ + GQ + + """ + Eritrea. + """ + ER + + """ + Estonia. + """ + EE + + """ + Eswatini. + """ + SZ + + """ + Ethiopia. + """ + ET + + """ + Falkland Islands. + """ + FK + + """ + Faroe Islands. + """ + FO + + """ + Fiji. + """ + FJ + + """ + Finland. + """ + FI + + """ + France. + """ + FR + + """ + French Guiana. + """ + GF + + """ + French Polynesia. + """ + PF + + """ + French Southern Territories. + """ + TF + + """ + Gabon. + """ + GA + + """ + Gambia. + """ + GM + + """ + Georgia. + """ + GE + + """ + Germany. + """ + DE + + """ + Ghana. + """ + GH + + """ + Gibraltar. + """ + GI + + """ + Greece. + """ + GR + + """ + Greenland. + """ + GL + + """ + Grenada. + """ + GD + + """ + Guadeloupe. + """ + GP + + """ + Guatemala. + """ + GT + + """ + Guernsey. + """ + GG + + """ + Guinea. + """ + GN + + """ + Guinea-Bissau. + """ + GW + + """ + Guyana. + """ + GY + + """ + Haiti. + """ + HT + + """ + Heard & McDonald Islands. + """ + HM + + """ + Vatican City. + """ + VA + + """ + Honduras. + """ + HN + + """ + Hong Kong SAR. + """ + HK + + """ + Hungary. + """ + HU + + """ + Iceland. + """ + IS + + """ + India. + """ + IN + + """ + Indonesia. + """ + ID + + """ + Iran. + """ + IR + + """ + Iraq. + """ + IQ + + """ + Ireland. + """ + IE + + """ + Isle of Man. + """ + IM + + """ + Israel. + """ + IL + + """ + Italy. + """ + IT + + """ + Jamaica. + """ + JM + + """ + Japan. + """ + JP + + """ + Jersey. + """ + JE + + """ + Jordan. + """ + JO + + """ + Kazakhstan. + """ + KZ + + """ + Kenya. + """ + KE + + """ + Kiribati. + """ + KI + + """ + North Korea. + """ + KP + + """ + Kosovo. + """ + XK + + """ + Kuwait. + """ + KW + + """ + Kyrgyzstan. + """ + KG + + """ + Laos. + """ + LA + + """ + Latvia. + """ + LV + + """ + Lebanon. + """ + LB + + """ + Lesotho. + """ + LS + + """ + Liberia. + """ + LR + + """ + Libya. + """ + LY + + """ + Liechtenstein. + """ + LI + + """ + Lithuania. + """ + LT + + """ + Luxembourg. + """ + LU + + """ + Macao SAR. + """ + MO + + """ + Madagascar. + """ + MG + + """ + Malawi. + """ + MW + + """ + Malaysia. + """ + MY + + """ + Maldives. + """ + MV + + """ + Mali. + """ + ML + + """ + Malta. + """ + MT + + """ + Martinique. + """ + MQ + + """ + Mauritania. + """ + MR + + """ + Mauritius. + """ + MU + + """ + Mayotte. + """ + YT + + """ + Mexico. + """ + MX + + """ + Moldova. + """ + MD + + """ + Monaco. + """ + MC + + """ + Mongolia. + """ + MN + + """ + Montenegro. + """ + ME + + """ + Montserrat. + """ + MS + + """ + Morocco. + """ + MA + + """ + Mozambique. + """ + MZ + + """ + Myanmar (Burma). + """ + MM + + """ + Namibia. + """ + NA + + """ + Nauru. + """ + NR + + """ + Nepal. + """ + NP + + """ + Netherlands. + """ + NL + + """ + Netherlands Antilles. + """ + AN + + """ + New Caledonia. + """ + NC + + """ + New Zealand. + """ + NZ + + """ + Nicaragua. + """ + NI + + """ + Niger. + """ + NE + + """ + Nigeria. + """ + NG + + """ + Niue. + """ + NU + + """ + Norfolk Island. + """ + NF + + """ + North Macedonia. + """ + MK + + """ + Norway. + """ + NO + + """ + Oman. + """ + OM + + """ + Pakistan. + """ + PK + + """ + Palestinian Territories. + """ + PS + + """ + Panama. + """ + PA + + """ + Papua New Guinea. + """ + PG + + """ + Paraguay. + """ + PY + + """ + Peru. + """ + PE + + """ + Philippines. + """ + PH + + """ + Pitcairn Islands. + """ + PN + + """ + Poland. + """ + PL + + """ + Portugal. + """ + PT + + """ + Qatar. + """ + QA + + """ + Cameroon. + """ + CM + + """ + Réunion. + """ + RE + + """ + Romania. + """ + RO + + """ + Russia. + """ + RU + + """ + Rwanda. + """ + RW + + """ + St. Barthélemy. + """ + BL + + """ + St. Helena. + """ + SH + + """ + St. Kitts & Nevis. + """ + KN + + """ + St. Lucia. + """ + LC + + """ + St. Martin. + """ + MF + + """ + St. Pierre & Miquelon. + """ + PM + + """ + Samoa. + """ + WS + + """ + San Marino. + """ + SM + + """ + São Tomé & Príncipe. + """ + ST + + """ + Saudi Arabia. + """ + SA + + """ + Senegal. + """ + SN + + """ + Serbia. + """ + RS + + """ + Seychelles. + """ + SC + + """ + Sierra Leone. + """ + SL + + """ + Singapore. + """ + SG + + """ + Sint Maarten. + """ + SX + + """ + Slovakia. + """ + SK + + """ + Slovenia. + """ + SI + + """ + Solomon Islands. + """ + SB + + """ + Somalia. + """ + SO + + """ + South Africa. + """ + ZA + + """ + South Georgia & South Sandwich Islands. + """ + GS + + """ + South Korea. + """ + KR + + """ + South Sudan. + """ + SS + + """ + Spain. + """ + ES + + """ + Sri Lanka. + """ + LK + + """ + St. Vincent & Grenadines. + """ + VC + + """ + Sudan. + """ + SD + + """ + Suriname. + """ + SR + + """ + Svalbard & Jan Mayen. + """ + SJ + + """ + Sweden. + """ + SE + + """ + Switzerland. + """ + CH + + """ + Syria. + """ + SY + + """ + Taiwan. + """ + TW + + """ + Tajikistan. + """ + TJ + + """ + Tanzania. + """ + TZ + + """ + Thailand. + """ + TH + + """ + Timor-Leste. + """ + TL + + """ + Togo. + """ + TG + + """ + Tokelau. + """ + TK + + """ + Tonga. + """ + TO + + """ + Trinidad & Tobago. + """ + TT + + """ + Tunisia. + """ + TN + + """ + Turkey. + """ + TR + + """ + Turkmenistan. + """ + TM + + """ + Turks & Caicos Islands. + """ + TC + + """ + Tuvalu. + """ + TV + + """ + Uganda. + """ + UG + + """ + Ukraine. + """ + UA + + """ + United Arab Emirates. + """ + AE + + """ + United Kingdom. + """ + GB + + """ + United States. + """ + US + + """ + U.S. Outlying Islands. + """ + UM + + """ + Uruguay. + """ + UY + + """ + Uzbekistan. + """ + UZ + + """ + Vanuatu. + """ + VU + + """ + Venezuela. + """ + VE + + """ + Vietnam. + """ + VN + + """ + British Virgin Islands. + """ + VG + + """ + Wallis & Futuna. + """ + WF + + """ + Western Sahara. + """ + EH + + """ + Yemen. + """ + YE + + """ + Zambia. + """ + ZM + + """ + Zimbabwe. + """ + ZW +} + +""" +Credit card information used for a payment. +""" +type CreditCard { + """ + The brand of the credit card. + """ + brand: String + + """ + The expiry month of the credit card. + """ + expiryMonth: Int + + """ + The expiry year of the credit card. + """ + expiryYear: Int + + """ + The credit card's BIN number. + """ + firstDigits: String + + """ + The first name of the card holder. + """ + firstName: String + + """ + The last 4 digits of the credit card. + """ + lastDigits: String + + """ + The last name of the card holder. + """ + lastName: String + + """ + The masked credit card number with only the last 4 digits displayed. + """ + maskedNumber: String +} + +""" +Specifies the fields required to complete a checkout with +a Shopify vaulted credit card payment. +""" +input CreditCardPaymentInput { + """ + The amount of the payment. + """ + amount: Money! + + """ + A unique client generated key used to avoid duplicate charges. When a duplicate payment is found, the original is returned instead of creating a new one. + """ + idempotencyKey: String! + + """ + The billing address for the payment. + """ + billingAddress: MailingAddressInput! + + """ + The ID returned by Shopify's Card Vault. + """ + vaultId: String! + + """ + Executes the payment in test mode if possible. Defaults to `false`. + """ + test: Boolean +} + +""" +Specifies the fields required to complete a checkout with +a Shopify vaulted credit card payment. +""" +input CreditCardPaymentInputV2 { + """ + The amount and currency of the payment. + """ + paymentAmount: MoneyInput! + + """ + A unique client generated key used to avoid duplicate charges. When a duplicate payment is found, the original is returned instead of creating a new one. + """ + idempotencyKey: String! + + """ + The billing address for the payment. + """ + billingAddress: MailingAddressInput! + + """ + The ID returned by Shopify's Card Vault. + """ + vaultId: String! + + """ + Executes the payment in test mode if possible. Defaults to `false`. + """ + test: Boolean +} + +""" +The part of the image that should remain after cropping. +""" +enum CropRegion { + """ + Keep the center of the image. + """ + CENTER + + """ + Keep the top of the image. + """ + TOP + + """ + Keep the bottom of the image. + """ + BOTTOM + + """ + Keep the left of the image. + """ + LEFT + + """ + Keep the right of the image. + """ + RIGHT +} + +""" +Currency codes. +""" +enum CurrencyCode { + """ + United States Dollars (USD). + """ + USD + + """ + Euro (EUR). + """ + EUR + + """ + United Kingdom Pounds (GBP). + """ + GBP + + """ + Canadian Dollars (CAD). + """ + CAD + + """ + Afghan Afghani (AFN). + """ + AFN + + """ + Albanian Lek (ALL). + """ + ALL + + """ + Algerian Dinar (DZD). + """ + DZD + + """ + Angolan Kwanza (AOA). + """ + AOA + + """ + Argentine Pesos (ARS). + """ + ARS + + """ + Armenian Dram (AMD). + """ + AMD + + """ + Aruban Florin (AWG). + """ + AWG + + """ + Australian Dollars (AUD). + """ + AUD + + """ + Barbadian Dollar (BBD). + """ + BBD + + """ + Azerbaijani Manat (AZN). + """ + AZN + + """ + Bangladesh Taka (BDT). + """ + BDT + + """ + Bahamian Dollar (BSD). + """ + BSD + + """ + Bahraini Dinar (BHD). + """ + BHD + + """ + Burundian Franc (BIF). + """ + BIF + + """ + Belarusian Ruble (BYN). + """ + BYN + + """ + Belarusian Ruble (BYR). + """ + BYR + + """ + Belize Dollar (BZD). + """ + BZD + + """ + Bermudian Dollar (BMD). + """ + BMD + + """ + Bhutanese Ngultrum (BTN). + """ + BTN + + """ + Bosnia and Herzegovina Convertible Mark (BAM). + """ + BAM + + """ + Brazilian Real (BRL). + """ + BRL + + """ + Bolivian Boliviano (BOB). + """ + BOB + + """ + Botswana Pula (BWP). + """ + BWP + + """ + Brunei Dollar (BND). + """ + BND + + """ + Bulgarian Lev (BGN). + """ + BGN + + """ + Burmese Kyat (MMK). + """ + MMK + + """ + Cambodian Riel. + """ + KHR + + """ + Cape Verdean escudo (CVE). + """ + CVE + + """ + Cayman Dollars (KYD). + """ + KYD + + """ + Central African CFA Franc (XAF). + """ + XAF + + """ + Chilean Peso (CLP). + """ + CLP + + """ + Chinese Yuan Renminbi (CNY). + """ + CNY + + """ + Colombian Peso (COP). + """ + COP + + """ + Comorian Franc (KMF). + """ + KMF + + """ + Congolese franc (CDF). + """ + CDF + + """ + Costa Rican Colones (CRC). + """ + CRC + + """ + Croatian Kuna (HRK). + """ + HRK + + """ + Czech Koruny (CZK). + """ + CZK + + """ + Danish Kroner (DKK). + """ + DKK + + """ + Djiboutian Franc (DJF). + """ + DJF + + """ + Dominican Peso (DOP). + """ + DOP + + """ + East Caribbean Dollar (XCD). + """ + XCD + + """ + Egyptian Pound (EGP). + """ + EGP + + """ + Eritrean Nakfa (ERN). + """ + ERN + + """ + Ethiopian Birr (ETB). + """ + ETB + + """ + Falkland Islands Pounds (FKP). + """ + FKP + + """ + CFP Franc (XPF). + """ + XPF + + """ + Fijian Dollars (FJD). + """ + FJD + + """ + Gibraltar Pounds (GIP). + """ + GIP + + """ + Gambian Dalasi (GMD). + """ + GMD + + """ + Ghanaian Cedi (GHS). + """ + GHS + + """ + Guatemalan Quetzal (GTQ). + """ + GTQ + + """ + Guyanese Dollar (GYD). + """ + GYD + + """ + Georgian Lari (GEL). + """ + GEL + + """ + Guinean Franc (GNF). + """ + GNF + + """ + Haitian Gourde (HTG). + """ + HTG + + """ + Honduran Lempira (HNL). + """ + HNL + + """ + Hong Kong Dollars (HKD). + """ + HKD + + """ + Hungarian Forint (HUF). + """ + HUF + + """ + Icelandic Kronur (ISK). + """ + ISK + + """ + Indian Rupees (INR). + """ + INR + + """ + Indonesian Rupiah (IDR). + """ + IDR + + """ + Israeli New Shekel (NIS). + """ + ILS + + """ + Iranian Rial (IRR). + """ + IRR + + """ + Iraqi Dinar (IQD). + """ + IQD + + """ + Jamaican Dollars (JMD). + """ + JMD + + """ + Japanese Yen (JPY). + """ + JPY + + """ + Jersey Pound. + """ + JEP + + """ + Jordanian Dinar (JOD). + """ + JOD + + """ + Kazakhstani Tenge (KZT). + """ + KZT + + """ + Kenyan Shilling (KES). + """ + KES + + """ + Kiribati Dollar (KID). + """ + KID + + """ + Kuwaiti Dinar (KWD). + """ + KWD + + """ + Kyrgyzstani Som (KGS). + """ + KGS + + """ + Laotian Kip (LAK). + """ + LAK + + """ + Latvian Lati (LVL). + """ + LVL + + """ + Lebanese Pounds (LBP). + """ + LBP + + """ + Lesotho Loti (LSL). + """ + LSL + + """ + Liberian Dollar (LRD). + """ + LRD + + """ + Libyan Dinar (LYD). + """ + LYD + + """ + Lithuanian Litai (LTL). + """ + LTL + + """ + Malagasy Ariary (MGA). + """ + MGA + + """ + Macedonia Denar (MKD). + """ + MKD + + """ + Macanese Pataca (MOP). + """ + MOP + + """ + Malawian Kwacha (MWK). + """ + MWK + + """ + Maldivian Rufiyaa (MVR). + """ + MVR + + """ + Mauritanian Ouguiya (MRU). + """ + MRU + + """ + Mexican Pesos (MXN). + """ + MXN + + """ + Malaysian Ringgits (MYR). + """ + MYR + + """ + Mauritian Rupee (MUR). + """ + MUR + + """ + Moldovan Leu (MDL). + """ + MDL + + """ + Moroccan Dirham. + """ + MAD + + """ + Mongolian Tugrik. + """ + MNT + + """ + Mozambican Metical. + """ + MZN + + """ + Namibian Dollar. + """ + NAD + + """ + Nepalese Rupee (NPR). + """ + NPR + + """ + Netherlands Antillean Guilder. + """ + ANG + + """ + New Zealand Dollars (NZD). + """ + NZD + + """ + Nicaraguan Córdoba (NIO). + """ + NIO + + """ + Nigerian Naira (NGN). + """ + NGN + + """ + Norwegian Kroner (NOK). + """ + NOK + + """ + Omani Rial (OMR). + """ + OMR + + """ + Panamian Balboa (PAB). + """ + PAB + + """ + Pakistani Rupee (PKR). + """ + PKR + + """ + Papua New Guinean Kina (PGK). + """ + PGK + + """ + Paraguayan Guarani (PYG). + """ + PYG + + """ + Peruvian Nuevo Sol (PEN). + """ + PEN + + """ + Philippine Peso (PHP). + """ + PHP + + """ + Polish Zlotych (PLN). + """ + PLN + + """ + Qatari Rial (QAR). + """ + QAR + + """ + Romanian Lei (RON). + """ + RON + + """ + Russian Rubles (RUB). + """ + RUB + + """ + Rwandan Franc (RWF). + """ + RWF + + """ + Samoan Tala (WST). + """ + WST + + """ + Saint Helena Pounds (SHP). + """ + SHP + + """ + Saudi Riyal (SAR). + """ + SAR + + """ + Sao Tome And Principe Dobra (STD). + """ + STD + + """ + Serbian dinar (RSD). + """ + RSD + + """ + Seychellois Rupee (SCR). + """ + SCR + + """ + Sierra Leonean Leone (SLL). + """ + SLL + + """ + Singapore Dollars (SGD). + """ + SGD + + """ + Sudanese Pound (SDG). + """ + SDG + + """ + Somali Shilling (SOS). + """ + SOS + + """ + Syrian Pound (SYP). + """ + SYP + + """ + South African Rand (ZAR). + """ + ZAR + + """ + South Korean Won (KRW). + """ + KRW + + """ + South Sudanese Pound (SSP). + """ + SSP + + """ + Solomon Islands Dollar (SBD). + """ + SBD + + """ + Sri Lankan Rupees (LKR). + """ + LKR + + """ + Surinamese Dollar (SRD). + """ + SRD + + """ + Swazi Lilangeni (SZL). + """ + SZL + + """ + Swedish Kronor (SEK). + """ + SEK + + """ + Swiss Francs (CHF). + """ + CHF + + """ + Taiwan Dollars (TWD). + """ + TWD + + """ + Thai baht (THB). + """ + THB + + """ + Tajikistani Somoni (TJS). + """ + TJS + + """ + Tanzanian Shilling (TZS). + """ + TZS + + """ + Tongan Pa'anga (TOP). + """ + TOP + + """ + Trinidad and Tobago Dollars (TTD). + """ + TTD + + """ + Tunisian Dinar (TND). + """ + TND + + """ + Turkish Lira (TRY). + """ + TRY + + """ + Turkmenistani Manat (TMT). + """ + TMT + + """ + Ugandan Shilling (UGX). + """ + UGX + + """ + Ukrainian Hryvnia (UAH). + """ + UAH + + """ + United Arab Emirates Dirham (AED). + """ + AED + + """ + Uruguayan Pesos (UYU). + """ + UYU + + """ + Uzbekistan som (UZS). + """ + UZS + + """ + Vanuatu Vatu (VUV). + """ + VUV + + """ + Venezuelan Bolivares (VEF). + """ + VEF + + """ + Venezuelan Bolivares (VES). + """ + VES + + """ + Vietnamese đồng (VND). + """ + VND + + """ + West African CFA franc (XOF). + """ + XOF + + """ + Yemeni Rial (YER). + """ + YER + + """ + Zambian Kwacha (ZMW). + """ + ZMW +} + +""" +A customer represents a customer account with the shop. Customer accounts store contact information for the customer, saving logged-in customers the trouble of having to provide it at every checkout. +""" +type Customer { + """ + Indicates whether the customer has consented to be sent marketing material via email. + """ + acceptsMarketing: Boolean! + + """ + A list of addresses for the customer. + """ + addresses( + """ + Returns up to the first `n` elements from the list. + """ + first: Int + + """ + Returns the elements that come after the specified cursor. + """ + after: String + + """ + Returns up to the last `n` elements from the list. + """ + last: Int + + """ + Returns the elements that come before the specified cursor. + """ + before: String + + """ + Reverse the order of the underlying list. + """ + reverse: Boolean = false + ): MailingAddressConnection! + + """ + The date and time when the customer was created. + """ + createdAt: DateTime! + + """ + The customer’s default address. + """ + defaultAddress: MailingAddress + + """ + The customer’s name, email or phone number. + """ + displayName: String! + + """ + The customer’s email address. + """ + email: String + + """ + The customer’s first name. + """ + firstName: String + + """ + A unique identifier for the customer. + """ + id: ID! + + """ + The customer's most recently updated, incomplete checkout. + """ + lastIncompleteCheckout: Checkout + + """ + The customer’s last name. + """ + lastName: String + + """ + The orders associated with the customer. + """ + orders( + """ + Returns up to the first `n` elements from the list. + """ + first: Int + + """ + Returns the elements that come after the specified cursor. + """ + after: String + + """ + Returns up to the last `n` elements from the list. + """ + last: Int + + """ + Returns the elements that come before the specified cursor. + """ + before: String + + """ + Reverse the order of the underlying list. + """ + reverse: Boolean = false + + """ + Sort the underlying list by the given key. + """ + sortKey: OrderSortKeys = ID + + """ + Supported filter parameters: + - `processed_at` + + See the detailed [search syntax](https://help.shopify.com/api/getting-started/search-syntax) + for more information about using filters. + """ + query: String + ): OrderConnection! + + """ + The customer’s phone number. + """ + phone: String + + """ + A comma separated list of tags that have been added to the customer. + Additional access scope required: unauthenticated_read_customer_tags. + """ + tags: [String!]! + + """ + The date and time when the customer information was updated. + """ + updatedAt: DateTime! +} + +""" +A CustomerAccessToken represents the unique token required to make modifications to the customer object. +""" +type CustomerAccessToken { + """ + The customer’s access token. + """ + accessToken: String! + + """ + The date and time when the customer access token expires. + """ + expiresAt: DateTime! +} + +""" +Specifies the input fields required to create a customer access token. +""" +input CustomerAccessTokenCreateInput { + """ + The email associated to the customer. + """ + email: String! + + """ + The login password to be used by the customer. + """ + password: String! +} + +""" +Return type for `customerAccessTokenCreate` mutation. +""" +type CustomerAccessTokenCreatePayload { + """ + The newly created customer access token object. + """ + customerAccessToken: CustomerAccessToken + + """ + List of errors that occurred executing the mutation. + """ + customerUserErrors: [CustomerUserError!]! + + """ + List of errors that occurred executing the mutation. + """ + userErrors: [UserError!]! + @deprecated(reason: "Use `customerUserErrors` instead") +} + +""" +Return type for `customerAccessTokenCreateWithMultipass` mutation. +""" +type CustomerAccessTokenCreateWithMultipassPayload { + """ + An access token object associated with the customer. + """ + customerAccessToken: CustomerAccessToken + + """ + List of errors that occurred executing the mutation. + """ + customerUserErrors: [CustomerUserError!]! +} + +""" +Return type for `customerAccessTokenDelete` mutation. +""" +type CustomerAccessTokenDeletePayload { + """ + The destroyed access token. + """ + deletedAccessToken: String + + """ + ID of the destroyed customer access token. + """ + deletedCustomerAccessTokenId: String + + """ + List of errors that occurred executing the mutation. + """ + userErrors: [UserError!]! +} + +""" +Return type for `customerAccessTokenRenew` mutation. +""" +type CustomerAccessTokenRenewPayload { + """ + The renewed customer access token object. + """ + customerAccessToken: CustomerAccessToken + + """ + List of errors that occurred executing the mutation. + """ + userErrors: [UserError!]! +} + +""" +Return type for `customerActivateByUrl` mutation. +""" +type CustomerActivateByUrlPayload { + """ + The customer that was activated. + """ + customer: Customer + + """ + A new customer access token for the customer. + """ + customerAccessToken: CustomerAccessToken + + """ + List of errors that occurred executing the mutation. + """ + customerUserErrors: [CustomerUserError!]! +} + +""" +Specifies the input fields required to activate a customer. +""" +input CustomerActivateInput { + """ + The activation token required to activate the customer. + """ + activationToken: String! + + """ + New password that will be set during activation. + """ + password: String! +} + +""" +Return type for `customerActivate` mutation. +""" +type CustomerActivatePayload { + """ + The customer object. + """ + customer: Customer + + """ + A newly created customer access token object for the customer. + """ + customerAccessToken: CustomerAccessToken + + """ + List of errors that occurred executing the mutation. + """ + customerUserErrors: [CustomerUserError!]! + + """ + List of errors that occurred executing the mutation. + """ + userErrors: [UserError!]! + @deprecated(reason: "Use `customerUserErrors` instead") +} + +""" +Return type for `customerAddressCreate` mutation. +""" +type CustomerAddressCreatePayload { + """ + The new customer address object. + """ + customerAddress: MailingAddress + + """ + List of errors that occurred executing the mutation. + """ + customerUserErrors: [CustomerUserError!]! + + """ + List of errors that occurred executing the mutation. + """ + userErrors: [UserError!]! + @deprecated(reason: "Use `customerUserErrors` instead") +} + +""" +Return type for `customerAddressDelete` mutation. +""" +type CustomerAddressDeletePayload { + """ + List of errors that occurred executing the mutation. + """ + customerUserErrors: [CustomerUserError!]! + + """ + ID of the deleted customer address. + """ + deletedCustomerAddressId: String + + """ + List of errors that occurred executing the mutation. + """ + userErrors: [UserError!]! + @deprecated(reason: "Use `customerUserErrors` instead") +} + +""" +Return type for `customerAddressUpdate` mutation. +""" +type CustomerAddressUpdatePayload { + """ + The customer’s updated mailing address. + """ + customerAddress: MailingAddress + + """ + List of errors that occurred executing the mutation. + """ + customerUserErrors: [CustomerUserError!]! + + """ + List of errors that occurred executing the mutation. + """ + userErrors: [UserError!]! + @deprecated(reason: "Use `customerUserErrors` instead") +} + +""" +Specifies the fields required to create a new customer. +""" +input CustomerCreateInput { + """ + The customer’s first name. + """ + firstName: String + + """ + The customer’s last name. + """ + lastName: String + + """ + The customer’s email. + """ + email: String! + + """ + A unique phone number for the customer. + + Formatted using E.164 standard. For example, _+16135551111_. + """ + phone: String + + """ + The login password used by the customer. + """ + password: String! + + """ + Indicates whether the customer has consented to be sent marketing material via email. + """ + acceptsMarketing: Boolean +} + +""" +Return type for `customerCreate` mutation. +""" +type CustomerCreatePayload { + """ + The created customer object. + """ + customer: Customer + + """ + List of errors that occurred executing the mutation. + """ + customerUserErrors: [CustomerUserError!]! + + """ + List of errors that occurred executing the mutation. + """ + userErrors: [UserError!]! + @deprecated(reason: "Use `customerUserErrors` instead") +} + +""" +Return type for `customerDefaultAddressUpdate` mutation. +""" +type CustomerDefaultAddressUpdatePayload { + """ + The updated customer object. + """ + customer: Customer + + """ + List of errors that occurred executing the mutation. + """ + customerUserErrors: [CustomerUserError!]! + + """ + List of errors that occurred executing the mutation. + """ + userErrors: [UserError!]! + @deprecated(reason: "Use `customerUserErrors` instead") +} + +""" +Possible error codes that could be returned by CustomerUserError. +""" +enum CustomerErrorCode { + """ + Input value is blank. + """ + BLANK + + """ + Input value is invalid. + """ + INVALID + + """ + Input value is already taken. + """ + TAKEN + + """ + Input value is too long. + """ + TOO_LONG + + """ + Input value is too short. + """ + TOO_SHORT + + """ + Unidentified customer. + """ + UNIDENTIFIED_CUSTOMER + + """ + Customer is disabled. + """ + CUSTOMER_DISABLED + + """ + Input password starts or ends with whitespace. + """ + PASSWORD_STARTS_OR_ENDS_WITH_WHITESPACE + + """ + Input contains HTML tags. + """ + CONTAINS_HTML_TAGS + + """ + Input contains URL. + """ + CONTAINS_URL + + """ + Invalid activation token. + """ + TOKEN_INVALID + + """ + Customer already enabled. + """ + ALREADY_ENABLED + + """ + Address does not exist. + """ + NOT_FOUND + + """ + Input email contains an invalid domain name. + """ + BAD_DOMAIN + + """ + Multipass token is not valid. + """ + INVALID_MULTIPASS_REQUEST +} + +""" +Return type for `customerRecover` mutation. +""" +type CustomerRecoverPayload { + """ + List of errors that occurred executing the mutation. + """ + customerUserErrors: [CustomerUserError!]! + + """ + List of errors that occurred executing the mutation. + """ + userErrors: [UserError!]! + @deprecated(reason: "Use `customerUserErrors` instead") +} + +""" +Return type for `customerResetByUrl` mutation. +""" +type CustomerResetByUrlPayload { + """ + The customer object which was reset. + """ + customer: Customer + + """ + A newly created customer access token object for the customer. + """ + customerAccessToken: CustomerAccessToken + + """ + List of errors that occurred executing the mutation. + """ + customerUserErrors: [CustomerUserError!]! + + """ + List of errors that occurred executing the mutation. + """ + userErrors: [UserError!]! + @deprecated(reason: "Use `customerUserErrors` instead") +} + +""" +Specifies the fields required to reset a customer’s password. +""" +input CustomerResetInput { + """ + The reset token required to reset the customer’s password. + """ + resetToken: String! + + """ + New password that will be set as part of the reset password process. + """ + password: String! +} + +""" +Return type for `customerReset` mutation. +""" +type CustomerResetPayload { + """ + The customer object which was reset. + """ + customer: Customer + + """ + A newly created customer access token object for the customer. + """ + customerAccessToken: CustomerAccessToken + + """ + List of errors that occurred executing the mutation. + """ + customerUserErrors: [CustomerUserError!]! + + """ + List of errors that occurred executing the mutation. + """ + userErrors: [UserError!]! + @deprecated(reason: "Use `customerUserErrors` instead") +} + +""" +Specifies the fields required to update the Customer information. +""" +input CustomerUpdateInput { + """ + The customer’s first name. + """ + firstName: String + + """ + The customer’s last name. + """ + lastName: String + + """ + The customer’s email. + """ + email: String + + """ + A unique phone number for the customer. + + Formatted using E.164 standard. For example, _+16135551111_. To remove the phone number, specify `null`. + """ + phone: String + + """ + The login password used by the customer. + """ + password: String + + """ + Indicates whether the customer has consented to be sent marketing material via email. + """ + acceptsMarketing: Boolean +} + +""" +Return type for `customerUpdate` mutation. +""" +type CustomerUpdatePayload { + """ + The updated customer object. + """ + customer: Customer + + """ + The newly created customer access token. If the customer's password is updated, all previous access tokens + (including the one used to perform this mutation) become invalid, and a new token is generated. + """ + customerAccessToken: CustomerAccessToken + + """ + List of errors that occurred executing the mutation. + """ + customerUserErrors: [CustomerUserError!]! + + """ + List of errors that occurred executing the mutation. + """ + userErrors: [UserError!]! + @deprecated(reason: "Use `customerUserErrors` instead") +} + +""" +Represents an error that happens during execution of a customer mutation. +""" +type CustomerUserError implements DisplayableError { + """ + Error code to uniquely identify the error. + """ + code: CustomerErrorCode + + """ + Path to the input field which caused the error. + """ + field: [String!] + + """ + The error message. + """ + message: String! +} + +""" +An ISO-8601 encoded UTC date time string. Example value: `"2019-07-03T20:47:55Z"`. +""" +scalar DateTime + +""" +A signed decimal number, which supports arbitrary precision and is serialized as a string. Example value: `"29.99"`. +""" +scalar Decimal + +""" +Digital wallet, such as Apple Pay, which can be used for accelerated checkouts. +""" +enum DigitalWallet { + """ + Apple Pay. + """ + APPLE_PAY + + """ + Android Pay. + """ + ANDROID_PAY + + """ + Google Pay. + """ + GOOGLE_PAY + + """ + Shopify Pay. + """ + SHOPIFY_PAY +} + +""" +An amount discounting the line that has been allocated by a discount. +""" +type DiscountAllocation { + """ + Amount of discount allocated. + """ + allocatedAmount: MoneyV2! + + """ + The discount this allocated amount originated from. + """ + discountApplication: DiscountApplication! +} + +""" +Discount applications capture the intentions of a discount source at +the time of application. +""" +interface DiscountApplication { + """ + The method by which the discount's value is allocated to its entitled items. + """ + allocationMethod: DiscountApplicationAllocationMethod! + + """ + Which lines of targetType that the discount is allocated over. + """ + targetSelection: DiscountApplicationTargetSelection! + + """ + The type of line that the discount is applicable towards. + """ + targetType: DiscountApplicationTargetType! + + """ + The value of the discount application. + """ + value: PricingValue! +} + +""" +The method by which the discount's value is allocated onto its entitled lines. +""" +enum DiscountApplicationAllocationMethod { + """ + The value is spread across all entitled lines. + """ + ACROSS + + """ + The value is applied onto every entitled line. + """ + EACH + + """ + The value is specifically applied onto a particular line. + """ + ONE +} + +""" +An auto-generated type for paginating through multiple DiscountApplications. +""" +type DiscountApplicationConnection { + """ + A list of edges. + """ + edges: [DiscountApplicationEdge!]! + + """ + Information to aid in pagination. + """ + pageInfo: PageInfo! +} + +""" +An auto-generated type which holds one DiscountApplication and a cursor during pagination. +""" +type DiscountApplicationEdge { + """ + A cursor for use in pagination. + """ + cursor: String! + + """ + The item at the end of DiscountApplicationEdge. + """ + node: DiscountApplication! +} + +""" +Which lines on the order that the discount is allocated over, of the type +defined by the Discount Application's target_type. +""" +enum DiscountApplicationTargetSelection { + """ + The discount is allocated onto all the lines. + """ + ALL + + """ + The discount is allocated onto only the lines it is entitled for. + """ + ENTITLED + + """ + The discount is allocated onto explicitly chosen lines. + """ + EXPLICIT +} + +""" +The type of line (i.e. line item or shipping line) on an order that the discount is applicable towards. +""" +enum DiscountApplicationTargetType { + """ + The discount applies onto line items. + """ + LINE_ITEM + + """ + The discount applies onto shipping lines. + """ + SHIPPING_LINE +} + +""" +Discount code applications capture the intentions of a discount code at +the time that it is applied. +""" +type DiscountCodeApplication implements DiscountApplication { + """ + The method by which the discount's value is allocated to its entitled items. + """ + allocationMethod: DiscountApplicationAllocationMethod! + + """ + Specifies whether the discount code was applied successfully. + """ + applicable: Boolean! + + """ + The string identifying the discount code that was used at the time of application. + """ + code: String! + + """ + Which lines of targetType that the discount is allocated over. + """ + targetSelection: DiscountApplicationTargetSelection! + + """ + The type of line that the discount is applicable towards. + """ + targetType: DiscountApplicationTargetType! + + """ + The value of the discount application. + """ + value: PricingValue! +} + +""" +Represents an error in the input of a mutation. +""" +interface DisplayableError { + """ + Path to the input field which caused the error. + """ + field: [String!] + + """ + The error message. + """ + message: String! +} + +""" +Represents a web address. +""" +type Domain { + """ + The host name of the domain (eg: `example.com`). + """ + host: String! + + """ + Whether SSL is enabled or not. + """ + sslEnabled: Boolean! + + """ + The URL of the domain (eg: `https://example.com`). + """ + url: URL! +} + +""" +Represents a video hosted outside of Shopify. +""" +type ExternalVideo implements Node & Media { + """ + A word or phrase to share the nature or contents of a media. + """ + alt: String + + """ + The URL. + """ + embeddedUrl: URL! + + """ + Globally unique identifier. + """ + id: ID! + + """ + The media content type. + """ + mediaContentType: MediaContentType! + + """ + The preview image for the media. + """ + previewImage: Image +} + +""" +Represents a single fulfillment in an order. +""" +type Fulfillment { + """ + List of the fulfillment's line items. + """ + fulfillmentLineItems( + """ + Returns up to the first `n` elements from the list. + """ + first: Int + + """ + Returns the elements that come after the specified cursor. + """ + after: String + + """ + Returns up to the last `n` elements from the list. + """ + last: Int + + """ + Returns the elements that come before the specified cursor. + """ + before: String + + """ + Reverse the order of the underlying list. + """ + reverse: Boolean = false + ): FulfillmentLineItemConnection! + + """ + The name of the tracking company. + """ + trackingCompany: String + + """ + Tracking information associated with the fulfillment, + such as the tracking number and tracking URL. + """ + trackingInfo( + """ + Truncate the array result to this size. + """ + first: Int + ): [FulfillmentTrackingInfo!]! +} + +""" +Represents a single line item in a fulfillment. There is at most one fulfillment line item for each order line item. +""" +type FulfillmentLineItem { + """ + The associated order's line item. + """ + lineItem: OrderLineItem! + + """ + The amount fulfilled in this fulfillment. + """ + quantity: Int! +} + +""" +An auto-generated type for paginating through multiple FulfillmentLineItems. +""" +type FulfillmentLineItemConnection { + """ + A list of edges. + """ + edges: [FulfillmentLineItemEdge!]! + + """ + Information to aid in pagination. + """ + pageInfo: PageInfo! +} + +""" +An auto-generated type which holds one FulfillmentLineItem and a cursor during pagination. +""" +type FulfillmentLineItemEdge { + """ + A cursor for use in pagination. + """ + cursor: String! + + """ + The item at the end of FulfillmentLineItemEdge. + """ + node: FulfillmentLineItem! +} + +""" +Tracking information associated with the fulfillment. +""" +type FulfillmentTrackingInfo { + """ + The tracking number of the fulfillment. + """ + number: String + + """ + The URL to track the fulfillment. + """ + url: URL +} + +""" +A string containing HTML code. Example value: `"

    Grey cotton knit sweater.

    "`. +""" +scalar HTML + +""" +Represents information about the metafields associated to the specified resource. +""" +interface HasMetafields { + """ + The metafield associated with the resource. + """ + metafield( + """ + Container for a set of metafields (maximum of 20 characters). + """ + namespace: String! + + """ + Identifier for the metafield (maximum of 30 characters). + """ + key: String! + ): Metafield + + """ + A paginated list of metafields associated with the resource. + """ + metafields( + """ + Container for a set of metafields (maximum of 20 characters). + """ + namespace: String + + """ + Returns up to the first `n` elements from the list. + """ + first: Int + + """ + Returns the elements that come after the specified cursor. + """ + after: String + + """ + Returns up to the last `n` elements from the list. + """ + last: Int + + """ + Returns the elements that come before the specified cursor. + """ + before: String + + """ + Reverse the order of the underlying list. + """ + reverse: Boolean = false + ): MetafieldConnection! +} + +""" +Represents an image resource. +""" +type Image { + """ + A word or phrase to share the nature or contents of an image. + """ + altText: String + + """ + The original height of the image in pixels. Returns `null` if the image is not hosted by Shopify. + """ + height: Int + + """ + A unique identifier for the image. + """ + id: ID + + """ + The location of the original image as a URL. + + If there are any existing transformations in the original source URL, they will remain and not be stripped. + """ + originalSrc: URL! + + """ + The location of the image as a URL. + """ + src: URL! + @deprecated( + reason: "Previously an image had a single `src` field. This could either return the original image\nlocation or a URL that contained transformations such as sizing or scale.\n\nThese transformations were specified by arguments on the parent field.\n\nNow an image has two distinct URL fields: `originalSrc` and `transformedSrc`.\n\n* `originalSrc` - the original unmodified image URL\n* `transformedSrc` - the image URL with the specified transformations included\n\nTo migrate to the new fields, image transformations should be moved from the parent field to `transformedSrc`.\n\nBefore:\n```graphql\n{\n shop {\n productImages(maxWidth: 200, scale: 2) {\n edges {\n node {\n src\n }\n }\n }\n }\n}\n```\n\nAfter:\n```graphql\n{\n shop {\n productImages {\n edges {\n node {\n transformedSrc(maxWidth: 200, scale: 2)\n }\n }\n }\n }\n}\n```\n" + ) + + """ + The location of the transformed image as a URL. + + All transformation arguments are considered "best-effort". If they can be applied to an image, they will be. + Otherwise any transformations which an image type does not support will be ignored. + """ + transformedSrc( + """ + Image width in pixels between 1 and 5760. + """ + maxWidth: Int + + """ + Image height in pixels between 1 and 5760. + """ + maxHeight: Int + + """ + Crops the image according to the specified region. + """ + crop: CropRegion + + """ + Image size multiplier for high-resolution retina displays. Must be between 1 and 3. + """ + scale: Int = 1 + + """ + Best effort conversion of image into content type (SVG -> PNG, Anything -> JGP, Anything -> WEBP are supported). + """ + preferredContentType: ImageContentType + ): URL! + + """ + The original width of the image in pixels. Returns `null` if the image is not hosted by Shopify. + """ + width: Int +} + +""" +An auto-generated type for paginating through multiple Images. +""" +type ImageConnection { + """ + A list of edges. + """ + edges: [ImageEdge!]! + + """ + Information to aid in pagination. + """ + pageInfo: PageInfo! +} + +""" +List of supported image content types. +""" +enum ImageContentType { + """ + A PNG image. + """ + PNG + + """ + A JPG image. + """ + JPG + + """ + A WEBP image. + """ + WEBP +} + +""" +An auto-generated type which holds one Image and a cursor during pagination. +""" +type ImageEdge { + """ + A cursor for use in pagination. + """ + cursor: String! + + """ + The item at the end of ImageEdge. + """ + node: Image! +} + +""" +Represents a mailing address for customers and shipping. +""" +type MailingAddress implements Node { + """ + The first line of the address. Typically the street address or PO Box number. + """ + address1: String + + """ + The second line of the address. Typically the number of the apartment, suite, or unit. + """ + address2: String + + """ + The name of the city, district, village, or town. + """ + city: String + + """ + The name of the customer's company or organization. + """ + company: String + + """ + The name of the country. + """ + country: String + + """ + The two-letter code for the country of the address. + + For example, US. + """ + countryCode: String @deprecated(reason: "Use `countryCodeV2` instead") + + """ + The two-letter code for the country of the address. + + For example, US. + """ + countryCodeV2: CountryCode + + """ + The first name of the customer. + """ + firstName: String + + """ + A formatted version of the address, customized by the provided arguments. + """ + formatted( + """ + Whether to include the customer's name in the formatted address. + """ + withName: Boolean = false + + """ + Whether to include the customer's company in the formatted address. + """ + withCompany: Boolean = true + ): [String!]! + + """ + A comma-separated list of the values for city, province, and country. + """ + formattedArea: String + + """ + Globally unique identifier. + """ + id: ID! + + """ + The last name of the customer. + """ + lastName: String + + """ + The latitude coordinate of the customer address. + """ + latitude: Float + + """ + The longitude coordinate of the customer address. + """ + longitude: Float + + """ + The full name of the customer, based on firstName and lastName. + """ + name: String + + """ + A unique phone number for the customer. + + Formatted using E.164 standard. For example, _+16135551111_. + """ + phone: String + + """ + The region of the address, such as the province, state, or district. + """ + province: String + + """ + The two-letter code for the region. + + For example, ON. + """ + provinceCode: String + + """ + The zip or postal code of the address. + """ + zip: String +} + +""" +An auto-generated type for paginating through multiple MailingAddresses. +""" +type MailingAddressConnection { + """ + A list of edges. + """ + edges: [MailingAddressEdge!]! + + """ + Information to aid in pagination. + """ + pageInfo: PageInfo! +} + +""" +An auto-generated type which holds one MailingAddress and a cursor during pagination. +""" +type MailingAddressEdge { + """ + A cursor for use in pagination. + """ + cursor: String! + + """ + The item at the end of MailingAddressEdge. + """ + node: MailingAddress! +} + +""" +Specifies the fields accepted to create or update a mailing address. +""" +input MailingAddressInput { + """ + The first line of the address. Typically the street address or PO Box number. + """ + address1: String + + """ + The second line of the address. Typically the number of the apartment, suite, or unit. + """ + address2: String + + """ + The name of the city, district, village, or town. + """ + city: String + + """ + The name of the customer's company or organization. + """ + company: String + + """ + The name of the country. + """ + country: String + + """ + The first name of the customer. + """ + firstName: String + + """ + The last name of the customer. + """ + lastName: String + + """ + A unique phone number for the customer. + + Formatted using E.164 standard. For example, _+16135551111_. + """ + phone: String + + """ + The region of the address, such as the province, state, or district. + """ + province: String + + """ + The zip or postal code of the address. + """ + zip: String +} + +""" +Manual discount applications capture the intentions of a discount that was manually created. +""" +type ManualDiscountApplication implements DiscountApplication { + """ + The method by which the discount's value is allocated to its entitled items. + """ + allocationMethod: DiscountApplicationAllocationMethod! + + """ + The description of the application. + """ + description: String + + """ + Which lines of targetType that the discount is allocated over. + """ + targetSelection: DiscountApplicationTargetSelection! + + """ + The type of line that the discount is applicable towards. + """ + targetType: DiscountApplicationTargetType! + + """ + The title of the application. + """ + title: String! + + """ + The value of the discount application. + """ + value: PricingValue! +} + +""" +Represents a media interface. +""" +interface Media { + """ + A word or phrase to share the nature or contents of a media. + """ + alt: String + + """ + The media content type. + """ + mediaContentType: MediaContentType! + + """ + The preview image for the media. + """ + previewImage: Image +} + +""" +An auto-generated type for paginating through multiple Media. +""" +type MediaConnection { + """ + A list of edges. + """ + edges: [MediaEdge!]! + + """ + Information to aid in pagination. + """ + pageInfo: PageInfo! +} + +""" +The possible content types for a media object. +""" +enum MediaContentType { + """ + An externally hosted video. + """ + EXTERNAL_VIDEO + + """ + A Shopify hosted image. + """ + IMAGE + + """ + A 3d model. + """ + MODEL_3D + + """ + A Shopify hosted video. + """ + VIDEO +} + +""" +An auto-generated type which holds one Media and a cursor during pagination. +""" +type MediaEdge { + """ + A cursor for use in pagination. + """ + cursor: String! + + """ + The item at the end of MediaEdge. + """ + node: Media! +} + +""" +Represents a Shopify hosted image. +""" +type MediaImage implements Node & Media { + """ + A word or phrase to share the nature or contents of a media. + """ + alt: String + + """ + Globally unique identifier. + """ + id: ID! + + """ + The image for the media. + """ + image: Image + + """ + The media content type. + """ + mediaContentType: MediaContentType! + + """ + The preview image for the media. + """ + previewImage: Image +} + +""" +Metafields represent custom metadata attached to a resource. Metafields can be sorted into namespaces and are +comprised of keys, values, and value types. +""" +type Metafield implements Node { + """ + The date and time when the storefront metafield was created. + """ + createdAt: DateTime! + + """ + The description of a metafield. + """ + description: String + + """ + Globally unique identifier. + """ + id: ID! + + """ + The key name for a metafield. + """ + key: String! + + """ + The namespace for a metafield. + """ + namespace: String! + + """ + The parent object that the metafield belongs to. + """ + parentResource: MetafieldParentResource! + + """ + The date and time when the storefront metafield was updated. + """ + updatedAt: DateTime! + + """ + The value of a metafield. + """ + value: String! + + """ + Represents the metafield value type. + """ + valueType: MetafieldValueType! +} + +""" +An auto-generated type for paginating through multiple Metafields. +""" +type MetafieldConnection { + """ + A list of edges. + """ + edges: [MetafieldEdge!]! + + """ + Information to aid in pagination. + """ + pageInfo: PageInfo! +} + +""" +An auto-generated type which holds one Metafield and a cursor during pagination. +""" +type MetafieldEdge { + """ + A cursor for use in pagination. + """ + cursor: String! + + """ + The item at the end of MetafieldEdge. + """ + node: Metafield! +} + +""" +A resource that the metafield belongs to. +""" +union MetafieldParentResource = Product | ProductVariant + +""" +Metafield value types. +""" +enum MetafieldValueType { + """ + A string metafield. + """ + STRING + + """ + An integer metafield. + """ + INTEGER + + """ + A json string metafield. + """ + JSON_STRING +} + +""" +Represents a Shopify hosted 3D model. +""" +type Model3d implements Node & Media { + """ + A word or phrase to share the nature or contents of a media. + """ + alt: String + + """ + Globally unique identifier. + """ + id: ID! + + """ + The media content type. + """ + mediaContentType: MediaContentType! + + """ + The preview image for the media. + """ + previewImage: Image + + """ + The sources for a 3d model. + """ + sources: [Model3dSource!]! +} + +""" +Represents a source for a Shopify hosted 3d model. +""" +type Model3dSource { + """ + The filesize of the 3d model. + """ + filesize: Int! + + """ + The format of the 3d model. + """ + format: String! + + """ + The MIME type of the 3d model. + """ + mimeType: String! + + """ + The URL of the 3d model. + """ + url: String! +} + +""" +A monetary value string. Example value: `"100.57"`. +""" +scalar Money + +""" +Specifies the fields for a monetary value with currency. +""" +input MoneyInput { + """ + Decimal money amount. + """ + amount: Decimal! + + """ + Currency of the money. + """ + currencyCode: CurrencyCode! +} + +""" +A monetary value with currency. + +To format currencies, combine this type's amount and currencyCode fields with your client's locale. + +For example, in JavaScript you could use Intl.NumberFormat: + +```js +new Intl.NumberFormat(locale, { + style: 'currency', + currency: currencyCode +}).format(amount); +``` + +Other formatting libraries include: + +* iOS - [NumberFormatter](https://developer.apple.com/documentation/foundation/numberformatter) +* Android - [NumberFormat](https://developer.android.com/reference/java/text/NumberFormat.html) +* PHP - [NumberFormatter](http://php.net/manual/en/class.numberformatter.php) + +For a more general solution, the [Unicode CLDR number formatting database] is available with many implementations +(such as [TwitterCldr](https://github.com/twitter/twitter-cldr-rb)). +""" +type MoneyV2 { + """ + Decimal money amount. + """ + amount: Decimal! + + """ + Currency of the money. + """ + currencyCode: CurrencyCode! +} + +""" +An auto-generated type for paginating through multiple MoneyV2s. +""" +type MoneyV2Connection { + """ + A list of edges. + """ + edges: [MoneyV2Edge!]! + + """ + Information to aid in pagination. + """ + pageInfo: PageInfo! +} + +""" +An auto-generated type which holds one MoneyV2 and a cursor during pagination. +""" +type MoneyV2Edge { + """ + A cursor for use in pagination. + """ + cursor: String! + + """ + The item at the end of MoneyV2Edge. + """ + node: MoneyV2! +} + +""" +The schema’s entry-point for mutations. This acts as the public, top-level API from which all mutation queries must start. +""" +type Mutation { + """ + Updates the attributes of a checkout. + """ + checkoutAttributesUpdate( + """ + The ID of the checkout. + """ + checkoutId: ID! + + """ + The fields used to update a checkout's attributes. + """ + input: CheckoutAttributesUpdateInput! + ): CheckoutAttributesUpdatePayload + @deprecated(reason: "Use `checkoutAttributesUpdateV2` instead") + + """ + Updates the attributes of a checkout. + """ + checkoutAttributesUpdateV2( + """ + The ID of the checkout. + """ + checkoutId: ID! + + """ + The checkout attributes to update. + """ + input: CheckoutAttributesUpdateV2Input! + ): CheckoutAttributesUpdateV2Payload + + """ + Completes a checkout without providing payment information. You can use this mutation for free items or items whose purchase price is covered by a gift card. + """ + checkoutCompleteFree( + """ + The ID of the checkout. + """ + checkoutId: ID! + ): CheckoutCompleteFreePayload + + """ + Completes a checkout using a credit card token from Shopify's Vault. + """ + checkoutCompleteWithCreditCard( + """ + The ID of the checkout. + """ + checkoutId: ID! + + """ + The credit card info to apply as a payment. + """ + payment: CreditCardPaymentInput! + ): CheckoutCompleteWithCreditCardPayload + @deprecated(reason: "Use `checkoutCompleteWithCreditCardV2` instead") + + """ + Completes a checkout using a credit card token from Shopify's card vault. Before you can complete checkouts using CheckoutCompleteWithCreditCardV2, you need to [_request payment processing_](https://help.shopify.com/api/guides/sales-channel-sdk/getting-started#request-payment-processing). + """ + checkoutCompleteWithCreditCardV2( + """ + The ID of the checkout. + """ + checkoutId: ID! + + """ + The credit card info to apply as a payment. + """ + payment: CreditCardPaymentInputV2! + ): CheckoutCompleteWithCreditCardV2Payload + + """ + Completes a checkout with a tokenized payment. + """ + checkoutCompleteWithTokenizedPayment( + """ + The ID of the checkout. + """ + checkoutId: ID! + + """ + The info to apply as a tokenized payment. + """ + payment: TokenizedPaymentInput! + ): CheckoutCompleteWithTokenizedPaymentPayload + @deprecated(reason: "Use `checkoutCompleteWithTokenizedPaymentV2` instead") + + """ + Completes a checkout with a tokenized payment. + """ + checkoutCompleteWithTokenizedPaymentV2( + """ + The ID of the checkout. + """ + checkoutId: ID! + + """ + The info to apply as a tokenized payment. + """ + payment: TokenizedPaymentInputV2! + ): CheckoutCompleteWithTokenizedPaymentV2Payload + @deprecated(reason: "Use `checkoutCompleteWithTokenizedPaymentV3` instead") + + """ + Completes a checkout with a tokenized payment. + """ + checkoutCompleteWithTokenizedPaymentV3( + """ + The ID of the checkout. + """ + checkoutId: ID! + + """ + The info to apply as a tokenized payment. + """ + payment: TokenizedPaymentInputV3! + ): CheckoutCompleteWithTokenizedPaymentV3Payload + + """ + Creates a new checkout. + """ + checkoutCreate( + """ + The fields used to create a checkout. + """ + input: CheckoutCreateInput! + ): CheckoutCreatePayload + + """ + Associates a customer to the checkout. + """ + checkoutCustomerAssociate( + """ + The ID of the checkout. + """ + checkoutId: ID! + + """ + The customer access token of the customer to associate. + """ + customerAccessToken: String! + ): CheckoutCustomerAssociatePayload + @deprecated(reason: "Use `checkoutCustomerAssociateV2` instead") + + """ + Associates a customer to the checkout. + """ + checkoutCustomerAssociateV2( + """ + The ID of the checkout. + """ + checkoutId: ID! + + """ + The customer access token of the customer to associate. + """ + customerAccessToken: String! + ): CheckoutCustomerAssociateV2Payload + + """ + Disassociates the current checkout customer from the checkout. + """ + checkoutCustomerDisassociate( + """ + The ID of the checkout. + """ + checkoutId: ID! + ): CheckoutCustomerDisassociatePayload + @deprecated(reason: "Use `checkoutCustomerDisassociateV2` instead") + + """ + Disassociates the current checkout customer from the checkout. + """ + checkoutCustomerDisassociateV2( + """ + The ID of the checkout. + """ + checkoutId: ID! + ): CheckoutCustomerDisassociateV2Payload + + """ + Applies a discount to an existing checkout using a discount code. + """ + checkoutDiscountCodeApply( + """ + The discount code to apply to the checkout. + """ + discountCode: String! + + """ + The ID of the checkout. + """ + checkoutId: ID! + ): CheckoutDiscountCodeApplyPayload + @deprecated(reason: "Use `checkoutDiscountCodeApplyV2` instead") + + """ + Applies a discount to an existing checkout using a discount code. + """ + checkoutDiscountCodeApplyV2( + """ + The discount code to apply to the checkout. + """ + discountCode: String! + + """ + The ID of the checkout. + """ + checkoutId: ID! + ): CheckoutDiscountCodeApplyV2Payload + + """ + Removes the applied discount from an existing checkout. + """ + checkoutDiscountCodeRemove( + """ + The ID of the checkout. + """ + checkoutId: ID! + ): CheckoutDiscountCodeRemovePayload + + """ + Updates the email on an existing checkout. + """ + checkoutEmailUpdate( + """ + The ID of the checkout. + """ + checkoutId: ID! + + """ + The email to update the checkout with. + """ + email: String! + ): CheckoutEmailUpdatePayload + @deprecated(reason: "Use `checkoutEmailUpdateV2` instead") + + """ + Updates the email on an existing checkout. + """ + checkoutEmailUpdateV2( + """ + The ID of the checkout. + """ + checkoutId: ID! + + """ + The email to update the checkout with. + """ + email: String! + ): CheckoutEmailUpdateV2Payload + + """ + Applies a gift card to an existing checkout using a gift card code. This will replace all currently applied gift cards. + """ + checkoutGiftCardApply( + """ + The code of the gift card to apply on the checkout. + """ + giftCardCode: String! + + """ + The ID of the checkout. + """ + checkoutId: ID! + ): CheckoutGiftCardApplyPayload + @deprecated(reason: "Use `checkoutGiftCardsAppend` instead") + + """ + Removes an applied gift card from the checkout. + """ + checkoutGiftCardRemove( + """ + The ID of the Applied Gift Card to remove from the Checkout. + """ + appliedGiftCardId: ID! + + """ + The ID of the checkout. + """ + checkoutId: ID! + ): CheckoutGiftCardRemovePayload + @deprecated(reason: "Use `checkoutGiftCardRemoveV2` instead") + + """ + Removes an applied gift card from the checkout. + """ + checkoutGiftCardRemoveV2( + """ + The ID of the Applied Gift Card to remove from the Checkout. + """ + appliedGiftCardId: ID! + + """ + The ID of the checkout. + """ + checkoutId: ID! + ): CheckoutGiftCardRemoveV2Payload + + """ + Appends gift cards to an existing checkout. + """ + checkoutGiftCardsAppend( + """ + A list of gift card codes to append to the checkout. + """ + giftCardCodes: [String!]! + + """ + The ID of the checkout. + """ + checkoutId: ID! + ): CheckoutGiftCardsAppendPayload + + """ + Adds a list of line items to a checkout. + """ + checkoutLineItemsAdd( + """ + A list of line item objects to add to the checkout. + """ + lineItems: [CheckoutLineItemInput!]! + + """ + The ID of the checkout. + """ + checkoutId: ID! + ): CheckoutLineItemsAddPayload + + """ + Removes line items from an existing checkout. + """ + checkoutLineItemsRemove( + """ + The checkout on which to remove line items. + """ + checkoutId: ID! + + """ + Line item ids to remove. + """ + lineItemIds: [ID!]! + ): CheckoutLineItemsRemovePayload + + """ + Sets a list of line items to a checkout. + """ + checkoutLineItemsReplace( + """ + A list of line item objects to set on the checkout. + """ + lineItems: [CheckoutLineItemInput!]! + + """ + The ID of the checkout. + """ + checkoutId: ID! + ): CheckoutLineItemsReplacePayload + + """ + Updates line items on a checkout. + """ + checkoutLineItemsUpdate( + """ + The checkout on which to update line items. + """ + checkoutId: ID! + + """ + Line items to update. + """ + lineItems: [CheckoutLineItemUpdateInput!]! + ): CheckoutLineItemsUpdatePayload + + """ + Updates the shipping address of an existing checkout. + """ + checkoutShippingAddressUpdate( + """ + The shipping address to where the line items will be shipped. + """ + shippingAddress: MailingAddressInput! + + """ + The ID of the checkout. + """ + checkoutId: ID! + ): CheckoutShippingAddressUpdatePayload + @deprecated(reason: "Use `checkoutShippingAddressUpdateV2` instead") + + """ + Updates the shipping address of an existing checkout. + """ + checkoutShippingAddressUpdateV2( + """ + The shipping address to where the line items will be shipped. + """ + shippingAddress: MailingAddressInput! + + """ + The ID of the checkout. + """ + checkoutId: ID! + ): CheckoutShippingAddressUpdateV2Payload + + """ + Updates the shipping lines on an existing checkout. + """ + checkoutShippingLineUpdate( + """ + The ID of the checkout. + """ + checkoutId: ID! + + """ + A unique identifier to a Checkout’s shipping provider, price, and title combination, enabling the customer to select the availableShippingRates. + """ + shippingRateHandle: String! + ): CheckoutShippingLineUpdatePayload + + """ + Creates a customer access token. + The customer access token is required to modify the customer object in any way. + """ + customerAccessTokenCreate( + """ + The fields used to create a customer access token. + """ + input: CustomerAccessTokenCreateInput! + ): CustomerAccessTokenCreatePayload + + """ + Creates a customer access token using a multipass token instead of email and password. + A customer record is created if customer does not exist. If a customer record already + exists but the record is disabled, then it's enabled. + """ + customerAccessTokenCreateWithMultipass( + """ + A valid multipass token to be authenticated. + """ + multipassToken: String! + ): CustomerAccessTokenCreateWithMultipassPayload + + """ + Permanently destroys a customer access token. + """ + customerAccessTokenDelete( + """ + The access token used to identify the customer. + """ + customerAccessToken: String! + ): CustomerAccessTokenDeletePayload + + """ + Renews a customer access token. + + Access token renewal must happen *before* a token expires. + If a token has already expired, a new one should be created instead via `customerAccessTokenCreate`. + """ + customerAccessTokenRenew( + """ + The access token used to identify the customer. + """ + customerAccessToken: String! + ): CustomerAccessTokenRenewPayload + + """ + Activates a customer. + """ + customerActivate( + """ + Specifies the customer to activate. + """ + id: ID! + + """ + The fields used to activate a customer. + """ + input: CustomerActivateInput! + ): CustomerActivatePayload + + """ + Activates a customer with the activation url received from `customerCreate`. + """ + customerActivateByUrl( + """ + The customer activation URL. + """ + activationUrl: URL! + + """ + A new password set during activation. + """ + password: String! + ): CustomerActivateByUrlPayload + + """ + Creates a new address for a customer. + """ + customerAddressCreate( + """ + The access token used to identify the customer. + """ + customerAccessToken: String! + + """ + The customer mailing address to create. + """ + address: MailingAddressInput! + ): CustomerAddressCreatePayload + + """ + Permanently deletes the address of an existing customer. + """ + customerAddressDelete( + """ + Specifies the address to delete. + """ + id: ID! + + """ + The access token used to identify the customer. + """ + customerAccessToken: String! + ): CustomerAddressDeletePayload + + """ + Updates the address of an existing customer. + """ + customerAddressUpdate( + """ + The access token used to identify the customer. + """ + customerAccessToken: String! + + """ + Specifies the customer address to update. + """ + id: ID! + + """ + The customer’s mailing address. + """ + address: MailingAddressInput! + ): CustomerAddressUpdatePayload + + """ + Creates a new customer. + """ + customerCreate( + """ + The fields used to create a new customer. + """ + input: CustomerCreateInput! + ): CustomerCreatePayload + + """ + Updates the default address of an existing customer. + """ + customerDefaultAddressUpdate( + """ + The access token used to identify the customer. + """ + customerAccessToken: String! + + """ + ID of the address to set as the new default for the customer. + """ + addressId: ID! + ): CustomerDefaultAddressUpdatePayload + + """ + Sends a reset password email to the customer, as the first step in the reset password process. + """ + customerRecover( + """ + The email address of the customer to recover. + """ + email: String! + ): CustomerRecoverPayload + + """ + Resets a customer’s password with a token received from `CustomerRecover`. + """ + customerReset( + """ + Specifies the customer to reset. + """ + id: ID! + + """ + The fields used to reset a customer’s password. + """ + input: CustomerResetInput! + ): CustomerResetPayload + + """ + Resets a customer’s password with the reset password url received from `CustomerRecover`. + """ + customerResetByUrl( + """ + The customer's reset password url. + """ + resetUrl: URL! + + """ + New password that will be set as part of the reset password process. + """ + password: String! + ): CustomerResetByUrlPayload + + """ + Updates an existing customer. + """ + customerUpdate( + """ + The access token used to identify the customer. + """ + customerAccessToken: String! + + """ + The customer object input. + """ + customer: CustomerUpdateInput! + ): CustomerUpdatePayload +} + +""" +An object with an ID to support global identification. +""" +interface Node { + """ + Globally unique identifier. + """ + id: ID! +} + +""" +An order is a customer’s completed request to purchase one or more products from a shop. An order is created when a customer completes the checkout process, during which time they provides an email address, billing address and payment information. +""" +type Order implements Node { + """ + The reason for the order's cancellation. Returns `null` if the order wasn't canceled. + """ + cancelReason: OrderCancelReason + + """ + The date and time when the order was canceled. Returns null if the order wasn't canceled. + """ + canceledAt: DateTime + + """ + The code of the currency used for the payment. + """ + currencyCode: CurrencyCode! + + """ + The subtotal of line items and their discounts, excluding line items that have been removed. Does not contain order-level discounts, duties, shipping costs, or shipping discounts. Taxes are not included unless the order is a taxes-included order. + """ + currentSubtotalPrice: MoneyV2! + + """ + The total amount of the order, including duties, taxes and discounts, minus amounts for line items that have been removed. + """ + currentTotalPrice: MoneyV2! + + """ + The total of all taxes applied to the order, excluding taxes for returned line items. + """ + currentTotalTax: MoneyV2! + + """ + The locale code in which this specific order happened. + """ + customerLocale: String + + """ + The unique URL that the customer can use to access the order. + """ + customerUrl: URL + + """ + Discounts that have been applied on the order. + """ + discountApplications( + """ + Returns up to the first `n` elements from the list. + """ + first: Int + + """ + Returns the elements that come after the specified cursor. + """ + after: String + + """ + Returns up to the last `n` elements from the list. + """ + last: Int + + """ + Returns the elements that come before the specified cursor. + """ + before: String + + """ + Reverse the order of the underlying list. + """ + reverse: Boolean = false + ): DiscountApplicationConnection! + + """ + Whether the order has had any edits applied or not. + """ + edited: Boolean! + + """ + The customer's email address. + """ + email: String + + """ + The financial status of the order. + """ + financialStatus: OrderFinancialStatus + + """ + The fulfillment status for the order. + """ + fulfillmentStatus: OrderFulfillmentStatus! + + """ + Globally unique identifier. + """ + id: ID! + + """ + List of the order’s line items. + """ + lineItems( + """ + Returns up to the first `n` elements from the list. + """ + first: Int + + """ + Returns the elements that come after the specified cursor. + """ + after: String + + """ + Returns up to the last `n` elements from the list. + """ + last: Int + + """ + Returns the elements that come before the specified cursor. + """ + before: String + + """ + Reverse the order of the underlying list. + """ + reverse: Boolean = false + ): OrderLineItemConnection! + + """ + Unique identifier for the order that appears on the order. + For example, _#1000_ or _Store1001. + """ + name: String! + + """ + A unique numeric identifier for the order for use by shop owner and customer. + """ + orderNumber: Int! + + """ + The total price of the order before any applied edits. + """ + originalTotalPrice: MoneyV2! + + """ + The customer's phone number for receiving SMS notifications. + """ + phone: String + + """ + The date and time when the order was imported. + This value can be set to dates in the past when importing from other systems. + If no value is provided, it will be auto-generated based on current date and time. + """ + processedAt: DateTime! + + """ + The address to where the order will be shipped. + """ + shippingAddress: MailingAddress + + """ + The discounts that have been allocated onto the shipping line by discount applications. + """ + shippingDiscountAllocations: [DiscountAllocation!]! + + """ + The unique URL for the order's status page. + """ + statusUrl: URL! + + """ + Price of the order before shipping and taxes. + """ + subtotalPrice: Money @deprecated(reason: "Use `subtotalPriceV2` instead") + + """ + Price of the order before duties, shipping and taxes. + """ + subtotalPriceV2: MoneyV2 + + """ + List of the order’s successful fulfillments. + """ + successfulFulfillments( + """ + Truncate the array result to this size. + """ + first: Int + ): [Fulfillment!] + + """ + The sum of all the prices of all the items in the order, taxes and discounts included (must be positive). + """ + totalPrice: Money! @deprecated(reason: "Use `totalPriceV2` instead") + + """ + The sum of all the prices of all the items in the order, duties, taxes and discounts included (must be positive). + """ + totalPriceV2: MoneyV2! + + """ + The total amount that has been refunded. + """ + totalRefunded: Money! @deprecated(reason: "Use `totalRefundedV2` instead") + + """ + The total amount that has been refunded. + """ + totalRefundedV2: MoneyV2! + + """ + The total cost of shipping. + """ + totalShippingPrice: Money! + @deprecated(reason: "Use `totalShippingPriceV2` instead") + + """ + The total cost of shipping. + """ + totalShippingPriceV2: MoneyV2! + + """ + The total cost of taxes. + """ + totalTax: Money @deprecated(reason: "Use `totalTaxV2` instead") + + """ + The total cost of taxes. + """ + totalTaxV2: MoneyV2 +} + +""" +Represents the reason for the order's cancellation. +""" +enum OrderCancelReason { + """ + The customer wanted to cancel the order. + """ + CUSTOMER + + """ + The order was fraudulent. + """ + FRAUD + + """ + There was insufficient inventory. + """ + INVENTORY + + """ + Payment was declined. + """ + DECLINED + + """ + The order was canceled for an unlisted reason. + """ + OTHER +} + +""" +An auto-generated type for paginating through multiple Orders. +""" +type OrderConnection { + """ + A list of edges. + """ + edges: [OrderEdge!]! + + """ + Information to aid in pagination. + """ + pageInfo: PageInfo! +} + +""" +An auto-generated type which holds one Order and a cursor during pagination. +""" +type OrderEdge { + """ + A cursor for use in pagination. + """ + cursor: String! + + """ + The item at the end of OrderEdge. + """ + node: Order! +} + +""" +Represents the order's current financial status. +""" +enum OrderFinancialStatus { + """ + Displayed as **Pending**. + """ + PENDING + + """ + Displayed as **Authorized**. + """ + AUTHORIZED + + """ + Displayed as **Partially paid**. + """ + PARTIALLY_PAID + + """ + Displayed as **Partially refunded**. + """ + PARTIALLY_REFUNDED + + """ + Displayed as **Voided**. + """ + VOIDED + + """ + Displayed as **Paid**. + """ + PAID + + """ + Displayed as **Refunded**. + """ + REFUNDED +} + +""" +Represents the order's current fulfillment status. +""" +enum OrderFulfillmentStatus { + """ + Displayed as **Unfulfilled**. + """ + UNFULFILLED + + """ + Displayed as **Partially fulfilled**. + """ + PARTIALLY_FULFILLED + + """ + Displayed as **Fulfilled**. + """ + FULFILLED + + """ + Displayed as **Restocked**. + """ + RESTOCKED + + """ + Displayed as **Pending fulfillment**. + """ + PENDING_FULFILLMENT + + """ + Displayed as **Open**. + """ + OPEN + + """ + Displayed as **In progress**. + """ + IN_PROGRESS + + """ + Displayed as **Scheduled**. + """ + SCHEDULED +} + +""" +Represents a single line in an order. There is one line item for each distinct product variant. +""" +type OrderLineItem { + """ + The number of entries associated to the line item minus the items that have been removed. + """ + currentQuantity: Int! + + """ + List of custom attributes associated to the line item. + """ + customAttributes: [Attribute!]! + + """ + The discounts that have been allocated onto the order line item by discount applications. + """ + discountAllocations: [DiscountAllocation!]! + + """ + The total price of the line item, including discounts, and displayed in the presentment currency. + """ + discountedTotalPrice: MoneyV2! + + """ + The total price of the line item, not including any discounts. The total price is calculated using the original unit price multiplied by the quantity, and it is displayed in the presentment currency. + """ + originalTotalPrice: MoneyV2! + + """ + The number of products variants associated to the line item. + """ + quantity: Int! + + """ + The title of the product combined with title of the variant. + """ + title: String! + + """ + The product variant object associated to the line item. + """ + variant: ProductVariant +} + +""" +An auto-generated type for paginating through multiple OrderLineItems. +""" +type OrderLineItemConnection { + """ + A list of edges. + """ + edges: [OrderLineItemEdge!]! + + """ + Information to aid in pagination. + """ + pageInfo: PageInfo! +} + +""" +An auto-generated type which holds one OrderLineItem and a cursor during pagination. +""" +type OrderLineItemEdge { + """ + A cursor for use in pagination. + """ + cursor: String! + + """ + The item at the end of OrderLineItemEdge. + """ + node: OrderLineItem! +} + +""" +The set of valid sort keys for the Order query. +""" +enum OrderSortKeys { + """ + Sort by the `processed_at` value. + """ + PROCESSED_AT + + """ + Sort by the `total_price` value. + """ + TOTAL_PRICE + + """ + Sort by the `id` value. + """ + ID + + """ + During a search (i.e. when the `query` parameter has been specified on the connection) this sorts the + results by relevance to the search term(s). When no search query is specified, this sort key is not + deterministic and should not be used. + """ + RELEVANCE +} + +""" +Shopify merchants can create pages to hold static HTML content. Each Page object represents a custom page on the online store. +""" +type Page implements Node { + """ + The description of the page, complete with HTML formatting. + """ + body: HTML! + + """ + Summary of the page body. + """ + bodySummary: String! + + """ + The timestamp of the page creation. + """ + createdAt: DateTime! + + """ + A human-friendly unique string for the page automatically generated from its title. + """ + handle: String! + + """ + Globally unique identifier. + """ + id: ID! + + """ + The page's SEO information. + """ + seo: SEO + + """ + The title of the page. + """ + title: String! + + """ + The timestamp of the latest page update. + """ + updatedAt: DateTime! + + """ + The url pointing to the page accessible from the web. + """ + url: URL! +} + +""" +An auto-generated type for paginating through multiple Pages. +""" +type PageConnection { + """ + A list of edges. + """ + edges: [PageEdge!]! + + """ + Information to aid in pagination. + """ + pageInfo: PageInfo! +} + +""" +An auto-generated type which holds one Page and a cursor during pagination. +""" +type PageEdge { + """ + A cursor for use in pagination. + """ + cursor: String! + + """ + The item at the end of PageEdge. + """ + node: Page! +} + +""" +Information about pagination in a connection. +""" +type PageInfo { + """ + Indicates if there are more pages to fetch. + """ + hasNextPage: Boolean! + + """ + Indicates if there are any pages prior to the current page. + """ + hasPreviousPage: Boolean! +} + +""" +The set of valid sort keys for the Page query. +""" +enum PageSortKeys { + """ + Sort by the `title` value. + """ + TITLE + + """ + Sort by the `updated_at` value. + """ + UPDATED_AT + + """ + Sort by the `id` value. + """ + ID + + """ + During a search (i.e. when the `query` parameter has been specified on the connection) this sorts the + results by relevance to the search term(s). When no search query is specified, this sort key is not + deterministic and should not be used. + """ + RELEVANCE +} + +""" +A payment applied to a checkout. +""" +type Payment implements Node { + """ + The amount of the payment. + """ + amount: Money! @deprecated(reason: "Use `amountV2` instead") + + """ + The amount of the payment. + """ + amountV2: MoneyV2! + + """ + The billing address for the payment. + """ + billingAddress: MailingAddress + + """ + The checkout to which the payment belongs. + """ + checkout: Checkout! + + """ + The credit card used for the payment in the case of direct payments. + """ + creditCard: CreditCard + + """ + A message describing a processing error during asynchronous processing. + """ + errorMessage: String + + """ + Globally unique identifier. + """ + id: ID! + + """ + A client-side generated token to identify a payment and perform idempotent operations. + """ + idempotencyKey: String + + """ + The URL where the customer needs to be redirected so they can complete the 3D Secure payment flow. + """ + nextActionUrl: URL + + """ + Whether or not the payment is still processing asynchronously. + """ + ready: Boolean! + + """ + A flag to indicate if the payment is to be done in test mode for gateways that support it. + """ + test: Boolean! + + """ + The actual transaction recorded by Shopify after having processed the payment with the gateway. + """ + transaction: Transaction +} + +""" +Settings related to payments. +""" +type PaymentSettings { + """ + List of the card brands which the shop accepts. + """ + acceptedCardBrands: [CardBrand!]! + + """ + The url pointing to the endpoint to vault credit cards. + """ + cardVaultUrl: URL! + + """ + The country where the shop is located. + """ + countryCode: CountryCode! + + """ + The three-letter code for the shop's primary currency. + """ + currencyCode: CurrencyCode! + + """ + A list of enabled currencies (ISO 4217 format) that the shop accepts. Merchants can enable currencies from their Shopify Payments settings in the Shopify admin. + """ + enabledPresentmentCurrencies: [CurrencyCode!]! + + """ + The shop’s Shopify Payments account id. + """ + shopifyPaymentsAccountId: String + + """ + List of the digital wallets which the shop supports. + """ + supportedDigitalWallets: [DigitalWallet!]! +} + +""" +The valid values for the types of payment token. +""" +enum PaymentTokenType { + """ + Apple Pay token type. + """ + APPLE_PAY + + """ + Vault payment token type. + """ + VAULT + + """ + Shopify Pay token type. + """ + SHOPIFY_PAY + + """ + Google Pay token type. + """ + GOOGLE_PAY +} + +""" +The value of the percentage pricing object. +""" +type PricingPercentageValue { + """ + The percentage value of the object. + """ + percentage: Float! +} + +""" +The price value (fixed or percentage) for a discount application. +""" +union PricingValue = MoneyV2 | PricingPercentageValue + +""" +A product represents an individual item for sale in a Shopify store. Products are often physical, but they don't have to be. +For example, a digital download (such as a movie, music or ebook file) also qualifies as a product, as do services (such as equipment rental, work for hire, customization of another product or an extended warranty). +""" +type Product implements Node & HasMetafields { + """ + Indicates if at least one product variant is available for sale. + """ + availableForSale: Boolean! + + """ + List of collections a product belongs to. + """ + collections( + """ + Returns up to the first `n` elements from the list. + """ + first: Int + + """ + Returns the elements that come after the specified cursor. + """ + after: String + + """ + Returns up to the last `n` elements from the list. + """ + last: Int + + """ + Returns the elements that come before the specified cursor. + """ + before: String + + """ + Reverse the order of the underlying list. + """ + reverse: Boolean = false + ): CollectionConnection! + + """ + The compare at price of the product across all variants. + """ + compareAtPriceRange: ProductPriceRange! + + """ + The date and time when the product was created. + """ + createdAt: DateTime! + + """ + Stripped description of the product, single line with HTML tags removed. + """ + description( + """ + Truncates string after the given length. + """ + truncateAt: Int + ): String! + + """ + The description of the product, complete with HTML formatting. + """ + descriptionHtml: HTML! + + """ + A human-friendly unique string for the Product automatically generated from its title. + They are used by the Liquid templating language to refer to objects. + """ + handle: String! + + """ + Globally unique identifier. + """ + id: ID! + + """ + List of images associated with the product. + """ + images( + """ + Returns up to the first `n` elements from the list. + """ + first: Int + + """ + Returns the elements that come after the specified cursor. + """ + after: String + + """ + Returns up to the last `n` elements from the list. + """ + last: Int + + """ + Returns the elements that come before the specified cursor. + """ + before: String + + """ + Reverse the order of the underlying list. + """ + reverse: Boolean = false + + """ + Sort the underlying list by the given key. + """ + sortKey: ProductImageSortKeys = POSITION + + """ + Image width in pixels between 1 and 2048. This argument is deprecated: Use `maxWidth` on `Image.transformedSrc` instead. + """ + maxWidth: Int + + """ + Image height in pixels between 1 and 2048. This argument is deprecated: Use `maxHeight` on `Image.transformedSrc` instead. + """ + maxHeight: Int + + """ + Crops the image according to the specified region. This argument is deprecated: Use `crop` on `Image.transformedSrc` instead. + """ + crop: CropRegion + + """ + Image size multiplier for high-resolution retina displays. Must be between 1 and 3. This argument is deprecated: Use `scale` on `Image.transformedSrc` instead. + """ + scale: Int = 1 + ): ImageConnection! + + """ + The media associated with the product. + """ + media( + """ + Returns up to the first `n` elements from the list. + """ + first: Int + + """ + Returns the elements that come after the specified cursor. + """ + after: String + + """ + Returns up to the last `n` elements from the list. + """ + last: Int + + """ + Returns the elements that come before the specified cursor. + """ + before: String + + """ + Reverse the order of the underlying list. + """ + reverse: Boolean = false + + """ + Sort the underlying list by the given key. + """ + sortKey: ProductMediaSortKeys = POSITION + ): MediaConnection! + + """ + The metafield associated with the resource. + """ + metafield( + """ + Container for a set of metafields (maximum of 20 characters). + """ + namespace: String! + + """ + Identifier for the metafield (maximum of 30 characters). + """ + key: String! + ): Metafield + + """ + A paginated list of metafields associated with the resource. + """ + metafields( + """ + Container for a set of metafields (maximum of 20 characters). + """ + namespace: String + + """ + Returns up to the first `n` elements from the list. + """ + first: Int + + """ + Returns the elements that come after the specified cursor. + """ + after: String + + """ + Returns up to the last `n` elements from the list. + """ + last: Int + + """ + Returns the elements that come before the specified cursor. + """ + before: String + + """ + Reverse the order of the underlying list. + """ + reverse: Boolean = false + ): MetafieldConnection! + + """ + The online store URL for the product. + A value of `null` indicates that the product is not published to the Online Store sales channel. + """ + onlineStoreUrl: URL + + """ + List of product options. + """ + options( + """ + Truncate the array result to this size. + """ + first: Int + ): [ProductOption!]! + + """ + List of price ranges in the presentment currencies for this shop. + """ + presentmentPriceRanges( + """ + Specifies the presentment currencies to return a price range in. + """ + presentmentCurrencies: [CurrencyCode!] + + """ + Returns up to the first `n` elements from the list. + """ + first: Int + + """ + Returns the elements that come after the specified cursor. + """ + after: String + + """ + Returns up to the last `n` elements from the list. + """ + last: Int + + """ + Returns the elements that come before the specified cursor. + """ + before: String + + """ + Reverse the order of the underlying list. + """ + reverse: Boolean = false + ): ProductPriceRangeConnection! + + """ + The price range. + """ + priceRange: ProductPriceRange! + + """ + A categorization that a product can be tagged with, commonly used for filtering and searching. + """ + productType: String! + + """ + The date and time when the product was published to the channel. + """ + publishedAt: DateTime! + + """ + The product's SEO information. + """ + seo: SEO! + + """ + A comma separated list of tags that have been added to the product. + Additional access scope required for private apps: unauthenticated_read_product_tags. + """ + tags: [String!]! + + """ + The product’s title. + """ + title: String! + + """ + The total quantity of inventory in stock for this Product. + """ + totalInventory: Int + + """ + The date and time when the product was last modified. + A product's `updatedAt` value can change for different reasons. For example, if an order + is placed for a product that has inventory tracking set up, then the inventory adjustment + is counted as an update. + """ + updatedAt: DateTime! + + """ + Find a product’s variant based on its selected options. + This is useful for converting a user’s selection of product options into a single matching variant. + If there is not a variant for the selected options, `null` will be returned. + """ + variantBySelectedOptions( + """ + The input fields used for a selected option. + """ + selectedOptions: [SelectedOptionInput!]! + ): ProductVariant + + """ + List of the product’s variants. + """ + variants( + """ + Returns up to the first `n` elements from the list. + """ + first: Int + + """ + Returns the elements that come after the specified cursor. + """ + after: String + + """ + Returns up to the last `n` elements from the list. + """ + last: Int + + """ + Returns the elements that come before the specified cursor. + """ + before: String + + """ + Reverse the order of the underlying list. + """ + reverse: Boolean = false + + """ + Sort the underlying list by the given key. + """ + sortKey: ProductVariantSortKeys = POSITION + ): ProductVariantConnection! + + """ + The product’s vendor name. + """ + vendor: String! +} + +""" +The set of valid sort keys for the ProductCollection query. +""" +enum ProductCollectionSortKeys { + """ + Sort by the `title` value. + """ + TITLE + + """ + Sort by the `price` value. + """ + PRICE + + """ + Sort by the `best-selling` value. + """ + BEST_SELLING + + """ + Sort by the `created` value. + """ + CREATED + + """ + Sort by the `id` value. + """ + ID + + """ + Sort by the `manual` value. + """ + MANUAL + + """ + Sort by the `collection-default` value. + """ + COLLECTION_DEFAULT + + """ + During a search (i.e. when the `query` parameter has been specified on the connection) this sorts the + results by relevance to the search term(s). When no search query is specified, this sort key is not + deterministic and should not be used. + """ + RELEVANCE +} + +""" +An auto-generated type for paginating through multiple Products. +""" +type ProductConnection { + """ + A list of edges. + """ + edges: [ProductEdge!]! + + """ + Information to aid in pagination. + """ + pageInfo: PageInfo! +} + +""" +An auto-generated type which holds one Product and a cursor during pagination. +""" +type ProductEdge { + """ + A cursor for use in pagination. + """ + cursor: String! + + """ + The item at the end of ProductEdge. + """ + node: Product! +} + +""" +The set of valid sort keys for the ProductImage query. +""" +enum ProductImageSortKeys { + """ + Sort by the `created_at` value. + """ + CREATED_AT + + """ + Sort by the `position` value. + """ + POSITION + + """ + Sort by the `id` value. + """ + ID + + """ + During a search (i.e. when the `query` parameter has been specified on the connection) this sorts the + results by relevance to the search term(s). When no search query is specified, this sort key is not + deterministic and should not be used. + """ + RELEVANCE +} + +""" +The set of valid sort keys for the ProductMedia query. +""" +enum ProductMediaSortKeys { + """ + Sort by the `position` value. + """ + POSITION + + """ + Sort by the `id` value. + """ + ID + + """ + During a search (i.e. when the `query` parameter has been specified on the connection) this sorts the + results by relevance to the search term(s). When no search query is specified, this sort key is not + deterministic and should not be used. + """ + RELEVANCE +} + +""" +Product property names like "Size", "Color", and "Material" that the customers can select. +Variants are selected based on permutations of these options. +255 characters limit each. +""" +type ProductOption implements Node { + """ + Globally unique identifier. + """ + id: ID! + + """ + The product option’s name. + """ + name: String! + + """ + The corresponding value to the product option name. + """ + values: [String!]! +} + +""" +The price range of the product. +""" +type ProductPriceRange { + """ + The highest variant's price. + """ + maxVariantPrice: MoneyV2! + + """ + The lowest variant's price. + """ + minVariantPrice: MoneyV2! +} + +""" +An auto-generated type for paginating through multiple ProductPriceRanges. +""" +type ProductPriceRangeConnection { + """ + A list of edges. + """ + edges: [ProductPriceRangeEdge!]! + + """ + Information to aid in pagination. + """ + pageInfo: PageInfo! +} + +""" +An auto-generated type which holds one ProductPriceRange and a cursor during pagination. +""" +type ProductPriceRangeEdge { + """ + A cursor for use in pagination. + """ + cursor: String! + + """ + The item at the end of ProductPriceRangeEdge. + """ + node: ProductPriceRange! +} + +""" +The set of valid sort keys for the Product query. +""" +enum ProductSortKeys { + """ + Sort by the `title` value. + """ + TITLE + + """ + Sort by the `product_type` value. + """ + PRODUCT_TYPE + + """ + Sort by the `vendor` value. + """ + VENDOR + + """ + Sort by the `updated_at` value. + """ + UPDATED_AT + + """ + Sort by the `created_at` value. + """ + CREATED_AT + + """ + Sort by the `best_selling` value. + """ + BEST_SELLING + + """ + Sort by the `price` value. + """ + PRICE + + """ + Sort by the `id` value. + """ + ID + + """ + During a search (i.e. when the `query` parameter has been specified on the connection) this sorts the + results by relevance to the search term(s). When no search query is specified, this sort key is not + deterministic and should not be used. + """ + RELEVANCE +} + +""" +A product variant represents a different version of a product, such as differing sizes or differing colors. +""" +type ProductVariant implements Node & HasMetafields { + """ + Indicates if the product variant is in stock. + """ + available: Boolean @deprecated(reason: "Use `availableForSale` instead") + + """ + Indicates if the product variant is available for sale. + """ + availableForSale: Boolean! + + """ + The compare at price of the variant. This can be used to mark a variant as on sale, when `compareAtPrice` is higher than `price`. + """ + compareAtPrice: Money @deprecated(reason: "Use `compareAtPriceV2` instead") + + """ + The compare at price of the variant. This can be used to mark a variant as on sale, when `compareAtPriceV2` is higher than `priceV2`. + """ + compareAtPriceV2: MoneyV2 + + """ + Whether a product is out of stock but still available for purchase (used for backorders). + """ + currentlyNotInStock: Boolean! + + """ + Globally unique identifier. + """ + id: ID! + + """ + Image associated with the product variant. This field falls back to the product image if no image is available. + """ + image( + """ + Image width in pixels between 1 and 2048. This argument is deprecated: Use `maxWidth` on `Image.transformedSrc` instead. + """ + maxWidth: Int + + """ + Image height in pixels between 1 and 2048. This argument is deprecated: Use `maxHeight` on `Image.transformedSrc` instead. + """ + maxHeight: Int + + """ + Crops the image according to the specified region. This argument is deprecated: Use `crop` on `Image.transformedSrc` instead. + """ + crop: CropRegion + + """ + Image size multiplier for high-resolution retina displays. Must be between 1 and 3. This argument is deprecated: Use `scale` on `Image.transformedSrc` instead. + """ + scale: Int = 1 + ): Image + + """ + The metafield associated with the resource. + """ + metafield( + """ + Container for a set of metafields (maximum of 20 characters). + """ + namespace: String! + + """ + Identifier for the metafield (maximum of 30 characters). + """ + key: String! + ): Metafield + + """ + A paginated list of metafields associated with the resource. + """ + metafields( + """ + Container for a set of metafields (maximum of 20 characters). + """ + namespace: String + + """ + Returns up to the first `n` elements from the list. + """ + first: Int + + """ + Returns the elements that come after the specified cursor. + """ + after: String + + """ + Returns up to the last `n` elements from the list. + """ + last: Int + + """ + Returns the elements that come before the specified cursor. + """ + before: String + + """ + Reverse the order of the underlying list. + """ + reverse: Boolean = false + ): MetafieldConnection! + + """ + List of prices and compare-at prices in the presentment currencies for this shop. + """ + presentmentPrices( + """ + The presentment currencies prices should return in. + """ + presentmentCurrencies: [CurrencyCode!] + + """ + Returns up to the first `n` elements from the list. + """ + first: Int + + """ + Returns the elements that come after the specified cursor. + """ + after: String + + """ + Returns up to the last `n` elements from the list. + """ + last: Int + + """ + Returns the elements that come before the specified cursor. + """ + before: String + + """ + Reverse the order of the underlying list. + """ + reverse: Boolean = false + ): ProductVariantPricePairConnection! + + """ + List of unit prices in the presentment currencies for this shop. + """ + presentmentUnitPrices( + """ + Specify the currencies in which to return presentment unit prices. + """ + presentmentCurrencies: [CurrencyCode!] + + """ + Returns up to the first `n` elements from the list. + """ + first: Int + + """ + Returns the elements that come after the specified cursor. + """ + after: String + + """ + Returns up to the last `n` elements from the list. + """ + last: Int + + """ + Returns the elements that come before the specified cursor. + """ + before: String + + """ + Reverse the order of the underlying list. + """ + reverse: Boolean = false + ): MoneyV2Connection! + + """ + The product variant’s price. + """ + price: Money! @deprecated(reason: "Use `priceV2` instead") + + """ + The product variant’s price. + """ + priceV2: MoneyV2! + + """ + The product object that the product variant belongs to. + """ + product: Product! + + """ + The total sellable quantity of the variant for online sales channels. + """ + quantityAvailable: Int + + """ + Whether a customer needs to provide a shipping address when placing an order for the product variant. + """ + requiresShipping: Boolean! + + """ + List of product options applied to the variant. + """ + selectedOptions: [SelectedOption!]! + + """ + The SKU (stock keeping unit) associated with the variant. + """ + sku: String + + """ + The product variant’s title. + """ + title: String! + + """ + The unit price value for the variant based on the variant's measurement. + """ + unitPrice: MoneyV2 + + """ + The unit price measurement for the variant. + """ + unitPriceMeasurement: UnitPriceMeasurement + + """ + The weight of the product variant in the unit system specified with `weight_unit`. + """ + weight: Float + + """ + Unit of measurement for weight. + """ + weightUnit: WeightUnit! +} + +""" +An auto-generated type for paginating through multiple ProductVariants. +""" +type ProductVariantConnection { + """ + A list of edges. + """ + edges: [ProductVariantEdge!]! + + """ + Information to aid in pagination. + """ + pageInfo: PageInfo! +} + +""" +An auto-generated type which holds one ProductVariant and a cursor during pagination. +""" +type ProductVariantEdge { + """ + A cursor for use in pagination. + """ + cursor: String! + + """ + The item at the end of ProductVariantEdge. + """ + node: ProductVariant! +} + +""" +The compare-at price and price of a variant sharing a currency. +""" +type ProductVariantPricePair { + """ + The compare-at price of the variant with associated currency. + """ + compareAtPrice: MoneyV2 + + """ + The price of the variant with associated currency. + """ + price: MoneyV2! +} + +""" +An auto-generated type for paginating through multiple ProductVariantPricePairs. +""" +type ProductVariantPricePairConnection { + """ + A list of edges. + """ + edges: [ProductVariantPricePairEdge!]! + + """ + Information to aid in pagination. + """ + pageInfo: PageInfo! +} + +""" +An auto-generated type which holds one ProductVariantPricePair and a cursor during pagination. +""" +type ProductVariantPricePairEdge { + """ + A cursor for use in pagination. + """ + cursor: String! + + """ + The item at the end of ProductVariantPricePairEdge. + """ + node: ProductVariantPricePair! +} + +""" +The set of valid sort keys for the ProductVariant query. +""" +enum ProductVariantSortKeys { + """ + Sort by the `title` value. + """ + TITLE + + """ + Sort by the `sku` value. + """ + SKU + + """ + Sort by the `position` value. + """ + POSITION + + """ + Sort by the `id` value. + """ + ID + + """ + During a search (i.e. when the `query` parameter has been specified on the connection) this sorts the + results by relevance to the search term(s). When no search query is specified, this sort key is not + deterministic and should not be used. + """ + RELEVANCE +} + +""" +The schema’s entry-point for queries. This acts as the public, top-level API from which all queries must start. +""" +type QueryRoot { + """ + List of the shop's articles. + """ + articles( + """ + Returns up to the first `n` elements from the list. + """ + first: Int + + """ + Returns the elements that come after the specified cursor. + """ + after: String + + """ + Returns up to the last `n` elements from the list. + """ + last: Int + + """ + Returns the elements that come before the specified cursor. + """ + before: String + + """ + Reverse the order of the underlying list. + """ + reverse: Boolean = false + + """ + Sort the underlying list by the given key. + """ + sortKey: ArticleSortKeys = ID + + """ + Supported filter parameters: + - `author` + - `blog_title` + - `created_at` + - `tag` + - `updated_at` + + See the detailed [search syntax](https://help.shopify.com/api/getting-started/search-syntax) + for more information about using filters. + """ + query: String + ): ArticleConnection! + + """ + Find a blog by its handle. + """ + blogByHandle( + """ + The handle of the blog. + """ + handle: String! + ): Blog + + """ + List of the shop's blogs. + """ + blogs( + """ + Returns up to the first `n` elements from the list. + """ + first: Int + + """ + Returns the elements that come after the specified cursor. + """ + after: String + + """ + Returns up to the last `n` elements from the list. + """ + last: Int + + """ + Returns the elements that come before the specified cursor. + """ + before: String + + """ + Reverse the order of the underlying list. + """ + reverse: Boolean = false + + """ + Sort the underlying list by the given key. + """ + sortKey: BlogSortKeys = ID + + """ + Supported filter parameters: + - `created_at` + - `handle` + - `title` + - `updated_at` + + See the detailed [search syntax](https://help.shopify.com/api/getting-started/search-syntax) + for more information about using filters. + """ + query: String + ): BlogConnection! + + """ + Find a collection by its handle. + """ + collectionByHandle( + """ + The handle of the collection. + """ + handle: String! + ): Collection + + """ + List of the shop’s collections. + """ + collections( + """ + Returns up to the first `n` elements from the list. + """ + first: Int + + """ + Returns the elements that come after the specified cursor. + """ + after: String + + """ + Returns up to the last `n` elements from the list. + """ + last: Int + + """ + Returns the elements that come before the specified cursor. + """ + before: String + + """ + Reverse the order of the underlying list. + """ + reverse: Boolean = false + + """ + Sort the underlying list by the given key. + """ + sortKey: CollectionSortKeys = ID + + """ + Supported filter parameters: + - `collection_type` + - `title` + - `updated_at` + + See the detailed [search syntax](https://help.shopify.com/api/getting-started/search-syntax) + for more information about using filters. + """ + query: String + ): CollectionConnection! + + """ + Find a customer by its access token. + """ + customer( + """ + The customer access token. + """ + customerAccessToken: String! + ): Customer + node( + """ + The ID of the Node to return. + """ + id: ID! + ): Node + nodes( + """ + The IDs of the Nodes to return. + """ + ids: [ID!]! + ): [Node]! + + """ + Find a page by its handle. + """ + pageByHandle( + """ + The handle of the page. + """ + handle: String! + ): Page + + """ + List of the shop's pages. + """ + pages( + """ + Returns up to the first `n` elements from the list. + """ + first: Int + + """ + Returns the elements that come after the specified cursor. + """ + after: String + + """ + Returns up to the last `n` elements from the list. + """ + last: Int + + """ + Returns the elements that come before the specified cursor. + """ + before: String + + """ + Reverse the order of the underlying list. + """ + reverse: Boolean = false + + """ + Sort the underlying list by the given key. + """ + sortKey: PageSortKeys = ID + + """ + Supported filter parameters: + - `created_at` + - `handle` + - `title` + - `updated_at` + + See the detailed [search syntax](https://help.shopify.com/api/getting-started/search-syntax) + for more information about using filters. + """ + query: String + ): PageConnection! + + """ + Find a product by its handle. + """ + productByHandle( + """ + The handle of the product. + """ + handle: String! + ): Product + + """ + Find recommended products related to a given `product_id`. + To learn more about how recommendations are generated, see + [*Showing product recommendations on product pages*](https://help.shopify.com/themes/development/recommended-products). + """ + productRecommendations( + """ + The id of the product. + """ + productId: ID! + ): [Product!] + + """ + Tags added to products. + Additional access scope required: unauthenticated_read_product_tags. + """ + productTags( + """ + Returns up to the first `n` elements from the list. + """ + first: Int! + ): StringConnection! + + """ + List of product types for the shop's products that are published to your app. + """ + productTypes( + """ + Returns up to the first `n` elements from the list. + """ + first: Int! + ): StringConnection! + + """ + List of the shop’s products. + """ + products( + """ + Returns up to the first `n` elements from the list. + """ + first: Int + + """ + Returns the elements that come after the specified cursor. + """ + after: String + + """ + Returns up to the last `n` elements from the list. + """ + last: Int + + """ + Returns the elements that come before the specified cursor. + """ + before: String + + """ + Reverse the order of the underlying list. + """ + reverse: Boolean = false + + """ + Sort the underlying list by the given key. + """ + sortKey: ProductSortKeys = ID + + """ + Supported filter parameters: + - `available_for_sale` + - `created_at` + - `product_type` + - `tag` + - `title` + - `updated_at` + - `variants.price` + - `vendor` + + See the detailed [search syntax](https://help.shopify.com/api/getting-started/search-syntax) + for more information about using filters. + """ + query: String + ): ProductConnection! + + """ + The list of public Storefront API versions, including supported, release candidate and unstable versions. + """ + publicApiVersions: [ApiVersion!]! + + """ + The shop associated with the storefront access token. + """ + shop: Shop! +} + +""" +SEO information. +""" +type SEO { + """ + The meta description. + """ + description: String + + """ + The SEO title. + """ + title: String +} + +""" +Script discount applications capture the intentions of a discount that +was created by a Shopify Script. +""" +type ScriptDiscountApplication implements DiscountApplication { + """ + The method by which the discount's value is allocated to its entitled items. + """ + allocationMethod: DiscountApplicationAllocationMethod! + + """ + The description of the application as defined by the Script. + """ + description: String! @deprecated(reason: "Use `title` instead") + + """ + Which lines of targetType that the discount is allocated over. + """ + targetSelection: DiscountApplicationTargetSelection! + + """ + The type of line that the discount is applicable towards. + """ + targetType: DiscountApplicationTargetType! + + """ + The title of the application as defined by the Script. + """ + title: String! + + """ + The value of the discount application. + """ + value: PricingValue! +} + +""" +Properties used by customers to select a product variant. +Products can have multiple options, like different sizes or colors. +""" +type SelectedOption { + """ + The product option’s name. + """ + name: String! + + """ + The product option’s value. + """ + value: String! +} + +""" +Specifies the input fields required for a selected option. +""" +input SelectedOptionInput { + """ + The product option’s name. + """ + name: String! + + """ + The product option’s value. + """ + value: String! +} + +""" +A shipping rate to be applied to a checkout. +""" +type ShippingRate { + """ + Human-readable unique identifier for this shipping rate. + """ + handle: String! + + """ + Price of this shipping rate. + """ + price: Money! @deprecated(reason: "Use `priceV2` instead") + + """ + Price of this shipping rate. + """ + priceV2: MoneyV2! + + """ + Title of this shipping rate. + """ + title: String! +} + +""" +Shop represents a collection of the general settings and information about the shop. +""" +type Shop { + """ + List of the shop' articles. + """ + articles( + """ + Returns up to the first `n` elements from the list. + """ + first: Int + + """ + Returns the elements that come after the specified cursor. + """ + after: String + + """ + Returns up to the last `n` elements from the list. + """ + last: Int + + """ + Returns the elements that come before the specified cursor. + """ + before: String + + """ + Reverse the order of the underlying list. + """ + reverse: Boolean = false + + """ + Sort the underlying list by the given key. + """ + sortKey: ArticleSortKeys = ID + + """ + Supported filter parameters: + - `author` + - `blog_title` + - `created_at` + - `tag` + - `updated_at` + + See the detailed [search syntax](https://help.shopify.com/api/getting-started/search-syntax) + for more information about using filters. + """ + query: String + ): ArticleConnection! @deprecated(reason: "Use `QueryRoot.articles` instead.") + + """ + List of the shop' blogs. + """ + blogs( + """ + Returns up to the first `n` elements from the list. + """ + first: Int + + """ + Returns the elements that come after the specified cursor. + """ + after: String + + """ + Returns up to the last `n` elements from the list. + """ + last: Int + + """ + Returns the elements that come before the specified cursor. + """ + before: String + + """ + Reverse the order of the underlying list. + """ + reverse: Boolean = false + + """ + Sort the underlying list by the given key. + """ + sortKey: BlogSortKeys = ID + + """ + Supported filter parameters: + - `created_at` + - `handle` + - `title` + - `updated_at` + + See the detailed [search syntax](https://help.shopify.com/api/getting-started/search-syntax) + for more information about using filters. + """ + query: String + ): BlogConnection! @deprecated(reason: "Use `QueryRoot.blogs` instead.") + + """ + Find a collection by its handle. + """ + collectionByHandle( + """ + The handle of the collection. + """ + handle: String! + ): Collection + @deprecated(reason: "Use `QueryRoot.collectionByHandle` instead.") + + """ + List of the shop’s collections. + """ + collections( + """ + Returns up to the first `n` elements from the list. + """ + first: Int + + """ + Returns the elements that come after the specified cursor. + """ + after: String + + """ + Returns up to the last `n` elements from the list. + """ + last: Int + + """ + Returns the elements that come before the specified cursor. + """ + before: String + + """ + Reverse the order of the underlying list. + """ + reverse: Boolean = false + + """ + Sort the underlying list by the given key. + """ + sortKey: CollectionSortKeys = ID + + """ + Supported filter parameters: + - `collection_type` + - `title` + - `updated_at` + + See the detailed [search syntax](https://help.shopify.com/api/getting-started/search-syntax) + for more information about using filters. + """ + query: String + ): CollectionConnection! + @deprecated(reason: "Use `QueryRoot.collections` instead.") + + """ + The three-letter code for the currency that the shop accepts. + """ + currencyCode: CurrencyCode! + @deprecated(reason: "Use `paymentSettings` instead") + + """ + A description of the shop. + """ + description: String + + """ + A string representing the way currency is formatted when the currency isn’t specified. + """ + moneyFormat: String! + + """ + The shop’s name. + """ + name: String! + + """ + Settings related to payments. + """ + paymentSettings: PaymentSettings! + + """ + The shop’s primary domain. + """ + primaryDomain: Domain! + + """ + The shop’s privacy policy. + """ + privacyPolicy: ShopPolicy + + """ + Find a product by its handle. + """ + productByHandle( + """ + The handle of the product. + """ + handle: String! + ): Product @deprecated(reason: "Use `QueryRoot.productByHandle` instead.") + + """ + A list of tags that have been added to products. + Additional access scope required: unauthenticated_read_product_tags. + """ + productTags( + """ + Returns up to the first `n` elements from the list. + """ + first: Int! + ): StringConnection! + @deprecated(reason: "Use `QueryRoot.productTags` instead.") + + """ + List of the shop’s product types. + """ + productTypes( + """ + Returns up to the first `n` elements from the list. + """ + first: Int! + ): StringConnection! + @deprecated(reason: "Use `QueryRoot.productTypes` instead.") + + """ + List of the shop’s products. + """ + products( + """ + Returns up to the first `n` elements from the list. + """ + first: Int + + """ + Returns the elements that come after the specified cursor. + """ + after: String + + """ + Returns up to the last `n` elements from the list. + """ + last: Int + + """ + Returns the elements that come before the specified cursor. + """ + before: String + + """ + Reverse the order of the underlying list. + """ + reverse: Boolean = false + + """ + Sort the underlying list by the given key. + """ + sortKey: ProductSortKeys = ID + + """ + Supported filter parameters: + - `available_for_sale` + - `created_at` + - `product_type` + - `tag` + - `title` + - `updated_at` + - `variants.price` + - `vendor` + + See the detailed [search syntax](https://help.shopify.com/api/getting-started/search-syntax) + for more information about using filters. + """ + query: String + ): ProductConnection! @deprecated(reason: "Use `QueryRoot.products` instead.") + + """ + The shop’s refund policy. + """ + refundPolicy: ShopPolicy + + """ + The shop’s shipping policy. + """ + shippingPolicy: ShopPolicy + + """ + Countries that the shop ships to. + """ + shipsToCountries: [CountryCode!]! + + """ + The shop’s Shopify Payments account id. + """ + shopifyPaymentsAccountId: String + @deprecated(reason: "Use `paymentSettings` instead") + + """ + The shop’s terms of service. + """ + termsOfService: ShopPolicy +} + +""" +Policy that a merchant has configured for their store, such as their refund or privacy policy. +""" +type ShopPolicy implements Node { + """ + Policy text, maximum size of 64kb. + """ + body: String! + + """ + Policy’s handle. + """ + handle: String! + + """ + Globally unique identifier. + """ + id: ID! + + """ + Policy’s title. + """ + title: String! + + """ + Public URL to the policy. + """ + url: URL! +} + +""" +An auto-generated type for paginating through multiple Strings. +""" +type StringConnection { + """ + A list of edges. + """ + edges: [StringEdge!]! + + """ + Information to aid in pagination. + """ + pageInfo: PageInfo! +} + +""" +An auto-generated type which holds one String and a cursor during pagination. +""" +type StringEdge { + """ + A cursor for use in pagination. + """ + cursor: String! + + """ + The item at the end of StringEdge. + """ + node: String! +} + +""" +Specifies the fields required to complete a checkout with +a tokenized payment. +""" +input TokenizedPaymentInput { + """ + The amount of the payment. + """ + amount: Money! + + """ + A unique client generated key used to avoid duplicate charges. When a duplicate payment is found, the original is returned instead of creating a new one. + """ + idempotencyKey: String! + + """ + The billing address for the payment. + """ + billingAddress: MailingAddressInput! + + """ + The type of payment token. + """ + type: String! + + """ + A simple string or JSON containing the required payment data for the tokenized payment. + """ + paymentData: String! + + """ + Executes the payment in test mode if possible. Defaults to `false`. + """ + test: Boolean + + """ + Public Hash Key used for AndroidPay payments only. + """ + identifier: String +} + +""" +Specifies the fields required to complete a checkout with +a tokenized payment. +""" +input TokenizedPaymentInputV2 { + """ + The amount and currency of the payment. + """ + paymentAmount: MoneyInput! + + """ + A unique client generated key used to avoid duplicate charges. When a duplicate payment is found, the original is returned instead of creating a new one. + """ + idempotencyKey: String! + + """ + The billing address for the payment. + """ + billingAddress: MailingAddressInput! + + """ + A simple string or JSON containing the required payment data for the tokenized payment. + """ + paymentData: String! + + """ + Whether to execute the payment in test mode, if possible. Test mode is not supported in production stores. Defaults to `false`. + """ + test: Boolean + + """ + Public Hash Key used for AndroidPay payments only. + """ + identifier: String + + """ + The type of payment token. + """ + type: String! +} + +""" +Specifies the fields required to complete a checkout with +a tokenized payment. +""" +input TokenizedPaymentInputV3 { + """ + The amount and currency of the payment. + """ + paymentAmount: MoneyInput! + + """ + A unique client generated key used to avoid duplicate charges. When a duplicate payment is found, the original is returned instead of creating a new one. + """ + idempotencyKey: String! + + """ + The billing address for the payment. + """ + billingAddress: MailingAddressInput! + + """ + A simple string or JSON containing the required payment data for the tokenized payment. + """ + paymentData: String! + + """ + Whether to execute the payment in test mode, if possible. Test mode is not supported in production stores. Defaults to `false`. + """ + test: Boolean + + """ + Public Hash Key used for AndroidPay payments only. + """ + identifier: String + + """ + The type of payment token. + """ + type: PaymentTokenType! +} + +""" +An object representing exchange of money for a product or service. +""" +type Transaction { + """ + The amount of money that the transaction was for. + """ + amount: Money! @deprecated(reason: "Use `amountV2` instead") + + """ + The amount of money that the transaction was for. + """ + amountV2: MoneyV2! + + """ + The kind of the transaction. + """ + kind: TransactionKind! + + """ + The status of the transaction. + """ + status: TransactionStatus! @deprecated(reason: "Use `statusV2` instead") + + """ + The status of the transaction. + """ + statusV2: TransactionStatus + + """ + Whether the transaction was done in test mode or not. + """ + test: Boolean! +} + +enum TransactionKind { + SALE + CAPTURE + AUTHORIZATION + EMV_AUTHORIZATION + CHANGE +} + +enum TransactionStatus { + PENDING + SUCCESS + FAILURE + ERROR +} + +""" +An RFC 3986 and RFC 3987 compliant URI string. + +Example value: `"https://johns-apparel.myshopify.com"`. +""" +scalar URL + +""" +The measurement used to calculate a unit price for a product variant (e.g. $9.99 / 100ml). +""" +type UnitPriceMeasurement { + """ + The type of unit of measurement for the unit price measurement. + """ + measuredType: UnitPriceMeasurementMeasuredType + + """ + The quantity unit for the unit price measurement. + """ + quantityUnit: UnitPriceMeasurementMeasuredUnit + + """ + The quantity value for the unit price measurement. + """ + quantityValue: Float! + + """ + The reference unit for the unit price measurement. + """ + referenceUnit: UnitPriceMeasurementMeasuredUnit + + """ + The reference value for the unit price measurement. + """ + referenceValue: Int! +} + +""" +The accepted types of unit of measurement. +""" +enum UnitPriceMeasurementMeasuredType { + """ + Unit of measurements representing volumes. + """ + VOLUME + + """ + Unit of measurements representing weights. + """ + WEIGHT + + """ + Unit of measurements representing lengths. + """ + LENGTH + + """ + Unit of measurements representing areas. + """ + AREA +} + +""" +The valid units of measurement for a unit price measurement. +""" +enum UnitPriceMeasurementMeasuredUnit { + """ + 1000 milliliters equals 1 liter. + """ + ML + + """ + 100 centiliters equals 1 liter. + """ + CL + + """ + Metric system unit of volume. + """ + L + + """ + 1 cubic meter equals 1000 liters. + """ + M3 + + """ + 1000 milligrams equals 1 gram. + """ + MG + + """ + Metric system unit of weight. + """ + G + + """ + 1 kilogram equals 1000 grams. + """ + KG + + """ + 1000 millimeters equals 1 meter. + """ + MM + + """ + 100 centimeters equals 1 meter. + """ + CM + + """ + Metric system unit of length. + """ + M + + """ + Metric system unit of area. + """ + M2 +} + +""" +Represents an error in the input of a mutation. +""" +type UserError implements DisplayableError { + """ + Path to the input field which caused the error. + """ + field: [String!] + + """ + The error message. + """ + message: String! +} + +""" +Represents a Shopify hosted video. +""" +type Video implements Node & Media { + """ + A word or phrase to share the nature or contents of a media. + """ + alt: String + + """ + Globally unique identifier. + """ + id: ID! + + """ + The media content type. + """ + mediaContentType: MediaContentType! + + """ + The preview image for the media. + """ + previewImage: Image + + """ + The sources for a video. + """ + sources: [VideoSource!]! +} + +""" +Represents a source for a Shopify hosted video. +""" +type VideoSource { + """ + The format of the video source. + """ + format: String! + + """ + The height of the video. + """ + height: Int! + + """ + The video MIME type. + """ + mimeType: String! + + """ + The URL of the video. + """ + url: String! + + """ + The width of the video. + """ + width: Int! +} + +""" +Units of measurement for weight. +""" +enum WeightUnit { + """ + 1 kilogram equals 1000 grams. + """ + KILOGRAMS + + """ + Metric system unit of mass. + """ + GRAMS + + """ + 1 pound equals 16 ounces. + """ + POUNDS + + """ + Imperial system unit of mass. + """ + OUNCES +} diff --git a/framework/shopify/types.ts b/framework/shopify/types.ts index 47bb94e62..9ad9fd016 100644 --- a/framework/shopify/types.ts +++ b/framework/shopify/types.ts @@ -1,130 +1,48 @@ -import { - Product as BaseProduct, - ProductVariant as BaseProductVariant, - Cart as BaseCart, - CheckoutResource as BaseCheckoutResource, - AttributeInput, - Client as BaseClient, - Shop as BaseShop, - Image as BaseImage, -} from 'shopify-buy' +import * as Core from '@commerce/types' +import { CheckoutLineItem } from './schema' -export type SelectedOptions = { +export type ShopifyCheckout = { id: string - name: string - value: string + webUrl: string + lineItems: CheckoutLineItem[] } -export type PresentmentPrice = { - price: PriceV2 -} - -export type ProductVariant = BaseProductVariant & { - selectedOptions: Array - presentmentPrices: Array -} - -// TODO -export type ProductOptions = { - node: { - __typename: string - displayName: string - values: { - edges: [ - { - node: { - label: string - id: string - } - } - ] - } - } -} - -// TODO -export type ProductEdge = { - node: Product -} - -export type Product = BaseProduct & { - handle: string - name: string - path: string - entityId: number - descriptionHtml: string - prices: { - price: { - value: number - currencyCode: string - } - retailPrice: { - value: number - currencyCode: string - } - } - images: { - edges: [{ node: { urlOriginal: string; altText: string } }] - } - productOptions: ProductOptions - variants: Array & { - edges: [ - { - node: { - productOptions: ProductOptions[] - entityId: number - } - } - ] - } -} - -export type PriceV2 = { - amount: number - currencyCode: string -} - -export type Cart = BaseCart & { - webUrl?: string - currencyCode?: string - lineItemsSubtotalPrice?: PriceV2 - totalPriceV2?: PriceV2 -} - -export type Shop = BaseShop & { - currencyCode?: string -} - -export type Create = { - presentmentCurrencyCode?: string -} - -export type CheckoutResource = BaseCheckoutResource & { - updateLineItems( - checkoutId: string | number, - lineItems: AttributeInput[] - ): Promise - - create: (input: Create) => Promise -} - -export type Client = BaseClient & { - checkout: CheckoutResource -} - -export type Page = { +export interface Cart extends Core.Cart { id: string - title: string - name: string - handle: string - body: string - bodySummary: string - url: string - sort_order: number + lineItems: LineItem[] } -export type PageEdge = { - node: Page +export interface LineItem extends Core.LineItem { + options: any[] } -export type Image = BaseImage +/** + * Cart mutations + */ + +export type OptionSelections = { + option_id: number + option_value: number | string +} + +export type CartItemBody = Core.CartItemBody & { + productId: string // The product id is always required for BC + optionSelections?: OptionSelections +} + +type X = Core.CartItemBody extends CartItemBody ? any : never +type Y = CartItemBody extends Core.CartItemBody ? any : never + +export type GetCartHandlerBody = Core.GetCartHandlerBody + +export type AddCartItemBody = Core.AddCartItemBody + +export type AddCartItemHandlerBody = Core.AddCartItemHandlerBody + +export type UpdateCartItemBody = Core.UpdateCartItemBody + +export type UpdateCartItemHandlerBody = Core.UpdateCartItemHandlerBody + +export type RemoveCartItemBody = Core.RemoveCartItemBody + +export type RemoveCartItemHandlerBody = Core.RemoveCartItemHandlerBody diff --git a/framework/shopify/utils/customer-token.ts b/framework/shopify/utils/customer-token.ts new file mode 100644 index 000000000..beae54765 --- /dev/null +++ b/framework/shopify/utils/customer-token.ts @@ -0,0 +1,12 @@ +import Cookies from 'js-cookie' +import { SHOPIFY_CUSTOMER_TOKEN_COOKIE } from '../const' + +export const getCustomerToken = () => Cookies.get(SHOPIFY_CUSTOMER_TOKEN_COOKIE) + +export const setCustomerToken = (token: string | null, options?: any) => { + if (!token) { + Cookies.remove(SHOPIFY_CUSTOMER_TOKEN_COOKIE) + } else { + Cookies.set(SHOPIFY_CUSTOMER_TOKEN_COOKIE, token, options) + } +} diff --git a/framework/shopify/utils/get-categories.ts b/framework/shopify/utils/get-categories.ts new file mode 100644 index 000000000..942ec9c62 --- /dev/null +++ b/framework/shopify/utils/get-categories.ts @@ -0,0 +1,29 @@ +import { ShopifyConfig } from '@framework/api' +import { CollectionEdge } from '@framework/schema' +import getSiteCollectionsQuery from './queries/get-all-collections-query' + +export type Category = { + endityId: string + name: string + path: string +} + +const getCategories = async (config: ShopifyConfig): Promise => { + const { data } = await config.fetch(getSiteCollectionsQuery, { + variables: { + first: 250, + }, + }) + + return ( + data.collections?.edges?.map( + ({ node: { title: name, handle } }: CollectionEdge) => ({ + entityId: handle, + name, + path: `/${handle}`, + }) + ) ?? [] + ) +} + +export default getCategories diff --git a/framework/shopify/utils/get-checkout-id.ts b/framework/shopify/utils/get-checkout-id.ts new file mode 100644 index 000000000..11e3802d9 --- /dev/null +++ b/framework/shopify/utils/get-checkout-id.ts @@ -0,0 +1,8 @@ +import Cookies from 'js-cookie' +import { SHOPIFY_CHECKOUT_ID_COOKIE } from '../const' + +const getCheckoutId = (id?: string) => { + return id ?? Cookies.get(SHOPIFY_CHECKOUT_ID_COOKIE) +} + +export default getCheckoutId diff --git a/framework/shopify/utils/get-search-variables.ts b/framework/shopify/utils/get-search-variables.ts new file mode 100644 index 000000000..90d35ba50 --- /dev/null +++ b/framework/shopify/utils/get-search-variables.ts @@ -0,0 +1,30 @@ +import getSortVariables from './get-sort-variables' +import type { SearchProductsInput } from '@framework/product/use-search' + +export const getSearchVariables = ({ + categoryId, + brandId, + search, + sort, +}: SearchProductsInput) => { + let query = '' + + if (search) { + query += `product_type:${search} OR title:${search} OR tag:${search}` + } + + if (categoryId) { + query += `tag:${categoryId}` + } + + if (brandId) { + query += `${categoryId ? ' AND ' : ''}vendor:${brandId}` + } + + return { + query, + ...getSortVariables(sort), + } +} + +export default getSearchVariables diff --git a/framework/shopify/utils/get-sort-variables.ts b/framework/shopify/utils/get-sort-variables.ts new file mode 100644 index 000000000..47650c0d7 --- /dev/null +++ b/framework/shopify/utils/get-sort-variables.ts @@ -0,0 +1,32 @@ +const getSortVariables = (sort?: string) => { + let output = {} + switch (sort) { + case 'price-asc': + output = { + sortKey: 'PRICE', + reverse: false, + } + break + case 'price-desc': + output = { + sortKey: 'PRICE', + reverse: true, + } + break + case 'trending-desc': + output = { + sortKey: 'BEST_SELLING', + reverse: false, + } + break + case 'latest-desc': + output = { + sortKey: 'CREATED_AT', + reverse: true, + } + break + } + return output +} + +export default getSortVariables diff --git a/framework/shopify/utils/get-vendors.ts b/framework/shopify/utils/get-vendors.ts new file mode 100644 index 000000000..d3ebce194 --- /dev/null +++ b/framework/shopify/utils/get-vendors.ts @@ -0,0 +1,36 @@ +import { ShopifyConfig } from '@framework/api' +import fetchAllProducts from '@framework/api/utils/fetch-all-products' +import getAllProductVendors from './queries/get-all-product-vendors-query' + +export type BrandNode = { + name: string + path: string +} + +export type BrandEdge = { + node: BrandNode +} + +export type Brands = BrandEdge[] + +const getVendors = async (config: ShopifyConfig): Promise => { + const vendors = await fetchAllProducts({ + config, + query: getAllProductVendors, + variables: { + first: 250, + }, + }) + + let vendorsStrings = vendors.map(({ node: { vendor } }) => vendor) + + return [...new Set(vendorsStrings)].map((v) => ({ + node: { + entityId: v, + name: v, + path: `brands/${v}`, + }, + })) +} + +export default getVendors diff --git a/framework/shopify/utils/handle-fetch-response.ts b/framework/shopify/utils/handle-fetch-response.ts new file mode 100644 index 000000000..8d7427d91 --- /dev/null +++ b/framework/shopify/utils/handle-fetch-response.ts @@ -0,0 +1,27 @@ +import { FetcherError } from '@commerce/utils/errors' + +export function getError(errors: any[], status: number) { + errors = errors ?? [{ message: 'Failed to fetch Shopify API' }] + return new FetcherError({ errors, status }) +} + +export async function getAsyncError(res: Response) { + const data = await res.json() + return getError(data.errors, res.status) +} + +const handleFetchResponse = async (res: Response) => { + if (res.ok) { + const { data, errors } = await res.json() + + if (errors && errors.length) { + throw getError(errors, res.status) + } + + return data + } + + throw await getAsyncError(res) +} + +export default handleFetchResponse diff --git a/framework/shopify/utils/handle-login.ts b/framework/shopify/utils/handle-login.ts new file mode 100644 index 000000000..77b6873e3 --- /dev/null +++ b/framework/shopify/utils/handle-login.ts @@ -0,0 +1,39 @@ +import { ValidationError } from '@commerce/utils/errors' +import { setCustomerToken } from './customer-token' + +const getErrorMessage = ({ + code, + message, +}: { + code: string + message: string +}) => { + switch (code) { + case 'UNIDENTIFIED_CUSTOMER': + message = 'Cannot find an account that matches the provided credentials' + break + } + return message +} + +const handleLogin = (data: any) => { + const response = data.customerAccessTokenCreate + const errors = response?.customerUserErrors + + if (errors && errors.length) { + throw new ValidationError({ + message: getErrorMessage(errors[0]), + }) + } + + const customerAccessToken = response?.customerAccessToken + const accessToken = customerAccessToken?.accessToken + + if (accessToken) { + setCustomerToken(accessToken) + } + + return customerAccessToken +} + +export default handleLogin diff --git a/framework/shopify/utils/index.ts b/framework/shopify/utils/index.ts new file mode 100644 index 000000000..2d59aa506 --- /dev/null +++ b/framework/shopify/utils/index.ts @@ -0,0 +1,10 @@ +export { default as handleFetchResponse } from './handle-fetch-response' +export { default as getSearchVariables } from './get-search-variables' +export { default as getSortVariables } from './get-sort-variables' +export { default as getVendors } from './get-vendors' +export { default as getCategories } from './get-categories' +export { default as getCheckoutId } from './get-checkout-id' +export * from './queries' +export * from './mutations' +export * from './normalize' +export * from './customer-token' diff --git a/framework/shopify/utils/mutations/associate-customer-with-checkout.ts b/framework/shopify/utils/mutations/associate-customer-with-checkout.ts new file mode 100644 index 000000000..6b1350e05 --- /dev/null +++ b/framework/shopify/utils/mutations/associate-customer-with-checkout.ts @@ -0,0 +1,18 @@ +const associateCustomerWithCheckoutMutation = /* GraphQl */ ` +mutation associateCustomerWithCheckout($checkoutId: ID!, $customerAccessToken: String!) { + checkoutCustomerAssociateV2(checkoutId: $checkoutId, customerAccessToken: $customerAccessToken) { + checkout { + id + } + checkoutUserErrors { + code + field + message + } + customer { + id + } + } + } +` +export default associateCustomerWithCheckoutMutation diff --git a/framework/shopify/utils/mutations/checkout-create.ts b/framework/shopify/utils/mutations/checkout-create.ts new file mode 100644 index 000000000..912e1cbd2 --- /dev/null +++ b/framework/shopify/utils/mutations/checkout-create.ts @@ -0,0 +1,16 @@ +import { checkoutDetailsFragment } from '../queries/get-checkout-query' + +const checkoutCreateMutation = /* GraphQL */ ` + mutation { + checkoutCreate(input: {}) { + userErrors { + message + field + } + checkout { + ${checkoutDetailsFragment} + } + } + } +` +export default checkoutCreateMutation diff --git a/framework/shopify/utils/mutations/checkout-line-item-add.ts b/framework/shopify/utils/mutations/checkout-line-item-add.ts new file mode 100644 index 000000000..67b9cf250 --- /dev/null +++ b/framework/shopify/utils/mutations/checkout-line-item-add.ts @@ -0,0 +1,16 @@ +import { checkoutDetailsFragment } from '../queries/get-checkout-query' + +const checkoutLineItemAddMutation = /* GraphQL */ ` + mutation($checkoutId: ID!, $lineItems: [CheckoutLineItemInput!]!) { + checkoutLineItemsAdd(checkoutId: $checkoutId, lineItems: $lineItems) { + userErrors { + message + field + } + checkout { + ${checkoutDetailsFragment} + } + } + } +` +export default checkoutLineItemAddMutation diff --git a/framework/shopify/utils/mutations/checkout-line-item-remove.ts b/framework/shopify/utils/mutations/checkout-line-item-remove.ts new file mode 100644 index 000000000..d967a5168 --- /dev/null +++ b/framework/shopify/utils/mutations/checkout-line-item-remove.ts @@ -0,0 +1,19 @@ +import { checkoutDetailsFragment } from '../queries/get-checkout-query' + +const checkoutLineItemRemoveMutation = /* GraphQL */ ` + mutation($checkoutId: ID!, $lineItemIds: [ID!]!) { + checkoutLineItemsRemove( + checkoutId: $checkoutId + lineItemIds: $lineItemIds + ) { + userErrors { + message + field + } + checkout { + ${checkoutDetailsFragment} + } + } + } +` +export default checkoutLineItemRemoveMutation diff --git a/framework/shopify/utils/mutations/checkout-line-item-update.ts b/framework/shopify/utils/mutations/checkout-line-item-update.ts new file mode 100644 index 000000000..8edf17587 --- /dev/null +++ b/framework/shopify/utils/mutations/checkout-line-item-update.ts @@ -0,0 +1,16 @@ +import { checkoutDetailsFragment } from '../queries/get-checkout-query' + +const checkoutLineItemUpdateMutation = /* GraphQL */ ` + mutation($checkoutId: ID!, $lineItems: [CheckoutLineItemUpdateInput!]!) { + checkoutLineItemsUpdate(checkoutId: $checkoutId, lineItems: $lineItems) { + userErrors { + message + field + } + checkout { + ${checkoutDetailsFragment} + } + } + } +` +export default checkoutLineItemUpdateMutation diff --git a/framework/shopify/utils/mutations/customer-access-token-create.ts b/framework/shopify/utils/mutations/customer-access-token-create.ts new file mode 100644 index 000000000..7a45c3f49 --- /dev/null +++ b/framework/shopify/utils/mutations/customer-access-token-create.ts @@ -0,0 +1,16 @@ +const customerAccessTokenCreateMutation = /* GraphQL */ ` + mutation customerAccessTokenCreate($input: CustomerAccessTokenCreateInput!) { + customerAccessTokenCreate(input: $input) { + customerAccessToken { + accessToken + expiresAt + } + customerUserErrors { + code + field + message + } + } + } +` +export default customerAccessTokenCreateMutation diff --git a/framework/shopify/utils/mutations/customer-access-token-delete.ts b/framework/shopify/utils/mutations/customer-access-token-delete.ts new file mode 100644 index 000000000..c46eff1e5 --- /dev/null +++ b/framework/shopify/utils/mutations/customer-access-token-delete.ts @@ -0,0 +1,14 @@ +const customerAccessTokenDeleteMutation = /* GraphQL */ ` + mutation customerAccessTokenDelete($customerAccessToken: String!) { + customerAccessTokenDelete(customerAccessToken: $customerAccessToken) { + deletedAccessToken + deletedCustomerAccessTokenId + userErrors { + field + message + } + } + } +` + +export default customerAccessTokenDeleteMutation diff --git a/framework/shopify/utils/mutations/customer-create.ts b/framework/shopify/utils/mutations/customer-create.ts new file mode 100644 index 000000000..05c728a25 --- /dev/null +++ b/framework/shopify/utils/mutations/customer-create.ts @@ -0,0 +1,15 @@ +const customerCreateMutation = /* GraphQL */ ` + mutation customerCreate($input: CustomerCreateInput!) { + customerCreate(input: $input) { + customerUserErrors { + code + field + message + } + customer { + id + } + } + } +` +export default customerCreateMutation diff --git a/framework/shopify/utils/mutations/index.ts b/framework/shopify/utils/mutations/index.ts new file mode 100644 index 000000000..3a16d7cec --- /dev/null +++ b/framework/shopify/utils/mutations/index.ts @@ -0,0 +1,7 @@ +export { default as customerCreateMutation } from './customer-create' +export { default as checkoutCreateMutation } from './checkout-create' +export { default as checkoutLineItemAddMutation } from './checkout-line-item-add' +export { default as checkoutLineItemUpdateMutation } from './checkout-line-item-update' +export { default as checkoutLineItemRemoveMutation } from './checkout-line-item-remove' +export { default as customerAccessTokenCreateMutation } from './customer-access-token-create' +export { default as customerAccessTokenDeleteMutation } from './customer-access-token-delete' diff --git a/framework/shopify/utils/normalize.ts b/framework/shopify/utils/normalize.ts new file mode 100644 index 000000000..1eee9f336 --- /dev/null +++ b/framework/shopify/utils/normalize.ts @@ -0,0 +1,133 @@ +import { + Product as ShopifyProduct, + Checkout, + CheckoutLineItemEdge, + SelectedOption, + ImageConnection, + ProductVariantConnection, + ProductOption, + MoneyV2, +} from '@framework/schema' + +import type { Cart, LineItem } from '../types' + +const money = ({ amount, currencyCode }: MoneyV2) => { + return { + value: +amount, + currencyCode, + } +} + +const normalizeProductOption = ({ + name: displayName, + values, + ...rest +}: ProductOption) => { + return { + __typename: 'MultipleChoiceOption', + displayName, + values: values.map((value) => ({ + label: value, + hexColors: displayName === 'Color' ? [value] : null, + })), + ...rest, + } +} + +const normalizeProductImages = ({ edges }: ImageConnection) => + edges?.map(({ node: { originalSrc: url, ...rest } }) => ({ + url, + ...rest, + })) + +const normalizeProductVariants = ({ edges }: ProductVariantConnection) => { + return edges?.map(({ node: { id, selectedOptions } }) => ({ + id, + options: selectedOptions.map(({ name, value }: SelectedOption) => + normalizeProductOption({ + id, + name, + values: [value], + }) + ), + })) +} + +export function normalizeProduct(productNode: ShopifyProduct): any { + const { + id, + title: name, + vendor, + images, + variants, + description, + handle, + priceRange, + options, + ...rest + } = productNode + + const product = { + id, + name, + vendor, + description, + path: `/${handle}`, + slug: handle?.replace(/^\/+|\/+$/g, ''), + price: money(priceRange?.minVariantPrice), + images: normalizeProductImages(images), + variants: variants ? normalizeProductVariants(variants) : [], + options: options ? options.map((o) => normalizeProductOption(o)) : [], + ...rest, + } + + return product +} + +export function normalizeCart(checkout: Checkout): Cart { + return { + id: checkout.id, + customerId: '', + email: '', + createdAt: checkout.createdAt, + currency: { + code: checkout.totalPriceV2?.currencyCode, + }, + taxesIncluded: checkout.taxesIncluded, + lineItems: checkout.lineItems?.edges.map(normalizeLineItem), + lineItemsSubtotalPrice: checkout.subtotalPriceV2?.amount, + subtotalPrice: checkout.subtotalPriceV2?.amount, + totalPrice: checkout.totalPriceV2?.amount, + discounts: [], + } +} + +function normalizeLineItem({ + node: { id, title, variant, quantity }, +}: CheckoutLineItemEdge): LineItem { + return { + id, + variantId: String(variant?.id), + productId: String(variant?.id), + name: `${title}`, + quantity, + variant: { + id: String(variant?.id), + sku: variant?.sku ?? '', + name: variant?.title!, + image: { + url: variant?.image?.originalSrc, + }, + requiresShipping: variant?.requiresShipping ?? false, + price: variant?.priceV2?.amount, + listPrice: variant?.compareAtPriceV2?.amount, + }, + path: '', + discounts: [], + options: [ + { + value: variant?.title, + }, + ], + } +} diff --git a/framework/shopify/utils/queries/get-all-collections-query.ts b/framework/shopify/utils/queries/get-all-collections-query.ts new file mode 100644 index 000000000..2abf374d6 --- /dev/null +++ b/framework/shopify/utils/queries/get-all-collections-query.ts @@ -0,0 +1,14 @@ +const getSiteCollectionsQuery = /* GraphQL */ ` + query getSiteCollections($first: Int!) { + collections(first: $first) { + edges { + node { + id + title + handle + } + } + } + } +` +export default getSiteCollectionsQuery diff --git a/framework/shopify/utils/queries/get-all-pages-query.ts b/framework/shopify/utils/queries/get-all-pages-query.ts new file mode 100644 index 000000000..e3aee1f10 --- /dev/null +++ b/framework/shopify/utils/queries/get-all-pages-query.ts @@ -0,0 +1,14 @@ +export const getAllPagesQuery = /* GraphQL */ ` + query getAllPages($first: Int = 250) { + pages(first: $first) { + edges { + node { + id + title + handle + } + } + } + } +` +export default getAllPagesQuery diff --git a/framework/shopify/utils/queries/get-all-product-vendors-query.ts b/framework/shopify/utils/queries/get-all-product-vendors-query.ts new file mode 100644 index 000000000..be08b8ec6 --- /dev/null +++ b/framework/shopify/utils/queries/get-all-product-vendors-query.ts @@ -0,0 +1,17 @@ +const getAllProductVendors = /* GraphQL */ ` + query getAllProductVendors($first: Int = 250, $cursor: String) { + products(first: $first, after: $cursor) { + pageInfo { + hasNextPage + hasPreviousPage + } + edges { + node { + vendor + } + cursor + } + } + } +` +export default getAllProductVendors diff --git a/framework/shopify/utils/queries/get-all-products-paths-query.ts b/framework/shopify/utils/queries/get-all-products-paths-query.ts new file mode 100644 index 000000000..56298c204 --- /dev/null +++ b/framework/shopify/utils/queries/get-all-products-paths-query.ts @@ -0,0 +1,17 @@ +const getAllProductsPathsQuery = /* GraphQL */ ` + query getAllProductPaths($first: Int = 250, $cursor: String) { + products(first: $first, after: $cursor) { + pageInfo { + hasNextPage + hasPreviousPage + } + edges { + node { + handle + } + cursor + } + } + } +` +export default getAllProductsPathsQuery diff --git a/framework/shopify/utils/queries/get-all-products-query.ts b/framework/shopify/utils/queries/get-all-products-query.ts new file mode 100644 index 000000000..4a6c20b6e --- /dev/null +++ b/framework/shopify/utils/queries/get-all-products-query.ts @@ -0,0 +1,54 @@ +export const productsFragment = ` +products( + first: $first + sortKey: $sortKey + reverse: $reverse + query: $query +) { + pageInfo { + hasNextPage + hasPreviousPage + } + edges { + node { + id + title + vendor + handle + description + priceRange { + minVariantPrice { + amount + currencyCode + } + } + images(first: 1) { + pageInfo { + hasNextPage + hasPreviousPage + } + edges { + node { + originalSrc + altText + width + height + } + } + } + } + } +} +` + +const getAllProductsQuery = /* GraphQL */ ` + query getAllProducts( + $first: Int = 250 + $query: String = "" + $sortKey: ProductSortKeys = RELEVANCE + $reverse: Boolean = false + ) { + ${productsFragment} + } +` +export default getAllProductsQuery diff --git a/framework/shopify/utils/queries/get-checkout-query.ts b/framework/shopify/utils/queries/get-checkout-query.ts new file mode 100644 index 000000000..194e1619a --- /dev/null +++ b/framework/shopify/utils/queries/get-checkout-query.ts @@ -0,0 +1,62 @@ +export const checkoutDetailsFragment = ` + id + webUrl + subtotalPriceV2{ + amount + currencyCode + } + totalTaxV2 { + amount + currencyCode + } + totalPriceV2 { + amount + currencyCode + } + completedAt + createdAt + taxesIncluded + lineItems(first: 250) { + pageInfo { + hasNextPage + hasPreviousPage + } + edges { + node { + id + title + variant { + id + sku + title + image { + originalSrc + altText + width + height + } + priceV2{ + amount + currencyCode + } + compareAtPriceV2{ + amount + currencyCode + } + } + quantity + } + } + } +` + +const getCheckoutQuery = /* GraphQL */ ` + query($checkoutId: ID!) { + node(id: $checkoutId) { + ... on Checkout { + ${checkoutDetailsFragment} + } + } + } +` +export default getCheckoutQuery diff --git a/framework/shopify/utils/queries/get-collection-products-query.ts b/framework/shopify/utils/queries/get-collection-products-query.ts new file mode 100644 index 000000000..dd504b575 --- /dev/null +++ b/framework/shopify/utils/queries/get-collection-products-query.ts @@ -0,0 +1,17 @@ +import { productsFragment } from './get-all-products-query' + +const getCollectionProductsQuery = /* GraphQL */ ` + query getProductsFromCollection( + $categoryHandle: String! + $first: Int = 250 + $query: String = "" + $sortKey: ProductSortKeys = RELEVANCE + $reverse: Boolean = false + ) { + collectionByHandle(handle: $categoryHandle) + { + ${productsFragment} + } + } +` +export default getCollectionProductsQuery diff --git a/framework/shopify/utils/queries/get-customer-id-query.ts b/framework/shopify/utils/queries/get-customer-id-query.ts new file mode 100644 index 000000000..076ceb10b --- /dev/null +++ b/framework/shopify/utils/queries/get-customer-id-query.ts @@ -0,0 +1,8 @@ +export const getCustomerQuery = /* GraphQL */ ` + query getCustomerId($customerAccessToken: String!) { + customer(customerAccessToken: $customerAccessToken) { + id + } + } +` +export default getCustomerQuery diff --git a/framework/shopify/utils/queries/get-customer-query.ts b/framework/shopify/utils/queries/get-customer-query.ts new file mode 100644 index 000000000..87e37e68d --- /dev/null +++ b/framework/shopify/utils/queries/get-customer-query.ts @@ -0,0 +1,16 @@ +export const getCustomerQuery = /* GraphQL */ ` + query getCustomer($customerAccessToken: String!) { + customer(customerAccessToken: $customerAccessToken) { + id + firstName + lastName + displayName + email + phone + tags + acceptsMarketing + createdAt + } + } +` +export default getCustomerQuery diff --git a/framework/shopify/utils/queries/get-page-query.ts b/framework/shopify/utils/queries/get-page-query.ts new file mode 100644 index 000000000..dcafdc30d --- /dev/null +++ b/framework/shopify/utils/queries/get-page-query.ts @@ -0,0 +1,13 @@ +export const getPageQuery = /* GraphQL */ ` + query getPageBySlug($slug: String!) { + pageByHandle(handle: $slug) { + id + title + handle + body + bodySummary + url + } + } +` +export default getPageQuery diff --git a/framework/shopify/utils/queries/get-product-query.ts b/framework/shopify/utils/queries/get-product-query.ts new file mode 100644 index 000000000..d054c023d --- /dev/null +++ b/framework/shopify/utils/queries/get-product-query.ts @@ -0,0 +1,68 @@ +const getProductQuery = /* GraphQL */ ` + query getProductBySlug($slug: String!) { + productByHandle(handle: $slug) { + id + handle + title + productType + vendor + description + descriptionHtml + options { + id + name + values + } + priceRange { + maxVariantPrice { + amount + currencyCode + } + minVariantPrice { + amount + currencyCode + } + } + variants(first: 250) { + pageInfo { + hasNextPage + hasPreviousPage + } + edges { + node { + id + title + selectedOptions { + name + value + } + priceV2 { + amount + currencyCode + } + compareAtPriceV2 { + amount + currencyCode + } + } + } + } + images(first: 250) { + pageInfo { + hasNextPage + hasPreviousPage + } + edges { + node { + originalSrc + altText + width + height + } + } + } + } + } +` + +export default getProductQuery diff --git a/framework/shopify/utils/queries/index.ts b/framework/shopify/utils/queries/index.ts new file mode 100644 index 000000000..e19be9c8c --- /dev/null +++ b/framework/shopify/utils/queries/index.ts @@ -0,0 +1,10 @@ +export { default as getSiteCollectionsQuery } from './get-all-collections-query' +export { default as getProductQuery } from './get-product-query' +export { default as getAllProductsQuery } from './get-all-products-query' +export { default as getAllProductsPathtsQuery } from './get-all-products-paths-query' +export { default as getAllProductVendors } from './get-all-product-vendors-query' +export { default as getCollectionProductsQuery } from './get-collection-products-query' +export { default as getCheckoutQuery } from './get-checkout-query' +export { default as getAllPagesQuery } from './get-all-pages-query' +export { default as getPageQuery } from './get-page-query' +export { default as getCustomerQuery } from './get-customer-query' diff --git a/framework/shopify/wishlist/use-wishlist.tsx b/framework/shopify/wishlist/use-wishlist.tsx index 2aac16810..f8db4216f 100644 --- a/framework/shopify/wishlist/use-wishlist.tsx +++ b/framework/shopify/wishlist/use-wishlist.tsx @@ -1,7 +1,7 @@ import { HookFetcher } from '@commerce/utils/types' import { SwrOptions } from '@commerce/utils/use-data' import useCommerceWishlist from '@commerce/wishlist/use-wishlist' -import { Product } from '../types' +import { Product } from '../schema' import useCustomer from '../customer/use-customer' const defaultOpts = {} diff --git a/next.config.js b/next.config.js index 725024066..742a0690e 100644 --- a/next.config.js +++ b/next.config.js @@ -1,7 +1,8 @@ const withCommerceConfig = require('./framework/commerce/with-config') -const commerce = { provider: 'bigcommerce' } +const commerce = { provider: 'shopify' } const isBC = commerce.provider === 'bigcommerce' +const isShopify = commerce.provider === 'shopify' module.exports = withCommerceConfig({ commerce, @@ -11,7 +12,7 @@ module.exports = withCommerceConfig({ }, rewrites() { return [ - isBC && { + (isBC || isShopify) && { source: '/checkout', destination: '/api/bigcommerce/checkout', }, diff --git a/tsconfig.json b/tsconfig.json index 9e712fb18..e20f37099 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -22,8 +22,8 @@ "@components/*": ["components/*"], "@commerce": ["framework/commerce"], "@commerce/*": ["framework/commerce/*"], - "@framework": ["framework/bigcommerce"], - "@framework/*": ["framework/bigcommerce/*"] + "@framework": ["framework/shopify"], + "@framework/*": ["framework/shopify/*"] } }, "include": ["next-env.d.ts", "**/*.d.ts", "**/*.ts", "**/*.tsx", "**/*.js"], From 121ec4b61f9e778d7905de4b7059ecbf38febbad Mon Sep 17 00:00:00 2001 From: Luis Alvarez Date: Thu, 25 Feb 2021 16:39:01 -0500 Subject: [PATCH 176/216] Updated the commerce config structure --- commerce.config.json | 6 ++++++ .../bigcommerce/{config.json => commerce.config.json} | 1 + framework/bigcommerce/next.config.js | 7 ++----- framework/shopify/{config.json => commerce.config.json} | 1 + framework/shopify/next.config.js | 7 ++----- next.config.js | 4 +++- tsconfig.json | 4 ++-- 7 files changed, 17 insertions(+), 13 deletions(-) create mode 100644 commerce.config.json rename framework/bigcommerce/{config.json => commerce.config.json} (60%) rename framework/shopify/{config.json => commerce.config.json} (64%) diff --git a/commerce.config.json b/commerce.config.json new file mode 100644 index 000000000..1c14a53f5 --- /dev/null +++ b/commerce.config.json @@ -0,0 +1,6 @@ +{ + "provider": "bigcommerce", + "features": { + "wishlist": false + } +} diff --git a/framework/bigcommerce/config.json b/framework/bigcommerce/commerce.config.json similarity index 60% rename from framework/bigcommerce/config.json rename to framework/bigcommerce/commerce.config.json index a0e7afc5d..3a8738f47 100644 --- a/framework/bigcommerce/config.json +++ b/framework/bigcommerce/commerce.config.json @@ -1,4 +1,5 @@ { + "provider": "bigcommerce", "features": { "wishlist": true } diff --git a/framework/bigcommerce/next.config.js b/framework/bigcommerce/next.config.js index 5703f2343..f33b16630 100644 --- a/framework/bigcommerce/next.config.js +++ b/framework/bigcommerce/next.config.js @@ -1,10 +1,7 @@ -const providerConfig = require('./config.json') +const commerce = require('./commerce.config.json') module.exports = { - commerce: { - provider: 'bigcommerce', - ...providerConfig, - }, + commerce, images: { domains: ['cdn11.bigcommerce.com'], }, diff --git a/framework/shopify/config.json b/framework/shopify/commerce.config.json similarity index 64% rename from framework/shopify/config.json rename to framework/shopify/commerce.config.json index 17ef37e25..b30ab39d9 100644 --- a/framework/shopify/config.json +++ b/framework/shopify/commerce.config.json @@ -1,4 +1,5 @@ { + "provider": "shopify", "features": { "wishlist": false } diff --git a/framework/shopify/next.config.js b/framework/shopify/next.config.js index 0f9bc31ff..e9d48c02c 100644 --- a/framework/shopify/next.config.js +++ b/framework/shopify/next.config.js @@ -1,10 +1,7 @@ -const providerConfig = require('./config.json') +const commerce = require('./commerce.config.json') module.exports = { - commerce: { - provider: 'shopify', - ...providerConfig, - }, + commerce, images: { domains: ['cdn.shopify.com'], }, diff --git a/next.config.js b/next.config.js index 742a0690e..046ba2aa1 100644 --- a/next.config.js +++ b/next.config.js @@ -1,6 +1,6 @@ +const commerce = require('./commerce.config.json') const withCommerceConfig = require('./framework/commerce/with-config') -const commerce = { provider: 'shopify' } const isBC = commerce.provider === 'bigcommerce' const isShopify = commerce.provider === 'shopify' @@ -39,3 +39,5 @@ module.exports = withCommerceConfig({ ].filter((x) => x) }, }) + +console.log('configs', module.exports) diff --git a/tsconfig.json b/tsconfig.json index e20f37099..9e712fb18 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -22,8 +22,8 @@ "@components/*": ["components/*"], "@commerce": ["framework/commerce"], "@commerce/*": ["framework/commerce/*"], - "@framework": ["framework/shopify"], - "@framework/*": ["framework/shopify/*"] + "@framework": ["framework/bigcommerce"], + "@framework/*": ["framework/bigcommerce/*"] } }, "include": ["next-env.d.ts", "**/*.d.ts", "**/*.ts", "**/*.tsx", "**/*.js"], From 46ae76c67f3d1e0fb987cf85aca3f7afb54c2df0 Mon Sep 17 00:00:00 2001 From: Luis Alvarez Date: Thu, 25 Feb 2021 16:54:18 -0500 Subject: [PATCH 177/216] Removed @framework imports within framework providers --- framework/bigcommerce/product/get-product.ts | 2 +- framework/shopify/api/checkout/index.ts | 4 ++-- framework/shopify/api/index.ts | 2 +- framework/shopify/api/utils/fetch-all-products.ts | 2 +- framework/shopify/api/utils/fetch-graphql-api.ts | 2 +- framework/shopify/auth/use-login.tsx | 4 ++-- framework/shopify/auth/use-logout.tsx | 7 ++----- framework/shopify/auth/use-signup.tsx | 6 +++--- framework/shopify/cart/use-remove-item.tsx | 9 +++------ framework/shopify/cart/use-update-item.tsx | 5 +---- framework/shopify/cart/utils/checkout-create.ts | 4 ++-- framework/shopify/cart/utils/checkout-to-cart.ts | 4 ++-- framework/shopify/common/get-site-info.ts | 4 ++-- framework/shopify/customer/get-customer-id.ts | 4 ++-- framework/shopify/product/get-all-collections.ts | 2 +- framework/shopify/product/get-all-products.ts | 2 +- framework/shopify/product/use-search.tsx | 12 +++++++----- framework/shopify/utils/get-categories.ts | 4 ++-- framework/shopify/utils/get-search-variables.ts | 2 +- framework/shopify/utils/get-vendors.ts | 4 ++-- framework/shopify/utils/normalize.ts | 2 +- 21 files changed, 40 insertions(+), 47 deletions(-) diff --git a/framework/bigcommerce/product/get-product.ts b/framework/bigcommerce/product/get-product.ts index 7d77eb194..b52568b62 100644 --- a/framework/bigcommerce/product/get-product.ts +++ b/framework/bigcommerce/product/get-product.ts @@ -2,7 +2,7 @@ import type { GetProductQuery, GetProductQueryVariables } from '../schema' import setProductLocaleMeta from '../api/utils/set-product-locale-meta' import { productInfoFragment } from '../api/fragments/product' import { BigcommerceConfig, getConfig } from '../api' -import { normalizeProduct } from '@framework/lib/normalize' +import { normalizeProduct } from '../lib/normalize' import type { Product } from '@commerce/types' export const getProductQuery = /* GraphQL */ ` diff --git a/framework/shopify/api/checkout/index.ts b/framework/shopify/api/checkout/index.ts index d5d6d7f6e..244078466 100644 --- a/framework/shopify/api/checkout/index.ts +++ b/framework/shopify/api/checkout/index.ts @@ -7,10 +7,10 @@ import { SHOPIFY_CHECKOUT_ID_COOKIE, SHOPIFY_CHECKOUT_URL_COOKIE, SHOPIFY_CUSTOMER_TOKEN_COOKIE, -} from '@framework/const' +} from '../../const' import { getConfig } from '..' -import associateCustomerWithCheckoutMutation from '@framework/utils/mutations/associate-customer-with-checkout' +import associateCustomerWithCheckoutMutation from '../../utils/mutations/associate-customer-with-checkout' const METHODS = ['GET'] diff --git a/framework/shopify/api/index.ts b/framework/shopify/api/index.ts index 184d03748..0fe58f2df 100644 --- a/framework/shopify/api/index.ts +++ b/framework/shopify/api/index.ts @@ -5,7 +5,7 @@ import { API_TOKEN, SHOPIFY_CHECKOUT_ID_COOKIE, SHOPIFY_CUSTOMER_TOKEN_COOKIE, -} from '@framework/const' +} from '../const' if (!API_URL) { console.log(process.env) diff --git a/framework/shopify/api/utils/fetch-all-products.ts b/framework/shopify/api/utils/fetch-all-products.ts index efeb809f1..9fa70a5ee 100644 --- a/framework/shopify/api/utils/fetch-all-products.ts +++ b/framework/shopify/api/utils/fetch-all-products.ts @@ -1,4 +1,4 @@ -import { ProductEdge } from '@framework/schema' +import { ProductEdge } from '../../schema' import { ShopifyConfig } from '..' const fetchAllProducts = async ({ diff --git a/framework/shopify/api/utils/fetch-graphql-api.ts b/framework/shopify/api/utils/fetch-graphql-api.ts index 92d4f2cf6..321cba2aa 100644 --- a/framework/shopify/api/utils/fetch-graphql-api.ts +++ b/framework/shopify/api/utils/fetch-graphql-api.ts @@ -2,7 +2,7 @@ import type { GraphQLFetcher } from '@commerce/api' import fetch from './fetch' import { API_URL, API_TOKEN } from '../../const' -import { getError } from '@framework/utils/handle-fetch-response' +import { getError } from '../../utils/handle-fetch-response' const fetchGraphqlApi: GraphQLFetcher = async ( query: string, diff --git a/framework/shopify/auth/use-login.tsx b/framework/shopify/auth/use-login.tsx index 32dd91920..188dd54a2 100644 --- a/framework/shopify/auth/use-login.tsx +++ b/framework/shopify/auth/use-login.tsx @@ -8,9 +8,9 @@ import { CustomerUserError, Mutation, MutationCheckoutCreateArgs, -} from '@framework/schema' +} from '../schema' import useLogin, { UseLogin } from '@commerce/auth/use-login' -import { setCustomerToken } from '@framework/utils' +import { setCustomerToken } from '../utils' export default useLogin as UseLogin diff --git a/framework/shopify/auth/use-logout.tsx b/framework/shopify/auth/use-logout.tsx index ccbeb8166..81a3b8cdd 100644 --- a/framework/shopify/auth/use-logout.tsx +++ b/framework/shopify/auth/use-logout.tsx @@ -2,11 +2,8 @@ import { useCallback } from 'react' import type { MutationHook } from '@commerce/utils/types' import useLogout, { UseLogout } from '@commerce/auth/use-logout' import useCustomer from '../customer/use-customer' -import customerAccessTokenDeleteMutation from '@framework/utils/mutations/customer-access-token-delete' -import { - getCustomerToken, - setCustomerToken, -} from '@framework/utils/customer-token' +import customerAccessTokenDeleteMutation from '../utils/mutations/customer-access-token-delete' +import { getCustomerToken, setCustomerToken } from '../utils/customer-token' export default useLogout as UseLogout diff --git a/framework/shopify/auth/use-signup.tsx b/framework/shopify/auth/use-signup.tsx index f072f1925..7f66448d3 100644 --- a/framework/shopify/auth/use-signup.tsx +++ b/framework/shopify/auth/use-signup.tsx @@ -3,13 +3,13 @@ import type { MutationHook } from '@commerce/utils/types' import { CommerceError } from '@commerce/utils/errors' import useSignup, { UseSignup } from '@commerce/auth/use-signup' import useCustomer from '../customer/use-customer' -import { CustomerCreateInput } from '@framework/schema' +import { CustomerCreateInput } from '../schema' import { customerCreateMutation, customerAccessTokenCreateMutation, -} from '@framework/utils/mutations' -import handleLogin from '@framework/utils/handle-login' +} from '../utils/mutations' +import handleLogin from '../utils/handle-login' export default useSignup as UseSignup diff --git a/framework/shopify/cart/use-remove-item.tsx b/framework/shopify/cart/use-remove-item.tsx index 1963176c8..e2aef13d8 100644 --- a/framework/shopify/cart/use-remove-item.tsx +++ b/framework/shopify/cart/use-remove-item.tsx @@ -13,13 +13,10 @@ import useRemoveItem, { } from '@commerce/cart/use-remove-item' import useCart from './use-cart' -import { checkoutLineItemRemoveMutation, getCheckoutId } from '@framework/utils' +import { checkoutLineItemRemoveMutation, getCheckoutId } from '../utils' import { checkoutToCart } from './utils' -import { Cart, LineItem } from '@framework/types' -import { - Mutation, - MutationCheckoutLineItemsRemoveArgs, -} from '@framework/schema' +import { Cart, LineItem } from '../types' +import { Mutation, MutationCheckoutLineItemsRemoveArgs } from '../schema' import { RemoveCartItemBody } from '@commerce/types' export type RemoveItemFn = T extends LineItem diff --git a/framework/shopify/cart/use-update-item.tsx b/framework/shopify/cart/use-update-item.tsx index 9e89d0aca..666ce3d08 100644 --- a/framework/shopify/cart/use-update-item.tsx +++ b/framework/shopify/cart/use-update-item.tsx @@ -15,10 +15,7 @@ import { handler as removeItemHandler } from './use-remove-item' import type { Cart, LineItem, UpdateCartItemBody } from '../types' import { checkoutToCart } from './utils' import { getCheckoutId, checkoutLineItemUpdateMutation } from '../utils' -import { - Mutation, - MutationCheckoutLineItemsUpdateArgs, -} from '@framework/schema' +import { Mutation, MutationCheckoutLineItemsUpdateArgs } from '../schema' export type UpdateItemInput = T extends LineItem ? Partial> diff --git a/framework/shopify/cart/utils/checkout-create.ts b/framework/shopify/cart/utils/checkout-create.ts index 0e71be62f..6c4f81c21 100644 --- a/framework/shopify/cart/utils/checkout-create.ts +++ b/framework/shopify/cart/utils/checkout-create.ts @@ -1,9 +1,9 @@ import { SHOPIFY_CHECKOUT_ID_COOKIE, SHOPIFY_CHECKOUT_URL_COOKIE, -} from '@framework/const' +} from '../../const' -import checkoutCreateMutation from '@framework/utils/mutations/checkout-create' +import checkoutCreateMutation from '../../utils/mutations/checkout-create' import Cookies from 'js-cookie' export const checkoutCreate = async (fetch: any) => { diff --git a/framework/shopify/cart/utils/checkout-to-cart.ts b/framework/shopify/cart/utils/checkout-to-cart.ts index 662db1c45..fa8b988f9 100644 --- a/framework/shopify/cart/utils/checkout-to-cart.ts +++ b/framework/shopify/cart/utils/checkout-to-cart.ts @@ -6,8 +6,8 @@ import { CheckoutLineItemsRemovePayload, CheckoutLineItemsUpdatePayload, Maybe, -} from '@framework/schema' -import { normalizeCart } from '@framework/utils' +} from '../../schema' +import { normalizeCart } from '../../utils' export type CheckoutPayload = | CheckoutLineItemsAddPayload diff --git a/framework/shopify/common/get-site-info.ts b/framework/shopify/common/get-site-info.ts index f6cdaad85..cbbacf5b6 100644 --- a/framework/shopify/common/get-site-info.ts +++ b/framework/shopify/common/get-site-info.ts @@ -1,5 +1,5 @@ -import getCategories, { Category } from '@framework/utils/get-categories' -import getVendors, { Brands } from '@framework/utils/get-vendors' +import getCategories, { Category } from '../utils/get-categories' +import getVendors, { Brands } from '../utils/get-vendors' import { getConfig, ShopifyConfig } from '../api' diff --git a/framework/shopify/customer/get-customer-id.ts b/framework/shopify/customer/get-customer-id.ts index 78309a8ec..ca096645a 100644 --- a/framework/shopify/customer/get-customer-id.ts +++ b/framework/shopify/customer/get-customer-id.ts @@ -1,5 +1,5 @@ -import { getConfig, ShopifyConfig } from '@framework/api' -import getCustomerIdQuery from '@framework/utils/queries/get-customer-id-query' +import { getConfig, ShopifyConfig } from '../api' +import getCustomerIdQuery from '../utils/queries/get-customer-id-query' import Cookies from 'js-cookie' async function getCustomerId({ diff --git a/framework/shopify/product/get-all-collections.ts b/framework/shopify/product/get-all-collections.ts index bf3fee392..15c4bc51a 100644 --- a/framework/shopify/product/get-all-collections.ts +++ b/framework/shopify/product/get-all-collections.ts @@ -1,4 +1,4 @@ -import { CollectionEdge } from '@framework/schema' +import { CollectionEdge } from '../schema' import { getConfig, ShopifyConfig } from '../api' import getAllCollectionsQuery from '../utils/queries/get-all-collections-query' diff --git a/framework/shopify/product/get-all-products.ts b/framework/shopify/product/get-all-products.ts index e1eb96aac..14e486563 100644 --- a/framework/shopify/product/get-all-products.ts +++ b/framework/shopify/product/get-all-products.ts @@ -2,7 +2,7 @@ import { GraphQLFetcherResult } from '@commerce/api' import { getConfig, ShopifyConfig } from '../api' import { ProductEdge } from '../schema' import { getAllProductsQuery } from '../utils/queries' -import { normalizeProduct } from '@framework/utils/normalize' +import { normalizeProduct } from '../utils/normalize' import { Product } from '@commerce/types' type Variables = { diff --git a/framework/shopify/product/use-search.tsx b/framework/shopify/product/use-search.tsx index 7ca37916b..4b14249ca 100644 --- a/framework/shopify/product/use-search.tsx +++ b/framework/shopify/product/use-search.tsx @@ -1,17 +1,16 @@ import { SWRHook } from '@commerce/utils/types' import useSearch, { UseSearch } from '@commerce/product/use-search' -import { ProductEdge } from '@framework/schema' +import { ProductEdge } from '../schema' import { getAllProductsQuery, getSearchVariables, normalizeProduct, -} from '@framework/utils' -import type { ShopifyProvider } from '..' +} from '../utils' import { Product } from '@commerce/types' -export default useSearch as UseSearch +export default useSearch as UseSearch export type SearchProductsInput = { search?: string @@ -40,7 +39,10 @@ export const handler: SWRHook< }) const edges = resp.products?.edges return { - products: edges?.map(({ node: p }: ProductEdge) => normalizeProduct(p)), + products: edges?.map(({ node: p }: ProductEdge) => + // TODO: Fix this product type + normalizeProduct(p as any) + ), found: !!edges?.length, } }, diff --git a/framework/shopify/utils/get-categories.ts b/framework/shopify/utils/get-categories.ts index 942ec9c62..e1176b068 100644 --- a/framework/shopify/utils/get-categories.ts +++ b/framework/shopify/utils/get-categories.ts @@ -1,5 +1,5 @@ -import { ShopifyConfig } from '@framework/api' -import { CollectionEdge } from '@framework/schema' +import { ShopifyConfig } from '../api' +import { CollectionEdge } from '../schema' import getSiteCollectionsQuery from './queries/get-all-collections-query' export type Category = { diff --git a/framework/shopify/utils/get-search-variables.ts b/framework/shopify/utils/get-search-variables.ts index 90d35ba50..6f5d08b1a 100644 --- a/framework/shopify/utils/get-search-variables.ts +++ b/framework/shopify/utils/get-search-variables.ts @@ -1,5 +1,5 @@ import getSortVariables from './get-sort-variables' -import type { SearchProductsInput } from '@framework/product/use-search' +import type { SearchProductsInput } from '../product/use-search' export const getSearchVariables = ({ categoryId, diff --git a/framework/shopify/utils/get-vendors.ts b/framework/shopify/utils/get-vendors.ts index d3ebce194..f04483bb1 100644 --- a/framework/shopify/utils/get-vendors.ts +++ b/framework/shopify/utils/get-vendors.ts @@ -1,5 +1,5 @@ -import { ShopifyConfig } from '@framework/api' -import fetchAllProducts from '@framework/api/utils/fetch-all-products' +import { ShopifyConfig } from '../api' +import fetchAllProducts from '../api/utils/fetch-all-products' import getAllProductVendors from './queries/get-all-product-vendors-query' export type BrandNode = { diff --git a/framework/shopify/utils/normalize.ts b/framework/shopify/utils/normalize.ts index 1eee9f336..67ab3a8a2 100644 --- a/framework/shopify/utils/normalize.ts +++ b/framework/shopify/utils/normalize.ts @@ -7,7 +7,7 @@ import { ProductVariantConnection, ProductOption, MoneyV2, -} from '@framework/schema' +} from '../schema' import type { Cart, LineItem } from '../types' From e90d9a2121e4b5f4e8967f9619548ad937956dd3 Mon Sep 17 00:00:00 2001 From: Luis Alvarez Date: Thu, 25 Feb 2021 17:18:50 -0500 Subject: [PATCH 178/216] Fixed types --- framework/shopify/api/operations/get-page.ts | 4 +--- framework/shopify/cart/use-add-item.tsx | 3 ++- framework/shopify/cart/use-cart.tsx | 7 +++---- framework/shopify/cart/utils/fetcher.ts | 3 ++- framework/shopify/customer/use-customer.tsx | 4 ++-- framework/shopify/types.ts | 3 --- .../shopify/utils/to-commerce-products.ts | 18 +++++++++++++----- framework/shopify/wishlist/use-wishlist.tsx | 7 +++++-- next.config.js | 2 -- 9 files changed, 28 insertions(+), 23 deletions(-) diff --git a/framework/shopify/api/operations/get-page.ts b/framework/shopify/api/operations/get-page.ts index 11651e335..32acb7c8f 100644 --- a/framework/shopify/api/operations/get-page.ts +++ b/framework/shopify/api/operations/get-page.ts @@ -1,7 +1,5 @@ +import { Page } from '../../schema' import { ShopifyConfig, getConfig } from '..' -import type { Page } from '../../types' - -export type { Page } export type GetPageResult = T diff --git a/framework/shopify/cart/use-add-item.tsx b/framework/shopify/cart/use-add-item.tsx index 36f02847b..d0f891148 100644 --- a/framework/shopify/cart/use-add-item.tsx +++ b/framework/shopify/cart/use-add-item.tsx @@ -40,7 +40,8 @@ export const handler: MutationHook = { }, }) - return checkoutToCart(checkoutLineItemsAdd) + // TODO: Fix this Cart type here + return checkoutToCart(checkoutLineItemsAdd) as any }, useHook: ({ fetch }) => () => { const { mutate } = useCart() diff --git a/framework/shopify/cart/use-cart.tsx b/framework/shopify/cart/use-cart.tsx index 2cf3a3e95..5f1f87299 100644 --- a/framework/shopify/cart/use-cart.tsx +++ b/framework/shopify/cart/use-cart.tsx @@ -1,6 +1,4 @@ import { useMemo } from 'react' -import type { ShopifyProvider } from '..' - import useCommerceCart, { FetchCartInput, UseCart, @@ -11,7 +9,7 @@ import { SWRHook } from '@commerce/utils/types' import { checkoutCreate, checkoutToCart } from './utils' import getCheckoutQuery from '../utils/queries/get-checkout-query' -export default useCommerceCart as UseCart +export default useCommerceCart as UseCart export const handler: SWRHook< Cart | null, @@ -38,7 +36,8 @@ export const handler: SWRHook< checkout = await checkoutCreate(fetch) } - return checkoutToCart({ checkout }) + // TODO: Fix this type + return checkoutToCart({ checkout } as any) }, useHook: ({ useData }) => (input) => { const response = useData({ diff --git a/framework/shopify/cart/utils/fetcher.ts b/framework/shopify/cart/utils/fetcher.ts index a69492f0d..6afb55f18 100644 --- a/framework/shopify/cart/utils/fetcher.ts +++ b/framework/shopify/cart/utils/fetcher.ts @@ -24,7 +24,8 @@ const fetcher: HookFetcherFn = async ({ checkout = await checkoutCreate(fetch) } - return checkoutToCart({ checkout }) + // TODO: Fix this type + return checkoutToCart({ checkout } as any) } export default fetcher diff --git a/framework/shopify/customer/use-customer.tsx b/framework/shopify/customer/use-customer.tsx index 91b7281af..137f0da74 100644 --- a/framework/shopify/customer/use-customer.tsx +++ b/framework/shopify/customer/use-customer.tsx @@ -2,9 +2,9 @@ import useCustomer, { UseCustomer } from '@commerce/customer/use-customer' import { Customer } from '@commerce/types' import { SWRHook } from '@commerce/utils/types' import { getCustomerQuery, getCustomerToken } from '../utils' -import type { ShopifyProvider } from '..' -export default useCustomer as UseCustomer +export default useCustomer as UseCustomer + export const handler: SWRHook = { fetchOptions: { query: getCustomerQuery, diff --git a/framework/shopify/types.ts b/framework/shopify/types.ts index 9ad9fd016..c4e42b67d 100644 --- a/framework/shopify/types.ts +++ b/framework/shopify/types.ts @@ -30,9 +30,6 @@ export type CartItemBody = Core.CartItemBody & { optionSelections?: OptionSelections } -type X = Core.CartItemBody extends CartItemBody ? any : never -type Y = CartItemBody extends Core.CartItemBody ? any : never - export type GetCartHandlerBody = Core.GetCartHandlerBody export type AddCartItemBody = Core.AddCartItemBody diff --git a/framework/shopify/utils/to-commerce-products.ts b/framework/shopify/utils/to-commerce-products.ts index c0b411eb6..84925e001 100644 --- a/framework/shopify/utils/to-commerce-products.ts +++ b/framework/shopify/utils/to-commerce-products.ts @@ -1,4 +1,8 @@ -import { Product, Image } from '../types' +// TODO: Fix the types in this file +// import { Product, Image } from '../types' + +type Product = any +type Image = any export default function toCommerceProducts(products: Product[]) { return products.map((product: Product) => { @@ -20,10 +24,12 @@ export default function toCommerceProducts(products: Product[]) { url: image.src, } }), - variants: product.variants.map((variant) => { + // TODO: Fix the variant type + variants: product.variants.map((variant: any) => { return { id: variant.id, - options: variant.selectedOptions.map((selectedOption) => { + // TODO: Fix the selectedOption type + options: variant.selectedOptions.map((selectedOption: any) => { return { __typename: 'MultipleChoiceOption', displayName: selectedOption.name, @@ -39,11 +45,13 @@ export default function toCommerceProducts(products: Product[]) { }), } }), - productOptions: product.options.map((option) => { + // TODO: Fix the option type + productOptions: product.options.map((option: any) => { return { __typename: 'MultipleChoiceOption', displayName: option.name, - values: option.values.map((value) => { + // TODO: Fix the value type + values: option.values.map((value: any) => { return { node: { entityId: 1, diff --git a/framework/shopify/wishlist/use-wishlist.tsx b/framework/shopify/wishlist/use-wishlist.tsx index f8db4216f..13632bb95 100644 --- a/framework/shopify/wishlist/use-wishlist.tsx +++ b/framework/shopify/wishlist/use-wishlist.tsx @@ -1,5 +1,7 @@ +// TODO: replace this hook and other wishlist hooks with a handler, or remove them if +// Shopify doesn't have a wishlist + import { HookFetcher } from '@commerce/utils/types' -import { SwrOptions } from '@commerce/utils/use-data' import useCommerceWishlist from '@commerce/wishlist/use-wishlist' import { Product } from '../schema' import useCustomer from '../customer/use-customer' @@ -31,7 +33,8 @@ export const fetcher: HookFetcher = () => { export function extendHook( customFetcher: typeof fetcher, - swrOptions?: SwrOptions + // swrOptions?: SwrOptions + swrOptions?: any ) { const useWishlist = ({ includeProducts }: UseWishlistOptions = {}) => { return { data: null } diff --git a/next.config.js b/next.config.js index 046ba2aa1..7e86695a0 100644 --- a/next.config.js +++ b/next.config.js @@ -39,5 +39,3 @@ module.exports = withCommerceConfig({ ].filter((x) => x) }, }) - -console.log('configs', module.exports) From 75aec1441fd927006e53485d2ff73f2393e03084 Mon Sep 17 00:00:00 2001 From: okbel Date: Thu, 25 Feb 2021 19:34:54 -0300 Subject: [PATCH 179/216] Adding env templates to the providers --- framework/bigcommerce/.env.template | 6 ++++++ framework/shopify/.env.template | 2 ++ 2 files changed, 8 insertions(+) create mode 100644 framework/bigcommerce/.env.template create mode 100644 framework/shopify/.env.template diff --git a/framework/bigcommerce/.env.template b/framework/bigcommerce/.env.template new file mode 100644 index 000000000..83e7dd403 --- /dev/null +++ b/framework/bigcommerce/.env.template @@ -0,0 +1,6 @@ +BIGCOMMERCE_STOREFRONT_API_URL= +BIGCOMMERCE_STOREFRONT_API_TOKEN= +BIGCOMMERCE_STORE_API_URL= +BIGCOMMERCE_STORE_API_TOKEN= +BIGCOMMERCE_STORE_API_CLIENT_ID= +BIGCOMMERCE_CHANNEL_ID= \ No newline at end of file diff --git a/framework/shopify/.env.template b/framework/shopify/.env.template new file mode 100644 index 000000000..24521c2a1 --- /dev/null +++ b/framework/shopify/.env.template @@ -0,0 +1,2 @@ +SHOPIFY_STORE_DOMAIN= +SHOPIFY_STOREFRONT_ACCESS_TOKEN= From fc023de8445fc5fd23553e1dd895598c44f6f774 Mon Sep 17 00:00:00 2001 From: Luis Alvarez Date: Thu, 25 Feb 2021 18:10:59 -0500 Subject: [PATCH 180/216] Ignore some types --- components/wishlist/WishlistButton/WishlistButton.tsx | 2 ++ components/wishlist/WishlistCard/WishlistCard.tsx | 1 + framework/commerce/types.ts | 6 +++--- framework/shopify/cart/use-cart.tsx | 2 +- framework/shopify/cart/utils/checkout-to-cart.ts | 2 +- framework/shopify/index.tsx | 3 ++- framework/shopify/utils/get-categories.ts | 2 +- package.json | 1 + pages/[...pages].tsx | 3 ++- pages/search.tsx | 7 +++++-- pages/wishlist.tsx | 2 ++ scripts/commerce.js | 1 + 12 files changed, 22 insertions(+), 10 deletions(-) create mode 100644 scripts/commerce.js diff --git a/components/wishlist/WishlistButton/WishlistButton.tsx b/components/wishlist/WishlistButton/WishlistButton.tsx index 57f769e3d..290f7f9ec 100644 --- a/components/wishlist/WishlistButton/WishlistButton.tsx +++ b/components/wishlist/WishlistButton/WishlistButton.tsx @@ -26,7 +26,9 @@ const WishlistButton: FC = ({ const { openModal, setModalView } = useUI() const [loading, setLoading] = useState(false) + // @ts-ignore Wishlist is not always enabled const itemInWishlist = data?.items?.find( + // @ts-ignore Wishlist is not always enabled (item) => item.product_id === productId && (item.variant_id as any) === variant.id ) diff --git a/components/wishlist/WishlistCard/WishlistCard.tsx b/components/wishlist/WishlistCard/WishlistCard.tsx index 5e4cce72a..1568d9e7e 100644 --- a/components/wishlist/WishlistCard/WishlistCard.tsx +++ b/components/wishlist/WishlistCard/WishlistCard.tsx @@ -22,6 +22,7 @@ const WishlistCard: FC = ({ product }) => { baseAmount: product.prices?.retailPrice?.value, currencyCode: product.prices?.price?.currencyCode!, }) + // @ts-ignore Wishlist is not always enabled const removeItem = useRemoveItem({ wishlist: { includeProducts: true } }) const [loading, setLoading] = useState(false) const [removing, setRemoving] = useState(false) diff --git a/framework/commerce/types.ts b/framework/commerce/types.ts index bf635c9dc..a398070ac 100644 --- a/framework/commerce/types.ts +++ b/framework/commerce/types.ts @@ -1,6 +1,6 @@ -import type { Wishlist as BCWishlist } from '@framework/api/wishlist' -import type { Customer as BCCustomer } from '@framework/api/customers' -import type { SearchProductsData as BCSearchProductsData } from '@framework/api/catalog/products' +import type { Wishlist as BCWishlist } from '../bigcommerce/api/wishlist' +import type { Customer as BCCustomer } from '../bigcommerce/api/customers' +import type { SearchProductsData as BCSearchProductsData } from '../bigcommerce/api/catalog/products' export type Discount = { // The value of the discount, can be an amount or percentage diff --git a/framework/shopify/cart/use-cart.tsx b/framework/shopify/cart/use-cart.tsx index 5f1f87299..d154bb837 100644 --- a/framework/shopify/cart/use-cart.tsx +++ b/framework/shopify/cart/use-cart.tsx @@ -4,7 +4,7 @@ import useCommerceCart, { UseCart, } from '@commerce/cart/use-cart' -import { Cart } from '@commerce/types' +import { Cart } from '../types' import { SWRHook } from '@commerce/utils/types' import { checkoutCreate, checkoutToCart } from './utils' import getCheckoutQuery from '../utils/queries/get-checkout-query' diff --git a/framework/shopify/cart/utils/checkout-to-cart.ts b/framework/shopify/cart/utils/checkout-to-cart.ts index fa8b988f9..03005f342 100644 --- a/framework/shopify/cart/utils/checkout-to-cart.ts +++ b/framework/shopify/cart/utils/checkout-to-cart.ts @@ -1,4 +1,4 @@ -import { Cart } from '@commerce/types' +import { Cart } from '../../types' import { CommerceError, ValidationError } from '@commerce/utils/errors' import { diff --git a/framework/shopify/index.tsx b/framework/shopify/index.tsx index 5b25d6b21..c26704771 100644 --- a/framework/shopify/index.tsx +++ b/framework/shopify/index.tsx @@ -28,7 +28,8 @@ export type ShopifyProps = { export function CommerceProvider({ children, ...config }: ShopifyProps) { return ( {children} diff --git a/framework/shopify/utils/get-categories.ts b/framework/shopify/utils/get-categories.ts index e1176b068..54048b896 100644 --- a/framework/shopify/utils/get-categories.ts +++ b/framework/shopify/utils/get-categories.ts @@ -3,7 +3,7 @@ import { CollectionEdge } from '../schema' import getSiteCollectionsQuery from './queries/get-all-collections-query' export type Category = { - endityId: string + entityId: string name: string path: string } diff --git a/package.json b/package.json index 906d950dc..491071e55 100644 --- a/package.json +++ b/package.json @@ -8,6 +8,7 @@ "analyze": "BUNDLE_ANALYZE=both yarn build", "prettier-fix": "prettier --write .", "find:unused": "next-unused", + "commerce": "node scripts/commerce.js", "generate": "graphql-codegen", "generate:definitions": "node framework/bigcommerce/scripts/generate-definitions.js" }, diff --git a/pages/[...pages].tsx b/pages/[...pages].tsx index 3f39845b5..67adb6287 100644 --- a/pages/[...pages].tsx +++ b/pages/[...pages].tsx @@ -25,7 +25,8 @@ export async function getStaticProps({ const pageItem = pages.find((p) => (p.url ? getSlug(p.url) === slug : false)) const data = pageItem && - (await getPage({ variables: { id: pageItem.id! }, config, preview })) + // TODO: Shopify - Fix this type + (await getPage({ variables: { id: pageItem.id! } as any, config, preview })) const page = data?.page if (!page) { diff --git a/pages/search.tsx b/pages/search.tsx index a05203892..da2edccd8 100644 --- a/pages/search.tsx +++ b/pages/search.tsx @@ -75,8 +75,10 @@ export default function Search({ const { data } = useSearch({ search: typeof q === 'string' ? q : '', - categoryId: activeCategory?.entityId, - brandId: activeBrand?.entityId, + // TODO: Shopify - Fix this type + categoryId: activeCategory?.entityId as any, + // TODO: Shopify - Fix this type + brandId: (activeBrand as any)?.entityId, sort: typeof sort === 'string' ? sort : '', }) @@ -266,6 +268,7 @@ export default function Search({ className={cn( 'block text-sm leading-5 text-gray-700 hover:bg-gray-100 lg:hover:bg-transparent hover:text-gray-900 focus:outline-none focus:bg-gray-100 focus:text-gray-900', { + // @ts-ignore Shopify - Fix this types underline: activeBrand?.entityId === node.entityId, } )} diff --git a/pages/wishlist.tsx b/pages/wishlist.tsx index ce97532b0..9938698d4 100644 --- a/pages/wishlist.tsx +++ b/pages/wishlist.tsx @@ -35,6 +35,7 @@ export async function getStaticProps({ export default function Wishlist() { const { data: customer } = useCustomer() + // @ts-ignore Shopify - Fix this types const { data, isLoading, isEmpty } = useWishlist() const router = useRouter() @@ -57,6 +58,7 @@ export default function Wishlist() {
    ) : ( data && + // @ts-ignore Shopify - Fix this types data.items?.map((item) => ( )) diff --git a/scripts/commerce.js b/scripts/commerce.js new file mode 100644 index 000000000..e6eefa224 --- /dev/null +++ b/scripts/commerce.js @@ -0,0 +1 @@ +console.log('Hello') From 42be44c7ee62b3139e6eba8518c5dd03c85e8908 Mon Sep 17 00:00:00 2001 From: okbel Date: Fri, 26 Feb 2021 14:25:02 -0300 Subject: [PATCH 181/216] Adding link for Cart --- commerce.config.json | 3 ++- .../cart/CartSidebarView/CartSidebarView.tsx | 25 +++++++++++-------- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/commerce.config.json b/commerce.config.json index 1c14a53f5..05dd2a043 100644 --- a/commerce.config.json +++ b/commerce.config.json @@ -1,6 +1,7 @@ { "provider": "bigcommerce", "features": { - "wishlist": false + "wishlist": true, + "customCheckout": true } } diff --git a/components/cart/CartSidebarView/CartSidebarView.tsx b/components/cart/CartSidebarView/CartSidebarView.tsx index cb932247f..326390327 100644 --- a/components/cart/CartSidebarView/CartSidebarView.tsx +++ b/components/cart/CartSidebarView/CartSidebarView.tsx @@ -1,14 +1,14 @@ import { FC } from 'react' import cn from 'classnames' -import { UserNav } from '@components/common' -import { Button } from '@components/ui' -import { Bag, Cross, Check } from '@components/icons' -import { useUI } from '@components/ui/context' -import useCart from '@framework/cart/use-cart' -import usePrice from '@framework/product/use-price' +import Link from 'next/link' import CartItem from '../CartItem' import s from './CartSidebarView.module.css' -import { LineItem } from '@commerce/types' +import { Button } from '@components/ui' +import { UserNav } from '@components/common' +import { useUI } from '@components/ui/context' +import { Bag, Cross, Check } from '@components/icons' +import useCart from '@framework/cart/use-cart' +import usePrice from '@framework/product/use-price' const CartSidebarView: FC = () => { const { closeSidebar } = useUI() @@ -88,9 +88,14 @@ const CartSidebarView: FC = () => { ) : ( <>
    -

    - My Cart -

    + +

    + My Cart +

    +
      {data!.lineItems.map((item: any) => ( Date: Fri, 26 Feb 2021 15:52:09 -0300 Subject: [PATCH 182/216] Adding customCheckout --- commerce.config.json | 2 +- components/icons/CreditCard.tsx | 20 ++++++++++++++++++++ components/icons/MapPin.tsx | 20 ++++++++++++++++++++ components/icons/index.ts | 2 ++ components/ui/context.tsx | 7 ++++++- pages/cart.tsx | 33 +++++++++++++++++++++++++++++++-- 6 files changed, 80 insertions(+), 4 deletions(-) create mode 100644 components/icons/CreditCard.tsx create mode 100644 components/icons/MapPin.tsx diff --git a/commerce.config.json b/commerce.config.json index 05dd2a043..bef7db222 100644 --- a/commerce.config.json +++ b/commerce.config.json @@ -2,6 +2,6 @@ "provider": "bigcommerce", "features": { "wishlist": true, - "customCheckout": true + "customCheckout": false } } diff --git a/components/icons/CreditCard.tsx b/components/icons/CreditCard.tsx new file mode 100644 index 000000000..85504d8ba --- /dev/null +++ b/components/icons/CreditCard.tsx @@ -0,0 +1,20 @@ +const CreditCard = ({ ...props }) => { + return ( + + + + + ) +} + +export default CreditCard diff --git a/components/icons/MapPin.tsx b/components/icons/MapPin.tsx new file mode 100644 index 000000000..6323b9c1c --- /dev/null +++ b/components/icons/MapPin.tsx @@ -0,0 +1,20 @@ +const MapPin = ({ ...props }) => { + return ( + + + + + ) +} + +export default MapPin diff --git a/components/icons/index.ts b/components/icons/index.ts index 6e57ab0e8..1f2089085 100644 --- a/components/icons/index.ts +++ b/components/icons/index.ts @@ -14,3 +14,5 @@ export { default as RightArrow } from './RightArrow' export { default as Info } from './Info' export { default as ChevronUp } from './ChevronUp' export { default as Vercel } from './Vercel' +export { default as MapPin } from './MapPin' +export { default as CreditCard } from './CreditCard' diff --git a/components/ui/context.tsx b/components/ui/context.tsx index 13992a736..f66adb9d7 100644 --- a/components/ui/context.tsx +++ b/components/ui/context.tsx @@ -59,7 +59,12 @@ type Action = value: string } -type MODAL_VIEWS = 'SIGNUP_VIEW' | 'LOGIN_VIEW' | 'FORGOT_VIEW' +type MODAL_VIEWS = + | 'SIGNUP_VIEW' + | 'LOGIN_VIEW' + | 'FORGOT_VIEW' + | 'NEW_SHIPPING_ADDRESS' + | 'NEW_PAYMENT_METHOD' type ToastText = string export const UIContext = React.createContext(initialState) diff --git a/pages/cart.tsx b/pages/cart.tsx index 8b2dbb57b..cd5bedacc 100644 --- a/pages/cart.tsx +++ b/pages/cart.tsx @@ -5,7 +5,7 @@ import useCart from '@framework/cart/use-cart' import usePrice from '@framework/product/use-price' import { Layout } from '@components/common' import { Button, Text } from '@components/ui' -import { Bag, Cross, Check } from '@components/icons' +import { Bag, Cross, Check, MapPin, CreditCard } from '@components/icons' import { CartItem } from '@components/cart' export async function getStaticProps({ @@ -38,7 +38,7 @@ export default function Cart() { ) return ( -
      +
      {isLoading || isEmpty ? (
      @@ -103,6 +103,35 @@ export default function Cart() {
      + {process.env.COMMERCE_CUSTOMCHECKOUT_ENABLED && ( + <> + {/* Shipping Address */} + {/* Only available with customCheckout set to true - Meaning that the provider does offer checkout functionality. */} +
      +
      + +
      +
      + + Add Shipping Address + {/* + 1046 Kearny Street.
      + San Franssisco, California +
      */} +
      +
      + {/* Payment Method */} + {/* Only available with customCheckout set to true - Meaning that the provider does offer checkout functionality. */} +
      +
      + +
      +
      + + Add Payment Method + {/* VISA #### #### #### 2345 */} +
      +
      + + )}
      • From 751011767a93e670755f24cec490cfd86b5faaf1 Mon Sep 17 00:00:00 2001 From: Luis Alvarez Date: Fri, 26 Feb 2021 21:35:09 -0500 Subject: [PATCH 183/216] multiple changes to fix the wishlist --- .../wishlist/WishlistButton/WishlistButton.tsx | 3 ++- framework/bigcommerce/api/utils/parse-item.ts | 13 ++++++++++--- .../bigcommerce/customer/get-customer-wishlist.ts | 5 +++-- framework/bigcommerce/wishlist/use-wishlist.tsx | 4 ++-- framework/shopify/api/index.ts | 1 - package.json | 1 - pages/wishlist.tsx | 8 ++------ scripts/commerce.js | 1 - 8 files changed, 19 insertions(+), 17 deletions(-) delete mode 100644 scripts/commerce.js diff --git a/components/wishlist/WishlistButton/WishlistButton.tsx b/components/wishlist/WishlistButton/WishlistButton.tsx index 290f7f9ec..6dc59b900 100644 --- a/components/wishlist/WishlistButton/WishlistButton.tsx +++ b/components/wishlist/WishlistButton/WishlistButton.tsx @@ -30,7 +30,8 @@ const WishlistButton: FC = ({ const itemInWishlist = data?.items?.find( // @ts-ignore Wishlist is not always enabled (item) => - item.product_id === productId && (item.variant_id as any) === variant.id + item.product_id === Number(productId) && + (item.variant_id as any) === Number(variant.id) ) const handleWishlistChange = async (e: any) => { diff --git a/framework/bigcommerce/api/utils/parse-item.ts b/framework/bigcommerce/api/utils/parse-item.ts index dcc716c23..7c8cd4728 100644 --- a/framework/bigcommerce/api/utils/parse-item.ts +++ b/framework/bigcommerce/api/utils/parse-item.ts @@ -1,6 +1,11 @@ import type { ItemBody as WishlistItemBody } from '../wishlist' import type { CartItemBody, OptionSelections } from '../../types' +type BCWishlistItemBody = { + product_id: number + variant_id: number +} + type BCCartItemBody = { product_id: number variant_id: number @@ -8,9 +13,11 @@ type BCCartItemBody = { option_selections?: OptionSelections } -export const parseWishlistItem = (item: WishlistItemBody) => ({ - product_id: item.productId, - variant_id: item.variantId, +export const parseWishlistItem = ( + item: WishlistItemBody +): BCWishlistItemBody => ({ + product_id: Number(item.productId), + variant_id: Number(item.variantId), }) export const parseCartItem = (item: CartItemBody): BCCartItemBody => ({ diff --git a/framework/bigcommerce/customer/get-customer-wishlist.ts b/framework/bigcommerce/customer/get-customer-wishlist.ts index e854ff933..97e5654a9 100644 --- a/framework/bigcommerce/customer/get-customer-wishlist.ts +++ b/framework/bigcommerce/customer/get-customer-wishlist.ts @@ -68,14 +68,15 @@ async function getCustomerWishlist({ const productsById = graphqlData.products.reduce<{ [k: number]: ProductEdge }>((prods, p) => { - prods[Number(p.node.entityId)] = p as any + prods[Number(p.id)] = p as any return prods }, {}) // Populate the wishlist items with the graphql products wishlist.items.forEach((item) => { const product = item && productsById[item.product_id!] if (item && product) { - item.product = product.node + // @ts-ignore Fix this type when the wishlist type is properly defined + item.product = product } }) } diff --git a/framework/bigcommerce/wishlist/use-wishlist.tsx b/framework/bigcommerce/wishlist/use-wishlist.tsx index 3efba7ffd..4850d1cd9 100644 --- a/framework/bigcommerce/wishlist/use-wishlist.tsx +++ b/framework/bigcommerce/wishlist/use-wishlist.tsx @@ -18,7 +18,7 @@ export const handler: SWRHook< url: '/api/bigcommerce/wishlist', method: 'GET', }, - fetcher({ input: { customerId, includeProducts }, options, fetch }) { + async fetcher({ input: { customerId, includeProducts }, options, fetch }) { if (!customerId) return null // Use a dummy base as we only care about the relative path @@ -35,7 +35,7 @@ export const handler: SWRHook< const { data: customer } = useCustomer() const response = useData({ input: [ - ['customerId', (customer as any)?.id], + ['customerId', customer?.entityId], ['includeProducts', input?.includeProducts], ], swrOptions: { diff --git a/framework/shopify/api/index.ts b/framework/shopify/api/index.ts index 0fe58f2df..4e23ce99c 100644 --- a/framework/shopify/api/index.ts +++ b/framework/shopify/api/index.ts @@ -8,7 +8,6 @@ import { } from '../const' if (!API_URL) { - console.log(process.env) throw new Error( `The environment variable NEXT_PUBLIC_SHOPIFY_STORE_DOMAIN is missing and it's required to access your store` ) diff --git a/package.json b/package.json index 491071e55..906d950dc 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,6 @@ "analyze": "BUNDLE_ANALYZE=both yarn build", "prettier-fix": "prettier --write .", "find:unused": "next-unused", - "commerce": "node scripts/commerce.js", "generate": "graphql-codegen", "generate:definitions": "node framework/bigcommerce/scripts/generate-definitions.js" }, diff --git a/pages/wishlist.tsx b/pages/wishlist.tsx index 9938698d4..0dddaf23d 100644 --- a/pages/wishlist.tsx +++ b/pages/wishlist.tsx @@ -1,7 +1,4 @@ -import { useEffect } from 'react' -import { useRouter } from 'next/router' import type { GetStaticPropsContext } from 'next' - import { Heart } from '@components/icons' import { Layout } from '@components/common' import { Text, Container } from '@components/ui' @@ -36,8 +33,7 @@ export async function getStaticProps({ export default function Wishlist() { const { data: customer } = useCustomer() // @ts-ignore Shopify - Fix this types - const { data, isLoading, isEmpty } = useWishlist() - const router = useRouter() + const { data, isLoading, isEmpty } = useWishlist({ includeProducts: true }) return ( @@ -60,7 +56,7 @@ export default function Wishlist() { data && // @ts-ignore Shopify - Fix this types data.items?.map((item) => ( - + )) )}
      diff --git a/scripts/commerce.js b/scripts/commerce.js deleted file mode 100644 index e6eefa224..000000000 --- a/scripts/commerce.js +++ /dev/null @@ -1 +0,0 @@ -console.log('Hello') From 641ce0aa64cc46fbdc492dc55df7942d1d2be3fa Mon Sep 17 00:00:00 2001 From: cond0r Date: Mon, 1 Mar 2021 16:47:30 +0200 Subject: [PATCH 184/216] Shopify Provier Updates (#212) * changes * Adding shopify commit * Changed to query page by id * Fixed page query, Changed use-search GraphQl query * Update use-search.tsx * remove unused util * Changed cookie expiration * Update tsconfig.json Co-authored-by: okbel --- framework/bigcommerce/.env.template | 2 +- framework/shopify/api/index.ts | 4 +- .../shopify/cart/utils/checkout-create.ts | 8 ++- framework/shopify/common/get-all-pages.ts | 3 +- framework/shopify/common/get-page.ts | 15 ++-- framework/shopify/const.ts | 2 + framework/shopify/product/use-search.tsx | 34 ++++++--- framework/shopify/utils/customer-token.ts | 17 +++-- framework/shopify/utils/get-categories.ts | 4 +- .../shopify/utils/get-search-variables.ts | 11 ++- framework/shopify/utils/get-sort-variables.ts | 4 +- framework/shopify/utils/normalize.ts | 59 ++++++++++------ .../utils/queries/get-all-products-query.ts | 69 ++++++++++--------- .../queries/get-collection-products-query.ts | 21 ++++-- .../shopify/utils/queries/get-page-query.ts | 15 ++-- .../utils/queries/get-product-query.ts | 1 + .../shopify/utils/to-commerce-products.ts | 68 ------------------ framework/shopify/wishlist/use-wishlist.tsx | 2 - 18 files changed, 164 insertions(+), 175 deletions(-) delete mode 100644 framework/shopify/utils/to-commerce-products.ts diff --git a/framework/bigcommerce/.env.template b/framework/bigcommerce/.env.template index 83e7dd403..43e85c046 100644 --- a/framework/bigcommerce/.env.template +++ b/framework/bigcommerce/.env.template @@ -3,4 +3,4 @@ BIGCOMMERCE_STOREFRONT_API_TOKEN= BIGCOMMERCE_STORE_API_URL= BIGCOMMERCE_STORE_API_TOKEN= BIGCOMMERCE_STORE_API_CLIENT_ID= -BIGCOMMERCE_CHANNEL_ID= \ No newline at end of file +BIGCOMMERCE_CHANNEL_ID= diff --git a/framework/shopify/api/index.ts b/framework/shopify/api/index.ts index 4e23ce99c..4f15cae15 100644 --- a/framework/shopify/api/index.ts +++ b/framework/shopify/api/index.ts @@ -5,6 +5,7 @@ import { API_TOKEN, SHOPIFY_CHECKOUT_ID_COOKIE, SHOPIFY_CUSTOMER_TOKEN_COOKIE, + SHOPIFY_COOKIE_EXPIRE, } from '../const' if (!API_URL) { @@ -43,10 +44,11 @@ export class Config { } const config = new Config({ + locale: 'en-US', commerceUrl: API_URL, apiToken: API_TOKEN!, cartCookie: SHOPIFY_CHECKOUT_ID_COOKIE, - cartCookieMaxAge: 60 * 60 * 24 * 30, + cartCookieMaxAge: SHOPIFY_COOKIE_EXPIRE, fetch: fetchGraphqlApi, customerCookie: SHOPIFY_CUSTOMER_TOKEN_COOKIE, }) diff --git a/framework/shopify/cart/utils/checkout-create.ts b/framework/shopify/cart/utils/checkout-create.ts index 6c4f81c21..e950cc7e4 100644 --- a/framework/shopify/cart/utils/checkout-create.ts +++ b/framework/shopify/cart/utils/checkout-create.ts @@ -1,6 +1,7 @@ import { SHOPIFY_CHECKOUT_ID_COOKIE, SHOPIFY_CHECKOUT_URL_COOKIE, + SHOPIFY_COOKIE_EXPIRE, } from '../../const' import checkoutCreateMutation from '../../utils/mutations/checkout-create' @@ -15,8 +16,11 @@ export const checkoutCreate = async (fetch: any) => { const checkoutId = checkout?.id if (checkoutId) { - Cookies.set(SHOPIFY_CHECKOUT_ID_COOKIE, checkoutId) - Cookies.set(SHOPIFY_CHECKOUT_URL_COOKIE, checkout?.webUrl) + const options = { + expires: SHOPIFY_COOKIE_EXPIRE, + } + Cookies.set(SHOPIFY_CHECKOUT_ID_COOKIE, checkoutId, options) + Cookies.set(SHOPIFY_CHECKOUT_URL_COOKIE, checkout?.webUrl, options) } return checkout diff --git a/framework/shopify/common/get-all-pages.ts b/framework/shopify/common/get-all-pages.ts index 6f06185e2..54231ed03 100644 --- a/framework/shopify/common/get-all-pages.ts +++ b/framework/shopify/common/get-all-pages.ts @@ -25,12 +25,13 @@ const getAllPages = async (options?: { }): Promise => { let { config, variables = { first: 250 } } = options ?? {} config = getConfig(config) + const { locale } = config const { data } = await config.fetch(getAllPagesQuery, { variables }) const pages = data.pages?.edges?.map( ({ node: { title: name, handle, ...node } }: PageEdge) => ({ ...node, - url: `/${handle}`, + url: `/${locale}/${handle}`, name, }) ) diff --git a/framework/shopify/common/get-page.ts b/framework/shopify/common/get-page.ts index 6016c8c9a..be934aa42 100644 --- a/framework/shopify/common/get-page.ts +++ b/framework/shopify/common/get-page.ts @@ -3,33 +3,32 @@ import getPageQuery from '../utils/queries/get-page-query' import { Page } from './get-all-pages' type Variables = { - slug: string + id: string } -type ReturnType = { - page: Page -} +export type GetPageResult = T const getPage = async (options: { variables: Variables config: ShopifyConfig preview?: boolean -}): Promise => { +}): Promise => { let { config, variables } = options ?? {} + config = getConfig(config) + const { locale } = config const { data } = await config.fetch(getPageQuery, { variables, }) - - const { pageByHandle: page } = data + const page = data.node return { page: page ? { ...page, name: page.title, - url: page?.handle, + url: `/${locale}/${page.handle}`, } : null, } diff --git a/framework/shopify/const.ts b/framework/shopify/const.ts index a6e9e8d90..06fbe5054 100644 --- a/framework/shopify/const.ts +++ b/framework/shopify/const.ts @@ -6,6 +6,8 @@ export const SHOPIFY_CUSTOMER_TOKEN_COOKIE = 'shopify_customerToken' export const STORE_DOMAIN = process.env.NEXT_PUBLIC_SHOPIFY_STORE_DOMAIN +export const SHOPIFY_COOKIE_EXPIRE = 30 + export const API_URL = `https://${STORE_DOMAIN}/api/2021-01/graphql.json` export const API_TOKEN = process.env.NEXT_PUBLIC_SHOPIFY_STOREFRONT_ACCESS_TOKEN diff --git a/framework/shopify/product/use-search.tsx b/framework/shopify/product/use-search.tsx index 4b14249ca..425df9e83 100644 --- a/framework/shopify/product/use-search.tsx +++ b/framework/shopify/product/use-search.tsx @@ -4,6 +4,7 @@ import useSearch, { UseSearch } from '@commerce/product/use-search' import { ProductEdge } from '../schema' import { getAllProductsQuery, + getCollectionProductsQuery, getSearchVariables, normalizeProduct, } from '../utils' @@ -14,8 +15,8 @@ export default useSearch as UseSearch export type SearchProductsInput = { search?: string - categoryId?: number - brandId?: number + categoryId?: string + brandId?: string sort?: string } @@ -23,6 +24,7 @@ export type SearchProductsData = { products: Product[] found: boolean } + export const handler: SWRHook< SearchProductsData, SearchProductsInput, @@ -32,18 +34,30 @@ export const handler: SWRHook< query: getAllProductsQuery, }, async fetcher({ input, options, fetch }) { - const resp = await fetch({ - query: options?.query, + const { categoryId, brandId } = input + + const data = await fetch({ + query: categoryId ? getCollectionProductsQuery : options.query, method: options?.method, variables: getSearchVariables(input), }) - const edges = resp.products?.edges + + let edges + + if (categoryId) { + edges = data.node?.products?.edges ?? [] + if (brandId) { + edges = edges.filter( + ({ node: { vendor } }: ProductEdge) => vendor === brandId + ) + } + } else { + edges = data.products?.edges ?? [] + } + return { - products: edges?.map(({ node: p }: ProductEdge) => - // TODO: Fix this product type - normalizeProduct(p as any) - ), - found: !!edges?.length, + products: edges.map(({ node }: ProductEdge) => normalizeProduct(node)), + found: !!edges.length, } }, useHook: ({ useData }) => (input = {}) => { diff --git a/framework/shopify/utils/customer-token.ts b/framework/shopify/utils/customer-token.ts index beae54765..85454cb83 100644 --- a/framework/shopify/utils/customer-token.ts +++ b/framework/shopify/utils/customer-token.ts @@ -1,12 +1,21 @@ -import Cookies from 'js-cookie' -import { SHOPIFY_CUSTOMER_TOKEN_COOKIE } from '../const' +import Cookies, { CookieAttributes } from 'js-cookie' +import { SHOPIFY_COOKIE_EXPIRE, SHOPIFY_CUSTOMER_TOKEN_COOKIE } from '../const' export const getCustomerToken = () => Cookies.get(SHOPIFY_CUSTOMER_TOKEN_COOKIE) -export const setCustomerToken = (token: string | null, options?: any) => { +export const setCustomerToken = ( + token: string | null, + options?: CookieAttributes +) => { if (!token) { Cookies.remove(SHOPIFY_CUSTOMER_TOKEN_COOKIE) } else { - Cookies.set(SHOPIFY_CUSTOMER_TOKEN_COOKIE, token, options) + Cookies.set( + SHOPIFY_CUSTOMER_TOKEN_COOKIE, + token, + options ?? { + expires: SHOPIFY_COOKIE_EXPIRE, + } + ) } } diff --git a/framework/shopify/utils/get-categories.ts b/framework/shopify/utils/get-categories.ts index 54048b896..cce4b2ad7 100644 --- a/framework/shopify/utils/get-categories.ts +++ b/framework/shopify/utils/get-categories.ts @@ -17,8 +17,8 @@ const getCategories = async (config: ShopifyConfig): Promise => { return ( data.collections?.edges?.map( - ({ node: { title: name, handle } }: CollectionEdge) => ({ - entityId: handle, + ({ node: { id: entityId, title: name, handle } }: CollectionEdge) => ({ + entityId, name, path: `/${handle}`, }) diff --git a/framework/shopify/utils/get-search-variables.ts b/framework/shopify/utils/get-search-variables.ts index 6f5d08b1a..c1b40ae5d 100644 --- a/framework/shopify/utils/get-search-variables.ts +++ b/framework/shopify/utils/get-search-variables.ts @@ -2,9 +2,9 @@ import getSortVariables from './get-sort-variables' import type { SearchProductsInput } from '../product/use-search' export const getSearchVariables = ({ - categoryId, brandId, search, + categoryId, sort, }: SearchProductsInput) => { let query = '' @@ -13,17 +13,14 @@ export const getSearchVariables = ({ query += `product_type:${search} OR title:${search} OR tag:${search}` } - if (categoryId) { - query += `tag:${categoryId}` - } - if (brandId) { - query += `${categoryId ? ' AND ' : ''}vendor:${brandId}` + query += `${search ? ' AND ' : ''}vendor:${brandId}` } return { + categoryId, query, - ...getSortVariables(sort), + ...getSortVariables(sort, !!categoryId), } } diff --git a/framework/shopify/utils/get-sort-variables.ts b/framework/shopify/utils/get-sort-variables.ts index 47650c0d7..b8cdeec51 100644 --- a/framework/shopify/utils/get-sort-variables.ts +++ b/framework/shopify/utils/get-sort-variables.ts @@ -1,4 +1,4 @@ -const getSortVariables = (sort?: string) => { +const getSortVariables = (sort?: string, isCategory = false) => { let output = {} switch (sort) { case 'price-asc': @@ -21,7 +21,7 @@ const getSortVariables = (sort?: string) => { break case 'latest-desc': output = { - sortKey: 'CREATED_AT', + sortKey: isCategory ? 'CREATED' : 'CREATED_AT', reverse: true, } break diff --git a/framework/shopify/utils/normalize.ts b/framework/shopify/utils/normalize.ts index 67ab3a8a2..c9b428b37 100644 --- a/framework/shopify/utils/normalize.ts +++ b/framework/shopify/utils/normalize.ts @@ -1,3 +1,5 @@ +import { Product } from '@commerce/types' + import { Product as ShopifyProduct, Checkout, @@ -5,8 +7,8 @@ import { SelectedOption, ImageConnection, ProductVariantConnection, - ProductOption, MoneyV2, + ProductOption, } from '../schema' import type { Cart, LineItem } from '../types' @@ -19,18 +21,26 @@ const money = ({ amount, currencyCode }: MoneyV2) => { } const normalizeProductOption = ({ + id, name: displayName, values, - ...rest }: ProductOption) => { return { __typename: 'MultipleChoiceOption', + id, displayName, - values: values.map((value) => ({ - label: value, - hexColors: displayName === 'Color' ? [value] : null, - })), - ...rest, + values: values.map((value) => { + let output: any = { + label: value, + } + if (displayName === 'Color') { + output = { + ...output, + hexColors: [value], + } + } + return output + }), } } @@ -41,19 +51,28 @@ const normalizeProductImages = ({ edges }: ImageConnection) => })) const normalizeProductVariants = ({ edges }: ProductVariantConnection) => { - return edges?.map(({ node: { id, selectedOptions } }) => ({ - id, - options: selectedOptions.map(({ name, value }: SelectedOption) => - normalizeProductOption({ - id, - name, - values: [value], - }) - ), - })) + return edges?.map( + ({ + node: { id, selectedOptions, sku, title, priceV2, compareAtPriceV2 }, + }) => ({ + id, + name: title, + sku: sku ?? id, + price: +priceV2.amount, + listPrice: +compareAtPriceV2?.amount, + requiresShipping: true, + options: selectedOptions.map(({ name, value }: SelectedOption) => + normalizeProductOption({ + id, + name, + values: [value], + }) + ), + }) + ) } -export function normalizeProduct(productNode: ShopifyProduct): any { +export function normalizeProduct(productNode: ShopifyProduct): Product { const { id, title: name, @@ -95,8 +114,8 @@ export function normalizeCart(checkout: Checkout): Cart { }, taxesIncluded: checkout.taxesIncluded, lineItems: checkout.lineItems?.edges.map(normalizeLineItem), - lineItemsSubtotalPrice: checkout.subtotalPriceV2?.amount, - subtotalPrice: checkout.subtotalPriceV2?.amount, + lineItemsSubtotalPrice: +checkout.subtotalPriceV2?.amount, + subtotalPrice: +checkout.subtotalPriceV2?.amount, totalPrice: checkout.totalPriceV2?.amount, discounts: [], } diff --git a/framework/shopify/utils/queries/get-all-products-query.ts b/framework/shopify/utils/queries/get-all-products-query.ts index 4a6c20b6e..5eb44c7a7 100644 --- a/framework/shopify/utils/queries/get-all-products-query.ts +++ b/framework/shopify/utils/queries/get-all-products-query.ts @@ -1,3 +1,38 @@ +export const productConnection = ` +pageInfo { + hasNextPage + hasPreviousPage +} +edges { + node { + id + title + vendor + handle + description + priceRange { + minVariantPrice { + amount + currencyCode + } + } + images(first: 1) { + pageInfo { + hasNextPage + hasPreviousPage + } + edges { + node { + originalSrc + altText + width + height + } + } + } + } +}` + export const productsFragment = ` products( first: $first @@ -5,39 +40,7 @@ products( reverse: $reverse query: $query ) { - pageInfo { - hasNextPage - hasPreviousPage - } - edges { - node { - id - title - vendor - handle - description - priceRange { - minVariantPrice { - amount - currencyCode - } - } - images(first: 1) { - pageInfo { - hasNextPage - hasPreviousPage - } - edges { - node { - originalSrc - altText - width - height - } - } - } - } - } + ${productConnection} } ` diff --git a/framework/shopify/utils/queries/get-collection-products-query.ts b/framework/shopify/utils/queries/get-collection-products-query.ts index dd504b575..04766caa4 100644 --- a/framework/shopify/utils/queries/get-collection-products-query.ts +++ b/framework/shopify/utils/queries/get-collection-products-query.ts @@ -1,16 +1,23 @@ -import { productsFragment } from './get-all-products-query' +import { productConnection } from './get-all-products-query' const getCollectionProductsQuery = /* GraphQL */ ` query getProductsFromCollection( - $categoryHandle: String! + $categoryId: ID! $first: Int = 250 - $query: String = "" - $sortKey: ProductSortKeys = RELEVANCE + $sortKey: ProductCollectionSortKeys = RELEVANCE $reverse: Boolean = false ) { - collectionByHandle(handle: $categoryHandle) - { - ${productsFragment} + node(id: $categoryId) { + id + ... on Collection { + products( + first: $first + sortKey: $sortKey + reverse: $reverse + ) { + ${productConnection} + } + } } } ` diff --git a/framework/shopify/utils/queries/get-page-query.ts b/framework/shopify/utils/queries/get-page-query.ts index dcafdc30d..2ca79abd4 100644 --- a/framework/shopify/utils/queries/get-page-query.ts +++ b/framework/shopify/utils/queries/get-page-query.ts @@ -1,12 +1,13 @@ export const getPageQuery = /* GraphQL */ ` - query getPageBySlug($slug: String!) { - pageByHandle(handle: $slug) { + query($id: ID!) { + node(id: $id) { id - title - handle - body - bodySummary - url + ... on Page { + title + handle + body + bodySummary + } } } ` diff --git a/framework/shopify/utils/queries/get-product-query.ts b/framework/shopify/utils/queries/get-product-query.ts index d054c023d..5c109901b 100644 --- a/framework/shopify/utils/queries/get-product-query.ts +++ b/framework/shopify/utils/queries/get-product-query.ts @@ -32,6 +32,7 @@ const getProductQuery = /* GraphQL */ ` node { id title + sku selectedOptions { name value diff --git a/framework/shopify/utils/to-commerce-products.ts b/framework/shopify/utils/to-commerce-products.ts deleted file mode 100644 index 84925e001..000000000 --- a/framework/shopify/utils/to-commerce-products.ts +++ /dev/null @@ -1,68 +0,0 @@ -// TODO: Fix the types in this file -// import { Product, Image } from '../types' - -type Product = any -type Image = any - -export default function toCommerceProducts(products: Product[]) { - return products.map((product: Product) => { - return { - id: product.id, - entityId: product.id, - name: product.title, - slug: product.handle, - title: product.title, - vendor: product.vendor, - description: product.descriptionHtml, - path: `/${product.handle}`, - price: { - value: +product.variants[0].price, - currencyCode: 'USD', // TODO - }, - images: product.images.map((image: Image) => { - return { - url: image.src, - } - }), - // TODO: Fix the variant type - variants: product.variants.map((variant: any) => { - return { - id: variant.id, - // TODO: Fix the selectedOption type - options: variant.selectedOptions.map((selectedOption: any) => { - return { - __typename: 'MultipleChoiceOption', - displayName: selectedOption.name, - values: [ - { - node: { - id: variant.id, - label: selectedOption.value, - }, - }, - ], - } - }), - } - }), - // TODO: Fix the option type - productOptions: product.options.map((option: any) => { - return { - __typename: 'MultipleChoiceOption', - displayName: option.name, - // TODO: Fix the value type - values: option.values.map((value: any) => { - return { - node: { - entityId: 1, - label: value.value, - hexColors: [value.value], - }, - } - }), - } - }), - options: [], - } - }) -} diff --git a/framework/shopify/wishlist/use-wishlist.tsx b/framework/shopify/wishlist/use-wishlist.tsx index 13632bb95..d2ce9db5b 100644 --- a/framework/shopify/wishlist/use-wishlist.tsx +++ b/framework/shopify/wishlist/use-wishlist.tsx @@ -2,9 +2,7 @@ // Shopify doesn't have a wishlist import { HookFetcher } from '@commerce/utils/types' -import useCommerceWishlist from '@commerce/wishlist/use-wishlist' import { Product } from '../schema' -import useCustomer from '../customer/use-customer' const defaultOpts = {} From 7780ec4818f730cad50eef2ffec306151f3b410b Mon Sep 17 00:00:00 2001 From: Bel Curcio Date: Mon, 1 Mar 2021 15:59:45 -0300 Subject: [PATCH 185/216] Bump and adding dependency --- components/product/Swatch/Swatch.module.css | 1 + package.json | 7 ++++--- yarn.lock | 23 ++++++++++++++++++--- 3 files changed, 25 insertions(+), 6 deletions(-) diff --git a/components/product/Swatch/Swatch.module.css b/components/product/Swatch/Swatch.module.css index ae37771ad..051435afd 100644 --- a/components/product/Swatch/Swatch.module.css +++ b/components/product/Swatch/Swatch.module.css @@ -1,4 +1,5 @@ .root { + composes: root from 'components/ui/Button/Button.module.css'; @apply h-12 w-12 bg-primary text-primary rounded-full mr-3 inline-flex items-center justify-center cursor-pointer transition duration-150 ease-in-out p-0 shadow-none border-gray-200 border box-border; diff --git a/package.json b/package.json index 906d950dc..a3aac641b 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,7 @@ "sideEffects": false, "license": "MIT", "engines": { - "node": "12.x" + "node": "14.x" }, "prettier": { "semi": false, @@ -23,6 +23,7 @@ "dependencies": { "@reach/portal": "^0.11.2", "@vercel/fetch": "^6.1.0", + "autoprefixer": "^10.2.4", "body-scroll-lock": "^3.1.5", "bowser": "^2.11.0", "classnames": "^2.2.6", @@ -38,7 +39,7 @@ "next": "^10.0.7", "next-seo": "^4.11.0", "next-themes": "^0.0.4", - "postcss": "^8.2.4", + "postcss": "^8.2.6", "postcss-nesting": "^7.0.1", "react": "^17.0.1", "react-dom": "^17.0.1", @@ -47,7 +48,7 @@ "shopify-buy": "^2.11.0", "swr": "^0.4.0", "tabbable": "^5.1.5", - "tailwindcss": "^2.0.2" + "tailwindcss": "^2.0.3" }, "devDependencies": { "@graphql-codegen/cli": "^1.20.0", diff --git a/yarn.lock b/yarn.lock index 9238b1f03..2f23e6a57 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1609,6 +1609,18 @@ auto-bind@~4.0.0: resolved "https://registry.yarnpkg.com/auto-bind/-/auto-bind-4.0.0.tgz#e3589fc6c2da8f7ca43ba9f84fa52a744fc997fb" integrity sha512-Hdw8qdNiqdJ8LqT0iK0sVzkFbzg6fhnQqqfWhBDxcHZvU75+B+ayzTy8x+k5Ix0Y92XOhOUlx74ps+bA6BeYMQ== +autoprefixer@^10.2.4: + version "10.2.4" + resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-10.2.4.tgz#c0e7cf24fcc6a1ae5d6250c623f0cb8beef2f7e1" + integrity sha512-DCCdUQiMD+P/as8m3XkeTUkUKuuRqLGcwD0nll7wevhqoJfMRpJlkFd1+MQh1pvupjiQuip42lc/VFvfUTMSKw== + dependencies: + browserslist "^4.16.1" + caniuse-lite "^1.0.30001181" + colorette "^1.2.1" + fraction.js "^4.0.13" + normalize-range "^0.1.2" + postcss-value-parser "^4.1.0" + autoprefixer@^9.6.1: version "9.8.6" resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-9.8.6.tgz#3b73594ca1bf9266320c5acf1588d74dea74210f" @@ -1818,7 +1830,7 @@ browserslist@4.16.1: escalade "^3.1.1" node-releases "^1.1.69" -browserslist@^4.12.0, browserslist@^4.14.5, browserslist@^4.6.4: +browserslist@^4.12.0, browserslist@^4.14.5, browserslist@^4.16.1, browserslist@^4.6.4: version "4.16.3" resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.16.3.tgz#340aa46940d7db878748567c5dea24a48ddf3717" integrity sha512-vIyhWmIkULaq04Gt93txdh+j02yX/JzlyhLYbV3YQCn/zvES3JnY7TifHHvvr1w5hTDluNKMkV05cs4vy8Q7sw== @@ -3187,6 +3199,11 @@ form-data@^3.0.0: combined-stream "^1.0.8" mime-types "^2.1.12" +fraction.js@^4.0.13: + version "4.0.13" + resolved "https://registry.yarnpkg.com/fraction.js/-/fraction.js-4.0.13.tgz#3c1c315fa16b35c85fffa95725a36fa729c69dfe" + integrity sha512-E1fz2Xs9ltlUp+qbiyx9wmt2n9dRzPsS11Jtdb8D2o+cC7wr9xkkKsVKJuBX0ST+LVS+LhLO+SbLJNtfWcJvXA== + fs-capacitor@^6.1.0: version "6.2.0" resolved "https://registry.yarnpkg.com/fs-capacitor/-/fs-capacitor-6.2.0.tgz#fa79ac6576629163cb84561995602d8999afb7f5" @@ -5586,7 +5603,7 @@ postcss@^7.0.14, postcss@^7.0.17, postcss@^7.0.2, postcss@^7.0.26, postcss@^7.0. source-map "^0.6.1" supports-color "^6.1.0" -postcss@^8.1.6, postcss@^8.2.1, postcss@^8.2.4: +postcss@^8.1.6, postcss@^8.2.1, postcss@^8.2.6: version "8.2.6" resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.2.6.tgz#5d69a974543b45f87e464bc4c3e392a97d6be9fe" integrity sha512-xpB8qYxgPuly166AGlpRjUdEYtmOWx2iCwGmrv4vqZL9YPVviDVPZPRXxnXr6xPZOdxQ9lp3ZBFCRgWJ7LE3Sg== @@ -6617,7 +6634,7 @@ tabbable@^5.1.5: resolved "https://registry.yarnpkg.com/tabbable/-/tabbable-5.1.5.tgz#efec48ede268d511c261e3b81facbb4782a35147" integrity sha512-oVAPrWgLLqrbvQE8XqcU7CVBq6SQbaIbHkhOca3u7/jzuQvyZycrUKPCGr04qpEIUslmUlULbSeN+m3QrKEykA== -tailwindcss@^2.0.2: +tailwindcss@^2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/tailwindcss/-/tailwindcss-2.0.3.tgz#f8d07797d1f89dc4b171673c26237b58783c2c86" integrity sha512-s8NEqdLBiVbbdL0a5XwTb8jKmIonOuI4RMENEcKLR61jw6SdKvBss7NWZzwCaD+ZIjlgmesv8tmrjXEp7C0eAQ== From 6e8dbf1156d0223d570aded44174e78b2a426805 Mon Sep 17 00:00:00 2001 From: Bel Curcio Date: Mon, 1 Mar 2021 19:02:56 -0300 Subject: [PATCH 186/216] Adding color checks --- .prettierrc | 6 + .../ProductView/ProductView.module.css | 2 +- lib/colors.ts | 155 +++++++++++++++++- package.json | 6 +- yarn.lock | 2 +- 5 files changed, 162 insertions(+), 9 deletions(-) create mode 100644 .prettierrc diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 000000000..e1076edfa --- /dev/null +++ b/.prettierrc @@ -0,0 +1,6 @@ +{ + "semi": false, + "singleQuote": true, + "tabWidth": 2, + "useTabs": false +} diff --git a/components/product/ProductView/ProductView.module.css b/components/product/ProductView/ProductView.module.css index dec06f665..6545d611b 100644 --- a/components/product/ProductView/ProductView.module.css +++ b/components/product/ProductView/ProductView.module.css @@ -7,7 +7,7 @@ } .productDisplay { - @apply relative flex px-0 pb-0 relative box-border col-span-1 bg-violet; + @apply relative flex px-0 pb-0 box-border col-span-1 bg-violet; min-height: 600px; @screen md { diff --git a/lib/colors.ts b/lib/colors.ts index 355201146..f9c0b5b0b 100644 --- a/lib/colors.ts +++ b/lib/colors.ts @@ -42,9 +42,160 @@ function hexToRgb(hex: string = '') { return [r, g, b] } -export function isDark(color = '') { +const colorMap: Record = { + aliceblue: '#F0F8FF', + antiquewhite: '#FAEBD7', + aqua: '#00FFFF', + aquamarine: '#7FFFD4', + azure: '#F0FFFF', + beige: '#F5F5DC', + bisque: '#FFE4C4', + black: '#000000', + blanchedalmond: '#FFEBCD', + blue: '#0000FF', + blueviolet: '#8A2BE2', + brown: '#A52A2A', + burlywood: '#DEB887', + cadetblue: '#5F9EA0', + chartreuse: '#7FFF00', + chocolate: '#D2691E', + coral: '#FF7F50', + cornflowerblue: '#6495ED', + cornsilk: '#FFF8DC', + crimson: '#DC143C', + cyan: '#00FFFF', + darkblue: '#00008B', + darkcyan: '#008B8B', + darkgoldenrod: '#B8860B', + darkgray: '#A9A9A9', + darkgreen: '#006400', + darkgrey: '#A9A9A9', + darkkhaki: '#BDB76B', + darkmagenta: '#8B008B', + darkolivegreen: '#556B2F', + darkorange: '#FF8C00', + darkorchid: '#9932CC', + darkred: '#8B0000', + darksalmon: '#E9967A', + darkseagreen: '#8FBC8F', + darkslateblue: '#483D8B', + darkslategray: '#2F4F4F', + darkslategrey: '#2F4F4F', + darkturquoise: '#00CED1', + darkviolet: '#9400D3', + deeppink: '#FF1493', + deepskyblue: '#00BFFF', + dimgray: '#696969', + dimgrey: '#696969', + dodgerblue: '#1E90FF', + firebrick: '#B22222', + floralwhite: '#FFFAF0', + forestgreen: '#228B22', + fuchsia: '#FF00FF', + gainsboro: '#DCDCDC', + ghostwhite: '#F8F8FF', + gold: '#FFD700', + goldenrod: '#DAA520', + gray: '#808080', + green: '#008000', + greenyellow: '#ADFF2F', + grey: '#808080', + honeydew: '#F0FFF0', + hotpink: '#FF69B4', + indianred: '#CD5C5C', + indigo: '#4B0082', + ivory: '#FFFFF0', + khaki: '#F0E68C', + lavender: '#E6E6FA', + lavenderblush: '#FFF0F5', + lawngreen: '#7CFC00', + lemonchiffon: '#FFFACD', + lightblue: '#ADD8E6', + lightcoral: '#F08080', + lightcyan: '#E0FFFF', + lightgoldenrodyellow: '#FAFAD2', + lightgray: '#D3D3D3', + lightgreen: '#90EE90', + lightgrey: '#D3D3D3', + lightpink: '#FFB6C1', + lightsalmon: '#FFA07A', + lightseagreen: '#20B2AA', + lightskyblue: '#87CEFA', + lightslategray: '#778899', + lightslategrey: '#778899', + lightsteelblue: '#B0C4DE', + lightyellow: '#FFFFE0', + lime: '#00FF00', + limegreen: '#32CD32', + linen: '#FAF0E6', + magenta: '#FF00FF', + maroon: '#800000', + mediumaquamarine: '#66CDAA', + mediumblue: '#0000CD', + mediumorchid: '#BA55D3', + mediumpurple: '#9370DB', + mediumseagreen: '#3CB371', + mediumslateblue: '#7B68EE', + mediumspringgreen: '#00FA9A', + mediumturquoise: '#48D1CC', + mediumvioletred: '#C71585', + midnightblue: '#191970', + mintcream: '#F5FFFA', + mistyrose: '#FFE4E1', + moccasin: '#FFE4B5', + navajowhite: '#FFDEAD', + navy: '#000080', + oldlace: '#FDF5E6', + olive: '#808000', + olivedrab: '#6B8E23', + orange: '#FFA500', + orangered: '#FF4500', + orchid: '#DA70D6', + palegoldenrod: '#EEE8AA', + palegreen: '#98FB98', + paleturquoise: '#AFEEEE', + palevioletred: '#DB7093', + papayawhip: '#FFEFD5', + peachpuff: '#FFDAB9', + peru: '#CD853F', + pink: '#FFC0CB', + plum: '#DDA0DD', + powderblue: '#B0E0E6', + purple: '#800080', + rebeccapurple: '#663399', + red: '#FF0000', + rosybrown: '#BC8F8F', + royalblue: '#4169E1', + saddlebrown: '#8B4513', + salmon: '#FA8072', + sandybrown: '#F4A460', + seagreen: '#2E8B57', + seashell: '#FFF5EE', + sienna: '#A0522D', + silver: '#C0C0C0', + skyblue: '#87CEEB', + slateblue: '#6A5ACD', + slategray: '#708090', + slategrey: '#708090', + snow: '#FFFAFA', + springgreen: '#00FF7F', + steelblue: '#4682B4', + tan: '#D2B48C', + teal: '#008080', + thistle: '#D8BFD8', + tomato: '#FF6347', + turquoise: '#40E0D0', + violet: '#EE82EE', + wheat: '#F5DEB3', + white: '#FFFFFF', + whitesmoke: '#F5F5F5', + yellow: '#FFFF00', + yellowgreen: '#9ACD32', +} + +export function isDark(color: string = ''): boolean { // Equation from http://24ways.org/2010/calculating-color-contrast - const rgb = hexToRgb(color) + let rgb = colorMap[color] ? hexToRgb(colorMap[color]) : hexToRgb(color) const res = (rgb[0] * 299 + rgb[1] * 587 + rgb[2] * 114) / 1000 return res < 128 } diff --git a/package.json b/package.json index a3aac641b..4e8fa8d30 100644 --- a/package.json +++ b/package.json @@ -16,10 +16,6 @@ "engines": { "node": "14.x" }, - "prettier": { - "semi": false, - "singleQuote": true - }, "dependencies": { "@reach/portal": "^0.11.2", "@vercel/fetch": "^6.1.0", @@ -74,7 +70,7 @@ "next-unused": "^0.0.3", "postcss-flexbugs-fixes": "^4.2.1", "postcss-preset-env": "^6.7.0", - "prettier": "^2.1.2", + "prettier": "^2.2.1", "typescript": "^4.0.3" }, "resolutions": { diff --git a/yarn.lock b/yarn.lock index 2f23e6a57..7a1dce814 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5662,7 +5662,7 @@ prepend-http@^2.0.0: resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-2.0.0.tgz#e92434bfa5ea8c19f41cdfd401d741a3c819d897" integrity sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc= -prettier@^2.0.5, prettier@^2.1.2: +prettier@^2.0.5, prettier@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.2.1.tgz#795a1a78dd52f073da0cd42b21f9c91381923ff5" integrity sha512-PqyhM2yCjg/oKkFPtTGUojv7gnZAoG80ttl45O6x2Ug/rMJw4wcc9k6aaf2hibP7BGVCCM33gZoGjyvt9mm16Q== From 394efd9e8191c2f3d44198388e03dc9a4fa4627a Mon Sep 17 00:00:00 2001 From: Luis Alvarez Date: Tue, 2 Mar 2021 18:13:30 -0500 Subject: [PATCH 187/216] Updated main readme --- README.md | 57 ++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 46 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index f254b1b07..cc181b411 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,7 @@ We're using Github Projects to keep track of issues in progress and todo's. Here ## Integrations -Next.js Commerce integrates out-of-the-box with BigCommerce. We plan to support all major ecommerce backends. +Next.js Commerce integrates out-of-the-box with BigCommerce and Shopify. We plan to support all major ecommerce backends. ## Goals @@ -38,13 +38,13 @@ Next.js Commerce integrates out-of-the-box with BigCommerce. We plan to support There is a `framework` folder in the root folder that will contain multiple ecommerce providers. -Additionally, we need to ensure feature parity (not all providers have e.g. wishlist) we will also have to build a feature API to disable/enable features in the UI. +Additionally, we need to ensure feature parity (not all providers have e.g. wishlist) so we also have a feature API to disable/enable features in the UI. People actively working on this project: @okbel & @lfades. ## Framework -Framework is where the data comes from. It contains mostly hooks and functions. +Framework is where the data comes from. It contains mostly hook handlers and functions. ## Structure @@ -77,7 +77,7 @@ Main folder and its exposed functions - `config.json` - README.md -#### Example of correct usage of Commerce Framework +#### Example of correct usage of the Commerce Framework ```js import { useUI } from '@components/ui' @@ -85,22 +85,57 @@ import { useCustomer } from '@framework/customer' import { useWishlist, useAddItem, useRemoveItem } from '@framework/wishlist' ``` -## Config +## Configuration -### Features +### How to change providers -In order to make the UI entirely functional, we need to specify which features certain providers do not **provide**. +First, update the provider selected in `commerce.config.json`: -**Disabling wishlist:** - -``` +```json { + "provider": "bigcommerce", "features": { - "wishlist": false + "wishlist": true } } ``` +Then, change the paths defined in `tsconfig.json` and update the `@framework` paths to point to the right folder provider: + +```json +"@framework": ["framework/bigcommerce"], +"@framework/*": ["framework/bigcommerce/*"] +``` + +Make sure to add the environment variables required by the new provider. + +### Features + +Every provider defines the features that it supports under `framework/{provider}/commerce.config.json` + +#### How to turn Features on and off + +> NOTE: The selected provider should support the feature that you are toggling. (This means that you can't turn wishlist on if the provider doesn't support this functionality out the box) + +- Open `commerce.config.json` +- You'll see a config file like this: + ```json + { + "provider": "bigcommerce", + "features": { + "wishlist": false + } + } + ``` +- Turn wishlist on by setting wishlist to true. +- Run the app and the wishlist functionality should be back on. + +### How to create a new provider + +We'd recommend to duplicate a provider folder and push your providers SDK. + +If you succeeded building a provider, submit a PR so we can all enjoy it. + ## Contribute Our commitment to Open Source can be found [here](https://vercel.com/oss). From 753234dc51b90114abb0c8fa1d247d163511095f Mon Sep 17 00:00:00 2001 From: Dave Loneragan Date: Tue, 2 Mar 2021 21:05:13 -0600 Subject: [PATCH 188/216] Add swell provider folder --- framework/swell/.env.template | 2 + framework/swell/README.md | 260 + framework/swell/api/cart/index.ts | 1 + framework/swell/api/catalog/index.ts | 1 + framework/swell/api/catalog/products.ts | 1 + framework/swell/api/checkout/index.ts | 46 + framework/swell/api/customer.ts | 1 + framework/swell/api/customers/index.ts | 1 + framework/swell/api/customers/login.ts | 1 + framework/swell/api/customers/logout.ts | 1 + framework/swell/api/customers/signup.ts | 1 + framework/swell/api/index.ts | 62 + .../api/operations/get-all-collections.ts | 21 + framework/swell/api/operations/get-page.ts | 25 + .../swell/api/utils/create-api-handler.ts | 58 + .../swell/api/utils/fetch-all-products.ts | 41 + .../swell/api/utils/fetch-graphql-api.ts | 34 + framework/swell/api/utils/fetch.ts | 2 + .../swell/api/utils/is-allowed-method.ts | 28 + framework/swell/api/wishlist/index.tsx | 2 + framework/swell/auth/use-login.tsx | 76 + framework/swell/auth/use-logout.tsx | 36 + framework/swell/auth/use-signup.tsx | 74 + framework/swell/cart/index.ts | 3 + framework/swell/cart/use-add-item.tsx | 58 + framework/swell/cart/use-cart.tsx | 59 + framework/swell/cart/use-remove-item.tsx | 72 + framework/swell/cart/use-update-item.tsx | 107 + framework/swell/cart/utils/checkout-create.ts | 29 + .../swell/cart/utils/checkout-to-cart.ts | 42 + framework/swell/cart/utils/fetcher.ts | 31 + framework/swell/cart/utils/index.ts | 2 + framework/swell/commerce.config.json | 6 + framework/swell/common/get-all-pages.ts | 42 + framework/swell/common/get-page.ts | 37 + framework/swell/common/get-site-info.ts | 31 + framework/swell/const.ts | 13 + framework/swell/customer/get-customer-id.ts | 24 + framework/swell/customer/index.ts | 1 + framework/swell/customer/use-customer.tsx | 27 + framework/swell/fetcher.ts | 18 + framework/swell/index.tsx | 40 + framework/swell/next.config.js | 8 + .../swell/product/get-all-collections.ts | 29 + .../swell/product/get-all-product-paths.ts | 42 + framework/swell/product/get-all-products.ts | 40 + framework/swell/product/get-product.ts | 32 + framework/swell/product/use-price.tsx | 2 + framework/swell/product/use-search.tsx | 77 + framework/swell/provider.ts | 31 + framework/swell/schema.d.ts | 4985 +++++++++ framework/swell/schema.graphql | 9631 +++++++++++++++++ framework/swell/types.ts | 45 + framework/swell/utils/customer-token.ts | 21 + framework/swell/utils/get-categories.ts | 29 + framework/swell/utils/get-checkout-id.ts | 8 + framework/swell/utils/get-search-variables.ts | 27 + framework/swell/utils/get-sort-variables.ts | 32 + framework/swell/utils/get-vendors.ts | 36 + .../swell/utils/handle-fetch-response.ts | 27 + framework/swell/utils/handle-login.ts | 39 + framework/swell/utils/index.ts | 10 + .../associate-customer-with-checkout.ts | 18 + .../swell/utils/mutations/checkout-create.ts | 16 + .../utils/mutations/checkout-line-item-add.ts | 16 + .../mutations/checkout-line-item-remove.ts | 19 + .../mutations/checkout-line-item-update.ts | 16 + .../mutations/customer-access-token-create.ts | 16 + .../mutations/customer-access-token-delete.ts | 14 + .../swell/utils/mutations/customer-create.ts | 15 + framework/swell/utils/mutations/index.ts | 7 + framework/swell/utils/normalize.ts | 152 + .../queries/get-all-collections-query.ts | 14 + .../utils/queries/get-all-pages-query.ts | 14 + .../queries/get-all-product-vendors-query.ts | 17 + .../queries/get-all-products-paths-query.ts | 17 + .../utils/queries/get-all-products-query.ts | 57 + .../swell/utils/queries/get-checkout-query.ts | 62 + .../queries/get-collection-products-query.ts | 24 + .../utils/queries/get-customer-id-query.ts | 8 + .../swell/utils/queries/get-customer-query.ts | 16 + .../swell/utils/queries/get-page-query.ts | 14 + .../swell/utils/queries/get-product-query.ts | 69 + framework/swell/utils/queries/index.ts | 10 + framework/swell/utils/storage.ts | 13 + framework/swell/wishlist/use-add-item.tsx | 13 + framework/swell/wishlist/use-remove-item.tsx | 17 + framework/swell/wishlist/use-wishlist.tsx | 46 + 88 files changed, 17268 insertions(+) create mode 100644 framework/swell/.env.template create mode 100644 framework/swell/README.md create mode 100644 framework/swell/api/cart/index.ts create mode 100644 framework/swell/api/catalog/index.ts create mode 100644 framework/swell/api/catalog/products.ts create mode 100644 framework/swell/api/checkout/index.ts create mode 100644 framework/swell/api/customer.ts create mode 100644 framework/swell/api/customers/index.ts create mode 100644 framework/swell/api/customers/login.ts create mode 100644 framework/swell/api/customers/logout.ts create mode 100644 framework/swell/api/customers/signup.ts create mode 100644 framework/swell/api/index.ts create mode 100644 framework/swell/api/operations/get-all-collections.ts create mode 100644 framework/swell/api/operations/get-page.ts create mode 100644 framework/swell/api/utils/create-api-handler.ts create mode 100644 framework/swell/api/utils/fetch-all-products.ts create mode 100644 framework/swell/api/utils/fetch-graphql-api.ts create mode 100644 framework/swell/api/utils/fetch.ts create mode 100644 framework/swell/api/utils/is-allowed-method.ts create mode 100644 framework/swell/api/wishlist/index.tsx create mode 100644 framework/swell/auth/use-login.tsx create mode 100644 framework/swell/auth/use-logout.tsx create mode 100644 framework/swell/auth/use-signup.tsx create mode 100644 framework/swell/cart/index.ts create mode 100644 framework/swell/cart/use-add-item.tsx create mode 100644 framework/swell/cart/use-cart.tsx create mode 100644 framework/swell/cart/use-remove-item.tsx create mode 100644 framework/swell/cart/use-update-item.tsx create mode 100644 framework/swell/cart/utils/checkout-create.ts create mode 100644 framework/swell/cart/utils/checkout-to-cart.ts create mode 100644 framework/swell/cart/utils/fetcher.ts create mode 100644 framework/swell/cart/utils/index.ts create mode 100644 framework/swell/commerce.config.json create mode 100644 framework/swell/common/get-all-pages.ts create mode 100644 framework/swell/common/get-page.ts create mode 100644 framework/swell/common/get-site-info.ts create mode 100644 framework/swell/const.ts create mode 100644 framework/swell/customer/get-customer-id.ts create mode 100644 framework/swell/customer/index.ts create mode 100644 framework/swell/customer/use-customer.tsx create mode 100644 framework/swell/fetcher.ts create mode 100644 framework/swell/index.tsx create mode 100644 framework/swell/next.config.js create mode 100644 framework/swell/product/get-all-collections.ts create mode 100644 framework/swell/product/get-all-product-paths.ts create mode 100644 framework/swell/product/get-all-products.ts create mode 100644 framework/swell/product/get-product.ts create mode 100644 framework/swell/product/use-price.tsx create mode 100644 framework/swell/product/use-search.tsx create mode 100644 framework/swell/provider.ts create mode 100644 framework/swell/schema.d.ts create mode 100644 framework/swell/schema.graphql create mode 100644 framework/swell/types.ts create mode 100644 framework/swell/utils/customer-token.ts create mode 100644 framework/swell/utils/get-categories.ts create mode 100644 framework/swell/utils/get-checkout-id.ts create mode 100644 framework/swell/utils/get-search-variables.ts create mode 100644 framework/swell/utils/get-sort-variables.ts create mode 100644 framework/swell/utils/get-vendors.ts create mode 100644 framework/swell/utils/handle-fetch-response.ts create mode 100644 framework/swell/utils/handle-login.ts create mode 100644 framework/swell/utils/index.ts create mode 100644 framework/swell/utils/mutations/associate-customer-with-checkout.ts create mode 100644 framework/swell/utils/mutations/checkout-create.ts create mode 100644 framework/swell/utils/mutations/checkout-line-item-add.ts create mode 100644 framework/swell/utils/mutations/checkout-line-item-remove.ts create mode 100644 framework/swell/utils/mutations/checkout-line-item-update.ts create mode 100644 framework/swell/utils/mutations/customer-access-token-create.ts create mode 100644 framework/swell/utils/mutations/customer-access-token-delete.ts create mode 100644 framework/swell/utils/mutations/customer-create.ts create mode 100644 framework/swell/utils/mutations/index.ts create mode 100644 framework/swell/utils/normalize.ts create mode 100644 framework/swell/utils/queries/get-all-collections-query.ts create mode 100644 framework/swell/utils/queries/get-all-pages-query.ts create mode 100644 framework/swell/utils/queries/get-all-product-vendors-query.ts create mode 100644 framework/swell/utils/queries/get-all-products-paths-query.ts create mode 100644 framework/swell/utils/queries/get-all-products-query.ts create mode 100644 framework/swell/utils/queries/get-checkout-query.ts create mode 100644 framework/swell/utils/queries/get-collection-products-query.ts create mode 100644 framework/swell/utils/queries/get-customer-id-query.ts create mode 100644 framework/swell/utils/queries/get-customer-query.ts create mode 100644 framework/swell/utils/queries/get-page-query.ts create mode 100644 framework/swell/utils/queries/get-product-query.ts create mode 100644 framework/swell/utils/queries/index.ts create mode 100644 framework/swell/utils/storage.ts create mode 100644 framework/swell/wishlist/use-add-item.tsx create mode 100644 framework/swell/wishlist/use-remove-item.tsx create mode 100644 framework/swell/wishlist/use-wishlist.tsx diff --git a/framework/swell/.env.template b/framework/swell/.env.template new file mode 100644 index 000000000..24521c2a1 --- /dev/null +++ b/framework/swell/.env.template @@ -0,0 +1,2 @@ +SHOPIFY_STORE_DOMAIN= +SHOPIFY_STOREFRONT_ACCESS_TOKEN= diff --git a/framework/swell/README.md b/framework/swell/README.md new file mode 100644 index 000000000..fc6a70ce3 --- /dev/null +++ b/framework/swell/README.md @@ -0,0 +1,260 @@ +## Table of Contents + +- [Getting Started](#getting-started) + - [Modifications](#modifications) + - [Adding item to Cart](#adding-item-to-cart) + - [Proceed to Checkout](#proceed-to-checkout) +- [General Usage](#general-usage) + - [CommerceProvider](#commerceprovider) + - [useCommerce](#usecommerce) +- [Hooks](#hooks) + - [usePrice](#useprice) + - [useAddItem](#useadditem) + - [useRemoveItem](#useremoveitem) + - [useUpdateItem](#useupdateitem) +- [APIs](#apis) + - [getProduct](#getproduct) + - [getAllProducts](#getallproducts) + - [getAllCollections](#getallcollections) + - [getAllPages](#getallpages) + +# Shopify Storefront Data Hooks + +Collection of hooks and data fetching functions to integrate Shopify in a React application. Designed to work with [Next.js Commerce](https://demo.vercel.store/). + +## Getting Started + +1. Install dependencies: + +``` +yarn install shopify-buy +yarn install -D @types/shopify-buy +``` + +3. Environment variables need to be set: + +``` +SHOPIFY_STORE_DOMAIN= +SHOPIFY_STOREFRONT_ACCESS_TOKEN= +NEXT_PUBLIC_SHOPIFY_STORE_DOMAIN= +NEXT_PUBLIC_SHOPIFY_STOREFRONT_ACCESS_TOKEN= +``` + +4. Point the framework to `shopify` by updating `tsconfig.json`: + +``` +"@framework/*": ["framework/shopify/*"], +"@framework": ["framework/shopify"] +``` + +### Modifications + +These modifications are temporarily until contributions are made to remove them. + +#### Adding item to Cart + +```js +// components/product/ProductView/ProductView.tsx +const ProductView: FC = ({ product }) => { + const addToCart = async () => { + setLoading(true) + try { + await addItem({ + productId: product.id, + variantId: variant ? variant.id : product.variants[0].id, + }) + openSidebar() + setLoading(false) + } catch (err) { + setLoading(false) + } + } +} +``` + +#### Proceed to Checkout + +```js +// components/cart/CartSidebarView/CartSidebarView.tsx +import { useCommerce } from '@framework' + +const CartSidebarView: FC = () => { + const { checkout } = useCommerce() + return ( + + ) +} +``` + +## General Usage + +### CommerceProvider + +Provider component that creates the commerce context for children. + +```js +import { CommerceProvider } from '@framework' + +const App = ({ children }) => { + return {children} +} + +export default App +``` + +### useCommerce + +Returns the configs that are defined in the nearest `CommerceProvider`. Also provides access to Shopify's `checkout` and `shop`. + +```js +import { useCommerce } from 'nextjs-commerce-shopify' + +const { checkout, shop } = useCommerce() +``` + +- `checkout`: The information required to checkout items and pay ([Documentation](https://shopify.dev/docs/storefront-api/reference/checkouts/checkout)). +- `shop`: Represents a collection of the general settings and information about the shop ([Documentation](https://shopify.dev/docs/storefront-api/reference/online-store/shop/index)). + +## Hooks + +### usePrice + +Display the product variant price according to currency and locale. + +```js +import usePrice from '@framework/product/use-price' + +const { price } = usePrice({ + amount, +}) +``` + +Takes in either `amount` or `variant`: + +- `amount`: A price value for a particular item if the amount is known. +- `variant`: A shopify product variant. Price will be extracted from the variant. + +### useAddItem + +```js +import { useAddItem } from '@framework/cart' + +const AddToCartButton = ({ variantId, quantity }) => { + const addItem = useAddItem() + + const addToCart = async () => { + await addItem({ + variantId, + }) + } + + return +} +``` + +### useRemoveItem + +```js +import { useRemoveItem } from '@framework/cart' + +const RemoveButton = ({ item }) => { + const removeItem = useRemoveItem() + + const handleRemove = async () => { + await removeItem({ id: item.id }) + } + + return +} +``` + +### useUpdateItem + +```js +import { useUpdateItem } from '@framework/cart' + +const CartItem = ({ item }) => { + const [quantity, setQuantity] = useState(item.quantity) + const updateItem = useUpdateItem(item) + + const updateQuantity = async (e) => { + const val = e.target.value + await updateItem({ quantity: val }) + } + + return ( + + ) +} +``` + +## APIs + +Collections of APIs to fetch data from a Shopify store. + +The data is fetched using the [Shopify JavaScript Buy SDK](https://github.com/Shopify/js-buy-sdk#readme). Read the [Shopify Storefront API reference](https://shopify.dev/docs/storefront-api/reference) for more information. + +### getProduct + +Get a single product by its `handle`. + +```js +import getProduct from '@framework/product/get-product' +import { getConfig } from '@framework/api' + +const config = getConfig() + +const product = await getProduct({ + variables: { slug }, + config, +}) +``` + +### getAllProducts + +```js +import getAllProducts from '@framework/product/get-all-products' +import { getConfig } from '@framework/api' + +const config = getConfig() + +const { products } = await getAllProducts({ + variables: { first: 12 }, + config, +}) +``` + +### getAllCollections + +```js +import getAllCollections from '@framework/product/get-all-collections' +import { getConfig } from '@framework/api' + +const config = getConfig() + +const collections = await getAllCollections({ + config, +}) +``` + +### getAllPages + +```js +import getAllPages from '@framework/common/get-all-pages' +import { getConfig } from '@framework/api' + +const config = getConfig() + +const pages = await getAllPages({ + variables: { first: 12 }, + config, +}) +``` diff --git a/framework/swell/api/cart/index.ts b/framework/swell/api/cart/index.ts new file mode 100644 index 000000000..ea9b101e1 --- /dev/null +++ b/framework/swell/api/cart/index.ts @@ -0,0 +1 @@ +export default function () {} diff --git a/framework/swell/api/catalog/index.ts b/framework/swell/api/catalog/index.ts new file mode 100644 index 000000000..ea9b101e1 --- /dev/null +++ b/framework/swell/api/catalog/index.ts @@ -0,0 +1 @@ +export default function () {} diff --git a/framework/swell/api/catalog/products.ts b/framework/swell/api/catalog/products.ts new file mode 100644 index 000000000..ea9b101e1 --- /dev/null +++ b/framework/swell/api/catalog/products.ts @@ -0,0 +1 @@ +export default function () {} diff --git a/framework/swell/api/checkout/index.ts b/framework/swell/api/checkout/index.ts new file mode 100644 index 000000000..244078466 --- /dev/null +++ b/framework/swell/api/checkout/index.ts @@ -0,0 +1,46 @@ +import isAllowedMethod from '../utils/is-allowed-method' +import createApiHandler, { + ShopifyApiHandler, +} from '../utils/create-api-handler' + +import { + SHOPIFY_CHECKOUT_ID_COOKIE, + SHOPIFY_CHECKOUT_URL_COOKIE, + SHOPIFY_CUSTOMER_TOKEN_COOKIE, +} from '../../const' + +import { getConfig } from '..' +import associateCustomerWithCheckoutMutation from '../../utils/mutations/associate-customer-with-checkout' + +const METHODS = ['GET'] + +const checkoutApi: ShopifyApiHandler = async (req, res, config) => { + if (!isAllowedMethod(req, res, METHODS)) return + + config = getConfig() + + const { cookies } = req + const checkoutUrl = cookies[SHOPIFY_CHECKOUT_URL_COOKIE] + const customerCookie = cookies[SHOPIFY_CUSTOMER_TOKEN_COOKIE] + + if (customerCookie) { + try { + await config.fetch(associateCustomerWithCheckoutMutation, { + variables: { + checkoutId: cookies[SHOPIFY_CHECKOUT_ID_COOKIE], + customerAccessToken: cookies[SHOPIFY_CUSTOMER_TOKEN_COOKIE], + }, + }) + } catch (error) { + console.error(error) + } + } + + if (checkoutUrl) { + res.redirect(checkoutUrl) + } else { + res.redirect('/cart') + } +} + +export default createApiHandler(checkoutApi, {}, {}) diff --git a/framework/swell/api/customer.ts b/framework/swell/api/customer.ts new file mode 100644 index 000000000..ea9b101e1 --- /dev/null +++ b/framework/swell/api/customer.ts @@ -0,0 +1 @@ +export default function () {} diff --git a/framework/swell/api/customers/index.ts b/framework/swell/api/customers/index.ts new file mode 100644 index 000000000..ea9b101e1 --- /dev/null +++ b/framework/swell/api/customers/index.ts @@ -0,0 +1 @@ +export default function () {} diff --git a/framework/swell/api/customers/login.ts b/framework/swell/api/customers/login.ts new file mode 100644 index 000000000..ea9b101e1 --- /dev/null +++ b/framework/swell/api/customers/login.ts @@ -0,0 +1 @@ +export default function () {} diff --git a/framework/swell/api/customers/logout.ts b/framework/swell/api/customers/logout.ts new file mode 100644 index 000000000..ea9b101e1 --- /dev/null +++ b/framework/swell/api/customers/logout.ts @@ -0,0 +1 @@ +export default function () {} diff --git a/framework/swell/api/customers/signup.ts b/framework/swell/api/customers/signup.ts new file mode 100644 index 000000000..ea9b101e1 --- /dev/null +++ b/framework/swell/api/customers/signup.ts @@ -0,0 +1 @@ +export default function () {} diff --git a/framework/swell/api/index.ts b/framework/swell/api/index.ts new file mode 100644 index 000000000..4f15cae15 --- /dev/null +++ b/framework/swell/api/index.ts @@ -0,0 +1,62 @@ +import type { CommerceAPIConfig } from '@commerce/api' + +import { + API_URL, + API_TOKEN, + SHOPIFY_CHECKOUT_ID_COOKIE, + SHOPIFY_CUSTOMER_TOKEN_COOKIE, + SHOPIFY_COOKIE_EXPIRE, +} from '../const' + +if (!API_URL) { + throw new Error( + `The environment variable NEXT_PUBLIC_SHOPIFY_STORE_DOMAIN is missing and it's required to access your store` + ) +} + +if (!API_TOKEN) { + throw new Error( + `The environment variable NEXT_PUBLIC_SHOPIFY_STOREFRONT_ACCESS_TOKEN is missing and it's required to access your store` + ) +} + +import fetchGraphqlApi from './utils/fetch-graphql-api' + +export interface ShopifyConfig extends CommerceAPIConfig {} + +export class Config { + private config: ShopifyConfig + + constructor(config: ShopifyConfig) { + this.config = config + } + + getConfig(userConfig: Partial = {}) { + return Object.entries(userConfig).reduce( + (cfg, [key, value]) => Object.assign(cfg, { [key]: value }), + { ...this.config } + ) + } + + setConfig(newConfig: Partial) { + Object.assign(this.config, newConfig) + } +} + +const config = new Config({ + locale: 'en-US', + commerceUrl: API_URL, + apiToken: API_TOKEN!, + cartCookie: SHOPIFY_CHECKOUT_ID_COOKIE, + cartCookieMaxAge: SHOPIFY_COOKIE_EXPIRE, + fetch: fetchGraphqlApi, + customerCookie: SHOPIFY_CUSTOMER_TOKEN_COOKIE, +}) + +export function getConfig(userConfig?: Partial) { + return config.getConfig(userConfig) +} + +export function setConfig(newConfig: Partial) { + return config.setConfig(newConfig) +} diff --git a/framework/swell/api/operations/get-all-collections.ts b/framework/swell/api/operations/get-all-collections.ts new file mode 100644 index 000000000..9cf216a91 --- /dev/null +++ b/framework/swell/api/operations/get-all-collections.ts @@ -0,0 +1,21 @@ +import Client from 'shopify-buy' +import { ShopifyConfig } from '../index' + +type Options = { + config: ShopifyConfig +} + +const getAllCollections = async (options: Options) => { + const { config } = options + + const client = Client.buildClient({ + storefrontAccessToken: config.apiToken, + domain: config.commerceUrl, + }) + + const res = await client.collection.fetchAllWithProducts() + + return JSON.parse(JSON.stringify(res)) +} + +export default getAllCollections diff --git a/framework/swell/api/operations/get-page.ts b/framework/swell/api/operations/get-page.ts new file mode 100644 index 000000000..32acb7c8f --- /dev/null +++ b/framework/swell/api/operations/get-page.ts @@ -0,0 +1,25 @@ +import { Page } from '../../schema' +import { ShopifyConfig, getConfig } from '..' + +export type GetPageResult = T + +export type PageVariables = { + id: string +} + +async function getPage({ + url, + variables, + config, + preview, +}: { + url?: string + variables: PageVariables + config?: ShopifyConfig + preview?: boolean +}): Promise { + config = getConfig(config) + return {} +} + +export default getPage diff --git a/framework/swell/api/utils/create-api-handler.ts b/framework/swell/api/utils/create-api-handler.ts new file mode 100644 index 000000000..8820aeabc --- /dev/null +++ b/framework/swell/api/utils/create-api-handler.ts @@ -0,0 +1,58 @@ +import type { NextApiHandler, NextApiRequest, NextApiResponse } from 'next' +import { ShopifyConfig, getConfig } from '..' + +export type ShopifyApiHandler< + T = any, + H extends ShopifyHandlers = {}, + Options extends {} = {} +> = ( + req: NextApiRequest, + res: NextApiResponse>, + config: ShopifyConfig, + handlers: H, + // Custom configs that may be used by a particular handler + options: Options +) => void | Promise + +export type ShopifyHandler = (options: { + req: NextApiRequest + res: NextApiResponse> + config: ShopifyConfig + body: Body +}) => void | Promise + +export type ShopifyHandlers = { + [k: string]: ShopifyHandler +} + +export type ShopifyApiResponse = { + data: T | null + errors?: { message: string; code?: string }[] +} + +export default function createApiHandler< + T = any, + H extends ShopifyHandlers = {}, + Options extends {} = {} +>( + handler: ShopifyApiHandler, + handlers: H, + defaultOptions: Options +) { + return function getApiHandler({ + config, + operations, + options, + }: { + config?: ShopifyConfig + operations?: Partial + options?: Options extends {} ? Partial : never + } = {}): NextApiHandler { + const ops = { ...operations, ...handlers } + const opts = { ...defaultOptions, ...options } + + return function apiHandler(req, res) { + return handler(req, res, getConfig(config), ops, opts) + } + } +} diff --git a/framework/swell/api/utils/fetch-all-products.ts b/framework/swell/api/utils/fetch-all-products.ts new file mode 100644 index 000000000..9fa70a5ee --- /dev/null +++ b/framework/swell/api/utils/fetch-all-products.ts @@ -0,0 +1,41 @@ +import { ProductEdge } from '../../schema' +import { ShopifyConfig } from '..' + +const fetchAllProducts = async ({ + config, + query, + variables, + acc = [], + cursor, +}: { + config: ShopifyConfig + query: string + acc?: ProductEdge[] + variables?: any + cursor?: string +}): Promise => { + const { data } = await config.fetch(query, { + variables: { ...variables, cursor }, + }) + + const edges: ProductEdge[] = data.products?.edges ?? [] + const hasNextPage = data.products?.pageInfo?.hasNextPage + acc = acc.concat(edges) + + if (hasNextPage) { + const cursor = edges.pop()?.cursor + if (cursor) { + return fetchAllProducts({ + config, + query, + variables, + acc, + cursor, + }) + } + } + + return acc +} + +export default fetchAllProducts diff --git a/framework/swell/api/utils/fetch-graphql-api.ts b/framework/swell/api/utils/fetch-graphql-api.ts new file mode 100644 index 000000000..321cba2aa --- /dev/null +++ b/framework/swell/api/utils/fetch-graphql-api.ts @@ -0,0 +1,34 @@ +import type { GraphQLFetcher } from '@commerce/api' +import fetch from './fetch' + +import { API_URL, API_TOKEN } from '../../const' +import { getError } from '../../utils/handle-fetch-response' + +const fetchGraphqlApi: GraphQLFetcher = async ( + query: string, + { variables } = {}, + fetchOptions +) => { + const res = await fetch(API_URL, { + ...fetchOptions, + method: 'POST', + headers: { + 'X-Shopify-Storefront-Access-Token': API_TOKEN!, + ...fetchOptions?.headers, + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + query, + variables, + }), + }) + + const { data, errors, status } = await res.json() + + if (errors) { + throw getError(errors, status) + } + + return { data, res } +} +export default fetchGraphqlApi diff --git a/framework/swell/api/utils/fetch.ts b/framework/swell/api/utils/fetch.ts new file mode 100644 index 000000000..0b8367102 --- /dev/null +++ b/framework/swell/api/utils/fetch.ts @@ -0,0 +1,2 @@ +import zeitFetch from '@vercel/fetch' +export default zeitFetch() diff --git a/framework/swell/api/utils/is-allowed-method.ts b/framework/swell/api/utils/is-allowed-method.ts new file mode 100644 index 000000000..78bbba568 --- /dev/null +++ b/framework/swell/api/utils/is-allowed-method.ts @@ -0,0 +1,28 @@ +import type { NextApiRequest, NextApiResponse } from 'next' + +export default function isAllowedMethod( + req: NextApiRequest, + res: NextApiResponse, + allowedMethods: string[] +) { + const methods = allowedMethods.includes('OPTIONS') + ? allowedMethods + : [...allowedMethods, 'OPTIONS'] + + if (!req.method || !methods.includes(req.method)) { + res.status(405) + res.setHeader('Allow', methods.join(', ')) + res.end() + return false + } + + if (req.method === 'OPTIONS') { + res.status(200) + res.setHeader('Allow', methods.join(', ')) + res.setHeader('Content-Length', '0') + res.end() + return false + } + + return true +} diff --git a/framework/swell/api/wishlist/index.tsx b/framework/swell/api/wishlist/index.tsx new file mode 100644 index 000000000..a72856673 --- /dev/null +++ b/framework/swell/api/wishlist/index.tsx @@ -0,0 +1,2 @@ +export type WishlistItem = { product: any; id: number } +export default function () {} diff --git a/framework/swell/auth/use-login.tsx b/framework/swell/auth/use-login.tsx new file mode 100644 index 000000000..188dd54a2 --- /dev/null +++ b/framework/swell/auth/use-login.tsx @@ -0,0 +1,76 @@ +import { useCallback } from 'react' +import type { MutationHook } from '@commerce/utils/types' +import { CommerceError, ValidationError } from '@commerce/utils/errors' +import useCustomer from '../customer/use-customer' +import createCustomerAccessTokenMutation from '../utils/mutations/customer-access-token-create' +import { + CustomerAccessTokenCreateInput, + CustomerUserError, + Mutation, + MutationCheckoutCreateArgs, +} from '../schema' +import useLogin, { UseLogin } from '@commerce/auth/use-login' +import { setCustomerToken } from '../utils' + +export default useLogin as UseLogin + +const getErrorMessage = ({ code, message }: CustomerUserError) => { + switch (code) { + case 'UNIDENTIFIED_CUSTOMER': + message = 'Cannot find an account that matches the provided credentials' + break + } + return message +} + +export const handler: MutationHook = { + fetchOptions: { + query: createCustomerAccessTokenMutation, + }, + async fetcher({ input: { email, password }, options, fetch }) { + if (!(email && password)) { + throw new CommerceError({ + message: + 'A first name, last name, email and password are required to login', + }) + } + + const { customerAccessTokenCreate } = await fetch< + Mutation, + MutationCheckoutCreateArgs + >({ + ...options, + variables: { + input: { email, password }, + }, + }) + + const errors = customerAccessTokenCreate?.customerUserErrors + + if (errors && errors.length) { + throw new ValidationError({ + message: getErrorMessage(errors[0]), + }) + } + const customerAccessToken = customerAccessTokenCreate?.customerAccessToken + const accessToken = customerAccessToken?.accessToken + + if (accessToken) { + setCustomerToken(accessToken) + } + + return null + }, + useHook: ({ fetch }) => () => { + const { revalidate } = useCustomer() + + return useCallback( + async function login(input) { + const data = await fetch({ input }) + await revalidate() + return data + }, + [fetch, revalidate] + ) + }, +} diff --git a/framework/swell/auth/use-logout.tsx b/framework/swell/auth/use-logout.tsx new file mode 100644 index 000000000..81a3b8cdd --- /dev/null +++ b/framework/swell/auth/use-logout.tsx @@ -0,0 +1,36 @@ +import { useCallback } from 'react' +import type { MutationHook } from '@commerce/utils/types' +import useLogout, { UseLogout } from '@commerce/auth/use-logout' +import useCustomer from '../customer/use-customer' +import customerAccessTokenDeleteMutation from '../utils/mutations/customer-access-token-delete' +import { getCustomerToken, setCustomerToken } from '../utils/customer-token' + +export default useLogout as UseLogout + +export const handler: MutationHook = { + fetchOptions: { + query: customerAccessTokenDeleteMutation, + }, + async fetcher({ options, fetch }) { + await fetch({ + ...options, + variables: { + customerAccessToken: getCustomerToken(), + }, + }) + setCustomerToken(null) + return null + }, + useHook: ({ fetch }) => () => { + const { mutate } = useCustomer() + + return useCallback( + async function logout() { + const data = await fetch() + await mutate(null, false) + return data + }, + [fetch, mutate] + ) + }, +} diff --git a/framework/swell/auth/use-signup.tsx b/framework/swell/auth/use-signup.tsx new file mode 100644 index 000000000..7f66448d3 --- /dev/null +++ b/framework/swell/auth/use-signup.tsx @@ -0,0 +1,74 @@ +import { useCallback } from 'react' +import type { MutationHook } from '@commerce/utils/types' +import { CommerceError } from '@commerce/utils/errors' +import useSignup, { UseSignup } from '@commerce/auth/use-signup' +import useCustomer from '../customer/use-customer' +import { CustomerCreateInput } from '../schema' + +import { + customerCreateMutation, + customerAccessTokenCreateMutation, +} from '../utils/mutations' +import handleLogin from '../utils/handle-login' + +export default useSignup as UseSignup + +export const handler: MutationHook< + null, + {}, + CustomerCreateInput, + CustomerCreateInput +> = { + fetchOptions: { + query: customerCreateMutation, + }, + async fetcher({ + input: { firstName, lastName, email, password }, + options, + fetch, + }) { + if (!(firstName && lastName && email && password)) { + throw new CommerceError({ + message: + 'A first name, last name, email and password are required to signup', + }) + } + const data = await fetch({ + ...options, + variables: { + input: { + firstName, + lastName, + email, + password, + }, + }, + }) + + try { + const loginData = await fetch({ + query: customerAccessTokenCreateMutation, + variables: { + input: { + email, + password, + }, + }, + }) + handleLogin(loginData) + } catch (error) {} + return data + }, + useHook: ({ fetch }) => () => { + const { revalidate } = useCustomer() + + return useCallback( + async function signup(input) { + const data = await fetch({ input }) + await revalidate() + return data + }, + [fetch, revalidate] + ) + }, +} diff --git a/framework/swell/cart/index.ts b/framework/swell/cart/index.ts new file mode 100644 index 000000000..3d288b1df --- /dev/null +++ b/framework/swell/cart/index.ts @@ -0,0 +1,3 @@ +export { default as useCart } from './use-cart' +export { default as useAddItem } from './use-add-item' +export { default as useRemoveItem } from './use-remove-item' diff --git a/framework/swell/cart/use-add-item.tsx b/framework/swell/cart/use-add-item.tsx new file mode 100644 index 000000000..d0f891148 --- /dev/null +++ b/framework/swell/cart/use-add-item.tsx @@ -0,0 +1,58 @@ +import type { MutationHook } from '@commerce/utils/types' +import { CommerceError } from '@commerce/utils/errors' +import useAddItem, { UseAddItem } from '@commerce/cart/use-add-item' +import useCart from './use-cart' +import { Cart, CartItemBody } from '../types' +import { checkoutLineItemAddMutation, getCheckoutId } from '../utils' +import { checkoutToCart } from './utils' +import { Mutation, MutationCheckoutLineItemsAddArgs } from '../schema' +import { useCallback } from 'react' + +export default useAddItem as UseAddItem + +export const handler: MutationHook = { + fetchOptions: { + query: checkoutLineItemAddMutation, + }, + async fetcher({ input: item, options, fetch }) { + if ( + item.quantity && + (!Number.isInteger(item.quantity) || item.quantity! < 1) + ) { + throw new CommerceError({ + message: 'The item quantity has to be a valid integer greater than 0', + }) + } + + const { checkoutLineItemsAdd } = await fetch< + Mutation, + MutationCheckoutLineItemsAddArgs + >({ + ...options, + variables: { + checkoutId: getCheckoutId(), + lineItems: [ + { + variantId: item.variantId, + quantity: item.quantity ?? 1, + }, + ], + }, + }) + + // TODO: Fix this Cart type here + return checkoutToCart(checkoutLineItemsAdd) as any + }, + useHook: ({ fetch }) => () => { + const { mutate } = useCart() + + return useCallback( + async function addItem(input) { + const data = await fetch({ input }) + await mutate(data, false) + return data + }, + [fetch, mutate] + ) + }, +} diff --git a/framework/swell/cart/use-cart.tsx b/framework/swell/cart/use-cart.tsx new file mode 100644 index 000000000..d154bb837 --- /dev/null +++ b/framework/swell/cart/use-cart.tsx @@ -0,0 +1,59 @@ +import { useMemo } from 'react' +import useCommerceCart, { + FetchCartInput, + UseCart, +} from '@commerce/cart/use-cart' + +import { Cart } from '../types' +import { SWRHook } from '@commerce/utils/types' +import { checkoutCreate, checkoutToCart } from './utils' +import getCheckoutQuery from '../utils/queries/get-checkout-query' + +export default useCommerceCart as UseCart + +export const handler: SWRHook< + Cart | null, + {}, + FetchCartInput, + { isEmpty?: boolean } +> = { + fetchOptions: { + query: getCheckoutQuery, + }, + async fetcher({ input: { cartId: checkoutId }, options, fetch }) { + let checkout + if (checkoutId) { + const data = await fetch({ + ...options, + variables: { + checkoutId, + }, + }) + checkout = data.node + } + + if (checkout?.completedAt || !checkoutId) { + checkout = await checkoutCreate(fetch) + } + + // TODO: Fix this type + return checkoutToCart({ checkout } as any) + }, + useHook: ({ useData }) => (input) => { + const response = useData({ + swrOptions: { revalidateOnFocus: false, ...input?.swrOptions }, + }) + return useMemo( + () => + Object.create(response, { + isEmpty: { + get() { + return (response.data?.lineItems.length ?? 0) <= 0 + }, + enumerable: true, + }, + }), + [response] + ) + }, +} diff --git a/framework/swell/cart/use-remove-item.tsx b/framework/swell/cart/use-remove-item.tsx new file mode 100644 index 000000000..e2aef13d8 --- /dev/null +++ b/framework/swell/cart/use-remove-item.tsx @@ -0,0 +1,72 @@ +import { useCallback } from 'react' + +import type { + MutationHookContext, + HookFetcherContext, +} from '@commerce/utils/types' + +import { ValidationError } from '@commerce/utils/errors' + +import useRemoveItem, { + RemoveItemInput as RemoveItemInputBase, + UseRemoveItem, +} from '@commerce/cart/use-remove-item' + +import useCart from './use-cart' +import { checkoutLineItemRemoveMutation, getCheckoutId } from '../utils' +import { checkoutToCart } from './utils' +import { Cart, LineItem } from '../types' +import { Mutation, MutationCheckoutLineItemsRemoveArgs } from '../schema' +import { RemoveCartItemBody } from '@commerce/types' + +export type RemoveItemFn = T extends LineItem + ? (input?: RemoveItemInput) => Promise + : (input: RemoveItemInput) => Promise + +export type RemoveItemInput = T extends LineItem + ? Partial + : RemoveItemInputBase + +export default useRemoveItem as UseRemoveItem + +export const handler = { + fetchOptions: { + query: checkoutLineItemRemoveMutation, + }, + async fetcher({ + input: { itemId }, + options, + fetch, + }: HookFetcherContext) { + const data = await fetch({ + ...options, + variables: { checkoutId: getCheckoutId(), lineItemIds: [itemId] }, + }) + return checkoutToCart(data.checkoutLineItemsRemove) + }, + useHook: ({ + fetch, + }: MutationHookContext) => < + T extends LineItem | undefined = undefined + >( + ctx: { item?: T } = {} + ) => { + const { item } = ctx + const { mutate } = useCart() + const removeItem: RemoveItemFn = async (input) => { + const itemId = input?.id ?? item?.id + + if (!itemId) { + throw new ValidationError({ + message: 'Invalid input used for this operation', + }) + } + + const data = await fetch({ input: { itemId } }) + await mutate(data, false) + return data + } + + return useCallback(removeItem as RemoveItemFn, [fetch, mutate]) + }, +} diff --git a/framework/swell/cart/use-update-item.tsx b/framework/swell/cart/use-update-item.tsx new file mode 100644 index 000000000..666ce3d08 --- /dev/null +++ b/framework/swell/cart/use-update-item.tsx @@ -0,0 +1,107 @@ +import { useCallback } from 'react' +import debounce from 'lodash.debounce' +import type { + HookFetcherContext, + MutationHookContext, +} from '@commerce/utils/types' +import { ValidationError } from '@commerce/utils/errors' +import useUpdateItem, { + UpdateItemInput as UpdateItemInputBase, + UseUpdateItem, +} from '@commerce/cart/use-update-item' + +import useCart from './use-cart' +import { handler as removeItemHandler } from './use-remove-item' +import type { Cart, LineItem, UpdateCartItemBody } from '../types' +import { checkoutToCart } from './utils' +import { getCheckoutId, checkoutLineItemUpdateMutation } from '../utils' +import { Mutation, MutationCheckoutLineItemsUpdateArgs } from '../schema' + +export type UpdateItemInput = T extends LineItem + ? Partial> + : UpdateItemInputBase + +export default useUpdateItem as UseUpdateItem + +export const handler = { + fetchOptions: { + query: checkoutLineItemUpdateMutation, + }, + async fetcher({ + input: { itemId, item }, + options, + fetch, + }: HookFetcherContext) { + if (Number.isInteger(item.quantity)) { + // Also allow the update hook to remove an item if the quantity is lower than 1 + if (item.quantity! < 1) { + return removeItemHandler.fetcher({ + options: removeItemHandler.fetchOptions, + input: { itemId }, + fetch, + }) + } + } else if (item.quantity) { + throw new ValidationError({ + message: 'The item quantity has to be a valid integer', + }) + } + const { checkoutLineItemsUpdate } = await fetch< + Mutation, + MutationCheckoutLineItemsUpdateArgs + >({ + ...options, + variables: { + checkoutId: getCheckoutId(), + lineItems: [ + { + id: itemId, + quantity: item.quantity, + }, + ], + }, + }) + + return checkoutToCart(checkoutLineItemsUpdate) + }, + useHook: ({ + fetch, + }: MutationHookContext) => < + T extends LineItem | undefined = undefined + >( + ctx: { + item?: T + wait?: number + } = {} + ) => { + const { item } = ctx + const { mutate } = useCart() as any + + return useCallback( + debounce(async (input: UpdateItemInput) => { + const itemId = input.id ?? item?.id + const productId = input.productId ?? item?.productId + const variantId = input.productId ?? item?.variantId + if (!itemId || !productId || !variantId) { + throw new ValidationError({ + message: 'Invalid input used for this operation', + }) + } + + const data = await fetch({ + input: { + item: { + productId, + variantId, + quantity: input.quantity, + }, + itemId, + }, + }) + await mutate(data, false) + return data + }, ctx.wait ?? 500), + [fetch, mutate] + ) + }, +} diff --git a/framework/swell/cart/utils/checkout-create.ts b/framework/swell/cart/utils/checkout-create.ts new file mode 100644 index 000000000..e950cc7e4 --- /dev/null +++ b/framework/swell/cart/utils/checkout-create.ts @@ -0,0 +1,29 @@ +import { + SHOPIFY_CHECKOUT_ID_COOKIE, + SHOPIFY_CHECKOUT_URL_COOKIE, + SHOPIFY_COOKIE_EXPIRE, +} from '../../const' + +import checkoutCreateMutation from '../../utils/mutations/checkout-create' +import Cookies from 'js-cookie' + +export const checkoutCreate = async (fetch: any) => { + const data = await fetch({ + query: checkoutCreateMutation, + }) + + const checkout = data.checkoutCreate?.checkout + const checkoutId = checkout?.id + + if (checkoutId) { + const options = { + expires: SHOPIFY_COOKIE_EXPIRE, + } + Cookies.set(SHOPIFY_CHECKOUT_ID_COOKIE, checkoutId, options) + Cookies.set(SHOPIFY_CHECKOUT_URL_COOKIE, checkout?.webUrl, options) + } + + return checkout +} + +export default checkoutCreate diff --git a/framework/swell/cart/utils/checkout-to-cart.ts b/framework/swell/cart/utils/checkout-to-cart.ts new file mode 100644 index 000000000..03005f342 --- /dev/null +++ b/framework/swell/cart/utils/checkout-to-cart.ts @@ -0,0 +1,42 @@ +import { Cart } from '../../types' +import { CommerceError, ValidationError } from '@commerce/utils/errors' + +import { + CheckoutLineItemsAddPayload, + CheckoutLineItemsRemovePayload, + CheckoutLineItemsUpdatePayload, + Maybe, +} from '../../schema' +import { normalizeCart } from '../../utils' + +export type CheckoutPayload = + | CheckoutLineItemsAddPayload + | CheckoutLineItemsUpdatePayload + | CheckoutLineItemsRemovePayload + +const checkoutToCart = (checkoutPayload?: Maybe): Cart => { + if (!checkoutPayload) { + throw new CommerceError({ + message: 'Invalid response from Shopify', + }) + } + + const checkout = checkoutPayload?.checkout + const userErrors = checkoutPayload?.userErrors + + if (userErrors && userErrors.length) { + throw new ValidationError({ + message: userErrors[0].message, + }) + } + + if (!checkout) { + throw new CommerceError({ + message: 'Invalid response from Shopify', + }) + } + + return normalizeCart(checkout) +} + +export default checkoutToCart diff --git a/framework/swell/cart/utils/fetcher.ts b/framework/swell/cart/utils/fetcher.ts new file mode 100644 index 000000000..6afb55f18 --- /dev/null +++ b/framework/swell/cart/utils/fetcher.ts @@ -0,0 +1,31 @@ +import { HookFetcherFn } from '@commerce/utils/types' +import { Cart } from '@commerce/types' +import { checkoutCreate, checkoutToCart } from '.' +import { FetchCartInput } from '@commerce/cart/use-cart' + +const fetcher: HookFetcherFn = async ({ + options, + input: { cartId: checkoutId }, + fetch, +}) => { + let checkout + + if (checkoutId) { + const data = await fetch({ + ...options, + variables: { + checkoutId, + }, + }) + checkout = data.node + } + + if (checkout?.completedAt || !checkoutId) { + checkout = await checkoutCreate(fetch) + } + + // TODO: Fix this type + return checkoutToCart({ checkout } as any) +} + +export default fetcher diff --git a/framework/swell/cart/utils/index.ts b/framework/swell/cart/utils/index.ts new file mode 100644 index 000000000..20d04955d --- /dev/null +++ b/framework/swell/cart/utils/index.ts @@ -0,0 +1,2 @@ +export { default as checkoutToCart } from './checkout-to-cart' +export { default as checkoutCreate } from './checkout-create' diff --git a/framework/swell/commerce.config.json b/framework/swell/commerce.config.json new file mode 100644 index 000000000..b30ab39d9 --- /dev/null +++ b/framework/swell/commerce.config.json @@ -0,0 +1,6 @@ +{ + "provider": "shopify", + "features": { + "wishlist": false + } +} diff --git a/framework/swell/common/get-all-pages.ts b/framework/swell/common/get-all-pages.ts new file mode 100644 index 000000000..54231ed03 --- /dev/null +++ b/framework/swell/common/get-all-pages.ts @@ -0,0 +1,42 @@ +import { getConfig, ShopifyConfig } from '../api' +import { PageEdge } from '../schema' +import { getAllPagesQuery } from '../utils/queries' + +type Variables = { + first?: number +} + +type ReturnType = { + pages: Page[] +} + +export type Page = { + id: string + name: string + url: string + sort_order?: number + body: string +} + +const getAllPages = async (options?: { + variables?: Variables + config: ShopifyConfig + preview?: boolean +}): Promise => { + let { config, variables = { first: 250 } } = options ?? {} + config = getConfig(config) + const { locale } = config + const { data } = await config.fetch(getAllPagesQuery, { variables }) + + const pages = data.pages?.edges?.map( + ({ node: { title: name, handle, ...node } }: PageEdge) => ({ + ...node, + url: `/${locale}/${handle}`, + name, + }) + ) + + return { pages } +} + +export default getAllPages diff --git a/framework/swell/common/get-page.ts b/framework/swell/common/get-page.ts new file mode 100644 index 000000000..be934aa42 --- /dev/null +++ b/framework/swell/common/get-page.ts @@ -0,0 +1,37 @@ +import { getConfig, ShopifyConfig } from '../api' +import getPageQuery from '../utils/queries/get-page-query' +import { Page } from './get-all-pages' + +type Variables = { + id: string +} + +export type GetPageResult = T + +const getPage = async (options: { + variables: Variables + config: ShopifyConfig + preview?: boolean +}): Promise => { + let { config, variables } = options ?? {} + + config = getConfig(config) + const { locale } = config + + const { data } = await config.fetch(getPageQuery, { + variables, + }) + const page = data.node + + return { + page: page + ? { + ...page, + name: page.title, + url: `/${locale}/${page.handle}`, + } + : null, + } +} + +export default getPage diff --git a/framework/swell/common/get-site-info.ts b/framework/swell/common/get-site-info.ts new file mode 100644 index 000000000..cbbacf5b6 --- /dev/null +++ b/framework/swell/common/get-site-info.ts @@ -0,0 +1,31 @@ +import getCategories, { Category } from '../utils/get-categories' +import getVendors, { Brands } from '../utils/get-vendors' + +import { getConfig, ShopifyConfig } from '../api' + +export type GetSiteInfoResult< + T extends { categories: any[]; brands: any[] } = { + categories: Category[] + brands: Brands + } +> = T + +const getSiteInfo = async (options?: { + variables?: any + config: ShopifyConfig + preview?: boolean +}): Promise => { + let { config } = options ?? {} + + config = getConfig(config) + + const categories = await getCategories(config) + const brands = await getVendors(config) + + return { + categories, + brands, + } +} + +export default getSiteInfo diff --git a/framework/swell/const.ts b/framework/swell/const.ts new file mode 100644 index 000000000..06fbe5054 --- /dev/null +++ b/framework/swell/const.ts @@ -0,0 +1,13 @@ +export const SHOPIFY_CHECKOUT_ID_COOKIE = 'shopify_checkoutId' + +export const SHOPIFY_CHECKOUT_URL_COOKIE = 'shopify_checkoutUrl' + +export const SHOPIFY_CUSTOMER_TOKEN_COOKIE = 'shopify_customerToken' + +export const STORE_DOMAIN = process.env.NEXT_PUBLIC_SHOPIFY_STORE_DOMAIN + +export const SHOPIFY_COOKIE_EXPIRE = 30 + +export const API_URL = `https://${STORE_DOMAIN}/api/2021-01/graphql.json` + +export const API_TOKEN = process.env.NEXT_PUBLIC_SHOPIFY_STOREFRONT_ACCESS_TOKEN diff --git a/framework/swell/customer/get-customer-id.ts b/framework/swell/customer/get-customer-id.ts new file mode 100644 index 000000000..ca096645a --- /dev/null +++ b/framework/swell/customer/get-customer-id.ts @@ -0,0 +1,24 @@ +import { getConfig, ShopifyConfig } from '../api' +import getCustomerIdQuery from '../utils/queries/get-customer-id-query' +import Cookies from 'js-cookie' + +async function getCustomerId({ + customerToken: customerAccesToken, + config, +}: { + customerToken: string + config?: ShopifyConfig +}): Promise { + config = getConfig(config) + + const { data } = await config.fetch(getCustomerIdQuery, { + variables: { + customerAccesToken: + customerAccesToken || Cookies.get(config.customerCookie), + }, + }) + + return data.customer?.id +} + +export default getCustomerId diff --git a/framework/swell/customer/index.ts b/framework/swell/customer/index.ts new file mode 100644 index 000000000..6c903ecc5 --- /dev/null +++ b/framework/swell/customer/index.ts @@ -0,0 +1 @@ +export { default as useCustomer } from './use-customer' diff --git a/framework/swell/customer/use-customer.tsx b/framework/swell/customer/use-customer.tsx new file mode 100644 index 000000000..137f0da74 --- /dev/null +++ b/framework/swell/customer/use-customer.tsx @@ -0,0 +1,27 @@ +import useCustomer, { UseCustomer } from '@commerce/customer/use-customer' +import { Customer } from '@commerce/types' +import { SWRHook } from '@commerce/utils/types' +import { getCustomerQuery, getCustomerToken } from '../utils' + +export default useCustomer as UseCustomer + +export const handler: SWRHook = { + fetchOptions: { + query: getCustomerQuery, + }, + async fetcher({ options, fetch }) { + const data = await fetch({ + ...options, + variables: { customerAccessToken: getCustomerToken() }, + }) + return data.customer ?? null + }, + useHook: ({ useData }) => (input) => { + return useData({ + swrOptions: { + revalidateOnFocus: false, + ...input?.swrOptions, + }, + }) + }, +} diff --git a/framework/swell/fetcher.ts b/framework/swell/fetcher.ts new file mode 100644 index 000000000..9c4fe9a9e --- /dev/null +++ b/framework/swell/fetcher.ts @@ -0,0 +1,18 @@ +import { Fetcher } from '@commerce/utils/types' +import { API_TOKEN, API_URL } from './const' +import { handleFetchResponse } from './utils' + +const fetcher: Fetcher = async ({ method = 'POST', variables, query }) => { + return handleFetchResponse( + await fetch(API_URL, { + method, + body: JSON.stringify({ query, variables }), + headers: { + 'X-Shopify-Storefront-Access-Token': API_TOKEN!, + 'Content-Type': 'application/json', + }, + }) + ) +} + +export default fetcher diff --git a/framework/swell/index.tsx b/framework/swell/index.tsx new file mode 100644 index 000000000..c26704771 --- /dev/null +++ b/framework/swell/index.tsx @@ -0,0 +1,40 @@ +import * as React from 'react' +import { ReactNode } from 'react' + +import { + CommerceConfig, + CommerceProvider as CoreCommerceProvider, + useCommerce as useCoreCommerce, +} from '@commerce' + +import { shopifyProvider, ShopifyProvider } from './provider' +import { SHOPIFY_CHECKOUT_ID_COOKIE } from './const' + +export { shopifyProvider } +export type { ShopifyProvider } + +export const shopifyConfig: CommerceConfig = { + locale: 'en-us', + cartCookie: SHOPIFY_CHECKOUT_ID_COOKIE, +} + +export type ShopifyConfig = Partial + +export type ShopifyProps = { + children?: ReactNode + locale: string +} & ShopifyConfig + +export function CommerceProvider({ children, ...config }: ShopifyProps) { + return ( + + {children} + + ) +} + +export const useCommerce = () => useCoreCommerce() diff --git a/framework/swell/next.config.js b/framework/swell/next.config.js new file mode 100644 index 000000000..e9d48c02c --- /dev/null +++ b/framework/swell/next.config.js @@ -0,0 +1,8 @@ +const commerce = require('./commerce.config.json') + +module.exports = { + commerce, + images: { + domains: ['cdn.shopify.com'], + }, +} diff --git a/framework/swell/product/get-all-collections.ts b/framework/swell/product/get-all-collections.ts new file mode 100644 index 000000000..15c4bc51a --- /dev/null +++ b/framework/swell/product/get-all-collections.ts @@ -0,0 +1,29 @@ +import { CollectionEdge } from '../schema' +import { getConfig, ShopifyConfig } from '../api' +import getAllCollectionsQuery from '../utils/queries/get-all-collections-query' + +const getAllCollections = async (options?: { + variables?: any + config: ShopifyConfig + preview?: boolean +}) => { + let { config, variables = { first: 250 } } = options ?? {} + config = getConfig(config) + + const { data } = await config.fetch(getAllCollectionsQuery, { variables }) + const edges = data.collections?.edges ?? [] + + const categories = edges.map( + ({ node: { id: entityId, title: name, handle } }: CollectionEdge) => ({ + entityId, + name, + path: `/${handle}`, + }) + ) + + return { + categories, + } +} + +export default getAllCollections diff --git a/framework/swell/product/get-all-product-paths.ts b/framework/swell/product/get-all-product-paths.ts new file mode 100644 index 000000000..4431d1e53 --- /dev/null +++ b/framework/swell/product/get-all-product-paths.ts @@ -0,0 +1,42 @@ +import { Product } from '@commerce/types' +import { getConfig, ShopifyConfig } from '../api' +import fetchAllProducts from '../api/utils/fetch-all-products' +import { ProductEdge } from '../schema' +import getAllProductsPathsQuery from '../utils/queries/get-all-products-paths-query' + +type ProductPath = { + path: string +} + +export type ProductPathNode = { + node: ProductPath +} + +type ReturnType = { + products: ProductPathNode[] +} + +const getAllProductPaths = async (options?: { + variables?: any + config?: ShopifyConfig + preview?: boolean +}): Promise => { + let { config, variables = { first: 250 } } = options ?? {} + config = getConfig(config) + + const products = await fetchAllProducts({ + config, + query: getAllProductsPathsQuery, + variables, + }) + + return { + products: products?.map(({ node: { handle } }: ProductEdge) => ({ + node: { + path: `/${handle}`, + }, + })), + } +} + +export default getAllProductPaths diff --git a/framework/swell/product/get-all-products.ts b/framework/swell/product/get-all-products.ts new file mode 100644 index 000000000..14e486563 --- /dev/null +++ b/framework/swell/product/get-all-products.ts @@ -0,0 +1,40 @@ +import { GraphQLFetcherResult } from '@commerce/api' +import { getConfig, ShopifyConfig } from '../api' +import { ProductEdge } from '../schema' +import { getAllProductsQuery } from '../utils/queries' +import { normalizeProduct } from '../utils/normalize' +import { Product } from '@commerce/types' + +type Variables = { + first?: number + field?: string +} + +type ReturnType = { + products: Product[] +} + +const getAllProducts = async (options: { + variables?: Variables + config?: ShopifyConfig + preview?: boolean +}): Promise => { + let { config, variables = { first: 250 } } = options ?? {} + config = getConfig(config) + + const { data }: GraphQLFetcherResult = await config.fetch( + getAllProductsQuery, + { variables } + ) + + const products = + data.products?.edges?.map(({ node: p }: ProductEdge) => + normalizeProduct(p) + ) ?? [] + + return { + products, + } +} + +export default getAllProducts diff --git a/framework/swell/product/get-product.ts b/framework/swell/product/get-product.ts new file mode 100644 index 000000000..1f00288c7 --- /dev/null +++ b/framework/swell/product/get-product.ts @@ -0,0 +1,32 @@ +import { GraphQLFetcherResult } from '@commerce/api' +import { getConfig, ShopifyConfig } from '../api' +import { normalizeProduct, getProductQuery } from '../utils' + +type Variables = { + slug: string +} + +type ReturnType = { + product: any +} + +const getProduct = async (options: { + variables: Variables + config: ShopifyConfig + preview?: boolean +}): Promise => { + let { config, variables } = options ?? {} + config = getConfig(config) + + const { data }: GraphQLFetcherResult = await config.fetch(getProductQuery, { + variables, + }) + + const { productByHandle: product } = data + + return { + product: product ? normalizeProduct(product) : null, + } +} + +export default getProduct diff --git a/framework/swell/product/use-price.tsx b/framework/swell/product/use-price.tsx new file mode 100644 index 000000000..0174faf5e --- /dev/null +++ b/framework/swell/product/use-price.tsx @@ -0,0 +1,2 @@ +export * from '@commerce/product/use-price' +export { default } from '@commerce/product/use-price' diff --git a/framework/swell/product/use-search.tsx b/framework/swell/product/use-search.tsx new file mode 100644 index 000000000..425df9e83 --- /dev/null +++ b/framework/swell/product/use-search.tsx @@ -0,0 +1,77 @@ +import { SWRHook } from '@commerce/utils/types' +import useSearch, { UseSearch } from '@commerce/product/use-search' + +import { ProductEdge } from '../schema' +import { + getAllProductsQuery, + getCollectionProductsQuery, + getSearchVariables, + normalizeProduct, +} from '../utils' + +import { Product } from '@commerce/types' + +export default useSearch as UseSearch + +export type SearchProductsInput = { + search?: string + categoryId?: string + brandId?: string + sort?: string +} + +export type SearchProductsData = { + products: Product[] + found: boolean +} + +export const handler: SWRHook< + SearchProductsData, + SearchProductsInput, + SearchProductsInput +> = { + fetchOptions: { + query: getAllProductsQuery, + }, + async fetcher({ input, options, fetch }) { + const { categoryId, brandId } = input + + const data = await fetch({ + query: categoryId ? getCollectionProductsQuery : options.query, + method: options?.method, + variables: getSearchVariables(input), + }) + + let edges + + if (categoryId) { + edges = data.node?.products?.edges ?? [] + if (brandId) { + edges = edges.filter( + ({ node: { vendor } }: ProductEdge) => vendor === brandId + ) + } + } else { + edges = data.products?.edges ?? [] + } + + return { + products: edges.map(({ node }: ProductEdge) => normalizeProduct(node)), + found: !!edges.length, + } + }, + useHook: ({ useData }) => (input = {}) => { + return useData({ + input: [ + ['search', input.search], + ['categoryId', input.categoryId], + ['brandId', input.brandId], + ['sort', input.sort], + ], + swrOptions: { + revalidateOnFocus: false, + ...input.swrOptions, + }, + }) + }, +} diff --git a/framework/swell/provider.ts b/framework/swell/provider.ts new file mode 100644 index 000000000..383822baa --- /dev/null +++ b/framework/swell/provider.ts @@ -0,0 +1,31 @@ +import { SHOPIFY_CHECKOUT_ID_COOKIE, STORE_DOMAIN } from './const' + +import { handler as useCart } from './cart/use-cart' +import { handler as useAddItem } from './cart/use-add-item' +import { handler as useUpdateItem } from './cart/use-update-item' +import { handler as useRemoveItem } from './cart/use-remove-item' + +import { handler as useCustomer } from './customer/use-customer' +import { handler as useSearch } from './product/use-search' + +import { handler as useLogin } from './auth/use-login' +import { handler as useLogout } from './auth/use-logout' +import { handler as useSignup } from './auth/use-signup' + +import fetcher from './fetcher' + +export const shopifyProvider = { + locale: 'en-us', + cartCookie: SHOPIFY_CHECKOUT_ID_COOKIE, + storeDomain: STORE_DOMAIN, + fetcher, + cart: { useCart, useAddItem, useUpdateItem, useRemoveItem }, + customer: { useCustomer }, + products: { useSearch }, + auth: { useLogin, useLogout, useSignup }, + features: { + wishlist: false, + }, +} + +export type ShopifyProvider = typeof shopifyProvider diff --git a/framework/swell/schema.d.ts b/framework/swell/schema.d.ts new file mode 100644 index 000000000..b1b23a3e5 --- /dev/null +++ b/framework/swell/schema.d.ts @@ -0,0 +1,4985 @@ +export type Maybe = T | null +export type Exact = { + [K in keyof T]: T[K] +} +export type MakeOptional = Omit & + { [SubKey in K]?: Maybe } +export type MakeMaybe = Omit & + { [SubKey in K]: Maybe } +/** All built-in and custom scalars, mapped to their actual values */ +export type Scalars = { + ID: string + String: string + Boolean: boolean + Int: number + Float: number + /** An ISO-8601 encoded UTC date time string. Example value: `"2019-07-03T20:47:55Z"`. */ + DateTime: any + /** A signed decimal number, which supports arbitrary precision and is serialized as a string. Example value: `"29.99"`. */ + Decimal: any + /** A string containing HTML code. Example value: `"

      Grey cotton knit sweater.

      "`. */ + HTML: any + /** A monetary value string. Example value: `"100.57"`. */ + Money: any + /** + * An RFC 3986 and RFC 3987 compliant URI string. + * + * Example value: `"https://johns-apparel.myshopify.com"`. + * + */ + URL: any +} + +/** A version of the API. */ +export type ApiVersion = { + __typename?: 'ApiVersion' + /** The human-readable name of the version. */ + displayName: Scalars['String'] + /** The unique identifier of an ApiVersion. All supported API versions have a date-based (YYYY-MM) or `unstable` handle. */ + handle: Scalars['String'] + /** Whether the version is supported by Shopify. */ + supported: Scalars['Boolean'] +} + +/** Details about the gift card used on the checkout. */ +export type AppliedGiftCard = Node & { + __typename?: 'AppliedGiftCard' + /** + * The amount that was taken from the gift card by applying it. + * @deprecated Use `amountUsedV2` instead + */ + amountUsed: Scalars['Money'] + /** The amount that was taken from the gift card by applying it. */ + amountUsedV2: MoneyV2 + /** + * The amount left on the gift card. + * @deprecated Use `balanceV2` instead + */ + balance: Scalars['Money'] + /** The amount left on the gift card. */ + balanceV2: MoneyV2 + /** Globally unique identifier. */ + id: Scalars['ID'] + /** The last characters of the gift card. */ + lastCharacters: Scalars['String'] + /** The amount that was applied to the checkout in its currency. */ + presentmentAmountUsed: MoneyV2 +} + +/** An article in an online store blog. */ +export type Article = Node & { + __typename?: 'Article' + /** + * The article's author. + * @deprecated Use `authorV2` instead + */ + author: ArticleAuthor + /** The article's author. */ + authorV2?: Maybe + /** The blog that the article belongs to. */ + blog: Blog + /** List of comments posted on the article. */ + comments: CommentConnection + /** Stripped content of the article, single line with HTML tags removed. */ + content: Scalars['String'] + /** The content of the article, complete with HTML formatting. */ + contentHtml: Scalars['HTML'] + /** Stripped excerpt of the article, single line with HTML tags removed. */ + excerpt?: Maybe + /** The excerpt of the article, complete with HTML formatting. */ + excerptHtml?: Maybe + /** A human-friendly unique string for the Article automatically generated from its title. */ + handle: Scalars['String'] + /** Globally unique identifier. */ + id: Scalars['ID'] + /** The image associated with the article. */ + image?: Maybe + /** The date and time when the article was published. */ + publishedAt: Scalars['DateTime'] + /** The article’s SEO information. */ + seo?: Maybe + /** A categorization that a article can be tagged with. */ + tags: Array + /** The article’s name. */ + title: Scalars['String'] + /** The url pointing to the article accessible from the web. */ + url: Scalars['URL'] +} + +/** An article in an online store blog. */ +export type ArticleCommentsArgs = { + first?: Maybe + after?: Maybe + last?: Maybe + before?: Maybe + reverse?: Maybe +} + +/** An article in an online store blog. */ +export type ArticleContentArgs = { + truncateAt?: Maybe +} + +/** An article in an online store blog. */ +export type ArticleExcerptArgs = { + truncateAt?: Maybe +} + +/** An article in an online store blog. */ +export type ArticleImageArgs = { + maxWidth?: Maybe + maxHeight?: Maybe + crop?: Maybe + scale?: Maybe +} + +/** The author of an article. */ +export type ArticleAuthor = { + __typename?: 'ArticleAuthor' + /** The author's bio. */ + bio?: Maybe + /** The author’s email. */ + email: Scalars['String'] + /** The author's first name. */ + firstName: Scalars['String'] + /** The author's last name. */ + lastName: Scalars['String'] + /** The author's full name. */ + name: Scalars['String'] +} + +/** An auto-generated type for paginating through multiple Articles. */ +export type ArticleConnection = { + __typename?: 'ArticleConnection' + /** A list of edges. */ + edges: Array + /** Information to aid in pagination. */ + pageInfo: PageInfo +} + +/** An auto-generated type which holds one Article and a cursor during pagination. */ +export type ArticleEdge = { + __typename?: 'ArticleEdge' + /** A cursor for use in pagination. */ + cursor: Scalars['String'] + /** The item at the end of ArticleEdge. */ + node: Article +} + +/** The set of valid sort keys for the Article query. */ +export enum ArticleSortKeys { + /** Sort by the `title` value. */ + Title = 'TITLE', + /** Sort by the `blog_title` value. */ + BlogTitle = 'BLOG_TITLE', + /** Sort by the `author` value. */ + Author = 'AUTHOR', + /** Sort by the `updated_at` value. */ + UpdatedAt = 'UPDATED_AT', + /** Sort by the `published_at` value. */ + PublishedAt = 'PUBLISHED_AT', + /** Sort by the `id` value. */ + Id = 'ID', + /** + * During a search (i.e. when the `query` parameter has been specified on the connection) this sorts the + * results by relevance to the search term(s). When no search query is specified, this sort key is not + * deterministic and should not be used. + */ + Relevance = 'RELEVANCE', +} + +/** Represents a generic custom attribute. */ +export type Attribute = { + __typename?: 'Attribute' + /** Key or name of the attribute. */ + key: Scalars['String'] + /** Value of the attribute. */ + value?: Maybe +} + +/** Specifies the input fields required for an attribute. */ +export type AttributeInput = { + /** Key or name of the attribute. */ + key: Scalars['String'] + /** Value of the attribute. */ + value: Scalars['String'] +} + +/** Automatic discount applications capture the intentions of a discount that was automatically applied. */ +export type AutomaticDiscountApplication = DiscountApplication & { + __typename?: 'AutomaticDiscountApplication' + /** The method by which the discount's value is allocated to its entitled items. */ + allocationMethod: DiscountApplicationAllocationMethod + /** Which lines of targetType that the discount is allocated over. */ + targetSelection: DiscountApplicationTargetSelection + /** The type of line that the discount is applicable towards. */ + targetType: DiscountApplicationTargetType + /** The title of the application. */ + title: Scalars['String'] + /** The value of the discount application. */ + value: PricingValue +} + +/** A collection of available shipping rates for a checkout. */ +export type AvailableShippingRates = { + __typename?: 'AvailableShippingRates' + /** + * Whether or not the shipping rates are ready. + * The `shippingRates` field is `null` when this value is `false`. + * This field should be polled until its value becomes `true`. + */ + ready: Scalars['Boolean'] + /** The fetched shipping rates. `null` until the `ready` field is `true`. */ + shippingRates?: Maybe> +} + +/** An online store blog. */ +export type Blog = Node & { + __typename?: 'Blog' + /** Find an article by its handle. */ + articleByHandle?: Maybe
      + /** List of the blog's articles. */ + articles: ArticleConnection + /** The authors who have contributed to the blog. */ + authors: Array + /** A human-friendly unique string for the Blog automatically generated from its title. */ + handle: Scalars['String'] + /** Globally unique identifier. */ + id: Scalars['ID'] + /** The blog's SEO information. */ + seo?: Maybe + /** The blogs’s title. */ + title: Scalars['String'] + /** The url pointing to the blog accessible from the web. */ + url: Scalars['URL'] +} + +/** An online store blog. */ +export type BlogArticleByHandleArgs = { + handle: Scalars['String'] +} + +/** An online store blog. */ +export type BlogArticlesArgs = { + first?: Maybe + after?: Maybe + last?: Maybe + before?: Maybe + reverse?: Maybe + sortKey?: Maybe + query?: Maybe +} + +/** An auto-generated type for paginating through multiple Blogs. */ +export type BlogConnection = { + __typename?: 'BlogConnection' + /** A list of edges. */ + edges: Array + /** Information to aid in pagination. */ + pageInfo: PageInfo +} + +/** An auto-generated type which holds one Blog and a cursor during pagination. */ +export type BlogEdge = { + __typename?: 'BlogEdge' + /** A cursor for use in pagination. */ + cursor: Scalars['String'] + /** The item at the end of BlogEdge. */ + node: Blog +} + +/** The set of valid sort keys for the Blog query. */ +export enum BlogSortKeys { + /** Sort by the `handle` value. */ + Handle = 'HANDLE', + /** Sort by the `title` value. */ + Title = 'TITLE', + /** Sort by the `id` value. */ + Id = 'ID', + /** + * During a search (i.e. when the `query` parameter has been specified on the connection) this sorts the + * results by relevance to the search term(s). When no search query is specified, this sort key is not + * deterministic and should not be used. + */ + Relevance = 'RELEVANCE', +} + +/** Card brand, such as Visa or Mastercard, which can be used for payments. */ +export enum CardBrand { + /** Visa */ + Visa = 'VISA', + /** Mastercard */ + Mastercard = 'MASTERCARD', + /** Discover */ + Discover = 'DISCOVER', + /** American Express */ + AmericanExpress = 'AMERICAN_EXPRESS', + /** Diners Club */ + DinersClub = 'DINERS_CLUB', + /** JCB */ + Jcb = 'JCB', +} + +/** A container for all the information required to checkout items and pay. */ +export type Checkout = Node & { + __typename?: 'Checkout' + /** The gift cards used on the checkout. */ + appliedGiftCards: Array + /** + * The available shipping rates for this Checkout. + * Should only be used when checkout `requiresShipping` is `true` and + * the shipping address is valid. + */ + availableShippingRates?: Maybe + /** The date and time when the checkout was completed. */ + completedAt?: Maybe + /** The date and time when the checkout was created. */ + createdAt: Scalars['DateTime'] + /** The currency code for the Checkout. */ + currencyCode: CurrencyCode + /** A list of extra information that is added to the checkout. */ + customAttributes: Array + /** + * The customer associated with the checkout. + * @deprecated This field will always return null. If you have an authentication token for the customer, you can use the `customer` field on the query root to retrieve it. + */ + customer?: Maybe + /** Discounts that have been applied on the checkout. */ + discountApplications: DiscountApplicationConnection + /** The email attached to this checkout. */ + email?: Maybe + /** Globally unique identifier. */ + id: Scalars['ID'] + /** A list of line item objects, each one containing information about an item in the checkout. */ + lineItems: CheckoutLineItemConnection + /** The sum of all the prices of all the items in the checkout. Duties, taxes, shipping and discounts excluded. */ + lineItemsSubtotalPrice: MoneyV2 + /** The note associated with the checkout. */ + note?: Maybe + /** The resulting order from a paid checkout. */ + order?: Maybe + /** The Order Status Page for this Checkout, null when checkout is not completed. */ + orderStatusUrl?: Maybe + /** + * The amount left to be paid. This is equal to the cost of the line items, taxes and shipping minus discounts and gift cards. + * @deprecated Use `paymentDueV2` instead + */ + paymentDue: Scalars['Money'] + /** The amount left to be paid. This is equal to the cost of the line items, duties, taxes and shipping minus discounts and gift cards. */ + paymentDueV2: MoneyV2 + /** + * Whether or not the Checkout is ready and can be completed. Checkouts may + * have asynchronous operations that can take time to finish. If you want + * to complete a checkout or ensure all the fields are populated and up to + * date, polling is required until the value is true. + */ + ready: Scalars['Boolean'] + /** States whether or not the fulfillment requires shipping. */ + requiresShipping: Scalars['Boolean'] + /** The shipping address to where the line items will be shipped. */ + shippingAddress?: Maybe + /** The discounts that have been allocated onto the shipping line by discount applications. */ + shippingDiscountAllocations: Array + /** Once a shipping rate is selected by the customer it is transitioned to a `shipping_line` object. */ + shippingLine?: Maybe + /** + * Price of the checkout before shipping and taxes. + * @deprecated Use `subtotalPriceV2` instead + */ + subtotalPrice: Scalars['Money'] + /** Price of the checkout before duties, shipping and taxes. */ + subtotalPriceV2: MoneyV2 + /** Specifies if the Checkout is tax exempt. */ + taxExempt: Scalars['Boolean'] + /** Specifies if taxes are included in the line item and shipping line prices. */ + taxesIncluded: Scalars['Boolean'] + /** + * The sum of all the prices of all the items in the checkout, taxes and discounts included. + * @deprecated Use `totalPriceV2` instead + */ + totalPrice: Scalars['Money'] + /** The sum of all the prices of all the items in the checkout, duties, taxes and discounts included. */ + totalPriceV2: MoneyV2 + /** + * The sum of all the taxes applied to the line items and shipping lines in the checkout. + * @deprecated Use `totalTaxV2` instead + */ + totalTax: Scalars['Money'] + /** The sum of all the taxes applied to the line items and shipping lines in the checkout. */ + totalTaxV2: MoneyV2 + /** The date and time when the checkout was last updated. */ + updatedAt: Scalars['DateTime'] + /** The url pointing to the checkout accessible from the web. */ + webUrl: Scalars['URL'] +} + +/** A container for all the information required to checkout items and pay. */ +export type CheckoutDiscountApplicationsArgs = { + first?: Maybe + after?: Maybe + last?: Maybe + before?: Maybe + reverse?: Maybe +} + +/** A container for all the information required to checkout items and pay. */ +export type CheckoutLineItemsArgs = { + first?: Maybe + after?: Maybe + last?: Maybe + before?: Maybe + reverse?: Maybe +} + +/** Specifies the fields required to update a checkout's attributes. */ +export type CheckoutAttributesUpdateInput = { + /** The text of an optional note that a shop owner can attach to the checkout. */ + note?: Maybe + /** A list of extra information that is added to the checkout. */ + customAttributes?: Maybe> + /** + * Allows setting partial addresses on a Checkout, skipping the full validation of attributes. + * The required attributes are city, province, and country. + * Full validation of the addresses is still done at complete time. + */ + allowPartialAddresses?: Maybe +} + +/** Return type for `checkoutAttributesUpdate` mutation. */ +export type CheckoutAttributesUpdatePayload = { + __typename?: 'CheckoutAttributesUpdatePayload' + /** The updated checkout object. */ + checkout: Checkout + /** List of errors that occurred executing the mutation. */ + checkoutUserErrors: Array + /** + * List of errors that occurred executing the mutation. + * @deprecated Use `checkoutUserErrors` instead + */ + userErrors: Array +} + +/** Specifies the fields required to update a checkout's attributes. */ +export type CheckoutAttributesUpdateV2Input = { + /** The text of an optional note that a shop owner can attach to the checkout. */ + note?: Maybe + /** A list of extra information that is added to the checkout. */ + customAttributes?: Maybe> + /** + * Allows setting partial addresses on a Checkout, skipping the full validation of attributes. + * The required attributes are city, province, and country. + * Full validation of the addresses is still done at complete time. + */ + allowPartialAddresses?: Maybe +} + +/** Return type for `checkoutAttributesUpdateV2` mutation. */ +export type CheckoutAttributesUpdateV2Payload = { + __typename?: 'CheckoutAttributesUpdateV2Payload' + /** The updated checkout object. */ + checkout?: Maybe + /** List of errors that occurred executing the mutation. */ + checkoutUserErrors: Array + /** + * List of errors that occurred executing the mutation. + * @deprecated Use `checkoutUserErrors` instead + */ + userErrors: Array +} + +/** Return type for `checkoutCompleteFree` mutation. */ +export type CheckoutCompleteFreePayload = { + __typename?: 'CheckoutCompleteFreePayload' + /** The updated checkout object. */ + checkout?: Maybe + /** List of errors that occurred executing the mutation. */ + checkoutUserErrors: Array + /** + * List of errors that occurred executing the mutation. + * @deprecated Use `checkoutUserErrors` instead + */ + userErrors: Array +} + +/** Return type for `checkoutCompleteWithCreditCard` mutation. */ +export type CheckoutCompleteWithCreditCardPayload = { + __typename?: 'CheckoutCompleteWithCreditCardPayload' + /** The checkout on which the payment was applied. */ + checkout: Checkout + /** List of errors that occurred executing the mutation. */ + checkoutUserErrors: Array + /** A representation of the attempted payment. */ + payment?: Maybe + /** + * List of errors that occurred executing the mutation. + * @deprecated Use `checkoutUserErrors` instead + */ + userErrors: Array +} + +/** Return type for `checkoutCompleteWithCreditCardV2` mutation. */ +export type CheckoutCompleteWithCreditCardV2Payload = { + __typename?: 'CheckoutCompleteWithCreditCardV2Payload' + /** The checkout on which the payment was applied. */ + checkout?: Maybe + /** List of errors that occurred executing the mutation. */ + checkoutUserErrors: Array + /** A representation of the attempted payment. */ + payment?: Maybe + /** + * List of errors that occurred executing the mutation. + * @deprecated Use `checkoutUserErrors` instead + */ + userErrors: Array +} + +/** Return type for `checkoutCompleteWithTokenizedPayment` mutation. */ +export type CheckoutCompleteWithTokenizedPaymentPayload = { + __typename?: 'CheckoutCompleteWithTokenizedPaymentPayload' + /** The checkout on which the payment was applied. */ + checkout: Checkout + /** List of errors that occurred executing the mutation. */ + checkoutUserErrors: Array + /** A representation of the attempted payment. */ + payment?: Maybe + /** + * List of errors that occurred executing the mutation. + * @deprecated Use `checkoutUserErrors` instead + */ + userErrors: Array +} + +/** Return type for `checkoutCompleteWithTokenizedPaymentV2` mutation. */ +export type CheckoutCompleteWithTokenizedPaymentV2Payload = { + __typename?: 'CheckoutCompleteWithTokenizedPaymentV2Payload' + /** The checkout on which the payment was applied. */ + checkout?: Maybe + /** List of errors that occurred executing the mutation. */ + checkoutUserErrors: Array + /** A representation of the attempted payment. */ + payment?: Maybe + /** + * List of errors that occurred executing the mutation. + * @deprecated Use `checkoutUserErrors` instead + */ + userErrors: Array +} + +/** Return type for `checkoutCompleteWithTokenizedPaymentV3` mutation. */ +export type CheckoutCompleteWithTokenizedPaymentV3Payload = { + __typename?: 'CheckoutCompleteWithTokenizedPaymentV3Payload' + /** The checkout on which the payment was applied. */ + checkout?: Maybe + /** List of errors that occurred executing the mutation. */ + checkoutUserErrors: Array + /** A representation of the attempted payment. */ + payment?: Maybe + /** + * List of errors that occurred executing the mutation. + * @deprecated Use `checkoutUserErrors` instead + */ + userErrors: Array +} + +/** Specifies the fields required to create a checkout. */ +export type CheckoutCreateInput = { + /** The email with which the customer wants to checkout. */ + email?: Maybe + /** A list of line item objects, each one containing information about an item in the checkout. */ + lineItems?: Maybe> + /** The shipping address to where the line items will be shipped. */ + shippingAddress?: Maybe + /** The text of an optional note that a shop owner can attach to the checkout. */ + note?: Maybe + /** A list of extra information that is added to the checkout. */ + customAttributes?: Maybe> + /** + * Allows setting partial addresses on a Checkout, skipping the full validation of attributes. + * The required attributes are city, province, and country. + * Full validation of addresses is still done at complete time. + */ + allowPartialAddresses?: Maybe + /** + * The three-letter currency code of one of the shop's enabled presentment currencies. + * Including this field creates a checkout in the specified currency. By default, new + * checkouts are created in the shop's primary currency. + */ + presentmentCurrencyCode?: Maybe +} + +/** Return type for `checkoutCreate` mutation. */ +export type CheckoutCreatePayload = { + __typename?: 'CheckoutCreatePayload' + /** The new checkout object. */ + checkout?: Maybe + /** List of errors that occurred executing the mutation. */ + checkoutUserErrors: Array + /** + * List of errors that occurred executing the mutation. + * @deprecated Use `checkoutUserErrors` instead + */ + userErrors: Array +} + +/** Return type for `checkoutCustomerAssociate` mutation. */ +export type CheckoutCustomerAssociatePayload = { + __typename?: 'CheckoutCustomerAssociatePayload' + /** The updated checkout object. */ + checkout: Checkout + /** The associated customer object. */ + customer?: Maybe + /** List of errors that occurred executing the mutation. */ + userErrors: Array +} + +/** Return type for `checkoutCustomerAssociateV2` mutation. */ +export type CheckoutCustomerAssociateV2Payload = { + __typename?: 'CheckoutCustomerAssociateV2Payload' + /** The updated checkout object. */ + checkout?: Maybe + /** List of errors that occurred executing the mutation. */ + checkoutUserErrors: Array + /** The associated customer object. */ + customer?: Maybe + /** + * List of errors that occurred executing the mutation. + * @deprecated Use `checkoutUserErrors` instead + */ + userErrors: Array +} + +/** Return type for `checkoutCustomerDisassociate` mutation. */ +export type CheckoutCustomerDisassociatePayload = { + __typename?: 'CheckoutCustomerDisassociatePayload' + /** The updated checkout object. */ + checkout: Checkout + /** List of errors that occurred executing the mutation. */ + checkoutUserErrors: Array + /** + * List of errors that occurred executing the mutation. + * @deprecated Use `checkoutUserErrors` instead + */ + userErrors: Array +} + +/** Return type for `checkoutCustomerDisassociateV2` mutation. */ +export type CheckoutCustomerDisassociateV2Payload = { + __typename?: 'CheckoutCustomerDisassociateV2Payload' + /** The updated checkout object. */ + checkout?: Maybe + /** List of errors that occurred executing the mutation. */ + checkoutUserErrors: Array + /** + * List of errors that occurred executing the mutation. + * @deprecated Use `checkoutUserErrors` instead + */ + userErrors: Array +} + +/** Return type for `checkoutDiscountCodeApply` mutation. */ +export type CheckoutDiscountCodeApplyPayload = { + __typename?: 'CheckoutDiscountCodeApplyPayload' + /** The updated checkout object. */ + checkout: Checkout + /** List of errors that occurred executing the mutation. */ + checkoutUserErrors: Array + /** + * List of errors that occurred executing the mutation. + * @deprecated Use `checkoutUserErrors` instead + */ + userErrors: Array +} + +/** Return type for `checkoutDiscountCodeApplyV2` mutation. */ +export type CheckoutDiscountCodeApplyV2Payload = { + __typename?: 'CheckoutDiscountCodeApplyV2Payload' + /** The updated checkout object. */ + checkout?: Maybe + /** List of errors that occurred executing the mutation. */ + checkoutUserErrors: Array + /** + * List of errors that occurred executing the mutation. + * @deprecated Use `checkoutUserErrors` instead + */ + userErrors: Array +} + +/** Return type for `checkoutDiscountCodeRemove` mutation. */ +export type CheckoutDiscountCodeRemovePayload = { + __typename?: 'CheckoutDiscountCodeRemovePayload' + /** The updated checkout object. */ + checkout?: Maybe + /** List of errors that occurred executing the mutation. */ + checkoutUserErrors: Array + /** + * List of errors that occurred executing the mutation. + * @deprecated Use `checkoutUserErrors` instead + */ + userErrors: Array +} + +/** Return type for `checkoutEmailUpdate` mutation. */ +export type CheckoutEmailUpdatePayload = { + __typename?: 'CheckoutEmailUpdatePayload' + /** The checkout object with the updated email. */ + checkout: Checkout + /** List of errors that occurred executing the mutation. */ + checkoutUserErrors: Array + /** + * List of errors that occurred executing the mutation. + * @deprecated Use `checkoutUserErrors` instead + */ + userErrors: Array +} + +/** Return type for `checkoutEmailUpdateV2` mutation. */ +export type CheckoutEmailUpdateV2Payload = { + __typename?: 'CheckoutEmailUpdateV2Payload' + /** The checkout object with the updated email. */ + checkout?: Maybe + /** List of errors that occurred executing the mutation. */ + checkoutUserErrors: Array + /** + * List of errors that occurred executing the mutation. + * @deprecated Use `checkoutUserErrors` instead + */ + userErrors: Array +} + +/** Possible error codes that could be returned by CheckoutUserError. */ +export enum CheckoutErrorCode { + /** Input value is blank. */ + Blank = 'BLANK', + /** Input value is invalid. */ + Invalid = 'INVALID', + /** Input value is too long. */ + TooLong = 'TOO_LONG', + /** Input value is not present. */ + Present = 'PRESENT', + /** Input value should be less than maximum allowed value. */ + LessThan = 'LESS_THAN', + /** Input value should be greater than or equal to minimum allowed value. */ + GreaterThanOrEqualTo = 'GREATER_THAN_OR_EQUAL_TO', + /** Input value should be less or equal to maximum allowed value. */ + LessThanOrEqualTo = 'LESS_THAN_OR_EQUAL_TO', + /** Checkout is already completed. */ + AlreadyCompleted = 'ALREADY_COMPLETED', + /** Checkout is locked. */ + Locked = 'LOCKED', + /** Input value is not supported. */ + NotSupported = 'NOT_SUPPORTED', + /** Input email contains an invalid domain name. */ + BadDomain = 'BAD_DOMAIN', + /** Input Zip is invalid for country provided. */ + InvalidForCountry = 'INVALID_FOR_COUNTRY', + /** Input Zip is invalid for country and province provided. */ + InvalidForCountryAndProvince = 'INVALID_FOR_COUNTRY_AND_PROVINCE', + /** Invalid state in country. */ + InvalidStateInCountry = 'INVALID_STATE_IN_COUNTRY', + /** Invalid province in country. */ + InvalidProvinceInCountry = 'INVALID_PROVINCE_IN_COUNTRY', + /** Invalid region in country. */ + InvalidRegionInCountry = 'INVALID_REGION_IN_COUNTRY', + /** Shipping rate expired. */ + ShippingRateExpired = 'SHIPPING_RATE_EXPIRED', + /** Gift card cannot be applied to a checkout that contains a gift card. */ + GiftCardUnusable = 'GIFT_CARD_UNUSABLE', + /** Gift card is disabled. */ + GiftCardDisabled = 'GIFT_CARD_DISABLED', + /** Gift card code is invalid. */ + GiftCardCodeInvalid = 'GIFT_CARD_CODE_INVALID', + /** Gift card has already been applied. */ + GiftCardAlreadyApplied = 'GIFT_CARD_ALREADY_APPLIED', + /** Gift card currency does not match checkout currency. */ + GiftCardCurrencyMismatch = 'GIFT_CARD_CURRENCY_MISMATCH', + /** Gift card is expired. */ + GiftCardExpired = 'GIFT_CARD_EXPIRED', + /** Gift card has no funds left. */ + GiftCardDepleted = 'GIFT_CARD_DEPLETED', + /** Gift card was not found. */ + GiftCardNotFound = 'GIFT_CARD_NOT_FOUND', + /** Cart does not meet discount requirements notice. */ + CartDoesNotMeetDiscountRequirementsNotice = 'CART_DOES_NOT_MEET_DISCOUNT_REQUIREMENTS_NOTICE', + /** Discount expired. */ + DiscountExpired = 'DISCOUNT_EXPIRED', + /** Discount disabled. */ + DiscountDisabled = 'DISCOUNT_DISABLED', + /** Discount limit reached. */ + DiscountLimitReached = 'DISCOUNT_LIMIT_REACHED', + /** Discount not found. */ + DiscountNotFound = 'DISCOUNT_NOT_FOUND', + /** Customer already used once per customer discount notice. */ + CustomerAlreadyUsedOncePerCustomerDiscountNotice = 'CUSTOMER_ALREADY_USED_ONCE_PER_CUSTOMER_DISCOUNT_NOTICE', + /** Checkout is already completed. */ + Empty = 'EMPTY', + /** Not enough in stock. */ + NotEnoughInStock = 'NOT_ENOUGH_IN_STOCK', + /** Missing payment input. */ + MissingPaymentInput = 'MISSING_PAYMENT_INPUT', + /** The amount of the payment does not match the value to be paid. */ + TotalPriceMismatch = 'TOTAL_PRICE_MISMATCH', + /** Line item was not found in checkout. */ + LineItemNotFound = 'LINE_ITEM_NOT_FOUND', + /** Unable to apply discount. */ + UnableToApply = 'UNABLE_TO_APPLY', + /** Discount already applied. */ + DiscountAlreadyApplied = 'DISCOUNT_ALREADY_APPLIED', +} + +/** Return type for `checkoutGiftCardApply` mutation. */ +export type CheckoutGiftCardApplyPayload = { + __typename?: 'CheckoutGiftCardApplyPayload' + /** The updated checkout object. */ + checkout: Checkout + /** List of errors that occurred executing the mutation. */ + checkoutUserErrors: Array + /** + * List of errors that occurred executing the mutation. + * @deprecated Use `checkoutUserErrors` instead + */ + userErrors: Array +} + +/** Return type for `checkoutGiftCardRemove` mutation. */ +export type CheckoutGiftCardRemovePayload = { + __typename?: 'CheckoutGiftCardRemovePayload' + /** The updated checkout object. */ + checkout: Checkout + /** List of errors that occurred executing the mutation. */ + checkoutUserErrors: Array + /** + * List of errors that occurred executing the mutation. + * @deprecated Use `checkoutUserErrors` instead + */ + userErrors: Array +} + +/** Return type for `checkoutGiftCardRemoveV2` mutation. */ +export type CheckoutGiftCardRemoveV2Payload = { + __typename?: 'CheckoutGiftCardRemoveV2Payload' + /** The updated checkout object. */ + checkout?: Maybe + /** List of errors that occurred executing the mutation. */ + checkoutUserErrors: Array + /** + * List of errors that occurred executing the mutation. + * @deprecated Use `checkoutUserErrors` instead + */ + userErrors: Array +} + +/** Return type for `checkoutGiftCardsAppend` mutation. */ +export type CheckoutGiftCardsAppendPayload = { + __typename?: 'CheckoutGiftCardsAppendPayload' + /** The updated checkout object. */ + checkout?: Maybe + /** List of errors that occurred executing the mutation. */ + checkoutUserErrors: Array + /** + * List of errors that occurred executing the mutation. + * @deprecated Use `checkoutUserErrors` instead + */ + userErrors: Array +} + +/** A single line item in the checkout, grouped by variant and attributes. */ +export type CheckoutLineItem = Node & { + __typename?: 'CheckoutLineItem' + /** Extra information in the form of an array of Key-Value pairs about the line item. */ + customAttributes: Array + /** The discounts that have been allocated onto the checkout line item by discount applications. */ + discountAllocations: Array + /** Globally unique identifier. */ + id: Scalars['ID'] + /** The quantity of the line item. */ + quantity: Scalars['Int'] + /** Title of the line item. Defaults to the product's title. */ + title: Scalars['String'] + /** Unit price of the line item. */ + unitPrice?: Maybe + /** Product variant of the line item. */ + variant?: Maybe +} + +/** An auto-generated type for paginating through multiple CheckoutLineItems. */ +export type CheckoutLineItemConnection = { + __typename?: 'CheckoutLineItemConnection' + /** A list of edges. */ + edges: Array + /** Information to aid in pagination. */ + pageInfo: PageInfo +} + +/** An auto-generated type which holds one CheckoutLineItem and a cursor during pagination. */ +export type CheckoutLineItemEdge = { + __typename?: 'CheckoutLineItemEdge' + /** A cursor for use in pagination. */ + cursor: Scalars['String'] + /** The item at the end of CheckoutLineItemEdge. */ + node: CheckoutLineItem +} + +/** Specifies the input fields to create a line item on a checkout. */ +export type CheckoutLineItemInput = { + /** Extra information in the form of an array of Key-Value pairs about the line item. */ + customAttributes?: Maybe> + /** The quantity of the line item. */ + quantity: Scalars['Int'] + /** The identifier of the product variant for the line item. */ + variantId: Scalars['ID'] +} + +/** Specifies the input fields to update a line item on the checkout. */ +export type CheckoutLineItemUpdateInput = { + /** The identifier of the line item. */ + id?: Maybe + /** The variant identifier of the line item. */ + variantId?: Maybe + /** The quantity of the line item. */ + quantity?: Maybe + /** Extra information in the form of an array of Key-Value pairs about the line item. */ + customAttributes?: Maybe> +} + +/** Return type for `checkoutLineItemsAdd` mutation. */ +export type CheckoutLineItemsAddPayload = { + __typename?: 'CheckoutLineItemsAddPayload' + /** The updated checkout object. */ + checkout?: Maybe + /** List of errors that occurred executing the mutation. */ + checkoutUserErrors: Array + /** + * List of errors that occurred executing the mutation. + * @deprecated Use `checkoutUserErrors` instead + */ + userErrors: Array +} + +/** Return type for `checkoutLineItemsRemove` mutation. */ +export type CheckoutLineItemsRemovePayload = { + __typename?: 'CheckoutLineItemsRemovePayload' + /** The updated checkout object. */ + checkout?: Maybe + /** List of errors that occurred executing the mutation. */ + checkoutUserErrors: Array + /** + * List of errors that occurred executing the mutation. + * @deprecated Use `checkoutUserErrors` instead + */ + userErrors: Array +} + +/** Return type for `checkoutLineItemsReplace` mutation. */ +export type CheckoutLineItemsReplacePayload = { + __typename?: 'CheckoutLineItemsReplacePayload' + /** The updated checkout object. */ + checkout?: Maybe + /** List of errors that occurred executing the mutation. */ + userErrors: Array +} + +/** Return type for `checkoutLineItemsUpdate` mutation. */ +export type CheckoutLineItemsUpdatePayload = { + __typename?: 'CheckoutLineItemsUpdatePayload' + /** The updated checkout object. */ + checkout?: Maybe + /** List of errors that occurred executing the mutation. */ + checkoutUserErrors: Array + /** + * List of errors that occurred executing the mutation. + * @deprecated Use `checkoutUserErrors` instead + */ + userErrors: Array +} + +/** Return type for `checkoutShippingAddressUpdate` mutation. */ +export type CheckoutShippingAddressUpdatePayload = { + __typename?: 'CheckoutShippingAddressUpdatePayload' + /** The updated checkout object. */ + checkout: Checkout + /** List of errors that occurred executing the mutation. */ + checkoutUserErrors: Array + /** + * List of errors that occurred executing the mutation. + * @deprecated Use `checkoutUserErrors` instead + */ + userErrors: Array +} + +/** Return type for `checkoutShippingAddressUpdateV2` mutation. */ +export type CheckoutShippingAddressUpdateV2Payload = { + __typename?: 'CheckoutShippingAddressUpdateV2Payload' + /** The updated checkout object. */ + checkout?: Maybe + /** List of errors that occurred executing the mutation. */ + checkoutUserErrors: Array + /** + * List of errors that occurred executing the mutation. + * @deprecated Use `checkoutUserErrors` instead + */ + userErrors: Array +} + +/** Return type for `checkoutShippingLineUpdate` mutation. */ +export type CheckoutShippingLineUpdatePayload = { + __typename?: 'CheckoutShippingLineUpdatePayload' + /** The updated checkout object. */ + checkout?: Maybe + /** List of errors that occurred executing the mutation. */ + checkoutUserErrors: Array + /** + * List of errors that occurred executing the mutation. + * @deprecated Use `checkoutUserErrors` instead + */ + userErrors: Array +} + +/** Represents an error that happens during execution of a checkout mutation. */ +export type CheckoutUserError = DisplayableError & { + __typename?: 'CheckoutUserError' + /** Error code to uniquely identify the error. */ + code?: Maybe + /** Path to the input field which caused the error. */ + field?: Maybe> + /** The error message. */ + message: Scalars['String'] +} + +/** A collection represents a grouping of products that a shop owner can create to organize them or make their shops easier to browse. */ +export type Collection = Node & { + __typename?: 'Collection' + /** Stripped description of the collection, single line with HTML tags removed. */ + description: Scalars['String'] + /** The description of the collection, complete with HTML formatting. */ + descriptionHtml: Scalars['HTML'] + /** + * A human-friendly unique string for the collection automatically generated from its title. + * Limit of 255 characters. + */ + handle: Scalars['String'] + /** Globally unique identifier. */ + id: Scalars['ID'] + /** Image associated with the collection. */ + image?: Maybe + /** List of products in the collection. */ + products: ProductConnection + /** The collection’s name. Limit of 255 characters. */ + title: Scalars['String'] + /** The date and time when the collection was last modified. */ + updatedAt: Scalars['DateTime'] +} + +/** A collection represents a grouping of products that a shop owner can create to organize them or make their shops easier to browse. */ +export type CollectionDescriptionArgs = { + truncateAt?: Maybe +} + +/** A collection represents a grouping of products that a shop owner can create to organize them or make their shops easier to browse. */ +export type CollectionImageArgs = { + maxWidth?: Maybe + maxHeight?: Maybe + crop?: Maybe + scale?: Maybe +} + +/** A collection represents a grouping of products that a shop owner can create to organize them or make their shops easier to browse. */ +export type CollectionProductsArgs = { + first?: Maybe + after?: Maybe + last?: Maybe + before?: Maybe + reverse?: Maybe + sortKey?: Maybe +} + +/** An auto-generated type for paginating through multiple Collections. */ +export type CollectionConnection = { + __typename?: 'CollectionConnection' + /** A list of edges. */ + edges: Array + /** Information to aid in pagination. */ + pageInfo: PageInfo +} + +/** An auto-generated type which holds one Collection and a cursor during pagination. */ +export type CollectionEdge = { + __typename?: 'CollectionEdge' + /** A cursor for use in pagination. */ + cursor: Scalars['String'] + /** The item at the end of CollectionEdge. */ + node: Collection +} + +/** The set of valid sort keys for the Collection query. */ +export enum CollectionSortKeys { + /** Sort by the `title` value. */ + Title = 'TITLE', + /** Sort by the `updated_at` value. */ + UpdatedAt = 'UPDATED_AT', + /** Sort by the `id` value. */ + Id = 'ID', + /** + * During a search (i.e. when the `query` parameter has been specified on the connection) this sorts the + * results by relevance to the search term(s). When no search query is specified, this sort key is not + * deterministic and should not be used. + */ + Relevance = 'RELEVANCE', +} + +/** A comment on an article. */ +export type Comment = Node & { + __typename?: 'Comment' + /** The comment’s author. */ + author: CommentAuthor + /** Stripped content of the comment, single line with HTML tags removed. */ + content: Scalars['String'] + /** The content of the comment, complete with HTML formatting. */ + contentHtml: Scalars['HTML'] + /** Globally unique identifier. */ + id: Scalars['ID'] +} + +/** A comment on an article. */ +export type CommentContentArgs = { + truncateAt?: Maybe +} + +/** The author of a comment. */ +export type CommentAuthor = { + __typename?: 'CommentAuthor' + /** The author's email. */ + email: Scalars['String'] + /** The author’s name. */ + name: Scalars['String'] +} + +/** An auto-generated type for paginating through multiple Comments. */ +export type CommentConnection = { + __typename?: 'CommentConnection' + /** A list of edges. */ + edges: Array + /** Information to aid in pagination. */ + pageInfo: PageInfo +} + +/** An auto-generated type which holds one Comment and a cursor during pagination. */ +export type CommentEdge = { + __typename?: 'CommentEdge' + /** A cursor for use in pagination. */ + cursor: Scalars['String'] + /** The item at the end of CommentEdge. */ + node: Comment +} + +/** ISO 3166-1 alpha-2 country codes with some differences. */ +export enum CountryCode { + /** Afghanistan. */ + Af = 'AF', + /** Åland Islands. */ + Ax = 'AX', + /** Albania. */ + Al = 'AL', + /** Algeria. */ + Dz = 'DZ', + /** Andorra. */ + Ad = 'AD', + /** Angola. */ + Ao = 'AO', + /** Anguilla. */ + Ai = 'AI', + /** Antigua & Barbuda. */ + Ag = 'AG', + /** Argentina. */ + Ar = 'AR', + /** Armenia. */ + Am = 'AM', + /** Aruba. */ + Aw = 'AW', + /** Australia. */ + Au = 'AU', + /** Austria. */ + At = 'AT', + /** Azerbaijan. */ + Az = 'AZ', + /** Bahamas. */ + Bs = 'BS', + /** Bahrain. */ + Bh = 'BH', + /** Bangladesh. */ + Bd = 'BD', + /** Barbados. */ + Bb = 'BB', + /** Belarus. */ + By = 'BY', + /** Belgium. */ + Be = 'BE', + /** Belize. */ + Bz = 'BZ', + /** Benin. */ + Bj = 'BJ', + /** Bermuda. */ + Bm = 'BM', + /** Bhutan. */ + Bt = 'BT', + /** Bolivia. */ + Bo = 'BO', + /** Bosnia & Herzegovina. */ + Ba = 'BA', + /** Botswana. */ + Bw = 'BW', + /** Bouvet Island. */ + Bv = 'BV', + /** Brazil. */ + Br = 'BR', + /** British Indian Ocean Territory. */ + Io = 'IO', + /** Brunei. */ + Bn = 'BN', + /** Bulgaria. */ + Bg = 'BG', + /** Burkina Faso. */ + Bf = 'BF', + /** Burundi. */ + Bi = 'BI', + /** Cambodia. */ + Kh = 'KH', + /** Canada. */ + Ca = 'CA', + /** Cape Verde. */ + Cv = 'CV', + /** Caribbean Netherlands. */ + Bq = 'BQ', + /** Cayman Islands. */ + Ky = 'KY', + /** Central African Republic. */ + Cf = 'CF', + /** Chad. */ + Td = 'TD', + /** Chile. */ + Cl = 'CL', + /** China. */ + Cn = 'CN', + /** Christmas Island. */ + Cx = 'CX', + /** Cocos (Keeling) Islands. */ + Cc = 'CC', + /** Colombia. */ + Co = 'CO', + /** Comoros. */ + Km = 'KM', + /** Congo - Brazzaville. */ + Cg = 'CG', + /** Congo - Kinshasa. */ + Cd = 'CD', + /** Cook Islands. */ + Ck = 'CK', + /** Costa Rica. */ + Cr = 'CR', + /** Croatia. */ + Hr = 'HR', + /** Cuba. */ + Cu = 'CU', + /** Curaçao. */ + Cw = 'CW', + /** Cyprus. */ + Cy = 'CY', + /** Czechia. */ + Cz = 'CZ', + /** Côte d’Ivoire. */ + Ci = 'CI', + /** Denmark. */ + Dk = 'DK', + /** Djibouti. */ + Dj = 'DJ', + /** Dominica. */ + Dm = 'DM', + /** Dominican Republic. */ + Do = 'DO', + /** Ecuador. */ + Ec = 'EC', + /** Egypt. */ + Eg = 'EG', + /** El Salvador. */ + Sv = 'SV', + /** Equatorial Guinea. */ + Gq = 'GQ', + /** Eritrea. */ + Er = 'ER', + /** Estonia. */ + Ee = 'EE', + /** Eswatini. */ + Sz = 'SZ', + /** Ethiopia. */ + Et = 'ET', + /** Falkland Islands. */ + Fk = 'FK', + /** Faroe Islands. */ + Fo = 'FO', + /** Fiji. */ + Fj = 'FJ', + /** Finland. */ + Fi = 'FI', + /** France. */ + Fr = 'FR', + /** French Guiana. */ + Gf = 'GF', + /** French Polynesia. */ + Pf = 'PF', + /** French Southern Territories. */ + Tf = 'TF', + /** Gabon. */ + Ga = 'GA', + /** Gambia. */ + Gm = 'GM', + /** Georgia. */ + Ge = 'GE', + /** Germany. */ + De = 'DE', + /** Ghana. */ + Gh = 'GH', + /** Gibraltar. */ + Gi = 'GI', + /** Greece. */ + Gr = 'GR', + /** Greenland. */ + Gl = 'GL', + /** Grenada. */ + Gd = 'GD', + /** Guadeloupe. */ + Gp = 'GP', + /** Guatemala. */ + Gt = 'GT', + /** Guernsey. */ + Gg = 'GG', + /** Guinea. */ + Gn = 'GN', + /** Guinea-Bissau. */ + Gw = 'GW', + /** Guyana. */ + Gy = 'GY', + /** Haiti. */ + Ht = 'HT', + /** Heard & McDonald Islands. */ + Hm = 'HM', + /** Vatican City. */ + Va = 'VA', + /** Honduras. */ + Hn = 'HN', + /** Hong Kong SAR. */ + Hk = 'HK', + /** Hungary. */ + Hu = 'HU', + /** Iceland. */ + Is = 'IS', + /** India. */ + In = 'IN', + /** Indonesia. */ + Id = 'ID', + /** Iran. */ + Ir = 'IR', + /** Iraq. */ + Iq = 'IQ', + /** Ireland. */ + Ie = 'IE', + /** Isle of Man. */ + Im = 'IM', + /** Israel. */ + Il = 'IL', + /** Italy. */ + It = 'IT', + /** Jamaica. */ + Jm = 'JM', + /** Japan. */ + Jp = 'JP', + /** Jersey. */ + Je = 'JE', + /** Jordan. */ + Jo = 'JO', + /** Kazakhstan. */ + Kz = 'KZ', + /** Kenya. */ + Ke = 'KE', + /** Kiribati. */ + Ki = 'KI', + /** North Korea. */ + Kp = 'KP', + /** Kosovo. */ + Xk = 'XK', + /** Kuwait. */ + Kw = 'KW', + /** Kyrgyzstan. */ + Kg = 'KG', + /** Laos. */ + La = 'LA', + /** Latvia. */ + Lv = 'LV', + /** Lebanon. */ + Lb = 'LB', + /** Lesotho. */ + Ls = 'LS', + /** Liberia. */ + Lr = 'LR', + /** Libya. */ + Ly = 'LY', + /** Liechtenstein. */ + Li = 'LI', + /** Lithuania. */ + Lt = 'LT', + /** Luxembourg. */ + Lu = 'LU', + /** Macao SAR. */ + Mo = 'MO', + /** Madagascar. */ + Mg = 'MG', + /** Malawi. */ + Mw = 'MW', + /** Malaysia. */ + My = 'MY', + /** Maldives. */ + Mv = 'MV', + /** Mali. */ + Ml = 'ML', + /** Malta. */ + Mt = 'MT', + /** Martinique. */ + Mq = 'MQ', + /** Mauritania. */ + Mr = 'MR', + /** Mauritius. */ + Mu = 'MU', + /** Mayotte. */ + Yt = 'YT', + /** Mexico. */ + Mx = 'MX', + /** Moldova. */ + Md = 'MD', + /** Monaco. */ + Mc = 'MC', + /** Mongolia. */ + Mn = 'MN', + /** Montenegro. */ + Me = 'ME', + /** Montserrat. */ + Ms = 'MS', + /** Morocco. */ + Ma = 'MA', + /** Mozambique. */ + Mz = 'MZ', + /** Myanmar (Burma). */ + Mm = 'MM', + /** Namibia. */ + Na = 'NA', + /** Nauru. */ + Nr = 'NR', + /** Nepal. */ + Np = 'NP', + /** Netherlands. */ + Nl = 'NL', + /** Netherlands Antilles. */ + An = 'AN', + /** New Caledonia. */ + Nc = 'NC', + /** New Zealand. */ + Nz = 'NZ', + /** Nicaragua. */ + Ni = 'NI', + /** Niger. */ + Ne = 'NE', + /** Nigeria. */ + Ng = 'NG', + /** Niue. */ + Nu = 'NU', + /** Norfolk Island. */ + Nf = 'NF', + /** North Macedonia. */ + Mk = 'MK', + /** Norway. */ + No = 'NO', + /** Oman. */ + Om = 'OM', + /** Pakistan. */ + Pk = 'PK', + /** Palestinian Territories. */ + Ps = 'PS', + /** Panama. */ + Pa = 'PA', + /** Papua New Guinea. */ + Pg = 'PG', + /** Paraguay. */ + Py = 'PY', + /** Peru. */ + Pe = 'PE', + /** Philippines. */ + Ph = 'PH', + /** Pitcairn Islands. */ + Pn = 'PN', + /** Poland. */ + Pl = 'PL', + /** Portugal. */ + Pt = 'PT', + /** Qatar. */ + Qa = 'QA', + /** Cameroon. */ + Cm = 'CM', + /** Réunion. */ + Re = 'RE', + /** Romania. */ + Ro = 'RO', + /** Russia. */ + Ru = 'RU', + /** Rwanda. */ + Rw = 'RW', + /** St. Barthélemy. */ + Bl = 'BL', + /** St. Helena. */ + Sh = 'SH', + /** St. Kitts & Nevis. */ + Kn = 'KN', + /** St. Lucia. */ + Lc = 'LC', + /** St. Martin. */ + Mf = 'MF', + /** St. Pierre & Miquelon. */ + Pm = 'PM', + /** Samoa. */ + Ws = 'WS', + /** San Marino. */ + Sm = 'SM', + /** São Tomé & Príncipe. */ + St = 'ST', + /** Saudi Arabia. */ + Sa = 'SA', + /** Senegal. */ + Sn = 'SN', + /** Serbia. */ + Rs = 'RS', + /** Seychelles. */ + Sc = 'SC', + /** Sierra Leone. */ + Sl = 'SL', + /** Singapore. */ + Sg = 'SG', + /** Sint Maarten. */ + Sx = 'SX', + /** Slovakia. */ + Sk = 'SK', + /** Slovenia. */ + Si = 'SI', + /** Solomon Islands. */ + Sb = 'SB', + /** Somalia. */ + So = 'SO', + /** South Africa. */ + Za = 'ZA', + /** South Georgia & South Sandwich Islands. */ + Gs = 'GS', + /** South Korea. */ + Kr = 'KR', + /** South Sudan. */ + Ss = 'SS', + /** Spain. */ + Es = 'ES', + /** Sri Lanka. */ + Lk = 'LK', + /** St. Vincent & Grenadines. */ + Vc = 'VC', + /** Sudan. */ + Sd = 'SD', + /** Suriname. */ + Sr = 'SR', + /** Svalbard & Jan Mayen. */ + Sj = 'SJ', + /** Sweden. */ + Se = 'SE', + /** Switzerland. */ + Ch = 'CH', + /** Syria. */ + Sy = 'SY', + /** Taiwan. */ + Tw = 'TW', + /** Tajikistan. */ + Tj = 'TJ', + /** Tanzania. */ + Tz = 'TZ', + /** Thailand. */ + Th = 'TH', + /** Timor-Leste. */ + Tl = 'TL', + /** Togo. */ + Tg = 'TG', + /** Tokelau. */ + Tk = 'TK', + /** Tonga. */ + To = 'TO', + /** Trinidad & Tobago. */ + Tt = 'TT', + /** Tunisia. */ + Tn = 'TN', + /** Turkey. */ + Tr = 'TR', + /** Turkmenistan. */ + Tm = 'TM', + /** Turks & Caicos Islands. */ + Tc = 'TC', + /** Tuvalu. */ + Tv = 'TV', + /** Uganda. */ + Ug = 'UG', + /** Ukraine. */ + Ua = 'UA', + /** United Arab Emirates. */ + Ae = 'AE', + /** United Kingdom. */ + Gb = 'GB', + /** United States. */ + Us = 'US', + /** U.S. Outlying Islands. */ + Um = 'UM', + /** Uruguay. */ + Uy = 'UY', + /** Uzbekistan. */ + Uz = 'UZ', + /** Vanuatu. */ + Vu = 'VU', + /** Venezuela. */ + Ve = 'VE', + /** Vietnam. */ + Vn = 'VN', + /** British Virgin Islands. */ + Vg = 'VG', + /** Wallis & Futuna. */ + Wf = 'WF', + /** Western Sahara. */ + Eh = 'EH', + /** Yemen. */ + Ye = 'YE', + /** Zambia. */ + Zm = 'ZM', + /** Zimbabwe. */ + Zw = 'ZW', +} + +/** Credit card information used for a payment. */ +export type CreditCard = { + __typename?: 'CreditCard' + /** The brand of the credit card. */ + brand?: Maybe + /** The expiry month of the credit card. */ + expiryMonth?: Maybe + /** The expiry year of the credit card. */ + expiryYear?: Maybe + /** The credit card's BIN number. */ + firstDigits?: Maybe + /** The first name of the card holder. */ + firstName?: Maybe + /** The last 4 digits of the credit card. */ + lastDigits?: Maybe + /** The last name of the card holder. */ + lastName?: Maybe + /** The masked credit card number with only the last 4 digits displayed. */ + maskedNumber?: Maybe +} + +/** + * Specifies the fields required to complete a checkout with + * a Shopify vaulted credit card payment. + */ +export type CreditCardPaymentInput = { + /** The amount of the payment. */ + amount: Scalars['Money'] + /** A unique client generated key used to avoid duplicate charges. When a duplicate payment is found, the original is returned instead of creating a new one. */ + idempotencyKey: Scalars['String'] + /** The billing address for the payment. */ + billingAddress: MailingAddressInput + /** The ID returned by Shopify's Card Vault. */ + vaultId: Scalars['String'] + /** Executes the payment in test mode if possible. Defaults to `false`. */ + test?: Maybe +} + +/** + * Specifies the fields required to complete a checkout with + * a Shopify vaulted credit card payment. + */ +export type CreditCardPaymentInputV2 = { + /** The amount and currency of the payment. */ + paymentAmount: MoneyInput + /** A unique client generated key used to avoid duplicate charges. When a duplicate payment is found, the original is returned instead of creating a new one. */ + idempotencyKey: Scalars['String'] + /** The billing address for the payment. */ + billingAddress: MailingAddressInput + /** The ID returned by Shopify's Card Vault. */ + vaultId: Scalars['String'] + /** Executes the payment in test mode if possible. Defaults to `false`. */ + test?: Maybe +} + +/** The part of the image that should remain after cropping. */ +export enum CropRegion { + /** Keep the center of the image. */ + Center = 'CENTER', + /** Keep the top of the image. */ + Top = 'TOP', + /** Keep the bottom of the image. */ + Bottom = 'BOTTOM', + /** Keep the left of the image. */ + Left = 'LEFT', + /** Keep the right of the image. */ + Right = 'RIGHT', +} + +/** Currency codes. */ +export enum CurrencyCode { + /** United States Dollars (USD). */ + Usd = 'USD', + /** Euro (EUR). */ + Eur = 'EUR', + /** United Kingdom Pounds (GBP). */ + Gbp = 'GBP', + /** Canadian Dollars (CAD). */ + Cad = 'CAD', + /** Afghan Afghani (AFN). */ + Afn = 'AFN', + /** Albanian Lek (ALL). */ + All = 'ALL', + /** Algerian Dinar (DZD). */ + Dzd = 'DZD', + /** Angolan Kwanza (AOA). */ + Aoa = 'AOA', + /** Argentine Pesos (ARS). */ + Ars = 'ARS', + /** Armenian Dram (AMD). */ + Amd = 'AMD', + /** Aruban Florin (AWG). */ + Awg = 'AWG', + /** Australian Dollars (AUD). */ + Aud = 'AUD', + /** Barbadian Dollar (BBD). */ + Bbd = 'BBD', + /** Azerbaijani Manat (AZN). */ + Azn = 'AZN', + /** Bangladesh Taka (BDT). */ + Bdt = 'BDT', + /** Bahamian Dollar (BSD). */ + Bsd = 'BSD', + /** Bahraini Dinar (BHD). */ + Bhd = 'BHD', + /** Burundian Franc (BIF). */ + Bif = 'BIF', + /** Belarusian Ruble (BYN). */ + Byn = 'BYN', + /** Belarusian Ruble (BYR). */ + Byr = 'BYR', + /** Belize Dollar (BZD). */ + Bzd = 'BZD', + /** Bermudian Dollar (BMD). */ + Bmd = 'BMD', + /** Bhutanese Ngultrum (BTN). */ + Btn = 'BTN', + /** Bosnia and Herzegovina Convertible Mark (BAM). */ + Bam = 'BAM', + /** Brazilian Real (BRL). */ + Brl = 'BRL', + /** Bolivian Boliviano (BOB). */ + Bob = 'BOB', + /** Botswana Pula (BWP). */ + Bwp = 'BWP', + /** Brunei Dollar (BND). */ + Bnd = 'BND', + /** Bulgarian Lev (BGN). */ + Bgn = 'BGN', + /** Burmese Kyat (MMK). */ + Mmk = 'MMK', + /** Cambodian Riel. */ + Khr = 'KHR', + /** Cape Verdean escudo (CVE). */ + Cve = 'CVE', + /** Cayman Dollars (KYD). */ + Kyd = 'KYD', + /** Central African CFA Franc (XAF). */ + Xaf = 'XAF', + /** Chilean Peso (CLP). */ + Clp = 'CLP', + /** Chinese Yuan Renminbi (CNY). */ + Cny = 'CNY', + /** Colombian Peso (COP). */ + Cop = 'COP', + /** Comorian Franc (KMF). */ + Kmf = 'KMF', + /** Congolese franc (CDF). */ + Cdf = 'CDF', + /** Costa Rican Colones (CRC). */ + Crc = 'CRC', + /** Croatian Kuna (HRK). */ + Hrk = 'HRK', + /** Czech Koruny (CZK). */ + Czk = 'CZK', + /** Danish Kroner (DKK). */ + Dkk = 'DKK', + /** Djiboutian Franc (DJF). */ + Djf = 'DJF', + /** Dominican Peso (DOP). */ + Dop = 'DOP', + /** East Caribbean Dollar (XCD). */ + Xcd = 'XCD', + /** Egyptian Pound (EGP). */ + Egp = 'EGP', + /** Eritrean Nakfa (ERN). */ + Ern = 'ERN', + /** Ethiopian Birr (ETB). */ + Etb = 'ETB', + /** Falkland Islands Pounds (FKP). */ + Fkp = 'FKP', + /** CFP Franc (XPF). */ + Xpf = 'XPF', + /** Fijian Dollars (FJD). */ + Fjd = 'FJD', + /** Gibraltar Pounds (GIP). */ + Gip = 'GIP', + /** Gambian Dalasi (GMD). */ + Gmd = 'GMD', + /** Ghanaian Cedi (GHS). */ + Ghs = 'GHS', + /** Guatemalan Quetzal (GTQ). */ + Gtq = 'GTQ', + /** Guyanese Dollar (GYD). */ + Gyd = 'GYD', + /** Georgian Lari (GEL). */ + Gel = 'GEL', + /** Guinean Franc (GNF). */ + Gnf = 'GNF', + /** Haitian Gourde (HTG). */ + Htg = 'HTG', + /** Honduran Lempira (HNL). */ + Hnl = 'HNL', + /** Hong Kong Dollars (HKD). */ + Hkd = 'HKD', + /** Hungarian Forint (HUF). */ + Huf = 'HUF', + /** Icelandic Kronur (ISK). */ + Isk = 'ISK', + /** Indian Rupees (INR). */ + Inr = 'INR', + /** Indonesian Rupiah (IDR). */ + Idr = 'IDR', + /** Israeli New Shekel (NIS). */ + Ils = 'ILS', + /** Iranian Rial (IRR). */ + Irr = 'IRR', + /** Iraqi Dinar (IQD). */ + Iqd = 'IQD', + /** Jamaican Dollars (JMD). */ + Jmd = 'JMD', + /** Japanese Yen (JPY). */ + Jpy = 'JPY', + /** Jersey Pound. */ + Jep = 'JEP', + /** Jordanian Dinar (JOD). */ + Jod = 'JOD', + /** Kazakhstani Tenge (KZT). */ + Kzt = 'KZT', + /** Kenyan Shilling (KES). */ + Kes = 'KES', + /** Kiribati Dollar (KID). */ + Kid = 'KID', + /** Kuwaiti Dinar (KWD). */ + Kwd = 'KWD', + /** Kyrgyzstani Som (KGS). */ + Kgs = 'KGS', + /** Laotian Kip (LAK). */ + Lak = 'LAK', + /** Latvian Lati (LVL). */ + Lvl = 'LVL', + /** Lebanese Pounds (LBP). */ + Lbp = 'LBP', + /** Lesotho Loti (LSL). */ + Lsl = 'LSL', + /** Liberian Dollar (LRD). */ + Lrd = 'LRD', + /** Libyan Dinar (LYD). */ + Lyd = 'LYD', + /** Lithuanian Litai (LTL). */ + Ltl = 'LTL', + /** Malagasy Ariary (MGA). */ + Mga = 'MGA', + /** Macedonia Denar (MKD). */ + Mkd = 'MKD', + /** Macanese Pataca (MOP). */ + Mop = 'MOP', + /** Malawian Kwacha (MWK). */ + Mwk = 'MWK', + /** Maldivian Rufiyaa (MVR). */ + Mvr = 'MVR', + /** Mauritanian Ouguiya (MRU). */ + Mru = 'MRU', + /** Mexican Pesos (MXN). */ + Mxn = 'MXN', + /** Malaysian Ringgits (MYR). */ + Myr = 'MYR', + /** Mauritian Rupee (MUR). */ + Mur = 'MUR', + /** Moldovan Leu (MDL). */ + Mdl = 'MDL', + /** Moroccan Dirham. */ + Mad = 'MAD', + /** Mongolian Tugrik. */ + Mnt = 'MNT', + /** Mozambican Metical. */ + Mzn = 'MZN', + /** Namibian Dollar. */ + Nad = 'NAD', + /** Nepalese Rupee (NPR). */ + Npr = 'NPR', + /** Netherlands Antillean Guilder. */ + Ang = 'ANG', + /** New Zealand Dollars (NZD). */ + Nzd = 'NZD', + /** Nicaraguan Córdoba (NIO). */ + Nio = 'NIO', + /** Nigerian Naira (NGN). */ + Ngn = 'NGN', + /** Norwegian Kroner (NOK). */ + Nok = 'NOK', + /** Omani Rial (OMR). */ + Omr = 'OMR', + /** Panamian Balboa (PAB). */ + Pab = 'PAB', + /** Pakistani Rupee (PKR). */ + Pkr = 'PKR', + /** Papua New Guinean Kina (PGK). */ + Pgk = 'PGK', + /** Paraguayan Guarani (PYG). */ + Pyg = 'PYG', + /** Peruvian Nuevo Sol (PEN). */ + Pen = 'PEN', + /** Philippine Peso (PHP). */ + Php = 'PHP', + /** Polish Zlotych (PLN). */ + Pln = 'PLN', + /** Qatari Rial (QAR). */ + Qar = 'QAR', + /** Romanian Lei (RON). */ + Ron = 'RON', + /** Russian Rubles (RUB). */ + Rub = 'RUB', + /** Rwandan Franc (RWF). */ + Rwf = 'RWF', + /** Samoan Tala (WST). */ + Wst = 'WST', + /** Saint Helena Pounds (SHP). */ + Shp = 'SHP', + /** Saudi Riyal (SAR). */ + Sar = 'SAR', + /** Sao Tome And Principe Dobra (STD). */ + Std = 'STD', + /** Serbian dinar (RSD). */ + Rsd = 'RSD', + /** Seychellois Rupee (SCR). */ + Scr = 'SCR', + /** Sierra Leonean Leone (SLL). */ + Sll = 'SLL', + /** Singapore Dollars (SGD). */ + Sgd = 'SGD', + /** Sudanese Pound (SDG). */ + Sdg = 'SDG', + /** Somali Shilling (SOS). */ + Sos = 'SOS', + /** Syrian Pound (SYP). */ + Syp = 'SYP', + /** South African Rand (ZAR). */ + Zar = 'ZAR', + /** South Korean Won (KRW). */ + Krw = 'KRW', + /** South Sudanese Pound (SSP). */ + Ssp = 'SSP', + /** Solomon Islands Dollar (SBD). */ + Sbd = 'SBD', + /** Sri Lankan Rupees (LKR). */ + Lkr = 'LKR', + /** Surinamese Dollar (SRD). */ + Srd = 'SRD', + /** Swazi Lilangeni (SZL). */ + Szl = 'SZL', + /** Swedish Kronor (SEK). */ + Sek = 'SEK', + /** Swiss Francs (CHF). */ + Chf = 'CHF', + /** Taiwan Dollars (TWD). */ + Twd = 'TWD', + /** Thai baht (THB). */ + Thb = 'THB', + /** Tajikistani Somoni (TJS). */ + Tjs = 'TJS', + /** Tanzanian Shilling (TZS). */ + Tzs = 'TZS', + /** Tongan Pa'anga (TOP). */ + Top = 'TOP', + /** Trinidad and Tobago Dollars (TTD). */ + Ttd = 'TTD', + /** Tunisian Dinar (TND). */ + Tnd = 'TND', + /** Turkish Lira (TRY). */ + Try = 'TRY', + /** Turkmenistani Manat (TMT). */ + Tmt = 'TMT', + /** Ugandan Shilling (UGX). */ + Ugx = 'UGX', + /** Ukrainian Hryvnia (UAH). */ + Uah = 'UAH', + /** United Arab Emirates Dirham (AED). */ + Aed = 'AED', + /** Uruguayan Pesos (UYU). */ + Uyu = 'UYU', + /** Uzbekistan som (UZS). */ + Uzs = 'UZS', + /** Vanuatu Vatu (VUV). */ + Vuv = 'VUV', + /** Venezuelan Bolivares (VEF). */ + Vef = 'VEF', + /** Venezuelan Bolivares (VES). */ + Ves = 'VES', + /** Vietnamese đồng (VND). */ + Vnd = 'VND', + /** West African CFA franc (XOF). */ + Xof = 'XOF', + /** Yemeni Rial (YER). */ + Yer = 'YER', + /** Zambian Kwacha (ZMW). */ + Zmw = 'ZMW', +} + +/** A customer represents a customer account with the shop. Customer accounts store contact information for the customer, saving logged-in customers the trouble of having to provide it at every checkout. */ +export type Customer = { + __typename?: 'Customer' + /** Indicates whether the customer has consented to be sent marketing material via email. */ + acceptsMarketing: Scalars['Boolean'] + /** A list of addresses for the customer. */ + addresses: MailingAddressConnection + /** The date and time when the customer was created. */ + createdAt: Scalars['DateTime'] + /** The customer’s default address. */ + defaultAddress?: Maybe + /** The customer’s name, email or phone number. */ + displayName: Scalars['String'] + /** The customer’s email address. */ + email?: Maybe + /** The customer’s first name. */ + firstName?: Maybe + /** A unique identifier for the customer. */ + id: Scalars['ID'] + /** The customer's most recently updated, incomplete checkout. */ + lastIncompleteCheckout?: Maybe + /** The customer’s last name. */ + lastName?: Maybe + /** The orders associated with the customer. */ + orders: OrderConnection + /** The customer’s phone number. */ + phone?: Maybe + /** + * A comma separated list of tags that have been added to the customer. + * Additional access scope required: unauthenticated_read_customer_tags. + */ + tags: Array + /** The date and time when the customer information was updated. */ + updatedAt: Scalars['DateTime'] +} + +/** A customer represents a customer account with the shop. Customer accounts store contact information for the customer, saving logged-in customers the trouble of having to provide it at every checkout. */ +export type CustomerAddressesArgs = { + first?: Maybe + after?: Maybe + last?: Maybe + before?: Maybe + reverse?: Maybe +} + +/** A customer represents a customer account with the shop. Customer accounts store contact information for the customer, saving logged-in customers the trouble of having to provide it at every checkout. */ +export type CustomerOrdersArgs = { + first?: Maybe + after?: Maybe + last?: Maybe + before?: Maybe + reverse?: Maybe + sortKey?: Maybe + query?: Maybe +} + +/** A CustomerAccessToken represents the unique token required to make modifications to the customer object. */ +export type CustomerAccessToken = { + __typename?: 'CustomerAccessToken' + /** The customer’s access token. */ + accessToken: Scalars['String'] + /** The date and time when the customer access token expires. */ + expiresAt: Scalars['DateTime'] +} + +/** Specifies the input fields required to create a customer access token. */ +export type CustomerAccessTokenCreateInput = { + /** The email associated to the customer. */ + email: Scalars['String'] + /** The login password to be used by the customer. */ + password: Scalars['String'] +} + +/** Return type for `customerAccessTokenCreate` mutation. */ +export type CustomerAccessTokenCreatePayload = { + __typename?: 'CustomerAccessTokenCreatePayload' + /** The newly created customer access token object. */ + customerAccessToken?: Maybe + /** List of errors that occurred executing the mutation. */ + customerUserErrors: Array + /** + * List of errors that occurred executing the mutation. + * @deprecated Use `customerUserErrors` instead + */ + userErrors: Array +} + +/** Return type for `customerAccessTokenCreateWithMultipass` mutation. */ +export type CustomerAccessTokenCreateWithMultipassPayload = { + __typename?: 'CustomerAccessTokenCreateWithMultipassPayload' + /** An access token object associated with the customer. */ + customerAccessToken?: Maybe + /** List of errors that occurred executing the mutation. */ + customerUserErrors: Array +} + +/** Return type for `customerAccessTokenDelete` mutation. */ +export type CustomerAccessTokenDeletePayload = { + __typename?: 'CustomerAccessTokenDeletePayload' + /** The destroyed access token. */ + deletedAccessToken?: Maybe + /** ID of the destroyed customer access token. */ + deletedCustomerAccessTokenId?: Maybe + /** List of errors that occurred executing the mutation. */ + userErrors: Array +} + +/** Return type for `customerAccessTokenRenew` mutation. */ +export type CustomerAccessTokenRenewPayload = { + __typename?: 'CustomerAccessTokenRenewPayload' + /** The renewed customer access token object. */ + customerAccessToken?: Maybe + /** List of errors that occurred executing the mutation. */ + userErrors: Array +} + +/** Return type for `customerActivateByUrl` mutation. */ +export type CustomerActivateByUrlPayload = { + __typename?: 'CustomerActivateByUrlPayload' + /** The customer that was activated. */ + customer?: Maybe + /** A new customer access token for the customer. */ + customerAccessToken?: Maybe + /** List of errors that occurred executing the mutation. */ + customerUserErrors: Array +} + +/** Specifies the input fields required to activate a customer. */ +export type CustomerActivateInput = { + /** The activation token required to activate the customer. */ + activationToken: Scalars['String'] + /** New password that will be set during activation. */ + password: Scalars['String'] +} + +/** Return type for `customerActivate` mutation. */ +export type CustomerActivatePayload = { + __typename?: 'CustomerActivatePayload' + /** The customer object. */ + customer?: Maybe + /** A newly created customer access token object for the customer. */ + customerAccessToken?: Maybe + /** List of errors that occurred executing the mutation. */ + customerUserErrors: Array + /** + * List of errors that occurred executing the mutation. + * @deprecated Use `customerUserErrors` instead + */ + userErrors: Array +} + +/** Return type for `customerAddressCreate` mutation. */ +export type CustomerAddressCreatePayload = { + __typename?: 'CustomerAddressCreatePayload' + /** The new customer address object. */ + customerAddress?: Maybe + /** List of errors that occurred executing the mutation. */ + customerUserErrors: Array + /** + * List of errors that occurred executing the mutation. + * @deprecated Use `customerUserErrors` instead + */ + userErrors: Array +} + +/** Return type for `customerAddressDelete` mutation. */ +export type CustomerAddressDeletePayload = { + __typename?: 'CustomerAddressDeletePayload' + /** List of errors that occurred executing the mutation. */ + customerUserErrors: Array + /** ID of the deleted customer address. */ + deletedCustomerAddressId?: Maybe + /** + * List of errors that occurred executing the mutation. + * @deprecated Use `customerUserErrors` instead + */ + userErrors: Array +} + +/** Return type for `customerAddressUpdate` mutation. */ +export type CustomerAddressUpdatePayload = { + __typename?: 'CustomerAddressUpdatePayload' + /** The customer’s updated mailing address. */ + customerAddress?: Maybe + /** List of errors that occurred executing the mutation. */ + customerUserErrors: Array + /** + * List of errors that occurred executing the mutation. + * @deprecated Use `customerUserErrors` instead + */ + userErrors: Array +} + +/** Specifies the fields required to create a new customer. */ +export type CustomerCreateInput = { + /** The customer’s first name. */ + firstName?: Maybe + /** The customer’s last name. */ + lastName?: Maybe + /** The customer’s email. */ + email: Scalars['String'] + /** + * A unique phone number for the customer. + * + * Formatted using E.164 standard. For example, _+16135551111_. + */ + phone?: Maybe + /** The login password used by the customer. */ + password: Scalars['String'] + /** Indicates whether the customer has consented to be sent marketing material via email. */ + acceptsMarketing?: Maybe +} + +/** Return type for `customerCreate` mutation. */ +export type CustomerCreatePayload = { + __typename?: 'CustomerCreatePayload' + /** The created customer object. */ + customer?: Maybe + /** List of errors that occurred executing the mutation. */ + customerUserErrors: Array + /** + * List of errors that occurred executing the mutation. + * @deprecated Use `customerUserErrors` instead + */ + userErrors: Array +} + +/** Return type for `customerDefaultAddressUpdate` mutation. */ +export type CustomerDefaultAddressUpdatePayload = { + __typename?: 'CustomerDefaultAddressUpdatePayload' + /** The updated customer object. */ + customer?: Maybe + /** List of errors that occurred executing the mutation. */ + customerUserErrors: Array + /** + * List of errors that occurred executing the mutation. + * @deprecated Use `customerUserErrors` instead + */ + userErrors: Array +} + +/** Possible error codes that could be returned by CustomerUserError. */ +export enum CustomerErrorCode { + /** Input value is blank. */ + Blank = 'BLANK', + /** Input value is invalid. */ + Invalid = 'INVALID', + /** Input value is already taken. */ + Taken = 'TAKEN', + /** Input value is too long. */ + TooLong = 'TOO_LONG', + /** Input value is too short. */ + TooShort = 'TOO_SHORT', + /** Unidentified customer. */ + UnidentifiedCustomer = 'UNIDENTIFIED_CUSTOMER', + /** Customer is disabled. */ + CustomerDisabled = 'CUSTOMER_DISABLED', + /** Input password starts or ends with whitespace. */ + PasswordStartsOrEndsWithWhitespace = 'PASSWORD_STARTS_OR_ENDS_WITH_WHITESPACE', + /** Input contains HTML tags. */ + ContainsHtmlTags = 'CONTAINS_HTML_TAGS', + /** Input contains URL. */ + ContainsUrl = 'CONTAINS_URL', + /** Invalid activation token. */ + TokenInvalid = 'TOKEN_INVALID', + /** Customer already enabled. */ + AlreadyEnabled = 'ALREADY_ENABLED', + /** Address does not exist. */ + NotFound = 'NOT_FOUND', + /** Input email contains an invalid domain name. */ + BadDomain = 'BAD_DOMAIN', + /** Multipass token is not valid. */ + InvalidMultipassRequest = 'INVALID_MULTIPASS_REQUEST', +} + +/** Return type for `customerRecover` mutation. */ +export type CustomerRecoverPayload = { + __typename?: 'CustomerRecoverPayload' + /** List of errors that occurred executing the mutation. */ + customerUserErrors: Array + /** + * List of errors that occurred executing the mutation. + * @deprecated Use `customerUserErrors` instead + */ + userErrors: Array +} + +/** Return type for `customerResetByUrl` mutation. */ +export type CustomerResetByUrlPayload = { + __typename?: 'CustomerResetByUrlPayload' + /** The customer object which was reset. */ + customer?: Maybe + /** A newly created customer access token object for the customer. */ + customerAccessToken?: Maybe + /** List of errors that occurred executing the mutation. */ + customerUserErrors: Array + /** + * List of errors that occurred executing the mutation. + * @deprecated Use `customerUserErrors` instead + */ + userErrors: Array +} + +/** Specifies the fields required to reset a customer’s password. */ +export type CustomerResetInput = { + /** The reset token required to reset the customer’s password. */ + resetToken: Scalars['String'] + /** New password that will be set as part of the reset password process. */ + password: Scalars['String'] +} + +/** Return type for `customerReset` mutation. */ +export type CustomerResetPayload = { + __typename?: 'CustomerResetPayload' + /** The customer object which was reset. */ + customer?: Maybe + /** A newly created customer access token object for the customer. */ + customerAccessToken?: Maybe + /** List of errors that occurred executing the mutation. */ + customerUserErrors: Array + /** + * List of errors that occurred executing the mutation. + * @deprecated Use `customerUserErrors` instead + */ + userErrors: Array +} + +/** Specifies the fields required to update the Customer information. */ +export type CustomerUpdateInput = { + /** The customer’s first name. */ + firstName?: Maybe + /** The customer’s last name. */ + lastName?: Maybe + /** The customer’s email. */ + email?: Maybe + /** + * A unique phone number for the customer. + * + * Formatted using E.164 standard. For example, _+16135551111_. To remove the phone number, specify `null`. + */ + phone?: Maybe + /** The login password used by the customer. */ + password?: Maybe + /** Indicates whether the customer has consented to be sent marketing material via email. */ + acceptsMarketing?: Maybe +} + +/** Return type for `customerUpdate` mutation. */ +export type CustomerUpdatePayload = { + __typename?: 'CustomerUpdatePayload' + /** The updated customer object. */ + customer?: Maybe + /** + * The newly created customer access token. If the customer's password is updated, all previous access tokens + * (including the one used to perform this mutation) become invalid, and a new token is generated. + */ + customerAccessToken?: Maybe + /** List of errors that occurred executing the mutation. */ + customerUserErrors: Array + /** + * List of errors that occurred executing the mutation. + * @deprecated Use `customerUserErrors` instead + */ + userErrors: Array +} + +/** Represents an error that happens during execution of a customer mutation. */ +export type CustomerUserError = DisplayableError & { + __typename?: 'CustomerUserError' + /** Error code to uniquely identify the error. */ + code?: Maybe + /** Path to the input field which caused the error. */ + field?: Maybe> + /** The error message. */ + message: Scalars['String'] +} + +/** Digital wallet, such as Apple Pay, which can be used for accelerated checkouts. */ +export enum DigitalWallet { + /** Apple Pay. */ + ApplePay = 'APPLE_PAY', + /** Android Pay. */ + AndroidPay = 'ANDROID_PAY', + /** Google Pay. */ + GooglePay = 'GOOGLE_PAY', + /** Shopify Pay. */ + ShopifyPay = 'SHOPIFY_PAY', +} + +/** An amount discounting the line that has been allocated by a discount. */ +export type DiscountAllocation = { + __typename?: 'DiscountAllocation' + /** Amount of discount allocated. */ + allocatedAmount: MoneyV2 + /** The discount this allocated amount originated from. */ + discountApplication: DiscountApplication +} + +/** + * Discount applications capture the intentions of a discount source at + * the time of application. + */ +export type DiscountApplication = { + /** The method by which the discount's value is allocated to its entitled items. */ + allocationMethod: DiscountApplicationAllocationMethod + /** Which lines of targetType that the discount is allocated over. */ + targetSelection: DiscountApplicationTargetSelection + /** The type of line that the discount is applicable towards. */ + targetType: DiscountApplicationTargetType + /** The value of the discount application. */ + value: PricingValue +} + +/** The method by which the discount's value is allocated onto its entitled lines. */ +export enum DiscountApplicationAllocationMethod { + /** The value is spread across all entitled lines. */ + Across = 'ACROSS', + /** The value is applied onto every entitled line. */ + Each = 'EACH', + /** The value is specifically applied onto a particular line. */ + One = 'ONE', +} + +/** An auto-generated type for paginating through multiple DiscountApplications. */ +export type DiscountApplicationConnection = { + __typename?: 'DiscountApplicationConnection' + /** A list of edges. */ + edges: Array + /** Information to aid in pagination. */ + pageInfo: PageInfo +} + +/** An auto-generated type which holds one DiscountApplication and a cursor during pagination. */ +export type DiscountApplicationEdge = { + __typename?: 'DiscountApplicationEdge' + /** A cursor for use in pagination. */ + cursor: Scalars['String'] + /** The item at the end of DiscountApplicationEdge. */ + node: DiscountApplication +} + +/** + * Which lines on the order that the discount is allocated over, of the type + * defined by the Discount Application's target_type. + */ +export enum DiscountApplicationTargetSelection { + /** The discount is allocated onto all the lines. */ + All = 'ALL', + /** The discount is allocated onto only the lines it is entitled for. */ + Entitled = 'ENTITLED', + /** The discount is allocated onto explicitly chosen lines. */ + Explicit = 'EXPLICIT', +} + +/** The type of line (i.e. line item or shipping line) on an order that the discount is applicable towards. */ +export enum DiscountApplicationTargetType { + /** The discount applies onto line items. */ + LineItem = 'LINE_ITEM', + /** The discount applies onto shipping lines. */ + ShippingLine = 'SHIPPING_LINE', +} + +/** + * Discount code applications capture the intentions of a discount code at + * the time that it is applied. + */ +export type DiscountCodeApplication = DiscountApplication & { + __typename?: 'DiscountCodeApplication' + /** The method by which the discount's value is allocated to its entitled items. */ + allocationMethod: DiscountApplicationAllocationMethod + /** Specifies whether the discount code was applied successfully. */ + applicable: Scalars['Boolean'] + /** The string identifying the discount code that was used at the time of application. */ + code: Scalars['String'] + /** Which lines of targetType that the discount is allocated over. */ + targetSelection: DiscountApplicationTargetSelection + /** The type of line that the discount is applicable towards. */ + targetType: DiscountApplicationTargetType + /** The value of the discount application. */ + value: PricingValue +} + +/** Represents an error in the input of a mutation. */ +export type DisplayableError = { + /** Path to the input field which caused the error. */ + field?: Maybe> + /** The error message. */ + message: Scalars['String'] +} + +/** Represents a web address. */ +export type Domain = { + __typename?: 'Domain' + /** The host name of the domain (eg: `example.com`). */ + host: Scalars['String'] + /** Whether SSL is enabled or not. */ + sslEnabled: Scalars['Boolean'] + /** The URL of the domain (eg: `https://example.com`). */ + url: Scalars['URL'] +} + +/** Represents a video hosted outside of Shopify. */ +export type ExternalVideo = Node & + Media & { + __typename?: 'ExternalVideo' + /** A word or phrase to share the nature or contents of a media. */ + alt?: Maybe + /** The URL. */ + embeddedUrl: Scalars['URL'] + /** Globally unique identifier. */ + id: Scalars['ID'] + /** The media content type. */ + mediaContentType: MediaContentType + /** The preview image for the media. */ + previewImage?: Maybe + } + +/** Represents a single fulfillment in an order. */ +export type Fulfillment = { + __typename?: 'Fulfillment' + /** List of the fulfillment's line items. */ + fulfillmentLineItems: FulfillmentLineItemConnection + /** The name of the tracking company. */ + trackingCompany?: Maybe + /** + * Tracking information associated with the fulfillment, + * such as the tracking number and tracking URL. + */ + trackingInfo: Array +} + +/** Represents a single fulfillment in an order. */ +export type FulfillmentFulfillmentLineItemsArgs = { + first?: Maybe + after?: Maybe + last?: Maybe + before?: Maybe + reverse?: Maybe +} + +/** Represents a single fulfillment in an order. */ +export type FulfillmentTrackingInfoArgs = { + first?: Maybe +} + +/** Represents a single line item in a fulfillment. There is at most one fulfillment line item for each order line item. */ +export type FulfillmentLineItem = { + __typename?: 'FulfillmentLineItem' + /** The associated order's line item. */ + lineItem: OrderLineItem + /** The amount fulfilled in this fulfillment. */ + quantity: Scalars['Int'] +} + +/** An auto-generated type for paginating through multiple FulfillmentLineItems. */ +export type FulfillmentLineItemConnection = { + __typename?: 'FulfillmentLineItemConnection' + /** A list of edges. */ + edges: Array + /** Information to aid in pagination. */ + pageInfo: PageInfo +} + +/** An auto-generated type which holds one FulfillmentLineItem and a cursor during pagination. */ +export type FulfillmentLineItemEdge = { + __typename?: 'FulfillmentLineItemEdge' + /** A cursor for use in pagination. */ + cursor: Scalars['String'] + /** The item at the end of FulfillmentLineItemEdge. */ + node: FulfillmentLineItem +} + +/** Tracking information associated with the fulfillment. */ +export type FulfillmentTrackingInfo = { + __typename?: 'FulfillmentTrackingInfo' + /** The tracking number of the fulfillment. */ + number?: Maybe + /** The URL to track the fulfillment. */ + url?: Maybe +} + +/** Represents information about the metafields associated to the specified resource. */ +export type HasMetafields = { + /** The metafield associated with the resource. */ + metafield?: Maybe + /** A paginated list of metafields associated with the resource. */ + metafields: MetafieldConnection +} + +/** Represents information about the metafields associated to the specified resource. */ +export type HasMetafieldsMetafieldArgs = { + namespace: Scalars['String'] + key: Scalars['String'] +} + +/** Represents information about the metafields associated to the specified resource. */ +export type HasMetafieldsMetafieldsArgs = { + namespace?: Maybe + first?: Maybe + after?: Maybe + last?: Maybe + before?: Maybe + reverse?: Maybe +} + +/** Represents an image resource. */ +export type Image = { + __typename?: 'Image' + /** A word or phrase to share the nature or contents of an image. */ + altText?: Maybe + /** The original height of the image in pixels. Returns `null` if the image is not hosted by Shopify. */ + height?: Maybe + /** A unique identifier for the image. */ + id?: Maybe + /** + * The location of the original image as a URL. + * + * If there are any existing transformations in the original source URL, they will remain and not be stripped. + */ + originalSrc: Scalars['URL'] + /** + * The location of the image as a URL. + * @deprecated Previously an image had a single `src` field. This could either return the original image + * location or a URL that contained transformations such as sizing or scale. + * + * These transformations were specified by arguments on the parent field. + * + * Now an image has two distinct URL fields: `originalSrc` and `transformedSrc`. + * + * * `originalSrc` - the original unmodified image URL + * * `transformedSrc` - the image URL with the specified transformations included + * + * To migrate to the new fields, image transformations should be moved from the parent field to `transformedSrc`. + * + * Before: + * ```graphql + * { + * shop { + * productImages(maxWidth: 200, scale: 2) { + * edges { + * node { + * src + * } + * } + * } + * } + * } + * ``` + * + * After: + * ```graphql + * { + * shop { + * productImages { + * edges { + * node { + * transformedSrc(maxWidth: 200, scale: 2) + * } + * } + * } + * } + * } + * ``` + * + */ + src: Scalars['URL'] + /** + * The location of the transformed image as a URL. + * + * All transformation arguments are considered "best-effort". If they can be applied to an image, they will be. + * Otherwise any transformations which an image type does not support will be ignored. + */ + transformedSrc: Scalars['URL'] + /** The original width of the image in pixels. Returns `null` if the image is not hosted by Shopify. */ + width?: Maybe +} + +/** Represents an image resource. */ +export type ImageTransformedSrcArgs = { + maxWidth?: Maybe + maxHeight?: Maybe + crop?: Maybe + scale?: Maybe + preferredContentType?: Maybe +} + +/** An auto-generated type for paginating through multiple Images. */ +export type ImageConnection = { + __typename?: 'ImageConnection' + /** A list of edges. */ + edges: Array + /** Information to aid in pagination. */ + pageInfo: PageInfo +} + +/** List of supported image content types. */ +export enum ImageContentType { + /** A PNG image. */ + Png = 'PNG', + /** A JPG image. */ + Jpg = 'JPG', + /** A WEBP image. */ + Webp = 'WEBP', +} + +/** An auto-generated type which holds one Image and a cursor during pagination. */ +export type ImageEdge = { + __typename?: 'ImageEdge' + /** A cursor for use in pagination. */ + cursor: Scalars['String'] + /** The item at the end of ImageEdge. */ + node: Image +} + +/** Represents a mailing address for customers and shipping. */ +export type MailingAddress = Node & { + __typename?: 'MailingAddress' + /** The first line of the address. Typically the street address or PO Box number. */ + address1?: Maybe + /** The second line of the address. Typically the number of the apartment, suite, or unit. */ + address2?: Maybe + /** The name of the city, district, village, or town. */ + city?: Maybe + /** The name of the customer's company or organization. */ + company?: Maybe + /** The name of the country. */ + country?: Maybe + /** + * The two-letter code for the country of the address. + * + * For example, US. + * @deprecated Use `countryCodeV2` instead + */ + countryCode?: Maybe + /** + * The two-letter code for the country of the address. + * + * For example, US. + */ + countryCodeV2?: Maybe + /** The first name of the customer. */ + firstName?: Maybe + /** A formatted version of the address, customized by the provided arguments. */ + formatted: Array + /** A comma-separated list of the values for city, province, and country. */ + formattedArea?: Maybe + /** Globally unique identifier. */ + id: Scalars['ID'] + /** The last name of the customer. */ + lastName?: Maybe + /** The latitude coordinate of the customer address. */ + latitude?: Maybe + /** The longitude coordinate of the customer address. */ + longitude?: Maybe + /** The full name of the customer, based on firstName and lastName. */ + name?: Maybe + /** + * A unique phone number for the customer. + * + * Formatted using E.164 standard. For example, _+16135551111_. + */ + phone?: Maybe + /** The region of the address, such as the province, state, or district. */ + province?: Maybe + /** + * The two-letter code for the region. + * + * For example, ON. + */ + provinceCode?: Maybe + /** The zip or postal code of the address. */ + zip?: Maybe +} + +/** Represents a mailing address for customers and shipping. */ +export type MailingAddressFormattedArgs = { + withName?: Maybe + withCompany?: Maybe +} + +/** An auto-generated type for paginating through multiple MailingAddresses. */ +export type MailingAddressConnection = { + __typename?: 'MailingAddressConnection' + /** A list of edges. */ + edges: Array + /** Information to aid in pagination. */ + pageInfo: PageInfo +} + +/** An auto-generated type which holds one MailingAddress and a cursor during pagination. */ +export type MailingAddressEdge = { + __typename?: 'MailingAddressEdge' + /** A cursor for use in pagination. */ + cursor: Scalars['String'] + /** The item at the end of MailingAddressEdge. */ + node: MailingAddress +} + +/** Specifies the fields accepted to create or update a mailing address. */ +export type MailingAddressInput = { + /** The first line of the address. Typically the street address or PO Box number. */ + address1?: Maybe + /** The second line of the address. Typically the number of the apartment, suite, or unit. */ + address2?: Maybe + /** The name of the city, district, village, or town. */ + city?: Maybe + /** The name of the customer's company or organization. */ + company?: Maybe + /** The name of the country. */ + country?: Maybe + /** The first name of the customer. */ + firstName?: Maybe + /** The last name of the customer. */ + lastName?: Maybe + /** + * A unique phone number for the customer. + * + * Formatted using E.164 standard. For example, _+16135551111_. + */ + phone?: Maybe + /** The region of the address, such as the province, state, or district. */ + province?: Maybe + /** The zip or postal code of the address. */ + zip?: Maybe +} + +/** Manual discount applications capture the intentions of a discount that was manually created. */ +export type ManualDiscountApplication = DiscountApplication & { + __typename?: 'ManualDiscountApplication' + /** The method by which the discount's value is allocated to its entitled items. */ + allocationMethod: DiscountApplicationAllocationMethod + /** The description of the application. */ + description?: Maybe + /** Which lines of targetType that the discount is allocated over. */ + targetSelection: DiscountApplicationTargetSelection + /** The type of line that the discount is applicable towards. */ + targetType: DiscountApplicationTargetType + /** The title of the application. */ + title: Scalars['String'] + /** The value of the discount application. */ + value: PricingValue +} + +/** Represents a media interface. */ +export type Media = { + /** A word or phrase to share the nature or contents of a media. */ + alt?: Maybe + /** The media content type. */ + mediaContentType: MediaContentType + /** The preview image for the media. */ + previewImage?: Maybe +} + +/** An auto-generated type for paginating through multiple Media. */ +export type MediaConnection = { + __typename?: 'MediaConnection' + /** A list of edges. */ + edges: Array + /** Information to aid in pagination. */ + pageInfo: PageInfo +} + +/** The possible content types for a media object. */ +export enum MediaContentType { + /** An externally hosted video. */ + ExternalVideo = 'EXTERNAL_VIDEO', + /** A Shopify hosted image. */ + Image = 'IMAGE', + /** A 3d model. */ + Model_3D = 'MODEL_3D', + /** A Shopify hosted video. */ + Video = 'VIDEO', +} + +/** An auto-generated type which holds one Media and a cursor during pagination. */ +export type MediaEdge = { + __typename?: 'MediaEdge' + /** A cursor for use in pagination. */ + cursor: Scalars['String'] + /** The item at the end of MediaEdge. */ + node: Media +} + +/** Represents a Shopify hosted image. */ +export type MediaImage = Node & + Media & { + __typename?: 'MediaImage' + /** A word or phrase to share the nature or contents of a media. */ + alt?: Maybe + /** Globally unique identifier. */ + id: Scalars['ID'] + /** The image for the media. */ + image?: Maybe + /** The media content type. */ + mediaContentType: MediaContentType + /** The preview image for the media. */ + previewImage?: Maybe + } + +/** + * Metafields represent custom metadata attached to a resource. Metafields can be sorted into namespaces and are + * comprised of keys, values, and value types. + */ +export type Metafield = Node & { + __typename?: 'Metafield' + /** The date and time when the storefront metafield was created. */ + createdAt: Scalars['DateTime'] + /** The description of a metafield. */ + description?: Maybe + /** Globally unique identifier. */ + id: Scalars['ID'] + /** The key name for a metafield. */ + key: Scalars['String'] + /** The namespace for a metafield. */ + namespace: Scalars['String'] + /** The parent object that the metafield belongs to. */ + parentResource: MetafieldParentResource + /** The date and time when the storefront metafield was updated. */ + updatedAt: Scalars['DateTime'] + /** The value of a metafield. */ + value: Scalars['String'] + /** Represents the metafield value type. */ + valueType: MetafieldValueType +} + +/** An auto-generated type for paginating through multiple Metafields. */ +export type MetafieldConnection = { + __typename?: 'MetafieldConnection' + /** A list of edges. */ + edges: Array + /** Information to aid in pagination. */ + pageInfo: PageInfo +} + +/** An auto-generated type which holds one Metafield and a cursor during pagination. */ +export type MetafieldEdge = { + __typename?: 'MetafieldEdge' + /** A cursor for use in pagination. */ + cursor: Scalars['String'] + /** The item at the end of MetafieldEdge. */ + node: Metafield +} + +/** A resource that the metafield belongs to. */ +export type MetafieldParentResource = Product | ProductVariant + +/** Metafield value types. */ +export enum MetafieldValueType { + /** A string metafield. */ + String = 'STRING', + /** An integer metafield. */ + Integer = 'INTEGER', + /** A json string metafield. */ + JsonString = 'JSON_STRING', +} + +/** Represents a Shopify hosted 3D model. */ +export type Model3d = Node & + Media & { + __typename?: 'Model3d' + /** A word or phrase to share the nature or contents of a media. */ + alt?: Maybe + /** Globally unique identifier. */ + id: Scalars['ID'] + /** The media content type. */ + mediaContentType: MediaContentType + /** The preview image for the media. */ + previewImage?: Maybe + /** The sources for a 3d model. */ + sources: Array + } + +/** Represents a source for a Shopify hosted 3d model. */ +export type Model3dSource = { + __typename?: 'Model3dSource' + /** The filesize of the 3d model. */ + filesize: Scalars['Int'] + /** The format of the 3d model. */ + format: Scalars['String'] + /** The MIME type of the 3d model. */ + mimeType: Scalars['String'] + /** The URL of the 3d model. */ + url: Scalars['String'] +} + +/** Specifies the fields for a monetary value with currency. */ +export type MoneyInput = { + /** Decimal money amount. */ + amount: Scalars['Decimal'] + /** Currency of the money. */ + currencyCode: CurrencyCode +} + +/** + * A monetary value with currency. + * + * To format currencies, combine this type's amount and currencyCode fields with your client's locale. + * + * For example, in JavaScript you could use Intl.NumberFormat: + * + * ```js + * new Intl.NumberFormat(locale, { + * style: 'currency', + * currency: currencyCode + * }).format(amount); + * ``` + * + * Other formatting libraries include: + * + * * iOS - [NumberFormatter](https://developer.apple.com/documentation/foundation/numberformatter) + * * Android - [NumberFormat](https://developer.android.com/reference/java/text/NumberFormat.html) + * * PHP - [NumberFormatter](http://php.net/manual/en/class.numberformatter.php) + * + * For a more general solution, the [Unicode CLDR number formatting database] is available with many implementations + * (such as [TwitterCldr](https://github.com/twitter/twitter-cldr-rb)). + */ +export type MoneyV2 = { + __typename?: 'MoneyV2' + /** Decimal money amount. */ + amount: Scalars['Decimal'] + /** Currency of the money. */ + currencyCode: CurrencyCode +} + +/** An auto-generated type for paginating through multiple MoneyV2s. */ +export type MoneyV2Connection = { + __typename?: 'MoneyV2Connection' + /** A list of edges. */ + edges: Array + /** Information to aid in pagination. */ + pageInfo: PageInfo +} + +/** An auto-generated type which holds one MoneyV2 and a cursor during pagination. */ +export type MoneyV2Edge = { + __typename?: 'MoneyV2Edge' + /** A cursor for use in pagination. */ + cursor: Scalars['String'] + /** The item at the end of MoneyV2Edge. */ + node: MoneyV2 +} + +/** The schema’s entry-point for mutations. This acts as the public, top-level API from which all mutation queries must start. */ +export type Mutation = { + __typename?: 'Mutation' + /** + * Updates the attributes of a checkout. + * @deprecated Use `checkoutAttributesUpdateV2` instead + */ + checkoutAttributesUpdate?: Maybe + /** Updates the attributes of a checkout. */ + checkoutAttributesUpdateV2?: Maybe + /** Completes a checkout without providing payment information. You can use this mutation for free items or items whose purchase price is covered by a gift card. */ + checkoutCompleteFree?: Maybe + /** + * Completes a checkout using a credit card token from Shopify's Vault. + * @deprecated Use `checkoutCompleteWithCreditCardV2` instead + */ + checkoutCompleteWithCreditCard?: Maybe + /** Completes a checkout using a credit card token from Shopify's card vault. Before you can complete checkouts using CheckoutCompleteWithCreditCardV2, you need to [_request payment processing_](https://help.shopify.com/api/guides/sales-channel-sdk/getting-started#request-payment-processing). */ + checkoutCompleteWithCreditCardV2?: Maybe + /** + * Completes a checkout with a tokenized payment. + * @deprecated Use `checkoutCompleteWithTokenizedPaymentV2` instead + */ + checkoutCompleteWithTokenizedPayment?: Maybe + /** + * Completes a checkout with a tokenized payment. + * @deprecated Use `checkoutCompleteWithTokenizedPaymentV3` instead + */ + checkoutCompleteWithTokenizedPaymentV2?: Maybe + /** Completes a checkout with a tokenized payment. */ + checkoutCompleteWithTokenizedPaymentV3?: Maybe + /** Creates a new checkout. */ + checkoutCreate?: Maybe + /** + * Associates a customer to the checkout. + * @deprecated Use `checkoutCustomerAssociateV2` instead + */ + checkoutCustomerAssociate?: Maybe + /** Associates a customer to the checkout. */ + checkoutCustomerAssociateV2?: Maybe + /** + * Disassociates the current checkout customer from the checkout. + * @deprecated Use `checkoutCustomerDisassociateV2` instead + */ + checkoutCustomerDisassociate?: Maybe + /** Disassociates the current checkout customer from the checkout. */ + checkoutCustomerDisassociateV2?: Maybe + /** + * Applies a discount to an existing checkout using a discount code. + * @deprecated Use `checkoutDiscountCodeApplyV2` instead + */ + checkoutDiscountCodeApply?: Maybe + /** Applies a discount to an existing checkout using a discount code. */ + checkoutDiscountCodeApplyV2?: Maybe + /** Removes the applied discount from an existing checkout. */ + checkoutDiscountCodeRemove?: Maybe + /** + * Updates the email on an existing checkout. + * @deprecated Use `checkoutEmailUpdateV2` instead + */ + checkoutEmailUpdate?: Maybe + /** Updates the email on an existing checkout. */ + checkoutEmailUpdateV2?: Maybe + /** + * Applies a gift card to an existing checkout using a gift card code. This will replace all currently applied gift cards. + * @deprecated Use `checkoutGiftCardsAppend` instead + */ + checkoutGiftCardApply?: Maybe + /** + * Removes an applied gift card from the checkout. + * @deprecated Use `checkoutGiftCardRemoveV2` instead + */ + checkoutGiftCardRemove?: Maybe + /** Removes an applied gift card from the checkout. */ + checkoutGiftCardRemoveV2?: Maybe + /** Appends gift cards to an existing checkout. */ + checkoutGiftCardsAppend?: Maybe + /** Adds a list of line items to a checkout. */ + checkoutLineItemsAdd?: Maybe + /** Removes line items from an existing checkout. */ + checkoutLineItemsRemove?: Maybe + /** Sets a list of line items to a checkout. */ + checkoutLineItemsReplace?: Maybe + /** Updates line items on a checkout. */ + checkoutLineItemsUpdate?: Maybe + /** + * Updates the shipping address of an existing checkout. + * @deprecated Use `checkoutShippingAddressUpdateV2` instead + */ + checkoutShippingAddressUpdate?: Maybe + /** Updates the shipping address of an existing checkout. */ + checkoutShippingAddressUpdateV2?: Maybe + /** Updates the shipping lines on an existing checkout. */ + checkoutShippingLineUpdate?: Maybe + /** + * Creates a customer access token. + * The customer access token is required to modify the customer object in any way. + */ + customerAccessTokenCreate?: Maybe + /** + * Creates a customer access token using a multipass token instead of email and password. + * A customer record is created if customer does not exist. If a customer record already + * exists but the record is disabled, then it's enabled. + */ + customerAccessTokenCreateWithMultipass?: Maybe + /** Permanently destroys a customer access token. */ + customerAccessTokenDelete?: Maybe + /** + * Renews a customer access token. + * + * Access token renewal must happen *before* a token expires. + * If a token has already expired, a new one should be created instead via `customerAccessTokenCreate`. + */ + customerAccessTokenRenew?: Maybe + /** Activates a customer. */ + customerActivate?: Maybe + /** Activates a customer with the activation url received from `customerCreate`. */ + customerActivateByUrl?: Maybe + /** Creates a new address for a customer. */ + customerAddressCreate?: Maybe + /** Permanently deletes the address of an existing customer. */ + customerAddressDelete?: Maybe + /** Updates the address of an existing customer. */ + customerAddressUpdate?: Maybe + /** Creates a new customer. */ + customerCreate?: Maybe + /** Updates the default address of an existing customer. */ + customerDefaultAddressUpdate?: Maybe + /** Sends a reset password email to the customer, as the first step in the reset password process. */ + customerRecover?: Maybe + /** Resets a customer’s password with a token received from `CustomerRecover`. */ + customerReset?: Maybe + /** Resets a customer’s password with the reset password url received from `CustomerRecover`. */ + customerResetByUrl?: Maybe + /** Updates an existing customer. */ + customerUpdate?: Maybe +} + +/** The schema’s entry-point for mutations. This acts as the public, top-level API from which all mutation queries must start. */ +export type MutationCheckoutAttributesUpdateArgs = { + checkoutId: Scalars['ID'] + input: CheckoutAttributesUpdateInput +} + +/** The schema’s entry-point for mutations. This acts as the public, top-level API from which all mutation queries must start. */ +export type MutationCheckoutAttributesUpdateV2Args = { + checkoutId: Scalars['ID'] + input: CheckoutAttributesUpdateV2Input +} + +/** The schema’s entry-point for mutations. This acts as the public, top-level API from which all mutation queries must start. */ +export type MutationCheckoutCompleteFreeArgs = { + checkoutId: Scalars['ID'] +} + +/** The schema’s entry-point for mutations. This acts as the public, top-level API from which all mutation queries must start. */ +export type MutationCheckoutCompleteWithCreditCardArgs = { + checkoutId: Scalars['ID'] + payment: CreditCardPaymentInput +} + +/** The schema’s entry-point for mutations. This acts as the public, top-level API from which all mutation queries must start. */ +export type MutationCheckoutCompleteWithCreditCardV2Args = { + checkoutId: Scalars['ID'] + payment: CreditCardPaymentInputV2 +} + +/** The schema’s entry-point for mutations. This acts as the public, top-level API from which all mutation queries must start. */ +export type MutationCheckoutCompleteWithTokenizedPaymentArgs = { + checkoutId: Scalars['ID'] + payment: TokenizedPaymentInput +} + +/** The schema’s entry-point for mutations. This acts as the public, top-level API from which all mutation queries must start. */ +export type MutationCheckoutCompleteWithTokenizedPaymentV2Args = { + checkoutId: Scalars['ID'] + payment: TokenizedPaymentInputV2 +} + +/** The schema’s entry-point for mutations. This acts as the public, top-level API from which all mutation queries must start. */ +export type MutationCheckoutCompleteWithTokenizedPaymentV3Args = { + checkoutId: Scalars['ID'] + payment: TokenizedPaymentInputV3 +} + +/** The schema’s entry-point for mutations. This acts as the public, top-level API from which all mutation queries must start. */ +export type MutationCheckoutCreateArgs = { + input: CheckoutCreateInput +} + +/** The schema’s entry-point for mutations. This acts as the public, top-level API from which all mutation queries must start. */ +export type MutationCheckoutCustomerAssociateArgs = { + checkoutId: Scalars['ID'] + customerAccessToken: Scalars['String'] +} + +/** The schema’s entry-point for mutations. This acts as the public, top-level API from which all mutation queries must start. */ +export type MutationCheckoutCustomerAssociateV2Args = { + checkoutId: Scalars['ID'] + customerAccessToken: Scalars['String'] +} + +/** The schema’s entry-point for mutations. This acts as the public, top-level API from which all mutation queries must start. */ +export type MutationCheckoutCustomerDisassociateArgs = { + checkoutId: Scalars['ID'] +} + +/** The schema’s entry-point for mutations. This acts as the public, top-level API from which all mutation queries must start. */ +export type MutationCheckoutCustomerDisassociateV2Args = { + checkoutId: Scalars['ID'] +} + +/** The schema’s entry-point for mutations. This acts as the public, top-level API from which all mutation queries must start. */ +export type MutationCheckoutDiscountCodeApplyArgs = { + discountCode: Scalars['String'] + checkoutId: Scalars['ID'] +} + +/** The schema’s entry-point for mutations. This acts as the public, top-level API from which all mutation queries must start. */ +export type MutationCheckoutDiscountCodeApplyV2Args = { + discountCode: Scalars['String'] + checkoutId: Scalars['ID'] +} + +/** The schema’s entry-point for mutations. This acts as the public, top-level API from which all mutation queries must start. */ +export type MutationCheckoutDiscountCodeRemoveArgs = { + checkoutId: Scalars['ID'] +} + +/** The schema’s entry-point for mutations. This acts as the public, top-level API from which all mutation queries must start. */ +export type MutationCheckoutEmailUpdateArgs = { + checkoutId: Scalars['ID'] + email: Scalars['String'] +} + +/** The schema’s entry-point for mutations. This acts as the public, top-level API from which all mutation queries must start. */ +export type MutationCheckoutEmailUpdateV2Args = { + checkoutId: Scalars['ID'] + email: Scalars['String'] +} + +/** The schema’s entry-point for mutations. This acts as the public, top-level API from which all mutation queries must start. */ +export type MutationCheckoutGiftCardApplyArgs = { + giftCardCode: Scalars['String'] + checkoutId: Scalars['ID'] +} + +/** The schema’s entry-point for mutations. This acts as the public, top-level API from which all mutation queries must start. */ +export type MutationCheckoutGiftCardRemoveArgs = { + appliedGiftCardId: Scalars['ID'] + checkoutId: Scalars['ID'] +} + +/** The schema’s entry-point for mutations. This acts as the public, top-level API from which all mutation queries must start. */ +export type MutationCheckoutGiftCardRemoveV2Args = { + appliedGiftCardId: Scalars['ID'] + checkoutId: Scalars['ID'] +} + +/** The schema’s entry-point for mutations. This acts as the public, top-level API from which all mutation queries must start. */ +export type MutationCheckoutGiftCardsAppendArgs = { + giftCardCodes: Array + checkoutId: Scalars['ID'] +} + +/** The schema’s entry-point for mutations. This acts as the public, top-level API from which all mutation queries must start. */ +export type MutationCheckoutLineItemsAddArgs = { + lineItems: Array + checkoutId: Scalars['ID'] +} + +/** The schema’s entry-point for mutations. This acts as the public, top-level API from which all mutation queries must start. */ +export type MutationCheckoutLineItemsRemoveArgs = { + checkoutId: Scalars['ID'] + lineItemIds: Array +} + +/** The schema’s entry-point for mutations. This acts as the public, top-level API from which all mutation queries must start. */ +export type MutationCheckoutLineItemsReplaceArgs = { + lineItems: Array + checkoutId: Scalars['ID'] +} + +/** The schema’s entry-point for mutations. This acts as the public, top-level API from which all mutation queries must start. */ +export type MutationCheckoutLineItemsUpdateArgs = { + checkoutId: Scalars['ID'] + lineItems: Array +} + +/** The schema’s entry-point for mutations. This acts as the public, top-level API from which all mutation queries must start. */ +export type MutationCheckoutShippingAddressUpdateArgs = { + shippingAddress: MailingAddressInput + checkoutId: Scalars['ID'] +} + +/** The schema’s entry-point for mutations. This acts as the public, top-level API from which all mutation queries must start. */ +export type MutationCheckoutShippingAddressUpdateV2Args = { + shippingAddress: MailingAddressInput + checkoutId: Scalars['ID'] +} + +/** The schema’s entry-point for mutations. This acts as the public, top-level API from which all mutation queries must start. */ +export type MutationCheckoutShippingLineUpdateArgs = { + checkoutId: Scalars['ID'] + shippingRateHandle: Scalars['String'] +} + +/** The schema’s entry-point for mutations. This acts as the public, top-level API from which all mutation queries must start. */ +export type MutationCustomerAccessTokenCreateArgs = { + input: CustomerAccessTokenCreateInput +} + +/** The schema’s entry-point for mutations. This acts as the public, top-level API from which all mutation queries must start. */ +export type MutationCustomerAccessTokenCreateWithMultipassArgs = { + multipassToken: Scalars['String'] +} + +/** The schema’s entry-point for mutations. This acts as the public, top-level API from which all mutation queries must start. */ +export type MutationCustomerAccessTokenDeleteArgs = { + customerAccessToken: Scalars['String'] +} + +/** The schema’s entry-point for mutations. This acts as the public, top-level API from which all mutation queries must start. */ +export type MutationCustomerAccessTokenRenewArgs = { + customerAccessToken: Scalars['String'] +} + +/** The schema’s entry-point for mutations. This acts as the public, top-level API from which all mutation queries must start. */ +export type MutationCustomerActivateArgs = { + id: Scalars['ID'] + input: CustomerActivateInput +} + +/** The schema’s entry-point for mutations. This acts as the public, top-level API from which all mutation queries must start. */ +export type MutationCustomerActivateByUrlArgs = { + activationUrl: Scalars['URL'] + password: Scalars['String'] +} + +/** The schema’s entry-point for mutations. This acts as the public, top-level API from which all mutation queries must start. */ +export type MutationCustomerAddressCreateArgs = { + customerAccessToken: Scalars['String'] + address: MailingAddressInput +} + +/** The schema’s entry-point for mutations. This acts as the public, top-level API from which all mutation queries must start. */ +export type MutationCustomerAddressDeleteArgs = { + id: Scalars['ID'] + customerAccessToken: Scalars['String'] +} + +/** The schema’s entry-point for mutations. This acts as the public, top-level API from which all mutation queries must start. */ +export type MutationCustomerAddressUpdateArgs = { + customerAccessToken: Scalars['String'] + id: Scalars['ID'] + address: MailingAddressInput +} + +/** The schema’s entry-point for mutations. This acts as the public, top-level API from which all mutation queries must start. */ +export type MutationCustomerCreateArgs = { + input: CustomerCreateInput +} + +/** The schema’s entry-point for mutations. This acts as the public, top-level API from which all mutation queries must start. */ +export type MutationCustomerDefaultAddressUpdateArgs = { + customerAccessToken: Scalars['String'] + addressId: Scalars['ID'] +} + +/** The schema’s entry-point for mutations. This acts as the public, top-level API from which all mutation queries must start. */ +export type MutationCustomerRecoverArgs = { + email: Scalars['String'] +} + +/** The schema’s entry-point for mutations. This acts as the public, top-level API from which all mutation queries must start. */ +export type MutationCustomerResetArgs = { + id: Scalars['ID'] + input: CustomerResetInput +} + +/** The schema’s entry-point for mutations. This acts as the public, top-level API from which all mutation queries must start. */ +export type MutationCustomerResetByUrlArgs = { + resetUrl: Scalars['URL'] + password: Scalars['String'] +} + +/** The schema’s entry-point for mutations. This acts as the public, top-level API from which all mutation queries must start. */ +export type MutationCustomerUpdateArgs = { + customerAccessToken: Scalars['String'] + customer: CustomerUpdateInput +} + +/** An object with an ID to support global identification. */ +export type Node = { + /** Globally unique identifier. */ + id: Scalars['ID'] +} + +/** An order is a customer’s completed request to purchase one or more products from a shop. An order is created when a customer completes the checkout process, during which time they provides an email address, billing address and payment information. */ +export type Order = Node & { + __typename?: 'Order' + /** The reason for the order's cancellation. Returns `null` if the order wasn't canceled. */ + cancelReason?: Maybe + /** The date and time when the order was canceled. Returns null if the order wasn't canceled. */ + canceledAt?: Maybe + /** The code of the currency used for the payment. */ + currencyCode: CurrencyCode + /** The subtotal of line items and their discounts, excluding line items that have been removed. Does not contain order-level discounts, duties, shipping costs, or shipping discounts. Taxes are not included unless the order is a taxes-included order. */ + currentSubtotalPrice: MoneyV2 + /** The total amount of the order, including duties, taxes and discounts, minus amounts for line items that have been removed. */ + currentTotalPrice: MoneyV2 + /** The total of all taxes applied to the order, excluding taxes for returned line items. */ + currentTotalTax: MoneyV2 + /** The locale code in which this specific order happened. */ + customerLocale?: Maybe + /** The unique URL that the customer can use to access the order. */ + customerUrl?: Maybe + /** Discounts that have been applied on the order. */ + discountApplications: DiscountApplicationConnection + /** Whether the order has had any edits applied or not. */ + edited: Scalars['Boolean'] + /** The customer's email address. */ + email?: Maybe + /** The financial status of the order. */ + financialStatus?: Maybe + /** The fulfillment status for the order. */ + fulfillmentStatus: OrderFulfillmentStatus + /** Globally unique identifier. */ + id: Scalars['ID'] + /** List of the order’s line items. */ + lineItems: OrderLineItemConnection + /** + * Unique identifier for the order that appears on the order. + * For example, _#1000_ or _Store1001. + */ + name: Scalars['String'] + /** A unique numeric identifier for the order for use by shop owner and customer. */ + orderNumber: Scalars['Int'] + /** The total price of the order before any applied edits. */ + originalTotalPrice: MoneyV2 + /** The customer's phone number for receiving SMS notifications. */ + phone?: Maybe + /** + * The date and time when the order was imported. + * This value can be set to dates in the past when importing from other systems. + * If no value is provided, it will be auto-generated based on current date and time. + */ + processedAt: Scalars['DateTime'] + /** The address to where the order will be shipped. */ + shippingAddress?: Maybe + /** The discounts that have been allocated onto the shipping line by discount applications. */ + shippingDiscountAllocations: Array + /** The unique URL for the order's status page. */ + statusUrl: Scalars['URL'] + /** + * Price of the order before shipping and taxes. + * @deprecated Use `subtotalPriceV2` instead + */ + subtotalPrice?: Maybe + /** Price of the order before duties, shipping and taxes. */ + subtotalPriceV2?: Maybe + /** List of the order’s successful fulfillments. */ + successfulFulfillments?: Maybe> + /** + * The sum of all the prices of all the items in the order, taxes and discounts included (must be positive). + * @deprecated Use `totalPriceV2` instead + */ + totalPrice: Scalars['Money'] + /** The sum of all the prices of all the items in the order, duties, taxes and discounts included (must be positive). */ + totalPriceV2: MoneyV2 + /** + * The total amount that has been refunded. + * @deprecated Use `totalRefundedV2` instead + */ + totalRefunded: Scalars['Money'] + /** The total amount that has been refunded. */ + totalRefundedV2: MoneyV2 + /** + * The total cost of shipping. + * @deprecated Use `totalShippingPriceV2` instead + */ + totalShippingPrice: Scalars['Money'] + /** The total cost of shipping. */ + totalShippingPriceV2: MoneyV2 + /** + * The total cost of taxes. + * @deprecated Use `totalTaxV2` instead + */ + totalTax?: Maybe + /** The total cost of taxes. */ + totalTaxV2?: Maybe +} + +/** An order is a customer’s completed request to purchase one or more products from a shop. An order is created when a customer completes the checkout process, during which time they provides an email address, billing address and payment information. */ +export type OrderDiscountApplicationsArgs = { + first?: Maybe + after?: Maybe + last?: Maybe + before?: Maybe + reverse?: Maybe +} + +/** An order is a customer’s completed request to purchase one or more products from a shop. An order is created when a customer completes the checkout process, during which time they provides an email address, billing address and payment information. */ +export type OrderLineItemsArgs = { + first?: Maybe + after?: Maybe + last?: Maybe + before?: Maybe + reverse?: Maybe +} + +/** An order is a customer’s completed request to purchase one or more products from a shop. An order is created when a customer completes the checkout process, during which time they provides an email address, billing address and payment information. */ +export type OrderSuccessfulFulfillmentsArgs = { + first?: Maybe +} + +/** Represents the reason for the order's cancellation. */ +export enum OrderCancelReason { + /** The customer wanted to cancel the order. */ + Customer = 'CUSTOMER', + /** The order was fraudulent. */ + Fraud = 'FRAUD', + /** There was insufficient inventory. */ + Inventory = 'INVENTORY', + /** Payment was declined. */ + Declined = 'DECLINED', + /** The order was canceled for an unlisted reason. */ + Other = 'OTHER', +} + +/** An auto-generated type for paginating through multiple Orders. */ +export type OrderConnection = { + __typename?: 'OrderConnection' + /** A list of edges. */ + edges: Array + /** Information to aid in pagination. */ + pageInfo: PageInfo +} + +/** An auto-generated type which holds one Order and a cursor during pagination. */ +export type OrderEdge = { + __typename?: 'OrderEdge' + /** A cursor for use in pagination. */ + cursor: Scalars['String'] + /** The item at the end of OrderEdge. */ + node: Order +} + +/** Represents the order's current financial status. */ +export enum OrderFinancialStatus { + /** Displayed as **Pending**. */ + Pending = 'PENDING', + /** Displayed as **Authorized**. */ + Authorized = 'AUTHORIZED', + /** Displayed as **Partially paid**. */ + PartiallyPaid = 'PARTIALLY_PAID', + /** Displayed as **Partially refunded**. */ + PartiallyRefunded = 'PARTIALLY_REFUNDED', + /** Displayed as **Voided**. */ + Voided = 'VOIDED', + /** Displayed as **Paid**. */ + Paid = 'PAID', + /** Displayed as **Refunded**. */ + Refunded = 'REFUNDED', +} + +/** Represents the order's current fulfillment status. */ +export enum OrderFulfillmentStatus { + /** Displayed as **Unfulfilled**. */ + Unfulfilled = 'UNFULFILLED', + /** Displayed as **Partially fulfilled**. */ + PartiallyFulfilled = 'PARTIALLY_FULFILLED', + /** Displayed as **Fulfilled**. */ + Fulfilled = 'FULFILLED', + /** Displayed as **Restocked**. */ + Restocked = 'RESTOCKED', + /** Displayed as **Pending fulfillment**. */ + PendingFulfillment = 'PENDING_FULFILLMENT', + /** Displayed as **Open**. */ + Open = 'OPEN', + /** Displayed as **In progress**. */ + InProgress = 'IN_PROGRESS', + /** Displayed as **Scheduled**. */ + Scheduled = 'SCHEDULED', +} + +/** Represents a single line in an order. There is one line item for each distinct product variant. */ +export type OrderLineItem = { + __typename?: 'OrderLineItem' + /** The number of entries associated to the line item minus the items that have been removed. */ + currentQuantity: Scalars['Int'] + /** List of custom attributes associated to the line item. */ + customAttributes: Array + /** The discounts that have been allocated onto the order line item by discount applications. */ + discountAllocations: Array + /** The total price of the line item, including discounts, and displayed in the presentment currency. */ + discountedTotalPrice: MoneyV2 + /** The total price of the line item, not including any discounts. The total price is calculated using the original unit price multiplied by the quantity, and it is displayed in the presentment currency. */ + originalTotalPrice: MoneyV2 + /** The number of products variants associated to the line item. */ + quantity: Scalars['Int'] + /** The title of the product combined with title of the variant. */ + title: Scalars['String'] + /** The product variant object associated to the line item. */ + variant?: Maybe +} + +/** An auto-generated type for paginating through multiple OrderLineItems. */ +export type OrderLineItemConnection = { + __typename?: 'OrderLineItemConnection' + /** A list of edges. */ + edges: Array + /** Information to aid in pagination. */ + pageInfo: PageInfo +} + +/** An auto-generated type which holds one OrderLineItem and a cursor during pagination. */ +export type OrderLineItemEdge = { + __typename?: 'OrderLineItemEdge' + /** A cursor for use in pagination. */ + cursor: Scalars['String'] + /** The item at the end of OrderLineItemEdge. */ + node: OrderLineItem +} + +/** The set of valid sort keys for the Order query. */ +export enum OrderSortKeys { + /** Sort by the `processed_at` value. */ + ProcessedAt = 'PROCESSED_AT', + /** Sort by the `total_price` value. */ + TotalPrice = 'TOTAL_PRICE', + /** Sort by the `id` value. */ + Id = 'ID', + /** + * During a search (i.e. when the `query` parameter has been specified on the connection) this sorts the + * results by relevance to the search term(s). When no search query is specified, this sort key is not + * deterministic and should not be used. + */ + Relevance = 'RELEVANCE', +} + +/** Shopify merchants can create pages to hold static HTML content. Each Page object represents a custom page on the online store. */ +export type Page = Node & { + __typename?: 'Page' + /** The description of the page, complete with HTML formatting. */ + body: Scalars['HTML'] + /** Summary of the page body. */ + bodySummary: Scalars['String'] + /** The timestamp of the page creation. */ + createdAt: Scalars['DateTime'] + /** A human-friendly unique string for the page automatically generated from its title. */ + handle: Scalars['String'] + /** Globally unique identifier. */ + id: Scalars['ID'] + /** The page's SEO information. */ + seo?: Maybe + /** The title of the page. */ + title: Scalars['String'] + /** The timestamp of the latest page update. */ + updatedAt: Scalars['DateTime'] + /** The url pointing to the page accessible from the web. */ + url: Scalars['URL'] +} + +/** An auto-generated type for paginating through multiple Pages. */ +export type PageConnection = { + __typename?: 'PageConnection' + /** A list of edges. */ + edges: Array + /** Information to aid in pagination. */ + pageInfo: PageInfo +} + +/** An auto-generated type which holds one Page and a cursor during pagination. */ +export type PageEdge = { + __typename?: 'PageEdge' + /** A cursor for use in pagination. */ + cursor: Scalars['String'] + /** The item at the end of PageEdge. */ + node: Page +} + +/** Information about pagination in a connection. */ +export type PageInfo = { + __typename?: 'PageInfo' + /** Indicates if there are more pages to fetch. */ + hasNextPage: Scalars['Boolean'] + /** Indicates if there are any pages prior to the current page. */ + hasPreviousPage: Scalars['Boolean'] +} + +/** The set of valid sort keys for the Page query. */ +export enum PageSortKeys { + /** Sort by the `title` value. */ + Title = 'TITLE', + /** Sort by the `updated_at` value. */ + UpdatedAt = 'UPDATED_AT', + /** Sort by the `id` value. */ + Id = 'ID', + /** + * During a search (i.e. when the `query` parameter has been specified on the connection) this sorts the + * results by relevance to the search term(s). When no search query is specified, this sort key is not + * deterministic and should not be used. + */ + Relevance = 'RELEVANCE', +} + +/** A payment applied to a checkout. */ +export type Payment = Node & { + __typename?: 'Payment' + /** + * The amount of the payment. + * @deprecated Use `amountV2` instead + */ + amount: Scalars['Money'] + /** The amount of the payment. */ + amountV2: MoneyV2 + /** The billing address for the payment. */ + billingAddress?: Maybe + /** The checkout to which the payment belongs. */ + checkout: Checkout + /** The credit card used for the payment in the case of direct payments. */ + creditCard?: Maybe + /** A message describing a processing error during asynchronous processing. */ + errorMessage?: Maybe + /** Globally unique identifier. */ + id: Scalars['ID'] + /** A client-side generated token to identify a payment and perform idempotent operations. */ + idempotencyKey?: Maybe + /** The URL where the customer needs to be redirected so they can complete the 3D Secure payment flow. */ + nextActionUrl?: Maybe + /** Whether or not the payment is still processing asynchronously. */ + ready: Scalars['Boolean'] + /** A flag to indicate if the payment is to be done in test mode for gateways that support it. */ + test: Scalars['Boolean'] + /** The actual transaction recorded by Shopify after having processed the payment with the gateway. */ + transaction?: Maybe +} + +/** Settings related to payments. */ +export type PaymentSettings = { + __typename?: 'PaymentSettings' + /** List of the card brands which the shop accepts. */ + acceptedCardBrands: Array + /** The url pointing to the endpoint to vault credit cards. */ + cardVaultUrl: Scalars['URL'] + /** The country where the shop is located. */ + countryCode: CountryCode + /** The three-letter code for the shop's primary currency. */ + currencyCode: CurrencyCode + /** A list of enabled currencies (ISO 4217 format) that the shop accepts. Merchants can enable currencies from their Shopify Payments settings in the Shopify admin. */ + enabledPresentmentCurrencies: Array + /** The shop’s Shopify Payments account id. */ + shopifyPaymentsAccountId?: Maybe + /** List of the digital wallets which the shop supports. */ + supportedDigitalWallets: Array +} + +/** The valid values for the types of payment token. */ +export enum PaymentTokenType { + /** Apple Pay token type. */ + ApplePay = 'APPLE_PAY', + /** Vault payment token type. */ + Vault = 'VAULT', + /** Shopify Pay token type. */ + ShopifyPay = 'SHOPIFY_PAY', + /** Google Pay token type. */ + GooglePay = 'GOOGLE_PAY', +} + +/** The value of the percentage pricing object. */ +export type PricingPercentageValue = { + __typename?: 'PricingPercentageValue' + /** The percentage value of the object. */ + percentage: Scalars['Float'] +} + +/** The price value (fixed or percentage) for a discount application. */ +export type PricingValue = MoneyV2 | PricingPercentageValue + +/** + * A product represents an individual item for sale in a Shopify store. Products are often physical, but they don't have to be. + * For example, a digital download (such as a movie, music or ebook file) also qualifies as a product, as do services (such as equipment rental, work for hire, customization of another product or an extended warranty). + */ +export type Product = Node & + HasMetafields & { + __typename?: 'Product' + /** Indicates if at least one product variant is available for sale. */ + availableForSale: Scalars['Boolean'] + /** List of collections a product belongs to. */ + collections: CollectionConnection + /** The compare at price of the product across all variants. */ + compareAtPriceRange: ProductPriceRange + /** The date and time when the product was created. */ + createdAt: Scalars['DateTime'] + /** Stripped description of the product, single line with HTML tags removed. */ + description: Scalars['String'] + /** The description of the product, complete with HTML formatting. */ + descriptionHtml: Scalars['HTML'] + /** + * A human-friendly unique string for the Product automatically generated from its title. + * They are used by the Liquid templating language to refer to objects. + */ + handle: Scalars['String'] + /** Globally unique identifier. */ + id: Scalars['ID'] + /** List of images associated with the product. */ + images: ImageConnection + /** The media associated with the product. */ + media: MediaConnection + /** The metafield associated with the resource. */ + metafield?: Maybe + /** A paginated list of metafields associated with the resource. */ + metafields: MetafieldConnection + /** + * The online store URL for the product. + * A value of `null` indicates that the product is not published to the Online Store sales channel. + */ + onlineStoreUrl?: Maybe + /** List of product options. */ + options: Array + /** List of price ranges in the presentment currencies for this shop. */ + presentmentPriceRanges: ProductPriceRangeConnection + /** The price range. */ + priceRange: ProductPriceRange + /** A categorization that a product can be tagged with, commonly used for filtering and searching. */ + productType: Scalars['String'] + /** The date and time when the product was published to the channel. */ + publishedAt: Scalars['DateTime'] + /** The product's SEO information. */ + seo: Seo + /** + * A comma separated list of tags that have been added to the product. + * Additional access scope required for private apps: unauthenticated_read_product_tags. + */ + tags: Array + /** The product’s title. */ + title: Scalars['String'] + /** The total quantity of inventory in stock for this Product. */ + totalInventory?: Maybe + /** + * The date and time when the product was last modified. + * A product's `updatedAt` value can change for different reasons. For example, if an order + * is placed for a product that has inventory tracking set up, then the inventory adjustment + * is counted as an update. + */ + updatedAt: Scalars['DateTime'] + /** + * Find a product’s variant based on its selected options. + * This is useful for converting a user’s selection of product options into a single matching variant. + * If there is not a variant for the selected options, `null` will be returned. + */ + variantBySelectedOptions?: Maybe + /** List of the product’s variants. */ + variants: ProductVariantConnection + /** The product’s vendor name. */ + vendor: Scalars['String'] + } + +/** + * A product represents an individual item for sale in a Shopify store. Products are often physical, but they don't have to be. + * For example, a digital download (such as a movie, music or ebook file) also qualifies as a product, as do services (such as equipment rental, work for hire, customization of another product or an extended warranty). + */ +export type ProductCollectionsArgs = { + first?: Maybe + after?: Maybe + last?: Maybe + before?: Maybe + reverse?: Maybe +} + +/** + * A product represents an individual item for sale in a Shopify store. Products are often physical, but they don't have to be. + * For example, a digital download (such as a movie, music or ebook file) also qualifies as a product, as do services (such as equipment rental, work for hire, customization of another product or an extended warranty). + */ +export type ProductDescriptionArgs = { + truncateAt?: Maybe +} + +/** + * A product represents an individual item for sale in a Shopify store. Products are often physical, but they don't have to be. + * For example, a digital download (such as a movie, music or ebook file) also qualifies as a product, as do services (such as equipment rental, work for hire, customization of another product or an extended warranty). + */ +export type ProductImagesArgs = { + first?: Maybe + after?: Maybe + last?: Maybe + before?: Maybe + reverse?: Maybe + sortKey?: Maybe + maxWidth?: Maybe + maxHeight?: Maybe + crop?: Maybe + scale?: Maybe +} + +/** + * A product represents an individual item for sale in a Shopify store. Products are often physical, but they don't have to be. + * For example, a digital download (such as a movie, music or ebook file) also qualifies as a product, as do services (such as equipment rental, work for hire, customization of another product or an extended warranty). + */ +export type ProductMediaArgs = { + first?: Maybe + after?: Maybe + last?: Maybe + before?: Maybe + reverse?: Maybe + sortKey?: Maybe +} + +/** + * A product represents an individual item for sale in a Shopify store. Products are often physical, but they don't have to be. + * For example, a digital download (such as a movie, music or ebook file) also qualifies as a product, as do services (such as equipment rental, work for hire, customization of another product or an extended warranty). + */ +export type ProductMetafieldArgs = { + namespace: Scalars['String'] + key: Scalars['String'] +} + +/** + * A product represents an individual item for sale in a Shopify store. Products are often physical, but they don't have to be. + * For example, a digital download (such as a movie, music or ebook file) also qualifies as a product, as do services (such as equipment rental, work for hire, customization of another product or an extended warranty). + */ +export type ProductMetafieldsArgs = { + namespace?: Maybe + first?: Maybe + after?: Maybe + last?: Maybe + before?: Maybe + reverse?: Maybe +} + +/** + * A product represents an individual item for sale in a Shopify store. Products are often physical, but they don't have to be. + * For example, a digital download (such as a movie, music or ebook file) also qualifies as a product, as do services (such as equipment rental, work for hire, customization of another product or an extended warranty). + */ +export type ProductOptionsArgs = { + first?: Maybe +} + +/** + * A product represents an individual item for sale in a Shopify store. Products are often physical, but they don't have to be. + * For example, a digital download (such as a movie, music or ebook file) also qualifies as a product, as do services (such as equipment rental, work for hire, customization of another product or an extended warranty). + */ +export type ProductPresentmentPriceRangesArgs = { + presentmentCurrencies?: Maybe> + first?: Maybe + after?: Maybe + last?: Maybe + before?: Maybe + reverse?: Maybe +} + +/** + * A product represents an individual item for sale in a Shopify store. Products are often physical, but they don't have to be. + * For example, a digital download (such as a movie, music or ebook file) also qualifies as a product, as do services (such as equipment rental, work for hire, customization of another product or an extended warranty). + */ +export type ProductVariantBySelectedOptionsArgs = { + selectedOptions: Array +} + +/** + * A product represents an individual item for sale in a Shopify store. Products are often physical, but they don't have to be. + * For example, a digital download (such as a movie, music or ebook file) also qualifies as a product, as do services (such as equipment rental, work for hire, customization of another product or an extended warranty). + */ +export type ProductVariantsArgs = { + first?: Maybe + after?: Maybe + last?: Maybe + before?: Maybe + reverse?: Maybe + sortKey?: Maybe +} + +/** The set of valid sort keys for the ProductCollection query. */ +export enum ProductCollectionSortKeys { + /** Sort by the `title` value. */ + Title = 'TITLE', + /** Sort by the `price` value. */ + Price = 'PRICE', + /** Sort by the `best-selling` value. */ + BestSelling = 'BEST_SELLING', + /** Sort by the `created` value. */ + Created = 'CREATED', + /** Sort by the `id` value. */ + Id = 'ID', + /** Sort by the `manual` value. */ + Manual = 'MANUAL', + /** Sort by the `collection-default` value. */ + CollectionDefault = 'COLLECTION_DEFAULT', + /** + * During a search (i.e. when the `query` parameter has been specified on the connection) this sorts the + * results by relevance to the search term(s). When no search query is specified, this sort key is not + * deterministic and should not be used. + */ + Relevance = 'RELEVANCE', +} + +/** An auto-generated type for paginating through multiple Products. */ +export type ProductConnection = { + __typename?: 'ProductConnection' + /** A list of edges. */ + edges: Array + /** Information to aid in pagination. */ + pageInfo: PageInfo +} + +/** An auto-generated type which holds one Product and a cursor during pagination. */ +export type ProductEdge = { + __typename?: 'ProductEdge' + /** A cursor for use in pagination. */ + cursor: Scalars['String'] + /** The item at the end of ProductEdge. */ + node: Product +} + +/** The set of valid sort keys for the ProductImage query. */ +export enum ProductImageSortKeys { + /** Sort by the `created_at` value. */ + CreatedAt = 'CREATED_AT', + /** Sort by the `position` value. */ + Position = 'POSITION', + /** Sort by the `id` value. */ + Id = 'ID', + /** + * During a search (i.e. when the `query` parameter has been specified on the connection) this sorts the + * results by relevance to the search term(s). When no search query is specified, this sort key is not + * deterministic and should not be used. + */ + Relevance = 'RELEVANCE', +} + +/** The set of valid sort keys for the ProductMedia query. */ +export enum ProductMediaSortKeys { + /** Sort by the `position` value. */ + Position = 'POSITION', + /** Sort by the `id` value. */ + Id = 'ID', + /** + * During a search (i.e. when the `query` parameter has been specified on the connection) this sorts the + * results by relevance to the search term(s). When no search query is specified, this sort key is not + * deterministic and should not be used. + */ + Relevance = 'RELEVANCE', +} + +/** + * Product property names like "Size", "Color", and "Material" that the customers can select. + * Variants are selected based on permutations of these options. + * 255 characters limit each. + */ +export type ProductOption = Node & { + __typename?: 'ProductOption' + /** Globally unique identifier. */ + id: Scalars['ID'] + /** The product option’s name. */ + name: Scalars['String'] + /** The corresponding value to the product option name. */ + values: Array +} + +/** The price range of the product. */ +export type ProductPriceRange = { + __typename?: 'ProductPriceRange' + /** The highest variant's price. */ + maxVariantPrice: MoneyV2 + /** The lowest variant's price. */ + minVariantPrice: MoneyV2 +} + +/** An auto-generated type for paginating through multiple ProductPriceRanges. */ +export type ProductPriceRangeConnection = { + __typename?: 'ProductPriceRangeConnection' + /** A list of edges. */ + edges: Array + /** Information to aid in pagination. */ + pageInfo: PageInfo +} + +/** An auto-generated type which holds one ProductPriceRange and a cursor during pagination. */ +export type ProductPriceRangeEdge = { + __typename?: 'ProductPriceRangeEdge' + /** A cursor for use in pagination. */ + cursor: Scalars['String'] + /** The item at the end of ProductPriceRangeEdge. */ + node: ProductPriceRange +} + +/** The set of valid sort keys for the Product query. */ +export enum ProductSortKeys { + /** Sort by the `title` value. */ + Title = 'TITLE', + /** Sort by the `product_type` value. */ + ProductType = 'PRODUCT_TYPE', + /** Sort by the `vendor` value. */ + Vendor = 'VENDOR', + /** Sort by the `updated_at` value. */ + UpdatedAt = 'UPDATED_AT', + /** Sort by the `created_at` value. */ + CreatedAt = 'CREATED_AT', + /** Sort by the `best_selling` value. */ + BestSelling = 'BEST_SELLING', + /** Sort by the `price` value. */ + Price = 'PRICE', + /** Sort by the `id` value. */ + Id = 'ID', + /** + * During a search (i.e. when the `query` parameter has been specified on the connection) this sorts the + * results by relevance to the search term(s). When no search query is specified, this sort key is not + * deterministic and should not be used. + */ + Relevance = 'RELEVANCE', +} + +/** A product variant represents a different version of a product, such as differing sizes or differing colors. */ +export type ProductVariant = Node & + HasMetafields & { + __typename?: 'ProductVariant' + /** + * Indicates if the product variant is in stock. + * @deprecated Use `availableForSale` instead + */ + available?: Maybe + /** Indicates if the product variant is available for sale. */ + availableForSale: Scalars['Boolean'] + /** + * The compare at price of the variant. This can be used to mark a variant as on sale, when `compareAtPrice` is higher than `price`. + * @deprecated Use `compareAtPriceV2` instead + */ + compareAtPrice?: Maybe + /** The compare at price of the variant. This can be used to mark a variant as on sale, when `compareAtPriceV2` is higher than `priceV2`. */ + compareAtPriceV2?: Maybe + /** Whether a product is out of stock but still available for purchase (used for backorders). */ + currentlyNotInStock: Scalars['Boolean'] + /** Globally unique identifier. */ + id: Scalars['ID'] + /** Image associated with the product variant. This field falls back to the product image if no image is available. */ + image?: Maybe + /** The metafield associated with the resource. */ + metafield?: Maybe + /** A paginated list of metafields associated with the resource. */ + metafields: MetafieldConnection + /** List of prices and compare-at prices in the presentment currencies for this shop. */ + presentmentPrices: ProductVariantPricePairConnection + /** List of unit prices in the presentment currencies for this shop. */ + presentmentUnitPrices: MoneyV2Connection + /** + * The product variant’s price. + * @deprecated Use `priceV2` instead + */ + price: Scalars['Money'] + /** The product variant’s price. */ + priceV2: MoneyV2 + /** The product object that the product variant belongs to. */ + product: Product + /** The total sellable quantity of the variant for online sales channels. */ + quantityAvailable?: Maybe + /** Whether a customer needs to provide a shipping address when placing an order for the product variant. */ + requiresShipping: Scalars['Boolean'] + /** List of product options applied to the variant. */ + selectedOptions: Array + /** The SKU (stock keeping unit) associated with the variant. */ + sku?: Maybe + /** The product variant’s title. */ + title: Scalars['String'] + /** The unit price value for the variant based on the variant's measurement. */ + unitPrice?: Maybe + /** The unit price measurement for the variant. */ + unitPriceMeasurement?: Maybe + /** The weight of the product variant in the unit system specified with `weight_unit`. */ + weight?: Maybe + /** Unit of measurement for weight. */ + weightUnit: WeightUnit + } + +/** A product variant represents a different version of a product, such as differing sizes or differing colors. */ +export type ProductVariantImageArgs = { + maxWidth?: Maybe + maxHeight?: Maybe + crop?: Maybe + scale?: Maybe +} + +/** A product variant represents a different version of a product, such as differing sizes or differing colors. */ +export type ProductVariantMetafieldArgs = { + namespace: Scalars['String'] + key: Scalars['String'] +} + +/** A product variant represents a different version of a product, such as differing sizes or differing colors. */ +export type ProductVariantMetafieldsArgs = { + namespace?: Maybe + first?: Maybe + after?: Maybe + last?: Maybe + before?: Maybe + reverse?: Maybe +} + +/** A product variant represents a different version of a product, such as differing sizes or differing colors. */ +export type ProductVariantPresentmentPricesArgs = { + presentmentCurrencies?: Maybe> + first?: Maybe + after?: Maybe + last?: Maybe + before?: Maybe + reverse?: Maybe +} + +/** A product variant represents a different version of a product, such as differing sizes or differing colors. */ +export type ProductVariantPresentmentUnitPricesArgs = { + presentmentCurrencies?: Maybe> + first?: Maybe + after?: Maybe + last?: Maybe + before?: Maybe + reverse?: Maybe +} + +/** An auto-generated type for paginating through multiple ProductVariants. */ +export type ProductVariantConnection = { + __typename?: 'ProductVariantConnection' + /** A list of edges. */ + edges: Array + /** Information to aid in pagination. */ + pageInfo: PageInfo +} + +/** An auto-generated type which holds one ProductVariant and a cursor during pagination. */ +export type ProductVariantEdge = { + __typename?: 'ProductVariantEdge' + /** A cursor for use in pagination. */ + cursor: Scalars['String'] + /** The item at the end of ProductVariantEdge. */ + node: ProductVariant +} + +/** The compare-at price and price of a variant sharing a currency. */ +export type ProductVariantPricePair = { + __typename?: 'ProductVariantPricePair' + /** The compare-at price of the variant with associated currency. */ + compareAtPrice?: Maybe + /** The price of the variant with associated currency. */ + price: MoneyV2 +} + +/** An auto-generated type for paginating through multiple ProductVariantPricePairs. */ +export type ProductVariantPricePairConnection = { + __typename?: 'ProductVariantPricePairConnection' + /** A list of edges. */ + edges: Array + /** Information to aid in pagination. */ + pageInfo: PageInfo +} + +/** An auto-generated type which holds one ProductVariantPricePair and a cursor during pagination. */ +export type ProductVariantPricePairEdge = { + __typename?: 'ProductVariantPricePairEdge' + /** A cursor for use in pagination. */ + cursor: Scalars['String'] + /** The item at the end of ProductVariantPricePairEdge. */ + node: ProductVariantPricePair +} + +/** The set of valid sort keys for the ProductVariant query. */ +export enum ProductVariantSortKeys { + /** Sort by the `title` value. */ + Title = 'TITLE', + /** Sort by the `sku` value. */ + Sku = 'SKU', + /** Sort by the `position` value. */ + Position = 'POSITION', + /** Sort by the `id` value. */ + Id = 'ID', + /** + * During a search (i.e. when the `query` parameter has been specified on the connection) this sorts the + * results by relevance to the search term(s). When no search query is specified, this sort key is not + * deterministic and should not be used. + */ + Relevance = 'RELEVANCE', +} + +/** The schema’s entry-point for queries. This acts as the public, top-level API from which all queries must start. */ +export type QueryRoot = { + __typename?: 'QueryRoot' + /** List of the shop's articles. */ + articles: ArticleConnection + /** Find a blog by its handle. */ + blogByHandle?: Maybe + /** List of the shop's blogs. */ + blogs: BlogConnection + /** Find a collection by its handle. */ + collectionByHandle?: Maybe + /** List of the shop’s collections. */ + collections: CollectionConnection + /** Find a customer by its access token. */ + customer?: Maybe + node?: Maybe + nodes: Array> + /** Find a page by its handle. */ + pageByHandle?: Maybe + /** List of the shop's pages. */ + pages: PageConnection + /** Find a product by its handle. */ + productByHandle?: Maybe + /** + * Find recommended products related to a given `product_id`. + * To learn more about how recommendations are generated, see + * [*Showing product recommendations on product pages*](https://help.shopify.com/themes/development/recommended-products). + */ + productRecommendations?: Maybe> + /** + * Tags added to products. + * Additional access scope required: unauthenticated_read_product_tags. + */ + productTags: StringConnection + /** List of product types for the shop's products that are published to your app. */ + productTypes: StringConnection + /** List of the shop’s products. */ + products: ProductConnection + /** The list of public Storefront API versions, including supported, release candidate and unstable versions. */ + publicApiVersions: Array + /** The shop associated with the storefront access token. */ + shop: Shop +} + +/** The schema’s entry-point for queries. This acts as the public, top-level API from which all queries must start. */ +export type QueryRootArticlesArgs = { + first?: Maybe + after?: Maybe + last?: Maybe + before?: Maybe + reverse?: Maybe + sortKey?: Maybe + query?: Maybe +} + +/** The schema’s entry-point for queries. This acts as the public, top-level API from which all queries must start. */ +export type QueryRootBlogByHandleArgs = { + handle: Scalars['String'] +} + +/** The schema’s entry-point for queries. This acts as the public, top-level API from which all queries must start. */ +export type QueryRootBlogsArgs = { + first?: Maybe + after?: Maybe + last?: Maybe + before?: Maybe + reverse?: Maybe + sortKey?: Maybe + query?: Maybe +} + +/** The schema’s entry-point for queries. This acts as the public, top-level API from which all queries must start. */ +export type QueryRootCollectionByHandleArgs = { + handle: Scalars['String'] +} + +/** The schema’s entry-point for queries. This acts as the public, top-level API from which all queries must start. */ +export type QueryRootCollectionsArgs = { + first?: Maybe + after?: Maybe + last?: Maybe + before?: Maybe + reverse?: Maybe + sortKey?: Maybe + query?: Maybe +} + +/** The schema’s entry-point for queries. This acts as the public, top-level API from which all queries must start. */ +export type QueryRootCustomerArgs = { + customerAccessToken: Scalars['String'] +} + +/** The schema’s entry-point for queries. This acts as the public, top-level API from which all queries must start. */ +export type QueryRootNodeArgs = { + id: Scalars['ID'] +} + +/** The schema’s entry-point for queries. This acts as the public, top-level API from which all queries must start. */ +export type QueryRootNodesArgs = { + ids: Array +} + +/** The schema’s entry-point for queries. This acts as the public, top-level API from which all queries must start. */ +export type QueryRootPageByHandleArgs = { + handle: Scalars['String'] +} + +/** The schema’s entry-point for queries. This acts as the public, top-level API from which all queries must start. */ +export type QueryRootPagesArgs = { + first?: Maybe + after?: Maybe + last?: Maybe + before?: Maybe + reverse?: Maybe + sortKey?: Maybe + query?: Maybe +} + +/** The schema’s entry-point for queries. This acts as the public, top-level API from which all queries must start. */ +export type QueryRootProductByHandleArgs = { + handle: Scalars['String'] +} + +/** The schema’s entry-point for queries. This acts as the public, top-level API from which all queries must start. */ +export type QueryRootProductRecommendationsArgs = { + productId: Scalars['ID'] +} + +/** The schema’s entry-point for queries. This acts as the public, top-level API from which all queries must start. */ +export type QueryRootProductTagsArgs = { + first: Scalars['Int'] +} + +/** The schema’s entry-point for queries. This acts as the public, top-level API from which all queries must start. */ +export type QueryRootProductTypesArgs = { + first: Scalars['Int'] +} + +/** The schema’s entry-point for queries. This acts as the public, top-level API from which all queries must start. */ +export type QueryRootProductsArgs = { + first?: Maybe + after?: Maybe + last?: Maybe + before?: Maybe + reverse?: Maybe + sortKey?: Maybe + query?: Maybe +} + +/** SEO information. */ +export type Seo = { + __typename?: 'SEO' + /** The meta description. */ + description?: Maybe + /** The SEO title. */ + title?: Maybe +} + +/** + * Script discount applications capture the intentions of a discount that + * was created by a Shopify Script. + */ +export type ScriptDiscountApplication = DiscountApplication & { + __typename?: 'ScriptDiscountApplication' + /** The method by which the discount's value is allocated to its entitled items. */ + allocationMethod: DiscountApplicationAllocationMethod + /** + * The description of the application as defined by the Script. + * @deprecated Use `title` instead + */ + description: Scalars['String'] + /** Which lines of targetType that the discount is allocated over. */ + targetSelection: DiscountApplicationTargetSelection + /** The type of line that the discount is applicable towards. */ + targetType: DiscountApplicationTargetType + /** The title of the application as defined by the Script. */ + title: Scalars['String'] + /** The value of the discount application. */ + value: PricingValue +} + +/** + * Properties used by customers to select a product variant. + * Products can have multiple options, like different sizes or colors. + */ +export type SelectedOption = { + __typename?: 'SelectedOption' + /** The product option’s name. */ + name: Scalars['String'] + /** The product option’s value. */ + value: Scalars['String'] +} + +/** Specifies the input fields required for a selected option. */ +export type SelectedOptionInput = { + /** The product option’s name. */ + name: Scalars['String'] + /** The product option’s value. */ + value: Scalars['String'] +} + +/** A shipping rate to be applied to a checkout. */ +export type ShippingRate = { + __typename?: 'ShippingRate' + /** Human-readable unique identifier for this shipping rate. */ + handle: Scalars['String'] + /** + * Price of this shipping rate. + * @deprecated Use `priceV2` instead + */ + price: Scalars['Money'] + /** Price of this shipping rate. */ + priceV2: MoneyV2 + /** Title of this shipping rate. */ + title: Scalars['String'] +} + +/** Shop represents a collection of the general settings and information about the shop. */ +export type Shop = { + __typename?: 'Shop' + /** + * List of the shop' articles. + * @deprecated Use `QueryRoot.articles` instead. + */ + articles: ArticleConnection + /** + * List of the shop' blogs. + * @deprecated Use `QueryRoot.blogs` instead. + */ + blogs: BlogConnection + /** + * Find a collection by its handle. + * @deprecated Use `QueryRoot.collectionByHandle` instead. + */ + collectionByHandle?: Maybe + /** + * List of the shop’s collections. + * @deprecated Use `QueryRoot.collections` instead. + */ + collections: CollectionConnection + /** + * The three-letter code for the currency that the shop accepts. + * @deprecated Use `paymentSettings` instead + */ + currencyCode: CurrencyCode + /** A description of the shop. */ + description?: Maybe + /** A string representing the way currency is formatted when the currency isn’t specified. */ + moneyFormat: Scalars['String'] + /** The shop’s name. */ + name: Scalars['String'] + /** Settings related to payments. */ + paymentSettings: PaymentSettings + /** The shop’s primary domain. */ + primaryDomain: Domain + /** The shop’s privacy policy. */ + privacyPolicy?: Maybe + /** + * Find a product by its handle. + * @deprecated Use `QueryRoot.productByHandle` instead. + */ + productByHandle?: Maybe + /** + * A list of tags that have been added to products. + * Additional access scope required: unauthenticated_read_product_tags. + * @deprecated Use `QueryRoot.productTags` instead. + */ + productTags: StringConnection + /** + * List of the shop’s product types. + * @deprecated Use `QueryRoot.productTypes` instead. + */ + productTypes: StringConnection + /** + * List of the shop’s products. + * @deprecated Use `QueryRoot.products` instead. + */ + products: ProductConnection + /** The shop’s refund policy. */ + refundPolicy?: Maybe + /** The shop’s shipping policy. */ + shippingPolicy?: Maybe + /** Countries that the shop ships to. */ + shipsToCountries: Array + /** + * The shop’s Shopify Payments account id. + * @deprecated Use `paymentSettings` instead + */ + shopifyPaymentsAccountId?: Maybe + /** The shop’s terms of service. */ + termsOfService?: Maybe +} + +/** Shop represents a collection of the general settings and information about the shop. */ +export type ShopArticlesArgs = { + first?: Maybe + after?: Maybe + last?: Maybe + before?: Maybe + reverse?: Maybe + sortKey?: Maybe + query?: Maybe +} + +/** Shop represents a collection of the general settings and information about the shop. */ +export type ShopBlogsArgs = { + first?: Maybe + after?: Maybe + last?: Maybe + before?: Maybe + reverse?: Maybe + sortKey?: Maybe + query?: Maybe +} + +/** Shop represents a collection of the general settings and information about the shop. */ +export type ShopCollectionByHandleArgs = { + handle: Scalars['String'] +} + +/** Shop represents a collection of the general settings and information about the shop. */ +export type ShopCollectionsArgs = { + first?: Maybe + after?: Maybe + last?: Maybe + before?: Maybe + reverse?: Maybe + sortKey?: Maybe + query?: Maybe +} + +/** Shop represents a collection of the general settings and information about the shop. */ +export type ShopProductByHandleArgs = { + handle: Scalars['String'] +} + +/** Shop represents a collection of the general settings and information about the shop. */ +export type ShopProductTagsArgs = { + first: Scalars['Int'] +} + +/** Shop represents a collection of the general settings and information about the shop. */ +export type ShopProductTypesArgs = { + first: Scalars['Int'] +} + +/** Shop represents a collection of the general settings and information about the shop. */ +export type ShopProductsArgs = { + first?: Maybe + after?: Maybe + last?: Maybe + before?: Maybe + reverse?: Maybe + sortKey?: Maybe + query?: Maybe +} + +/** Policy that a merchant has configured for their store, such as their refund or privacy policy. */ +export type ShopPolicy = Node & { + __typename?: 'ShopPolicy' + /** Policy text, maximum size of 64kb. */ + body: Scalars['String'] + /** Policy’s handle. */ + handle: Scalars['String'] + /** Globally unique identifier. */ + id: Scalars['ID'] + /** Policy’s title. */ + title: Scalars['String'] + /** Public URL to the policy. */ + url: Scalars['URL'] +} + +/** An auto-generated type for paginating through multiple Strings. */ +export type StringConnection = { + __typename?: 'StringConnection' + /** A list of edges. */ + edges: Array + /** Information to aid in pagination. */ + pageInfo: PageInfo +} + +/** An auto-generated type which holds one String and a cursor during pagination. */ +export type StringEdge = { + __typename?: 'StringEdge' + /** A cursor for use in pagination. */ + cursor: Scalars['String'] + /** The item at the end of StringEdge. */ + node: Scalars['String'] +} + +/** + * Specifies the fields required to complete a checkout with + * a tokenized payment. + */ +export type TokenizedPaymentInput = { + /** The amount of the payment. */ + amount: Scalars['Money'] + /** A unique client generated key used to avoid duplicate charges. When a duplicate payment is found, the original is returned instead of creating a new one. */ + idempotencyKey: Scalars['String'] + /** The billing address for the payment. */ + billingAddress: MailingAddressInput + /** The type of payment token. */ + type: Scalars['String'] + /** A simple string or JSON containing the required payment data for the tokenized payment. */ + paymentData: Scalars['String'] + /** Executes the payment in test mode if possible. Defaults to `false`. */ + test?: Maybe + /** Public Hash Key used for AndroidPay payments only. */ + identifier?: Maybe +} + +/** + * Specifies the fields required to complete a checkout with + * a tokenized payment. + */ +export type TokenizedPaymentInputV2 = { + /** The amount and currency of the payment. */ + paymentAmount: MoneyInput + /** A unique client generated key used to avoid duplicate charges. When a duplicate payment is found, the original is returned instead of creating a new one. */ + idempotencyKey: Scalars['String'] + /** The billing address for the payment. */ + billingAddress: MailingAddressInput + /** A simple string or JSON containing the required payment data for the tokenized payment. */ + paymentData: Scalars['String'] + /** Whether to execute the payment in test mode, if possible. Test mode is not supported in production stores. Defaults to `false`. */ + test?: Maybe + /** Public Hash Key used for AndroidPay payments only. */ + identifier?: Maybe + /** The type of payment token. */ + type: Scalars['String'] +} + +/** + * Specifies the fields required to complete a checkout with + * a tokenized payment. + */ +export type TokenizedPaymentInputV3 = { + /** The amount and currency of the payment. */ + paymentAmount: MoneyInput + /** A unique client generated key used to avoid duplicate charges. When a duplicate payment is found, the original is returned instead of creating a new one. */ + idempotencyKey: Scalars['String'] + /** The billing address for the payment. */ + billingAddress: MailingAddressInput + /** A simple string or JSON containing the required payment data for the tokenized payment. */ + paymentData: Scalars['String'] + /** Whether to execute the payment in test mode, if possible. Test mode is not supported in production stores. Defaults to `false`. */ + test?: Maybe + /** Public Hash Key used for AndroidPay payments only. */ + identifier?: Maybe + /** The type of payment token. */ + type: PaymentTokenType +} + +/** An object representing exchange of money for a product or service. */ +export type Transaction = { + __typename?: 'Transaction' + /** + * The amount of money that the transaction was for. + * @deprecated Use `amountV2` instead + */ + amount: Scalars['Money'] + /** The amount of money that the transaction was for. */ + amountV2: MoneyV2 + /** The kind of the transaction. */ + kind: TransactionKind + /** + * The status of the transaction. + * @deprecated Use `statusV2` instead + */ + status: TransactionStatus + /** The status of the transaction. */ + statusV2?: Maybe + /** Whether the transaction was done in test mode or not. */ + test: Scalars['Boolean'] +} + +export enum TransactionKind { + Sale = 'SALE', + Capture = 'CAPTURE', + Authorization = 'AUTHORIZATION', + EmvAuthorization = 'EMV_AUTHORIZATION', + Change = 'CHANGE', +} + +export enum TransactionStatus { + Pending = 'PENDING', + Success = 'SUCCESS', + Failure = 'FAILURE', + Error = 'ERROR', +} + +/** The measurement used to calculate a unit price for a product variant (e.g. $9.99 / 100ml). */ +export type UnitPriceMeasurement = { + __typename?: 'UnitPriceMeasurement' + /** The type of unit of measurement for the unit price measurement. */ + measuredType?: Maybe + /** The quantity unit for the unit price measurement. */ + quantityUnit?: Maybe + /** The quantity value for the unit price measurement. */ + quantityValue: Scalars['Float'] + /** The reference unit for the unit price measurement. */ + referenceUnit?: Maybe + /** The reference value for the unit price measurement. */ + referenceValue: Scalars['Int'] +} + +/** The accepted types of unit of measurement. */ +export enum UnitPriceMeasurementMeasuredType { + /** Unit of measurements representing volumes. */ + Volume = 'VOLUME', + /** Unit of measurements representing weights. */ + Weight = 'WEIGHT', + /** Unit of measurements representing lengths. */ + Length = 'LENGTH', + /** Unit of measurements representing areas. */ + Area = 'AREA', +} + +/** The valid units of measurement for a unit price measurement. */ +export enum UnitPriceMeasurementMeasuredUnit { + /** 1000 milliliters equals 1 liter. */ + Ml = 'ML', + /** 100 centiliters equals 1 liter. */ + Cl = 'CL', + /** Metric system unit of volume. */ + L = 'L', + /** 1 cubic meter equals 1000 liters. */ + M3 = 'M3', + /** 1000 milligrams equals 1 gram. */ + Mg = 'MG', + /** Metric system unit of weight. */ + G = 'G', + /** 1 kilogram equals 1000 grams. */ + Kg = 'KG', + /** 1000 millimeters equals 1 meter. */ + Mm = 'MM', + /** 100 centimeters equals 1 meter. */ + Cm = 'CM', + /** Metric system unit of length. */ + M = 'M', + /** Metric system unit of area. */ + M2 = 'M2', +} + +/** Represents an error in the input of a mutation. */ +export type UserError = DisplayableError & { + __typename?: 'UserError' + /** Path to the input field which caused the error. */ + field?: Maybe> + /** The error message. */ + message: Scalars['String'] +} + +/** Represents a Shopify hosted video. */ +export type Video = Node & + Media & { + __typename?: 'Video' + /** A word or phrase to share the nature or contents of a media. */ + alt?: Maybe + /** Globally unique identifier. */ + id: Scalars['ID'] + /** The media content type. */ + mediaContentType: MediaContentType + /** The preview image for the media. */ + previewImage?: Maybe + /** The sources for a video. */ + sources: Array + } + +/** Represents a source for a Shopify hosted video. */ +export type VideoSource = { + __typename?: 'VideoSource' + /** The format of the video source. */ + format: Scalars['String'] + /** The height of the video. */ + height: Scalars['Int'] + /** The video MIME type. */ + mimeType: Scalars['String'] + /** The URL of the video. */ + url: Scalars['String'] + /** The width of the video. */ + width: Scalars['Int'] +} + +/** Units of measurement for weight. */ +export enum WeightUnit { + /** 1 kilogram equals 1000 grams. */ + Kilograms = 'KILOGRAMS', + /** Metric system unit of mass. */ + Grams = 'GRAMS', + /** 1 pound equals 16 ounces. */ + Pounds = 'POUNDS', + /** Imperial system unit of mass. */ + Ounces = 'OUNCES', +} + +export type Unnamed_1_QueryVariables = Exact<{ + first: Scalars['Int'] +}> + +export type Unnamed_1_Query = { __typename?: 'QueryRoot' } & { + pages: { __typename?: 'PageConnection' } & { + edges: Array< + { __typename?: 'PageEdge' } & { + node: { __typename?: 'Page' } & Pick< + Page, + 'id' | 'title' | 'handle' | 'body' | 'bodySummary' | 'url' + > + } + > + } +} diff --git a/framework/swell/schema.graphql b/framework/swell/schema.graphql new file mode 100644 index 000000000..822e6007e --- /dev/null +++ b/framework/swell/schema.graphql @@ -0,0 +1,9631 @@ +schema { + query: QueryRoot + mutation: Mutation +} + +""" +Marks an element of a GraphQL schema as having restricted access. +""" +directive @accessRestricted( + """ + Explains the reason around this restriction + """ + reason: String = null +) on FIELD_DEFINITION | OBJECT + +""" +A version of the API. +""" +type ApiVersion { + """ + The human-readable name of the version. + """ + displayName: String! + + """ + The unique identifier of an ApiVersion. All supported API versions have a date-based (YYYY-MM) or `unstable` handle. + """ + handle: String! + + """ + Whether the version is supported by Shopify. + """ + supported: Boolean! +} + +""" +Details about the gift card used on the checkout. +""" +type AppliedGiftCard implements Node { + """ + The amount that was taken from the gift card by applying it. + """ + amountUsed: Money! @deprecated(reason: "Use `amountUsedV2` instead") + + """ + The amount that was taken from the gift card by applying it. + """ + amountUsedV2: MoneyV2! + + """ + The amount left on the gift card. + """ + balance: Money! @deprecated(reason: "Use `balanceV2` instead") + + """ + The amount left on the gift card. + """ + balanceV2: MoneyV2! + + """ + Globally unique identifier. + """ + id: ID! + + """ + The last characters of the gift card. + """ + lastCharacters: String! + + """ + The amount that was applied to the checkout in its currency. + """ + presentmentAmountUsed: MoneyV2! +} + +""" +An article in an online store blog. +""" +type Article implements Node { + """ + The article's author. + """ + author: ArticleAuthor! @deprecated(reason: "Use `authorV2` instead") + + """ + The article's author. + """ + authorV2: ArticleAuthor + + """ + The blog that the article belongs to. + """ + blog: Blog! + + """ + List of comments posted on the article. + """ + comments( + """ + Returns up to the first `n` elements from the list. + """ + first: Int + + """ + Returns the elements that come after the specified cursor. + """ + after: String + + """ + Returns up to the last `n` elements from the list. + """ + last: Int + + """ + Returns the elements that come before the specified cursor. + """ + before: String + + """ + Reverse the order of the underlying list. + """ + reverse: Boolean = false + ): CommentConnection! + + """ + Stripped content of the article, single line with HTML tags removed. + """ + content( + """ + Truncates string after the given length. + """ + truncateAt: Int + ): String! + + """ + The content of the article, complete with HTML formatting. + """ + contentHtml: HTML! + + """ + Stripped excerpt of the article, single line with HTML tags removed. + """ + excerpt( + """ + Truncates string after the given length. + """ + truncateAt: Int + ): String + + """ + The excerpt of the article, complete with HTML formatting. + """ + excerptHtml: HTML + + """ + A human-friendly unique string for the Article automatically generated from its title. + """ + handle: String! + + """ + Globally unique identifier. + """ + id: ID! + + """ + The image associated with the article. + """ + image( + """ + Image width in pixels between 1 and 2048. This argument is deprecated: Use `maxWidth` on `Image.transformedSrc` instead. + """ + maxWidth: Int + + """ + Image height in pixels between 1 and 2048. This argument is deprecated: Use `maxHeight` on `Image.transformedSrc` instead. + """ + maxHeight: Int + + """ + Crops the image according to the specified region. This argument is deprecated: Use `crop` on `Image.transformedSrc` instead. + """ + crop: CropRegion + + """ + Image size multiplier for high-resolution retina displays. Must be between 1 and 3. This argument is deprecated: Use `scale` on `Image.transformedSrc` instead. + """ + scale: Int = 1 + ): Image + + """ + The date and time when the article was published. + """ + publishedAt: DateTime! + + """ + The article’s SEO information. + """ + seo: SEO + + """ + A categorization that a article can be tagged with. + """ + tags: [String!]! + + """ + The article’s name. + """ + title: String! + + """ + The url pointing to the article accessible from the web. + """ + url: URL! +} + +""" +The author of an article. +""" +type ArticleAuthor { + """ + The author's bio. + """ + bio: String + + """ + The author’s email. + """ + email: String! + + """ + The author's first name. + """ + firstName: String! + + """ + The author's last name. + """ + lastName: String! + + """ + The author's full name. + """ + name: String! +} + +""" +An auto-generated type for paginating through multiple Articles. +""" +type ArticleConnection { + """ + A list of edges. + """ + edges: [ArticleEdge!]! + + """ + Information to aid in pagination. + """ + pageInfo: PageInfo! +} + +""" +An auto-generated type which holds one Article and a cursor during pagination. +""" +type ArticleEdge { + """ + A cursor for use in pagination. + """ + cursor: String! + + """ + The item at the end of ArticleEdge. + """ + node: Article! +} + +""" +The set of valid sort keys for the Article query. +""" +enum ArticleSortKeys { + """ + Sort by the `title` value. + """ + TITLE + + """ + Sort by the `blog_title` value. + """ + BLOG_TITLE + + """ + Sort by the `author` value. + """ + AUTHOR + + """ + Sort by the `updated_at` value. + """ + UPDATED_AT + + """ + Sort by the `published_at` value. + """ + PUBLISHED_AT + + """ + Sort by the `id` value. + """ + ID + + """ + During a search (i.e. when the `query` parameter has been specified on the connection) this sorts the + results by relevance to the search term(s). When no search query is specified, this sort key is not + deterministic and should not be used. + """ + RELEVANCE +} + +""" +Represents a generic custom attribute. +""" +type Attribute { + """ + Key or name of the attribute. + """ + key: String! + + """ + Value of the attribute. + """ + value: String +} + +""" +Specifies the input fields required for an attribute. +""" +input AttributeInput { + """ + Key or name of the attribute. + """ + key: String! + + """ + Value of the attribute. + """ + value: String! +} + +""" +Automatic discount applications capture the intentions of a discount that was automatically applied. +""" +type AutomaticDiscountApplication implements DiscountApplication { + """ + The method by which the discount's value is allocated to its entitled items. + """ + allocationMethod: DiscountApplicationAllocationMethod! + + """ + Which lines of targetType that the discount is allocated over. + """ + targetSelection: DiscountApplicationTargetSelection! + + """ + The type of line that the discount is applicable towards. + """ + targetType: DiscountApplicationTargetType! + + """ + The title of the application. + """ + title: String! + + """ + The value of the discount application. + """ + value: PricingValue! +} + +""" +A collection of available shipping rates for a checkout. +""" +type AvailableShippingRates { + """ + Whether or not the shipping rates are ready. + The `shippingRates` field is `null` when this value is `false`. + This field should be polled until its value becomes `true`. + """ + ready: Boolean! + + """ + The fetched shipping rates. `null` until the `ready` field is `true`. + """ + shippingRates: [ShippingRate!] +} + +""" +An online store blog. +""" +type Blog implements Node { + """ + Find an article by its handle. + """ + articleByHandle( + """ + The handle of the article. + """ + handle: String! + ): Article + + """ + List of the blog's articles. + """ + articles( + """ + Returns up to the first `n` elements from the list. + """ + first: Int + + """ + Returns the elements that come after the specified cursor. + """ + after: String + + """ + Returns up to the last `n` elements from the list. + """ + last: Int + + """ + Returns the elements that come before the specified cursor. + """ + before: String + + """ + Reverse the order of the underlying list. + """ + reverse: Boolean = false + + """ + Sort the underlying list by the given key. + """ + sortKey: ArticleSortKeys = ID + + """ + Supported filter parameters: + - `author` + - `blog_title` + - `created_at` + - `tag` + - `updated_at` + + See the detailed [search syntax](https://help.shopify.com/api/getting-started/search-syntax) + for more information about using filters. + """ + query: String + ): ArticleConnection! + + """ + The authors who have contributed to the blog. + """ + authors: [ArticleAuthor!]! + + """ + A human-friendly unique string for the Blog automatically generated from its title. + """ + handle: String! + + """ + Globally unique identifier. + """ + id: ID! + + """ + The blog's SEO information. + """ + seo: SEO + + """ + The blogs’s title. + """ + title: String! + + """ + The url pointing to the blog accessible from the web. + """ + url: URL! +} + +""" +An auto-generated type for paginating through multiple Blogs. +""" +type BlogConnection { + """ + A list of edges. + """ + edges: [BlogEdge!]! + + """ + Information to aid in pagination. + """ + pageInfo: PageInfo! +} + +""" +An auto-generated type which holds one Blog and a cursor during pagination. +""" +type BlogEdge { + """ + A cursor for use in pagination. + """ + cursor: String! + + """ + The item at the end of BlogEdge. + """ + node: Blog! +} + +""" +The set of valid sort keys for the Blog query. +""" +enum BlogSortKeys { + """ + Sort by the `handle` value. + """ + HANDLE + + """ + Sort by the `title` value. + """ + TITLE + + """ + Sort by the `id` value. + """ + ID + + """ + During a search (i.e. when the `query` parameter has been specified on the connection) this sorts the + results by relevance to the search term(s). When no search query is specified, this sort key is not + deterministic and should not be used. + """ + RELEVANCE +} + +""" +Card brand, such as Visa or Mastercard, which can be used for payments. +""" +enum CardBrand { + """ + Visa + """ + VISA + + """ + Mastercard + """ + MASTERCARD + + """ + Discover + """ + DISCOVER + + """ + American Express + """ + AMERICAN_EXPRESS + + """ + Diners Club + """ + DINERS_CLUB + + """ + JCB + """ + JCB +} + +""" +A container for all the information required to checkout items and pay. +""" +type Checkout implements Node { + """ + The gift cards used on the checkout. + """ + appliedGiftCards: [AppliedGiftCard!]! + + """ + The available shipping rates for this Checkout. + Should only be used when checkout `requiresShipping` is `true` and + the shipping address is valid. + """ + availableShippingRates: AvailableShippingRates + + """ + The date and time when the checkout was completed. + """ + completedAt: DateTime + + """ + The date and time when the checkout was created. + """ + createdAt: DateTime! + + """ + The currency code for the Checkout. + """ + currencyCode: CurrencyCode! + + """ + A list of extra information that is added to the checkout. + """ + customAttributes: [Attribute!]! + + """ + The customer associated with the checkout. + """ + customer: Customer + @deprecated( + reason: "This field will always return null. If you have an authentication token for the customer, you can use the `customer` field on the query root to retrieve it." + ) + + """ + Discounts that have been applied on the checkout. + """ + discountApplications( + """ + Returns up to the first `n` elements from the list. + """ + first: Int + + """ + Returns the elements that come after the specified cursor. + """ + after: String + + """ + Returns up to the last `n` elements from the list. + """ + last: Int + + """ + Returns the elements that come before the specified cursor. + """ + before: String + + """ + Reverse the order of the underlying list. + """ + reverse: Boolean = false + ): DiscountApplicationConnection! + + """ + The email attached to this checkout. + """ + email: String + + """ + Globally unique identifier. + """ + id: ID! + + """ + A list of line item objects, each one containing information about an item in the checkout. + """ + lineItems( + """ + Returns up to the first `n` elements from the list. + """ + first: Int + + """ + Returns the elements that come after the specified cursor. + """ + after: String + + """ + Returns up to the last `n` elements from the list. + """ + last: Int + + """ + Returns the elements that come before the specified cursor. + """ + before: String + + """ + Reverse the order of the underlying list. + """ + reverse: Boolean = false + ): CheckoutLineItemConnection! + + """ + The sum of all the prices of all the items in the checkout. Duties, taxes, shipping and discounts excluded. + """ + lineItemsSubtotalPrice: MoneyV2! + + """ + The note associated with the checkout. + """ + note: String + + """ + The resulting order from a paid checkout. + """ + order: Order + + """ + The Order Status Page for this Checkout, null when checkout is not completed. + """ + orderStatusUrl: URL + + """ + The amount left to be paid. This is equal to the cost of the line items, taxes and shipping minus discounts and gift cards. + """ + paymentDue: Money! @deprecated(reason: "Use `paymentDueV2` instead") + + """ + The amount left to be paid. This is equal to the cost of the line items, duties, taxes and shipping minus discounts and gift cards. + """ + paymentDueV2: MoneyV2! + + """ + Whether or not the Checkout is ready and can be completed. Checkouts may + have asynchronous operations that can take time to finish. If you want + to complete a checkout or ensure all the fields are populated and up to + date, polling is required until the value is true. + """ + ready: Boolean! + + """ + States whether or not the fulfillment requires shipping. + """ + requiresShipping: Boolean! + + """ + The shipping address to where the line items will be shipped. + """ + shippingAddress: MailingAddress + + """ + The discounts that have been allocated onto the shipping line by discount applications. + """ + shippingDiscountAllocations: [DiscountAllocation!]! + + """ + Once a shipping rate is selected by the customer it is transitioned to a `shipping_line` object. + """ + shippingLine: ShippingRate + + """ + Price of the checkout before shipping and taxes. + """ + subtotalPrice: Money! @deprecated(reason: "Use `subtotalPriceV2` instead") + + """ + Price of the checkout before duties, shipping and taxes. + """ + subtotalPriceV2: MoneyV2! + + """ + Specifies if the Checkout is tax exempt. + """ + taxExempt: Boolean! + + """ + Specifies if taxes are included in the line item and shipping line prices. + """ + taxesIncluded: Boolean! + + """ + The sum of all the prices of all the items in the checkout, taxes and discounts included. + """ + totalPrice: Money! @deprecated(reason: "Use `totalPriceV2` instead") + + """ + The sum of all the prices of all the items in the checkout, duties, taxes and discounts included. + """ + totalPriceV2: MoneyV2! + + """ + The sum of all the taxes applied to the line items and shipping lines in the checkout. + """ + totalTax: Money! @deprecated(reason: "Use `totalTaxV2` instead") + + """ + The sum of all the taxes applied to the line items and shipping lines in the checkout. + """ + totalTaxV2: MoneyV2! + + """ + The date and time when the checkout was last updated. + """ + updatedAt: DateTime! + + """ + The url pointing to the checkout accessible from the web. + """ + webUrl: URL! +} + +""" +Specifies the fields required to update a checkout's attributes. +""" +input CheckoutAttributesUpdateInput { + """ + The text of an optional note that a shop owner can attach to the checkout. + """ + note: String + + """ + A list of extra information that is added to the checkout. + """ + customAttributes: [AttributeInput!] + + """ + Allows setting partial addresses on a Checkout, skipping the full validation of attributes. + The required attributes are city, province, and country. + Full validation of the addresses is still done at complete time. + """ + allowPartialAddresses: Boolean +} + +""" +Return type for `checkoutAttributesUpdate` mutation. +""" +type CheckoutAttributesUpdatePayload { + """ + The updated checkout object. + """ + checkout: Checkout! + + """ + List of errors that occurred executing the mutation. + """ + checkoutUserErrors: [CheckoutUserError!]! + + """ + List of errors that occurred executing the mutation. + """ + userErrors: [UserError!]! + @deprecated(reason: "Use `checkoutUserErrors` instead") +} + +""" +Specifies the fields required to update a checkout's attributes. +""" +input CheckoutAttributesUpdateV2Input { + """ + The text of an optional note that a shop owner can attach to the checkout. + """ + note: String + + """ + A list of extra information that is added to the checkout. + """ + customAttributes: [AttributeInput!] + + """ + Allows setting partial addresses on a Checkout, skipping the full validation of attributes. + The required attributes are city, province, and country. + Full validation of the addresses is still done at complete time. + """ + allowPartialAddresses: Boolean +} + +""" +Return type for `checkoutAttributesUpdateV2` mutation. +""" +type CheckoutAttributesUpdateV2Payload { + """ + The updated checkout object. + """ + checkout: Checkout + + """ + List of errors that occurred executing the mutation. + """ + checkoutUserErrors: [CheckoutUserError!]! + + """ + List of errors that occurred executing the mutation. + """ + userErrors: [UserError!]! + @deprecated(reason: "Use `checkoutUserErrors` instead") +} + +""" +Return type for `checkoutCompleteFree` mutation. +""" +type CheckoutCompleteFreePayload { + """ + The updated checkout object. + """ + checkout: Checkout + + """ + List of errors that occurred executing the mutation. + """ + checkoutUserErrors: [CheckoutUserError!]! + + """ + List of errors that occurred executing the mutation. + """ + userErrors: [UserError!]! + @deprecated(reason: "Use `checkoutUserErrors` instead") +} + +""" +Return type for `checkoutCompleteWithCreditCard` mutation. +""" +type CheckoutCompleteWithCreditCardPayload { + """ + The checkout on which the payment was applied. + """ + checkout: Checkout! + + """ + List of errors that occurred executing the mutation. + """ + checkoutUserErrors: [CheckoutUserError!]! + + """ + A representation of the attempted payment. + """ + payment: Payment + + """ + List of errors that occurred executing the mutation. + """ + userErrors: [UserError!]! + @deprecated(reason: "Use `checkoutUserErrors` instead") +} + +""" +Return type for `checkoutCompleteWithCreditCardV2` mutation. +""" +type CheckoutCompleteWithCreditCardV2Payload { + """ + The checkout on which the payment was applied. + """ + checkout: Checkout + + """ + List of errors that occurred executing the mutation. + """ + checkoutUserErrors: [CheckoutUserError!]! + + """ + A representation of the attempted payment. + """ + payment: Payment + + """ + List of errors that occurred executing the mutation. + """ + userErrors: [UserError!]! + @deprecated(reason: "Use `checkoutUserErrors` instead") +} + +""" +Return type for `checkoutCompleteWithTokenizedPayment` mutation. +""" +type CheckoutCompleteWithTokenizedPaymentPayload { + """ + The checkout on which the payment was applied. + """ + checkout: Checkout! + + """ + List of errors that occurred executing the mutation. + """ + checkoutUserErrors: [CheckoutUserError!]! + + """ + A representation of the attempted payment. + """ + payment: Payment + + """ + List of errors that occurred executing the mutation. + """ + userErrors: [UserError!]! + @deprecated(reason: "Use `checkoutUserErrors` instead") +} + +""" +Return type for `checkoutCompleteWithTokenizedPaymentV2` mutation. +""" +type CheckoutCompleteWithTokenizedPaymentV2Payload { + """ + The checkout on which the payment was applied. + """ + checkout: Checkout + + """ + List of errors that occurred executing the mutation. + """ + checkoutUserErrors: [CheckoutUserError!]! + + """ + A representation of the attempted payment. + """ + payment: Payment + + """ + List of errors that occurred executing the mutation. + """ + userErrors: [UserError!]! + @deprecated(reason: "Use `checkoutUserErrors` instead") +} + +""" +Return type for `checkoutCompleteWithTokenizedPaymentV3` mutation. +""" +type CheckoutCompleteWithTokenizedPaymentV3Payload { + """ + The checkout on which the payment was applied. + """ + checkout: Checkout + + """ + List of errors that occurred executing the mutation. + """ + checkoutUserErrors: [CheckoutUserError!]! + + """ + A representation of the attempted payment. + """ + payment: Payment + + """ + List of errors that occurred executing the mutation. + """ + userErrors: [UserError!]! + @deprecated(reason: "Use `checkoutUserErrors` instead") +} + +""" +Specifies the fields required to create a checkout. +""" +input CheckoutCreateInput { + """ + The email with which the customer wants to checkout. + """ + email: String + + """ + A list of line item objects, each one containing information about an item in the checkout. + """ + lineItems: [CheckoutLineItemInput!] + + """ + The shipping address to where the line items will be shipped. + """ + shippingAddress: MailingAddressInput + + """ + The text of an optional note that a shop owner can attach to the checkout. + """ + note: String + + """ + A list of extra information that is added to the checkout. + """ + customAttributes: [AttributeInput!] + + """ + Allows setting partial addresses on a Checkout, skipping the full validation of attributes. + The required attributes are city, province, and country. + Full validation of addresses is still done at complete time. + """ + allowPartialAddresses: Boolean + + """ + The three-letter currency code of one of the shop's enabled presentment currencies. + Including this field creates a checkout in the specified currency. By default, new + checkouts are created in the shop's primary currency. + """ + presentmentCurrencyCode: CurrencyCode +} + +""" +Return type for `checkoutCreate` mutation. +""" +type CheckoutCreatePayload { + """ + The new checkout object. + """ + checkout: Checkout + + """ + List of errors that occurred executing the mutation. + """ + checkoutUserErrors: [CheckoutUserError!]! + + """ + List of errors that occurred executing the mutation. + """ + userErrors: [UserError!]! + @deprecated(reason: "Use `checkoutUserErrors` instead") +} + +""" +Return type for `checkoutCustomerAssociate` mutation. +""" +type CheckoutCustomerAssociatePayload { + """ + The updated checkout object. + """ + checkout: Checkout! + + """ + The associated customer object. + """ + customer: Customer + + """ + List of errors that occurred executing the mutation. + """ + userErrors: [UserError!]! +} + +""" +Return type for `checkoutCustomerAssociateV2` mutation. +""" +type CheckoutCustomerAssociateV2Payload { + """ + The updated checkout object. + """ + checkout: Checkout + + """ + List of errors that occurred executing the mutation. + """ + checkoutUserErrors: [CheckoutUserError!]! + + """ + The associated customer object. + """ + customer: Customer + + """ + List of errors that occurred executing the mutation. + """ + userErrors: [UserError!]! + @deprecated(reason: "Use `checkoutUserErrors` instead") +} + +""" +Return type for `checkoutCustomerDisassociate` mutation. +""" +type CheckoutCustomerDisassociatePayload { + """ + The updated checkout object. + """ + checkout: Checkout! + + """ + List of errors that occurred executing the mutation. + """ + checkoutUserErrors: [CheckoutUserError!]! + + """ + List of errors that occurred executing the mutation. + """ + userErrors: [UserError!]! + @deprecated(reason: "Use `checkoutUserErrors` instead") +} + +""" +Return type for `checkoutCustomerDisassociateV2` mutation. +""" +type CheckoutCustomerDisassociateV2Payload { + """ + The updated checkout object. + """ + checkout: Checkout + + """ + List of errors that occurred executing the mutation. + """ + checkoutUserErrors: [CheckoutUserError!]! + + """ + List of errors that occurred executing the mutation. + """ + userErrors: [UserError!]! + @deprecated(reason: "Use `checkoutUserErrors` instead") +} + +""" +Return type for `checkoutDiscountCodeApply` mutation. +""" +type CheckoutDiscountCodeApplyPayload { + """ + The updated checkout object. + """ + checkout: Checkout! + + """ + List of errors that occurred executing the mutation. + """ + checkoutUserErrors: [CheckoutUserError!]! + + """ + List of errors that occurred executing the mutation. + """ + userErrors: [UserError!]! + @deprecated(reason: "Use `checkoutUserErrors` instead") +} + +""" +Return type for `checkoutDiscountCodeApplyV2` mutation. +""" +type CheckoutDiscountCodeApplyV2Payload { + """ + The updated checkout object. + """ + checkout: Checkout + + """ + List of errors that occurred executing the mutation. + """ + checkoutUserErrors: [CheckoutUserError!]! + + """ + List of errors that occurred executing the mutation. + """ + userErrors: [UserError!]! + @deprecated(reason: "Use `checkoutUserErrors` instead") +} + +""" +Return type for `checkoutDiscountCodeRemove` mutation. +""" +type CheckoutDiscountCodeRemovePayload { + """ + The updated checkout object. + """ + checkout: Checkout + + """ + List of errors that occurred executing the mutation. + """ + checkoutUserErrors: [CheckoutUserError!]! + + """ + List of errors that occurred executing the mutation. + """ + userErrors: [UserError!]! + @deprecated(reason: "Use `checkoutUserErrors` instead") +} + +""" +Return type for `checkoutEmailUpdate` mutation. +""" +type CheckoutEmailUpdatePayload { + """ + The checkout object with the updated email. + """ + checkout: Checkout! + + """ + List of errors that occurred executing the mutation. + """ + checkoutUserErrors: [CheckoutUserError!]! + + """ + List of errors that occurred executing the mutation. + """ + userErrors: [UserError!]! + @deprecated(reason: "Use `checkoutUserErrors` instead") +} + +""" +Return type for `checkoutEmailUpdateV2` mutation. +""" +type CheckoutEmailUpdateV2Payload { + """ + The checkout object with the updated email. + """ + checkout: Checkout + + """ + List of errors that occurred executing the mutation. + """ + checkoutUserErrors: [CheckoutUserError!]! + + """ + List of errors that occurred executing the mutation. + """ + userErrors: [UserError!]! + @deprecated(reason: "Use `checkoutUserErrors` instead") +} + +""" +Possible error codes that could be returned by CheckoutUserError. +""" +enum CheckoutErrorCode { + """ + Input value is blank. + """ + BLANK + + """ + Input value is invalid. + """ + INVALID + + """ + Input value is too long. + """ + TOO_LONG + + """ + Input value is not present. + """ + PRESENT + + """ + Input value should be less than maximum allowed value. + """ + LESS_THAN + + """ + Input value should be greater than or equal to minimum allowed value. + """ + GREATER_THAN_OR_EQUAL_TO + + """ + Input value should be less or equal to maximum allowed value. + """ + LESS_THAN_OR_EQUAL_TO + + """ + Checkout is already completed. + """ + ALREADY_COMPLETED + + """ + Checkout is locked. + """ + LOCKED + + """ + Input value is not supported. + """ + NOT_SUPPORTED + + """ + Input email contains an invalid domain name. + """ + BAD_DOMAIN + + """ + Input Zip is invalid for country provided. + """ + INVALID_FOR_COUNTRY + + """ + Input Zip is invalid for country and province provided. + """ + INVALID_FOR_COUNTRY_AND_PROVINCE + + """ + Invalid state in country. + """ + INVALID_STATE_IN_COUNTRY + + """ + Invalid province in country. + """ + INVALID_PROVINCE_IN_COUNTRY + + """ + Invalid region in country. + """ + INVALID_REGION_IN_COUNTRY + + """ + Shipping rate expired. + """ + SHIPPING_RATE_EXPIRED + + """ + Gift card cannot be applied to a checkout that contains a gift card. + """ + GIFT_CARD_UNUSABLE + + """ + Gift card is disabled. + """ + GIFT_CARD_DISABLED + + """ + Gift card code is invalid. + """ + GIFT_CARD_CODE_INVALID + + """ + Gift card has already been applied. + """ + GIFT_CARD_ALREADY_APPLIED + + """ + Gift card currency does not match checkout currency. + """ + GIFT_CARD_CURRENCY_MISMATCH + + """ + Gift card is expired. + """ + GIFT_CARD_EXPIRED + + """ + Gift card has no funds left. + """ + GIFT_CARD_DEPLETED + + """ + Gift card was not found. + """ + GIFT_CARD_NOT_FOUND + + """ + Cart does not meet discount requirements notice. + """ + CART_DOES_NOT_MEET_DISCOUNT_REQUIREMENTS_NOTICE + + """ + Discount expired. + """ + DISCOUNT_EXPIRED + + """ + Discount disabled. + """ + DISCOUNT_DISABLED + + """ + Discount limit reached. + """ + DISCOUNT_LIMIT_REACHED + + """ + Discount not found. + """ + DISCOUNT_NOT_FOUND + + """ + Customer already used once per customer discount notice. + """ + CUSTOMER_ALREADY_USED_ONCE_PER_CUSTOMER_DISCOUNT_NOTICE + + """ + Checkout is already completed. + """ + EMPTY + + """ + Not enough in stock. + """ + NOT_ENOUGH_IN_STOCK + + """ + Missing payment input. + """ + MISSING_PAYMENT_INPUT + + """ + The amount of the payment does not match the value to be paid. + """ + TOTAL_PRICE_MISMATCH + + """ + Line item was not found in checkout. + """ + LINE_ITEM_NOT_FOUND + + """ + Unable to apply discount. + """ + UNABLE_TO_APPLY + + """ + Discount already applied. + """ + DISCOUNT_ALREADY_APPLIED +} + +""" +Return type for `checkoutGiftCardApply` mutation. +""" +type CheckoutGiftCardApplyPayload { + """ + The updated checkout object. + """ + checkout: Checkout! + + """ + List of errors that occurred executing the mutation. + """ + checkoutUserErrors: [CheckoutUserError!]! + + """ + List of errors that occurred executing the mutation. + """ + userErrors: [UserError!]! + @deprecated(reason: "Use `checkoutUserErrors` instead") +} + +""" +Return type for `checkoutGiftCardRemove` mutation. +""" +type CheckoutGiftCardRemovePayload { + """ + The updated checkout object. + """ + checkout: Checkout! + + """ + List of errors that occurred executing the mutation. + """ + checkoutUserErrors: [CheckoutUserError!]! + + """ + List of errors that occurred executing the mutation. + """ + userErrors: [UserError!]! + @deprecated(reason: "Use `checkoutUserErrors` instead") +} + +""" +Return type for `checkoutGiftCardRemoveV2` mutation. +""" +type CheckoutGiftCardRemoveV2Payload { + """ + The updated checkout object. + """ + checkout: Checkout + + """ + List of errors that occurred executing the mutation. + """ + checkoutUserErrors: [CheckoutUserError!]! + + """ + List of errors that occurred executing the mutation. + """ + userErrors: [UserError!]! + @deprecated(reason: "Use `checkoutUserErrors` instead") +} + +""" +Return type for `checkoutGiftCardsAppend` mutation. +""" +type CheckoutGiftCardsAppendPayload { + """ + The updated checkout object. + """ + checkout: Checkout + + """ + List of errors that occurred executing the mutation. + """ + checkoutUserErrors: [CheckoutUserError!]! + + """ + List of errors that occurred executing the mutation. + """ + userErrors: [UserError!]! + @deprecated(reason: "Use `checkoutUserErrors` instead") +} + +""" +A single line item in the checkout, grouped by variant and attributes. +""" +type CheckoutLineItem implements Node { + """ + Extra information in the form of an array of Key-Value pairs about the line item. + """ + customAttributes: [Attribute!]! + + """ + The discounts that have been allocated onto the checkout line item by discount applications. + """ + discountAllocations: [DiscountAllocation!]! + + """ + Globally unique identifier. + """ + id: ID! + + """ + The quantity of the line item. + """ + quantity: Int! + + """ + Title of the line item. Defaults to the product's title. + """ + title: String! + + """ + Unit price of the line item. + """ + unitPrice: MoneyV2 + + """ + Product variant of the line item. + """ + variant: ProductVariant +} + +""" +An auto-generated type for paginating through multiple CheckoutLineItems. +""" +type CheckoutLineItemConnection { + """ + A list of edges. + """ + edges: [CheckoutLineItemEdge!]! + + """ + Information to aid in pagination. + """ + pageInfo: PageInfo! +} + +""" +An auto-generated type which holds one CheckoutLineItem and a cursor during pagination. +""" +type CheckoutLineItemEdge { + """ + A cursor for use in pagination. + """ + cursor: String! + + """ + The item at the end of CheckoutLineItemEdge. + """ + node: CheckoutLineItem! +} + +""" +Specifies the input fields to create a line item on a checkout. +""" +input CheckoutLineItemInput { + """ + Extra information in the form of an array of Key-Value pairs about the line item. + """ + customAttributes: [AttributeInput!] + + """ + The quantity of the line item. + """ + quantity: Int! + + """ + The identifier of the product variant for the line item. + """ + variantId: ID! +} + +""" +Specifies the input fields to update a line item on the checkout. +""" +input CheckoutLineItemUpdateInput { + """ + The identifier of the line item. + """ + id: ID + + """ + The variant identifier of the line item. + """ + variantId: ID + + """ + The quantity of the line item. + """ + quantity: Int + + """ + Extra information in the form of an array of Key-Value pairs about the line item. + """ + customAttributes: [AttributeInput!] +} + +""" +Return type for `checkoutLineItemsAdd` mutation. +""" +type CheckoutLineItemsAddPayload { + """ + The updated checkout object. + """ + checkout: Checkout + + """ + List of errors that occurred executing the mutation. + """ + checkoutUserErrors: [CheckoutUserError!]! + + """ + List of errors that occurred executing the mutation. + """ + userErrors: [UserError!]! + @deprecated(reason: "Use `checkoutUserErrors` instead") +} + +""" +Return type for `checkoutLineItemsRemove` mutation. +""" +type CheckoutLineItemsRemovePayload { + """ + The updated checkout object. + """ + checkout: Checkout + + """ + List of errors that occurred executing the mutation. + """ + checkoutUserErrors: [CheckoutUserError!]! + + """ + List of errors that occurred executing the mutation. + """ + userErrors: [UserError!]! + @deprecated(reason: "Use `checkoutUserErrors` instead") +} + +""" +Return type for `checkoutLineItemsReplace` mutation. +""" +type CheckoutLineItemsReplacePayload { + """ + The updated checkout object. + """ + checkout: Checkout + + """ + List of errors that occurred executing the mutation. + """ + userErrors: [CheckoutUserError!]! +} + +""" +Return type for `checkoutLineItemsUpdate` mutation. +""" +type CheckoutLineItemsUpdatePayload { + """ + The updated checkout object. + """ + checkout: Checkout + + """ + List of errors that occurred executing the mutation. + """ + checkoutUserErrors: [CheckoutUserError!]! + + """ + List of errors that occurred executing the mutation. + """ + userErrors: [UserError!]! + @deprecated(reason: "Use `checkoutUserErrors` instead") +} + +""" +Return type for `checkoutShippingAddressUpdate` mutation. +""" +type CheckoutShippingAddressUpdatePayload { + """ + The updated checkout object. + """ + checkout: Checkout! + + """ + List of errors that occurred executing the mutation. + """ + checkoutUserErrors: [CheckoutUserError!]! + + """ + List of errors that occurred executing the mutation. + """ + userErrors: [UserError!]! + @deprecated(reason: "Use `checkoutUserErrors` instead") +} + +""" +Return type for `checkoutShippingAddressUpdateV2` mutation. +""" +type CheckoutShippingAddressUpdateV2Payload { + """ + The updated checkout object. + """ + checkout: Checkout + + """ + List of errors that occurred executing the mutation. + """ + checkoutUserErrors: [CheckoutUserError!]! + + """ + List of errors that occurred executing the mutation. + """ + userErrors: [UserError!]! + @deprecated(reason: "Use `checkoutUserErrors` instead") +} + +""" +Return type for `checkoutShippingLineUpdate` mutation. +""" +type CheckoutShippingLineUpdatePayload { + """ + The updated checkout object. + """ + checkout: Checkout + + """ + List of errors that occurred executing the mutation. + """ + checkoutUserErrors: [CheckoutUserError!]! + + """ + List of errors that occurred executing the mutation. + """ + userErrors: [UserError!]! + @deprecated(reason: "Use `checkoutUserErrors` instead") +} + +""" +Represents an error that happens during execution of a checkout mutation. +""" +type CheckoutUserError implements DisplayableError { + """ + Error code to uniquely identify the error. + """ + code: CheckoutErrorCode + + """ + Path to the input field which caused the error. + """ + field: [String!] + + """ + The error message. + """ + message: String! +} + +""" +A collection represents a grouping of products that a shop owner can create to organize them or make their shops easier to browse. +""" +type Collection implements Node { + """ + Stripped description of the collection, single line with HTML tags removed. + """ + description( + """ + Truncates string after the given length. + """ + truncateAt: Int + ): String! + + """ + The description of the collection, complete with HTML formatting. + """ + descriptionHtml: HTML! + + """ + A human-friendly unique string for the collection automatically generated from its title. + Limit of 255 characters. + """ + handle: String! + + """ + Globally unique identifier. + """ + id: ID! + + """ + Image associated with the collection. + """ + image( + """ + Image width in pixels between 1 and 2048. This argument is deprecated: Use `maxWidth` on `Image.transformedSrc` instead. + """ + maxWidth: Int + + """ + Image height in pixels between 1 and 2048. This argument is deprecated: Use `maxHeight` on `Image.transformedSrc` instead. + """ + maxHeight: Int + + """ + Crops the image according to the specified region. This argument is deprecated: Use `crop` on `Image.transformedSrc` instead. + """ + crop: CropRegion + + """ + Image size multiplier for high-resolution retina displays. Must be between 1 and 3. This argument is deprecated: Use `scale` on `Image.transformedSrc` instead. + """ + scale: Int = 1 + ): Image + + """ + List of products in the collection. + """ + products( + """ + Returns up to the first `n` elements from the list. + """ + first: Int + + """ + Returns the elements that come after the specified cursor. + """ + after: String + + """ + Returns up to the last `n` elements from the list. + """ + last: Int + + """ + Returns the elements that come before the specified cursor. + """ + before: String + + """ + Reverse the order of the underlying list. + """ + reverse: Boolean = false + + """ + Sort the underlying list by the given key. + """ + sortKey: ProductCollectionSortKeys = COLLECTION_DEFAULT + ): ProductConnection! + + """ + The collection’s name. Limit of 255 characters. + """ + title: String! + + """ + The date and time when the collection was last modified. + """ + updatedAt: DateTime! +} + +""" +An auto-generated type for paginating through multiple Collections. +""" +type CollectionConnection { + """ + A list of edges. + """ + edges: [CollectionEdge!]! + + """ + Information to aid in pagination. + """ + pageInfo: PageInfo! +} + +""" +An auto-generated type which holds one Collection and a cursor during pagination. +""" +type CollectionEdge { + """ + A cursor for use in pagination. + """ + cursor: String! + + """ + The item at the end of CollectionEdge. + """ + node: Collection! +} + +""" +The set of valid sort keys for the Collection query. +""" +enum CollectionSortKeys { + """ + Sort by the `title` value. + """ + TITLE + + """ + Sort by the `updated_at` value. + """ + UPDATED_AT + + """ + Sort by the `id` value. + """ + ID + + """ + During a search (i.e. when the `query` parameter has been specified on the connection) this sorts the + results by relevance to the search term(s). When no search query is specified, this sort key is not + deterministic and should not be used. + """ + RELEVANCE +} + +""" +A comment on an article. +""" +type Comment implements Node { + """ + The comment’s author. + """ + author: CommentAuthor! + + """ + Stripped content of the comment, single line with HTML tags removed. + """ + content( + """ + Truncates string after the given length. + """ + truncateAt: Int + ): String! + + """ + The content of the comment, complete with HTML formatting. + """ + contentHtml: HTML! + + """ + Globally unique identifier. + """ + id: ID! +} + +""" +The author of a comment. +""" +type CommentAuthor { + """ + The author's email. + """ + email: String! + + """ + The author’s name. + """ + name: String! +} + +""" +An auto-generated type for paginating through multiple Comments. +""" +type CommentConnection { + """ + A list of edges. + """ + edges: [CommentEdge!]! + + """ + Information to aid in pagination. + """ + pageInfo: PageInfo! +} + +""" +An auto-generated type which holds one Comment and a cursor during pagination. +""" +type CommentEdge { + """ + A cursor for use in pagination. + """ + cursor: String! + + """ + The item at the end of CommentEdge. + """ + node: Comment! +} + +""" +ISO 3166-1 alpha-2 country codes with some differences. +""" +enum CountryCode { + """ + Afghanistan. + """ + AF + + """ + Åland Islands. + """ + AX + + """ + Albania. + """ + AL + + """ + Algeria. + """ + DZ + + """ + Andorra. + """ + AD + + """ + Angola. + """ + AO + + """ + Anguilla. + """ + AI + + """ + Antigua & Barbuda. + """ + AG + + """ + Argentina. + """ + AR + + """ + Armenia. + """ + AM + + """ + Aruba. + """ + AW + + """ + Australia. + """ + AU + + """ + Austria. + """ + AT + + """ + Azerbaijan. + """ + AZ + + """ + Bahamas. + """ + BS + + """ + Bahrain. + """ + BH + + """ + Bangladesh. + """ + BD + + """ + Barbados. + """ + BB + + """ + Belarus. + """ + BY + + """ + Belgium. + """ + BE + + """ + Belize. + """ + BZ + + """ + Benin. + """ + BJ + + """ + Bermuda. + """ + BM + + """ + Bhutan. + """ + BT + + """ + Bolivia. + """ + BO + + """ + Bosnia & Herzegovina. + """ + BA + + """ + Botswana. + """ + BW + + """ + Bouvet Island. + """ + BV + + """ + Brazil. + """ + BR + + """ + British Indian Ocean Territory. + """ + IO + + """ + Brunei. + """ + BN + + """ + Bulgaria. + """ + BG + + """ + Burkina Faso. + """ + BF + + """ + Burundi. + """ + BI + + """ + Cambodia. + """ + KH + + """ + Canada. + """ + CA + + """ + Cape Verde. + """ + CV + + """ + Caribbean Netherlands. + """ + BQ + + """ + Cayman Islands. + """ + KY + + """ + Central African Republic. + """ + CF + + """ + Chad. + """ + TD + + """ + Chile. + """ + CL + + """ + China. + """ + CN + + """ + Christmas Island. + """ + CX + + """ + Cocos (Keeling) Islands. + """ + CC + + """ + Colombia. + """ + CO + + """ + Comoros. + """ + KM + + """ + Congo - Brazzaville. + """ + CG + + """ + Congo - Kinshasa. + """ + CD + + """ + Cook Islands. + """ + CK + + """ + Costa Rica. + """ + CR + + """ + Croatia. + """ + HR + + """ + Cuba. + """ + CU + + """ + Curaçao. + """ + CW + + """ + Cyprus. + """ + CY + + """ + Czechia. + """ + CZ + + """ + Côte d’Ivoire. + """ + CI + + """ + Denmark. + """ + DK + + """ + Djibouti. + """ + DJ + + """ + Dominica. + """ + DM + + """ + Dominican Republic. + """ + DO + + """ + Ecuador. + """ + EC + + """ + Egypt. + """ + EG + + """ + El Salvador. + """ + SV + + """ + Equatorial Guinea. + """ + GQ + + """ + Eritrea. + """ + ER + + """ + Estonia. + """ + EE + + """ + Eswatini. + """ + SZ + + """ + Ethiopia. + """ + ET + + """ + Falkland Islands. + """ + FK + + """ + Faroe Islands. + """ + FO + + """ + Fiji. + """ + FJ + + """ + Finland. + """ + FI + + """ + France. + """ + FR + + """ + French Guiana. + """ + GF + + """ + French Polynesia. + """ + PF + + """ + French Southern Territories. + """ + TF + + """ + Gabon. + """ + GA + + """ + Gambia. + """ + GM + + """ + Georgia. + """ + GE + + """ + Germany. + """ + DE + + """ + Ghana. + """ + GH + + """ + Gibraltar. + """ + GI + + """ + Greece. + """ + GR + + """ + Greenland. + """ + GL + + """ + Grenada. + """ + GD + + """ + Guadeloupe. + """ + GP + + """ + Guatemala. + """ + GT + + """ + Guernsey. + """ + GG + + """ + Guinea. + """ + GN + + """ + Guinea-Bissau. + """ + GW + + """ + Guyana. + """ + GY + + """ + Haiti. + """ + HT + + """ + Heard & McDonald Islands. + """ + HM + + """ + Vatican City. + """ + VA + + """ + Honduras. + """ + HN + + """ + Hong Kong SAR. + """ + HK + + """ + Hungary. + """ + HU + + """ + Iceland. + """ + IS + + """ + India. + """ + IN + + """ + Indonesia. + """ + ID + + """ + Iran. + """ + IR + + """ + Iraq. + """ + IQ + + """ + Ireland. + """ + IE + + """ + Isle of Man. + """ + IM + + """ + Israel. + """ + IL + + """ + Italy. + """ + IT + + """ + Jamaica. + """ + JM + + """ + Japan. + """ + JP + + """ + Jersey. + """ + JE + + """ + Jordan. + """ + JO + + """ + Kazakhstan. + """ + KZ + + """ + Kenya. + """ + KE + + """ + Kiribati. + """ + KI + + """ + North Korea. + """ + KP + + """ + Kosovo. + """ + XK + + """ + Kuwait. + """ + KW + + """ + Kyrgyzstan. + """ + KG + + """ + Laos. + """ + LA + + """ + Latvia. + """ + LV + + """ + Lebanon. + """ + LB + + """ + Lesotho. + """ + LS + + """ + Liberia. + """ + LR + + """ + Libya. + """ + LY + + """ + Liechtenstein. + """ + LI + + """ + Lithuania. + """ + LT + + """ + Luxembourg. + """ + LU + + """ + Macao SAR. + """ + MO + + """ + Madagascar. + """ + MG + + """ + Malawi. + """ + MW + + """ + Malaysia. + """ + MY + + """ + Maldives. + """ + MV + + """ + Mali. + """ + ML + + """ + Malta. + """ + MT + + """ + Martinique. + """ + MQ + + """ + Mauritania. + """ + MR + + """ + Mauritius. + """ + MU + + """ + Mayotte. + """ + YT + + """ + Mexico. + """ + MX + + """ + Moldova. + """ + MD + + """ + Monaco. + """ + MC + + """ + Mongolia. + """ + MN + + """ + Montenegro. + """ + ME + + """ + Montserrat. + """ + MS + + """ + Morocco. + """ + MA + + """ + Mozambique. + """ + MZ + + """ + Myanmar (Burma). + """ + MM + + """ + Namibia. + """ + NA + + """ + Nauru. + """ + NR + + """ + Nepal. + """ + NP + + """ + Netherlands. + """ + NL + + """ + Netherlands Antilles. + """ + AN + + """ + New Caledonia. + """ + NC + + """ + New Zealand. + """ + NZ + + """ + Nicaragua. + """ + NI + + """ + Niger. + """ + NE + + """ + Nigeria. + """ + NG + + """ + Niue. + """ + NU + + """ + Norfolk Island. + """ + NF + + """ + North Macedonia. + """ + MK + + """ + Norway. + """ + NO + + """ + Oman. + """ + OM + + """ + Pakistan. + """ + PK + + """ + Palestinian Territories. + """ + PS + + """ + Panama. + """ + PA + + """ + Papua New Guinea. + """ + PG + + """ + Paraguay. + """ + PY + + """ + Peru. + """ + PE + + """ + Philippines. + """ + PH + + """ + Pitcairn Islands. + """ + PN + + """ + Poland. + """ + PL + + """ + Portugal. + """ + PT + + """ + Qatar. + """ + QA + + """ + Cameroon. + """ + CM + + """ + Réunion. + """ + RE + + """ + Romania. + """ + RO + + """ + Russia. + """ + RU + + """ + Rwanda. + """ + RW + + """ + St. Barthélemy. + """ + BL + + """ + St. Helena. + """ + SH + + """ + St. Kitts & Nevis. + """ + KN + + """ + St. Lucia. + """ + LC + + """ + St. Martin. + """ + MF + + """ + St. Pierre & Miquelon. + """ + PM + + """ + Samoa. + """ + WS + + """ + San Marino. + """ + SM + + """ + São Tomé & Príncipe. + """ + ST + + """ + Saudi Arabia. + """ + SA + + """ + Senegal. + """ + SN + + """ + Serbia. + """ + RS + + """ + Seychelles. + """ + SC + + """ + Sierra Leone. + """ + SL + + """ + Singapore. + """ + SG + + """ + Sint Maarten. + """ + SX + + """ + Slovakia. + """ + SK + + """ + Slovenia. + """ + SI + + """ + Solomon Islands. + """ + SB + + """ + Somalia. + """ + SO + + """ + South Africa. + """ + ZA + + """ + South Georgia & South Sandwich Islands. + """ + GS + + """ + South Korea. + """ + KR + + """ + South Sudan. + """ + SS + + """ + Spain. + """ + ES + + """ + Sri Lanka. + """ + LK + + """ + St. Vincent & Grenadines. + """ + VC + + """ + Sudan. + """ + SD + + """ + Suriname. + """ + SR + + """ + Svalbard & Jan Mayen. + """ + SJ + + """ + Sweden. + """ + SE + + """ + Switzerland. + """ + CH + + """ + Syria. + """ + SY + + """ + Taiwan. + """ + TW + + """ + Tajikistan. + """ + TJ + + """ + Tanzania. + """ + TZ + + """ + Thailand. + """ + TH + + """ + Timor-Leste. + """ + TL + + """ + Togo. + """ + TG + + """ + Tokelau. + """ + TK + + """ + Tonga. + """ + TO + + """ + Trinidad & Tobago. + """ + TT + + """ + Tunisia. + """ + TN + + """ + Turkey. + """ + TR + + """ + Turkmenistan. + """ + TM + + """ + Turks & Caicos Islands. + """ + TC + + """ + Tuvalu. + """ + TV + + """ + Uganda. + """ + UG + + """ + Ukraine. + """ + UA + + """ + United Arab Emirates. + """ + AE + + """ + United Kingdom. + """ + GB + + """ + United States. + """ + US + + """ + U.S. Outlying Islands. + """ + UM + + """ + Uruguay. + """ + UY + + """ + Uzbekistan. + """ + UZ + + """ + Vanuatu. + """ + VU + + """ + Venezuela. + """ + VE + + """ + Vietnam. + """ + VN + + """ + British Virgin Islands. + """ + VG + + """ + Wallis & Futuna. + """ + WF + + """ + Western Sahara. + """ + EH + + """ + Yemen. + """ + YE + + """ + Zambia. + """ + ZM + + """ + Zimbabwe. + """ + ZW +} + +""" +Credit card information used for a payment. +""" +type CreditCard { + """ + The brand of the credit card. + """ + brand: String + + """ + The expiry month of the credit card. + """ + expiryMonth: Int + + """ + The expiry year of the credit card. + """ + expiryYear: Int + + """ + The credit card's BIN number. + """ + firstDigits: String + + """ + The first name of the card holder. + """ + firstName: String + + """ + The last 4 digits of the credit card. + """ + lastDigits: String + + """ + The last name of the card holder. + """ + lastName: String + + """ + The masked credit card number with only the last 4 digits displayed. + """ + maskedNumber: String +} + +""" +Specifies the fields required to complete a checkout with +a Shopify vaulted credit card payment. +""" +input CreditCardPaymentInput { + """ + The amount of the payment. + """ + amount: Money! + + """ + A unique client generated key used to avoid duplicate charges. When a duplicate payment is found, the original is returned instead of creating a new one. + """ + idempotencyKey: String! + + """ + The billing address for the payment. + """ + billingAddress: MailingAddressInput! + + """ + The ID returned by Shopify's Card Vault. + """ + vaultId: String! + + """ + Executes the payment in test mode if possible. Defaults to `false`. + """ + test: Boolean +} + +""" +Specifies the fields required to complete a checkout with +a Shopify vaulted credit card payment. +""" +input CreditCardPaymentInputV2 { + """ + The amount and currency of the payment. + """ + paymentAmount: MoneyInput! + + """ + A unique client generated key used to avoid duplicate charges. When a duplicate payment is found, the original is returned instead of creating a new one. + """ + idempotencyKey: String! + + """ + The billing address for the payment. + """ + billingAddress: MailingAddressInput! + + """ + The ID returned by Shopify's Card Vault. + """ + vaultId: String! + + """ + Executes the payment in test mode if possible. Defaults to `false`. + """ + test: Boolean +} + +""" +The part of the image that should remain after cropping. +""" +enum CropRegion { + """ + Keep the center of the image. + """ + CENTER + + """ + Keep the top of the image. + """ + TOP + + """ + Keep the bottom of the image. + """ + BOTTOM + + """ + Keep the left of the image. + """ + LEFT + + """ + Keep the right of the image. + """ + RIGHT +} + +""" +Currency codes. +""" +enum CurrencyCode { + """ + United States Dollars (USD). + """ + USD + + """ + Euro (EUR). + """ + EUR + + """ + United Kingdom Pounds (GBP). + """ + GBP + + """ + Canadian Dollars (CAD). + """ + CAD + + """ + Afghan Afghani (AFN). + """ + AFN + + """ + Albanian Lek (ALL). + """ + ALL + + """ + Algerian Dinar (DZD). + """ + DZD + + """ + Angolan Kwanza (AOA). + """ + AOA + + """ + Argentine Pesos (ARS). + """ + ARS + + """ + Armenian Dram (AMD). + """ + AMD + + """ + Aruban Florin (AWG). + """ + AWG + + """ + Australian Dollars (AUD). + """ + AUD + + """ + Barbadian Dollar (BBD). + """ + BBD + + """ + Azerbaijani Manat (AZN). + """ + AZN + + """ + Bangladesh Taka (BDT). + """ + BDT + + """ + Bahamian Dollar (BSD). + """ + BSD + + """ + Bahraini Dinar (BHD). + """ + BHD + + """ + Burundian Franc (BIF). + """ + BIF + + """ + Belarusian Ruble (BYN). + """ + BYN + + """ + Belarusian Ruble (BYR). + """ + BYR + + """ + Belize Dollar (BZD). + """ + BZD + + """ + Bermudian Dollar (BMD). + """ + BMD + + """ + Bhutanese Ngultrum (BTN). + """ + BTN + + """ + Bosnia and Herzegovina Convertible Mark (BAM). + """ + BAM + + """ + Brazilian Real (BRL). + """ + BRL + + """ + Bolivian Boliviano (BOB). + """ + BOB + + """ + Botswana Pula (BWP). + """ + BWP + + """ + Brunei Dollar (BND). + """ + BND + + """ + Bulgarian Lev (BGN). + """ + BGN + + """ + Burmese Kyat (MMK). + """ + MMK + + """ + Cambodian Riel. + """ + KHR + + """ + Cape Verdean escudo (CVE). + """ + CVE + + """ + Cayman Dollars (KYD). + """ + KYD + + """ + Central African CFA Franc (XAF). + """ + XAF + + """ + Chilean Peso (CLP). + """ + CLP + + """ + Chinese Yuan Renminbi (CNY). + """ + CNY + + """ + Colombian Peso (COP). + """ + COP + + """ + Comorian Franc (KMF). + """ + KMF + + """ + Congolese franc (CDF). + """ + CDF + + """ + Costa Rican Colones (CRC). + """ + CRC + + """ + Croatian Kuna (HRK). + """ + HRK + + """ + Czech Koruny (CZK). + """ + CZK + + """ + Danish Kroner (DKK). + """ + DKK + + """ + Djiboutian Franc (DJF). + """ + DJF + + """ + Dominican Peso (DOP). + """ + DOP + + """ + East Caribbean Dollar (XCD). + """ + XCD + + """ + Egyptian Pound (EGP). + """ + EGP + + """ + Eritrean Nakfa (ERN). + """ + ERN + + """ + Ethiopian Birr (ETB). + """ + ETB + + """ + Falkland Islands Pounds (FKP). + """ + FKP + + """ + CFP Franc (XPF). + """ + XPF + + """ + Fijian Dollars (FJD). + """ + FJD + + """ + Gibraltar Pounds (GIP). + """ + GIP + + """ + Gambian Dalasi (GMD). + """ + GMD + + """ + Ghanaian Cedi (GHS). + """ + GHS + + """ + Guatemalan Quetzal (GTQ). + """ + GTQ + + """ + Guyanese Dollar (GYD). + """ + GYD + + """ + Georgian Lari (GEL). + """ + GEL + + """ + Guinean Franc (GNF). + """ + GNF + + """ + Haitian Gourde (HTG). + """ + HTG + + """ + Honduran Lempira (HNL). + """ + HNL + + """ + Hong Kong Dollars (HKD). + """ + HKD + + """ + Hungarian Forint (HUF). + """ + HUF + + """ + Icelandic Kronur (ISK). + """ + ISK + + """ + Indian Rupees (INR). + """ + INR + + """ + Indonesian Rupiah (IDR). + """ + IDR + + """ + Israeli New Shekel (NIS). + """ + ILS + + """ + Iranian Rial (IRR). + """ + IRR + + """ + Iraqi Dinar (IQD). + """ + IQD + + """ + Jamaican Dollars (JMD). + """ + JMD + + """ + Japanese Yen (JPY). + """ + JPY + + """ + Jersey Pound. + """ + JEP + + """ + Jordanian Dinar (JOD). + """ + JOD + + """ + Kazakhstani Tenge (KZT). + """ + KZT + + """ + Kenyan Shilling (KES). + """ + KES + + """ + Kiribati Dollar (KID). + """ + KID + + """ + Kuwaiti Dinar (KWD). + """ + KWD + + """ + Kyrgyzstani Som (KGS). + """ + KGS + + """ + Laotian Kip (LAK). + """ + LAK + + """ + Latvian Lati (LVL). + """ + LVL + + """ + Lebanese Pounds (LBP). + """ + LBP + + """ + Lesotho Loti (LSL). + """ + LSL + + """ + Liberian Dollar (LRD). + """ + LRD + + """ + Libyan Dinar (LYD). + """ + LYD + + """ + Lithuanian Litai (LTL). + """ + LTL + + """ + Malagasy Ariary (MGA). + """ + MGA + + """ + Macedonia Denar (MKD). + """ + MKD + + """ + Macanese Pataca (MOP). + """ + MOP + + """ + Malawian Kwacha (MWK). + """ + MWK + + """ + Maldivian Rufiyaa (MVR). + """ + MVR + + """ + Mauritanian Ouguiya (MRU). + """ + MRU + + """ + Mexican Pesos (MXN). + """ + MXN + + """ + Malaysian Ringgits (MYR). + """ + MYR + + """ + Mauritian Rupee (MUR). + """ + MUR + + """ + Moldovan Leu (MDL). + """ + MDL + + """ + Moroccan Dirham. + """ + MAD + + """ + Mongolian Tugrik. + """ + MNT + + """ + Mozambican Metical. + """ + MZN + + """ + Namibian Dollar. + """ + NAD + + """ + Nepalese Rupee (NPR). + """ + NPR + + """ + Netherlands Antillean Guilder. + """ + ANG + + """ + New Zealand Dollars (NZD). + """ + NZD + + """ + Nicaraguan Córdoba (NIO). + """ + NIO + + """ + Nigerian Naira (NGN). + """ + NGN + + """ + Norwegian Kroner (NOK). + """ + NOK + + """ + Omani Rial (OMR). + """ + OMR + + """ + Panamian Balboa (PAB). + """ + PAB + + """ + Pakistani Rupee (PKR). + """ + PKR + + """ + Papua New Guinean Kina (PGK). + """ + PGK + + """ + Paraguayan Guarani (PYG). + """ + PYG + + """ + Peruvian Nuevo Sol (PEN). + """ + PEN + + """ + Philippine Peso (PHP). + """ + PHP + + """ + Polish Zlotych (PLN). + """ + PLN + + """ + Qatari Rial (QAR). + """ + QAR + + """ + Romanian Lei (RON). + """ + RON + + """ + Russian Rubles (RUB). + """ + RUB + + """ + Rwandan Franc (RWF). + """ + RWF + + """ + Samoan Tala (WST). + """ + WST + + """ + Saint Helena Pounds (SHP). + """ + SHP + + """ + Saudi Riyal (SAR). + """ + SAR + + """ + Sao Tome And Principe Dobra (STD). + """ + STD + + """ + Serbian dinar (RSD). + """ + RSD + + """ + Seychellois Rupee (SCR). + """ + SCR + + """ + Sierra Leonean Leone (SLL). + """ + SLL + + """ + Singapore Dollars (SGD). + """ + SGD + + """ + Sudanese Pound (SDG). + """ + SDG + + """ + Somali Shilling (SOS). + """ + SOS + + """ + Syrian Pound (SYP). + """ + SYP + + """ + South African Rand (ZAR). + """ + ZAR + + """ + South Korean Won (KRW). + """ + KRW + + """ + South Sudanese Pound (SSP). + """ + SSP + + """ + Solomon Islands Dollar (SBD). + """ + SBD + + """ + Sri Lankan Rupees (LKR). + """ + LKR + + """ + Surinamese Dollar (SRD). + """ + SRD + + """ + Swazi Lilangeni (SZL). + """ + SZL + + """ + Swedish Kronor (SEK). + """ + SEK + + """ + Swiss Francs (CHF). + """ + CHF + + """ + Taiwan Dollars (TWD). + """ + TWD + + """ + Thai baht (THB). + """ + THB + + """ + Tajikistani Somoni (TJS). + """ + TJS + + """ + Tanzanian Shilling (TZS). + """ + TZS + + """ + Tongan Pa'anga (TOP). + """ + TOP + + """ + Trinidad and Tobago Dollars (TTD). + """ + TTD + + """ + Tunisian Dinar (TND). + """ + TND + + """ + Turkish Lira (TRY). + """ + TRY + + """ + Turkmenistani Manat (TMT). + """ + TMT + + """ + Ugandan Shilling (UGX). + """ + UGX + + """ + Ukrainian Hryvnia (UAH). + """ + UAH + + """ + United Arab Emirates Dirham (AED). + """ + AED + + """ + Uruguayan Pesos (UYU). + """ + UYU + + """ + Uzbekistan som (UZS). + """ + UZS + + """ + Vanuatu Vatu (VUV). + """ + VUV + + """ + Venezuelan Bolivares (VEF). + """ + VEF + + """ + Venezuelan Bolivares (VES). + """ + VES + + """ + Vietnamese đồng (VND). + """ + VND + + """ + West African CFA franc (XOF). + """ + XOF + + """ + Yemeni Rial (YER). + """ + YER + + """ + Zambian Kwacha (ZMW). + """ + ZMW +} + +""" +A customer represents a customer account with the shop. Customer accounts store contact information for the customer, saving logged-in customers the trouble of having to provide it at every checkout. +""" +type Customer { + """ + Indicates whether the customer has consented to be sent marketing material via email. + """ + acceptsMarketing: Boolean! + + """ + A list of addresses for the customer. + """ + addresses( + """ + Returns up to the first `n` elements from the list. + """ + first: Int + + """ + Returns the elements that come after the specified cursor. + """ + after: String + + """ + Returns up to the last `n` elements from the list. + """ + last: Int + + """ + Returns the elements that come before the specified cursor. + """ + before: String + + """ + Reverse the order of the underlying list. + """ + reverse: Boolean = false + ): MailingAddressConnection! + + """ + The date and time when the customer was created. + """ + createdAt: DateTime! + + """ + The customer’s default address. + """ + defaultAddress: MailingAddress + + """ + The customer’s name, email or phone number. + """ + displayName: String! + + """ + The customer’s email address. + """ + email: String + + """ + The customer’s first name. + """ + firstName: String + + """ + A unique identifier for the customer. + """ + id: ID! + + """ + The customer's most recently updated, incomplete checkout. + """ + lastIncompleteCheckout: Checkout + + """ + The customer’s last name. + """ + lastName: String + + """ + The orders associated with the customer. + """ + orders( + """ + Returns up to the first `n` elements from the list. + """ + first: Int + + """ + Returns the elements that come after the specified cursor. + """ + after: String + + """ + Returns up to the last `n` elements from the list. + """ + last: Int + + """ + Returns the elements that come before the specified cursor. + """ + before: String + + """ + Reverse the order of the underlying list. + """ + reverse: Boolean = false + + """ + Sort the underlying list by the given key. + """ + sortKey: OrderSortKeys = ID + + """ + Supported filter parameters: + - `processed_at` + + See the detailed [search syntax](https://help.shopify.com/api/getting-started/search-syntax) + for more information about using filters. + """ + query: String + ): OrderConnection! + + """ + The customer’s phone number. + """ + phone: String + + """ + A comma separated list of tags that have been added to the customer. + Additional access scope required: unauthenticated_read_customer_tags. + """ + tags: [String!]! + + """ + The date and time when the customer information was updated. + """ + updatedAt: DateTime! +} + +""" +A CustomerAccessToken represents the unique token required to make modifications to the customer object. +""" +type CustomerAccessToken { + """ + The customer’s access token. + """ + accessToken: String! + + """ + The date and time when the customer access token expires. + """ + expiresAt: DateTime! +} + +""" +Specifies the input fields required to create a customer access token. +""" +input CustomerAccessTokenCreateInput { + """ + The email associated to the customer. + """ + email: String! + + """ + The login password to be used by the customer. + """ + password: String! +} + +""" +Return type for `customerAccessTokenCreate` mutation. +""" +type CustomerAccessTokenCreatePayload { + """ + The newly created customer access token object. + """ + customerAccessToken: CustomerAccessToken + + """ + List of errors that occurred executing the mutation. + """ + customerUserErrors: [CustomerUserError!]! + + """ + List of errors that occurred executing the mutation. + """ + userErrors: [UserError!]! + @deprecated(reason: "Use `customerUserErrors` instead") +} + +""" +Return type for `customerAccessTokenCreateWithMultipass` mutation. +""" +type CustomerAccessTokenCreateWithMultipassPayload { + """ + An access token object associated with the customer. + """ + customerAccessToken: CustomerAccessToken + + """ + List of errors that occurred executing the mutation. + """ + customerUserErrors: [CustomerUserError!]! +} + +""" +Return type for `customerAccessTokenDelete` mutation. +""" +type CustomerAccessTokenDeletePayload { + """ + The destroyed access token. + """ + deletedAccessToken: String + + """ + ID of the destroyed customer access token. + """ + deletedCustomerAccessTokenId: String + + """ + List of errors that occurred executing the mutation. + """ + userErrors: [UserError!]! +} + +""" +Return type for `customerAccessTokenRenew` mutation. +""" +type CustomerAccessTokenRenewPayload { + """ + The renewed customer access token object. + """ + customerAccessToken: CustomerAccessToken + + """ + List of errors that occurred executing the mutation. + """ + userErrors: [UserError!]! +} + +""" +Return type for `customerActivateByUrl` mutation. +""" +type CustomerActivateByUrlPayload { + """ + The customer that was activated. + """ + customer: Customer + + """ + A new customer access token for the customer. + """ + customerAccessToken: CustomerAccessToken + + """ + List of errors that occurred executing the mutation. + """ + customerUserErrors: [CustomerUserError!]! +} + +""" +Specifies the input fields required to activate a customer. +""" +input CustomerActivateInput { + """ + The activation token required to activate the customer. + """ + activationToken: String! + + """ + New password that will be set during activation. + """ + password: String! +} + +""" +Return type for `customerActivate` mutation. +""" +type CustomerActivatePayload { + """ + The customer object. + """ + customer: Customer + + """ + A newly created customer access token object for the customer. + """ + customerAccessToken: CustomerAccessToken + + """ + List of errors that occurred executing the mutation. + """ + customerUserErrors: [CustomerUserError!]! + + """ + List of errors that occurred executing the mutation. + """ + userErrors: [UserError!]! + @deprecated(reason: "Use `customerUserErrors` instead") +} + +""" +Return type for `customerAddressCreate` mutation. +""" +type CustomerAddressCreatePayload { + """ + The new customer address object. + """ + customerAddress: MailingAddress + + """ + List of errors that occurred executing the mutation. + """ + customerUserErrors: [CustomerUserError!]! + + """ + List of errors that occurred executing the mutation. + """ + userErrors: [UserError!]! + @deprecated(reason: "Use `customerUserErrors` instead") +} + +""" +Return type for `customerAddressDelete` mutation. +""" +type CustomerAddressDeletePayload { + """ + List of errors that occurred executing the mutation. + """ + customerUserErrors: [CustomerUserError!]! + + """ + ID of the deleted customer address. + """ + deletedCustomerAddressId: String + + """ + List of errors that occurred executing the mutation. + """ + userErrors: [UserError!]! + @deprecated(reason: "Use `customerUserErrors` instead") +} + +""" +Return type for `customerAddressUpdate` mutation. +""" +type CustomerAddressUpdatePayload { + """ + The customer’s updated mailing address. + """ + customerAddress: MailingAddress + + """ + List of errors that occurred executing the mutation. + """ + customerUserErrors: [CustomerUserError!]! + + """ + List of errors that occurred executing the mutation. + """ + userErrors: [UserError!]! + @deprecated(reason: "Use `customerUserErrors` instead") +} + +""" +Specifies the fields required to create a new customer. +""" +input CustomerCreateInput { + """ + The customer’s first name. + """ + firstName: String + + """ + The customer’s last name. + """ + lastName: String + + """ + The customer’s email. + """ + email: String! + + """ + A unique phone number for the customer. + + Formatted using E.164 standard. For example, _+16135551111_. + """ + phone: String + + """ + The login password used by the customer. + """ + password: String! + + """ + Indicates whether the customer has consented to be sent marketing material via email. + """ + acceptsMarketing: Boolean +} + +""" +Return type for `customerCreate` mutation. +""" +type CustomerCreatePayload { + """ + The created customer object. + """ + customer: Customer + + """ + List of errors that occurred executing the mutation. + """ + customerUserErrors: [CustomerUserError!]! + + """ + List of errors that occurred executing the mutation. + """ + userErrors: [UserError!]! + @deprecated(reason: "Use `customerUserErrors` instead") +} + +""" +Return type for `customerDefaultAddressUpdate` mutation. +""" +type CustomerDefaultAddressUpdatePayload { + """ + The updated customer object. + """ + customer: Customer + + """ + List of errors that occurred executing the mutation. + """ + customerUserErrors: [CustomerUserError!]! + + """ + List of errors that occurred executing the mutation. + """ + userErrors: [UserError!]! + @deprecated(reason: "Use `customerUserErrors` instead") +} + +""" +Possible error codes that could be returned by CustomerUserError. +""" +enum CustomerErrorCode { + """ + Input value is blank. + """ + BLANK + + """ + Input value is invalid. + """ + INVALID + + """ + Input value is already taken. + """ + TAKEN + + """ + Input value is too long. + """ + TOO_LONG + + """ + Input value is too short. + """ + TOO_SHORT + + """ + Unidentified customer. + """ + UNIDENTIFIED_CUSTOMER + + """ + Customer is disabled. + """ + CUSTOMER_DISABLED + + """ + Input password starts or ends with whitespace. + """ + PASSWORD_STARTS_OR_ENDS_WITH_WHITESPACE + + """ + Input contains HTML tags. + """ + CONTAINS_HTML_TAGS + + """ + Input contains URL. + """ + CONTAINS_URL + + """ + Invalid activation token. + """ + TOKEN_INVALID + + """ + Customer already enabled. + """ + ALREADY_ENABLED + + """ + Address does not exist. + """ + NOT_FOUND + + """ + Input email contains an invalid domain name. + """ + BAD_DOMAIN + + """ + Multipass token is not valid. + """ + INVALID_MULTIPASS_REQUEST +} + +""" +Return type for `customerRecover` mutation. +""" +type CustomerRecoverPayload { + """ + List of errors that occurred executing the mutation. + """ + customerUserErrors: [CustomerUserError!]! + + """ + List of errors that occurred executing the mutation. + """ + userErrors: [UserError!]! + @deprecated(reason: "Use `customerUserErrors` instead") +} + +""" +Return type for `customerResetByUrl` mutation. +""" +type CustomerResetByUrlPayload { + """ + The customer object which was reset. + """ + customer: Customer + + """ + A newly created customer access token object for the customer. + """ + customerAccessToken: CustomerAccessToken + + """ + List of errors that occurred executing the mutation. + """ + customerUserErrors: [CustomerUserError!]! + + """ + List of errors that occurred executing the mutation. + """ + userErrors: [UserError!]! + @deprecated(reason: "Use `customerUserErrors` instead") +} + +""" +Specifies the fields required to reset a customer’s password. +""" +input CustomerResetInput { + """ + The reset token required to reset the customer’s password. + """ + resetToken: String! + + """ + New password that will be set as part of the reset password process. + """ + password: String! +} + +""" +Return type for `customerReset` mutation. +""" +type CustomerResetPayload { + """ + The customer object which was reset. + """ + customer: Customer + + """ + A newly created customer access token object for the customer. + """ + customerAccessToken: CustomerAccessToken + + """ + List of errors that occurred executing the mutation. + """ + customerUserErrors: [CustomerUserError!]! + + """ + List of errors that occurred executing the mutation. + """ + userErrors: [UserError!]! + @deprecated(reason: "Use `customerUserErrors` instead") +} + +""" +Specifies the fields required to update the Customer information. +""" +input CustomerUpdateInput { + """ + The customer’s first name. + """ + firstName: String + + """ + The customer’s last name. + """ + lastName: String + + """ + The customer’s email. + """ + email: String + + """ + A unique phone number for the customer. + + Formatted using E.164 standard. For example, _+16135551111_. To remove the phone number, specify `null`. + """ + phone: String + + """ + The login password used by the customer. + """ + password: String + + """ + Indicates whether the customer has consented to be sent marketing material via email. + """ + acceptsMarketing: Boolean +} + +""" +Return type for `customerUpdate` mutation. +""" +type CustomerUpdatePayload { + """ + The updated customer object. + """ + customer: Customer + + """ + The newly created customer access token. If the customer's password is updated, all previous access tokens + (including the one used to perform this mutation) become invalid, and a new token is generated. + """ + customerAccessToken: CustomerAccessToken + + """ + List of errors that occurred executing the mutation. + """ + customerUserErrors: [CustomerUserError!]! + + """ + List of errors that occurred executing the mutation. + """ + userErrors: [UserError!]! + @deprecated(reason: "Use `customerUserErrors` instead") +} + +""" +Represents an error that happens during execution of a customer mutation. +""" +type CustomerUserError implements DisplayableError { + """ + Error code to uniquely identify the error. + """ + code: CustomerErrorCode + + """ + Path to the input field which caused the error. + """ + field: [String!] + + """ + The error message. + """ + message: String! +} + +""" +An ISO-8601 encoded UTC date time string. Example value: `"2019-07-03T20:47:55Z"`. +""" +scalar DateTime + +""" +A signed decimal number, which supports arbitrary precision and is serialized as a string. Example value: `"29.99"`. +""" +scalar Decimal + +""" +Digital wallet, such as Apple Pay, which can be used for accelerated checkouts. +""" +enum DigitalWallet { + """ + Apple Pay. + """ + APPLE_PAY + + """ + Android Pay. + """ + ANDROID_PAY + + """ + Google Pay. + """ + GOOGLE_PAY + + """ + Shopify Pay. + """ + SHOPIFY_PAY +} + +""" +An amount discounting the line that has been allocated by a discount. +""" +type DiscountAllocation { + """ + Amount of discount allocated. + """ + allocatedAmount: MoneyV2! + + """ + The discount this allocated amount originated from. + """ + discountApplication: DiscountApplication! +} + +""" +Discount applications capture the intentions of a discount source at +the time of application. +""" +interface DiscountApplication { + """ + The method by which the discount's value is allocated to its entitled items. + """ + allocationMethod: DiscountApplicationAllocationMethod! + + """ + Which lines of targetType that the discount is allocated over. + """ + targetSelection: DiscountApplicationTargetSelection! + + """ + The type of line that the discount is applicable towards. + """ + targetType: DiscountApplicationTargetType! + + """ + The value of the discount application. + """ + value: PricingValue! +} + +""" +The method by which the discount's value is allocated onto its entitled lines. +""" +enum DiscountApplicationAllocationMethod { + """ + The value is spread across all entitled lines. + """ + ACROSS + + """ + The value is applied onto every entitled line. + """ + EACH + + """ + The value is specifically applied onto a particular line. + """ + ONE +} + +""" +An auto-generated type for paginating through multiple DiscountApplications. +""" +type DiscountApplicationConnection { + """ + A list of edges. + """ + edges: [DiscountApplicationEdge!]! + + """ + Information to aid in pagination. + """ + pageInfo: PageInfo! +} + +""" +An auto-generated type which holds one DiscountApplication and a cursor during pagination. +""" +type DiscountApplicationEdge { + """ + A cursor for use in pagination. + """ + cursor: String! + + """ + The item at the end of DiscountApplicationEdge. + """ + node: DiscountApplication! +} + +""" +Which lines on the order that the discount is allocated over, of the type +defined by the Discount Application's target_type. +""" +enum DiscountApplicationTargetSelection { + """ + The discount is allocated onto all the lines. + """ + ALL + + """ + The discount is allocated onto only the lines it is entitled for. + """ + ENTITLED + + """ + The discount is allocated onto explicitly chosen lines. + """ + EXPLICIT +} + +""" +The type of line (i.e. line item or shipping line) on an order that the discount is applicable towards. +""" +enum DiscountApplicationTargetType { + """ + The discount applies onto line items. + """ + LINE_ITEM + + """ + The discount applies onto shipping lines. + """ + SHIPPING_LINE +} + +""" +Discount code applications capture the intentions of a discount code at +the time that it is applied. +""" +type DiscountCodeApplication implements DiscountApplication { + """ + The method by which the discount's value is allocated to its entitled items. + """ + allocationMethod: DiscountApplicationAllocationMethod! + + """ + Specifies whether the discount code was applied successfully. + """ + applicable: Boolean! + + """ + The string identifying the discount code that was used at the time of application. + """ + code: String! + + """ + Which lines of targetType that the discount is allocated over. + """ + targetSelection: DiscountApplicationTargetSelection! + + """ + The type of line that the discount is applicable towards. + """ + targetType: DiscountApplicationTargetType! + + """ + The value of the discount application. + """ + value: PricingValue! +} + +""" +Represents an error in the input of a mutation. +""" +interface DisplayableError { + """ + Path to the input field which caused the error. + """ + field: [String!] + + """ + The error message. + """ + message: String! +} + +""" +Represents a web address. +""" +type Domain { + """ + The host name of the domain (eg: `example.com`). + """ + host: String! + + """ + Whether SSL is enabled or not. + """ + sslEnabled: Boolean! + + """ + The URL of the domain (eg: `https://example.com`). + """ + url: URL! +} + +""" +Represents a video hosted outside of Shopify. +""" +type ExternalVideo implements Node & Media { + """ + A word or phrase to share the nature or contents of a media. + """ + alt: String + + """ + The URL. + """ + embeddedUrl: URL! + + """ + Globally unique identifier. + """ + id: ID! + + """ + The media content type. + """ + mediaContentType: MediaContentType! + + """ + The preview image for the media. + """ + previewImage: Image +} + +""" +Represents a single fulfillment in an order. +""" +type Fulfillment { + """ + List of the fulfillment's line items. + """ + fulfillmentLineItems( + """ + Returns up to the first `n` elements from the list. + """ + first: Int + + """ + Returns the elements that come after the specified cursor. + """ + after: String + + """ + Returns up to the last `n` elements from the list. + """ + last: Int + + """ + Returns the elements that come before the specified cursor. + """ + before: String + + """ + Reverse the order of the underlying list. + """ + reverse: Boolean = false + ): FulfillmentLineItemConnection! + + """ + The name of the tracking company. + """ + trackingCompany: String + + """ + Tracking information associated with the fulfillment, + such as the tracking number and tracking URL. + """ + trackingInfo( + """ + Truncate the array result to this size. + """ + first: Int + ): [FulfillmentTrackingInfo!]! +} + +""" +Represents a single line item in a fulfillment. There is at most one fulfillment line item for each order line item. +""" +type FulfillmentLineItem { + """ + The associated order's line item. + """ + lineItem: OrderLineItem! + + """ + The amount fulfilled in this fulfillment. + """ + quantity: Int! +} + +""" +An auto-generated type for paginating through multiple FulfillmentLineItems. +""" +type FulfillmentLineItemConnection { + """ + A list of edges. + """ + edges: [FulfillmentLineItemEdge!]! + + """ + Information to aid in pagination. + """ + pageInfo: PageInfo! +} + +""" +An auto-generated type which holds one FulfillmentLineItem and a cursor during pagination. +""" +type FulfillmentLineItemEdge { + """ + A cursor for use in pagination. + """ + cursor: String! + + """ + The item at the end of FulfillmentLineItemEdge. + """ + node: FulfillmentLineItem! +} + +""" +Tracking information associated with the fulfillment. +""" +type FulfillmentTrackingInfo { + """ + The tracking number of the fulfillment. + """ + number: String + + """ + The URL to track the fulfillment. + """ + url: URL +} + +""" +A string containing HTML code. Example value: `"

      Grey cotton knit sweater.

      "`. +""" +scalar HTML + +""" +Represents information about the metafields associated to the specified resource. +""" +interface HasMetafields { + """ + The metafield associated with the resource. + """ + metafield( + """ + Container for a set of metafields (maximum of 20 characters). + """ + namespace: String! + + """ + Identifier for the metafield (maximum of 30 characters). + """ + key: String! + ): Metafield + + """ + A paginated list of metafields associated with the resource. + """ + metafields( + """ + Container for a set of metafields (maximum of 20 characters). + """ + namespace: String + + """ + Returns up to the first `n` elements from the list. + """ + first: Int + + """ + Returns the elements that come after the specified cursor. + """ + after: String + + """ + Returns up to the last `n` elements from the list. + """ + last: Int + + """ + Returns the elements that come before the specified cursor. + """ + before: String + + """ + Reverse the order of the underlying list. + """ + reverse: Boolean = false + ): MetafieldConnection! +} + +""" +Represents an image resource. +""" +type Image { + """ + A word or phrase to share the nature or contents of an image. + """ + altText: String + + """ + The original height of the image in pixels. Returns `null` if the image is not hosted by Shopify. + """ + height: Int + + """ + A unique identifier for the image. + """ + id: ID + + """ + The location of the original image as a URL. + + If there are any existing transformations in the original source URL, they will remain and not be stripped. + """ + originalSrc: URL! + + """ + The location of the image as a URL. + """ + src: URL! + @deprecated( + reason: "Previously an image had a single `src` field. This could either return the original image\nlocation or a URL that contained transformations such as sizing or scale.\n\nThese transformations were specified by arguments on the parent field.\n\nNow an image has two distinct URL fields: `originalSrc` and `transformedSrc`.\n\n* `originalSrc` - the original unmodified image URL\n* `transformedSrc` - the image URL with the specified transformations included\n\nTo migrate to the new fields, image transformations should be moved from the parent field to `transformedSrc`.\n\nBefore:\n```graphql\n{\n shop {\n productImages(maxWidth: 200, scale: 2) {\n edges {\n node {\n src\n }\n }\n }\n }\n}\n```\n\nAfter:\n```graphql\n{\n shop {\n productImages {\n edges {\n node {\n transformedSrc(maxWidth: 200, scale: 2)\n }\n }\n }\n }\n}\n```\n" + ) + + """ + The location of the transformed image as a URL. + + All transformation arguments are considered "best-effort". If they can be applied to an image, they will be. + Otherwise any transformations which an image type does not support will be ignored. + """ + transformedSrc( + """ + Image width in pixels between 1 and 5760. + """ + maxWidth: Int + + """ + Image height in pixels between 1 and 5760. + """ + maxHeight: Int + + """ + Crops the image according to the specified region. + """ + crop: CropRegion + + """ + Image size multiplier for high-resolution retina displays. Must be between 1 and 3. + """ + scale: Int = 1 + + """ + Best effort conversion of image into content type (SVG -> PNG, Anything -> JGP, Anything -> WEBP are supported). + """ + preferredContentType: ImageContentType + ): URL! + + """ + The original width of the image in pixels. Returns `null` if the image is not hosted by Shopify. + """ + width: Int +} + +""" +An auto-generated type for paginating through multiple Images. +""" +type ImageConnection { + """ + A list of edges. + """ + edges: [ImageEdge!]! + + """ + Information to aid in pagination. + """ + pageInfo: PageInfo! +} + +""" +List of supported image content types. +""" +enum ImageContentType { + """ + A PNG image. + """ + PNG + + """ + A JPG image. + """ + JPG + + """ + A WEBP image. + """ + WEBP +} + +""" +An auto-generated type which holds one Image and a cursor during pagination. +""" +type ImageEdge { + """ + A cursor for use in pagination. + """ + cursor: String! + + """ + The item at the end of ImageEdge. + """ + node: Image! +} + +""" +Represents a mailing address for customers and shipping. +""" +type MailingAddress implements Node { + """ + The first line of the address. Typically the street address or PO Box number. + """ + address1: String + + """ + The second line of the address. Typically the number of the apartment, suite, or unit. + """ + address2: String + + """ + The name of the city, district, village, or town. + """ + city: String + + """ + The name of the customer's company or organization. + """ + company: String + + """ + The name of the country. + """ + country: String + + """ + The two-letter code for the country of the address. + + For example, US. + """ + countryCode: String @deprecated(reason: "Use `countryCodeV2` instead") + + """ + The two-letter code for the country of the address. + + For example, US. + """ + countryCodeV2: CountryCode + + """ + The first name of the customer. + """ + firstName: String + + """ + A formatted version of the address, customized by the provided arguments. + """ + formatted( + """ + Whether to include the customer's name in the formatted address. + """ + withName: Boolean = false + + """ + Whether to include the customer's company in the formatted address. + """ + withCompany: Boolean = true + ): [String!]! + + """ + A comma-separated list of the values for city, province, and country. + """ + formattedArea: String + + """ + Globally unique identifier. + """ + id: ID! + + """ + The last name of the customer. + """ + lastName: String + + """ + The latitude coordinate of the customer address. + """ + latitude: Float + + """ + The longitude coordinate of the customer address. + """ + longitude: Float + + """ + The full name of the customer, based on firstName and lastName. + """ + name: String + + """ + A unique phone number for the customer. + + Formatted using E.164 standard. For example, _+16135551111_. + """ + phone: String + + """ + The region of the address, such as the province, state, or district. + """ + province: String + + """ + The two-letter code for the region. + + For example, ON. + """ + provinceCode: String + + """ + The zip or postal code of the address. + """ + zip: String +} + +""" +An auto-generated type for paginating through multiple MailingAddresses. +""" +type MailingAddressConnection { + """ + A list of edges. + """ + edges: [MailingAddressEdge!]! + + """ + Information to aid in pagination. + """ + pageInfo: PageInfo! +} + +""" +An auto-generated type which holds one MailingAddress and a cursor during pagination. +""" +type MailingAddressEdge { + """ + A cursor for use in pagination. + """ + cursor: String! + + """ + The item at the end of MailingAddressEdge. + """ + node: MailingAddress! +} + +""" +Specifies the fields accepted to create or update a mailing address. +""" +input MailingAddressInput { + """ + The first line of the address. Typically the street address or PO Box number. + """ + address1: String + + """ + The second line of the address. Typically the number of the apartment, suite, or unit. + """ + address2: String + + """ + The name of the city, district, village, or town. + """ + city: String + + """ + The name of the customer's company or organization. + """ + company: String + + """ + The name of the country. + """ + country: String + + """ + The first name of the customer. + """ + firstName: String + + """ + The last name of the customer. + """ + lastName: String + + """ + A unique phone number for the customer. + + Formatted using E.164 standard. For example, _+16135551111_. + """ + phone: String + + """ + The region of the address, such as the province, state, or district. + """ + province: String + + """ + The zip or postal code of the address. + """ + zip: String +} + +""" +Manual discount applications capture the intentions of a discount that was manually created. +""" +type ManualDiscountApplication implements DiscountApplication { + """ + The method by which the discount's value is allocated to its entitled items. + """ + allocationMethod: DiscountApplicationAllocationMethod! + + """ + The description of the application. + """ + description: String + + """ + Which lines of targetType that the discount is allocated over. + """ + targetSelection: DiscountApplicationTargetSelection! + + """ + The type of line that the discount is applicable towards. + """ + targetType: DiscountApplicationTargetType! + + """ + The title of the application. + """ + title: String! + + """ + The value of the discount application. + """ + value: PricingValue! +} + +""" +Represents a media interface. +""" +interface Media { + """ + A word or phrase to share the nature or contents of a media. + """ + alt: String + + """ + The media content type. + """ + mediaContentType: MediaContentType! + + """ + The preview image for the media. + """ + previewImage: Image +} + +""" +An auto-generated type for paginating through multiple Media. +""" +type MediaConnection { + """ + A list of edges. + """ + edges: [MediaEdge!]! + + """ + Information to aid in pagination. + """ + pageInfo: PageInfo! +} + +""" +The possible content types for a media object. +""" +enum MediaContentType { + """ + An externally hosted video. + """ + EXTERNAL_VIDEO + + """ + A Shopify hosted image. + """ + IMAGE + + """ + A 3d model. + """ + MODEL_3D + + """ + A Shopify hosted video. + """ + VIDEO +} + +""" +An auto-generated type which holds one Media and a cursor during pagination. +""" +type MediaEdge { + """ + A cursor for use in pagination. + """ + cursor: String! + + """ + The item at the end of MediaEdge. + """ + node: Media! +} + +""" +Represents a Shopify hosted image. +""" +type MediaImage implements Node & Media { + """ + A word or phrase to share the nature or contents of a media. + """ + alt: String + + """ + Globally unique identifier. + """ + id: ID! + + """ + The image for the media. + """ + image: Image + + """ + The media content type. + """ + mediaContentType: MediaContentType! + + """ + The preview image for the media. + """ + previewImage: Image +} + +""" +Metafields represent custom metadata attached to a resource. Metafields can be sorted into namespaces and are +comprised of keys, values, and value types. +""" +type Metafield implements Node { + """ + The date and time when the storefront metafield was created. + """ + createdAt: DateTime! + + """ + The description of a metafield. + """ + description: String + + """ + Globally unique identifier. + """ + id: ID! + + """ + The key name for a metafield. + """ + key: String! + + """ + The namespace for a metafield. + """ + namespace: String! + + """ + The parent object that the metafield belongs to. + """ + parentResource: MetafieldParentResource! + + """ + The date and time when the storefront metafield was updated. + """ + updatedAt: DateTime! + + """ + The value of a metafield. + """ + value: String! + + """ + Represents the metafield value type. + """ + valueType: MetafieldValueType! +} + +""" +An auto-generated type for paginating through multiple Metafields. +""" +type MetafieldConnection { + """ + A list of edges. + """ + edges: [MetafieldEdge!]! + + """ + Information to aid in pagination. + """ + pageInfo: PageInfo! +} + +""" +An auto-generated type which holds one Metafield and a cursor during pagination. +""" +type MetafieldEdge { + """ + A cursor for use in pagination. + """ + cursor: String! + + """ + The item at the end of MetafieldEdge. + """ + node: Metafield! +} + +""" +A resource that the metafield belongs to. +""" +union MetafieldParentResource = Product | ProductVariant + +""" +Metafield value types. +""" +enum MetafieldValueType { + """ + A string metafield. + """ + STRING + + """ + An integer metafield. + """ + INTEGER + + """ + A json string metafield. + """ + JSON_STRING +} + +""" +Represents a Shopify hosted 3D model. +""" +type Model3d implements Node & Media { + """ + A word or phrase to share the nature or contents of a media. + """ + alt: String + + """ + Globally unique identifier. + """ + id: ID! + + """ + The media content type. + """ + mediaContentType: MediaContentType! + + """ + The preview image for the media. + """ + previewImage: Image + + """ + The sources for a 3d model. + """ + sources: [Model3dSource!]! +} + +""" +Represents a source for a Shopify hosted 3d model. +""" +type Model3dSource { + """ + The filesize of the 3d model. + """ + filesize: Int! + + """ + The format of the 3d model. + """ + format: String! + + """ + The MIME type of the 3d model. + """ + mimeType: String! + + """ + The URL of the 3d model. + """ + url: String! +} + +""" +A monetary value string. Example value: `"100.57"`. +""" +scalar Money + +""" +Specifies the fields for a monetary value with currency. +""" +input MoneyInput { + """ + Decimal money amount. + """ + amount: Decimal! + + """ + Currency of the money. + """ + currencyCode: CurrencyCode! +} + +""" +A monetary value with currency. + +To format currencies, combine this type's amount and currencyCode fields with your client's locale. + +For example, in JavaScript you could use Intl.NumberFormat: + +```js +new Intl.NumberFormat(locale, { + style: 'currency', + currency: currencyCode +}).format(amount); +``` + +Other formatting libraries include: + +* iOS - [NumberFormatter](https://developer.apple.com/documentation/foundation/numberformatter) +* Android - [NumberFormat](https://developer.android.com/reference/java/text/NumberFormat.html) +* PHP - [NumberFormatter](http://php.net/manual/en/class.numberformatter.php) + +For a more general solution, the [Unicode CLDR number formatting database] is available with many implementations +(such as [TwitterCldr](https://github.com/twitter/twitter-cldr-rb)). +""" +type MoneyV2 { + """ + Decimal money amount. + """ + amount: Decimal! + + """ + Currency of the money. + """ + currencyCode: CurrencyCode! +} + +""" +An auto-generated type for paginating through multiple MoneyV2s. +""" +type MoneyV2Connection { + """ + A list of edges. + """ + edges: [MoneyV2Edge!]! + + """ + Information to aid in pagination. + """ + pageInfo: PageInfo! +} + +""" +An auto-generated type which holds one MoneyV2 and a cursor during pagination. +""" +type MoneyV2Edge { + """ + A cursor for use in pagination. + """ + cursor: String! + + """ + The item at the end of MoneyV2Edge. + """ + node: MoneyV2! +} + +""" +The schema’s entry-point for mutations. This acts as the public, top-level API from which all mutation queries must start. +""" +type Mutation { + """ + Updates the attributes of a checkout. + """ + checkoutAttributesUpdate( + """ + The ID of the checkout. + """ + checkoutId: ID! + + """ + The fields used to update a checkout's attributes. + """ + input: CheckoutAttributesUpdateInput! + ): CheckoutAttributesUpdatePayload + @deprecated(reason: "Use `checkoutAttributesUpdateV2` instead") + + """ + Updates the attributes of a checkout. + """ + checkoutAttributesUpdateV2( + """ + The ID of the checkout. + """ + checkoutId: ID! + + """ + The checkout attributes to update. + """ + input: CheckoutAttributesUpdateV2Input! + ): CheckoutAttributesUpdateV2Payload + + """ + Completes a checkout without providing payment information. You can use this mutation for free items or items whose purchase price is covered by a gift card. + """ + checkoutCompleteFree( + """ + The ID of the checkout. + """ + checkoutId: ID! + ): CheckoutCompleteFreePayload + + """ + Completes a checkout using a credit card token from Shopify's Vault. + """ + checkoutCompleteWithCreditCard( + """ + The ID of the checkout. + """ + checkoutId: ID! + + """ + The credit card info to apply as a payment. + """ + payment: CreditCardPaymentInput! + ): CheckoutCompleteWithCreditCardPayload + @deprecated(reason: "Use `checkoutCompleteWithCreditCardV2` instead") + + """ + Completes a checkout using a credit card token from Shopify's card vault. Before you can complete checkouts using CheckoutCompleteWithCreditCardV2, you need to [_request payment processing_](https://help.shopify.com/api/guides/sales-channel-sdk/getting-started#request-payment-processing). + """ + checkoutCompleteWithCreditCardV2( + """ + The ID of the checkout. + """ + checkoutId: ID! + + """ + The credit card info to apply as a payment. + """ + payment: CreditCardPaymentInputV2! + ): CheckoutCompleteWithCreditCardV2Payload + + """ + Completes a checkout with a tokenized payment. + """ + checkoutCompleteWithTokenizedPayment( + """ + The ID of the checkout. + """ + checkoutId: ID! + + """ + The info to apply as a tokenized payment. + """ + payment: TokenizedPaymentInput! + ): CheckoutCompleteWithTokenizedPaymentPayload + @deprecated(reason: "Use `checkoutCompleteWithTokenizedPaymentV2` instead") + + """ + Completes a checkout with a tokenized payment. + """ + checkoutCompleteWithTokenizedPaymentV2( + """ + The ID of the checkout. + """ + checkoutId: ID! + + """ + The info to apply as a tokenized payment. + """ + payment: TokenizedPaymentInputV2! + ): CheckoutCompleteWithTokenizedPaymentV2Payload + @deprecated(reason: "Use `checkoutCompleteWithTokenizedPaymentV3` instead") + + """ + Completes a checkout with a tokenized payment. + """ + checkoutCompleteWithTokenizedPaymentV3( + """ + The ID of the checkout. + """ + checkoutId: ID! + + """ + The info to apply as a tokenized payment. + """ + payment: TokenizedPaymentInputV3! + ): CheckoutCompleteWithTokenizedPaymentV3Payload + + """ + Creates a new checkout. + """ + checkoutCreate( + """ + The fields used to create a checkout. + """ + input: CheckoutCreateInput! + ): CheckoutCreatePayload + + """ + Associates a customer to the checkout. + """ + checkoutCustomerAssociate( + """ + The ID of the checkout. + """ + checkoutId: ID! + + """ + The customer access token of the customer to associate. + """ + customerAccessToken: String! + ): CheckoutCustomerAssociatePayload + @deprecated(reason: "Use `checkoutCustomerAssociateV2` instead") + + """ + Associates a customer to the checkout. + """ + checkoutCustomerAssociateV2( + """ + The ID of the checkout. + """ + checkoutId: ID! + + """ + The customer access token of the customer to associate. + """ + customerAccessToken: String! + ): CheckoutCustomerAssociateV2Payload + + """ + Disassociates the current checkout customer from the checkout. + """ + checkoutCustomerDisassociate( + """ + The ID of the checkout. + """ + checkoutId: ID! + ): CheckoutCustomerDisassociatePayload + @deprecated(reason: "Use `checkoutCustomerDisassociateV2` instead") + + """ + Disassociates the current checkout customer from the checkout. + """ + checkoutCustomerDisassociateV2( + """ + The ID of the checkout. + """ + checkoutId: ID! + ): CheckoutCustomerDisassociateV2Payload + + """ + Applies a discount to an existing checkout using a discount code. + """ + checkoutDiscountCodeApply( + """ + The discount code to apply to the checkout. + """ + discountCode: String! + + """ + The ID of the checkout. + """ + checkoutId: ID! + ): CheckoutDiscountCodeApplyPayload + @deprecated(reason: "Use `checkoutDiscountCodeApplyV2` instead") + + """ + Applies a discount to an existing checkout using a discount code. + """ + checkoutDiscountCodeApplyV2( + """ + The discount code to apply to the checkout. + """ + discountCode: String! + + """ + The ID of the checkout. + """ + checkoutId: ID! + ): CheckoutDiscountCodeApplyV2Payload + + """ + Removes the applied discount from an existing checkout. + """ + checkoutDiscountCodeRemove( + """ + The ID of the checkout. + """ + checkoutId: ID! + ): CheckoutDiscountCodeRemovePayload + + """ + Updates the email on an existing checkout. + """ + checkoutEmailUpdate( + """ + The ID of the checkout. + """ + checkoutId: ID! + + """ + The email to update the checkout with. + """ + email: String! + ): CheckoutEmailUpdatePayload + @deprecated(reason: "Use `checkoutEmailUpdateV2` instead") + + """ + Updates the email on an existing checkout. + """ + checkoutEmailUpdateV2( + """ + The ID of the checkout. + """ + checkoutId: ID! + + """ + The email to update the checkout with. + """ + email: String! + ): CheckoutEmailUpdateV2Payload + + """ + Applies a gift card to an existing checkout using a gift card code. This will replace all currently applied gift cards. + """ + checkoutGiftCardApply( + """ + The code of the gift card to apply on the checkout. + """ + giftCardCode: String! + + """ + The ID of the checkout. + """ + checkoutId: ID! + ): CheckoutGiftCardApplyPayload + @deprecated(reason: "Use `checkoutGiftCardsAppend` instead") + + """ + Removes an applied gift card from the checkout. + """ + checkoutGiftCardRemove( + """ + The ID of the Applied Gift Card to remove from the Checkout. + """ + appliedGiftCardId: ID! + + """ + The ID of the checkout. + """ + checkoutId: ID! + ): CheckoutGiftCardRemovePayload + @deprecated(reason: "Use `checkoutGiftCardRemoveV2` instead") + + """ + Removes an applied gift card from the checkout. + """ + checkoutGiftCardRemoveV2( + """ + The ID of the Applied Gift Card to remove from the Checkout. + """ + appliedGiftCardId: ID! + + """ + The ID of the checkout. + """ + checkoutId: ID! + ): CheckoutGiftCardRemoveV2Payload + + """ + Appends gift cards to an existing checkout. + """ + checkoutGiftCardsAppend( + """ + A list of gift card codes to append to the checkout. + """ + giftCardCodes: [String!]! + + """ + The ID of the checkout. + """ + checkoutId: ID! + ): CheckoutGiftCardsAppendPayload + + """ + Adds a list of line items to a checkout. + """ + checkoutLineItemsAdd( + """ + A list of line item objects to add to the checkout. + """ + lineItems: [CheckoutLineItemInput!]! + + """ + The ID of the checkout. + """ + checkoutId: ID! + ): CheckoutLineItemsAddPayload + + """ + Removes line items from an existing checkout. + """ + checkoutLineItemsRemove( + """ + The checkout on which to remove line items. + """ + checkoutId: ID! + + """ + Line item ids to remove. + """ + lineItemIds: [ID!]! + ): CheckoutLineItemsRemovePayload + + """ + Sets a list of line items to a checkout. + """ + checkoutLineItemsReplace( + """ + A list of line item objects to set on the checkout. + """ + lineItems: [CheckoutLineItemInput!]! + + """ + The ID of the checkout. + """ + checkoutId: ID! + ): CheckoutLineItemsReplacePayload + + """ + Updates line items on a checkout. + """ + checkoutLineItemsUpdate( + """ + The checkout on which to update line items. + """ + checkoutId: ID! + + """ + Line items to update. + """ + lineItems: [CheckoutLineItemUpdateInput!]! + ): CheckoutLineItemsUpdatePayload + + """ + Updates the shipping address of an existing checkout. + """ + checkoutShippingAddressUpdate( + """ + The shipping address to where the line items will be shipped. + """ + shippingAddress: MailingAddressInput! + + """ + The ID of the checkout. + """ + checkoutId: ID! + ): CheckoutShippingAddressUpdatePayload + @deprecated(reason: "Use `checkoutShippingAddressUpdateV2` instead") + + """ + Updates the shipping address of an existing checkout. + """ + checkoutShippingAddressUpdateV2( + """ + The shipping address to where the line items will be shipped. + """ + shippingAddress: MailingAddressInput! + + """ + The ID of the checkout. + """ + checkoutId: ID! + ): CheckoutShippingAddressUpdateV2Payload + + """ + Updates the shipping lines on an existing checkout. + """ + checkoutShippingLineUpdate( + """ + The ID of the checkout. + """ + checkoutId: ID! + + """ + A unique identifier to a Checkout’s shipping provider, price, and title combination, enabling the customer to select the availableShippingRates. + """ + shippingRateHandle: String! + ): CheckoutShippingLineUpdatePayload + + """ + Creates a customer access token. + The customer access token is required to modify the customer object in any way. + """ + customerAccessTokenCreate( + """ + The fields used to create a customer access token. + """ + input: CustomerAccessTokenCreateInput! + ): CustomerAccessTokenCreatePayload + + """ + Creates a customer access token using a multipass token instead of email and password. + A customer record is created if customer does not exist. If a customer record already + exists but the record is disabled, then it's enabled. + """ + customerAccessTokenCreateWithMultipass( + """ + A valid multipass token to be authenticated. + """ + multipassToken: String! + ): CustomerAccessTokenCreateWithMultipassPayload + + """ + Permanently destroys a customer access token. + """ + customerAccessTokenDelete( + """ + The access token used to identify the customer. + """ + customerAccessToken: String! + ): CustomerAccessTokenDeletePayload + + """ + Renews a customer access token. + + Access token renewal must happen *before* a token expires. + If a token has already expired, a new one should be created instead via `customerAccessTokenCreate`. + """ + customerAccessTokenRenew( + """ + The access token used to identify the customer. + """ + customerAccessToken: String! + ): CustomerAccessTokenRenewPayload + + """ + Activates a customer. + """ + customerActivate( + """ + Specifies the customer to activate. + """ + id: ID! + + """ + The fields used to activate a customer. + """ + input: CustomerActivateInput! + ): CustomerActivatePayload + + """ + Activates a customer with the activation url received from `customerCreate`. + """ + customerActivateByUrl( + """ + The customer activation URL. + """ + activationUrl: URL! + + """ + A new password set during activation. + """ + password: String! + ): CustomerActivateByUrlPayload + + """ + Creates a new address for a customer. + """ + customerAddressCreate( + """ + The access token used to identify the customer. + """ + customerAccessToken: String! + + """ + The customer mailing address to create. + """ + address: MailingAddressInput! + ): CustomerAddressCreatePayload + + """ + Permanently deletes the address of an existing customer. + """ + customerAddressDelete( + """ + Specifies the address to delete. + """ + id: ID! + + """ + The access token used to identify the customer. + """ + customerAccessToken: String! + ): CustomerAddressDeletePayload + + """ + Updates the address of an existing customer. + """ + customerAddressUpdate( + """ + The access token used to identify the customer. + """ + customerAccessToken: String! + + """ + Specifies the customer address to update. + """ + id: ID! + + """ + The customer’s mailing address. + """ + address: MailingAddressInput! + ): CustomerAddressUpdatePayload + + """ + Creates a new customer. + """ + customerCreate( + """ + The fields used to create a new customer. + """ + input: CustomerCreateInput! + ): CustomerCreatePayload + + """ + Updates the default address of an existing customer. + """ + customerDefaultAddressUpdate( + """ + The access token used to identify the customer. + """ + customerAccessToken: String! + + """ + ID of the address to set as the new default for the customer. + """ + addressId: ID! + ): CustomerDefaultAddressUpdatePayload + + """ + Sends a reset password email to the customer, as the first step in the reset password process. + """ + customerRecover( + """ + The email address of the customer to recover. + """ + email: String! + ): CustomerRecoverPayload + + """ + Resets a customer’s password with a token received from `CustomerRecover`. + """ + customerReset( + """ + Specifies the customer to reset. + """ + id: ID! + + """ + The fields used to reset a customer’s password. + """ + input: CustomerResetInput! + ): CustomerResetPayload + + """ + Resets a customer’s password with the reset password url received from `CustomerRecover`. + """ + customerResetByUrl( + """ + The customer's reset password url. + """ + resetUrl: URL! + + """ + New password that will be set as part of the reset password process. + """ + password: String! + ): CustomerResetByUrlPayload + + """ + Updates an existing customer. + """ + customerUpdate( + """ + The access token used to identify the customer. + """ + customerAccessToken: String! + + """ + The customer object input. + """ + customer: CustomerUpdateInput! + ): CustomerUpdatePayload +} + +""" +An object with an ID to support global identification. +""" +interface Node { + """ + Globally unique identifier. + """ + id: ID! +} + +""" +An order is a customer’s completed request to purchase one or more products from a shop. An order is created when a customer completes the checkout process, during which time they provides an email address, billing address and payment information. +""" +type Order implements Node { + """ + The reason for the order's cancellation. Returns `null` if the order wasn't canceled. + """ + cancelReason: OrderCancelReason + + """ + The date and time when the order was canceled. Returns null if the order wasn't canceled. + """ + canceledAt: DateTime + + """ + The code of the currency used for the payment. + """ + currencyCode: CurrencyCode! + + """ + The subtotal of line items and their discounts, excluding line items that have been removed. Does not contain order-level discounts, duties, shipping costs, or shipping discounts. Taxes are not included unless the order is a taxes-included order. + """ + currentSubtotalPrice: MoneyV2! + + """ + The total amount of the order, including duties, taxes and discounts, minus amounts for line items that have been removed. + """ + currentTotalPrice: MoneyV2! + + """ + The total of all taxes applied to the order, excluding taxes for returned line items. + """ + currentTotalTax: MoneyV2! + + """ + The locale code in which this specific order happened. + """ + customerLocale: String + + """ + The unique URL that the customer can use to access the order. + """ + customerUrl: URL + + """ + Discounts that have been applied on the order. + """ + discountApplications( + """ + Returns up to the first `n` elements from the list. + """ + first: Int + + """ + Returns the elements that come after the specified cursor. + """ + after: String + + """ + Returns up to the last `n` elements from the list. + """ + last: Int + + """ + Returns the elements that come before the specified cursor. + """ + before: String + + """ + Reverse the order of the underlying list. + """ + reverse: Boolean = false + ): DiscountApplicationConnection! + + """ + Whether the order has had any edits applied or not. + """ + edited: Boolean! + + """ + The customer's email address. + """ + email: String + + """ + The financial status of the order. + """ + financialStatus: OrderFinancialStatus + + """ + The fulfillment status for the order. + """ + fulfillmentStatus: OrderFulfillmentStatus! + + """ + Globally unique identifier. + """ + id: ID! + + """ + List of the order’s line items. + """ + lineItems( + """ + Returns up to the first `n` elements from the list. + """ + first: Int + + """ + Returns the elements that come after the specified cursor. + """ + after: String + + """ + Returns up to the last `n` elements from the list. + """ + last: Int + + """ + Returns the elements that come before the specified cursor. + """ + before: String + + """ + Reverse the order of the underlying list. + """ + reverse: Boolean = false + ): OrderLineItemConnection! + + """ + Unique identifier for the order that appears on the order. + For example, _#1000_ or _Store1001. + """ + name: String! + + """ + A unique numeric identifier for the order for use by shop owner and customer. + """ + orderNumber: Int! + + """ + The total price of the order before any applied edits. + """ + originalTotalPrice: MoneyV2! + + """ + The customer's phone number for receiving SMS notifications. + """ + phone: String + + """ + The date and time when the order was imported. + This value can be set to dates in the past when importing from other systems. + If no value is provided, it will be auto-generated based on current date and time. + """ + processedAt: DateTime! + + """ + The address to where the order will be shipped. + """ + shippingAddress: MailingAddress + + """ + The discounts that have been allocated onto the shipping line by discount applications. + """ + shippingDiscountAllocations: [DiscountAllocation!]! + + """ + The unique URL for the order's status page. + """ + statusUrl: URL! + + """ + Price of the order before shipping and taxes. + """ + subtotalPrice: Money @deprecated(reason: "Use `subtotalPriceV2` instead") + + """ + Price of the order before duties, shipping and taxes. + """ + subtotalPriceV2: MoneyV2 + + """ + List of the order’s successful fulfillments. + """ + successfulFulfillments( + """ + Truncate the array result to this size. + """ + first: Int + ): [Fulfillment!] + + """ + The sum of all the prices of all the items in the order, taxes and discounts included (must be positive). + """ + totalPrice: Money! @deprecated(reason: "Use `totalPriceV2` instead") + + """ + The sum of all the prices of all the items in the order, duties, taxes and discounts included (must be positive). + """ + totalPriceV2: MoneyV2! + + """ + The total amount that has been refunded. + """ + totalRefunded: Money! @deprecated(reason: "Use `totalRefundedV2` instead") + + """ + The total amount that has been refunded. + """ + totalRefundedV2: MoneyV2! + + """ + The total cost of shipping. + """ + totalShippingPrice: Money! + @deprecated(reason: "Use `totalShippingPriceV2` instead") + + """ + The total cost of shipping. + """ + totalShippingPriceV2: MoneyV2! + + """ + The total cost of taxes. + """ + totalTax: Money @deprecated(reason: "Use `totalTaxV2` instead") + + """ + The total cost of taxes. + """ + totalTaxV2: MoneyV2 +} + +""" +Represents the reason for the order's cancellation. +""" +enum OrderCancelReason { + """ + The customer wanted to cancel the order. + """ + CUSTOMER + + """ + The order was fraudulent. + """ + FRAUD + + """ + There was insufficient inventory. + """ + INVENTORY + + """ + Payment was declined. + """ + DECLINED + + """ + The order was canceled for an unlisted reason. + """ + OTHER +} + +""" +An auto-generated type for paginating through multiple Orders. +""" +type OrderConnection { + """ + A list of edges. + """ + edges: [OrderEdge!]! + + """ + Information to aid in pagination. + """ + pageInfo: PageInfo! +} + +""" +An auto-generated type which holds one Order and a cursor during pagination. +""" +type OrderEdge { + """ + A cursor for use in pagination. + """ + cursor: String! + + """ + The item at the end of OrderEdge. + """ + node: Order! +} + +""" +Represents the order's current financial status. +""" +enum OrderFinancialStatus { + """ + Displayed as **Pending**. + """ + PENDING + + """ + Displayed as **Authorized**. + """ + AUTHORIZED + + """ + Displayed as **Partially paid**. + """ + PARTIALLY_PAID + + """ + Displayed as **Partially refunded**. + """ + PARTIALLY_REFUNDED + + """ + Displayed as **Voided**. + """ + VOIDED + + """ + Displayed as **Paid**. + """ + PAID + + """ + Displayed as **Refunded**. + """ + REFUNDED +} + +""" +Represents the order's current fulfillment status. +""" +enum OrderFulfillmentStatus { + """ + Displayed as **Unfulfilled**. + """ + UNFULFILLED + + """ + Displayed as **Partially fulfilled**. + """ + PARTIALLY_FULFILLED + + """ + Displayed as **Fulfilled**. + """ + FULFILLED + + """ + Displayed as **Restocked**. + """ + RESTOCKED + + """ + Displayed as **Pending fulfillment**. + """ + PENDING_FULFILLMENT + + """ + Displayed as **Open**. + """ + OPEN + + """ + Displayed as **In progress**. + """ + IN_PROGRESS + + """ + Displayed as **Scheduled**. + """ + SCHEDULED +} + +""" +Represents a single line in an order. There is one line item for each distinct product variant. +""" +type OrderLineItem { + """ + The number of entries associated to the line item minus the items that have been removed. + """ + currentQuantity: Int! + + """ + List of custom attributes associated to the line item. + """ + customAttributes: [Attribute!]! + + """ + The discounts that have been allocated onto the order line item by discount applications. + """ + discountAllocations: [DiscountAllocation!]! + + """ + The total price of the line item, including discounts, and displayed in the presentment currency. + """ + discountedTotalPrice: MoneyV2! + + """ + The total price of the line item, not including any discounts. The total price is calculated using the original unit price multiplied by the quantity, and it is displayed in the presentment currency. + """ + originalTotalPrice: MoneyV2! + + """ + The number of products variants associated to the line item. + """ + quantity: Int! + + """ + The title of the product combined with title of the variant. + """ + title: String! + + """ + The product variant object associated to the line item. + """ + variant: ProductVariant +} + +""" +An auto-generated type for paginating through multiple OrderLineItems. +""" +type OrderLineItemConnection { + """ + A list of edges. + """ + edges: [OrderLineItemEdge!]! + + """ + Information to aid in pagination. + """ + pageInfo: PageInfo! +} + +""" +An auto-generated type which holds one OrderLineItem and a cursor during pagination. +""" +type OrderLineItemEdge { + """ + A cursor for use in pagination. + """ + cursor: String! + + """ + The item at the end of OrderLineItemEdge. + """ + node: OrderLineItem! +} + +""" +The set of valid sort keys for the Order query. +""" +enum OrderSortKeys { + """ + Sort by the `processed_at` value. + """ + PROCESSED_AT + + """ + Sort by the `total_price` value. + """ + TOTAL_PRICE + + """ + Sort by the `id` value. + """ + ID + + """ + During a search (i.e. when the `query` parameter has been specified on the connection) this sorts the + results by relevance to the search term(s). When no search query is specified, this sort key is not + deterministic and should not be used. + """ + RELEVANCE +} + +""" +Shopify merchants can create pages to hold static HTML content. Each Page object represents a custom page on the online store. +""" +type Page implements Node { + """ + The description of the page, complete with HTML formatting. + """ + body: HTML! + + """ + Summary of the page body. + """ + bodySummary: String! + + """ + The timestamp of the page creation. + """ + createdAt: DateTime! + + """ + A human-friendly unique string for the page automatically generated from its title. + """ + handle: String! + + """ + Globally unique identifier. + """ + id: ID! + + """ + The page's SEO information. + """ + seo: SEO + + """ + The title of the page. + """ + title: String! + + """ + The timestamp of the latest page update. + """ + updatedAt: DateTime! + + """ + The url pointing to the page accessible from the web. + """ + url: URL! +} + +""" +An auto-generated type for paginating through multiple Pages. +""" +type PageConnection { + """ + A list of edges. + """ + edges: [PageEdge!]! + + """ + Information to aid in pagination. + """ + pageInfo: PageInfo! +} + +""" +An auto-generated type which holds one Page and a cursor during pagination. +""" +type PageEdge { + """ + A cursor for use in pagination. + """ + cursor: String! + + """ + The item at the end of PageEdge. + """ + node: Page! +} + +""" +Information about pagination in a connection. +""" +type PageInfo { + """ + Indicates if there are more pages to fetch. + """ + hasNextPage: Boolean! + + """ + Indicates if there are any pages prior to the current page. + """ + hasPreviousPage: Boolean! +} + +""" +The set of valid sort keys for the Page query. +""" +enum PageSortKeys { + """ + Sort by the `title` value. + """ + TITLE + + """ + Sort by the `updated_at` value. + """ + UPDATED_AT + + """ + Sort by the `id` value. + """ + ID + + """ + During a search (i.e. when the `query` parameter has been specified on the connection) this sorts the + results by relevance to the search term(s). When no search query is specified, this sort key is not + deterministic and should not be used. + """ + RELEVANCE +} + +""" +A payment applied to a checkout. +""" +type Payment implements Node { + """ + The amount of the payment. + """ + amount: Money! @deprecated(reason: "Use `amountV2` instead") + + """ + The amount of the payment. + """ + amountV2: MoneyV2! + + """ + The billing address for the payment. + """ + billingAddress: MailingAddress + + """ + The checkout to which the payment belongs. + """ + checkout: Checkout! + + """ + The credit card used for the payment in the case of direct payments. + """ + creditCard: CreditCard + + """ + A message describing a processing error during asynchronous processing. + """ + errorMessage: String + + """ + Globally unique identifier. + """ + id: ID! + + """ + A client-side generated token to identify a payment and perform idempotent operations. + """ + idempotencyKey: String + + """ + The URL where the customer needs to be redirected so they can complete the 3D Secure payment flow. + """ + nextActionUrl: URL + + """ + Whether or not the payment is still processing asynchronously. + """ + ready: Boolean! + + """ + A flag to indicate if the payment is to be done in test mode for gateways that support it. + """ + test: Boolean! + + """ + The actual transaction recorded by Shopify after having processed the payment with the gateway. + """ + transaction: Transaction +} + +""" +Settings related to payments. +""" +type PaymentSettings { + """ + List of the card brands which the shop accepts. + """ + acceptedCardBrands: [CardBrand!]! + + """ + The url pointing to the endpoint to vault credit cards. + """ + cardVaultUrl: URL! + + """ + The country where the shop is located. + """ + countryCode: CountryCode! + + """ + The three-letter code for the shop's primary currency. + """ + currencyCode: CurrencyCode! + + """ + A list of enabled currencies (ISO 4217 format) that the shop accepts. Merchants can enable currencies from their Shopify Payments settings in the Shopify admin. + """ + enabledPresentmentCurrencies: [CurrencyCode!]! + + """ + The shop’s Shopify Payments account id. + """ + shopifyPaymentsAccountId: String + + """ + List of the digital wallets which the shop supports. + """ + supportedDigitalWallets: [DigitalWallet!]! +} + +""" +The valid values for the types of payment token. +""" +enum PaymentTokenType { + """ + Apple Pay token type. + """ + APPLE_PAY + + """ + Vault payment token type. + """ + VAULT + + """ + Shopify Pay token type. + """ + SHOPIFY_PAY + + """ + Google Pay token type. + """ + GOOGLE_PAY +} + +""" +The value of the percentage pricing object. +""" +type PricingPercentageValue { + """ + The percentage value of the object. + """ + percentage: Float! +} + +""" +The price value (fixed or percentage) for a discount application. +""" +union PricingValue = MoneyV2 | PricingPercentageValue + +""" +A product represents an individual item for sale in a Shopify store. Products are often physical, but they don't have to be. +For example, a digital download (such as a movie, music or ebook file) also qualifies as a product, as do services (such as equipment rental, work for hire, customization of another product or an extended warranty). +""" +type Product implements Node & HasMetafields { + """ + Indicates if at least one product variant is available for sale. + """ + availableForSale: Boolean! + + """ + List of collections a product belongs to. + """ + collections( + """ + Returns up to the first `n` elements from the list. + """ + first: Int + + """ + Returns the elements that come after the specified cursor. + """ + after: String + + """ + Returns up to the last `n` elements from the list. + """ + last: Int + + """ + Returns the elements that come before the specified cursor. + """ + before: String + + """ + Reverse the order of the underlying list. + """ + reverse: Boolean = false + ): CollectionConnection! + + """ + The compare at price of the product across all variants. + """ + compareAtPriceRange: ProductPriceRange! + + """ + The date and time when the product was created. + """ + createdAt: DateTime! + + """ + Stripped description of the product, single line with HTML tags removed. + """ + description( + """ + Truncates string after the given length. + """ + truncateAt: Int + ): String! + + """ + The description of the product, complete with HTML formatting. + """ + descriptionHtml: HTML! + + """ + A human-friendly unique string for the Product automatically generated from its title. + They are used by the Liquid templating language to refer to objects. + """ + handle: String! + + """ + Globally unique identifier. + """ + id: ID! + + """ + List of images associated with the product. + """ + images( + """ + Returns up to the first `n` elements from the list. + """ + first: Int + + """ + Returns the elements that come after the specified cursor. + """ + after: String + + """ + Returns up to the last `n` elements from the list. + """ + last: Int + + """ + Returns the elements that come before the specified cursor. + """ + before: String + + """ + Reverse the order of the underlying list. + """ + reverse: Boolean = false + + """ + Sort the underlying list by the given key. + """ + sortKey: ProductImageSortKeys = POSITION + + """ + Image width in pixels between 1 and 2048. This argument is deprecated: Use `maxWidth` on `Image.transformedSrc` instead. + """ + maxWidth: Int + + """ + Image height in pixels between 1 and 2048. This argument is deprecated: Use `maxHeight` on `Image.transformedSrc` instead. + """ + maxHeight: Int + + """ + Crops the image according to the specified region. This argument is deprecated: Use `crop` on `Image.transformedSrc` instead. + """ + crop: CropRegion + + """ + Image size multiplier for high-resolution retina displays. Must be between 1 and 3. This argument is deprecated: Use `scale` on `Image.transformedSrc` instead. + """ + scale: Int = 1 + ): ImageConnection! + + """ + The media associated with the product. + """ + media( + """ + Returns up to the first `n` elements from the list. + """ + first: Int + + """ + Returns the elements that come after the specified cursor. + """ + after: String + + """ + Returns up to the last `n` elements from the list. + """ + last: Int + + """ + Returns the elements that come before the specified cursor. + """ + before: String + + """ + Reverse the order of the underlying list. + """ + reverse: Boolean = false + + """ + Sort the underlying list by the given key. + """ + sortKey: ProductMediaSortKeys = POSITION + ): MediaConnection! + + """ + The metafield associated with the resource. + """ + metafield( + """ + Container for a set of metafields (maximum of 20 characters). + """ + namespace: String! + + """ + Identifier for the metafield (maximum of 30 characters). + """ + key: String! + ): Metafield + + """ + A paginated list of metafields associated with the resource. + """ + metafields( + """ + Container for a set of metafields (maximum of 20 characters). + """ + namespace: String + + """ + Returns up to the first `n` elements from the list. + """ + first: Int + + """ + Returns the elements that come after the specified cursor. + """ + after: String + + """ + Returns up to the last `n` elements from the list. + """ + last: Int + + """ + Returns the elements that come before the specified cursor. + """ + before: String + + """ + Reverse the order of the underlying list. + """ + reverse: Boolean = false + ): MetafieldConnection! + + """ + The online store URL for the product. + A value of `null` indicates that the product is not published to the Online Store sales channel. + """ + onlineStoreUrl: URL + + """ + List of product options. + """ + options( + """ + Truncate the array result to this size. + """ + first: Int + ): [ProductOption!]! + + """ + List of price ranges in the presentment currencies for this shop. + """ + presentmentPriceRanges( + """ + Specifies the presentment currencies to return a price range in. + """ + presentmentCurrencies: [CurrencyCode!] + + """ + Returns up to the first `n` elements from the list. + """ + first: Int + + """ + Returns the elements that come after the specified cursor. + """ + after: String + + """ + Returns up to the last `n` elements from the list. + """ + last: Int + + """ + Returns the elements that come before the specified cursor. + """ + before: String + + """ + Reverse the order of the underlying list. + """ + reverse: Boolean = false + ): ProductPriceRangeConnection! + + """ + The price range. + """ + priceRange: ProductPriceRange! + + """ + A categorization that a product can be tagged with, commonly used for filtering and searching. + """ + productType: String! + + """ + The date and time when the product was published to the channel. + """ + publishedAt: DateTime! + + """ + The product's SEO information. + """ + seo: SEO! + + """ + A comma separated list of tags that have been added to the product. + Additional access scope required for private apps: unauthenticated_read_product_tags. + """ + tags: [String!]! + + """ + The product’s title. + """ + title: String! + + """ + The total quantity of inventory in stock for this Product. + """ + totalInventory: Int + + """ + The date and time when the product was last modified. + A product's `updatedAt` value can change for different reasons. For example, if an order + is placed for a product that has inventory tracking set up, then the inventory adjustment + is counted as an update. + """ + updatedAt: DateTime! + + """ + Find a product’s variant based on its selected options. + This is useful for converting a user’s selection of product options into a single matching variant. + If there is not a variant for the selected options, `null` will be returned. + """ + variantBySelectedOptions( + """ + The input fields used for a selected option. + """ + selectedOptions: [SelectedOptionInput!]! + ): ProductVariant + + """ + List of the product’s variants. + """ + variants( + """ + Returns up to the first `n` elements from the list. + """ + first: Int + + """ + Returns the elements that come after the specified cursor. + """ + after: String + + """ + Returns up to the last `n` elements from the list. + """ + last: Int + + """ + Returns the elements that come before the specified cursor. + """ + before: String + + """ + Reverse the order of the underlying list. + """ + reverse: Boolean = false + + """ + Sort the underlying list by the given key. + """ + sortKey: ProductVariantSortKeys = POSITION + ): ProductVariantConnection! + + """ + The product’s vendor name. + """ + vendor: String! +} + +""" +The set of valid sort keys for the ProductCollection query. +""" +enum ProductCollectionSortKeys { + """ + Sort by the `title` value. + """ + TITLE + + """ + Sort by the `price` value. + """ + PRICE + + """ + Sort by the `best-selling` value. + """ + BEST_SELLING + + """ + Sort by the `created` value. + """ + CREATED + + """ + Sort by the `id` value. + """ + ID + + """ + Sort by the `manual` value. + """ + MANUAL + + """ + Sort by the `collection-default` value. + """ + COLLECTION_DEFAULT + + """ + During a search (i.e. when the `query` parameter has been specified on the connection) this sorts the + results by relevance to the search term(s). When no search query is specified, this sort key is not + deterministic and should not be used. + """ + RELEVANCE +} + +""" +An auto-generated type for paginating through multiple Products. +""" +type ProductConnection { + """ + A list of edges. + """ + edges: [ProductEdge!]! + + """ + Information to aid in pagination. + """ + pageInfo: PageInfo! +} + +""" +An auto-generated type which holds one Product and a cursor during pagination. +""" +type ProductEdge { + """ + A cursor for use in pagination. + """ + cursor: String! + + """ + The item at the end of ProductEdge. + """ + node: Product! +} + +""" +The set of valid sort keys for the ProductImage query. +""" +enum ProductImageSortKeys { + """ + Sort by the `created_at` value. + """ + CREATED_AT + + """ + Sort by the `position` value. + """ + POSITION + + """ + Sort by the `id` value. + """ + ID + + """ + During a search (i.e. when the `query` parameter has been specified on the connection) this sorts the + results by relevance to the search term(s). When no search query is specified, this sort key is not + deterministic and should not be used. + """ + RELEVANCE +} + +""" +The set of valid sort keys for the ProductMedia query. +""" +enum ProductMediaSortKeys { + """ + Sort by the `position` value. + """ + POSITION + + """ + Sort by the `id` value. + """ + ID + + """ + During a search (i.e. when the `query` parameter has been specified on the connection) this sorts the + results by relevance to the search term(s). When no search query is specified, this sort key is not + deterministic and should not be used. + """ + RELEVANCE +} + +""" +Product property names like "Size", "Color", and "Material" that the customers can select. +Variants are selected based on permutations of these options. +255 characters limit each. +""" +type ProductOption implements Node { + """ + Globally unique identifier. + """ + id: ID! + + """ + The product option’s name. + """ + name: String! + + """ + The corresponding value to the product option name. + """ + values: [String!]! +} + +""" +The price range of the product. +""" +type ProductPriceRange { + """ + The highest variant's price. + """ + maxVariantPrice: MoneyV2! + + """ + The lowest variant's price. + """ + minVariantPrice: MoneyV2! +} + +""" +An auto-generated type for paginating through multiple ProductPriceRanges. +""" +type ProductPriceRangeConnection { + """ + A list of edges. + """ + edges: [ProductPriceRangeEdge!]! + + """ + Information to aid in pagination. + """ + pageInfo: PageInfo! +} + +""" +An auto-generated type which holds one ProductPriceRange and a cursor during pagination. +""" +type ProductPriceRangeEdge { + """ + A cursor for use in pagination. + """ + cursor: String! + + """ + The item at the end of ProductPriceRangeEdge. + """ + node: ProductPriceRange! +} + +""" +The set of valid sort keys for the Product query. +""" +enum ProductSortKeys { + """ + Sort by the `title` value. + """ + TITLE + + """ + Sort by the `product_type` value. + """ + PRODUCT_TYPE + + """ + Sort by the `vendor` value. + """ + VENDOR + + """ + Sort by the `updated_at` value. + """ + UPDATED_AT + + """ + Sort by the `created_at` value. + """ + CREATED_AT + + """ + Sort by the `best_selling` value. + """ + BEST_SELLING + + """ + Sort by the `price` value. + """ + PRICE + + """ + Sort by the `id` value. + """ + ID + + """ + During a search (i.e. when the `query` parameter has been specified on the connection) this sorts the + results by relevance to the search term(s). When no search query is specified, this sort key is not + deterministic and should not be used. + """ + RELEVANCE +} + +""" +A product variant represents a different version of a product, such as differing sizes or differing colors. +""" +type ProductVariant implements Node & HasMetafields { + """ + Indicates if the product variant is in stock. + """ + available: Boolean @deprecated(reason: "Use `availableForSale` instead") + + """ + Indicates if the product variant is available for sale. + """ + availableForSale: Boolean! + + """ + The compare at price of the variant. This can be used to mark a variant as on sale, when `compareAtPrice` is higher than `price`. + """ + compareAtPrice: Money @deprecated(reason: "Use `compareAtPriceV2` instead") + + """ + The compare at price of the variant. This can be used to mark a variant as on sale, when `compareAtPriceV2` is higher than `priceV2`. + """ + compareAtPriceV2: MoneyV2 + + """ + Whether a product is out of stock but still available for purchase (used for backorders). + """ + currentlyNotInStock: Boolean! + + """ + Globally unique identifier. + """ + id: ID! + + """ + Image associated with the product variant. This field falls back to the product image if no image is available. + """ + image( + """ + Image width in pixels between 1 and 2048. This argument is deprecated: Use `maxWidth` on `Image.transformedSrc` instead. + """ + maxWidth: Int + + """ + Image height in pixels between 1 and 2048. This argument is deprecated: Use `maxHeight` on `Image.transformedSrc` instead. + """ + maxHeight: Int + + """ + Crops the image according to the specified region. This argument is deprecated: Use `crop` on `Image.transformedSrc` instead. + """ + crop: CropRegion + + """ + Image size multiplier for high-resolution retina displays. Must be between 1 and 3. This argument is deprecated: Use `scale` on `Image.transformedSrc` instead. + """ + scale: Int = 1 + ): Image + + """ + The metafield associated with the resource. + """ + metafield( + """ + Container for a set of metafields (maximum of 20 characters). + """ + namespace: String! + + """ + Identifier for the metafield (maximum of 30 characters). + """ + key: String! + ): Metafield + + """ + A paginated list of metafields associated with the resource. + """ + metafields( + """ + Container for a set of metafields (maximum of 20 characters). + """ + namespace: String + + """ + Returns up to the first `n` elements from the list. + """ + first: Int + + """ + Returns the elements that come after the specified cursor. + """ + after: String + + """ + Returns up to the last `n` elements from the list. + """ + last: Int + + """ + Returns the elements that come before the specified cursor. + """ + before: String + + """ + Reverse the order of the underlying list. + """ + reverse: Boolean = false + ): MetafieldConnection! + + """ + List of prices and compare-at prices in the presentment currencies for this shop. + """ + presentmentPrices( + """ + The presentment currencies prices should return in. + """ + presentmentCurrencies: [CurrencyCode!] + + """ + Returns up to the first `n` elements from the list. + """ + first: Int + + """ + Returns the elements that come after the specified cursor. + """ + after: String + + """ + Returns up to the last `n` elements from the list. + """ + last: Int + + """ + Returns the elements that come before the specified cursor. + """ + before: String + + """ + Reverse the order of the underlying list. + """ + reverse: Boolean = false + ): ProductVariantPricePairConnection! + + """ + List of unit prices in the presentment currencies for this shop. + """ + presentmentUnitPrices( + """ + Specify the currencies in which to return presentment unit prices. + """ + presentmentCurrencies: [CurrencyCode!] + + """ + Returns up to the first `n` elements from the list. + """ + first: Int + + """ + Returns the elements that come after the specified cursor. + """ + after: String + + """ + Returns up to the last `n` elements from the list. + """ + last: Int + + """ + Returns the elements that come before the specified cursor. + """ + before: String + + """ + Reverse the order of the underlying list. + """ + reverse: Boolean = false + ): MoneyV2Connection! + + """ + The product variant’s price. + """ + price: Money! @deprecated(reason: "Use `priceV2` instead") + + """ + The product variant’s price. + """ + priceV2: MoneyV2! + + """ + The product object that the product variant belongs to. + """ + product: Product! + + """ + The total sellable quantity of the variant for online sales channels. + """ + quantityAvailable: Int + + """ + Whether a customer needs to provide a shipping address when placing an order for the product variant. + """ + requiresShipping: Boolean! + + """ + List of product options applied to the variant. + """ + selectedOptions: [SelectedOption!]! + + """ + The SKU (stock keeping unit) associated with the variant. + """ + sku: String + + """ + The product variant’s title. + """ + title: String! + + """ + The unit price value for the variant based on the variant's measurement. + """ + unitPrice: MoneyV2 + + """ + The unit price measurement for the variant. + """ + unitPriceMeasurement: UnitPriceMeasurement + + """ + The weight of the product variant in the unit system specified with `weight_unit`. + """ + weight: Float + + """ + Unit of measurement for weight. + """ + weightUnit: WeightUnit! +} + +""" +An auto-generated type for paginating through multiple ProductVariants. +""" +type ProductVariantConnection { + """ + A list of edges. + """ + edges: [ProductVariantEdge!]! + + """ + Information to aid in pagination. + """ + pageInfo: PageInfo! +} + +""" +An auto-generated type which holds one ProductVariant and a cursor during pagination. +""" +type ProductVariantEdge { + """ + A cursor for use in pagination. + """ + cursor: String! + + """ + The item at the end of ProductVariantEdge. + """ + node: ProductVariant! +} + +""" +The compare-at price and price of a variant sharing a currency. +""" +type ProductVariantPricePair { + """ + The compare-at price of the variant with associated currency. + """ + compareAtPrice: MoneyV2 + + """ + The price of the variant with associated currency. + """ + price: MoneyV2! +} + +""" +An auto-generated type for paginating through multiple ProductVariantPricePairs. +""" +type ProductVariantPricePairConnection { + """ + A list of edges. + """ + edges: [ProductVariantPricePairEdge!]! + + """ + Information to aid in pagination. + """ + pageInfo: PageInfo! +} + +""" +An auto-generated type which holds one ProductVariantPricePair and a cursor during pagination. +""" +type ProductVariantPricePairEdge { + """ + A cursor for use in pagination. + """ + cursor: String! + + """ + The item at the end of ProductVariantPricePairEdge. + """ + node: ProductVariantPricePair! +} + +""" +The set of valid sort keys for the ProductVariant query. +""" +enum ProductVariantSortKeys { + """ + Sort by the `title` value. + """ + TITLE + + """ + Sort by the `sku` value. + """ + SKU + + """ + Sort by the `position` value. + """ + POSITION + + """ + Sort by the `id` value. + """ + ID + + """ + During a search (i.e. when the `query` parameter has been specified on the connection) this sorts the + results by relevance to the search term(s). When no search query is specified, this sort key is not + deterministic and should not be used. + """ + RELEVANCE +} + +""" +The schema’s entry-point for queries. This acts as the public, top-level API from which all queries must start. +""" +type QueryRoot { + """ + List of the shop's articles. + """ + articles( + """ + Returns up to the first `n` elements from the list. + """ + first: Int + + """ + Returns the elements that come after the specified cursor. + """ + after: String + + """ + Returns up to the last `n` elements from the list. + """ + last: Int + + """ + Returns the elements that come before the specified cursor. + """ + before: String + + """ + Reverse the order of the underlying list. + """ + reverse: Boolean = false + + """ + Sort the underlying list by the given key. + """ + sortKey: ArticleSortKeys = ID + + """ + Supported filter parameters: + - `author` + - `blog_title` + - `created_at` + - `tag` + - `updated_at` + + See the detailed [search syntax](https://help.shopify.com/api/getting-started/search-syntax) + for more information about using filters. + """ + query: String + ): ArticleConnection! + + """ + Find a blog by its handle. + """ + blogByHandle( + """ + The handle of the blog. + """ + handle: String! + ): Blog + + """ + List of the shop's blogs. + """ + blogs( + """ + Returns up to the first `n` elements from the list. + """ + first: Int + + """ + Returns the elements that come after the specified cursor. + """ + after: String + + """ + Returns up to the last `n` elements from the list. + """ + last: Int + + """ + Returns the elements that come before the specified cursor. + """ + before: String + + """ + Reverse the order of the underlying list. + """ + reverse: Boolean = false + + """ + Sort the underlying list by the given key. + """ + sortKey: BlogSortKeys = ID + + """ + Supported filter parameters: + - `created_at` + - `handle` + - `title` + - `updated_at` + + See the detailed [search syntax](https://help.shopify.com/api/getting-started/search-syntax) + for more information about using filters. + """ + query: String + ): BlogConnection! + + """ + Find a collection by its handle. + """ + collectionByHandle( + """ + The handle of the collection. + """ + handle: String! + ): Collection + + """ + List of the shop’s collections. + """ + collections( + """ + Returns up to the first `n` elements from the list. + """ + first: Int + + """ + Returns the elements that come after the specified cursor. + """ + after: String + + """ + Returns up to the last `n` elements from the list. + """ + last: Int + + """ + Returns the elements that come before the specified cursor. + """ + before: String + + """ + Reverse the order of the underlying list. + """ + reverse: Boolean = false + + """ + Sort the underlying list by the given key. + """ + sortKey: CollectionSortKeys = ID + + """ + Supported filter parameters: + - `collection_type` + - `title` + - `updated_at` + + See the detailed [search syntax](https://help.shopify.com/api/getting-started/search-syntax) + for more information about using filters. + """ + query: String + ): CollectionConnection! + + """ + Find a customer by its access token. + """ + customer( + """ + The customer access token. + """ + customerAccessToken: String! + ): Customer + node( + """ + The ID of the Node to return. + """ + id: ID! + ): Node + nodes( + """ + The IDs of the Nodes to return. + """ + ids: [ID!]! + ): [Node]! + + """ + Find a page by its handle. + """ + pageByHandle( + """ + The handle of the page. + """ + handle: String! + ): Page + + """ + List of the shop's pages. + """ + pages( + """ + Returns up to the first `n` elements from the list. + """ + first: Int + + """ + Returns the elements that come after the specified cursor. + """ + after: String + + """ + Returns up to the last `n` elements from the list. + """ + last: Int + + """ + Returns the elements that come before the specified cursor. + """ + before: String + + """ + Reverse the order of the underlying list. + """ + reverse: Boolean = false + + """ + Sort the underlying list by the given key. + """ + sortKey: PageSortKeys = ID + + """ + Supported filter parameters: + - `created_at` + - `handle` + - `title` + - `updated_at` + + See the detailed [search syntax](https://help.shopify.com/api/getting-started/search-syntax) + for more information about using filters. + """ + query: String + ): PageConnection! + + """ + Find a product by its handle. + """ + productByHandle( + """ + The handle of the product. + """ + handle: String! + ): Product + + """ + Find recommended products related to a given `product_id`. + To learn more about how recommendations are generated, see + [*Showing product recommendations on product pages*](https://help.shopify.com/themes/development/recommended-products). + """ + productRecommendations( + """ + The id of the product. + """ + productId: ID! + ): [Product!] + + """ + Tags added to products. + Additional access scope required: unauthenticated_read_product_tags. + """ + productTags( + """ + Returns up to the first `n` elements from the list. + """ + first: Int! + ): StringConnection! + + """ + List of product types for the shop's products that are published to your app. + """ + productTypes( + """ + Returns up to the first `n` elements from the list. + """ + first: Int! + ): StringConnection! + + """ + List of the shop’s products. + """ + products( + """ + Returns up to the first `n` elements from the list. + """ + first: Int + + """ + Returns the elements that come after the specified cursor. + """ + after: String + + """ + Returns up to the last `n` elements from the list. + """ + last: Int + + """ + Returns the elements that come before the specified cursor. + """ + before: String + + """ + Reverse the order of the underlying list. + """ + reverse: Boolean = false + + """ + Sort the underlying list by the given key. + """ + sortKey: ProductSortKeys = ID + + """ + Supported filter parameters: + - `available_for_sale` + - `created_at` + - `product_type` + - `tag` + - `title` + - `updated_at` + - `variants.price` + - `vendor` + + See the detailed [search syntax](https://help.shopify.com/api/getting-started/search-syntax) + for more information about using filters. + """ + query: String + ): ProductConnection! + + """ + The list of public Storefront API versions, including supported, release candidate and unstable versions. + """ + publicApiVersions: [ApiVersion!]! + + """ + The shop associated with the storefront access token. + """ + shop: Shop! +} + +""" +SEO information. +""" +type SEO { + """ + The meta description. + """ + description: String + + """ + The SEO title. + """ + title: String +} + +""" +Script discount applications capture the intentions of a discount that +was created by a Shopify Script. +""" +type ScriptDiscountApplication implements DiscountApplication { + """ + The method by which the discount's value is allocated to its entitled items. + """ + allocationMethod: DiscountApplicationAllocationMethod! + + """ + The description of the application as defined by the Script. + """ + description: String! @deprecated(reason: "Use `title` instead") + + """ + Which lines of targetType that the discount is allocated over. + """ + targetSelection: DiscountApplicationTargetSelection! + + """ + The type of line that the discount is applicable towards. + """ + targetType: DiscountApplicationTargetType! + + """ + The title of the application as defined by the Script. + """ + title: String! + + """ + The value of the discount application. + """ + value: PricingValue! +} + +""" +Properties used by customers to select a product variant. +Products can have multiple options, like different sizes or colors. +""" +type SelectedOption { + """ + The product option’s name. + """ + name: String! + + """ + The product option’s value. + """ + value: String! +} + +""" +Specifies the input fields required for a selected option. +""" +input SelectedOptionInput { + """ + The product option’s name. + """ + name: String! + + """ + The product option’s value. + """ + value: String! +} + +""" +A shipping rate to be applied to a checkout. +""" +type ShippingRate { + """ + Human-readable unique identifier for this shipping rate. + """ + handle: String! + + """ + Price of this shipping rate. + """ + price: Money! @deprecated(reason: "Use `priceV2` instead") + + """ + Price of this shipping rate. + """ + priceV2: MoneyV2! + + """ + Title of this shipping rate. + """ + title: String! +} + +""" +Shop represents a collection of the general settings and information about the shop. +""" +type Shop { + """ + List of the shop' articles. + """ + articles( + """ + Returns up to the first `n` elements from the list. + """ + first: Int + + """ + Returns the elements that come after the specified cursor. + """ + after: String + + """ + Returns up to the last `n` elements from the list. + """ + last: Int + + """ + Returns the elements that come before the specified cursor. + """ + before: String + + """ + Reverse the order of the underlying list. + """ + reverse: Boolean = false + + """ + Sort the underlying list by the given key. + """ + sortKey: ArticleSortKeys = ID + + """ + Supported filter parameters: + - `author` + - `blog_title` + - `created_at` + - `tag` + - `updated_at` + + See the detailed [search syntax](https://help.shopify.com/api/getting-started/search-syntax) + for more information about using filters. + """ + query: String + ): ArticleConnection! @deprecated(reason: "Use `QueryRoot.articles` instead.") + + """ + List of the shop' blogs. + """ + blogs( + """ + Returns up to the first `n` elements from the list. + """ + first: Int + + """ + Returns the elements that come after the specified cursor. + """ + after: String + + """ + Returns up to the last `n` elements from the list. + """ + last: Int + + """ + Returns the elements that come before the specified cursor. + """ + before: String + + """ + Reverse the order of the underlying list. + """ + reverse: Boolean = false + + """ + Sort the underlying list by the given key. + """ + sortKey: BlogSortKeys = ID + + """ + Supported filter parameters: + - `created_at` + - `handle` + - `title` + - `updated_at` + + See the detailed [search syntax](https://help.shopify.com/api/getting-started/search-syntax) + for more information about using filters. + """ + query: String + ): BlogConnection! @deprecated(reason: "Use `QueryRoot.blogs` instead.") + + """ + Find a collection by its handle. + """ + collectionByHandle( + """ + The handle of the collection. + """ + handle: String! + ): Collection + @deprecated(reason: "Use `QueryRoot.collectionByHandle` instead.") + + """ + List of the shop’s collections. + """ + collections( + """ + Returns up to the first `n` elements from the list. + """ + first: Int + + """ + Returns the elements that come after the specified cursor. + """ + after: String + + """ + Returns up to the last `n` elements from the list. + """ + last: Int + + """ + Returns the elements that come before the specified cursor. + """ + before: String + + """ + Reverse the order of the underlying list. + """ + reverse: Boolean = false + + """ + Sort the underlying list by the given key. + """ + sortKey: CollectionSortKeys = ID + + """ + Supported filter parameters: + - `collection_type` + - `title` + - `updated_at` + + See the detailed [search syntax](https://help.shopify.com/api/getting-started/search-syntax) + for more information about using filters. + """ + query: String + ): CollectionConnection! + @deprecated(reason: "Use `QueryRoot.collections` instead.") + + """ + The three-letter code for the currency that the shop accepts. + """ + currencyCode: CurrencyCode! + @deprecated(reason: "Use `paymentSettings` instead") + + """ + A description of the shop. + """ + description: String + + """ + A string representing the way currency is formatted when the currency isn’t specified. + """ + moneyFormat: String! + + """ + The shop’s name. + """ + name: String! + + """ + Settings related to payments. + """ + paymentSettings: PaymentSettings! + + """ + The shop’s primary domain. + """ + primaryDomain: Domain! + + """ + The shop’s privacy policy. + """ + privacyPolicy: ShopPolicy + + """ + Find a product by its handle. + """ + productByHandle( + """ + The handle of the product. + """ + handle: String! + ): Product @deprecated(reason: "Use `QueryRoot.productByHandle` instead.") + + """ + A list of tags that have been added to products. + Additional access scope required: unauthenticated_read_product_tags. + """ + productTags( + """ + Returns up to the first `n` elements from the list. + """ + first: Int! + ): StringConnection! + @deprecated(reason: "Use `QueryRoot.productTags` instead.") + + """ + List of the shop’s product types. + """ + productTypes( + """ + Returns up to the first `n` elements from the list. + """ + first: Int! + ): StringConnection! + @deprecated(reason: "Use `QueryRoot.productTypes` instead.") + + """ + List of the shop’s products. + """ + products( + """ + Returns up to the first `n` elements from the list. + """ + first: Int + + """ + Returns the elements that come after the specified cursor. + """ + after: String + + """ + Returns up to the last `n` elements from the list. + """ + last: Int + + """ + Returns the elements that come before the specified cursor. + """ + before: String + + """ + Reverse the order of the underlying list. + """ + reverse: Boolean = false + + """ + Sort the underlying list by the given key. + """ + sortKey: ProductSortKeys = ID + + """ + Supported filter parameters: + - `available_for_sale` + - `created_at` + - `product_type` + - `tag` + - `title` + - `updated_at` + - `variants.price` + - `vendor` + + See the detailed [search syntax](https://help.shopify.com/api/getting-started/search-syntax) + for more information about using filters. + """ + query: String + ): ProductConnection! @deprecated(reason: "Use `QueryRoot.products` instead.") + + """ + The shop’s refund policy. + """ + refundPolicy: ShopPolicy + + """ + The shop’s shipping policy. + """ + shippingPolicy: ShopPolicy + + """ + Countries that the shop ships to. + """ + shipsToCountries: [CountryCode!]! + + """ + The shop’s Shopify Payments account id. + """ + shopifyPaymentsAccountId: String + @deprecated(reason: "Use `paymentSettings` instead") + + """ + The shop’s terms of service. + """ + termsOfService: ShopPolicy +} + +""" +Policy that a merchant has configured for their store, such as their refund or privacy policy. +""" +type ShopPolicy implements Node { + """ + Policy text, maximum size of 64kb. + """ + body: String! + + """ + Policy’s handle. + """ + handle: String! + + """ + Globally unique identifier. + """ + id: ID! + + """ + Policy’s title. + """ + title: String! + + """ + Public URL to the policy. + """ + url: URL! +} + +""" +An auto-generated type for paginating through multiple Strings. +""" +type StringConnection { + """ + A list of edges. + """ + edges: [StringEdge!]! + + """ + Information to aid in pagination. + """ + pageInfo: PageInfo! +} + +""" +An auto-generated type which holds one String and a cursor during pagination. +""" +type StringEdge { + """ + A cursor for use in pagination. + """ + cursor: String! + + """ + The item at the end of StringEdge. + """ + node: String! +} + +""" +Specifies the fields required to complete a checkout with +a tokenized payment. +""" +input TokenizedPaymentInput { + """ + The amount of the payment. + """ + amount: Money! + + """ + A unique client generated key used to avoid duplicate charges. When a duplicate payment is found, the original is returned instead of creating a new one. + """ + idempotencyKey: String! + + """ + The billing address for the payment. + """ + billingAddress: MailingAddressInput! + + """ + The type of payment token. + """ + type: String! + + """ + A simple string or JSON containing the required payment data for the tokenized payment. + """ + paymentData: String! + + """ + Executes the payment in test mode if possible. Defaults to `false`. + """ + test: Boolean + + """ + Public Hash Key used for AndroidPay payments only. + """ + identifier: String +} + +""" +Specifies the fields required to complete a checkout with +a tokenized payment. +""" +input TokenizedPaymentInputV2 { + """ + The amount and currency of the payment. + """ + paymentAmount: MoneyInput! + + """ + A unique client generated key used to avoid duplicate charges. When a duplicate payment is found, the original is returned instead of creating a new one. + """ + idempotencyKey: String! + + """ + The billing address for the payment. + """ + billingAddress: MailingAddressInput! + + """ + A simple string or JSON containing the required payment data for the tokenized payment. + """ + paymentData: String! + + """ + Whether to execute the payment in test mode, if possible. Test mode is not supported in production stores. Defaults to `false`. + """ + test: Boolean + + """ + Public Hash Key used for AndroidPay payments only. + """ + identifier: String + + """ + The type of payment token. + """ + type: String! +} + +""" +Specifies the fields required to complete a checkout with +a tokenized payment. +""" +input TokenizedPaymentInputV3 { + """ + The amount and currency of the payment. + """ + paymentAmount: MoneyInput! + + """ + A unique client generated key used to avoid duplicate charges. When a duplicate payment is found, the original is returned instead of creating a new one. + """ + idempotencyKey: String! + + """ + The billing address for the payment. + """ + billingAddress: MailingAddressInput! + + """ + A simple string or JSON containing the required payment data for the tokenized payment. + """ + paymentData: String! + + """ + Whether to execute the payment in test mode, if possible. Test mode is not supported in production stores. Defaults to `false`. + """ + test: Boolean + + """ + Public Hash Key used for AndroidPay payments only. + """ + identifier: String + + """ + The type of payment token. + """ + type: PaymentTokenType! +} + +""" +An object representing exchange of money for a product or service. +""" +type Transaction { + """ + The amount of money that the transaction was for. + """ + amount: Money! @deprecated(reason: "Use `amountV2` instead") + + """ + The amount of money that the transaction was for. + """ + amountV2: MoneyV2! + + """ + The kind of the transaction. + """ + kind: TransactionKind! + + """ + The status of the transaction. + """ + status: TransactionStatus! @deprecated(reason: "Use `statusV2` instead") + + """ + The status of the transaction. + """ + statusV2: TransactionStatus + + """ + Whether the transaction was done in test mode or not. + """ + test: Boolean! +} + +enum TransactionKind { + SALE + CAPTURE + AUTHORIZATION + EMV_AUTHORIZATION + CHANGE +} + +enum TransactionStatus { + PENDING + SUCCESS + FAILURE + ERROR +} + +""" +An RFC 3986 and RFC 3987 compliant URI string. + +Example value: `"https://johns-apparel.myshopify.com"`. +""" +scalar URL + +""" +The measurement used to calculate a unit price for a product variant (e.g. $9.99 / 100ml). +""" +type UnitPriceMeasurement { + """ + The type of unit of measurement for the unit price measurement. + """ + measuredType: UnitPriceMeasurementMeasuredType + + """ + The quantity unit for the unit price measurement. + """ + quantityUnit: UnitPriceMeasurementMeasuredUnit + + """ + The quantity value for the unit price measurement. + """ + quantityValue: Float! + + """ + The reference unit for the unit price measurement. + """ + referenceUnit: UnitPriceMeasurementMeasuredUnit + + """ + The reference value for the unit price measurement. + """ + referenceValue: Int! +} + +""" +The accepted types of unit of measurement. +""" +enum UnitPriceMeasurementMeasuredType { + """ + Unit of measurements representing volumes. + """ + VOLUME + + """ + Unit of measurements representing weights. + """ + WEIGHT + + """ + Unit of measurements representing lengths. + """ + LENGTH + + """ + Unit of measurements representing areas. + """ + AREA +} + +""" +The valid units of measurement for a unit price measurement. +""" +enum UnitPriceMeasurementMeasuredUnit { + """ + 1000 milliliters equals 1 liter. + """ + ML + + """ + 100 centiliters equals 1 liter. + """ + CL + + """ + Metric system unit of volume. + """ + L + + """ + 1 cubic meter equals 1000 liters. + """ + M3 + + """ + 1000 milligrams equals 1 gram. + """ + MG + + """ + Metric system unit of weight. + """ + G + + """ + 1 kilogram equals 1000 grams. + """ + KG + + """ + 1000 millimeters equals 1 meter. + """ + MM + + """ + 100 centimeters equals 1 meter. + """ + CM + + """ + Metric system unit of length. + """ + M + + """ + Metric system unit of area. + """ + M2 +} + +""" +Represents an error in the input of a mutation. +""" +type UserError implements DisplayableError { + """ + Path to the input field which caused the error. + """ + field: [String!] + + """ + The error message. + """ + message: String! +} + +""" +Represents a Shopify hosted video. +""" +type Video implements Node & Media { + """ + A word or phrase to share the nature or contents of a media. + """ + alt: String + + """ + Globally unique identifier. + """ + id: ID! + + """ + The media content type. + """ + mediaContentType: MediaContentType! + + """ + The preview image for the media. + """ + previewImage: Image + + """ + The sources for a video. + """ + sources: [VideoSource!]! +} + +""" +Represents a source for a Shopify hosted video. +""" +type VideoSource { + """ + The format of the video source. + """ + format: String! + + """ + The height of the video. + """ + height: Int! + + """ + The video MIME type. + """ + mimeType: String! + + """ + The URL of the video. + """ + url: String! + + """ + The width of the video. + """ + width: Int! +} + +""" +Units of measurement for weight. +""" +enum WeightUnit { + """ + 1 kilogram equals 1000 grams. + """ + KILOGRAMS + + """ + Metric system unit of mass. + """ + GRAMS + + """ + 1 pound equals 16 ounces. + """ + POUNDS + + """ + Imperial system unit of mass. + """ + OUNCES +} diff --git a/framework/swell/types.ts b/framework/swell/types.ts new file mode 100644 index 000000000..c4e42b67d --- /dev/null +++ b/framework/swell/types.ts @@ -0,0 +1,45 @@ +import * as Core from '@commerce/types' +import { CheckoutLineItem } from './schema' + +export type ShopifyCheckout = { + id: string + webUrl: string + lineItems: CheckoutLineItem[] +} + +export interface Cart extends Core.Cart { + id: string + lineItems: LineItem[] +} + +export interface LineItem extends Core.LineItem { + options: any[] +} + +/** + * Cart mutations + */ + +export type OptionSelections = { + option_id: number + option_value: number | string +} + +export type CartItemBody = Core.CartItemBody & { + productId: string // The product id is always required for BC + optionSelections?: OptionSelections +} + +export type GetCartHandlerBody = Core.GetCartHandlerBody + +export type AddCartItemBody = Core.AddCartItemBody + +export type AddCartItemHandlerBody = Core.AddCartItemHandlerBody + +export type UpdateCartItemBody = Core.UpdateCartItemBody + +export type UpdateCartItemHandlerBody = Core.UpdateCartItemHandlerBody + +export type RemoveCartItemBody = Core.RemoveCartItemBody + +export type RemoveCartItemHandlerBody = Core.RemoveCartItemHandlerBody diff --git a/framework/swell/utils/customer-token.ts b/framework/swell/utils/customer-token.ts new file mode 100644 index 000000000..85454cb83 --- /dev/null +++ b/framework/swell/utils/customer-token.ts @@ -0,0 +1,21 @@ +import Cookies, { CookieAttributes } from 'js-cookie' +import { SHOPIFY_COOKIE_EXPIRE, SHOPIFY_CUSTOMER_TOKEN_COOKIE } from '../const' + +export const getCustomerToken = () => Cookies.get(SHOPIFY_CUSTOMER_TOKEN_COOKIE) + +export const setCustomerToken = ( + token: string | null, + options?: CookieAttributes +) => { + if (!token) { + Cookies.remove(SHOPIFY_CUSTOMER_TOKEN_COOKIE) + } else { + Cookies.set( + SHOPIFY_CUSTOMER_TOKEN_COOKIE, + token, + options ?? { + expires: SHOPIFY_COOKIE_EXPIRE, + } + ) + } +} diff --git a/framework/swell/utils/get-categories.ts b/framework/swell/utils/get-categories.ts new file mode 100644 index 000000000..cce4b2ad7 --- /dev/null +++ b/framework/swell/utils/get-categories.ts @@ -0,0 +1,29 @@ +import { ShopifyConfig } from '../api' +import { CollectionEdge } from '../schema' +import getSiteCollectionsQuery from './queries/get-all-collections-query' + +export type Category = { + entityId: string + name: string + path: string +} + +const getCategories = async (config: ShopifyConfig): Promise => { + const { data } = await config.fetch(getSiteCollectionsQuery, { + variables: { + first: 250, + }, + }) + + return ( + data.collections?.edges?.map( + ({ node: { id: entityId, title: name, handle } }: CollectionEdge) => ({ + entityId, + name, + path: `/${handle}`, + }) + ) ?? [] + ) +} + +export default getCategories diff --git a/framework/swell/utils/get-checkout-id.ts b/framework/swell/utils/get-checkout-id.ts new file mode 100644 index 000000000..11e3802d9 --- /dev/null +++ b/framework/swell/utils/get-checkout-id.ts @@ -0,0 +1,8 @@ +import Cookies from 'js-cookie' +import { SHOPIFY_CHECKOUT_ID_COOKIE } from '../const' + +const getCheckoutId = (id?: string) => { + return id ?? Cookies.get(SHOPIFY_CHECKOUT_ID_COOKIE) +} + +export default getCheckoutId diff --git a/framework/swell/utils/get-search-variables.ts b/framework/swell/utils/get-search-variables.ts new file mode 100644 index 000000000..c1b40ae5d --- /dev/null +++ b/framework/swell/utils/get-search-variables.ts @@ -0,0 +1,27 @@ +import getSortVariables from './get-sort-variables' +import type { SearchProductsInput } from '../product/use-search' + +export const getSearchVariables = ({ + brandId, + search, + categoryId, + sort, +}: SearchProductsInput) => { + let query = '' + + if (search) { + query += `product_type:${search} OR title:${search} OR tag:${search}` + } + + if (brandId) { + query += `${search ? ' AND ' : ''}vendor:${brandId}` + } + + return { + categoryId, + query, + ...getSortVariables(sort, !!categoryId), + } +} + +export default getSearchVariables diff --git a/framework/swell/utils/get-sort-variables.ts b/framework/swell/utils/get-sort-variables.ts new file mode 100644 index 000000000..b8cdeec51 --- /dev/null +++ b/framework/swell/utils/get-sort-variables.ts @@ -0,0 +1,32 @@ +const getSortVariables = (sort?: string, isCategory = false) => { + let output = {} + switch (sort) { + case 'price-asc': + output = { + sortKey: 'PRICE', + reverse: false, + } + break + case 'price-desc': + output = { + sortKey: 'PRICE', + reverse: true, + } + break + case 'trending-desc': + output = { + sortKey: 'BEST_SELLING', + reverse: false, + } + break + case 'latest-desc': + output = { + sortKey: isCategory ? 'CREATED' : 'CREATED_AT', + reverse: true, + } + break + } + return output +} + +export default getSortVariables diff --git a/framework/swell/utils/get-vendors.ts b/framework/swell/utils/get-vendors.ts new file mode 100644 index 000000000..f04483bb1 --- /dev/null +++ b/framework/swell/utils/get-vendors.ts @@ -0,0 +1,36 @@ +import { ShopifyConfig } from '../api' +import fetchAllProducts from '../api/utils/fetch-all-products' +import getAllProductVendors from './queries/get-all-product-vendors-query' + +export type BrandNode = { + name: string + path: string +} + +export type BrandEdge = { + node: BrandNode +} + +export type Brands = BrandEdge[] + +const getVendors = async (config: ShopifyConfig): Promise => { + const vendors = await fetchAllProducts({ + config, + query: getAllProductVendors, + variables: { + first: 250, + }, + }) + + let vendorsStrings = vendors.map(({ node: { vendor } }) => vendor) + + return [...new Set(vendorsStrings)].map((v) => ({ + node: { + entityId: v, + name: v, + path: `brands/${v}`, + }, + })) +} + +export default getVendors diff --git a/framework/swell/utils/handle-fetch-response.ts b/framework/swell/utils/handle-fetch-response.ts new file mode 100644 index 000000000..8d7427d91 --- /dev/null +++ b/framework/swell/utils/handle-fetch-response.ts @@ -0,0 +1,27 @@ +import { FetcherError } from '@commerce/utils/errors' + +export function getError(errors: any[], status: number) { + errors = errors ?? [{ message: 'Failed to fetch Shopify API' }] + return new FetcherError({ errors, status }) +} + +export async function getAsyncError(res: Response) { + const data = await res.json() + return getError(data.errors, res.status) +} + +const handleFetchResponse = async (res: Response) => { + if (res.ok) { + const { data, errors } = await res.json() + + if (errors && errors.length) { + throw getError(errors, res.status) + } + + return data + } + + throw await getAsyncError(res) +} + +export default handleFetchResponse diff --git a/framework/swell/utils/handle-login.ts b/framework/swell/utils/handle-login.ts new file mode 100644 index 000000000..77b6873e3 --- /dev/null +++ b/framework/swell/utils/handle-login.ts @@ -0,0 +1,39 @@ +import { ValidationError } from '@commerce/utils/errors' +import { setCustomerToken } from './customer-token' + +const getErrorMessage = ({ + code, + message, +}: { + code: string + message: string +}) => { + switch (code) { + case 'UNIDENTIFIED_CUSTOMER': + message = 'Cannot find an account that matches the provided credentials' + break + } + return message +} + +const handleLogin = (data: any) => { + const response = data.customerAccessTokenCreate + const errors = response?.customerUserErrors + + if (errors && errors.length) { + throw new ValidationError({ + message: getErrorMessage(errors[0]), + }) + } + + const customerAccessToken = response?.customerAccessToken + const accessToken = customerAccessToken?.accessToken + + if (accessToken) { + setCustomerToken(accessToken) + } + + return customerAccessToken +} + +export default handleLogin diff --git a/framework/swell/utils/index.ts b/framework/swell/utils/index.ts new file mode 100644 index 000000000..2d59aa506 --- /dev/null +++ b/framework/swell/utils/index.ts @@ -0,0 +1,10 @@ +export { default as handleFetchResponse } from './handle-fetch-response' +export { default as getSearchVariables } from './get-search-variables' +export { default as getSortVariables } from './get-sort-variables' +export { default as getVendors } from './get-vendors' +export { default as getCategories } from './get-categories' +export { default as getCheckoutId } from './get-checkout-id' +export * from './queries' +export * from './mutations' +export * from './normalize' +export * from './customer-token' diff --git a/framework/swell/utils/mutations/associate-customer-with-checkout.ts b/framework/swell/utils/mutations/associate-customer-with-checkout.ts new file mode 100644 index 000000000..6b1350e05 --- /dev/null +++ b/framework/swell/utils/mutations/associate-customer-with-checkout.ts @@ -0,0 +1,18 @@ +const associateCustomerWithCheckoutMutation = /* GraphQl */ ` +mutation associateCustomerWithCheckout($checkoutId: ID!, $customerAccessToken: String!) { + checkoutCustomerAssociateV2(checkoutId: $checkoutId, customerAccessToken: $customerAccessToken) { + checkout { + id + } + checkoutUserErrors { + code + field + message + } + customer { + id + } + } + } +` +export default associateCustomerWithCheckoutMutation diff --git a/framework/swell/utils/mutations/checkout-create.ts b/framework/swell/utils/mutations/checkout-create.ts new file mode 100644 index 000000000..912e1cbd2 --- /dev/null +++ b/framework/swell/utils/mutations/checkout-create.ts @@ -0,0 +1,16 @@ +import { checkoutDetailsFragment } from '../queries/get-checkout-query' + +const checkoutCreateMutation = /* GraphQL */ ` + mutation { + checkoutCreate(input: {}) { + userErrors { + message + field + } + checkout { + ${checkoutDetailsFragment} + } + } + } +` +export default checkoutCreateMutation diff --git a/framework/swell/utils/mutations/checkout-line-item-add.ts b/framework/swell/utils/mutations/checkout-line-item-add.ts new file mode 100644 index 000000000..67b9cf250 --- /dev/null +++ b/framework/swell/utils/mutations/checkout-line-item-add.ts @@ -0,0 +1,16 @@ +import { checkoutDetailsFragment } from '../queries/get-checkout-query' + +const checkoutLineItemAddMutation = /* GraphQL */ ` + mutation($checkoutId: ID!, $lineItems: [CheckoutLineItemInput!]!) { + checkoutLineItemsAdd(checkoutId: $checkoutId, lineItems: $lineItems) { + userErrors { + message + field + } + checkout { + ${checkoutDetailsFragment} + } + } + } +` +export default checkoutLineItemAddMutation diff --git a/framework/swell/utils/mutations/checkout-line-item-remove.ts b/framework/swell/utils/mutations/checkout-line-item-remove.ts new file mode 100644 index 000000000..d967a5168 --- /dev/null +++ b/framework/swell/utils/mutations/checkout-line-item-remove.ts @@ -0,0 +1,19 @@ +import { checkoutDetailsFragment } from '../queries/get-checkout-query' + +const checkoutLineItemRemoveMutation = /* GraphQL */ ` + mutation($checkoutId: ID!, $lineItemIds: [ID!]!) { + checkoutLineItemsRemove( + checkoutId: $checkoutId + lineItemIds: $lineItemIds + ) { + userErrors { + message + field + } + checkout { + ${checkoutDetailsFragment} + } + } + } +` +export default checkoutLineItemRemoveMutation diff --git a/framework/swell/utils/mutations/checkout-line-item-update.ts b/framework/swell/utils/mutations/checkout-line-item-update.ts new file mode 100644 index 000000000..8edf17587 --- /dev/null +++ b/framework/swell/utils/mutations/checkout-line-item-update.ts @@ -0,0 +1,16 @@ +import { checkoutDetailsFragment } from '../queries/get-checkout-query' + +const checkoutLineItemUpdateMutation = /* GraphQL */ ` + mutation($checkoutId: ID!, $lineItems: [CheckoutLineItemUpdateInput!]!) { + checkoutLineItemsUpdate(checkoutId: $checkoutId, lineItems: $lineItems) { + userErrors { + message + field + } + checkout { + ${checkoutDetailsFragment} + } + } + } +` +export default checkoutLineItemUpdateMutation diff --git a/framework/swell/utils/mutations/customer-access-token-create.ts b/framework/swell/utils/mutations/customer-access-token-create.ts new file mode 100644 index 000000000..7a45c3f49 --- /dev/null +++ b/framework/swell/utils/mutations/customer-access-token-create.ts @@ -0,0 +1,16 @@ +const customerAccessTokenCreateMutation = /* GraphQL */ ` + mutation customerAccessTokenCreate($input: CustomerAccessTokenCreateInput!) { + customerAccessTokenCreate(input: $input) { + customerAccessToken { + accessToken + expiresAt + } + customerUserErrors { + code + field + message + } + } + } +` +export default customerAccessTokenCreateMutation diff --git a/framework/swell/utils/mutations/customer-access-token-delete.ts b/framework/swell/utils/mutations/customer-access-token-delete.ts new file mode 100644 index 000000000..c46eff1e5 --- /dev/null +++ b/framework/swell/utils/mutations/customer-access-token-delete.ts @@ -0,0 +1,14 @@ +const customerAccessTokenDeleteMutation = /* GraphQL */ ` + mutation customerAccessTokenDelete($customerAccessToken: String!) { + customerAccessTokenDelete(customerAccessToken: $customerAccessToken) { + deletedAccessToken + deletedCustomerAccessTokenId + userErrors { + field + message + } + } + } +` + +export default customerAccessTokenDeleteMutation diff --git a/framework/swell/utils/mutations/customer-create.ts b/framework/swell/utils/mutations/customer-create.ts new file mode 100644 index 000000000..05c728a25 --- /dev/null +++ b/framework/swell/utils/mutations/customer-create.ts @@ -0,0 +1,15 @@ +const customerCreateMutation = /* GraphQL */ ` + mutation customerCreate($input: CustomerCreateInput!) { + customerCreate(input: $input) { + customerUserErrors { + code + field + message + } + customer { + id + } + } + } +` +export default customerCreateMutation diff --git a/framework/swell/utils/mutations/index.ts b/framework/swell/utils/mutations/index.ts new file mode 100644 index 000000000..3a16d7cec --- /dev/null +++ b/framework/swell/utils/mutations/index.ts @@ -0,0 +1,7 @@ +export { default as customerCreateMutation } from './customer-create' +export { default as checkoutCreateMutation } from './checkout-create' +export { default as checkoutLineItemAddMutation } from './checkout-line-item-add' +export { default as checkoutLineItemUpdateMutation } from './checkout-line-item-update' +export { default as checkoutLineItemRemoveMutation } from './checkout-line-item-remove' +export { default as customerAccessTokenCreateMutation } from './customer-access-token-create' +export { default as customerAccessTokenDeleteMutation } from './customer-access-token-delete' diff --git a/framework/swell/utils/normalize.ts b/framework/swell/utils/normalize.ts new file mode 100644 index 000000000..c9b428b37 --- /dev/null +++ b/framework/swell/utils/normalize.ts @@ -0,0 +1,152 @@ +import { Product } from '@commerce/types' + +import { + Product as ShopifyProduct, + Checkout, + CheckoutLineItemEdge, + SelectedOption, + ImageConnection, + ProductVariantConnection, + MoneyV2, + ProductOption, +} from '../schema' + +import type { Cart, LineItem } from '../types' + +const money = ({ amount, currencyCode }: MoneyV2) => { + return { + value: +amount, + currencyCode, + } +} + +const normalizeProductOption = ({ + id, + name: displayName, + values, +}: ProductOption) => { + return { + __typename: 'MultipleChoiceOption', + id, + displayName, + values: values.map((value) => { + let output: any = { + label: value, + } + if (displayName === 'Color') { + output = { + ...output, + hexColors: [value], + } + } + return output + }), + } +} + +const normalizeProductImages = ({ edges }: ImageConnection) => + edges?.map(({ node: { originalSrc: url, ...rest } }) => ({ + url, + ...rest, + })) + +const normalizeProductVariants = ({ edges }: ProductVariantConnection) => { + return edges?.map( + ({ + node: { id, selectedOptions, sku, title, priceV2, compareAtPriceV2 }, + }) => ({ + id, + name: title, + sku: sku ?? id, + price: +priceV2.amount, + listPrice: +compareAtPriceV2?.amount, + requiresShipping: true, + options: selectedOptions.map(({ name, value }: SelectedOption) => + normalizeProductOption({ + id, + name, + values: [value], + }) + ), + }) + ) +} + +export function normalizeProduct(productNode: ShopifyProduct): Product { + const { + id, + title: name, + vendor, + images, + variants, + description, + handle, + priceRange, + options, + ...rest + } = productNode + + const product = { + id, + name, + vendor, + description, + path: `/${handle}`, + slug: handle?.replace(/^\/+|\/+$/g, ''), + price: money(priceRange?.minVariantPrice), + images: normalizeProductImages(images), + variants: variants ? normalizeProductVariants(variants) : [], + options: options ? options.map((o) => normalizeProductOption(o)) : [], + ...rest, + } + + return product +} + +export function normalizeCart(checkout: Checkout): Cart { + return { + id: checkout.id, + customerId: '', + email: '', + createdAt: checkout.createdAt, + currency: { + code: checkout.totalPriceV2?.currencyCode, + }, + taxesIncluded: checkout.taxesIncluded, + lineItems: checkout.lineItems?.edges.map(normalizeLineItem), + lineItemsSubtotalPrice: +checkout.subtotalPriceV2?.amount, + subtotalPrice: +checkout.subtotalPriceV2?.amount, + totalPrice: checkout.totalPriceV2?.amount, + discounts: [], + } +} + +function normalizeLineItem({ + node: { id, title, variant, quantity }, +}: CheckoutLineItemEdge): LineItem { + return { + id, + variantId: String(variant?.id), + productId: String(variant?.id), + name: `${title}`, + quantity, + variant: { + id: String(variant?.id), + sku: variant?.sku ?? '', + name: variant?.title!, + image: { + url: variant?.image?.originalSrc, + }, + requiresShipping: variant?.requiresShipping ?? false, + price: variant?.priceV2?.amount, + listPrice: variant?.compareAtPriceV2?.amount, + }, + path: '', + discounts: [], + options: [ + { + value: variant?.title, + }, + ], + } +} diff --git a/framework/swell/utils/queries/get-all-collections-query.ts b/framework/swell/utils/queries/get-all-collections-query.ts new file mode 100644 index 000000000..2abf374d6 --- /dev/null +++ b/framework/swell/utils/queries/get-all-collections-query.ts @@ -0,0 +1,14 @@ +const getSiteCollectionsQuery = /* GraphQL */ ` + query getSiteCollections($first: Int!) { + collections(first: $first) { + edges { + node { + id + title + handle + } + } + } + } +` +export default getSiteCollectionsQuery diff --git a/framework/swell/utils/queries/get-all-pages-query.ts b/framework/swell/utils/queries/get-all-pages-query.ts new file mode 100644 index 000000000..e3aee1f10 --- /dev/null +++ b/framework/swell/utils/queries/get-all-pages-query.ts @@ -0,0 +1,14 @@ +export const getAllPagesQuery = /* GraphQL */ ` + query getAllPages($first: Int = 250) { + pages(first: $first) { + edges { + node { + id + title + handle + } + } + } + } +` +export default getAllPagesQuery diff --git a/framework/swell/utils/queries/get-all-product-vendors-query.ts b/framework/swell/utils/queries/get-all-product-vendors-query.ts new file mode 100644 index 000000000..be08b8ec6 --- /dev/null +++ b/framework/swell/utils/queries/get-all-product-vendors-query.ts @@ -0,0 +1,17 @@ +const getAllProductVendors = /* GraphQL */ ` + query getAllProductVendors($first: Int = 250, $cursor: String) { + products(first: $first, after: $cursor) { + pageInfo { + hasNextPage + hasPreviousPage + } + edges { + node { + vendor + } + cursor + } + } + } +` +export default getAllProductVendors diff --git a/framework/swell/utils/queries/get-all-products-paths-query.ts b/framework/swell/utils/queries/get-all-products-paths-query.ts new file mode 100644 index 000000000..56298c204 --- /dev/null +++ b/framework/swell/utils/queries/get-all-products-paths-query.ts @@ -0,0 +1,17 @@ +const getAllProductsPathsQuery = /* GraphQL */ ` + query getAllProductPaths($first: Int = 250, $cursor: String) { + products(first: $first, after: $cursor) { + pageInfo { + hasNextPage + hasPreviousPage + } + edges { + node { + handle + } + cursor + } + } + } +` +export default getAllProductsPathsQuery diff --git a/framework/swell/utils/queries/get-all-products-query.ts b/framework/swell/utils/queries/get-all-products-query.ts new file mode 100644 index 000000000..5eb44c7a7 --- /dev/null +++ b/framework/swell/utils/queries/get-all-products-query.ts @@ -0,0 +1,57 @@ +export const productConnection = ` +pageInfo { + hasNextPage + hasPreviousPage +} +edges { + node { + id + title + vendor + handle + description + priceRange { + minVariantPrice { + amount + currencyCode + } + } + images(first: 1) { + pageInfo { + hasNextPage + hasPreviousPage + } + edges { + node { + originalSrc + altText + width + height + } + } + } + } +}` + +export const productsFragment = ` +products( + first: $first + sortKey: $sortKey + reverse: $reverse + query: $query +) { + ${productConnection} +} +` + +const getAllProductsQuery = /* GraphQL */ ` + query getAllProducts( + $first: Int = 250 + $query: String = "" + $sortKey: ProductSortKeys = RELEVANCE + $reverse: Boolean = false + ) { + ${productsFragment} + } +` +export default getAllProductsQuery diff --git a/framework/swell/utils/queries/get-checkout-query.ts b/framework/swell/utils/queries/get-checkout-query.ts new file mode 100644 index 000000000..194e1619a --- /dev/null +++ b/framework/swell/utils/queries/get-checkout-query.ts @@ -0,0 +1,62 @@ +export const checkoutDetailsFragment = ` + id + webUrl + subtotalPriceV2{ + amount + currencyCode + } + totalTaxV2 { + amount + currencyCode + } + totalPriceV2 { + amount + currencyCode + } + completedAt + createdAt + taxesIncluded + lineItems(first: 250) { + pageInfo { + hasNextPage + hasPreviousPage + } + edges { + node { + id + title + variant { + id + sku + title + image { + originalSrc + altText + width + height + } + priceV2{ + amount + currencyCode + } + compareAtPriceV2{ + amount + currencyCode + } + } + quantity + } + } + } +` + +const getCheckoutQuery = /* GraphQL */ ` + query($checkoutId: ID!) { + node(id: $checkoutId) { + ... on Checkout { + ${checkoutDetailsFragment} + } + } + } +` +export default getCheckoutQuery diff --git a/framework/swell/utils/queries/get-collection-products-query.ts b/framework/swell/utils/queries/get-collection-products-query.ts new file mode 100644 index 000000000..04766caa4 --- /dev/null +++ b/framework/swell/utils/queries/get-collection-products-query.ts @@ -0,0 +1,24 @@ +import { productConnection } from './get-all-products-query' + +const getCollectionProductsQuery = /* GraphQL */ ` + query getProductsFromCollection( + $categoryId: ID! + $first: Int = 250 + $sortKey: ProductCollectionSortKeys = RELEVANCE + $reverse: Boolean = false + ) { + node(id: $categoryId) { + id + ... on Collection { + products( + first: $first + sortKey: $sortKey + reverse: $reverse + ) { + ${productConnection} + } + } + } + } +` +export default getCollectionProductsQuery diff --git a/framework/swell/utils/queries/get-customer-id-query.ts b/framework/swell/utils/queries/get-customer-id-query.ts new file mode 100644 index 000000000..076ceb10b --- /dev/null +++ b/framework/swell/utils/queries/get-customer-id-query.ts @@ -0,0 +1,8 @@ +export const getCustomerQuery = /* GraphQL */ ` + query getCustomerId($customerAccessToken: String!) { + customer(customerAccessToken: $customerAccessToken) { + id + } + } +` +export default getCustomerQuery diff --git a/framework/swell/utils/queries/get-customer-query.ts b/framework/swell/utils/queries/get-customer-query.ts new file mode 100644 index 000000000..87e37e68d --- /dev/null +++ b/framework/swell/utils/queries/get-customer-query.ts @@ -0,0 +1,16 @@ +export const getCustomerQuery = /* GraphQL */ ` + query getCustomer($customerAccessToken: String!) { + customer(customerAccessToken: $customerAccessToken) { + id + firstName + lastName + displayName + email + phone + tags + acceptsMarketing + createdAt + } + } +` +export default getCustomerQuery diff --git a/framework/swell/utils/queries/get-page-query.ts b/framework/swell/utils/queries/get-page-query.ts new file mode 100644 index 000000000..2ca79abd4 --- /dev/null +++ b/framework/swell/utils/queries/get-page-query.ts @@ -0,0 +1,14 @@ +export const getPageQuery = /* GraphQL */ ` + query($id: ID!) { + node(id: $id) { + id + ... on Page { + title + handle + body + bodySummary + } + } + } +` +export default getPageQuery diff --git a/framework/swell/utils/queries/get-product-query.ts b/framework/swell/utils/queries/get-product-query.ts new file mode 100644 index 000000000..5c109901b --- /dev/null +++ b/framework/swell/utils/queries/get-product-query.ts @@ -0,0 +1,69 @@ +const getProductQuery = /* GraphQL */ ` + query getProductBySlug($slug: String!) { + productByHandle(handle: $slug) { + id + handle + title + productType + vendor + description + descriptionHtml + options { + id + name + values + } + priceRange { + maxVariantPrice { + amount + currencyCode + } + minVariantPrice { + amount + currencyCode + } + } + variants(first: 250) { + pageInfo { + hasNextPage + hasPreviousPage + } + edges { + node { + id + title + sku + selectedOptions { + name + value + } + priceV2 { + amount + currencyCode + } + compareAtPriceV2 { + amount + currencyCode + } + } + } + } + images(first: 250) { + pageInfo { + hasNextPage + hasPreviousPage + } + edges { + node { + originalSrc + altText + width + height + } + } + } + } + } +` + +export default getProductQuery diff --git a/framework/swell/utils/queries/index.ts b/framework/swell/utils/queries/index.ts new file mode 100644 index 000000000..e19be9c8c --- /dev/null +++ b/framework/swell/utils/queries/index.ts @@ -0,0 +1,10 @@ +export { default as getSiteCollectionsQuery } from './get-all-collections-query' +export { default as getProductQuery } from './get-product-query' +export { default as getAllProductsQuery } from './get-all-products-query' +export { default as getAllProductsPathtsQuery } from './get-all-products-paths-query' +export { default as getAllProductVendors } from './get-all-product-vendors-query' +export { default as getCollectionProductsQuery } from './get-collection-products-query' +export { default as getCheckoutQuery } from './get-checkout-query' +export { default as getAllPagesQuery } from './get-all-pages-query' +export { default as getPageQuery } from './get-page-query' +export { default as getCustomerQuery } from './get-customer-query' diff --git a/framework/swell/utils/storage.ts b/framework/swell/utils/storage.ts new file mode 100644 index 000000000..d46dadb21 --- /dev/null +++ b/framework/swell/utils/storage.ts @@ -0,0 +1,13 @@ +export const getCheckoutIdFromStorage = (token: string) => { + if (window && window.sessionStorage) { + return window.sessionStorage.getItem(token) + } + + return null +} + +export const setCheckoutIdInStorage = (token: string, id: string | number) => { + if (window && window.sessionStorage) { + return window.sessionStorage.setItem(token, id + '') + } +} diff --git a/framework/swell/wishlist/use-add-item.tsx b/framework/swell/wishlist/use-add-item.tsx new file mode 100644 index 000000000..75f067c3a --- /dev/null +++ b/framework/swell/wishlist/use-add-item.tsx @@ -0,0 +1,13 @@ +import { useCallback } from 'react' + +export function emptyHook() { + const useEmptyHook = async (options = {}) => { + return useCallback(async function () { + return Promise.resolve() + }, []) + } + + return useEmptyHook +} + +export default emptyHook diff --git a/framework/swell/wishlist/use-remove-item.tsx b/framework/swell/wishlist/use-remove-item.tsx new file mode 100644 index 000000000..a2d3a8a05 --- /dev/null +++ b/framework/swell/wishlist/use-remove-item.tsx @@ -0,0 +1,17 @@ +import { useCallback } from 'react' + +type Options = { + includeProducts?: boolean +} + +export function emptyHook(options?: Options) { + const useEmptyHook = async ({ id }: { id: string | number }) => { + return useCallback(async function () { + return Promise.resolve() + }, []) + } + + return useEmptyHook +} + +export default emptyHook diff --git a/framework/swell/wishlist/use-wishlist.tsx b/framework/swell/wishlist/use-wishlist.tsx new file mode 100644 index 000000000..d2ce9db5b --- /dev/null +++ b/framework/swell/wishlist/use-wishlist.tsx @@ -0,0 +1,46 @@ +// TODO: replace this hook and other wishlist hooks with a handler, or remove them if +// Shopify doesn't have a wishlist + +import { HookFetcher } from '@commerce/utils/types' +import { Product } from '../schema' + +const defaultOpts = {} + +export type Wishlist = { + items: [ + { + product_id: number + variant_id: number + id: number + product: Product + } + ] +} + +export interface UseWishlistOptions { + includeProducts?: boolean +} + +export interface UseWishlistInput extends UseWishlistOptions { + customerId?: number +} + +export const fetcher: HookFetcher = () => { + return null +} + +export function extendHook( + customFetcher: typeof fetcher, + // swrOptions?: SwrOptions + swrOptions?: any +) { + const useWishlist = ({ includeProducts }: UseWishlistOptions = {}) => { + return { data: null } + } + + useWishlist.extend = extendHook + + return useWishlist +} + +export default extendHook(fetcher) From ee1d8ed461372ec9d87ceddd07e88a283a012e50 Mon Sep 17 00:00:00 2001 From: Greg Hoskin Date: Sat, 27 Mar 2021 15:54:32 -0600 Subject: [PATCH 189/216] setup custom fetcher and auth hooks --- .env.template | 3 + .vscode/launch.json | 15 +++ commerce.config.json | 4 +- framework/commerce/with-config.js | 2 +- framework/swell/.env.template | 3 + framework/swell/api/index.ts | 16 +-- .../api/operations/get-all-collections.ts | 4 +- framework/swell/api/operations/get-page.ts | 4 +- .../swell/api/utils/create-api-handler.ts | 8 +- .../swell/api/utils/fetch-all-products.ts | 4 +- framework/swell/auth/use-login.tsx | 7 +- framework/swell/auth/use-logout.tsx | 3 +- framework/swell/auth/use-signup.tsx | 22 ++-- framework/swell/cart/use-cart.tsx | 3 +- framework/swell/commerce.config.json | 2 +- framework/swell/common/get-all-pages.ts | 4 +- framework/swell/common/get-page.ts | 4 +- framework/swell/common/get-site-info.ts | 4 +- framework/swell/const.ts | 4 + framework/swell/customer/get-customer-id.ts | 4 +- framework/swell/customer/use-customer.tsx | 36 +++++- framework/swell/fetcher.ts | 31 +++-- framework/swell/index.tsx | 29 +++-- .../swell/product/get-all-collections.ts | 4 +- .../swell/product/get-all-product-paths.ts | 4 +- framework/swell/product/get-all-products.ts | 4 +- framework/swell/product/get-product.ts | 4 +- framework/swell/provider.ts | 4 +- framework/swell/swell-js.d.ts | 1 + framework/swell/types.ts | 5 + framework/swell/utils/get-categories.ts | 4 +- framework/swell/utils/get-vendors.ts | 4 +- .../swell/utils/handle-fetch-response.ts | 15 +-- framework/swell/utils/normalize.ts | 12 +- package.json | 1 + tsconfig.json | 6 +- yarn.lock | 118 +++++++++++++++++- 37 files changed, 299 insertions(+), 103 deletions(-) create mode 100644 .vscode/launch.json create mode 100644 framework/swell/swell-js.d.ts diff --git a/.env.template b/.env.template index 9b45afe4b..221e7a74e 100644 --- a/.env.template +++ b/.env.template @@ -7,3 +7,6 @@ BIGCOMMERCE_CHANNEL_ID= SHOPIFY_STORE_DOMAIN= SHOPIFY_STOREFRONT_ACCESS_TOKEN= + +SWELL_STORE_ID= +SWELL_PUBLIC_KEY= \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 000000000..177bc7dfa --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,15 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "type": "pwa-chrome", + "request": "launch", + "name": "Launch Chrome against localhost", + "url": "http://localhost:8080", + "webRoot": "${workspaceFolder}" + } + ] +} diff --git a/commerce.config.json b/commerce.config.json index bef7db222..ab9497fd3 100644 --- a/commerce.config.json +++ b/commerce.config.json @@ -1,7 +1,7 @@ { - "provider": "bigcommerce", + "provider": "swell", "features": { - "wishlist": true, + "wishlist": false, "customCheckout": false } } diff --git a/framework/commerce/with-config.js b/framework/commerce/with-config.js index da6705cef..cc244dac0 100644 --- a/framework/commerce/with-config.js +++ b/framework/commerce/with-config.js @@ -4,7 +4,7 @@ const merge = require('deepmerge') -const PROVIDERS = ['bigcommerce', 'shopify'] +const PROVIDERS = ['bigcommerce', 'shopify', 'swell'] function getProviderName() { return process.env.BIGCOMMERCE_STOREFRONT_API_URL ? 'bigcommerce' : null diff --git a/framework/swell/.env.template b/framework/swell/.env.template index 24521c2a1..b5f38e883 100644 --- a/framework/swell/.env.template +++ b/framework/swell/.env.template @@ -1,2 +1,5 @@ SHOPIFY_STORE_DOMAIN= SHOPIFY_STOREFRONT_ACCESS_TOKEN= + +NEXT_PUBLIC_SWELL_STORE_ID= +NEXT_PUBLIC_SWELL_PUBLIC_KEY= diff --git a/framework/swell/api/index.ts b/framework/swell/api/index.ts index 4f15cae15..fc48116a6 100644 --- a/framework/swell/api/index.ts +++ b/framework/swell/api/index.ts @@ -22,23 +22,23 @@ if (!API_TOKEN) { import fetchGraphqlApi from './utils/fetch-graphql-api' -export interface ShopifyConfig extends CommerceAPIConfig {} +export interface SwellConfig extends CommerceAPIConfig {} export class Config { - private config: ShopifyConfig + private config: SwellConfig - constructor(config: ShopifyConfig) { + constructor(config: SwellConfig) { this.config = config } - getConfig(userConfig: Partial = {}) { - return Object.entries(userConfig).reduce( + getConfig(userConfig: Partial = {}) { + return Object.entries(userConfig).reduce( (cfg, [key, value]) => Object.assign(cfg, { [key]: value }), { ...this.config } ) } - setConfig(newConfig: Partial) { + setConfig(newConfig: Partial) { Object.assign(this.config, newConfig) } } @@ -53,10 +53,10 @@ const config = new Config({ customerCookie: SHOPIFY_CUSTOMER_TOKEN_COOKIE, }) -export function getConfig(userConfig?: Partial) { +export function getConfig(userConfig?: Partial) { return config.getConfig(userConfig) } -export function setConfig(newConfig: Partial) { +export function setConfig(newConfig: Partial) { return config.setConfig(newConfig) } diff --git a/framework/swell/api/operations/get-all-collections.ts b/framework/swell/api/operations/get-all-collections.ts index 9cf216a91..ed906ffcc 100644 --- a/framework/swell/api/operations/get-all-collections.ts +++ b/framework/swell/api/operations/get-all-collections.ts @@ -1,8 +1,8 @@ import Client from 'shopify-buy' -import { ShopifyConfig } from '../index' +import { SwellConfig } from '../index' type Options = { - config: ShopifyConfig + config: SwellConfig } const getAllCollections = async (options: Options) => { diff --git a/framework/swell/api/operations/get-page.ts b/framework/swell/api/operations/get-page.ts index 32acb7c8f..b04002dda 100644 --- a/framework/swell/api/operations/get-page.ts +++ b/framework/swell/api/operations/get-page.ts @@ -1,5 +1,5 @@ import { Page } from '../../schema' -import { ShopifyConfig, getConfig } from '..' +import { SwellConfig, getConfig } from '..' export type GetPageResult = T @@ -15,7 +15,7 @@ async function getPage({ }: { url?: string variables: PageVariables - config?: ShopifyConfig + config?: SwellConfig preview?: boolean }): Promise { config = getConfig(config) diff --git a/framework/swell/api/utils/create-api-handler.ts b/framework/swell/api/utils/create-api-handler.ts index 8820aeabc..7ceb7d423 100644 --- a/framework/swell/api/utils/create-api-handler.ts +++ b/framework/swell/api/utils/create-api-handler.ts @@ -1,5 +1,5 @@ import type { NextApiHandler, NextApiRequest, NextApiResponse } from 'next' -import { ShopifyConfig, getConfig } from '..' +import { SwellConfig, getConfig } from '..' export type ShopifyApiHandler< T = any, @@ -8,7 +8,7 @@ export type ShopifyApiHandler< > = ( req: NextApiRequest, res: NextApiResponse>, - config: ShopifyConfig, + config: SwellConfig, handlers: H, // Custom configs that may be used by a particular handler options: Options @@ -17,7 +17,7 @@ export type ShopifyApiHandler< export type ShopifyHandler = (options: { req: NextApiRequest res: NextApiResponse> - config: ShopifyConfig + config: SwellConfig body: Body }) => void | Promise @@ -44,7 +44,7 @@ export default function createApiHandler< operations, options, }: { - config?: ShopifyConfig + config?: SwellConfig operations?: Partial options?: Options extends {} ? Partial : never } = {}): NextApiHandler { diff --git a/framework/swell/api/utils/fetch-all-products.ts b/framework/swell/api/utils/fetch-all-products.ts index 9fa70a5ee..7ad308b04 100644 --- a/framework/swell/api/utils/fetch-all-products.ts +++ b/framework/swell/api/utils/fetch-all-products.ts @@ -1,5 +1,5 @@ import { ProductEdge } from '../../schema' -import { ShopifyConfig } from '..' +import { SwellConfig } from '..' const fetchAllProducts = async ({ config, @@ -8,7 +8,7 @@ const fetchAllProducts = async ({ acc = [], cursor, }: { - config: ShopifyConfig + config: SwellConfig query: string acc?: ProductEdge[] variables?: any diff --git a/framework/swell/auth/use-login.tsx b/framework/swell/auth/use-login.tsx index 188dd54a2..cdaf6151b 100644 --- a/framework/swell/auth/use-login.tsx +++ b/framework/swell/auth/use-login.tsx @@ -25,7 +25,8 @@ const getErrorMessage = ({ code, message }: CustomerUserError) => { export const handler: MutationHook = { fetchOptions: { - query: createCustomerAccessTokenMutation, + query: 'account', + method: 'login', }, async fetcher({ input: { email, password }, options, fetch }) { if (!(email && password)) { @@ -40,9 +41,7 @@ export const handler: MutationHook = { MutationCheckoutCreateArgs >({ ...options, - variables: { - input: { email, password }, - }, + variables: [email, password], }) const errors = customerAccessTokenCreate?.customerUserErrors diff --git a/framework/swell/auth/use-logout.tsx b/framework/swell/auth/use-logout.tsx index 81a3b8cdd..6eebd997f 100644 --- a/framework/swell/auth/use-logout.tsx +++ b/framework/swell/auth/use-logout.tsx @@ -9,7 +9,8 @@ export default useLogout as UseLogout export const handler: MutationHook = { fetchOptions: { - query: customerAccessTokenDeleteMutation, + query: 'account', + method: 'logout', }, async fetcher({ options, fetch }) { await fetch({ diff --git a/framework/swell/auth/use-signup.tsx b/framework/swell/auth/use-signup.tsx index 7f66448d3..a3dbf73a3 100644 --- a/framework/swell/auth/use-signup.tsx +++ b/framework/swell/auth/use-signup.tsx @@ -20,7 +20,8 @@ export const handler: MutationHook< CustomerCreateInput > = { fetchOptions: { - query: customerCreateMutation, + query: 'account', + method: 'create', }, async fetcher({ input: { firstName, lastName, email, password }, @@ -36,23 +37,20 @@ export const handler: MutationHook< const data = await fetch({ ...options, variables: { - input: { - firstName, - lastName, - email, - password, - }, + first_name: firstName, + last_name: lastName, + email, + password, }, }) try { const loginData = await fetch({ - query: customerAccessTokenCreateMutation, + query: 'account', + method: 'login', variables: { - input: { - email, - password, - }, + email, + password, }, }) handleLogin(loginData) diff --git a/framework/swell/cart/use-cart.tsx b/framework/swell/cart/use-cart.tsx index d154bb837..a1a303210 100644 --- a/framework/swell/cart/use-cart.tsx +++ b/framework/swell/cart/use-cart.tsx @@ -18,7 +18,8 @@ export const handler: SWRHook< { isEmpty?: boolean } > = { fetchOptions: { - query: getCheckoutQuery, + query: 'cart', + method: 'get', }, async fetcher({ input: { cartId: checkoutId }, options, fetch }) { let checkout diff --git a/framework/swell/commerce.config.json b/framework/swell/commerce.config.json index b30ab39d9..01c9bf919 100644 --- a/framework/swell/commerce.config.json +++ b/framework/swell/commerce.config.json @@ -1,5 +1,5 @@ { - "provider": "shopify", + "provider": "swell", "features": { "wishlist": false } diff --git a/framework/swell/common/get-all-pages.ts b/framework/swell/common/get-all-pages.ts index 54231ed03..a092823ca 100644 --- a/framework/swell/common/get-all-pages.ts +++ b/framework/swell/common/get-all-pages.ts @@ -1,4 +1,4 @@ -import { getConfig, ShopifyConfig } from '../api' +import { getConfig, SwellConfig } from '../api' import { PageEdge } from '../schema' import { getAllPagesQuery } from '../utils/queries' @@ -20,7 +20,7 @@ export type Page = { const getAllPages = async (options?: { variables?: Variables - config: ShopifyConfig + config: SwellConfig preview?: boolean }): Promise => { let { config, variables = { first: 250 } } = options ?? {} diff --git a/framework/swell/common/get-page.ts b/framework/swell/common/get-page.ts index be934aa42..ae7c0370b 100644 --- a/framework/swell/common/get-page.ts +++ b/framework/swell/common/get-page.ts @@ -1,4 +1,4 @@ -import { getConfig, ShopifyConfig } from '../api' +import { getConfig, SwellConfig } from '../api' import getPageQuery from '../utils/queries/get-page-query' import { Page } from './get-all-pages' @@ -10,7 +10,7 @@ export type GetPageResult = T const getPage = async (options: { variables: Variables - config: ShopifyConfig + config: SwellConfig preview?: boolean }): Promise => { let { config, variables } = options ?? {} diff --git a/framework/swell/common/get-site-info.ts b/framework/swell/common/get-site-info.ts index cbbacf5b6..e44d9cc06 100644 --- a/framework/swell/common/get-site-info.ts +++ b/framework/swell/common/get-site-info.ts @@ -1,7 +1,7 @@ import getCategories, { Category } from '../utils/get-categories' import getVendors, { Brands } from '../utils/get-vendors' -import { getConfig, ShopifyConfig } from '../api' +import { getConfig, SwellConfig } from '../api' export type GetSiteInfoResult< T extends { categories: any[]; brands: any[] } = { @@ -12,7 +12,7 @@ export type GetSiteInfoResult< const getSiteInfo = async (options?: { variables?: any - config: ShopifyConfig + config: SwellConfig preview?: boolean }): Promise => { let { config } = options ?? {} diff --git a/framework/swell/const.ts b/framework/swell/const.ts index 06fbe5054..f2b0d5396 100644 --- a/framework/swell/const.ts +++ b/framework/swell/const.ts @@ -11,3 +11,7 @@ export const SHOPIFY_COOKIE_EXPIRE = 30 export const API_URL = `https://${STORE_DOMAIN}/api/2021-01/graphql.json` export const API_TOKEN = process.env.NEXT_PUBLIC_SHOPIFY_STOREFRONT_ACCESS_TOKEN + +export const SWELL_STORE_ID = process.env.NEXT_PUBLIC_SWELL_STORE_ID + +export const SWELL_PUBLIC_KEY = process.env.NEXT_PUBLIC_SWELL_PUBLIC_KEY diff --git a/framework/swell/customer/get-customer-id.ts b/framework/swell/customer/get-customer-id.ts index ca096645a..c3a1b8d2f 100644 --- a/framework/swell/customer/get-customer-id.ts +++ b/framework/swell/customer/get-customer-id.ts @@ -1,4 +1,4 @@ -import { getConfig, ShopifyConfig } from '../api' +import { getConfig, SwellConfig } from '../api' import getCustomerIdQuery from '../utils/queries/get-customer-id-query' import Cookies from 'js-cookie' @@ -7,7 +7,7 @@ async function getCustomerId({ config, }: { customerToken: string - config?: ShopifyConfig + config?: SwellConfig }): Promise { config = getConfig(config) diff --git a/framework/swell/customer/use-customer.tsx b/framework/swell/customer/use-customer.tsx index 137f0da74..ec3dd99fd 100644 --- a/framework/swell/customer/use-customer.tsx +++ b/framework/swell/customer/use-customer.tsx @@ -1,20 +1,25 @@ import useCustomer, { UseCustomer } from '@commerce/customer/use-customer' import { Customer } from '@commerce/types' import { SWRHook } from '@commerce/utils/types' -import { getCustomerQuery, getCustomerToken } from '../utils' +import { normalizeCustomer } from '../utils/normalize' +// import { getCustomerQuery, getCustomerToken } from '../utils' export default useCustomer as UseCustomer export const handler: SWRHook = { fetchOptions: { - query: getCustomerQuery, + query: 'account', + method: 'get', }, async fetcher({ options, fetch }) { + // console.log('STORE_ID', STORE_ID, 'PUBLIC_KEY', PUBLIC_KEY); + // const data = await swell.account.get() const data = await fetch({ ...options, - variables: { customerAccessToken: getCustomerToken() }, + // variables: { customerAccessToken: getCustomerToken() }, }) - return data.customer ?? null + console.log(`Customer data ${data}`) + return data ? normalizeCustomer(data) : null }, useHook: ({ useData }) => (input) => { return useData({ @@ -25,3 +30,26 @@ export const handler: SWRHook = { }) }, } + +// const handler = (): { data: Customer } => { +// const swell = getContext(); +// const response = swell.account.get(); +// const { firstName, lastName, email, company, customerGroupId, notes, phone, +// entityId, addressCount, attributeCount, storeCredit } = response; +// return { +// data: { +// firstName, +// lastName, +// email, +// company, +// customerGroupId, +// notes, +// phone, +// entityId, +// addressCount, +// attributeCount, +// storeCredit +// } +// } +// } +// export default handler; diff --git a/framework/swell/fetcher.ts b/framework/swell/fetcher.ts index 9c4fe9a9e..f10032957 100644 --- a/framework/swell/fetcher.ts +++ b/framework/swell/fetcher.ts @@ -1,18 +1,25 @@ import { Fetcher } from '@commerce/utils/types' -import { API_TOKEN, API_URL } from './const' import { handleFetchResponse } from './utils' +import { swellConfig } from './index' -const fetcher: Fetcher = async ({ method = 'POST', variables, query }) => { - return handleFetchResponse( - await fetch(API_URL, { - method, - body: JSON.stringify({ query, variables }), - headers: { - 'X-Shopify-Storefront-Access-Token': API_TOKEN!, - 'Content-Type': 'application/json', - }, - }) - ) +const fetcher: Fetcher = async ({ method = 'get', variables, query }) => { + const { swell } = swellConfig + async function callSwell() { + if (Array.isArray(variables)) { + const arg1 = variables[0] + const arg2 = variables[1] + const response = await swell[query][method](arg1, arg2) + console.log(response) + return handleFetchResponse(response) + } else { + const response = await swell[query][method](variables) + console.log(response) + return handleFetchResponse(response) + } + } + if (query) { + return await callSwell() + } } export default fetcher diff --git a/framework/swell/index.tsx b/framework/swell/index.tsx index c26704771..db8cd3e1f 100644 --- a/framework/swell/index.tsx +++ b/framework/swell/index.tsx @@ -1,4 +1,5 @@ import * as React from 'react' +import swell from 'swell-js' import { ReactNode } from 'react' import { @@ -7,30 +8,36 @@ import { useCommerce as useCoreCommerce, } from '@commerce' -import { shopifyProvider, ShopifyProvider } from './provider' -import { SHOPIFY_CHECKOUT_ID_COOKIE } from './const' +import { swellProvider, SwellProvider } from './provider' +import { + SHOPIFY_CHECKOUT_ID_COOKIE, + SWELL_STORE_ID, + SWELL_PUBLIC_KEY, +} from './const' +swell.init(SWELL_STORE_ID, SWELL_PUBLIC_KEY) -export { shopifyProvider } -export type { ShopifyProvider } +export { swellProvider } +export type { SwellProvider } -export const shopifyConfig: CommerceConfig = { +export const swellConfig: any = { locale: 'en-us', cartCookie: SHOPIFY_CHECKOUT_ID_COOKIE, + swell, } -export type ShopifyConfig = Partial +export type SwellConfig = Partial -export type ShopifyProps = { +export type SwellProps = { children?: ReactNode locale: string -} & ShopifyConfig +} & SwellConfig -export function CommerceProvider({ children, ...config }: ShopifyProps) { +export function CommerceProvider({ children, ...config }: SwellProps) { return ( {children} diff --git a/framework/swell/product/get-all-collections.ts b/framework/swell/product/get-all-collections.ts index 15c4bc51a..b3832316c 100644 --- a/framework/swell/product/get-all-collections.ts +++ b/framework/swell/product/get-all-collections.ts @@ -1,10 +1,10 @@ import { CollectionEdge } from '../schema' -import { getConfig, ShopifyConfig } from '../api' +import { getConfig, SwellConfig } from '../api' import getAllCollectionsQuery from '../utils/queries/get-all-collections-query' const getAllCollections = async (options?: { variables?: any - config: ShopifyConfig + config: SwellConfig preview?: boolean }) => { let { config, variables = { first: 250 } } = options ?? {} diff --git a/framework/swell/product/get-all-product-paths.ts b/framework/swell/product/get-all-product-paths.ts index 4431d1e53..4f3dec29a 100644 --- a/framework/swell/product/get-all-product-paths.ts +++ b/framework/swell/product/get-all-product-paths.ts @@ -1,5 +1,5 @@ import { Product } from '@commerce/types' -import { getConfig, ShopifyConfig } from '../api' +import { getConfig, SwellConfig } from '../api' import fetchAllProducts from '../api/utils/fetch-all-products' import { ProductEdge } from '../schema' import getAllProductsPathsQuery from '../utils/queries/get-all-products-paths-query' @@ -18,7 +18,7 @@ type ReturnType = { const getAllProductPaths = async (options?: { variables?: any - config?: ShopifyConfig + config?: SwellConfig preview?: boolean }): Promise => { let { config, variables = { first: 250 } } = options ?? {} diff --git a/framework/swell/product/get-all-products.ts b/framework/swell/product/get-all-products.ts index 14e486563..78e081238 100644 --- a/framework/swell/product/get-all-products.ts +++ b/framework/swell/product/get-all-products.ts @@ -1,5 +1,5 @@ import { GraphQLFetcherResult } from '@commerce/api' -import { getConfig, ShopifyConfig } from '../api' +import { getConfig, SwellConfig } from '../api' import { ProductEdge } from '../schema' import { getAllProductsQuery } from '../utils/queries' import { normalizeProduct } from '../utils/normalize' @@ -16,7 +16,7 @@ type ReturnType = { const getAllProducts = async (options: { variables?: Variables - config?: ShopifyConfig + config?: SwellConfig preview?: boolean }): Promise => { let { config, variables = { first: 250 } } = options ?? {} diff --git a/framework/swell/product/get-product.ts b/framework/swell/product/get-product.ts index 1f00288c7..cfac8e984 100644 --- a/framework/swell/product/get-product.ts +++ b/framework/swell/product/get-product.ts @@ -1,5 +1,5 @@ import { GraphQLFetcherResult } from '@commerce/api' -import { getConfig, ShopifyConfig } from '../api' +import { getConfig, SwellConfig } from '../api' import { normalizeProduct, getProductQuery } from '../utils' type Variables = { @@ -12,7 +12,7 @@ type ReturnType = { const getProduct = async (options: { variables: Variables - config: ShopifyConfig + config: SwellConfig preview?: boolean }): Promise => { let { config, variables } = options ?? {} diff --git a/framework/swell/provider.ts b/framework/swell/provider.ts index 383822baa..f8a4ac1d6 100644 --- a/framework/swell/provider.ts +++ b/framework/swell/provider.ts @@ -14,7 +14,7 @@ import { handler as useSignup } from './auth/use-signup' import fetcher from './fetcher' -export const shopifyProvider = { +export const swellProvider = { locale: 'en-us', cartCookie: SHOPIFY_CHECKOUT_ID_COOKIE, storeDomain: STORE_DOMAIN, @@ -28,4 +28,4 @@ export const shopifyProvider = { }, } -export type ShopifyProvider = typeof shopifyProvider +export type SwellProvider = typeof swellProvider diff --git a/framework/swell/swell-js.d.ts b/framework/swell/swell-js.d.ts new file mode 100644 index 000000000..64a94d89e --- /dev/null +++ b/framework/swell/swell-js.d.ts @@ -0,0 +1 @@ +declare module 'swell-js' diff --git a/framework/swell/types.ts b/framework/swell/types.ts index c4e42b67d..579402f97 100644 --- a/framework/swell/types.ts +++ b/framework/swell/types.ts @@ -1,6 +1,11 @@ import * as Core from '@commerce/types' import { CheckoutLineItem } from './schema' +export interface SwellCustomer extends Core.Customer { + first_name: string + last_name: string +} + export type ShopifyCheckout = { id: string webUrl: string diff --git a/framework/swell/utils/get-categories.ts b/framework/swell/utils/get-categories.ts index cce4b2ad7..0f8c3c9d8 100644 --- a/framework/swell/utils/get-categories.ts +++ b/framework/swell/utils/get-categories.ts @@ -1,4 +1,4 @@ -import { ShopifyConfig } from '../api' +import { SwellConfig } from '../api' import { CollectionEdge } from '../schema' import getSiteCollectionsQuery from './queries/get-all-collections-query' @@ -8,7 +8,7 @@ export type Category = { path: string } -const getCategories = async (config: ShopifyConfig): Promise => { +const getCategories = async (config: SwellConfig): Promise => { const { data } = await config.fetch(getSiteCollectionsQuery, { variables: { first: 250, diff --git a/framework/swell/utils/get-vendors.ts b/framework/swell/utils/get-vendors.ts index f04483bb1..632f5daaf 100644 --- a/framework/swell/utils/get-vendors.ts +++ b/framework/swell/utils/get-vendors.ts @@ -1,4 +1,4 @@ -import { ShopifyConfig } from '../api' +import { SwellConfig } from '../api' import fetchAllProducts from '../api/utils/fetch-all-products' import getAllProductVendors from './queries/get-all-product-vendors-query' @@ -13,7 +13,7 @@ export type BrandEdge = { export type Brands = BrandEdge[] -const getVendors = async (config: ShopifyConfig): Promise => { +const getVendors = async (config: SwellConfig): Promise => { const vendors = await fetchAllProducts({ config, query: getAllProductVendors, diff --git a/framework/swell/utils/handle-fetch-response.ts b/framework/swell/utils/handle-fetch-response.ts index 8d7427d91..79aba8bd3 100644 --- a/framework/swell/utils/handle-fetch-response.ts +++ b/framework/swell/utils/handle-fetch-response.ts @@ -11,15 +11,16 @@ export async function getAsyncError(res: Response) { } const handleFetchResponse = async (res: Response) => { - if (res.ok) { - const { data, errors } = await res.json() + // if (res.ok) { + // const { data, errors } = await res.json() - if (errors && errors.length) { - throw getError(errors, res.status) - } + // if (errors && errors.length) { + // throw getError(errors, res.status) + // } - return data - } + // return data + // } + if (res) return res throw await getAsyncError(res) } diff --git a/framework/swell/utils/normalize.ts b/framework/swell/utils/normalize.ts index c9b428b37..17579c2d3 100644 --- a/framework/swell/utils/normalize.ts +++ b/framework/swell/utils/normalize.ts @@ -1,4 +1,5 @@ import { Product } from '@commerce/types' +import { Customer } from '@commerce/types' import { Product as ShopifyProduct, @@ -11,7 +12,7 @@ import { ProductOption, } from '../schema' -import type { Cart, LineItem } from '../types' +import type { Cart, LineItem, SwellCustomer } from '../types' const money = ({ amount, currencyCode }: MoneyV2) => { return { @@ -121,6 +122,15 @@ export function normalizeCart(checkout: Checkout): Cart { } } +export function normalizeCustomer(customer: SwellCustomer): Customer { + const { first_name: firstName, last_name: lastName } = customer + return { + ...customer, + firstName, + lastName, + } +} + function normalizeLineItem({ node: { id, title, variant, quantity }, }: CheckoutLineItemEdge): LineItem { diff --git a/package.json b/package.json index 4e8fa8d30..b054dec66 100644 --- a/package.json +++ b/package.json @@ -42,6 +42,7 @@ "react-merge-refs": "^1.1.0", "react-ticker": "^1.2.2", "shopify-buy": "^2.11.0", + "swell-js": "^4.0.0-next.0", "swr": "^0.4.0", "tabbable": "^5.1.5", "tailwindcss": "^2.0.3" diff --git a/tsconfig.json b/tsconfig.json index 9e712fb18..3d1b7584d 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -22,10 +22,10 @@ "@components/*": ["components/*"], "@commerce": ["framework/commerce"], "@commerce/*": ["framework/commerce/*"], - "@framework": ["framework/bigcommerce"], - "@framework/*": ["framework/bigcommerce/*"] + "@framework": ["framework/swell"], + "@framework/*": ["framework/swell/*"] } }, "include": ["next-env.d.ts", "**/*.d.ts", "**/*.ts", "**/*.tsx", "**/*.js"], - "exclude": ["node_modules"] + "exclude": ["node_modules", "swell-js"] } diff --git a/yarn.lock b/yarn.lock index 7a1dce814..a0846380f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -401,6 +401,13 @@ dependencies: regenerator-runtime "^0.13.4" +"@babel/runtime@7.4.5": + version "7.4.5" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.4.5.tgz#582bb531f5f9dc67d2fcb682979894f75e253f12" + integrity sha512-TuI4qpWZP6lGOGIuGWtp9sPluqYICmbk8T/1vpSysqJxRPkudh/ofFWyqdcMsDf2s7KvDL4/YHgKyvcS3g9CJQ== + dependencies: + regenerator-runtime "^0.13.2" + "@babel/runtime@^7.0.0": version "7.12.13" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.12.13.tgz#0a21452352b02542db0ffb928ac2d3ca7cb6d66d" @@ -408,6 +415,13 @@ dependencies: regenerator-runtime "^0.13.4" +"@babel/runtime@^7.12.13", "@babel/runtime@^7.13.10": + version "7.13.10" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.13.10.tgz#47d42a57b6095f4468da440388fdbad8bebf0d7d" + integrity sha512-4QPkjJq6Ns3V/RgpEahRk+AGfL0eO6RHHtTWoNNr5mO49G6B5+X6d6THgWEAvTrznU5xYpbAlVKRYcsCgh/Akw== + dependencies: + regenerator-runtime "^0.13.4" + "@babel/template@^7.12.13": version "7.12.13" resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.12.13.tgz#530265be8a2589dbb37523844c5bcb55947fb327" @@ -1522,6 +1536,14 @@ array-flatten@^3.0.0: resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-3.0.0.tgz#6428ca2ee52c7b823192ec600fa3ed2f157cd541" integrity sha512-zPMVc3ZYlGLNk4mpK1NzP2wg0ml9t7fUgDsayR5Y5rSzxQilzR9FGu/EH2jQOcKSAeAfWeylyW8juy3OkWRvNA== +array-includes-with-glob@^3.0.6: + version "3.0.8" + resolved "https://registry.yarnpkg.com/array-includes-with-glob/-/array-includes-with-glob-3.0.8.tgz#522a982e7913a9e6397efd3d933aa3cc61776cb2" + integrity sha512-g1XH4sJ/LMdyUSDB/9pNEC/eEO62chSTIi9I5agGHi4NI90SASER1Qe4emrTgCeaNPCAcivfi3Ba0owq6Pwo4Q== + dependencies: + "@babel/runtime" "^7.13.10" + matcher "^4.0.0" + array-union@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" @@ -2542,7 +2564,7 @@ deep-is@~0.1.3: resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ= -deepmerge@^4.2.2: +deepmerge@4.2.2, deepmerge@^4.2.2: version "4.2.2" resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.2.2.tgz#44d2ea3679b8f4d4ffba33f03d865fc1e7bf4955" integrity sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg== @@ -2914,6 +2936,11 @@ escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= +escape-string-regexp@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" + integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== + escodegen@^1.8.0: version "1.14.3" resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.14.3.tgz#4e7b81fba61581dc97582ed78cab7f0e8d63f503" @@ -3896,7 +3923,7 @@ isobject@^4.0.0: resolved "https://registry.yarnpkg.com/isobject/-/isobject-4.0.0.tgz#3f1c9155e73b192022a80819bacd0343711697b0" integrity sha512-S/2fF5wH8SJA/kmwr6HYhK/RI/OkhD84k8ntalo0iJjZikgq1XFvR5M8NPT1x5F7fBwCG3qHfnzeP/Vh/ZxCUA== -isomorphic-fetch@^3.0.0: +isomorphic-fetch@3.0.0, isomorphic-fetch@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/isomorphic-fetch/-/isomorphic-fetch-3.0.0.tgz#0267b005049046d2421207215d45d6a262b8b8b4" integrity sha512-qvUtwJ3j6qwsF3jLxkZ72qCgjMysPzDfeV240JHiGZsANBYd+EEuu35v7dfrJ9Up0Ak07D7GGSkGhCHTqg/5wA== @@ -4219,6 +4246,16 @@ lodash._reinterpolate@^3.0.0: resolved "https://registry.yarnpkg.com/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz#0ccf2d89166af03b3663c796538b75ac6e114d9d" integrity sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0= +lodash.camelcase@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6" + integrity sha1-soqmKIorn8ZRA1x3EfZathkDMaY= + +lodash.clonedeep@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" + integrity sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8= + lodash.debounce@^4.0.8: version "4.0.8" resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" @@ -4239,6 +4276,11 @@ lodash.isboolean@^3.0.3: resolved "https://registry.yarnpkg.com/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz#6c2e171db2a257cd96802fd43b01b20d5f5870f6" integrity sha1-bC4XHbKiV82WgC/UOwGyDV9YcPY= +lodash.isdate@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/lodash.isdate/-/lodash.isdate-4.0.1.tgz#35a543673b9d76110de4114b32cc577048a7f366" + integrity sha1-NaVDZzuddhEN5BFLMsxXcEin82Y= + lodash.isinteger@^4.0.4: version "4.0.4" resolved "https://registry.yarnpkg.com/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz#619c0af3d03f8b04c31f5882840b77b11cd68343" @@ -4269,6 +4311,11 @@ lodash.random@^3.2.0: resolved "https://registry.yarnpkg.com/lodash.random/-/lodash.random-3.2.0.tgz#96e24e763333199130d2c9e2fd57f91703cc262d" integrity sha1-luJOdjMzGZEw0sni/Vf5FwPMJi0= +lodash.snakecase@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/lodash.snakecase/-/lodash.snakecase-4.1.1.tgz#39d714a35357147837aefd64b5dcbb16becd8f8d" + integrity sha1-OdcUo1NXFHg3rv1ktdy7Fr7Nj40= + lodash.sortby@^4.7.0: version "4.7.0" resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438" @@ -4299,6 +4346,16 @@ lodash.toarray@^4.4.0: resolved "https://registry.yarnpkg.com/lodash.toarray/-/lodash.toarray-4.4.0.tgz#24c4bfcd6b2fba38bfd0594db1179d8e9b656561" integrity sha1-JMS/zWsvuji/0FlNsRedjptlZWE= +lodash.uniq@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" + integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M= + +lodash@4.17.21: + version "4.17.21" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" + integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== + lodash@^4.17.13, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20, lodash@~4.17.20: version "4.17.20" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.20.tgz#b44a9b6297bcb698f1c51a3545a2b3b368d59c52" @@ -4445,6 +4502,13 @@ map-obj@^4.0.0: resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-4.1.0.tgz#b91221b542734b9f14256c0132c897c5d7256fd5" integrity sha512-glc9y00wgtwcDmp7GaE/0b0OnxpNJsVf3ael/An6Fe2Q51LLwN1er6sdomLRzz5h0+yMpiYLhWYF5R7HeqVd4g== +matcher@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/matcher/-/matcher-4.0.0.tgz#a42a05a09aaed92e2d241eb91fddac689461ea51" + integrity sha512-S6x5wmcDmsDRRU/c2dkccDwQPXoFczc5+HpQ2lON8pnvHlnvHAHj5WlLVvw6n6vNyHuVugYrFohYxbS+pvFpKQ== + dependencies: + escape-string-regexp "^4.0.0" + md5.js@^1.3.4: version "1.3.5" resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f" @@ -4891,11 +4955,33 @@ object-inspect@^1.9.0: resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.9.0.tgz#c90521d74e1127b67266ded3394ad6116986533a" integrity sha512-i3Bp9iTqwhaLZBxGkRfo5ZbE07BQRT7MGu8+nNgwW9ItGp1TzCTw2DLEoWwjClxBjOFI/hWljTAmYGCEwmtnOw== +object-keys-normalizer@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/object-keys-normalizer/-/object-keys-normalizer-1.0.1.tgz#db178dbba5e4c7b18b40837c8ef83365ee9348e7" + integrity sha1-2xeNu6Xkx7GLQIN8jvgzZe6TSOc= + dependencies: + lodash.camelcase "^4.3.0" + lodash.snakecase "^4.1.1" + object-keys@^1.0.12, object-keys@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== +object-merge-advanced@12.0.3: + version "12.0.3" + resolved "https://registry.yarnpkg.com/object-merge-advanced/-/object-merge-advanced-12.0.3.tgz#e03c19aa33cf88da6b32187e4907b487668808d9" + integrity sha512-xQIf2Vup1rpKiHr2tQca5jyNYgT4O0kNxOfAp3ZNonm2hS+5yaJgI0Czdk/QMy52bcRwQKX3uc3H8XtAiiYfVA== + dependencies: + "@babel/runtime" "^7.12.13" + array-includes-with-glob "^3.0.6" + lodash.clonedeep "^4.5.0" + lodash.includes "^4.3.0" + lodash.isdate "^4.0.1" + lodash.isplainobject "^4.0.6" + lodash.uniq "^4.5.0" + util-nonempty "^3.0.6" + object-path@^0.11.4: version "0.11.5" resolved "https://registry.yarnpkg.com/object-path/-/object-path-0.11.5.tgz#d4e3cf19601a5140a55a16ad712019a9c50b577a" @@ -5755,6 +5841,11 @@ purgecss@^3.1.3: postcss "^8.2.1" postcss-selector-parser "^6.0.2" +qs@6.7.0: + version "6.7.0" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.7.0.tgz#41dc1a015e3d581f1621776be31afb2876a9b1bc" + integrity sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ== + querystring-es3@^0.2.0: version "0.2.1" resolved "https://registry.yarnpkg.com/querystring-es3/-/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73" @@ -5916,7 +6007,7 @@ reduce-css-calc@^2.1.8: css-unit-converter "^1.1.1" postcss-value-parser "^3.3.0" -regenerator-runtime@^0.13.4: +regenerator-runtime@^0.13.2, regenerator-runtime@^0.13.4: version "0.13.7" resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz#cac2dacc8a1ea675feaabaeb8ae833898ae46f55" integrity sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew== @@ -6609,6 +6700,19 @@ supports-color@^7.0.0, supports-color@^7.1.0: dependencies: has-flag "^4.0.0" +swell-js@^4.0.0-next.0: + version "4.0.0-next.0" + resolved "https://registry.yarnpkg.com/swell-js/-/swell-js-4.0.0-next.0.tgz#870599372e3c9eafefeafc2c63863c4032d8be6b" + integrity sha512-OQ1FLft3ruKpQw5P0TiCzs/X2Ma95+Qz+I2Xzs4KC6v+zVaFVUGNs80dQdtjfInisWoFC7iFZF2AITgellVGAg== + dependencies: + "@babel/runtime" "7.4.5" + deepmerge "4.2.2" + isomorphic-fetch "3.0.0" + lodash "4.17.21" + object-keys-normalizer "1.0.1" + object-merge-advanced "12.0.3" + qs "6.7.0" + swr@^0.4.0: version "0.4.2" resolved "https://registry.yarnpkg.com/swr/-/swr-0.4.2.tgz#4a9ed5e9948088af145c79d716d294cb99712a29" @@ -6982,6 +7086,14 @@ util-deprecate@^1.0.1, util-deprecate@^1.0.2, util-deprecate@~1.0.1: resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= +util-nonempty@^3.0.6: + version "3.0.8" + resolved "https://registry.yarnpkg.com/util-nonempty/-/util-nonempty-3.0.8.tgz#0e53820a29e2c6cdcc3ecece52bc7fdd193c9b2b" + integrity sha512-eB6dfVQWEBMT7i9EgWigvJiHUlW/iaq/Wg6pcWviwKsPWFwgprPVilZHkTAhzmXgv9LnGOLjrszm/HvIHpbeQw== + dependencies: + "@babel/runtime" "^7.13.10" + lodash.isplainobject "^4.0.6" + util@0.10.3: version "0.10.3" resolved "https://registry.yarnpkg.com/util/-/util-0.10.3.tgz#7afb1afe50805246489e3db7fe0ed379336ac0f9" From e4c1050880a0a8d8fd8e31fcdc74bc73c8678059 Mon Sep 17 00:00:00 2001 From: Greg Hoskin Date: Mon, 29 Mar 2021 17:05:20 -0600 Subject: [PATCH 190/216] update get categories hook --- framework/swell/api/index.ts | 6 ++++- framework/swell/api/utils/fetch-swell-api.ts | 9 +++++++ framework/swell/utils/get-categories.ts | 25 +++++++------------- 3 files changed, 22 insertions(+), 18 deletions(-) create mode 100644 framework/swell/api/utils/fetch-swell-api.ts diff --git a/framework/swell/api/index.ts b/framework/swell/api/index.ts index fc48116a6..9c41b18ae 100644 --- a/framework/swell/api/index.ts +++ b/framework/swell/api/index.ts @@ -21,8 +21,11 @@ if (!API_TOKEN) { } import fetchGraphqlApi from './utils/fetch-graphql-api' +import fetchSwellApi from './utils/fetch-swell-api' -export interface SwellConfig extends CommerceAPIConfig {} +export interface SwellConfig extends CommerceAPIConfig { + fetchSwell: any +} export class Config { private config: SwellConfig @@ -49,6 +52,7 @@ const config = new Config({ apiToken: API_TOKEN!, cartCookie: SHOPIFY_CHECKOUT_ID_COOKIE, cartCookieMaxAge: SHOPIFY_COOKIE_EXPIRE, + fetchSwell: fetchSwellApi, fetch: fetchGraphqlApi, customerCookie: SHOPIFY_CUSTOMER_TOKEN_COOKIE, }) diff --git a/framework/swell/api/utils/fetch-swell-api.ts b/framework/swell/api/utils/fetch-swell-api.ts new file mode 100644 index 000000000..c4c9472cf --- /dev/null +++ b/framework/swell/api/utils/fetch-swell-api.ts @@ -0,0 +1,9 @@ +import { swellConfig } from '../../index' + +const fetchSwellApi = async (query: string, method: string) => { + const { swell } = swellConfig + const res = await swell[query][method]() + + return res +} +export default fetchSwellApi diff --git a/framework/swell/utils/get-categories.ts b/framework/swell/utils/get-categories.ts index 0f8c3c9d8..5b9ba501e 100644 --- a/framework/swell/utils/get-categories.ts +++ b/framework/swell/utils/get-categories.ts @@ -1,28 +1,19 @@ import { SwellConfig } from '../api' -import { CollectionEdge } from '../schema' -import getSiteCollectionsQuery from './queries/get-all-collections-query' export type Category = { - entityId: string + id: string name: string - path: string + slug: string } const getCategories = async (config: SwellConfig): Promise => { - const { data } = await config.fetch(getSiteCollectionsQuery, { - variables: { - first: 250, - }, - }) - + const data = await config.fetchSwell('categories', 'get') return ( - data.collections?.edges?.map( - ({ node: { id: entityId, title: name, handle } }: CollectionEdge) => ({ - entityId, - name, - path: `/${handle}`, - }) - ) ?? [] + data.results.map(({ id: entityId, name, slug }: Category) => ({ + entityId, + name, + path: `/${slug}`, + })) ?? [] ) } From 1ebf458fb23f3f8907503634394ad9b2e2f8e0e1 Mon Sep 17 00:00:00 2001 From: Greg Hoskin Date: Mon, 29 Mar 2021 17:49:14 -0600 Subject: [PATCH 191/216] update product search hook. whitelist cdn --- framework/swell/customer/use-customer.tsx | 4 --- framework/swell/fetcher.ts | 4 +-- framework/swell/next.config.js | 2 +- framework/swell/product/get-all-products.ts | 12 ++------ framework/swell/product/use-search.tsx | 33 +++++---------------- framework/swell/schema.d.ts | 2 +- framework/swell/types.ts | 5 ++++ framework/swell/utils/normalize.ts | 25 ++++++++-------- 8 files changed, 31 insertions(+), 56 deletions(-) diff --git a/framework/swell/customer/use-customer.tsx b/framework/swell/customer/use-customer.tsx index ec3dd99fd..7b84795aa 100644 --- a/framework/swell/customer/use-customer.tsx +++ b/framework/swell/customer/use-customer.tsx @@ -12,13 +12,9 @@ export const handler: SWRHook = { method: 'get', }, async fetcher({ options, fetch }) { - // console.log('STORE_ID', STORE_ID, 'PUBLIC_KEY', PUBLIC_KEY); - // const data = await swell.account.get() const data = await fetch({ ...options, - // variables: { customerAccessToken: getCustomerToken() }, }) - console.log(`Customer data ${data}`) return data ? normalizeCustomer(data) : null }, useHook: ({ useData }) => (input) => { diff --git a/framework/swell/fetcher.ts b/framework/swell/fetcher.ts index f10032957..e52d8fd54 100644 --- a/framework/swell/fetcher.ts +++ b/framework/swell/fetcher.ts @@ -9,15 +9,13 @@ const fetcher: Fetcher = async ({ method = 'get', variables, query }) => { const arg1 = variables[0] const arg2 = variables[1] const response = await swell[query][method](arg1, arg2) - console.log(response) return handleFetchResponse(response) } else { const response = await swell[query][method](variables) - console.log(response) return handleFetchResponse(response) } } - if (query) { + if (query in swell) { return await callSwell() } } diff --git a/framework/swell/next.config.js b/framework/swell/next.config.js index e9d48c02c..f6ac38345 100644 --- a/framework/swell/next.config.js +++ b/framework/swell/next.config.js @@ -3,6 +3,6 @@ const commerce = require('./commerce.config.json') module.exports = { commerce, images: { - domains: ['cdn.shopify.com'], + domains: ['cdn.schema.io'], }, } diff --git a/framework/swell/product/get-all-products.ts b/framework/swell/product/get-all-products.ts index 78e081238..8ca85eecd 100644 --- a/framework/swell/product/get-all-products.ts +++ b/framework/swell/product/get-all-products.ts @@ -21,16 +21,8 @@ const getAllProducts = async (options: { }): Promise => { let { config, variables = { first: 250 } } = options ?? {} config = getConfig(config) - - const { data }: GraphQLFetcherResult = await config.fetch( - getAllProductsQuery, - { variables } - ) - - const products = - data.products?.edges?.map(({ node: p }: ProductEdge) => - normalizeProduct(p) - ) ?? [] + const { results } = await config.fetchSwell('products', 'get') + const products = results.map((product) => normalizeProduct(product)) ?? [] return { products, diff --git a/framework/swell/product/use-search.tsx b/framework/swell/product/use-search.tsx index 425df9e83..a00e39dc9 100644 --- a/framework/swell/product/use-search.tsx +++ b/framework/swell/product/use-search.tsx @@ -1,13 +1,7 @@ import { SWRHook } from '@commerce/utils/types' import useSearch, { UseSearch } from '@commerce/product/use-search' -import { ProductEdge } from '../schema' -import { - getAllProductsQuery, - getCollectionProductsQuery, - getSearchVariables, - normalizeProduct, -} from '../utils' +import { getAllProductsQuery, normalizeProduct } from '../utils' import { Product } from '@commerce/types' @@ -36,28 +30,17 @@ export const handler: SWRHook< async fetcher({ input, options, fetch }) { const { categoryId, brandId } = input - const data = await fetch({ - query: categoryId ? getCollectionProductsQuery : options.query, - method: options?.method, - variables: getSearchVariables(input), + const { results, count: found } = await fetch({ + query: 'products', + method: 'get', + // variables: { categoryId }, }) - let edges - - if (categoryId) { - edges = data.node?.products?.edges ?? [] - if (brandId) { - edges = edges.filter( - ({ node: { vendor } }: ProductEdge) => vendor === brandId - ) - } - } else { - edges = data.products?.edges ?? [] - } + const products = results.map((product) => normalizeProduct(product)) return { - products: edges.map(({ node }: ProductEdge) => normalizeProduct(node)), - found: !!edges.length, + products, + found, } }, useHook: ({ useData }) => (input = {}) => { diff --git a/framework/swell/schema.d.ts b/framework/swell/schema.d.ts index b1b23a3e5..8ffa23f73 100644 --- a/framework/swell/schema.d.ts +++ b/framework/swell/schema.d.ts @@ -4147,7 +4147,7 @@ export type ProductOption = Node & { /** The product option’s name. */ name: Scalars['String'] /** The corresponding value to the product option name. */ - values: Array + values: Array } /** The price range of the product. */ diff --git a/framework/swell/types.ts b/framework/swell/types.ts index 579402f97..2878295e1 100644 --- a/framework/swell/types.ts +++ b/framework/swell/types.ts @@ -1,6 +1,11 @@ import * as Core from '@commerce/types' import { CheckoutLineItem } from './schema' +export interface SwellProduct extends Core.Product { + name: string + slug: string +} + export interface SwellCustomer extends Core.Customer { first_name: string last_name: string diff --git a/framework/swell/utils/normalize.ts b/framework/swell/utils/normalize.ts index 17579c2d3..6dbb6d708 100644 --- a/framework/swell/utils/normalize.ts +++ b/framework/swell/utils/normalize.ts @@ -1,5 +1,6 @@ import { Product } from '@commerce/types' import { Customer } from '@commerce/types' +import { fileURLToPath } from 'node:url' import { Product as ShopifyProduct, @@ -12,7 +13,7 @@ import { ProductOption, } from '../schema' -import type { Cart, LineItem, SwellCustomer } from '../types' +import type { Cart, LineItem, SwellCustomer, SwellProduct } from '../types' const money = ({ amount, currencyCode }: MoneyV2) => { return { @@ -32,7 +33,7 @@ const normalizeProductOption = ({ displayName, values: values.map((value) => { let output: any = { - label: value, + label: value.name, } if (displayName === 'Color') { output = { @@ -45,9 +46,9 @@ const normalizeProductOption = ({ } } -const normalizeProductImages = ({ edges }: ImageConnection) => - edges?.map(({ node: { originalSrc: url, ...rest } }) => ({ - url, +const normalizeProductImages = (images) => + images?.map(({ file, ...rest }) => ({ + url: file.url, ...rest, })) @@ -73,16 +74,16 @@ const normalizeProductVariants = ({ edges }: ProductVariantConnection) => { ) } -export function normalizeProduct(productNode: ShopifyProduct): Product { +export function normalizeProduct(productNode: SwellProduct): Product { const { id, - title: name, + name, vendor, images, variants, description, - handle, - priceRange, + slug, + price, options, ...rest } = productNode @@ -92,9 +93,9 @@ export function normalizeProduct(productNode: ShopifyProduct): Product { name, vendor, description, - path: `/${handle}`, - slug: handle?.replace(/^\/+|\/+$/g, ''), - price: money(priceRange?.minVariantPrice), + path: `/${slug}`, + slug, + price, images: normalizeProductImages(images), variants: variants ? normalizeProductVariants(variants) : [], options: options ? options.map((o) => normalizeProductOption(o)) : [], From 18936b7544f39eed8e86d2bd3fd9a3a345144c78 Mon Sep 17 00:00:00 2001 From: Greg Hoskin Date: Thu, 1 Apr 2021 16:32:12 -0600 Subject: [PATCH 192/216] update get product hook --- framework/swell/api/utils/fetch-swell-api.ts | 8 +- framework/swell/cart/use-cart.tsx | 64 ++++--------- framework/swell/cart/utils/checkout-create.ts | 27 +++--- framework/swell/cart/utils/fetcher.ts | 32 ++++--- framework/swell/fetcher.ts | 2 + framework/swell/product/get-product.ts | 6 +- framework/swell/product/use-search.tsx | 4 +- framework/swell/utils/normalize.ts | 91 +++++++++---------- 8 files changed, 103 insertions(+), 131 deletions(-) diff --git a/framework/swell/api/utils/fetch-swell-api.ts b/framework/swell/api/utils/fetch-swell-api.ts index c4c9472cf..805aa46e8 100644 --- a/framework/swell/api/utils/fetch-swell-api.ts +++ b/framework/swell/api/utils/fetch-swell-api.ts @@ -1,8 +1,12 @@ import { swellConfig } from '../../index' -const fetchSwellApi = async (query: string, method: string) => { +const fetchSwellApi = async ( + query: string, + method: string, + variables: object | string +) => { const { swell } = swellConfig - const res = await swell[query][method]() + const res = await swell[query][method](variables) return res } diff --git a/framework/swell/cart/use-cart.tsx b/framework/swell/cart/use-cart.tsx index a1a303210..c9589f484 100644 --- a/framework/swell/cart/use-cart.tsx +++ b/framework/swell/cart/use-cart.tsx @@ -1,60 +1,28 @@ -import { useMemo } from 'react' -import useCommerceCart, { - FetchCartInput, - UseCart, -} from '@commerce/cart/use-cart' - -import { Cart } from '../types' +import useCart, { UseCart } from '@commerce/cart/use-cart' +import { Customer } from '@commerce/types' import { SWRHook } from '@commerce/utils/types' -import { checkoutCreate, checkoutToCart } from './utils' -import getCheckoutQuery from '../utils/queries/get-checkout-query' +import { normalizeCart } from '../utils/normalize' +// import { getCustomerQuery, getCustomerToken } from '../utils' -export default useCommerceCart as UseCart +export default useCart as UseCart -export const handler: SWRHook< - Cart | null, - {}, - FetchCartInput, - { isEmpty?: boolean } -> = { +export const handler: SWRHook = { fetchOptions: { query: 'cart', method: 'get', }, - async fetcher({ input: { cartId: checkoutId }, options, fetch }) { - let checkout - if (checkoutId) { - const data = await fetch({ - ...options, - variables: { - checkoutId, - }, - }) - checkout = data.node - } - - if (checkout?.completedAt || !checkoutId) { - checkout = await checkoutCreate(fetch) - } - - // TODO: Fix this type - return checkoutToCart({ checkout } as any) + async fetcher({ options, fetch }) { + const data = await fetch({ + ...options, + }) + return data ? normalizeCart(data) : null }, useHook: ({ useData }) => (input) => { - const response = useData({ - swrOptions: { revalidateOnFocus: false, ...input?.swrOptions }, + return useData({ + swrOptions: { + revalidateOnFocus: false, + ...input?.swrOptions, + }, }) - return useMemo( - () => - Object.create(response, { - isEmpty: { - get() { - return (response.data?.lineItems.length ?? 0) <= 0 - }, - enumerable: true, - }, - }), - [response] - ) }, } diff --git a/framework/swell/cart/utils/checkout-create.ts b/framework/swell/cart/utils/checkout-create.ts index e950cc7e4..73109baad 100644 --- a/framework/swell/cart/utils/checkout-create.ts +++ b/framework/swell/cart/utils/checkout-create.ts @@ -4,26 +4,27 @@ import { SHOPIFY_COOKIE_EXPIRE, } from '../../const' -import checkoutCreateMutation from '../../utils/mutations/checkout-create' +// import checkoutCreateMutation from '../../utils/mutations/checkout-create' import Cookies from 'js-cookie' export const checkoutCreate = async (fetch: any) => { - const data = await fetch({ - query: checkoutCreateMutation, + const cart = await fetch({ + query: 'cart', + method: 'get', }) - const checkout = data.checkoutCreate?.checkout - const checkoutId = checkout?.id + // const checkout = data.checkoutCreate?.checkout + const checkoutId = cart?.id - if (checkoutId) { - const options = { - expires: SHOPIFY_COOKIE_EXPIRE, - } - Cookies.set(SHOPIFY_CHECKOUT_ID_COOKIE, checkoutId, options) - Cookies.set(SHOPIFY_CHECKOUT_URL_COOKIE, checkout?.webUrl, options) - } + // if (checkoutId) { + // const options = { + // expires: SHOPIFY_COOKIE_EXPIRE, + // } + // Cookies.set(SHOPIFY_CHECKOUT_ID_COOKIE, checkoutId, options) + // Cookies.set(SHOPIFY_CHECKOUT_URL_COOKIE, checkout?.webUrl, options) + // } - return checkout + return cart } export default checkoutCreate diff --git a/framework/swell/cart/utils/fetcher.ts b/framework/swell/cart/utils/fetcher.ts index 6afb55f18..2e7ae15d3 100644 --- a/framework/swell/cart/utils/fetcher.ts +++ b/framework/swell/cart/utils/fetcher.ts @@ -1,31 +1,33 @@ import { HookFetcherFn } from '@commerce/utils/types' import { Cart } from '@commerce/types' -import { checkoutCreate, checkoutToCart } from '.' +// import { checkoutCreate, checkoutToCart } from '.' import { FetchCartInput } from '@commerce/cart/use-cart' +import { data } from 'autoprefixer' +import { normalizeCart } from '../../utils' const fetcher: HookFetcherFn = async ({ options, - input: { cartId: checkoutId }, + // input: { cartId: checkoutId }, fetch, }) => { let checkout - if (checkoutId) { - const data = await fetch({ - ...options, - variables: { - checkoutId, - }, - }) - checkout = data.node - } + // if (checkoutId) { + const data = await fetch({ + query: 'cart', + method: 'get', + // variables: { category: categoryId }, + }) + // checkout = data.node + // } - if (checkout?.completedAt || !checkoutId) { - checkout = await checkoutCreate(fetch) - } + // if (checkout?.completedAt || !checkoutId) { + // checkout = await checkoutCreate(fetch) + // } // TODO: Fix this type - return checkoutToCart({ checkout } as any) + // return checkoutToCart({ checkout } as any) + return normalizeCart(data) } export default fetcher diff --git a/framework/swell/fetcher.ts b/framework/swell/fetcher.ts index e52d8fd54..4c65b91d2 100644 --- a/framework/swell/fetcher.ts +++ b/framework/swell/fetcher.ts @@ -8,9 +8,11 @@ const fetcher: Fetcher = async ({ method = 'get', variables, query }) => { if (Array.isArray(variables)) { const arg1 = variables[0] const arg2 = variables[1] + // console.log('fetcher', query, method, variables); const response = await swell[query][method](arg1, arg2) return handleFetchResponse(response) } else { + // console.log('fetcher', query, method, variables); const response = await swell[query][method](variables) return handleFetchResponse(response) } diff --git a/framework/swell/product/get-product.ts b/framework/swell/product/get-product.ts index cfac8e984..c06617221 100644 --- a/framework/swell/product/get-product.ts +++ b/framework/swell/product/get-product.ts @@ -18,11 +18,7 @@ const getProduct = async (options: { let { config, variables } = options ?? {} config = getConfig(config) - const { data }: GraphQLFetcherResult = await config.fetch(getProductQuery, { - variables, - }) - - const { productByHandle: product } = data + const product = await config.fetchSwell('products', 'get', variables.slug) return { product: product ? normalizeProduct(product) : null, diff --git a/framework/swell/product/use-search.tsx b/framework/swell/product/use-search.tsx index a00e39dc9..4e55da22a 100644 --- a/framework/swell/product/use-search.tsx +++ b/framework/swell/product/use-search.tsx @@ -32,8 +32,8 @@ export const handler: SWRHook< const { results, count: found } = await fetch({ query: 'products', - method: 'get', - // variables: { categoryId }, + method: 'list', + variables: { category: categoryId }, }) const products = results.map((product) => normalizeProduct(product)) diff --git a/framework/swell/utils/normalize.ts b/framework/swell/utils/normalize.ts index 6dbb6d708..bbb974c5e 100644 --- a/framework/swell/utils/normalize.ts +++ b/framework/swell/utils/normalize.ts @@ -47,31 +47,28 @@ const normalizeProductOption = ({ } const normalizeProductImages = (images) => - images?.map(({ file, ...rest }) => ({ + images?.map(({ file, id }) => ({ url: file.url, - ...rest, + id, })) -const normalizeProductVariants = ({ edges }: ProductVariantConnection) => { - return edges?.map( - ({ - node: { id, selectedOptions, sku, title, priceV2, compareAtPriceV2 }, - }) => ({ - id, - name: title, - sku: sku ?? id, - price: +priceV2.amount, - listPrice: +compareAtPriceV2?.amount, - requiresShipping: true, - options: selectedOptions.map(({ name, value }: SelectedOption) => - normalizeProductOption({ - id, - name, - values: [value], - }) - ), - }) - ) +const normalizeProductVariants = (variants) => { + // console.log('variant', variants); + return variants?.map(({ id, name, values, price, stock_status }) => ({ + id, + name, + sku: sku ?? id, + price, + listPrice: price, + // requiresShipping: true, + options: values.map(({ name, value }: SelectedOption) => + normalizeProductOption({ + id, + name, + values: [value], + }) + ), + })) } export function normalizeProduct(productNode: SwellProduct): Product { @@ -91,13 +88,13 @@ export function normalizeProduct(productNode: SwellProduct): Product { const product = { id, name, - vendor, + vendor: 'our brands', description, path: `/${slug}`, slug, price, images: normalizeProductImages(images), - variants: variants ? normalizeProductVariants(variants) : [], + variants: [], //variants ? normalizeProductVariants(options) : [], options: options ? options.map((o) => normalizeProductOption(o)) : [], ...rest, } @@ -105,21 +102,19 @@ export function normalizeProduct(productNode: SwellProduct): Product { return product } -export function normalizeCart(checkout: Checkout): Cart { +export function normalizeCart(cart: Checkout): Cart { return { - id: checkout.id, - customerId: '', + id: cart.id, + customerId: cart.account_id, email: '', - createdAt: checkout.createdAt, - currency: { - code: checkout.totalPriceV2?.currencyCode, - }, - taxesIncluded: checkout.taxesIncluded, - lineItems: checkout.lineItems?.edges.map(normalizeLineItem), - lineItemsSubtotalPrice: +checkout.subtotalPriceV2?.amount, - subtotalPrice: +checkout.subtotalPriceV2?.amount, - totalPrice: checkout.totalPriceV2?.amount, - discounts: [], + createdAt: cart.date_created, + currency: cart.currency, + taxesIncluded: cart.tax_included_total, + lineItems: cart.items?.map(normalizeLineItem), + lineItemsSubtotalPrice: +cart.sub_total, + subtotalPrice: +cart.sub_total, + totalPrice: cart.grand_total, + discounts: cart.discounts, } } @@ -133,30 +128,34 @@ export function normalizeCustomer(customer: SwellCustomer): Customer { } function normalizeLineItem({ - node: { id, title, variant, quantity }, + id, + product, + price, + variant, + quantity, }: CheckoutLineItemEdge): LineItem { return { id, variantId: String(variant?.id), - productId: String(variant?.id), - name: `${title}`, + productId: String(product?.id), + name: product.name, quantity, variant: { id: String(variant?.id), sku: variant?.sku ?? '', - name: variant?.title!, + name: variant?.name!, image: { - url: variant?.image?.originalSrc, + url: product?.images[0].file.url, }, - requiresShipping: variant?.requiresShipping ?? false, - price: variant?.priceV2?.amount, - listPrice: variant?.compareAtPriceV2?.amount, + requiresShipping: false, + price: price, + listPrice: price, }, path: '', discounts: [], options: [ { - value: variant?.title, + value: variant?.name, }, ], } From d0a04a8fe957fbd29d8fde84f3d826c8d0d82a04 Mon Sep 17 00:00:00 2001 From: Greg Hoskin Date: Sun, 4 Apr 2021 16:16:27 -0600 Subject: [PATCH 193/216] enable add and remove items (update) from cart. Update Search --- framework/swell/cart/use-add-item.tsx | 6 +--- framework/swell/cart/use-cart.tsx | 4 +-- framework/swell/cart/use-update-item.tsx | 36 ++++++++----------- .../swell/cart/utils/checkout-to-cart.ts | 19 ++-------- framework/swell/product/use-search.tsx | 5 ++- framework/swell/types.ts | 20 +++++++++++ framework/swell/utils/normalize.ts | 1 - 7 files changed, 41 insertions(+), 50 deletions(-) diff --git a/framework/swell/cart/use-add-item.tsx b/framework/swell/cart/use-add-item.tsx index d0f891148..34bdb3df8 100644 --- a/framework/swell/cart/use-add-item.tsx +++ b/framework/swell/cart/use-add-item.tsx @@ -23,11 +23,7 @@ export const handler: MutationHook = { message: 'The item quantity has to be a valid integer greater than 0', }) } - - const { checkoutLineItemsAdd } = await fetch< - Mutation, - MutationCheckoutLineItemsAddArgs - >({ + const response = await fetch({ ...options, variables: { checkoutId: getCheckoutId(), diff --git a/framework/swell/cart/use-cart.tsx b/framework/swell/cart/use-cart.tsx index c9589f484..183a9ad6d 100644 --- a/framework/swell/cart/use-cart.tsx +++ b/framework/swell/cart/use-cart.tsx @@ -1,12 +1,12 @@ import useCart, { UseCart } from '@commerce/cart/use-cart' -import { Customer } from '@commerce/types' +import { Cart } from '@commerce/types' import { SWRHook } from '@commerce/utils/types' import { normalizeCart } from '../utils/normalize' // import { getCustomerQuery, getCustomerToken } from '../utils' export default useCart as UseCart -export const handler: SWRHook = { +export const handler: SWRHook = { fetchOptions: { query: 'cart', method: 'get', diff --git a/framework/swell/cart/use-update-item.tsx b/framework/swell/cart/use-update-item.tsx index 666ce3d08..3155778c6 100644 --- a/framework/swell/cart/use-update-item.tsx +++ b/framework/swell/cart/use-update-item.tsx @@ -14,7 +14,6 @@ import useCart from './use-cart' import { handler as removeItemHandler } from './use-remove-item' import type { Cart, LineItem, UpdateCartItemBody } from '../types' import { checkoutToCart } from './utils' -import { getCheckoutId, checkoutLineItemUpdateMutation } from '../utils' import { Mutation, MutationCheckoutLineItemsUpdateArgs } from '../schema' export type UpdateItemInput = T extends LineItem @@ -25,7 +24,8 @@ export default useUpdateItem as UseUpdateItem export const handler = { fetchOptions: { - query: checkoutLineItemUpdateMutation, + query: 'cart', + method: 'updateItem', }, async fetcher({ input: { itemId, item }, @@ -46,23 +46,14 @@ export const handler = { message: 'The item quantity has to be a valid integer', }) } - const { checkoutLineItemsUpdate } = await fetch< - Mutation, - MutationCheckoutLineItemsUpdateArgs - >({ - ...options, - variables: { - checkoutId: getCheckoutId(), - lineItems: [ - { - id: itemId, - quantity: item.quantity, - }, - ], - }, - }) + const response = await fetch( + { + ...options, + variables: [item.itemId, { quantity: item.quantity }], + } + ) - return checkoutToCart(checkoutLineItemsUpdate) + return checkoutToCart(response) }, useHook: ({ fetch, @@ -75,13 +66,13 @@ export const handler = { } = {} ) => { const { item } = ctx - const { mutate } = useCart() as any + const { mutate, data: cartData } = useCart() as any return useCallback( debounce(async (input: UpdateItemInput) => { - const itemId = input.id ?? item?.id - const productId = input.productId ?? item?.productId - const variantId = input.productId ?? item?.variantId + const itemId = cartData.lineItems[0].id + const productId = cartData.lineItems[0].productId + const variantId = cartData.lineItems[0].variant.id if (!itemId || !productId || !variantId) { throw new ValidationError({ message: 'Invalid input used for this operation', @@ -91,6 +82,7 @@ export const handler = { const data = await fetch({ input: { item: { + itemId, productId, variantId, quantity: input.quantity, diff --git a/framework/swell/cart/utils/checkout-to-cart.ts b/framework/swell/cart/utils/checkout-to-cart.ts index 03005f342..19a8bfd0b 100644 --- a/framework/swell/cart/utils/checkout-to-cart.ts +++ b/framework/swell/cart/utils/checkout-to-cart.ts @@ -17,26 +17,11 @@ export type CheckoutPayload = const checkoutToCart = (checkoutPayload?: Maybe): Cart => { if (!checkoutPayload) { throw new CommerceError({ - message: 'Invalid response from Shopify', + message: 'Invalid response from Swell', }) } - const checkout = checkoutPayload?.checkout - const userErrors = checkoutPayload?.userErrors - - if (userErrors && userErrors.length) { - throw new ValidationError({ - message: userErrors[0].message, - }) - } - - if (!checkout) { - throw new CommerceError({ - message: 'Invalid response from Shopify', - }) - } - - return normalizeCart(checkout) + return normalizeCart(checkoutPayload) } export default checkoutToCart diff --git a/framework/swell/product/use-search.tsx b/framework/swell/product/use-search.tsx index 4e55da22a..204c65352 100644 --- a/framework/swell/product/use-search.tsx +++ b/framework/swell/product/use-search.tsx @@ -28,12 +28,11 @@ export const handler: SWRHook< query: getAllProductsQuery, }, async fetcher({ input, options, fetch }) { - const { categoryId, brandId } = input - + const { categoryId, search } = input const { results, count: found } = await fetch({ query: 'products', method: 'list', - variables: { category: categoryId }, + variables: { category: categoryId, search }, }) const products = results.map((product) => normalizeProduct(product)) diff --git a/framework/swell/types.ts b/framework/swell/types.ts index 2878295e1..0d1e85657 100644 --- a/framework/swell/types.ts +++ b/framework/swell/types.ts @@ -1,6 +1,26 @@ import * as Core from '@commerce/types' import { CheckoutLineItem } from './schema' +export type SwellCart = { + id: string + account_id: number + currency: string + tax_included_total: number + sub_total: number + discount_total: number + quantity: number + items: { + id: string + product: object + price: number + variant: boolean + quantity: number + } + date_created: string + discounts?: { id: number; amount: number }[] + // TODO: add missing fields +} + export interface SwellProduct extends Core.Product { name: string slug: string diff --git a/framework/swell/utils/normalize.ts b/framework/swell/utils/normalize.ts index bbb974c5e..2707489a6 100644 --- a/framework/swell/utils/normalize.ts +++ b/framework/swell/utils/normalize.ts @@ -53,7 +53,6 @@ const normalizeProductImages = (images) => })) const normalizeProductVariants = (variants) => { - // console.log('variant', variants); return variants?.map(({ id, name, values, price, stock_status }) => ({ id, name, From abd86329d5c862cc1467544d99b60fe1503a8dc4 Mon Sep 17 00:00:00 2001 From: Greg Hoskin Date: Sun, 4 Apr 2021 18:07:14 -0600 Subject: [PATCH 194/216] update remove item from cart, landing page fetch, image normalization --- framework/swell/cart/use-remove-item.tsx | 19 ++++++++++-------- framework/swell/product/get-all-products.ts | 5 +++-- framework/swell/utils/normalize.ts | 22 +++++++++++++++++---- 3 files changed, 32 insertions(+), 14 deletions(-) diff --git a/framework/swell/cart/use-remove-item.tsx b/framework/swell/cart/use-remove-item.tsx index e2aef13d8..13d137da4 100644 --- a/framework/swell/cart/use-remove-item.tsx +++ b/framework/swell/cart/use-remove-item.tsx @@ -31,27 +31,30 @@ export default useRemoveItem as UseRemoveItem export const handler = { fetchOptions: { - query: checkoutLineItemRemoveMutation, + query: 'cart', + method: 'removeItem', }, async fetcher({ input: { itemId }, options, fetch, }: HookFetcherContext) { - const data = await fetch({ - ...options, - variables: { checkoutId: getCheckoutId(), lineItemIds: [itemId] }, - }) - return checkoutToCart(data.checkoutLineItemsRemove) + const response = await fetch( + { + ...options, + variables: [itemId], + } + ) + return checkoutToCart(response) }, useHook: ({ fetch, }: MutationHookContext) => < T extends LineItem | undefined = undefined >( - ctx: { item?: T } = {} + item ) => { - const { item } = ctx + // const { item } = ctx const { mutate } = useCart() const removeItem: RemoveItemFn = async (input) => { const itemId = input?.id ?? item?.id diff --git a/framework/swell/product/get-all-products.ts b/framework/swell/product/get-all-products.ts index 8ca85eecd..5150af993 100644 --- a/framework/swell/product/get-all-products.ts +++ b/framework/swell/product/get-all-products.ts @@ -21,9 +21,10 @@ const getAllProducts = async (options: { }): Promise => { let { config, variables = { first: 250 } } = options ?? {} config = getConfig(config) - const { results } = await config.fetchSwell('products', 'get') + const { results } = await config.fetchSwell('products', 'list', { + limit: variables.first, + }) const products = results.map((product) => normalizeProduct(product)) ?? [] - return { products, } diff --git a/framework/swell/utils/normalize.ts b/framework/swell/utils/normalize.ts index 2707489a6..5a95d94dc 100644 --- a/framework/swell/utils/normalize.ts +++ b/framework/swell/utils/normalize.ts @@ -46,11 +46,25 @@ const normalizeProductOption = ({ } } -const normalizeProductImages = (images) => - images?.map(({ file, id }) => ({ - url: file.url, - id, +type SwellImage = { + file: { + url: String + height: Number + width: Number + } + id: string +} +const normalizeProductImages = (images) => { + if (!images) { + return [{ url: '/' }] + } + return images?.map(({ file, ...rest }: SwellImage) => ({ + url: file?.url, + height: file.height, + width: file.width, + ...rest, })) +} const normalizeProductVariants = (variants) => { return variants?.map(({ id, name, values, price, stock_status }) => ({ From 644f196c972cb7da4e732e32e3e53414c2feaeb1 Mon Sep 17 00:00:00 2001 From: Greg Hoskin Date: Fri, 9 Apr 2021 16:51:35 -0600 Subject: [PATCH 195/216] update get-page and get-all-pages content hooks --- framework/swell/api/utils/fetch-swell-api.ts | 5 ++--- framework/swell/common/get-all-pages.ts | 16 ++++++---------- framework/swell/common/get-page.ts | 11 ++++------- framework/swell/product/get-all-products.ts | 8 +++++--- framework/swell/product/get-product.ts | 2 +- 5 files changed, 18 insertions(+), 24 deletions(-) diff --git a/framework/swell/api/utils/fetch-swell-api.ts b/framework/swell/api/utils/fetch-swell-api.ts index 805aa46e8..c8707230d 100644 --- a/framework/swell/api/utils/fetch-swell-api.ts +++ b/framework/swell/api/utils/fetch-swell-api.ts @@ -3,11 +3,10 @@ import { swellConfig } from '../../index' const fetchSwellApi = async ( query: string, method: string, - variables: object | string + variables: [] = [] ) => { const { swell } = swellConfig - const res = await swell[query][method](variables) - return res + return await swell[query][method](...variables) } export default fetchSwellApi diff --git a/framework/swell/common/get-all-pages.ts b/framework/swell/common/get-all-pages.ts index a092823ca..1088a472c 100644 --- a/framework/swell/common/get-all-pages.ts +++ b/framework/swell/common/get-all-pages.ts @@ -25,16 +25,12 @@ const getAllPages = async (options?: { }): Promise => { let { config, variables = { first: 250 } } = options ?? {} config = getConfig(config) - const { locale } = config - const { data } = await config.fetch(getAllPagesQuery, { variables }) - - const pages = data.pages?.edges?.map( - ({ node: { title: name, handle, ...node } }: PageEdge) => ({ - ...node, - url: `/${locale}/${handle}`, - name, - }) - ) + const { locale, fetchSwell } = config + const { results } = await fetchSwell('content', 'list', ['pages']) + const pages = results.map(({ slug, ...rest }) => ({ + url: `/${locale}/${slug}`, + ...rest, + })) return { pages } } diff --git a/framework/swell/common/get-page.ts b/framework/swell/common/get-page.ts index ae7c0370b..40e9f6982 100644 --- a/framework/swell/common/get-page.ts +++ b/framework/swell/common/get-page.ts @@ -17,18 +17,15 @@ const getPage = async (options: { config = getConfig(config) const { locale } = config - - const { data } = await config.fetch(getPageQuery, { - variables, - }) - const page = data.node + const { id } = variables + const result = await config.fetchSwell('content', 'get', ['pages', id]) + const page = result return { page: page ? { ...page, - name: page.title, - url: `/${locale}/${page.handle}`, + url: `/${locale}/${page.slug}`, } : null, } diff --git a/framework/swell/product/get-all-products.ts b/framework/swell/product/get-all-products.ts index 5150af993..e212a2494 100644 --- a/framework/swell/product/get-all-products.ts +++ b/framework/swell/product/get-all-products.ts @@ -21,9 +21,11 @@ const getAllProducts = async (options: { }): Promise => { let { config, variables = { first: 250 } } = options ?? {} config = getConfig(config) - const { results } = await config.fetchSwell('products', 'list', { - limit: variables.first, - }) + const { results } = await config.fetchSwell('products', 'list', [ + { + limit: variables.first, + }, + ]) const products = results.map((product) => normalizeProduct(product)) ?? [] return { products, diff --git a/framework/swell/product/get-product.ts b/framework/swell/product/get-product.ts index c06617221..a95610a10 100644 --- a/framework/swell/product/get-product.ts +++ b/framework/swell/product/get-product.ts @@ -18,7 +18,7 @@ const getProduct = async (options: { let { config, variables } = options ?? {} config = getConfig(config) - const product = await config.fetchSwell('products', 'get', variables.slug) + const product = await config.fetchSwell('products', 'get', [variables.slug]) return { product: product ? normalizeProduct(product) : null, From 7e0d126531e843c5724ec8e9c639dbea95cf4730 Mon Sep 17 00:00:00 2001 From: Greg Hoskin Date: Sun, 11 Apr 2021 16:53:57 -0500 Subject: [PATCH 196/216] update product normalization --- framework/swell/utils/normalize.ts | 72 +++++++++++++----------------- 1 file changed, 32 insertions(+), 40 deletions(-) diff --git a/framework/swell/utils/normalize.ts b/framework/swell/utils/normalize.ts index 5a95d94dc..d50cdbb91 100644 --- a/framework/swell/utils/normalize.ts +++ b/framework/swell/utils/normalize.ts @@ -27,22 +27,24 @@ const normalizeProductOption = ({ name: displayName, values, }: ProductOption) => { + let returnValues = values.map((value) => { + let output: any = { + label: value.name, + } + if (displayName === 'Color') { + output = { + ...output, + hexColors: [value.name], + } + } + return output + }) + return { __typename: 'MultipleChoiceOption', id, displayName, - values: values.map((value) => { - let output: any = { - label: value.name, - } - if (displayName === 'Color') { - output = { - ...output, - hexColors: [value], - } - } - return output - }), + values: returnValues, } } @@ -60,56 +62,46 @@ const normalizeProductImages = (images) => { } return images?.map(({ file, ...rest }: SwellImage) => ({ url: file?.url, - height: file.height, - width: file.width, + height: file?.height, + width: file?.width, ...rest, })) } const normalizeProductVariants = (variants) => { - return variants?.map(({ id, name, values, price, stock_status }) => ({ + return variants?.map(({ id, name, values, price, sku }) => ({ id, name, sku: sku ?? id, - price, - listPrice: price, + price: price ?? null, + listPrice: price ?? null, // requiresShipping: true, options: values.map(({ name, value }: SelectedOption) => normalizeProductOption({ id, name, - values: [value], + values: value ? [value] : [], }) ), })) } export function normalizeProduct(productNode: SwellProduct): Product { - const { - id, - name, - vendor, - images, - variants, - description, - slug, - price, - options, - ...rest - } = productNode + const { images, options, slug, price } = productNode + + const productOptions = options.map((o) => normalizeProductOption(o)) + const productVariants = normalizeProductVariants( + options.filter((option) => option.variant) + ) + const productImages = normalizeProductImages(images) const product = { - id, - name, + ...productNode, vendor: 'our brands', - description, path: `/${slug}`, - slug, - price, - images: normalizeProductImages(images), - variants: [], //variants ? normalizeProductVariants(options) : [], - options: options ? options.map((o) => normalizeProductOption(o)) : [], - ...rest, + images: productImages ?? [], + variants: productVariants, + options: productOptions, } return product @@ -158,7 +150,7 @@ function normalizeLineItem({ sku: variant?.sku ?? '', name: variant?.name!, image: { - url: product?.images[0].file.url, + url: product.images ? product?.images[0].file.url : '', }, requiresShipping: false, price: price, From d489f59171d6561dfe63de7384bc03092f8d84b0 Mon Sep 17 00:00:00 2001 From: Greg Hoskin Date: Sat, 17 Apr 2021 19:01:46 -0500 Subject: [PATCH 197/216] update add item to cart hook --- framework/swell/cart/use-add-item.tsx | 15 +++----- framework/swell/utils/normalize.ts | 52 ++++++++++++++++----------- 2 files changed, 37 insertions(+), 30 deletions(-) diff --git a/framework/swell/cart/use-add-item.tsx b/framework/swell/cart/use-add-item.tsx index 34bdb3df8..ff6c7143f 100644 --- a/framework/swell/cart/use-add-item.tsx +++ b/framework/swell/cart/use-add-item.tsx @@ -3,7 +3,6 @@ import { CommerceError } from '@commerce/utils/errors' import useAddItem, { UseAddItem } from '@commerce/cart/use-add-item' import useCart from './use-cart' import { Cart, CartItemBody } from '../types' -import { checkoutLineItemAddMutation, getCheckoutId } from '../utils' import { checkoutToCart } from './utils' import { Mutation, MutationCheckoutLineItemsAddArgs } from '../schema' import { useCallback } from 'react' @@ -12,7 +11,8 @@ export default useAddItem as UseAddItem export const handler: MutationHook = { fetchOptions: { - query: checkoutLineItemAddMutation, + query: 'cart', + method: 'addItem', }, async fetcher({ input: item, options, fetch }) { if ( @@ -26,18 +26,13 @@ export const handler: MutationHook = { const response = await fetch({ ...options, variables: { - checkoutId: getCheckoutId(), - lineItems: [ - { - variantId: item.variantId, - quantity: item.quantity ?? 1, - }, - ], + product_id: item.productId, + quantity: item.quantity, }, }) // TODO: Fix this Cart type here - return checkoutToCart(checkoutLineItemsAdd) as any + return checkoutToCart(response) as any }, useHook: ({ fetch }) => () => { const { mutate } = useCart() diff --git a/framework/swell/utils/normalize.ts b/framework/swell/utils/normalize.ts index d50cdbb91..f40a7d8ec 100644 --- a/framework/swell/utils/normalize.ts +++ b/framework/swell/utils/normalize.ts @@ -29,6 +29,7 @@ const normalizeProductOption = ({ }: ProductOption) => { let returnValues = values.map((value) => { let output: any = { + displayName, label: value.name, } if (displayName === 'Color') { @@ -39,7 +40,6 @@ const normalizeProductOption = ({ } return output }) - return { __typename: 'MultipleChoiceOption', id, @@ -69,38 +69,49 @@ const normalizeProductImages = (images) => { } const normalizeProductVariants = (variants) => { - return variants?.map(({ id, name, values, price, sku }) => ({ - id, - name, - sku: sku ?? id, - price: price ?? null, - listPrice: price ?? null, - // requiresShipping: true, - options: values.map(({ name, value }: SelectedOption) => - normalizeProductOption({ + return variants?.map(({ id, name, values, price, sku }) => { + const options = values.map((option: SelectedOption) => { + return normalizeProductOption({ id, name, - values: value ? [value] : [], + values: option ? [option] : [], }) - ), - })) + }) + + return { + id, + name, + sku: sku ?? id, + price: price ?? null, + listPrice: price ?? null, + // requiresShipping: true, + options, + } + }) } export function normalizeProduct(productNode: SwellProduct): Product { const { images, options, slug, price } = productNode - - const productOptions = options.map((o) => normalizeProductOption(o)) + const productOptions = options + ? options.map((o) => normalizeProductOption(o)) + : [] const productVariants = normalizeProductVariants( options.filter((option) => option.variant) ) + + // ProductView.tsx assumes the existence of at least one product variant + const emptyVariants = [{ options: [{ id: 123 }] }] const productImages = normalizeProductImages(images) const product = { ...productNode, vendor: 'our brands', path: `/${slug}`, - images: productImages ?? [], - variants: productVariants, + images: productImages, + variants: + productVariants && productVariants.length + ? productVariants + : emptyVariants, options: productOptions, } @@ -139,18 +150,18 @@ function normalizeLineItem({ variant, quantity, }: CheckoutLineItemEdge): LineItem { - return { + const item = { id, variantId: String(variant?.id), productId: String(product?.id), - name: product.name, + name: product?.name ?? '', quantity, variant: { id: String(variant?.id), sku: variant?.sku ?? '', name: variant?.name!, image: { - url: product.images ? product?.images[0].file.url : '', + url: product && product.images ? product?.images[0].file.url : '', }, requiresShipping: false, price: price, @@ -164,4 +175,5 @@ function normalizeLineItem({ }, ], } + return item } From 79ed72a7102f5bb93f3374a8281796f3e8003b96 Mon Sep 17 00:00:00 2001 From: Greg Hoskin Date: Sun, 18 Apr 2021 19:33:23 -0500 Subject: [PATCH 198/216] update product normalization --- framework/swell/product/get-all-products.ts | 7 +++- framework/swell/product/get-product.ts | 7 ++-- framework/swell/product/use-search.tsx | 7 +++- framework/swell/types.ts | 14 +++++++- framework/swell/utils/normalize.ts | 39 ++++++++++++++------- 5 files changed, 57 insertions(+), 17 deletions(-) diff --git a/framework/swell/product/get-all-products.ts b/framework/swell/product/get-all-products.ts index e212a2494..1f4f4152c 100644 --- a/framework/swell/product/get-all-products.ts +++ b/framework/swell/product/get-all-products.ts @@ -26,7 +26,12 @@ const getAllProducts = async (options: { limit: variables.first, }, ]) - const products = results.map((product) => normalizeProduct(product)) ?? [] + const products = results.map((product) => { + if (product.variants) { + product.variants = product.variants.results + } + return normalizeProduct(product) ?? [] + }) return { products, } diff --git a/framework/swell/product/get-product.ts b/framework/swell/product/get-product.ts index a95610a10..49bc5b67f 100644 --- a/framework/swell/product/get-product.ts +++ b/framework/swell/product/get-product.ts @@ -19,9 +19,12 @@ const getProduct = async (options: { config = getConfig(config) const product = await config.fetchSwell('products', 'get', [variables.slug]) - + if (product.variants) { + product.variants = product.variants?.results + } + // console.log('product', product) return { - product: product ? normalizeProduct(product) : null, + product: normalizeProduct(product), } } diff --git a/framework/swell/product/use-search.tsx b/framework/swell/product/use-search.tsx index 204c65352..14b966319 100644 --- a/framework/swell/product/use-search.tsx +++ b/framework/swell/product/use-search.tsx @@ -35,7 +35,12 @@ export const handler: SWRHook< variables: { category: categoryId, search }, }) - const products = results.map((product) => normalizeProduct(product)) + const products = results.map((product) => { + if (product.variants) { + product.variants = product.variants?.results + } + return normalizeProduct(product) + }) return { products, diff --git a/framework/swell/types.ts b/framework/swell/types.ts index 0d1e85657..456b3da05 100644 --- a/framework/swell/types.ts +++ b/framework/swell/types.ts @@ -21,9 +21,21 @@ export type SwellCart = { // TODO: add missing fields } -export interface SwellProduct extends Core.Product { +export type VariantResult = { + id: string + option_value_ids: string[] +} + +export interface SwellProduct { + id: string + description: string name: string slug: string + currency: string + price: number + images: any[] + options: any[] + variants: any[] } export interface SwellCustomer extends Core.Customer { diff --git a/framework/swell/utils/normalize.ts b/framework/swell/utils/normalize.ts index f40a7d8ec..ea12acbae 100644 --- a/framework/swell/utils/normalize.ts +++ b/framework/swell/utils/normalize.ts @@ -69,12 +69,16 @@ const normalizeProductImages = (images) => { } const normalizeProductVariants = (variants) => { - return variants?.map(({ id, name, values, price, sku }) => { - const options = values.map((option: SelectedOption) => { + return variants?.map(({ id, name, price, sku }) => { + const values = name + .split(',') + .map((i) => ({ name: i.trim(), label: i.trim() })) + + const options = values.map((value) => { return normalizeProductOption({ id, name, - values: option ? [option] : [], + values: [value], }) }) @@ -90,22 +94,30 @@ const normalizeProductVariants = (variants) => { }) } -export function normalizeProduct(productNode: SwellProduct): Product { - const { images, options, slug, price } = productNode +export function normalizeProduct(swellProduct: SwellProduct): Product { + const { + id, + description, + images, + options, + slug, + variants, + price: value, + currency: currencyCode, + } = swellProduct const productOptions = options ? options.map((o) => normalizeProductOption(o)) : [] - const productVariants = normalizeProductVariants( - options.filter((option) => option.variant) - ) + const productVariants = variants ? normalizeProductVariants(variants) : [] // ProductView.tsx assumes the existence of at least one product variant const emptyVariants = [{ options: [{ id: 123 }] }] const productImages = normalizeProductImages(images) - const product = { - ...productNode, - vendor: 'our brands', + ...swellProduct, + description, + id, + vendor: '', path: `/${slug}`, images: productImages, variants: @@ -113,8 +125,11 @@ export function normalizeProduct(productNode: SwellProduct): Product { ? productVariants : emptyVariants, options: productOptions, + price: { + value, + currencyCode, + }, } - return product } From 8a8ef7dbba8a4aa53475379aaa01f30960ac0ca4 Mon Sep 17 00:00:00 2001 From: Greg Hoskin Date: Mon, 19 Apr 2021 20:37:33 -0500 Subject: [PATCH 199/216] setup swell checkout --- framework/swell/api/checkout/index.ts | 28 ++----------------- framework/swell/cart/use-cart.tsx | 10 +++---- framework/swell/cart/utils/checkout-create.ts | 20 ++++--------- framework/swell/const.ts | 2 +- framework/swell/provider.ts | 4 +-- next.config.js | 3 +- 6 files changed, 17 insertions(+), 50 deletions(-) diff --git a/framework/swell/api/checkout/index.ts b/framework/swell/api/checkout/index.ts index 244078466..03f166a1a 100644 --- a/framework/swell/api/checkout/index.ts +++ b/framework/swell/api/checkout/index.ts @@ -1,40 +1,16 @@ -import isAllowedMethod from '../utils/is-allowed-method' import createApiHandler, { ShopifyApiHandler, } from '../utils/create-api-handler' -import { - SHOPIFY_CHECKOUT_ID_COOKIE, - SHOPIFY_CHECKOUT_URL_COOKIE, - SHOPIFY_CUSTOMER_TOKEN_COOKIE, -} from '../../const' +import { SWELL_CHECKOUT_URL_COOKIE } from '../../const' import { getConfig } from '..' -import associateCustomerWithCheckoutMutation from '../../utils/mutations/associate-customer-with-checkout' - -const METHODS = ['GET'] const checkoutApi: ShopifyApiHandler = async (req, res, config) => { - if (!isAllowedMethod(req, res, METHODS)) return - config = getConfig() const { cookies } = req - const checkoutUrl = cookies[SHOPIFY_CHECKOUT_URL_COOKIE] - const customerCookie = cookies[SHOPIFY_CUSTOMER_TOKEN_COOKIE] - - if (customerCookie) { - try { - await config.fetch(associateCustomerWithCheckoutMutation, { - variables: { - checkoutId: cookies[SHOPIFY_CHECKOUT_ID_COOKIE], - customerAccessToken: cookies[SHOPIFY_CUSTOMER_TOKEN_COOKIE], - }, - }) - } catch (error) { - console.error(error) - } - } + const checkoutUrl = cookies[SWELL_CHECKOUT_URL_COOKIE] if (checkoutUrl) { res.redirect(checkoutUrl) diff --git a/framework/swell/cart/use-cart.tsx b/framework/swell/cart/use-cart.tsx index 183a9ad6d..04d07914d 100644 --- a/framework/swell/cart/use-cart.tsx +++ b/framework/swell/cart/use-cart.tsx @@ -2,7 +2,7 @@ import useCart, { UseCart } from '@commerce/cart/use-cart' import { Cart } from '@commerce/types' import { SWRHook } from '@commerce/utils/types' import { normalizeCart } from '../utils/normalize' -// import { getCustomerQuery, getCustomerToken } from '../utils' +import { checkoutCreate, checkoutToCart } from './utils' export default useCart as UseCart @@ -12,10 +12,10 @@ export const handler: SWRHook = { method: 'get', }, async fetcher({ options, fetch }) { - const data = await fetch({ - ...options, - }) - return data ? normalizeCart(data) : null + const cart = await checkoutCreate(fetch) + + return cart ? normalizeCart(cart) : null + // return checkoutToCart({ checkout } as any) }, useHook: ({ useData }) => (input) => { return useData({ diff --git a/framework/swell/cart/utils/checkout-create.ts b/framework/swell/cart/utils/checkout-create.ts index 73109baad..cc08007f4 100644 --- a/framework/swell/cart/utils/checkout-create.ts +++ b/framework/swell/cart/utils/checkout-create.ts @@ -1,10 +1,5 @@ -import { - SHOPIFY_CHECKOUT_ID_COOKIE, - SHOPIFY_CHECKOUT_URL_COOKIE, - SHOPIFY_COOKIE_EXPIRE, -} from '../../const' +import { SWELL_CHECKOUT_URL_COOKIE } from '../../const' -// import checkoutCreateMutation from '../../utils/mutations/checkout-create' import Cookies from 'js-cookie' export const checkoutCreate = async (fetch: any) => { @@ -13,16 +8,11 @@ export const checkoutCreate = async (fetch: any) => { method: 'get', }) - // const checkout = data.checkoutCreate?.checkout - const checkoutId = cart?.id + const checkoutUrl = cart?.checkout_url - // if (checkoutId) { - // const options = { - // expires: SHOPIFY_COOKIE_EXPIRE, - // } - // Cookies.set(SHOPIFY_CHECKOUT_ID_COOKIE, checkoutId, options) - // Cookies.set(SHOPIFY_CHECKOUT_URL_COOKIE, checkout?.webUrl, options) - // } + if (checkoutUrl) { + Cookies.set(SWELL_CHECKOUT_URL_COOKIE, checkoutUrl) + } return cart } diff --git a/framework/swell/const.ts b/framework/swell/const.ts index f2b0d5396..7226b19cb 100644 --- a/framework/swell/const.ts +++ b/framework/swell/const.ts @@ -1,6 +1,6 @@ export const SHOPIFY_CHECKOUT_ID_COOKIE = 'shopify_checkoutId' -export const SHOPIFY_CHECKOUT_URL_COOKIE = 'shopify_checkoutUrl' +export const SWELL_CHECKOUT_URL_COOKIE = 'swell_checkoutUrl' export const SHOPIFY_CUSTOMER_TOKEN_COOKIE = 'shopify_customerToken' diff --git a/framework/swell/provider.ts b/framework/swell/provider.ts index f8a4ac1d6..0bcbd7888 100644 --- a/framework/swell/provider.ts +++ b/framework/swell/provider.ts @@ -1,4 +1,4 @@ -import { SHOPIFY_CHECKOUT_ID_COOKIE, STORE_DOMAIN } from './const' +import { SWELL_CHECKOUT_URL_COOKIE, STORE_DOMAIN } from './const' import { handler as useCart } from './cart/use-cart' import { handler as useAddItem } from './cart/use-add-item' @@ -16,7 +16,7 @@ import fetcher from './fetcher' export const swellProvider = { locale: 'en-us', - cartCookie: SHOPIFY_CHECKOUT_ID_COOKIE, + cartCookie: SWELL_CHECKOUT_URL_COOKIE, storeDomain: STORE_DOMAIN, fetcher, cart: { useCart, useAddItem, useUpdateItem, useRemoveItem }, diff --git a/next.config.js b/next.config.js index 7e86695a0..3569eff26 100644 --- a/next.config.js +++ b/next.config.js @@ -3,6 +3,7 @@ const withCommerceConfig = require('./framework/commerce/with-config') const isBC = commerce.provider === 'bigcommerce' const isShopify = commerce.provider === 'shopify' +const isSwell = commerce.provider === 'swell' module.exports = withCommerceConfig({ commerce, @@ -12,7 +13,7 @@ module.exports = withCommerceConfig({ }, rewrites() { return [ - (isBC || isShopify) && { + (isBC || isShopify || isSwell) && { source: '/checkout', destination: '/api/bigcommerce/checkout', }, From dd40b8c60465a202605f370bddc6396c86906118 Mon Sep 17 00:00:00 2001 From: Greg Hoskin Date: Wed, 21 Apr 2021 19:56:00 -0500 Subject: [PATCH 200/216] Match product options with variants --- framework/swell/common/get-page.ts | 1 - framework/swell/schema.d.ts | 197 ++++++++++++++++------------- framework/swell/types.ts | 30 ++++- framework/swell/utils/normalize.ts | 111 ++++++++-------- 4 files changed, 196 insertions(+), 143 deletions(-) diff --git a/framework/swell/common/get-page.ts b/framework/swell/common/get-page.ts index 40e9f6982..e5ca005e0 100644 --- a/framework/swell/common/get-page.ts +++ b/framework/swell/common/get-page.ts @@ -1,5 +1,4 @@ import { getConfig, SwellConfig } from '../api' -import getPageQuery from '../utils/queries/get-page-query' import { Page } from './get-all-pages' type Variables = { diff --git a/framework/swell/schema.d.ts b/framework/swell/schema.d.ts index 8ffa23f73..c5309310d 100644 --- a/framework/swell/schema.d.ts +++ b/framework/swell/schema.d.ts @@ -321,96 +321,113 @@ export enum CardBrand { } /** A container for all the information required to checkout items and pay. */ -export type Checkout = Node & { - __typename?: 'Checkout' - /** The gift cards used on the checkout. */ - appliedGiftCards: Array - /** - * The available shipping rates for this Checkout. - * Should only be used when checkout `requiresShipping` is `true` and - * the shipping address is valid. - */ - availableShippingRates?: Maybe - /** The date and time when the checkout was completed. */ - completedAt?: Maybe - /** The date and time when the checkout was created. */ - createdAt: Scalars['DateTime'] - /** The currency code for the Checkout. */ - currencyCode: CurrencyCode - /** A list of extra information that is added to the checkout. */ - customAttributes: Array - /** - * The customer associated with the checkout. - * @deprecated This field will always return null. If you have an authentication token for the customer, you can use the `customer` field on the query root to retrieve it. - */ - customer?: Maybe - /** Discounts that have been applied on the checkout. */ - discountApplications: DiscountApplicationConnection - /** The email attached to this checkout. */ - email?: Maybe - /** Globally unique identifier. */ - id: Scalars['ID'] - /** A list of line item objects, each one containing information about an item in the checkout. */ - lineItems: CheckoutLineItemConnection - /** The sum of all the prices of all the items in the checkout. Duties, taxes, shipping and discounts excluded. */ - lineItemsSubtotalPrice: MoneyV2 - /** The note associated with the checkout. */ - note?: Maybe - /** The resulting order from a paid checkout. */ - order?: Maybe - /** The Order Status Page for this Checkout, null when checkout is not completed. */ - orderStatusUrl?: Maybe - /** - * The amount left to be paid. This is equal to the cost of the line items, taxes and shipping minus discounts and gift cards. - * @deprecated Use `paymentDueV2` instead - */ - paymentDue: Scalars['Money'] - /** The amount left to be paid. This is equal to the cost of the line items, duties, taxes and shipping minus discounts and gift cards. */ - paymentDueV2: MoneyV2 - /** - * Whether or not the Checkout is ready and can be completed. Checkouts may - * have asynchronous operations that can take time to finish. If you want - * to complete a checkout or ensure all the fields are populated and up to - * date, polling is required until the value is true. - */ - ready: Scalars['Boolean'] - /** States whether or not the fulfillment requires shipping. */ - requiresShipping: Scalars['Boolean'] - /** The shipping address to where the line items will be shipped. */ - shippingAddress?: Maybe - /** The discounts that have been allocated onto the shipping line by discount applications. */ - shippingDiscountAllocations: Array - /** Once a shipping rate is selected by the customer it is transitioned to a `shipping_line` object. */ - shippingLine?: Maybe - /** - * Price of the checkout before shipping and taxes. - * @deprecated Use `subtotalPriceV2` instead - */ - subtotalPrice: Scalars['Money'] - /** Price of the checkout before duties, shipping and taxes. */ - subtotalPriceV2: MoneyV2 - /** Specifies if the Checkout is tax exempt. */ - taxExempt: Scalars['Boolean'] - /** Specifies if taxes are included in the line item and shipping line prices. */ - taxesIncluded: Scalars['Boolean'] - /** - * The sum of all the prices of all the items in the checkout, taxes and discounts included. - * @deprecated Use `totalPriceV2` instead - */ - totalPrice: Scalars['Money'] - /** The sum of all the prices of all the items in the checkout, duties, taxes and discounts included. */ - totalPriceV2: MoneyV2 - /** - * The sum of all the taxes applied to the line items and shipping lines in the checkout. - * @deprecated Use `totalTaxV2` instead - */ - totalTax: Scalars['Money'] - /** The sum of all the taxes applied to the line items and shipping lines in the checkout. */ - totalTaxV2: MoneyV2 - /** The date and time when the checkout was last updated. */ - updatedAt: Scalars['DateTime'] - /** The url pointing to the checkout accessible from the web. */ - webUrl: Scalars['URL'] +export type Checkout = { + name: string + currency: string + support_email: string + fields: any[] + scripts: any[] + accounts: string + email_optin: boolean + terms_policy?: string + refund_policy?: string + privacy_policy?: string + theme?: stirng + countries: any[] + currencies: any[] + payment_methods: any[] + coupons: boolean + giftcards: boolean + + // __typename?: 'Checkout' + // /** The gift cards used on the checkout. */ + // appliedGiftCards: Array + // /** + // * The available shipping rates for this Checkout. + // * Should only be used when checkout `requiresShipping` is `true` and + // * the shipping address is valid. + // */ + // availableShippingRates?: Maybe + // /** The date and time when the checkout was completed. */ + // completedAt?: Maybe + // /** The date and time when the checkout was created. */ + // createdAt: Scalars['DateTime'] + // /** The currency code for the Checkout. */ + // currencyCode: CurrencyCode + // /** A list of extra information that is added to the checkout. */ + // customAttributes: Array + // /** + // * The customer associated with the checkout. + // * @deprecated This field will always return null. If you have an authentication token for the customer, you can use the `customer` field on the query root to retrieve it. + // */ + // customer?: Maybe + // /** Discounts that have been applied on the checkout. */ + // discountApplications: DiscountApplicationConnection + // /** The email attached to this checkout. */ + // email?: Maybe + // /** Globally unique identifier. */ + // id: Scalars['ID'] + // /** A list of line item objects, each one containing information about an item in the checkout. */ + // lineItems: CheckoutLineItemConnection + // /** The sum of all the prices of all the items in the checkout. Duties, taxes, shipping and discounts excluded. */ + // lineItemsSubtotalPrice: MoneyV2 + // /** The note associated with the checkout. */ + // note?: Maybe + // /** The resulting order from a paid checkout. */ + // order?: Maybe + // /** The Order Status Page for this Checkout, null when checkout is not completed. */ + // orderStatusUrl?: Maybe + // /** + // * The amount left to be paid. This is equal to the cost of the line items, taxes and shipping minus discounts and gift cards. + // * @deprecated Use `paymentDueV2` instead + // */ + // paymentDue: Scalars['Money'] + // /** The amount left to be paid. This is equal to the cost of the line items, duties, taxes and shipping minus discounts and gift cards. */ + // paymentDueV2: MoneyV2 + // /** + // * Whether or not the Checkout is ready and can be completed. Checkouts may + // * have asynchronous operations that can take time to finish. If you want + // * to complete a checkout or ensure all the fields are populated and up to + // * date, polling is required until the value is true. + // */ + // ready: Scalars['Boolean'] + // /** States whether or not the fulfillment requires shipping. */ + // requiresShipping: Scalars['Boolean'] + // /** The shipping address to where the line items will be shipped. */ + // shippingAddress?: Maybe + // /** The discounts that have been allocated onto the shipping line by discount applications. */ + // shippingDiscountAllocations: Array + // /** Once a shipping rate is selected by the customer it is transitioned to a `shipping_line` object. */ + // shippingLine?: Maybe + // /** + // * Price of the checkout before shipping and taxes. + // * @deprecated Use `subtotalPriceV2` instead + // */ + // subtotalPrice: Scalars['Money'] + // /** Price of the checkout before duties, shipping and taxes. */ + // subtotalPriceV2: MoneyV2 + // /** Specifies if the Checkout is tax exempt. */ + // taxExempt: Scalars['Boolean'] + // /** Specifies if taxes are included in the line item and shipping line prices. */ + // taxesIncluded: Scalars['Boolean'] + // /** + // * The sum of all the prices of all the items in the checkout, taxes and discounts included. + // * @deprecated Use `totalPriceV2` instead + // */ + // totalPrice: Scalars['Money'] + // /** The sum of all the prices of all the items in the checkout, duties, taxes and discounts included. */ + // totalPriceV2: MoneyV2 + // /** + // * The sum of all the taxes applied to the line items and shipping lines in the checkout. + // * @deprecated Use `totalTaxV2` instead + // */ + // totalTax: Scalars['Money'] + // /** The sum of all the taxes applied to the line items and shipping lines in the checkout. */ + // totalTaxV2: MoneyV2 + // /** The date and time when the checkout was last updated. */ + // updatedAt: Scalars['DateTime'] + // /** The url pointing to the checkout accessible from the web. */ + // webUrl: Scalars['URL'] } /** A container for all the information required to checkout items and pay. */ diff --git a/framework/swell/types.ts b/framework/swell/types.ts index 456b3da05..24362ea38 100644 --- a/framework/swell/types.ts +++ b/framework/swell/types.ts @@ -1,6 +1,15 @@ import * as Core from '@commerce/types' import { CheckoutLineItem } from './schema' +export type SwellImage = { + file: { + url: String + height: Number + width: Number + } + id: string +} + export type SwellCart = { id: string account_id: number @@ -21,9 +30,28 @@ export type SwellCart = { // TODO: add missing fields } -export type VariantResult = { +export type SwellVariant = { id: string option_value_ids: string[] + name: string + price?: number + stock_status?: string +} + +export interface ProductOptionValue { + label: string + hexColors?: string[] + id: string +} + +export type ProductOptions = { + id: string + name: string + variant: boolean + values: ProductOptionValue[] + required: boolean + active: boolean + attribute_id: string } export interface SwellProduct { diff --git a/framework/swell/utils/normalize.ts b/framework/swell/utils/normalize.ts index ea12acbae..a4c8cb732 100644 --- a/framework/swell/utils/normalize.ts +++ b/framework/swell/utils/normalize.ts @@ -1,19 +1,22 @@ -import { Product } from '@commerce/types' -import { Customer } from '@commerce/types' +import { Product, Customer } from '@commerce/types' import { fileURLToPath } from 'node:url' import { - Product as ShopifyProduct, Checkout, CheckoutLineItemEdge, - SelectedOption, - ImageConnection, - ProductVariantConnection, MoneyV2, ProductOption, } from '../schema' -import type { Cart, LineItem, SwellCustomer, SwellProduct } from '../types' +import type { + Cart, + LineItem, + SwellCustomer, + SwellProduct, + SwellImage, + SwellVariant, + ProductOptionValue, +} from '../types' const money = ({ amount, currencyCode }: MoneyV2) => { return { @@ -22,15 +25,22 @@ const money = ({ amount, currencyCode }: MoneyV2) => { } } +type normalizedProductOption = { + __typename?: string + id: string + displayName: string + values: ProductOptionValue[] +} + const normalizeProductOption = ({ id, - name: displayName, + name: displayName = '', values, }: ProductOption) => { let returnValues = values.map((value) => { let output: any = { - displayName, label: value.name, + id: value?.id || id, } if (displayName === 'Color') { output = { @@ -48,50 +58,52 @@ const normalizeProductOption = ({ } } -type SwellImage = { - file: { - url: String - height: Number - width: Number - } - id: string -} -const normalizeProductImages = (images) => { +const normalizeProductImages = (images: SwellImage[]) => { if (!images) { return [{ url: '/' }] } return images?.map(({ file, ...rest }: SwellImage) => ({ - url: file?.url, - height: file?.height, - width: file?.width, + url: file?.url + '', + height: Number(file?.height), + width: Number(file?.width), ...rest, })) } -const normalizeProductVariants = (variants) => { - return variants?.map(({ id, name, price, sku }) => { - const values = name - .split(',') - .map((i) => ({ name: i.trim(), label: i.trim() })) +const normalizeProductVariants = ( + variants: SwellVariant[], + productOptions: normalizedProductOption[] +) => { + return variants?.map( + ({ id, name, price, option_value_ids: optionValueIds }) => { + const values = name + .split(',') + .map((i) => ({ name: i.trim(), label: i.trim() })) - const options = values.map((value) => { - return normalizeProductOption({ + const options = optionValueIds.map((id) => { + const matchingOption = productOptions.find((option) => { + return option.values.find( + (value: ProductOptionValue) => value.id == id + ) + }) + return normalizeProductOption({ + id, + name: matchingOption?.displayName ?? '', + values, + }) + }) + + return { id, name, - values: [value], - }) - }) - - return { - id, - name, - sku: sku ?? id, - price: price ?? null, - listPrice: price ?? null, - // requiresShipping: true, - options, + // sku: sku ?? id, + price: price ?? null, + listPrice: price ?? null, + // requiresShipping: true, + options, + } } - }) + ) } export function normalizeProduct(swellProduct: SwellProduct): Product { @@ -108,10 +120,10 @@ export function normalizeProduct(swellProduct: SwellProduct): Product { const productOptions = options ? options.map((o) => normalizeProductOption(o)) : [] - const productVariants = variants ? normalizeProductVariants(variants) : [] + const productVariants = variants + ? normalizeProductVariants(variants, productOptions) + : [] - // ProductView.tsx assumes the existence of at least one product variant - const emptyVariants = [{ options: [{ id: 123 }] }] const productImages = normalizeProductImages(images) const product = { ...swellProduct, @@ -120,10 +132,7 @@ export function normalizeProduct(swellProduct: SwellProduct): Product { vendor: '', path: `/${slug}`, images: productImages, - variants: - productVariants && productVariants.length - ? productVariants - : emptyVariants, + variants: productVariants, options: productOptions, price: { value, @@ -167,12 +176,12 @@ function normalizeLineItem({ }: CheckoutLineItemEdge): LineItem { const item = { id, - variantId: String(variant?.id), - productId: String(product?.id), + variantId: variant?.id ?? '', + productId: product?.id ?? '', name: product?.name ?? '', quantity, variant: { - id: String(variant?.id), + id: variant?.id ?? '', sku: variant?.sku ?? '', name: variant?.name!, image: { From 6a9c6c3bca8a920404a1ded78a910b66a4fbf6df Mon Sep 17 00:00:00 2001 From: Greg Hoskin Date: Sat, 24 Apr 2021 20:00:13 -0500 Subject: [PATCH 201/216] normalize cart. list brands (attribute) --- framework/swell/cart/use-update-item.tsx | 2 +- framework/swell/types.ts | 23 +++++++----- framework/swell/utils/get-vendors.ts | 18 ++++------ framework/swell/utils/normalize.ts | 46 +++++++++++++++--------- 4 files changed, 51 insertions(+), 38 deletions(-) diff --git a/framework/swell/cart/use-update-item.tsx b/framework/swell/cart/use-update-item.tsx index 3155778c6..38ad65bf1 100644 --- a/framework/swell/cart/use-update-item.tsx +++ b/framework/swell/cart/use-update-item.tsx @@ -73,7 +73,7 @@ export const handler = { const itemId = cartData.lineItems[0].id const productId = cartData.lineItems[0].productId const variantId = cartData.lineItems[0].variant.id - if (!itemId || !productId || !variantId) { + if (!itemId || !productId) { throw new ValidationError({ message: 'Invalid input used for this operation', }) diff --git a/framework/swell/types.ts b/framework/swell/types.ts index 24362ea38..a4ce4afa8 100644 --- a/framework/swell/types.ts +++ b/framework/swell/types.ts @@ -10,23 +10,30 @@ export type SwellImage = { id: string } +export type CartLineItem = { + id: string + product: SwellProduct + price: number + variant: { + name: string | null + sku: string | null + id: string + } + quantity: number +} + export type SwellCart = { id: string account_id: number currency: string tax_included_total: number sub_total: number + grand_total: number discount_total: number quantity: number - items: { - id: string - product: object - price: number - variant: boolean - quantity: number - } + items: CartLineItem[] date_created: string - discounts?: { id: number; amount: number }[] + discounts?: { id: number; amount: number }[] | null // TODO: add missing fields } diff --git a/framework/swell/utils/get-vendors.ts b/framework/swell/utils/get-vendors.ts index 632f5daaf..d80854f6d 100644 --- a/framework/swell/utils/get-vendors.ts +++ b/framework/swell/utils/get-vendors.ts @@ -1,4 +1,5 @@ -import { SwellConfig } from '../api' +import { swellConfig } from '@framework' +import { getConfig, SwellConfig } from '../api' import fetchAllProducts from '../api/utils/fetch-all-products' import getAllProductVendors from './queries/get-all-product-vendors-query' @@ -13,18 +14,11 @@ export type BrandEdge = { export type Brands = BrandEdge[] -const getVendors = async (config: SwellConfig): Promise => { - const vendors = await fetchAllProducts({ - config, - query: getAllProductVendors, - variables: { - first: 250, - }, - }) +const getVendors = async (config: SwellConfig) => { + const vendors = + (await config.fetchSwell('attributes', 'get', ['brand']).values) ?? [] - let vendorsStrings = vendors.map(({ node: { vendor } }) => vendor) - - return [...new Set(vendorsStrings)].map((v) => ({ + return [...new Set(vendors)].map((v) => ({ node: { entityId: v, name: v, diff --git a/framework/swell/utils/normalize.ts b/framework/swell/utils/normalize.ts index a4c8cb732..63b63feb0 100644 --- a/framework/swell/utils/normalize.ts +++ b/framework/swell/utils/normalize.ts @@ -1,5 +1,4 @@ import { Product, Customer } from '@commerce/types' -import { fileURLToPath } from 'node:url' import { Checkout, @@ -10,12 +9,14 @@ import { import type { Cart, - LineItem, + CartLineItem, SwellCustomer, SwellProduct, SwellImage, SwellVariant, ProductOptionValue, + SwellCart, + LineItem, } from '../types' const money = ({ amount, currencyCode }: MoneyV2) => { @@ -142,20 +143,31 @@ export function normalizeProduct(swellProduct: SwellProduct): Product { return product } -export function normalizeCart(cart: Checkout): Cart { - return { - id: cart.id, - customerId: cart.account_id, +export function normalizeCart({ + id, + account_id, + date_created, + currency, + tax_included_total, + items, + sub_total, + grand_total, + discounts, +}: SwellCart) { + const cart: Cart = { + id: id, + customerId: account_id + '', email: '', - createdAt: cart.date_created, - currency: cart.currency, - taxesIncluded: cart.tax_included_total, - lineItems: cart.items?.map(normalizeLineItem), - lineItemsSubtotalPrice: +cart.sub_total, - subtotalPrice: +cart.sub_total, - totalPrice: cart.grand_total, - discounts: cart.discounts, + createdAt: date_created, + currency: { code: currency }, + taxesIncluded: tax_included_total > 0, + lineItems: items?.map(normalizeLineItem), + lineItemsSubtotalPrice: +sub_total, + subtotalPrice: +sub_total, + totalPrice: grand_total, + discounts: discounts?.map((discount) => ({ value: discount.amount })), } + return cart } export function normalizeCustomer(customer: SwellCustomer): Customer { @@ -173,11 +185,11 @@ function normalizeLineItem({ price, variant, quantity, -}: CheckoutLineItemEdge): LineItem { +}: CartLineItem): LineItem { const item = { id, - variantId: variant?.id ?? '', - productId: product?.id ?? '', + variantId: variant?.id, + productId: product.id ?? '', name: product?.name ?? '', quantity, variant: { From a409c373c43eeed126b004cadf0a16db5e43ba87 Mon Sep 17 00:00:00 2001 From: Greg Hoskin Date: Sun, 25 Apr 2021 14:20:58 -0500 Subject: [PATCH 202/216] cleanup, add sorting --- framework/swell/.env.template | 4 +- framework/swell/README.md | 2 +- framework/swell/api/checkout/index.ts | 6 +- framework/swell/api/index.ts | 34 +++------ .../swell/api/utils/create-api-handler.ts | 20 +++--- .../swell/api/utils/fetch-all-products.ts | 12 ++-- .../swell/api/utils/fetch-graphql-api.ts | 34 --------- framework/swell/api/utils/fetch-swell-api.ts | 1 - framework/swell/auth/use-login.tsx | 1 - framework/swell/auth/use-logout.tsx | 1 - framework/swell/cart/use-add-item.tsx | 3 +- framework/swell/cart/use-cart.tsx | 1 - framework/swell/common/get-all-pages.ts | 2 - framework/swell/const.ts | 12 ++-- framework/swell/customer/get-customer-id.ts | 24 ------- framework/swell/customer/use-customer.tsx | 1 - framework/swell/fetcher.ts | 2 - framework/swell/index.tsx | 4 +- .../swell/product/get-all-collections.ts | 7 +- .../swell/product/get-all-product-paths.ts | 8 +-- framework/swell/product/get-all-products.ts | 3 - framework/swell/product/get-product.ts | 1 - framework/swell/product/use-search.tsx | 16 +++-- framework/swell/types.ts | 2 +- framework/swell/utils/customer-token.ts | 10 +-- framework/swell/utils/get-checkout-id.ts | 4 +- framework/swell/utils/get-vendors.ts | 9 +-- .../swell/utils/handle-fetch-response.ts | 2 +- framework/swell/utils/index.ts | 3 +- .../associate-customer-with-checkout.ts | 18 ----- .../swell/utils/mutations/checkout-create.ts | 16 ----- .../utils/mutations/checkout-line-item-add.ts | 16 ----- .../mutations/checkout-line-item-remove.ts | 19 ----- .../mutations/checkout-line-item-update.ts | 16 ----- .../mutations/customer-access-token-create.ts | 16 ----- .../mutations/customer-access-token-delete.ts | 14 ---- .../swell/utils/mutations/customer-create.ts | 15 ---- framework/swell/utils/mutations/index.ts | 7 -- framework/swell/utils/normalize.ts | 2 +- .../queries/get-all-collections-query.ts | 14 ---- .../utils/queries/get-all-pages-query.ts | 14 ---- .../queries/get-all-product-vendors-query.ts | 17 ----- .../queries/get-all-products-paths-query.ts | 17 ----- .../utils/queries/get-all-products-query.ts | 57 --------------- .../swell/utils/queries/get-checkout-query.ts | 62 ----------------- .../queries/get-collection-products-query.ts | 24 ------- .../utils/queries/get-customer-id-query.ts | 8 --- .../swell/utils/queries/get-customer-query.ts | 16 ----- .../swell/utils/queries/get-page-query.ts | 14 ---- .../swell/utils/queries/get-product-query.ts | 69 ------------------- framework/swell/utils/queries/index.ts | 10 --- framework/swell/wishlist/use-wishlist.tsx | 2 +- 52 files changed, 74 insertions(+), 618 deletions(-) delete mode 100644 framework/swell/api/utils/fetch-graphql-api.ts delete mode 100644 framework/swell/customer/get-customer-id.ts delete mode 100644 framework/swell/utils/mutations/associate-customer-with-checkout.ts delete mode 100644 framework/swell/utils/mutations/checkout-create.ts delete mode 100644 framework/swell/utils/mutations/checkout-line-item-add.ts delete mode 100644 framework/swell/utils/mutations/checkout-line-item-remove.ts delete mode 100644 framework/swell/utils/mutations/checkout-line-item-update.ts delete mode 100644 framework/swell/utils/mutations/customer-access-token-create.ts delete mode 100644 framework/swell/utils/mutations/customer-access-token-delete.ts delete mode 100644 framework/swell/utils/mutations/customer-create.ts delete mode 100644 framework/swell/utils/mutations/index.ts delete mode 100644 framework/swell/utils/queries/get-all-collections-query.ts delete mode 100644 framework/swell/utils/queries/get-all-pages-query.ts delete mode 100644 framework/swell/utils/queries/get-all-product-vendors-query.ts delete mode 100644 framework/swell/utils/queries/get-all-products-paths-query.ts delete mode 100644 framework/swell/utils/queries/get-all-products-query.ts delete mode 100644 framework/swell/utils/queries/get-checkout-query.ts delete mode 100644 framework/swell/utils/queries/get-collection-products-query.ts delete mode 100644 framework/swell/utils/queries/get-customer-id-query.ts delete mode 100644 framework/swell/utils/queries/get-customer-query.ts delete mode 100644 framework/swell/utils/queries/get-page-query.ts delete mode 100644 framework/swell/utils/queries/get-product-query.ts delete mode 100644 framework/swell/utils/queries/index.ts diff --git a/framework/swell/.env.template b/framework/swell/.env.template index b5f38e883..43c931f45 100644 --- a/framework/swell/.env.template +++ b/framework/swell/.env.template @@ -1,5 +1,5 @@ -SHOPIFY_STORE_DOMAIN= -SHOPIFY_STOREFRONT_ACCESS_TOKEN= +SWELL_STORE_DOMAIN= +SWELL_STOREFRONT_ACCESS_TOKEN= NEXT_PUBLIC_SWELL_STORE_ID= NEXT_PUBLIC_SWELL_PUBLIC_KEY= diff --git a/framework/swell/README.md b/framework/swell/README.md index fc6a70ce3..f47a7a028 100644 --- a/framework/swell/README.md +++ b/framework/swell/README.md @@ -36,7 +36,7 @@ yarn install -D @types/shopify-buy ``` SHOPIFY_STORE_DOMAIN= SHOPIFY_STOREFRONT_ACCESS_TOKEN= -NEXT_PUBLIC_SHOPIFY_STORE_DOMAIN= +NEXT_PUBLIC_SWELL_STORE_DOMAIN= NEXT_PUBLIC_SHOPIFY_STOREFRONT_ACCESS_TOKEN= ``` diff --git a/framework/swell/api/checkout/index.ts b/framework/swell/api/checkout/index.ts index 03f166a1a..0759e2abc 100644 --- a/framework/swell/api/checkout/index.ts +++ b/framework/swell/api/checkout/index.ts @@ -1,12 +1,10 @@ -import createApiHandler, { - ShopifyApiHandler, -} from '../utils/create-api-handler' +import createApiHandler, { SwellApiHandler } from '../utils/create-api-handler' import { SWELL_CHECKOUT_URL_COOKIE } from '../../const' import { getConfig } from '..' -const checkoutApi: ShopifyApiHandler = async (req, res, config) => { +const checkoutApi: SwellApiHandler = async (req, res, config) => { config = getConfig() const { cookies } = req diff --git a/framework/swell/api/index.ts b/framework/swell/api/index.ts index 9c41b18ae..1e328062b 100644 --- a/framework/swell/api/index.ts +++ b/framework/swell/api/index.ts @@ -1,26 +1,12 @@ import type { CommerceAPIConfig } from '@commerce/api' import { - API_URL, - API_TOKEN, - SHOPIFY_CHECKOUT_ID_COOKIE, - SHOPIFY_CUSTOMER_TOKEN_COOKIE, - SHOPIFY_COOKIE_EXPIRE, + SWELL_CHECKOUT_ID_COOKIE, + SWELL_CUSTOMER_TOKEN_COOKIE, + SWELL_COOKIE_EXPIRE, } from '../const' -if (!API_URL) { - throw new Error( - `The environment variable NEXT_PUBLIC_SHOPIFY_STORE_DOMAIN is missing and it's required to access your store` - ) -} - -if (!API_TOKEN) { - throw new Error( - `The environment variable NEXT_PUBLIC_SHOPIFY_STOREFRONT_ACCESS_TOKEN is missing and it's required to access your store` - ) -} - -import fetchGraphqlApi from './utils/fetch-graphql-api' +import fetcher from '../fetcher' import fetchSwellApi from './utils/fetch-swell-api' export interface SwellConfig extends CommerceAPIConfig { @@ -48,13 +34,13 @@ export class Config { const config = new Config({ locale: 'en-US', - commerceUrl: API_URL, - apiToken: API_TOKEN!, - cartCookie: SHOPIFY_CHECKOUT_ID_COOKIE, - cartCookieMaxAge: SHOPIFY_COOKIE_EXPIRE, + commerceUrl: '', + apiToken: ''!, + cartCookie: SWELL_CHECKOUT_ID_COOKIE, + cartCookieMaxAge: SWELL_COOKIE_EXPIRE, fetchSwell: fetchSwellApi, - fetch: fetchGraphqlApi, - customerCookie: SHOPIFY_CUSTOMER_TOKEN_COOKIE, + fetch: fetcher, + customerCookie: SWELL_CUSTOMER_TOKEN_COOKIE, }) export function getConfig(userConfig?: Partial) { diff --git a/framework/swell/api/utils/create-api-handler.ts b/framework/swell/api/utils/create-api-handler.ts index 7ceb7d423..bd40a7ee4 100644 --- a/framework/swell/api/utils/create-api-handler.ts +++ b/framework/swell/api/utils/create-api-handler.ts @@ -1,41 +1,41 @@ import type { NextApiHandler, NextApiRequest, NextApiResponse } from 'next' import { SwellConfig, getConfig } from '..' -export type ShopifyApiHandler< +export type SwellApiHandler< T = any, - H extends ShopifyHandlers = {}, + H extends SwellHandlers = {}, Options extends {} = {} > = ( req: NextApiRequest, - res: NextApiResponse>, + res: NextApiResponse>, config: SwellConfig, handlers: H, // Custom configs that may be used by a particular handler options: Options ) => void | Promise -export type ShopifyHandler = (options: { +export type SwellHandler = (options: { req: NextApiRequest - res: NextApiResponse> + res: NextApiResponse> config: SwellConfig body: Body }) => void | Promise -export type ShopifyHandlers = { - [k: string]: ShopifyHandler +export type SwellHandlers = { + [k: string]: SwellHandler } -export type ShopifyApiResponse = { +export type SwellApiResponse = { data: T | null errors?: { message: string; code?: string }[] } export default function createApiHandler< T = any, - H extends ShopifyHandlers = {}, + H extends SwellHandlers = {}, Options extends {} = {} >( - handler: ShopifyApiHandler, + handler: SwellApiHandler, handlers: H, defaultOptions: Options ) { diff --git a/framework/swell/api/utils/fetch-all-products.ts b/framework/swell/api/utils/fetch-all-products.ts index 7ad308b04..859ec0212 100644 --- a/framework/swell/api/utils/fetch-all-products.ts +++ b/framework/swell/api/utils/fetch-all-products.ts @@ -4,6 +4,7 @@ import { SwellConfig } from '..' const fetchAllProducts = async ({ config, query, + method, variables, acc = [], cursor, @@ -14,12 +15,13 @@ const fetchAllProducts = async ({ variables?: any cursor?: string }): Promise => { - const { data } = await config.fetch(query, { - variables: { ...variables, cursor }, - }) + // const response = await config.fetch(query, { + // variables: { ...variables, cursor }, + // }) + const response = await config.fetchSwell('products', 'list', [{ limit: 100 }]) - const edges: ProductEdge[] = data.products?.edges ?? [] - const hasNextPage = data.products?.pageInfo?.hasNextPage + const edges: ProductEdge[] = response.results ?? [] + const hasNextPage = response.results.length < response.count acc = acc.concat(edges) if (hasNextPage) { diff --git a/framework/swell/api/utils/fetch-graphql-api.ts b/framework/swell/api/utils/fetch-graphql-api.ts deleted file mode 100644 index 321cba2aa..000000000 --- a/framework/swell/api/utils/fetch-graphql-api.ts +++ /dev/null @@ -1,34 +0,0 @@ -import type { GraphQLFetcher } from '@commerce/api' -import fetch from './fetch' - -import { API_URL, API_TOKEN } from '../../const' -import { getError } from '../../utils/handle-fetch-response' - -const fetchGraphqlApi: GraphQLFetcher = async ( - query: string, - { variables } = {}, - fetchOptions -) => { - const res = await fetch(API_URL, { - ...fetchOptions, - method: 'POST', - headers: { - 'X-Shopify-Storefront-Access-Token': API_TOKEN!, - ...fetchOptions?.headers, - 'Content-Type': 'application/json', - }, - body: JSON.stringify({ - query, - variables, - }), - }) - - const { data, errors, status } = await res.json() - - if (errors) { - throw getError(errors, status) - } - - return { data, res } -} -export default fetchGraphqlApi diff --git a/framework/swell/api/utils/fetch-swell-api.ts b/framework/swell/api/utils/fetch-swell-api.ts index c8707230d..e070483ae 100644 --- a/framework/swell/api/utils/fetch-swell-api.ts +++ b/framework/swell/api/utils/fetch-swell-api.ts @@ -6,7 +6,6 @@ const fetchSwellApi = async ( variables: [] = [] ) => { const { swell } = swellConfig - return await swell[query][method](...variables) } export default fetchSwellApi diff --git a/framework/swell/auth/use-login.tsx b/framework/swell/auth/use-login.tsx index cdaf6151b..57c3ce921 100644 --- a/framework/swell/auth/use-login.tsx +++ b/framework/swell/auth/use-login.tsx @@ -2,7 +2,6 @@ import { useCallback } from 'react' import type { MutationHook } from '@commerce/utils/types' import { CommerceError, ValidationError } from '@commerce/utils/errors' import useCustomer from '../customer/use-customer' -import createCustomerAccessTokenMutation from '../utils/mutations/customer-access-token-create' import { CustomerAccessTokenCreateInput, CustomerUserError, diff --git a/framework/swell/auth/use-logout.tsx b/framework/swell/auth/use-logout.tsx index 6eebd997f..ae17ba74e 100644 --- a/framework/swell/auth/use-logout.tsx +++ b/framework/swell/auth/use-logout.tsx @@ -2,7 +2,6 @@ import { useCallback } from 'react' import type { MutationHook } from '@commerce/utils/types' import useLogout, { UseLogout } from '@commerce/auth/use-logout' import useCustomer from '../customer/use-customer' -import customerAccessTokenDeleteMutation from '../utils/mutations/customer-access-token-delete' import { getCustomerToken, setCustomerToken } from '../utils/customer-token' export default useLogout as UseLogout diff --git a/framework/swell/cart/use-add-item.tsx b/framework/swell/cart/use-add-item.tsx index ff6c7143f..346c6c955 100644 --- a/framework/swell/cart/use-add-item.tsx +++ b/framework/swell/cart/use-add-item.tsx @@ -4,6 +4,7 @@ import useAddItem, { UseAddItem } from '@commerce/cart/use-add-item' import useCart from './use-cart' import { Cart, CartItemBody } from '../types' import { checkoutToCart } from './utils' +import { getCheckoutId } from '../utils' import { Mutation, MutationCheckoutLineItemsAddArgs } from '../schema' import { useCallback } from 'react' @@ -26,12 +27,12 @@ export const handler: MutationHook = { const response = await fetch({ ...options, variables: { + checkoutId: getCheckoutId(), product_id: item.productId, quantity: item.quantity, }, }) - // TODO: Fix this Cart type here return checkoutToCart(response) as any }, useHook: ({ fetch }) => () => { diff --git a/framework/swell/cart/use-cart.tsx b/framework/swell/cart/use-cart.tsx index 04d07914d..354b4f947 100644 --- a/framework/swell/cart/use-cart.tsx +++ b/framework/swell/cart/use-cart.tsx @@ -15,7 +15,6 @@ export const handler: SWRHook = { const cart = await checkoutCreate(fetch) return cart ? normalizeCart(cart) : null - // return checkoutToCart({ checkout } as any) }, useHook: ({ useData }) => (input) => { return useData({ diff --git a/framework/swell/common/get-all-pages.ts b/framework/swell/common/get-all-pages.ts index 1088a472c..489af339c 100644 --- a/framework/swell/common/get-all-pages.ts +++ b/framework/swell/common/get-all-pages.ts @@ -1,6 +1,4 @@ import { getConfig, SwellConfig } from '../api' -import { PageEdge } from '../schema' -import { getAllPagesQuery } from '../utils/queries' type Variables = { first?: number diff --git a/framework/swell/const.ts b/framework/swell/const.ts index 7226b19cb..669194298 100644 --- a/framework/swell/const.ts +++ b/framework/swell/const.ts @@ -1,16 +1,12 @@ -export const SHOPIFY_CHECKOUT_ID_COOKIE = 'shopify_checkoutId' +export const SWELL_CHECKOUT_ID_COOKIE = 'SWELL_checkoutId' export const SWELL_CHECKOUT_URL_COOKIE = 'swell_checkoutUrl' -export const SHOPIFY_CUSTOMER_TOKEN_COOKIE = 'shopify_customerToken' +export const SWELL_CUSTOMER_TOKEN_COOKIE = 'swell_customerToken' -export const STORE_DOMAIN = process.env.NEXT_PUBLIC_SHOPIFY_STORE_DOMAIN +export const STORE_DOMAIN = process.env.NEXT_PUBLIC_SWELL_STORE_DOMAIN -export const SHOPIFY_COOKIE_EXPIRE = 30 - -export const API_URL = `https://${STORE_DOMAIN}/api/2021-01/graphql.json` - -export const API_TOKEN = process.env.NEXT_PUBLIC_SHOPIFY_STOREFRONT_ACCESS_TOKEN +export const SWELL_COOKIE_EXPIRE = 30 export const SWELL_STORE_ID = process.env.NEXT_PUBLIC_SWELL_STORE_ID diff --git a/framework/swell/customer/get-customer-id.ts b/framework/swell/customer/get-customer-id.ts deleted file mode 100644 index c3a1b8d2f..000000000 --- a/framework/swell/customer/get-customer-id.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { getConfig, SwellConfig } from '../api' -import getCustomerIdQuery from '../utils/queries/get-customer-id-query' -import Cookies from 'js-cookie' - -async function getCustomerId({ - customerToken: customerAccesToken, - config, -}: { - customerToken: string - config?: SwellConfig -}): Promise { - config = getConfig(config) - - const { data } = await config.fetch(getCustomerIdQuery, { - variables: { - customerAccesToken: - customerAccesToken || Cookies.get(config.customerCookie), - }, - }) - - return data.customer?.id -} - -export default getCustomerId diff --git a/framework/swell/customer/use-customer.tsx b/framework/swell/customer/use-customer.tsx index 7b84795aa..632065d5a 100644 --- a/framework/swell/customer/use-customer.tsx +++ b/framework/swell/customer/use-customer.tsx @@ -2,7 +2,6 @@ import useCustomer, { UseCustomer } from '@commerce/customer/use-customer' import { Customer } from '@commerce/types' import { SWRHook } from '@commerce/utils/types' import { normalizeCustomer } from '../utils/normalize' -// import { getCustomerQuery, getCustomerToken } from '../utils' export default useCustomer as UseCustomer diff --git a/framework/swell/fetcher.ts b/framework/swell/fetcher.ts index 4c65b91d2..e52d8fd54 100644 --- a/framework/swell/fetcher.ts +++ b/framework/swell/fetcher.ts @@ -8,11 +8,9 @@ const fetcher: Fetcher = async ({ method = 'get', variables, query }) => { if (Array.isArray(variables)) { const arg1 = variables[0] const arg2 = variables[1] - // console.log('fetcher', query, method, variables); const response = await swell[query][method](arg1, arg2) return handleFetchResponse(response) } else { - // console.log('fetcher', query, method, variables); const response = await swell[query][method](variables) return handleFetchResponse(response) } diff --git a/framework/swell/index.tsx b/framework/swell/index.tsx index db8cd3e1f..28f60b394 100644 --- a/framework/swell/index.tsx +++ b/framework/swell/index.tsx @@ -10,7 +10,7 @@ import { import { swellProvider, SwellProvider } from './provider' import { - SHOPIFY_CHECKOUT_ID_COOKIE, + SWELL_CHECKOUT_ID_COOKIE, SWELL_STORE_ID, SWELL_PUBLIC_KEY, } from './const' @@ -21,7 +21,7 @@ export type { SwellProvider } export const swellConfig: any = { locale: 'en-us', - cartCookie: SHOPIFY_CHECKOUT_ID_COOKIE, + cartCookie: SWELL_CHECKOUT_ID_COOKIE, swell, } diff --git a/framework/swell/product/get-all-collections.ts b/framework/swell/product/get-all-collections.ts index b3832316c..e6da3ade4 100644 --- a/framework/swell/product/get-all-collections.ts +++ b/framework/swell/product/get-all-collections.ts @@ -1,17 +1,16 @@ import { CollectionEdge } from '../schema' import { getConfig, SwellConfig } from '../api' -import getAllCollectionsQuery from '../utils/queries/get-all-collections-query' const getAllCollections = async (options?: { variables?: any config: SwellConfig preview?: boolean }) => { - let { config, variables = { first: 250 } } = options ?? {} + let { config, variables = { limit: 25 } } = options ?? {} config = getConfig(config) - const { data } = await config.fetch(getAllCollectionsQuery, { variables }) - const edges = data.collections?.edges ?? [] + const response = await config.fetchSwell('categories', 'list', { variables }) + const edges = response.results ?? [] const categories = edges.map( ({ node: { id: entityId, title: name, handle } }: CollectionEdge) => ({ diff --git a/framework/swell/product/get-all-product-paths.ts b/framework/swell/product/get-all-product-paths.ts index 4f3dec29a..fad11f8c2 100644 --- a/framework/swell/product/get-all-product-paths.ts +++ b/framework/swell/product/get-all-product-paths.ts @@ -2,7 +2,6 @@ import { Product } from '@commerce/types' import { getConfig, SwellConfig } from '../api' import fetchAllProducts from '../api/utils/fetch-all-products' import { ProductEdge } from '../schema' -import getAllProductsPathsQuery from '../utils/queries/get-all-products-paths-query' type ProductPath = { path: string @@ -21,17 +20,18 @@ const getAllProductPaths = async (options?: { config?: SwellConfig preview?: boolean }): Promise => { - let { config, variables = { first: 250 } } = options ?? {} + let { config, variables = { limit: 100 } } = options ?? {} config = getConfig(config) const products = await fetchAllProducts({ config, - query: getAllProductsPathsQuery, + query: 'products', + method: 'list', variables, }) return { - products: products?.map(({ node: { handle } }: ProductEdge) => ({ + products: products?.map(({ slug: handle }) => ({ node: { path: `/${handle}`, }, diff --git a/framework/swell/product/get-all-products.ts b/framework/swell/product/get-all-products.ts index 1f4f4152c..dff5bf067 100644 --- a/framework/swell/product/get-all-products.ts +++ b/framework/swell/product/get-all-products.ts @@ -1,7 +1,4 @@ -import { GraphQLFetcherResult } from '@commerce/api' import { getConfig, SwellConfig } from '../api' -import { ProductEdge } from '../schema' -import { getAllProductsQuery } from '../utils/queries' import { normalizeProduct } from '../utils/normalize' import { Product } from '@commerce/types' diff --git a/framework/swell/product/get-product.ts b/framework/swell/product/get-product.ts index 49bc5b67f..1923fc75a 100644 --- a/framework/swell/product/get-product.ts +++ b/framework/swell/product/get-product.ts @@ -22,7 +22,6 @@ const getProduct = async (options: { if (product.variants) { product.variants = product.variants?.results } - // console.log('product', product) return { product: normalizeProduct(product), } diff --git a/framework/swell/product/use-search.tsx b/framework/swell/product/use-search.tsx index 14b966319..b93a5598f 100644 --- a/framework/swell/product/use-search.tsx +++ b/framework/swell/product/use-search.tsx @@ -1,7 +1,7 @@ import { SWRHook } from '@commerce/utils/types' import useSearch, { UseSearch } from '@commerce/product/use-search' -import { getAllProductsQuery, normalizeProduct } from '../utils' +import { normalizeProduct } from '../utils' import { Product } from '@commerce/types' @@ -25,14 +25,22 @@ export const handler: SWRHook< SearchProductsInput > = { fetchOptions: { - query: getAllProductsQuery, + query: 'products', // String(Math.random()), + method: 'list', }, async fetcher({ input, options, fetch }) { - const { categoryId, search } = input + const sortMap = new Map([ + ['latest-desc', ''], + ['price-asc', 'price_asc'], + ['price-desc', 'price_desc'], + ['trending-desc', 'popularity'], + ]) + const { categoryId, search, sort = 'latest-desc' } = input + const mappedSort = sortMap.get(sort) const { results, count: found } = await fetch({ query: 'products', method: 'list', - variables: { category: categoryId, search }, + variables: { category: categoryId, search, sort: mappedSort }, }) const products = results.map((product) => { diff --git a/framework/swell/types.ts b/framework/swell/types.ts index a4ce4afa8..248ea3158 100644 --- a/framework/swell/types.ts +++ b/framework/swell/types.ts @@ -78,7 +78,7 @@ export interface SwellCustomer extends Core.Customer { last_name: string } -export type ShopifyCheckout = { +export type SwellCheckout = { id: string webUrl: string lineItems: CheckoutLineItem[] diff --git a/framework/swell/utils/customer-token.ts b/framework/swell/utils/customer-token.ts index 85454cb83..63bd51bc0 100644 --- a/framework/swell/utils/customer-token.ts +++ b/framework/swell/utils/customer-token.ts @@ -1,20 +1,20 @@ import Cookies, { CookieAttributes } from 'js-cookie' -import { SHOPIFY_COOKIE_EXPIRE, SHOPIFY_CUSTOMER_TOKEN_COOKIE } from '../const' +import { SWELL_COOKIE_EXPIRE, SWELL_CUSTOMER_TOKEN_COOKIE } from '../const' -export const getCustomerToken = () => Cookies.get(SHOPIFY_CUSTOMER_TOKEN_COOKIE) +export const getCustomerToken = () => Cookies.get(SWELL_CUSTOMER_TOKEN_COOKIE) export const setCustomerToken = ( token: string | null, options?: CookieAttributes ) => { if (!token) { - Cookies.remove(SHOPIFY_CUSTOMER_TOKEN_COOKIE) + Cookies.remove(SWELL_CUSTOMER_TOKEN_COOKIE) } else { Cookies.set( - SHOPIFY_CUSTOMER_TOKEN_COOKIE, + SWELL_CUSTOMER_TOKEN_COOKIE, token, options ?? { - expires: SHOPIFY_COOKIE_EXPIRE, + expires: SWELL_COOKIE_EXPIRE, } ) } diff --git a/framework/swell/utils/get-checkout-id.ts b/framework/swell/utils/get-checkout-id.ts index 11e3802d9..07643f475 100644 --- a/framework/swell/utils/get-checkout-id.ts +++ b/framework/swell/utils/get-checkout-id.ts @@ -1,8 +1,8 @@ import Cookies from 'js-cookie' -import { SHOPIFY_CHECKOUT_ID_COOKIE } from '../const' +import { SWELL_CHECKOUT_ID_COOKIE } from '../const' const getCheckoutId = (id?: string) => { - return id ?? Cookies.get(SHOPIFY_CHECKOUT_ID_COOKIE) + return id ?? Cookies.get(SWELL_CHECKOUT_ID_COOKIE) } export default getCheckoutId diff --git a/framework/swell/utils/get-vendors.ts b/framework/swell/utils/get-vendors.ts index d80854f6d..a96d9dccd 100644 --- a/framework/swell/utils/get-vendors.ts +++ b/framework/swell/utils/get-vendors.ts @@ -1,7 +1,4 @@ -import { swellConfig } from '@framework' -import { getConfig, SwellConfig } from '../api' -import fetchAllProducts from '../api/utils/fetch-all-products' -import getAllProductVendors from './queries/get-all-product-vendors-query' +import { SwellConfig } from '../api' export type BrandNode = { name: string @@ -15,8 +12,8 @@ export type BrandEdge = { export type Brands = BrandEdge[] const getVendors = async (config: SwellConfig) => { - const vendors = - (await config.fetchSwell('attributes', 'get', ['brand']).values) ?? [] + const vendors: [string] = + (await config.fetchSwell('attributes', 'get', ['brand'])).values ?? [] return [...new Set(vendors)].map((v) => ({ node: { diff --git a/framework/swell/utils/handle-fetch-response.ts b/framework/swell/utils/handle-fetch-response.ts index 79aba8bd3..96ceb2469 100644 --- a/framework/swell/utils/handle-fetch-response.ts +++ b/framework/swell/utils/handle-fetch-response.ts @@ -1,7 +1,7 @@ import { FetcherError } from '@commerce/utils/errors' export function getError(errors: any[], status: number) { - errors = errors ?? [{ message: 'Failed to fetch Shopify API' }] + errors = errors ?? [{ message: 'Failed to fetch Swell API' }] return new FetcherError({ errors, status }) } diff --git a/framework/swell/utils/index.ts b/framework/swell/utils/index.ts index 2d59aa506..9ec81bfb8 100644 --- a/framework/swell/utils/index.ts +++ b/framework/swell/utils/index.ts @@ -4,7 +4,6 @@ export { default as getSortVariables } from './get-sort-variables' export { default as getVendors } from './get-vendors' export { default as getCategories } from './get-categories' export { default as getCheckoutId } from './get-checkout-id' -export * from './queries' -export * from './mutations' + export * from './normalize' export * from './customer-token' diff --git a/framework/swell/utils/mutations/associate-customer-with-checkout.ts b/framework/swell/utils/mutations/associate-customer-with-checkout.ts deleted file mode 100644 index 6b1350e05..000000000 --- a/framework/swell/utils/mutations/associate-customer-with-checkout.ts +++ /dev/null @@ -1,18 +0,0 @@ -const associateCustomerWithCheckoutMutation = /* GraphQl */ ` -mutation associateCustomerWithCheckout($checkoutId: ID!, $customerAccessToken: String!) { - checkoutCustomerAssociateV2(checkoutId: $checkoutId, customerAccessToken: $customerAccessToken) { - checkout { - id - } - checkoutUserErrors { - code - field - message - } - customer { - id - } - } - } -` -export default associateCustomerWithCheckoutMutation diff --git a/framework/swell/utils/mutations/checkout-create.ts b/framework/swell/utils/mutations/checkout-create.ts deleted file mode 100644 index 912e1cbd2..000000000 --- a/framework/swell/utils/mutations/checkout-create.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { checkoutDetailsFragment } from '../queries/get-checkout-query' - -const checkoutCreateMutation = /* GraphQL */ ` - mutation { - checkoutCreate(input: {}) { - userErrors { - message - field - } - checkout { - ${checkoutDetailsFragment} - } - } - } -` -export default checkoutCreateMutation diff --git a/framework/swell/utils/mutations/checkout-line-item-add.ts b/framework/swell/utils/mutations/checkout-line-item-add.ts deleted file mode 100644 index 67b9cf250..000000000 --- a/framework/swell/utils/mutations/checkout-line-item-add.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { checkoutDetailsFragment } from '../queries/get-checkout-query' - -const checkoutLineItemAddMutation = /* GraphQL */ ` - mutation($checkoutId: ID!, $lineItems: [CheckoutLineItemInput!]!) { - checkoutLineItemsAdd(checkoutId: $checkoutId, lineItems: $lineItems) { - userErrors { - message - field - } - checkout { - ${checkoutDetailsFragment} - } - } - } -` -export default checkoutLineItemAddMutation diff --git a/framework/swell/utils/mutations/checkout-line-item-remove.ts b/framework/swell/utils/mutations/checkout-line-item-remove.ts deleted file mode 100644 index d967a5168..000000000 --- a/framework/swell/utils/mutations/checkout-line-item-remove.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { checkoutDetailsFragment } from '../queries/get-checkout-query' - -const checkoutLineItemRemoveMutation = /* GraphQL */ ` - mutation($checkoutId: ID!, $lineItemIds: [ID!]!) { - checkoutLineItemsRemove( - checkoutId: $checkoutId - lineItemIds: $lineItemIds - ) { - userErrors { - message - field - } - checkout { - ${checkoutDetailsFragment} - } - } - } -` -export default checkoutLineItemRemoveMutation diff --git a/framework/swell/utils/mutations/checkout-line-item-update.ts b/framework/swell/utils/mutations/checkout-line-item-update.ts deleted file mode 100644 index 8edf17587..000000000 --- a/framework/swell/utils/mutations/checkout-line-item-update.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { checkoutDetailsFragment } from '../queries/get-checkout-query' - -const checkoutLineItemUpdateMutation = /* GraphQL */ ` - mutation($checkoutId: ID!, $lineItems: [CheckoutLineItemUpdateInput!]!) { - checkoutLineItemsUpdate(checkoutId: $checkoutId, lineItems: $lineItems) { - userErrors { - message - field - } - checkout { - ${checkoutDetailsFragment} - } - } - } -` -export default checkoutLineItemUpdateMutation diff --git a/framework/swell/utils/mutations/customer-access-token-create.ts b/framework/swell/utils/mutations/customer-access-token-create.ts deleted file mode 100644 index 7a45c3f49..000000000 --- a/framework/swell/utils/mutations/customer-access-token-create.ts +++ /dev/null @@ -1,16 +0,0 @@ -const customerAccessTokenCreateMutation = /* GraphQL */ ` - mutation customerAccessTokenCreate($input: CustomerAccessTokenCreateInput!) { - customerAccessTokenCreate(input: $input) { - customerAccessToken { - accessToken - expiresAt - } - customerUserErrors { - code - field - message - } - } - } -` -export default customerAccessTokenCreateMutation diff --git a/framework/swell/utils/mutations/customer-access-token-delete.ts b/framework/swell/utils/mutations/customer-access-token-delete.ts deleted file mode 100644 index c46eff1e5..000000000 --- a/framework/swell/utils/mutations/customer-access-token-delete.ts +++ /dev/null @@ -1,14 +0,0 @@ -const customerAccessTokenDeleteMutation = /* GraphQL */ ` - mutation customerAccessTokenDelete($customerAccessToken: String!) { - customerAccessTokenDelete(customerAccessToken: $customerAccessToken) { - deletedAccessToken - deletedCustomerAccessTokenId - userErrors { - field - message - } - } - } -` - -export default customerAccessTokenDeleteMutation diff --git a/framework/swell/utils/mutations/customer-create.ts b/framework/swell/utils/mutations/customer-create.ts deleted file mode 100644 index 05c728a25..000000000 --- a/framework/swell/utils/mutations/customer-create.ts +++ /dev/null @@ -1,15 +0,0 @@ -const customerCreateMutation = /* GraphQL */ ` - mutation customerCreate($input: CustomerCreateInput!) { - customerCreate(input: $input) { - customerUserErrors { - code - field - message - } - customer { - id - } - } - } -` -export default customerCreateMutation diff --git a/framework/swell/utils/mutations/index.ts b/framework/swell/utils/mutations/index.ts deleted file mode 100644 index 3a16d7cec..000000000 --- a/framework/swell/utils/mutations/index.ts +++ /dev/null @@ -1,7 +0,0 @@ -export { default as customerCreateMutation } from './customer-create' -export { default as checkoutCreateMutation } from './checkout-create' -export { default as checkoutLineItemAddMutation } from './checkout-line-item-add' -export { default as checkoutLineItemUpdateMutation } from './checkout-line-item-update' -export { default as checkoutLineItemRemoveMutation } from './checkout-line-item-remove' -export { default as customerAccessTokenCreateMutation } from './customer-access-token-create' -export { default as customerAccessTokenDeleteMutation } from './customer-access-token-delete' diff --git a/framework/swell/utils/normalize.ts b/framework/swell/utils/normalize.ts index 63b63feb0..9f69f702e 100644 --- a/framework/swell/utils/normalize.ts +++ b/framework/swell/utils/normalize.ts @@ -36,7 +36,7 @@ type normalizedProductOption = { const normalizeProductOption = ({ id, name: displayName = '', - values, + values = [], }: ProductOption) => { let returnValues = values.map((value) => { let output: any = { diff --git a/framework/swell/utils/queries/get-all-collections-query.ts b/framework/swell/utils/queries/get-all-collections-query.ts deleted file mode 100644 index 2abf374d6..000000000 --- a/framework/swell/utils/queries/get-all-collections-query.ts +++ /dev/null @@ -1,14 +0,0 @@ -const getSiteCollectionsQuery = /* GraphQL */ ` - query getSiteCollections($first: Int!) { - collections(first: $first) { - edges { - node { - id - title - handle - } - } - } - } -` -export default getSiteCollectionsQuery diff --git a/framework/swell/utils/queries/get-all-pages-query.ts b/framework/swell/utils/queries/get-all-pages-query.ts deleted file mode 100644 index e3aee1f10..000000000 --- a/framework/swell/utils/queries/get-all-pages-query.ts +++ /dev/null @@ -1,14 +0,0 @@ -export const getAllPagesQuery = /* GraphQL */ ` - query getAllPages($first: Int = 250) { - pages(first: $first) { - edges { - node { - id - title - handle - } - } - } - } -` -export default getAllPagesQuery diff --git a/framework/swell/utils/queries/get-all-product-vendors-query.ts b/framework/swell/utils/queries/get-all-product-vendors-query.ts deleted file mode 100644 index be08b8ec6..000000000 --- a/framework/swell/utils/queries/get-all-product-vendors-query.ts +++ /dev/null @@ -1,17 +0,0 @@ -const getAllProductVendors = /* GraphQL */ ` - query getAllProductVendors($first: Int = 250, $cursor: String) { - products(first: $first, after: $cursor) { - pageInfo { - hasNextPage - hasPreviousPage - } - edges { - node { - vendor - } - cursor - } - } - } -` -export default getAllProductVendors diff --git a/framework/swell/utils/queries/get-all-products-paths-query.ts b/framework/swell/utils/queries/get-all-products-paths-query.ts deleted file mode 100644 index 56298c204..000000000 --- a/framework/swell/utils/queries/get-all-products-paths-query.ts +++ /dev/null @@ -1,17 +0,0 @@ -const getAllProductsPathsQuery = /* GraphQL */ ` - query getAllProductPaths($first: Int = 250, $cursor: String) { - products(first: $first, after: $cursor) { - pageInfo { - hasNextPage - hasPreviousPage - } - edges { - node { - handle - } - cursor - } - } - } -` -export default getAllProductsPathsQuery diff --git a/framework/swell/utils/queries/get-all-products-query.ts b/framework/swell/utils/queries/get-all-products-query.ts deleted file mode 100644 index 5eb44c7a7..000000000 --- a/framework/swell/utils/queries/get-all-products-query.ts +++ /dev/null @@ -1,57 +0,0 @@ -export const productConnection = ` -pageInfo { - hasNextPage - hasPreviousPage -} -edges { - node { - id - title - vendor - handle - description - priceRange { - minVariantPrice { - amount - currencyCode - } - } - images(first: 1) { - pageInfo { - hasNextPage - hasPreviousPage - } - edges { - node { - originalSrc - altText - width - height - } - } - } - } -}` - -export const productsFragment = ` -products( - first: $first - sortKey: $sortKey - reverse: $reverse - query: $query -) { - ${productConnection} -} -` - -const getAllProductsQuery = /* GraphQL */ ` - query getAllProducts( - $first: Int = 250 - $query: String = "" - $sortKey: ProductSortKeys = RELEVANCE - $reverse: Boolean = false - ) { - ${productsFragment} - } -` -export default getAllProductsQuery diff --git a/framework/swell/utils/queries/get-checkout-query.ts b/framework/swell/utils/queries/get-checkout-query.ts deleted file mode 100644 index 194e1619a..000000000 --- a/framework/swell/utils/queries/get-checkout-query.ts +++ /dev/null @@ -1,62 +0,0 @@ -export const checkoutDetailsFragment = ` - id - webUrl - subtotalPriceV2{ - amount - currencyCode - } - totalTaxV2 { - amount - currencyCode - } - totalPriceV2 { - amount - currencyCode - } - completedAt - createdAt - taxesIncluded - lineItems(first: 250) { - pageInfo { - hasNextPage - hasPreviousPage - } - edges { - node { - id - title - variant { - id - sku - title - image { - originalSrc - altText - width - height - } - priceV2{ - amount - currencyCode - } - compareAtPriceV2{ - amount - currencyCode - } - } - quantity - } - } - } -` - -const getCheckoutQuery = /* GraphQL */ ` - query($checkoutId: ID!) { - node(id: $checkoutId) { - ... on Checkout { - ${checkoutDetailsFragment} - } - } - } -` -export default getCheckoutQuery diff --git a/framework/swell/utils/queries/get-collection-products-query.ts b/framework/swell/utils/queries/get-collection-products-query.ts deleted file mode 100644 index 04766caa4..000000000 --- a/framework/swell/utils/queries/get-collection-products-query.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { productConnection } from './get-all-products-query' - -const getCollectionProductsQuery = /* GraphQL */ ` - query getProductsFromCollection( - $categoryId: ID! - $first: Int = 250 - $sortKey: ProductCollectionSortKeys = RELEVANCE - $reverse: Boolean = false - ) { - node(id: $categoryId) { - id - ... on Collection { - products( - first: $first - sortKey: $sortKey - reverse: $reverse - ) { - ${productConnection} - } - } - } - } -` -export default getCollectionProductsQuery diff --git a/framework/swell/utils/queries/get-customer-id-query.ts b/framework/swell/utils/queries/get-customer-id-query.ts deleted file mode 100644 index 076ceb10b..000000000 --- a/framework/swell/utils/queries/get-customer-id-query.ts +++ /dev/null @@ -1,8 +0,0 @@ -export const getCustomerQuery = /* GraphQL */ ` - query getCustomerId($customerAccessToken: String!) { - customer(customerAccessToken: $customerAccessToken) { - id - } - } -` -export default getCustomerQuery diff --git a/framework/swell/utils/queries/get-customer-query.ts b/framework/swell/utils/queries/get-customer-query.ts deleted file mode 100644 index 87e37e68d..000000000 --- a/framework/swell/utils/queries/get-customer-query.ts +++ /dev/null @@ -1,16 +0,0 @@ -export const getCustomerQuery = /* GraphQL */ ` - query getCustomer($customerAccessToken: String!) { - customer(customerAccessToken: $customerAccessToken) { - id - firstName - lastName - displayName - email - phone - tags - acceptsMarketing - createdAt - } - } -` -export default getCustomerQuery diff --git a/framework/swell/utils/queries/get-page-query.ts b/framework/swell/utils/queries/get-page-query.ts deleted file mode 100644 index 2ca79abd4..000000000 --- a/framework/swell/utils/queries/get-page-query.ts +++ /dev/null @@ -1,14 +0,0 @@ -export const getPageQuery = /* GraphQL */ ` - query($id: ID!) { - node(id: $id) { - id - ... on Page { - title - handle - body - bodySummary - } - } - } -` -export default getPageQuery diff --git a/framework/swell/utils/queries/get-product-query.ts b/framework/swell/utils/queries/get-product-query.ts deleted file mode 100644 index 5c109901b..000000000 --- a/framework/swell/utils/queries/get-product-query.ts +++ /dev/null @@ -1,69 +0,0 @@ -const getProductQuery = /* GraphQL */ ` - query getProductBySlug($slug: String!) { - productByHandle(handle: $slug) { - id - handle - title - productType - vendor - description - descriptionHtml - options { - id - name - values - } - priceRange { - maxVariantPrice { - amount - currencyCode - } - minVariantPrice { - amount - currencyCode - } - } - variants(first: 250) { - pageInfo { - hasNextPage - hasPreviousPage - } - edges { - node { - id - title - sku - selectedOptions { - name - value - } - priceV2 { - amount - currencyCode - } - compareAtPriceV2 { - amount - currencyCode - } - } - } - } - images(first: 250) { - pageInfo { - hasNextPage - hasPreviousPage - } - edges { - node { - originalSrc - altText - width - height - } - } - } - } - } -` - -export default getProductQuery diff --git a/framework/swell/utils/queries/index.ts b/framework/swell/utils/queries/index.ts deleted file mode 100644 index e19be9c8c..000000000 --- a/framework/swell/utils/queries/index.ts +++ /dev/null @@ -1,10 +0,0 @@ -export { default as getSiteCollectionsQuery } from './get-all-collections-query' -export { default as getProductQuery } from './get-product-query' -export { default as getAllProductsQuery } from './get-all-products-query' -export { default as getAllProductsPathtsQuery } from './get-all-products-paths-query' -export { default as getAllProductVendors } from './get-all-product-vendors-query' -export { default as getCollectionProductsQuery } from './get-collection-products-query' -export { default as getCheckoutQuery } from './get-checkout-query' -export { default as getAllPagesQuery } from './get-all-pages-query' -export { default as getPageQuery } from './get-page-query' -export { default as getCustomerQuery } from './get-customer-query' diff --git a/framework/swell/wishlist/use-wishlist.tsx b/framework/swell/wishlist/use-wishlist.tsx index d2ce9db5b..cd1bfa0ad 100644 --- a/framework/swell/wishlist/use-wishlist.tsx +++ b/framework/swell/wishlist/use-wishlist.tsx @@ -1,5 +1,5 @@ // TODO: replace this hook and other wishlist hooks with a handler, or remove them if -// Shopify doesn't have a wishlist +// Swell doesn't have a wishlist import { HookFetcher } from '@commerce/utils/types' import { Product } from '../schema' From c6d06e60b6ba4b5745f98735fc302646f1617bb5 Mon Sep 17 00:00:00 2001 From: Greg Hoskin Date: Tue, 27 Apr 2021 17:54:42 -0500 Subject: [PATCH 203/216] ensure products have at least one variant --- framework/swell/cart/use-add-item.tsx | 20 +++++++--- framework/swell/product/get-all-products.ts | 11 +++--- framework/swell/product/get-product.ts | 2 +- framework/swell/product/use-search.tsx | 11 +++--- framework/swell/schema.d.ts | 42 ++++++++++----------- framework/swell/utils/normalize.ts | 8 +++- 6 files changed, 54 insertions(+), 40 deletions(-) diff --git a/framework/swell/cart/use-add-item.tsx b/framework/swell/cart/use-add-item.tsx index 346c6c955..a86d2ab28 100644 --- a/framework/swell/cart/use-add-item.tsx +++ b/framework/swell/cart/use-add-item.tsx @@ -24,13 +24,23 @@ export const handler: MutationHook = { message: 'The item quantity has to be a valid integer greater than 0', }) } + const variables: { + product_id: string + variant_id?: string + checkoutId?: string + quantity?: number + } = { + checkoutId: getCheckoutId(), + product_id: item.productId, + quantity: item.quantity, + } + if (item.productId !== item.variantId) { + variables.variant_id = item.variantId + } + const response = await fetch({ ...options, - variables: { - checkoutId: getCheckoutId(), - product_id: item.productId, - quantity: item.quantity, - }, + variables, }) return checkoutToCart(response) as any diff --git a/framework/swell/product/get-all-products.ts b/framework/swell/product/get-all-products.ts index dff5bf067..a129c18a2 100644 --- a/framework/swell/product/get-all-products.ts +++ b/framework/swell/product/get-all-products.ts @@ -1,6 +1,7 @@ import { getConfig, SwellConfig } from '../api' import { normalizeProduct } from '../utils/normalize' import { Product } from '@commerce/types' +import { SwellProduct } from '../types' type Variables = { first?: number @@ -23,12 +24,10 @@ const getAllProducts = async (options: { limit: variables.first, }, ]) - const products = results.map((product) => { - if (product.variants) { - product.variants = product.variants.results - } - return normalizeProduct(product) ?? [] - }) + const products = results.map((product: SwellProduct) => + normalizeProduct(product) + ) + return { products, } diff --git a/framework/swell/product/get-product.ts b/framework/swell/product/get-product.ts index 1923fc75a..8cd59f6e0 100644 --- a/framework/swell/product/get-product.ts +++ b/framework/swell/product/get-product.ts @@ -1,6 +1,6 @@ import { GraphQLFetcherResult } from '@commerce/api' import { getConfig, SwellConfig } from '../api' -import { normalizeProduct, getProductQuery } from '../utils' +import { normalizeProduct } from '../utils' type Variables = { slug: string diff --git a/framework/swell/product/use-search.tsx b/framework/swell/product/use-search.tsx index b93a5598f..ce116caa3 100644 --- a/framework/swell/product/use-search.tsx +++ b/framework/swell/product/use-search.tsx @@ -5,6 +5,8 @@ import { normalizeProduct } from '../utils' import { Product } from '@commerce/types' +import { SwellProduct } from '../types' + export default useSearch as UseSearch export type SearchProductsInput = { @@ -43,12 +45,9 @@ export const handler: SWRHook< variables: { category: categoryId, search, sort: mappedSort }, }) - const products = results.map((product) => { - if (product.variants) { - product.variants = product.variants?.results - } - return normalizeProduct(product) - }) + const products = results.map((product: SwellProduct) => + normalizeProduct(product) + ) return { products, diff --git a/framework/swell/schema.d.ts b/framework/swell/schema.d.ts index c5309310d..e77d3c8d9 100644 --- a/framework/swell/schema.d.ts +++ b/framework/swell/schema.d.ts @@ -962,28 +962,28 @@ export type CheckoutLineItemUpdateInput = { export type CheckoutLineItemsAddPayload = { __typename?: 'CheckoutLineItemsAddPayload' /** The updated checkout object. */ - checkout?: Maybe + items?: Maybe /** List of errors that occurred executing the mutation. */ - checkoutUserErrors: Array - /** - * List of errors that occurred executing the mutation. - * @deprecated Use `checkoutUserErrors` instead - */ - userErrors: Array + // checkoutUserErrors: Array + // /** + // * List of errors that occurred executing the mutation. + // * @deprecated Use `checkoutUserErrors` instead + // */ + // userErrors: Array } /** Return type for `checkoutLineItemsRemove` mutation. */ export type CheckoutLineItemsRemovePayload = { __typename?: 'CheckoutLineItemsRemovePayload' /** The updated checkout object. */ - checkout?: Maybe + items?: Maybe /** List of errors that occurred executing the mutation. */ - checkoutUserErrors: Array - /** - * List of errors that occurred executing the mutation. - * @deprecated Use `checkoutUserErrors` instead - */ - userErrors: Array + // checkoutUserErrors: Array + // /** + // * List of errors that occurred executing the mutation. + // * @deprecated Use `checkoutUserErrors` instead + // */ + // userErrors: Array } /** Return type for `checkoutLineItemsReplace` mutation. */ @@ -999,14 +999,14 @@ export type CheckoutLineItemsReplacePayload = { export type CheckoutLineItemsUpdatePayload = { __typename?: 'CheckoutLineItemsUpdatePayload' /** The updated checkout object. */ - checkout?: Maybe + items?: Maybe /** List of errors that occurred executing the mutation. */ - checkoutUserErrors: Array - /** - * List of errors that occurred executing the mutation. - * @deprecated Use `checkoutUserErrors` instead - */ - userErrors: Array + // checkoutUserErrors: Array + // /** + // * List of errors that occurred executing the mutation. + // * @deprecated Use `checkoutUserErrors` instead + // */ + // userErrors: Array } /** Return type for `checkoutShippingAddressUpdate` mutation. */ diff --git a/framework/swell/utils/normalize.ts b/framework/swell/utils/normalize.ts index 9f69f702e..57215d485 100644 --- a/framework/swell/utils/normalize.ts +++ b/framework/swell/utils/normalize.ts @@ -110,6 +110,7 @@ const normalizeProductVariants = ( export function normalizeProduct(swellProduct: SwellProduct): Product { const { id, + name, description, images, options, @@ -118,6 +119,8 @@ export function normalizeProduct(swellProduct: SwellProduct): Product { price: value, currency: currencyCode, } = swellProduct + // ProductView accesses variants for each product + const emptyVariants = [{ options: [], id, name }] const productOptions = options ? options.map((o) => normalizeProductOption(o)) : [] @@ -133,7 +136,10 @@ export function normalizeProduct(swellProduct: SwellProduct): Product { vendor: '', path: `/${slug}`, images: productImages, - variants: productVariants, + variants: + productVariants && productVariants.length + ? productVariants + : emptyVariants, options: productOptions, price: { value, From ffbcce2a9e1631de90fffec8a48c290b4fc05d93 Mon Sep 17 00:00:00 2001 From: Greg Hoskin Date: Fri, 30 Apr 2021 18:35:19 -0500 Subject: [PATCH 204/216] handle empty cart, variants, options, errors --- .../api/operations/get-all-collections.ts | 21 ----------- .../swell/api/utils/fetch-all-products.ts | 30 ++++------------ framework/swell/cart/utils/checkout-create.ts | 8 +++++ .../swell/product/get-all-product-paths.ts | 4 +-- framework/swell/product/get-product.ts | 4 +-- framework/swell/utils/get-vendors.ts | 2 +- .../swell/utils/handle-fetch-response.ts | 35 +++++++------------ framework/swell/utils/normalize.ts | 4 +-- 8 files changed, 33 insertions(+), 75 deletions(-) delete mode 100644 framework/swell/api/operations/get-all-collections.ts diff --git a/framework/swell/api/operations/get-all-collections.ts b/framework/swell/api/operations/get-all-collections.ts deleted file mode 100644 index ed906ffcc..000000000 --- a/framework/swell/api/operations/get-all-collections.ts +++ /dev/null @@ -1,21 +0,0 @@ -import Client from 'shopify-buy' -import { SwellConfig } from '../index' - -type Options = { - config: SwellConfig -} - -const getAllCollections = async (options: Options) => { - const { config } = options - - const client = Client.buildClient({ - storefrontAccessToken: config.apiToken, - domain: config.commerceUrl, - }) - - const res = await client.collection.fetchAllWithProducts() - - return JSON.parse(JSON.stringify(res)) -} - -export default getAllCollections diff --git a/framework/swell/api/utils/fetch-all-products.ts b/framework/swell/api/utils/fetch-all-products.ts index 859ec0212..38ba5f6e3 100644 --- a/framework/swell/api/utils/fetch-all-products.ts +++ b/framework/swell/api/utils/fetch-all-products.ts @@ -1,5 +1,5 @@ -import { ProductEdge } from '../../schema' import { SwellConfig } from '..' +import { SwellProduct } from '../../types' const fetchAllProducts = async ({ config, @@ -7,35 +7,17 @@ const fetchAllProducts = async ({ method, variables, acc = [], - cursor, }: { config: SwellConfig query: string - acc?: ProductEdge[] + method: string + acc?: SwellProduct[] variables?: any cursor?: string -}): Promise => { - // const response = await config.fetch(query, { - // variables: { ...variables, cursor }, - // }) - const response = await config.fetchSwell('products', 'list', [{ limit: 100 }]) +}): Promise => { + const response = await config.fetchSwell(query, method, variables) - const edges: ProductEdge[] = response.results ?? [] - const hasNextPage = response.results.length < response.count - acc = acc.concat(edges) - - if (hasNextPage) { - const cursor = edges.pop()?.cursor - if (cursor) { - return fetchAllProducts({ - config, - query, - variables, - acc, - cursor, - }) - } - } + acc = acc.concat(response.results) return acc } diff --git a/framework/swell/cart/utils/checkout-create.ts b/framework/swell/cart/utils/checkout-create.ts index cc08007f4..5ee3833c5 100644 --- a/framework/swell/cart/utils/checkout-create.ts +++ b/framework/swell/cart/utils/checkout-create.ts @@ -8,6 +8,14 @@ export const checkoutCreate = async (fetch: any) => { method: 'get', }) + if (!cart) { + const cart = await fetch({ + query: 'cart', + method: 'setItems', + variables: [[]], + }) + } + const checkoutUrl = cart?.checkout_url if (checkoutUrl) { diff --git a/framework/swell/product/get-all-product-paths.ts b/framework/swell/product/get-all-product-paths.ts index fad11f8c2..3b95798e4 100644 --- a/framework/swell/product/get-all-product-paths.ts +++ b/framework/swell/product/get-all-product-paths.ts @@ -1,7 +1,5 @@ -import { Product } from '@commerce/types' import { getConfig, SwellConfig } from '../api' import fetchAllProducts from '../api/utils/fetch-all-products' -import { ProductEdge } from '../schema' type ProductPath = { path: string @@ -20,7 +18,7 @@ const getAllProductPaths = async (options?: { config?: SwellConfig preview?: boolean }): Promise => { - let { config, variables = { limit: 100 } } = options ?? {} + let { config, variables = [{ limit: 100 }] } = options ?? {} config = getConfig(config) const products = await fetchAllProducts({ diff --git a/framework/swell/product/get-product.ts b/framework/swell/product/get-product.ts index 8cd59f6e0..15fde1cfa 100644 --- a/framework/swell/product/get-product.ts +++ b/framework/swell/product/get-product.ts @@ -19,11 +19,11 @@ const getProduct = async (options: { config = getConfig(config) const product = await config.fetchSwell('products', 'get', [variables.slug]) - if (product.variants) { + if (product && product.variants) { product.variants = product.variants?.results } return { - product: normalizeProduct(product), + product: product ? normalizeProduct(product) : null, } } diff --git a/framework/swell/utils/get-vendors.ts b/framework/swell/utils/get-vendors.ts index a96d9dccd..9f2184fc3 100644 --- a/framework/swell/utils/get-vendors.ts +++ b/framework/swell/utils/get-vendors.ts @@ -13,7 +13,7 @@ export type Brands = BrandEdge[] const getVendors = async (config: SwellConfig) => { const vendors: [string] = - (await config.fetchSwell('attributes', 'get', ['brand'])).values ?? [] + (await config.fetchSwell('attributes', 'get', ['brand']))?.values ?? [] return [...new Set(vendors)].map((v) => ({ node: { diff --git a/framework/swell/utils/handle-fetch-response.ts b/framework/swell/utils/handle-fetch-response.ts index 96ceb2469..2688c9c70 100644 --- a/framework/swell/utils/handle-fetch-response.ts +++ b/framework/swell/utils/handle-fetch-response.ts @@ -1,28 +1,19 @@ -import { FetcherError } from '@commerce/utils/errors' +import { CommerceError } from '@commerce/utils/errors' -export function getError(errors: any[], status: number) { - errors = errors ?? [{ message: 'Failed to fetch Swell API' }] - return new FetcherError({ errors, status }) +type SwellFetchResponse = { + error: { + message: string + code?: string + } } -export async function getAsyncError(res: Response) { - const data = await res.json() - return getError(data.errors, res.status) -} - -const handleFetchResponse = async (res: Response) => { - // if (res.ok) { - // const { data, errors } = await res.json() - - // if (errors && errors.length) { - // throw getError(errors, res.status) - // } - - // return data - // } - if (res) return res - - throw await getAsyncError(res) +const handleFetchResponse = async (res: SwellFetchResponse) => { + if (res) { + if (res.error) { + throw new CommerceError(res.error) + } + return res + } } export default handleFetchResponse diff --git a/framework/swell/utils/normalize.ts b/framework/swell/utils/normalize.ts index 57215d485..a7a7be1ce 100644 --- a/framework/swell/utils/normalize.ts +++ b/framework/swell/utils/normalize.ts @@ -76,7 +76,7 @@ const normalizeProductVariants = ( productOptions: normalizedProductOption[] ) => { return variants?.map( - ({ id, name, price, option_value_ids: optionValueIds }) => { + ({ id, name, price, option_value_ids: optionValueIds = [] }) => { const values = name .split(',') .map((i) => ({ name: i.trim(), label: i.trim() })) @@ -167,7 +167,7 @@ export function normalizeCart({ createdAt: date_created, currency: { code: currency }, taxesIncluded: tax_included_total > 0, - lineItems: items?.map(normalizeLineItem), + lineItems: items?.map(normalizeLineItem) ?? [], lineItemsSubtotalPrice: +sub_total, subtotalPrice: +sub_total, totalPrice: grand_total, From 7f438aa67d7ef9e6e8acdd90d35904474bef17ff Mon Sep 17 00:00:00 2001 From: Greg Hoskin Date: Wed, 5 May 2021 12:42:47 -0500 Subject: [PATCH 205/216] remove provider --- .env.template | 2 +- commerce.config.json | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/.env.template b/.env.template index 5ebc092d3..9d8a57355 100644 --- a/.env.template +++ b/.env.template @@ -1,5 +1,5 @@ # Available providers: bigcommerce, shopify, swell -COMMERCE_PROVIDER=swell +COMMERCE_PROVIDER= BIGCOMMERCE_STOREFRONT_API_URL= BIGCOMMERCE_STOREFRONT_API_TOKEN= diff --git a/commerce.config.json b/commerce.config.json index ab9497fd3..06b985504 100644 --- a/commerce.config.json +++ b/commerce.config.json @@ -1,5 +1,4 @@ { - "provider": "swell", "features": { "wishlist": false, "customCheckout": false From 7786d6445dbe29f902d08396532cffcac9f2e86e Mon Sep 17 00:00:00 2001 From: Greg Hoskin Date: Wed, 5 May 2021 15:21:35 -0500 Subject: [PATCH 206/216] cleanup for PR --- .vscode/launch.json | 15 - README.md | 231 ---------------- commerce.config.json | 2 +- framework/commerce/with-config.js | 40 --- .../api/operations/get-all-collections.ts | 21 -- framework/shopify/api/operations/get-page.ts | 25 -- framework/shopify/cart/use-cart.tsx | 1 + .../shopify/cart/utils/checkout-create.ts | 29 -- .../shopify/cart/utils/checkout-to-cart.ts | 42 --- framework/shopify/cart/utils/fetcher.ts | 31 --- framework/shopify/cart/utils/index.ts | 2 - framework/shopify/utils/storage.ts | 13 - framework/swell/README.md | 260 ------------------ tsconfig.json | 4 +- 14 files changed, 4 insertions(+), 712 deletions(-) delete mode 100644 .vscode/launch.json delete mode 100644 README.md delete mode 100644 framework/commerce/with-config.js delete mode 100644 framework/shopify/api/operations/get-all-collections.ts delete mode 100644 framework/shopify/api/operations/get-page.ts delete mode 100644 framework/shopify/cart/utils/checkout-create.ts delete mode 100644 framework/shopify/cart/utils/checkout-to-cart.ts delete mode 100644 framework/shopify/cart/utils/fetcher.ts delete mode 100644 framework/shopify/cart/utils/index.ts delete mode 100644 framework/shopify/utils/storage.ts delete mode 100644 framework/swell/README.md diff --git a/.vscode/launch.json b/.vscode/launch.json deleted file mode 100644 index 177bc7dfa..000000000 --- a/.vscode/launch.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - // Use IntelliSense to learn about possible attributes. - // Hover to view descriptions of existing attributes. - // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 - "version": "0.2.0", - "configurations": [ - { - "type": "pwa-chrome", - "request": "launch", - "name": "Launch Chrome against localhost", - "url": "http://localhost:8080", - "webRoot": "${workspaceFolder}" - } - ] -} diff --git a/README.md b/README.md deleted file mode 100644 index 2eabbe6c1..000000000 --- a/README.md +++ /dev/null @@ -1,231 +0,0 @@ -[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/git/external?repository-url=https%3A%2F%2Fgithub.com%2Fvercel%2Fcommerce&project-name=commerce&repo-name=commerce&demo-title=Next.js%20Commerce&demo-description=An%20all-in-one%20starter%20kit%20for%20high-performance%20e-commerce%20sites.&demo-url=https%3A%2F%2Fdemo.vercel.store&demo-image=https%3A%2F%2Fbigcommerce-demo-asset-ksvtgfvnd.vercel.app%2Fbigcommerce.png&integration-ids=oac_MuWZiE4jtmQ2ejZQaQ7ncuDT) - -# Next.js Commerce - -The all-in-one starter kit for high-performance e-commerce sites. With a few clicks, Next.js developers can clone, deploy and fully customize their own store. -Start right now at [nextjs.org/commerce](https://nextjs.org/commerce) - -Demo live at: [demo.vercel.store](https://demo.vercel.store/) - -- Shopify Demo: https://shopify.demo.vercel.store/ -- BigCommerce Demo: https://bigcommerce.demo.vercel.store/ - -## Features - -- Performant by default -- SEO Ready -- Internationalization -- Responsive -- UI Components -- Theming -- Standardized Data Hooks -- Integrations - Integrate seamlessly with the most common ecommerce platforms. -- Dark Mode Support - -## Integrations - -Next.js Commerce integrates out-of-the-box with BigCommerce and Shopify. We plan to support all major ecommerce backends. - -## Considerations - -- `framework/commerce` contains all types, helpers and functions to be used as base to build a new **provider**. -- **Providers** live under `framework`'s root folder and they will extend Next.js Commerce types and functionality (`framework/commerce`). -- We have a **Features API** to ensure feature parity between the UI and the Provider. The UI should update accordingly and no extra code should be bundled. All extra configuration for features will live under `features` in `commerce.config.json` and if needed it can also be accessed programatically. -- Each **provider** should add its corresponding `next.config.js` and `commerce.config.json` adding specific data related to the provider. For example in case of BigCommerce, the images CDN and additional API routes. -- **Providers don't depend on anything that's specific to the application they're used in**. They only depend on `framework/commerce`, on their own framework folder and on some dependencies included in `package.json` - -## Configuration - -### How to change providers - -Open `.env.local` and change the value of `COMMERCE_PROVIDER` to the provider you would like to use, then set the environment variables for that provider (use `.env.template` as the base). - -### Features - -Every provider defines the features that it supports under `framework/{provider}/commerce.config.json` - -#### How to turn Features on and off - -> NOTE: The selected provider should support the feature that you are toggling. (This means that you can't turn wishlist on if the provider doesn't support this functionality out the box) - -- Open `commerce.config.json` -- You'll see a config file like this: - ```json - { - "features": { - "wishlist": false - } - } - ``` -- Turn wishlist on by setting wishlist to true. -- Run the app and the wishlist functionality should be back on. - -### How to create a new provider - -Follow our docs for [Adding a new Commerce Provider](framework/commerce/new-provider.md). - -If you succeeded building a provider, submit a PR with a valid demo and we'll review it asap. - -## Contribute - -Our commitment to Open Source can be found [here](https://vercel.com/oss). - -1. [Fork](https://help.github.com/articles/fork-a-repo/) this repository to your own GitHub account and then [clone](https://help.github.com/articles/cloning-a-repository/) it to your local device. -2. Create a new branch `git checkout -b MY_BRANCH_NAME` -3. Install yarn: `npm install -g yarn` -4. Install the dependencies: `yarn` -5. Duplicate `.env.template` and rename it to `.env.local` -6. Add proper store values to `.env.local` -7. Run `yarn dev` to build and watch for code changes - -## Work in progress - -We're using Github Projects to keep track of issues in progress and todo's. Here is our [Board](https://github.com/vercel/commerce/projects/1) - -People actively working on this project: @okbel & @lfades. - -## Framework - -Framework is where the data comes from. It contains mostly hook handlers and functions. - -## Structure - -Main folder and its exposed functions - -- `product` - - usePrice - - useSearch - - getProduct - - getAllProducts -- `wishlist` - - useWishlist - - useAddItem - - useRemoveItem -- `auth` - - useLogin - - useLogout - - useSignup -- `customer` - - useCustomer - - getCustomerId - - getCustomerWistlist -- `cart` - - - useCart - - useAddItem - - useRemoveItem - - useUpdateItem - -- `config.json` -- README.md - -#### Example of correct usage of the Commerce Framework - -```js -import { useUI } from '@components/ui' -import { useCustomer } from '@framework/customer' -import { useWishlist, useAddItem, useRemoveItem } from '@framework/wishlist' -``` - -## Configuration - -### How to change providers - -First, update the provider selected in `commerce.config.json`: - -```json -{ - "provider": "bigcommerce", - "features": { - "wishlist": true - } -} -``` - -Then, change the paths defined in `tsconfig.json` and update the `@framework` paths to point to the right folder provider: - -```json -"@framework": ["framework/bigcommerce"], -"@framework/*": ["framework/bigcommerce/*"] -``` - -Make sure to add the environment variables required by the new provider. - -### Features - -Every provider defines the features that it supports under `framework/{provider}/commerce.config.json` - -#### How to turn Features on and off - -> NOTE: The selected provider should support the feature that you are toggling. (This means that you can't turn wishlist on if the provider doesn't support this functionality out the box) - -- Open `commerce.config.json` -- You'll see a config file like this: - ```json - { - "provider": "bigcommerce", - "features": { - "wishlist": false - } - } - ``` -- Turn wishlist on by setting wishlist to true. -- Run the app and the wishlist functionality should be back on. - -### How to create a new provider - -We'd recommend to duplicate a provider folder and push your providers SDK. - -If you succeeded building a provider, submit a PR so we can all enjoy it. - -## Contribute - -Our commitment to Open Source can be found [here](https://vercel.com/oss). - -1. [Fork](https://help.github.com/articles/fork-a-repo/) this repository to your own GitHub account and then [clone](https://help.github.com/articles/cloning-a-repository/) it to your local device. -2. Create a new branch `git checkout -b MY_BRANCH_NAME` -3. Install yarn: `npm install -g yarn` -4. Install the dependencies: `yarn` -5. Duplicate `.env.template` and rename it to `.env.local`. -6. Add proper store values to `.env.local`. -7. Run `yarn dev` to build and watch for code changes -8. The development branch is `canary` (this is the branch pull requests should be made against). - On a release, `canary` branch is rebased into `master`. - -## Troubleshoot - -
      -I already own a BigCommerce store. What should I do? -
      -First thing you do is: set your environment variables -
      -
      -.env.local - -```sh -BIGCOMMERCE_STOREFRONT_API_URL=<> -BIGCOMMERCE_STOREFRONT_API_TOKEN=<> -BIGCOMMERCE_STORE_API_URL=<> -BIGCOMMERCE_STORE_API_TOKEN=<> -BIGCOMMERCE_STORE_API_CLIENT_ID=<> -BIGCOMMERCE_CHANNEL_ID=<> -``` - -If your project was started with a "Deploy with Vercel" button, you can use Vercel's CLI to retrieve these credentials. - -1. Install Vercel CLI: `npm i -g vercel` -2. Link local instance with Vercel and Github accounts (creates .vercel file): `vercel link` -3. Download your environment variables: `vercel env pull .env.local` - -Next, you're free to customize the starter. More updates coming soon. Stay tuned. - -
      - -
      -BigCommerce shows a Coming Soon page and requests a Preview Code -
      -After Email confirmation, Checkout should be manually enabled through BigCommerce platform. Look for "Review & test your store" section through BigCommerce's dashboard. -
      -
      -BigCommerce team has been notified and they plan to add more detailed about this subject. -
      diff --git a/commerce.config.json b/commerce.config.json index 06b985504..08ea78814 100644 --- a/commerce.config.json +++ b/commerce.config.json @@ -1,6 +1,6 @@ { "features": { - "wishlist": false, + "wishlist": true, "customCheckout": false } } diff --git a/framework/commerce/with-config.js b/framework/commerce/with-config.js deleted file mode 100644 index cc244dac0..000000000 --- a/framework/commerce/with-config.js +++ /dev/null @@ -1,40 +0,0 @@ -/** - * This file is expected to be used in next.config.js only - */ - -const merge = require('deepmerge') - -const PROVIDERS = ['bigcommerce', 'shopify', 'swell'] - -function getProviderName() { - return process.env.BIGCOMMERCE_STOREFRONT_API_URL ? 'bigcommerce' : null -} - -module.exports = (nextConfig = {}) => { - const commerce = nextConfig.commerce || {} - const name = commerce.provider || getProviderName() - - if (!name) { - throw new Error( - `The commerce provider is missing, please add a valid provider name or its environment variables` - ) - } - if (!PROVIDERS.includes(name)) { - throw new Error( - `The commerce provider "${name}" can't be found, please use one of "${PROVIDERS.join( - ', ' - )}"` - ) - } - - const commerceNextConfig = require(`../${name}/next.config`) - const config = merge(commerceNextConfig, nextConfig) - - config.env = config.env || {} - - Object.entries(config.commerce.features).forEach(([k, v]) => { - if (v) config.env[`COMMERCE_${k.toUpperCase()}_ENABLED`] = true - }) - - return config -} diff --git a/framework/shopify/api/operations/get-all-collections.ts b/framework/shopify/api/operations/get-all-collections.ts deleted file mode 100644 index 9cf216a91..000000000 --- a/framework/shopify/api/operations/get-all-collections.ts +++ /dev/null @@ -1,21 +0,0 @@ -import Client from 'shopify-buy' -import { ShopifyConfig } from '../index' - -type Options = { - config: ShopifyConfig -} - -const getAllCollections = async (options: Options) => { - const { config } = options - - const client = Client.buildClient({ - storefrontAccessToken: config.apiToken, - domain: config.commerceUrl, - }) - - const res = await client.collection.fetchAllWithProducts() - - return JSON.parse(JSON.stringify(res)) -} - -export default getAllCollections diff --git a/framework/shopify/api/operations/get-page.ts b/framework/shopify/api/operations/get-page.ts deleted file mode 100644 index 32acb7c8f..000000000 --- a/framework/shopify/api/operations/get-page.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { Page } from '../../schema' -import { ShopifyConfig, getConfig } from '..' - -export type GetPageResult = T - -export type PageVariables = { - id: string -} - -async function getPage({ - url, - variables, - config, - preview, -}: { - url?: string - variables: PageVariables - config?: ShopifyConfig - preview?: boolean -}): Promise { - config = getConfig(config) - return {} -} - -export default getPage diff --git a/framework/shopify/cart/use-cart.tsx b/framework/shopify/cart/use-cart.tsx index c2ea7ea49..5f77360bb 100644 --- a/framework/shopify/cart/use-cart.tsx +++ b/framework/shopify/cart/use-cart.tsx @@ -22,6 +22,7 @@ export const handler: SWRHook< }, async fetcher({ input: { cartId: checkoutId }, options, fetch }) { let checkout + if (checkoutId) { const data = await fetch({ ...options, diff --git a/framework/shopify/cart/utils/checkout-create.ts b/framework/shopify/cart/utils/checkout-create.ts deleted file mode 100644 index e950cc7e4..000000000 --- a/framework/shopify/cart/utils/checkout-create.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { - SHOPIFY_CHECKOUT_ID_COOKIE, - SHOPIFY_CHECKOUT_URL_COOKIE, - SHOPIFY_COOKIE_EXPIRE, -} from '../../const' - -import checkoutCreateMutation from '../../utils/mutations/checkout-create' -import Cookies from 'js-cookie' - -export const checkoutCreate = async (fetch: any) => { - const data = await fetch({ - query: checkoutCreateMutation, - }) - - const checkout = data.checkoutCreate?.checkout - const checkoutId = checkout?.id - - if (checkoutId) { - const options = { - expires: SHOPIFY_COOKIE_EXPIRE, - } - Cookies.set(SHOPIFY_CHECKOUT_ID_COOKIE, checkoutId, options) - Cookies.set(SHOPIFY_CHECKOUT_URL_COOKIE, checkout?.webUrl, options) - } - - return checkout -} - -export default checkoutCreate diff --git a/framework/shopify/cart/utils/checkout-to-cart.ts b/framework/shopify/cart/utils/checkout-to-cart.ts deleted file mode 100644 index 03005f342..000000000 --- a/framework/shopify/cart/utils/checkout-to-cart.ts +++ /dev/null @@ -1,42 +0,0 @@ -import { Cart } from '../../types' -import { CommerceError, ValidationError } from '@commerce/utils/errors' - -import { - CheckoutLineItemsAddPayload, - CheckoutLineItemsRemovePayload, - CheckoutLineItemsUpdatePayload, - Maybe, -} from '../../schema' -import { normalizeCart } from '../../utils' - -export type CheckoutPayload = - | CheckoutLineItemsAddPayload - | CheckoutLineItemsUpdatePayload - | CheckoutLineItemsRemovePayload - -const checkoutToCart = (checkoutPayload?: Maybe): Cart => { - if (!checkoutPayload) { - throw new CommerceError({ - message: 'Invalid response from Shopify', - }) - } - - const checkout = checkoutPayload?.checkout - const userErrors = checkoutPayload?.userErrors - - if (userErrors && userErrors.length) { - throw new ValidationError({ - message: userErrors[0].message, - }) - } - - if (!checkout) { - throw new CommerceError({ - message: 'Invalid response from Shopify', - }) - } - - return normalizeCart(checkout) -} - -export default checkoutToCart diff --git a/framework/shopify/cart/utils/fetcher.ts b/framework/shopify/cart/utils/fetcher.ts deleted file mode 100644 index 6afb55f18..000000000 --- a/framework/shopify/cart/utils/fetcher.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { HookFetcherFn } from '@commerce/utils/types' -import { Cart } from '@commerce/types' -import { checkoutCreate, checkoutToCart } from '.' -import { FetchCartInput } from '@commerce/cart/use-cart' - -const fetcher: HookFetcherFn = async ({ - options, - input: { cartId: checkoutId }, - fetch, -}) => { - let checkout - - if (checkoutId) { - const data = await fetch({ - ...options, - variables: { - checkoutId, - }, - }) - checkout = data.node - } - - if (checkout?.completedAt || !checkoutId) { - checkout = await checkoutCreate(fetch) - } - - // TODO: Fix this type - return checkoutToCart({ checkout } as any) -} - -export default fetcher diff --git a/framework/shopify/cart/utils/index.ts b/framework/shopify/cart/utils/index.ts deleted file mode 100644 index 20d04955d..000000000 --- a/framework/shopify/cart/utils/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export { default as checkoutToCart } from './checkout-to-cart' -export { default as checkoutCreate } from './checkout-create' diff --git a/framework/shopify/utils/storage.ts b/framework/shopify/utils/storage.ts deleted file mode 100644 index d46dadb21..000000000 --- a/framework/shopify/utils/storage.ts +++ /dev/null @@ -1,13 +0,0 @@ -export const getCheckoutIdFromStorage = (token: string) => { - if (window && window.sessionStorage) { - return window.sessionStorage.getItem(token) - } - - return null -} - -export const setCheckoutIdInStorage = (token: string, id: string | number) => { - if (window && window.sessionStorage) { - return window.sessionStorage.setItem(token, id + '') - } -} diff --git a/framework/swell/README.md b/framework/swell/README.md deleted file mode 100644 index f47a7a028..000000000 --- a/framework/swell/README.md +++ /dev/null @@ -1,260 +0,0 @@ -## Table of Contents - -- [Getting Started](#getting-started) - - [Modifications](#modifications) - - [Adding item to Cart](#adding-item-to-cart) - - [Proceed to Checkout](#proceed-to-checkout) -- [General Usage](#general-usage) - - [CommerceProvider](#commerceprovider) - - [useCommerce](#usecommerce) -- [Hooks](#hooks) - - [usePrice](#useprice) - - [useAddItem](#useadditem) - - [useRemoveItem](#useremoveitem) - - [useUpdateItem](#useupdateitem) -- [APIs](#apis) - - [getProduct](#getproduct) - - [getAllProducts](#getallproducts) - - [getAllCollections](#getallcollections) - - [getAllPages](#getallpages) - -# Shopify Storefront Data Hooks - -Collection of hooks and data fetching functions to integrate Shopify in a React application. Designed to work with [Next.js Commerce](https://demo.vercel.store/). - -## Getting Started - -1. Install dependencies: - -``` -yarn install shopify-buy -yarn install -D @types/shopify-buy -``` - -3. Environment variables need to be set: - -``` -SHOPIFY_STORE_DOMAIN= -SHOPIFY_STOREFRONT_ACCESS_TOKEN= -NEXT_PUBLIC_SWELL_STORE_DOMAIN= -NEXT_PUBLIC_SHOPIFY_STOREFRONT_ACCESS_TOKEN= -``` - -4. Point the framework to `shopify` by updating `tsconfig.json`: - -``` -"@framework/*": ["framework/shopify/*"], -"@framework": ["framework/shopify"] -``` - -### Modifications - -These modifications are temporarily until contributions are made to remove them. - -#### Adding item to Cart - -```js -// components/product/ProductView/ProductView.tsx -const ProductView: FC = ({ product }) => { - const addToCart = async () => { - setLoading(true) - try { - await addItem({ - productId: product.id, - variantId: variant ? variant.id : product.variants[0].id, - }) - openSidebar() - setLoading(false) - } catch (err) { - setLoading(false) - } - } -} -``` - -#### Proceed to Checkout - -```js -// components/cart/CartSidebarView/CartSidebarView.tsx -import { useCommerce } from '@framework' - -const CartSidebarView: FC = () => { - const { checkout } = useCommerce() - return ( - - ) -} -``` - -## General Usage - -### CommerceProvider - -Provider component that creates the commerce context for children. - -```js -import { CommerceProvider } from '@framework' - -const App = ({ children }) => { - return {children} -} - -export default App -``` - -### useCommerce - -Returns the configs that are defined in the nearest `CommerceProvider`. Also provides access to Shopify's `checkout` and `shop`. - -```js -import { useCommerce } from 'nextjs-commerce-shopify' - -const { checkout, shop } = useCommerce() -``` - -- `checkout`: The information required to checkout items and pay ([Documentation](https://shopify.dev/docs/storefront-api/reference/checkouts/checkout)). -- `shop`: Represents a collection of the general settings and information about the shop ([Documentation](https://shopify.dev/docs/storefront-api/reference/online-store/shop/index)). - -## Hooks - -### usePrice - -Display the product variant price according to currency and locale. - -```js -import usePrice from '@framework/product/use-price' - -const { price } = usePrice({ - amount, -}) -``` - -Takes in either `amount` or `variant`: - -- `amount`: A price value for a particular item if the amount is known. -- `variant`: A shopify product variant. Price will be extracted from the variant. - -### useAddItem - -```js -import { useAddItem } from '@framework/cart' - -const AddToCartButton = ({ variantId, quantity }) => { - const addItem = useAddItem() - - const addToCart = async () => { - await addItem({ - variantId, - }) - } - - return -} -``` - -### useRemoveItem - -```js -import { useRemoveItem } from '@framework/cart' - -const RemoveButton = ({ item }) => { - const removeItem = useRemoveItem() - - const handleRemove = async () => { - await removeItem({ id: item.id }) - } - - return -} -``` - -### useUpdateItem - -```js -import { useUpdateItem } from '@framework/cart' - -const CartItem = ({ item }) => { - const [quantity, setQuantity] = useState(item.quantity) - const updateItem = useUpdateItem(item) - - const updateQuantity = async (e) => { - const val = e.target.value - await updateItem({ quantity: val }) - } - - return ( - - ) -} -``` - -## APIs - -Collections of APIs to fetch data from a Shopify store. - -The data is fetched using the [Shopify JavaScript Buy SDK](https://github.com/Shopify/js-buy-sdk#readme). Read the [Shopify Storefront API reference](https://shopify.dev/docs/storefront-api/reference) for more information. - -### getProduct - -Get a single product by its `handle`. - -```js -import getProduct from '@framework/product/get-product' -import { getConfig } from '@framework/api' - -const config = getConfig() - -const product = await getProduct({ - variables: { slug }, - config, -}) -``` - -### getAllProducts - -```js -import getAllProducts from '@framework/product/get-all-products' -import { getConfig } from '@framework/api' - -const config = getConfig() - -const { products } = await getAllProducts({ - variables: { first: 12 }, - config, -}) -``` - -### getAllCollections - -```js -import getAllCollections from '@framework/product/get-all-collections' -import { getConfig } from '@framework/api' - -const config = getConfig() - -const collections = await getAllCollections({ - config, -}) -``` - -### getAllPages - -```js -import getAllPages from '@framework/common/get-all-pages' -import { getConfig } from '@framework/api' - -const config = getConfig() - -const pages = await getAllPages({ - variables: { first: 12 }, - config, -}) -``` diff --git a/tsconfig.json b/tsconfig.json index ffb74e388..e20f37099 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -22,8 +22,8 @@ "@components/*": ["components/*"], "@commerce": ["framework/commerce"], "@commerce/*": ["framework/commerce/*"], - "@framework": ["framework/swell"], - "@framework/*": ["framework/swell/*"] + "@framework": ["framework/shopify"], + "@framework/*": ["framework/shopify/*"] } }, "include": ["next-env.d.ts", "**/*.d.ts", "**/*.ts", "**/*.tsx", "**/*.js"], From 9675be154643b7302bbbad4196436c66b4613eaf Mon Sep 17 00:00:00 2001 From: Greg Hoskin Date: Tue, 11 May 2021 14:28:46 -0500 Subject: [PATCH 207/216] update swell consts, cleanup cart types --- .env.template | 4 ++-- framework/swell/api/utils/fetch-swell-api.ts | 2 +- framework/swell/cart/use-add-item.tsx | 3 +-- framework/swell/cart/use-remove-item.tsx | 16 ++++++---------- framework/swell/cart/use-update-item.tsx | 11 ++++------- framework/swell/common/get-all-pages.ts | 2 +- 6 files changed, 15 insertions(+), 23 deletions(-) diff --git a/.env.template b/.env.template index 9d8a57355..b68daaffe 100644 --- a/.env.template +++ b/.env.template @@ -11,5 +11,5 @@ BIGCOMMERCE_CHANNEL_ID= NEXT_PUBLIC_SHOPIFY_STORE_DOMAIN= NEXT_PUBLIC_SHOPIFY_STOREFRONT_ACCESS_TOKEN= -SWELL_STORE_ID= -SWELL_PUBLIC_KEY= \ No newline at end of file +NEXT_PUBLIC_SWELL_STORE_ID= +NEXT_PUBLIC_SWELL_PUBLIC_KEY= diff --git a/framework/swell/api/utils/fetch-swell-api.ts b/framework/swell/api/utils/fetch-swell-api.ts index e070483ae..d70b71954 100644 --- a/framework/swell/api/utils/fetch-swell-api.ts +++ b/framework/swell/api/utils/fetch-swell-api.ts @@ -1,4 +1,4 @@ -import { swellConfig } from '../../index' +import { swellConfig } from '../..' const fetchSwellApi = async ( query: string, diff --git a/framework/swell/cart/use-add-item.tsx b/framework/swell/cart/use-add-item.tsx index a86d2ab28..990514d42 100644 --- a/framework/swell/cart/use-add-item.tsx +++ b/framework/swell/cart/use-add-item.tsx @@ -5,7 +5,6 @@ import useCart from './use-cart' import { Cart, CartItemBody } from '../types' import { checkoutToCart } from './utils' import { getCheckoutId } from '../utils' -import { Mutation, MutationCheckoutLineItemsAddArgs } from '../schema' import { useCallback } from 'react' export default useAddItem as UseAddItem @@ -38,7 +37,7 @@ export const handler: MutationHook = { variables.variant_id = item.variantId } - const response = await fetch({ + const response = await fetch({ ...options, variables, }) diff --git a/framework/swell/cart/use-remove-item.tsx b/framework/swell/cart/use-remove-item.tsx index 13d137da4..8dc1ea713 100644 --- a/framework/swell/cart/use-remove-item.tsx +++ b/framework/swell/cart/use-remove-item.tsx @@ -13,10 +13,8 @@ import useRemoveItem, { } from '@commerce/cart/use-remove-item' import useCart from './use-cart' -import { checkoutLineItemRemoveMutation, getCheckoutId } from '../utils' import { checkoutToCart } from './utils' import { Cart, LineItem } from '../types' -import { Mutation, MutationCheckoutLineItemsRemoveArgs } from '../schema' import { RemoveCartItemBody } from '@commerce/types' export type RemoveItemFn = T extends LineItem @@ -39,12 +37,10 @@ export const handler = { options, fetch, }: HookFetcherContext) { - const response = await fetch( - { - ...options, - variables: [itemId], - } - ) + const response = await fetch({ + ...options, + variables: [itemId], + }) return checkoutToCart(response) }, useHook: ({ @@ -52,9 +48,9 @@ export const handler = { }: MutationHookContext) => < T extends LineItem | undefined = undefined >( - item + ctx: { item?: T } = {} ) => { - // const { item } = ctx + const { item } = ctx const { mutate } = useCart() const removeItem: RemoveItemFn = async (input) => { const itemId = input?.id ?? item?.id diff --git a/framework/swell/cart/use-update-item.tsx b/framework/swell/cart/use-update-item.tsx index 38ad65bf1..b74b65dc9 100644 --- a/framework/swell/cart/use-update-item.tsx +++ b/framework/swell/cart/use-update-item.tsx @@ -14,7 +14,6 @@ import useCart from './use-cart' import { handler as removeItemHandler } from './use-remove-item' import type { Cart, LineItem, UpdateCartItemBody } from '../types' import { checkoutToCart } from './utils' -import { Mutation, MutationCheckoutLineItemsUpdateArgs } from '../schema' export type UpdateItemInput = T extends LineItem ? Partial> @@ -46,12 +45,10 @@ export const handler = { message: 'The item quantity has to be a valid integer', }) } - const response = await fetch( - { - ...options, - variables: [item.itemId, { quantity: item.quantity }], - } - ) + const response = await fetch({ + ...options, + variables: [item.itemId, { quantity: item.quantity }], + }) return checkoutToCart(response) }, diff --git a/framework/swell/common/get-all-pages.ts b/framework/swell/common/get-all-pages.ts index 489af339c..99e07f6e6 100644 --- a/framework/swell/common/get-all-pages.ts +++ b/framework/swell/common/get-all-pages.ts @@ -25,7 +25,7 @@ const getAllPages = async (options?: { config = getConfig(config) const { locale, fetchSwell } = config const { results } = await fetchSwell('content', 'list', ['pages']) - const pages = results.map(({ slug, ...rest }) => ({ + const pages = results.map(({ slug, ...rest }: { slug: string }) => ({ url: `/${locale}/${slug}`, ...rest, })) From e7d0f56e85428edc5f1d26075d5adf6ff1bddd24 Mon Sep 17 00:00:00 2001 From: Greg Hoskin Date: Wed, 12 May 2021 11:23:04 -0500 Subject: [PATCH 208/216] fix checkout url, product w/ no images error --- framework/swell/utils/normalize.ts | 2 +- next.config.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/framework/swell/utils/normalize.ts b/framework/swell/utils/normalize.ts index a7a7be1ce..cc8eafdb7 100644 --- a/framework/swell/utils/normalize.ts +++ b/framework/swell/utils/normalize.ts @@ -60,7 +60,7 @@ const normalizeProductOption = ({ } const normalizeProductImages = (images: SwellImage[]) => { - if (!images) { + if (!images || images.length < 1) { return [{ url: '/' }] } return images?.map(({ file, ...rest }: SwellImage) => ({ diff --git a/next.config.js b/next.config.js index 1e1b1a126..e17d3e5c4 100644 --- a/next.config.js +++ b/next.config.js @@ -7,7 +7,7 @@ const { const provider = commerce.provider || getProviderName() const isBC = provider === 'bigcommerce' const isShopify = provider === 'shopify' -const isSwell = commerce.provider === 'swell' +const isSwell = provider === 'swell' module.exports = withCommerceConfig({ commerce, From bff94e73aedc21c2e1a10562c61b8b256c4c7630 Mon Sep 17 00:00:00 2001 From: cond0r Date: Thu, 13 May 2021 16:10:09 +0300 Subject: [PATCH 209/216] Fix build errors --- framework/swell/api/index.ts | 8 +- .../swell/api/utils/fetch-all-products.ts | 25 -- framework/swell/api/utils/fetch-swell-api.ts | 10 +- framework/swell/auth/use-signup.tsx | 4 - framework/swell/cart/use-cart.tsx | 24 +- framework/swell/cart/use-update-item.tsx | 3 +- .../swell/cart/utils/checkout-to-cart.ts | 5 +- framework/swell/common/get-all-pages.ts | 13 +- framework/swell/common/get-page.ts | 2 +- framework/swell/fetcher.ts | 11 +- .../swell/product/get-all-collections.ts | 2 +- .../swell/product/get-all-product-paths.ts | 15 +- framework/swell/product/get-all-products.ts | 2 +- framework/swell/product/get-product.ts | 4 +- framework/swell/types.ts | 2 +- framework/swell/utils/get-categories.ts | 8 +- framework/swell/utils/get-vendors.ts | 2 +- framework/swell/utils/normalize.ts | 7 +- pages/[...pages].tsx | 3 +- pages/search.tsx | 3 +- tsconfig.json | 4 +- yarn.lock | 388 +----------------- 22 files changed, 87 insertions(+), 458 deletions(-) delete mode 100644 framework/swell/api/utils/fetch-all-products.ts diff --git a/framework/swell/api/index.ts b/framework/swell/api/index.ts index 1e328062b..1494af9c7 100644 --- a/framework/swell/api/index.ts +++ b/framework/swell/api/index.ts @@ -6,11 +6,10 @@ import { SWELL_COOKIE_EXPIRE, } from '../const' -import fetcher from '../fetcher' -import fetchSwellApi from './utils/fetch-swell-api' +import fetchApi from './utils/fetch-swell-api' export interface SwellConfig extends CommerceAPIConfig { - fetchSwell: any + fetch: any } export class Config { @@ -38,8 +37,7 @@ const config = new Config({ apiToken: ''!, cartCookie: SWELL_CHECKOUT_ID_COOKIE, cartCookieMaxAge: SWELL_COOKIE_EXPIRE, - fetchSwell: fetchSwellApi, - fetch: fetcher, + fetch: fetchApi, customerCookie: SWELL_CUSTOMER_TOKEN_COOKIE, }) diff --git a/framework/swell/api/utils/fetch-all-products.ts b/framework/swell/api/utils/fetch-all-products.ts deleted file mode 100644 index 38ba5f6e3..000000000 --- a/framework/swell/api/utils/fetch-all-products.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { SwellConfig } from '..' -import { SwellProduct } from '../../types' - -const fetchAllProducts = async ({ - config, - query, - method, - variables, - acc = [], -}: { - config: SwellConfig - query: string - method: string - acc?: SwellProduct[] - variables?: any - cursor?: string -}): Promise => { - const response = await config.fetchSwell(query, method, variables) - - acc = acc.concat(response.results) - - return acc -} - -export default fetchAllProducts diff --git a/framework/swell/api/utils/fetch-swell-api.ts b/framework/swell/api/utils/fetch-swell-api.ts index d70b71954..65caed763 100644 --- a/framework/swell/api/utils/fetch-swell-api.ts +++ b/framework/swell/api/utils/fetch-swell-api.ts @@ -1,11 +1,7 @@ import { swellConfig } from '../..' -const fetchSwellApi = async ( - query: string, - method: string, - variables: [] = [] -) => { +const fetchApi = async (query: string, method: string, variables: [] = []) => { const { swell } = swellConfig - return await swell[query][method](...variables) + return swell[query][method](...variables) } -export default fetchSwellApi +export default fetchApi diff --git a/framework/swell/auth/use-signup.tsx b/framework/swell/auth/use-signup.tsx index a3dbf73a3..f01d45044 100644 --- a/framework/swell/auth/use-signup.tsx +++ b/framework/swell/auth/use-signup.tsx @@ -5,10 +5,6 @@ import useSignup, { UseSignup } from '@commerce/auth/use-signup' import useCustomer from '../customer/use-customer' import { CustomerCreateInput } from '../schema' -import { - customerCreateMutation, - customerAccessTokenCreateMutation, -} from '../utils/mutations' import handleLogin from '../utils/handle-login' export default useSignup as UseSignup diff --git a/framework/swell/cart/use-cart.tsx b/framework/swell/cart/use-cart.tsx index 354b4f947..531286ee6 100644 --- a/framework/swell/cart/use-cart.tsx +++ b/framework/swell/cart/use-cart.tsx @@ -1,27 +1,37 @@ import useCart, { UseCart } from '@commerce/cart/use-cart' import { Cart } from '@commerce/types' import { SWRHook } from '@commerce/utils/types' +import { useMemo } from 'react' import { normalizeCart } from '../utils/normalize' import { checkoutCreate, checkoutToCart } from './utils' export default useCart as UseCart -export const handler: SWRHook = { +export const handler: SWRHook = { fetchOptions: { query: 'cart', method: 'get', }, - async fetcher({ options, fetch }) { + async fetcher({ fetch }) { const cart = await checkoutCreate(fetch) return cart ? normalizeCart(cart) : null }, useHook: ({ useData }) => (input) => { - return useData({ - swrOptions: { - revalidateOnFocus: false, - ...input?.swrOptions, - }, + const response = useData({ + swrOptions: { revalidateOnFocus: false, ...input?.swrOptions }, }) + return useMemo( + () => + Object.create(response, { + isEmpty: { + get() { + return (response.data?.lineItems.length ?? 0) <= 0 + }, + enumerable: true, + }, + }), + [response] + ) }, } diff --git a/framework/swell/cart/use-update-item.tsx b/framework/swell/cart/use-update-item.tsx index b74b65dc9..e4261fc85 100644 --- a/framework/swell/cart/use-update-item.tsx +++ b/framework/swell/cart/use-update-item.tsx @@ -47,7 +47,7 @@ export const handler = { } const response = await fetch({ ...options, - variables: [item.itemId, { quantity: item.quantity }], + variables: [itemId, { quantity: item.quantity }], }) return checkoutToCart(response) @@ -79,7 +79,6 @@ export const handler = { const data = await fetch({ input: { item: { - itemId, productId, variantId, quantity: input.quantity, diff --git a/framework/swell/cart/utils/checkout-to-cart.ts b/framework/swell/cart/utils/checkout-to-cart.ts index 19a8bfd0b..d6dfda206 100644 --- a/framework/swell/cart/utils/checkout-to-cart.ts +++ b/framework/swell/cart/utils/checkout-to-cart.ts @@ -1,5 +1,5 @@ import { Cart } from '../../types' -import { CommerceError, ValidationError } from '@commerce/utils/errors' +import { CommerceError } from '@commerce/utils/errors' import { CheckoutLineItemsAddPayload, @@ -20,8 +20,7 @@ const checkoutToCart = (checkoutPayload?: Maybe): Cart => { message: 'Invalid response from Swell', }) } - - return normalizeCart(checkoutPayload) + return normalizeCart(checkoutPayload as any) } export default checkoutToCart diff --git a/framework/swell/common/get-all-pages.ts b/framework/swell/common/get-all-pages.ts index 99e07f6e6..8d0b9cf36 100644 --- a/framework/swell/common/get-all-pages.ts +++ b/framework/swell/common/get-all-pages.ts @@ -23,12 +23,13 @@ const getAllPages = async (options?: { }): Promise => { let { config, variables = { first: 250 } } = options ?? {} config = getConfig(config) - const { locale, fetchSwell } = config - const { results } = await fetchSwell('content', 'list', ['pages']) - const pages = results.map(({ slug, ...rest }: { slug: string }) => ({ - url: `/${locale}/${slug}`, - ...rest, - })) + const { locale, fetch } = config + const data = await fetch('content', 'list', ['pages']) + const pages = + data?.results?.map(({ slug, ...rest }: { slug: string }) => ({ + url: `/${locale}/${slug}`, + ...rest, + })) ?? [] return { pages } } diff --git a/framework/swell/common/get-page.ts b/framework/swell/common/get-page.ts index e5ca005e0..dca317a19 100644 --- a/framework/swell/common/get-page.ts +++ b/framework/swell/common/get-page.ts @@ -17,7 +17,7 @@ const getPage = async (options: { config = getConfig(config) const { locale } = config const { id } = variables - const result = await config.fetchSwell('content', 'get', ['pages', id]) + const result = await config.fetch('content', 'get', ['pages', id]) const page = result return { diff --git a/framework/swell/fetcher.ts b/framework/swell/fetcher.ts index e52d8fd54..f18dcf667 100644 --- a/framework/swell/fetcher.ts +++ b/framework/swell/fetcher.ts @@ -1,22 +1,27 @@ import { Fetcher } from '@commerce/utils/types' import { handleFetchResponse } from './utils' import { swellConfig } from './index' +import { CommerceError } from '@commerce/utils/errors' const fetcher: Fetcher = async ({ method = 'get', variables, query }) => { const { swell } = swellConfig + async function callSwell() { if (Array.isArray(variables)) { const arg1 = variables[0] const arg2 = variables[1] - const response = await swell[query][method](arg1, arg2) + const response = await swell[query!][method](arg1, arg2) return handleFetchResponse(response) } else { - const response = await swell[query][method](variables) + const response = await swell[query!][method](variables) return handleFetchResponse(response) } } - if (query in swell) { + + if (query && query in swell) { return await callSwell() + } else { + throw new CommerceError({ message: 'Invalid query argument!' }) } } diff --git a/framework/swell/product/get-all-collections.ts b/framework/swell/product/get-all-collections.ts index e6da3ade4..6b82ce449 100644 --- a/framework/swell/product/get-all-collections.ts +++ b/framework/swell/product/get-all-collections.ts @@ -9,7 +9,7 @@ const getAllCollections = async (options?: { let { config, variables = { limit: 25 } } = options ?? {} config = getConfig(config) - const response = await config.fetchSwell('categories', 'list', { variables }) + const response = await config.fetch('categories', 'list', { variables }) const edges = response.results ?? [] const categories = edges.map( diff --git a/framework/swell/product/get-all-product-paths.ts b/framework/swell/product/get-all-product-paths.ts index 3b95798e4..baa9ce8fe 100644 --- a/framework/swell/product/get-all-product-paths.ts +++ b/framework/swell/product/get-all-product-paths.ts @@ -1,5 +1,5 @@ +import { SwellProduct } from '@framework/types' import { getConfig, SwellConfig } from '../api' -import fetchAllProducts from '../api/utils/fetch-all-products' type ProductPath = { path: string @@ -21,15 +21,14 @@ const getAllProductPaths = async (options?: { let { config, variables = [{ limit: 100 }] } = options ?? {} config = getConfig(config) - const products = await fetchAllProducts({ - config, - query: 'products', - method: 'list', - variables, - }) + const { results } = await config.fetch('products', 'list', [ + { + limit: variables.first, + }, + ]) return { - products: products?.map(({ slug: handle }) => ({ + products: results?.map(({ slug: handle }: SwellProduct) => ({ node: { path: `/${handle}`, }, diff --git a/framework/swell/product/get-all-products.ts b/framework/swell/product/get-all-products.ts index a129c18a2..c0746efca 100644 --- a/framework/swell/product/get-all-products.ts +++ b/framework/swell/product/get-all-products.ts @@ -19,7 +19,7 @@ const getAllProducts = async (options: { }): Promise => { let { config, variables = { first: 250 } } = options ?? {} config = getConfig(config) - const { results } = await config.fetchSwell('products', 'list', [ + const { results } = await config.fetch('products', 'list', [ { limit: variables.first, }, diff --git a/framework/swell/product/get-product.ts b/framework/swell/product/get-product.ts index 15fde1cfa..0d75a57cd 100644 --- a/framework/swell/product/get-product.ts +++ b/framework/swell/product/get-product.ts @@ -18,10 +18,12 @@ const getProduct = async (options: { let { config, variables } = options ?? {} config = getConfig(config) - const product = await config.fetchSwell('products', 'get', [variables.slug]) + const product = await config.fetch('products', 'get', [variables.slug]) + if (product && product.variants) { product.variants = product.variants?.results } + return { product: product ? normalizeProduct(product) : null, } diff --git a/framework/swell/types.ts b/framework/swell/types.ts index 248ea3158..71848d4a4 100644 --- a/framework/swell/types.ts +++ b/framework/swell/types.ts @@ -90,7 +90,7 @@ export interface Cart extends Core.Cart { } export interface LineItem extends Core.LineItem { - options: any[] + options?: any[] } /** diff --git a/framework/swell/utils/get-categories.ts b/framework/swell/utils/get-categories.ts index 5b9ba501e..4372dde4e 100644 --- a/framework/swell/utils/get-categories.ts +++ b/framework/swell/utils/get-categories.ts @@ -1,15 +1,15 @@ import { SwellConfig } from '../api' export type Category = { - id: string + entityId: string name: string - slug: string + path: string } const getCategories = async (config: SwellConfig): Promise => { - const data = await config.fetchSwell('categories', 'get') + const data = await config.fetch('categories', 'get') return ( - data.results.map(({ id: entityId, name, slug }: Category) => ({ + data.results.map(({ id: entityId, name, slug }: any) => ({ entityId, name, path: `/${slug}`, diff --git a/framework/swell/utils/get-vendors.ts b/framework/swell/utils/get-vendors.ts index 9f2184fc3..1ede68835 100644 --- a/framework/swell/utils/get-vendors.ts +++ b/framework/swell/utils/get-vendors.ts @@ -13,7 +13,7 @@ export type Brands = BrandEdge[] const getVendors = async (config: SwellConfig) => { const vendors: [string] = - (await config.fetchSwell('attributes', 'get', ['brand']))?.values ?? [] + (await config.fetch('attributes', 'get', ['brand']))?.values ?? [] return [...new Set(vendors)].map((v) => ({ node: { diff --git a/framework/swell/utils/normalize.ts b/framework/swell/utils/normalize.ts index cc8eafdb7..5e54428ca 100644 --- a/framework/swell/utils/normalize.ts +++ b/framework/swell/utils/normalize.ts @@ -1,11 +1,6 @@ import { Product, Customer } from '@commerce/types' -import { - Checkout, - CheckoutLineItemEdge, - MoneyV2, - ProductOption, -} from '../schema' +import { MoneyV2, ProductOption } from '../schema' import type { Cart, diff --git a/pages/[...pages].tsx b/pages/[...pages].tsx index 67adb6287..3f39845b5 100644 --- a/pages/[...pages].tsx +++ b/pages/[...pages].tsx @@ -25,8 +25,7 @@ export async function getStaticProps({ const pageItem = pages.find((p) => (p.url ? getSlug(p.url) === slug : false)) const data = pageItem && - // TODO: Shopify - Fix this type - (await getPage({ variables: { id: pageItem.id! } as any, config, preview })) + (await getPage({ variables: { id: pageItem.id! }, config, preview })) const page = data?.page if (!page) { diff --git a/pages/search.tsx b/pages/search.tsx index da2edccd8..3b26e7a14 100644 --- a/pages/search.tsx +++ b/pages/search.tsx @@ -75,9 +75,8 @@ export default function Search({ const { data } = useSearch({ search: typeof q === 'string' ? q : '', - // TODO: Shopify - Fix this type + // @ts-ignore Swell - Fix this types categoryId: activeCategory?.entityId as any, - // TODO: Shopify - Fix this type brandId: (activeBrand as any)?.entityId, sort: typeof sort === 'string' ? sort : '', }) diff --git a/tsconfig.json b/tsconfig.json index e20f37099..ffb74e388 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -22,8 +22,8 @@ "@components/*": ["components/*"], "@commerce": ["framework/commerce"], "@commerce/*": ["framework/commerce/*"], - "@framework": ["framework/shopify"], - "@framework/*": ["framework/shopify/*"] + "@framework": ["framework/swell"], + "@framework/*": ["framework/swell/*"] } }, "include": ["next-env.d.ts", "**/*.d.ts", "**/*.ts", "**/*.tsx", "**/*.js"], diff --git a/yarn.lock b/yarn.lock index 8bc30e067..6a04c4ac7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1007,32 +1007,6 @@ resolved "https://registry.yarnpkg.com/@types/cookie/-/cookie-0.4.0.tgz#14f854c0f93d326e39da6e3b6f34f7d37513d108" integrity sha512-y7mImlc/rNkvCRmg8gC3/lj87S7pTUIJ6QGjwHR9WQJcFs+ZMTOaoPrkdFA/YdbuqVEmEbb5RdhVxMkAcgOnpg== -"@types/eslint-scope@^3.7.0": - version "3.7.0" - resolved "https://registry.yarnpkg.com/@types/eslint-scope/-/eslint-scope-3.7.0.tgz#4792816e31119ebd506902a482caec4951fabd86" - integrity sha512-O/ql2+rrCUe2W2rs7wMR+GqPRcgB6UiqN5RhrR5xruFlY7l9YLMn0ZkDzjoHLeiFkR8MCQZVudUuuvQ2BLC9Qw== - dependencies: - "@types/eslint" "*" - "@types/estree" "*" - -"@types/eslint@*": - version "7.2.6" - resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-7.2.6.tgz#5e9aff555a975596c03a98b59ecd103decc70c3c" - integrity sha512-I+1sYH+NPQ3/tVqCeUSBwTE/0heyvtXqpIopUUArlBm0Kpocb8FbMa3AZ/ASKIFpN3rnEx932TTXDbt9OXsNDw== - dependencies: - "@types/estree" "*" - "@types/json-schema" "*" - -"@types/estree@*": - version "0.0.46" - resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.46.tgz#0fb6bfbbeabd7a30880504993369c4bf1deab1fe" - integrity sha512-laIjwTQaD+5DukBZaygQ79K1Z0jb1bPEMRrkXSLjtCcZm+abyp5YbrqpSLzD42FwWW6gK/aS4NYpJ804nG2brg== - -"@types/estree@^0.0.45": - version "0.0.45" - resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.45.tgz#e9387572998e5ecdac221950dab3e8c3b16af884" - integrity sha512-jnqIUKDUqJbDIUxm0Uj7bnlMnRm1T/eZ9N+AVMqhPgzrba2GhGG5o/jCTwmdPK709nEZsGoMzXEDUjcXHa3W0g== - "@types/http-proxy-agent@^2.0.2": version "2.0.2" resolved "https://registry.yarnpkg.com/@types/http-proxy-agent/-/http-proxy-agent-2.0.2.tgz#942c1f35c7e1f0edd1b6ffae5d0f9051cfb32be1" @@ -1050,11 +1024,6 @@ resolved "https://registry.yarnpkg.com/@types/js-yaml/-/js-yaml-3.12.6.tgz#7f10c926aa41e189a2755c4c7fcf8e4573bd7ac1" integrity sha512-cK4XqrLvP17X6c0C8n4iTbT59EixqyXL3Fk8/Rsk4dF3oX4dg70gYUXrXVUUHpnsGMPNlTQMqf+TVmNPX6FmSQ== -"@types/json-schema@*", "@types/json-schema@^7.0.6": - version "7.0.7" - resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.7.tgz#98a993516c859eb0d5c4c8f098317a9ea68db9ad" - integrity sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA== - "@types/json-stable-stringify@^1.0.32": version "1.0.32" resolved "https://registry.yarnpkg.com/@types/json-stable-stringify/-/json-stable-stringify-1.0.32.tgz#121f6917c4389db3923640b2e68de5fa64dda88e" @@ -1200,161 +1169,6 @@ agentkeepalive "3.4.1" debug "3.1.0" -"@webassemblyjs/ast@1.9.1": - version "1.9.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.9.1.tgz#76c6937716d68bf1484c15139f5ed30b9abc8bb4" - integrity sha512-uMu1nCWn2Wxyy126LlGqRVlhdTOsO/bsBRI4dNq3+6SiSuRKRQX6ejjKgh82LoGAPSq72lDUiQ4FWVaf0PecYw== - dependencies: - "@webassemblyjs/helper-module-context" "1.9.1" - "@webassemblyjs/helper-wasm-bytecode" "1.9.1" - "@webassemblyjs/wast-parser" "1.9.1" - -"@webassemblyjs/floating-point-hex-parser@1.9.1": - version "1.9.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.9.1.tgz#9eb0ff90a1cdeef51f36ba533ed9f06b5cdadd09" - integrity sha512-5VEKu024RySmLKTTBl9q1eO/2K5jk9ZS+2HXDBLA9s9p5IjkaXxWiDb/+b7wSQp6FRdLaH1IVGIfOex58Na2pg== - -"@webassemblyjs/helper-api-error@1.9.1": - version "1.9.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.9.1.tgz#ad89015c4246cd7f5ed0556700237f8b9c2c752f" - integrity sha512-y1lGmfm38djrScwpeL37rRR9f1D6sM8RhMpvM7CYLzOlHVboouZokXK/G88BpzW0NQBSvCCOnW5BFhten4FPfA== - -"@webassemblyjs/helper-buffer@1.9.1": - version "1.9.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.9.1.tgz#186e67ac25f9546ea7939759413987f157524133" - integrity sha512-uS6VSgieHbk/m4GSkMU5cqe/5TekdCzQso4revCIEQ3vpGZgqSSExi4jWpTWwDpAHOIAb1Jfrs0gUB9AA4n71w== - -"@webassemblyjs/helper-code-frame@1.9.1": - version "1.9.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.9.1.tgz#aab177b7cc87a318a8f8664ad68e2c3828ebc42b" - integrity sha512-ZQ2ZT6Evk4DPIfD+92AraGYaFIqGm4U20e7FpXwl7WUo2Pn1mZ1v8VGH8i+Y++IQpxPbQo/UyG0Khs7eInskzA== - dependencies: - "@webassemblyjs/wast-printer" "1.9.1" - -"@webassemblyjs/helper-fsm@1.9.1": - version "1.9.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-fsm/-/helper-fsm-1.9.1.tgz#527e91628e84d13d3573884b3dc4c53a81dcb911" - integrity sha512-J32HGpveEqqcKFS0YbgicB0zAlpfIxJa5MjxDxhu3i5ltPcVfY5EPvKQ1suRguFPehxiUs+/hfkwPEXom/l0lw== - -"@webassemblyjs/helper-module-context@1.9.1": - version "1.9.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-module-context/-/helper-module-context-1.9.1.tgz#778670b3d471f7cf093d1e7c0dde431b54310e16" - integrity sha512-IEH2cMmEQKt7fqelLWB5e/cMdZXf2rST1JIrzWmf4XBt3QTxGdnnLvV4DYoN8pJjOx0VYXsWg+yF16MmJtolZg== - dependencies: - "@webassemblyjs/ast" "1.9.1" - -"@webassemblyjs/helper-wasm-bytecode@1.9.1": - version "1.9.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.9.1.tgz#563f59bcf409ccf469edde168b9426961ffbf6df" - integrity sha512-i2rGTBqFUcSXxyjt2K4vm/3kkHwyzG6o427iCjcIKjOqpWH8SEem+xe82jUk1iydJO250/CvE5o7hzNAMZf0dQ== - -"@webassemblyjs/helper-wasm-section@1.9.1": - version "1.9.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.9.1.tgz#f7988f94c12b01b99a16120cb01dc099b00e4798" - integrity sha512-FetqzjtXZr2d57IECK+aId3D0IcGweeM0CbAnJHkYJkcRTHP+YcMb7Wmc0j21h5UWBpwYGb9dSkK/93SRCTrGg== - dependencies: - "@webassemblyjs/ast" "1.9.1" - "@webassemblyjs/helper-buffer" "1.9.1" - "@webassemblyjs/helper-wasm-bytecode" "1.9.1" - "@webassemblyjs/wasm-gen" "1.9.1" - -"@webassemblyjs/ieee754@1.9.1": - version "1.9.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.9.1.tgz#3b715871ca7d75784717cf9ceca9d7b81374b8af" - integrity sha512-EvTG9M78zP1MmkBpUjGQHZc26DzPGZSLIPxYHCjQsBMo60Qy2W34qf8z0exRDtxBbRIoiKa5dFyWer/7r1aaSQ== - dependencies: - "@xtuc/ieee754" "^1.2.0" - -"@webassemblyjs/leb128@1.9.1": - version "1.9.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.9.1.tgz#b2ecaa39f9e8277cc9c707c1ca8b2aa7b27d0b72" - integrity sha512-Oc04ub0vFfLnF+2/+ki3AE+anmW4sv9uNBqb+79fgTaPv6xJsOT0dhphNfL3FrME84CbX/D1T9XT8tjFo0IIiw== - dependencies: - "@xtuc/long" "4.2.2" - -"@webassemblyjs/utf8@1.9.1": - version "1.9.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.9.1.tgz#d02d9daab85cda3211e43caf31dca74c260a73b0" - integrity sha512-llkYtppagjCodFjo0alWOUhAkfOiQPQDIc5oA6C9sFAXz7vC9QhZf/f8ijQIX+A9ToM3c9Pq85X0EX7nx9gVhg== - -"@webassemblyjs/wasm-edit@1.9.1": - version "1.9.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.9.1.tgz#e27a6bdbf78e5c72fa812a2fc3cbaad7c3e37578" - integrity sha512-S2IaD6+x9B2Xi8BCT0eGsrXXd8UxAh2LVJpg1ZMtHXnrDcsTtIX2bDjHi40Hio6Lc62dWHmKdvksI+MClCYbbw== - dependencies: - "@webassemblyjs/ast" "1.9.1" - "@webassemblyjs/helper-buffer" "1.9.1" - "@webassemblyjs/helper-wasm-bytecode" "1.9.1" - "@webassemblyjs/helper-wasm-section" "1.9.1" - "@webassemblyjs/wasm-gen" "1.9.1" - "@webassemblyjs/wasm-opt" "1.9.1" - "@webassemblyjs/wasm-parser" "1.9.1" - "@webassemblyjs/wast-printer" "1.9.1" - -"@webassemblyjs/wasm-gen@1.9.1": - version "1.9.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.9.1.tgz#56a0787d1fa7994fdc7bea59004e5bec7189c5fc" - integrity sha512-bqWI0S4lBQsEN5FTZ35vYzfKUJvtjNnBobB1agCALH30xNk1LToZ7Z8eiaR/Z5iVECTlBndoRQV3F6mbEqE/fg== - dependencies: - "@webassemblyjs/ast" "1.9.1" - "@webassemblyjs/helper-wasm-bytecode" "1.9.1" - "@webassemblyjs/ieee754" "1.9.1" - "@webassemblyjs/leb128" "1.9.1" - "@webassemblyjs/utf8" "1.9.1" - -"@webassemblyjs/wasm-opt@1.9.1": - version "1.9.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.9.1.tgz#fbdf8943a825e6dcc4cd69c3e092289fa4aec96c" - integrity sha512-gSf7I7YWVXZ5c6XqTEqkZjVs8K1kc1k57vsB6KBQscSagDNbAdxt6MwuJoMjsE1yWY1tsuL+pga268A6u+Fdkg== - dependencies: - "@webassemblyjs/ast" "1.9.1" - "@webassemblyjs/helper-buffer" "1.9.1" - "@webassemblyjs/wasm-gen" "1.9.1" - "@webassemblyjs/wasm-parser" "1.9.1" - -"@webassemblyjs/wasm-parser@1.9.1": - version "1.9.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.9.1.tgz#5e8352a246d3f605312c8e414f7990de55aaedfa" - integrity sha512-ImM4N2T1MEIond0MyE3rXvStVxEmivQrDKf/ggfh5pP6EHu3lL/YTAoSrR7shrbKNPpeKpGesW1LIK/L4kqduw== - dependencies: - "@webassemblyjs/ast" "1.9.1" - "@webassemblyjs/helper-api-error" "1.9.1" - "@webassemblyjs/helper-wasm-bytecode" "1.9.1" - "@webassemblyjs/ieee754" "1.9.1" - "@webassemblyjs/leb128" "1.9.1" - "@webassemblyjs/utf8" "1.9.1" - -"@webassemblyjs/wast-parser@1.9.1": - version "1.9.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-parser/-/wast-parser-1.9.1.tgz#e25ef13585c060073c1db0d6bd94340fdeee7596" - integrity sha512-2xVxejXSvj3ls/o2TR/zI6p28qsGupjHhnHL6URULQRcXmryn3w7G83jQMcT7PHqUfyle65fZtWLukfdLdE7qw== - dependencies: - "@webassemblyjs/ast" "1.9.1" - "@webassemblyjs/floating-point-hex-parser" "1.9.1" - "@webassemblyjs/helper-api-error" "1.9.1" - "@webassemblyjs/helper-code-frame" "1.9.1" - "@webassemblyjs/helper-fsm" "1.9.1" - "@xtuc/long" "4.2.2" - -"@webassemblyjs/wast-printer@1.9.1": - version "1.9.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.9.1.tgz#b9f38e93652037d4f3f9c91584635af4191ed7c1" - integrity sha512-tDV8V15wm7mmbAH6XvQRU1X+oPGmeOzYsd6h7hlRLz6QpV4Ec/KKxM8OpLtFmQPLCreGxTp+HuxtH4pRIZyL9w== - dependencies: - "@webassemblyjs/ast" "1.9.1" - "@webassemblyjs/wast-parser" "1.9.1" - "@xtuc/long" "4.2.2" - -"@xtuc/ieee754@^1.2.0": - version "1.2.0" - resolved "https://registry.yarnpkg.com/@xtuc/ieee754/-/ieee754-1.2.0.tgz#eef014a3145ae477a1cbc00cd1e552336dceb790" - integrity sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA== - -"@xtuc/long@4.2.2": - version "4.2.2" - resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.2.tgz#d291c6a4e97989b5c61d9acf396ae4fe133a718d" - integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ== - "@zeit/dns-cached-resolve@2.1.0": version "2.1.0" resolved "https://registry.yarnpkg.com/@zeit/dns-cached-resolve/-/dns-cached-resolve-2.1.0.tgz#78583010df1683fdb7b05949b75593c9a8641bc1" @@ -1417,12 +1231,7 @@ aggregate-error@^3.0.0: clean-stack "^2.0.0" indent-string "^4.0.0" -ajv-keywords@^3.5.2: - version "3.5.2" - resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz#31f29da5ab6e00d1c2d329acf7b5929614d5014d" - integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ== - -ajv@^6.12.5, ajv@^6.12.6: +ajv@^6.12.6: version "6.12.6" resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== @@ -1518,6 +1327,14 @@ argparse@^1.0.7: dependencies: sprintf-js "~1.0.2" +array-includes-with-glob@^3.0.6: + version "3.0.16" + resolved "https://registry.yarnpkg.com/array-includes-with-glob/-/array-includes-with-glob-3.0.16.tgz#fdf2bf1e914cb9b95bd2a866194ede0ab3225d7b" + integrity sha512-uFwmmz78W4WzmMsLKojbCA2q5EbqugWFMm5zDyO+SSR6eW1rqzoxramiTCJYq1o/NZijt1szOJMA29JHZuU34A== + dependencies: + "@babel/runtime" "^7.13.10" + matcher "^4.0.0" + array-union@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" @@ -1826,7 +1643,7 @@ browserslist@4.16.1: escalade "^3.1.1" node-releases "^1.1.69" -browserslist@^4.12.0, browserslist@^4.14.5, browserslist@^4.16.1, browserslist@^4.6.4: +browserslist@^4.12.0, browserslist@^4.16.1, browserslist@^4.6.4: version "4.16.3" resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.16.3.tgz#340aa46940d7db878748567c5dea24a48ddf3717" integrity sha512-vIyhWmIkULaq04Gt93txdh+j02yX/JzlyhLYbV3YQCn/zvES3JnY7TifHHvvr1w5hTDluNKMkV05cs4vy8Q7sw== @@ -2023,13 +1840,6 @@ chokidar@3.5.1, chokidar@^3.4.3: optionalDependencies: fsevents "~2.3.1" -chrome-trace-event@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz#234090ee97c7d4ad1a2c4beae27505deffc608a4" - integrity sha512-9e/zx1jw7B4CO+c/RXoCsfg/x1AfUBioy4owYH0bJprEYAx5hRFLRhWBqHAG57D0ZM4H7vxbP7bPe0VwhQRYDQ== - dependencies: - tslib "^1.9.0" - ci-info@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46" @@ -2180,7 +1990,7 @@ combined-stream@^1.0.6, combined-stream@^1.0.8: dependencies: delayed-stream "~1.0.0" -commander@^2.13.0, commander@^2.16.0, commander@^2.20.0, commander@^2.20.3, commander@^2.8.1: +commander@^2.13.0, commander@^2.16.0, commander@^2.20.3, commander@^2.8.1: version "2.20.3" resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== @@ -2511,11 +2321,6 @@ dedent@^0.7.0: resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c" integrity sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw= -dedent@^0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c" - integrity sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw= - deep-extend@^0.6.0: version "0.6.0" resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" @@ -2526,7 +2331,7 @@ deep-is@~0.1.3: resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ= -deepmerge@^4.2.2: +deepmerge@4.2.2, deepmerge@^4.2.2: version "4.2.2" resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.2.2.tgz#44d2ea3679b8f4d4ffba33f03d865fc1e7bf4955" integrity sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg== @@ -2820,14 +2625,6 @@ enhanced-resolve@^4.0.0, enhanced-resolve@^4.1.0: memory-fs "^0.5.0" tapable "^1.0.0" -enhanced-resolve@^5.3.1: - version "5.7.0" - resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.7.0.tgz#525c5d856680fbd5052de453ac83e32049958b5c" - integrity sha512-6njwt/NsZFUKhM6j9U8hzVyD4E4r0x7NQzhTCbcWOJ0IQjNSAoalWmb0AE51Wn+fwan5qVESWi7t2ToBxs9vrw== - dependencies: - graceful-fs "^4.2.4" - tapable "^2.2.0" - enquirer@^2.3.6: version "2.3.6" resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.3.6.tgz#2a7fe5dd634a1e4125a975ec994ff5456dc3734d" @@ -2905,14 +2702,6 @@ escodegen@^1.8.0: optionalDependencies: source-map "~0.6.1" -eslint-scope@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" - integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== - dependencies: - esrecurse "^4.3.0" - estraverse "^4.1.1" - eslint-visitor-keys@^1.1.0: version "1.3.0" resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz#30ebd1ef7c2fdff01c3a4f151044af25fab0523e" @@ -2923,23 +2712,11 @@ esprima@4.0.1, esprima@^4.0.0, esprima@^4.0.1: resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== -esrecurse@^4.3.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" - integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== - dependencies: - estraverse "^5.2.0" - -estraverse@^4.1.1, estraverse@^4.2.0: +estraverse@^4.2.0: version "4.3.0" resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== -estraverse@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.2.0.tgz#307df42547e6cc7324d3cf03c155d5cdb8c53880" - integrity sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ== - esutils@^2.0.2: version "2.0.3" resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" @@ -2950,7 +2727,7 @@ etag@1.8.1: resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc= -events@^3.0.0, events@^3.2.0: +events@^3.0.0: version "3.2.0" resolved "https://registry.yarnpkg.com/events/-/events-3.2.0.tgz#93b87c18f8efcd4202a461aec4dfc0556b639379" integrity sha512-/46HWwbfCX2xTawVfkKLGxMifJYQBWMwY1mjywRtb4c9x8l5NP3KoJtnIOiL1hfdRkIuYhETxQlo62IF8tcnlg== @@ -3326,7 +3103,7 @@ got@^9.6.0: to-readable-stream "^1.0.0" url-parse-lax "^3.0.0" -graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.4: +graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0: version "4.2.6" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.6.tgz#ff040b2b0853b23c3d31027523706f1885d76bee" integrity sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ== @@ -3876,15 +3653,6 @@ jest-worker@24.9.0: merge-stream "^2.0.0" supports-color "^6.1.0" -jest-worker@^26.6.2: - version "26.6.2" - resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-26.6.2.tgz#7f72cbc4d643c365e27b9fd775f9d0eaa9c7a8ed" - integrity sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ== - dependencies: - "@types/node" "*" - merge-stream "^2.0.0" - supports-color "^7.0.0" - js-cookie@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/js-cookie/-/js-cookie-2.2.1.tgz#69e106dc5d5806894562902aa5baec3744e9b2b8" @@ -3913,11 +3681,6 @@ json-buffer@3.0.0: resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.0.tgz#5b1f397afc75d677bde8bcfc0e47e1f9a3d9a898" integrity sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg= -json-parse-better-errors@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" - integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw== - json-parse-even-better-errors@^2.3.0: version "2.3.1" resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" @@ -4129,11 +3892,6 @@ listr@^0.14.3: p-map "^2.0.0" rxjs "^6.3.3" -loader-runner@^4.1.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-4.2.0.tgz#d7022380d66d14c5fb1d496b89864ebcfd478384" - integrity sha512-92+huvxMvYlMzMt0iIOukcwYBFpkYJdpl2xsZ7LrlayO7E8SOv+JJUEK17B/dJIHAOLMfh2dZZ/Y18WgmGtYNw== - loader-utils@1.2.3: version "1.2.3" resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.2.3.tgz#1ff5dc6911c9f0a062531a4c04b609406108c2c7" @@ -4499,7 +4257,7 @@ mime-db@1.45.0: resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.45.0.tgz#cceeda21ccd7c3a745eba2decd55d4b73e7879ea" integrity sha512-CkqLUxUk15hofLoLyljJSrukZi8mAtgd+yE5uO4tqRZsdsAJKv0O+rFMhVDRJgozy+yG6md5KwuXhD4ocIoP+w== -mime-types@^2.1.12, mime-types@^2.1.27: +mime-types@^2.1.12: version "2.1.28" resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.28.tgz#1160c4757eab2c5363888e005273ecf79d2a0ecd" integrity sha512-0TO2yJ5YHYr7M2zzT7gDU1tbwHxEUWBCLt0lscSNpcdAfFyJOVEpRYNS7EXVcTLNj/25QO8gulHC5JtTzSE2UQ== @@ -4624,11 +4382,6 @@ native-url@0.3.4: dependencies: querystring "^0.2.0" -neo-async@^2.6.2: - version "2.6.2" - resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" - integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== - next-seo@^4.11.0: version "4.19.0" resolved "https://registry.yarnpkg.com/next-seo/-/next-seo-4.19.0.tgz#b3be79a544e420dbbf1e4fcff98dad9790f15e36" @@ -4960,7 +4713,7 @@ p-limit@3.0.2: dependencies: p-try "^2.0.0" -p-limit@3.1.0, p-limit@^3.0.2, p-limit@^3.1.0: +p-limit@3.1.0, p-limit@^3.0.2: version "3.1.0" resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== @@ -5727,7 +5480,7 @@ quick-lru@^4.0.1: resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-4.0.1.tgz#5b8878f113a58217848c6482026c73e1ba57727f" integrity sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g== -randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5, randombytes@^2.1.0: +randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5: version "2.1.0" resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== @@ -6074,15 +5827,6 @@ scheduler@^0.20.1: loose-envify "^1.1.0" object-assign "^4.1.1" -schema-utils@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-3.0.0.tgz#67502f6aa2b66a2d4032b4279a2944978a0913ef" - integrity sha512-6D82/xSzO094ajanoOSbe4YvXWMfn2A//8Y1+MUqFAJul5Bs+yn36xbK9OtNDcRVSBJ9jjeoXftM6CfztsjOAA== - dependencies: - "@types/json-schema" "^7.0.6" - ajv "^6.12.5" - ajv-keywords "^3.5.2" - scuid@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/scuid/-/scuid-1.1.0.tgz#d3f9f920956e737a60f72d0e4ad280bf324d5dab" @@ -6115,13 +5859,6 @@ semver@^7.3.2: dependencies: lru-cache "^6.0.0" -serialize-javascript@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-5.0.1.tgz#7886ec848049a462467a97d3d918ebb2aaf934f4" - integrity sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA== - dependencies: - randombytes "^2.1.0" - set-blocking@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" @@ -6162,18 +5899,6 @@ shebang-regex@^3.0.0: resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== -shebang-command@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" - integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== - dependencies: - shebang-regex "^3.0.0" - -shebang-regex@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" - integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== - shell-quote@1.7.2: version "1.7.2" resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.7.2.tgz#67a7d02c76c9da24f99d20808fcaded0e0e04be2" @@ -6238,12 +5963,7 @@ slice-ansi@^4.0.0: astral-regex "^2.0.0" is-fullwidth-code-point "^3.0.0" -source-list-map@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.1.tgz#3993bd873bfc48479cca9ea3a547835c7c154b34" - integrity sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw== - -source-map-support@^0.5.17, source-map-support@~0.5.19: +source-map-support@^0.5.17: version "0.5.19" resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.19.tgz#a98b62f86dcaf4f67399648c085291ab9e8fed61" integrity sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw== @@ -6251,7 +5971,7 @@ source-map-support@^0.5.17, source-map-support@~0.5.19: buffer-from "^1.0.0" source-map "^0.6.0" -source-map@0.7.3, source-map@~0.7.2: +source-map@0.7.3: version "0.7.3" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383" integrity sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ== @@ -6529,7 +6249,7 @@ supports-color@^6.1.0: dependencies: has-flag "^3.0.0" -supports-color@^7.0.0, supports-color@^7.1.0: +supports-color@^7.1.0: version "7.2.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== @@ -6605,37 +6325,11 @@ tapable@^1.0.0: resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.1.3.tgz#a1fccc06b58db61fd7a45da2da44f5f3a3e67ba2" integrity sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA== -tapable@^2.1.1, tapable@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.0.tgz#5c373d281d9c672848213d0e037d1c4165ab426b" - integrity sha512-FBk4IesMV1rBxX2tfiK8RAmogtWn53puLOQlvO8XuwlgxcYbP4mVPS9Ph4aeamSyyVjOl24aYWAuc8U5kCVwMw== - temp@~0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/temp/-/temp-0.4.0.tgz#671ad63d57be0fe9d7294664b3fc400636678a60" integrity sha1-ZxrWPVe+D+nXKUZks/xABjZnimA= -terser-webpack-plugin@^5.0.3: - version "5.1.1" - resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.1.1.tgz#7effadee06f7ecfa093dbbd3e9ab23f5f3ed8673" - integrity sha512-5XNNXZiR8YO6X6KhSGXfY0QrGrCRlSwAEjIIrlRQR4W8nP69TaJUlh3bkuac6zzgspiGPfKEHcY295MMVExl5Q== - dependencies: - jest-worker "^26.6.2" - p-limit "^3.1.0" - schema-utils "^3.0.0" - serialize-javascript "^5.0.1" - source-map "^0.6.1" - terser "^5.5.1" - -terser@^5.5.1: - version "5.6.0" - resolved "https://registry.yarnpkg.com/terser/-/terser-5.6.0.tgz#138cdf21c5e3100b1b3ddfddf720962f88badcd2" - integrity sha512-vyqLMoqadC1uR0vywqOZzriDYzgEkNJFK4q9GeyOBHIbiECHiWLKcWfbQWAUaPfxkjDhapSlZB9f7fkMrvkVjA== - dependencies: - commander "^2.20.0" - source-map "~0.7.2" - source-map-support "~0.5.19" - through@^2.3.6, through@^2.3.8: version "2.3.8" resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" @@ -6946,7 +6640,7 @@ warning@^4.0.3: dependencies: loose-envify "^1.0.0" -watchpack@2.1.1, watchpack@^2.0.0: +watchpack@2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.1.1.tgz#e99630550fca07df9f90a06056987baa40a689c7" integrity sha512-Oo7LXCmc1eE1AjyuSBmtC3+Wy4HcV8PxWh2kP6fOl8yTlNS7r0K9l1ao2lrrUza7V39Y3D/BbJgY8VeSlc5JKw== @@ -6981,44 +6675,6 @@ webpack-bundle-analyzer@4.3.0: sirv "^1.0.7" ws "^7.3.1" -webpack-sources@^2.1.1: - version "2.2.0" - resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-2.2.0.tgz#058926f39e3d443193b6c31547229806ffd02bac" - integrity sha512-bQsA24JLwcnWGArOKUxYKhX3Mz/nK1Xf6hxullKERyktjNMC4x8koOeaDNTA2fEJ09BdWLbM/iTW0ithREUP0w== - dependencies: - source-list-map "^2.0.1" - source-map "^0.6.1" - -webpack@5.11.1: - version "5.11.1" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.11.1.tgz#39b2b9daeb5c6c620e03b7556ec674eaed4016b4" - integrity sha512-tNUIdAmYJv+nupRs/U/gqmADm6fgrf5xE+rSlSsf2PgsGO7j2WG7ccU6AWNlOJlHFl+HnmXlBmHIkiLf+XA9mQ== - dependencies: - "@types/eslint-scope" "^3.7.0" - "@types/estree" "^0.0.45" - "@webassemblyjs/ast" "1.9.1" - "@webassemblyjs/helper-module-context" "1.9.1" - "@webassemblyjs/wasm-edit" "1.9.1" - "@webassemblyjs/wasm-parser" "1.9.1" - acorn "^8.0.4" - browserslist "^4.14.5" - chrome-trace-event "^1.0.2" - enhanced-resolve "^5.3.1" - eslint-scope "^5.1.1" - events "^3.2.0" - glob-to-regexp "^0.4.1" - graceful-fs "^4.2.4" - json-parse-better-errors "^1.0.2" - loader-runner "^4.1.0" - mime-types "^2.1.27" - neo-async "^2.6.2" - pkg-dir "^5.0.0" - schema-utils "^3.0.0" - tapable "^2.1.1" - terser-webpack-plugin "^5.0.3" - watchpack "^2.0.0" - webpack-sources "^2.1.1" - whatwg-fetch@^3.4.1: version "3.5.0" resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-3.5.0.tgz#605a2cd0a7146e5db141e29d1c62ab84c0c4c868" From 926db9f4ad2b7dd1a0abbfb2b54a6d7af9eecfc8 Mon Sep 17 00:00:00 2001 From: cond0r Date: Thu, 13 May 2021 16:14:21 +0300 Subject: [PATCH 210/216] Create README.md --- README.md | 123 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 123 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 000000000..941b1699b --- /dev/null +++ b/README.md @@ -0,0 +1,123 @@ +[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/git/external?repository-url=https%3A%2F%2Fgithub.com%2Fvercel%2Fcommerce&project-name=commerce&repo-name=commerce&demo-title=Next.js%20Commerce&demo-description=An%20all-in-one%20starter%20kit%20for%20high-performance%20e-commerce%20sites.&demo-url=https%3A%2F%2Fdemo.vercel.store&demo-image=https%3A%2F%2Fbigcommerce-demo-asset-ksvtgfvnd.vercel.app%2Fbigcommerce.png&integration-ids=oac_MuWZiE4jtmQ2ejZQaQ7ncuDT) + +# Next.js Commerce + +The all-in-one starter kit for high-performance e-commerce sites. With a few clicks, Next.js developers can clone, deploy and fully customize their own store. +Start right now at [nextjs.org/commerce](https://nextjs.org/commerce) + +Demo live at: [demo.vercel.store](https://demo.vercel.store/) + +- Shopify Demo: https://shopify.demo.vercel.store/ +- BigCommerce Demo: https://bigcommerce.demo.vercel.store/ + +## Features + +- Performant by default +- SEO Ready +- Internationalization +- Responsive +- UI Components +- Theming +- Standardized Data Hooks +- Integrations - Integrate seamlessly with the most common ecommerce platforms. +- Dark Mode Support + +## Integrations + +Next.js Commerce integrates out-of-the-box with BigCommerce and Shopify. We plan to support all major ecommerce backends. + +## Considerations + +- `framework/commerce` contains all types, helpers and functions to be used as base to build a new **provider**. +- **Providers** live under `framework`'s root folder and they will extend Next.js Commerce types and functionality (`framework/commerce`). +- We have a **Features API** to ensure feature parity between the UI and the Provider. The UI should update accordingly and no extra code should be bundled. All extra configuration for features will live under `features` in `commerce.config.json` and if needed it can also be accessed programatically. +- Each **provider** should add its corresponding `next.config.js` and `commerce.config.json` adding specific data related to the provider. For example in case of BigCommerce, the images CDN and additional API routes. +- **Providers don't depend on anything that's specific to the application they're used in**. They only depend on `framework/commerce`, on their own framework folder and on some dependencies included in `package.json` + +## Configuration + +### How to change providers + +Open `.env.local` and change the value of `COMMERCE_PROVIDER` to the provider you would like to use, then set the environment variables for that provider (use `.env.template` as the base). + +### Features + +Every provider defines the features that it supports under `framework/{provider}/commerce.config.json` + +#### How to turn Features on and off + +> NOTE: The selected provider should support the feature that you are toggling. (This means that you can't turn wishlist on if the provider doesn't support this functionality out the box) + +- Open `commerce.config.json` +- You'll see a config file like this: + ```json + { + "features": { + "wishlist": false + } + } + ``` +- Turn wishlist on by setting wishlist to true. +- Run the app and the wishlist functionality should be back on. + +### How to create a new provider + +Follow our docs for [Adding a new Commerce Provider](framework/commerce/new-provider.md). + +If you succeeded building a provider, submit a PR with a valid demo and we'll review it asap. + +## Contribute + +Our commitment to Open Source can be found [here](https://vercel.com/oss). + +1. [Fork](https://help.github.com/articles/fork-a-repo/) this repository to your own GitHub account and then [clone](https://help.github.com/articles/cloning-a-repository/) it to your local device. +2. Create a new branch `git checkout -b MY_BRANCH_NAME` +3. Install yarn: `npm install -g yarn` +4. Install the dependencies: `yarn` +5. Duplicate `.env.template` and rename it to `.env.local` +6. Add proper store values to `.env.local` +7. Run `yarn dev` to build and watch for code changes + +## Work in progress + +We're using Github Projects to keep track of issues in progress and todo's. Here is our [Board](https://github.com/vercel/commerce/projects/1) + +People actively working on this project: @okbel & @lfades. + +## Troubleshoot + +
      +I already own a BigCommerce store. What should I do? +
      +First thing you do is: set your environment variables +
      +
      +.env.local + +```sh +BIGCOMMERCE_STOREFRONT_API_URL=<> +BIGCOMMERCE_STOREFRONT_API_TOKEN=<> +BIGCOMMERCE_STORE_API_URL=<> +BIGCOMMERCE_STORE_API_TOKEN=<> +BIGCOMMERCE_STORE_API_CLIENT_ID=<> +BIGCOMMERCE_CHANNEL_ID=<> +``` + +If your project was started with a "Deploy with Vercel" button, you can use Vercel's CLI to retrieve these credentials. + +1. Install Vercel CLI: `npm i -g vercel` +2. Link local instance with Vercel and Github accounts (creates .vercel file): `vercel link` +3. Download your environment variables: `vercel env pull .env.local` + +Next, you're free to customize the starter. More updates coming soon. Stay tuned. + +
      + +
      +BigCommerce shows a Coming Soon page and requests a Preview Code +
      +After Email confirmation, Checkout should be manually enabled through BigCommerce platform. Look for "Review & test your store" section through BigCommerce's dashboard. +
      +
      +BigCommerce team has been notified and they plan to add more detailed about this subject. +
      From 48306052ecf2c58d34989dbccfed709e0a6812a2 Mon Sep 17 00:00:00 2001 From: cond0r Date: Thu, 13 May 2021 16:29:24 +0300 Subject: [PATCH 211/216] Update tsconfig.json --- tsconfig.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tsconfig.json b/tsconfig.json index ffb74e388..9e712fb18 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -22,8 +22,8 @@ "@components/*": ["components/*"], "@commerce": ["framework/commerce"], "@commerce/*": ["framework/commerce/*"], - "@framework": ["framework/swell"], - "@framework/*": ["framework/swell/*"] + "@framework": ["framework/bigcommerce"], + "@framework/*": ["framework/bigcommerce/*"] } }, "include": ["next-env.d.ts", "**/*.d.ts", "**/*.ts", "**/*.tsx", "**/*.js"], From b852cd477902cd5284628e32d6d9a26ea7ed1ebe Mon Sep 17 00:00:00 2001 From: cond0r Date: Thu, 13 May 2021 16:30:30 +0300 Subject: [PATCH 212/216] Update get-all-product-paths.ts --- framework/swell/product/get-all-product-paths.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/framework/swell/product/get-all-product-paths.ts b/framework/swell/product/get-all-product-paths.ts index baa9ce8fe..933eb73bc 100644 --- a/framework/swell/product/get-all-product-paths.ts +++ b/framework/swell/product/get-all-product-paths.ts @@ -1,4 +1,4 @@ -import { SwellProduct } from '@framework/types' +import { SwellProduct } from '../types' import { getConfig, SwellConfig } from '../api' type ProductPath = { From d981475818fd1b7880440ea79b036dc19fb7178e Mon Sep 17 00:00:00 2001 From: cond0r Date: Thu, 13 May 2021 17:00:10 +0300 Subject: [PATCH 213/216] Default to Bigcommerce --- pages/search.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/pages/search.tsx b/pages/search.tsx index 3b26e7a14..78f784572 100644 --- a/pages/search.tsx +++ b/pages/search.tsx @@ -75,8 +75,7 @@ export default function Search({ const { data } = useSearch({ search: typeof q === 'string' ? q : '', - // @ts-ignore Swell - Fix this types - categoryId: activeCategory?.entityId as any, + categoryId: activeCategory?.entityId, brandId: (activeBrand as any)?.entityId, sort: typeof sort === 'string' ? sort : '', }) From c8cf6e733c834d374e9f437e754f0c958162ce28 Mon Sep 17 00:00:00 2001 From: Greg Hoskin Date: Sun, 16 May 2021 13:31:57 -0700 Subject: [PATCH 214/216] fix error from missing product imgages --- framework/swell/utils/normalize.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/framework/swell/utils/normalize.ts b/framework/swell/utils/normalize.ts index 5e54428ca..8dc7d0e28 100644 --- a/framework/swell/utils/normalize.ts +++ b/framework/swell/utils/normalize.ts @@ -198,7 +198,10 @@ function normalizeLineItem({ sku: variant?.sku ?? '', name: variant?.name!, image: { - url: product && product.images ? product?.images[0].file.url : '', + url: + product?.images && product.images.length > 0 + ? product?.images[0].file.url + : '/', }, requiresShipping: false, price: price, From 7d62e7ce18337743f5e834c32cf6878e8fb4b617 Mon Sep 17 00:00:00 2001 From: Greg Hoskin Date: Sun, 16 May 2021 14:15:49 -0700 Subject: [PATCH 215/216] fix product option color check --- framework/swell/utils/normalize.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/framework/swell/utils/normalize.ts b/framework/swell/utils/normalize.ts index 8dc7d0e28..b0cfb6193 100644 --- a/framework/swell/utils/normalize.ts +++ b/framework/swell/utils/normalize.ts @@ -38,7 +38,7 @@ const normalizeProductOption = ({ label: value.name, id: value?.id || id, } - if (displayName === 'Color') { + if (displayName.match(/colou?r/gi)) { output = { ...output, hexColors: [value.name], From 385dc1b672dc00fc895f403d0c54f0762f52ef09 Mon Sep 17 00:00:00 2001 From: Greg Hoskin Date: Mon, 17 May 2021 09:34:53 -0700 Subject: [PATCH 216/216] fix signup-triggered login --- framework/swell/auth/use-signup.tsx | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/framework/swell/auth/use-signup.tsx b/framework/swell/auth/use-signup.tsx index f01d45044..d417122fc 100644 --- a/framework/swell/auth/use-signup.tsx +++ b/framework/swell/auth/use-signup.tsx @@ -44,10 +44,7 @@ export const handler: MutationHook< const loginData = await fetch({ query: 'account', method: 'login', - variables: { - email, - password, - }, + variables: [email, password], }) handleLogin(loginData) } catch (error) {}