From a8814983a6dad2142e616e6646a99b2ffd5134c6 Mon Sep 17 00:00:00 2001 From: Belen Curcio Date: Wed, 6 Jan 2021 17:01:32 -0300 Subject: [PATCH 001/261] 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/261] 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/261] 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/261] 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/261] 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/261] 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/261] 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/261] 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/261] 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/261] 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/261] 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/261] 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/261] 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/261] 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/261] 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/261] 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/261] 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/261] 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/261] 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/261] 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/261] 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/261] 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/261] 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/261] 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/261] 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/261] 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/261] 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/261] 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/261] 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/261] 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/261] 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/261] 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/261] 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/261] 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/261] 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/261] 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/261] 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/261] 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
- {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 174/261] 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 175/261] 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 176/261] 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 177/261] 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 178/261] 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 184/261] 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 185/261] 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 186/261] 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 187/261] 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 188/261] 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 189/261] 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 190/261] 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 191/261] 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 192/261] 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 193/261] 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 194/261] 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 195/261] 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 196/261] 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 9b71bd77fcb7e7fa8314b4d6494203f974c97a16 Mon Sep 17 00:00:00 2001 From: B Date: Thu, 4 Mar 2021 07:57:25 -0300 Subject: [PATCH 197/261] Agnostic UI (#199) * changes * Progress * Normalized Products output * Progress * Restored Index Agnostic * Progress * Reordering * Moved normalizer to BC function * Removed Futures * More Types * More Types * More Types * Fix useCallback * Progress, Changes types, readme and restoring functionality * Changes * TS Issues * Changes * Normalizer * Normalizing more operations * Normalizing more operations * changes * Merge Issues * Cleanup * change * changes * index.ts broke my tree shaking * slug * Normalized Options and Swatches * Restored Add to cart * Correct Variant Added to Cart * Normalizing Cart Responses * Changes * changes breaking * Adding immutable normalizer for Product * Cart Normalized * changes * Progress * More updates * Removed some comments * Add loading state for data hooks * Bug fix * Changed the way isEmpty works * Improve navbar performance * Added useResponse hook * added useResponse to useWhishlist * Added husky and lint-staged * Ran prettier fix * Added more cart types * Moved types.d.ts to the commerce folder * Minor changes * Moved normalizer to happen after fetch * updated useCart types * Updated normalizer for useData * Added new normalizer for the cart to the UI * More corrections for useCart * Updated cart update hooks * Removed import * Progress * Switch away from global types * Making multiple changes * Improved types for operations * Moved and updated cart types * Updated the useAddItem and useRemoveItem hooks * Minor life improvement * Minor change * Implement Shopify Provider * Update README.md * Update README.md * normalizations & missing files * Update index.ts * fixes * Update normalize.ts * fix: cart error on first load * shopify checkout redirect & api handler * Update get-checkout-id.ts * userAvatar * Fix: color option * Update normalize.ts * changes * Update next.config.js * start customer auth & signup * Update config.ts * Login, Sign Up, Log Out, and checkout & customer association * Automatic login after sign-up * Update handle-login.ts * MOving stuff around and adding temporal new files * changes * Replace use-cart with the new hook * Removed old hook * Improved HookHandler type * Moved types * Simplified useData types * Updated Fetcher type * Moved SwrOptions type * Removed duplicated fetcher * Moved provider to its own file * Added proper type for fetch input * Revert "Merge branch 'agnostic' of https://github.com/vercel/commerce into agnostic" This reverts commit 23c8ed7c2d48d30e74ad94216f9910650fadf30c, reversing changes made to bf50965a39ef0b1b956461ebe62070809fbe1d63. * change readme * Revert "Merge branch 'master' of https://github.com/vercel/commerce into agnostic" This reverts commit bf50965a39ef0b1b956461ebe62070809fbe1d63, reversing changes made to 0dad4ddedbf0bff2d0b5800ca469fda0073889ea. * Revert "Revert "Merge branch 'agnostic' of https://github.com/vercel/commerce into agnostic"" This reverts commit c9a43f1bce0572d0eff41f3af893be8bdb00bedd. * align with upstream changes * Updated how the hook input is handled * Add more options to the hook handler * Final touches to the hook handler type * Moved useWishlist to use new handler * Move useCustomer to the new hook * Added a default fetcher * query all products for vendors & paths, improve search * Update use-search.tsx * fix cart after upstream changes * Shopify Provider (#186) * Start of Shopify provider * add missing comment to documentation * add missing env vars to documentation * update reference to types file * Moved useSearch to the new hook * Removed old use-data lib * Removed generics for result and body * Removed normalizr * Wishlist * New changes and initial Features API * Fixed some types * Fixed more types * fixes after upstream changes * Fixed product types * Fixed another product type * Updated type * Fixed remaining issues with types * Added a MutationHandler * Moved the handlers to each hook * Moved the fetcher to its own file * Moved handler to each hook * Added initial version of useAddItem * Added better mutation types, and moved some hooks * Removed use-cart-actions * Added initial version of useAddItem * Updated types * Update use-add-item.tsx * changes * Changes * Reordering and changes * Adding Features APO * Adding wishlist api * Implementing FeaturesAPI with Wishlist * Removing bug with touchstart * Adding tyni typing * moved use-remove-item * Removed MutationHandler type * Moved more hooks and updated types to make them smaller * Moved data hooks to new format * Removed no longer required types * Removed useResponse helper * Updated useData type * Moved wishlist use-add-item * Moved wishlist use-remove-item to provider * Moved use-login and use-logout * Update use-signup * Removed use-action helper * Moved auth & cart hooks + several fixes * Updated cart item, fixed deprecations * Update next.config.js * Updates to wishlist feature * Moved the features to be environment variable only * More changes for wishlist config * Disable wishlist * Removed useWishlistActions * Updated readme * updates * typos * Updated the way the provider config is set * Removed features.ts * Removed bootstrap.js * Aligned with upstream changes * Updates * shopify: changes * shopify: changes * Update next.config.js * Shopify Provider Updates (#209) * Implement Shopify Provider * Update README.md * Update README.md * normalizations & missing files * Update index.ts * fixes * Update normalize.ts * fix: cart error on first load * shopify checkout redirect & api handler * Update get-checkout-id.ts * Fix: color option * Update normalize.ts * changes * Update next.config.js * start customer auth & signup * Update config.ts * Login, Sign Up, Log Out, and checkout & customer association * Automatic login after sign-up * Update handle-login.ts * changes * Revert "Merge branch 'agnostic' of https://github.com/vercel/commerce into agnostic" This reverts commit 23c8ed7c2d48d30e74ad94216f9910650fadf30c, reversing changes made to bf50965a39ef0b1b956461ebe62070809fbe1d63. * change readme * Revert "Merge branch 'master' of https://github.com/vercel/commerce into agnostic" This reverts commit bf50965a39ef0b1b956461ebe62070809fbe1d63, reversing changes made to 0dad4ddedbf0bff2d0b5800ca469fda0073889ea. * Revert "Revert "Merge branch 'agnostic' of https://github.com/vercel/commerce into agnostic"" This reverts commit c9a43f1bce0572d0eff41f3af893be8bdb00bedd. * align with upstream changes * query all products for vendors & paths, improve search * Update use-search.tsx * fix cart after upstream changes * fixes after upstream changes * Moved handler to each hook * Added initial version of useAddItem * Updated types * Update use-add-item.tsx * Moved auth & cart hooks + several fixes * Updated cart item, fixed deprecations * Update next.config.js * Aligned with upstream changes * Updates * Update next.config.js * Updated the commerce config structure * Removed @framework imports within framework providers * Fixed types * changes * Adding extra config * Adding shopify commit * Adding env templates to the providers * Ignore some types * Adding link for Cart * Adding customCheckout * multiple changes to fix the wishlist * 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 * Bump and adding dependency * Adding color checks * Now colors work with lighter colors * Stable commerce.config.json * Updated main readme * Readme changes * Default to bigcommerce Co-authored-by: bc Co-authored-by: Luis Alvarez Co-authored-by: cond0r Co-authored-by: Peter Mekhaeil <4616064+petermekhaeil@users.noreply.github.com> --- .env.template | 6 +- .prettierrc | 6 + .vscode/extensions.json | 3 + README.md | 149 +- commerce.config.json | 7 + components/auth/LoginView.tsx | 2 +- components/auth/SignUpView.tsx | 2 +- components/cart/CartItem/CartItem.tsx | 65 +- .../cart/CartSidebarView/CartSidebarView.tsx | 45 +- components/common/Footer/Footer.tsx | 2 +- .../HomeAllProductsGrid.tsx | 23 +- components/common/I18nWidget/I18nWidget.tsx | 2 +- components/common/Layout/Layout.tsx | 14 +- components/common/Navbar/Navbar.tsx | 96 +- components/common/Navbar/NavbarRoot.tsx | 33 + components/common/UserNav/DropdownMenu.tsx | 3 +- components/common/UserNav/UserNav.tsx | 29 +- components/icons/CreditCard.tsx | 20 + components/icons/MapPin.tsx | 20 + components/icons/Vercel.tsx | 46 +- components/icons/index.ts | 2 + .../product/ProductCard/ProductCard.tsx | 143 +- .../product/ProductSlider/ProductSlider.tsx | 28 +- .../ProductView/ProductView.module.css | 2 +- .../product/ProductView/ProductView.tsx | 83 +- components/product/Swatch/Swatch.module.css | 1 + components/product/Swatch/Swatch.tsx | 2 +- components/product/helpers.ts | 56 +- components/ui/Container/Container.tsx | 6 +- components/ui/Marquee/Marquee.module.css | 11 +- components/ui/context.tsx | 16 +- components/ui/index.ts | 1 + .../WishlistButton/WishlistButton.tsx | 29 +- .../wishlist/WishlistCard/WishlistCard.tsx | 33 +- components/wishlist/index.ts | 1 + config/seo.json | 14 +- framework/bigcommerce/.env.template | 6 + framework/bigcommerce/README.md | 55 +- .../bigcommerce/api/cart/handlers/add-item.ts | 11 +- .../bigcommerce/api/cart/handlers/get-cart.ts | 9 +- .../api/cart/handlers/remove-item.ts | 1 - .../api/cart/handlers/update-item.ts | 1 - framework/bigcommerce/api/cart/index.ts | 62 +- .../api/catalog/handlers/get-products.ts | 14 +- framework/bigcommerce/api/catalog/products.ts | 8 +- .../api/customers/handlers/login.ts | 2 +- .../api/customers/handlers/signup.ts | 2 +- framework/bigcommerce/api/utils/parse-item.ts | 30 +- .../api/utils/set-product-locale-meta.ts | 2 +- .../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 | 11 +- framework/bigcommerce/auth/index.ts | 3 + .../{api/operations => auth}/login.ts | 10 +- framework/bigcommerce/auth/use-login.tsx | 40 + framework/bigcommerce/auth/use-logout.tsx | 25 + framework/bigcommerce/auth/use-signup.tsx | 44 + framework/bigcommerce/cart/index.ts | 4 + framework/bigcommerce/cart/use-add-item.tsx | 76 +- .../bigcommerce/cart/use-cart-actions.tsx | 13 - framework/bigcommerce/cart/use-cart.tsx | 81 +- .../bigcommerce/cart/use-remove-item.tsx | 102 +- .../bigcommerce/cart/use-update-item.tsx | 135 +- framework/bigcommerce/commerce.config.json | 6 + .../operations => common}/get-all-pages.ts | 6 +- .../{api/operations => common}/get-page.ts | 12 +- .../operations => common}/get-site-info.ts | 10 +- .../get-customer-id.ts | 4 +- .../get-customer-wishlist.ts | 13 +- framework/bigcommerce/customer/index.ts | 1 + .../bigcommerce/customer/use-customer.tsx | 24 + framework/bigcommerce/fetcher.ts | 41 + framework/bigcommerce/index.tsx | 44 +- framework/bigcommerce/lib/immutability.ts | 13 + framework/bigcommerce/lib/normalize.ts | 113 + framework/bigcommerce/next.config.js | 8 + .../get-all-product-paths.ts | 8 +- .../get-all-products.ts | 21 +- .../operations => product}/get-product.ts | 15 +- framework/bigcommerce/product/index.ts | 4 + framework/bigcommerce/product/use-price.tsx | 2 + framework/bigcommerce/product/use-search.tsx | 53 + framework/bigcommerce/products/use-search.tsx | 63 - framework/bigcommerce/provider.ts | 34 + framework/bigcommerce/types.ts | 58 + framework/bigcommerce/use-customer.tsx | 38 - framework/bigcommerce/use-login.tsx | 54 - framework/bigcommerce/use-logout.tsx | 38 - framework/bigcommerce/use-price.tsx | 2 - framework/bigcommerce/use-signup.tsx | 54 - framework/bigcommerce/wishlist/index.ts | 3 + .../bigcommerce/wishlist/use-add-item.tsx | 54 +- .../bigcommerce/wishlist/use-remove-item.tsx | 67 +- .../wishlist/use-wishlist-actions.tsx | 11 - .../bigcommerce/wishlist/use-wishlist.tsx | 106 +- framework/commerce/api/index.ts | 2 - framework/commerce/auth/use-login.tsx | 19 + framework/commerce/auth/use-logout.tsx | 19 + framework/commerce/auth/use-signup.tsx | 19 + framework/commerce/cart/use-add-item.tsx | 22 +- framework/commerce/cart/use-cart-actions.tsx | 17 - framework/commerce/cart/use-cart.tsx | 54 +- framework/commerce/cart/use-remove-item.tsx | 34 +- framework/commerce/cart/use-update-item.tsx | 37 +- framework/commerce/customer/use-customer.tsx | 20 + framework/commerce/index.tsx | 62 +- .../commerce/{ => product}/use-price.tsx | 2 +- framework/commerce/product/use-search.tsx | 20 + framework/commerce/products/use-search.tsx | 5 - framework/commerce/types.ts | 203 + framework/commerce/use-customer.tsx | 5 - framework/commerce/use-login.tsx | 5 - framework/commerce/use-logout.tsx | 5 - framework/commerce/use-signup.tsx | 5 - framework/commerce/utils/default-fetcher.ts | 12 + framework/commerce/utils/define-property.ts | 37 + framework/commerce/utils/errors.ts | 8 + framework/commerce/utils/types.ts | 131 +- framework/commerce/utils/use-action.tsx | 15 - framework/commerce/utils/use-data.tsx | 65 +- framework/commerce/utils/use-hook.ts | 50 + framework/commerce/wishlist/index.ts | 3 + framework/commerce/wishlist/use-add-item.tsx | 18 +- .../commerce/wishlist/use-remove-item.tsx | 27 +- framework/commerce/wishlist/use-wishlist.tsx | 36 +- framework/commerce/with-config.js | 41 + framework/shopify/.env.template | 2 + framework/shopify/README.md | 260 + framework/shopify/api/cart/index.ts | 1 + framework/shopify/api/catalog/index.ts | 1 + framework/shopify/api/catalog/products.ts | 1 + framework/shopify/api/checkout/index.ts | 46 + framework/shopify/api/customer.ts | 1 + framework/shopify/api/customers/index.ts | 1 + framework/shopify/api/customers/login.ts | 1 + framework/shopify/api/customers/logout.ts | 1 + framework/shopify/api/customers/signup.ts | 1 + framework/shopify/api/index.ts | 62 + .../api/operations/get-all-collections.ts | 21 + framework/shopify/api/operations/get-page.ts | 25 + .../shopify/api/utils/create-api-handler.ts | 58 + .../shopify/api/utils/fetch-all-products.ts | 41 + .../shopify/api/utils/fetch-graphql-api.ts | 34 + framework/shopify/api/utils/fetch.ts | 2 + .../shopify/api/utils/is-allowed-method.ts | 28 + framework/shopify/api/wishlist/index.tsx | 2 + framework/shopify/auth/use-login.tsx | 76 + framework/shopify/auth/use-logout.tsx | 36 + framework/shopify/auth/use-signup.tsx | 74 + framework/shopify/cart/index.ts | 3 + framework/shopify/cart/use-add-item.tsx | 58 + framework/shopify/cart/use-cart.tsx | 59 + framework/shopify/cart/use-remove-item.tsx | 72 + framework/shopify/cart/use-update-item.tsx | 107 + .../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/commerce.config.json | 6 + framework/shopify/common/get-all-pages.ts | 42 + framework/shopify/common/get-page.ts | 37 + framework/shopify/common/get-site-info.ts | 31 + framework/shopify/const.ts | 13 + framework/shopify/customer/get-customer-id.ts | 24 + framework/shopify/customer/index.ts | 1 + framework/shopify/customer/use-customer.tsx | 27 + framework/shopify/fetcher.ts | 18 + framework/shopify/index.tsx | 40 + framework/shopify/next.config.js | 8 + .../shopify/product/get-all-collections.ts | 29 + .../shopify/product/get-all-product-paths.ts | 42 + framework/shopify/product/get-all-products.ts | 40 + framework/shopify/product/get-product.ts | 32 + framework/shopify/product/use-price.tsx | 2 + framework/shopify/product/use-search.tsx | 77 + framework/shopify/provider.ts | 31 + framework/shopify/schema.d.ts | 4985 +++++++++ framework/shopify/schema.graphql | 9631 +++++++++++++++++ framework/shopify/types.ts | 45 + framework/shopify/utils/customer-token.ts | 21 + framework/shopify/utils/get-categories.ts | 29 + framework/shopify/utils/get-checkout-id.ts | 8 + .../shopify/utils/get-search-variables.ts | 27 + framework/shopify/utils/get-sort-variables.ts | 32 + framework/shopify/utils/get-vendors.ts | 36 + .../shopify/utils/handle-fetch-response.ts | 27 + framework/shopify/utils/handle-login.ts | 39 + framework/shopify/utils/index.ts | 10 + .../associate-customer-with-checkout.ts | 18 + .../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 + .../utils/mutations/customer-create.ts | 15 + framework/shopify/utils/mutations/index.ts | 7 + framework/shopify/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 + .../utils/queries/get-checkout-query.ts | 62 + .../queries/get-collection-products-query.ts | 24 + .../utils/queries/get-customer-id-query.ts | 8 + .../utils/queries/get-customer-query.ts | 16 + .../shopify/utils/queries/get-page-query.ts | 14 + .../utils/queries/get-product-query.ts | 69 + framework/shopify/utils/queries/index.ts | 10 + framework/shopify/utils/storage.ts | 13 + framework/shopify/wishlist/use-add-item.tsx | 13 + .../shopify/wishlist/use-remove-item.tsx | 17 + framework/shopify/wishlist/use-wishlist.tsx | 46 + lib/click-outside/click-outside.tsx | 50 +- lib/colors.ts | 156 +- next.config.js | 20 +- package.json | 138 +- pages/[...pages].tsx | 7 +- pages/_app.tsx | 5 +- pages/blog.tsx | 2 +- pages/cart.tsx | 60 +- pages/index.tsx | 123 +- pages/orders.tsx | 6 +- pages/product/[slug].tsx | 16 +- pages/profile.tsx | 4 +- pages/search.tsx | 56 +- pages/wishlist.tsx | 32 +- public/card.png | Bin 0 -> 6286 bytes tsconfig.json | 14 +- yarn.lock | 745 +- 232 files changed, 20545 insertions(+), 1895 deletions(-) create mode 100644 .prettierrc create mode 100644 .vscode/extensions.json create mode 100644 commerce.config.json create mode 100644 components/common/Navbar/NavbarRoot.tsx create mode 100644 components/icons/CreditCard.tsx create mode 100644 components/icons/MapPin.tsx create mode 100644 framework/bigcommerce/.env.template create mode 100644 framework/bigcommerce/auth/index.ts rename framework/bigcommerce/{api/operations => auth}/login.ts (87%) create mode 100644 framework/bigcommerce/auth/use-login.tsx create mode 100644 framework/bigcommerce/auth/use-logout.tsx create mode 100644 framework/bigcommerce/auth/use-signup.tsx create mode 100644 framework/bigcommerce/cart/index.ts delete mode 100644 framework/bigcommerce/cart/use-cart-actions.tsx create mode 100644 framework/bigcommerce/commerce.config.json rename framework/bigcommerce/{api/operations => common}/get-all-pages.ts (83%) rename framework/bigcommerce/{api/operations => common}/get-page.ts (75%) 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 (83%) create mode 100644 framework/bigcommerce/customer/index.ts create mode 100644 framework/bigcommerce/customer/use-customer.tsx create mode 100644 framework/bigcommerce/fetcher.ts create mode 100644 framework/bigcommerce/lib/immutability.ts create mode 100644 framework/bigcommerce/lib/normalize.ts create mode 100644 framework/bigcommerce/next.config.js rename framework/bigcommerce/{api/operations => product}/get-all-product-paths.ts (89%) rename framework/bigcommerce/{api/operations => product}/get-all-products.ts (82%) rename framework/bigcommerce/{api/operations => product}/get-product.ts (87%) create mode 100644 framework/bigcommerce/product/index.ts create mode 100644 framework/bigcommerce/product/use-price.tsx create mode 100644 framework/bigcommerce/product/use-search.tsx delete mode 100644 framework/bigcommerce/products/use-search.tsx create mode 100644 framework/bigcommerce/provider.ts create mode 100644 framework/bigcommerce/types.ts delete mode 100644 framework/bigcommerce/use-customer.tsx delete mode 100644 framework/bigcommerce/use-login.tsx delete mode 100644 framework/bigcommerce/use-logout.tsx delete mode 100644 framework/bigcommerce/use-price.tsx delete mode 100644 framework/bigcommerce/use-signup.tsx create mode 100644 framework/bigcommerce/wishlist/index.ts delete mode 100644 framework/bigcommerce/wishlist/use-wishlist-actions.tsx create mode 100644 framework/commerce/auth/use-login.tsx create mode 100644 framework/commerce/auth/use-logout.tsx create mode 100644 framework/commerce/auth/use-signup.tsx delete mode 100644 framework/commerce/cart/use-cart-actions.tsx create mode 100644 framework/commerce/customer/use-customer.tsx rename framework/commerce/{ => product}/use-price.tsx (97%) create mode 100644 framework/commerce/product/use-search.tsx delete mode 100644 framework/commerce/products/use-search.tsx create mode 100644 framework/commerce/types.ts delete mode 100644 framework/commerce/use-customer.tsx delete mode 100644 framework/commerce/use-login.tsx delete mode 100644 framework/commerce/use-logout.tsx delete mode 100644 framework/commerce/use-signup.tsx create mode 100644 framework/commerce/utils/default-fetcher.ts create mode 100644 framework/commerce/utils/define-property.ts delete mode 100644 framework/commerce/utils/use-action.tsx create mode 100644 framework/commerce/utils/use-hook.ts create mode 100644 framework/commerce/wishlist/index.ts create mode 100644 framework/commerce/with-config.js create mode 100644 framework/shopify/.env.template create mode 100644 framework/shopify/README.md create mode 100644 framework/shopify/api/cart/index.ts create mode 100644 framework/shopify/api/catalog/index.ts create mode 100644 framework/shopify/api/catalog/products.ts create mode 100644 framework/shopify/api/checkout/index.ts create mode 100644 framework/shopify/api/customer.ts create mode 100644 framework/shopify/api/customers/index.ts create mode 100644 framework/shopify/api/customers/login.ts create mode 100644 framework/shopify/api/customers/logout.ts create mode 100644 framework/shopify/api/customers/signup.ts create mode 100644 framework/shopify/api/index.ts create mode 100644 framework/shopify/api/operations/get-all-collections.ts create mode 100644 framework/shopify/api/operations/get-page.ts create mode 100644 framework/shopify/api/utils/create-api-handler.ts create mode 100644 framework/shopify/api/utils/fetch-all-products.ts create mode 100644 framework/shopify/api/utils/fetch-graphql-api.ts create mode 100644 framework/shopify/api/utils/fetch.ts create mode 100644 framework/shopify/api/utils/is-allowed-method.ts create mode 100644 framework/shopify/api/wishlist/index.tsx create mode 100644 framework/shopify/auth/use-login.tsx create mode 100644 framework/shopify/auth/use-logout.tsx create mode 100644 framework/shopify/auth/use-signup.tsx create mode 100644 framework/shopify/cart/index.ts create mode 100644 framework/shopify/cart/use-add-item.tsx create mode 100644 framework/shopify/cart/use-cart.tsx create mode 100644 framework/shopify/cart/use-remove-item.tsx create mode 100644 framework/shopify/cart/use-update-item.tsx create mode 100644 framework/shopify/cart/utils/checkout-create.ts create mode 100644 framework/shopify/cart/utils/checkout-to-cart.ts create mode 100644 framework/shopify/cart/utils/fetcher.ts create mode 100644 framework/shopify/cart/utils/index.ts create mode 100644 framework/shopify/commerce.config.json create mode 100644 framework/shopify/common/get-all-pages.ts create mode 100644 framework/shopify/common/get-page.ts create mode 100644 framework/shopify/common/get-site-info.ts create mode 100644 framework/shopify/const.ts create mode 100644 framework/shopify/customer/get-customer-id.ts create mode 100644 framework/shopify/customer/index.ts create mode 100644 framework/shopify/customer/use-customer.tsx create mode 100644 framework/shopify/fetcher.ts create mode 100644 framework/shopify/index.tsx create mode 100644 framework/shopify/next.config.js create mode 100644 framework/shopify/product/get-all-collections.ts create mode 100644 framework/shopify/product/get-all-product-paths.ts create mode 100644 framework/shopify/product/get-all-products.ts create mode 100644 framework/shopify/product/get-product.ts create mode 100644 framework/shopify/product/use-price.tsx create mode 100644 framework/shopify/product/use-search.tsx create mode 100644 framework/shopify/provider.ts create mode 100644 framework/shopify/schema.d.ts create mode 100644 framework/shopify/schema.graphql create mode 100644 framework/shopify/types.ts create mode 100644 framework/shopify/utils/customer-token.ts create mode 100644 framework/shopify/utils/get-categories.ts create mode 100644 framework/shopify/utils/get-checkout-id.ts create mode 100644 framework/shopify/utils/get-search-variables.ts create mode 100644 framework/shopify/utils/get-sort-variables.ts create mode 100644 framework/shopify/utils/get-vendors.ts create mode 100644 framework/shopify/utils/handle-fetch-response.ts create mode 100644 framework/shopify/utils/handle-login.ts create mode 100644 framework/shopify/utils/index.ts create mode 100644 framework/shopify/utils/mutations/associate-customer-with-checkout.ts create mode 100644 framework/shopify/utils/mutations/checkout-create.ts create mode 100644 framework/shopify/utils/mutations/checkout-line-item-add.ts create mode 100644 framework/shopify/utils/mutations/checkout-line-item-remove.ts create mode 100644 framework/shopify/utils/mutations/checkout-line-item-update.ts create mode 100644 framework/shopify/utils/mutations/customer-access-token-create.ts create mode 100644 framework/shopify/utils/mutations/customer-access-token-delete.ts create mode 100644 framework/shopify/utils/mutations/customer-create.ts create mode 100644 framework/shopify/utils/mutations/index.ts create mode 100644 framework/shopify/utils/normalize.ts create mode 100644 framework/shopify/utils/queries/get-all-collections-query.ts create mode 100644 framework/shopify/utils/queries/get-all-pages-query.ts create mode 100644 framework/shopify/utils/queries/get-all-product-vendors-query.ts create mode 100644 framework/shopify/utils/queries/get-all-products-paths-query.ts create mode 100644 framework/shopify/utils/queries/get-all-products-query.ts create mode 100644 framework/shopify/utils/queries/get-checkout-query.ts create mode 100644 framework/shopify/utils/queries/get-collection-products-query.ts create mode 100644 framework/shopify/utils/queries/get-customer-id-query.ts create mode 100644 framework/shopify/utils/queries/get-customer-query.ts create mode 100644 framework/shopify/utils/queries/get-page-query.ts create mode 100644 framework/shopify/utils/queries/get-product-query.ts create mode 100644 framework/shopify/utils/queries/index.ts create mode 100644 framework/shopify/utils/storage.ts create mode 100644 framework/shopify/wishlist/use-add-item.tsx create mode 100644 framework/shopify/wishlist/use-remove-item.tsx create mode 100644 framework/shopify/wishlist/use-wishlist.tsx create mode 100644 public/card.png diff --git a/.env.template b/.env.template index 73a8a6e3b..9b45afe4b 100644 --- a/.env.template +++ b/.env.template @@ -2,4 +2,8 @@ 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= + +SHOPIFY_STORE_DOMAIN= +SHOPIFY_STOREFRONT_ACCESS_TOKEN= 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/.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/README.md b/README.md index 8eb69383c..885c95e85 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,8 @@ Start right now at [nextjs.org/commerce](https://nextjs.org/commerce) Demo live at: [demo.vercel.store](https://demo.vercel.store/) -This project is currently under development. +- Shopify Demo: https://shopify.demo.vercel.store/ +- BigCommerce Demo: https://bigcommerce.demo.vercel.store/ ## Features @@ -21,26 +22,122 @@ This project is currently under development. - 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. +- **Features API** is 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` +- We recommend that each **provider** ships with an `env.template` file and a `[readme.md](http://readme.md)` file. + +## Provider Structure + +Next.js Commerce provides a set of utilities and functions to create new providers. This is how a provider structure looks like. + +- `product` + - usePrice + - useSearch + - getProduct + - getAllProducts +- `wishlist` + - useWishlist + - useAddItem + - useRemoveItem +- `auth` + - useLogin + - useLogout + - useSignup +- `customer` + - useCustomer + - getCustomerId + - getCustomerWistlist +- `cart` + - useCart + - useAddItem + - useRemoveItem + - useUpdateItem +- `env.template` +- `provider.ts` +- `commerce.config.json` +- `next.config.js` +- `README.md` + +## 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. + ## 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. - - -## 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._ - -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. +## 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
    @@ -57,6 +154,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. @@ -77,22 +175,3 @@ After Email confirmation, Checkout should be manually enabled through BigCommerc
    BigCommerce team has been notified and they plan to add more detailed about this subject.
    - -## 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`. - - - - - diff --git a/commerce.config.json b/commerce.config.json new file mode 100644 index 000000000..bef7db222 --- /dev/null +++ b/commerce.config.json @@ -0,0 +1,7 @@ +{ + "provider": "bigcommerce", + "features": { + "wishlist": true, + "customCheckout": false + } +} 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 2769ac715..cb7f8600e 100644 --- a/components/cart/CartItem/CartItem.tsx +++ b/components/cart/CartItem/CartItem.tsx @@ -2,43 +2,51 @@ 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/use-price' +import { useUI } from '@components/ui/context' +import type { LineItem } from '@framework/types' +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' type ItemOption = { - name: string, - nameId: number, - value: string, + name: string + nameId: number + value: string valueId: number } const CartItem = ({ item, currencyCode, + ...rest }: { - item: any + item: LineItem currencyCode: string }) => { + const { closeSidebarIfPresent } = useUI() + const { price } = usePrice({ - amount: item.extended_sale_price, - baseAmount: item.extended_list_price, + amount: item.variant.price * item.quantity, + baseAmount: item.variant.listPrice * item.quantity, currencyCode, }) - const updateItem = useUpdateItem(item) + + 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) if (Number.isInteger(val) && val >= 0) { - setQuantity(e.target.value) + setQuantity(Number(e.target.value)) } } const handleBlur = () => { @@ -62,11 +70,13 @@ 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(item) } catch (error) { setRemoving(false) } } + // TODO: Add a type for this + const options = (item as any).options useEffect(() => { // Reset the quantity state if the item quantity changes @@ -80,32 +90,38 @@ const CartItem = ({ className={cn('flex flex-row space-x-8 py-8', { 'opacity-75 pointer-events-none': removing, })} + {...rest} >
    Product Image
    - {/** TODO: Replace this. No `path` found at Cart */} - - + + closeSidebarIfPresent()} + > {item.name} - {item.options && item.options.length > 0 ? ( + {options && options.length > 0 ? (
    - {item.options.map((option:ItemOption, i: number) => - - {option.value}{ i === item.options.length -1 ? "" : ", " } + {options.map((option: ItemOption, i: number) => ( + + {option.value} + {i === options.length - 1 ? '' : ', '} - )} + ))}
    ) : null}
    @@ -130,7 +146,10 @@ const CartItem = ({
    {price} -
    diff --git a/components/cart/CartSidebarView/CartSidebarView.tsx b/components/cart/CartSidebarView/CartSidebarView.tsx index eb76c5da5..326390327 100644 --- a/components/cart/CartSidebarView/CartSidebarView.tsx +++ b/components/cart/CartSidebarView/CartSidebarView.tsx @@ -1,42 +1,40 @@ 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/use-price' +import Link from 'next/link' import CartItem from '../CartItem' import s from './CartSidebarView.module.css' +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() - const { data, isEmpty } = useCart() + const { data, isLoading, isEmpty } = useCart() + const { price: subTotal } = usePrice( data && { - amount: data.base_amount, + amount: Number(data.subtotalPrice), currencyCode: data.currency.code, } ) const { price: total } = usePrice( data && { - amount: data.cart_amount, + amount: Number(data.totalPrice), currencyCode: data.currency.code, } ) const handleClose = () => closeSidebar() - const items = data?.line_items.physical_items ?? [] - const error = null const success = null return (
    @@ -51,12 +49,12 @@ const CartSidebarView: FC = () => {
    - +
    - {isEmpty ? ( + {isLoading || isEmpty ? (
    @@ -90,15 +88,20 @@ const CartSidebarView: FC = () => { ) : ( <>
    -

    - My Cart -

    + +

    + My Cart +

    +
      - {items.map((item: any) => ( + {data!.lineItems.map((item: any) => ( ))}
    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/HomeAllProductsGrid/HomeAllProductsGrid.tsx b/components/common/HomeAllProductsGrid/HomeAllProductsGrid.tsx index f19e1586a..423048f75 100644 --- a/components/common/HomeAllProductsGrid/HomeAllProductsGrid.tsx +++ b/components/common/HomeAllProductsGrid/HomeAllProductsGrid.tsx @@ -1,5 +1,6 @@ import { FC } from 'react' import Link from 'next/link' +import type { Product } from '@commerce/types' import { Grid } from '@components/ui' import { ProductCard } from '@components/product' import s from './HomeAllProductsGrid.module.css' @@ -8,10 +9,14 @@ import { getCategoryPath, getDesignerPath } from '@lib/search' interface Props { categories?: any brands?: any - newestProducts?: any + products?: Product[] } -const Head: FC = ({ categories, brands, newestProducts }) => { +const HomeAllProductsGrid: FC = ({ + categories, + brands, + products = [], +}) => { return (
    @@ -48,13 +53,15 @@ const Head: FC = ({ categories, brands, newestProducts }) => {
    - {newestProducts.map(({ node }: any) => ( + {products.map((product) => ( ))} @@ -63,4 +70,4 @@ const Head: FC = ({ categories, brands, newestProducts }) => { ) } -export default Head +export default HomeAllProductsGrid diff --git a/components/common/I18nWidget/I18nWidget.tsx b/components/common/I18nWidget/I18nWidget.tsx index 9bfc7b63c..fbe67a4c1 100644 --- a/components/common/I18nWidget/I18nWidget.tsx +++ b/components/common/I18nWidget/I18nWidget.tsx @@ -43,7 +43,7 @@ const I18nWidget: FC = () => { const currentLocale = locale || defaultLocale return ( - setDisplay(false)} > + setDisplay(false)}>
    -
    - +
    +
    - -
    - ) -} + +
    + +
    +
    + +
    + +
    + + +) export default Navbar diff --git a/components/common/Navbar/NavbarRoot.tsx b/components/common/Navbar/NavbarRoot.tsx new file mode 100644 index 000000000..2eb8c5429 --- /dev/null +++ b/components/common/Navbar/NavbarRoot.tsx @@ -0,0 +1,33 @@ +import { FC, useState, useEffect } from 'react' +import throttle from 'lodash.throttle' +import cn from 'classnames' +import s from './Navbar.module.css' + +const NavbarRoot: FC = ({ children }) => { + const [hasScrolled, setHasScrolled] = useState(false) + + useEffect(() => { + const handleScroll = throttle(() => { + const offset = 0 + const { scrollTop } = document.documentElement + const scrolled = scrollTop > offset + + if (hasScrolled !== scrolled) { + setHasScrolled(scrolled) + } + }, 200) + + document.addEventListener('scroll', handleScroll) + return () => { + document.removeEventListener('scroll', handleScroll) + } + }, [hasScrolled]) + + return ( +
    + {children} +
    + ) +} + +export default NavbarRoot diff --git a/components/common/UserNav/DropdownMenu.tsx b/components/common/UserNav/DropdownMenu.tsx index 7b02c863a..43f842009 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/use-logout' import { disableBodyScroll, @@ -15,8 +16,6 @@ import { clearAllBodyScrollLocks, } from 'body-scroll-lock' -import useLogout from '@framework/use-logout' - interface DropdownMenuProps { open?: boolean } diff --git a/components/common/UserNav/UserNav.tsx b/components/common/UserNav/UserNav.tsx index 31852f658..4d00970a9 100644 --- a/components/common/UserNav/UserNav.tsx +++ b/components/common/UserNav/UserNav.tsx @@ -1,27 +1,26 @@ import { FC } from 'react' import Link from 'next/link' import cn from 'classnames' +import type { LineItem } from '@framework/types' import useCart from '@framework/cart/use-cart' -import useCustomer from '@framework/use-customer' +import useCustomer from '@framework/customer/use-customer' +import { Avatar } from '@components/common' import { Heart, Bag } from '@components/icons' import { useUI } from '@components/ui/context' import DropdownMenu from './DropdownMenu' import s from './UserNav.module.css' -import { Avatar } from '@components/common' interface Props { className?: string } -const countItem = (count: number, item: any) => count + item.quantity -const countItems = (count: number, items: any[]) => - items.reduce(countItem, count) +const countItem = (count: number, item: LineItem) => count + item.quantity -const UserNav: FC = ({ className, children, ...props }) => { +const UserNav: FC = ({ className }) => { const { data } = useCart() const { data: customer } = useCustomer() const { toggleSidebar, closeSidebarIfPresent, openModal } = useUI() - const itemsCount = Object.values(data?.line_items ?? {}).reduce(countItems, 0) + const itemsCount = data?.lineItems.reduce(countItem, 0) ?? 0 return (
diff --git a/framework/commerce/types.ts b/framework/commerce/types.ts index a398070ac..86361fd9f 100644 --- a/framework/commerce/types.ts +++ b/framework/commerce/types.ts @@ -163,6 +163,7 @@ interface Entity { export interface Product extends Entity { name: string description: string + descriptionHtml?: string slug?: string path?: string images: ProductImage[] diff --git a/framework/shopify/product/get-product.ts b/framework/shopify/product/get-product.ts index 1f00288c7..1d861e1a1 100644 --- a/framework/shopify/product/get-product.ts +++ b/framework/shopify/product/get-product.ts @@ -21,11 +21,10 @@ const getProduct = async (options: { const { data }: GraphQLFetcherResult = await config.fetch(getProductQuery, { variables, }) - - const { productByHandle: product } = data + const { productByHandle } = data return { - product: product ? normalizeProduct(product) : null, + product: productByHandle ? normalizeProduct(productByHandle) : null, } } diff --git a/framework/shopify/utils/normalize.ts b/framework/shopify/utils/normalize.ts index 25bdca053..4ebc3a1ae 100644 --- a/framework/shopify/utils/normalize.ts +++ b/framework/shopify/utils/normalize.ts @@ -83,6 +83,7 @@ export function normalizeProduct(productNode: ShopifyProduct): Product { images, variants, description, + descriptionHtml, handle, priceRange, options, @@ -93,7 +94,6 @@ export function normalizeProduct(productNode: ShopifyProduct): Product { id, name, vendor, - description, path: `/${handle}`, slug: handle?.replace(/^\/+|\/+$/g, ''), price: money(priceRange?.minVariantPrice), @@ -104,6 +104,8 @@ export function normalizeProduct(productNode: ShopifyProduct): Product { .filter((o) => o.name !== 'Title') // By default Shopify adds a 'Title' name when there's only one option. We don't need it. https://community.shopify.com/c/Shopify-APIs-SDKs/Adding-new-product-variant-is-automatically-adding-quot-Default/td-p/358095 .map((o) => normalizeProductOption(o)) : [], + ...(description && { description }), + ...(descriptionHtml && { descriptionHtml }), ...rest, } diff --git a/framework/shopify/utils/queries/get-all-products-query.ts b/framework/shopify/utils/queries/get-all-products-query.ts index 5eb44c7a7..f48140d31 100644 --- a/framework/shopify/utils/queries/get-all-products-query.ts +++ b/framework/shopify/utils/queries/get-all-products-query.ts @@ -9,7 +9,6 @@ edges { title vendor handle - description priceRange { minVariantPrice { amount From d489f59171d6561dfe63de7384bc03092f8d84b0 Mon Sep 17 00:00:00 2001 From: Greg Hoskin Date: Sat, 17 Apr 2021 19:01:46 -0500 Subject: [PATCH 215/261] 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 216/261] 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 217/261] 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 a4f56d15496c837a73d83281cb0ff55fd95520e1 Mon Sep 17 00:00:00 2001 From: B Date: Wed, 21 Apr 2021 19:15:44 -0300 Subject: [PATCH 218/261] Delete ROADMAP.md --- docs/ROADMAP.md | 1 - 1 file changed, 1 deletion(-) delete mode 100644 docs/ROADMAP.md diff --git a/docs/ROADMAP.md b/docs/ROADMAP.md deleted file mode 100644 index 437766dd8..000000000 --- a/docs/ROADMAP.md +++ /dev/null @@ -1 +0,0 @@ -# Roadmap From dd40b8c60465a202605f370bddc6396c86906118 Mon Sep 17 00:00:00 2001 From: Greg Hoskin Date: Wed, 21 Apr 2021 19:56:00 -0500 Subject: [PATCH 219/261] 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 220/261] 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 221/261] 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 222/261] 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 223/261] 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 224/261] 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 225/261] 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 226/261] 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 227/261] 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 228/261] 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 229/261] 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 230/261] 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 231/261] 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 232/261] 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 233/261] 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 234/261] 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 235/261] 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) {} From 800ba45faeebe86cbcd3d75026c7b1b1aaee468b Mon Sep 17 00:00:00 2001 From: cond0r Date: Mon, 24 May 2021 19:44:38 +0300 Subject: [PATCH 236/261] Fetch only first 100 best selling products (#310) * Fetch only first 250 best selling products * Update get-all-product-paths.ts * Update use-customer.tsx --- framework/shopify/customer/use-customer.tsx | 14 ++++++++----- .../shopify/product/get-all-product-paths.ts | 21 +++++++++---------- framework/shopify/product/get-all-products.ts | 7 +++---- 3 files changed, 22 insertions(+), 20 deletions(-) diff --git a/framework/shopify/customer/use-customer.tsx b/framework/shopify/customer/use-customer.tsx index 137f0da74..7b600838e 100644 --- a/framework/shopify/customer/use-customer.tsx +++ b/framework/shopify/customer/use-customer.tsx @@ -10,11 +10,15 @@ export const handler: SWRHook = { query: getCustomerQuery, }, async fetcher({ options, fetch }) { - const data = await fetch({ - ...options, - variables: { customerAccessToken: getCustomerToken() }, - }) - return data.customer ?? null + const customerAccessToken = getCustomerToken() + if (customerAccessToken) { + const data = await fetch({ + ...options, + variables: { customerAccessToken: getCustomerToken() }, + }) + return data.customer + } + return null }, useHook: ({ useData }) => (input) => { return useData({ diff --git a/framework/shopify/product/get-all-product-paths.ts b/framework/shopify/product/get-all-product-paths.ts index 4431d1e53..e8ee04065 100644 --- a/framework/shopify/product/get-all-product-paths.ts +++ b/framework/shopify/product/get-all-product-paths.ts @@ -1,6 +1,4 @@ -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' @@ -21,21 +19,22 @@ const getAllProductPaths = async (options?: { config?: ShopifyConfig preview?: boolean }): Promise => { - let { config, variables = { first: 250 } } = options ?? {} + let { config, variables = { first: 100, sortKey: 'BEST_SELLING' } } = + options ?? {} config = getConfig(config) - const products = await fetchAllProducts({ - config, - query: getAllProductsPathsQuery, + const { data } = await config.fetch(getAllProductsPathsQuery, { variables, }) return { - products: products?.map(({ node: { handle } }: ProductEdge) => ({ - node: { - path: `/${handle}`, - }, - })), + products: data.products?.edges?.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 14e486563..3915abebf 100644 --- a/framework/shopify/product/get-all-products.ts +++ b/framework/shopify/product/get-all-products.ts @@ -27,10 +27,9 @@ const getAllProducts = async (options: { { variables } ) - const products = - data.products?.edges?.map(({ node: p }: ProductEdge) => - normalizeProduct(p) - ) ?? [] + const products = data.products?.edges?.map(({ node: p }: ProductEdge) => + normalizeProduct(p) + ) return { products, From 4f3674aafa2fa83495d4f17b30207fecd6b0e1cc Mon Sep 17 00:00:00 2001 From: B Date: Wed, 26 May 2021 17:18:50 -0300 Subject: [PATCH 237/261] New provider and tiny fixes. (#326) * changes * Adding new provider * Adding new provider * Adding new provider * Adding new provider --- .../common/FeatureBar/FeatureBar.module.css | 4 +- .../common/I18nWidget/I18nWidget.module.css | 8 +- .../common/UserNav/DropdownMenu.module.css | 4 +- components/ui/Grid/Grid.module.css | 15 +- components/ui/Hero/Hero.module.css | 5 +- framework/commerce/config.js | 4 +- yarn.lock | 493 +++++------------- 7 files changed, 161 insertions(+), 372 deletions(-) diff --git a/components/common/FeatureBar/FeatureBar.module.css b/components/common/FeatureBar/FeatureBar.module.css index a3cb61cd2..419fd4b08 100644 --- a/components/common/FeatureBar/FeatureBar.module.css +++ b/components/common/FeatureBar/FeatureBar.module.css @@ -1,7 +1,9 @@ .root { @apply text-center p-6 bg-primary text-sm flex-row justify-center items-center font-medium fixed bottom-0 w-full z-30 transition-all duration-300 ease-out; +} - @screen md { +@screen md { + .root { @apply flex text-left; } } diff --git a/components/common/I18nWidget/I18nWidget.module.css b/components/common/I18nWidget/I18nWidget.module.css index b216f5706..f100fd475 100644 --- a/components/common/I18nWidget/I18nWidget.module.css +++ b/components/common/I18nWidget/I18nWidget.module.css @@ -16,14 +16,16 @@ .dropdownMenu { @apply fixed right-0 top-12 mt-2 origin-top-right outline-none bg-primary z-40 w-full h-full; +} - @screen lg { +@screen lg { + .dropdownMenu { @apply absolute border border-accents-1 shadow-lg w-56 h-auto; } } -.closeButton { - @screen md { +@screen md { + .closeButton { @apply hidden; } } diff --git a/components/common/UserNav/DropdownMenu.module.css b/components/common/UserNav/DropdownMenu.module.css index 404726bc5..b2756e9d5 100644 --- a/components/common/UserNav/DropdownMenu.module.css +++ b/components/common/UserNav/DropdownMenu.module.css @@ -1,7 +1,9 @@ .dropdownMenu { @apply fixed right-0 mt-2 origin-top-right outline-none bg-primary z-40 w-full h-full; +} - @screen lg { +@screen lg { + .dropdownMenu { @apply absolute top-10 border border-accents-1 shadow-lg w-56 h-auto; } } diff --git a/components/ui/Grid/Grid.module.css b/components/ui/Grid/Grid.module.css index d3302fc61..9b331be8f 100644 --- a/components/ui/Grid/Grid.module.css +++ b/components/ui/Grid/Grid.module.css @@ -3,10 +3,6 @@ @apply grid grid-cols-1 gap-0; min-height: var(--row-height); - @screen lg { - @apply grid-cols-3 grid-rows-2; - } - & > * { @apply row-span-1 bg-transparent box-border overflow-hidden; height: 500px; @@ -19,6 +15,17 @@ } } +@screen lg { + .root { + @apply grid-cols-3 grid-rows-2; + } + + .root & > * { + @apply col-span-1; + height: inherit; + } +} + .default { & > * { @apply bg-transparent; diff --git a/components/ui/Hero/Hero.module.css b/components/ui/Hero/Hero.module.css index 364ad6580..c2032c8ae 100644 --- a/components/ui/Hero/Hero.module.css +++ b/components/ui/Hero/Hero.module.css @@ -1,6 +1,9 @@ .root { @apply mx-auto grid grid-cols-1 py-32 gap-4; - @screen md { +} + +@screen md { + .root { @apply grid-cols-2; } } diff --git a/framework/commerce/config.js b/framework/commerce/config.js index 2dd3284bc..dc20b518e 100644 --- a/framework/commerce/config.js +++ b/framework/commerce/config.js @@ -7,7 +7,7 @@ const fs = require('fs') const merge = require('deepmerge') const prettier = require('prettier') -const PROVIDERS = ['bigcommerce', 'shopify'] +const PROVIDERS = ['bigcommerce', 'shopify', 'swell'] function getProviderName() { return ( @@ -16,6 +16,8 @@ function getProviderName() { ? 'bigcommerce' : process.env.NEXT_PUBLIC_SHOPIFY_STORE_DOMAIN ? 'shopify' + : process.env.NEXT_PUBLIC_SWELL_STORE_ID + ? 'swell' : null) ) } diff --git a/yarn.lock b/yarn.lock index 45181fd21..7ea915b60 100644 --- a/yarn.lock +++ b/yarn.lock @@ -968,6 +968,19 @@ dependencies: defer-to-connect "^1.0.1" +"@tailwindcss/jit@^0.1.3": + version "0.1.3" + resolved "https://registry.yarnpkg.com/@tailwindcss/jit/-/jit-0.1.3.tgz#50390d9ac95fee78ed23a7e2320ef20bd4a35354" + integrity sha512-7VAvHKNLJxbGWRKxo2Z+beiodag7vWPx8b/+Egd5fve4zFihsngeNt6RwQFnll+almjppRYefRC5Py5v5K+6vg== + dependencies: + chokidar "^3.5.1" + dlv "^1.1.3" + fast-glob "^3.2.5" + lodash.topath "^4.5.2" + object-hash "^2.1.1" + postcss-selector-parser "^6.0.4" + quick-lru "^5.1.1" + "@tootallnate/once@1": version "1.1.2" resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-1.1.2.tgz#ccb91445360179a04e7fe6aff78c00ffc1eeaf82" @@ -993,32 +1006,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" @@ -1036,11 +1023,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" @@ -1186,161 +1168,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" @@ -1403,12 +1230,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== @@ -1812,7 +1634,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== @@ -1994,7 +1816,7 @@ chardet@^0.7.0: resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA== -chokidar@3.5.1, chokidar@^3.4.3: +chokidar@3.5.1, chokidar@^3.4.3, chokidar@^3.5.1: version "3.5.1" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.1.tgz#ee9ce7bbebd2b79f49f304799d5468e31e14e68a" integrity sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw== @@ -2009,13 +1831,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" @@ -2159,6 +1974,11 @@ colorette@^1.2.1: resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.2.1.tgz#4d0b921325c14faf92633086a536db6e89564b1b" integrity sha512-puCDz0CzydiSYOrnXpz/PKd69zRrribezjtE9yd4zvytoRc8+RY/KJPvtPFKZS3E3wP6neGyMe0vOTlHO5L3Pw== +colorette@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.2.2.tgz#cbcc79d5e99caea2dbf10eb3a26fd8b3e6acfa94" + integrity sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w== + combined-stream@^1.0.6, combined-stream@^1.0.8: version "1.0.8" resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" @@ -2166,7 +1986,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== @@ -2699,6 +2519,11 @@ dir-glob@^3.0.1: dependencies: path-type "^4.0.0" +dlv@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/dlv/-/dlv-1.1.3.tgz#5c198a8a11453596e751494d49874bc7732f2e79" + integrity sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA== + domain-browser@^1.1.1: version "1.2.0" resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.2.0.tgz#3d31f50191a6749dd1375a7f522e823d42e54eda" @@ -2801,14 +2626,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" @@ -2881,14 +2698,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" @@ -2899,23 +2708,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" @@ -2926,7 +2723,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== @@ -2980,7 +2777,7 @@ fast-deep-equal@^3.1.1: 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: +fast-glob@^3.1.1, fast-glob@^3.2.5: version "3.2.5" resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.5.tgz#7939af2a656de79a4f1901903ee8adcaa7cb9661" integrity sha512-2DtFcgT68wiTTiwZ2hNdJfcHNke9XOfnwmBRWXhmeKM8rF0TGwmC/Qto3S7RoZKp5cilZbxzO5iTNTQsJ+EeDg== @@ -3237,6 +3034,21 @@ get-stream@^5.0.0, get-stream@^5.1.0: dependencies: pump "^3.0.0" +glob-base@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/glob-base/-/glob-base-0.3.0.tgz#dbb164f6221b1c0b1ccf82aea328b497df0ea3c4" + integrity sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q= + dependencies: + glob-parent "^2.0.0" + is-glob "^2.0.0" + +glob-parent@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-2.0.0.tgz#81383d72db054fcccf5336daa902f182f6edbb28" + integrity sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg= + dependencies: + is-glob "^2.0.0" + 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" @@ -3302,7 +3114,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== @@ -3672,6 +3484,16 @@ is-date-object@^1.0.1: resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.2.tgz#bda736f2cd8fd06d32844e7743bfa7494c3bfd7e" integrity sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g== +is-dotfile@^1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/is-dotfile/-/is-dotfile-1.0.3.tgz#a6a2f32ffd2dfb04f5ca25ecd0f6b83cf798a1e1" + integrity sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE= + +is-extglob@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-1.0.0.tgz#ac468177c4943405a092fc8f29760c6ffc6206c0" + integrity sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA= + is-extglob@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" @@ -3701,6 +3523,13 @@ is-glob@4.0.1, is-glob@^4.0.1, is-glob@~4.0.1: dependencies: is-extglob "^2.1.1" +is-glob@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-2.0.1.tgz#d096f926a3ded5600f3fdfd91198cb0888c2d863" + integrity sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM= + dependencies: + is-extglob "^1.0.0" + is-interactive@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-interactive/-/is-interactive-1.0.0.tgz#cea6e6ae5c870a7b0a0004070b7b587e0252912e" @@ -3852,15 +3681,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" @@ -3889,11 +3709,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" @@ -4105,11 +3920,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" @@ -4227,11 +4037,21 @@ 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.topath@^4.5.2: + version "4.5.2" + resolved "https://registry.yarnpkg.com/lodash.topath/-/lodash.topath-4.5.2.tgz#3616351f3bba61994a0931989660bd03254fd009" + integrity sha1-NhY1Hzu6YZlKCTGYlmC9AyVP0Ak= + 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== +lodash@^4.17.21: + version "4.17.21" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" + integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== + log-symbols@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-1.0.2.tgz#376ff7b58ea3086a0f09facc74617eca501e1a18" @@ -4438,7 +4258,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== @@ -4556,6 +4376,11 @@ nanoid@^3.1.16, nanoid@^3.1.20: resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.20.tgz#badc263c6b1dcf14b71efaa85f6ab4c1d6cfc788" integrity sha512-a1cQNyczgKbLX9jwbS/+d7W8fX/RfgYR7lVWwWOGIPNgK2m0MWvrGF6/m4kk6U3QcFMnZf3RIhL0v2Jgh/0Uxw== +nanoid@^3.1.23: + version "3.1.23" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.23.tgz#f744086ce7c2bc47ee0a8472574d5c78e4183a81" + integrity sha512-FiB0kzdP0FFVGDKlRLEQ1BgDzU87dy5NnzjeW9YZNt+/c3+q82EQDUwniSAUxp/F0gFNI1ZhKU1FqYsMuqZVnw== + native-url@0.3.4: version "0.3.4" resolved "https://registry.yarnpkg.com/native-url/-/native-url-0.3.4.tgz#29c943172aed86c63cee62c8c04db7f5756661f8" @@ -4563,11 +4388,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" @@ -4877,7 +4697,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== @@ -4972,6 +4792,16 @@ parse-filepath@^1.0.2: map-cache "^0.2.0" path-root "^0.1.1" +parse-glob@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/parse-glob/-/parse-glob-3.0.4.tgz#b2c376cfb11f35513badd173ef0bb6e3a388391c" + integrity sha1-ssN2z7EfNVE7rdFz7wu246OIORw= + dependencies: + glob-base "^0.3.0" + is-dotfile "^1.0.0" + is-extglob "^1.0.0" + is-glob "^2.0.0" + parse-json@^5.0.0: version "5.2.0" resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd" @@ -5298,10 +5128,10 @@ postcss-media-minmax@^4.0.0: dependencies: postcss "^7.0.2" -postcss-nested@^5.0.1: - version "5.0.3" - resolved "https://registry.yarnpkg.com/postcss-nested/-/postcss-nested-5.0.3.tgz#2f46d77a06fc98d9c22344fd097396f5431386db" - integrity sha512-R2LHPw+u5hFfDgJG748KpGbJyTv7Yr33/2tIMWxquYuHTd9EXu27PYnKi7BxMXLtzKC0a0WVsqHtd7qIluQu/g== +postcss-nested@5.0.5: + version "5.0.5" + resolved "https://registry.yarnpkg.com/postcss-nested/-/postcss-nested-5.0.5.tgz#f0a107d33a9fab11d7637205f5321e27223e3603" + integrity sha512-GSRXYz5bccobpTzLQZXOnSOfKl6TwVr5CyAQJUPub4nuRJSOECK5AqurxVgmtxP48p0Kc/ndY/YyS1yqldX0Ew== dependencies: postcss-selector-parser "^6.0.4" @@ -5483,7 +5313,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.6: +postcss@^8.1.6, postcss@^8.2.1: version "8.2.6" resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.2.6.tgz#5d69a974543b45f87e464bc4c3e392a97d6be9fe" integrity sha512-xpB8qYxgPuly166AGlpRjUdEYtmOWx2iCwGmrv4vqZL9YPVviDVPZPRXxnXr6xPZOdxQ9lp3ZBFCRgWJ7LE3Sg== @@ -5492,6 +5322,15 @@ postcss@^8.1.6, postcss@^8.2.1, postcss@^8.2.6: nanoid "^3.1.20" source-map "^0.6.1" +postcss@^8.2.6: + version "8.3.0" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.3.0.tgz#b1a713f6172ca427e3f05ef1303de8b65683325f" + integrity sha512-+ogXpdAjWGa+fdYY5BQ96V/6tAo+TdSSIMP5huJBIygdWwKtVoB5JWZ7yUd4xZ8r+8Kvvx4nyg/PQ071H4UtcQ== + dependencies: + colorette "^1.2.2" + nanoid "^3.1.23" + source-map-js "^0.6.2" + precinct@^6.3.1: version "6.3.1" resolved "https://registry.yarnpkg.com/precinct/-/precinct-6.3.1.tgz#8ad735a8afdfc48b56ed39c9ad3bf999b6b928dc" @@ -5639,7 +5478,12 @@ 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: +quick-lru@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-5.1.1.tgz#366493e6b3e42a3a6885e2e99d18f80fb7a8c932" + integrity sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA== + +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== @@ -5888,7 +5732,7 @@ resolve-from@^4.0.0: resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== -resolve@^1.10.0, resolve@^1.11.1, resolve@^1.19.0: +resolve@^1.10.0, resolve@^1.11.1, resolve@^1.20.0: version "1.20.0" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.20.0.tgz#629a013fb3f70755d6f0b7935cc1c2c5378b1975" integrity sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A== @@ -5986,15 +5830,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" @@ -6027,13 +5862,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" @@ -6138,12 +5966,12 @@ 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-js@^0.6.2: + version "0.6.2" + resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-0.6.2.tgz#0bb5de631b41cfbda6cfba8bd05a80efdfd2385e" + integrity sha512-/3GptzWzu0+0MBQFrDKzw/DvvMTUORvgY6k6jd/VS6iCR4RDTKWH6v6WPwQoUO8667uQEf9Oe38DxAYWY5F/Ug== -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== @@ -6151,7 +5979,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== @@ -6429,7 +6257,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== @@ -6462,67 +6290,48 @@ tabbable@^5.1.5: integrity sha512-oVAPrWgLLqrbvQE8XqcU7CVBq6SQbaIbHkhOca3u7/jzuQvyZycrUKPCGr04qpEIUslmUlULbSeN+m3QrKEykA== tailwindcss@^2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/tailwindcss/-/tailwindcss-2.0.3.tgz#f8d07797d1f89dc4b171673c26237b58783c2c86" - integrity sha512-s8NEqdLBiVbbdL0a5XwTb8jKmIonOuI4RMENEcKLR61jw6SdKvBss7NWZzwCaD+ZIjlgmesv8tmrjXEp7C0eAQ== + version "2.1.2" + resolved "https://registry.yarnpkg.com/tailwindcss/-/tailwindcss-2.1.2.tgz#29402bf73a445faedd03df6d3b177e7b52b7c4a1" + integrity sha512-T5t+wwd+/hsOyRw2HJuFuv0LTUm3MUdHm2DJ94GPVgzqwPPFa9XxX0KlwLWupUuiOUj6uiKURCzYPHFcuPch/w== dependencies: "@fullhuman/postcss-purgecss" "^3.1.3" bytes "^3.0.0" chalk "^4.1.0" + chokidar "^3.5.1" color "^3.1.3" detective "^5.2.0" didyoumean "^1.2.1" + dlv "^1.1.3" + fast-glob "^3.2.5" fs-extra "^9.1.0" html-tags "^3.1.0" - lodash "^4.17.20" + lodash "^4.17.21" + lodash.topath "^4.5.2" modern-normalize "^1.0.0" node-emoji "^1.8.1" + normalize-path "^3.0.0" object-hash "^2.1.1" + parse-glob "^3.0.4" postcss-functions "^3" postcss-js "^3.0.3" - postcss-nested "^5.0.1" + postcss-nested "5.0.5" postcss-selector-parser "^6.0.4" postcss-value-parser "^4.1.0" pretty-hrtime "^1.0.3" + quick-lru "^5.1.1" reduce-css-calc "^2.1.8" - resolve "^1.19.0" + resolve "^1.20.0" 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== - 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" @@ -6825,7 +6634,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== @@ -6860,44 +6669,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 a84bc462d7a052ad9c17d27cdec895d12733d5bf Mon Sep 17 00:00:00 2001 From: okbel Date: Wed, 26 May 2021 18:32:15 -0300 Subject: [PATCH 238/261] Jit --- postcss.config.js | 2 +- yarn.lock | 57 ----------------------------------------------- 2 files changed, 1 insertion(+), 58 deletions(-) diff --git a/postcss.config.js b/postcss.config.js index 9bff627f2..9e0f0b2ca 100644 --- a/postcss.config.js +++ b/postcss.config.js @@ -1,6 +1,6 @@ module.exports = { plugins: [ - '@tailwindcss/jit', + 'tailwindcss', 'postcss-nesting', 'postcss-flexbugs-fixes', [ diff --git a/yarn.lock b/yarn.lock index e8110bef3..8c96bd2a3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4089,7 +4089,6 @@ lodash.topath@^4.5.2: resolved "https://registry.yarnpkg.com/lodash.topath/-/lodash.topath-4.5.2.tgz#3616351f3bba61994a0931989660bd03254fd009" integrity sha1-NhY1Hzu6YZlKCTGYlmC9AyVP0Ak= -<<<<<<< HEAD lodash.uniq@^4.5.0: version "4.5.0" resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" @@ -4100,18 +4099,11 @@ lodash@4.17.21, lodash@^4.17.21: resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== -======= ->>>>>>> 4f3674aafa2fa83495d4f17b30207fecd6b0e1cc 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== -lodash@^4.17.21: - version "4.17.21" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" - integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== - log-symbols@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-1.0.2.tgz#376ff7b58ea3086a0f09facc74617eca501e1a18" @@ -4443,11 +4435,6 @@ nanoid@^3.1.16, nanoid@^3.1.20: resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.20.tgz#badc263c6b1dcf14b71efaa85f6ab4c1d6cfc788" integrity sha512-a1cQNyczgKbLX9jwbS/+d7W8fX/RfgYR7lVWwWOGIPNgK2m0MWvrGF6/m4kk6U3QcFMnZf3RIhL0v2Jgh/0Uxw== -nanoid@^3.1.23: - version "3.1.23" - resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.23.tgz#f744086ce7c2bc47ee0a8472574d5c78e4183a81" - integrity sha512-FiB0kzdP0FFVGDKlRLEQ1BgDzU87dy5NnzjeW9YZNt+/c3+q82EQDUwniSAUxp/F0gFNI1ZhKU1FqYsMuqZVnw== - native-url@0.3.4: version "0.3.4" resolved "https://registry.yarnpkg.com/native-url/-/native-url-0.3.4.tgz#29c943172aed86c63cee62c8c04db7f5756661f8" @@ -5217,11 +5204,7 @@ postcss-media-minmax@^4.0.0: dependencies: postcss "^7.0.2" -<<<<<<< HEAD postcss-nested@^5.0.5: -======= -postcss-nested@5.0.5: ->>>>>>> 4f3674aafa2fa83495d4f17b30207fecd6b0e1cc version "5.0.5" resolved "https://registry.yarnpkg.com/postcss-nested/-/postcss-nested-5.0.5.tgz#f0a107d33a9fab11d7637205f5321e27223e3603" integrity sha512-GSRXYz5bccobpTzLQZXOnSOfKl6TwVr5CyAQJUPub4nuRJSOECK5AqurxVgmtxP48p0Kc/ndY/YyS1yqldX0Ew== @@ -5415,7 +5398,6 @@ postcss@^8.1.6, postcss@^8.2.1: nanoid "^3.1.20" source-map "^0.6.1" -<<<<<<< HEAD postcss@^8.2.8: version "8.2.8" resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.2.8.tgz#0b90f9382efda424c4f0f69a2ead6f6830d08ece" @@ -5424,16 +5406,6 @@ postcss@^8.2.8: colorette "^1.2.2" nanoid "^3.1.20" source-map "^0.6.1" -======= -postcss@^8.2.6: - version "8.3.0" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.3.0.tgz#b1a713f6172ca427e3f05ef1303de8b65683325f" - integrity sha512-+ogXpdAjWGa+fdYY5BQ96V/6tAo+TdSSIMP5huJBIygdWwKtVoB5JWZ7yUd4xZ8r+8Kvvx4nyg/PQ071H4UtcQ== - dependencies: - colorette "^1.2.2" - nanoid "^3.1.23" - source-map-js "^0.6.2" ->>>>>>> 4f3674aafa2fa83495d4f17b30207fecd6b0e1cc precinct@^6.3.1: version "6.3.1" @@ -6075,14 +6047,6 @@ slice-ansi@^4.0.0: astral-regex "^2.0.0" is-fullwidth-code-point "^3.0.0" -<<<<<<< HEAD -======= -source-map-js@^0.6.2: - version "0.6.2" - resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-0.6.2.tgz#0bb5de631b41cfbda6cfba8bd05a80efdfd2385e" - integrity sha512-/3GptzWzu0+0MBQFrDKzw/DvvMTUORvgY6k6jd/VS6iCR4RDTKWH6v6WPwQoUO8667uQEf9Oe38DxAYWY5F/Ug== - ->>>>>>> 4f3674aafa2fa83495d4f17b30207fecd6b0e1cc 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" @@ -6414,50 +6378,29 @@ tabbable@^5.1.5: resolved "https://registry.yarnpkg.com/tabbable/-/tabbable-5.1.5.tgz#efec48ede268d511c261e3b81facbb4782a35147" integrity sha512-oVAPrWgLLqrbvQE8XqcU7CVBq6SQbaIbHkhOca3u7/jzuQvyZycrUKPCGr04qpEIUslmUlULbSeN+m3QrKEykA== -<<<<<<< HEAD tailwindcss@^2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/tailwindcss/-/tailwindcss-2.0.4.tgz#cf13e62738c3a27065664e449d93b66ee2945506" integrity sha512-WhgR0oiBxGOZ9jY0yVfaJCHnckR7U74Fs/BMsYxGdwGJQ5Hd/HlaKD26bEJFZOvYScJo0QcUj2ImldzedsG7Bw== -======= -tailwindcss@^2.0.3: - version "2.1.2" - resolved "https://registry.yarnpkg.com/tailwindcss/-/tailwindcss-2.1.2.tgz#29402bf73a445faedd03df6d3b177e7b52b7c4a1" - integrity sha512-T5t+wwd+/hsOyRw2HJuFuv0LTUm3MUdHm2DJ94GPVgzqwPPFa9XxX0KlwLWupUuiOUj6uiKURCzYPHFcuPch/w== ->>>>>>> 4f3674aafa2fa83495d4f17b30207fecd6b0e1cc dependencies: "@fullhuman/postcss-purgecss" "^3.1.3" bytes "^3.0.0" chalk "^4.1.0" - chokidar "^3.5.1" color "^3.1.3" detective "^5.2.0" didyoumean "^1.2.1" - dlv "^1.1.3" - fast-glob "^3.2.5" fs-extra "^9.1.0" html-tags "^3.1.0" lodash "^4.17.21" -<<<<<<< HEAD -======= - lodash.topath "^4.5.2" ->>>>>>> 4f3674aafa2fa83495d4f17b30207fecd6b0e1cc modern-normalize "^1.0.0" node-emoji "^1.8.1" - normalize-path "^3.0.0" object-hash "^2.1.1" - parse-glob "^3.0.4" postcss-functions "^3" postcss-js "^3.0.3" -<<<<<<< HEAD postcss-nested "^5.0.5" -======= - postcss-nested "5.0.5" ->>>>>>> 4f3674aafa2fa83495d4f17b30207fecd6b0e1cc postcss-selector-parser "^6.0.4" postcss-value-parser "^4.1.0" pretty-hrtime "^1.0.3" - quick-lru "^5.1.1" reduce-css-calc "^2.1.8" resolve "^1.20.0" From 50be2a7e6e6cc34301811b27cd3522e2353e91a0 Mon Sep 17 00:00:00 2001 From: B Date: Wed, 26 May 2021 18:57:03 -0300 Subject: [PATCH 239/261] Removing Blog and changes in Footer (#328) --- components/common/Footer/Footer.tsx | 14 ----- components/ui/Hero/Hero.tsx | 2 +- pages/blog.tsx | 97 ----------------------------- 3 files changed, 1 insertion(+), 112 deletions(-) delete mode 100644 pages/blog.tsx diff --git a/components/common/Footer/Footer.tsx b/components/common/Footer/Footer.tsx index 75b2806ef..5fb9ede58 100644 --- a/components/common/Footer/Footer.tsx +++ b/components/common/Footer/Footer.tsx @@ -44,20 +44,6 @@ const Footer: FC = ({ className, pages }) => { -
  • - - - Careers - - -
  • -
  • - - - Blog - - -
  • {sitePages.map((page) => (
  • diff --git a/components/ui/Hero/Hero.tsx b/components/ui/Hero/Hero.tsx index 2e1f124ae..1802f9ee8 100644 --- a/components/ui/Hero/Hero.tsx +++ b/components/ui/Hero/Hero.tsx @@ -21,7 +21,7 @@ const Hero: FC = ({ headline, description }) => {

    {description}

    - + Read it here diff --git a/pages/blog.tsx b/pages/blog.tsx deleted file mode 100644 index eca3b2295..000000000 --- a/pages/blog.tsx +++ /dev/null @@ -1,97 +0,0 @@ -import type { GetStaticPropsContext } from 'next' -import { getConfig } from '@framework/api' -import getAllPages from '@framework/common/get-all-pages' -import { Layout } from '@components/common' -import { Container } from '@components/ui' - -export async function getStaticProps({ - preview, - locale, -}: GetStaticPropsContext) { - const config = getConfig({ locale }) - const { pages } = await getAllPages({ config, preview }) - return { - props: { pages }, - } -} - -export default function Blog() { - return ( -
    -
    - -

    - Welcome to Acme, the simplest way to start publishing with Next.js -

    -

    - The Yeezy BOOST 350 V2 lineup continues to grow. We recently had the - ‘Carbon’ iteration, and now release details have been locked in for - this ‘Natural’ joint. Revealed by Yeezy Mafia earlier this year, the - shoe was originally called ‘Abez’, which translated to ‘Tin’ in - Hebrew. It’s now undergone a name change, and will be referred to as - ‘Natura` -

    -
    -
    -
    - Avatar -
    -
    -
    - José Rodriguez -
    -
    - CEO, Acme -
    -
    -
    -
    -
    -
    - -
    - Jacket -
    - {/** Replace by HTML Content */} -
    -

    - Biscuit oat cake wafer icing ice cream tiramisu pudding cupcake. - Candy canes bonbon dragée jujubes chocolate bar. Cotton candy gummi - bears toffee cake muffin caramels. Gummi bears danish liquorice ice - cream pie chocolate cake lemon drops tootsie roll tart. Biscuit - gingerbread fruitcake cake powder pudding cotton candy chocolate - bar. Sweet donut marshmallow powder gummies jelly tart powder. - Cheesecake bonbon caramels cupcake jujubes halvah donut dessert - chocolate bar. Jelly gummies liquorice lollipop chocolate bar - chocolate cake sugar plum. Lollipop toffee dragée chocolate bar - jelly beans biscuit. Halvah danish cheesecake. Tiramisu donut - lollipop pie donut caramels tiramisu. Jujubes candy canes pudding - danish fruitcake chupa chups jujubes carrot cake bonbon. Halvah - donut jelly halvah bonbon. -

    -

    - Biscuit sugar plum sweet chocolate cake sesame snaps soufflé - topping. Gummies topping bonbon chocolate pudding cookie. Wafer - icing cake pastry. Gummies candy dessert chupa chups lemon drops. - Soufflé marshmallow oat cake chocolate jelly-o caramels pie marzipan - jelly beans. Cheesecake liquorice donut jujubes halvah ice cream - cotton candy cupcake sugar plum. Ice cream ice cream sweet roll - fruitcake icing. Muffin candy canes bonbon croissant gummies lemon - drops pie danish. Oat cake chocolate toffee cake jelly tart - caramels. Sweet donut cheesecake pastry pie sweet. Bonbon lollipop - brownie. Soufflé pudding macaroon cotton candy gingerbread. Biscuit - macaroon gummi bears candy canes chocolate cake lemon drops - marshmallow. Chocolate cake cotton candy marshmallow cake sweet - tootsie roll bonbon carrot cake sugar plum. -

    -
    -
    -
    - ) -} - -Blog.Layout = Layout From 8fb6c7b206472d0fa0a79f4097f783934c409ee3 Mon Sep 17 00:00:00 2001 From: B Date: Wed, 26 May 2021 19:14:34 -0300 Subject: [PATCH 240/261] Update README.md --- README.md | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 941b1699b..4e7a1aa1e 100644 --- a/README.md +++ b/README.md @@ -7,8 +7,9 @@ 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/ +- Shopify Demo: https://shopify.vercel.store/ +- Swell Demo: https://swell.vercel.store/ +- BigCommerce Demo: https://bigcommerce.vercel.store/ ## Features @@ -40,6 +41,22 @@ Next.js Commerce integrates out-of-the-box with BigCommerce and Shopify. We plan 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). +The setup for Shopify would look like this for example: + +``` +COMMERCE_PROVIDER=shopify +NEXT_PUBLIC_SHOPIFY_STOREFRONT_ACCESS_TOKEN=xxxxxxxxxxxxxxxxxxxxxxxxxxxx +NEXT_PUBLIC_SHOPIFY_STORE_DOMAIN=xxxxxxx.myshopify.com +``` + +And change the `tsconfig.json` to resolve to the chosen provider: +``` + "@framework": ["framework/shopify"], + "@framework/*": ["framework/shopify/*"] +``` + +That's it! + ### Features Every provider defines the features that it supports under `framework/{provider}/commerce.config.json` From da4371090d9036d51b17245a1f37ec59d894c8be Mon Sep 17 00:00:00 2001 From: Michael Bromley Date: Thu, 27 May 2021 23:06:56 +0200 Subject: [PATCH 241/261] Vendure provider (#223) * Minimal list/detail views working with Vendure * Implement useCart/useAddItem * Implement useUpdateItem & useRemoveItem * Implement useSearch * Add operations codegen, tidy up * Dummy checkout page * Implement auth/customer hooks * Use env var for Shop API url * Add some documentation * Improve error handling * Optimize preview image size * Fix accidental change * Update Vendure provider to latest changes * Vendure provider: split out gql operations, remove unused files * Update Vendure provider readme * Add local next.config to Vendure provider, update docs * Update to use demo server * Fix build errors * Use proxy for vendure api * Simplify instructions in Vendure readme * Refactor Vendure checkout api handler * Improve image quality --- .gitignore | 1 + framework/commerce/config.js | 2 +- framework/vendure/.env.template | 1 + framework/vendure/README.md | 33 + framework/vendure/api/cart/index.ts | 1 + framework/vendure/api/catalog/index.ts | 1 + framework/vendure/api/catalog/products.ts | 1 + framework/vendure/api/checkout/index.ts | 60 + framework/vendure/api/customers/index.ts | 1 + framework/vendure/api/customers/login.ts | 1 + framework/vendure/api/customers/logout.ts | 1 + framework/vendure/api/customers/signup.ts | 1 + framework/vendure/api/index.ts | 51 + .../vendure/api/utils/fetch-graphql-api.ts | 37 + framework/vendure/api/utils/fetch.ts | 3 + framework/vendure/api/wishlist/index.tsx | 2 + framework/vendure/auth/use-login.tsx | 50 + framework/vendure/auth/use-logout.tsx | 32 + framework/vendure/auth/use-signup.tsx | 68 + framework/vendure/cart/index.ts | 5 + framework/vendure/cart/use-add-item.tsx | 52 + framework/vendure/cart/use-cart-actions.tsx | 13 + framework/vendure/cart/use-cart.tsx | 49 + framework/vendure/cart/use-remove-item.tsx | 48 + framework/vendure/cart/use-update-item.tsx | 78 + framework/vendure/codegen.json | 28 + framework/vendure/commerce.config.json | 6 + framework/vendure/common/get-all-pages.ts | 35 + framework/vendure/common/get-page.ts | 40 + framework/vendure/common/get-site-info.ts | 49 + .../vendure/customer/get-customer-wishlist.ts | 18 + framework/vendure/customer/index.ts | 1 + framework/vendure/customer/use-customer.tsx | 33 + framework/vendure/fetcher.ts | 51 + framework/vendure/index.tsx | 33 + framework/vendure/lib/array-to-tree.ts | 67 + .../vendure/lib/fragments/cart-fragment.ts | 42 + .../lib/fragments/search-result-fragment.ts | 24 + .../mutations/add-item-to-order-mutation.ts | 15 + .../mutations/adjust-order-line-mutation.ts | 15 + .../vendure/lib/mutations/log-in-mutation.ts | 14 + .../vendure/lib/mutations/log-out-mutation.ts | 7 + .../mutations/remove-order-line-mutation.ts | 15 + .../vendure/lib/mutations/sign-up-mutation.ts | 14 + framework/vendure/lib/normalize.ts | 55 + .../lib/queries/active-customer-query.ts | 10 + .../queries/get-all-product-paths-query.ts | 9 + .../lib/queries/get-all-products-query.ts | 12 + .../vendure/lib/queries/get-cart-query.ts | 10 + .../lib/queries/get-collections-query.ts | 21 + .../vendure/lib/queries/get-product-query.ts | 41 + framework/vendure/lib/queries/search-query.ts | 13 + framework/vendure/next.config.js | 8 + .../vendure/product/get-all-product-paths.ts | 48 + framework/vendure/product/get-all-products.ts | 39 + framework/vendure/product/get-product.ts | 57 + framework/vendure/product/index.ts | 4 + framework/vendure/product/use-price.tsx | 2 + framework/vendure/product/use-search.tsx | 65 + framework/vendure/provider.ts | 21 + framework/vendure/schema.d.ts | 3122 +++++++++++++ framework/vendure/schema.graphql | 3860 +++++++++++++++++ framework/vendure/types.ts | 5 + framework/vendure/wishlist/use-add-item.tsx | 13 + .../vendure/wishlist/use-remove-item.tsx | 17 + framework/vendure/wishlist/use-wishlist.tsx | 46 + next.config.js | 10 +- package.json | 1 + pages/index.tsx | 10 +- tsconfig.json | 4 +- yarn.lock | 42 - 71 files changed, 8593 insertions(+), 51 deletions(-) create mode 100644 framework/vendure/.env.template create mode 100644 framework/vendure/README.md create mode 100644 framework/vendure/api/cart/index.ts create mode 100644 framework/vendure/api/catalog/index.ts create mode 100644 framework/vendure/api/catalog/products.ts create mode 100644 framework/vendure/api/checkout/index.ts create mode 100644 framework/vendure/api/customers/index.ts create mode 100644 framework/vendure/api/customers/login.ts create mode 100644 framework/vendure/api/customers/logout.ts create mode 100644 framework/vendure/api/customers/signup.ts create mode 100644 framework/vendure/api/index.ts create mode 100644 framework/vendure/api/utils/fetch-graphql-api.ts create mode 100644 framework/vendure/api/utils/fetch.ts create mode 100644 framework/vendure/api/wishlist/index.tsx create mode 100644 framework/vendure/auth/use-login.tsx create mode 100644 framework/vendure/auth/use-logout.tsx create mode 100644 framework/vendure/auth/use-signup.tsx create mode 100644 framework/vendure/cart/index.ts create mode 100644 framework/vendure/cart/use-add-item.tsx create mode 100644 framework/vendure/cart/use-cart-actions.tsx create mode 100644 framework/vendure/cart/use-cart.tsx create mode 100644 framework/vendure/cart/use-remove-item.tsx create mode 100644 framework/vendure/cart/use-update-item.tsx create mode 100644 framework/vendure/codegen.json create mode 100644 framework/vendure/commerce.config.json create mode 100644 framework/vendure/common/get-all-pages.ts create mode 100644 framework/vendure/common/get-page.ts create mode 100644 framework/vendure/common/get-site-info.ts create mode 100644 framework/vendure/customer/get-customer-wishlist.ts create mode 100644 framework/vendure/customer/index.ts create mode 100644 framework/vendure/customer/use-customer.tsx create mode 100644 framework/vendure/fetcher.ts create mode 100644 framework/vendure/index.tsx create mode 100644 framework/vendure/lib/array-to-tree.ts create mode 100644 framework/vendure/lib/fragments/cart-fragment.ts create mode 100644 framework/vendure/lib/fragments/search-result-fragment.ts create mode 100644 framework/vendure/lib/mutations/add-item-to-order-mutation.ts create mode 100644 framework/vendure/lib/mutations/adjust-order-line-mutation.ts create mode 100644 framework/vendure/lib/mutations/log-in-mutation.ts create mode 100644 framework/vendure/lib/mutations/log-out-mutation.ts create mode 100644 framework/vendure/lib/mutations/remove-order-line-mutation.ts create mode 100644 framework/vendure/lib/mutations/sign-up-mutation.ts create mode 100644 framework/vendure/lib/normalize.ts create mode 100644 framework/vendure/lib/queries/active-customer-query.ts create mode 100644 framework/vendure/lib/queries/get-all-product-paths-query.ts create mode 100644 framework/vendure/lib/queries/get-all-products-query.ts create mode 100644 framework/vendure/lib/queries/get-cart-query.ts create mode 100644 framework/vendure/lib/queries/get-collections-query.ts create mode 100644 framework/vendure/lib/queries/get-product-query.ts create mode 100644 framework/vendure/lib/queries/search-query.ts create mode 100644 framework/vendure/next.config.js create mode 100644 framework/vendure/product/get-all-product-paths.ts create mode 100644 framework/vendure/product/get-all-products.ts create mode 100644 framework/vendure/product/get-product.ts create mode 100644 framework/vendure/product/index.ts create mode 100644 framework/vendure/product/use-price.tsx create mode 100644 framework/vendure/product/use-search.tsx create mode 100644 framework/vendure/provider.ts create mode 100644 framework/vendure/schema.d.ts create mode 100644 framework/vendure/schema.graphql create mode 100644 framework/vendure/types.ts create mode 100644 framework/vendure/wishlist/use-add-item.tsx create mode 100644 framework/vendure/wishlist/use-remove-item.tsx create mode 100644 framework/vendure/wishlist/use-wishlist.tsx diff --git a/.gitignore b/.gitignore index 50d4285ba..22f1bf4f3 100644 --- a/.gitignore +++ b/.gitignore @@ -18,6 +18,7 @@ out/ # misc .DS_Store *.pem +.idea # debug npm-debug.log* diff --git a/framework/commerce/config.js b/framework/commerce/config.js index dc20b518e..dc016d47a 100644 --- a/framework/commerce/config.js +++ b/framework/commerce/config.js @@ -7,7 +7,7 @@ const fs = require('fs') const merge = require('deepmerge') const prettier = require('prettier') -const PROVIDERS = ['bigcommerce', 'shopify', 'swell'] +const PROVIDERS = ['bigcommerce', 'shopify', 'swell', 'vendure'] function getProviderName() { return ( diff --git a/framework/vendure/.env.template b/framework/vendure/.env.template new file mode 100644 index 000000000..d8f7f14b5 --- /dev/null +++ b/framework/vendure/.env.template @@ -0,0 +1 @@ +NEXT_PUBLIC_VENDURE_SHOP_API_URL=http://localhost:3001/shop-api diff --git a/framework/vendure/README.md b/framework/vendure/README.md new file mode 100644 index 000000000..c1bcd7b5b --- /dev/null +++ b/framework/vendure/README.md @@ -0,0 +1,33 @@ +# Vendure Storefront Data Hooks + +UI hooks and data fetching methods built from the ground up for e-commerce applications written in React, that use [Vendure](http://vendure.io/) as a headless e-commerce platform. + +## Usage + +1. Clone this repo and install its dependencies with `yarn install` or `npm install` +2. Set the Vendure provider and API URL in your `.env.local` file: + ``` + COMMERCE_PROVIDER=vendure + NEXT_PUBLIC_VENDURE_SHOP_API_URL=https://demo.vendure.io/shop-api + NEXT_PUBLIC_VENDURE_LOCAL_URL=/vendure-shop-api + ``` +3. With the Vendure server running, start this project using `yarn dev` or `npm run dev`. + +## Known Limitations + +1. Vendure does not ship with built-in wishlist functionality. +2. Nor does it come with any kind of blog/page-building feature. Both of these can be created as Vendure plugins, however. +3. The entire Vendure customer flow is carried out via its GraphQL API. This means that there is no external, pre-existing checkout flow. The checkout flow must be created as part of the Next.js app. See https://github.com/vercel/commerce/issues/64 for further discusion. +4. By default, the sign-up flow in Vendure uses email verification. This means that using the existing "sign up" flow from this project will not grant a new user the ability to authenticate, since the new account must first be verified. Again, the necessary parts to support this flow can be created as part of the Next.js app. + +## Code generation + +This provider makes use of GraphQL code generation. The [schema.graphql](./schema.graphql) and [schema.d.ts](./schema.d.ts) files contain the generated types & schema introspection results. + +When developing the provider, changes to any GraphQL operations should be followed by re-generation of the types and schema files: + +From the project root dir, run + +```sh +graphql-codegen --config ./framework/vendure/codegen.json +``` diff --git a/framework/vendure/api/cart/index.ts b/framework/vendure/api/cart/index.ts new file mode 100644 index 000000000..ea9b101e1 --- /dev/null +++ b/framework/vendure/api/cart/index.ts @@ -0,0 +1 @@ +export default function () {} diff --git a/framework/vendure/api/catalog/index.ts b/framework/vendure/api/catalog/index.ts new file mode 100644 index 000000000..ea9b101e1 --- /dev/null +++ b/framework/vendure/api/catalog/index.ts @@ -0,0 +1 @@ +export default function () {} diff --git a/framework/vendure/api/catalog/products.ts b/framework/vendure/api/catalog/products.ts new file mode 100644 index 000000000..ea9b101e1 --- /dev/null +++ b/framework/vendure/api/catalog/products.ts @@ -0,0 +1 @@ +export default function () {} diff --git a/framework/vendure/api/checkout/index.ts b/framework/vendure/api/checkout/index.ts new file mode 100644 index 000000000..21083e9b7 --- /dev/null +++ b/framework/vendure/api/checkout/index.ts @@ -0,0 +1,60 @@ +import { NextApiHandler } from 'next' + +const checkoutApi = async (req: any, res: any, config: any) => { + try { + const html = ` + + + + + + Checkout + + +
    + + + ` + + res.status(200) + res.setHeader('Content-Type', 'text/html') + res.write(html) + res.end() + } catch (error) { + console.error(error) + + const message = 'An unexpected error ocurred' + + res.status(500).json({ data: null, errors: [{ message }] }) + } +} + +export function createApiHandler( + handler: any, + handlers: H, + defaultOptions: Options +) { + return function getApiHandler({ + config, + operations, + options, + }: { + config?: any + 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, config, ops, opts) + } + } +} + +export default createApiHandler(checkoutApi, {}, {}) diff --git a/framework/vendure/api/customers/index.ts b/framework/vendure/api/customers/index.ts new file mode 100644 index 000000000..ea9b101e1 --- /dev/null +++ b/framework/vendure/api/customers/index.ts @@ -0,0 +1 @@ +export default function () {} diff --git a/framework/vendure/api/customers/login.ts b/framework/vendure/api/customers/login.ts new file mode 100644 index 000000000..ea9b101e1 --- /dev/null +++ b/framework/vendure/api/customers/login.ts @@ -0,0 +1 @@ +export default function () {} diff --git a/framework/vendure/api/customers/logout.ts b/framework/vendure/api/customers/logout.ts new file mode 100644 index 000000000..ea9b101e1 --- /dev/null +++ b/framework/vendure/api/customers/logout.ts @@ -0,0 +1 @@ +export default function () {} diff --git a/framework/vendure/api/customers/signup.ts b/framework/vendure/api/customers/signup.ts new file mode 100644 index 000000000..ea9b101e1 --- /dev/null +++ b/framework/vendure/api/customers/signup.ts @@ -0,0 +1 @@ +export default function () {} diff --git a/framework/vendure/api/index.ts b/framework/vendure/api/index.ts new file mode 100644 index 000000000..f6b06a10c --- /dev/null +++ b/framework/vendure/api/index.ts @@ -0,0 +1,51 @@ +import type { CommerceAPIConfig } from '@commerce/api' +import fetchGraphqlApi from './utils/fetch-graphql-api' + +export interface VendureConfig extends CommerceAPIConfig {} + +const API_URL = process.env.NEXT_PUBLIC_VENDURE_SHOP_API_URL + +if (!API_URL) { + throw new Error( + `The environment variable NEXT_PUBLIC_VENDURE_SHOP_API_URL is missing and it's required to access your store` + ) +} + +export class Config { + private config: VendureConfig + + constructor(config: VendureConfig) { + 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 ONE_DAY = 60 * 60 * 24 +const config = new Config({ + commerceUrl: API_URL, + apiToken: '', + cartCookie: '', + customerCookie: '', + cartCookieMaxAge: ONE_DAY * 30, + fetch: fetchGraphqlApi, +}) + +export function getConfig(userConfig?: Partial) { + return config.getConfig(userConfig) +} + +export function setConfig(newConfig: Partial) { + return config.setConfig(newConfig) +} diff --git a/framework/vendure/api/utils/fetch-graphql-api.ts b/framework/vendure/api/utils/fetch-graphql-api.ts new file mode 100644 index 000000000..f769123e4 --- /dev/null +++ b/framework/vendure/api/utils/fetch-graphql-api.ts @@ -0,0 +1,37 @@ +import { FetcherError } from '@commerce/utils/errors' +import type { GraphQLFetcher } from '@commerce/api' +import { getConfig } from '..' +import fetch from './fetch' + +const fetchGraphqlApi: GraphQLFetcher = async ( + query: string, + { variables, preview } = {}, + fetchOptions +) => { + const config = getConfig() + const res = await fetch(config.commerceUrl, { + ...fetchOptions, + method: 'POST', + headers: { + Authorization: `Bearer ${config.apiToken}`, + ...fetchOptions?.headers, + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + query, + variables, + }), + }) + + const json = await res.json() + if (json.errors) { + throw new FetcherError({ + errors: json.errors ?? [{ message: 'Failed to fetch Vendure API' }], + status: res.status, + }) + } + + return { data: json.data, res } +} + +export default fetchGraphqlApi diff --git a/framework/vendure/api/utils/fetch.ts b/framework/vendure/api/utils/fetch.ts new file mode 100644 index 000000000..9d9fff3ed --- /dev/null +++ b/framework/vendure/api/utils/fetch.ts @@ -0,0 +1,3 @@ +import zeitFetch from '@vercel/fetch' + +export default zeitFetch() diff --git a/framework/vendure/api/wishlist/index.tsx b/framework/vendure/api/wishlist/index.tsx new file mode 100644 index 000000000..a72856673 --- /dev/null +++ b/framework/vendure/api/wishlist/index.tsx @@ -0,0 +1,2 @@ +export type WishlistItem = { product: any; id: number } +export default function () {} diff --git a/framework/vendure/auth/use-login.tsx b/framework/vendure/auth/use-login.tsx new file mode 100644 index 000000000..f0fc85cbc --- /dev/null +++ b/framework/vendure/auth/use-login.tsx @@ -0,0 +1,50 @@ +import { useCallback } from 'react' +import { MutationHook } from '@commerce/utils/types' +import useLogin, { UseLogin } from '@commerce/auth/use-login' +import { CommerceError, ValidationError } from '@commerce/utils/errors' +import useCustomer from '../customer/use-customer' +import { LoginMutation, LoginMutationVariables } from '../schema' +import { loginMutation } from '../lib/mutations/log-in-mutation' + +export default useLogin as UseLogin + +export const handler: MutationHook = { + fetchOptions: { + query: loginMutation, + }, + async fetcher({ input: { email, password }, options, fetch }) { + if (!(email && password)) { + throw new CommerceError({ + message: 'A email and password are required to login', + }) + } + + const variables: LoginMutationVariables = { + username: email, + password, + } + + const { login } = await fetch({ + ...options, + variables, + }) + + if (login.__typename !== 'CurrentUser') { + throw new ValidationError(login) + } + + 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/vendure/auth/use-logout.tsx b/framework/vendure/auth/use-logout.tsx new file mode 100644 index 000000000..93ba665b8 --- /dev/null +++ b/framework/vendure/auth/use-logout.tsx @@ -0,0 +1,32 @@ +import { useCallback } from 'react' +import { MutationHook } from '@commerce/utils/types' +import useLogout, { UseLogout } from '@commerce/auth/use-logout' +import useCustomer from '../customer/use-customer' +import { LogoutMutation } from '../schema' +import { logoutMutation } from '../lib/mutations/log-out-mutation' + +export default useLogout as UseLogout + +export const handler: MutationHook = { + fetchOptions: { + query: logoutMutation, + }, + async fetcher({ options, fetch }) { + await fetch({ + ...options, + }) + 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/vendure/auth/use-signup.tsx b/framework/vendure/auth/use-signup.tsx new file mode 100644 index 000000000..816b95738 --- /dev/null +++ b/framework/vendure/auth/use-signup.tsx @@ -0,0 +1,68 @@ +import { useCallback } from 'react' +import { MutationHook } from '@commerce/utils/types' +import { CommerceError, ValidationError } from '@commerce/utils/errors' +import useSignup, { UseSignup } from '@commerce/auth/use-signup' +import useCustomer from '../customer/use-customer' +import { + RegisterCustomerInput, + SignupMutation, + SignupMutationVariables, +} from '../schema' +import { signupMutation } from '../lib/mutations/sign-up-mutation' + +export default useSignup as UseSignup + +export type SignupInput = { + email: string + firstName: string + lastName: string + password: string +} + +export const handler: MutationHook = { + fetchOptions: { + query: signupMutation, + }, + 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 variables: SignupMutationVariables = { + input: { + firstName, + lastName, + emailAddress: email, + password, + }, + } + const { registerCustomerAccount } = await fetch({ + ...options, + variables, + }) + + if (registerCustomerAccount.__typename !== 'Success') { + throw new ValidationError(registerCustomerAccount) + } + + return null + }, + 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/vendure/cart/index.ts b/framework/vendure/cart/index.ts new file mode 100644 index 000000000..43c6db2b7 --- /dev/null +++ b/framework/vendure/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/vendure/cart/use-add-item.tsx b/framework/vendure/cart/use-add-item.tsx new file mode 100644 index 000000000..42c5e5a63 --- /dev/null +++ b/framework/vendure/cart/use-add-item.tsx @@ -0,0 +1,52 @@ +import { Cart, CartItemBody } from '@commerce/types' +import useAddItem, { UseAddItem } from '@commerce/cart/use-add-item' +import { CommerceError } from '@commerce/utils/errors' +import { MutationHook } from '@commerce/utils/types' +import { useCallback } from 'react' +import useCart from './use-cart' +import { AddItemToOrderMutation } from '../schema' +import { normalizeCart } from '../lib/normalize' +import { addItemToOrderMutation } from '../lib/mutations/add-item-to-order-mutation' + +export default useAddItem as UseAddItem + +export const handler: MutationHook = { + fetchOptions: { + query: addItemToOrderMutation, + }, + async fetcher({ input, options, fetch }) { + if ( + input.quantity && + (!Number.isInteger(input.quantity) || input.quantity! < 1) + ) { + throw new CommerceError({ + message: 'The item quantity has to be a valid integer greater than 0', + }) + } + + const { addItemToOrder } = await fetch({ + ...options, + variables: { + quantity: input.quantity || 1, + variantId: input.variantId, + }, + }) + + if (addItemToOrder.__typename === 'Order') { + return normalizeCart(addItemToOrder) + } + throw new CommerceError(addItemToOrder) + }, + 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/vendure/cart/use-cart-actions.tsx b/framework/vendure/cart/use-cart-actions.tsx new file mode 100644 index 000000000..abb4a998e --- /dev/null +++ b/framework/vendure/cart/use-cart-actions.tsx @@ -0,0 +1,13 @@ +import useAddItem from './use-add-item' +import useRemoveItem from './use-remove-item' +import useUpdateItem from './use-update-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 useCartActions() { + const addItem = useAddItem() + const updateItem = useUpdateItem() + const removeItem = useRemoveItem() + + return { addItem, updateItem, removeItem } +} diff --git a/framework/vendure/cart/use-cart.tsx b/framework/vendure/cart/use-cart.tsx new file mode 100644 index 000000000..ee9975f87 --- /dev/null +++ b/framework/vendure/cart/use-cart.tsx @@ -0,0 +1,49 @@ +import { Cart } from '@commerce/types' +import { SWRHook } from '@commerce/utils/types' +import useCart, { FetchCartInput, UseCart } from '@commerce/cart/use-cart' +import { ActiveOrderQuery, CartFragment } from '../schema' +import { normalizeCart } from '../lib/normalize' +import { useMemo } from 'react' +import { getCartQuery } from '../lib/queries/get-cart-query' + +export type CartResult = { + activeOrder?: CartFragment + addItemToOrder?: CartFragment + adjustOrderLine?: CartFragment + removeOrderLine?: CartFragment +} + +export default useCart as UseCart + +export const handler: SWRHook< + Cart | null, + {}, + FetchCartInput, + { isEmpty?: boolean } +> = { + fetchOptions: { + query: getCartQuery, + }, + async fetcher({ input: { cartId }, options, fetch }) { + const { activeOrder } = await fetch(options) + return activeOrder ? normalizeCart(activeOrder) : null + }, + 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/vendure/cart/use-remove-item.tsx b/framework/vendure/cart/use-remove-item.tsx new file mode 100644 index 000000000..f23f04d00 --- /dev/null +++ b/framework/vendure/cart/use-remove-item.tsx @@ -0,0 +1,48 @@ +import { useCallback } from 'react' +import { HookFetcherContext, MutationHookContext } from '@commerce/utils/types' +import useRemoveItem, { UseRemoveItem } from '@commerce/cart/use-remove-item' +import { CommerceError } from '@commerce/utils/errors' +import useCart from './use-cart' +import { + RemoveOrderLineMutation, + RemoveOrderLineMutationVariables, +} from '../schema' +import { Cart, LineItem, RemoveCartItemBody } from '@commerce/types' +import { normalizeCart } from '../lib/normalize' +import { removeOrderLineMutation } from '../lib/mutations/remove-order-line-mutation' + +export default useRemoveItem as UseRemoveItem + +export const handler = { + fetchOptions: { + query: removeOrderLineMutation, + }, + async fetcher({ input, options, fetch }: HookFetcherContext) { + const variables: RemoveOrderLineMutationVariables = { + orderLineId: input.id, + } + const { removeOrderLine } = await fetch({ + ...options, + variables, + }) + + if (removeOrderLine.__typename === 'Order') { + return normalizeCart(removeOrderLine) + } + throw new CommerceError(removeOrderLine) + }, + useHook: ({ + fetch, + }: MutationHookContext) => (ctx = {}) => { + const { mutate } = useCart() + + return useCallback( + async function removeItem(input) { + const data = await fetch({ input }) + await mutate(data, false) + return data + }, + [fetch, mutate] + ) + }, +} diff --git a/framework/vendure/cart/use-update-item.tsx b/framework/vendure/cart/use-update-item.tsx new file mode 100644 index 000000000..4e871514e --- /dev/null +++ b/framework/vendure/cart/use-update-item.tsx @@ -0,0 +1,78 @@ +import { useCallback } from 'react' +import { HookFetcherContext, MutationHookContext } from '@commerce/utils/types' +import { CommerceError, ValidationError } from '@commerce/utils/errors' +import useUpdateItem, { UseUpdateItem } from '@commerce/cart/use-update-item' +import { + Cart, + CartItemBody, + LineItem, + UpdateCartItemBody, +} from '@commerce/types' +import useCart from './use-cart' +import { + AdjustOrderLineMutation, + AdjustOrderLineMutationVariables, +} from '../schema' +import { normalizeCart } from '../lib/normalize' +import { adjustOrderLineMutation } from '../lib/mutations/adjust-order-line-mutation' + +export default useUpdateItem as UseUpdateItem + +export const handler = { + fetchOptions: { + query: adjustOrderLineMutation, + }, + async fetcher(context: HookFetcherContext>) { + const { input, options, fetch } = context + const variables: AdjustOrderLineMutationVariables = { + quantity: input.item.quantity || 1, + orderLineId: input.itemId, + } + const { adjustOrderLine } = await fetch({ + ...options, + variables, + }) + + if (adjustOrderLine.__typename === 'Order') { + return normalizeCart(adjustOrderLine) + } + throw new CommerceError(adjustOrderLine) + }, + useHook: ({ + fetch, + }: MutationHookContext>) => ( + ctx: { + item?: LineItem + wait?: number + } = {} + ) => { + const { item } = ctx + const { mutate } = useCart() + + return useCallback( + async function addItem(input: Partial) { + const itemId = 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 + }, + [fetch, mutate] + ) + }, +} diff --git a/framework/vendure/codegen.json b/framework/vendure/codegen.json new file mode 100644 index 000000000..79a2b6ffa --- /dev/null +++ b/framework/vendure/codegen.json @@ -0,0 +1,28 @@ +{ + "schema": { + "http://localhost:3001/shop-api": {} + }, + "documents": [ + { + "./framework/vendure/**/*.{ts,tsx}": { + "noRequire": true + } + } + ], + "generates": { + "./framework/vendure/schema.d.ts": { + "plugins": ["typescript", "typescript-operations"], + "config": { + "scalars": { + "ID": "string" + } + } + }, + "./framework/vendure/schema.graphql": { + "plugins": ["schema-ast"] + } + }, + "hooks": { + "afterAllFileWrite": ["prettier --write"] + } +} diff --git a/framework/vendure/commerce.config.json b/framework/vendure/commerce.config.json new file mode 100644 index 000000000..70806f062 --- /dev/null +++ b/framework/vendure/commerce.config.json @@ -0,0 +1,6 @@ +{ + "provider": "vendure", + "features": { + "wishlist": false + } +} diff --git a/framework/vendure/common/get-all-pages.ts b/framework/vendure/common/get-all-pages.ts new file mode 100644 index 000000000..1200b02b1 --- /dev/null +++ b/framework/vendure/common/get-all-pages.ts @@ -0,0 +1,35 @@ +import { getConfig, VendureConfig } from '../api' + +export type Page = any + +export type GetAllPagesResult< + T extends { pages: any[] } = { pages: Page[] } +> = T + +async function getAllPages(opts?: { + config?: VendureConfig + preview?: boolean +}): Promise + +async function getAllPages(opts: { + url: string + config?: VendureConfig + preview?: boolean +}): Promise> + +async function getAllPages({ + config, + preview, +}: { + url?: string + config?: VendureConfig + preview?: boolean +} = {}): Promise { + config = getConfig(config) + + return { + pages: [], + } +} + +export default getAllPages diff --git a/framework/vendure/common/get-page.ts b/framework/vendure/common/get-page.ts new file mode 100644 index 000000000..48a183630 --- /dev/null +++ b/framework/vendure/common/get-page.ts @@ -0,0 +1,40 @@ +import { VendureConfig, getConfig } from '../api' + +export type Page = any + +export type GetPageResult = T + +export type PageVariables = { + id: number +} + +async function getPage(opts: { + url?: string + variables: PageVariables + config?: VendureConfig + preview?: boolean +}): Promise + +async function getPage(opts: { + url: string + variables: V + config?: VendureConfig + preview?: boolean +}): Promise> + +async function getPage({ + url, + variables, + config, + preview, +}: { + url?: string + variables: PageVariables + config?: VendureConfig + preview?: boolean +}): Promise { + config = getConfig(config) + return {} +} + +export default getPage diff --git a/framework/vendure/common/get-site-info.ts b/framework/vendure/common/get-site-info.ts new file mode 100644 index 000000000..9410c4493 --- /dev/null +++ b/framework/vendure/common/get-site-info.ts @@ -0,0 +1,49 @@ +import { getConfig, VendureConfig } from '../api' +import { GetCollectionsQuery } from '../schema' +import { arrayToTree } from '../lib/array-to-tree' +import { getCollectionsQuery } from '../lib/queries/get-collections-query' + +export type Category = { + entityId: string + name: string + path: string + productCount: number +} + +export type GetSiteInfoResult< + T extends { categories: any[]; brands: any[] } = { + categories: Category[] + brands: any[] + } +> = T + +async function getSiteInfo({ + query = getCollectionsQuery, + variables, + config, +}: { + query?: string + variables?: any + config?: VendureConfig + preview?: boolean +} = {}): Promise { + config = getConfig(config) + // RecursivePartial forces the method to check for every prop in the data, which is + // required in case there's a custom `query` + const { data } = await config.fetch(query, { variables }) + const collections = data.collections?.items.map((i) => ({ + ...i, + entityId: i.id, + path: i.slug, + productCount: i.productVariants.totalItems, + })) + const categories = arrayToTree(collections).children + const brands = [] as any[] + + return { + categories: categories ?? [], + brands, + } +} + +export default getSiteInfo diff --git a/framework/vendure/customer/get-customer-wishlist.ts b/framework/vendure/customer/get-customer-wishlist.ts new file mode 100644 index 000000000..81ec96956 --- /dev/null +++ b/framework/vendure/customer/get-customer-wishlist.ts @@ -0,0 +1,18 @@ +import { getConfig, VendureConfig } from '../api' + +async function getCustomerWishlist({ + config, + variables, + includeProducts, +}: { + url?: string + variables: any + config?: VendureConfig + includeProducts?: boolean +}): Promise { + // Not implemented as Vendure does not ship with wishlist functionality at present + config = getConfig(config) + return { wishlist: {} } +} + +export default getCustomerWishlist diff --git a/framework/vendure/customer/index.ts b/framework/vendure/customer/index.ts new file mode 100644 index 000000000..6c903ecc5 --- /dev/null +++ b/framework/vendure/customer/index.ts @@ -0,0 +1 @@ +export { default as useCustomer } from './use-customer' diff --git a/framework/vendure/customer/use-customer.tsx b/framework/vendure/customer/use-customer.tsx new file mode 100644 index 000000000..4de821253 --- /dev/null +++ b/framework/vendure/customer/use-customer.tsx @@ -0,0 +1,33 @@ +import { SWRHook } from '@commerce/utils/types' +import useCustomer, { UseCustomer } from '@commerce/customer/use-customer' +import { Customer } from '@commerce/types' +import { ActiveCustomerQuery } from '../schema' +import { activeCustomerQuery } from '../lib/queries/active-customer-query' + +export default useCustomer as UseCustomer + +export const handler: SWRHook = { + fetchOptions: { + query: activeCustomerQuery, + }, + async fetcher({ options, fetch }) { + const { activeCustomer } = await fetch({ + ...options, + }) + return activeCustomer + ? ({ + firstName: activeCustomer.firstName ?? '', + lastName: activeCustomer.lastName ?? '', + email: activeCustomer.emailAddress ?? '', + } as any) + : null + }, + useHook: ({ useData }) => (input) => { + return useData({ + swrOptions: { + revalidateOnFocus: false, + ...input?.swrOptions, + }, + }) + }, +} diff --git a/framework/vendure/fetcher.ts b/framework/vendure/fetcher.ts new file mode 100644 index 000000000..bf8f0dcd8 --- /dev/null +++ b/framework/vendure/fetcher.ts @@ -0,0 +1,51 @@ +import { Fetcher } from '@commerce/utils/types' +import { FetcherError } from '@commerce/utils/errors' + +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 }) +} + +export const fetcher: Fetcher = async ({ + url, + method = 'POST', + variables, + query, + body: bodyObj, +}) => { + const shopApiUrl = + process.env.NEXT_PUBLIC_VENDURE_LOCAL_URL || + process.env.NEXT_PUBLIC_VENDURE_SHOP_API_URL + if (!shopApiUrl) { + throw new Error( + 'The Vendure Shop API url has not been provided. Please define NEXT_PUBLIC_VENDURE_SHOP_API_URL in .env.local' + ) + } + const hasBody = Boolean(variables || query) + const body = hasBody ? JSON.stringify({ query, variables }) : undefined + const headers = hasBody ? { 'Content-Type': 'application/json' } : undefined + const res = await fetch(shopApiUrl, { + method, + body, + headers, + credentials: 'include', + }) + + if (res.ok) { + const { data } = await res.json() + return data + } + + throw await getError(res) +} diff --git a/framework/vendure/index.tsx b/framework/vendure/index.tsx new file mode 100644 index 000000000..47e60c7df --- /dev/null +++ b/framework/vendure/index.tsx @@ -0,0 +1,33 @@ +import * as React from 'react' +import { ReactNode } from 'react' +import { + CommerceConfig, + CommerceProvider as CoreCommerceProvider, + useCommerce as useCoreCommerce, +} from '@commerce' +import { vendureProvider } from './provider' + +export const vendureConfig: CommerceConfig = { + locale: 'en-us', + cartCookie: 'session', +} + +export type VendureConfig = Partial + +export type VendureProps = { + children?: ReactNode + locale: string +} & VendureConfig + +export function CommerceProvider({ children, ...config }: VendureProps) { + return ( + + {children} + + ) +} + +export const useCommerce = () => useCoreCommerce() diff --git a/framework/vendure/lib/array-to-tree.ts b/framework/vendure/lib/array-to-tree.ts new file mode 100644 index 000000000..403cf226e --- /dev/null +++ b/framework/vendure/lib/array-to-tree.ts @@ -0,0 +1,67 @@ +export type HasParent = { id: string; parent?: { id: string } | null } +export type TreeNode = T & { + children: Array> + expanded: boolean +} +export type RootNode = { + id?: string + children: Array> +} + +export function arrayToTree( + nodes: T[], + currentState?: RootNode +): RootNode { + const topLevelNodes: Array> = [] + const mappedArr: { [id: string]: TreeNode } = {} + const currentStateMap = treeToMap(currentState) + + // First map the nodes of the array to an object -> create a hash table. + for (const node of nodes) { + mappedArr[node.id] = { ...(node as any), children: [] } + } + + for (const id of nodes.map((n) => n.id)) { + if (mappedArr.hasOwnProperty(id)) { + const mappedElem = mappedArr[id] + mappedElem.expanded = currentStateMap.get(id)?.expanded ?? false + const parent = mappedElem.parent + if (!parent) { + continue + } + // If the element is not at the root level, add it to its parent array of children. + const parentIsRoot = !mappedArr[parent.id] + if (!parentIsRoot) { + if (mappedArr[parent.id]) { + mappedArr[parent.id].children.push(mappedElem) + } else { + mappedArr[parent.id] = { children: [mappedElem] } as any + } + } else { + topLevelNodes.push(mappedElem) + } + } + } + // tslint:disable-next-line:no-non-null-assertion + const rootId = topLevelNodes.length ? topLevelNodes[0].parent!.id : undefined + return { id: rootId, children: topLevelNodes } +} + +/** + * Converts an existing tree (as generated by the arrayToTree function) into a flat + * Map. This is used to persist certain states (e.g. `expanded`) when re-building the + * tree. + */ +function treeToMap( + tree?: RootNode +): Map> { + const nodeMap = new Map>() + function visit(node: TreeNode) { + nodeMap.set(node.id, node) + node.children.forEach(visit) + } + if (tree) { + visit(tree as TreeNode) + } + return nodeMap +} diff --git a/framework/vendure/lib/fragments/cart-fragment.ts b/framework/vendure/lib/fragments/cart-fragment.ts new file mode 100644 index 000000000..36371e07c --- /dev/null +++ b/framework/vendure/lib/fragments/cart-fragment.ts @@ -0,0 +1,42 @@ +export const cartFragment = /* GraphQL */ ` + fragment Cart on Order { + id + code + createdAt + totalQuantity + subTotal + subTotalWithTax + total + totalWithTax + currencyCode + customer { + id + } + lines { + id + quantity + linePriceWithTax + discountedLinePriceWithTax + featuredAsset { + id + preview + } + discounts { + description + amount + } + productVariant { + id + name + sku + price + priceWithTax + stockLevel + product { + slug + } + productId + } + } + } +` diff --git a/framework/vendure/lib/fragments/search-result-fragment.ts b/framework/vendure/lib/fragments/search-result-fragment.ts new file mode 100644 index 000000000..6155b5b47 --- /dev/null +++ b/framework/vendure/lib/fragments/search-result-fragment.ts @@ -0,0 +1,24 @@ +export const searchResultFragment = /* GraphQL */ ` + fragment SearchResult on SearchResult { + productId + productName + description + description + slug + sku + currencyCode + productAsset { + id + preview + } + priceWithTax { + ... on SinglePrice { + value + } + ... on PriceRange { + min + max + } + } + } +` diff --git a/framework/vendure/lib/mutations/add-item-to-order-mutation.ts b/framework/vendure/lib/mutations/add-item-to-order-mutation.ts new file mode 100644 index 000000000..5ed41d972 --- /dev/null +++ b/framework/vendure/lib/mutations/add-item-to-order-mutation.ts @@ -0,0 +1,15 @@ +import { cartFragment } from '../fragments/cart-fragment' + +export const addItemToOrderMutation = /* GraphQL */ ` + mutation addItemToOrder($variantId: ID!, $quantity: Int!) { + addItemToOrder(productVariantId: $variantId, quantity: $quantity) { + __typename + ...Cart + ... on ErrorResult { + errorCode + message + } + } + } + ${cartFragment} +` diff --git a/framework/vendure/lib/mutations/adjust-order-line-mutation.ts b/framework/vendure/lib/mutations/adjust-order-line-mutation.ts new file mode 100644 index 000000000..ce9864b12 --- /dev/null +++ b/framework/vendure/lib/mutations/adjust-order-line-mutation.ts @@ -0,0 +1,15 @@ +import { cartFragment } from '../fragments/cart-fragment' + +export const adjustOrderLineMutation = /* GraphQL */ ` + mutation adjustOrderLine($orderLineId: ID!, $quantity: Int!) { + adjustOrderLine(orderLineId: $orderLineId, quantity: $quantity) { + __typename + ...Cart + ... on ErrorResult { + errorCode + message + } + } + } + ${cartFragment} +` diff --git a/framework/vendure/lib/mutations/log-in-mutation.ts b/framework/vendure/lib/mutations/log-in-mutation.ts new file mode 100644 index 000000000..75e2ddba9 --- /dev/null +++ b/framework/vendure/lib/mutations/log-in-mutation.ts @@ -0,0 +1,14 @@ +export const loginMutation = /* GraphQL */ ` + mutation login($username: String!, $password: String!) { + login(username: $username, password: $password) { + __typename + ... on CurrentUser { + id + } + ... on ErrorResult { + errorCode + message + } + } + } +` diff --git a/framework/vendure/lib/mutations/log-out-mutation.ts b/framework/vendure/lib/mutations/log-out-mutation.ts new file mode 100644 index 000000000..6f222c5c8 --- /dev/null +++ b/framework/vendure/lib/mutations/log-out-mutation.ts @@ -0,0 +1,7 @@ +export const logoutMutation = /* GraphQL */ ` + mutation logout { + logout { + success + } + } +` diff --git a/framework/vendure/lib/mutations/remove-order-line-mutation.ts b/framework/vendure/lib/mutations/remove-order-line-mutation.ts new file mode 100644 index 000000000..47a89039e --- /dev/null +++ b/framework/vendure/lib/mutations/remove-order-line-mutation.ts @@ -0,0 +1,15 @@ +import { cartFragment } from '../fragments/cart-fragment' + +export const removeOrderLineMutation = /* GraphQL */ ` + mutation removeOrderLine($orderLineId: ID!) { + removeOrderLine(orderLineId: $orderLineId) { + __typename + ...Cart + ... on ErrorResult { + errorCode + message + } + } + } + ${cartFragment} +` diff --git a/framework/vendure/lib/mutations/sign-up-mutation.ts b/framework/vendure/lib/mutations/sign-up-mutation.ts new file mode 100644 index 000000000..410e395c2 --- /dev/null +++ b/framework/vendure/lib/mutations/sign-up-mutation.ts @@ -0,0 +1,14 @@ +export const signupMutation = /* GraphQL */ ` + mutation signup($input: RegisterCustomerInput!) { + registerCustomerAccount(input: $input) { + __typename + ... on Success { + success + } + ... on ErrorResult { + errorCode + message + } + } + } +` diff --git a/framework/vendure/lib/normalize.ts b/framework/vendure/lib/normalize.ts new file mode 100644 index 000000000..c64ff2136 --- /dev/null +++ b/framework/vendure/lib/normalize.ts @@ -0,0 +1,55 @@ +import { Cart, Product } from '@commerce/types' +import { CartFragment, SearchResultFragment } from '../schema' + +export function normalizeSearchResult(item: SearchResultFragment): Product { + return { + id: item.productId, + name: item.productName, + description: item.description, + slug: item.slug, + path: item.slug, + images: [{ url: item.productAsset?.preview + '?w=800&mode=crop' || '' }], + variants: [], + price: { + value: (item.priceWithTax as any).min / 100, + currencyCode: item.currencyCode, + }, + options: [], + sku: item.sku, + } +} + +export function normalizeCart(order: CartFragment): Cart { + return { + id: order.id.toString(), + createdAt: order.createdAt, + taxesIncluded: true, + lineItemsSubtotalPrice: order.subTotalWithTax / 100, + currency: { code: order.currencyCode }, + subtotalPrice: order.subTotalWithTax / 100, + totalPrice: order.totalWithTax / 100, + customerId: order.customer?.id, + lineItems: order.lines?.map((l) => ({ + id: l.id, + name: l.productVariant.name, + quantity: l.quantity, + url: l.productVariant.product.slug, + variantId: l.productVariant.id, + productId: l.productVariant.productId, + images: [{ url: l.featuredAsset?.preview + '?preset=thumb' || '' }], + discounts: l.discounts.map((d) => ({ value: d.amount / 100 })), + path: '', + variant: { + id: l.productVariant.id, + name: l.productVariant.name, + sku: l.productVariant.sku, + price: l.discountedLinePriceWithTax / 100, + listPrice: l.linePriceWithTax / 100, + image: { + url: l.featuredAsset?.preview + '?preset=thumb' || '', + }, + requiresShipping: true, + }, + })), + } +} diff --git a/framework/vendure/lib/queries/active-customer-query.ts b/framework/vendure/lib/queries/active-customer-query.ts new file mode 100644 index 000000000..65b280743 --- /dev/null +++ b/framework/vendure/lib/queries/active-customer-query.ts @@ -0,0 +1,10 @@ +export const activeCustomerQuery = /* GraphQL */ ` + query activeCustomer { + activeCustomer { + id + firstName + lastName + emailAddress + } + } +` diff --git a/framework/vendure/lib/queries/get-all-product-paths-query.ts b/framework/vendure/lib/queries/get-all-product-paths-query.ts new file mode 100644 index 000000000..29922dca2 --- /dev/null +++ b/framework/vendure/lib/queries/get-all-product-paths-query.ts @@ -0,0 +1,9 @@ +export const getAllProductPathsQuery = /* GraphQL */ ` + query getAllProductPaths($first: Int = 100) { + products(options: { take: $first }) { + items { + slug + } + } + } +` diff --git a/framework/vendure/lib/queries/get-all-products-query.ts b/framework/vendure/lib/queries/get-all-products-query.ts new file mode 100644 index 000000000..1b44b2017 --- /dev/null +++ b/framework/vendure/lib/queries/get-all-products-query.ts @@ -0,0 +1,12 @@ +import { searchResultFragment } from '../fragments/search-result-fragment' + +export const getAllProductsQuery = /* GraphQL */ ` + query getAllProducts($input: SearchInput!) { + search(input: $input) { + items { + ...SearchResult + } + } + } + ${searchResultFragment} +` diff --git a/framework/vendure/lib/queries/get-cart-query.ts b/framework/vendure/lib/queries/get-cart-query.ts new file mode 100644 index 000000000..7faac355c --- /dev/null +++ b/framework/vendure/lib/queries/get-cart-query.ts @@ -0,0 +1,10 @@ +import { cartFragment } from '../fragments/cart-fragment' + +export const getCartQuery = /* GraphQL */ ` + query activeOrder { + activeOrder { + ...Cart + } + } + ${cartFragment} +` diff --git a/framework/vendure/lib/queries/get-collections-query.ts b/framework/vendure/lib/queries/get-collections-query.ts new file mode 100644 index 000000000..ed0919652 --- /dev/null +++ b/framework/vendure/lib/queries/get-collections-query.ts @@ -0,0 +1,21 @@ +export const getCollectionsQuery = /* GraphQL */ ` + query getCollections { + collections { + items { + id + name + description + slug + productVariants { + totalItems + } + parent { + id + } + children { + id + } + } + } + } +` diff --git a/framework/vendure/lib/queries/get-product-query.ts b/framework/vendure/lib/queries/get-product-query.ts new file mode 100644 index 000000000..b2c502da9 --- /dev/null +++ b/framework/vendure/lib/queries/get-product-query.ts @@ -0,0 +1,41 @@ +export const getProductQuery = /* GraphQL */ ` + query getProduct($slug: String!) { + product(slug: $slug) { + id + name + slug + description + assets { + id + preview + name + } + variants { + id + priceWithTax + currencyCode + options { + id + name + code + groupId + group { + id + options { + name + } + } + } + } + optionGroups { + id + code + name + options { + id + name + } + } + } + } +` diff --git a/framework/vendure/lib/queries/search-query.ts b/framework/vendure/lib/queries/search-query.ts new file mode 100644 index 000000000..f95c43703 --- /dev/null +++ b/framework/vendure/lib/queries/search-query.ts @@ -0,0 +1,13 @@ +import { searchResultFragment } from '../fragments/search-result-fragment' + +export const searchQuery = /* GraphQL */ ` + query search($input: SearchInput!) { + search(input: $input) { + items { + ...SearchResult + } + totalItems + } + } + ${searchResultFragment} +` diff --git a/framework/vendure/next.config.js b/framework/vendure/next.config.js new file mode 100644 index 000000000..96153ad1e --- /dev/null +++ b/framework/vendure/next.config.js @@ -0,0 +1,8 @@ +const commerce = require('./commerce.config.json') + +module.exports = { + commerce, + images: { + domains: ['localhost', 'demo.vendure.io'], + }, +} diff --git a/framework/vendure/product/get-all-product-paths.ts b/framework/vendure/product/get-all-product-paths.ts new file mode 100644 index 000000000..dfbaff1b8 --- /dev/null +++ b/framework/vendure/product/get-all-product-paths.ts @@ -0,0 +1,48 @@ +import type { + GetAllProductPathsQuery, + GetAllProductPathsQueryVariables, +} from '../schema' +import { getConfig, VendureConfig } from '../api' +import { getAllProductPathsQuery } from '../lib/queries/get-all-product-paths-query' + +export type GetAllProductPathsResult = { + products: Array<{ node: { path: string } }> +} + +async function getAllProductPaths(opts?: { + variables?: GetAllProductPathsQueryVariables + config?: VendureConfig +}): Promise + +async function getAllProductPaths< + T extends { products: any[] }, + V = any +>(opts: { + query: string + variables?: V + config?: VendureConfig +}): Promise + +async function getAllProductPaths({ + query = getAllProductPathsQuery, + variables, + config, +}: { + query?: string + variables?: GetAllProductPathsQueryVariables + config?: VendureConfig +} = {}): Promise { + config = getConfig(config) + // RecursivePartial forces the method to check for every prop in the data, which is + // required in case there's a custom `query` + const { data } = await config.fetch(query, { + variables, + }) + const products = data.products.items + + return { + products: products.map((p) => ({ node: { path: `/${p.slug}` } })), + } +} + +export default getAllProductPaths diff --git a/framework/vendure/product/get-all-products.ts b/framework/vendure/product/get-all-products.ts new file mode 100644 index 000000000..b292e0246 --- /dev/null +++ b/framework/vendure/product/get-all-products.ts @@ -0,0 +1,39 @@ +import { Product } from '@commerce/types' +import { getConfig, VendureConfig } from '../api' +import { GetAllProductsQuery } from '../schema' +import { normalizeSearchResult } from '../lib/normalize' +import { getAllProductsQuery } from '../lib/queries/get-all-products-query' + +export type ProductVariables = { first?: number } + +async function getAllProducts(opts?: { + variables?: ProductVariables + config?: VendureConfig + preview?: boolean +}): Promise<{ products: Product[] }> + +async function getAllProducts({ + query = getAllProductsQuery, + variables: { ...vars } = {}, + config, +}: { + query?: string + variables?: ProductVariables + config?: VendureConfig + preview?: boolean +} = {}): Promise<{ products: Product[] | any[] }> { + config = getConfig(config) + const variables = { + input: { + take: vars.first, + groupByProduct: true, + }, + } + const { data } = await config.fetch(query, { variables }) + + return { + products: data.search.items.map((item) => normalizeSearchResult(item)), + } +} + +export default getAllProducts diff --git a/framework/vendure/product/get-product.ts b/framework/vendure/product/get-product.ts new file mode 100644 index 000000000..735164ec1 --- /dev/null +++ b/framework/vendure/product/get-product.ts @@ -0,0 +1,57 @@ +import { Product } from '@commerce/types' +import { getConfig, VendureConfig } from '../api' +import { GetProductQuery } from '../schema' +import { getProductQuery } from '../lib/queries/get-product-query' + +async function getProduct({ + query = getProductQuery, + variables, + config, +}: { + query?: string + variables: { slug: string } + config?: VendureConfig + preview?: boolean +}): Promise { + config = getConfig(config) + + const locale = config.locale + const { data } = await config.fetch(query, { variables }) + const product = data.product + + if (product) { + return { + product: { + id: product.id, + name: product.name, + description: product.description, + slug: product.slug, + images: product.assets.map((a) => ({ + url: a.preview, + alt: a.name, + })), + variants: product.variants.map((v) => ({ + id: v.id, + options: v.options.map((o) => ({ + id: o.id, + displayName: o.name, + values: o.group.options.map((_o) => ({ label: _o.name })), + })), + })), + price: { + value: product.variants[0].priceWithTax / 100, + currencyCode: product.variants[0].currencyCode, + }, + options: product.optionGroups.map((og) => ({ + id: og.id, + displayName: og.name, + values: og.options.map((o) => ({ label: o.name })), + })), + } as Product, + } + } + + return {} +} + +export default getProduct diff --git a/framework/vendure/product/index.ts b/framework/vendure/product/index.ts new file mode 100644 index 000000000..b290c189f --- /dev/null +++ b/framework/vendure/product/index.ts @@ -0,0 +1,4 @@ +export { default as usePrice } from './use-price' +export { default as useSearch } from './use-search' +export { default as getProduct } from './get-product' +export { default as getAllProducts } from './get-all-products' diff --git a/framework/vendure/product/use-price.tsx b/framework/vendure/product/use-price.tsx new file mode 100644 index 000000000..0174faf5e --- /dev/null +++ b/framework/vendure/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/vendure/product/use-search.tsx b/framework/vendure/product/use-search.tsx new file mode 100644 index 000000000..00d9db36c --- /dev/null +++ b/framework/vendure/product/use-search.tsx @@ -0,0 +1,65 @@ +import { SWRHook } from '@commerce/utils/types' +import useSearch, { UseSearch } from '@commerce/product/use-search' +import { Product } from '@commerce/types' +import { SearchQuery, SearchQueryVariables } from '../schema' +import { normalizeSearchResult } from '../lib/normalize' +import { searchQuery } from '../lib/queries/search-query' + +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: searchQuery, + }, + async fetcher({ input, options, fetch }) { + const { categoryId, brandId } = input + + const variables: SearchQueryVariables = { + input: { + term: input.search, + collectionId: input.categoryId, + groupByProduct: true, + // TODO: what is the "sort" value? + }, + } + const { search } = await fetch({ + query: searchQuery, + variables, + }) + + return { + found: search.totalItems > 0, + products: search.items.map((item) => normalizeSearchResult(item)) ?? [], + } + }, + 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/vendure/provider.ts b/framework/vendure/provider.ts new file mode 100644 index 000000000..e100c277b --- /dev/null +++ b/framework/vendure/provider.ts @@ -0,0 +1,21 @@ +import { Provider } from '@commerce' +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 vendureProvider: Provider = { + locale: 'en-us', + cartCookie: 'session', + fetcher, + cart: { useCart, useAddItem, useUpdateItem, useRemoveItem }, + customer: { useCustomer }, + products: { useSearch }, + auth: { useLogin, useLogout, useSignup }, +} diff --git a/framework/vendure/schema.d.ts b/framework/vendure/schema.d.ts new file mode 100644 index 000000000..78e821257 --- /dev/null +++ b/framework/vendure/schema.d.ts @@ -0,0 +1,3122 @@ +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 + /** The `JSON` scalar type represents JSON values as specified by [ECMA-404](http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf). */ + JSON: any + /** A date-time string at UTC, such as 2007-12-03T10:15:30Z, compliant with the `date-time` format outlined in section 5.6 of the RFC 3339 profile of the ISO 8601 standard for representation of dates and times using the Gregorian calendar. */ + DateTime: any + /** The `Upload` scalar type represents a file upload. */ + Upload: any +} + +export type Query = { + __typename?: 'Query' + /** The active Channel */ + activeChannel: Channel + /** The active Customer */ + activeCustomer?: Maybe + /** + * The active Order. Will be `null` until an Order is created via `addItemToOrder`. Once an Order reaches the + * state of `PaymentApproved` or `PaymentSettled`, then that Order is no longer considered "active" and this + * query will once again return `null`. + */ + activeOrder?: Maybe + /** An array of supported Countries */ + availableCountries: Array + /** A list of Collections available to the shop */ + collections: CollectionList + /** Returns a Collection either by its id or slug. If neither 'id' nor 'slug' is speicified, an error will result. */ + collection?: Maybe + /** Returns a list of eligible shipping methods based on the current active Order */ + eligibleShippingMethods: Array + /** Returns a list of payment methods and their eligibility based on the current active Order */ + eligiblePaymentMethods: Array + /** Returns information about the current authenticated User */ + me?: Maybe + /** Returns the possible next states that the activeOrder can transition to */ + nextOrderStates: Array + /** + * Returns an Order based on the id. Note that in the Shop API, only orders belonging to the + * currently-authenticated User may be queried. + */ + order?: Maybe + /** + * Returns an Order based on the order `code`. For guest Orders (i.e. Orders placed by non-authenticated Customers) + * this query will only return the Order within 2 hours of the Order being placed. This allows an Order confirmation + * screen to be shown immediately after completion of a guest checkout, yet prevents security risks of allowing + * general anonymous access to Order data. + */ + orderByCode?: Maybe + /** Get a Product either by id or slug. If neither 'id' nor 'slug' is speicified, an error will result. */ + product?: Maybe + /** Get a list of Products */ + products: ProductList + /** Search Products based on the criteria set by the `SearchInput` */ + search: SearchResponse +} + +export type QueryCollectionsArgs = { + options?: Maybe +} + +export type QueryCollectionArgs = { + id?: Maybe + slug?: Maybe +} + +export type QueryOrderArgs = { + id: Scalars['ID'] +} + +export type QueryOrderByCodeArgs = { + code: Scalars['String'] +} + +export type QueryProductArgs = { + id?: Maybe + slug?: Maybe +} + +export type QueryProductsArgs = { + options?: Maybe +} + +export type QuerySearchArgs = { + input: SearchInput +} + +export type Mutation = { + __typename?: 'Mutation' + /** Adds an item to the order. If custom fields are defined on the OrderLine entity, a third argument 'customFields' will be available. */ + addItemToOrder: UpdateOrderItemsResult + /** Remove an OrderLine from the Order */ + removeOrderLine: RemoveOrderItemsResult + /** Remove all OrderLine from the Order */ + removeAllOrderLines: RemoveOrderItemsResult + /** Adjusts an OrderLine. If custom fields are defined on the OrderLine entity, a third argument 'customFields' of type `OrderLineCustomFieldsInput` will be available. */ + adjustOrderLine: UpdateOrderItemsResult + /** Applies the given coupon code to the active Order */ + applyCouponCode: ApplyCouponCodeResult + /** Removes the given coupon code from the active Order */ + removeCouponCode?: Maybe + /** Transitions an Order to a new state. Valid next states can be found by querying `nextOrderStates` */ + transitionOrderToState?: Maybe + /** Sets the shipping address for this order */ + setOrderShippingAddress: ActiveOrderResult + /** Sets the billing address for this order */ + setOrderBillingAddress: ActiveOrderResult + /** Allows any custom fields to be set for the active order */ + setOrderCustomFields: ActiveOrderResult + /** Sets the shipping method by id, which can be obtained with the `eligibleShippingMethods` query */ + setOrderShippingMethod: SetOrderShippingMethodResult + /** Add a Payment to the Order */ + addPaymentToOrder: AddPaymentToOrderResult + /** Set the Customer for the Order. Required only if the Customer is not currently logged in */ + setCustomerForOrder: SetCustomerForOrderResult + /** Authenticates the user using the native authentication strategy. This mutation is an alias for `authenticate({ native: { ... }})` */ + login: NativeAuthenticationResult + /** Authenticates the user using a named authentication strategy */ + authenticate: AuthenticationResult + /** End the current authenticated session */ + logout: Success + /** + * Register a Customer account with the given credentials. There are three possible registration flows: + * + * _If `authOptions.requireVerification` is set to `true`:_ + * + * 1. **The Customer is registered _with_ a password**. A verificationToken will be created (and typically emailed to the Customer). That + * verificationToken would then be passed to the `verifyCustomerAccount` mutation _without_ a password. The Customer is then + * verified and authenticated in one step. + * 2. **The Customer is registered _without_ a password**. A verificationToken will be created (and typically emailed to the Customer). That + * verificationToken would then be passed to the `verifyCustomerAccount` mutation _with_ the chosed password of the Customer. The Customer is then + * verified and authenticated in one step. + * + * _If `authOptions.requireVerification` is set to `false`:_ + * + * 3. The Customer _must_ be registered _with_ a password. No further action is needed - the Customer is able to authenticate immediately. + */ + registerCustomerAccount: RegisterCustomerAccountResult + /** Regenerate and send a verification token for a new Customer registration. Only applicable if `authOptions.requireVerification` is set to true. */ + refreshCustomerVerification: RefreshCustomerVerificationResult + /** Update an existing Customer */ + updateCustomer: Customer + /** Create a new Customer Address */ + createCustomerAddress: Address + /** Update an existing Address */ + updateCustomerAddress: Address + /** Delete an existing Address */ + deleteCustomerAddress: Success + /** + * Verify a Customer email address with the token sent to that address. Only applicable if `authOptions.requireVerification` is set to true. + * + * If the Customer was not registered with a password in the `registerCustomerAccount` mutation, the a password _must_ be + * provided here. + */ + verifyCustomerAccount: VerifyCustomerAccountResult + /** Update the password of the active Customer */ + updateCustomerPassword: UpdateCustomerPasswordResult + /** + * Request to update the emailAddress of the active Customer. If `authOptions.requireVerification` is enabled + * (as is the default), then the `identifierChangeToken` will be assigned to the current User and + * a IdentifierChangeRequestEvent will be raised. This can then be used e.g. by the EmailPlugin to email + * that verification token to the Customer, which is then used to verify the change of email address. + */ + requestUpdateCustomerEmailAddress: RequestUpdateCustomerEmailAddressResult + /** + * Confirm the update of the emailAddress with the provided token, which has been generated by the + * `requestUpdateCustomerEmailAddress` mutation. + */ + updateCustomerEmailAddress: UpdateCustomerEmailAddressResult + /** Requests a password reset email to be sent */ + requestPasswordReset?: Maybe + /** Resets a Customer's password based on the provided token */ + resetPassword: ResetPasswordResult +} + +export type MutationAddItemToOrderArgs = { + productVariantId: Scalars['ID'] + quantity: Scalars['Int'] +} + +export type MutationRemoveOrderLineArgs = { + orderLineId: Scalars['ID'] +} + +export type MutationAdjustOrderLineArgs = { + orderLineId: Scalars['ID'] + quantity: Scalars['Int'] +} + +export type MutationApplyCouponCodeArgs = { + couponCode: Scalars['String'] +} + +export type MutationRemoveCouponCodeArgs = { + couponCode: Scalars['String'] +} + +export type MutationTransitionOrderToStateArgs = { + state: Scalars['String'] +} + +export type MutationSetOrderShippingAddressArgs = { + input: CreateAddressInput +} + +export type MutationSetOrderBillingAddressArgs = { + input: CreateAddressInput +} + +export type MutationSetOrderCustomFieldsArgs = { + input: UpdateOrderInput +} + +export type MutationSetOrderShippingMethodArgs = { + shippingMethodId: Scalars['ID'] +} + +export type MutationAddPaymentToOrderArgs = { + input: PaymentInput +} + +export type MutationSetCustomerForOrderArgs = { + input: CreateCustomerInput +} + +export type MutationLoginArgs = { + username: Scalars['String'] + password: Scalars['String'] + rememberMe?: Maybe +} + +export type MutationAuthenticateArgs = { + input: AuthenticationInput + rememberMe?: Maybe +} + +export type MutationRegisterCustomerAccountArgs = { + input: RegisterCustomerInput +} + +export type MutationRefreshCustomerVerificationArgs = { + emailAddress: Scalars['String'] +} + +export type MutationUpdateCustomerArgs = { + input: UpdateCustomerInput +} + +export type MutationCreateCustomerAddressArgs = { + input: CreateAddressInput +} + +export type MutationUpdateCustomerAddressArgs = { + input: UpdateAddressInput +} + +export type MutationDeleteCustomerAddressArgs = { + id: Scalars['ID'] +} + +export type MutationVerifyCustomerAccountArgs = { + token: Scalars['String'] + password?: Maybe +} + +export type MutationUpdateCustomerPasswordArgs = { + currentPassword: Scalars['String'] + newPassword: Scalars['String'] +} + +export type MutationRequestUpdateCustomerEmailAddressArgs = { + password: Scalars['String'] + newEmailAddress: Scalars['String'] +} + +export type MutationUpdateCustomerEmailAddressArgs = { + token: Scalars['String'] +} + +export type MutationRequestPasswordResetArgs = { + emailAddress: Scalars['String'] +} + +export type MutationResetPasswordArgs = { + token: Scalars['String'] + password: Scalars['String'] +} + +export type Address = Node & { + __typename?: 'Address' + id: Scalars['ID'] + createdAt: Scalars['DateTime'] + updatedAt: Scalars['DateTime'] + fullName?: Maybe + company?: Maybe + streetLine1: Scalars['String'] + streetLine2?: Maybe + city?: Maybe + province?: Maybe + postalCode?: Maybe + country: Country + phoneNumber?: Maybe + defaultShippingAddress?: Maybe + defaultBillingAddress?: Maybe + customFields?: Maybe +} + +export type Asset = Node & { + __typename?: 'Asset' + id: Scalars['ID'] + createdAt: Scalars['DateTime'] + updatedAt: Scalars['DateTime'] + name: Scalars['String'] + type: AssetType + fileSize: Scalars['Int'] + mimeType: Scalars['String'] + width: Scalars['Int'] + height: Scalars['Int'] + source: Scalars['String'] + preview: Scalars['String'] + focalPoint?: Maybe + customFields?: Maybe +} + +export type Coordinate = { + __typename?: 'Coordinate' + x: Scalars['Float'] + y: Scalars['Float'] +} + +export type AssetList = PaginatedList & { + __typename?: 'AssetList' + items: Array + totalItems: Scalars['Int'] +} + +export enum AssetType { + Image = 'IMAGE', + Video = 'VIDEO', + Binary = 'BINARY', +} + +export type CurrentUser = { + __typename?: 'CurrentUser' + id: Scalars['ID'] + identifier: Scalars['String'] + channels: Array +} + +export type CurrentUserChannel = { + __typename?: 'CurrentUserChannel' + id: Scalars['ID'] + token: Scalars['String'] + code: Scalars['String'] + permissions: Array +} + +export type Channel = Node & { + __typename?: 'Channel' + id: Scalars['ID'] + createdAt: Scalars['DateTime'] + updatedAt: Scalars['DateTime'] + code: Scalars['String'] + token: Scalars['String'] + defaultTaxZone?: Maybe + defaultShippingZone?: Maybe + defaultLanguageCode: LanguageCode + currencyCode: CurrencyCode + pricesIncludeTax: Scalars['Boolean'] + customFields?: Maybe +} + +export type Collection = Node & { + __typename?: 'Collection' + id: Scalars['ID'] + createdAt: Scalars['DateTime'] + updatedAt: Scalars['DateTime'] + languageCode?: Maybe + name: Scalars['String'] + slug: Scalars['String'] + breadcrumbs: Array + position: Scalars['Int'] + description: Scalars['String'] + featuredAsset?: Maybe + assets: Array + parent?: Maybe + children?: Maybe> + filters: Array + translations: Array + productVariants: ProductVariantList + customFields?: Maybe +} + +export type CollectionProductVariantsArgs = { + options?: Maybe +} + +export type CollectionBreadcrumb = { + __typename?: 'CollectionBreadcrumb' + id: Scalars['ID'] + name: Scalars['String'] + slug: Scalars['String'] +} + +export type CollectionTranslation = { + __typename?: 'CollectionTranslation' + id: Scalars['ID'] + createdAt: Scalars['DateTime'] + updatedAt: Scalars['DateTime'] + languageCode: LanguageCode + name: Scalars['String'] + slug: Scalars['String'] + description: Scalars['String'] +} + +export type CollectionList = PaginatedList & { + __typename?: 'CollectionList' + items: Array + totalItems: Scalars['Int'] +} + +export type ProductVariantList = PaginatedList & { + __typename?: 'ProductVariantList' + items: Array + totalItems: Scalars['Int'] +} + +export enum GlobalFlag { + True = 'TRUE', + False = 'FALSE', + Inherit = 'INHERIT', +} + +export enum AdjustmentType { + Promotion = 'PROMOTION', + DistributedOrderPromotion = 'DISTRIBUTED_ORDER_PROMOTION', +} + +export enum DeletionResult { + /** The entity was successfully deleted */ + Deleted = 'DELETED', + /** Deletion did not take place, reason given in message */ + NotDeleted = 'NOT_DELETED', +} + +/** + * @description + * Permissions for administrators and customers. Used to control access to + * GraphQL resolvers via the {@link Allow} decorator. + * + * @docsCategory common + */ +export enum Permission { + /** Authenticated means simply that the user is logged in */ + Authenticated = 'Authenticated', + /** SuperAdmin has unrestricted access to all operations */ + SuperAdmin = 'SuperAdmin', + /** Owner means the user owns this entity, e.g. a Customer's own Order */ + Owner = 'Owner', + /** Public means any unauthenticated user may perform the operation */ + Public = 'Public', + /** Grants permission to create Catalog */ + CreateCatalog = 'CreateCatalog', + /** Grants permission to read Catalog */ + ReadCatalog = 'ReadCatalog', + /** Grants permission to update Catalog */ + UpdateCatalog = 'UpdateCatalog', + /** Grants permission to delete Catalog */ + DeleteCatalog = 'DeleteCatalog', + /** Grants permission to create Customer */ + CreateCustomer = 'CreateCustomer', + /** Grants permission to read Customer */ + ReadCustomer = 'ReadCustomer', + /** Grants permission to update Customer */ + UpdateCustomer = 'UpdateCustomer', + /** Grants permission to delete Customer */ + DeleteCustomer = 'DeleteCustomer', + /** Grants permission to create Administrator */ + CreateAdministrator = 'CreateAdministrator', + /** Grants permission to read Administrator */ + ReadAdministrator = 'ReadAdministrator', + /** Grants permission to update Administrator */ + UpdateAdministrator = 'UpdateAdministrator', + /** Grants permission to delete Administrator */ + DeleteAdministrator = 'DeleteAdministrator', + /** Grants permission to create Order */ + CreateOrder = 'CreateOrder', + /** Grants permission to read Order */ + ReadOrder = 'ReadOrder', + /** Grants permission to update Order */ + UpdateOrder = 'UpdateOrder', + /** Grants permission to delete Order */ + DeleteOrder = 'DeleteOrder', + /** Grants permission to create Promotion */ + CreatePromotion = 'CreatePromotion', + /** Grants permission to read Promotion */ + ReadPromotion = 'ReadPromotion', + /** Grants permission to update Promotion */ + UpdatePromotion = 'UpdatePromotion', + /** Grants permission to delete Promotion */ + DeletePromotion = 'DeletePromotion', + /** Grants permission to create Settings */ + CreateSettings = 'CreateSettings', + /** Grants permission to read Settings */ + ReadSettings = 'ReadSettings', + /** Grants permission to update Settings */ + UpdateSettings = 'UpdateSettings', + /** Grants permission to delete Settings */ + DeleteSettings = 'DeleteSettings', +} + +export enum SortOrder { + Asc = 'ASC', + Desc = 'DESC', +} + +export enum ErrorCode { + UnknownError = 'UNKNOWN_ERROR', + NativeAuthStrategyError = 'NATIVE_AUTH_STRATEGY_ERROR', + InvalidCredentialsError = 'INVALID_CREDENTIALS_ERROR', + OrderStateTransitionError = 'ORDER_STATE_TRANSITION_ERROR', + EmailAddressConflictError = 'EMAIL_ADDRESS_CONFLICT_ERROR', + OrderLimitError = 'ORDER_LIMIT_ERROR', + NegativeQuantityError = 'NEGATIVE_QUANTITY_ERROR', + InsufficientStockError = 'INSUFFICIENT_STOCK_ERROR', + OrderModificationError = 'ORDER_MODIFICATION_ERROR', + IneligibleShippingMethodError = 'INELIGIBLE_SHIPPING_METHOD_ERROR', + OrderPaymentStateError = 'ORDER_PAYMENT_STATE_ERROR', + IneligiblePaymentMethodError = 'INELIGIBLE_PAYMENT_METHOD_ERROR', + PaymentFailedError = 'PAYMENT_FAILED_ERROR', + PaymentDeclinedError = 'PAYMENT_DECLINED_ERROR', + CouponCodeInvalidError = 'COUPON_CODE_INVALID_ERROR', + CouponCodeExpiredError = 'COUPON_CODE_EXPIRED_ERROR', + CouponCodeLimitError = 'COUPON_CODE_LIMIT_ERROR', + AlreadyLoggedInError = 'ALREADY_LOGGED_IN_ERROR', + MissingPasswordError = 'MISSING_PASSWORD_ERROR', + PasswordAlreadySetError = 'PASSWORD_ALREADY_SET_ERROR', + VerificationTokenInvalidError = 'VERIFICATION_TOKEN_INVALID_ERROR', + VerificationTokenExpiredError = 'VERIFICATION_TOKEN_EXPIRED_ERROR', + IdentifierChangeTokenInvalidError = 'IDENTIFIER_CHANGE_TOKEN_INVALID_ERROR', + IdentifierChangeTokenExpiredError = 'IDENTIFIER_CHANGE_TOKEN_EXPIRED_ERROR', + PasswordResetTokenInvalidError = 'PASSWORD_RESET_TOKEN_INVALID_ERROR', + PasswordResetTokenExpiredError = 'PASSWORD_RESET_TOKEN_EXPIRED_ERROR', + NotVerifiedError = 'NOT_VERIFIED_ERROR', + NoActiveOrderError = 'NO_ACTIVE_ORDER_ERROR', +} + +export enum LogicalOperator { + And = 'AND', + Or = 'OR', +} + +/** Retured when attempting an operation that relies on the NativeAuthStrategy, if that strategy is not configured. */ +export type NativeAuthStrategyError = ErrorResult & { + __typename?: 'NativeAuthStrategyError' + errorCode: ErrorCode + message: Scalars['String'] +} + +/** Returned if the user authentication credentials are not valid */ +export type InvalidCredentialsError = ErrorResult & { + __typename?: 'InvalidCredentialsError' + errorCode: ErrorCode + message: Scalars['String'] + authenticationError: Scalars['String'] +} + +/** Returned if there is an error in transitioning the Order state */ +export type OrderStateTransitionError = ErrorResult & { + __typename?: 'OrderStateTransitionError' + errorCode: ErrorCode + message: Scalars['String'] + transitionError: Scalars['String'] + fromState: Scalars['String'] + toState: Scalars['String'] +} + +/** Retured when attemting to create a Customer with an email address already registered to an existing User. */ +export type EmailAddressConflictError = ErrorResult & { + __typename?: 'EmailAddressConflictError' + errorCode: ErrorCode + message: Scalars['String'] +} + +/** Retured when the maximum order size limit has been reached. */ +export type OrderLimitError = ErrorResult & { + __typename?: 'OrderLimitError' + errorCode: ErrorCode + message: Scalars['String'] + maxItems: Scalars['Int'] +} + +/** Retured when attemting to set a negative OrderLine quantity. */ +export type NegativeQuantityError = ErrorResult & { + __typename?: 'NegativeQuantityError' + errorCode: ErrorCode + message: Scalars['String'] +} + +/** Returned when attempting to add more items to the Order than are available */ +export type InsufficientStockError = ErrorResult & { + __typename?: 'InsufficientStockError' + errorCode: ErrorCode + message: Scalars['String'] + quantityAvailable: Scalars['Int'] + order: Order +} + +export type PaginatedList = { + items: Array + totalItems: Scalars['Int'] +} + +export type Node = { + id: Scalars['ID'] +} + +export type ErrorResult = { + errorCode: ErrorCode + message: Scalars['String'] +} + +export type Adjustment = { + __typename?: 'Adjustment' + adjustmentSource: Scalars['String'] + type: AdjustmentType + description: Scalars['String'] + amount: Scalars['Int'] +} + +export type TaxLine = { + __typename?: 'TaxLine' + description: Scalars['String'] + taxRate: Scalars['Float'] +} + +export type ConfigArg = { + __typename?: 'ConfigArg' + name: Scalars['String'] + value: Scalars['String'] +} + +export type ConfigArgDefinition = { + __typename?: 'ConfigArgDefinition' + name: Scalars['String'] + type: Scalars['String'] + list: Scalars['Boolean'] + required: Scalars['Boolean'] + defaultValue?: Maybe + label?: Maybe + description?: Maybe + ui?: Maybe +} + +export type ConfigurableOperation = { + __typename?: 'ConfigurableOperation' + code: Scalars['String'] + args: Array +} + +export type ConfigurableOperationDefinition = { + __typename?: 'ConfigurableOperationDefinition' + code: Scalars['String'] + args: Array + description: Scalars['String'] +} + +export type DeletionResponse = { + __typename?: 'DeletionResponse' + result: DeletionResult + message?: Maybe +} + +export type ConfigArgInput = { + name: Scalars['String'] + /** A JSON stringified representation of the actual value */ + value: Scalars['String'] +} + +export type ConfigurableOperationInput = { + code: Scalars['String'] + arguments: Array +} + +export type StringOperators = { + eq?: Maybe + notEq?: Maybe + contains?: Maybe + notContains?: Maybe + in?: Maybe> + notIn?: Maybe> + regex?: Maybe +} + +export type BooleanOperators = { + eq?: Maybe +} + +export type NumberRange = { + start: Scalars['Float'] + end: Scalars['Float'] +} + +export type NumberOperators = { + eq?: Maybe + lt?: Maybe + lte?: Maybe + gt?: Maybe + gte?: Maybe + between?: Maybe +} + +export type DateRange = { + start: Scalars['DateTime'] + end: Scalars['DateTime'] +} + +export type DateOperators = { + eq?: Maybe + before?: Maybe + after?: Maybe + between?: Maybe +} + +export type SearchInput = { + term?: Maybe + facetValueIds?: Maybe> + facetValueOperator?: Maybe + collectionId?: Maybe + collectionSlug?: Maybe + groupByProduct?: Maybe + take?: Maybe + skip?: Maybe + sort?: Maybe +} + +export type SearchResultSortParameter = { + name?: Maybe + price?: Maybe +} + +export type CreateCustomerInput = { + title?: Maybe + firstName: Scalars['String'] + lastName: Scalars['String'] + phoneNumber?: Maybe + emailAddress: Scalars['String'] + customFields?: Maybe +} + +export type CreateAddressInput = { + fullName?: Maybe + company?: Maybe + streetLine1: Scalars['String'] + streetLine2?: Maybe + city?: Maybe + province?: Maybe + postalCode?: Maybe + countryCode: Scalars['String'] + phoneNumber?: Maybe + defaultShippingAddress?: Maybe + defaultBillingAddress?: Maybe + customFields?: Maybe +} + +export type UpdateAddressInput = { + id: Scalars['ID'] + fullName?: Maybe + company?: Maybe + streetLine1?: Maybe + streetLine2?: Maybe + city?: Maybe + province?: Maybe + postalCode?: Maybe + countryCode?: Maybe + phoneNumber?: Maybe + defaultShippingAddress?: Maybe + defaultBillingAddress?: Maybe + customFields?: Maybe +} + +/** Indicates that an operation succeeded, where we do not want to return any more specific information. */ +export type Success = { + __typename?: 'Success' + success: Scalars['Boolean'] +} + +export type ShippingMethodQuote = { + __typename?: 'ShippingMethodQuote' + id: Scalars['ID'] + price: Scalars['Int'] + priceWithTax: Scalars['Int'] + name: Scalars['String'] + description: Scalars['String'] + /** Any optional metadata returned by the ShippingCalculator in the ShippingCalculationResult */ + metadata?: Maybe +} + +export type PaymentMethodQuote = { + __typename?: 'PaymentMethodQuote' + id: Scalars['ID'] + code: Scalars['String'] + isEligible: Scalars['Boolean'] + eligibilityMessage?: Maybe +} + +export type Country = Node & { + __typename?: 'Country' + id: Scalars['ID'] + createdAt: Scalars['DateTime'] + updatedAt: Scalars['DateTime'] + languageCode: LanguageCode + code: Scalars['String'] + name: Scalars['String'] + enabled: Scalars['Boolean'] + translations: Array +} + +export type CountryTranslation = { + __typename?: 'CountryTranslation' + id: Scalars['ID'] + createdAt: Scalars['DateTime'] + updatedAt: Scalars['DateTime'] + languageCode: LanguageCode + name: Scalars['String'] +} + +export type CountryList = PaginatedList & { + __typename?: 'CountryList' + items: Array + totalItems: Scalars['Int'] +} + +/** + * @description + * ISO 4217 currency code + * + * @docsCategory common + */ +export enum CurrencyCode { + /** United Arab Emirates dirham */ + Aed = 'AED', + /** Afghan afghani */ + Afn = 'AFN', + /** Albanian lek */ + All = 'ALL', + /** Armenian dram */ + Amd = 'AMD', + /** Netherlands Antillean guilder */ + Ang = 'ANG', + /** Angolan kwanza */ + Aoa = 'AOA', + /** Argentine peso */ + Ars = 'ARS', + /** Australian dollar */ + Aud = 'AUD', + /** Aruban florin */ + Awg = 'AWG', + /** Azerbaijani manat */ + Azn = 'AZN', + /** Bosnia and Herzegovina convertible mark */ + Bam = 'BAM', + /** Barbados dollar */ + Bbd = 'BBD', + /** Bangladeshi taka */ + Bdt = 'BDT', + /** Bulgarian lev */ + Bgn = 'BGN', + /** Bahraini dinar */ + Bhd = 'BHD', + /** Burundian franc */ + Bif = 'BIF', + /** Bermudian dollar */ + Bmd = 'BMD', + /** Brunei dollar */ + Bnd = 'BND', + /** Boliviano */ + Bob = 'BOB', + /** Brazilian real */ + Brl = 'BRL', + /** Bahamian dollar */ + Bsd = 'BSD', + /** Bhutanese ngultrum */ + Btn = 'BTN', + /** Botswana pula */ + Bwp = 'BWP', + /** Belarusian ruble */ + Byn = 'BYN', + /** Belize dollar */ + Bzd = 'BZD', + /** Canadian dollar */ + Cad = 'CAD', + /** Congolese franc */ + Cdf = 'CDF', + /** Swiss franc */ + Chf = 'CHF', + /** Chilean peso */ + Clp = 'CLP', + /** Renminbi (Chinese) yuan */ + Cny = 'CNY', + /** Colombian peso */ + Cop = 'COP', + /** Costa Rican colon */ + Crc = 'CRC', + /** Cuban convertible peso */ + Cuc = 'CUC', + /** Cuban peso */ + Cup = 'CUP', + /** Cape Verde escudo */ + Cve = 'CVE', + /** Czech koruna */ + Czk = 'CZK', + /** Djiboutian franc */ + Djf = 'DJF', + /** Danish krone */ + Dkk = 'DKK', + /** Dominican peso */ + Dop = 'DOP', + /** Algerian dinar */ + Dzd = 'DZD', + /** Egyptian pound */ + Egp = 'EGP', + /** Eritrean nakfa */ + Ern = 'ERN', + /** Ethiopian birr */ + Etb = 'ETB', + /** Euro */ + Eur = 'EUR', + /** Fiji dollar */ + Fjd = 'FJD', + /** Falkland Islands pound */ + Fkp = 'FKP', + /** Pound sterling */ + Gbp = 'GBP', + /** Georgian lari */ + Gel = 'GEL', + /** Ghanaian cedi */ + Ghs = 'GHS', + /** Gibraltar pound */ + Gip = 'GIP', + /** Gambian dalasi */ + Gmd = 'GMD', + /** Guinean franc */ + Gnf = 'GNF', + /** Guatemalan quetzal */ + Gtq = 'GTQ', + /** Guyanese dollar */ + Gyd = 'GYD', + /** Hong Kong dollar */ + Hkd = 'HKD', + /** Honduran lempira */ + Hnl = 'HNL', + /** Croatian kuna */ + Hrk = 'HRK', + /** Haitian gourde */ + Htg = 'HTG', + /** Hungarian forint */ + Huf = 'HUF', + /** Indonesian rupiah */ + Idr = 'IDR', + /** Israeli new shekel */ + Ils = 'ILS', + /** Indian rupee */ + Inr = 'INR', + /** Iraqi dinar */ + Iqd = 'IQD', + /** Iranian rial */ + Irr = 'IRR', + /** Icelandic króna */ + Isk = 'ISK', + /** Jamaican dollar */ + Jmd = 'JMD', + /** Jordanian dinar */ + Jod = 'JOD', + /** Japanese yen */ + Jpy = 'JPY', + /** Kenyan shilling */ + Kes = 'KES', + /** Kyrgyzstani som */ + Kgs = 'KGS', + /** Cambodian riel */ + Khr = 'KHR', + /** Comoro franc */ + Kmf = 'KMF', + /** North Korean won */ + Kpw = 'KPW', + /** South Korean won */ + Krw = 'KRW', + /** Kuwaiti dinar */ + Kwd = 'KWD', + /** Cayman Islands dollar */ + Kyd = 'KYD', + /** Kazakhstani tenge */ + Kzt = 'KZT', + /** Lao kip */ + Lak = 'LAK', + /** Lebanese pound */ + Lbp = 'LBP', + /** Sri Lankan rupee */ + Lkr = 'LKR', + /** Liberian dollar */ + Lrd = 'LRD', + /** Lesotho loti */ + Lsl = 'LSL', + /** Libyan dinar */ + Lyd = 'LYD', + /** Moroccan dirham */ + Mad = 'MAD', + /** Moldovan leu */ + Mdl = 'MDL', + /** Malagasy ariary */ + Mga = 'MGA', + /** Macedonian denar */ + Mkd = 'MKD', + /** Myanmar kyat */ + Mmk = 'MMK', + /** Mongolian tögrög */ + Mnt = 'MNT', + /** Macanese pataca */ + Mop = 'MOP', + /** Mauritanian ouguiya */ + Mru = 'MRU', + /** Mauritian rupee */ + Mur = 'MUR', + /** Maldivian rufiyaa */ + Mvr = 'MVR', + /** Malawian kwacha */ + Mwk = 'MWK', + /** Mexican peso */ + Mxn = 'MXN', + /** Malaysian ringgit */ + Myr = 'MYR', + /** Mozambican metical */ + Mzn = 'MZN', + /** Namibian dollar */ + Nad = 'NAD', + /** Nigerian naira */ + Ngn = 'NGN', + /** Nicaraguan córdoba */ + Nio = 'NIO', + /** Norwegian krone */ + Nok = 'NOK', + /** Nepalese rupee */ + Npr = 'NPR', + /** New Zealand dollar */ + Nzd = 'NZD', + /** Omani rial */ + Omr = 'OMR', + /** Panamanian balboa */ + Pab = 'PAB', + /** Peruvian sol */ + Pen = 'PEN', + /** Papua New Guinean kina */ + Pgk = 'PGK', + /** Philippine peso */ + Php = 'PHP', + /** Pakistani rupee */ + Pkr = 'PKR', + /** Polish złoty */ + Pln = 'PLN', + /** Paraguayan guaraní */ + Pyg = 'PYG', + /** Qatari riyal */ + Qar = 'QAR', + /** Romanian leu */ + Ron = 'RON', + /** Serbian dinar */ + Rsd = 'RSD', + /** Russian ruble */ + Rub = 'RUB', + /** Rwandan franc */ + Rwf = 'RWF', + /** Saudi riyal */ + Sar = 'SAR', + /** Solomon Islands dollar */ + Sbd = 'SBD', + /** Seychelles rupee */ + Scr = 'SCR', + /** Sudanese pound */ + Sdg = 'SDG', + /** Swedish krona/kronor */ + Sek = 'SEK', + /** Singapore dollar */ + Sgd = 'SGD', + /** Saint Helena pound */ + Shp = 'SHP', + /** Sierra Leonean leone */ + Sll = 'SLL', + /** Somali shilling */ + Sos = 'SOS', + /** Surinamese dollar */ + Srd = 'SRD', + /** South Sudanese pound */ + Ssp = 'SSP', + /** São Tomé and Príncipe dobra */ + Stn = 'STN', + /** Salvadoran colón */ + Svc = 'SVC', + /** Syrian pound */ + Syp = 'SYP', + /** Swazi lilangeni */ + Szl = 'SZL', + /** Thai baht */ + Thb = 'THB', + /** Tajikistani somoni */ + Tjs = 'TJS', + /** Turkmenistan manat */ + Tmt = 'TMT', + /** Tunisian dinar */ + Tnd = 'TND', + /** Tongan paʻanga */ + Top = 'TOP', + /** Turkish lira */ + Try = 'TRY', + /** Trinidad and Tobago dollar */ + Ttd = 'TTD', + /** New Taiwan dollar */ + Twd = 'TWD', + /** Tanzanian shilling */ + Tzs = 'TZS', + /** Ukrainian hryvnia */ + Uah = 'UAH', + /** Ugandan shilling */ + Ugx = 'UGX', + /** United States dollar */ + Usd = 'USD', + /** Uruguayan peso */ + Uyu = 'UYU', + /** Uzbekistan som */ + Uzs = 'UZS', + /** Venezuelan bolívar soberano */ + Ves = 'VES', + /** Vietnamese đồng */ + Vnd = 'VND', + /** Vanuatu vatu */ + Vuv = 'VUV', + /** Samoan tala */ + Wst = 'WST', + /** CFA franc BEAC */ + Xaf = 'XAF', + /** East Caribbean dollar */ + Xcd = 'XCD', + /** CFA franc BCEAO */ + Xof = 'XOF', + /** CFP franc (franc Pacifique) */ + Xpf = 'XPF', + /** Yemeni rial */ + Yer = 'YER', + /** South African rand */ + Zar = 'ZAR', + /** Zambian kwacha */ + Zmw = 'ZMW', + /** Zimbabwean dollar */ + Zwl = 'ZWL', +} + +export type CustomField = { + name: Scalars['String'] + type: Scalars['String'] + list: Scalars['Boolean'] + label?: Maybe> + description?: Maybe> + readonly?: Maybe + internal?: Maybe +} + +export type StringCustomFieldConfig = CustomField & { + __typename?: 'StringCustomFieldConfig' + name: Scalars['String'] + type: Scalars['String'] + list: Scalars['Boolean'] + length?: Maybe + label?: Maybe> + description?: Maybe> + readonly?: Maybe + internal?: Maybe + pattern?: Maybe + options?: Maybe> +} + +export type StringFieldOption = { + __typename?: 'StringFieldOption' + value: Scalars['String'] + label?: Maybe> +} + +export type LocaleStringCustomFieldConfig = CustomField & { + __typename?: 'LocaleStringCustomFieldConfig' + name: Scalars['String'] + type: Scalars['String'] + list: Scalars['Boolean'] + length?: Maybe + label?: Maybe> + description?: Maybe> + readonly?: Maybe + internal?: Maybe + pattern?: Maybe +} + +export type IntCustomFieldConfig = CustomField & { + __typename?: 'IntCustomFieldConfig' + name: Scalars['String'] + type: Scalars['String'] + list: Scalars['Boolean'] + label?: Maybe> + description?: Maybe> + readonly?: Maybe + internal?: Maybe + min?: Maybe + max?: Maybe + step?: Maybe +} + +export type FloatCustomFieldConfig = CustomField & { + __typename?: 'FloatCustomFieldConfig' + name: Scalars['String'] + type: Scalars['String'] + list: Scalars['Boolean'] + label?: Maybe> + description?: Maybe> + readonly?: Maybe + internal?: Maybe + min?: Maybe + max?: Maybe + step?: Maybe +} + +export type BooleanCustomFieldConfig = CustomField & { + __typename?: 'BooleanCustomFieldConfig' + name: Scalars['String'] + type: Scalars['String'] + list: Scalars['Boolean'] + label?: Maybe> + description?: Maybe> + readonly?: Maybe + internal?: Maybe +} + +/** + * Expects the same validation formats as the `` HTML element. + * See https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/datetime-local#Additional_attributes + */ +export type DateTimeCustomFieldConfig = CustomField & { + __typename?: 'DateTimeCustomFieldConfig' + name: Scalars['String'] + type: Scalars['String'] + list: Scalars['Boolean'] + label?: Maybe> + description?: Maybe> + readonly?: Maybe + internal?: Maybe + min?: Maybe + max?: Maybe + step?: Maybe +} + +export type RelationCustomFieldConfig = CustomField & { + __typename?: 'RelationCustomFieldConfig' + name: Scalars['String'] + type: Scalars['String'] + list: Scalars['Boolean'] + label?: Maybe> + description?: Maybe> + readonly?: Maybe + internal?: Maybe + entity: Scalars['String'] + scalarFields: Array +} + +export type LocalizedString = { + __typename?: 'LocalizedString' + languageCode: LanguageCode + value: Scalars['String'] +} + +export type CustomFieldConfig = + | StringCustomFieldConfig + | LocaleStringCustomFieldConfig + | IntCustomFieldConfig + | FloatCustomFieldConfig + | BooleanCustomFieldConfig + | DateTimeCustomFieldConfig + | RelationCustomFieldConfig + +export type CustomerGroup = Node & { + __typename?: 'CustomerGroup' + id: Scalars['ID'] + createdAt: Scalars['DateTime'] + updatedAt: Scalars['DateTime'] + name: Scalars['String'] + customers: CustomerList +} + +export type CustomerGroupCustomersArgs = { + options?: Maybe +} + +export type Customer = Node & { + __typename?: 'Customer' + id: Scalars['ID'] + createdAt: Scalars['DateTime'] + updatedAt: Scalars['DateTime'] + title?: Maybe + firstName: Scalars['String'] + lastName: Scalars['String'] + phoneNumber?: Maybe + emailAddress: Scalars['String'] + addresses?: Maybe> + orders: OrderList + user?: Maybe + customFields?: Maybe +} + +export type CustomerOrdersArgs = { + options?: Maybe +} + +export type CustomerList = PaginatedList & { + __typename?: 'CustomerList' + items: Array + totalItems: Scalars['Int'] +} + +export type FacetValue = Node & { + __typename?: 'FacetValue' + id: Scalars['ID'] + createdAt: Scalars['DateTime'] + updatedAt: Scalars['DateTime'] + languageCode: LanguageCode + facet: Facet + name: Scalars['String'] + code: Scalars['String'] + translations: Array + customFields?: Maybe +} + +export type FacetValueTranslation = { + __typename?: 'FacetValueTranslation' + id: Scalars['ID'] + createdAt: Scalars['DateTime'] + updatedAt: Scalars['DateTime'] + languageCode: LanguageCode + name: Scalars['String'] +} + +export type Facet = Node & { + __typename?: 'Facet' + id: Scalars['ID'] + createdAt: Scalars['DateTime'] + updatedAt: Scalars['DateTime'] + languageCode: LanguageCode + name: Scalars['String'] + code: Scalars['String'] + values: Array + translations: Array + customFields?: Maybe +} + +export type FacetTranslation = { + __typename?: 'FacetTranslation' + id: Scalars['ID'] + createdAt: Scalars['DateTime'] + updatedAt: Scalars['DateTime'] + languageCode: LanguageCode + name: Scalars['String'] +} + +export type FacetList = PaginatedList & { + __typename?: 'FacetList' + items: Array + totalItems: Scalars['Int'] +} + +export type HistoryEntry = Node & { + __typename?: 'HistoryEntry' + id: Scalars['ID'] + createdAt: Scalars['DateTime'] + updatedAt: Scalars['DateTime'] + type: HistoryEntryType + data: Scalars['JSON'] +} + +export enum HistoryEntryType { + CustomerRegistered = 'CUSTOMER_REGISTERED', + CustomerVerified = 'CUSTOMER_VERIFIED', + CustomerDetailUpdated = 'CUSTOMER_DETAIL_UPDATED', + CustomerAddedToGroup = 'CUSTOMER_ADDED_TO_GROUP', + CustomerRemovedFromGroup = 'CUSTOMER_REMOVED_FROM_GROUP', + CustomerAddressCreated = 'CUSTOMER_ADDRESS_CREATED', + CustomerAddressUpdated = 'CUSTOMER_ADDRESS_UPDATED', + CustomerAddressDeleted = 'CUSTOMER_ADDRESS_DELETED', + CustomerPasswordUpdated = 'CUSTOMER_PASSWORD_UPDATED', + CustomerPasswordResetRequested = 'CUSTOMER_PASSWORD_RESET_REQUESTED', + CustomerPasswordResetVerified = 'CUSTOMER_PASSWORD_RESET_VERIFIED', + CustomerEmailUpdateRequested = 'CUSTOMER_EMAIL_UPDATE_REQUESTED', + CustomerEmailUpdateVerified = 'CUSTOMER_EMAIL_UPDATE_VERIFIED', + CustomerNote = 'CUSTOMER_NOTE', + OrderStateTransition = 'ORDER_STATE_TRANSITION', + OrderPaymentTransition = 'ORDER_PAYMENT_TRANSITION', + OrderFulfillment = 'ORDER_FULFILLMENT', + OrderCancellation = 'ORDER_CANCELLATION', + OrderRefundTransition = 'ORDER_REFUND_TRANSITION', + OrderFulfillmentTransition = 'ORDER_FULFILLMENT_TRANSITION', + OrderNote = 'ORDER_NOTE', + OrderCouponApplied = 'ORDER_COUPON_APPLIED', + OrderCouponRemoved = 'ORDER_COUPON_REMOVED', + OrderModified = 'ORDER_MODIFIED', +} + +export type HistoryEntryList = PaginatedList & { + __typename?: 'HistoryEntryList' + items: Array + totalItems: Scalars['Int'] +} + +/** + * @description + * Languages in the form of a ISO 639-1 language code with optional + * region or script modifier (e.g. de_AT). The selection available is based + * on the [Unicode CLDR summary list](https://unicode-org.github.io/cldr-staging/charts/37/summary/root.html) + * and includes the major spoken languages of the world and any widely-used variants. + * + * @docsCategory common + */ +export enum LanguageCode { + /** Afrikaans */ + Af = 'af', + /** Akan */ + Ak = 'ak', + /** Albanian */ + Sq = 'sq', + /** Amharic */ + Am = 'am', + /** Arabic */ + Ar = 'ar', + /** Armenian */ + Hy = 'hy', + /** Assamese */ + As = 'as', + /** Azerbaijani */ + Az = 'az', + /** Bambara */ + Bm = 'bm', + /** Bangla */ + Bn = 'bn', + /** Basque */ + Eu = 'eu', + /** Belarusian */ + Be = 'be', + /** Bosnian */ + Bs = 'bs', + /** Breton */ + Br = 'br', + /** Bulgarian */ + Bg = 'bg', + /** Burmese */ + My = 'my', + /** Catalan */ + Ca = 'ca', + /** Chechen */ + Ce = 'ce', + /** Chinese */ + Zh = 'zh', + /** Simplified Chinese */ + ZhHans = 'zh_Hans', + /** Traditional Chinese */ + ZhHant = 'zh_Hant', + /** Church Slavic */ + Cu = 'cu', + /** Cornish */ + Kw = 'kw', + /** Corsican */ + Co = 'co', + /** Croatian */ + Hr = 'hr', + /** Czech */ + Cs = 'cs', + /** Danish */ + Da = 'da', + /** Dutch */ + Nl = 'nl', + /** Flemish */ + NlBe = 'nl_BE', + /** Dzongkha */ + Dz = 'dz', + /** English */ + En = 'en', + /** Australian English */ + EnAu = 'en_AU', + /** Canadian English */ + EnCa = 'en_CA', + /** British English */ + EnGb = 'en_GB', + /** American English */ + EnUs = 'en_US', + /** Esperanto */ + Eo = 'eo', + /** Estonian */ + Et = 'et', + /** Ewe */ + Ee = 'ee', + /** Faroese */ + Fo = 'fo', + /** Finnish */ + Fi = 'fi', + /** French */ + Fr = 'fr', + /** Canadian French */ + FrCa = 'fr_CA', + /** Swiss French */ + FrCh = 'fr_CH', + /** Fulah */ + Ff = 'ff', + /** Galician */ + Gl = 'gl', + /** Ganda */ + Lg = 'lg', + /** Georgian */ + Ka = 'ka', + /** German */ + De = 'de', + /** Austrian German */ + DeAt = 'de_AT', + /** Swiss High German */ + DeCh = 'de_CH', + /** Greek */ + El = 'el', + /** Gujarati */ + Gu = 'gu', + /** Haitian Creole */ + Ht = 'ht', + /** Hausa */ + Ha = 'ha', + /** Hebrew */ + He = 'he', + /** Hindi */ + Hi = 'hi', + /** Hungarian */ + Hu = 'hu', + /** Icelandic */ + Is = 'is', + /** Igbo */ + Ig = 'ig', + /** Indonesian */ + Id = 'id', + /** Interlingua */ + Ia = 'ia', + /** Irish */ + Ga = 'ga', + /** Italian */ + It = 'it', + /** Japanese */ + Ja = 'ja', + /** Javanese */ + Jv = 'jv', + /** Kalaallisut */ + Kl = 'kl', + /** Kannada */ + Kn = 'kn', + /** Kashmiri */ + Ks = 'ks', + /** Kazakh */ + Kk = 'kk', + /** Khmer */ + Km = 'km', + /** Kikuyu */ + Ki = 'ki', + /** Kinyarwanda */ + Rw = 'rw', + /** Korean */ + Ko = 'ko', + /** Kurdish */ + Ku = 'ku', + /** Kyrgyz */ + Ky = 'ky', + /** Lao */ + Lo = 'lo', + /** Latin */ + La = 'la', + /** Latvian */ + Lv = 'lv', + /** Lingala */ + Ln = 'ln', + /** Lithuanian */ + Lt = 'lt', + /** Luba-Katanga */ + Lu = 'lu', + /** Luxembourgish */ + Lb = 'lb', + /** Macedonian */ + Mk = 'mk', + /** Malagasy */ + Mg = 'mg', + /** Malay */ + Ms = 'ms', + /** Malayalam */ + Ml = 'ml', + /** Maltese */ + Mt = 'mt', + /** Manx */ + Gv = 'gv', + /** Maori */ + Mi = 'mi', + /** Marathi */ + Mr = 'mr', + /** Mongolian */ + Mn = 'mn', + /** Nepali */ + Ne = 'ne', + /** North Ndebele */ + Nd = 'nd', + /** Northern Sami */ + Se = 'se', + /** Norwegian Bokmål */ + Nb = 'nb', + /** Norwegian Nynorsk */ + Nn = 'nn', + /** Nyanja */ + Ny = 'ny', + /** Odia */ + Or = 'or', + /** Oromo */ + Om = 'om', + /** Ossetic */ + Os = 'os', + /** Pashto */ + Ps = 'ps', + /** Persian */ + Fa = 'fa', + /** Dari */ + FaAf = 'fa_AF', + /** Polish */ + Pl = 'pl', + /** Portuguese */ + Pt = 'pt', + /** Brazilian Portuguese */ + PtBr = 'pt_BR', + /** European Portuguese */ + PtPt = 'pt_PT', + /** Punjabi */ + Pa = 'pa', + /** Quechua */ + Qu = 'qu', + /** Romanian */ + Ro = 'ro', + /** Moldavian */ + RoMd = 'ro_MD', + /** Romansh */ + Rm = 'rm', + /** Rundi */ + Rn = 'rn', + /** Russian */ + Ru = 'ru', + /** Samoan */ + Sm = 'sm', + /** Sango */ + Sg = 'sg', + /** Sanskrit */ + Sa = 'sa', + /** Scottish Gaelic */ + Gd = 'gd', + /** Serbian */ + Sr = 'sr', + /** Shona */ + Sn = 'sn', + /** Sichuan Yi */ + Ii = 'ii', + /** Sindhi */ + Sd = 'sd', + /** Sinhala */ + Si = 'si', + /** Slovak */ + Sk = 'sk', + /** Slovenian */ + Sl = 'sl', + /** Somali */ + So = 'so', + /** Southern Sotho */ + St = 'st', + /** Spanish */ + Es = 'es', + /** European Spanish */ + EsEs = 'es_ES', + /** Mexican Spanish */ + EsMx = 'es_MX', + /** Sundanese */ + Su = 'su', + /** Swahili */ + Sw = 'sw', + /** Congo Swahili */ + SwCd = 'sw_CD', + /** Swedish */ + Sv = 'sv', + /** Tajik */ + Tg = 'tg', + /** Tamil */ + Ta = 'ta', + /** Tatar */ + Tt = 'tt', + /** Telugu */ + Te = 'te', + /** Thai */ + Th = 'th', + /** Tibetan */ + Bo = 'bo', + /** Tigrinya */ + Ti = 'ti', + /** Tongan */ + To = 'to', + /** Turkish */ + Tr = 'tr', + /** Turkmen */ + Tk = 'tk', + /** Ukrainian */ + Uk = 'uk', + /** Urdu */ + Ur = 'ur', + /** Uyghur */ + Ug = 'ug', + /** Uzbek */ + Uz = 'uz', + /** Vietnamese */ + Vi = 'vi', + /** Volapük */ + Vo = 'vo', + /** Welsh */ + Cy = 'cy', + /** Western Frisian */ + Fy = 'fy', + /** Wolof */ + Wo = 'wo', + /** Xhosa */ + Xh = 'xh', + /** Yiddish */ + Yi = 'yi', + /** Yoruba */ + Yo = 'yo', + /** Zulu */ + Zu = 'zu', +} + +export type Order = Node & { + __typename?: 'Order' + id: Scalars['ID'] + createdAt: Scalars['DateTime'] + updatedAt: Scalars['DateTime'] + /** + * The date & time that the Order was placed, i.e. the Customer + * completed the checkout and the Order is no longer "active" + */ + orderPlacedAt?: Maybe + /** A unique code for the Order */ + code: Scalars['String'] + state: Scalars['String'] + /** An order is active as long as the payment process has not been completed */ + active: Scalars['Boolean'] + customer?: Maybe + shippingAddress?: Maybe + billingAddress?: Maybe + lines: Array + /** + * Surcharges are arbitrary modifications to the Order total which are neither + * ProductVariants nor discounts resulting from applied Promotions. For example, + * one-off discounts based on customer interaction, or surcharges based on payment + * methods. + */ + surcharges: Array + /** + * Order-level adjustments to the order total, such as discounts from promotions + * @deprecated Use `discounts` instead + */ + adjustments: Array + discounts: Array + /** An array of all coupon codes applied to the Order */ + couponCodes: Array + /** Promotions applied to the order. Only gets populated after the payment process has completed. */ + promotions: Array + payments?: Maybe> + fulfillments?: Maybe> + totalQuantity: Scalars['Int'] + /** + * The subTotal is the total of all OrderLines in the Order. This figure also includes any Order-level + * discounts which have been prorated (proportionally distributed) amongst the OrderItems. + * To get a total of all OrderLines which does not account for prorated discounts, use the + * sum of `OrderLine.discountedLinePrice` values. + */ + subTotal: Scalars['Int'] + /** Same as subTotal, but inclusive of tax */ + subTotalWithTax: Scalars['Int'] + currencyCode: CurrencyCode + shippingLines: Array + shipping: Scalars['Int'] + shippingWithTax: Scalars['Int'] + /** Equal to subTotal plus shipping */ + total: Scalars['Int'] + /** The final payable amount. Equal to subTotalWithTax plus shippingWithTax */ + totalWithTax: Scalars['Int'] + /** A summary of the taxes being applied to this Order */ + taxSummary: Array + history: HistoryEntryList + customFields?: Maybe +} + +export type OrderHistoryArgs = { + options?: Maybe +} + +/** + * A summary of the taxes being applied to this order, grouped + * by taxRate. + */ +export type OrderTaxSummary = { + __typename?: 'OrderTaxSummary' + /** A description of this tax */ + description: Scalars['String'] + /** The taxRate as a percentage */ + taxRate: Scalars['Float'] + /** The total net price or OrderItems to which this taxRate applies */ + taxBase: Scalars['Int'] + /** The total tax being applied to the Order at this taxRate */ + taxTotal: Scalars['Int'] +} + +export type OrderAddress = { + __typename?: 'OrderAddress' + fullName?: Maybe + company?: Maybe + streetLine1?: Maybe + streetLine2?: Maybe + city?: Maybe + province?: Maybe + postalCode?: Maybe + country?: Maybe + countryCode?: Maybe + phoneNumber?: Maybe + customFields?: Maybe +} + +export type OrderList = PaginatedList & { + __typename?: 'OrderList' + items: Array + totalItems: Scalars['Int'] +} + +export type ShippingLine = { + __typename?: 'ShippingLine' + shippingMethod: ShippingMethod + price: Scalars['Int'] + priceWithTax: Scalars['Int'] + discountedPrice: Scalars['Int'] + discountedPriceWithTax: Scalars['Int'] + discounts: Array +} + +export type OrderItem = Node & { + __typename?: 'OrderItem' + id: Scalars['ID'] + createdAt: Scalars['DateTime'] + updatedAt: Scalars['DateTime'] + cancelled: Scalars['Boolean'] + /** The price of a single unit, excluding tax and discounts */ + unitPrice: Scalars['Int'] + /** The price of a single unit, including tax but excluding discounts */ + unitPriceWithTax: Scalars['Int'] + /** + * The price of a single unit including discounts, excluding tax. + * + * If Order-level discounts have been applied, this will not be the + * actual taxable unit price (see `proratedUnitPrice`), but is generally the + * correct price to display to customers to avoid confusion + * about the internal handling of distributed Order-level discounts. + */ + discountedUnitPrice: Scalars['Int'] + /** The price of a single unit including discounts and tax */ + discountedUnitPriceWithTax: Scalars['Int'] + /** + * The actual unit price, taking into account both item discounts _and_ prorated (proportially-distributed) + * Order-level discounts. This value is the true economic value of the OrderItem, and is used in tax + * and refund calculations. + */ + proratedUnitPrice: Scalars['Int'] + /** The proratedUnitPrice including tax */ + proratedUnitPriceWithTax: Scalars['Int'] + unitTax: Scalars['Int'] + /** @deprecated `unitPrice` is now always without tax */ + unitPriceIncludesTax: Scalars['Boolean'] + taxRate: Scalars['Float'] + adjustments: Array + taxLines: Array + fulfillment?: Maybe + refundId?: Maybe +} + +export type OrderLine = Node & { + __typename?: 'OrderLine' + id: Scalars['ID'] + createdAt: Scalars['DateTime'] + updatedAt: Scalars['DateTime'] + productVariant: ProductVariant + featuredAsset?: Maybe + /** The price of a single unit, excluding tax and discounts */ + unitPrice: Scalars['Int'] + /** The price of a single unit, including tax but excluding discounts */ + unitPriceWithTax: Scalars['Int'] + /** Non-zero if the unitPrice has changed since it was initially added to Order */ + unitPriceChangeSinceAdded: Scalars['Int'] + /** Non-zero if the unitPriceWithTax has changed since it was initially added to Order */ + unitPriceWithTaxChangeSinceAdded: Scalars['Int'] + /** + * The price of a single unit including discounts, excluding tax. + * + * If Order-level discounts have been applied, this will not be the + * actual taxable unit price (see `proratedUnitPrice`), but is generally the + * correct price to display to customers to avoid confusion + * about the internal handling of distributed Order-level discounts. + */ + discountedUnitPrice: Scalars['Int'] + /** The price of a single unit including discounts and tax */ + discountedUnitPriceWithTax: Scalars['Int'] + /** + * The actual unit price, taking into account both item discounts _and_ prorated (proportially-distributed) + * Order-level discounts. This value is the true economic value of the OrderItem, and is used in tax + * and refund calculations. + */ + proratedUnitPrice: Scalars['Int'] + /** The proratedUnitPrice including tax */ + proratedUnitPriceWithTax: Scalars['Int'] + quantity: Scalars['Int'] + items: Array + /** @deprecated Use `linePriceWithTax` instead */ + totalPrice: Scalars['Int'] + taxRate: Scalars['Float'] + /** The total price of the line excluding tax and discounts. */ + linePrice: Scalars['Int'] + /** The total price of the line including tax bit excluding discounts. */ + linePriceWithTax: Scalars['Int'] + /** The price of the line including discounts, excluding tax */ + discountedLinePrice: Scalars['Int'] + /** The price of the line including discounts and tax */ + discountedLinePriceWithTax: Scalars['Int'] + /** + * The actual line price, taking into account both item discounts _and_ prorated (proportially-distributed) + * Order-level discounts. This value is the true economic value of the OrderLine, and is used in tax + * and refund calculations. + */ + proratedLinePrice: Scalars['Int'] + /** The proratedLinePrice including tax */ + proratedLinePriceWithTax: Scalars['Int'] + /** The total tax on this line */ + lineTax: Scalars['Int'] + /** @deprecated Use `discounts` instead */ + adjustments: Array + discounts: Array + taxLines: Array + order: Order + customFields?: Maybe +} + +export type Payment = Node & { + __typename?: 'Payment' + id: Scalars['ID'] + createdAt: Scalars['DateTime'] + updatedAt: Scalars['DateTime'] + method: Scalars['String'] + amount: Scalars['Int'] + state: Scalars['String'] + transactionId?: Maybe + errorMessage?: Maybe + refunds: Array + metadata?: Maybe +} + +export type Refund = Node & { + __typename?: 'Refund' + id: Scalars['ID'] + createdAt: Scalars['DateTime'] + updatedAt: Scalars['DateTime'] + items: Scalars['Int'] + shipping: Scalars['Int'] + adjustment: Scalars['Int'] + total: Scalars['Int'] + method?: Maybe + state: Scalars['String'] + transactionId?: Maybe + reason?: Maybe + orderItems: Array + paymentId: Scalars['ID'] + metadata?: Maybe +} + +export type Fulfillment = Node & { + __typename?: 'Fulfillment' + id: Scalars['ID'] + createdAt: Scalars['DateTime'] + updatedAt: Scalars['DateTime'] + orderItems: Array + state: Scalars['String'] + method: Scalars['String'] + trackingCode?: Maybe + customFields?: Maybe +} + +export type Surcharge = Node & { + __typename?: 'Surcharge' + id: Scalars['ID'] + createdAt: Scalars['DateTime'] + updatedAt: Scalars['DateTime'] + description: Scalars['String'] + sku?: Maybe + taxLines: Array + price: Scalars['Int'] + priceWithTax: Scalars['Int'] + taxRate: Scalars['Float'] +} + +export type ProductOptionGroup = Node & { + __typename?: 'ProductOptionGroup' + id: Scalars['ID'] + createdAt: Scalars['DateTime'] + updatedAt: Scalars['DateTime'] + languageCode: LanguageCode + code: Scalars['String'] + name: Scalars['String'] + options: Array + translations: Array + customFields?: Maybe +} + +export type ProductOptionGroupTranslation = { + __typename?: 'ProductOptionGroupTranslation' + id: Scalars['ID'] + createdAt: Scalars['DateTime'] + updatedAt: Scalars['DateTime'] + languageCode: LanguageCode + name: Scalars['String'] +} + +export type ProductOption = Node & { + __typename?: 'ProductOption' + id: Scalars['ID'] + createdAt: Scalars['DateTime'] + updatedAt: Scalars['DateTime'] + languageCode: LanguageCode + code: Scalars['String'] + name: Scalars['String'] + groupId: Scalars['ID'] + group: ProductOptionGroup + translations: Array + customFields?: Maybe +} + +export type ProductOptionTranslation = { + __typename?: 'ProductOptionTranslation' + id: Scalars['ID'] + createdAt: Scalars['DateTime'] + updatedAt: Scalars['DateTime'] + languageCode: LanguageCode + name: Scalars['String'] +} + +export type SearchReindexResponse = { + __typename?: 'SearchReindexResponse' + success: Scalars['Boolean'] +} + +export type SearchResponse = { + __typename?: 'SearchResponse' + items: Array + totalItems: Scalars['Int'] + facetValues: Array +} + +/** + * Which FacetValues are present in the products returned + * by the search, and in what quantity. + */ +export type FacetValueResult = { + __typename?: 'FacetValueResult' + facetValue: FacetValue + count: Scalars['Int'] +} + +export type SearchResultAsset = { + __typename?: 'SearchResultAsset' + id: Scalars['ID'] + preview: Scalars['String'] + focalPoint?: Maybe +} + +export type SearchResult = { + __typename?: 'SearchResult' + sku: Scalars['String'] + slug: Scalars['String'] + productId: Scalars['ID'] + productName: Scalars['String'] + /** @deprecated Use `productAsset.preview` instead */ + productPreview: Scalars['String'] + productAsset?: Maybe + productVariantId: Scalars['ID'] + productVariantName: Scalars['String'] + /** @deprecated Use `productVariantAsset.preview` instead */ + productVariantPreview: Scalars['String'] + productVariantAsset?: Maybe + price: SearchResultPrice + priceWithTax: SearchResultPrice + currencyCode: CurrencyCode + description: Scalars['String'] + facetIds: Array + facetValueIds: Array + /** An array of ids of the Collections in which this result appears */ + collectionIds: Array + /** A relevence score for the result. Differs between database implementations */ + score: Scalars['Float'] +} + +/** The price of a search result product, either as a range or as a single price */ +export type SearchResultPrice = PriceRange | SinglePrice + +/** The price value where the result has a single price */ +export type SinglePrice = { + __typename?: 'SinglePrice' + value: Scalars['Int'] +} + +/** The price range where the result has more than one price */ +export type PriceRange = { + __typename?: 'PriceRange' + min: Scalars['Int'] + max: Scalars['Int'] +} + +export type Product = Node & { + __typename?: 'Product' + id: Scalars['ID'] + createdAt: Scalars['DateTime'] + updatedAt: Scalars['DateTime'] + languageCode: LanguageCode + name: Scalars['String'] + slug: Scalars['String'] + description: Scalars['String'] + featuredAsset?: Maybe + assets: Array + variants: Array + optionGroups: Array + facetValues: Array + translations: Array + collections: Array + customFields?: Maybe +} + +export type ProductTranslation = { + __typename?: 'ProductTranslation' + id: Scalars['ID'] + createdAt: Scalars['DateTime'] + updatedAt: Scalars['DateTime'] + languageCode: LanguageCode + name: Scalars['String'] + slug: Scalars['String'] + description: Scalars['String'] +} + +export type ProductList = PaginatedList & { + __typename?: 'ProductList' + items: Array + totalItems: Scalars['Int'] +} + +export type ProductVariant = Node & { + __typename?: 'ProductVariant' + id: Scalars['ID'] + product: Product + productId: Scalars['ID'] + createdAt: Scalars['DateTime'] + updatedAt: Scalars['DateTime'] + languageCode: LanguageCode + sku: Scalars['String'] + name: Scalars['String'] + featuredAsset?: Maybe + assets: Array + price: Scalars['Int'] + currencyCode: CurrencyCode + /** @deprecated price now always excludes tax */ + priceIncludesTax: Scalars['Boolean'] + priceWithTax: Scalars['Int'] + stockLevel: Scalars['String'] + taxRateApplied: TaxRate + taxCategory: TaxCategory + options: Array + facetValues: Array + translations: Array + customFields?: Maybe +} + +export type ProductVariantTranslation = { + __typename?: 'ProductVariantTranslation' + id: Scalars['ID'] + createdAt: Scalars['DateTime'] + updatedAt: Scalars['DateTime'] + languageCode: LanguageCode + name: Scalars['String'] +} + +export type Promotion = Node & { + __typename?: 'Promotion' + id: Scalars['ID'] + createdAt: Scalars['DateTime'] + updatedAt: Scalars['DateTime'] + startsAt?: Maybe + endsAt?: Maybe + couponCode?: Maybe + perCustomerUsageLimit?: Maybe + name: Scalars['String'] + enabled: Scalars['Boolean'] + conditions: Array + actions: Array +} + +export type PromotionList = PaginatedList & { + __typename?: 'PromotionList' + items: Array + totalItems: Scalars['Int'] +} + +export type Role = Node & { + __typename?: 'Role' + id: Scalars['ID'] + createdAt: Scalars['DateTime'] + updatedAt: Scalars['DateTime'] + code: Scalars['String'] + description: Scalars['String'] + permissions: Array + channels: Array +} + +export type RoleList = PaginatedList & { + __typename?: 'RoleList' + items: Array + totalItems: Scalars['Int'] +} + +export type ShippingMethod = Node & { + __typename?: 'ShippingMethod' + id: Scalars['ID'] + createdAt: Scalars['DateTime'] + updatedAt: Scalars['DateTime'] + code: Scalars['String'] + name: Scalars['String'] + description: Scalars['String'] + fulfillmentHandlerCode: Scalars['String'] + checker: ConfigurableOperation + calculator: ConfigurableOperation + translations: Array + customFields?: Maybe +} + +export type ShippingMethodTranslation = { + __typename?: 'ShippingMethodTranslation' + id: Scalars['ID'] + createdAt: Scalars['DateTime'] + updatedAt: Scalars['DateTime'] + languageCode: LanguageCode + name: Scalars['String'] + description: Scalars['String'] +} + +export type ShippingMethodList = PaginatedList & { + __typename?: 'ShippingMethodList' + items: Array + totalItems: Scalars['Int'] +} + +export type Tag = Node & { + __typename?: 'Tag' + id: Scalars['ID'] + createdAt: Scalars['DateTime'] + updatedAt: Scalars['DateTime'] + value: Scalars['String'] +} + +export type TagList = PaginatedList & { + __typename?: 'TagList' + items: Array + totalItems: Scalars['Int'] +} + +export type TaxCategory = Node & { + __typename?: 'TaxCategory' + id: Scalars['ID'] + createdAt: Scalars['DateTime'] + updatedAt: Scalars['DateTime'] + name: Scalars['String'] + isDefault: Scalars['Boolean'] +} + +export type TaxRate = Node & { + __typename?: 'TaxRate' + id: Scalars['ID'] + createdAt: Scalars['DateTime'] + updatedAt: Scalars['DateTime'] + name: Scalars['String'] + enabled: Scalars['Boolean'] + value: Scalars['Float'] + category: TaxCategory + zone: Zone + customerGroup?: Maybe +} + +export type TaxRateList = PaginatedList & { + __typename?: 'TaxRateList' + items: Array + totalItems: Scalars['Int'] +} + +export type User = Node & { + __typename?: 'User' + id: Scalars['ID'] + createdAt: Scalars['DateTime'] + updatedAt: Scalars['DateTime'] + identifier: Scalars['String'] + verified: Scalars['Boolean'] + roles: Array + lastLogin?: Maybe + authenticationMethods: Array + customFields?: Maybe +} + +export type AuthenticationMethod = Node & { + __typename?: 'AuthenticationMethod' + id: Scalars['ID'] + createdAt: Scalars['DateTime'] + updatedAt: Scalars['DateTime'] + strategy: Scalars['String'] +} + +export type Zone = Node & { + __typename?: 'Zone' + id: Scalars['ID'] + createdAt: Scalars['DateTime'] + updatedAt: Scalars['DateTime'] + name: Scalars['String'] + members: Array +} + +/** Returned when attempting to modify the contents of an Order that is not in the `AddingItems` state. */ +export type OrderModificationError = ErrorResult & { + __typename?: 'OrderModificationError' + errorCode: ErrorCode + message: Scalars['String'] +} + +/** Returned when attempting to set a ShippingMethod for which the Order is not eligible */ +export type IneligibleShippingMethodError = ErrorResult & { + __typename?: 'IneligibleShippingMethodError' + errorCode: ErrorCode + message: Scalars['String'] +} + +/** Returned when attempting to add a Payment to an Order that is not in the `ArrangingPayment` state. */ +export type OrderPaymentStateError = ErrorResult & { + __typename?: 'OrderPaymentStateError' + errorCode: ErrorCode + message: Scalars['String'] +} + +/** Returned when attempting to add a Payment using a PaymentMethod for which the Order is not eligible. */ +export type IneligiblePaymentMethodError = ErrorResult & { + __typename?: 'IneligiblePaymentMethodError' + errorCode: ErrorCode + message: Scalars['String'] + eligibilityCheckerMessage?: Maybe +} + +/** Returned when a Payment fails due to an error. */ +export type PaymentFailedError = ErrorResult & { + __typename?: 'PaymentFailedError' + errorCode: ErrorCode + message: Scalars['String'] + paymentErrorMessage: Scalars['String'] +} + +/** Returned when a Payment is declined by the payment provider. */ +export type PaymentDeclinedError = ErrorResult & { + __typename?: 'PaymentDeclinedError' + errorCode: ErrorCode + message: Scalars['String'] + paymentErrorMessage: Scalars['String'] +} + +/** Returned if the provided coupon code is invalid */ +export type CouponCodeInvalidError = ErrorResult & { + __typename?: 'CouponCodeInvalidError' + errorCode: ErrorCode + message: Scalars['String'] + couponCode: Scalars['String'] +} + +/** Returned if the provided coupon code is invalid */ +export type CouponCodeExpiredError = ErrorResult & { + __typename?: 'CouponCodeExpiredError' + errorCode: ErrorCode + message: Scalars['String'] + couponCode: Scalars['String'] +} + +/** Returned if the provided coupon code is invalid */ +export type CouponCodeLimitError = ErrorResult & { + __typename?: 'CouponCodeLimitError' + errorCode: ErrorCode + message: Scalars['String'] + couponCode: Scalars['String'] + limit: Scalars['Int'] +} + +/** Retured when attemting to set the Customer for an Order when already logged in. */ +export type AlreadyLoggedInError = ErrorResult & { + __typename?: 'AlreadyLoggedInError' + errorCode: ErrorCode + message: Scalars['String'] +} + +/** Retured when attemting to register or verify a customer account without a password, when one is required. */ +export type MissingPasswordError = ErrorResult & { + __typename?: 'MissingPasswordError' + errorCode: ErrorCode + message: Scalars['String'] +} + +/** Retured when attemting to verify a customer account with a password, when a password has already been set. */ +export type PasswordAlreadySetError = ErrorResult & { + __typename?: 'PasswordAlreadySetError' + errorCode: ErrorCode + message: Scalars['String'] +} + +/** + * Retured if the verification token (used to verify a Customer's email address) is either + * invalid or does not match any expected tokens. + */ +export type VerificationTokenInvalidError = ErrorResult & { + __typename?: 'VerificationTokenInvalidError' + errorCode: ErrorCode + message: Scalars['String'] +} + +/** + * Returned if the verification token (used to verify a Customer's email address) is valid, but has + * expired according to the `verificationTokenDuration` setting in the AuthOptions. + */ +export type VerificationTokenExpiredError = ErrorResult & { + __typename?: 'VerificationTokenExpiredError' + errorCode: ErrorCode + message: Scalars['String'] +} + +/** + * Retured if the token used to change a Customer's email address is either + * invalid or does not match any expected tokens. + */ +export type IdentifierChangeTokenInvalidError = ErrorResult & { + __typename?: 'IdentifierChangeTokenInvalidError' + errorCode: ErrorCode + message: Scalars['String'] +} + +/** + * Retured if the token used to change a Customer's email address is valid, but has + * expired according to the `verificationTokenDuration` setting in the AuthOptions. + */ +export type IdentifierChangeTokenExpiredError = ErrorResult & { + __typename?: 'IdentifierChangeTokenExpiredError' + errorCode: ErrorCode + message: Scalars['String'] +} + +/** + * Retured if the token used to reset a Customer's password is either + * invalid or does not match any expected tokens. + */ +export type PasswordResetTokenInvalidError = ErrorResult & { + __typename?: 'PasswordResetTokenInvalidError' + errorCode: ErrorCode + message: Scalars['String'] +} + +/** + * Retured if the token used to reset a Customer's password is valid, but has + * expired according to the `verificationTokenDuration` setting in the AuthOptions. + */ +export type PasswordResetTokenExpiredError = ErrorResult & { + __typename?: 'PasswordResetTokenExpiredError' + errorCode: ErrorCode + message: Scalars['String'] +} + +/** + * Returned if `authOptions.requireVerification` is set to `true` (which is the default) + * and an unverified user attempts to authenticate. + */ +export type NotVerifiedError = ErrorResult & { + __typename?: 'NotVerifiedError' + errorCode: ErrorCode + message: Scalars['String'] +} + +/** + * Returned when invoking a mutation which depends on there being an active Order on the + * current session. + */ +export type NoActiveOrderError = ErrorResult & { + __typename?: 'NoActiveOrderError' + errorCode: ErrorCode + message: Scalars['String'] +} + +export type RegisterCustomerInput = { + emailAddress: Scalars['String'] + title?: Maybe + firstName?: Maybe + lastName?: Maybe + phoneNumber?: Maybe + password?: Maybe +} + +export type UpdateCustomerInput = { + title?: Maybe + firstName?: Maybe + lastName?: Maybe + phoneNumber?: Maybe + customFields?: Maybe +} + +/** Passed as input to the `addPaymentToOrder` mutation. */ +export type PaymentInput = { + /** This field should correspond to the `code` property of a PaymentMethodHandler. */ + method: Scalars['String'] + /** + * This field should contain arbitrary data passed to the specified PaymentMethodHandler's `createPayment()` method + * as the "metadata" argument. For example, it could contain an ID for the payment and other + * data generated by the payment provider. + */ + metadata: Scalars['JSON'] +} + +export type UpdateOrderItemsResult = + | Order + | OrderModificationError + | OrderLimitError + | NegativeQuantityError + | InsufficientStockError + +export type RemoveOrderItemsResult = Order | OrderModificationError + +export type SetOrderShippingMethodResult = + | Order + | OrderModificationError + | IneligibleShippingMethodError + | NoActiveOrderError + +export type ApplyCouponCodeResult = + | Order + | CouponCodeExpiredError + | CouponCodeInvalidError + | CouponCodeLimitError + +export type AddPaymentToOrderResult = + | Order + | OrderPaymentStateError + | IneligiblePaymentMethodError + | PaymentFailedError + | PaymentDeclinedError + | OrderStateTransitionError + | NoActiveOrderError + +export type TransitionOrderToStateResult = Order | OrderStateTransitionError + +export type SetCustomerForOrderResult = + | Order + | AlreadyLoggedInError + | EmailAddressConflictError + | NoActiveOrderError + +export type RegisterCustomerAccountResult = + | Success + | MissingPasswordError + | NativeAuthStrategyError + +export type RefreshCustomerVerificationResult = + | Success + | NativeAuthStrategyError + +export type VerifyCustomerAccountResult = + | CurrentUser + | VerificationTokenInvalidError + | VerificationTokenExpiredError + | MissingPasswordError + | PasswordAlreadySetError + | NativeAuthStrategyError + +export type UpdateCustomerPasswordResult = + | Success + | InvalidCredentialsError + | NativeAuthStrategyError + +export type RequestUpdateCustomerEmailAddressResult = + | Success + | InvalidCredentialsError + | EmailAddressConflictError + | NativeAuthStrategyError + +export type UpdateCustomerEmailAddressResult = + | Success + | IdentifierChangeTokenInvalidError + | IdentifierChangeTokenExpiredError + | NativeAuthStrategyError + +export type RequestPasswordResetResult = Success | NativeAuthStrategyError + +export type ResetPasswordResult = + | CurrentUser + | PasswordResetTokenInvalidError + | PasswordResetTokenExpiredError + | NativeAuthStrategyError + +export type NativeAuthenticationResult = + | CurrentUser + | InvalidCredentialsError + | NotVerifiedError + | NativeAuthStrategyError + +export type AuthenticationResult = + | CurrentUser + | InvalidCredentialsError + | NotVerifiedError + +export type ActiveOrderResult = Order | NoActiveOrderError + +export type CollectionListOptions = { + skip?: Maybe + take?: Maybe + sort?: Maybe + filter?: Maybe +} + +export type ProductListOptions = { + skip?: Maybe + take?: Maybe + sort?: Maybe + filter?: Maybe +} + +export type ProductVariantListOptions = { + skip?: Maybe + take?: Maybe + sort?: Maybe + filter?: Maybe +} + +export type CustomerListOptions = { + skip?: Maybe + take?: Maybe + sort?: Maybe + filter?: Maybe +} + +export type OrderListOptions = { + skip?: Maybe + take?: Maybe + sort?: Maybe + filter?: Maybe +} + +export type HistoryEntryListOptions = { + skip?: Maybe + take?: Maybe + sort?: Maybe + filter?: Maybe +} + +export type CollectionFilterParameter = { + createdAt?: Maybe + updatedAt?: Maybe + languageCode?: Maybe + name?: Maybe + slug?: Maybe + position?: Maybe + description?: Maybe +} + +export type CollectionSortParameter = { + id?: Maybe + createdAt?: Maybe + updatedAt?: Maybe + name?: Maybe + slug?: Maybe + position?: Maybe + description?: Maybe +} + +export type ProductFilterParameter = { + createdAt?: Maybe + updatedAt?: Maybe + languageCode?: Maybe + name?: Maybe + slug?: Maybe + description?: Maybe +} + +export type ProductSortParameter = { + id?: Maybe + createdAt?: Maybe + updatedAt?: Maybe + name?: Maybe + slug?: Maybe + description?: Maybe +} + +export type ProductVariantFilterParameter = { + createdAt?: Maybe + updatedAt?: Maybe + languageCode?: Maybe + sku?: Maybe + name?: Maybe + price?: Maybe + currencyCode?: Maybe + priceIncludesTax?: Maybe + priceWithTax?: Maybe + stockLevel?: Maybe +} + +export type ProductVariantSortParameter = { + id?: Maybe + productId?: Maybe + createdAt?: Maybe + updatedAt?: Maybe + sku?: Maybe + name?: Maybe + price?: Maybe + priceWithTax?: Maybe + stockLevel?: Maybe +} + +export type CustomerFilterParameter = { + createdAt?: Maybe + updatedAt?: Maybe + title?: Maybe + firstName?: Maybe + lastName?: Maybe + phoneNumber?: Maybe + emailAddress?: Maybe +} + +export type CustomerSortParameter = { + id?: Maybe + createdAt?: Maybe + updatedAt?: Maybe + title?: Maybe + firstName?: Maybe + lastName?: Maybe + phoneNumber?: Maybe + emailAddress?: Maybe +} + +export type OrderFilterParameter = { + createdAt?: Maybe + updatedAt?: Maybe + orderPlacedAt?: Maybe + code?: Maybe + state?: Maybe + active?: Maybe + totalQuantity?: Maybe + subTotal?: Maybe + subTotalWithTax?: Maybe + currencyCode?: Maybe + shipping?: Maybe + shippingWithTax?: Maybe + total?: Maybe + totalWithTax?: Maybe +} + +export type OrderSortParameter = { + id?: Maybe + createdAt?: Maybe + updatedAt?: Maybe + orderPlacedAt?: Maybe + code?: Maybe + state?: Maybe + totalQuantity?: Maybe + subTotal?: Maybe + subTotalWithTax?: Maybe + shipping?: Maybe + shippingWithTax?: Maybe + total?: Maybe + totalWithTax?: Maybe +} + +export type HistoryEntryFilterParameter = { + createdAt?: Maybe + updatedAt?: Maybe + type?: Maybe +} + +export type HistoryEntrySortParameter = { + id?: Maybe + createdAt?: Maybe + updatedAt?: Maybe +} + +export type UpdateOrderInput = { + customFields?: Maybe +} + +export type AuthenticationInput = { + native?: Maybe +} + +export type NativeAuthInput = { + username: Scalars['String'] + password: Scalars['String'] +} + +export type CartFragment = { __typename?: 'Order' } & Pick< + Order, + | 'id' + | 'code' + | 'createdAt' + | 'totalQuantity' + | 'subTotal' + | 'subTotalWithTax' + | 'total' + | 'totalWithTax' + | 'currencyCode' +> & { + customer?: Maybe<{ __typename?: 'Customer' } & Pick> + lines: Array< + { __typename?: 'OrderLine' } & Pick< + OrderLine, + 'id' | 'quantity' | 'linePriceWithTax' | 'discountedLinePriceWithTax' + > & { + featuredAsset?: Maybe< + { __typename?: 'Asset' } & Pick + > + discounts: Array< + { __typename?: 'Adjustment' } & Pick< + Adjustment, + 'description' | 'amount' + > + > + productVariant: { __typename?: 'ProductVariant' } & Pick< + ProductVariant, + | 'id' + | 'name' + | 'sku' + | 'price' + | 'priceWithTax' + | 'stockLevel' + | 'productId' + > & { product: { __typename?: 'Product' } & Pick } + } + > + } + +export type SearchResultFragment = { __typename?: 'SearchResult' } & Pick< + SearchResult, + 'productId' | 'productName' | 'description' | 'slug' | 'sku' | 'currencyCode' +> & { + productAsset?: Maybe< + { __typename?: 'SearchResultAsset' } & Pick< + SearchResultAsset, + 'id' | 'preview' + > + > + priceWithTax: + | ({ __typename?: 'PriceRange' } & Pick) + | ({ __typename?: 'SinglePrice' } & Pick) + } + +export type LoginMutationVariables = Exact<{ + username: Scalars['String'] + password: Scalars['String'] +}> + +export type LoginMutation = { __typename?: 'Mutation' } & { + login: + | ({ __typename: 'CurrentUser' } & Pick) + | ({ __typename: 'InvalidCredentialsError' } & Pick< + InvalidCredentialsError, + 'errorCode' | 'message' + >) + | ({ __typename: 'NotVerifiedError' } & Pick< + NotVerifiedError, + 'errorCode' | 'message' + >) + | ({ __typename: 'NativeAuthStrategyError' } & Pick< + NativeAuthStrategyError, + 'errorCode' | 'message' + >) +} + +export type LogoutMutationVariables = Exact<{ [key: string]: never }> + +export type LogoutMutation = { __typename?: 'Mutation' } & { + logout: { __typename?: 'Success' } & Pick +} + +export type SignupMutationVariables = Exact<{ + input: RegisterCustomerInput +}> + +export type SignupMutation = { __typename?: 'Mutation' } & { + registerCustomerAccount: + | ({ __typename: 'Success' } & Pick) + | ({ __typename: 'MissingPasswordError' } & Pick< + MissingPasswordError, + 'errorCode' | 'message' + >) + | ({ __typename: 'NativeAuthStrategyError' } & Pick< + NativeAuthStrategyError, + 'errorCode' | 'message' + >) +} + +export type AddItemToOrderMutationVariables = Exact<{ + variantId: Scalars['ID'] + quantity: Scalars['Int'] +}> + +export type AddItemToOrderMutation = { __typename?: 'Mutation' } & { + addItemToOrder: + | ({ __typename: 'Order' } & CartFragment) + | ({ __typename: 'OrderModificationError' } & Pick< + OrderModificationError, + 'errorCode' | 'message' + >) + | ({ __typename: 'OrderLimitError' } & Pick< + OrderLimitError, + 'errorCode' | 'message' + >) + | ({ __typename: 'NegativeQuantityError' } & Pick< + NegativeQuantityError, + 'errorCode' | 'message' + >) + | ({ __typename: 'InsufficientStockError' } & Pick< + InsufficientStockError, + 'errorCode' | 'message' + >) +} + +export type ActiveOrderQueryVariables = Exact<{ [key: string]: never }> + +export type ActiveOrderQuery = { __typename?: 'Query' } & { + activeOrder?: Maybe<{ __typename?: 'Order' } & CartFragment> +} + +export type RemoveOrderLineMutationVariables = Exact<{ + orderLineId: Scalars['ID'] +}> + +export type RemoveOrderLineMutation = { __typename?: 'Mutation' } & { + removeOrderLine: + | ({ __typename: 'Order' } & CartFragment) + | ({ __typename: 'OrderModificationError' } & Pick< + OrderModificationError, + 'errorCode' | 'message' + >) +} + +export type AdjustOrderLineMutationVariables = Exact<{ + orderLineId: Scalars['ID'] + quantity: Scalars['Int'] +}> + +export type AdjustOrderLineMutation = { __typename?: 'Mutation' } & { + adjustOrderLine: + | ({ __typename: 'Order' } & CartFragment) + | ({ __typename: 'OrderModificationError' } & Pick< + OrderModificationError, + 'errorCode' | 'message' + >) + | ({ __typename: 'OrderLimitError' } & Pick< + OrderLimitError, + 'errorCode' | 'message' + >) + | ({ __typename: 'NegativeQuantityError' } & Pick< + NegativeQuantityError, + 'errorCode' | 'message' + >) + | ({ __typename: 'InsufficientStockError' } & Pick< + InsufficientStockError, + 'errorCode' | 'message' + >) +} + +export type GetCollectionsQueryVariables = Exact<{ [key: string]: never }> + +export type GetCollectionsQuery = { __typename?: 'Query' } & { + collections: { __typename?: 'CollectionList' } & { + items: Array< + { __typename?: 'Collection' } & Pick< + Collection, + 'id' | 'name' | 'description' | 'slug' + > & { + productVariants: { __typename?: 'ProductVariantList' } & Pick< + ProductVariantList, + 'totalItems' + > + parent?: Maybe<{ __typename?: 'Collection' } & Pick> + children?: Maybe< + Array<{ __typename?: 'Collection' } & Pick> + > + } + > + } +} + +export type ActiveCustomerQueryVariables = Exact<{ [key: string]: never }> + +export type ActiveCustomerQuery = { __typename?: 'Query' } & { + activeCustomer?: Maybe< + { __typename?: 'Customer' } & Pick< + Customer, + 'id' | 'firstName' | 'lastName' | 'emailAddress' + > + > +} + +export type GetAllProductPathsQueryVariables = Exact<{ + first?: Maybe +}> + +export type GetAllProductPathsQuery = { __typename?: 'Query' } & { + products: { __typename?: 'ProductList' } & { + items: Array<{ __typename?: 'Product' } & Pick> + } +} + +export type GetAllProductsQueryVariables = Exact<{ + input: SearchInput +}> + +export type GetAllProductsQuery = { __typename?: 'Query' } & { + search: { __typename?: 'SearchResponse' } & { + items: Array<{ __typename?: 'SearchResult' } & SearchResultFragment> + } +} + +export type GetProductQueryVariables = Exact<{ + slug: Scalars['String'] +}> + +export type GetProductQuery = { __typename?: 'Query' } & { + product?: Maybe< + { __typename?: 'Product' } & Pick< + Product, + 'id' | 'name' | 'slug' | 'description' + > & { + assets: Array< + { __typename?: 'Asset' } & Pick + > + variants: Array< + { __typename?: 'ProductVariant' } & Pick< + ProductVariant, + 'id' | 'priceWithTax' | 'currencyCode' + > & { + options: Array< + { __typename?: 'ProductOption' } & Pick< + ProductOption, + 'id' | 'name' | 'code' | 'groupId' + > & { + group: { __typename?: 'ProductOptionGroup' } & Pick< + ProductOptionGroup, + 'id' + > & { + options: Array< + { __typename?: 'ProductOption' } & Pick< + ProductOption, + 'name' + > + > + } + } + > + } + > + optionGroups: Array< + { __typename?: 'ProductOptionGroup' } & Pick< + ProductOptionGroup, + 'id' | 'code' | 'name' + > & { + options: Array< + { __typename?: 'ProductOption' } & Pick< + ProductOption, + 'id' | 'name' + > + > + } + > + } + > +} + +export type SearchQueryVariables = Exact<{ + input: SearchInput +}> + +export type SearchQuery = { __typename?: 'Query' } & { + search: { __typename?: 'SearchResponse' } & Pick< + SearchResponse, + 'totalItems' + > & { items: Array<{ __typename?: 'SearchResult' } & SearchResultFragment> } +} diff --git a/framework/vendure/schema.graphql b/framework/vendure/schema.graphql new file mode 100644 index 000000000..88812044e --- /dev/null +++ b/framework/vendure/schema.graphql @@ -0,0 +1,3860 @@ +type Query { + """ + The active Channel + """ + activeChannel: Channel! + + """ + The active Customer + """ + activeCustomer: Customer + + """ + The active Order. Will be `null` until an Order is created via `addItemToOrder`. Once an Order reaches the + state of `PaymentApproved` or `PaymentSettled`, then that Order is no longer considered "active" and this + query will once again return `null`. + """ + activeOrder: Order + + """ + An array of supported Countries + """ + availableCountries: [Country!]! + + """ + A list of Collections available to the shop + """ + collections(options: CollectionListOptions): CollectionList! + + """ + Returns a Collection either by its id or slug. If neither 'id' nor 'slug' is speicified, an error will result. + """ + collection(id: ID, slug: String): Collection + + """ + Returns a list of eligible shipping methods based on the current active Order + """ + eligibleShippingMethods: [ShippingMethodQuote!]! + + """ + Returns a list of payment methods and their eligibility based on the current active Order + """ + eligiblePaymentMethods: [PaymentMethodQuote!]! + + """ + Returns information about the current authenticated User + """ + me: CurrentUser + + """ + Returns the possible next states that the activeOrder can transition to + """ + nextOrderStates: [String!]! + + """ + Returns an Order based on the id. Note that in the Shop API, only orders belonging to the + currently-authenticated User may be queried. + """ + order(id: ID!): Order + + """ + Returns an Order based on the order `code`. For guest Orders (i.e. Orders placed by non-authenticated Customers) + this query will only return the Order within 2 hours of the Order being placed. This allows an Order confirmation + screen to be shown immediately after completion of a guest checkout, yet prevents security risks of allowing + general anonymous access to Order data. + """ + orderByCode(code: String!): Order + + """ + Get a Product either by id or slug. If neither 'id' nor 'slug' is speicified, an error will result. + """ + product(id: ID, slug: String): Product + + """ + Get a list of Products + """ + products(options: ProductListOptions): ProductList! + + """ + Search Products based on the criteria set by the `SearchInput` + """ + search(input: SearchInput!): SearchResponse! +} + +type Mutation { + """ + Adds an item to the order. If custom fields are defined on the OrderLine entity, a third argument 'customFields' will be available. + """ + addItemToOrder(productVariantId: ID!, quantity: Int!): UpdateOrderItemsResult! + + """ + Remove an OrderLine from the Order + """ + removeOrderLine(orderLineId: ID!): RemoveOrderItemsResult! + + """ + Remove all OrderLine from the Order + """ + removeAllOrderLines: RemoveOrderItemsResult! + + """ + Adjusts an OrderLine. If custom fields are defined on the OrderLine entity, a third argument 'customFields' of type `OrderLineCustomFieldsInput` will be available. + """ + adjustOrderLine(orderLineId: ID!, quantity: Int!): UpdateOrderItemsResult! + + """ + Applies the given coupon code to the active Order + """ + applyCouponCode(couponCode: String!): ApplyCouponCodeResult! + + """ + Removes the given coupon code from the active Order + """ + removeCouponCode(couponCode: String!): Order + + """ + Transitions an Order to a new state. Valid next states can be found by querying `nextOrderStates` + """ + transitionOrderToState(state: String!): TransitionOrderToStateResult + + """ + Sets the shipping address for this order + """ + setOrderShippingAddress(input: CreateAddressInput!): ActiveOrderResult! + + """ + Sets the billing address for this order + """ + setOrderBillingAddress(input: CreateAddressInput!): ActiveOrderResult! + + """ + Allows any custom fields to be set for the active order + """ + setOrderCustomFields(input: UpdateOrderInput!): ActiveOrderResult! + + """ + Sets the shipping method by id, which can be obtained with the `eligibleShippingMethods` query + """ + setOrderShippingMethod(shippingMethodId: ID!): SetOrderShippingMethodResult! + + """ + Add a Payment to the Order + """ + addPaymentToOrder(input: PaymentInput!): AddPaymentToOrderResult! + + """ + Set the Customer for the Order. Required only if the Customer is not currently logged in + """ + setCustomerForOrder(input: CreateCustomerInput!): SetCustomerForOrderResult! + + """ + Authenticates the user using the native authentication strategy. This mutation is an alias for `authenticate({ native: { ... }})` + """ + login( + username: String! + password: String! + rememberMe: Boolean + ): NativeAuthenticationResult! + + """ + Authenticates the user using a named authentication strategy + """ + authenticate( + input: AuthenticationInput! + rememberMe: Boolean + ): AuthenticationResult! + + """ + End the current authenticated session + """ + logout: Success! + + """ + Register a Customer account with the given credentials. There are three possible registration flows: + + _If `authOptions.requireVerification` is set to `true`:_ + + 1. **The Customer is registered _with_ a password**. A verificationToken will be created (and typically emailed to the Customer). That + verificationToken would then be passed to the `verifyCustomerAccount` mutation _without_ a password. The Customer is then + verified and authenticated in one step. + 2. **The Customer is registered _without_ a password**. A verificationToken will be created (and typically emailed to the Customer). That + verificationToken would then be passed to the `verifyCustomerAccount` mutation _with_ the chosed password of the Customer. The Customer is then + verified and authenticated in one step. + + _If `authOptions.requireVerification` is set to `false`:_ + + 3. The Customer _must_ be registered _with_ a password. No further action is needed - the Customer is able to authenticate immediately. + """ + registerCustomerAccount( + input: RegisterCustomerInput! + ): RegisterCustomerAccountResult! + + """ + Regenerate and send a verification token for a new Customer registration. Only applicable if `authOptions.requireVerification` is set to true. + """ + refreshCustomerVerification( + emailAddress: String! + ): RefreshCustomerVerificationResult! + + """ + Update an existing Customer + """ + updateCustomer(input: UpdateCustomerInput!): Customer! + + """ + Create a new Customer Address + """ + createCustomerAddress(input: CreateAddressInput!): Address! + + """ + Update an existing Address + """ + updateCustomerAddress(input: UpdateAddressInput!): Address! + + """ + Delete an existing Address + """ + deleteCustomerAddress(id: ID!): Success! + + """ + Verify a Customer email address with the token sent to that address. Only applicable if `authOptions.requireVerification` is set to true. + + If the Customer was not registered with a password in the `registerCustomerAccount` mutation, the a password _must_ be + provided here. + """ + verifyCustomerAccount( + token: String! + password: String + ): VerifyCustomerAccountResult! + + """ + Update the password of the active Customer + """ + updateCustomerPassword( + currentPassword: String! + newPassword: String! + ): UpdateCustomerPasswordResult! + + """ + Request to update the emailAddress of the active Customer. If `authOptions.requireVerification` is enabled + (as is the default), then the `identifierChangeToken` will be assigned to the current User and + a IdentifierChangeRequestEvent will be raised. This can then be used e.g. by the EmailPlugin to email + that verification token to the Customer, which is then used to verify the change of email address. + """ + requestUpdateCustomerEmailAddress( + password: String! + newEmailAddress: String! + ): RequestUpdateCustomerEmailAddressResult! + + """ + Confirm the update of the emailAddress with the provided token, which has been generated by the + `requestUpdateCustomerEmailAddress` mutation. + """ + updateCustomerEmailAddress(token: String!): UpdateCustomerEmailAddressResult! + + """ + Requests a password reset email to be sent + """ + requestPasswordReset(emailAddress: String!): RequestPasswordResetResult + + """ + Resets a Customer's password based on the provided token + """ + resetPassword(token: String!, password: String!): ResetPasswordResult! +} + +type Address implements Node { + id: ID! + createdAt: DateTime! + updatedAt: DateTime! + fullName: String + company: String + streetLine1: String! + streetLine2: String + city: String + province: String + postalCode: String + country: Country! + phoneNumber: String + defaultShippingAddress: Boolean + defaultBillingAddress: Boolean + customFields: JSON +} + +type Asset implements Node { + id: ID! + createdAt: DateTime! + updatedAt: DateTime! + name: String! + type: AssetType! + fileSize: Int! + mimeType: String! + width: Int! + height: Int! + source: String! + preview: String! + focalPoint: Coordinate + customFields: JSON +} + +type Coordinate { + x: Float! + y: Float! +} + +type AssetList implements PaginatedList { + items: [Asset!]! + totalItems: Int! +} + +enum AssetType { + IMAGE + VIDEO + BINARY +} + +type CurrentUser { + id: ID! + identifier: String! + channels: [CurrentUserChannel!]! +} + +type CurrentUserChannel { + id: ID! + token: String! + code: String! + permissions: [Permission!]! +} + +type Channel implements Node { + id: ID! + createdAt: DateTime! + updatedAt: DateTime! + code: String! + token: String! + defaultTaxZone: Zone + defaultShippingZone: Zone + defaultLanguageCode: LanguageCode! + currencyCode: CurrencyCode! + pricesIncludeTax: Boolean! + customFields: JSON +} + +type Collection implements Node { + id: ID! + createdAt: DateTime! + updatedAt: DateTime! + languageCode: LanguageCode + name: String! + slug: String! + breadcrumbs: [CollectionBreadcrumb!]! + position: Int! + description: String! + featuredAsset: Asset + assets: [Asset!]! + parent: Collection + children: [Collection!] + filters: [ConfigurableOperation!]! + translations: [CollectionTranslation!]! + productVariants(options: ProductVariantListOptions): ProductVariantList! + customFields: JSON +} + +type CollectionBreadcrumb { + id: ID! + name: String! + slug: String! +} + +type CollectionTranslation { + id: ID! + createdAt: DateTime! + updatedAt: DateTime! + languageCode: LanguageCode! + name: String! + slug: String! + description: String! +} + +type CollectionList implements PaginatedList { + items: [Collection!]! + totalItems: Int! +} + +type ProductVariantList implements PaginatedList { + items: [ProductVariant!]! + totalItems: Int! +} + +enum GlobalFlag { + TRUE + FALSE + INHERIT +} + +enum AdjustmentType { + PROMOTION + DISTRIBUTED_ORDER_PROMOTION +} + +enum DeletionResult { + """ + The entity was successfully deleted + """ + DELETED + + """ + Deletion did not take place, reason given in message + """ + NOT_DELETED +} + +""" +@description +Permissions for administrators and customers. Used to control access to +GraphQL resolvers via the {@link Allow} decorator. + +@docsCategory common +""" +enum Permission { + """ + Authenticated means simply that the user is logged in + """ + Authenticated + + """ + SuperAdmin has unrestricted access to all operations + """ + SuperAdmin + + """ + Owner means the user owns this entity, e.g. a Customer's own Order + """ + Owner + + """ + Public means any unauthenticated user may perform the operation + """ + Public + + """ + Grants permission to create Catalog + """ + CreateCatalog + + """ + Grants permission to read Catalog + """ + ReadCatalog + + """ + Grants permission to update Catalog + """ + UpdateCatalog + + """ + Grants permission to delete Catalog + """ + DeleteCatalog + + """ + Grants permission to create Customer + """ + CreateCustomer + + """ + Grants permission to read Customer + """ + ReadCustomer + + """ + Grants permission to update Customer + """ + UpdateCustomer + + """ + Grants permission to delete Customer + """ + DeleteCustomer + + """ + Grants permission to create Administrator + """ + CreateAdministrator + + """ + Grants permission to read Administrator + """ + ReadAdministrator + + """ + Grants permission to update Administrator + """ + UpdateAdministrator + + """ + Grants permission to delete Administrator + """ + DeleteAdministrator + + """ + Grants permission to create Order + """ + CreateOrder + + """ + Grants permission to read Order + """ + ReadOrder + + """ + Grants permission to update Order + """ + UpdateOrder + + """ + Grants permission to delete Order + """ + DeleteOrder + + """ + Grants permission to create Promotion + """ + CreatePromotion + + """ + Grants permission to read Promotion + """ + ReadPromotion + + """ + Grants permission to update Promotion + """ + UpdatePromotion + + """ + Grants permission to delete Promotion + """ + DeletePromotion + + """ + Grants permission to create Settings + """ + CreateSettings + + """ + Grants permission to read Settings + """ + ReadSettings + + """ + Grants permission to update Settings + """ + UpdateSettings + + """ + Grants permission to delete Settings + """ + DeleteSettings +} + +enum SortOrder { + ASC + DESC +} + +enum ErrorCode { + UNKNOWN_ERROR + NATIVE_AUTH_STRATEGY_ERROR + INVALID_CREDENTIALS_ERROR + ORDER_STATE_TRANSITION_ERROR + EMAIL_ADDRESS_CONFLICT_ERROR + ORDER_LIMIT_ERROR + NEGATIVE_QUANTITY_ERROR + INSUFFICIENT_STOCK_ERROR + ORDER_MODIFICATION_ERROR + INELIGIBLE_SHIPPING_METHOD_ERROR + ORDER_PAYMENT_STATE_ERROR + INELIGIBLE_PAYMENT_METHOD_ERROR + PAYMENT_FAILED_ERROR + PAYMENT_DECLINED_ERROR + COUPON_CODE_INVALID_ERROR + COUPON_CODE_EXPIRED_ERROR + COUPON_CODE_LIMIT_ERROR + ALREADY_LOGGED_IN_ERROR + MISSING_PASSWORD_ERROR + PASSWORD_ALREADY_SET_ERROR + VERIFICATION_TOKEN_INVALID_ERROR + VERIFICATION_TOKEN_EXPIRED_ERROR + IDENTIFIER_CHANGE_TOKEN_INVALID_ERROR + IDENTIFIER_CHANGE_TOKEN_EXPIRED_ERROR + PASSWORD_RESET_TOKEN_INVALID_ERROR + PASSWORD_RESET_TOKEN_EXPIRED_ERROR + NOT_VERIFIED_ERROR + NO_ACTIVE_ORDER_ERROR +} + +enum LogicalOperator { + AND + OR +} + +""" +Retured when attempting an operation that relies on the NativeAuthStrategy, if that strategy is not configured. +""" +type NativeAuthStrategyError implements ErrorResult { + errorCode: ErrorCode! + message: String! +} + +""" +Returned if the user authentication credentials are not valid +""" +type InvalidCredentialsError implements ErrorResult { + errorCode: ErrorCode! + message: String! + authenticationError: String! +} + +""" +Returned if there is an error in transitioning the Order state +""" +type OrderStateTransitionError implements ErrorResult { + errorCode: ErrorCode! + message: String! + transitionError: String! + fromState: String! + toState: String! +} + +""" +Retured when attemting to create a Customer with an email address already registered to an existing User. +""" +type EmailAddressConflictError implements ErrorResult { + errorCode: ErrorCode! + message: String! +} + +""" +Retured when the maximum order size limit has been reached. +""" +type OrderLimitError implements ErrorResult { + errorCode: ErrorCode! + message: String! + maxItems: Int! +} + +""" +Retured when attemting to set a negative OrderLine quantity. +""" +type NegativeQuantityError implements ErrorResult { + errorCode: ErrorCode! + message: String! +} + +""" +Returned when attempting to add more items to the Order than are available +""" +type InsufficientStockError implements ErrorResult { + errorCode: ErrorCode! + message: String! + quantityAvailable: Int! + order: Order! +} + +""" +The `JSON` scalar type represents JSON values as specified by [ECMA-404](http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf). +""" +scalar JSON + +""" +A date-time string at UTC, such as 2007-12-03T10:15:30Z, compliant with the `date-time` format outlined in section 5.6 of the RFC 3339 profile of the ISO 8601 standard for representation of dates and times using the Gregorian calendar. +""" +scalar DateTime + +""" +The `Upload` scalar type represents a file upload. +""" +scalar Upload + +interface PaginatedList { + items: [Node!]! + totalItems: Int! +} + +interface Node { + id: ID! +} + +interface ErrorResult { + errorCode: ErrorCode! + message: String! +} + +type Adjustment { + adjustmentSource: String! + type: AdjustmentType! + description: String! + amount: Int! +} + +type TaxLine { + description: String! + taxRate: Float! +} + +type ConfigArg { + name: String! + value: String! +} + +type ConfigArgDefinition { + name: String! + type: String! + list: Boolean! + required: Boolean! + defaultValue: JSON + label: String + description: String + ui: JSON +} + +type ConfigurableOperation { + code: String! + args: [ConfigArg!]! +} + +type ConfigurableOperationDefinition { + code: String! + args: [ConfigArgDefinition!]! + description: String! +} + +type DeletionResponse { + result: DeletionResult! + message: String +} + +input ConfigArgInput { + name: String! + + """ + A JSON stringified representation of the actual value + """ + value: String! +} + +input ConfigurableOperationInput { + code: String! + arguments: [ConfigArgInput!]! +} + +input StringOperators { + eq: String + notEq: String + contains: String + notContains: String + in: [String!] + notIn: [String!] + regex: String +} + +input BooleanOperators { + eq: Boolean +} + +input NumberRange { + start: Float! + end: Float! +} + +input NumberOperators { + eq: Float + lt: Float + lte: Float + gt: Float + gte: Float + between: NumberRange +} + +input DateRange { + start: DateTime! + end: DateTime! +} + +input DateOperators { + eq: DateTime + before: DateTime + after: DateTime + between: DateRange +} + +input SearchInput { + term: String + facetValueIds: [ID!] + facetValueOperator: LogicalOperator + collectionId: ID + collectionSlug: String + groupByProduct: Boolean + take: Int + skip: Int + sort: SearchResultSortParameter +} + +input SearchResultSortParameter { + name: SortOrder + price: SortOrder +} + +input CreateCustomerInput { + title: String + firstName: String! + lastName: String! + phoneNumber: String + emailAddress: String! + customFields: JSON +} + +input CreateAddressInput { + fullName: String + company: String + streetLine1: String! + streetLine2: String + city: String + province: String + postalCode: String + countryCode: String! + phoneNumber: String + defaultShippingAddress: Boolean + defaultBillingAddress: Boolean + customFields: JSON +} + +input UpdateAddressInput { + id: ID! + fullName: String + company: String + streetLine1: String + streetLine2: String + city: String + province: String + postalCode: String + countryCode: String + phoneNumber: String + defaultShippingAddress: Boolean + defaultBillingAddress: Boolean + customFields: JSON +} + +""" +Indicates that an operation succeeded, where we do not want to return any more specific information. +""" +type Success { + success: Boolean! +} + +type ShippingMethodQuote { + id: ID! + price: Int! + priceWithTax: Int! + name: String! + description: String! + + """ + Any optional metadata returned by the ShippingCalculator in the ShippingCalculationResult + """ + metadata: JSON +} + +type PaymentMethodQuote { + id: ID! + code: String! + isEligible: Boolean! + eligibilityMessage: String +} + +type Country implements Node { + id: ID! + createdAt: DateTime! + updatedAt: DateTime! + languageCode: LanguageCode! + code: String! + name: String! + enabled: Boolean! + translations: [CountryTranslation!]! +} + +type CountryTranslation { + id: ID! + createdAt: DateTime! + updatedAt: DateTime! + languageCode: LanguageCode! + name: String! +} + +type CountryList implements PaginatedList { + items: [Country!]! + totalItems: Int! +} + +""" +@description +ISO 4217 currency code + +@docsCategory common +""" +enum CurrencyCode { + """ + United Arab Emirates dirham + """ + AED + + """ + Afghan afghani + """ + AFN + + """ + Albanian lek + """ + ALL + + """ + Armenian dram + """ + AMD + + """ + Netherlands Antillean guilder + """ + ANG + + """ + Angolan kwanza + """ + AOA + + """ + Argentine peso + """ + ARS + + """ + Australian dollar + """ + AUD + + """ + Aruban florin + """ + AWG + + """ + Azerbaijani manat + """ + AZN + + """ + Bosnia and Herzegovina convertible mark + """ + BAM + + """ + Barbados dollar + """ + BBD + + """ + Bangladeshi taka + """ + BDT + + """ + Bulgarian lev + """ + BGN + + """ + Bahraini dinar + """ + BHD + + """ + Burundian franc + """ + BIF + + """ + Bermudian dollar + """ + BMD + + """ + Brunei dollar + """ + BND + + """ + Boliviano + """ + BOB + + """ + Brazilian real + """ + BRL + + """ + Bahamian dollar + """ + BSD + + """ + Bhutanese ngultrum + """ + BTN + + """ + Botswana pula + """ + BWP + + """ + Belarusian ruble + """ + BYN + + """ + Belize dollar + """ + BZD + + """ + Canadian dollar + """ + CAD + + """ + Congolese franc + """ + CDF + + """ + Swiss franc + """ + CHF + + """ + Chilean peso + """ + CLP + + """ + Renminbi (Chinese) yuan + """ + CNY + + """ + Colombian peso + """ + COP + + """ + Costa Rican colon + """ + CRC + + """ + Cuban convertible peso + """ + CUC + + """ + Cuban peso + """ + CUP + + """ + Cape Verde escudo + """ + CVE + + """ + Czech koruna + """ + CZK + + """ + Djiboutian franc + """ + DJF + + """ + Danish krone + """ + DKK + + """ + Dominican peso + """ + DOP + + """ + Algerian dinar + """ + DZD + + """ + Egyptian pound + """ + EGP + + """ + Eritrean nakfa + """ + ERN + + """ + Ethiopian birr + """ + ETB + + """ + Euro + """ + EUR + + """ + Fiji dollar + """ + FJD + + """ + Falkland Islands pound + """ + FKP + + """ + Pound sterling + """ + GBP + + """ + Georgian lari + """ + GEL + + """ + Ghanaian cedi + """ + GHS + + """ + Gibraltar pound + """ + GIP + + """ + Gambian dalasi + """ + GMD + + """ + Guinean franc + """ + GNF + + """ + Guatemalan quetzal + """ + GTQ + + """ + Guyanese dollar + """ + GYD + + """ + Hong Kong dollar + """ + HKD + + """ + Honduran lempira + """ + HNL + + """ + Croatian kuna + """ + HRK + + """ + Haitian gourde + """ + HTG + + """ + Hungarian forint + """ + HUF + + """ + Indonesian rupiah + """ + IDR + + """ + Israeli new shekel + """ + ILS + + """ + Indian rupee + """ + INR + + """ + Iraqi dinar + """ + IQD + + """ + Iranian rial + """ + IRR + + """ + Icelandic króna + """ + ISK + + """ + Jamaican dollar + """ + JMD + + """ + Jordanian dinar + """ + JOD + + """ + Japanese yen + """ + JPY + + """ + Kenyan shilling + """ + KES + + """ + Kyrgyzstani som + """ + KGS + + """ + Cambodian riel + """ + KHR + + """ + Comoro franc + """ + KMF + + """ + North Korean won + """ + KPW + + """ + South Korean won + """ + KRW + + """ + Kuwaiti dinar + """ + KWD + + """ + Cayman Islands dollar + """ + KYD + + """ + Kazakhstani tenge + """ + KZT + + """ + Lao kip + """ + LAK + + """ + Lebanese pound + """ + LBP + + """ + Sri Lankan rupee + """ + LKR + + """ + Liberian dollar + """ + LRD + + """ + Lesotho loti + """ + LSL + + """ + Libyan dinar + """ + LYD + + """ + Moroccan dirham + """ + MAD + + """ + Moldovan leu + """ + MDL + + """ + Malagasy ariary + """ + MGA + + """ + Macedonian denar + """ + MKD + + """ + Myanmar kyat + """ + MMK + + """ + Mongolian tögrög + """ + MNT + + """ + Macanese pataca + """ + MOP + + """ + Mauritanian ouguiya + """ + MRU + + """ + Mauritian rupee + """ + MUR + + """ + Maldivian rufiyaa + """ + MVR + + """ + Malawian kwacha + """ + MWK + + """ + Mexican peso + """ + MXN + + """ + Malaysian ringgit + """ + MYR + + """ + Mozambican metical + """ + MZN + + """ + Namibian dollar + """ + NAD + + """ + Nigerian naira + """ + NGN + + """ + Nicaraguan córdoba + """ + NIO + + """ + Norwegian krone + """ + NOK + + """ + Nepalese rupee + """ + NPR + + """ + New Zealand dollar + """ + NZD + + """ + Omani rial + """ + OMR + + """ + Panamanian balboa + """ + PAB + + """ + Peruvian sol + """ + PEN + + """ + Papua New Guinean kina + """ + PGK + + """ + Philippine peso + """ + PHP + + """ + Pakistani rupee + """ + PKR + + """ + Polish złoty + """ + PLN + + """ + Paraguayan guaraní + """ + PYG + + """ + Qatari riyal + """ + QAR + + """ + Romanian leu + """ + RON + + """ + Serbian dinar + """ + RSD + + """ + Russian ruble + """ + RUB + + """ + Rwandan franc + """ + RWF + + """ + Saudi riyal + """ + SAR + + """ + Solomon Islands dollar + """ + SBD + + """ + Seychelles rupee + """ + SCR + + """ + Sudanese pound + """ + SDG + + """ + Swedish krona/kronor + """ + SEK + + """ + Singapore dollar + """ + SGD + + """ + Saint Helena pound + """ + SHP + + """ + Sierra Leonean leone + """ + SLL + + """ + Somali shilling + """ + SOS + + """ + Surinamese dollar + """ + SRD + + """ + South Sudanese pound + """ + SSP + + """ + São Tomé and Príncipe dobra + """ + STN + + """ + Salvadoran colón + """ + SVC + + """ + Syrian pound + """ + SYP + + """ + Swazi lilangeni + """ + SZL + + """ + Thai baht + """ + THB + + """ + Tajikistani somoni + """ + TJS + + """ + Turkmenistan manat + """ + TMT + + """ + Tunisian dinar + """ + TND + + """ + Tongan paʻanga + """ + TOP + + """ + Turkish lira + """ + TRY + + """ + Trinidad and Tobago dollar + """ + TTD + + """ + New Taiwan dollar + """ + TWD + + """ + Tanzanian shilling + """ + TZS + + """ + Ukrainian hryvnia + """ + UAH + + """ + Ugandan shilling + """ + UGX + + """ + United States dollar + """ + USD + + """ + Uruguayan peso + """ + UYU + + """ + Uzbekistan som + """ + UZS + + """ + Venezuelan bolívar soberano + """ + VES + + """ + Vietnamese đồng + """ + VND + + """ + Vanuatu vatu + """ + VUV + + """ + Samoan tala + """ + WST + + """ + CFA franc BEAC + """ + XAF + + """ + East Caribbean dollar + """ + XCD + + """ + CFA franc BCEAO + """ + XOF + + """ + CFP franc (franc Pacifique) + """ + XPF + + """ + Yemeni rial + """ + YER + + """ + South African rand + """ + ZAR + + """ + Zambian kwacha + """ + ZMW + + """ + Zimbabwean dollar + """ + ZWL +} + +interface CustomField { + name: String! + type: String! + list: Boolean! + label: [LocalizedString!] + description: [LocalizedString!] + readonly: Boolean + internal: Boolean +} + +type StringCustomFieldConfig implements CustomField { + name: String! + type: String! + list: Boolean! + length: Int + label: [LocalizedString!] + description: [LocalizedString!] + readonly: Boolean + internal: Boolean + pattern: String + options: [StringFieldOption!] +} + +type StringFieldOption { + value: String! + label: [LocalizedString!] +} + +type LocaleStringCustomFieldConfig implements CustomField { + name: String! + type: String! + list: Boolean! + length: Int + label: [LocalizedString!] + description: [LocalizedString!] + readonly: Boolean + internal: Boolean + pattern: String +} + +type IntCustomFieldConfig implements CustomField { + name: String! + type: String! + list: Boolean! + label: [LocalizedString!] + description: [LocalizedString!] + readonly: Boolean + internal: Boolean + min: Int + max: Int + step: Int +} + +type FloatCustomFieldConfig implements CustomField { + name: String! + type: String! + list: Boolean! + label: [LocalizedString!] + description: [LocalizedString!] + readonly: Boolean + internal: Boolean + min: Float + max: Float + step: Float +} + +type BooleanCustomFieldConfig implements CustomField { + name: String! + type: String! + list: Boolean! + label: [LocalizedString!] + description: [LocalizedString!] + readonly: Boolean + internal: Boolean +} + +""" +Expects the same validation formats as the `` HTML element. +See https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/datetime-local#Additional_attributes +""" +type DateTimeCustomFieldConfig implements CustomField { + name: String! + type: String! + list: Boolean! + label: [LocalizedString!] + description: [LocalizedString!] + readonly: Boolean + internal: Boolean + min: String + max: String + step: Int +} + +type RelationCustomFieldConfig implements CustomField { + name: String! + type: String! + list: Boolean! + label: [LocalizedString!] + description: [LocalizedString!] + readonly: Boolean + internal: Boolean + entity: String! + scalarFields: [String!]! +} + +type LocalizedString { + languageCode: LanguageCode! + value: String! +} + +union CustomFieldConfig = + StringCustomFieldConfig + | LocaleStringCustomFieldConfig + | IntCustomFieldConfig + | FloatCustomFieldConfig + | BooleanCustomFieldConfig + | DateTimeCustomFieldConfig + | RelationCustomFieldConfig + +type CustomerGroup implements Node { + id: ID! + createdAt: DateTime! + updatedAt: DateTime! + name: String! + customers(options: CustomerListOptions): CustomerList! +} + +type Customer implements Node { + id: ID! + createdAt: DateTime! + updatedAt: DateTime! + title: String + firstName: String! + lastName: String! + phoneNumber: String + emailAddress: String! + addresses: [Address!] + orders(options: OrderListOptions): OrderList! + user: User + customFields: JSON +} + +type CustomerList implements PaginatedList { + items: [Customer!]! + totalItems: Int! +} + +type FacetValue implements Node { + id: ID! + createdAt: DateTime! + updatedAt: DateTime! + languageCode: LanguageCode! + facet: Facet! + name: String! + code: String! + translations: [FacetValueTranslation!]! + customFields: JSON +} + +type FacetValueTranslation { + id: ID! + createdAt: DateTime! + updatedAt: DateTime! + languageCode: LanguageCode! + name: String! +} + +type Facet implements Node { + id: ID! + createdAt: DateTime! + updatedAt: DateTime! + languageCode: LanguageCode! + name: String! + code: String! + values: [FacetValue!]! + translations: [FacetTranslation!]! + customFields: JSON +} + +type FacetTranslation { + id: ID! + createdAt: DateTime! + updatedAt: DateTime! + languageCode: LanguageCode! + name: String! +} + +type FacetList implements PaginatedList { + items: [Facet!]! + totalItems: Int! +} + +type HistoryEntry implements Node { + id: ID! + createdAt: DateTime! + updatedAt: DateTime! + type: HistoryEntryType! + data: JSON! +} + +enum HistoryEntryType { + CUSTOMER_REGISTERED + CUSTOMER_VERIFIED + CUSTOMER_DETAIL_UPDATED + CUSTOMER_ADDED_TO_GROUP + CUSTOMER_REMOVED_FROM_GROUP + CUSTOMER_ADDRESS_CREATED + CUSTOMER_ADDRESS_UPDATED + CUSTOMER_ADDRESS_DELETED + CUSTOMER_PASSWORD_UPDATED + CUSTOMER_PASSWORD_RESET_REQUESTED + CUSTOMER_PASSWORD_RESET_VERIFIED + CUSTOMER_EMAIL_UPDATE_REQUESTED + CUSTOMER_EMAIL_UPDATE_VERIFIED + CUSTOMER_NOTE + ORDER_STATE_TRANSITION + ORDER_PAYMENT_TRANSITION + ORDER_FULFILLMENT + ORDER_CANCELLATION + ORDER_REFUND_TRANSITION + ORDER_FULFILLMENT_TRANSITION + ORDER_NOTE + ORDER_COUPON_APPLIED + ORDER_COUPON_REMOVED + ORDER_MODIFIED +} + +type HistoryEntryList implements PaginatedList { + items: [HistoryEntry!]! + totalItems: Int! +} + +""" +@description +Languages in the form of a ISO 639-1 language code with optional +region or script modifier (e.g. de_AT). The selection available is based +on the [Unicode CLDR summary list](https://unicode-org.github.io/cldr-staging/charts/37/summary/root.html) +and includes the major spoken languages of the world and any widely-used variants. + +@docsCategory common +""" +enum LanguageCode { + """ + Afrikaans + """ + af + + """ + Akan + """ + ak + + """ + Albanian + """ + sq + + """ + Amharic + """ + am + + """ + Arabic + """ + ar + + """ + Armenian + """ + hy + + """ + Assamese + """ + as + + """ + Azerbaijani + """ + az + + """ + Bambara + """ + bm + + """ + Bangla + """ + bn + + """ + Basque + """ + eu + + """ + Belarusian + """ + be + + """ + Bosnian + """ + bs + + """ + Breton + """ + br + + """ + Bulgarian + """ + bg + + """ + Burmese + """ + my + + """ + Catalan + """ + ca + + """ + Chechen + """ + ce + + """ + Chinese + """ + zh + + """ + Simplified Chinese + """ + zh_Hans + + """ + Traditional Chinese + """ + zh_Hant + + """ + Church Slavic + """ + cu + + """ + Cornish + """ + kw + + """ + Corsican + """ + co + + """ + Croatian + """ + hr + + """ + Czech + """ + cs + + """ + Danish + """ + da + + """ + Dutch + """ + nl + + """ + Flemish + """ + nl_BE + + """ + Dzongkha + """ + dz + + """ + English + """ + en + + """ + Australian English + """ + en_AU + + """ + Canadian English + """ + en_CA + + """ + British English + """ + en_GB + + """ + American English + """ + en_US + + """ + Esperanto + """ + eo + + """ + Estonian + """ + et + + """ + Ewe + """ + ee + + """ + Faroese + """ + fo + + """ + Finnish + """ + fi + + """ + French + """ + fr + + """ + Canadian French + """ + fr_CA + + """ + Swiss French + """ + fr_CH + + """ + Fulah + """ + ff + + """ + Galician + """ + gl + + """ + Ganda + """ + lg + + """ + Georgian + """ + ka + + """ + German + """ + de + + """ + Austrian German + """ + de_AT + + """ + Swiss High German + """ + de_CH + + """ + Greek + """ + el + + """ + Gujarati + """ + gu + + """ + Haitian Creole + """ + ht + + """ + Hausa + """ + ha + + """ + Hebrew + """ + he + + """ + Hindi + """ + hi + + """ + Hungarian + """ + hu + + """ + Icelandic + """ + is + + """ + Igbo + """ + ig + + """ + Indonesian + """ + id + + """ + Interlingua + """ + ia + + """ + Irish + """ + ga + + """ + Italian + """ + it + + """ + Japanese + """ + ja + + """ + Javanese + """ + jv + + """ + Kalaallisut + """ + kl + + """ + Kannada + """ + kn + + """ + Kashmiri + """ + ks + + """ + Kazakh + """ + kk + + """ + Khmer + """ + km + + """ + Kikuyu + """ + ki + + """ + Kinyarwanda + """ + rw + + """ + Korean + """ + ko + + """ + Kurdish + """ + ku + + """ + Kyrgyz + """ + ky + + """ + Lao + """ + lo + + """ + Latin + """ + la + + """ + Latvian + """ + lv + + """ + Lingala + """ + ln + + """ + Lithuanian + """ + lt + + """ + Luba-Katanga + """ + lu + + """ + Luxembourgish + """ + lb + + """ + Macedonian + """ + mk + + """ + Malagasy + """ + mg + + """ + Malay + """ + ms + + """ + Malayalam + """ + ml + + """ + Maltese + """ + mt + + """ + Manx + """ + gv + + """ + Maori + """ + mi + + """ + Marathi + """ + mr + + """ + Mongolian + """ + mn + + """ + Nepali + """ + ne + + """ + North Ndebele + """ + nd + + """ + Northern Sami + """ + se + + """ + Norwegian Bokmål + """ + nb + + """ + Norwegian Nynorsk + """ + nn + + """ + Nyanja + """ + ny + + """ + Odia + """ + or + + """ + Oromo + """ + om + + """ + Ossetic + """ + os + + """ + Pashto + """ + ps + + """ + Persian + """ + fa + + """ + Dari + """ + fa_AF + + """ + Polish + """ + pl + + """ + Portuguese + """ + pt + + """ + Brazilian Portuguese + """ + pt_BR + + """ + European Portuguese + """ + pt_PT + + """ + Punjabi + """ + pa + + """ + Quechua + """ + qu + + """ + Romanian + """ + ro + + """ + Moldavian + """ + ro_MD + + """ + Romansh + """ + rm + + """ + Rundi + """ + rn + + """ + Russian + """ + ru + + """ + Samoan + """ + sm + + """ + Sango + """ + sg + + """ + Sanskrit + """ + sa + + """ + Scottish Gaelic + """ + gd + + """ + Serbian + """ + sr + + """ + Shona + """ + sn + + """ + Sichuan Yi + """ + ii + + """ + Sindhi + """ + sd + + """ + Sinhala + """ + si + + """ + Slovak + """ + sk + + """ + Slovenian + """ + sl + + """ + Somali + """ + so + + """ + Southern Sotho + """ + st + + """ + Spanish + """ + es + + """ + European Spanish + """ + es_ES + + """ + Mexican Spanish + """ + es_MX + + """ + Sundanese + """ + su + + """ + Swahili + """ + sw + + """ + Congo Swahili + """ + sw_CD + + """ + Swedish + """ + sv + + """ + Tajik + """ + tg + + """ + Tamil + """ + ta + + """ + Tatar + """ + tt + + """ + Telugu + """ + te + + """ + Thai + """ + th + + """ + Tibetan + """ + bo + + """ + Tigrinya + """ + ti + + """ + Tongan + """ + to + + """ + Turkish + """ + tr + + """ + Turkmen + """ + tk + + """ + Ukrainian + """ + uk + + """ + Urdu + """ + ur + + """ + Uyghur + """ + ug + + """ + Uzbek + """ + uz + + """ + Vietnamese + """ + vi + + """ + Volapük + """ + vo + + """ + Welsh + """ + cy + + """ + Western Frisian + """ + fy + + """ + Wolof + """ + wo + + """ + Xhosa + """ + xh + + """ + Yiddish + """ + yi + + """ + Yoruba + """ + yo + + """ + Zulu + """ + zu +} + +type Order implements Node { + id: ID! + createdAt: DateTime! + updatedAt: DateTime! + + """ + The date & time that the Order was placed, i.e. the Customer + completed the checkout and the Order is no longer "active" + """ + orderPlacedAt: DateTime + + """ + A unique code for the Order + """ + code: String! + state: String! + + """ + An order is active as long as the payment process has not been completed + """ + active: Boolean! + customer: Customer + shippingAddress: OrderAddress + billingAddress: OrderAddress + lines: [OrderLine!]! + + """ + Surcharges are arbitrary modifications to the Order total which are neither + ProductVariants nor discounts resulting from applied Promotions. For example, + one-off discounts based on customer interaction, or surcharges based on payment + methods. + """ + surcharges: [Surcharge!]! + + """ + Order-level adjustments to the order total, such as discounts from promotions + """ + adjustments: [Adjustment!]! @deprecated(reason: "Use `discounts` instead") + discounts: [Adjustment!]! + + """ + An array of all coupon codes applied to the Order + """ + couponCodes: [String!]! + + """ + Promotions applied to the order. Only gets populated after the payment process has completed. + """ + promotions: [Promotion!]! + payments: [Payment!] + fulfillments: [Fulfillment!] + totalQuantity: Int! + + """ + The subTotal is the total of all OrderLines in the Order. This figure also includes any Order-level + discounts which have been prorated (proportionally distributed) amongst the OrderItems. + To get a total of all OrderLines which does not account for prorated discounts, use the + sum of `OrderLine.discountedLinePrice` values. + """ + subTotal: Int! + + """ + Same as subTotal, but inclusive of tax + """ + subTotalWithTax: Int! + currencyCode: CurrencyCode! + shippingLines: [ShippingLine!]! + shipping: Int! + shippingWithTax: Int! + + """ + Equal to subTotal plus shipping + """ + total: Int! + + """ + The final payable amount. Equal to subTotalWithTax plus shippingWithTax + """ + totalWithTax: Int! + + """ + A summary of the taxes being applied to this Order + """ + taxSummary: [OrderTaxSummary!]! + history(options: HistoryEntryListOptions): HistoryEntryList! + customFields: JSON +} + +""" +A summary of the taxes being applied to this order, grouped +by taxRate. +""" +type OrderTaxSummary { + """ + A description of this tax + """ + description: String! + + """ + The taxRate as a percentage + """ + taxRate: Float! + + """ + The total net price or OrderItems to which this taxRate applies + """ + taxBase: Int! + + """ + The total tax being applied to the Order at this taxRate + """ + taxTotal: Int! +} + +type OrderAddress { + fullName: String + company: String + streetLine1: String + streetLine2: String + city: String + province: String + postalCode: String + country: String + countryCode: String + phoneNumber: String + customFields: JSON +} + +type OrderList implements PaginatedList { + items: [Order!]! + totalItems: Int! +} + +type ShippingLine { + shippingMethod: ShippingMethod! + price: Int! + priceWithTax: Int! + discountedPrice: Int! + discountedPriceWithTax: Int! + discounts: [Adjustment!]! +} + +type OrderItem implements Node { + id: ID! + createdAt: DateTime! + updatedAt: DateTime! + cancelled: Boolean! + + """ + The price of a single unit, excluding tax and discounts + """ + unitPrice: Int! + + """ + The price of a single unit, including tax but excluding discounts + """ + unitPriceWithTax: Int! + + """ + The price of a single unit including discounts, excluding tax. + + If Order-level discounts have been applied, this will not be the + actual taxable unit price (see `proratedUnitPrice`), but is generally the + correct price to display to customers to avoid confusion + about the internal handling of distributed Order-level discounts. + """ + discountedUnitPrice: Int! + + """ + The price of a single unit including discounts and tax + """ + discountedUnitPriceWithTax: Int! + + """ + The actual unit price, taking into account both item discounts _and_ prorated (proportially-distributed) + Order-level discounts. This value is the true economic value of the OrderItem, and is used in tax + and refund calculations. + """ + proratedUnitPrice: Int! + + """ + The proratedUnitPrice including tax + """ + proratedUnitPriceWithTax: Int! + unitTax: Int! + unitPriceIncludesTax: Boolean! + @deprecated(reason: "`unitPrice` is now always without tax") + taxRate: Float! + adjustments: [Adjustment!]! + taxLines: [TaxLine!]! + fulfillment: Fulfillment + refundId: ID +} + +type OrderLine implements Node { + id: ID! + createdAt: DateTime! + updatedAt: DateTime! + productVariant: ProductVariant! + featuredAsset: Asset + + """ + The price of a single unit, excluding tax and discounts + """ + unitPrice: Int! + + """ + The price of a single unit, including tax but excluding discounts + """ + unitPriceWithTax: Int! + + """ + Non-zero if the unitPrice has changed since it was initially added to Order + """ + unitPriceChangeSinceAdded: Int! + + """ + Non-zero if the unitPriceWithTax has changed since it was initially added to Order + """ + unitPriceWithTaxChangeSinceAdded: Int! + + """ + The price of a single unit including discounts, excluding tax. + + If Order-level discounts have been applied, this will not be the + actual taxable unit price (see `proratedUnitPrice`), but is generally the + correct price to display to customers to avoid confusion + about the internal handling of distributed Order-level discounts. + """ + discountedUnitPrice: Int! + + """ + The price of a single unit including discounts and tax + """ + discountedUnitPriceWithTax: Int! + + """ + The actual unit price, taking into account both item discounts _and_ prorated (proportially-distributed) + Order-level discounts. This value is the true economic value of the OrderItem, and is used in tax + and refund calculations. + """ + proratedUnitPrice: Int! + + """ + The proratedUnitPrice including tax + """ + proratedUnitPriceWithTax: Int! + quantity: Int! + items: [OrderItem!]! + totalPrice: Int! @deprecated(reason: "Use `linePriceWithTax` instead") + taxRate: Float! + + """ + The total price of the line excluding tax and discounts. + """ + linePrice: Int! + + """ + The total price of the line including tax bit excluding discounts. + """ + linePriceWithTax: Int! + + """ + The price of the line including discounts, excluding tax + """ + discountedLinePrice: Int! + + """ + The price of the line including discounts and tax + """ + discountedLinePriceWithTax: Int! + + """ + The actual line price, taking into account both item discounts _and_ prorated (proportially-distributed) + Order-level discounts. This value is the true economic value of the OrderLine, and is used in tax + and refund calculations. + """ + proratedLinePrice: Int! + + """ + The proratedLinePrice including tax + """ + proratedLinePriceWithTax: Int! + + """ + The total tax on this line + """ + lineTax: Int! + adjustments: [Adjustment!]! @deprecated(reason: "Use `discounts` instead") + discounts: [Adjustment!]! + taxLines: [TaxLine!]! + order: Order! + customFields: JSON +} + +type Payment implements Node { + id: ID! + createdAt: DateTime! + updatedAt: DateTime! + method: String! + amount: Int! + state: String! + transactionId: String + errorMessage: String + refunds: [Refund!]! + metadata: JSON +} + +type Refund implements Node { + id: ID! + createdAt: DateTime! + updatedAt: DateTime! + items: Int! + shipping: Int! + adjustment: Int! + total: Int! + method: String + state: String! + transactionId: String + reason: String + orderItems: [OrderItem!]! + paymentId: ID! + metadata: JSON +} + +type Fulfillment implements Node { + id: ID! + createdAt: DateTime! + updatedAt: DateTime! + orderItems: [OrderItem!]! + state: String! + method: String! + trackingCode: String + customFields: JSON +} + +type Surcharge implements Node { + id: ID! + createdAt: DateTime! + updatedAt: DateTime! + description: String! + sku: String + taxLines: [TaxLine!]! + price: Int! + priceWithTax: Int! + taxRate: Float! +} + +type ProductOptionGroup implements Node { + id: ID! + createdAt: DateTime! + updatedAt: DateTime! + languageCode: LanguageCode! + code: String! + name: String! + options: [ProductOption!]! + translations: [ProductOptionGroupTranslation!]! + customFields: JSON +} + +type ProductOptionGroupTranslation { + id: ID! + createdAt: DateTime! + updatedAt: DateTime! + languageCode: LanguageCode! + name: String! +} + +type ProductOption implements Node { + id: ID! + createdAt: DateTime! + updatedAt: DateTime! + languageCode: LanguageCode! + code: String! + name: String! + groupId: ID! + group: ProductOptionGroup! + translations: [ProductOptionTranslation!]! + customFields: JSON +} + +type ProductOptionTranslation { + id: ID! + createdAt: DateTime! + updatedAt: DateTime! + languageCode: LanguageCode! + name: String! +} + +type SearchReindexResponse { + success: Boolean! +} + +type SearchResponse { + items: [SearchResult!]! + totalItems: Int! + facetValues: [FacetValueResult!]! +} + +""" +Which FacetValues are present in the products returned +by the search, and in what quantity. +""" +type FacetValueResult { + facetValue: FacetValue! + count: Int! +} + +type SearchResultAsset { + id: ID! + preview: String! + focalPoint: Coordinate +} + +type SearchResult { + sku: String! + slug: String! + productId: ID! + productName: String! + productPreview: String! + @deprecated(reason: "Use `productAsset.preview` instead") + productAsset: SearchResultAsset + productVariantId: ID! + productVariantName: String! + productVariantPreview: String! + @deprecated(reason: "Use `productVariantAsset.preview` instead") + productVariantAsset: SearchResultAsset + price: SearchResultPrice! + priceWithTax: SearchResultPrice! + currencyCode: CurrencyCode! + description: String! + facetIds: [ID!]! + facetValueIds: [ID!]! + + """ + An array of ids of the Collections in which this result appears + """ + collectionIds: [ID!]! + + """ + A relevence score for the result. Differs between database implementations + """ + score: Float! +} + +""" +The price of a search result product, either as a range or as a single price +""" +union SearchResultPrice = PriceRange | SinglePrice + +""" +The price value where the result has a single price +""" +type SinglePrice { + value: Int! +} + +""" +The price range where the result has more than one price +""" +type PriceRange { + min: Int! + max: Int! +} + +type Product implements Node { + id: ID! + createdAt: DateTime! + updatedAt: DateTime! + languageCode: LanguageCode! + name: String! + slug: String! + description: String! + featuredAsset: Asset + assets: [Asset!]! + variants: [ProductVariant!]! + optionGroups: [ProductOptionGroup!]! + facetValues: [FacetValue!]! + translations: [ProductTranslation!]! + collections: [Collection!]! + customFields: JSON +} + +type ProductTranslation { + id: ID! + createdAt: DateTime! + updatedAt: DateTime! + languageCode: LanguageCode! + name: String! + slug: String! + description: String! +} + +type ProductList implements PaginatedList { + items: [Product!]! + totalItems: Int! +} + +type ProductVariant implements Node { + id: ID! + product: Product! + productId: ID! + createdAt: DateTime! + updatedAt: DateTime! + languageCode: LanguageCode! + sku: String! + name: String! + featuredAsset: Asset + assets: [Asset!]! + price: Int! + currencyCode: CurrencyCode! + priceIncludesTax: Boolean! + @deprecated(reason: "price now always excludes tax") + priceWithTax: Int! + stockLevel: String! + taxRateApplied: TaxRate! + taxCategory: TaxCategory! + options: [ProductOption!]! + facetValues: [FacetValue!]! + translations: [ProductVariantTranslation!]! + customFields: JSON +} + +type ProductVariantTranslation { + id: ID! + createdAt: DateTime! + updatedAt: DateTime! + languageCode: LanguageCode! + name: String! +} + +type Promotion implements Node { + id: ID! + createdAt: DateTime! + updatedAt: DateTime! + startsAt: DateTime + endsAt: DateTime + couponCode: String + perCustomerUsageLimit: Int + name: String! + enabled: Boolean! + conditions: [ConfigurableOperation!]! + actions: [ConfigurableOperation!]! +} + +type PromotionList implements PaginatedList { + items: [Promotion!]! + totalItems: Int! +} + +type Role implements Node { + id: ID! + createdAt: DateTime! + updatedAt: DateTime! + code: String! + description: String! + permissions: [Permission!]! + channels: [Channel!]! +} + +type RoleList implements PaginatedList { + items: [Role!]! + totalItems: Int! +} + +type ShippingMethod implements Node { + id: ID! + createdAt: DateTime! + updatedAt: DateTime! + code: String! + name: String! + description: String! + fulfillmentHandlerCode: String! + checker: ConfigurableOperation! + calculator: ConfigurableOperation! + translations: [ShippingMethodTranslation!]! + customFields: JSON +} + +type ShippingMethodTranslation { + id: ID! + createdAt: DateTime! + updatedAt: DateTime! + languageCode: LanguageCode! + name: String! + description: String! +} + +type ShippingMethodList implements PaginatedList { + items: [ShippingMethod!]! + totalItems: Int! +} + +type Tag implements Node { + id: ID! + createdAt: DateTime! + updatedAt: DateTime! + value: String! +} + +type TagList implements PaginatedList { + items: [Tag!]! + totalItems: Int! +} + +type TaxCategory implements Node { + id: ID! + createdAt: DateTime! + updatedAt: DateTime! + name: String! + isDefault: Boolean! +} + +type TaxRate implements Node { + id: ID! + createdAt: DateTime! + updatedAt: DateTime! + name: String! + enabled: Boolean! + value: Float! + category: TaxCategory! + zone: Zone! + customerGroup: CustomerGroup +} + +type TaxRateList implements PaginatedList { + items: [TaxRate!]! + totalItems: Int! +} + +type User implements Node { + id: ID! + createdAt: DateTime! + updatedAt: DateTime! + identifier: String! + verified: Boolean! + roles: [Role!]! + lastLogin: DateTime + authenticationMethods: [AuthenticationMethod!]! + customFields: JSON +} + +type AuthenticationMethod implements Node { + id: ID! + createdAt: DateTime! + updatedAt: DateTime! + strategy: String! +} + +type Zone implements Node { + id: ID! + createdAt: DateTime! + updatedAt: DateTime! + name: String! + members: [Country!]! +} + +""" +Returned when attempting to modify the contents of an Order that is not in the `AddingItems` state. +""" +type OrderModificationError implements ErrorResult { + errorCode: ErrorCode! + message: String! +} + +""" +Returned when attempting to set a ShippingMethod for which the Order is not eligible +""" +type IneligibleShippingMethodError implements ErrorResult { + errorCode: ErrorCode! + message: String! +} + +""" +Returned when attempting to add a Payment to an Order that is not in the `ArrangingPayment` state. +""" +type OrderPaymentStateError implements ErrorResult { + errorCode: ErrorCode! + message: String! +} + +""" +Returned when attempting to add a Payment using a PaymentMethod for which the Order is not eligible. +""" +type IneligiblePaymentMethodError implements ErrorResult { + errorCode: ErrorCode! + message: String! + eligibilityCheckerMessage: String +} + +""" +Returned when a Payment fails due to an error. +""" +type PaymentFailedError implements ErrorResult { + errorCode: ErrorCode! + message: String! + paymentErrorMessage: String! +} + +""" +Returned when a Payment is declined by the payment provider. +""" +type PaymentDeclinedError implements ErrorResult { + errorCode: ErrorCode! + message: String! + paymentErrorMessage: String! +} + +""" +Returned if the provided coupon code is invalid +""" +type CouponCodeInvalidError implements ErrorResult { + errorCode: ErrorCode! + message: String! + couponCode: String! +} + +""" +Returned if the provided coupon code is invalid +""" +type CouponCodeExpiredError implements ErrorResult { + errorCode: ErrorCode! + message: String! + couponCode: String! +} + +""" +Returned if the provided coupon code is invalid +""" +type CouponCodeLimitError implements ErrorResult { + errorCode: ErrorCode! + message: String! + couponCode: String! + limit: Int! +} + +""" +Retured when attemting to set the Customer for an Order when already logged in. +""" +type AlreadyLoggedInError implements ErrorResult { + errorCode: ErrorCode! + message: String! +} + +""" +Retured when attemting to register or verify a customer account without a password, when one is required. +""" +type MissingPasswordError implements ErrorResult { + errorCode: ErrorCode! + message: String! +} + +""" +Retured when attemting to verify a customer account with a password, when a password has already been set. +""" +type PasswordAlreadySetError implements ErrorResult { + errorCode: ErrorCode! + message: String! +} + +""" +Retured if the verification token (used to verify a Customer's email address) is either +invalid or does not match any expected tokens. +""" +type VerificationTokenInvalidError implements ErrorResult { + errorCode: ErrorCode! + message: String! +} + +""" +Returned if the verification token (used to verify a Customer's email address) is valid, but has +expired according to the `verificationTokenDuration` setting in the AuthOptions. +""" +type VerificationTokenExpiredError implements ErrorResult { + errorCode: ErrorCode! + message: String! +} + +""" +Retured if the token used to change a Customer's email address is either +invalid or does not match any expected tokens. +""" +type IdentifierChangeTokenInvalidError implements ErrorResult { + errorCode: ErrorCode! + message: String! +} + +""" +Retured if the token used to change a Customer's email address is valid, but has +expired according to the `verificationTokenDuration` setting in the AuthOptions. +""" +type IdentifierChangeTokenExpiredError implements ErrorResult { + errorCode: ErrorCode! + message: String! +} + +""" +Retured if the token used to reset a Customer's password is either +invalid or does not match any expected tokens. +""" +type PasswordResetTokenInvalidError implements ErrorResult { + errorCode: ErrorCode! + message: String! +} + +""" +Retured if the token used to reset a Customer's password is valid, but has +expired according to the `verificationTokenDuration` setting in the AuthOptions. +""" +type PasswordResetTokenExpiredError implements ErrorResult { + errorCode: ErrorCode! + message: String! +} + +""" +Returned if `authOptions.requireVerification` is set to `true` (which is the default) +and an unverified user attempts to authenticate. +""" +type NotVerifiedError implements ErrorResult { + errorCode: ErrorCode! + message: String! +} + +""" +Returned when invoking a mutation which depends on there being an active Order on the +current session. +""" +type NoActiveOrderError implements ErrorResult { + errorCode: ErrorCode! + message: String! +} + +input RegisterCustomerInput { + emailAddress: String! + title: String + firstName: String + lastName: String + phoneNumber: String + password: String +} + +input UpdateCustomerInput { + title: String + firstName: String + lastName: String + phoneNumber: String + customFields: JSON +} + +""" +Passed as input to the `addPaymentToOrder` mutation. +""" +input PaymentInput { + """ + This field should correspond to the `code` property of a PaymentMethodHandler. + """ + method: String! + + """ + This field should contain arbitrary data passed to the specified PaymentMethodHandler's `createPayment()` method + as the "metadata" argument. For example, it could contain an ID for the payment and other + data generated by the payment provider. + """ + metadata: JSON! +} + +union UpdateOrderItemsResult = + Order + | OrderModificationError + | OrderLimitError + | NegativeQuantityError + | InsufficientStockError + +union RemoveOrderItemsResult = Order | OrderModificationError + +union SetOrderShippingMethodResult = + Order + | OrderModificationError + | IneligibleShippingMethodError + | NoActiveOrderError + +union ApplyCouponCodeResult = + Order + | CouponCodeExpiredError + | CouponCodeInvalidError + | CouponCodeLimitError + +union AddPaymentToOrderResult = + Order + | OrderPaymentStateError + | IneligiblePaymentMethodError + | PaymentFailedError + | PaymentDeclinedError + | OrderStateTransitionError + | NoActiveOrderError + +union TransitionOrderToStateResult = Order | OrderStateTransitionError + +union SetCustomerForOrderResult = + Order + | AlreadyLoggedInError + | EmailAddressConflictError + | NoActiveOrderError + +union RegisterCustomerAccountResult = + Success + | MissingPasswordError + | NativeAuthStrategyError + +union RefreshCustomerVerificationResult = Success | NativeAuthStrategyError + +union VerifyCustomerAccountResult = + CurrentUser + | VerificationTokenInvalidError + | VerificationTokenExpiredError + | MissingPasswordError + | PasswordAlreadySetError + | NativeAuthStrategyError + +union UpdateCustomerPasswordResult = + Success + | InvalidCredentialsError + | NativeAuthStrategyError + +union RequestUpdateCustomerEmailAddressResult = + Success + | InvalidCredentialsError + | EmailAddressConflictError + | NativeAuthStrategyError + +union UpdateCustomerEmailAddressResult = + Success + | IdentifierChangeTokenInvalidError + | IdentifierChangeTokenExpiredError + | NativeAuthStrategyError + +union RequestPasswordResetResult = Success | NativeAuthStrategyError + +union ResetPasswordResult = + CurrentUser + | PasswordResetTokenInvalidError + | PasswordResetTokenExpiredError + | NativeAuthStrategyError + +union NativeAuthenticationResult = + CurrentUser + | InvalidCredentialsError + | NotVerifiedError + | NativeAuthStrategyError + +union AuthenticationResult = + CurrentUser + | InvalidCredentialsError + | NotVerifiedError + +union ActiveOrderResult = Order | NoActiveOrderError + +input CollectionListOptions { + skip: Int + take: Int + sort: CollectionSortParameter + filter: CollectionFilterParameter +} + +input ProductListOptions { + skip: Int + take: Int + sort: ProductSortParameter + filter: ProductFilterParameter +} + +input ProductVariantListOptions { + skip: Int + take: Int + sort: ProductVariantSortParameter + filter: ProductVariantFilterParameter +} + +input CustomerListOptions { + skip: Int + take: Int + sort: CustomerSortParameter + filter: CustomerFilterParameter +} + +input OrderListOptions { + skip: Int + take: Int + sort: OrderSortParameter + filter: OrderFilterParameter +} + +input HistoryEntryListOptions { + skip: Int + take: Int + sort: HistoryEntrySortParameter + filter: HistoryEntryFilterParameter +} + +input CollectionFilterParameter { + createdAt: DateOperators + updatedAt: DateOperators + languageCode: StringOperators + name: StringOperators + slug: StringOperators + position: NumberOperators + description: StringOperators +} + +input CollectionSortParameter { + id: SortOrder + createdAt: SortOrder + updatedAt: SortOrder + name: SortOrder + slug: SortOrder + position: SortOrder + description: SortOrder +} + +input ProductFilterParameter { + createdAt: DateOperators + updatedAt: DateOperators + languageCode: StringOperators + name: StringOperators + slug: StringOperators + description: StringOperators +} + +input ProductSortParameter { + id: SortOrder + createdAt: SortOrder + updatedAt: SortOrder + name: SortOrder + slug: SortOrder + description: SortOrder +} + +input ProductVariantFilterParameter { + createdAt: DateOperators + updatedAt: DateOperators + languageCode: StringOperators + sku: StringOperators + name: StringOperators + price: NumberOperators + currencyCode: StringOperators + priceIncludesTax: BooleanOperators + priceWithTax: NumberOperators + stockLevel: StringOperators +} + +input ProductVariantSortParameter { + id: SortOrder + productId: SortOrder + createdAt: SortOrder + updatedAt: SortOrder + sku: SortOrder + name: SortOrder + price: SortOrder + priceWithTax: SortOrder + stockLevel: SortOrder +} + +input CustomerFilterParameter { + createdAt: DateOperators + updatedAt: DateOperators + title: StringOperators + firstName: StringOperators + lastName: StringOperators + phoneNumber: StringOperators + emailAddress: StringOperators +} + +input CustomerSortParameter { + id: SortOrder + createdAt: SortOrder + updatedAt: SortOrder + title: SortOrder + firstName: SortOrder + lastName: SortOrder + phoneNumber: SortOrder + emailAddress: SortOrder +} + +input OrderFilterParameter { + createdAt: DateOperators + updatedAt: DateOperators + orderPlacedAt: DateOperators + code: StringOperators + state: StringOperators + active: BooleanOperators + totalQuantity: NumberOperators + subTotal: NumberOperators + subTotalWithTax: NumberOperators + currencyCode: StringOperators + shipping: NumberOperators + shippingWithTax: NumberOperators + total: NumberOperators + totalWithTax: NumberOperators +} + +input OrderSortParameter { + id: SortOrder + createdAt: SortOrder + updatedAt: SortOrder + orderPlacedAt: SortOrder + code: SortOrder + state: SortOrder + totalQuantity: SortOrder + subTotal: SortOrder + subTotalWithTax: SortOrder + shipping: SortOrder + shippingWithTax: SortOrder + total: SortOrder + totalWithTax: SortOrder +} + +input HistoryEntryFilterParameter { + createdAt: DateOperators + updatedAt: DateOperators + type: StringOperators +} + +input HistoryEntrySortParameter { + id: SortOrder + createdAt: SortOrder + updatedAt: SortOrder +} + +input UpdateOrderInput { + customFields: JSON +} + +input AuthenticationInput { + native: NativeAuthInput +} + +input NativeAuthInput { + username: String! + password: String! +} diff --git a/framework/vendure/types.ts b/framework/vendure/types.ts new file mode 100644 index 000000000..ed39b5493 --- /dev/null +++ b/framework/vendure/types.ts @@ -0,0 +1,5 @@ +import * as Core from '@commerce/types' + +export interface LineItem extends Core.LineItem { + options?: any[] +} diff --git a/framework/vendure/wishlist/use-add-item.tsx b/framework/vendure/wishlist/use-add-item.tsx new file mode 100644 index 000000000..75f067c3a --- /dev/null +++ b/framework/vendure/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/vendure/wishlist/use-remove-item.tsx b/framework/vendure/wishlist/use-remove-item.tsx new file mode 100644 index 000000000..a2d3a8a05 --- /dev/null +++ b/framework/vendure/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/vendure/wishlist/use-wishlist.tsx b/framework/vendure/wishlist/use-wishlist.tsx new file mode 100644 index 000000000..d2ce9db5b --- /dev/null +++ b/framework/vendure/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) diff --git a/next.config.js b/next.config.js index e17d3e5c4..9d6a29ba1 100644 --- a/next.config.js +++ b/next.config.js @@ -8,6 +8,7 @@ const provider = commerce.provider || getProviderName() const isBC = provider === 'bigcommerce' const isShopify = provider === 'shopify' const isSwell = provider === 'swell' +const isVendure = provider === 'vendure' module.exports = withCommerceConfig({ commerce, @@ -17,7 +18,7 @@ module.exports = withCommerceConfig({ }, rewrites() { return [ - (isBC || isShopify || isSwell) && { + (isBC || isShopify || isSwell || isVendure) && { source: '/checkout', destination: '/api/bigcommerce/checkout', }, @@ -27,6 +28,13 @@ module.exports = withCommerceConfig({ source: '/logout', destination: '/api/bigcommerce/customers/logout?redirect_to=/', }, + // For Vendure, rewrite the local api url to the remote (external) api url. This is required + // to make the session cookies work. + isVendure && + process.env.NEXT_PUBLIC_VENDURE_LOCAL_URL && { + source: `${process.env.NEXT_PUBLIC_VENDURE_LOCAL_URL}/:path*`, + destination: `${process.env.NEXT_PUBLIC_VENDURE_SHOP_API_URL}/:path*`, + }, // Rewrites for /search { source: '/search/designers/:name', diff --git a/package.json b/package.json index 6774c8c73..5a9d40b79 100644 --- a/package.json +++ b/package.json @@ -9,6 +9,7 @@ "prettier-fix": "prettier --write .", "find:unused": "next-unused", "generate": "graphql-codegen", + "generate:vendure": "graphql-codegen --config framework/vendure/codegen.json", "generate:definitions": "node framework/bigcommerce/scripts/generate-definitions.js" }, "sideEffects": false, diff --git a/pages/index.tsx b/pages/index.tsx index 3a84112e5..e0182da08 100644 --- a/pages/index.tsx +++ b/pages/index.tsx @@ -21,15 +21,15 @@ export async function getStaticProps({ preview, }) - const { categories, brands } = await getSiteInfo({ config, preview }) - const { pages } = await getAllPages({ config, preview }) + // const { categories, brands } = await getSiteInfo({ config, preview }) + // const { pages } = await getAllPages({ config, preview }) return { props: { products, - categories, - brands, - pages, + categories: [], + brands: [], + pages: [], }, revalidate: 14400, } diff --git a/tsconfig.json b/tsconfig.json index 9e712fb18..1a6c28831 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/vendure"], + "@framework/*": ["framework/vendure/*"] } }, "include": ["next-env.d.ts", "**/*.d.ts", "**/*.ts", "**/*.tsx", "**/*.js"], diff --git a/yarn.lock b/yarn.lock index 8c96bd2a3..1b1fce30e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3061,21 +3061,6 @@ get-stream@^5.0.0, get-stream@^5.1.0: dependencies: pump "^3.0.0" -glob-base@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/glob-base/-/glob-base-0.3.0.tgz#dbb164f6221b1c0b1ccf82aea328b497df0ea3c4" - integrity sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q= - dependencies: - glob-parent "^2.0.0" - is-glob "^2.0.0" - -glob-parent@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-2.0.0.tgz#81383d72db054fcccf5336daa902f182f6edbb28" - integrity sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg= - dependencies: - is-glob "^2.0.0" - 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" @@ -3511,16 +3496,6 @@ is-date-object@^1.0.1: resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.2.tgz#bda736f2cd8fd06d32844e7743bfa7494c3bfd7e" integrity sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g== -is-dotfile@^1.0.0: - version "1.0.3" - resolved "https://registry.yarnpkg.com/is-dotfile/-/is-dotfile-1.0.3.tgz#a6a2f32ffd2dfb04f5ca25ecd0f6b83cf798a1e1" - integrity sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE= - -is-extglob@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-1.0.0.tgz#ac468177c4943405a092fc8f29760c6ffc6206c0" - integrity sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA= - is-extglob@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" @@ -3550,13 +3525,6 @@ is-glob@4.0.1, is-glob@^4.0.1, is-glob@~4.0.1: dependencies: is-extglob "^2.1.1" -is-glob@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-2.0.1.tgz#d096f926a3ded5600f3fdfd91198cb0888c2d863" - integrity sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM= - dependencies: - is-extglob "^1.0.0" - is-interactive@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-interactive/-/is-interactive-1.0.0.tgz#cea6e6ae5c870a7b0a0004070b7b587e0252912e" @@ -4868,16 +4836,6 @@ parse-filepath@^1.0.2: map-cache "^0.2.0" path-root "^0.1.1" -parse-glob@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/parse-glob/-/parse-glob-3.0.4.tgz#b2c376cfb11f35513badd173ef0bb6e3a388391c" - integrity sha1-ssN2z7EfNVE7rdFz7wu246OIORw= - dependencies: - glob-base "^0.3.0" - is-dotfile "^1.0.0" - is-extglob "^1.0.0" - is-glob "^2.0.0" - parse-json@^5.0.0: version "5.2.0" resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd" From f06fe25625cc47cb9503b77ec785969fa5ffc47e Mon Sep 17 00:00:00 2001 From: B Date: Thu, 27 May 2021 18:15:23 -0300 Subject: [PATCH 242/261] Adding Vendure --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 4e7a1aa1e..4b94441a0 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,7 @@ Demo live at: [demo.vercel.store](https://demo.vercel.store/) - Shopify Demo: https://shopify.vercel.store/ - Swell Demo: https://swell.vercel.store/ - BigCommerce Demo: https://bigcommerce.vercel.store/ +- Vendure Demo: https://vendure.vercel.store ## Features From 60dac1654b517b372eda52440845f74f66fac244 Mon Sep 17 00:00:00 2001 From: B Date: Fri, 28 May 2021 10:24:06 -0300 Subject: [PATCH 243/261] Better Swatch Support (#335) * Better support for swatches * Better support for swatches * Fix glitch for Swatch * Fix glitch for Swatch * Fix glitch for Swatch --- README.md | 3 +- commerce.config.json | 3 +- components/product/Swatch/Swatch.module.css | 53 ++++++++++++++------- components/product/Swatch/Swatch.tsx | 22 +++++---- tsconfig.json | 4 +- 5 files changed, 54 insertions(+), 31 deletions(-) diff --git a/README.md b/README.md index 4b94441a0..8f29734e5 100644 --- a/README.md +++ b/README.md @@ -50,7 +50,8 @@ NEXT_PUBLIC_SHOPIFY_STOREFRONT_ACCESS_TOKEN=xxxxxxxxxxxxxxxxxxxxxxxxxxxx NEXT_PUBLIC_SHOPIFY_STORE_DOMAIN=xxxxxxx.myshopify.com ``` -And change the `tsconfig.json` to resolve to the chosen provider: +And check that the `tsconfig.json` resolves to the chosen provider: + ``` "@framework": ["framework/shopify"], "@framework/*": ["framework/shopify/*"] diff --git a/commerce.config.json b/commerce.config.json index 08ea78814..a0e7afc5d 100644 --- a/commerce.config.json +++ b/commerce.config.json @@ -1,6 +1,5 @@ { "features": { - "wishlist": true, - "customCheckout": false + "wishlist": true } } diff --git a/components/product/Swatch/Swatch.module.css b/components/product/Swatch/Swatch.module.css index 051435afd..ede13267b 100644 --- a/components/product/Swatch/Swatch.module.css +++ b/components/product/Swatch/Swatch.module.css @@ -1,33 +1,52 @@ -.root { +.swatch { + box-sizing: border-box; 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; + margin-right: calc(0.75rem - 1px); + overflow: hidden; +} - & > span { - @apply absolute; - } +.swatch::before, +.swatch::after { + box-sizing: border-box; +} - &:hover { - @apply transform scale-110 bg-hover; - } +.swatch:hover { + @apply transform scale-110 bg-hover; +} + +.swatch > span { + @apply absolute; } .color { @apply text-black transition duration-150 ease-in-out; +} - &:hover { - @apply text-black; - } +.color :hover { + @apply text-black; +} - &.dark, - &.dark:hover { - color: white !important; - } +.color.dark, +.color.dark:hover { + color: white !important; } .active { - &.size { - @apply border-accents-9 border-2; - } + @apply border-accents-9 border-2; + padding-right: 1px; + padding-left: 1px; +} + +.textLabel { + @apply w-auto px-4; + min-width: 3rem; +} + +.active.textLabel { + @apply border-accents-9 border-2; + padding-right: calc(1rem - 1px); + padding-left: calc(1rem - 1px); } diff --git a/components/product/Swatch/Swatch.tsx b/components/product/Swatch/Swatch.tsx index 34244321f..7e8de3e4a 100644 --- a/components/product/Swatch/Swatch.tsx +++ b/components/product/Swatch/Swatch.tsx @@ -4,40 +4,44 @@ import s from './Swatch.module.css' import { Check } from '@components/icons' import Button, { ButtonProps } from '@components/ui/Button' import { isDark } from '@lib/colors' -interface Props { +interface SwatchProps { active?: boolean children?: any className?: string - label?: string variant?: 'size' | 'color' | string color?: string + label?: string | null } -const Swatch: FC & Props> = ({ +const Swatch: FC & SwatchProps> = ({ className, color = '', - label, + label = null, variant = 'size', active, ...props }) => { variant = variant?.toLowerCase() - label = label?.toLowerCase() - const rootClassName = cn( - s.root, + if (label) { + label = label?.toLowerCase() + } + + const swatchClassName = cn( + s.swatch, { [s.active]: active, [s.size]: variant === 'size', [s.color]: color, [s.dark]: color ? isDark(color) : false, + [s.textLabel]: !color && label && label.length > 3, }, className ) return ( ) } diff --git a/tsconfig.json b/tsconfig.json index 1a6c28831..9e712fb18 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -22,8 +22,8 @@ "@components/*": ["components/*"], "@commerce": ["framework/commerce"], "@commerce/*": ["framework/commerce/*"], - "@framework": ["framework/vendure"], - "@framework/*": ["framework/vendure/*"] + "@framework": ["framework/bigcommerce"], + "@framework/*": ["framework/bigcommerce/*"] } }, "include": ["next-env.d.ts", "**/*.d.ts", "**/*.ts", "**/*.tsx", "**/*.js"], From 925a68a78c24ad18f76b4791b84e8ad6c3f8dce0 Mon Sep 17 00:00:00 2001 From: Michael Bromley Date: Fri, 28 May 2021 16:19:49 +0200 Subject: [PATCH 244/261] Fix vendure variants (#338) * Fix variant selection in Vendure provider * Styling of checkout placeholder in Vendure provider --- framework/vendure/api/checkout/index.ts | 7 +++++-- framework/vendure/product/get-product.ts | 11 +++++++++-- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/framework/vendure/api/checkout/index.ts b/framework/vendure/api/checkout/index.ts index 21083e9b7..08b21f6a9 100644 --- a/framework/vendure/api/checkout/index.ts +++ b/framework/vendure/api/checkout/index.ts @@ -11,8 +11,11 @@ const checkoutApi = async (req: any, res: any, config: any) => { Checkout -
    -

    Checkout not implemented :(

    +
    + + + +

    Checkout not yet implemented :(

    See #64

    diff --git a/framework/vendure/product/get-product.ts b/framework/vendure/product/get-product.ts index 735164ec1..4427707bd 100644 --- a/framework/vendure/product/get-product.ts +++ b/framework/vendure/product/get-product.ts @@ -20,6 +20,9 @@ async function getProduct({ const product = data.product if (product) { + const getOptionGroupName = (id: string): string => { + return product.optionGroups.find((og) => og.id === id)!.name + } return { product: { id: product.id, @@ -33,9 +36,13 @@ async function getProduct({ variants: product.variants.map((v) => ({ id: v.id, options: v.options.map((o) => ({ + // This __typename property is required in order for the correct + // variant selection to work, see `components/product/helpers.ts` + // `getVariant()` function. + __typename: 'MultipleChoiceOption', id: o.id, - displayName: o.name, - values: o.group.options.map((_o) => ({ label: _o.name })), + displayName: getOptionGroupName(o.groupId), + values: [{ label: o.name }], })), })), price: { From 84a72718d2bdc5b370cf06536e3f494b6d0f90e8 Mon Sep 17 00:00:00 2001 From: ghoskin Date: Fri, 28 May 2021 08:28:45 -0700 Subject: [PATCH 245/261] fix update cart item (#333) Co-authored-by: Greg Hoskin --- framework/swell/cart/use-update-item.tsx | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/framework/swell/cart/use-update-item.tsx b/framework/swell/cart/use-update-item.tsx index e4261fc85..b1031b2e7 100644 --- a/framework/swell/cart/use-update-item.tsx +++ b/framework/swell/cart/use-update-item.tsx @@ -67,9 +67,10 @@ export const handler = { return useCallback( debounce(async (input: UpdateItemInput) => { - const itemId = cartData.lineItems[0].id - const productId = cartData.lineItems[0].productId - const variantId = cartData.lineItems[0].variant.id + const firstLineItem = cartData.lineItems[0] + const itemId = item?.id || firstLineItem.id + const productId = item?.productId || firstLineItem.productId + const variantId = item?.variant.id || firstLineItem.variant.id if (!itemId || !productId) { throw new ValidationError({ message: 'Invalid input used for this operation', From 1bc721de8313c15b837280a0a2e37c605af74560 Mon Sep 17 00:00:00 2001 From: B Date: Mon, 31 May 2021 19:44:08 -0300 Subject: [PATCH 246/261] Improved Categories (#339) * Improved Categories * Improved Categories * Improved Categories * Improved Categories * Improved Categories * Improved Categories --- components/common/Layout/Layout.tsx | 15 +++++++---- components/common/Navbar/Navbar.tsx | 26 ++++++++++++------- framework/bigcommerce/common/get-site-info.ts | 19 +++++++++++--- framework/bigcommerce/product/use-search.tsx | 2 +- framework/commerce/types.ts | 9 +++++++ framework/shopify/common/get-site-info.ts | 6 ++--- framework/shopify/utils/get-categories.ts | 12 +++------ framework/swell/common/get-site-info.ts | 4 +-- framework/swell/utils/get-categories.ts | 12 +++------ framework/vendure/common/get-site-info.ts | 8 +----- lib/defaults.ts | 14 ---------- pages/[...pages].tsx | 6 ++--- pages/cart.tsx | 4 ++- pages/index.tsx | 14 ++++------ pages/orders.tsx | 7 +++-- pages/product/[slug].tsx | 3 +++ pages/profile.tsx | 4 ++- pages/search.tsx | 10 +++---- pages/wishlist.tsx | 7 ++--- 19 files changed, 94 insertions(+), 88 deletions(-) delete mode 100644 lib/defaults.ts diff --git a/components/common/Layout/Layout.tsx b/components/common/Layout/Layout.tsx index 54749c46b..1e1a22967 100644 --- a/components/common/Layout/Layout.tsx +++ b/components/common/Layout/Layout.tsx @@ -8,10 +8,9 @@ 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/CartSidebarView' - +import type { Page, Category } from '@commerce/types' import LoginView from '@components/auth/LoginView' import { CommerceProvider } from '@framework' -import type { Page } from '@framework/common/get-all-pages' const Loading = () => (
    @@ -41,13 +40,13 @@ const FeatureBar = dynamic( interface Props { pageProps: { pages?: Page[] - commerceFeatures: Record + categories: Category[] } } const Layout: FC = ({ children, - pageProps: { commerceFeatures, ...pageProps }, + pageProps: { categories = [], ...pageProps }, }) => { const { displaySidebar, @@ -58,10 +57,16 @@ const Layout: FC = ({ } = useUI() const { acceptedCookies, onAcceptCookies } = useAcceptCookies() const { locale = 'en-US' } = useRouter() + + const navBarlinks = categories.slice(0, 2).map((c) => ({ + label: c.name, + href: `/search/${c.slug}`, + })) + return (
    - +
    {children}
    diff --git a/components/common/Navbar/Navbar.tsx b/components/common/Navbar/Navbar.tsx index fcf9f1e10..aa49993f3 100644 --- a/components/common/Navbar/Navbar.tsx +++ b/components/common/Navbar/Navbar.tsx @@ -5,7 +5,15 @@ import { Searchbar, UserNav } from '@components/common' import NavbarRoot from './NavbarRoot' import s from './Navbar.module.css' -const Navbar: FC = () => ( +interface Link { + href: string + label: string +} +interface NavbarProps { + links?: Link[] +} + +const Navbar: FC = ({ links }) => (
    @@ -19,15 +27,13 @@ const Navbar: FC = () => ( All - - Clothes - - - Accessories - - - Shoes - + {links + ? links.map((l) => ( + + {l.label} + + )) + : null}
    diff --git a/framework/bigcommerce/common/get-site-info.ts b/framework/bigcommerce/common/get-site-info.ts index 80cde8d82..a39608d38 100644 --- a/framework/bigcommerce/common/get-site-info.ts +++ b/framework/bigcommerce/common/get-site-info.ts @@ -3,6 +3,8 @@ 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' +import { Category } from '@commerce/types' +import getSlug from '@lib/get-slug' // Get 3 levels of categories export const getSiteInfoQuery = /* GraphQL */ ` @@ -56,7 +58,7 @@ export type Brands = BrandEdge[] export type GetSiteInfoResult< T extends { categories: any[]; brands: any[] } = { - categories: CategoriesTree + categories: Category[] brands: Brands } > = T @@ -68,7 +70,7 @@ async function getSiteInfo(opts?: { }): Promise async function getSiteInfo< - T extends { categories: any[]; brands: any[] }, + T extends { categories: Category[]; brands: any[] }, V = any >(opts: { query: string @@ -94,11 +96,20 @@ async function getSiteInfo({ query, { variables } ) - const categories = data.site?.categoryTree + + let categories = data!.site!.categoryTree?.map( + ({ entityId, name, path }: any) => ({ + id: `${entityId}`, + name, + slug: getSlug(path), + path, + }) + ) + const brands = data.site?.brands?.edges return { - categories: (categories as RecursiveRequired) ?? [], + categories: categories ?? [], brands: filterEdges(brands as RecursiveRequired), } } diff --git a/framework/bigcommerce/product/use-search.tsx b/framework/bigcommerce/product/use-search.tsx index 0ee135032..ff0ed848c 100644 --- a/framework/bigcommerce/product/use-search.tsx +++ b/framework/bigcommerce/product/use-search.tsx @@ -6,7 +6,7 @@ export default useSearch as UseSearch export type SearchProductsInput = { search?: string - categoryId?: number + categoryId?: number | string brandId?: number sort?: string } diff --git a/framework/commerce/types.ts b/framework/commerce/types.ts index 86361fd9f..62ce4de0a 100644 --- a/framework/commerce/types.ts +++ b/framework/commerce/types.ts @@ -151,6 +151,15 @@ export type RemoveCartItemHandlerBody = Partial & { cartId?: string } +export type Category = { + id: string + name: string + slug: string + path: string +} + +export type Page = any + /** * Temporal types */ diff --git a/framework/shopify/common/get-site-info.ts b/framework/shopify/common/get-site-info.ts index cbbacf5b6..f9e67b5de 100644 --- a/framework/shopify/common/get-site-info.ts +++ b/framework/shopify/common/get-site-info.ts @@ -1,7 +1,7 @@ -import getCategories, { Category } from '../utils/get-categories' -import getVendors, { Brands } from '../utils/get-vendors' - +import { Category } from '@commerce/types' import { getConfig, ShopifyConfig } from '../api' +import getCategories from '../utils/get-categories' +import getVendors, { Brands } from '../utils/get-vendors' export type GetSiteInfoResult< T extends { categories: any[]; brands: any[] } = { diff --git a/framework/shopify/utils/get-categories.ts b/framework/shopify/utils/get-categories.ts index cce4b2ad7..3884fe193 100644 --- a/framework/shopify/utils/get-categories.ts +++ b/framework/shopify/utils/get-categories.ts @@ -1,12 +1,7 @@ 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 -} +import { Category } from '@commerce/types' const getCategories = async (config: ShopifyConfig): Promise => { const { data } = await config.fetch(getSiteCollectionsQuery, { @@ -17,9 +12,10 @@ const getCategories = async (config: ShopifyConfig): Promise => { return ( data.collections?.edges?.map( - ({ node: { id: entityId, title: name, handle } }: CollectionEdge) => ({ - entityId, + ({ node: { id, title: name, handle } }: CollectionEdge) => ({ + id, name, + slug: handle, path: `/${handle}`, }) ) ?? [] diff --git a/framework/swell/common/get-site-info.ts b/framework/swell/common/get-site-info.ts index e44d9cc06..c7a06c52e 100644 --- a/framework/swell/common/get-site-info.ts +++ b/framework/swell/common/get-site-info.ts @@ -1,6 +1,6 @@ -import getCategories, { Category } from '../utils/get-categories' +import getCategories from '../utils/get-categories' import getVendors, { Brands } from '../utils/get-vendors' - +import { Category } from '@commerce/types' import { getConfig, SwellConfig } from '../api' export type GetSiteInfoResult< diff --git a/framework/swell/utils/get-categories.ts b/framework/swell/utils/get-categories.ts index 4372dde4e..acf33a5b9 100644 --- a/framework/swell/utils/get-categories.ts +++ b/framework/swell/utils/get-categories.ts @@ -1,17 +1,13 @@ import { SwellConfig } from '../api' - -export type Category = { - entityId: string - name: string - path: string -} +import { Category } from '@commerce/types' const getCategories = async (config: SwellConfig): Promise => { const data = await config.fetch('categories', 'get') return ( - data.results.map(({ id: entityId, name, slug }: any) => ({ - entityId, + data.results.map(({ id, name, slug }: any) => ({ + id, name, + slug, path: `/${slug}`, })) ?? [] ) diff --git a/framework/vendure/common/get-site-info.ts b/framework/vendure/common/get-site-info.ts index 9410c4493..99836c28b 100644 --- a/framework/vendure/common/get-site-info.ts +++ b/framework/vendure/common/get-site-info.ts @@ -2,13 +2,7 @@ import { getConfig, VendureConfig } from '../api' import { GetCollectionsQuery } from '../schema' import { arrayToTree } from '../lib/array-to-tree' import { getCollectionsQuery } from '../lib/queries/get-collections-query' - -export type Category = { - entityId: string - name: string - path: string - productCount: number -} +import { Category } from '@commerce/types' export type GetSiteInfoResult< T extends { categories: any[]; brands: any[] } = { diff --git a/lib/defaults.ts b/lib/defaults.ts deleted file mode 100644 index e74227732..000000000 --- a/lib/defaults.ts +++ /dev/null @@ -1,14 +0,0 @@ -// Fallback to CMS Data - -export const defaultPageProps = { - header: { - links: [ - { - link: { - title: 'New Arrivals', - url: '/', - }, - }, - ], - }, -} diff --git a/pages/[...pages].tsx b/pages/[...pages].tsx index 3f39845b5..eae7dca39 100644 --- a/pages/[...pages].tsx +++ b/pages/[...pages].tsx @@ -10,7 +10,7 @@ import { missingLocaleInPages } from '@lib/usage-warns' import { getConfig } from '@framework/api' import getPage from '@framework/common/get-page' import getAllPages from '@framework/common/get-all-pages' -import { defaultPageProps } from '@lib/defaults' +import getSiteInfo from '@framework/common/get-site-info' export async function getStaticProps({ preview, @@ -19,9 +19,9 @@ export async function getStaticProps({ }: GetStaticPropsContext<{ pages: string[] }>) { const config = getConfig({ locale }) const { pages } = await getAllPages({ preview, config }) + const { categories } = await getSiteInfo({ config, preview }) const path = params?.pages.join('/') const slug = locale ? `${locale}/${path}` : path - const pageItem = pages.find((p) => (p.url ? getSlug(p.url) === slug : false)) const data = pageItem && @@ -34,7 +34,7 @@ export async function getStaticProps({ } return { - props: { ...defaultPageProps, pages, page }, + props: { pages, page, categories }, revalidate: 60 * 60, // Every hour } } diff --git a/pages/cart.tsx b/pages/cart.tsx index cd5bedacc..c8deb1a02 100644 --- a/pages/cart.tsx +++ b/pages/cart.tsx @@ -7,15 +7,17 @@ import { Layout } from '@components/common' import { Button, Text } from '@components/ui' import { Bag, Cross, Check, MapPin, CreditCard } from '@components/icons' import { CartItem } from '@components/cart' +import getSiteInfo from '@framework/common/get-site-info' export async function getStaticProps({ preview, locale, }: GetStaticPropsContext) { const config = getConfig({ locale }) + const { categories } = await getSiteInfo({ config, preview }) const { pages } = await getAllPages({ config, preview }) return { - props: { pages }, + props: { pages, categories }, } } diff --git a/pages/index.tsx b/pages/index.tsx index e0182da08..4f65a93c8 100644 --- a/pages/index.tsx +++ b/pages/index.tsx @@ -1,9 +1,8 @@ import { Layout } from '@components/common' -import { Grid, Marquee, Hero } from '@components/ui' 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/product/get-all-products' import getSiteInfo from '@framework/common/get-site-info' @@ -14,6 +13,8 @@ export async function getStaticProps({ locale, }: GetStaticPropsContext) { const config = getConfig({ locale }) + const { pages } = await getAllPages({ config, preview }) + const { categories } = await getSiteInfo({ config, preview }) const { products } = await getAllProducts({ variables: { first: 12 }, @@ -21,15 +22,12 @@ export async function getStaticProps({ preview, }) - // const { categories, brands } = await getSiteInfo({ config, preview }) - // const { pages } = await getAllPages({ config, preview }) - return { props: { products, - categories: [], + categories, brands: [], - pages: [], + pages, }, revalidate: 14400, } @@ -37,8 +35,6 @@ export async function getStaticProps({ export default function Home({ products, - brands, - categories, }: InferGetStaticPropsType) { return ( <> diff --git a/pages/orders.tsx b/pages/orders.tsx index db4ab55b2..ee93f3f7f 100644 --- a/pages/orders.tsx +++ b/pages/orders.tsx @@ -1,18 +1,21 @@ import type { GetStaticPropsContext } from 'next' import { Bag } from '@components/icons' +import { getConfig } from '@framework/api' import { Layout } from '@components/common' import { Container, Text } from '@components/ui' -import { getConfig } from '@framework/api' import getAllPages from '@framework/common/get-all-pages' +import getSiteInfo from '@framework/common/get-site-info' export async function getStaticProps({ preview, locale, }: GetStaticPropsContext) { const config = getConfig({ locale }) + const { categories } = await getSiteInfo({ config, preview }) const { pages } = await getAllPages({ config, preview }) + return { - props: { pages }, + props: { pages, categories }, } } diff --git a/pages/product/[slug].tsx b/pages/product/[slug].tsx index 61420a8d9..ac55dc4be 100644 --- a/pages/product/[slug].tsx +++ b/pages/product/[slug].tsx @@ -11,6 +11,7 @@ import { getConfig } from '@framework/api' import getProduct from '@framework/product/get-product' import getAllPages from '@framework/common/get-all-pages' import getAllProductPaths from '@framework/product/get-all-product-paths' +import getSiteInfo from '@framework/common/get-site-info' export async function getStaticProps({ params, @@ -24,6 +25,7 @@ export async function getStaticProps({ config, preview, }) + const { categories } = await getSiteInfo({ config, preview }) if (!product) { throw new Error(`Product with slug '${params!.slug}' not found`) @@ -33,6 +35,7 @@ export async function getStaticProps({ props: { pages, product, + categories, }, revalidate: 200, } diff --git a/pages/profile.tsx b/pages/profile.tsx index ec845c879..b1e8e6628 100644 --- a/pages/profile.tsx +++ b/pages/profile.tsx @@ -4,15 +4,17 @@ 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' +import getSiteInfo from '@framework/common/get-site-info' export async function getStaticProps({ preview, locale, }: GetStaticPropsContext) { const config = getConfig({ locale }) + const { categories } = await getSiteInfo({ config, preview }) const { pages } = await getAllPages({ config, preview }) return { - props: { pages }, + props: { pages, categories }, } } diff --git a/pages/search.tsx b/pages/search.tsx index 78f784572..9a0330127 100644 --- a/pages/search.tsx +++ b/pages/search.tsx @@ -13,12 +13,9 @@ import useSearch from '@framework/product/use-search' import getAllPages from '@framework/common/get-all-pages' import getSiteInfo from '@framework/common/get-site-info' +import getSlug from '@lib/get-slug' 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', @@ -75,7 +72,7 @@ export default function Search({ const { data } = useSearch({ search: typeof q === 'string' ? q : '', - categoryId: activeCategory?.entityId, + categoryId: activeCategory?.id, brandId: (activeBrand as any)?.entityId, sort: typeof sort === 'string' ? sort : '', }) @@ -164,8 +161,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', { - underline: - activeCategory?.entityId === cat.entityId, + underline: activeCategory?.id === cat.id, } )} > diff --git a/pages/wishlist.tsx b/pages/wishlist.tsx index 0dddaf23d..0e6732ae2 100644 --- a/pages/wishlist.tsx +++ b/pages/wishlist.tsx @@ -1,13 +1,13 @@ import type { GetStaticPropsContext } from 'next' import { Heart } from '@components/icons' +import { getConfig } from '@framework/api' import { Layout } from '@components/common' import { Text, Container } from '@components/ui' -import { defaultPageProps } from '@lib/defaults' -import { getConfig } from '@framework/api' import { useCustomer } from '@framework/customer' import { WishlistCard } from '@components/wishlist' import useWishlist from '@framework/wishlist/use-wishlist' import getAllPages from '@framework/common/get-all-pages' +import getSiteInfo from '@framework/common/get-site-info' export async function getStaticProps({ preview, @@ -21,11 +21,12 @@ export async function getStaticProps({ } const config = getConfig({ locale }) + const { categories } = await getSiteInfo({ config, preview }) const { pages } = await getAllPages({ config, preview }) return { props: { pages, - ...defaultPageProps, + categories, }, } } From d71646a60d8a1b40c8bae76ff1570ead8df9d1fc Mon Sep 17 00:00:00 2001 From: John Vandivier Date: Mon, 31 May 2021 22:31:16 -0400 Subject: [PATCH 247/261] feat: concise card code (#348) --- pages/index.tsx | 20 ++------------------ 1 file changed, 2 insertions(+), 18 deletions(-) diff --git a/pages/index.tsx b/pages/index.tsx index 4f65a93c8..3a466c606 100644 --- a/pages/index.tsx +++ b/pages/index.tsx @@ -52,15 +52,7 @@ export default function Home({ {products.slice(0, 3).map((product, i) => ( - + ))} {products.slice(0, 3).map((product, i) => ( - + ))} {/* Date: Mon, 31 May 2021 23:32:10 -0300 Subject: [PATCH 248/261] Update next.config.js filter (#329) Its a little more explicit using boolean than x => x --- next.config.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/next.config.js b/next.config.js index 9d6a29ba1..b1e48cf1e 100644 --- a/next.config.js +++ b/next.config.js @@ -49,7 +49,7 @@ module.exports = withCommerceConfig({ source: '/search/:category', destination: '/search', }, - ].filter((x) => x) + ].filter(Boolean) }, }) From 0792eabd4cb2b911e7604c5545e40f785cd840fd Mon Sep 17 00:00:00 2001 From: cond0r Date: Tue, 1 Jun 2021 05:34:28 +0300 Subject: [PATCH 249/261] Fix missing images (#264) Co-authored-by: B --- components/product/ProductCard/ProductCard.tsx | 4 ++-- components/wishlist/WishlistCard/WishlistCard.tsx | 6 ++++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/components/product/ProductCard/ProductCard.tsx b/components/product/ProductCard/ProductCard.tsx index ade53380c..45a19d2dd 100644 --- a/components/product/ProductCard/ProductCard.tsx +++ b/components/product/ProductCard/ProductCard.tsx @@ -34,7 +34,7 @@ const ProductCard: FC = ({ {product?.images && ( {product.name = ({ {product.name = ({ product }) => { const { price } = usePrice({ amount: product.prices?.price?.value, @@ -58,10 +60,10 @@ const WishlistCard: FC = ({ product }) => {
    {product.images[0].alt
    From a98c95d447942c8966ae4aa56dba75d59d82033c Mon Sep 17 00:00:00 2001 From: Luis Alvarez D Date: Tue, 1 Jun 2021 03:18:10 -0500 Subject: [PATCH 250/261] [WIP] Node.js provider for the API (#252) * Adding multiple initial files * Updated the default cart endpoint * Fixes * Updated CommerceAPI class for better usage * Adding more migration changes * Taking multiple steps into better API types * Adding more experimental types * Removed many testing types * Adding types, fixes and other updates * Updated commerce types * Updated types for hooks now using the API * Updated mutation types * Simplified cart types for the provider * Updated cart hooks * Remove normalizers from the hooks * Updated cart endpoint * Removed cart handlers * bug fixes * Improve quantity input behavior in cart item * Removed endpoints folder * Making progress on api operations * Moved method * Moved types * Changed the way ops are created * Added customer endpoint * Login endpoint * Added logout endpoint * Add missing logout files * Added signup endpoint * Removed customers old endpoints * Moved endpoints to nested folder * Removed old customer endpoint builders * Updated login operation * Updated login operation * Added getAllPages operation * Renamed endpoint operations to handlers * Changed import * Renamed operations to handlers in usage * Moved getAllPages everywhere * Moved getPage * Updated getPage usage * Moved getSiteInfo * Added def types for product * Updated type * moved products catalog endpoint * removed old catalog endpoint * Moved wishlist * Removed commerce.endpoint * Replaced references to commerce.endpoint * Updated catalog products * Moved checkout api * Added the get customer wishlist operation * Removed old wishlist stuff * Added getAllProductPaths operation * updated reference to operation * Moved getAllProducts * Updated getProduct operation * Removed old getConfig and references * Removed is-allowed-method from BC * Updated types for auth hooks * Updated useCustomer and core types * Updated useData and util hooks * Updated useSearch hook * Updated types for useWishlist * Added index for types * Fixes * Updated urls to the API * Renamed fetchInput to fetcherInput * Updated fetch type * Fixes in search hook * Updated Shopify Provider Structure (#340) * Add codegen, update fragments & schemas * Update checkout-create.ts * Update checkout-create.ts * Update README.md * Update product mutations & queries * Uptate customer fetch types * Update schemas * Start updates * Moved Page, AllPages & Site Info * Moved product, all products (paths) * Add translations, update operations & fixes * Update api endpoints, types & fixes * Add api checkout endpoint * Updates * Fixes * Update commerce.config.json Co-authored-by: B * Added category type and normalizer * updated init script to exclude other providers * Excluded swell and venture temporarily * Fix category & color normalization * Fixed category normalizer in shopify * Don't use getSlug for category on /search * Update colors.ts Co-authored-by: cond0r Co-authored-by: B --- components/cart/CartItem/CartItem.tsx | 10 +- components/common/Footer/Footer.tsx | 2 +- .../HomeAllProductsGrid.tsx | 2 +- components/common/Layout/Layout.tsx | 15 +- components/common/Navbar/Navbar.tsx | 12 +- components/common/UserNav/UserNav.tsx | 2 +- .../product/ProductCard/ProductCard.tsx | 2 +- .../product/ProductView/ProductView.tsx | 9 +- components/product/Swatch/Swatch.tsx | 5 +- components/product/helpers.ts | 2 +- .../WishlistButton/WishlistButton.tsx | 2 +- .../wishlist/WishlistCard/WishlistCard.tsx | 11 +- framework/bigcommerce/api/cart/index.ts | 78 -- framework/bigcommerce/api/catalog/products.ts | 48 -- framework/bigcommerce/api/checkout.ts | 77 -- framework/bigcommerce/api/customers/index.ts | 46 -- framework/bigcommerce/api/customers/login.ts | 45 -- framework/bigcommerce/api/customers/logout.ts | 42 -- framework/bigcommerce/api/customers/signup.ts | 50 -- .../handlers => endpoints/cart}/add-item.ts | 7 +- .../handlers => endpoints/cart}/get-cart.ts | 11 +- .../bigcommerce/api/endpoints/cart/index.ts | 26 + .../cart}/remove-item.ts | 7 +- .../cart}/update-item.ts | 7 +- .../catalog/products}/get-products.ts | 30 +- .../api/endpoints/catalog/products/index.ts | 18 + .../api/endpoints/checkout/checkout.ts | 62 ++ .../api/endpoints/checkout/index.ts | 18 + .../customer}/get-logged-in-customer.ts | 4 +- .../api/endpoints/customer/index.ts | 18 + .../bigcommerce/api/endpoints/login/index.ts | 18 + .../handlers => endpoints/login}/login.ts | 10 +- .../bigcommerce/api/endpoints/logout/index.ts | 18 + .../handlers => endpoints/logout}/logout.ts | 6 +- .../bigcommerce/api/endpoints/signup/index.ts | 18 + .../handlers => endpoints/signup}/signup.ts | 8 +- .../wishlist}/add-item.ts | 13 +- .../wishlist}/get-wishlist.ts | 12 +- .../api/endpoints/wishlist/index.ts | 24 + .../wishlist}/remove-item.ts | 16 +- .../wishlist/utils}/get-customer-id.ts | 12 +- framework/bigcommerce/api/index.ts | 87 ++- .../api/operations/get-all-pages.ts | 46 ++ .../api/operations/get-all-product-paths.ts | 66 ++ .../api/operations/get-all-products.ts | 135 ++++ .../api/operations/get-customer-wishlist.ts | 81 ++ .../bigcommerce/api/operations/get-page.ts | 54 ++ .../bigcommerce/api/operations/get-product.ts | 119 +++ .../api/operations/get-site-info.ts | 87 +++ framework/bigcommerce/api/operations/login.ts | 79 ++ .../api/utils/create-api-handler.ts | 58 -- .../api/utils/fetch-graphql-api.ts | 4 +- .../bigcommerce/api/utils/fetch-store-api.ts | 4 +- .../api/utils/is-allowed-method.ts | 28 - framework/bigcommerce/api/utils/parse-item.ts | 4 +- .../api/utils/set-product-locale-meta.ts | 2 +- framework/bigcommerce/api/wishlist/index.ts | 104 --- framework/bigcommerce/auth/login.ts | 73 -- framework/bigcommerce/auth/use-login.tsx | 6 +- framework/bigcommerce/auth/use-logout.tsx | 5 +- framework/bigcommerce/auth/use-signup.tsx | 6 +- framework/bigcommerce/cart/use-add-item.tsx | 16 +- framework/bigcommerce/cart/use-cart.tsx | 18 +- .../bigcommerce/cart/use-remove-item.tsx | 37 +- .../bigcommerce/cart/use-update-item.tsx | 33 +- framework/bigcommerce/common/get-all-pages.ts | 43 -- framework/bigcommerce/common/get-page.ts | 53 -- framework/bigcommerce/common/get-site-info.ts | 117 --- .../customer/get-customer-wishlist.ts | 88 --- .../bigcommerce/customer/use-customer.tsx | 8 +- framework/bigcommerce/lib/get-slug.ts | 5 + framework/bigcommerce/lib/normalize.ts | 27 +- .../product/get-all-product-paths.ts | 71 -- .../bigcommerce/product/get-all-products.ts | 135 ---- framework/bigcommerce/product/get-product.ts | 121 --- framework/bigcommerce/product/index.ts | 2 - framework/bigcommerce/product/use-search.tsx | 15 +- .../bigcommerce/{types.ts => types/cart.ts} | 40 +- framework/bigcommerce/types/checkout.ts | 1 + framework/bigcommerce/types/common.ts | 1 + framework/bigcommerce/types/customer.ts | 5 + framework/bigcommerce/types/index.ts | 25 + framework/bigcommerce/types/login.ts | 8 + framework/bigcommerce/types/logout.ts | 1 + framework/bigcommerce/types/page.ts | 11 + framework/bigcommerce/types/product.ts | 1 + framework/bigcommerce/types/signup.ts | 1 + framework/bigcommerce/types/site.ts | 19 + framework/bigcommerce/types/wishlist.ts | 23 + .../bigcommerce/wishlist/use-add-item.tsx | 6 +- .../bigcommerce/wishlist/use-remove-item.tsx | 14 +- .../bigcommerce/wishlist/use-wishlist.tsx | 13 +- framework/commerce/api/endpoints/cart.ts | 62 ++ .../api/endpoints/catalog/products.ts | 31 + framework/commerce/api/endpoints/checkout.ts | 35 + framework/commerce/api/endpoints/customer.ts | 35 + framework/commerce/api/endpoints/login.ts | 35 + framework/commerce/api/endpoints/logout.ts | 37 + framework/commerce/api/endpoints/signup.ts | 38 + framework/commerce/api/endpoints/wishlist.ts | 58 ++ framework/commerce/api/index.ts | 147 ++++ framework/commerce/api/operations.ts | 177 +++++ framework/commerce/api/utils/errors.ts | 22 + .../api/utils/is-allowed-method.ts | 4 +- .../api/utils/is-allowed-operation.ts | 19 + framework/commerce/api/utils/types.ts | 49 ++ framework/commerce/auth/use-login.tsx | 5 +- framework/commerce/auth/use-logout.tsx | 5 +- framework/commerce/auth/use-signup.tsx | 5 +- framework/commerce/cart/use-add-item.tsx | 9 +- framework/commerce/cart/use-cart.tsx | 19 +- framework/commerce/cart/use-remove-item.tsx | 21 +- framework/commerce/cart/use-update-item.tsx | 24 +- framework/commerce/config.js | 13 + framework/commerce/customer/use-customer.tsx | 8 +- framework/commerce/index.tsx | 39 +- framework/commerce/new-provider.md | 4 +- framework/commerce/product/use-search.tsx | 8 +- framework/commerce/types.ts | 213 ------ framework/commerce/types/cart.ts | 179 +++++ framework/commerce/types/checkout.ts | 10 + framework/commerce/types/common.ts | 16 + framework/commerce/types/customer.ts | 22 + framework/commerce/types/index.ts | 25 + framework/commerce/types/login.ts | 29 + framework/commerce/types/logout.ts | 17 + framework/commerce/types/page.ts | 28 + framework/commerce/types/product.ts | 99 +++ framework/commerce/types/signup.ts | 26 + framework/commerce/types/site.ts | 20 + framework/commerce/types/wishlist.ts | 60 ++ framework/commerce/utils/default-fetcher.ts | 4 +- framework/commerce/utils/types.ts | 109 +-- framework/commerce/utils/use-data.tsx | 13 +- framework/commerce/utils/use-hook.ts | 6 +- framework/commerce/wishlist/use-add-item.tsx | 3 +- .../commerce/wishlist/use-remove-item.tsx | 18 +- framework/commerce/wishlist/use-wishlist.tsx | 15 +- framework/shopify/README.md | 12 + framework/shopify/api/cart/index.ts | 1 - framework/shopify/api/catalog/index.ts | 1 - framework/shopify/api/catalog/products.ts | 1 - framework/shopify/api/customer.ts | 1 - framework/shopify/api/customers/index.ts | 1 - framework/shopify/api/customers/login.ts | 1 - framework/shopify/api/customers/logout.ts | 1 - framework/shopify/api/customers/signup.ts | 1 - framework/shopify/api/endpoints/cart.ts | 1 + .../shopify/api/endpoints/catalog/products.ts | 1 + .../checkout/checkout.ts} | 26 +- .../shopify/api/endpoints/checkout/index.ts | 18 + framework/shopify/api/endpoints/customer.ts | 1 + framework/shopify/api/endpoints/login.ts | 1 + framework/shopify/api/endpoints/logout.ts | 1 + framework/shopify/api/endpoints/signup.ts | 1 + framework/shopify/api/endpoints/wishlist.ts | 1 + framework/shopify/api/index.ts | 64 +- .../shopify/api/operations/get-all-pages.ts | 67 ++ .../api/operations/get-all-product-paths.ts | 55 ++ .../api/operations/get-all-products.ts | 67 ++ framework/shopify/api/operations/get-page.ts | 64 ++ .../shopify/api/operations/get-product.ts | 63 ++ .../shopify/api/operations/get-site-info.ts | 62 ++ framework/shopify/api/operations/index.ts | 7 + framework/shopify/api/operations/login.ts | 48 ++ .../shopify/api/utils/create-api-handler.ts | 58 -- .../shopify/api/utils/fetch-all-products.ts | 41 - framework/shopify/api/wishlist/index.tsx | 2 - framework/shopify/auth/use-login.tsx | 35 +- framework/shopify/auth/use-logout.tsx | 3 +- framework/shopify/auth/use-signup.tsx | 23 +- framework/shopify/cart/use-add-item.tsx | 5 +- framework/shopify/cart/use-cart.tsx | 20 +- framework/shopify/cart/use-remove-item.tsx | 36 +- framework/shopify/cart/use-update-item.tsx | 28 +- framework/shopify/codegen.json | 32 + framework/shopify/common/get-all-pages.ts | 42 -- framework/shopify/common/get-page.ts | 37 - framework/shopify/common/get-site-info.ts | 31 - framework/shopify/customer/get-customer-id.ts | 24 - framework/shopify/customer/use-customer.tsx | 7 +- framework/shopify/fetcher.ts | 6 +- framework/shopify/index.tsx | 2 +- .../shopify/product/get-all-collections.ts | 29 - .../shopify/product/get-all-product-paths.ts | 41 - framework/shopify/product/get-all-products.ts | 39 - framework/shopify/product/get-product.ts | 31 - framework/shopify/product/use-search.tsx | 77 +- framework/shopify/schema.d.ts | 713 ++++++++++++++++-- framework/shopify/schema.graphql | 275 ++++--- framework/shopify/types.ts | 43 -- framework/shopify/types/cart.ts | 32 + framework/shopify/types/checkout.ts | 1 + framework/shopify/types/common.ts | 1 + framework/shopify/types/customer.ts | 5 + framework/shopify/types/index.ts | 25 + framework/shopify/types/login.ts | 8 + framework/shopify/types/logout.ts | 1 + framework/shopify/types/page.ts | 11 + framework/shopify/types/product.ts | 1 + framework/shopify/types/signup.ts | 1 + framework/shopify/types/site.ts | 1 + framework/shopify/types/wishlist.ts | 1 + framework/shopify/utils/checkout-to-cart.ts | 8 +- .../utils/{get-vendors.ts => get-brands.ts} | 18 +- framework/shopify/utils/get-categories.ts | 35 +- .../shopify/utils/get-search-variables.ts | 12 +- framework/shopify/utils/index.ts | 2 +- .../utils/mutations/checkout-create.ts | 8 +- .../utils/mutations/checkout-line-item-add.ts | 9 +- .../mutations/checkout-line-item-remove.ts | 5 +- .../mutations/checkout-line-item-update.ts | 9 +- framework/shopify/utils/normalize.ts | 107 ++- .../utils/queries/get-all-products-query.ts | 79 +- .../utils/queries/get-checkout-query.ts | 103 +-- .../queries/get-collection-products-query.ts | 11 +- .../shopify/utils/queries/get-page-query.ts | 2 +- .../utils/queries/get-product-query.ts | 3 + .../utils/queries/get-site-info-query.ts | 8 + framework/shopify/utils/queries/index.ts | 1 + lib/api/commerce.ts | 3 + lib/colors.ts | 6 +- next.config.js | 4 +- package.json | 1 + pages/[...pages].tsx | 21 +- pages/api/bigcommerce/cart.ts | 3 - pages/api/bigcommerce/catalog/products.ts | 3 - pages/api/bigcommerce/checkout.ts | 3 - pages/api/bigcommerce/customers/index.ts | 3 - pages/api/bigcommerce/customers/login.ts | 3 - pages/api/bigcommerce/customers/logout.ts | 3 - pages/api/bigcommerce/customers/signup.ts | 3 - pages/api/bigcommerce/wishlist.ts | 3 - pages/api/cart.ts | 4 + pages/api/catalog/products.ts | 4 + pages/api/checkout.ts | 4 + pages/api/customer.ts | 4 + pages/api/login.ts | 4 + pages/api/logout.ts | 4 + pages/api/signup.ts | 4 + pages/api/wishlist.ts | 4 + pages/cart.tsx | 11 +- pages/index.tsx | 17 +- pages/orders.tsx | 11 +- pages/product/[slug].tsx | 22 +- pages/profile.tsx | 12 +- pages/search.tsx | 39 +- pages/wishlist.tsx | 12 +- tsconfig.json | 6 +- 249 files changed, 4646 insertions(+), 2981 deletions(-) delete mode 100644 framework/bigcommerce/api/cart/index.ts delete mode 100644 framework/bigcommerce/api/catalog/products.ts delete mode 100644 framework/bigcommerce/api/checkout.ts delete mode 100644 framework/bigcommerce/api/customers/index.ts delete mode 100644 framework/bigcommerce/api/customers/login.ts delete mode 100644 framework/bigcommerce/api/customers/logout.ts delete mode 100644 framework/bigcommerce/api/customers/signup.ts rename framework/bigcommerce/api/{cart/handlers => endpoints/cart}/add-item.ts (82%) rename framework/bigcommerce/api/{cart/handlers => endpoints/cart}/get-cart.ts (69%) create mode 100644 framework/bigcommerce/api/endpoints/cart/index.ts rename framework/bigcommerce/api/{cart/handlers => endpoints/cart}/remove-item.ts (77%) rename framework/bigcommerce/api/{cart/handlers => endpoints/cart}/update-item.ts (77%) rename framework/bigcommerce/api/{catalog/handlers => endpoints/catalog/products}/get-products.ts (68%) create mode 100644 framework/bigcommerce/api/endpoints/catalog/products/index.ts create mode 100644 framework/bigcommerce/api/endpoints/checkout/checkout.ts create mode 100644 framework/bigcommerce/api/endpoints/checkout/index.ts rename framework/bigcommerce/api/{customers/handlers => endpoints/customer}/get-logged-in-customer.ts (89%) create mode 100644 framework/bigcommerce/api/endpoints/customer/index.ts create mode 100644 framework/bigcommerce/api/endpoints/login/index.ts rename framework/bigcommerce/api/{customers/handlers => endpoints/login}/login.ts (81%) create mode 100644 framework/bigcommerce/api/endpoints/logout/index.ts rename framework/bigcommerce/api/{customers/handlers => endpoints/logout}/logout.ts (74%) create mode 100644 framework/bigcommerce/api/endpoints/signup/index.ts rename framework/bigcommerce/api/{customers/handlers => endpoints/signup}/signup.ts (88%) rename framework/bigcommerce/api/{wishlist/handlers => endpoints/wishlist}/add-item.ts (76%) rename framework/bigcommerce/api/{wishlist/handlers => endpoints/wishlist}/get-wishlist.ts (64%) create mode 100644 framework/bigcommerce/api/endpoints/wishlist/index.ts rename framework/bigcommerce/api/{wishlist/handlers => endpoints/wishlist}/remove-item.ts (63%) rename framework/bigcommerce/{customer => api/endpoints/wishlist/utils}/get-customer-id.ts (65%) create mode 100644 framework/bigcommerce/api/operations/get-all-pages.ts create mode 100644 framework/bigcommerce/api/operations/get-all-product-paths.ts create mode 100644 framework/bigcommerce/api/operations/get-all-products.ts create mode 100644 framework/bigcommerce/api/operations/get-customer-wishlist.ts create mode 100644 framework/bigcommerce/api/operations/get-page.ts create mode 100644 framework/bigcommerce/api/operations/get-product.ts create mode 100644 framework/bigcommerce/api/operations/get-site-info.ts create mode 100644 framework/bigcommerce/api/operations/login.ts delete mode 100644 framework/bigcommerce/api/utils/create-api-handler.ts delete mode 100644 framework/bigcommerce/api/utils/is-allowed-method.ts delete mode 100644 framework/bigcommerce/api/wishlist/index.ts delete mode 100644 framework/bigcommerce/auth/login.ts delete mode 100644 framework/bigcommerce/common/get-all-pages.ts delete mode 100644 framework/bigcommerce/common/get-page.ts delete mode 100644 framework/bigcommerce/common/get-site-info.ts delete mode 100644 framework/bigcommerce/customer/get-customer-wishlist.ts create mode 100644 framework/bigcommerce/lib/get-slug.ts delete mode 100644 framework/bigcommerce/product/get-all-product-paths.ts delete mode 100644 framework/bigcommerce/product/get-all-products.ts delete mode 100644 framework/bigcommerce/product/get-product.ts rename framework/bigcommerce/{types.ts => types/cart.ts} (52%) create mode 100644 framework/bigcommerce/types/checkout.ts create mode 100644 framework/bigcommerce/types/common.ts create mode 100644 framework/bigcommerce/types/customer.ts create mode 100644 framework/bigcommerce/types/index.ts create mode 100644 framework/bigcommerce/types/login.ts create mode 100644 framework/bigcommerce/types/logout.ts create mode 100644 framework/bigcommerce/types/page.ts create mode 100644 framework/bigcommerce/types/product.ts create mode 100644 framework/bigcommerce/types/signup.ts create mode 100644 framework/bigcommerce/types/site.ts create mode 100644 framework/bigcommerce/types/wishlist.ts create mode 100644 framework/commerce/api/endpoints/cart.ts create mode 100644 framework/commerce/api/endpoints/catalog/products.ts create mode 100644 framework/commerce/api/endpoints/checkout.ts create mode 100644 framework/commerce/api/endpoints/customer.ts create mode 100644 framework/commerce/api/endpoints/login.ts create mode 100644 framework/commerce/api/endpoints/logout.ts create mode 100644 framework/commerce/api/endpoints/signup.ts create mode 100644 framework/commerce/api/endpoints/wishlist.ts create mode 100644 framework/commerce/api/operations.ts create mode 100644 framework/commerce/api/utils/errors.ts rename framework/{shopify => commerce}/api/utils/is-allowed-method.ts (85%) create mode 100644 framework/commerce/api/utils/is-allowed-operation.ts create mode 100644 framework/commerce/api/utils/types.ts delete mode 100644 framework/commerce/types.ts create mode 100644 framework/commerce/types/cart.ts create mode 100644 framework/commerce/types/checkout.ts create mode 100644 framework/commerce/types/common.ts create mode 100644 framework/commerce/types/customer.ts create mode 100644 framework/commerce/types/index.ts create mode 100644 framework/commerce/types/login.ts create mode 100644 framework/commerce/types/logout.ts create mode 100644 framework/commerce/types/page.ts create mode 100644 framework/commerce/types/product.ts create mode 100644 framework/commerce/types/signup.ts create mode 100644 framework/commerce/types/site.ts create mode 100644 framework/commerce/types/wishlist.ts delete mode 100644 framework/shopify/api/cart/index.ts delete mode 100644 framework/shopify/api/catalog/index.ts delete mode 100644 framework/shopify/api/catalog/products.ts delete mode 100644 framework/shopify/api/customer.ts delete mode 100644 framework/shopify/api/customers/index.ts delete mode 100644 framework/shopify/api/customers/login.ts delete mode 100644 framework/shopify/api/customers/logout.ts delete mode 100644 framework/shopify/api/customers/signup.ts create mode 100644 framework/shopify/api/endpoints/cart.ts create mode 100644 framework/shopify/api/endpoints/catalog/products.ts rename framework/shopify/api/{checkout/index.ts => endpoints/checkout/checkout.ts} (56%) create mode 100644 framework/shopify/api/endpoints/checkout/index.ts create mode 100644 framework/shopify/api/endpoints/customer.ts create mode 100644 framework/shopify/api/endpoints/login.ts create mode 100644 framework/shopify/api/endpoints/logout.ts create mode 100644 framework/shopify/api/endpoints/signup.ts create mode 100644 framework/shopify/api/endpoints/wishlist.ts create mode 100644 framework/shopify/api/operations/get-all-pages.ts create mode 100644 framework/shopify/api/operations/get-all-product-paths.ts create mode 100644 framework/shopify/api/operations/get-all-products.ts create mode 100644 framework/shopify/api/operations/get-page.ts create mode 100644 framework/shopify/api/operations/get-product.ts create mode 100644 framework/shopify/api/operations/get-site-info.ts create mode 100644 framework/shopify/api/operations/index.ts create mode 100644 framework/shopify/api/operations/login.ts delete mode 100644 framework/shopify/api/utils/create-api-handler.ts delete mode 100644 framework/shopify/api/utils/fetch-all-products.ts delete mode 100644 framework/shopify/api/wishlist/index.tsx create mode 100644 framework/shopify/codegen.json delete mode 100644 framework/shopify/common/get-all-pages.ts delete mode 100644 framework/shopify/common/get-page.ts delete mode 100644 framework/shopify/common/get-site-info.ts delete mode 100644 framework/shopify/customer/get-customer-id.ts delete mode 100644 framework/shopify/product/get-all-collections.ts delete mode 100644 framework/shopify/product/get-all-product-paths.ts delete mode 100644 framework/shopify/product/get-all-products.ts delete mode 100644 framework/shopify/product/get-product.ts delete mode 100644 framework/shopify/types.ts create mode 100644 framework/shopify/types/cart.ts create mode 100644 framework/shopify/types/checkout.ts create mode 100644 framework/shopify/types/common.ts create mode 100644 framework/shopify/types/customer.ts create mode 100644 framework/shopify/types/index.ts create mode 100644 framework/shopify/types/login.ts create mode 100644 framework/shopify/types/logout.ts create mode 100644 framework/shopify/types/page.ts create mode 100644 framework/shopify/types/product.ts create mode 100644 framework/shopify/types/signup.ts create mode 100644 framework/shopify/types/site.ts create mode 100644 framework/shopify/types/wishlist.ts rename framework/shopify/utils/{get-vendors.ts => get-brands.ts} (56%) create mode 100644 framework/shopify/utils/queries/get-site-info-query.ts create mode 100644 lib/api/commerce.ts delete mode 100644 pages/api/bigcommerce/cart.ts delete mode 100644 pages/api/bigcommerce/catalog/products.ts delete mode 100644 pages/api/bigcommerce/checkout.ts delete mode 100644 pages/api/bigcommerce/customers/index.ts delete mode 100644 pages/api/bigcommerce/customers/login.ts delete mode 100644 pages/api/bigcommerce/customers/logout.ts delete mode 100644 pages/api/bigcommerce/customers/signup.ts delete mode 100644 pages/api/bigcommerce/wishlist.ts create mode 100644 pages/api/cart.ts create mode 100644 pages/api/catalog/products.ts create mode 100644 pages/api/checkout.ts create mode 100644 pages/api/customer.ts create mode 100644 pages/api/login.ts create mode 100644 pages/api/logout.ts create mode 100644 pages/api/signup.ts create mode 100644 pages/api/wishlist.ts diff --git a/components/cart/CartItem/CartItem.tsx b/components/cart/CartItem/CartItem.tsx index e6820d32c..bc614722f 100644 --- a/components/cart/CartItem/CartItem.tsx +++ b/components/cart/CartItem/CartItem.tsx @@ -5,7 +5,7 @@ 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 type { LineItem } from '@framework/types' +import type { LineItem } from '@commerce/types/cart' import usePrice from '@framework/product/use-price' import useUpdateItem from '@framework/cart/use-update-item' import useRemoveItem from '@framework/cart/use-remove-item' @@ -35,7 +35,7 @@ const CartItem = ({ const updateItem = useUpdateItem({ item }) const removeItem = useRemoveItem() - const [quantity, setQuantity] = useState(item.quantity) + const [quantity, setQuantity] = useState(item.quantity) const [removing, setRemoving] = useState(false) const updateQuantity = async (val: number) => { @@ -43,10 +43,10 @@ const CartItem = ({ } const handleQuantity = (e: ChangeEvent) => { - const val = Number(e.target.value) + const val = !e.target.value ? '' : Number(e.target.value) - if (Number.isInteger(val) && val >= 0) { - setQuantity(Number(e.target.value)) + if (!val || (Number.isInteger(val) && val >= 0)) { + setQuantity(val) } } const handleBlur = () => { diff --git a/components/common/Footer/Footer.tsx b/components/common/Footer/Footer.tsx index 5fb9ede58..4190815ec 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/common/get-all-pages' +import type { Page } from '@commerce/types/page' import getSlug from '@lib/get-slug' import { Github, Vercel } from '@components/icons' import { Logo, Container } from '@components/ui' diff --git a/components/common/HomeAllProductsGrid/HomeAllProductsGrid.tsx b/components/common/HomeAllProductsGrid/HomeAllProductsGrid.tsx index 423048f75..8d8ea1adf 100644 --- a/components/common/HomeAllProductsGrid/HomeAllProductsGrid.tsx +++ b/components/common/HomeAllProductsGrid/HomeAllProductsGrid.tsx @@ -1,6 +1,6 @@ import { FC } from 'react' import Link from 'next/link' -import type { Product } from '@commerce/types' +import type { Product } from '@commerce/types/product' import { Grid } from '@components/ui' import { ProductCard } from '@components/product' import s from './HomeAllProductsGrid.module.css' diff --git a/components/common/Layout/Layout.tsx b/components/common/Layout/Layout.tsx index 1e1a22967..c5de5739a 100644 --- a/components/common/Layout/Layout.tsx +++ b/components/common/Layout/Layout.tsx @@ -1,16 +1,17 @@ -import cn from 'classnames' -import dynamic from 'next/dynamic' -import s from './Layout.module.css' -import { useRouter } from 'next/router' import React, { FC } from 'react' +import { useRouter } from 'next/router' +import dynamic from 'next/dynamic' +import cn from 'classnames' +import type { Page } from '@commerce/types/page' +import type { Category } from '@commerce/types/site' +import { CommerceProvider } from '@framework' +import { useAcceptCookies } from '@lib/hooks/useAcceptCookies' 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/CartSidebarView' -import type { Page, Category } from '@commerce/types' import LoginView from '@components/auth/LoginView' -import { CommerceProvider } from '@framework' +import s from './Layout.module.css' const Loading = () => (
    diff --git a/components/common/Navbar/Navbar.tsx b/components/common/Navbar/Navbar.tsx index aa49993f3..16088485f 100644 --- a/components/common/Navbar/Navbar.tsx +++ b/components/common/Navbar/Navbar.tsx @@ -27,13 +27,11 @@ const Navbar: FC = ({ links }) => ( All - {links - ? links.map((l) => ( - - {l.label} - - )) - : null} + {links?.map((l) => ( + + {l.label} + + ))}
    diff --git a/components/common/UserNav/UserNav.tsx b/components/common/UserNav/UserNav.tsx index 4d00970a9..83422a8cf 100644 --- a/components/common/UserNav/UserNav.tsx +++ b/components/common/UserNav/UserNav.tsx @@ -1,7 +1,7 @@ import { FC } from 'react' import Link from 'next/link' import cn from 'classnames' -import type { LineItem } from '@framework/types' +import type { LineItem } from '@commerce/types/cart' import useCart from '@framework/cart/use-cart' import useCustomer from '@framework/customer/use-customer' import { Avatar } from '@components/common' diff --git a/components/product/ProductCard/ProductCard.tsx b/components/product/ProductCard/ProductCard.tsx index 45a19d2dd..c2e210367 100644 --- a/components/product/ProductCard/ProductCard.tsx +++ b/components/product/ProductCard/ProductCard.tsx @@ -1,7 +1,7 @@ import { FC } from 'react' import cn from 'classnames' import Link from 'next/link' -import type { Product } from '@commerce/types' +import type { Product } from '@commerce/types/product' import s from './ProductCard.module.css' import Image, { ImageProps } from 'next/image' import WishlistButton from '@components/wishlist/WishlistButton' diff --git a/components/product/ProductView/ProductView.tsx b/components/product/ProductView/ProductView.tsx index 3b09fa39a..a9385b2f0 100644 --- a/components/product/ProductView/ProductView.tsx +++ b/components/product/ProductView/ProductView.tsx @@ -5,7 +5,7 @@ import { FC, useEffect, useState } from 'react' import s from './ProductView.module.css' import { Swatch, ProductSlider } from '@components/product' import { Button, Container, Text, useUI } from '@components/ui' -import type { Product } from '@commerce/types' +import type { Product } from '@commerce/types/product' import usePrice from '@framework/product/use-price' import { useAddItem } from '@framework/cart' import { getVariant, SelectedOptions } from '../helpers' @@ -18,6 +18,8 @@ interface Props { } const ProductView: FC = ({ product }) => { + // TODO: fix this missing argument issue + /* @ts-ignore */ const addItem = useAddItem() const { price } = usePrice({ amount: product.price.value, @@ -146,8 +148,11 @@ const ProductView: FC = ({ product }) => { className={s.button} onClick={addToCart} loading={loading} + disabled={variant?.availableForSale === false} > - Add to Cart + {variant?.availableForSale === false + ? 'Not Available' + : 'Add To Cart'}
    diff --git a/components/product/Swatch/Swatch.tsx b/components/product/Swatch/Swatch.tsx index 7e8de3e4a..bb8abf3d1 100644 --- a/components/product/Swatch/Swatch.tsx +++ b/components/product/Swatch/Swatch.tsx @@ -44,14 +44,15 @@ const Swatch: FC & SwatchProps> = ({ className={swatchClassName} style={color ? { backgroundColor: color } : {}} aria-label="Variant Swatch" + {...(label && color && { title: label })} {...props} > - {variant === 'color' && active && ( + {color && active && ( )} - {variant !== 'color' ? label : null} + {!color ? label : null} ) } diff --git a/components/product/helpers.ts b/components/product/helpers.ts index a0ceb7aa5..19ec2a171 100644 --- a/components/product/helpers.ts +++ b/components/product/helpers.ts @@ -1,4 +1,4 @@ -import type { Product } from '@commerce/types' +import type { Product } from '@commerce/types/product' export type SelectedOptions = Record export function getVariant(product: Product, opts: SelectedOptions) { diff --git a/components/wishlist/WishlistButton/WishlistButton.tsx b/components/wishlist/WishlistButton/WishlistButton.tsx index 6dc59b900..5841de11e 100644 --- a/components/wishlist/WishlistButton/WishlistButton.tsx +++ b/components/wishlist/WishlistButton/WishlistButton.tsx @@ -6,7 +6,7 @@ import useAddItem from '@framework/wishlist/use-add-item' import useCustomer from '@framework/customer/use-customer' import useWishlist from '@framework/wishlist/use-wishlist' import useRemoveItem from '@framework/wishlist/use-remove-item' -import type { Product, ProductVariant } from '@commerce/types' +import type { Product, ProductVariant } from '@commerce/types/product' type Props = { productId: Product['id'] diff --git a/components/wishlist/WishlistCard/WishlistCard.tsx b/components/wishlist/WishlistCard/WishlistCard.tsx index a30304132..dfc1165c2 100644 --- a/components/wishlist/WishlistCard/WishlistCard.tsx +++ b/components/wishlist/WishlistCard/WishlistCard.tsx @@ -7,7 +7,7 @@ import { Trash } from '@components/icons' import { Button, Text } from '@components/ui' import { useUI } from '@components/ui/context' -import type { Product } from '@commerce/types' +import type { Product } from '@commerce/types/product' import usePrice from '@framework/product/use-price' import useAddItem from '@framework/cart/use-add-item' import useRemoveItem from '@framework/wishlist/use-remove-item' @@ -20,14 +20,17 @@ const placeholderImg = '/product-img-placeholder.svg' const WishlistCard: FC = ({ product }) => { 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?.retailPrice, + currencyCode: product.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) + + // TODO: fix this missing argument issue + /* @ts-ignore */ const addItem = useAddItem() const { openSidebar } = useUI() diff --git a/framework/bigcommerce/api/cart/index.ts b/framework/bigcommerce/api/cart/index.ts deleted file mode 100644 index 4ee668895..000000000 --- a/framework/bigcommerce/api/cart/index.ts +++ /dev/null @@ -1,78 +0,0 @@ -import isAllowedMethod from '../utils/is-allowed-method' -import createApiHandler, { - BigcommerceApiHandler, - BigcommerceHandler, -} from '../utils/create-api-handler' -import { BigcommerceApiError } from '../utils/errors' -import getCart from './handlers/get-cart' -import addItem from './handlers/add-item' -import updateItem from './handlers/update-item' -import removeItem from './handlers/remove-item' -import type { - BigcommerceCart, - GetCartHandlerBody, - AddCartItemHandlerBody, - UpdateCartItemHandlerBody, - RemoveCartItemHandlerBody, -} from '../../types' - -export type CartHandlers = { - getCart: BigcommerceHandler - addItem: BigcommerceHandler - updateItem: BigcommerceHandler - removeItem: BigcommerceHandler -} - -const METHODS = ['GET', 'POST', 'PUT', 'DELETE'] - -// TODO: a complete implementation should have schema validation for `req.body` -const cartApi: BigcommerceApiHandler = async ( - req, - res, - config, - handlers -) => { - if (!isAllowedMethod(req, res, METHODS)) return - - const { cookies } = req - const cartId = cookies[config.cartCookie] - - try { - // Return current cart info - if (req.method === 'GET') { - const body = { cartId } - return await handlers['getCart']({ req, res, config, body }) - } - - // Create or add an item to the cart - if (req.method === 'POST') { - const body = { ...req.body, cartId } - return await handlers['addItem']({ req, res, config, body }) - } - - // Update item in cart - if (req.method === 'PUT') { - const body = { ...req.body, cartId } - return await handlers['updateItem']({ req, res, config, body }) - } - - // Remove an item from the cart - if (req.method === 'DELETE') { - const body = { ...req.body, cartId } - return await handlers['removeItem']({ req, res, config, body }) - } - } catch (error) { - console.error(error) - - const message = - error instanceof BigcommerceApiError - ? 'An unexpected error ocurred with the Bigcommerce API' - : 'An unexpected error ocurred' - - res.status(500).json({ data: null, errors: [{ message }] }) - } -} - -export const handlers = { getCart, addItem, updateItem, removeItem } - -export default createApiHandler(cartApi, handlers, {}) diff --git a/framework/bigcommerce/api/catalog/products.ts b/framework/bigcommerce/api/catalog/products.ts deleted file mode 100644 index d52b2de7e..000000000 --- a/framework/bigcommerce/api/catalog/products.ts +++ /dev/null @@ -1,48 +0,0 @@ -import type { Product } from '@commerce/types' -import isAllowedMethod from '../utils/is-allowed-method' -import createApiHandler, { - BigcommerceApiHandler, - BigcommerceHandler, -} from '../utils/create-api-handler' -import { BigcommerceApiError } from '../utils/errors' -import getProducts from './handlers/get-products' - -export type SearchProductsData = { - products: Product[] - found: boolean -} - -export type ProductsHandlers = { - getProducts: BigcommerceHandler< - SearchProductsData, - { search?: string; category?: string; brand?: string; sort?: string } - > -} - -const METHODS = ['GET'] - -// TODO(lf): a complete implementation should have schema validation for `req.body` -const productsApi: BigcommerceApiHandler< - SearchProductsData, - ProductsHandlers -> = async (req, res, config, handlers) => { - if (!isAllowedMethod(req, res, METHODS)) return - - try { - const body = req.query - return await handlers['getProducts']({ req, res, config, body }) - } catch (error) { - console.error(error) - - const message = - error instanceof BigcommerceApiError - ? 'An unexpected error ocurred with the Bigcommerce API' - : 'An unexpected error ocurred' - - res.status(500).json({ data: null, errors: [{ message }] }) - } -} - -export const handlers = { getProducts } - -export default createApiHandler(productsApi, handlers, {}) diff --git a/framework/bigcommerce/api/checkout.ts b/framework/bigcommerce/api/checkout.ts deleted file mode 100644 index 530f4c40a..000000000 --- a/framework/bigcommerce/api/checkout.ts +++ /dev/null @@ -1,77 +0,0 @@ -import isAllowedMethod from './utils/is-allowed-method' -import createApiHandler, { - BigcommerceApiHandler, -} from './utils/create-api-handler' -import { BigcommerceApiError } from './utils/errors' - -const METHODS = ['GET'] -const fullCheckout = true - -// TODO: a complete implementation should have schema validation for `req.body` -const checkoutApi: BigcommerceApiHandler = async (req, res, config) => { - if (!isAllowedMethod(req, res, METHODS)) return - - const { cookies } = req - const cartId = cookies[config.cartCookie] - - try { - if (!cartId) { - res.redirect('/cart') - return - } - - const { data } = await config.storeApiFetch( - `/v3/carts/${cartId}/redirect_urls`, - { - method: 'POST', - } - ) - - if (fullCheckout) { - res.redirect(data.checkout_url) - return - } - - // TODO: make the embedded checkout work too! - const html = ` - - - - - - Checkout - - - - -
    - - - ` - - res.status(200) - res.setHeader('Content-Type', 'text/html') - res.write(html) - res.end() - } catch (error) { - console.error(error) - - const message = - error instanceof BigcommerceApiError - ? 'An unexpected error ocurred with the Bigcommerce API' - : 'An unexpected error ocurred' - - res.status(500).json({ data: null, errors: [{ message }] }) - } -} - -export default createApiHandler(checkoutApi, {}, {}) diff --git a/framework/bigcommerce/api/customers/index.ts b/framework/bigcommerce/api/customers/index.ts deleted file mode 100644 index 5af4d1d1d..000000000 --- a/framework/bigcommerce/api/customers/index.ts +++ /dev/null @@ -1,46 +0,0 @@ -import createApiHandler, { - BigcommerceApiHandler, - BigcommerceHandler, -} from '../utils/create-api-handler' -import isAllowedMethod from '../utils/is-allowed-method' -import { BigcommerceApiError } from '../utils/errors' -import getLoggedInCustomer, { - Customer, -} from './handlers/get-logged-in-customer' - -export type { Customer } - -export type CustomerData = { - customer: Customer -} - -export type CustomersHandlers = { - getLoggedInCustomer: BigcommerceHandler -} - -const METHODS = ['GET'] - -const customersApi: BigcommerceApiHandler< - CustomerData, - CustomersHandlers -> = async (req, res, config, handlers) => { - if (!isAllowedMethod(req, res, METHODS)) return - - try { - const body = null - return await handlers['getLoggedInCustomer']({ req, res, config, body }) - } catch (error) { - console.error(error) - - const message = - error instanceof BigcommerceApiError - ? 'An unexpected error ocurred with the Bigcommerce API' - : 'An unexpected error ocurred' - - res.status(500).json({ data: null, errors: [{ message }] }) - } -} - -const handlers = { getLoggedInCustomer } - -export default createApiHandler(customersApi, handlers, {}) diff --git a/framework/bigcommerce/api/customers/login.ts b/framework/bigcommerce/api/customers/login.ts deleted file mode 100644 index e8f24a92d..000000000 --- a/framework/bigcommerce/api/customers/login.ts +++ /dev/null @@ -1,45 +0,0 @@ -import createApiHandler, { - BigcommerceApiHandler, - BigcommerceHandler, -} from '../utils/create-api-handler' -import isAllowedMethod from '../utils/is-allowed-method' -import { BigcommerceApiError } from '../utils/errors' -import login from './handlers/login' - -export type LoginBody = { - email: string - password: string -} - -export type LoginHandlers = { - login: BigcommerceHandler> -} - -const METHODS = ['POST'] - -const loginApi: BigcommerceApiHandler = async ( - req, - res, - config, - handlers -) => { - if (!isAllowedMethod(req, res, METHODS)) return - - try { - const body = req.body ?? {} - return await handlers['login']({ req, res, config, body }) - } catch (error) { - console.error(error) - - const message = - error instanceof BigcommerceApiError - ? 'An unexpected error ocurred with the Bigcommerce API' - : 'An unexpected error ocurred' - - res.status(500).json({ data: null, errors: [{ message }] }) - } -} - -const handlers = { login } - -export default createApiHandler(loginApi, handlers, {}) diff --git a/framework/bigcommerce/api/customers/logout.ts b/framework/bigcommerce/api/customers/logout.ts deleted file mode 100644 index 0a4965245..000000000 --- a/framework/bigcommerce/api/customers/logout.ts +++ /dev/null @@ -1,42 +0,0 @@ -import createApiHandler, { - BigcommerceApiHandler, - BigcommerceHandler, -} from '../utils/create-api-handler' -import isAllowedMethod from '../utils/is-allowed-method' -import { BigcommerceApiError } from '../utils/errors' -import logout from './handlers/logout' - -export type LogoutHandlers = { - logout: BigcommerceHandler -} - -const METHODS = ['GET'] - -const logoutApi: BigcommerceApiHandler = async ( - req, - res, - config, - handlers -) => { - if (!isAllowedMethod(req, res, METHODS)) return - - try { - const redirectTo = req.query.redirect_to - const body = typeof redirectTo === 'string' ? { redirectTo } : {} - - return await handlers['logout']({ req, res, config, body }) - } catch (error) { - console.error(error) - - const message = - error instanceof BigcommerceApiError - ? 'An unexpected error ocurred with the Bigcommerce API' - : 'An unexpected error ocurred' - - res.status(500).json({ data: null, errors: [{ message }] }) - } -} - -const handlers = { logout } - -export default createApiHandler(logoutApi, handlers, {}) diff --git a/framework/bigcommerce/api/customers/signup.ts b/framework/bigcommerce/api/customers/signup.ts deleted file mode 100644 index aa26f78cf..000000000 --- a/framework/bigcommerce/api/customers/signup.ts +++ /dev/null @@ -1,50 +0,0 @@ -import createApiHandler, { - BigcommerceApiHandler, - BigcommerceHandler, -} from '../utils/create-api-handler' -import isAllowedMethod from '../utils/is-allowed-method' -import { BigcommerceApiError } from '../utils/errors' -import signup from './handlers/signup' - -export type SignupBody = { - firstName: string - lastName: string - email: string - password: string -} - -export type SignupHandlers = { - signup: BigcommerceHandler> -} - -const METHODS = ['POST'] - -const signupApi: BigcommerceApiHandler = async ( - req, - res, - config, - handlers -) => { - if (!isAllowedMethod(req, res, METHODS)) return - - const { cookies } = req - const cartId = cookies[config.cartCookie] - - try { - const body = { ...req.body, cartId } - return await handlers['signup']({ req, res, config, body }) - } catch (error) { - console.error(error) - - const message = - error instanceof BigcommerceApiError - ? 'An unexpected error ocurred with the Bigcommerce API' - : 'An unexpected error ocurred' - - res.status(500).json({ data: null, errors: [{ message }] }) - } -} - -const handlers = { signup } - -export default createApiHandler(signupApi, handlers, {}) diff --git a/framework/bigcommerce/api/cart/handlers/add-item.ts b/framework/bigcommerce/api/endpoints/cart/add-item.ts similarity index 82% rename from framework/bigcommerce/api/cart/handlers/add-item.ts rename to framework/bigcommerce/api/endpoints/cart/add-item.ts index c47e72cdb..52ef1223d 100644 --- a/framework/bigcommerce/api/cart/handlers/add-item.ts +++ b/framework/bigcommerce/api/endpoints/cart/add-item.ts @@ -1,8 +1,9 @@ +import { normalizeCart } from '../../../lib/normalize' import { parseCartItem } from '../../utils/parse-item' import getCartCookie from '../../utils/get-cart-cookie' -import type { CartHandlers } from '..' +import type { CartEndpoint } from '.' -const addItem: CartHandlers['addItem'] = async ({ +const addItem: CartEndpoint['handlers']['addItem'] = async ({ res, body: { cartId, item }, config, @@ -39,7 +40,7 @@ const addItem: CartHandlers['addItem'] = async ({ 'Set-Cookie', getCartCookie(config.cartCookie, data.id, config.cartCookieMaxAge) ) - res.status(200).json({ data }) + res.status(200).json({ data: normalizeCart(data) }) } export default addItem diff --git a/framework/bigcommerce/api/cart/handlers/get-cart.ts b/framework/bigcommerce/api/endpoints/cart/get-cart.ts similarity index 69% rename from framework/bigcommerce/api/cart/handlers/get-cart.ts rename to framework/bigcommerce/api/endpoints/cart/get-cart.ts index 890ac9997..d3bb309e2 100644 --- a/framework/bigcommerce/api/cart/handlers/get-cart.ts +++ b/framework/bigcommerce/api/endpoints/cart/get-cart.ts @@ -1,10 +1,11 @@ -import type { BigcommerceCart } from '../../../types' +import { normalizeCart } from '../../../lib/normalize' import { BigcommerceApiError } from '../../utils/errors' import getCartCookie from '../../utils/get-cart-cookie' -import type { CartHandlers } from '../' +import type { BigcommerceCart } from '../../../types/cart' +import type { CartEndpoint } from '.' // Return current cart info -const getCart: CartHandlers['getCart'] = async ({ +const getCart: CartEndpoint['handlers']['getCart'] = async ({ res, body: { cartId }, config, @@ -26,7 +27,9 @@ const getCart: CartHandlers['getCart'] = async ({ } } - res.status(200).json({ data: result.data ?? null }) + res.status(200).json({ + data: result.data ? normalizeCart(result.data) : null, + }) } export default getCart diff --git a/framework/bigcommerce/api/endpoints/cart/index.ts b/framework/bigcommerce/api/endpoints/cart/index.ts new file mode 100644 index 000000000..ae2414d70 --- /dev/null +++ b/framework/bigcommerce/api/endpoints/cart/index.ts @@ -0,0 +1,26 @@ +import { GetAPISchema, createEndpoint } from '@commerce/api' +import cartEndpoint from '@commerce/api/endpoints/cart' +import type { CartSchema } from '../../../types/cart' +import type { BigcommerceAPI } from '../..' +import getCart from './get-cart' +import addItem from './add-item' +import updateItem from './update-item' +import removeItem from './remove-item' + +export type CartAPI = GetAPISchema + +export type CartEndpoint = CartAPI['endpoint'] + +export const handlers: CartEndpoint['handlers'] = { + getCart, + addItem, + updateItem, + removeItem, +} + +const cartApi = createEndpoint({ + handler: cartEndpoint, + handlers, +}) + +export default cartApi diff --git a/framework/bigcommerce/api/cart/handlers/remove-item.ts b/framework/bigcommerce/api/endpoints/cart/remove-item.ts similarity index 77% rename from framework/bigcommerce/api/cart/handlers/remove-item.ts rename to framework/bigcommerce/api/endpoints/cart/remove-item.ts index c09848948..baf10c80f 100644 --- a/framework/bigcommerce/api/cart/handlers/remove-item.ts +++ b/framework/bigcommerce/api/endpoints/cart/remove-item.ts @@ -1,7 +1,8 @@ +import { normalizeCart } from '../../../lib/normalize' import getCartCookie from '../../utils/get-cart-cookie' -import type { CartHandlers } from '..' +import type { CartEndpoint } from '.' -const removeItem: CartHandlers['removeItem'] = async ({ +const removeItem: CartEndpoint['handlers']['removeItem'] = async ({ res, body: { cartId, itemId }, config, @@ -27,7 +28,7 @@ const removeItem: CartHandlers['removeItem'] = async ({ : // Remove the cart cookie if the cart was removed (empty items) getCartCookie(config.cartCookie) ) - res.status(200).json({ data }) + res.status(200).json({ data: data && normalizeCart(data) }) } export default removeItem diff --git a/framework/bigcommerce/api/cart/handlers/update-item.ts b/framework/bigcommerce/api/endpoints/cart/update-item.ts similarity index 77% rename from framework/bigcommerce/api/cart/handlers/update-item.ts rename to framework/bigcommerce/api/endpoints/cart/update-item.ts index 27b74ca20..113553fad 100644 --- a/framework/bigcommerce/api/cart/handlers/update-item.ts +++ b/framework/bigcommerce/api/endpoints/cart/update-item.ts @@ -1,8 +1,9 @@ +import { normalizeCart } from '../../../lib/normalize' import { parseCartItem } from '../../utils/parse-item' import getCartCookie from '../../utils/get-cart-cookie' -import type { CartHandlers } from '..' +import type { CartEndpoint } from '.' -const updateItem: CartHandlers['updateItem'] = async ({ +const updateItem: CartEndpoint['handlers']['updateItem'] = async ({ res, body: { cartId, itemId, item }, config, @@ -29,7 +30,7 @@ const updateItem: CartHandlers['updateItem'] = async ({ 'Set-Cookie', getCartCookie(config.cartCookie, cartId, config.cartCookieMaxAge) ) - res.status(200).json({ data }) + res.status(200).json({ data: normalizeCart(data) }) } export default updateItem diff --git a/framework/bigcommerce/api/catalog/handlers/get-products.ts b/framework/bigcommerce/api/endpoints/catalog/products/get-products.ts similarity index 68% rename from framework/bigcommerce/api/catalog/handlers/get-products.ts rename to framework/bigcommerce/api/endpoints/catalog/products/get-products.ts index bedd773b0..6dde39e28 100644 --- a/framework/bigcommerce/api/catalog/handlers/get-products.ts +++ b/framework/bigcommerce/api/endpoints/catalog/products/get-products.ts @@ -1,6 +1,5 @@ -import { Product } from '@commerce/types' -import getAllProducts, { ProductEdge } from '../../../product/get-all-products' -import type { ProductsHandlers } from '../products' +import { Product } from '@commerce/types/product' +import { ProductsEndpoint } from '.' const SORT: { [key: string]: string | undefined } = { latest: 'id', @@ -11,10 +10,11 @@ const SORT: { [key: string]: string | undefined } = { const LIMIT = 12 // Return current cart info -const getProducts: ProductsHandlers['getProducts'] = async ({ +const getProducts: ProductsEndpoint['handlers']['getProducts'] = async ({ res, - body: { search, category, brand, sort }, + body: { search, categoryId, brandId, sort }, config, + commerce, }) => { // Use a dummy base as we only care about the relative path const url = new URL('/v3/catalog/products', 'http://a') @@ -24,11 +24,11 @@ const getProducts: ProductsHandlers['getProducts'] = async ({ if (search) url.searchParams.set('keyword', search) - if (category && Number.isInteger(Number(category))) - url.searchParams.set('categories:in', category) + if (categoryId && Number.isInteger(Number(categoryId))) + url.searchParams.set('categories:in', String(categoryId)) - if (brand && Number.isInteger(Number(brand))) - url.searchParams.set('brand_id', brand) + if (brandId && Number.isInteger(Number(brandId))) + url.searchParams.set('brand_id', String(brandId)) if (sort) { const [_sort, direction] = sort.split('-') @@ -47,18 +47,18 @@ const getProducts: ProductsHandlers['getProducts'] = async ({ url.pathname + url.search ) - const entityIds = data.map((p) => p.id) - const found = entityIds.length > 0 + const ids = data.map((p) => String(p.id)) + const found = ids.length > 0 // We want the GraphQL version of each product - const graphqlData = await getAllProducts({ - variables: { first: LIMIT, entityIds }, + const graphqlData = await commerce.getAllProducts({ + variables: { first: LIMIT, ids }, config, }) // Put the products in an object that we can use to get them by id const productsById = graphqlData.products.reduce<{ - [k: number]: Product + [k: string]: Product }>((prods, p) => { prods[Number(p.id)] = p return prods @@ -68,7 +68,7 @@ const getProducts: ProductsHandlers['getProducts'] = async ({ // Populate the products array with the graphql products, in the order // assigned by the list of entity ids - entityIds.forEach((id) => { + ids.forEach((id) => { const product = productsById[id] if (product) products.push(product) }) diff --git a/framework/bigcommerce/api/endpoints/catalog/products/index.ts b/framework/bigcommerce/api/endpoints/catalog/products/index.ts new file mode 100644 index 000000000..555740f60 --- /dev/null +++ b/framework/bigcommerce/api/endpoints/catalog/products/index.ts @@ -0,0 +1,18 @@ +import { GetAPISchema, createEndpoint } from '@commerce/api' +import productsEndpoint from '@commerce/api/endpoints/catalog/products' +import type { ProductsSchema } from '../../../../types/product' +import type { BigcommerceAPI } from '../../..' +import getProducts from './get-products' + +export type ProductsAPI = GetAPISchema + +export type ProductsEndpoint = ProductsAPI['endpoint'] + +export const handlers: ProductsEndpoint['handlers'] = { getProducts } + +const productsApi = createEndpoint({ + handler: productsEndpoint, + handlers, +}) + +export default productsApi diff --git a/framework/bigcommerce/api/endpoints/checkout/checkout.ts b/framework/bigcommerce/api/endpoints/checkout/checkout.ts new file mode 100644 index 000000000..517a57950 --- /dev/null +++ b/framework/bigcommerce/api/endpoints/checkout/checkout.ts @@ -0,0 +1,62 @@ +import type { CheckoutEndpoint } from '.' + +const fullCheckout = true + +const checkout: CheckoutEndpoint['handlers']['checkout'] = async ({ + req, + res, + config, +}) => { + const { cookies } = req + const cartId = cookies[config.cartCookie] + + if (!cartId) { + res.redirect('/cart') + return + } + + const { data } = await config.storeApiFetch( + `/v3/carts/${cartId}/redirect_urls`, + { + method: 'POST', + } + ) + + if (fullCheckout) { + res.redirect(data.checkout_url) + return + } + + // TODO: make the embedded checkout work too! + const html = ` + + + + + + Checkout + + + + +
    + + + ` + + res.status(200) + res.setHeader('Content-Type', 'text/html') + res.write(html) + res.end() +} + +export default checkout diff --git a/framework/bigcommerce/api/endpoints/checkout/index.ts b/framework/bigcommerce/api/endpoints/checkout/index.ts new file mode 100644 index 000000000..eaba32e47 --- /dev/null +++ b/framework/bigcommerce/api/endpoints/checkout/index.ts @@ -0,0 +1,18 @@ +import { GetAPISchema, createEndpoint } from '@commerce/api' +import checkoutEndpoint from '@commerce/api/endpoints/checkout' +import type { CheckoutSchema } from '../../../types/checkout' +import type { BigcommerceAPI } from '../..' +import checkout from './checkout' + +export type CheckoutAPI = GetAPISchema + +export type CheckoutEndpoint = CheckoutAPI['endpoint'] + +export const handlers: CheckoutEndpoint['handlers'] = { checkout } + +const checkoutApi = createEndpoint({ + handler: checkoutEndpoint, + handlers, +}) + +export default checkoutApi diff --git a/framework/bigcommerce/api/customers/handlers/get-logged-in-customer.ts b/framework/bigcommerce/api/endpoints/customer/get-logged-in-customer.ts similarity index 89% rename from framework/bigcommerce/api/customers/handlers/get-logged-in-customer.ts rename to framework/bigcommerce/api/endpoints/customer/get-logged-in-customer.ts index 698235dda..cfcce9532 100644 --- a/framework/bigcommerce/api/customers/handlers/get-logged-in-customer.ts +++ b/framework/bigcommerce/api/endpoints/customer/get-logged-in-customer.ts @@ -1,5 +1,5 @@ import type { GetLoggedInCustomerQuery } from '../../../schema' -import type { CustomersHandlers } from '..' +import type { CustomerEndpoint } from '.' export const getLoggedInCustomerQuery = /* GraphQL */ ` query getLoggedInCustomer { @@ -24,7 +24,7 @@ export const getLoggedInCustomerQuery = /* GraphQL */ ` export type Customer = NonNullable -const getLoggedInCustomer: CustomersHandlers['getLoggedInCustomer'] = async ({ +const getLoggedInCustomer: CustomerEndpoint['handlers']['getLoggedInCustomer'] = async ({ req, res, config, diff --git a/framework/bigcommerce/api/endpoints/customer/index.ts b/framework/bigcommerce/api/endpoints/customer/index.ts new file mode 100644 index 000000000..cb0f6787a --- /dev/null +++ b/framework/bigcommerce/api/endpoints/customer/index.ts @@ -0,0 +1,18 @@ +import { GetAPISchema, createEndpoint } from '@commerce/api' +import customerEndpoint from '@commerce/api/endpoints/customer' +import type { CustomerSchema } from '../../../types/customer' +import type { BigcommerceAPI } from '../..' +import getLoggedInCustomer from './get-logged-in-customer' + +export type CustomerAPI = GetAPISchema + +export type CustomerEndpoint = CustomerAPI['endpoint'] + +export const handlers: CustomerEndpoint['handlers'] = { getLoggedInCustomer } + +const customerApi = createEndpoint({ + handler: customerEndpoint, + handlers, +}) + +export default customerApi diff --git a/framework/bigcommerce/api/endpoints/login/index.ts b/framework/bigcommerce/api/endpoints/login/index.ts new file mode 100644 index 000000000..2b454c7c2 --- /dev/null +++ b/framework/bigcommerce/api/endpoints/login/index.ts @@ -0,0 +1,18 @@ +import { GetAPISchema, createEndpoint } from '@commerce/api' +import loginEndpoint from '@commerce/api/endpoints/login' +import type { LoginSchema } from '../../../types/login' +import type { BigcommerceAPI } from '../..' +import login from './login' + +export type LoginAPI = GetAPISchema + +export type LoginEndpoint = LoginAPI['endpoint'] + +export const handlers: LoginEndpoint['handlers'] = { login } + +const loginApi = createEndpoint({ + handler: loginEndpoint, + handlers, +}) + +export default loginApi diff --git a/framework/bigcommerce/api/customers/handlers/login.ts b/framework/bigcommerce/api/endpoints/login/login.ts similarity index 81% rename from framework/bigcommerce/api/customers/handlers/login.ts rename to framework/bigcommerce/api/endpoints/login/login.ts index 9e019f3a0..f55c3b54f 100644 --- a/framework/bigcommerce/api/customers/handlers/login.ts +++ b/framework/bigcommerce/api/endpoints/login/login.ts @@ -1,13 +1,13 @@ import { FetcherError } from '@commerce/utils/errors' -import login from '../../../auth/login' -import type { LoginHandlers } from '../login' +import type { LoginEndpoint } from '.' const invalidCredentials = /invalid credentials/i -const loginHandler: LoginHandlers['login'] = async ({ +const login: LoginEndpoint['handlers']['login'] = async ({ res, body: { email, password }, config, + commerce, }) => { // TODO: Add proper validations with something like Ajv if (!(email && password)) { @@ -21,7 +21,7 @@ const loginHandler: LoginHandlers['login'] = async ({ // and numeric characters. try { - await login({ variables: { email, password }, config, res }) + await commerce.login({ variables: { email, password }, config, res }) } catch (error) { // Check if the email and password didn't match an existing account if ( @@ -46,4 +46,4 @@ const loginHandler: LoginHandlers['login'] = async ({ res.status(200).json({ data: null }) } -export default loginHandler +export default login diff --git a/framework/bigcommerce/api/endpoints/logout/index.ts b/framework/bigcommerce/api/endpoints/logout/index.ts new file mode 100644 index 000000000..0dbb23bab --- /dev/null +++ b/framework/bigcommerce/api/endpoints/logout/index.ts @@ -0,0 +1,18 @@ +import { GetAPISchema, createEndpoint } from '@commerce/api' +import logoutEndpoint from '@commerce/api/endpoints/logout' +import type { LogoutSchema } from '../../../types/logout' +import type { BigcommerceAPI } from '../..' +import logout from './logout' + +export type LogoutAPI = GetAPISchema + +export type LogoutEndpoint = LogoutAPI['endpoint'] + +export const handlers: LogoutEndpoint['handlers'] = { logout } + +const logoutApi = createEndpoint({ + handler: logoutEndpoint, + handlers, +}) + +export default logoutApi diff --git a/framework/bigcommerce/api/customers/handlers/logout.ts b/framework/bigcommerce/api/endpoints/logout/logout.ts similarity index 74% rename from framework/bigcommerce/api/customers/handlers/logout.ts rename to framework/bigcommerce/api/endpoints/logout/logout.ts index 937ce0954..b90a8c3ce 100644 --- a/framework/bigcommerce/api/customers/handlers/logout.ts +++ b/framework/bigcommerce/api/endpoints/logout/logout.ts @@ -1,7 +1,7 @@ import { serialize } from 'cookie' -import { LogoutHandlers } from '../logout' +import type { LogoutEndpoint } from '.' -const logoutHandler: LogoutHandlers['logout'] = async ({ +const logout: LogoutEndpoint['handlers']['logout'] = async ({ res, body: { redirectTo }, config, @@ -20,4 +20,4 @@ const logoutHandler: LogoutHandlers['logout'] = async ({ } } -export default logoutHandler +export default logout diff --git a/framework/bigcommerce/api/endpoints/signup/index.ts b/framework/bigcommerce/api/endpoints/signup/index.ts new file mode 100644 index 000000000..6ce8be271 --- /dev/null +++ b/framework/bigcommerce/api/endpoints/signup/index.ts @@ -0,0 +1,18 @@ +import { GetAPISchema, createEndpoint } from '@commerce/api' +import signupEndpoint from '@commerce/api/endpoints/signup' +import type { SignupSchema } from '../../../types/signup' +import type { BigcommerceAPI } from '../..' +import signup from './signup' + +export type SignupAPI = GetAPISchema + +export type SignupEndpoint = SignupAPI['endpoint'] + +export const handlers: SignupEndpoint['handlers'] = { signup } + +const singupApi = createEndpoint({ + handler: signupEndpoint, + handlers, +}) + +export default singupApi diff --git a/framework/bigcommerce/api/customers/handlers/signup.ts b/framework/bigcommerce/api/endpoints/signup/signup.ts similarity index 88% rename from framework/bigcommerce/api/customers/handlers/signup.ts rename to framework/bigcommerce/api/endpoints/signup/signup.ts index 1b24db0cc..46c071be8 100644 --- a/framework/bigcommerce/api/customers/handlers/signup.ts +++ b/framework/bigcommerce/api/endpoints/signup/signup.ts @@ -1,11 +1,11 @@ import { BigcommerceApiError } from '../../utils/errors' -import login from '../../../auth/login' -import { SignupHandlers } from '../signup' +import type { SignupEndpoint } from '.' -const signup: SignupHandlers['signup'] = async ({ +const signup: SignupEndpoint['handlers']['signup'] = async ({ res, body: { firstName, lastName, email, password }, config, + commerce, }) => { // TODO: Add proper validations with something like Ajv if (!(firstName && lastName && email && password)) { @@ -54,7 +54,7 @@ const signup: SignupHandlers['signup'] = async ({ } // Login the customer right after creating it - await login({ variables: { email, password }, res, config }) + await commerce.login({ variables: { email, password }, res, config }) res.status(200).json({ data: null }) } diff --git a/framework/bigcommerce/api/wishlist/handlers/add-item.ts b/framework/bigcommerce/api/endpoints/wishlist/add-item.ts similarity index 76% rename from framework/bigcommerce/api/wishlist/handlers/add-item.ts rename to framework/bigcommerce/api/endpoints/wishlist/add-item.ts index 00d7b06bd..4c5970a5d 100644 --- a/framework/bigcommerce/api/wishlist/handlers/add-item.ts +++ b/framework/bigcommerce/api/endpoints/wishlist/add-item.ts @@ -1,13 +1,14 @@ -import type { WishlistHandlers } from '..' -import getCustomerId from '../../../customer/get-customer-id' -import getCustomerWishlist from '../../../customer/get-customer-wishlist' +import getCustomerWishlist from '../../operations/get-customer-wishlist' import { parseWishlistItem } from '../../utils/parse-item' +import getCustomerId from './utils/get-customer-id' +import type { WishlistEndpoint } from '.' -// Returns the wishlist of the signed customer -const addItem: WishlistHandlers['addItem'] = async ({ +// Return wishlist info +const addItem: WishlistEndpoint['handlers']['addItem'] = async ({ res, body: { customerToken, item }, config, + commerce, }) => { if (!item) { return res.status(400).json({ @@ -26,7 +27,7 @@ const addItem: WishlistHandlers['addItem'] = async ({ }) } - const { wishlist } = await getCustomerWishlist({ + const { wishlist } = await commerce.getCustomerWishlist({ variables: { customerId }, config, }) diff --git a/framework/bigcommerce/api/wishlist/handlers/get-wishlist.ts b/framework/bigcommerce/api/endpoints/wishlist/get-wishlist.ts similarity index 64% rename from framework/bigcommerce/api/wishlist/handlers/get-wishlist.ts rename to framework/bigcommerce/api/endpoints/wishlist/get-wishlist.ts index 3737c033a..21443119c 100644 --- a/framework/bigcommerce/api/wishlist/handlers/get-wishlist.ts +++ b/framework/bigcommerce/api/endpoints/wishlist/get-wishlist.ts @@ -1,12 +1,14 @@ -import getCustomerId from '../../../customer/get-customer-id' -import getCustomerWishlist from '../../../customer/get-customer-wishlist' -import type { Wishlist, WishlistHandlers } from '..' +import type { Wishlist } from '../../../types/wishlist' +import type { WishlistEndpoint } from '.' +import getCustomerId from './utils/get-customer-id' +import getCustomerWishlist from '../../operations/get-customer-wishlist' // Return wishlist info -const getWishlist: WishlistHandlers['getWishlist'] = async ({ +const getWishlist: WishlistEndpoint['handlers']['getWishlist'] = async ({ res, body: { customerToken, includeProducts }, config, + commerce, }) => { let result: { data?: Wishlist } = {} @@ -22,7 +24,7 @@ const getWishlist: WishlistHandlers['getWishlist'] = async ({ }) } - const { wishlist } = await getCustomerWishlist({ + const { wishlist } = await commerce.getCustomerWishlist({ variables: { customerId }, includeProducts, config, diff --git a/framework/bigcommerce/api/endpoints/wishlist/index.ts b/framework/bigcommerce/api/endpoints/wishlist/index.ts new file mode 100644 index 000000000..31af234ce --- /dev/null +++ b/framework/bigcommerce/api/endpoints/wishlist/index.ts @@ -0,0 +1,24 @@ +import { GetAPISchema, createEndpoint } from '@commerce/api' +import wishlistEndpoint from '@commerce/api/endpoints/wishlist' +import type { WishlistSchema } from '../../../types/wishlist' +import type { BigcommerceAPI } from '../..' +import getWishlist from './get-wishlist' +import addItem from './add-item' +import removeItem from './remove-item' + +export type WishlistAPI = GetAPISchema + +export type WishlistEndpoint = WishlistAPI['endpoint'] + +export const handlers: WishlistEndpoint['handlers'] = { + getWishlist, + addItem, + removeItem, +} + +const wishlistApi = createEndpoint({ + handler: wishlistEndpoint, + handlers, +}) + +export default wishlistApi diff --git a/framework/bigcommerce/api/wishlist/handlers/remove-item.ts b/framework/bigcommerce/api/endpoints/wishlist/remove-item.ts similarity index 63% rename from framework/bigcommerce/api/wishlist/handlers/remove-item.ts rename to framework/bigcommerce/api/endpoints/wishlist/remove-item.ts index a9cfd9db5..22ac31cf9 100644 --- a/framework/bigcommerce/api/wishlist/handlers/remove-item.ts +++ b/framework/bigcommerce/api/endpoints/wishlist/remove-item.ts @@ -1,20 +1,20 @@ -import getCustomerId from '../../../customer/get-customer-id' -import getCustomerWishlist, { - Wishlist, -} from '../../../customer/get-customer-wishlist' -import type { WishlistHandlers } from '..' +import type { Wishlist } from '../../../types/wishlist' +import getCustomerWishlist from '../../operations/get-customer-wishlist' +import getCustomerId from './utils/get-customer-id' +import type { WishlistEndpoint } from '.' -// Return current wishlist info -const removeItem: WishlistHandlers['removeItem'] = async ({ +// Return wishlist info +const removeItem: WishlistEndpoint['handlers']['removeItem'] = async ({ res, body: { customerToken, itemId }, config, + commerce, }) => { const customerId = customerToken && (await getCustomerId({ customerToken, config })) const { wishlist } = (customerId && - (await getCustomerWishlist({ + (await commerce.getCustomerWishlist({ variables: { customerId }, config, }))) || diff --git a/framework/bigcommerce/customer/get-customer-id.ts b/framework/bigcommerce/api/endpoints/wishlist/utils/get-customer-id.ts similarity index 65% rename from framework/bigcommerce/customer/get-customer-id.ts rename to framework/bigcommerce/api/endpoints/wishlist/utils/get-customer-id.ts index 65ce5a6a8..603f8be2d 100644 --- a/framework/bigcommerce/customer/get-customer-id.ts +++ b/framework/bigcommerce/api/endpoints/wishlist/utils/get-customer-id.ts @@ -1,5 +1,5 @@ -import { GetCustomerIdQuery } from '../schema' -import { BigcommerceConfig, getConfig } from '../api' +import type { GetCustomerIdQuery } from '../../../../schema' +import type { BigcommerceConfig } from '../../..' export const getCustomerIdQuery = /* GraphQL */ ` query getCustomerId { @@ -14,10 +14,8 @@ async function getCustomerId({ config, }: { customerToken: string - config?: BigcommerceConfig -}): Promise { - config = getConfig(config) - + config: BigcommerceConfig +}): Promise { const { data } = await config.fetch( getCustomerIdQuery, undefined, @@ -28,7 +26,7 @@ async function getCustomerId({ } ) - return data?.customer?.entityId + return String(data?.customer?.entityId) } export default getCustomerId diff --git a/framework/bigcommerce/api/index.ts b/framework/bigcommerce/api/index.ts index 0216fe61b..300f1087b 100644 --- a/framework/bigcommerce/api/index.ts +++ b/framework/bigcommerce/api/index.ts @@ -1,8 +1,29 @@ import type { RequestInit } from '@vercel/fetch' -import type { CommerceAPIConfig } from '@commerce/api' +import { + CommerceAPI, + CommerceAPIConfig, + getCommerceApi as commerceApi, +} from '@commerce/api' import fetchGraphqlApi from './utils/fetch-graphql-api' import fetchStoreApi from './utils/fetch-store-api' +import type { CartAPI } from './endpoints/cart' +import type { CustomerAPI } from './endpoints/customer' +import type { LoginAPI } from './endpoints/login' +import type { LogoutAPI } from './endpoints/logout' +import type { SignupAPI } from './endpoints/signup' +import type { ProductsAPI } from './endpoints/catalog/products' +import type { WishlistAPI } from './endpoints/wishlist' + +import login from './operations/login' +import getAllPages from './operations/get-all-pages' +import getPage from './operations/get-page' +import getSiteInfo from './operations/get-site-info' +import getCustomerWishlist from './operations/get-customer-wishlist' +import getAllProductPaths from './operations/get-all-product-paths' +import getAllProducts from './operations/get-all-products' +import getProduct from './operations/get-product' + export interface BigcommerceConfig extends CommerceAPIConfig { // Indicates if the returned metadata with translations should be applied to the // data or returned as it is @@ -39,34 +60,12 @@ if (!(STORE_API_URL && STORE_API_TOKEN && STORE_API_CLIENT_ID)) { ) } -export class Config { - private config: BigcommerceConfig - - constructor(config: Omit) { - this.config = { - ...config, - // The customerCookie is not customizable for now, BC sets the cookie and it's - // not important to rename it - customerCookie: 'SHOP_TOKEN', - } - } - - 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 ONE_DAY = 60 * 60 * 24 -const config = new Config({ + +const config: BigcommerceConfig = { commerceUrl: API_URL, apiToken: API_TOKEN, + customerCookie: 'SHOP_TOKEN', cartCookie: process.env.BIGCOMMERCE_CART_COOKIE ?? 'bc_cartId', cartCookieMaxAge: ONE_DAY * 30, fetch: fetchGraphqlApi, @@ -77,12 +76,36 @@ const config = new Config({ storeApiClientId: STORE_API_CLIENT_ID, storeChannelId: STORE_CHANNEL_ID, storeApiFetch: fetchStoreApi, -}) - -export function getConfig(userConfig?: Partial) { - return config.getConfig(userConfig) } -export function setConfig(newConfig: Partial) { - return config.setConfig(newConfig) +const operations = { + login, + getAllPages, + getPage, + getSiteInfo, + getCustomerWishlist, + getAllProductPaths, + getAllProducts, + getProduct, +} + +export const provider = { config, operations } + +export type Provider = typeof provider + +export type APIs = + | CartAPI + | CustomerAPI + | LoginAPI + | LogoutAPI + | SignupAPI + | ProductsAPI + | WishlistAPI + +export type BigcommerceAPI

    = CommerceAPI

    + +export function getCommerceApi

    ( + customProvider: P = provider as any +): BigcommerceAPI

    { + return commerceApi(customProvider) } diff --git a/framework/bigcommerce/api/operations/get-all-pages.ts b/framework/bigcommerce/api/operations/get-all-pages.ts new file mode 100644 index 000000000..3a9b64b1f --- /dev/null +++ b/framework/bigcommerce/api/operations/get-all-pages.ts @@ -0,0 +1,46 @@ +import type { + OperationContext, + OperationOptions, +} from '@commerce/api/operations' +import type { Page, GetAllPagesOperation } from '../../types/page' +import type { RecursivePartial, RecursiveRequired } from '../utils/types' +import { BigcommerceConfig, Provider } from '..' + +export default function getAllPagesOperation({ + commerce, +}: OperationContext) { + async function getAllPages(opts?: { + config?: Partial + preview?: boolean + }): Promise + + async function getAllPages( + opts: { + config?: Partial + preview?: boolean + } & OperationOptions + ): Promise + + async function getAllPages({ + config, + preview, + }: { + url?: string + config?: Partial + preview?: boolean + } = {}): Promise { + const cfg = commerce.getConfig(config) + // RecursivePartial forces the method to check for every prop in the data, which is + // required in case there's a custom `url` + const { data } = await cfg.storeApiFetch< + RecursivePartial<{ data: Page[] }> + >('/v3/content/pages') + const pages = (data as RecursiveRequired) ?? [] + + return { + pages: preview ? pages : pages.filter((p) => p.is_visible), + } + } + + return getAllPages +} diff --git a/framework/bigcommerce/api/operations/get-all-product-paths.ts b/framework/bigcommerce/api/operations/get-all-product-paths.ts new file mode 100644 index 000000000..da7b457eb --- /dev/null +++ b/framework/bigcommerce/api/operations/get-all-product-paths.ts @@ -0,0 +1,66 @@ +import type { + OperationContext, + OperationOptions, +} from '@commerce/api/operations' +import type { GetAllProductPathsQuery } from '../../schema' +import type { GetAllProductPathsOperation } from '../../types/product' +import type { RecursivePartial, RecursiveRequired } from '../utils/types' +import filterEdges from '../utils/filter-edges' +import { BigcommerceConfig, Provider } from '..' + +export const getAllProductPathsQuery = /* GraphQL */ ` + query getAllProductPaths($first: Int = 100) { + site { + products(first: $first) { + edges { + node { + path + } + } + } + } + } +` + +export default function getAllProductPathsOperation({ + commerce, +}: OperationContext) { + async function getAllProductPaths< + T extends GetAllProductPathsOperation + >(opts?: { + variables?: T['variables'] + config?: BigcommerceConfig + }): Promise + + async function getAllProductPaths( + opts: { + variables?: T['variables'] + config?: BigcommerceConfig + } & OperationOptions + ): Promise + + async function getAllProductPaths({ + query = getAllProductPathsQuery, + variables, + config, + }: { + query?: string + variables?: T['variables'] + config?: BigcommerceConfig + } = {}): Promise { + config = commerce.getConfig(config) + // RecursivePartial forces the method to check for every prop in the data, which is + // required in case there's a custom `query` + const { data } = await config.fetch< + RecursivePartial + >(query, { variables }) + const products = data.site?.products?.edges + + return { + products: filterEdges(products as RecursiveRequired).map( + ({ node }) => node + ), + } + } + return getAllProductPaths +} diff --git a/framework/bigcommerce/api/operations/get-all-products.ts b/framework/bigcommerce/api/operations/get-all-products.ts new file mode 100644 index 000000000..c2652f5bf --- /dev/null +++ b/framework/bigcommerce/api/operations/get-all-products.ts @@ -0,0 +1,135 @@ +import type { + OperationContext, + OperationOptions, +} from '@commerce/api/operations' +import type { + GetAllProductsQuery, + GetAllProductsQueryVariables, +} from '../../schema' +import type { GetAllProductsOperation } from '../../types/product' +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, Provider } from '..' +import { normalizeProduct } from '../../lib/normalize' + +export const getAllProductsQuery = /* GraphQL */ ` + query getAllProducts( + $hasLocale: Boolean = false + $locale: String = "null" + $entityIds: [Int!] + $first: Int = 10 + $products: Boolean = false + $featuredProducts: Boolean = false + $bestSellingProducts: Boolean = false + $newestProducts: Boolean = false + ) { + site { + products(first: $first, entityIds: $entityIds) @include(if: $products) { + ...productConnnection + } + featuredProducts(first: $first) @include(if: $featuredProducts) { + ...productConnnection + } + bestSellingProducts(first: $first) @include(if: $bestSellingProducts) { + ...productConnnection + } + newestProducts(first: $first) @include(if: $newestProducts) { + ...productConnnection + } + } + } + + ${productConnectionFragment} +` + +export type ProductEdge = NonNullable< + NonNullable[0] +> + +export type ProductNode = ProductEdge['node'] + +export type GetAllProductsResult< + T extends Record = { + products: ProductEdge[] + } +> = T + +function getProductsType( + relevance?: GetAllProductsOperation['variables']['relevance'] +) { + switch (relevance) { + case 'featured': + return 'featuredProducts' + case 'best_selling': + return 'bestSellingProducts' + case 'newest': + return 'newestProducts' + default: + return 'products' + } +} + +export default function getAllProductsOperation({ + commerce, +}: OperationContext) { + async function getAllProducts(opts?: { + variables?: T['variables'] + config?: Partial + preview?: boolean + }): Promise + + async function getAllProducts( + opts: { + variables?: T['variables'] + config?: Partial + preview?: boolean + } & OperationOptions + ): Promise + + async function getAllProducts({ + query = getAllProductsQuery, + variables: vars = {}, + config: cfg, + }: { + query?: string + variables?: T['variables'] + config?: Partial + preview?: boolean + } = {}): Promise { + const config = commerce.getConfig(cfg) + const { locale } = config + const field = getProductsType(vars.relevance) + const variables: GetAllProductsQueryVariables = { + locale, + hasLocale: !!locale, + } + + variables[field] = true + + if (vars.first) variables.first = vars.first + if (vars.ids) variables.entityIds = vars.ids.map((id) => Number(id)) + + // RecursivePartial forces the method to check for every prop in the data, which is + // required in case there's a custom `query` + const { data } = await config.fetch>( + query, + { variables } + ) + const edges = data.site?.[field]?.edges + const products = filterEdges(edges as RecursiveRequired) + + if (locale && config.applyLocale) { + products.forEach((product: RecursivePartial) => { + if (product.node) setProductLocaleMeta(product.node) + }) + } + + return { + products: products.map(({ node }) => normalizeProduct(node as any)), + } + } + + return getAllProducts +} diff --git a/framework/bigcommerce/api/operations/get-customer-wishlist.ts b/framework/bigcommerce/api/operations/get-customer-wishlist.ts new file mode 100644 index 000000000..fc9487ffe --- /dev/null +++ b/framework/bigcommerce/api/operations/get-customer-wishlist.ts @@ -0,0 +1,81 @@ +import type { + OperationContext, + OperationOptions, +} from '@commerce/api/operations' +import type { + GetCustomerWishlistOperation, + Wishlist, +} from '../../types/wishlist' +import type { RecursivePartial, RecursiveRequired } from '../utils/types' +import { BigcommerceConfig, Provider } from '..' +import getAllProducts, { ProductEdge } from './get-all-products' + +export default function getCustomerWishlistOperation({ + commerce, +}: OperationContext) { + async function getCustomerWishlist< + T extends GetCustomerWishlistOperation + >(opts: { + variables: T['variables'] + config?: BigcommerceConfig + includeProducts?: boolean + }): Promise + + async function getCustomerWishlist( + opts: { + variables: T['variables'] + config?: BigcommerceConfig + includeProducts?: boolean + } & OperationOptions + ): Promise + + async function getCustomerWishlist({ + config, + variables, + includeProducts, + }: { + url?: string + variables: T['variables'] + config?: BigcommerceConfig + includeProducts?: boolean + }): Promise { + config = commerce.getConfig(config) + + const { data = [] } = await config.storeApiFetch< + RecursivePartial<{ data: Wishlist[] }> + >(`/v3/wishlists?customer_id=${variables.customerId}`) + const wishlist = data[0] + + if (includeProducts && wishlist?.items?.length) { + const ids = wishlist.items + ?.map((item) => (item?.product_id ? String(item?.product_id) : null)) + .filter((id): id is string => !!id) + + if (ids?.length) { + const graphqlData = await commerce.getAllProducts({ + variables: { first: 100, ids }, + config, + }) + // Put the products in an object that we can use to get them by id + const productsById = graphqlData.products.reduce<{ + [k: number]: ProductEdge + }>((prods, p) => { + 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) { + // @ts-ignore Fix this type when the wishlist type is properly defined + item.product = product + } + }) + } + } + + return { wishlist: wishlist as RecursiveRequired } + } + + return getCustomerWishlist +} diff --git a/framework/bigcommerce/api/operations/get-page.ts b/framework/bigcommerce/api/operations/get-page.ts new file mode 100644 index 000000000..6a1fea9d0 --- /dev/null +++ b/framework/bigcommerce/api/operations/get-page.ts @@ -0,0 +1,54 @@ +import type { + OperationContext, + OperationOptions, +} from '@commerce/api/operations' +import type { GetPageOperation, Page } from '../../types/page' +import type { RecursivePartial, RecursiveRequired } from '../utils/types' +import type { BigcommerceConfig, Provider } from '..' +import { normalizePage } from '../../lib/normalize' + +export default function getPageOperation({ + commerce, +}: OperationContext) { + async function getPage(opts: { + variables: T['variables'] + config?: Partial + preview?: boolean + }): Promise + + async function getPage( + opts: { + variables: T['variables'] + config?: Partial + preview?: boolean + } & OperationOptions + ): Promise + + async function getPage({ + url, + variables, + config, + preview, + }: { + url?: string + variables: T['variables'] + config?: Partial + preview?: boolean + }): Promise { + const cfg = commerce.getConfig(config) + // RecursivePartial forces the method to check for every prop in the data, which is + // required in case there's a custom `url` + const { data } = await cfg.storeApiFetch< + RecursivePartial<{ data: Page[] }> + >(url || `/v3/content/pages?id=${variables.id}&include=body`) + const firstPage = data?.[0] + const page = firstPage as RecursiveRequired + + if (preview || page?.is_visible) { + return { page: normalizePage(page as any) } + } + return {} + } + + return getPage +} diff --git a/framework/bigcommerce/api/operations/get-product.ts b/framework/bigcommerce/api/operations/get-product.ts new file mode 100644 index 000000000..fb356e952 --- /dev/null +++ b/framework/bigcommerce/api/operations/get-product.ts @@ -0,0 +1,119 @@ +import type { + OperationContext, + OperationOptions, +} from '@commerce/api/operations' +import type { GetProductOperation } from '../../types/product' +import type { GetProductQuery, GetProductQueryVariables } from '../../schema' +import setProductLocaleMeta from '../utils/set-product-locale-meta' +import { productInfoFragment } from '../fragments/product' +import { BigcommerceConfig, Provider } from '..' +import { normalizeProduct } from '../../lib/normalize' + +export const getProductQuery = /* GraphQL */ ` + query getProduct( + $hasLocale: Boolean = false + $locale: String = "null" + $path: String! + ) { + site { + route(path: $path) { + node { + __typename + ... on Product { + ...productInfo + variants { + edges { + node { + entityId + defaultImage { + urlOriginal + altText + isDefault + } + prices { + ...productPrices + } + inventory { + aggregated { + availableToSell + warningLevel + } + isInStock + } + productOptions { + edges { + node { + __typename + entityId + displayName + ...multipleChoiceOption + } + } + } + } + } + } + } + } + } + } + } + + ${productInfoFragment} +` + +// TODO: See if this type is useful for defining the Product type +// export type ProductNode = Extract< +// GetProductQuery['site']['route']['node'], +// { __typename: 'Product' } +// > + +export default function getAllProductPathsOperation({ + commerce, +}: OperationContext) { + async function getProduct(opts: { + variables: T['variables'] + config?: Partial + preview?: boolean + }): Promise + + async function getProduct( + opts: { + variables: T['variables'] + config?: Partial + preview?: boolean + } & OperationOptions + ): Promise + + async function getProduct({ + query = getProductQuery, + variables: { slug, ...vars }, + config: cfg, + }: { + query?: string + variables: T['variables'] + config?: Partial + preview?: boolean + }): Promise { + const config = commerce.getConfig(cfg) + const { locale } = config + const variables: GetProductQueryVariables = { + locale, + hasLocale: !!locale, + path: slug ? `/${slug}/` : vars.path!, + } + const { data } = await config.fetch(query, { variables }) + const product = data.site?.route?.node + + if (product?.__typename === 'Product') { + if (locale && config.applyLocale) { + setProductLocaleMeta(product) + } + + return { product: normalizeProduct(product as any) } + } + + return {} + } + return getProduct +} diff --git a/framework/bigcommerce/api/operations/get-site-info.ts b/framework/bigcommerce/api/operations/get-site-info.ts new file mode 100644 index 000000000..0dd94dd9d --- /dev/null +++ b/framework/bigcommerce/api/operations/get-site-info.ts @@ -0,0 +1,87 @@ +import type { + OperationContext, + OperationOptions, +} from '@commerce/api/operations' +import type { GetSiteInfoOperation } from '../../types/site' +import type { GetSiteInfoQuery } from '../../schema' +import filterEdges from '../utils/filter-edges' +import type { BigcommerceConfig, Provider } from '..' +import { categoryTreeItemFragment } from '../fragments/category-tree' +import { normalizeCategory } from '../../lib/normalize' + +// Get 3 levels of categories +export const getSiteInfoQuery = /* GraphQL */ ` + query getSiteInfo { + site { + categoryTree { + ...categoryTreeItem + children { + ...categoryTreeItem + children { + ...categoryTreeItem + } + } + } + brands { + pageInfo { + startCursor + endCursor + } + edges { + cursor + node { + entityId + name + defaultImage { + urlOriginal + altText + } + pageTitle + metaDesc + metaKeywords + searchKeywords + path + } + } + } + } + } + ${categoryTreeItemFragment} +` + +export default function getSiteInfoOperation({ + commerce, +}: OperationContext) { + async function getSiteInfo(opts?: { + config?: Partial + preview?: boolean + }): Promise + + async function getSiteInfo( + opts: { + config?: Partial + preview?: boolean + } & OperationOptions + ): Promise + + async function getSiteInfo({ + query = getSiteInfoQuery, + config, + }: { + query?: string + config?: Partial + preview?: boolean + } = {}): Promise { + const cfg = commerce.getConfig(config) + const { data } = await cfg.fetch(query) + const categories = data.site.categoryTree.map(normalizeCategory) + const brands = data.site?.brands?.edges + + return { + categories: categories ?? [], + brands: filterEdges(brands), + } + } + + return getSiteInfo +} diff --git a/framework/bigcommerce/api/operations/login.ts b/framework/bigcommerce/api/operations/login.ts new file mode 100644 index 000000000..021ba3c65 --- /dev/null +++ b/framework/bigcommerce/api/operations/login.ts @@ -0,0 +1,79 @@ +import type { ServerResponse } from 'http' +import type { + OperationContext, + OperationOptions, +} from '@commerce/api/operations' +import type { LoginOperation } from '../../types/login' +import type { LoginMutation } from '../../schema' +import type { RecursivePartial } from '../utils/types' +import concatHeader from '../utils/concat-cookie' +import type { BigcommerceConfig, Provider } from '..' + +export const loginMutation = /* GraphQL */ ` + mutation login($email: String!, $password: String!) { + login(email: $email, password: $password) { + result + } + } +` + +export default function loginOperation({ + commerce, +}: OperationContext) { + async function login(opts: { + variables: T['variables'] + config?: BigcommerceConfig + res: ServerResponse + }): Promise + + async function login( + opts: { + variables: T['variables'] + config?: BigcommerceConfig + res: ServerResponse + } & OperationOptions + ): Promise + + async function login({ + query = loginMutation, + variables, + res: response, + config, + }: { + query?: string + variables: T['variables'] + res: ServerResponse + config?: BigcommerceConfig + }): Promise { + config = commerce.getConfig(config) + + const { data, res } = await config.fetch>( + query, + { variables } + ) + // Bigcommerce returns a Set-Cookie header with the auth cookie + let cookie = res.headers.get('Set-Cookie') + + if (cookie && typeof cookie === 'string') { + // In development, don't set a secure cookie or the browser will ignore it + if (process.env.NODE_ENV !== 'production') { + cookie = cookie.replace('; Secure', '') + // SameSite=none can't be set unless the cookie is Secure + // bc seems to sometimes send back SameSite=None rather than none so make + // this case insensitive + cookie = cookie.replace(/; SameSite=none/gi, '; SameSite=lax') + } + + response.setHeader( + 'Set-Cookie', + concatHeader(response.getHeader('Set-Cookie'), cookie)! + ) + } + + return { + result: data.login?.result, + } + } + + return login +} diff --git a/framework/bigcommerce/api/utils/create-api-handler.ts b/framework/bigcommerce/api/utils/create-api-handler.ts deleted file mode 100644 index 315ec464b..000000000 --- a/framework/bigcommerce/api/utils/create-api-handler.ts +++ /dev/null @@ -1,58 +0,0 @@ -import type { NextApiHandler, NextApiRequest, NextApiResponse } from 'next' -import { BigcommerceConfig, getConfig } from '..' - -export type BigcommerceApiHandler< - T = any, - H extends BigcommerceHandlers = {}, - Options extends {} = {} -> = ( - req: NextApiRequest, - res: NextApiResponse>, - config: BigcommerceConfig, - handlers: H, - // Custom configs that may be used by a particular handler - options: Options -) => void | Promise - -export type BigcommerceHandler = (options: { - req: NextApiRequest - res: NextApiResponse> - config: BigcommerceConfig - body: Body -}) => void | Promise - -export type BigcommerceHandlers = { - [k: string]: BigcommerceHandler -} - -export type BigcommerceApiResponse = { - data: T | null - errors?: { message: string; code?: string }[] -} - -export default function createApiHandler< - T = any, - H extends BigcommerceHandlers = {}, - Options extends {} = {} ->( - handler: BigcommerceApiHandler, - handlers: H, - defaultOptions: Options -) { - return function getApiHandler({ - config, - operations, - options, - }: { - config?: BigcommerceConfig - 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/bigcommerce/api/utils/fetch-graphql-api.ts b/framework/bigcommerce/api/utils/fetch-graphql-api.ts index a449b81e0..7dc39f987 100644 --- a/framework/bigcommerce/api/utils/fetch-graphql-api.ts +++ b/framework/bigcommerce/api/utils/fetch-graphql-api.ts @@ -1,6 +1,6 @@ import { FetcherError } from '@commerce/utils/errors' import type { GraphQLFetcher } from '@commerce/api' -import { getConfig } from '..' +import { provider } from '..' import fetch from './fetch' const fetchGraphqlApi: GraphQLFetcher = async ( @@ -9,7 +9,7 @@ const fetchGraphqlApi: GraphQLFetcher = async ( fetchOptions ) => { // log.warn(query) - const config = getConfig() + const { config } = provider const res = await fetch(config.commerceUrl + (preview ? '/preview' : ''), { ...fetchOptions, method: 'POST', diff --git a/framework/bigcommerce/api/utils/fetch-store-api.ts b/framework/bigcommerce/api/utils/fetch-store-api.ts index 7e59b9f06..a00b3777a 100644 --- a/framework/bigcommerce/api/utils/fetch-store-api.ts +++ b/framework/bigcommerce/api/utils/fetch-store-api.ts @@ -1,5 +1,5 @@ import type { RequestInit, Response } from '@vercel/fetch' -import { getConfig } from '..' +import { provider } from '..' import { BigcommerceApiError, BigcommerceNetworkError } from './errors' import fetch from './fetch' @@ -7,7 +7,7 @@ export default async function fetchStoreApi( endpoint: string, options?: RequestInit ): Promise { - const config = getConfig() + const { config } = provider let res: Response try { diff --git a/framework/bigcommerce/api/utils/is-allowed-method.ts b/framework/bigcommerce/api/utils/is-allowed-method.ts deleted file mode 100644 index 78bbba568..000000000 --- a/framework/bigcommerce/api/utils/is-allowed-method.ts +++ /dev/null @@ -1,28 +0,0 @@ -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/bigcommerce/api/utils/parse-item.ts b/framework/bigcommerce/api/utils/parse-item.ts index 7c8cd4728..14c9ac53d 100644 --- a/framework/bigcommerce/api/utils/parse-item.ts +++ b/framework/bigcommerce/api/utils/parse-item.ts @@ -1,5 +1,5 @@ -import type { ItemBody as WishlistItemBody } from '../wishlist' -import type { CartItemBody, OptionSelections } from '../../types' +import type { WishlistItemBody } from '../../types/wishlist' +import type { CartItemBody, OptionSelections } from '../../types/cart' type BCWishlistItemBody = { product_id: number diff --git a/framework/bigcommerce/api/utils/set-product-locale-meta.ts b/framework/bigcommerce/api/utils/set-product-locale-meta.ts index 974a197bd..767286477 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 '../../product/get-all-products' +import type { ProductNode } from '../operations/get-all-products' import type { RecursivePartial } from './types' export default function setProductLocaleMeta( diff --git a/framework/bigcommerce/api/wishlist/index.ts b/framework/bigcommerce/api/wishlist/index.ts deleted file mode 100644 index 7c700689c..000000000 --- a/framework/bigcommerce/api/wishlist/index.ts +++ /dev/null @@ -1,104 +0,0 @@ -import isAllowedMethod from '../utils/is-allowed-method' -import createApiHandler, { - BigcommerceApiHandler, - BigcommerceHandler, -} from '../utils/create-api-handler' -import { BigcommerceApiError } from '../utils/errors' -import type { - Wishlist, - WishlistItem, -} from '../../customer/get-customer-wishlist' -import getWishlist from './handlers/get-wishlist' -import addItem from './handlers/add-item' -import removeItem from './handlers/remove-item' -import type { Product, ProductVariant, Customer } from '@commerce/types' - -export type { Wishlist, WishlistItem } - -export type ItemBody = { - productId: Product['id'] - variantId: ProductVariant['id'] -} - -export type AddItemBody = { item: ItemBody } - -export type RemoveItemBody = { itemId: Product['id'] } - -export type WishlistBody = { - customer_id: Customer['entityId'] - is_public: number - name: string - items: any[] -} - -export type AddWishlistBody = { wishlist: WishlistBody } - -export type WishlistHandlers = { - getWishlist: BigcommerceHandler< - Wishlist, - { customerToken?: string; includeProducts?: boolean } - > - addItem: BigcommerceHandler< - Wishlist, - { customerToken?: string } & Partial - > - removeItem: BigcommerceHandler< - Wishlist, - { customerToken?: string } & Partial - > -} - -const METHODS = ['GET', 'POST', 'DELETE'] - -// TODO: a complete implementation should have schema validation for `req.body` -const wishlistApi: BigcommerceApiHandler = async ( - req, - res, - config, - handlers -) => { - if (!isAllowedMethod(req, res, METHODS)) return - - const { cookies } = req - const customerToken = cookies[config.customerCookie] - - try { - // Return current wishlist info - if (req.method === 'GET') { - const body = { - customerToken, - includeProducts: req.query.products === '1', - } - return await handlers['getWishlist']({ req, res, config, body }) - } - - // Add an item to the wishlist - if (req.method === 'POST') { - const body = { ...req.body, customerToken } - return await handlers['addItem']({ req, res, config, body }) - } - - // Remove an item from the wishlist - if (req.method === 'DELETE') { - const body = { ...req.body, customerToken } - return await handlers['removeItem']({ req, res, config, body }) - } - } catch (error) { - console.error(error) - - const message = - error instanceof BigcommerceApiError - ? 'An unexpected error ocurred with the Bigcommerce API' - : 'An unexpected error ocurred' - - res.status(500).json({ data: null, errors: [{ message }] }) - } -} - -export const handlers = { - getWishlist, - addItem, - removeItem, -} - -export default createApiHandler(wishlistApi, handlers, {}) diff --git a/framework/bigcommerce/auth/login.ts b/framework/bigcommerce/auth/login.ts deleted file mode 100644 index 3fef29879..000000000 --- a/framework/bigcommerce/auth/login.ts +++ /dev/null @@ -1,73 +0,0 @@ -import type { ServerResponse } from 'http' -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!) { - login(email: $email, password: $password) { - result - } - } -` - -export type LoginResult = T - -export type LoginVariables = LoginMutationVariables - -async function login(opts: { - variables: LoginVariables - config?: BigcommerceConfig - res: ServerResponse -}): Promise - -async function login(opts: { - query: string - variables: V - res: ServerResponse - config?: BigcommerceConfig -}): Promise> - -async function login({ - query = loginMutation, - variables, - res: response, - config, -}: { - query?: string - variables: LoginVariables - res: ServerResponse - config?: BigcommerceConfig -}): Promise { - config = getConfig(config) - - const { data, res } = await config.fetch>( - query, - { variables } - ) - // Bigcommerce returns a Set-Cookie header with the auth cookie - let cookie = res.headers.get('Set-Cookie') - - if (cookie && typeof cookie === 'string') { - // In development, don't set a secure cookie or the browser will ignore it - if (process.env.NODE_ENV !== 'production') { - cookie = cookie.replace('; Secure', '') - // SameSite=none can't be set unless the cookie is Secure - // bc seems to sometimes send back SameSite=None rather than none so make - // this case insensitive - cookie = cookie.replace(/; SameSite=none/gi, '; SameSite=lax') - } - - response.setHeader( - 'Set-Cookie', - concatHeader(response.getHeader('Set-Cookie'), cookie)! - ) - } - - return { - result: data.login?.result, - } -} - -export default login diff --git a/framework/bigcommerce/auth/use-login.tsx b/framework/bigcommerce/auth/use-login.tsx index 1be96a58c..3ebacc9b7 100644 --- a/framework/bigcommerce/auth/use-login.tsx +++ b/framework/bigcommerce/auth/use-login.tsx @@ -2,14 +2,14 @@ import { useCallback } from 'react' import type { MutationHook } from '@commerce/utils/types' import { CommerceError } from '@commerce/utils/errors' import useLogin, { UseLogin } from '@commerce/auth/use-login' -import type { LoginBody } from '../api/customers/login' +import type { LoginHook } from '../types/login' import useCustomer from '../customer/use-customer' export default useLogin as UseLogin -export const handler: MutationHook = { +export const handler: MutationHook = { fetchOptions: { - url: '/api/bigcommerce/customers/login', + url: '/api/login', method: 'POST', }, async fetcher({ input: { email, password }, options, fetch }) { diff --git a/framework/bigcommerce/auth/use-logout.tsx b/framework/bigcommerce/auth/use-logout.tsx index 71015a1c1..e75563e04 100644 --- a/framework/bigcommerce/auth/use-logout.tsx +++ b/framework/bigcommerce/auth/use-logout.tsx @@ -1,13 +1,14 @@ import { useCallback } from 'react' import type { MutationHook } from '@commerce/utils/types' import useLogout, { UseLogout } from '@commerce/auth/use-logout' +import type { LogoutHook } from '../types/logout' import useCustomer from '../customer/use-customer' export default useLogout as UseLogout -export const handler: MutationHook = { +export const handler: MutationHook = { fetchOptions: { - url: '/api/bigcommerce/customers/logout', + url: '/api/logout', method: 'GET', }, useHook: ({ fetch }) => () => { diff --git a/framework/bigcommerce/auth/use-signup.tsx b/framework/bigcommerce/auth/use-signup.tsx index 28f7024ef..da06fd3eb 100644 --- a/framework/bigcommerce/auth/use-signup.tsx +++ b/framework/bigcommerce/auth/use-signup.tsx @@ -2,14 +2,14 @@ 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 type { SignupBody } from '../api/customers/signup' +import type { SignupHook } from '../types/signup' import useCustomer from '../customer/use-customer' export default useSignup as UseSignup -export const handler: MutationHook = { +export const handler: MutationHook = { fetchOptions: { - url: '/api/bigcommerce/customers/signup', + url: '/api/signup', method: 'POST', }, async fetcher({ diff --git a/framework/bigcommerce/cart/use-add-item.tsx b/framework/bigcommerce/cart/use-add-item.tsx index d74c23567..1ac6ac6f8 100644 --- a/framework/bigcommerce/cart/use-add-item.tsx +++ b/framework/bigcommerce/cart/use-add-item.tsx @@ -2,20 +2,14 @@ import { useCallback } from 'react' import type { MutationHook } from '@commerce/utils/types' import { CommerceError } from '@commerce/utils/errors' import useAddItem, { UseAddItem } from '@commerce/cart/use-add-item' -import { normalizeCart } from '../lib/normalize' -import type { - Cart, - BigcommerceCart, - CartItemBody, - AddCartItemBody, -} from '../types' +import type { AddItemHook } from '@commerce/types/cart' import useCart from './use-cart' export default useAddItem as UseAddItem -export const handler: MutationHook = { +export const handler: MutationHook = { fetchOptions: { - url: '/api/bigcommerce/cart', + url: '/api/cart', method: 'POST', }, async fetcher({ input: item, options, fetch }) { @@ -28,12 +22,12 @@ export const handler: MutationHook = { }) } - const data = await fetch({ + const data = await fetch({ ...options, body: { item }, }) - return normalizeCart(data) + return data }, useHook: ({ fetch }) => () => { const { mutate } = useCart() diff --git a/framework/bigcommerce/cart/use-cart.tsx b/framework/bigcommerce/cart/use-cart.tsx index 2098e7431..4ba1724d9 100644 --- a/framework/bigcommerce/cart/use-cart.tsx +++ b/framework/bigcommerce/cart/use-cart.tsx @@ -1,25 +1,15 @@ import { useMemo } from 'react' import { SWRHook } from '@commerce/utils/types' -import useCart, { UseCart, FetchCartInput } from '@commerce/cart/use-cart' -import { normalizeCart } from '../lib/normalize' -import type { Cart } from '../types' +import useCart, { UseCart } from '@commerce/cart/use-cart' +import type { GetCartHook } from '@commerce/types/cart' export default useCart as UseCart -export const handler: SWRHook< - Cart | null, - {}, - FetchCartInput, - { isEmpty?: boolean } -> = { +export const handler: SWRHook = { fetchOptions: { - url: '/api/bigcommerce/cart', + url: '/api/cart', method: 'GET', }, - async fetcher({ input: { cartId }, options, fetch }) { - const data = cartId ? await fetch(options) : null - return data && normalizeCart(data) - }, useHook: ({ useData }) => (input) => { const response = useData({ swrOptions: { revalidateOnFocus: false, ...input?.swrOptions }, diff --git a/framework/bigcommerce/cart/use-remove-item.tsx b/framework/bigcommerce/cart/use-remove-item.tsx index 186780d6a..1376f29ce 100644 --- a/framework/bigcommerce/cart/use-remove-item.tsx +++ b/framework/bigcommerce/cart/use-remove-item.tsx @@ -4,48 +4,33 @@ import type { HookFetcherContext, } from '@commerce/utils/types' import { ValidationError } from '@commerce/utils/errors' -import useRemoveItem, { - RemoveItemInput as RemoveItemInputBase, - UseRemoveItem, -} from '@commerce/cart/use-remove-item' -import { normalizeCart } from '../lib/normalize' -import type { - RemoveCartItemBody, - Cart, - BigcommerceCart, - LineItem, -} from '../types' +import useRemoveItem, { UseRemoveItem } from '@commerce/cart/use-remove-item' +import type { Cart, LineItem, RemoveItemHook } from '@commerce/types/cart' import useCart from './use-cart' export type RemoveItemFn = T extends LineItem - ? (input?: RemoveItemInput) => Promise - : (input: RemoveItemInput) => Promise + ? (input?: RemoveItemActionInput) => Promise + : (input: RemoveItemActionInput) => Promise -export type RemoveItemInput = T extends LineItem - ? Partial - : RemoveItemInputBase +export type RemoveItemActionInput = T extends LineItem + ? Partial + : RemoveItemHook['actionInput'] export default useRemoveItem as UseRemoveItem export const handler = { fetchOptions: { - url: '/api/bigcommerce/cart', + url: '/api/cart', method: 'DELETE', }, async fetcher({ input: { itemId }, options, fetch, - }: HookFetcherContext) { - const data = await fetch({ - ...options, - body: { itemId }, - }) - return normalizeCart(data) + }: HookFetcherContext) { + return await fetch({ ...options, body: { itemId } }) }, - useHook: ({ - fetch, - }: MutationHookContext) => < + useHook: ({ fetch }: MutationHookContext) => < T extends LineItem | undefined = undefined >( ctx: { item?: T } = {} diff --git a/framework/bigcommerce/cart/use-update-item.tsx b/framework/bigcommerce/cart/use-update-item.tsx index f1840f806..0f9f5754d 100644 --- a/framework/bigcommerce/cart/use-update-item.tsx +++ b/framework/bigcommerce/cart/use-update-item.tsx @@ -5,36 +5,27 @@ import type { HookFetcherContext, } from '@commerce/utils/types' import { ValidationError } from '@commerce/utils/errors' -import useUpdateItem, { - UpdateItemInput as UpdateItemInputBase, - UseUpdateItem, -} from '@commerce/cart/use-update-item' -import { normalizeCart } from '../lib/normalize' -import type { - UpdateCartItemBody, - Cart, - BigcommerceCart, - LineItem, -} from '../types' +import useUpdateItem, { UseUpdateItem } from '@commerce/cart/use-update-item' +import type { LineItem, UpdateItemHook } from '@commerce/types/cart' import { handler as removeItemHandler } from './use-remove-item' import useCart from './use-cart' -export type UpdateItemInput = T extends LineItem - ? Partial> - : UpdateItemInputBase +export type UpdateItemActionInput = T extends LineItem + ? Partial + : UpdateItemHook['actionInput'] export default useUpdateItem as UseUpdateItem export const handler = { fetchOptions: { - url: '/api/bigcommerce/cart', + url: '/api/cart', method: 'PUT', }, async fetcher({ input: { itemId, item }, options, fetch, - }: HookFetcherContext) { + }: 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) { @@ -50,16 +41,12 @@ export const handler = { }) } - const data = await fetch({ + return await fetch({ ...options, body: { itemId, item }, }) - - return normalizeCart(data) }, - useHook: ({ - fetch, - }: MutationHookContext) => < + useHook: ({ fetch }: MutationHookContext) => < T extends LineItem | undefined = undefined >( ctx: { @@ -71,7 +58,7 @@ export const handler = { const { mutate } = useCart() as any return useCallback( - debounce(async (input: UpdateItemInput) => { + debounce(async (input: UpdateItemActionInput) => { const itemId = input.id ?? item?.id const productId = input.productId ?? item?.productId const variantId = input.productId ?? item?.variantId diff --git a/framework/bigcommerce/common/get-all-pages.ts b/framework/bigcommerce/common/get-all-pages.ts deleted file mode 100644 index dc5eb15a5..000000000 --- a/framework/bigcommerce/common/get-all-pages.ts +++ /dev/null @@ -1,43 +0,0 @@ -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'] - -export type GetAllPagesResult< - T extends { pages: any[] } = { pages: Page[] } -> = T - -async function getAllPages(opts?: { - config?: BigcommerceConfig - preview?: boolean -}): Promise - -async function getAllPages(opts: { - url: string - config?: BigcommerceConfig - preview?: boolean -}): Promise> - -async function getAllPages({ - config, - preview, -}: { - url?: string - config?: BigcommerceConfig - preview?: boolean -} = {}): Promise { - config = getConfig(config) - // RecursivePartial forces the method to check for every prop in the data, which is - // required in case there's a custom `url` - const { data } = await config.storeApiFetch< - RecursivePartial<{ data: Page[] }> - >('/v3/content/pages') - const pages = (data as RecursiveRequired) ?? [] - - return { - pages: preview ? pages : pages.filter((p) => p.is_visible), - } -} - -export default getAllPages diff --git a/framework/bigcommerce/common/get-page.ts b/framework/bigcommerce/common/get-page.ts deleted file mode 100644 index 932032efb..000000000 --- a/framework/bigcommerce/common/get-page.ts +++ /dev/null @@ -1,53 +0,0 @@ -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'] - -export type GetPageResult = T - -export type PageVariables = { - id: number -} - -async function getPage(opts: { - url?: string - variables: PageVariables - config?: BigcommerceConfig - preview?: boolean -}): Promise - -async function getPage(opts: { - url: string - variables: V - config?: BigcommerceConfig - preview?: boolean -}): Promise> - -async function getPage({ - url, - variables, - config, - preview, -}: { - url?: string - variables: PageVariables - config?: BigcommerceConfig - preview?: boolean -}): Promise { - config = getConfig(config) - // RecursivePartial forces the method to check for every prop in the data, which is - // required in case there's a custom `url` - const { data } = await config.storeApiFetch< - RecursivePartial<{ data: Page[] }> - >(url || `/v3/content/pages?id=${variables.id}&include=body`) - const firstPage = data?.[0] - const page = firstPage as RecursiveRequired - - if (preview || page?.is_visible) { - return { page } - } - return {} -} - -export default getPage diff --git a/framework/bigcommerce/common/get-site-info.ts b/framework/bigcommerce/common/get-site-info.ts deleted file mode 100644 index a39608d38..000000000 --- a/framework/bigcommerce/common/get-site-info.ts +++ /dev/null @@ -1,117 +0,0 @@ -import type { GetSiteInfoQuery, GetSiteInfoQueryVariables } from '../schema' -import type { RecursivePartial, RecursiveRequired } from '../api/utils/types' -import filterEdges from '../api/utils/filter-edges' -import { BigcommerceConfig, getConfig } from '../api' -import { categoryTreeItemFragment } from '../api/fragments/category-tree' -import { Category } from '@commerce/types' -import getSlug from '@lib/get-slug' - -// Get 3 levels of categories -export const getSiteInfoQuery = /* GraphQL */ ` - query getSiteInfo { - site { - categoryTree { - ...categoryTreeItem - children { - ...categoryTreeItem - children { - ...categoryTreeItem - } - } - } - brands { - pageInfo { - startCursor - endCursor - } - edges { - cursor - node { - entityId - name - defaultImage { - urlOriginal - altText - } - pageTitle - metaDesc - metaKeywords - searchKeywords - path - } - } - } - } - } - ${categoryTreeItemFragment} -` - -export type CategoriesTree = NonNullable< - GetSiteInfoQuery['site']['categoryTree'] -> - -export type BrandEdge = NonNullable< - NonNullable[0] -> - -export type Brands = BrandEdge[] - -export type GetSiteInfoResult< - T extends { categories: any[]; brands: any[] } = { - categories: Category[] - brands: Brands - } -> = T - -async function getSiteInfo(opts?: { - variables?: GetSiteInfoQueryVariables - config?: BigcommerceConfig - preview?: boolean -}): Promise - -async function getSiteInfo< - T extends { categories: Category[]; brands: any[] }, - V = any ->(opts: { - query: string - variables?: V - config?: BigcommerceConfig - preview?: boolean -}): Promise> - -async function getSiteInfo({ - query = getSiteInfoQuery, - variables, - config, -}: { - query?: string - variables?: GetSiteInfoQueryVariables - config?: BigcommerceConfig - preview?: boolean -} = {}): Promise { - config = getConfig(config) - // RecursivePartial forces the method to check for every prop in the data, which is - // required in case there's a custom `query` - const { data } = await config.fetch>( - query, - { variables } - ) - - let categories = data!.site!.categoryTree?.map( - ({ entityId, name, path }: any) => ({ - id: `${entityId}`, - name, - slug: getSlug(path), - path, - }) - ) - - const brands = data.site?.brands?.edges - - return { - categories: categories ?? [], - brands: filterEdges(brands as RecursiveRequired), - } -} - -export default getSiteInfo diff --git a/framework/bigcommerce/customer/get-customer-wishlist.ts b/framework/bigcommerce/customer/get-customer-wishlist.ts deleted file mode 100644 index 97e5654a9..000000000 --- a/framework/bigcommerce/customer/get-customer-wishlist.ts +++ /dev/null @@ -1,88 +0,0 @@ -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[] -} - -export type WishlistItem = NonNullable< - definitions['wishlist_Full']['items'] ->[0] & { - product?: ProductEdge['node'] -} - -export type GetCustomerWishlistResult< - T extends { wishlist?: any } = { wishlist?: Wishlist } -> = T - -export type GetCustomerWishlistVariables = { - customerId: number -} - -async function getCustomerWishlist(opts: { - variables: GetCustomerWishlistVariables - config?: BigcommerceConfig - includeProducts?: boolean -}): Promise - -async function getCustomerWishlist< - T extends { wishlist?: any }, - V = any ->(opts: { - url: string - variables: V - config?: BigcommerceConfig - includeProducts?: boolean -}): Promise> - -async function getCustomerWishlist({ - config, - variables, - includeProducts, -}: { - url?: string - variables: GetCustomerWishlistVariables - config?: BigcommerceConfig - includeProducts?: boolean -}): Promise { - config = getConfig(config) - - const { data = [] } = await config.storeApiFetch< - RecursivePartial<{ data: Wishlist[] }> - >(`/v3/wishlists?customer_id=${variables.customerId}`) - const wishlist = data[0] - - if (includeProducts && wishlist?.items?.length) { - const entityIds = wishlist.items - ?.map((item) => item?.product_id) - .filter((id): id is number => !!id) - - if (entityIds?.length) { - const graphqlData = await getAllProducts({ - variables: { first: 100, 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 - }>((prods, p) => { - 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) { - // @ts-ignore Fix this type when the wishlist type is properly defined - item.product = product - } - }) - } - } - - return { wishlist: wishlist as RecursiveRequired } -} - -export default getCustomerWishlist diff --git a/framework/bigcommerce/customer/use-customer.tsx b/framework/bigcommerce/customer/use-customer.tsx index 093007824..238b1229b 100644 --- a/framework/bigcommerce/customer/use-customer.tsx +++ b/framework/bigcommerce/customer/use-customer.tsx @@ -1,16 +1,16 @@ import { SWRHook } from '@commerce/utils/types' import useCustomer, { UseCustomer } from '@commerce/customer/use-customer' -import type { Customer, CustomerData } from '../api/customers' +import type { CustomerHook } from '../types/customer' export default useCustomer as UseCustomer -export const handler: SWRHook = { +export const handler: SWRHook = { fetchOptions: { - url: '/api/bigcommerce/customers', + url: '/api/customer', method: 'GET', }, async fetcher({ options, fetch }) { - const data = await fetch(options) + const data = await fetch(options) return data?.customer ?? null }, useHook: ({ useData }) => (input) => { diff --git a/framework/bigcommerce/lib/get-slug.ts b/framework/bigcommerce/lib/get-slug.ts new file mode 100644 index 000000000..329c5a27e --- /dev/null +++ b/framework/bigcommerce/lib/get-slug.ts @@ -0,0 +1,5 @@ +// Remove trailing and leading slash, usually included in nodes +// returned by the BigCommerce API +const getSlug = (path: string) => path.replace(/^\/|\/$/g, '') + +export default getSlug diff --git a/framework/bigcommerce/lib/normalize.ts b/framework/bigcommerce/lib/normalize.ts index cc7606099..cd1c3ce5a 100644 --- a/framework/bigcommerce/lib/normalize.ts +++ b/framework/bigcommerce/lib/normalize.ts @@ -1,6 +1,10 @@ -import type { Product } from '@commerce/types' -import type { Cart, BigcommerceCart, LineItem } from '../types' +import type { Product } from '../types/product' +import type { Cart, BigcommerceCart, LineItem } from '../types/cart' +import type { Page } from '../types/page' +import type { BCCategory, Category } from '../types/site' +import { definitions } from '../api/definitions/store-content' import update from './immutability' +import getSlug from './get-slug' function normalizeProductOption(productOption: any) { const { @@ -69,6 +73,16 @@ export function normalizeProduct(productNode: any): Product { }) } +export function normalizePage(page: definitions['page_Full']): Page { + return { + id: String(page.id), + name: page.name, + is_visible: page.is_visible, + sort_order: page.sort_order, + body: page.body, + } +} + export function normalizeCart(data: BigcommerceCart): Cart { return { id: data.id, @@ -111,3 +125,12 @@ function normalizeLineItem(item: any): LineItem { })), } } + +export function normalizeCategory(category: BCCategory): Category { + return { + id: `${category.entityId}`, + name: category.name, + slug: getSlug(category.path), + path: category.path, + } +} diff --git a/framework/bigcommerce/product/get-all-product-paths.ts b/framework/bigcommerce/product/get-all-product-paths.ts deleted file mode 100644 index c1b23b38d..000000000 --- a/framework/bigcommerce/product/get-all-product-paths.ts +++ /dev/null @@ -1,71 +0,0 @@ -import type { - GetAllProductPathsQuery, - GetAllProductPathsQueryVariables, -} 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) { - site { - products(first: $first) { - edges { - node { - path - } - } - } - } - } -` - -export type ProductPath = NonNullable< - NonNullable[0] -> - -export type ProductPaths = ProductPath[] - -export type { GetAllProductPathsQueryVariables } - -export type GetAllProductPathsResult< - T extends { products: any[] } = { products: ProductPaths } -> = T - -async function getAllProductPaths(opts?: { - variables?: GetAllProductPathsQueryVariables - config?: BigcommerceConfig -}): Promise - -async function getAllProductPaths< - T extends { products: any[] }, - V = any ->(opts: { - query: string - variables?: V - config?: BigcommerceConfig -}): Promise> - -async function getAllProductPaths({ - query = getAllProductPathsQuery, - variables, - config, -}: { - query?: string - variables?: GetAllProductPathsQueryVariables - config?: BigcommerceConfig -} = {}): Promise { - config = getConfig(config) - // RecursivePartial forces the method to check for every prop in the data, which is - // required in case there's a custom `query` - const { data } = await config.fetch< - RecursivePartial - >(query, { variables }) - const products = data.site?.products?.edges - - return { - products: filterEdges(products as RecursiveRequired), - } -} - -export default getAllProductPaths diff --git a/framework/bigcommerce/product/get-all-products.ts b/framework/bigcommerce/product/get-all-products.ts deleted file mode 100644 index 4c563bc62..000000000 --- a/framework/bigcommerce/product/get-all-products.ts +++ /dev/null @@ -1,135 +0,0 @@ -import type { - GetAllProductsQuery, - GetAllProductsQueryVariables, -} from '../schema' -import type { Product } from '@commerce/types' -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( - $hasLocale: Boolean = false - $locale: String = "null" - $entityIds: [Int!] - $first: Int = 10 - $products: Boolean = false - $featuredProducts: Boolean = false - $bestSellingProducts: Boolean = false - $newestProducts: Boolean = false - ) { - site { - products(first: $first, entityIds: $entityIds) @include(if: $products) { - ...productConnnection - } - featuredProducts(first: $first) @include(if: $featuredProducts) { - ...productConnnection - } - bestSellingProducts(first: $first) @include(if: $bestSellingProducts) { - ...productConnnection - } - newestProducts(first: $first) @include(if: $newestProducts) { - ...productConnnection - } - } - } - - ${productConnectionFragment} -` - -export type ProductEdge = NonNullable< - NonNullable[0] -> - -export type ProductNode = ProductEdge['node'] - -export type GetAllProductsResult< - T extends Record = { - products: ProductEdge[] - } -> = T - -const FIELDS = [ - 'products', - 'featuredProducts', - 'bestSellingProducts', - 'newestProducts', -] - -export type ProductTypes = - | 'products' - | 'featuredProducts' - | 'bestSellingProducts' - | 'newestProducts' - -export type ProductVariables = { field?: ProductTypes } & Omit< - GetAllProductsQueryVariables, - ProductTypes | 'hasLocale' -> - -async function getAllProducts(opts?: { - variables?: ProductVariables - config?: BigcommerceConfig - preview?: boolean -}): Promise<{ products: Product[] }> - -async function getAllProducts< - T extends Record, - V = any ->(opts: { - query: string - variables?: V - config?: BigcommerceConfig - preview?: boolean -}): Promise> - -async function getAllProducts({ - query = getAllProductsQuery, - variables: { field = 'products', ...vars } = {}, - config, -}: { - query?: string - variables?: ProductVariables - config?: BigcommerceConfig - preview?: boolean - // TODO: fix the product type here -} = {}): Promise<{ products: Product[] | any[] }> { - config = getConfig(config) - - const locale = vars.locale || config.locale - const variables: GetAllProductsQueryVariables = { - ...vars, - locale, - hasLocale: !!locale, - } - - if (!FIELDS.includes(field)) { - throw new Error( - `The field variable has to match one of ${FIELDS.join(', ')}` - ) - } - - variables[field] = true - - // RecursivePartial forces the method to check for every prop in the data, which is - // required in case there's a custom `query` - const { data } = await config.fetch>( - query, - { variables } - ) - const edges = data.site?.[field]?.edges - const products = filterEdges(edges as RecursiveRequired) - - if (locale && config.applyLocale) { - products.forEach((product: RecursivePartial) => { - if (product.node) setProductLocaleMeta(product.node) - }) - } - - return { products: products.map(({ node }) => normalizeProduct(node as any)) } -} - -export default getAllProducts diff --git a/framework/bigcommerce/product/get-product.ts b/framework/bigcommerce/product/get-product.ts deleted file mode 100644 index b52568b62..000000000 --- a/framework/bigcommerce/product/get-product.ts +++ /dev/null @@ -1,121 +0,0 @@ -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 '../lib/normalize' -import type { Product } from '@commerce/types' - -export const getProductQuery = /* GraphQL */ ` - query getProduct( - $hasLocale: Boolean = false - $locale: String = "null" - $path: String! - ) { - site { - route(path: $path) { - node { - __typename - ... on Product { - ...productInfo - variants { - edges { - node { - entityId - defaultImage { - urlOriginal - altText - isDefault - } - prices { - ...productPrices - } - inventory { - aggregated { - availableToSell - warningLevel - } - isInStock - } - productOptions { - edges { - node { - __typename - entityId - displayName - ...multipleChoiceOption - } - } - } - } - } - } - } - } - } - } - } - - ${productInfoFragment} -` - -export type ProductNode = Extract< - GetProductQuery['site']['route']['node'], - { __typename: 'Product' } -> - -export type GetProductResult< - T extends { product?: any } = { product?: ProductNode } -> = T - -export type ProductVariables = { locale?: string } & ( - | { path: string; slug?: never } - | { path?: never; slug: string } -) - -async function getProduct(opts: { - variables: ProductVariables - config?: BigcommerceConfig - preview?: boolean -}): Promise - -async function getProduct(opts: { - query: string - variables: V - config?: BigcommerceConfig - preview?: boolean -}): Promise> - -async function getProduct({ - query = getProductQuery, - variables: { slug, ...vars }, - config, -}: { - query?: string - variables: ProductVariables - config?: BigcommerceConfig - preview?: boolean -}): Promise { - config = getConfig(config) - - const locale = vars.locale || config.locale - const variables: GetProductQueryVariables = { - ...vars, - locale, - hasLocale: !!locale, - path: slug ? `/${slug}/` : vars.path!, - } - const { data } = await config.fetch(query, { variables }) - const product = data.site?.route?.node - - if (product?.__typename === 'Product') { - if (locale && config.applyLocale) { - setProductLocaleMeta(product) - } - - return { product: normalizeProduct(product as any) } - } - - return {} -} - -export default getProduct diff --git a/framework/bigcommerce/product/index.ts b/framework/bigcommerce/product/index.ts index b290c189f..426a3edcd 100644 --- a/framework/bigcommerce/product/index.ts +++ b/framework/bigcommerce/product/index.ts @@ -1,4 +1,2 @@ export { default as usePrice } from './use-price' export { default as useSearch } from './use-search' -export { default as getProduct } from './get-product' -export { default as getAllProducts } from './get-all-products' diff --git a/framework/bigcommerce/product/use-search.tsx b/framework/bigcommerce/product/use-search.tsx index ff0ed848c..bea01753b 100644 --- a/framework/bigcommerce/product/use-search.tsx +++ b/framework/bigcommerce/product/use-search.tsx @@ -1,6 +1,6 @@ import { SWRHook } from '@commerce/utils/types' import useSearch, { UseSearch } from '@commerce/product/use-search' -import type { SearchProductsData } from '../api/catalog/products' +import type { SearchProductsHook } from '../types/product' export default useSearch as UseSearch @@ -9,15 +9,12 @@ export type SearchProductsInput = { categoryId?: number | string brandId?: number sort?: string + locale?: string } -export const handler: SWRHook< - SearchProductsData, - SearchProductsInput, - SearchProductsInput -> = { +export const handler: SWRHook = { fetchOptions: { - url: '/api/bigcommerce/catalog/products', + url: '/api/catalog/products', method: 'GET', }, fetcher({ input: { search, categoryId, brandId, sort }, options, fetch }) { @@ -26,9 +23,9 @@ export const handler: SWRHook< if (search) url.searchParams.set('search', search) if (Number.isInteger(categoryId)) - url.searchParams.set('category', String(categoryId)) + url.searchParams.set('categoryId', String(categoryId)) if (Number.isInteger(brandId)) - url.searchParams.set('brand', String(brandId)) + url.searchParams.set('brandId', String(brandId)) if (sort) url.searchParams.set('sort', sort) return fetch({ diff --git a/framework/bigcommerce/types.ts b/framework/bigcommerce/types/cart.ts similarity index 52% rename from framework/bigcommerce/types.ts rename to framework/bigcommerce/types/cart.ts index beeab0223..83076ea09 100644 --- a/framework/bigcommerce/types.ts +++ b/framework/bigcommerce/types/cart.ts @@ -1,4 +1,6 @@ -import * as Core from '@commerce/types' +import * as Core from '@commerce/types/cart' + +export * from '@commerce/types/cart' // TODO: this type should match: // https://developer.bigcommerce.com/api-reference/cart-checkout/server-server-cart-api/cart/getacart#responses @@ -23,16 +25,14 @@ export type BigcommerceCart = { // TODO: add missing fields } -export type Cart = Core.Cart & { - lineItems: LineItem[] -} - -export type LineItem = Core.LineItem - /** - * Cart mutations + * Extend core cart types */ +export type Cart = Core.Cart & { + lineItems: Core.LineItem[] +} + export type OptionSelections = { option_id: number option_value: number | string @@ -43,16 +43,24 @@ export type CartItemBody = Core.CartItemBody & { optionSelections?: OptionSelections } -export type GetCartHandlerBody = Core.GetCartHandlerBody +export type CartTypes = { + cart: Cart + item: Core.LineItem + itemBody: CartItemBody +} -export type AddCartItemBody = Core.AddCartItemBody +export type CartHooks = Core.CartHooks -export type AddCartItemHandlerBody = Core.AddCartItemHandlerBody +export type GetCartHook = CartHooks['getCart'] +export type AddItemHook = CartHooks['addItem'] +export type UpdateItemHook = CartHooks['updateItem'] +export type RemoveItemHook = CartHooks['removeItem'] -export type UpdateCartItemBody = Core.UpdateCartItemBody +export type CartSchema = Core.CartSchema -export type UpdateCartItemHandlerBody = Core.UpdateCartItemHandlerBody +export type CartHandlers = Core.CartHandlers -export type RemoveCartItemBody = Core.RemoveCartItemBody - -export type RemoveCartItemHandlerBody = Core.RemoveCartItemHandlerBody +export type GetCartHandler = CartHandlers['getCart'] +export type AddItemHandler = CartHandlers['addItem'] +export type UpdateItemHandler = CartHandlers['updateItem'] +export type RemoveItemHandler = CartHandlers['removeItem'] diff --git a/framework/bigcommerce/types/checkout.ts b/framework/bigcommerce/types/checkout.ts new file mode 100644 index 000000000..4e2412ef6 --- /dev/null +++ b/framework/bigcommerce/types/checkout.ts @@ -0,0 +1 @@ +export * from '@commerce/types/checkout' diff --git a/framework/bigcommerce/types/common.ts b/framework/bigcommerce/types/common.ts new file mode 100644 index 000000000..b52c33a4d --- /dev/null +++ b/framework/bigcommerce/types/common.ts @@ -0,0 +1 @@ +export * from '@commerce/types/common' diff --git a/framework/bigcommerce/types/customer.ts b/framework/bigcommerce/types/customer.ts new file mode 100644 index 000000000..427bc0b03 --- /dev/null +++ b/framework/bigcommerce/types/customer.ts @@ -0,0 +1,5 @@ +import * as Core from '@commerce/types/customer' + +export * from '@commerce/types/customer' + +export type CustomerSchema = Core.CustomerSchema diff --git a/framework/bigcommerce/types/index.ts b/framework/bigcommerce/types/index.ts new file mode 100644 index 000000000..7ab0b7f64 --- /dev/null +++ b/framework/bigcommerce/types/index.ts @@ -0,0 +1,25 @@ +import * as Cart from './cart' +import * as Checkout from './checkout' +import * as Common from './common' +import * as Customer from './customer' +import * as Login from './login' +import * as Logout from './logout' +import * as Page from './page' +import * as Product from './product' +import * as Signup from './signup' +import * as Site from './site' +import * as Wishlist from './wishlist' + +export type { + Cart, + Checkout, + Common, + Customer, + Login, + Logout, + Page, + Product, + Signup, + Site, + Wishlist, +} diff --git a/framework/bigcommerce/types/login.ts b/framework/bigcommerce/types/login.ts new file mode 100644 index 000000000..24d5077ff --- /dev/null +++ b/framework/bigcommerce/types/login.ts @@ -0,0 +1,8 @@ +import * as Core from '@commerce/types/login' +import type { LoginMutationVariables } from '../schema' + +export * from '@commerce/types/login' + +export type LoginOperation = Core.LoginOperation & { + variables: LoginMutationVariables +} diff --git a/framework/bigcommerce/types/logout.ts b/framework/bigcommerce/types/logout.ts new file mode 100644 index 000000000..9f0a466af --- /dev/null +++ b/framework/bigcommerce/types/logout.ts @@ -0,0 +1 @@ +export * from '@commerce/types/logout' diff --git a/framework/bigcommerce/types/page.ts b/framework/bigcommerce/types/page.ts new file mode 100644 index 000000000..2bccfade2 --- /dev/null +++ b/framework/bigcommerce/types/page.ts @@ -0,0 +1,11 @@ +import * as Core from '@commerce/types/page' +export * from '@commerce/types/page' + +export type Page = Core.Page + +export type PageTypes = { + page: Page +} + +export type GetAllPagesOperation = Core.GetAllPagesOperation +export type GetPageOperation = Core.GetPageOperation diff --git a/framework/bigcommerce/types/product.ts b/framework/bigcommerce/types/product.ts new file mode 100644 index 000000000..c776d58fa --- /dev/null +++ b/framework/bigcommerce/types/product.ts @@ -0,0 +1 @@ +export * from '@commerce/types/product' diff --git a/framework/bigcommerce/types/signup.ts b/framework/bigcommerce/types/signup.ts new file mode 100644 index 000000000..58543c6f6 --- /dev/null +++ b/framework/bigcommerce/types/signup.ts @@ -0,0 +1 @@ +export * from '@commerce/types/signup' diff --git a/framework/bigcommerce/types/site.ts b/framework/bigcommerce/types/site.ts new file mode 100644 index 000000000..12dd7038c --- /dev/null +++ b/framework/bigcommerce/types/site.ts @@ -0,0 +1,19 @@ +import * as Core from '@commerce/types/site' +import type { GetSiteInfoQuery, GetSiteInfoQueryVariables } from '../schema' + +export * from '@commerce/types/site' + +export type BCCategory = NonNullable< + GetSiteInfoQuery['site']['categoryTree'] +>[0] + +export type Brand = NonNullable< + NonNullable[0] +> + +export type SiteTypes = { + category: Core.Category + brand: Brand +} + +export type GetSiteInfoOperation = Core.GetSiteInfoOperation diff --git a/framework/bigcommerce/types/wishlist.ts b/framework/bigcommerce/types/wishlist.ts new file mode 100644 index 000000000..1e148b88c --- /dev/null +++ b/framework/bigcommerce/types/wishlist.ts @@ -0,0 +1,23 @@ +import * as Core from '@commerce/types/wishlist' +import { definitions } from '../api/definitions/wishlist' +import type { ProductEdge } from '../api/operations/get-all-products' + +export * from '@commerce/types/wishlist' + +export type WishlistItem = NonNullable< + definitions['wishlist_Full']['items'] +>[0] & { + product?: ProductEdge['node'] +} + +export type Wishlist = Omit & { + items?: WishlistItem[] +} + +export type WishlistTypes = { + wishlist: Wishlist + itemBody: Core.WishlistItemBody +} + +export type WishlistSchema = Core.WishlistSchema +export type GetCustomerWishlistOperation = Core.GetCustomerWishlistOperation diff --git a/framework/bigcommerce/wishlist/use-add-item.tsx b/framework/bigcommerce/wishlist/use-add-item.tsx index 402e7da8b..1bf086731 100644 --- a/framework/bigcommerce/wishlist/use-add-item.tsx +++ b/framework/bigcommerce/wishlist/use-add-item.tsx @@ -2,15 +2,15 @@ import { useCallback } from 'react' import type { MutationHook } from '@commerce/utils/types' import { CommerceError } from '@commerce/utils/errors' import useAddItem, { UseAddItem } from '@commerce/wishlist/use-add-item' -import type { ItemBody, AddItemBody } from '../api/wishlist' +import type { AddItemHook } from '../types/wishlist' import useCustomer from '../customer/use-customer' import useWishlist from './use-wishlist' export default useAddItem as UseAddItem -export const handler: MutationHook = { +export const handler: MutationHook = { fetchOptions: { - url: '/api/bigcommerce/wishlist', + url: '/api/wishlist', method: 'POST', }, useHook: ({ fetch }) => () => { diff --git a/framework/bigcommerce/wishlist/use-remove-item.tsx b/framework/bigcommerce/wishlist/use-remove-item.tsx index 622f321db..9d25c1439 100644 --- a/framework/bigcommerce/wishlist/use-remove-item.tsx +++ b/framework/bigcommerce/wishlist/use-remove-item.tsx @@ -2,23 +2,17 @@ import { useCallback } from 'react' import type { MutationHook } from '@commerce/utils/types' import { CommerceError } from '@commerce/utils/errors' import useRemoveItem, { - RemoveItemInput, UseRemoveItem, } from '@commerce/wishlist/use-remove-item' -import type { RemoveItemBody, Wishlist } from '../api/wishlist' +import type { RemoveItemHook } from '../types/wishlist' import useCustomer from '../customer/use-customer' -import useWishlist, { UseWishlistInput } from './use-wishlist' +import useWishlist from './use-wishlist' export default useRemoveItem as UseRemoveItem -export const handler: MutationHook< - Wishlist | null, - { wishlist?: UseWishlistInput }, - RemoveItemInput, - RemoveItemBody -> = { +export const handler: MutationHook = { fetchOptions: { - url: '/api/bigcommerce/wishlist', + url: '/api/wishlist', method: 'DELETE', }, useHook: ({ fetch }) => ({ wishlist } = {}) => { diff --git a/framework/bigcommerce/wishlist/use-wishlist.tsx b/framework/bigcommerce/wishlist/use-wishlist.tsx index 4850d1cd9..b8fc946e3 100644 --- a/framework/bigcommerce/wishlist/use-wishlist.tsx +++ b/framework/bigcommerce/wishlist/use-wishlist.tsx @@ -1,21 +1,14 @@ import { useMemo } from 'react' import { SWRHook } from '@commerce/utils/types' import useWishlist, { UseWishlist } from '@commerce/wishlist/use-wishlist' -import type { Wishlist } from '../api/wishlist' +import type { GetWishlistHook } from '../types/wishlist' import useCustomer from '../customer/use-customer' -export type UseWishlistInput = { includeProducts?: boolean } - export default useWishlist as UseWishlist -export const handler: SWRHook< - Wishlist | null, - UseWishlistInput, - { customerId?: number } & UseWishlistInput, - { isEmpty?: boolean } -> = { +export const handler: SWRHook = { fetchOptions: { - url: '/api/bigcommerce/wishlist', + url: '/api/wishlist', method: 'GET', }, async fetcher({ input: { customerId, includeProducts }, options, fetch }) { diff --git a/framework/commerce/api/endpoints/cart.ts b/framework/commerce/api/endpoints/cart.ts new file mode 100644 index 000000000..ca39e7da3 --- /dev/null +++ b/framework/commerce/api/endpoints/cart.ts @@ -0,0 +1,62 @@ +import type { CartSchema } from '../../types/cart' +import { CommerceAPIError } from '../utils/errors' +import isAllowedOperation from '../utils/is-allowed-operation' +import type { GetAPISchema } from '..' + +const cartEndpoint: GetAPISchema< + any, + CartSchema +>['endpoint']['handler'] = async (ctx) => { + const { req, res, handlers, config } = ctx + + if ( + !isAllowedOperation(req, res, { + GET: handlers['getCart'], + POST: handlers['addItem'], + PUT: handlers['updateItem'], + DELETE: handlers['removeItem'], + }) + ) { + return + } + + const { cookies } = req + const cartId = cookies[config.cartCookie] + + try { + // Return current cart info + if (req.method === 'GET') { + const body = { cartId } + return await handlers['getCart']({ ...ctx, body }) + } + + // Create or add an item to the cart + if (req.method === 'POST') { + const body = { ...req.body, cartId } + return await handlers['addItem']({ ...ctx, body }) + } + + // Update item in cart + if (req.method === 'PUT') { + const body = { ...req.body, cartId } + return await handlers['updateItem']({ ...ctx, body }) + } + + // Remove an item from the cart + if (req.method === 'DELETE') { + const body = { ...req.body, cartId } + return await handlers['removeItem']({ ...ctx, body }) + } + } catch (error) { + console.error(error) + + const message = + error instanceof CommerceAPIError + ? 'An unexpected error ocurred with the Commerce API' + : 'An unexpected error ocurred' + + res.status(500).json({ data: null, errors: [{ message }] }) + } +} + +export default cartEndpoint diff --git a/framework/commerce/api/endpoints/catalog/products.ts b/framework/commerce/api/endpoints/catalog/products.ts new file mode 100644 index 000000000..d2a4794be --- /dev/null +++ b/framework/commerce/api/endpoints/catalog/products.ts @@ -0,0 +1,31 @@ +import type { ProductsSchema } from '../../../types/product' +import { CommerceAPIError } from '../../utils/errors' +import isAllowedOperation from '../../utils/is-allowed-operation' +import type { GetAPISchema } from '../..' + +const productsEndpoint: GetAPISchema< + any, + ProductsSchema +>['endpoint']['handler'] = async (ctx) => { + const { req, res, handlers } = ctx + + if (!isAllowedOperation(req, res, { GET: handlers['getProducts'] })) { + return + } + + try { + const body = req.query + return await handlers['getProducts']({ ...ctx, body }) + } catch (error) { + console.error(error) + + const message = + error instanceof CommerceAPIError + ? 'An unexpected error ocurred with the Commerce API' + : 'An unexpected error ocurred' + + res.status(500).json({ data: null, errors: [{ message }] }) + } +} + +export default productsEndpoint diff --git a/framework/commerce/api/endpoints/checkout.ts b/framework/commerce/api/endpoints/checkout.ts new file mode 100644 index 000000000..b39239a6a --- /dev/null +++ b/framework/commerce/api/endpoints/checkout.ts @@ -0,0 +1,35 @@ +import type { CheckoutSchema } from '../../types/checkout' +import { CommerceAPIError } from '../utils/errors' +import isAllowedOperation from '../utils/is-allowed-operation' +import type { GetAPISchema } from '..' + +const checkoutEndpoint: GetAPISchema< + any, + CheckoutSchema +>['endpoint']['handler'] = async (ctx) => { + const { req, res, handlers } = ctx + + if ( + !isAllowedOperation(req, res, { + GET: handlers['checkout'], + }) + ) { + return + } + + try { + const body = null + return await handlers['checkout']({ ...ctx, body }) + } catch (error) { + console.error(error) + + const message = + error instanceof CommerceAPIError + ? 'An unexpected error ocurred with the Commerce API' + : 'An unexpected error ocurred' + + res.status(500).json({ data: null, errors: [{ message }] }) + } +} + +export default checkoutEndpoint diff --git a/framework/commerce/api/endpoints/customer.ts b/framework/commerce/api/endpoints/customer.ts new file mode 100644 index 000000000..6372c494f --- /dev/null +++ b/framework/commerce/api/endpoints/customer.ts @@ -0,0 +1,35 @@ +import type { CustomerSchema } from '../../types/customer' +import { CommerceAPIError } from '../utils/errors' +import isAllowedOperation from '../utils/is-allowed-operation' +import type { GetAPISchema } from '..' + +const customerEndpoint: GetAPISchema< + any, + CustomerSchema +>['endpoint']['handler'] = async (ctx) => { + const { req, res, handlers } = ctx + + if ( + !isAllowedOperation(req, res, { + GET: handlers['getLoggedInCustomer'], + }) + ) { + return + } + + try { + const body = null + return await handlers['getLoggedInCustomer']({ ...ctx, body }) + } catch (error) { + console.error(error) + + const message = + error instanceof CommerceAPIError + ? 'An unexpected error ocurred with the Commerce API' + : 'An unexpected error ocurred' + + res.status(500).json({ data: null, errors: [{ message }] }) + } +} + +export default customerEndpoint diff --git a/framework/commerce/api/endpoints/login.ts b/framework/commerce/api/endpoints/login.ts new file mode 100644 index 000000000..bc071b751 --- /dev/null +++ b/framework/commerce/api/endpoints/login.ts @@ -0,0 +1,35 @@ +import type { LoginSchema } from '../../types/login' +import { CommerceAPIError } from '../utils/errors' +import isAllowedOperation from '../utils/is-allowed-operation' +import type { GetAPISchema } from '..' + +const loginEndpoint: GetAPISchema< + any, + LoginSchema +>['endpoint']['handler'] = async (ctx) => { + const { req, res, handlers } = ctx + + if ( + !isAllowedOperation(req, res, { + POST: handlers['login'], + }) + ) { + return + } + + try { + const body = req.body ?? {} + return await handlers['login']({ ...ctx, body }) + } catch (error) { + console.error(error) + + const message = + error instanceof CommerceAPIError + ? 'An unexpected error ocurred with the Commerce API' + : 'An unexpected error ocurred' + + res.status(500).json({ data: null, errors: [{ message }] }) + } +} + +export default loginEndpoint diff --git a/framework/commerce/api/endpoints/logout.ts b/framework/commerce/api/endpoints/logout.ts new file mode 100644 index 000000000..8da11acb0 --- /dev/null +++ b/framework/commerce/api/endpoints/logout.ts @@ -0,0 +1,37 @@ +import type { LogoutSchema } from '../../types/logout' +import { CommerceAPIError } from '../utils/errors' +import isAllowedOperation from '../utils/is-allowed-operation' +import type { GetAPISchema } from '..' + +const logoutEndpoint: GetAPISchema< + any, + LogoutSchema +>['endpoint']['handler'] = async (ctx) => { + const { req, res, handlers } = ctx + + if ( + !isAllowedOperation(req, res, { + GET: handlers['logout'], + }) + ) { + return + } + + try { + const redirectTo = req.query.redirect_to + const body = typeof redirectTo === 'string' ? { redirectTo } : {} + + return await handlers['logout']({ ...ctx, body }) + } catch (error) { + console.error(error) + + const message = + error instanceof CommerceAPIError + ? 'An unexpected error ocurred with the Commerce API' + : 'An unexpected error ocurred' + + res.status(500).json({ data: null, errors: [{ message }] }) + } +} + +export default logoutEndpoint diff --git a/framework/commerce/api/endpoints/signup.ts b/framework/commerce/api/endpoints/signup.ts new file mode 100644 index 000000000..aa73ae739 --- /dev/null +++ b/framework/commerce/api/endpoints/signup.ts @@ -0,0 +1,38 @@ +import type { SignupSchema } from '../../types/signup' +import { CommerceAPIError } from '../utils/errors' +import isAllowedOperation from '../utils/is-allowed-operation' +import type { GetAPISchema } from '..' + +const signupEndpoint: GetAPISchema< + any, + SignupSchema +>['endpoint']['handler'] = async (ctx) => { + const { req, res, handlers, config } = ctx + + if ( + !isAllowedOperation(req, res, { + POST: handlers['signup'], + }) + ) { + return + } + + const { cookies } = req + const cartId = cookies[config.cartCookie] + + try { + const body = { ...req.body, cartId } + return await handlers['signup']({ ...ctx, body }) + } catch (error) { + console.error(error) + + const message = + error instanceof CommerceAPIError + ? 'An unexpected error ocurred with the Commerce API' + : 'An unexpected error ocurred' + + res.status(500).json({ data: null, errors: [{ message }] }) + } +} + +export default signupEndpoint diff --git a/framework/commerce/api/endpoints/wishlist.ts b/framework/commerce/api/endpoints/wishlist.ts new file mode 100644 index 000000000..233ac5294 --- /dev/null +++ b/framework/commerce/api/endpoints/wishlist.ts @@ -0,0 +1,58 @@ +import type { WishlistSchema } from '../../types/wishlist' +import { CommerceAPIError } from '../utils/errors' +import isAllowedOperation from '../utils/is-allowed-operation' +import type { GetAPISchema } from '..' + +const wishlistEndpoint: GetAPISchema< + any, + WishlistSchema +>['endpoint']['handler'] = async (ctx) => { + const { req, res, handlers, config } = ctx + + if ( + !isAllowedOperation(req, res, { + GET: handlers['getWishlist'], + POST: handlers['addItem'], + DELETE: handlers['removeItem'], + }) + ) { + return + } + + const { cookies } = req + const customerToken = cookies[config.customerCookie] + + try { + // Return current wishlist info + if (req.method === 'GET') { + const body = { + customerToken, + includeProducts: req.query.products === '1', + } + return await handlers['getWishlist']({ ...ctx, body }) + } + + // Add an item to the wishlist + if (req.method === 'POST') { + const body = { ...req.body, customerToken } + return await handlers['addItem']({ ...ctx, body }) + } + + // Remove an item from the wishlist + if (req.method === 'DELETE') { + const body = { ...req.body, customerToken } + return await handlers['removeItem']({ ...ctx, body }) + } + } catch (error) { + console.error(error) + + const message = + error instanceof CommerceAPIError + ? 'An unexpected error ocurred with the Commerce API' + : 'An unexpected error ocurred' + + res.status(500).json({ data: null, errors: [{ message }] }) + } +} + +export default wishlistEndpoint diff --git a/framework/commerce/api/index.ts b/framework/commerce/api/index.ts index 77b2eeb7e..8b44bea33 100644 --- a/framework/commerce/api/index.ts +++ b/framework/commerce/api/index.ts @@ -1,7 +1,154 @@ +import type { NextApiHandler } from 'next' import type { RequestInit, Response } from '@vercel/fetch' +import type { APIEndpoint, APIHandler } from './utils/types' +import type { CartSchema } from '../types/cart' +import type { CustomerSchema } from '../types/customer' +import type { LoginSchema } from '../types/login' +import type { LogoutSchema } from '../types/logout' +import type { SignupSchema } from '../types/signup' +import type { ProductsSchema } from '../types/product' +import type { WishlistSchema } from '../types/wishlist' +import type { CheckoutSchema } from '../types/checkout' +import { + defaultOperations, + OPERATIONS, + AllOperations, + APIOperations, +} from './operations' + +export type APISchemas = + | CartSchema + | CustomerSchema + | LoginSchema + | LogoutSchema + | SignupSchema + | ProductsSchema + | WishlistSchema + | CheckoutSchema + +export type GetAPISchema< + C extends CommerceAPI, + S extends APISchemas = APISchemas +> = { + schema: S + endpoint: EndpointContext +} + +export type EndpointContext< + C extends CommerceAPI, + E extends EndpointSchemaBase +> = { + handler: Endpoint + handlers: EndpointHandlers +} + +export type EndpointSchemaBase = { + options: {} + handlers: { + [k: string]: { data?: any; body?: any } + } +} + +export type Endpoint< + C extends CommerceAPI, + E extends EndpointSchemaBase +> = APIEndpoint, any, E['options']> + +export type EndpointHandlers< + C extends CommerceAPI, + E extends EndpointSchemaBase +> = { + [H in keyof E['handlers']]: APIHandler< + C, + EndpointHandlers, + E['handlers'][H]['data'], + E['handlers'][H]['body'], + E['options'] + > +} + +export type APIProvider = { + config: CommerceAPIConfig + operations: APIOperations +} + +export type CommerceAPI< + P extends APIProvider = APIProvider +> = CommerceAPICore

    & AllOperations

    + +export class CommerceAPICore

    { + constructor(readonly provider: P) {} + + getConfig(userConfig: Partial = {}): P['config'] { + return Object.entries(userConfig).reduce( + (cfg, [key, value]) => Object.assign(cfg, { [key]: value }), + { ...this.provider.config } + ) + } + + setConfig(newConfig: Partial) { + Object.assign(this.provider.config, newConfig) + } +} + +export function getCommerceApi

    ( + customProvider: P +): CommerceAPI

    { + const commerce = Object.assign( + new CommerceAPICore(customProvider), + defaultOperations as AllOperations

    + ) + const ops = customProvider.operations + + OPERATIONS.forEach((k) => { + const op = ops[k] + if (op) { + commerce[k] = op({ commerce }) as AllOperations

    [typeof k] + } + }) + + return commerce +} + +export function getEndpoint< + P extends APIProvider, + T extends GetAPISchema +>( + commerce: CommerceAPI

    , + context: T['endpoint'] & { + config?: P['config'] + options?: T['schema']['endpoint']['options'] + } +): NextApiHandler { + const cfg = commerce.getConfig(context.config) + + return function apiHandler(req, res) { + return context.handler({ + req, + res, + commerce, + config: cfg, + handlers: context.handlers, + options: context.options ?? {}, + }) + } +} + +export const createEndpoint = >( + endpoint: API['endpoint'] +) =>

    ( + commerce: CommerceAPI

    , + context?: Partial & { + config?: P['config'] + options?: API['schema']['endpoint']['options'] + } +): NextApiHandler => { + return getEndpoint(commerce, { ...endpoint, ...context }) +} export interface CommerceAPIConfig { locale?: string + locales?: string[] commerceUrl: string apiToken: string cartCookie: string diff --git a/framework/commerce/api/operations.ts b/framework/commerce/api/operations.ts new file mode 100644 index 000000000..2910a2d82 --- /dev/null +++ b/framework/commerce/api/operations.ts @@ -0,0 +1,177 @@ +import type { ServerResponse } from 'http' +import type { LoginOperation } from '../types/login' +import type { GetAllPagesOperation, GetPageOperation } from '../types/page' +import type { GetSiteInfoOperation } from '../types/site' +import type { GetCustomerWishlistOperation } from '../types/wishlist' +import type { + GetAllProductPathsOperation, + GetAllProductsOperation, + GetProductOperation, +} from '../types/product' +import type { APIProvider, CommerceAPI } from '.' + +const noop = () => { + throw new Error('Not implemented') +} + +export const OPERATIONS = [ + 'login', + 'getAllPages', + 'getPage', + 'getSiteInfo', + 'getCustomerWishlist', + 'getAllProductPaths', + 'getAllProducts', + 'getProduct', +] as const + +export const defaultOperations = OPERATIONS.reduce((ops, k) => { + ops[k] = noop + return ops +}, {} as { [K in AllowedOperations]: typeof noop }) + +export type AllowedOperations = typeof OPERATIONS[number] + +export type Operations

    = { + login: { + (opts: { + variables: T['variables'] + config?: P['config'] + res: ServerResponse + }): Promise + + ( + opts: { + variables: T['variables'] + config?: P['config'] + res: ServerResponse + } & OperationOptions + ): Promise + } + + getAllPages: { + (opts?: { + config?: P['config'] + preview?: boolean + }): Promise + + ( + opts: { + config?: P['config'] + preview?: boolean + } & OperationOptions + ): Promise + } + + getPage: { + (opts: { + variables: T['variables'] + config?: P['config'] + preview?: boolean + }): Promise + + ( + opts: { + variables: T['variables'] + config?: P['config'] + preview?: boolean + } & OperationOptions + ): Promise + } + + getSiteInfo: { + (opts: { + config?: P['config'] + preview?: boolean + }): Promise + + ( + opts: { + config?: P['config'] + preview?: boolean + } & OperationOptions + ): Promise + } + + getCustomerWishlist: { + (opts: { + variables: T['variables'] + config?: P['config'] + includeProducts?: boolean + }): Promise + + ( + opts: { + variables: T['variables'] + config?: P['config'] + includeProducts?: boolean + } & OperationOptions + ): Promise + } + + getAllProductPaths: { + (opts: { + variables?: T['variables'] + config?: P['config'] + }): Promise + + ( + opts: { + variables?: T['variables'] + config?: P['config'] + } & OperationOptions + ): Promise + } + + getAllProducts: { + (opts: { + variables?: T['variables'] + config?: P['config'] + preview?: boolean + }): Promise + + ( + opts: { + variables?: T['variables'] + config?: P['config'] + preview?: boolean + } & OperationOptions + ): Promise + } + + getProduct: { + (opts: { + variables: T['variables'] + config?: P['config'] + preview?: boolean + }): Promise + + ( + opts: { + variables: T['variables'] + config?: P['config'] + preview?: boolean + } & OperationOptions + ): Promise + } +} + +export type APIOperations

    = { + [K in keyof Operations

    ]?: (ctx: OperationContext

    ) => Operations

    [K] +} + +export type AllOperations

    = { + [K in keyof APIOperations

    ]-?: P['operations'][K] extends ( + ...args: any + ) => any + ? ReturnType + : typeof noop +} + +export type OperationContext

    = { + commerce: CommerceAPI

    +} + +export type OperationOptions = + | { query: string; url?: never } + | { query?: never; url: string } diff --git a/framework/commerce/api/utils/errors.ts b/framework/commerce/api/utils/errors.ts new file mode 100644 index 000000000..6f9ecce0c --- /dev/null +++ b/framework/commerce/api/utils/errors.ts @@ -0,0 +1,22 @@ +import type { Response } from '@vercel/fetch' + +export class CommerceAPIError extends Error { + status: number + res: Response + data: any + + constructor(msg: string, res: Response, data?: any) { + super(msg) + this.name = 'CommerceApiError' + this.status = res.status + this.res = res + this.data = data + } +} + +export class CommerceNetworkError extends Error { + constructor(msg: string) { + super(msg) + this.name = 'CommerceNetworkError' + } +} diff --git a/framework/shopify/api/utils/is-allowed-method.ts b/framework/commerce/api/utils/is-allowed-method.ts similarity index 85% rename from framework/shopify/api/utils/is-allowed-method.ts rename to framework/commerce/api/utils/is-allowed-method.ts index 78bbba568..51c37e221 100644 --- a/framework/shopify/api/utils/is-allowed-method.ts +++ b/framework/commerce/api/utils/is-allowed-method.ts @@ -1,9 +1,11 @@ import type { NextApiRequest, NextApiResponse } from 'next' +export type HTTP_METHODS = 'OPTIONS' | 'GET' | 'POST' | 'PUT' | 'DELETE' + export default function isAllowedMethod( req: NextApiRequest, res: NextApiResponse, - allowedMethods: string[] + allowedMethods: HTTP_METHODS[] ) { const methods = allowedMethods.includes('OPTIONS') ? allowedMethods diff --git a/framework/commerce/api/utils/is-allowed-operation.ts b/framework/commerce/api/utils/is-allowed-operation.ts new file mode 100644 index 000000000..f507781bf --- /dev/null +++ b/framework/commerce/api/utils/is-allowed-operation.ts @@ -0,0 +1,19 @@ +import type { NextApiRequest, NextApiResponse } from 'next' +import isAllowedMethod, { HTTP_METHODS } from './is-allowed-method' +import { APIHandler } from './types' + +export default function isAllowedOperation( + req: NextApiRequest, + res: NextApiResponse, + allowedOperations: { [k in HTTP_METHODS]?: APIHandler } +) { + const methods = Object.keys(allowedOperations) as HTTP_METHODS[] + const allowedMethods = methods.reduce((arr, method) => { + if (allowedOperations[method]) { + arr.push(method) + } + return arr + }, []) + + return isAllowedMethod(req, res, allowedMethods) +} diff --git a/framework/commerce/api/utils/types.ts b/framework/commerce/api/utils/types.ts new file mode 100644 index 000000000..27a95df40 --- /dev/null +++ b/framework/commerce/api/utils/types.ts @@ -0,0 +1,49 @@ +import type { NextApiRequest, NextApiResponse } from 'next' +import type { CommerceAPI } from '..' + +export type ErrorData = { message: string; code?: string } + +export type APIResponse = + | { data: Data; errors?: ErrorData[] } + // If `data` doesn't include `null`, then `null` is only allowed on errors + | (Data extends null + ? { data: null; errors?: ErrorData[] } + : { data: null; errors: ErrorData[] }) + +export type APIHandlerContext< + C extends CommerceAPI, + H extends APIHandlers = {}, + Data = any, + Options extends {} = {} +> = { + req: NextApiRequest + res: NextApiResponse> + commerce: C + config: C['provider']['config'] + handlers: H + /** + * Custom configs that may be used by a particular handler + */ + options: Options +} + +export type APIHandler< + C extends CommerceAPI, + H extends APIHandlers = {}, + Data = any, + Body = any, + Options extends {} = {} +> = ( + context: APIHandlerContext & { body: Body } +) => void | Promise + +export type APIHandlers = { + [k: string]: APIHandler +} + +export type APIEndpoint< + C extends CommerceAPI = CommerceAPI, + H extends APIHandlers = {}, + Data = any, + Options extends {} = {} +> = (context: APIHandlerContext) => void | Promise diff --git a/framework/commerce/auth/use-login.tsx b/framework/commerce/auth/use-login.tsx index cc4cf6a73..67fb429dc 100644 --- a/framework/commerce/auth/use-login.tsx +++ b/framework/commerce/auth/use-login.tsx @@ -1,13 +1,14 @@ import { useHook, useMutationHook } from '../utils/use-hook' import { mutationFetcher } from '../utils/default-fetcher' import type { MutationHook, HookFetcherFn } from '../utils/types' +import type { LoginHook } from '../types/login' import type { Provider } from '..' export type UseLogin< - H extends MutationHook = MutationHook + H extends MutationHook> = MutationHook > = ReturnType -export const fetcher: HookFetcherFn = mutationFetcher +export const fetcher: HookFetcherFn = mutationFetcher const fn = (provider: Provider) => provider.auth?.useLogin! diff --git a/framework/commerce/auth/use-logout.tsx b/framework/commerce/auth/use-logout.tsx index d0f7e3ae0..6ca16decf 100644 --- a/framework/commerce/auth/use-logout.tsx +++ b/framework/commerce/auth/use-logout.tsx @@ -1,13 +1,14 @@ import { useHook, useMutationHook } from '../utils/use-hook' import { mutationFetcher } from '../utils/default-fetcher' import type { HookFetcherFn, MutationHook } from '../utils/types' +import type { LogoutHook } from '../types/logout' import type { Provider } from '..' export type UseLogout< - H extends MutationHook = MutationHook + H extends MutationHook> = MutationHook > = ReturnType -export const fetcher: HookFetcherFn = mutationFetcher +export const fetcher: HookFetcherFn = mutationFetcher const fn = (provider: Provider) => provider.auth?.useLogout! diff --git a/framework/commerce/auth/use-signup.tsx b/framework/commerce/auth/use-signup.tsx index 72e242209..2f846fad6 100644 --- a/framework/commerce/auth/use-signup.tsx +++ b/framework/commerce/auth/use-signup.tsx @@ -1,13 +1,14 @@ import { useHook, useMutationHook } from '../utils/use-hook' import { mutationFetcher } from '../utils/default-fetcher' import type { HookFetcherFn, MutationHook } from '../utils/types' +import type { SignupHook } from '../types/signup' import type { Provider } from '..' export type UseSignup< - H extends MutationHook = MutationHook + H extends MutationHook> = MutationHook > = ReturnType -export const fetcher: HookFetcherFn = mutationFetcher +export const fetcher: HookFetcherFn = mutationFetcher const fn = (provider: Provider) => provider.auth?.useSignup! diff --git a/framework/commerce/cart/use-add-item.tsx b/framework/commerce/cart/use-add-item.tsx index 324464656..f4072c763 100644 --- a/framework/commerce/cart/use-add-item.tsx +++ b/framework/commerce/cart/use-add-item.tsx @@ -1,17 +1,14 @@ import { useHook, useMutationHook } from '../utils/use-hook' import { mutationFetcher } from '../utils/default-fetcher' import type { HookFetcherFn, MutationHook } from '../utils/types' -import type { Cart, CartItemBody, AddCartItemBody } from '../types' +import type { AddItemHook } from '../types/cart' import type { Provider } from '..' export type UseAddItem< - H extends MutationHook = MutationHook + H extends MutationHook> = MutationHook > = ReturnType -export const fetcher: HookFetcherFn< - Cart, - AddCartItemBody -> = mutationFetcher +export const fetcher: HookFetcherFn = mutationFetcher const fn = (provider: Provider) => provider.cart?.useAddItem! diff --git a/framework/commerce/cart/use-cart.tsx b/framework/commerce/cart/use-cart.tsx index fbed715c8..cfce59e36 100644 --- a/framework/commerce/cart/use-cart.tsx +++ b/framework/commerce/cart/use-cart.tsx @@ -1,28 +1,19 @@ import Cookies from 'js-cookie' import { useHook, useSWRHook } from '../utils/use-hook' -import type { HookFetcherFn, SWRHook } from '../utils/types' -import type { Cart } from '../types' +import type { SWRHook, HookFetcherFn } from '../utils/types' +import type { GetCartHook } from '../types/cart' import { Provider, useCommerce } from '..' -export type FetchCartInput = { - cartId?: Cart['id'] -} - export type UseCart< - H extends SWRHook = SWRHook< - Cart | null, - {}, - FetchCartInput, - { isEmpty?: boolean } - > + H extends SWRHook> = SWRHook > = ReturnType -export const fetcher: HookFetcherFn = async ({ +export const fetcher: HookFetcherFn = async ({ options, input: { cartId }, fetch, }) => { - return cartId ? await fetch({ ...options }) : null + return cartId ? await fetch(options) : null } const fn = (provider: Provider) => provider.cart?.useCart! diff --git a/framework/commerce/cart/use-remove-item.tsx b/framework/commerce/cart/use-remove-item.tsx index a9d1b37d2..f2bb43ffb 100644 --- a/framework/commerce/cart/use-remove-item.tsx +++ b/framework/commerce/cart/use-remove-item.tsx @@ -1,29 +1,14 @@ import { useHook, useMutationHook } from '../utils/use-hook' import { mutationFetcher } from '../utils/default-fetcher' import type { HookFetcherFn, MutationHook } from '../utils/types' -import type { Cart, LineItem, RemoveCartItemBody } from '../types' +import type { RemoveItemHook } from '../types/cart' import type { Provider } from '..' -/** - * Input expected by the action returned by the `useRemoveItem` hook - */ -export type RemoveItemInput = { - id: string -} - export type UseRemoveItem< - H extends MutationHook = MutationHook< - Cart | null, - { item?: LineItem }, - RemoveItemInput, - RemoveCartItemBody - > + H extends MutationHook> = MutationHook > = ReturnType -export const fetcher: HookFetcherFn< - Cart | null, - RemoveCartItemBody -> = mutationFetcher +export const fetcher: HookFetcherFn = mutationFetcher const fn = (provider: Provider) => provider.cart?.useRemoveItem! diff --git a/framework/commerce/cart/use-update-item.tsx b/framework/commerce/cart/use-update-item.tsx index f8d0f1a40..2527732eb 100644 --- a/framework/commerce/cart/use-update-item.tsx +++ b/framework/commerce/cart/use-update-item.tsx @@ -1,32 +1,14 @@ import { useHook, useMutationHook } from '../utils/use-hook' import { mutationFetcher } from '../utils/default-fetcher' import type { HookFetcherFn, MutationHook } from '../utils/types' -import type { Cart, CartItemBody, LineItem, UpdateCartItemBody } from '../types' +import type { UpdateItemHook } from '../types/cart' import type { Provider } from '..' -/** - * Input expected by the action returned by the `useUpdateItem` hook - */ -export type UpdateItemInput = T & { - id: string -} - export type UseUpdateItem< - H extends MutationHook = MutationHook< - Cart | null, - { - item?: LineItem - wait?: number - }, - UpdateItemInput, - UpdateCartItemBody - > + H extends MutationHook> = MutationHook > = ReturnType -export const fetcher: HookFetcherFn< - Cart | null, - UpdateCartItemBody -> = mutationFetcher +export const fetcher: HookFetcherFn = mutationFetcher const fn = (provider: Provider) => provider.cart?.useUpdateItem! diff --git a/framework/commerce/config.js b/framework/commerce/config.js index dc016d47a..48f0d526b 100644 --- a/framework/commerce/config.js +++ b/framework/commerce/config.js @@ -56,6 +56,19 @@ function withCommerceConfig(nextConfig = {}) { tsconfig.compilerOptions.paths['@framework'] = [`framework/${name}`] tsconfig.compilerOptions.paths['@framework/*'] = [`framework/${name}/*`] + // When running for production it may be useful to exclude the other providers + // from TS checking + if (process.env.VERCEL) { + const exclude = tsconfig.exclude.filter( + (item) => !item.startsWith('framework/') + ) + + tsconfig.exclude = PROVIDERS.reduce((exclude, current) => { + if (current !== name) exclude.push(`framework/${current}`) + return exclude + }, exclude) + } + fs.writeFileSync( tsconfigPath, prettier.format(JSON.stringify(tsconfig), { parser: 'json' }) diff --git a/framework/commerce/customer/use-customer.tsx b/framework/commerce/customer/use-customer.tsx index 5d6416a4b..bbeeb3269 100644 --- a/framework/commerce/customer/use-customer.tsx +++ b/framework/commerce/customer/use-customer.tsx @@ -1,14 +1,14 @@ import { useHook, useSWRHook } from '../utils/use-hook' import { SWRFetcher } from '../utils/default-fetcher' +import type { CustomerHook } from '../types/customer' import type { HookFetcherFn, SWRHook } from '../utils/types' -import type { Customer } from '../types' -import { Provider } from '..' +import type { Provider } from '..' export type UseCustomer< - H extends SWRHook = SWRHook + H extends SWRHook> = SWRHook > = ReturnType -export const fetcher: HookFetcherFn = SWRFetcher +export const fetcher: HookFetcherFn = SWRFetcher const fn = (provider: Provider) => provider.customer?.useCustomer! diff --git a/framework/commerce/index.tsx b/framework/commerce/index.tsx index 07bf74a22..7ecb44dc1 100644 --- a/framework/commerce/index.tsx +++ b/framework/commerce/index.tsx @@ -6,35 +6,44 @@ import { useMemo, useRef, } from 'react' -import { Fetcher, SWRHook, MutationHook } from './utils/types' -import type { FetchCartInput } from './cart/use-cart' -import type { Cart, Wishlist, Customer, SearchProductsData } from './types' + +import type { + Customer, + Wishlist, + Cart, + Product, + Signup, + Login, + Logout, +} from '@commerce/types' + +import type { Fetcher, SWRHook, MutationHook } from './utils/types' const Commerce = createContext | {}>({}) export type Provider = CommerceConfig & { fetcher: Fetcher cart?: { - useCart?: SWRHook - useAddItem?: MutationHook - useUpdateItem?: MutationHook - useRemoveItem?: MutationHook + useCart?: SWRHook + useAddItem?: MutationHook + useUpdateItem?: MutationHook + useRemoveItem?: MutationHook } wishlist?: { - useWishlist?: SWRHook - useAddItem?: MutationHook - useRemoveItem?: MutationHook + useWishlist?: SWRHook + useAddItem?: MutationHook + useRemoveItem?: MutationHook } customer?: { - useCustomer?: SWRHook + useCustomer?: SWRHook } products?: { - useSearch?: SWRHook + useSearch?: SWRHook } auth?: { - useSignup?: MutationHook - useLogin?: MutationHook - useLogout?: MutationHook + useSignup?: MutationHook + useLogin?: MutationHook + useLogout?: MutationHook } } diff --git a/framework/commerce/new-provider.md b/framework/commerce/new-provider.md index 4051c0f01..511704af6 100644 --- a/framework/commerce/new-provider.md +++ b/framework/commerce/new-provider.md @@ -149,7 +149,7 @@ export const handler: SWRHook< { isEmpty?: boolean } > = { fetchOptions: { - url: '/api/bigcommerce/cart', + url: '/api/cart', method: 'GET', }, async fetcher({ input: { cartId }, options, fetch }) { @@ -197,7 +197,7 @@ export default useAddItem as UseAddItem export const handler: MutationHook = { fetchOptions: { - url: '/api/bigcommerce/cart', + url: '/api/cart', method: 'POST', }, async fetcher({ input: item, options, fetch }) { diff --git a/framework/commerce/product/use-search.tsx b/framework/commerce/product/use-search.tsx index d2b782045..342b49e6e 100644 --- a/framework/commerce/product/use-search.tsx +++ b/framework/commerce/product/use-search.tsx @@ -1,14 +1,14 @@ import { useHook, useSWRHook } from '../utils/use-hook' import { SWRFetcher } from '../utils/default-fetcher' import type { HookFetcherFn, SWRHook } from '../utils/types' -import type { SearchProductsData } from '../types' -import { Provider } from '..' +import type { SearchProductsHook } from '../types/product' +import type { Provider } from '..' export type UseSearch< - H extends SWRHook = SWRHook + H extends SWRHook> = SWRHook > = ReturnType -export const fetcher: HookFetcherFn = SWRFetcher +export const fetcher: HookFetcherFn = SWRFetcher const fn = (provider: Provider) => provider.products?.useSearch! diff --git a/framework/commerce/types.ts b/framework/commerce/types.ts deleted file mode 100644 index 62ce4de0a..000000000 --- a/framework/commerce/types.ts +++ /dev/null @@ -1,213 +0,0 @@ -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 - value: number -} - -export type LineItem = { - id: string - variantId: string - productId: string - name: string - quantity: number - discounts: Discount[] - // A human-friendly unique string automatically generated from the product’s name - path: string - variant: ProductVariant -} - -export type Measurement = { - value: number - unit: 'KILOGRAMS' | 'GRAMS' | 'POUNDS' | 'OUNCES' -} - -export type Image = { - url: string - altText?: string - width?: number - height?: number -} - -export type ProductVariant = { - id: string - // The SKU (stock keeping unit) associated with the product variant. - sku: string - // The product variant’s title, or the product's name. - name: string - // Whether a customer needs to provide a shipping address when placing - // an order for the product variant. - requiresShipping: boolean - // The product variant’s price after all discounts are applied. - price: number - // Product variant’s price, as quoted by the manufacturer/distributor. - listPrice: number - // Image associated with the product variant. Falls back to the product image - // if no image is available. - image?: Image - // Indicates whether this product variant is in stock. - isInStock?: boolean - // Indicates if the product variant is available for sale. - availableForSale?: boolean - // The variant's weight. If a weight was not explicitly specified on the - // variant this will be the product's weight. - weight?: Measurement - // The variant's height. If a height was not explicitly specified on the - // variant, this will be the product's height. - height?: Measurement - // The variant's width. If a width was not explicitly specified on the - // variant, this will be the product's width. - width?: Measurement - // The variant's depth. If a depth was not explicitly specified on the - // variant, this will be the product's depth. - depth?: Measurement -} - -// Shopping cart, a.k.a Checkout -export type Cart = { - id: string - // ID of the customer to which the cart belongs. - customerId?: string - // The email assigned to this cart - email?: string - // The date and time when the cart was created. - createdAt: string - // The currency used for this cart - currency: { code: string } - // Specifies if taxes are included in the line items. - taxesIncluded: boolean - lineItems: LineItem[] - // The sum of all the prices of all the items in the cart. - // Duties, taxes, shipping and discounts excluded. - lineItemsSubtotalPrice: number - // Price of the cart before duties, shipping and taxes. - subtotalPrice: number - // The sum of all the prices of all the items in the cart. - // Duties, taxes and discounts included. - totalPrice: number - // Discounts that have been applied on the cart. - discounts?: Discount[] -} - -// TODO: Properly define this type -export interface Wishlist extends BCWishlist {} - -// TODO: Properly define this type -export interface Customer extends BCCustomer {} - -// TODO: Properly define this type -export interface SearchProductsData extends BCSearchProductsData {} - -/** - * Cart mutations - */ - -// Base cart item body used for cart mutations -export type CartItemBody = { - variantId: string - productId?: string - quantity?: number -} - -// Body used by the `getCart` operation handler -export type GetCartHandlerBody = { - cartId?: string -} - -// Body used by the add item to cart operation -export type AddCartItemBody = { - item: T -} - -// Body expected by the add item to cart operation handler -export type AddCartItemHandlerBody = Partial< - AddCartItemBody -> & { - cartId?: string -} - -// Body used by the update cart item operation -export type UpdateCartItemBody = { - itemId: string - item: T -} - -// Body expected by the update cart item operation handler -export type UpdateCartItemHandlerBody = Partial< - UpdateCartItemBody -> & { - cartId?: string -} - -// Body used by the remove cart item operation -export type RemoveCartItemBody = { - itemId: string -} - -// Body expected by the remove cart item operation handler -export type RemoveCartItemHandlerBody = Partial & { - cartId?: string -} - -export type Category = { - id: string - name: string - slug: string - path: string -} - -export type Page = any - -/** - * Temporal types - */ - -interface Entity { - id: string | number - [prop: string]: any -} - -export interface Product extends Entity { - name: string - description: string - descriptionHtml?: string - slug?: string - path?: string - images: ProductImage[] - variants: ProductVariant2[] - price: ProductPrice - options: ProductOption[] - sku?: string -} - -interface ProductOption extends Entity { - displayName: string - values: ProductOptionValues[] -} - -interface ProductOptionValues { - label: string - hexColors?: string[] -} - -interface ProductImage { - url: string - alt?: string -} - -interface ProductVariant2 { - id: string | number - options: ProductOption[] -} - -interface ProductPrice { - value: number - currencyCode: 'USD' | 'ARS' | string | undefined - retailPrice?: number - salePrice?: number - listPrice?: number - extendedSalePrice?: number - extendedListPrice?: number -} diff --git a/framework/commerce/types/cart.ts b/framework/commerce/types/cart.ts new file mode 100644 index 000000000..7826f9b2d --- /dev/null +++ b/framework/commerce/types/cart.ts @@ -0,0 +1,179 @@ +import type { Discount, Measurement, Image } from './common' + +export type SelectedOption = { + // The option's id. + id?: string + // The product option’s name. + name: string + /// The product option’s value. + value: string +} + +export type LineItem = { + id: string + variantId: string + productId: string + name: string + quantity: number + discounts: Discount[] + // A human-friendly unique string automatically generated from the product’s name + path: string + variant: ProductVariant + options?: SelectedOption[] +} + +export type ProductVariant = { + id: string + // The SKU (stock keeping unit) associated with the product variant. + sku: string + // The product variant’s title, or the product's name. + name: string + // Whether a customer needs to provide a shipping address when placing + // an order for the product variant. + requiresShipping: boolean + // The product variant’s price after all discounts are applied. + price: number + // Product variant’s price, as quoted by the manufacturer/distributor. + listPrice: number + // Image associated with the product variant. Falls back to the product image + // if no image is available. + image?: Image + // Indicates whether this product variant is in stock. + isInStock?: boolean + // Indicates if the product variant is available for sale. + availableForSale?: boolean + // The variant's weight. If a weight was not explicitly specified on the + // variant this will be the product's weight. + weight?: Measurement + // The variant's height. If a height was not explicitly specified on the + // variant, this will be the product's height. + height?: Measurement + // The variant's width. If a width was not explicitly specified on the + // variant, this will be the product's width. + width?: Measurement + // The variant's depth. If a depth was not explicitly specified on the + // variant, this will be the product's depth. + depth?: Measurement +} + +// Shopping cart, a.k.a Checkout +export type Cart = { + id: string + // ID of the customer to which the cart belongs. + customerId?: string + // The email assigned to this cart + email?: string + // The date and time when the cart was created. + createdAt: string + // The currency used for this cart + currency: { code: string } + // Specifies if taxes are included in the line items. + taxesIncluded: boolean + lineItems: LineItem[] + // The sum of all the prices of all the items in the cart. + // Duties, taxes, shipping and discounts excluded. + lineItemsSubtotalPrice: number + // Price of the cart before duties, shipping and taxes. + subtotalPrice: number + // The sum of all the prices of all the items in the cart. + // Duties, taxes and discounts included. + totalPrice: number + // Discounts that have been applied on the cart. + discounts?: Discount[] +} + +/** + * Base cart item body used for cart mutations + */ +export type CartItemBody = { + variantId: string + productId?: string + quantity?: number +} + +/** + * Hooks schema + */ + +export type CartTypes = { + cart?: Cart + item: LineItem + itemBody: CartItemBody +} + +export type CartHooks = { + getCart: GetCartHook + addItem: AddItemHook + updateItem: UpdateItemHook + removeItem: RemoveItemHook +} + +export type GetCartHook = { + data: T['cart'] | null + input: {} + fetcherInput: { cartId?: string } + swrState: { isEmpty: boolean } +} + +export type AddItemHook = { + data: T['cart'] + input?: T['itemBody'] + fetcherInput: T['itemBody'] + body: { item: T['itemBody'] } + actionInput: T['itemBody'] +} + +export type UpdateItemHook = { + data: T['cart'] | null + input: { item?: T['item']; wait?: number } + fetcherInput: { itemId: string; item: T['itemBody'] } + body: { itemId: string; item: T['itemBody'] } + actionInput: T['itemBody'] & { id: string } +} + +export type RemoveItemHook = { + data: T['cart'] | null + input: { item?: T['item'] } + fetcherInput: { itemId: string } + body: { itemId: string } + actionInput: { id: string } +} + +/** + * API Schema + */ + +export type CartSchema = { + endpoint: { + options: {} + handlers: CartHandlers + } +} + +export type CartHandlers = { + getCart: GetCartHandler + addItem: AddItemHandler + updateItem: UpdateItemHandler + removeItem: RemoveItemHandler +} + +export type GetCartHandler = GetCartHook & { + body: { cartId?: string } +} + +export type AddItemHandler = AddItemHook & { + body: { cartId: string } +} + +export type UpdateItemHandler< + T extends CartTypes = CartTypes +> = UpdateItemHook & { + data: T['cart'] + body: { cartId: string } +} + +export type RemoveItemHandler< + T extends CartTypes = CartTypes +> = RemoveItemHook & { + body: { cartId: string } +} diff --git a/framework/commerce/types/checkout.ts b/framework/commerce/types/checkout.ts new file mode 100644 index 000000000..9e3c7ecfa --- /dev/null +++ b/framework/commerce/types/checkout.ts @@ -0,0 +1,10 @@ +export type CheckoutSchema = { + endpoint: { + options: {} + handlers: { + checkout: { + data: null + } + } + } +} diff --git a/framework/commerce/types/common.ts b/framework/commerce/types/common.ts new file mode 100644 index 000000000..06908c464 --- /dev/null +++ b/framework/commerce/types/common.ts @@ -0,0 +1,16 @@ +export type Discount = { + // The value of the discount, can be an amount or percentage + value: number +} + +export type Measurement = { + value: number + unit: 'KILOGRAMS' | 'GRAMS' | 'POUNDS' | 'OUNCES' +} + +export type Image = { + url: string + altText?: string + width?: number + height?: number +} diff --git a/framework/commerce/types/customer.ts b/framework/commerce/types/customer.ts new file mode 100644 index 000000000..ba90acdf4 --- /dev/null +++ b/framework/commerce/types/customer.ts @@ -0,0 +1,22 @@ +// TODO: define this type +export type Customer = any + +export type CustomerTypes = { + customer: Customer +} + +export type CustomerHook = { + data: T['customer'] | null + fetchData: { customer: T['customer'] } | null +} + +export type CustomerSchema = { + endpoint: { + options: {} + handlers: { + getLoggedInCustomer: { + data: { customer: T['customer'] } | null + } + } + } +} diff --git a/framework/commerce/types/index.ts b/framework/commerce/types/index.ts new file mode 100644 index 000000000..7ab0b7f64 --- /dev/null +++ b/framework/commerce/types/index.ts @@ -0,0 +1,25 @@ +import * as Cart from './cart' +import * as Checkout from './checkout' +import * as Common from './common' +import * as Customer from './customer' +import * as Login from './login' +import * as Logout from './logout' +import * as Page from './page' +import * as Product from './product' +import * as Signup from './signup' +import * as Site from './site' +import * as Wishlist from './wishlist' + +export type { + Cart, + Checkout, + Common, + Customer, + Login, + Logout, + Page, + Product, + Signup, + Site, + Wishlist, +} diff --git a/framework/commerce/types/login.ts b/framework/commerce/types/login.ts new file mode 100644 index 000000000..b6ef228e0 --- /dev/null +++ b/framework/commerce/types/login.ts @@ -0,0 +1,29 @@ +export type LoginBody = { + email: string + password: string +} + +export type LoginTypes = { + body: LoginBody +} + +export type LoginHook = { + data: null + actionInput: LoginBody + fetcherInput: LoginBody + body: T['body'] +} + +export type LoginSchema = { + endpoint: { + options: {} + handlers: { + login: LoginHook + } + } +} + +export type LoginOperation = { + data: { result?: string } + variables: unknown +} diff --git a/framework/commerce/types/logout.ts b/framework/commerce/types/logout.ts new file mode 100644 index 000000000..a7240052f --- /dev/null +++ b/framework/commerce/types/logout.ts @@ -0,0 +1,17 @@ +export type LogoutTypes = { + body: { redirectTo?: string } +} + +export type LogoutHook = { + data: null + body: T['body'] +} + +export type LogoutSchema = { + endpoint: { + options: {} + handlers: { + logout: LogoutHook + } + } +} diff --git a/framework/commerce/types/page.ts b/framework/commerce/types/page.ts new file mode 100644 index 000000000..89f82c1a6 --- /dev/null +++ b/framework/commerce/types/page.ts @@ -0,0 +1,28 @@ +// TODO: define this type +export type Page = { + // ID of the Web page. + id: string + // Page name, as displayed on the storefront. + name: string + // Relative URL on the storefront for this page. + url?: string + // HTML or variable that populates this page’s `` element, in default/desktop view. Required in POST if page type is `raw`. + body: string + // If true, this page appears in the storefront’s navigation menu. + is_visible?: boolean + // Order in which this page should display on the storefront. (Lower integers specify earlier display.) + sort_order?: number +} + +export type PageTypes = { + page: Page +} + +export type GetAllPagesOperation = { + data: { pages: T['page'][] } +} + +export type GetPageOperation = { + data: { page?: T['page'] } + variables: { id: string } +} diff --git a/framework/commerce/types/product.ts b/framework/commerce/types/product.ts new file mode 100644 index 000000000..a12e332b4 --- /dev/null +++ b/framework/commerce/types/product.ts @@ -0,0 +1,99 @@ +export type ProductImage = { + url: string + alt?: string +} + +export type ProductPrice = { + value: number + currencyCode?: 'USD' | 'ARS' | string + retailPrice?: number + salePrice?: number + listPrice?: number + extendedSalePrice?: number + extendedListPrice?: number +} + +export type ProductOption = { + __typename?: 'MultipleChoiceOption' + id: string + displayName: string + values: ProductOptionValues[] +} + +export type ProductOptionValues = { + label: string + hexColors?: string[] +} + +export type ProductVariant = { + id: string | number + options: ProductOption[] + availableForSale?: boolean +} + +export type Product = { + id: string + name: string + description: string + descriptionHtml?: string + sku?: string + slug?: string + path?: string + images: ProductImage[] + variants: ProductVariant[] + price: ProductPrice + options: ProductOption[] +} + +export type SearchProductsBody = { + search?: string + categoryId?: string | number + brandId?: string | number + sort?: string + locale?: string +} + +export type ProductTypes = { + product: Product + searchBody: SearchProductsBody +} + +export type SearchProductsHook = { + data: { + products: T['product'][] + found: boolean + } + body: T['searchBody'] + input: T['searchBody'] + fetcherInput: T['searchBody'] +} + +export type ProductsSchema = { + endpoint: { + options: {} + handlers: { + getProducts: SearchProductsHook + } + } +} + +export type GetAllProductPathsOperation< + T extends ProductTypes = ProductTypes +> = { + data: { products: Pick[] } + variables: { first?: number } +} + +export type GetAllProductsOperation = { + data: { products: T['product'][] } + variables: { + relevance?: 'featured' | 'best_selling' | 'newest' + ids?: string[] + first?: number + } +} + +export type GetProductOperation = { + data: { product?: T['product'] } + variables: { path: string; slug?: never } | { path?: never; slug: string } +} diff --git a/framework/commerce/types/signup.ts b/framework/commerce/types/signup.ts new file mode 100644 index 000000000..4e23da6c0 --- /dev/null +++ b/framework/commerce/types/signup.ts @@ -0,0 +1,26 @@ +export type SignupBody = { + firstName: string + lastName: string + email: string + password: string +} + +export type SignupTypes = { + body: SignupBody +} + +export type SignupHook = { + data: null + body: T['body'] + actionInput: T['body'] + fetcherInput: T['body'] +} + +export type SignupSchema = { + endpoint: { + options: {} + handlers: { + signup: SignupHook + } + } +} diff --git a/framework/commerce/types/site.ts b/framework/commerce/types/site.ts new file mode 100644 index 000000000..73c7dddd2 --- /dev/null +++ b/framework/commerce/types/site.ts @@ -0,0 +1,20 @@ +export type Category = { + id: string + name: string + slug: string + path: string +} + +export type Brand = any + +export type SiteTypes = { + category: Category + brand: Brand +} + +export type GetSiteInfoOperation = { + data: { + categories: T['category'][] + brands: T['brand'][] + } +} diff --git a/framework/commerce/types/wishlist.ts b/framework/commerce/types/wishlist.ts new file mode 100644 index 000000000..b3759849c --- /dev/null +++ b/framework/commerce/types/wishlist.ts @@ -0,0 +1,60 @@ +// TODO: define this type +export type Wishlist = any + +export type WishlistItemBody = { + variantId: string | number + productId: string +} + +export type WishlistTypes = { + wishlist: Wishlist + itemBody: WishlistItemBody +} + +export type GetWishlistHook = { + data: T['wishlist'] | null + body: { includeProducts?: boolean } + input: { includeProducts?: boolean } + fetcherInput: { customerId: string; includeProducts?: boolean } + swrState: { isEmpty: boolean } +} + +export type AddItemHook = { + data: T['wishlist'] + body: { item: T['itemBody'] } + fetcherInput: { item: T['itemBody'] } + actionInput: T['itemBody'] +} + +export type RemoveItemHook = { + data: T['wishlist'] | null + body: { itemId: string } + fetcherInput: { itemId: string } + actionInput: { id: string } + input: { wishlist?: { includeProducts?: boolean } } +} + +export type WishlistSchema = { + endpoint: { + options: {} + handlers: { + getWishlist: GetWishlistHook & { + data: T['wishlist'] | null + body: { customerToken?: string } + } + addItem: AddItemHook & { + body: { customerToken?: string } + } + removeItem: RemoveItemHook & { + body: { customerToken?: string } + } + } + } +} + +export type GetCustomerWishlistOperation< + T extends WishlistTypes = WishlistTypes +> = { + data: { wishlist?: T['wishlist'] } + variables: { customerId: string } +} diff --git a/framework/commerce/utils/default-fetcher.ts b/framework/commerce/utils/default-fetcher.ts index 493a9b5f9..53312fc96 100644 --- a/framework/commerce/utils/default-fetcher.ts +++ b/framework/commerce/utils/default-fetcher.ts @@ -1,9 +1,9 @@ import type { HookFetcherFn } from './types' -export const SWRFetcher: HookFetcherFn = ({ options, fetch }) => +export const SWRFetcher: HookFetcherFn = ({ options, fetch }) => fetch(options) -export const mutationFetcher: HookFetcherFn = ({ +export const mutationFetcher: HookFetcherFn = ({ input, options, fetch, diff --git a/framework/commerce/utils/types.ts b/framework/commerce/utils/types.ts index 852afb208..751cea4a5 100644 --- a/framework/commerce/utils/types.ts +++ b/framework/commerce/utils/types.ts @@ -36,14 +36,19 @@ export type HookFetcher = ( fetch: (options: FetcherOptions) => Promise ) => Data | Promise -export type HookFetcherFn = ( - context: HookFetcherContext -) => Data | Promise +export type HookFetcherFn = ( + context: HookFetcherContext +) => H['data'] | Promise -export type HookFetcherContext = { +export type HookFetcherContext = { options: HookFetcherOptions - input: Input - fetch: (options: FetcherOptions) => Promise + input: H['fetcherInput'] + fetch: < + T = H['fetchData'] extends {} | null ? H['fetchData'] : any, + B = H['body'] + >( + options: FetcherOptions + ) => Promise } export type HookFetcherOptions = { method?: string } & ( @@ -58,7 +63,7 @@ export type HookSWRInput = [string, HookInputValue][] export type HookFetchInput = { [k: string]: HookInputValue } export type HookFunction< - Input extends { [k: string]: unknown } | null, + Input extends { [k: string]: unknown } | undefined, T > = keyof Input extends never ? () => T @@ -66,62 +71,72 @@ export type HookFunction< ? (input?: Input) => T : (input: Input) => T -export type SWRHook< - // Data obj returned by the hook and fetch operation - Data, +export type HookSchemaBase = { + // Data obj returned by the hook + data: any // Input expected by the hook - Input extends { [k: string]: unknown } = {}, - // Input expected before doing a fetch operation - FetchInput extends HookFetchInput = {}, + input?: {} + // Input expected before doing a fetch operation (aka fetch handler) + fetcherInput?: {} + // Body object expected by the fetch operation + body?: {} + // Data returned by the fetch operation + fetchData?: any +} + +export type SWRHookSchemaBase = HookSchemaBase & { // Custom state added to the response object of SWR - State = {} -> = { + swrState?: {} +} + +export type MutationSchemaBase = HookSchemaBase & { + // Input expected by the action returned by the hook + actionInput?: {} +} + +/** + * Generates a SWR hook handler based on the schema of a hook + */ +export type SWRHook = { useHook( - context: SWRHookContext + context: SWRHookContext ): HookFunction< - Input & { swrOptions?: SwrOptions }, - ResponseState & State + H['input'] & { swrOptions?: SwrOptions }, + ResponseState & H['swrState'] > fetchOptions: HookFetcherOptions - fetcher?: HookFetcherFn + fetcher?: HookFetcherFn } -export type SWRHookContext< - Data, - FetchInput extends { [k: string]: unknown } = {} -> = { +export type SWRHookContext = { useData(context?: { input?: HookFetchInput | HookSWRInput - swrOptions?: SwrOptions - }): ResponseState + swrOptions?: SwrOptions + }): ResponseState } -export type MutationHook< - // Data obj returned by the hook and fetch operation - Data, - // Input expected by the hook - Input extends { [k: string]: unknown } = {}, - // Input expected by the action returned by the hook - ActionInput extends { [k: string]: unknown } = {}, - // Input expected before doing a fetch operation - FetchInput extends { [k: string]: unknown } = ActionInput -> = { +/** + * Generates a mutation hook handler based on the schema of a hook + */ +export type MutationHook = { useHook( - context: MutationHookContext - ): HookFunction>> + context: MutationHookContext + ): HookFunction< + H['input'], + HookFunction> + > fetchOptions: HookFetcherOptions - fetcher?: HookFetcherFn + fetcher?: HookFetcherFn } -export type MutationHookContext< - Data, - FetchInput extends { [k: string]: unknown } | null = {} -> = { - fetch: keyof FetchInput extends never - ? () => Data | Promise - : Partial extends FetchInput - ? (context?: { input?: FetchInput }) => Data | Promise - : (context: { input: FetchInput }) => Data | Promise +export type MutationHookContext = { + fetch: keyof H['fetcherInput'] extends never + ? () => H['data'] | Promise + : Partial extends H['fetcherInput'] + ? (context?: { + input?: H['fetcherInput'] + }) => H['data'] | Promise + : (context: { input: H['fetcherInput'] }) => H['data'] | Promise } export type SwrOptions = ConfigInterface< diff --git a/framework/commerce/utils/use-data.tsx b/framework/commerce/utils/use-data.tsx index 9224b612c..4fc208bab 100644 --- a/framework/commerce/utils/use-data.tsx +++ b/framework/commerce/utils/use-data.tsx @@ -2,10 +2,11 @@ import useSWR, { responseInterface } from 'swr' import type { HookSWRInput, HookFetchInput, - Fetcher, - SwrOptions, HookFetcherOptions, HookFetcherFn, + Fetcher, + SwrOptions, + SWRHookSchemaBase, } from './types' import defineProperty from './define-property' import { CommerceError } from './errors' @@ -14,15 +15,15 @@ export type ResponseState = responseInterface & { isLoading: boolean } -export type UseData = ( +export type UseData = ( options: { fetchOptions: HookFetcherOptions - fetcher: HookFetcherFn + fetcher: HookFetcherFn }, input: HookFetchInput | HookSWRInput, fetcherFn: Fetcher, - swrOptions?: SwrOptions -) => ResponseState + swrOptions?: SwrOptions +) => ResponseState const useData: UseData = (options, input, fetcherFn, swrOptions) => { const hookInput = Array.isArray(input) ? input : Object.entries(input) diff --git a/framework/commerce/utils/use-hook.ts b/framework/commerce/utils/use-hook.ts index da3431e3c..1bf0779c4 100644 --- a/framework/commerce/utils/use-hook.ts +++ b/framework/commerce/utils/use-hook.ts @@ -10,14 +10,14 @@ export function useFetcher() { export function useHook< P extends Provider, - H extends MutationHook | SWRHook + H extends MutationHook | SWRHook >(fn: (provider: P) => H) { const { providerRef } = useCommerce

    () const provider = providerRef.current return fn(provider) } -export function useSWRHook>( +export function useSWRHook>( hook: PickRequired ) { const fetcher = useFetcher() @@ -30,7 +30,7 @@ export function useSWRHook>( }) } -export function useMutationHook>( +export function useMutationHook>( hook: PickRequired ) { const fetcher = useFetcher() diff --git a/framework/commerce/wishlist/use-add-item.tsx b/framework/commerce/wishlist/use-add-item.tsx index 11c8cc241..f464be1ca 100644 --- a/framework/commerce/wishlist/use-add-item.tsx +++ b/framework/commerce/wishlist/use-add-item.tsx @@ -1,10 +1,11 @@ import { useHook, useMutationHook } from '../utils/use-hook' import { mutationFetcher } from '../utils/default-fetcher' import type { MutationHook } from '../utils/types' +import type { AddItemHook } from '../types/wishlist' import type { Provider } from '..' export type UseAddItem< - H extends MutationHook = MutationHook + H extends MutationHook> = MutationHook > = ReturnType export const fetcher = mutationFetcher diff --git a/framework/commerce/wishlist/use-remove-item.tsx b/framework/commerce/wishlist/use-remove-item.tsx index c8c34a5af..4419c17af 100644 --- a/framework/commerce/wishlist/use-remove-item.tsx +++ b/framework/commerce/wishlist/use-remove-item.tsx @@ -1,28 +1,20 @@ import { useHook, useMutationHook } from '../utils/use-hook' import { mutationFetcher } from '../utils/default-fetcher' import type { HookFetcherFn, MutationHook } from '../utils/types' +import type { RemoveItemHook } from '../types/wishlist' import type { Provider } from '..' -export type RemoveItemInput = { - id: string | number -} - export type UseRemoveItem< - H extends MutationHook = MutationHook< - any | null, - { wishlist?: any }, - RemoveItemInput, - {} - > + H extends MutationHook> = MutationHook > = ReturnType -export const fetcher: HookFetcherFn = mutationFetcher +export const fetcher: HookFetcherFn = mutationFetcher const fn = (provider: Provider) => provider.wishlist?.useRemoveItem! -const useRemoveItem: UseRemoveItem = (input) => { +const useRemoveItem: UseRemoveItem = (...args) => { const hook = useHook(fn) - return useMutationHook({ fetcher, ...hook })(input) + return useMutationHook({ fetcher, ...hook })(...args) } export default useRemoveItem diff --git a/framework/commerce/wishlist/use-wishlist.tsx b/framework/commerce/wishlist/use-wishlist.tsx index 7a93b20b1..672203f79 100644 --- a/framework/commerce/wishlist/use-wishlist.tsx +++ b/framework/commerce/wishlist/use-wishlist.tsx @@ -1,25 +1,20 @@ import { useHook, useSWRHook } from '../utils/use-hook' import { SWRFetcher } from '../utils/default-fetcher' import type { HookFetcherFn, SWRHook } from '../utils/types' -import type { Wishlist } from '../types' +import type { GetWishlistHook } from '../types/wishlist' import type { Provider } from '..' export type UseWishlist< - H extends SWRHook = SWRHook< - Wishlist | null, - { includeProducts?: boolean }, - { customerId?: number; includeProducts: boolean }, - { isEmpty?: boolean } - > + H extends SWRHook> = SWRHook > = ReturnType -export const fetcher: HookFetcherFn = SWRFetcher +export const fetcher: HookFetcherFn = SWRFetcher const fn = (provider: Provider) => provider.wishlist?.useWishlist! -const useWishlist: UseWishlist = (input) => { +const useWishlist: UseWishlist = (...args) => { const hook = useHook(fn) - return useSWRHook({ fetcher, ...hook })(input) + return useSWRHook({ fetcher, ...hook })(...args) } export default useWishlist diff --git a/framework/shopify/README.md b/framework/shopify/README.md index d67111a41..d5c4aa942 100644 --- a/framework/shopify/README.md +++ b/framework/shopify/README.md @@ -121,3 +121,15 @@ const pages = await getAllPages({ config, }) ``` + +## Code generation + +This provider makes use of GraphQL code generation. The [schema.graphql](./schema.graphql) and [schema.d.ts](./schema.d.ts) files contain the generated types & schema introspection results. + +When developing the provider, changes to any GraphQL operations should be followed by re-generation of the types and schema files: + +From the project root dir, run: + +```sh +yarn generate:shopify +``` diff --git a/framework/shopify/api/cart/index.ts b/framework/shopify/api/cart/index.ts deleted file mode 100644 index ea9b101e1..000000000 --- a/framework/shopify/api/cart/index.ts +++ /dev/null @@ -1 +0,0 @@ -export default function () {} diff --git a/framework/shopify/api/catalog/index.ts b/framework/shopify/api/catalog/index.ts deleted file mode 100644 index ea9b101e1..000000000 --- a/framework/shopify/api/catalog/index.ts +++ /dev/null @@ -1 +0,0 @@ -export default function () {} diff --git a/framework/shopify/api/catalog/products.ts b/framework/shopify/api/catalog/products.ts deleted file mode 100644 index ea9b101e1..000000000 --- a/framework/shopify/api/catalog/products.ts +++ /dev/null @@ -1 +0,0 @@ -export default function () {} diff --git a/framework/shopify/api/customer.ts b/framework/shopify/api/customer.ts deleted file mode 100644 index ea9b101e1..000000000 --- a/framework/shopify/api/customer.ts +++ /dev/null @@ -1 +0,0 @@ -export default function () {} diff --git a/framework/shopify/api/customers/index.ts b/framework/shopify/api/customers/index.ts deleted file mode 100644 index ea9b101e1..000000000 --- a/framework/shopify/api/customers/index.ts +++ /dev/null @@ -1 +0,0 @@ -export default function () {} diff --git a/framework/shopify/api/customers/login.ts b/framework/shopify/api/customers/login.ts deleted file mode 100644 index ea9b101e1..000000000 --- a/framework/shopify/api/customers/login.ts +++ /dev/null @@ -1 +0,0 @@ -export default function () {} diff --git a/framework/shopify/api/customers/logout.ts b/framework/shopify/api/customers/logout.ts deleted file mode 100644 index ea9b101e1..000000000 --- a/framework/shopify/api/customers/logout.ts +++ /dev/null @@ -1 +0,0 @@ -export default function () {} diff --git a/framework/shopify/api/customers/signup.ts b/framework/shopify/api/customers/signup.ts deleted file mode 100644 index ea9b101e1..000000000 --- a/framework/shopify/api/customers/signup.ts +++ /dev/null @@ -1 +0,0 @@ -export default function () {} diff --git a/framework/shopify/api/endpoints/cart.ts b/framework/shopify/api/endpoints/cart.ts new file mode 100644 index 000000000..d09c976c3 --- /dev/null +++ b/framework/shopify/api/endpoints/cart.ts @@ -0,0 +1 @@ +export default function (_commerce: any) {} diff --git a/framework/shopify/api/endpoints/catalog/products.ts b/framework/shopify/api/endpoints/catalog/products.ts new file mode 100644 index 000000000..d09c976c3 --- /dev/null +++ b/framework/shopify/api/endpoints/catalog/products.ts @@ -0,0 +1 @@ +export default function (_commerce: any) {} diff --git a/framework/shopify/api/checkout/index.ts b/framework/shopify/api/endpoints/checkout/checkout.ts similarity index 56% rename from framework/shopify/api/checkout/index.ts rename to framework/shopify/api/endpoints/checkout/checkout.ts index 244078466..0c340a129 100644 --- a/framework/shopify/api/checkout/index.ts +++ b/framework/shopify/api/endpoints/checkout/checkout.ts @@ -1,24 +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 { 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() +} from '../../../const' +import associateCustomerWithCheckoutMutation from '../../../utils/mutations/associate-customer-with-checkout' +import type { CheckoutEndpoint } from '.' +const checkout: CheckoutEndpoint['handlers']['checkout'] = async ({ + req, + res, + config, +}) => { const { cookies } = req const checkoutUrl = cookies[SHOPIFY_CHECKOUT_URL_COOKIE] const customerCookie = cookies[SHOPIFY_CUSTOMER_TOKEN_COOKIE] @@ -43,4 +35,4 @@ const checkoutApi: ShopifyApiHandler = async (req, res, config) => { } } -export default createApiHandler(checkoutApi, {}, {}) +export default checkout diff --git a/framework/shopify/api/endpoints/checkout/index.ts b/framework/shopify/api/endpoints/checkout/index.ts new file mode 100644 index 000000000..5d78f451b --- /dev/null +++ b/framework/shopify/api/endpoints/checkout/index.ts @@ -0,0 +1,18 @@ +import { GetAPISchema, createEndpoint } from '@commerce/api' +import checkoutEndpoint from '@commerce/api/endpoints/checkout' +import type { CheckoutSchema } from '../../../types/checkout' +import type { ShopifyAPI } from '../..' +import checkout from './checkout' + +export type CheckoutAPI = GetAPISchema + +export type CheckoutEndpoint = CheckoutAPI['endpoint'] + +export const handlers: CheckoutEndpoint['handlers'] = { checkout } + +const checkoutApi = createEndpoint({ + handler: checkoutEndpoint, + handlers, +}) + +export default checkoutApi diff --git a/framework/shopify/api/endpoints/customer.ts b/framework/shopify/api/endpoints/customer.ts new file mode 100644 index 000000000..d09c976c3 --- /dev/null +++ b/framework/shopify/api/endpoints/customer.ts @@ -0,0 +1 @@ +export default function (_commerce: any) {} diff --git a/framework/shopify/api/endpoints/login.ts b/framework/shopify/api/endpoints/login.ts new file mode 100644 index 000000000..d09c976c3 --- /dev/null +++ b/framework/shopify/api/endpoints/login.ts @@ -0,0 +1 @@ +export default function (_commerce: any) {} diff --git a/framework/shopify/api/endpoints/logout.ts b/framework/shopify/api/endpoints/logout.ts new file mode 100644 index 000000000..d09c976c3 --- /dev/null +++ b/framework/shopify/api/endpoints/logout.ts @@ -0,0 +1 @@ +export default function (_commerce: any) {} diff --git a/framework/shopify/api/endpoints/signup.ts b/framework/shopify/api/endpoints/signup.ts new file mode 100644 index 000000000..d09c976c3 --- /dev/null +++ b/framework/shopify/api/endpoints/signup.ts @@ -0,0 +1 @@ +export default function (_commerce: any) {} diff --git a/framework/shopify/api/endpoints/wishlist.ts b/framework/shopify/api/endpoints/wishlist.ts new file mode 100644 index 000000000..d09c976c3 --- /dev/null +++ b/framework/shopify/api/endpoints/wishlist.ts @@ -0,0 +1 @@ +export default function (_commerce: any) {} diff --git a/framework/shopify/api/index.ts b/framework/shopify/api/index.ts index 387ed02fc..28c7d34b3 100644 --- a/framework/shopify/api/index.ts +++ b/framework/shopify/api/index.ts @@ -1,12 +1,20 @@ -import type { CommerceAPIConfig } from '@commerce/api' +import { + CommerceAPI, + CommerceAPIConfig, + getCommerceApi as commerceApi, +} from '@commerce/api' import { API_URL, API_TOKEN, - SHOPIFY_CHECKOUT_ID_COOKIE, SHOPIFY_CUSTOMER_TOKEN_COOKIE, + SHOPIFY_CHECKOUT_ID_COOKIE, } from '../const' +import fetchGraphqlApi from './utils/fetch-graphql-api' + +import * as operations from './operations' + if (!API_URL) { throw new Error( `The environment variable NEXT_PUBLIC_SHOPIFY_STORE_DOMAIN is missing and it's required to access your store` @@ -18,44 +26,30 @@ if (!API_TOKEN) { `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 +const ONE_DAY = 60 * 60 * 24 - 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', +const config: ShopifyConfig = { commerceUrl: API_URL, - apiToken: API_TOKEN!, - cartCookie: SHOPIFY_CHECKOUT_ID_COOKIE, - cartCookieMaxAge: 60 * 60 * 24 * 30, - fetch: fetchGraphqlApi, + apiToken: API_TOKEN, customerCookie: SHOPIFY_CUSTOMER_TOKEN_COOKIE, -}) - -export function getConfig(userConfig?: Partial) { - return config.getConfig(userConfig) + cartCookie: SHOPIFY_CHECKOUT_ID_COOKIE, + cartCookieMaxAge: ONE_DAY * 30, + fetch: fetchGraphqlApi, } -export function setConfig(newConfig: Partial) { - return config.setConfig(newConfig) +export const provider = { + config, + operations, +} + +export type Provider = typeof provider + +export type ShopifyAPI

    = CommerceAPI

    + +export function getCommerceApi

    ( + customProvider: P = provider as any +): ShopifyAPI

    { + return commerceApi(customProvider) } diff --git a/framework/shopify/api/operations/get-all-pages.ts b/framework/shopify/api/operations/get-all-pages.ts new file mode 100644 index 000000000..ab0af9ff7 --- /dev/null +++ b/framework/shopify/api/operations/get-all-pages.ts @@ -0,0 +1,67 @@ +import type { + OperationContext, + OperationOptions, +} from '@commerce/api/operations' +import { + GetAllPagesQuery, + GetAllPagesQueryVariables, + PageEdge, +} from '../../schema' +import { normalizePages } from '../../utils' +import type { ShopifyConfig, Provider } from '..' +import type { GetAllPagesOperation, Page } from '../../types/page' +import getAllPagesQuery from '../../utils/queries/get-all-pages-query' + +export default function getAllPagesOperation({ + commerce, +}: OperationContext) { + async function getAllPages(opts?: { + config?: Partial + preview?: boolean + }): Promise + + async function getAllPages( + opts: { + config?: Partial + preview?: boolean + } & OperationOptions + ): Promise + + async function getAllPages({ + query = getAllPagesQuery, + config, + variables, + }: { + url?: string + config?: Partial + variables?: GetAllPagesQueryVariables + preview?: boolean + query?: string + } = {}): Promise { + const { fetch, locale, locales = ['en-US'] } = commerce.getConfig(config) + + const { data } = await fetch( + query, + { + variables, + }, + { + ...(locale && { + headers: { + 'Accept-Language': locale, + }, + }), + } + ) + + return { + pages: locales.reduce( + (arr, locale) => + arr.concat(normalizePages(data.pages.edges as PageEdge[], locale)), + [] + ), + } + } + + return getAllPages +} diff --git a/framework/shopify/api/operations/get-all-product-paths.ts b/framework/shopify/api/operations/get-all-product-paths.ts new file mode 100644 index 000000000..c84f8c90a --- /dev/null +++ b/framework/shopify/api/operations/get-all-product-paths.ts @@ -0,0 +1,55 @@ +import type { + OperationContext, + OperationOptions, +} from '@commerce/api/operations' +import { GetAllProductPathsOperation } from '../../types/product' +import { + GetAllProductPathsQuery, + GetAllProductPathsQueryVariables, + ProductEdge, +} from '../../schema' +import type { ShopifyConfig, Provider } from '..' +import { getAllProductsQuery } from '../../utils' + +export default function getAllProductPathsOperation({ + commerce, +}: OperationContext) { + async function getAllProductPaths< + T extends GetAllProductPathsOperation + >(opts?: { + variables?: T['variables'] + config?: ShopifyConfig + }): Promise + + async function getAllProductPaths( + opts: { + variables?: T['variables'] + config?: ShopifyConfig + } & OperationOptions + ): Promise + + async function getAllProductPaths({ + query = getAllProductsQuery, + config, + variables, + }: { + query?: string + config?: ShopifyConfig + variables?: T['variables'] + } = {}): Promise { + config = commerce.getConfig(config) + + const { data } = await config.fetch< + GetAllProductPathsQuery, + GetAllProductPathsQueryVariables + >(query, { variables }) + + return { + products: data.products.edges.map(({ node: { handle } }) => ({ + path: `/${handle}`, + })), + } + } + + return getAllProductPaths +} diff --git a/framework/shopify/api/operations/get-all-products.ts b/framework/shopify/api/operations/get-all-products.ts new file mode 100644 index 000000000..08d781d5c --- /dev/null +++ b/framework/shopify/api/operations/get-all-products.ts @@ -0,0 +1,67 @@ +import type { + OperationContext, + OperationOptions, +} from '@commerce/api/operations' +import { GetAllProductsOperation } from '../../types/product' +import { + GetAllProductsQuery, + GetAllProductsQueryVariables, + Product as ShopifyProduct, +} from '../../schema' +import type { ShopifyConfig, Provider } from '..' +import getAllProductsQuery from '../../utils/queries/get-all-products-query' +import { normalizeProduct } from '../../utils' + +export default function getAllProductsOperation({ + commerce, +}: OperationContext) { + async function getAllProducts(opts?: { + variables?: T['variables'] + config?: Partial + preview?: boolean + }): Promise + + async function getAllProducts( + opts: { + variables?: T['variables'] + config?: Partial + preview?: boolean + } & OperationOptions + ): Promise + + async function getAllProducts({ + query = getAllProductsQuery, + variables, + config, + }: { + query?: string + variables?: T['variables'] + config?: Partial + preview?: boolean + } = {}): Promise { + const { fetch, locale } = commerce.getConfig(config) + + const { data } = await fetch< + GetAllProductsQuery, + GetAllProductsQueryVariables + >( + query, + { variables }, + { + ...(locale && { + headers: { + 'Accept-Language': locale, + }, + }), + } + ) + + return { + products: data.products.edges.map(({ node }) => + normalizeProduct(node as ShopifyProduct) + ), + } + } + + return getAllProducts +} diff --git a/framework/shopify/api/operations/get-page.ts b/framework/shopify/api/operations/get-page.ts new file mode 100644 index 000000000..67e135ebe --- /dev/null +++ b/framework/shopify/api/operations/get-page.ts @@ -0,0 +1,64 @@ +import type { + OperationContext, + OperationOptions, +} from '@commerce/api/operations' +import { normalizePage } from '../../utils' +import type { ShopifyConfig, Provider } from '..' +import { + GetPageQuery, + GetPageQueryVariables, + Page as ShopifyPage, +} from '../../schema' +import { GetPageOperation } from '../../types/page' +import getPageQuery from '../../utils/queries/get-page-query' + +export default function getPageOperation({ + commerce, +}: OperationContext) { + async function getPage(opts: { + variables: T['variables'] + config?: Partial + preview?: boolean + }): Promise + + async function getPage( + opts: { + variables: T['variables'] + config?: Partial + preview?: boolean + } & OperationOptions + ): Promise + + async function getPage({ + query = getPageQuery, + variables, + config, + }: { + query?: string + variables: T['variables'] + config?: Partial + preview?: boolean + }): Promise { + const { fetch, locale = 'en-US' } = commerce.getConfig(config) + + const { + data: { node: page }, + } = await fetch( + query, + { + variables, + }, + { + ...(locale && { + headers: { + 'Accept-Language': locale, + }, + }), + } + ) + + return page ? { page: normalizePage(page as ShopifyPage, locale) } : {} + } + + return getPage +} diff --git a/framework/shopify/api/operations/get-product.ts b/framework/shopify/api/operations/get-product.ts new file mode 100644 index 000000000..447b5c792 --- /dev/null +++ b/framework/shopify/api/operations/get-product.ts @@ -0,0 +1,63 @@ +import type { + OperationContext, + OperationOptions, +} from '@commerce/api/operations' +import { GetProductOperation } from '../../types/product' +import { normalizeProduct, getProductQuery } from '../../utils' +import type { ShopifyConfig, Provider } from '..' +import { GetProductBySlugQuery, Product as ShopifyProduct } from '../../schema' + +export default function getProductOperation({ + commerce, +}: OperationContext) { + async function getProduct(opts: { + variables: T['variables'] + config?: Partial + preview?: boolean + }): Promise + + async function getProduct( + opts: { + variables: T['variables'] + config?: Partial + preview?: boolean + } & OperationOptions + ): Promise + + async function getProduct({ + query = getProductQuery, + variables, + config: cfg, + }: { + query?: string + variables: T['variables'] + config?: Partial + preview?: boolean + }): Promise { + const { fetch, locale } = commerce.getConfig(cfg) + + const { + data: { productByHandle }, + } = await fetch( + query, + { + variables, + }, + { + ...(locale && { + headers: { + 'Accept-Language': locale, + }, + }), + } + ) + + return { + ...(productByHandle && { + product: normalizeProduct(productByHandle as ShopifyProduct), + }), + } + } + + return getProduct +} diff --git a/framework/shopify/api/operations/get-site-info.ts b/framework/shopify/api/operations/get-site-info.ts new file mode 100644 index 000000000..27b63b0f9 --- /dev/null +++ b/framework/shopify/api/operations/get-site-info.ts @@ -0,0 +1,62 @@ +import type { + OperationContext, + OperationOptions, +} from '@commerce/api/operations' +import { GetSiteInfoQueryVariables } from '../../schema' +import type { ShopifyConfig, Provider } from '..' +import { GetSiteInfoOperation } from '../../types/site' + +import { getCategories, getBrands, getSiteInfoQuery } from '../../utils' + +export default function getSiteInfoOperation({ + commerce, +}: OperationContext) { + async function getSiteInfo(opts?: { + config?: Partial + preview?: boolean + }): Promise + + async function getSiteInfo( + opts: { + config?: Partial + preview?: boolean + } & OperationOptions + ): Promise + + async function getSiteInfo({ + query = getSiteInfoQuery, + config, + variables, + }: { + query?: string + config?: Partial + preview?: boolean + variables?: GetSiteInfoQueryVariables + } = {}): Promise { + const cfg = commerce.getConfig(config) + + const categories = await getCategories(cfg) + const brands = await getBrands(cfg) + /* + const { fetch, locale } = cfg + const { data } = await fetch( + query, + { variables }, + { + ...(locale && { + headers: { + 'Accept-Language': locale, + }, + }), + } + ) + */ + + return { + categories, + brands, + } + } + + return getSiteInfo +} diff --git a/framework/shopify/api/operations/index.ts b/framework/shopify/api/operations/index.ts new file mode 100644 index 000000000..7872a20b6 --- /dev/null +++ b/framework/shopify/api/operations/index.ts @@ -0,0 +1,7 @@ +export { default as getAllPages } from './get-all-pages' +export { default as getPage } from './get-page' +export { default as getAllProducts } from './get-all-products' +export { default as getAllProductPaths } from './get-all-product-paths' +export { default as getProduct } from './get-product' +export { default as getSiteInfo } from './get-site-info' +export { default as login } from './login' diff --git a/framework/shopify/api/operations/login.ts b/framework/shopify/api/operations/login.ts new file mode 100644 index 000000000..41e837a3f --- /dev/null +++ b/framework/shopify/api/operations/login.ts @@ -0,0 +1,48 @@ +import type { ServerResponse } from 'http' +import type { OperationContext } from '@commerce/api/operations' +import type { LoginOperation } from '../../types/login' +import type { ShopifyConfig, Provider } from '..' +import { + customerAccessTokenCreateMutation, + setCustomerToken, + throwUserErrors, +} from '../../utils' +import { CustomerAccessTokenCreateMutation } from '../../schema' + +export default function loginOperation({ + commerce, +}: OperationContext) { + async function login({ + query = customerAccessTokenCreateMutation, + variables, + config, + }: { + query?: string + variables: T['variables'] + res: ServerResponse + config?: ShopifyConfig + }): Promise { + config = commerce.getConfig(config) + + const { + data: { customerAccessTokenCreate }, + } = await config.fetch(query, { + variables, + }) + + throwUserErrors(customerAccessTokenCreate?.customerUserErrors) + + const customerAccessToken = customerAccessTokenCreate?.customerAccessToken + const accessToken = customerAccessToken?.accessToken + + if (accessToken) { + setCustomerToken(accessToken) + } + + return { + result: customerAccessToken?.accessToken, + } + } + + return login +} diff --git a/framework/shopify/api/utils/create-api-handler.ts b/framework/shopify/api/utils/create-api-handler.ts deleted file mode 100644 index 8820aeabc..000000000 --- a/framework/shopify/api/utils/create-api-handler.ts +++ /dev/null @@ -1,58 +0,0 @@ -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 deleted file mode 100644 index 9fa70a5ee..000000000 --- a/framework/shopify/api/utils/fetch-all-products.ts +++ /dev/null @@ -1,41 +0,0 @@ -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/shopify/api/wishlist/index.tsx b/framework/shopify/api/wishlist/index.tsx deleted file mode 100644 index a72856673..000000000 --- a/framework/shopify/api/wishlist/index.tsx +++ /dev/null @@ -1,2 +0,0 @@ -export type WishlistItem = { product: any; id: number } -export default function () {} diff --git a/framework/shopify/auth/use-login.tsx b/framework/shopify/auth/use-login.tsx index 7993822cd..d4369b7c2 100644 --- a/framework/shopify/auth/use-login.tsx +++ b/framework/shopify/auth/use-login.tsx @@ -1,31 +1,22 @@ 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 { CommerceError } from '@commerce/utils/errors' import useLogin, { UseLogin } from '@commerce/auth/use-login' -import { setCustomerToken, throwUserErrors } from '../utils' +import type { LoginHook } from '../types/login' +import useCustomer from '../customer/use-customer' + +import { + setCustomerToken, + throwUserErrors, + customerAccessTokenCreateMutation, +} from '../utils' +import { Mutation, MutationCustomerAccessTokenCreateArgs } from '../schema' 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 = { +export const handler: MutationHook = { fetchOptions: { - query: createCustomerAccessTokenMutation, + query: customerAccessTokenCreateMutation, }, async fetcher({ input: { email, password }, options, fetch }) { if (!(email && password)) { @@ -37,7 +28,7 @@ export const handler: MutationHook = { const { customerAccessTokenCreate } = await fetch< Mutation, - MutationCheckoutCreateArgs + MutationCustomerAccessTokenCreateArgs >({ ...options, variables: { diff --git a/framework/shopify/auth/use-logout.tsx b/framework/shopify/auth/use-logout.tsx index 81a3b8cdd..30074b8d5 100644 --- a/framework/shopify/auth/use-logout.tsx +++ b/framework/shopify/auth/use-logout.tsx @@ -1,13 +1,14 @@ import { useCallback } from 'react' import type { MutationHook } from '@commerce/utils/types' import useLogout, { UseLogout } from '@commerce/auth/use-logout' +import type { LogoutHook } from '../types/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 = { +export const handler: MutationHook = { fetchOptions: { query: customerAccessTokenDeleteMutation, }, diff --git a/framework/shopify/auth/use-signup.tsx b/framework/shopify/auth/use-signup.tsx index 9ca5c682f..29557e960 100644 --- a/framework/shopify/auth/use-signup.tsx +++ b/framework/shopify/auth/use-signup.tsx @@ -1,25 +1,20 @@ import { useCallback } from 'react' import type { MutationHook } from '@commerce/utils/types' -import { CommerceError, ValidationError } from '@commerce/utils/errors' +import { CommerceError } from '@commerce/utils/errors' import useSignup, { UseSignup } from '@commerce/auth/use-signup' +import type { SignupHook } from '../types/signup' import useCustomer from '../customer/use-customer' -import { - CustomerCreateInput, - Mutation, - MutationCustomerCreateArgs, -} from '../schema' +import { Mutation, MutationCustomerCreateArgs } from '../schema' -import { customerCreateMutation } from '../utils/mutations' -import { handleAutomaticLogin, throwUserErrors } from '../utils' +import { + handleAutomaticLogin, + throwUserErrors, + customerCreateMutation, +} from '../utils' export default useSignup as UseSignup -export const handler: MutationHook< - null, - {}, - CustomerCreateInput, - CustomerCreateInput -> = { +export const handler: MutationHook = { fetchOptions: { query: customerCreateMutation, }, diff --git a/framework/shopify/cart/use-add-item.tsx b/framework/shopify/cart/use-add-item.tsx index cce0950e9..5f0809d01 100644 --- a/framework/shopify/cart/use-add-item.tsx +++ b/framework/shopify/cart/use-add-item.tsx @@ -2,18 +2,19 @@ import { useCallback } from 'react' import type { MutationHook } from '@commerce/utils/types' import { CommerceError } from '@commerce/utils/errors' import useAddItem, { UseAddItem } from '@commerce/cart/use-add-item' +import type { AddItemHook } from '../types/cart' import useCart from './use-cart' + import { checkoutLineItemAddMutation, getCheckoutId, checkoutToCart, } from '../utils' -import { Cart, CartItemBody } from '../types' import { Mutation, MutationCheckoutLineItemsAddArgs } from '../schema' export default useAddItem as UseAddItem -export const handler: MutationHook = { +export const handler: MutationHook = { fetchOptions: { query: checkoutLineItemAddMutation, }, diff --git a/framework/shopify/cart/use-cart.tsx b/framework/shopify/cart/use-cart.tsx index 5f77360bb..d920d058a 100644 --- a/framework/shopify/cart/use-cart.tsx +++ b/framework/shopify/cart/use-cart.tsx @@ -1,22 +1,20 @@ import { useMemo } from 'react' -import useCommerceCart, { - FetchCartInput, - UseCart, -} from '@commerce/cart/use-cart' +import useCommerceCart, { 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' +import { GetCartHook } from '../types/cart' + +import { + GetCheckoutQuery, + GetCheckoutQueryVariables, + CheckoutDetailsFragment, +} from '../schema' export default useCommerceCart as UseCart -export const handler: SWRHook< - Cart | null, - {}, - FetchCartInput, - { isEmpty?: boolean } -> = { +export const handler: SWRHook = { fetchOptions: { query: getCheckoutQuery, }, diff --git a/framework/shopify/cart/use-remove-item.tsx b/framework/shopify/cart/use-remove-item.tsx index 8db38eac2..bf9fb2d95 100644 --- a/framework/shopify/cart/use-remove-item.tsx +++ b/framework/shopify/cart/use-remove-item.tsx @@ -3,31 +3,29 @@ import type { MutationHookContext, HookFetcherContext, } from '@commerce/utils/types' -import { RemoveCartItemBody } from '@commerce/types' import { ValidationError } from '@commerce/utils/errors' -import useRemoveItem, { - RemoveItemInput as RemoveItemInputBase, - UseRemoveItem, -} from '@commerce/cart/use-remove-item' +import useRemoveItem, { UseRemoveItem } from '@commerce/cart/use-remove-item' +import type { Cart, LineItem, RemoveItemHook } from '../types/cart' import useCart from './use-cart' + +export type RemoveItemFn = T extends LineItem + ? (input?: RemoveItemActionInput) => Promise + : (input: RemoveItemActionInput) => Promise + +export type RemoveItemActionInput = T extends LineItem + ? Partial + : RemoveItemHook['actionInput'] + +export default useRemoveItem as UseRemoveItem + import { checkoutLineItemRemoveMutation, getCheckoutId, checkoutToCart, } from '../utils' -import { Cart, LineItem } from '../types' + import { Mutation, MutationCheckoutLineItemsRemoveArgs } from '../schema' -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, @@ -36,16 +34,14 @@ export const handler = { input: { itemId }, options, fetch, - }: HookFetcherContext) { + }: HookFetcherContext) { const data = await fetch({ ...options, variables: { checkoutId: getCheckoutId(), lineItemIds: [itemId] }, }) return checkoutToCart(data.checkoutLineItemsRemove) }, - useHook: ({ - fetch, - }: MutationHookContext) => < + useHook: ({ fetch }: MutationHookContext) => < T extends LineItem | undefined = undefined >( ctx: { item?: T } = {} diff --git a/framework/shopify/cart/use-update-item.tsx b/framework/shopify/cart/use-update-item.tsx index 49dd6be14..3f1cf4315 100644 --- a/framework/shopify/cart/use-update-item.tsx +++ b/framework/shopify/cart/use-update-item.tsx @@ -5,21 +5,21 @@ import type { MutationHookContext, } from '@commerce/utils/types' import { ValidationError } from '@commerce/utils/errors' -import useUpdateItem, { - UpdateItemInput as UpdateItemInputBase, - UseUpdateItem, -} from '@commerce/cart/use-update-item' +import useUpdateItem, { 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 type { UpdateItemHook, LineItem } from '../types/cart' +import { + getCheckoutId, + checkoutLineItemUpdateMutation, + checkoutToCart, +} from '../utils' import { Mutation, MutationCheckoutLineItemsUpdateArgs } from '../schema' -export type UpdateItemInput = T extends LineItem - ? Partial> - : UpdateItemInputBase +export type UpdateItemActionInput = T extends LineItem + ? Partial + : UpdateItemHook['actionInput'] export default useUpdateItem as UseUpdateItem @@ -31,7 +31,7 @@ export const handler = { input: { itemId, item }, options, fetch, - }: HookFetcherContext) { + }: 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) { @@ -64,9 +64,7 @@ export const handler = { return checkoutToCart(checkoutLineItemsUpdate) }, - useHook: ({ - fetch, - }: MutationHookContext) => < + useHook: ({ fetch }: MutationHookContext) => < T extends LineItem | undefined = undefined >( ctx: { @@ -78,7 +76,7 @@ export const handler = { const { mutate } = useCart() as any return useCallback( - debounce(async (input: UpdateItemInput) => { + debounce(async (input: UpdateItemActionInput) => { const itemId = input.id ?? item?.id const productId = input.productId ?? item?.productId const variantId = input.productId ?? item?.variantId diff --git a/framework/shopify/codegen.json b/framework/shopify/codegen.json new file mode 100644 index 000000000..f0a757142 --- /dev/null +++ b/framework/shopify/codegen.json @@ -0,0 +1,32 @@ +{ + "schema": { + "https://${NEXT_PUBLIC_SHOPIFY_STORE_DOMAIN}/api/2021-01/graphql.json": { + "headers": { + "X-Shopify-Storefront-Access-Token": "${NEXT_PUBLIC_SHOPIFY_STOREFRONT_ACCESS_TOKEN}" + } + } + }, + "documents": [ + { + "./framework/shopify/**/*.{ts,tsx}": { + "noRequire": true + } + } + ], + "generates": { + "./framework/shopify/schema.d.ts": { + "plugins": ["typescript", "typescript-operations"], + "config": { + "scalars": { + "ID": "string" + } + } + }, + "./framework/shopify/schema.graphql": { + "plugins": ["schema-ast"] + } + }, + "hooks": { + "afterAllFileWrite": ["prettier --write"] + } +} diff --git a/framework/shopify/common/get-all-pages.ts b/framework/shopify/common/get-all-pages.ts deleted file mode 100644 index 54231ed03..000000000 --- a/framework/shopify/common/get-all-pages.ts +++ /dev/null @@ -1,42 +0,0 @@ -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/shopify/common/get-page.ts b/framework/shopify/common/get-page.ts deleted file mode 100644 index be934aa42..000000000 --- a/framework/shopify/common/get-page.ts +++ /dev/null @@ -1,37 +0,0 @@ -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/shopify/common/get-site-info.ts b/framework/shopify/common/get-site-info.ts deleted file mode 100644 index f9e67b5de..000000000 --- a/framework/shopify/common/get-site-info.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { Category } from '@commerce/types' -import { getConfig, ShopifyConfig } from '../api' -import getCategories from '../utils/get-categories' -import getVendors, { Brands } from '../utils/get-vendors' - -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/shopify/customer/get-customer-id.ts b/framework/shopify/customer/get-customer-id.ts deleted file mode 100644 index ca096645a..000000000 --- a/framework/shopify/customer/get-customer-id.ts +++ /dev/null @@ -1,24 +0,0 @@ -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/shopify/customer/use-customer.tsx b/framework/shopify/customer/use-customer.tsx index 7b600838e..be097fe80 100644 --- a/framework/shopify/customer/use-customer.tsx +++ b/framework/shopify/customer/use-customer.tsx @@ -1,18 +1,19 @@ import useCustomer, { UseCustomer } from '@commerce/customer/use-customer' -import { Customer } from '@commerce/types' +import type { CustomerHook } from '../types/customer' import { SWRHook } from '@commerce/utils/types' import { getCustomerQuery, getCustomerToken } from '../utils' +import { GetCustomerQuery, GetCustomerQueryVariables } from '../schema' export default useCustomer as UseCustomer -export const handler: SWRHook = { +export const handler: SWRHook = { fetchOptions: { query: getCustomerQuery, }, async fetcher({ options, fetch }) { const customerAccessToken = getCustomerToken() if (customerAccessToken) { - const data = await fetch({ + const data = await fetch({ ...options, variables: { customerAccessToken: getCustomerToken() }, }) diff --git a/framework/shopify/fetcher.ts b/framework/shopify/fetcher.ts index a69150503..9a8d2d8d5 100644 --- a/framework/shopify/fetcher.ts +++ b/framework/shopify/fetcher.ts @@ -8,13 +8,17 @@ const fetcher: Fetcher = async ({ variables, query, }) => { + const { locale, ...vars } = variables ?? {} return handleFetchResponse( await fetch(url, { method, - body: JSON.stringify({ query, variables }), + body: JSON.stringify({ query, variables: vars }), headers: { 'X-Shopify-Storefront-Access-Token': API_TOKEN!, 'Content-Type': 'application/json', + ...(locale && { + 'Accept-Language': locale, + }), }, }) ) diff --git a/framework/shopify/index.tsx b/framework/shopify/index.tsx index 5b25d6b21..13ff9d1f8 100644 --- a/framework/shopify/index.tsx +++ b/framework/shopify/index.tsx @@ -36,4 +36,4 @@ export function CommerceProvider({ children, ...config }: ShopifyProps) { ) } -export const useCommerce = () => useCoreCommerce() +export const useCommerce = () => useCoreCommerce() diff --git a/framework/shopify/product/get-all-collections.ts b/framework/shopify/product/get-all-collections.ts deleted file mode 100644 index 15c4bc51a..000000000 --- a/framework/shopify/product/get-all-collections.ts +++ /dev/null @@ -1,29 +0,0 @@ -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/shopify/product/get-all-product-paths.ts b/framework/shopify/product/get-all-product-paths.ts deleted file mode 100644 index e8ee04065..000000000 --- a/framework/shopify/product/get-all-product-paths.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { getConfig, ShopifyConfig } from '../api' -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: 100, sortKey: 'BEST_SELLING' } } = - options ?? {} - config = getConfig(config) - - const { data } = await config.fetch(getAllProductsPathsQuery, { - variables, - }) - - return { - products: data.products?.edges?.map( - ({ node: { handle } }: ProductEdge) => ({ - node: { - path: `/${handle}`, - }, - }) - ), - } -} - -export default getAllProductPaths diff --git a/framework/shopify/product/get-all-products.ts b/framework/shopify/product/get-all-products.ts deleted file mode 100644 index 3915abebf..000000000 --- a/framework/shopify/product/get-all-products.ts +++ /dev/null @@ -1,39 +0,0 @@ -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/shopify/product/get-product.ts b/framework/shopify/product/get-product.ts deleted file mode 100644 index 1d861e1a1..000000000 --- a/framework/shopify/product/get-product.ts +++ /dev/null @@ -1,31 +0,0 @@ -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 } = data - - return { - product: productByHandle ? normalizeProduct(productByHandle) : null, - } -} - -export default getProduct diff --git a/framework/shopify/product/use-search.tsx b/framework/shopify/product/use-search.tsx index bf812af3d..9588b65a2 100644 --- a/framework/shopify/product/use-search.tsx +++ b/framework/shopify/product/use-search.tsx @@ -1,7 +1,14 @@ import { SWRHook } from '@commerce/utils/types' import useSearch, { UseSearch } from '@commerce/product/use-search' -import { ProductEdge } from '../schema' +import { + CollectionEdge, + GetAllProductsQuery, + GetProductsFromCollectionQueryVariables, + Product as ShopifyProduct, + ProductEdge, +} from '../schema' + import { getAllProductsQuery, getCollectionProductsQuery, @@ -9,56 +16,59 @@ import { normalizeProduct, } from '../utils' -import { Product } from '@commerce/types' - -export default useSearch as UseSearch +import type { SearchProductsHook } from '../types/product' export type SearchProductsInput = { search?: string - categoryId?: string - brandId?: string + categoryId?: number + brandId?: number sort?: string + locale?: string } -export type SearchProductsData = { - products: Product[] - found: boolean -} +export default useSearch as UseSearch -export const handler: SWRHook< - SearchProductsData, - SearchProductsInput, - SearchProductsInput -> = { +export const handler: SWRHook = { fetchOptions: { query: getAllProductsQuery, }, async fetcher({ input, options, fetch }) { const { categoryId, brandId } = input + const method = options?.method + const variables = getSearchVariables(input) + let products - const data = await fetch({ - query: categoryId ? getCollectionProductsQuery : options.query, - method: options?.method, - variables: getSearchVariables(input), - }) - - let edges - + // change the query to getCollectionProductsQuery when categoryId is set if (categoryId) { - edges = data.node?.products?.edges ?? [] - if (brandId) { - edges = edges.filter( - ({ node: { vendor } }: ProductEdge) => - vendor.replace(/\s+/g, '-').toLowerCase() === brandId - ) - } + const data = await fetch< + CollectionEdge, + GetProductsFromCollectionQueryVariables + >({ + query: getCollectionProductsQuery, + method, + variables, + }) + // filter on client when brandId & categoryId are set since is not available on collection product query + products = brandId + ? data.node.products.edges.filter( + ({ node: { vendor } }: ProductEdge) => + vendor.replace(/\s+/g, '-').toLowerCase() === brandId + ) + : data.node.products.edges } else { - edges = data.products?.edges ?? [] + const data = await fetch({ + query: options.query, + method, + variables, + }) + products = data.products.edges } return { - products: edges.map(({ node }: ProductEdge) => normalizeProduct(node)), - found: !!edges.length, + products: products?.map(({ node }) => + normalizeProduct(node as ShopifyProduct) + ), + found: !!products?.length, } }, useHook: ({ useData }) => (input = {}) => { @@ -68,6 +78,7 @@ export const handler: SWRHook< ['categoryId', input.categoryId], ['brandId', input.brandId], ['sort', input.sort], + ['locale', input.locale], ], swrOptions: { revalidateOnFocus: false, diff --git a/framework/shopify/schema.d.ts b/framework/shopify/schema.d.ts index b1b23a3e5..328f0ff1b 100644 --- a/framework/shopify/schema.d.ts +++ b/framework/shopify/schema.d.ts @@ -37,7 +37,7 @@ export type ApiVersion = { 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. */ + /** Whether the version is actively supported by Shopify. Supported API versions are guaranteed to be stable. Unsupported API versions include unstable, release candidate, and end-of-life versions that are marked as unsupported. For more information, refer to [Versioning](https://shopify.dev/concepts/about-apis/versioning). */ supported: Scalars['Boolean'] } @@ -306,17 +306,17 @@ export enum BlogSortKeys { /** Card brand, such as Visa or Mastercard, which can be used for payments. */ export enum CardBrand { - /** Visa */ + /** Visa. */ Visa = 'VISA', - /** Mastercard */ + /** Mastercard. */ Mastercard = 'MASTERCARD', - /** Discover */ + /** Discover. */ Discover = 'DISCOVER', - /** American Express */ + /** American Express. */ AmericanExpress = 'AMERICAN_EXPRESS', - /** Diners Club */ + /** Diners Club. */ DinersClub = 'DINERS_CLUB', - /** JCB */ + /** JCB. */ Jcb = 'JCB', } @@ -1195,6 +1195,8 @@ export enum CountryCode { Am = 'AM', /** Aruba. */ Aw = 'AW', + /** Ascension Island. */ + Ac = 'AC', /** Australia. */ Au = 'AU', /** Austria. */ @@ -1613,6 +1615,8 @@ export enum CountryCode { To = 'TO', /** Trinidad & Tobago. */ Tt = 'TT', + /** Tristan da Cunha. */ + Ta = 'TA', /** Tunisia. */ Tn = 'TN', /** Turkey. */ @@ -1687,7 +1691,7 @@ export type CreditCard = { 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. */ + /** 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. For more information, refer to [Idempotent requests](https://shopify.dev/concepts/about-apis/idempotent-requests). */ idempotencyKey: Scalars['String'] /** The billing address for the payment. */ billingAddress: MailingAddressInput @@ -1704,7 +1708,7 @@ export type CreditCardPaymentInput = { 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. */ + /** 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. For more information, refer to [Idempotent requests](https://shopify.dev/concepts/about-apis/idempotent-requests). */ idempotencyKey: Scalars['String'] /** The billing address for the payment. */ billingAddress: MailingAddressInput @@ -1766,10 +1770,6 @@ export enum CurrencyCode { 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). */ @@ -1816,26 +1816,18 @@ export enum CurrencyCode { 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). */ @@ -1846,8 +1838,6 @@ export enum CurrencyCode { Gyd = 'GYD', /** Georgian Lari (GEL). */ Gel = 'GEL', - /** Guinean Franc (GNF). */ - Gnf = 'GNF', /** Haitian Gourde (HTG). */ Htg = 'HTG', /** Honduran Lempira (HNL). */ @@ -1864,8 +1854,6 @@ export enum CurrencyCode { Idr = 'IDR', /** Israeli New Shekel (NIS). */ Ils = 'ILS', - /** Iranian Rial (IRR). */ - Irr = 'IRR', /** Iraqi Dinar (IQD). */ Iqd = 'IQD', /** Jamaican Dollars (JMD). */ @@ -1880,8 +1868,6 @@ export enum CurrencyCode { Kzt = 'KZT', /** Kenyan Shilling (KES). */ Kes = 'KES', - /** Kiribati Dollar (KID). */ - Kid = 'KID', /** Kuwaiti Dinar (KWD). */ Kwd = 'KWD', /** Kyrgyzstani Som (KGS). */ @@ -1896,8 +1882,6 @@ export enum CurrencyCode { Lsl = 'LSL', /** Liberian Dollar (LRD). */ Lrd = 'LRD', - /** Libyan Dinar (LYD). */ - Lyd = 'LYD', /** Lithuanian Litai (LTL). */ Ltl = 'LTL', /** Malagasy Ariary (MGA). */ @@ -1910,8 +1894,6 @@ export enum CurrencyCode { Mwk = 'MWK', /** Maldivian Rufiyaa (MVR). */ Mvr = 'MVR', - /** Mauritanian Ouguiya (MRU). */ - Mru = 'MRU', /** Mexican Pesos (MXN). */ Mxn = 'MXN', /** Malaysian Ringgits (MYR). */ @@ -1966,8 +1948,6 @@ export enum CurrencyCode { Rwf = 'RWF', /** Samoan Tala (WST). */ Wst = 'WST', - /** Saint Helena Pounds (SHP). */ - Shp = 'SHP', /** Saudi Riyal (SAR). */ Sar = 'SAR', /** Sao Tome And Principe Dobra (STD). */ @@ -1976,14 +1956,10 @@ export enum CurrencyCode { 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). */ @@ -2008,12 +1984,8 @@ export enum CurrencyCode { 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). */ @@ -2034,10 +2006,6 @@ export enum CurrencyCode { 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). */ @@ -2046,6 +2014,42 @@ export enum CurrencyCode { Yer = 'YER', /** Zambian Kwacha (ZMW). */ Zmw = 'ZMW', + /** Belarusian Ruble (BYN). */ + Byn = 'BYN', + /** Belarusian Ruble (BYR). */ + Byr = 'BYR', + /** Djiboutian Franc (DJF). */ + Djf = 'DJF', + /** Eritrean Nakfa (ERN). */ + Ern = 'ERN', + /** Falkland Islands Pounds (FKP). */ + Fkp = 'FKP', + /** Gibraltar Pounds (GIP). */ + Gip = 'GIP', + /** Guinean Franc (GNF). */ + Gnf = 'GNF', + /** Iranian Rial (IRR). */ + Irr = 'IRR', + /** Kiribati Dollar (KID). */ + Kid = 'KID', + /** Libyan Dinar (LYD). */ + Lyd = 'LYD', + /** Mauritanian Ouguiya (MRU). */ + Mru = 'MRU', + /** Sierra Leonean Leone (SLL). */ + Sll = 'SLL', + /** Saint Helena Pounds (SHP). */ + Shp = 'SHP', + /** Somali Shilling (SOS). */ + Sos = 'SOS', + /** Tajikistani Somoni (TJS). */ + Tjs = 'TJS', + /** Tongan Pa'anga (TOP). */ + Top = 'TOP', + /** Venezuelan Bolivares (VEF). */ + Vef = 'VEF', + /** Venezuelan Bolivares (VES). */ + Ves = 'VES', } /** 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. */ @@ -3817,7 +3821,11 @@ export type Payment = Node & { errorMessage?: Maybe /** Globally unique identifier. */ id: Scalars['ID'] - /** A client-side generated token to identify a payment and perform idempotent operations. */ + /** + * A client-side generated token to identify a payment and perform idempotent operations. + * For more information, refer to + * [Idempotent requests](https://shopify.dev/concepts/about-apis/idempotent-requests). + */ idempotencyKey?: Maybe /** The URL where the customer needs to be redirected so they can complete the 3D Secure payment flow. */ nextActionUrl?: Maybe @@ -4386,7 +4394,9 @@ export type QueryRoot = { collections: CollectionConnection /** Find a customer by its access token. */ customer?: Maybe + /** Returns a specific node by ID. */ node?: Maybe + /** Returns the list of nodes with the given IDs. */ nodes: Array> /** Find a page by its handle. */ pageByHandle?: Maybe @@ -4768,7 +4778,7 @@ export type StringEdge = { 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. */ + /** 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. For more information, refer to [Idempotent requests](https://shopify.dev/concepts/about-apis/idempotent-requests). */ idempotencyKey: Scalars['String'] /** The billing address for the payment. */ billingAddress: MailingAddressInput @@ -4789,7 +4799,7 @@ export type TokenizedPaymentInput = { 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. */ + /** 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. For more information, refer to [Idempotent requests](https://shopify.dev/concepts/about-apis/idempotent-requests). */ idempotencyKey: Scalars['String'] /** The billing address for the payment. */ billingAddress: MailingAddressInput @@ -4810,7 +4820,7 @@ export type TokenizedPaymentInputV2 = { 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. */ + /** 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. For more information, refer to [Idempotent requests](https://shopify.dev/concepts/about-apis/idempotent-requests). */ idempotencyKey: Scalars['String'] /** The billing address for the payment. */ billingAddress: MailingAddressInput @@ -4847,18 +4857,32 @@ export type Transaction = { test: Scalars['Boolean'] } +/** The different kinds of order transactions. */ export enum TransactionKind { + /** An authorization and capture performed together in a single step. */ Sale = 'SALE', + /** A transfer of the money that was reserved during the authorization stage. */ Capture = 'CAPTURE', + /** + * An amount reserved against the cardholder's funding source. + * Money does not change hands until the authorization is captured. + */ Authorization = 'AUTHORIZATION', + /** An authorization for a payment taken with an EMV credit card reader. */ EmvAuthorization = 'EMV_AUTHORIZATION', + /** Money returned to the customer when they have paid too much. */ Change = 'CHANGE', } +/** Transaction statuses describe the status of a transaction. */ export enum TransactionStatus { + /** The transaction is pending. */ Pending = 'PENDING', + /** The transaction succeeded. */ Success = 'SUCCESS', + /** The transaction failed. */ Failure = 'FAILURE', + /** There was an error while processing the transaction. */ Error = 'ERROR', } @@ -4967,19 +4991,596 @@ export enum WeightUnit { Ounces = 'OUNCES', } -export type Unnamed_1_QueryVariables = Exact<{ +export type AssociateCustomerWithCheckoutMutationVariables = Exact<{ + checkoutId: Scalars['ID'] + customerAccessToken: Scalars['String'] +}> + +export type AssociateCustomerWithCheckoutMutation = { + __typename?: 'Mutation' +} & { + checkoutCustomerAssociateV2?: Maybe< + { __typename?: 'CheckoutCustomerAssociateV2Payload' } & { + checkout?: Maybe<{ __typename?: 'Checkout' } & Pick> + checkoutUserErrors: Array< + { __typename?: 'CheckoutUserError' } & Pick< + CheckoutUserError, + 'code' | 'field' | 'message' + > + > + customer?: Maybe<{ __typename?: 'Customer' } & Pick> + } + > +} + +export type CheckoutCreateMutationVariables = Exact<{ + input?: Maybe +}> + +export type CheckoutCreateMutation = { __typename?: 'Mutation' } & { + checkoutCreate?: Maybe< + { __typename?: 'CheckoutCreatePayload' } & { + checkoutUserErrors: Array< + { __typename?: 'CheckoutUserError' } & Pick< + CheckoutUserError, + 'code' | 'field' | 'message' + > + > + checkout?: Maybe<{ __typename?: 'Checkout' } & CheckoutDetailsFragment> + } + > +} + +export type CheckoutLineItemAddMutationVariables = Exact<{ + checkoutId: Scalars['ID'] + lineItems: Array | CheckoutLineItemInput +}> + +export type CheckoutLineItemAddMutation = { __typename?: 'Mutation' } & { + checkoutLineItemsAdd?: Maybe< + { __typename?: 'CheckoutLineItemsAddPayload' } & { + checkoutUserErrors: Array< + { __typename?: 'CheckoutUserError' } & Pick< + CheckoutUserError, + 'code' | 'field' | 'message' + > + > + checkout?: Maybe<{ __typename?: 'Checkout' } & CheckoutDetailsFragment> + } + > +} + +export type CheckoutLineItemRemoveMutationVariables = Exact<{ + checkoutId: Scalars['ID'] + lineItemIds: Array | Scalars['ID'] +}> + +export type CheckoutLineItemRemoveMutation = { __typename?: 'Mutation' } & { + checkoutLineItemsRemove?: Maybe< + { __typename?: 'CheckoutLineItemsRemovePayload' } & { + checkoutUserErrors: Array< + { __typename?: 'CheckoutUserError' } & Pick< + CheckoutUserError, + 'code' | 'field' | 'message' + > + > + checkout?: Maybe<{ __typename?: 'Checkout' } & CheckoutDetailsFragment> + } + > +} + +export type CheckoutLineItemUpdateMutationVariables = Exact<{ + checkoutId: Scalars['ID'] + lineItems: Array | CheckoutLineItemUpdateInput +}> + +export type CheckoutLineItemUpdateMutation = { __typename?: 'Mutation' } & { + checkoutLineItemsUpdate?: Maybe< + { __typename?: 'CheckoutLineItemsUpdatePayload' } & { + checkoutUserErrors: Array< + { __typename?: 'CheckoutUserError' } & Pick< + CheckoutUserError, + 'code' | 'field' | 'message' + > + > + checkout?: Maybe<{ __typename?: 'Checkout' } & CheckoutDetailsFragment> + } + > +} + +export type CustomerAccessTokenCreateMutationVariables = Exact<{ + input: CustomerAccessTokenCreateInput +}> + +export type CustomerAccessTokenCreateMutation = { __typename?: 'Mutation' } & { + customerAccessTokenCreate?: Maybe< + { __typename?: 'CustomerAccessTokenCreatePayload' } & { + customerAccessToken?: Maybe< + { __typename?: 'CustomerAccessToken' } & Pick< + CustomerAccessToken, + 'accessToken' | 'expiresAt' + > + > + customerUserErrors: Array< + { __typename?: 'CustomerUserError' } & Pick< + CustomerUserError, + 'code' | 'field' | 'message' + > + > + } + > +} + +export type CustomerAccessTokenDeleteMutationVariables = Exact<{ + customerAccessToken: Scalars['String'] +}> + +export type CustomerAccessTokenDeleteMutation = { __typename?: 'Mutation' } & { + customerAccessTokenDelete?: Maybe< + { __typename?: 'CustomerAccessTokenDeletePayload' } & Pick< + CustomerAccessTokenDeletePayload, + 'deletedAccessToken' | 'deletedCustomerAccessTokenId' + > & { + userErrors: Array< + { __typename?: 'UserError' } & Pick + > + } + > +} + +export type CustomerActivateByUrlMutationVariables = Exact<{ + activationUrl: Scalars['URL'] + password: Scalars['String'] +}> + +export type CustomerActivateByUrlMutation = { __typename?: 'Mutation' } & { + customerActivateByUrl?: Maybe< + { __typename?: 'CustomerActivateByUrlPayload' } & { + customer?: Maybe<{ __typename?: 'Customer' } & Pick> + customerAccessToken?: Maybe< + { __typename?: 'CustomerAccessToken' } & Pick< + CustomerAccessToken, + 'accessToken' | 'expiresAt' + > + > + customerUserErrors: Array< + { __typename?: 'CustomerUserError' } & Pick< + CustomerUserError, + 'code' | 'field' | 'message' + > + > + } + > +} + +export type CustomerActivateMutationVariables = Exact<{ + id: Scalars['ID'] + input: CustomerActivateInput +}> + +export type CustomerActivateMutation = { __typename?: 'Mutation' } & { + customerActivate?: Maybe< + { __typename?: 'CustomerActivatePayload' } & { + customer?: Maybe<{ __typename?: 'Customer' } & Pick> + customerAccessToken?: Maybe< + { __typename?: 'CustomerAccessToken' } & Pick< + CustomerAccessToken, + 'accessToken' | 'expiresAt' + > + > + customerUserErrors: Array< + { __typename?: 'CustomerUserError' } & Pick< + CustomerUserError, + 'code' | 'field' | 'message' + > + > + } + > +} + +export type CustomerCreateMutationVariables = Exact<{ + input: CustomerCreateInput +}> + +export type CustomerCreateMutation = { __typename?: 'Mutation' } & { + customerCreate?: Maybe< + { __typename?: 'CustomerCreatePayload' } & { + customerUserErrors: Array< + { __typename?: 'CustomerUserError' } & Pick< + CustomerUserError, + 'code' | 'field' | 'message' + > + > + customer?: Maybe<{ __typename?: 'Customer' } & Pick> + } + > +} + +export type GetSiteCollectionsQueryVariables = Exact<{ first: Scalars['Int'] }> -export type Unnamed_1_Query = { __typename?: 'QueryRoot' } & { - pages: { __typename?: 'PageConnection' } & { +export type GetSiteCollectionsQuery = { __typename?: 'QueryRoot' } & { + collections: { __typename?: 'CollectionConnection' } & { edges: Array< - { __typename?: 'PageEdge' } & { - node: { __typename?: 'Page' } & Pick< - Page, - 'id' | 'title' | 'handle' | 'body' | 'bodySummary' | 'url' + { __typename?: 'CollectionEdge' } & { + node: { __typename?: 'Collection' } & Pick< + Collection, + 'id' | 'title' | 'handle' > } > } } + +export type GetAllPagesQueryVariables = Exact<{ + first?: Maybe +}> + +export type GetAllPagesQuery = { __typename?: 'QueryRoot' } & { + pages: { __typename?: 'PageConnection' } & { + edges: Array< + { __typename?: 'PageEdge' } & { + node: { __typename?: 'Page' } & Pick + } + > + } +} + +export type GetAllProductVendorsQueryVariables = Exact<{ + first?: Maybe + cursor?: Maybe +}> + +export type GetAllProductVendorsQuery = { __typename?: 'QueryRoot' } & { + products: { __typename?: 'ProductConnection' } & { + pageInfo: { __typename?: 'PageInfo' } & Pick< + PageInfo, + 'hasNextPage' | 'hasPreviousPage' + > + edges: Array< + { __typename?: 'ProductEdge' } & Pick & { + node: { __typename?: 'Product' } & Pick + } + > + } +} + +export type GetAllProductPathsQueryVariables = Exact<{ + first?: Maybe + cursor?: Maybe +}> + +export type GetAllProductPathsQuery = { __typename?: 'QueryRoot' } & { + products: { __typename?: 'ProductConnection' } & { + pageInfo: { __typename?: 'PageInfo' } & Pick< + PageInfo, + 'hasNextPage' | 'hasPreviousPage' + > + edges: Array< + { __typename?: 'ProductEdge' } & Pick & { + node: { __typename?: 'Product' } & Pick + } + > + } +} + +export type ProductConnectionFragment = { __typename?: 'ProductConnection' } & { + pageInfo: { __typename?: 'PageInfo' } & Pick< + PageInfo, + 'hasNextPage' | 'hasPreviousPage' + > + edges: Array< + { __typename?: 'ProductEdge' } & { + node: { __typename?: 'Product' } & Pick< + Product, + 'id' | 'title' | 'vendor' | 'handle' + > & { + priceRange: { __typename?: 'ProductPriceRange' } & { + minVariantPrice: { __typename?: 'MoneyV2' } & Pick< + MoneyV2, + 'amount' | 'currencyCode' + > + } + images: { __typename?: 'ImageConnection' } & { + pageInfo: { __typename?: 'PageInfo' } & Pick< + PageInfo, + 'hasNextPage' | 'hasPreviousPage' + > + edges: Array< + { __typename?: 'ImageEdge' } & { + node: { __typename?: 'Image' } & Pick< + Image, + 'originalSrc' | 'altText' | 'width' | 'height' + > + } + > + } + } + } + > +} + +export type GetAllProductsQueryVariables = Exact<{ + first?: Maybe + query?: Maybe + sortKey?: Maybe + reverse?: Maybe +}> + +export type GetAllProductsQuery = { __typename?: 'QueryRoot' } & { + products: { __typename?: 'ProductConnection' } & ProductConnectionFragment +} + +export type CheckoutDetailsFragment = { __typename?: 'Checkout' } & Pick< + Checkout, + 'id' | 'webUrl' | 'completedAt' | 'createdAt' | 'taxesIncluded' +> & { + subtotalPriceV2: { __typename?: 'MoneyV2' } & Pick< + MoneyV2, + 'amount' | 'currencyCode' + > + totalTaxV2: { __typename?: 'MoneyV2' } & Pick< + MoneyV2, + 'amount' | 'currencyCode' + > + totalPriceV2: { __typename?: 'MoneyV2' } & Pick< + MoneyV2, + 'amount' | 'currencyCode' + > + lineItems: { __typename?: 'CheckoutLineItemConnection' } & { + pageInfo: { __typename?: 'PageInfo' } & Pick< + PageInfo, + 'hasNextPage' | 'hasPreviousPage' + > + edges: Array< + { __typename?: 'CheckoutLineItemEdge' } & { + node: { __typename?: 'CheckoutLineItem' } & Pick< + CheckoutLineItem, + 'id' | 'title' | 'quantity' + > & { + variant?: Maybe< + { __typename?: 'ProductVariant' } & Pick< + ProductVariant, + 'id' | 'sku' | 'title' + > & { + image?: Maybe< + { __typename?: 'Image' } & Pick< + Image, + 'originalSrc' | 'altText' | 'width' | 'height' + > + > + priceV2: { __typename?: 'MoneyV2' } & Pick< + MoneyV2, + 'amount' | 'currencyCode' + > + compareAtPriceV2?: Maybe< + { __typename?: 'MoneyV2' } & Pick< + MoneyV2, + 'amount' | 'currencyCode' + > + > + product: { __typename?: 'Product' } & Pick< + Product, + 'handle' + > + } + > + } + } + > + } + } + +export type GetCheckoutQueryVariables = Exact<{ + checkoutId: Scalars['ID'] +}> + +export type GetCheckoutQuery = { __typename?: 'QueryRoot' } & { + node?: Maybe< + | { __typename?: 'AppliedGiftCard' } + | { __typename?: 'Article' } + | { __typename?: 'Blog' } + | ({ __typename?: 'Checkout' } & CheckoutDetailsFragment) + | { __typename?: 'CheckoutLineItem' } + | { __typename?: 'Collection' } + | { __typename?: 'Comment' } + | { __typename?: 'ExternalVideo' } + | { __typename?: 'MailingAddress' } + | { __typename?: 'MediaImage' } + | { __typename?: 'Metafield' } + | { __typename?: 'Model3d' } + | { __typename?: 'Order' } + | { __typename?: 'Page' } + | { __typename?: 'Payment' } + | { __typename?: 'Product' } + | { __typename?: 'ProductOption' } + | { __typename?: 'ProductVariant' } + | { __typename?: 'ShopPolicy' } + | { __typename?: 'Video' } + > +} + +export type GetProductsFromCollectionQueryVariables = Exact<{ + categoryId: Scalars['ID'] + first?: Maybe + sortKey?: Maybe + reverse?: Maybe +}> + +export type GetProductsFromCollectionQuery = { __typename?: 'QueryRoot' } & { + node?: Maybe< + | ({ __typename?: 'AppliedGiftCard' } & Pick) + | ({ __typename?: 'Article' } & Pick) + | ({ __typename?: 'Blog' } & Pick) + | ({ __typename?: 'Checkout' } & Pick) + | ({ __typename?: 'CheckoutLineItem' } & Pick) + | ({ __typename?: 'Collection' } & Pick & { + products: { + __typename?: 'ProductConnection' + } & ProductConnectionFragment + }) + | ({ __typename?: 'Comment' } & Pick) + | ({ __typename?: 'ExternalVideo' } & Pick) + | ({ __typename?: 'MailingAddress' } & Pick) + | ({ __typename?: 'MediaImage' } & Pick) + | ({ __typename?: 'Metafield' } & Pick) + | ({ __typename?: 'Model3d' } & Pick) + | ({ __typename?: 'Order' } & Pick) + | ({ __typename?: 'Page' } & Pick) + | ({ __typename?: 'Payment' } & Pick) + | ({ __typename?: 'Product' } & Pick) + | ({ __typename?: 'ProductOption' } & Pick) + | ({ __typename?: 'ProductVariant' } & Pick) + | ({ __typename?: 'ShopPolicy' } & Pick) + | ({ __typename?: 'Video' } & Pick) + > +} + +export type GetCustomerIdQueryVariables = Exact<{ + customerAccessToken: Scalars['String'] +}> + +export type GetCustomerIdQuery = { __typename?: 'QueryRoot' } & { + customer?: Maybe<{ __typename?: 'Customer' } & Pick> +} + +export type GetCustomerQueryVariables = Exact<{ + customerAccessToken: Scalars['String'] +}> + +export type GetCustomerQuery = { __typename?: 'QueryRoot' } & { + customer?: Maybe< + { __typename?: 'Customer' } & Pick< + Customer, + | 'id' + | 'firstName' + | 'lastName' + | 'displayName' + | 'email' + | 'phone' + | 'tags' + | 'acceptsMarketing' + | 'createdAt' + > + > +} + +export type GetPageQueryVariables = Exact<{ + id: Scalars['ID'] +}> + +export type GetPageQuery = { __typename?: 'QueryRoot' } & { + node?: Maybe< + | ({ __typename?: 'AppliedGiftCard' } & Pick) + | ({ __typename?: 'Article' } & Pick) + | ({ __typename?: 'Blog' } & Pick) + | ({ __typename?: 'Checkout' } & Pick) + | ({ __typename?: 'CheckoutLineItem' } & Pick) + | ({ __typename?: 'Collection' } & Pick) + | ({ __typename?: 'Comment' } & Pick) + | ({ __typename?: 'ExternalVideo' } & Pick) + | ({ __typename?: 'MailingAddress' } & Pick) + | ({ __typename?: 'MediaImage' } & Pick) + | ({ __typename?: 'Metafield' } & Pick) + | ({ __typename?: 'Model3d' } & Pick) + | ({ __typename?: 'Order' } & Pick) + | ({ __typename?: 'Page' } & Pick< + Page, + 'title' | 'handle' | 'body' | 'bodySummary' | 'id' + >) + | ({ __typename?: 'Payment' } & Pick) + | ({ __typename?: 'Product' } & Pick) + | ({ __typename?: 'ProductOption' } & Pick) + | ({ __typename?: 'ProductVariant' } & Pick) + | ({ __typename?: 'ShopPolicy' } & Pick) + | ({ __typename?: 'Video' } & Pick) + > +} + +export type GetProductBySlugQueryVariables = Exact<{ + slug: Scalars['String'] +}> + +export type GetProductBySlugQuery = { __typename?: 'QueryRoot' } & { + productByHandle?: Maybe< + { __typename?: 'Product' } & Pick< + Product, + | 'id' + | 'handle' + | 'title' + | 'productType' + | 'vendor' + | 'description' + | 'descriptionHtml' + > & { + options: Array< + { __typename?: 'ProductOption' } & Pick< + ProductOption, + 'id' | 'name' | 'values' + > + > + priceRange: { __typename?: 'ProductPriceRange' } & { + maxVariantPrice: { __typename?: 'MoneyV2' } & Pick< + MoneyV2, + 'amount' | 'currencyCode' + > + minVariantPrice: { __typename?: 'MoneyV2' } & Pick< + MoneyV2, + 'amount' | 'currencyCode' + > + } + variants: { __typename?: 'ProductVariantConnection' } & { + pageInfo: { __typename?: 'PageInfo' } & Pick< + PageInfo, + 'hasNextPage' | 'hasPreviousPage' + > + edges: Array< + { __typename?: 'ProductVariantEdge' } & { + node: { __typename?: 'ProductVariant' } & Pick< + ProductVariant, + 'id' | 'title' | 'sku' + > & { + selectedOptions: Array< + { __typename?: 'SelectedOption' } & Pick< + SelectedOption, + 'name' | 'value' + > + > + priceV2: { __typename?: 'MoneyV2' } & Pick< + MoneyV2, + 'amount' | 'currencyCode' + > + compareAtPriceV2?: Maybe< + { __typename?: 'MoneyV2' } & Pick< + MoneyV2, + 'amount' | 'currencyCode' + > + > + } + } + > + } + images: { __typename?: 'ImageConnection' } & { + pageInfo: { __typename?: 'PageInfo' } & Pick< + PageInfo, + 'hasNextPage' | 'hasPreviousPage' + > + edges: Array< + { __typename?: 'ImageEdge' } & { + node: { __typename?: 'Image' } & Pick< + Image, + 'originalSrc' | 'altText' | 'width' | 'height' + > + } + > + } + } + > +} + +export type GetSiteInfoQueryVariables = Exact<{ [key: string]: never }> + +export type GetSiteInfoQuery = { __typename?: 'QueryRoot' } & { + shop: { __typename?: 'Shop' } & Pick +} diff --git a/framework/shopify/schema.graphql b/framework/shopify/schema.graphql index 822e6007e..9c657fe43 100644 --- a/framework/shopify/schema.graphql +++ b/framework/shopify/schema.graphql @@ -13,6 +13,16 @@ directive @accessRestricted( reason: String = null ) on FIELD_DEFINITION | OBJECT +""" +Contextualize data. +""" +directive @inContext( + """ + The country code for context. + """ + country: CountryCode! +) on QUERY | MUTATION + """ A version of the API. """ @@ -28,7 +38,7 @@ type ApiVersion { handle: String! """ - Whether the version is supported by Shopify. + Whether the version is actively supported by Shopify. Supported API versions are guaranteed to be stable. Unsupported API versions include unstable, release candidate, and end-of-life versions that are marked as unsupported. For more information, refer to [Versioning](https://shopify.dev/concepts/about-apis/versioning). """ supported: Boolean! } @@ -547,32 +557,32 @@ Card brand, such as Visa or Mastercard, which can be used for payments. """ enum CardBrand { """ - Visa + Visa. """ VISA """ - Mastercard + Mastercard. """ MASTERCARD """ - Discover + Discover. """ DISCOVER """ - American Express + American Express. """ AMERICAN_EXPRESS """ - Diners Club + Diners Club. """ DINERS_CLUB """ - JCB + JCB. """ JCB } @@ -2142,6 +2152,11 @@ enum CountryCode { """ AW + """ + Ascension Island. + """ + AC + """ Australia. """ @@ -3187,6 +3202,11 @@ enum CountryCode { """ TT + """ + Tristan da Cunha. + """ + TA + """ Tunisia. """ @@ -3354,7 +3374,7 @@ input CreditCardPaymentInput { 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. + 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. For more information, refer to [Idempotent requests](https://shopify.dev/concepts/about-apis/idempotent-requests). """ idempotencyKey: String! @@ -3385,7 +3405,7 @@ input CreditCardPaymentInputV2 { 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. + 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. For more information, refer to [Idempotent requests](https://shopify.dev/concepts/about-apis/idempotent-requests). """ idempotencyKey: String! @@ -3529,16 +3549,6 @@ enum CurrencyCode { """ BIF - """ - Belarusian Ruble (BYN). - """ - BYN - - """ - Belarusian Ruble (BYR). - """ - BYR - """ Belize Dollar (BZD). """ @@ -3654,11 +3664,6 @@ enum CurrencyCode { """ DKK - """ - Djiboutian Franc (DJF). - """ - DJF - """ Dominican Peso (DOP). """ @@ -3674,21 +3679,11 @@ enum CurrencyCode { """ EGP - """ - Eritrean Nakfa (ERN). - """ - ERN - """ Ethiopian Birr (ETB). """ ETB - """ - Falkland Islands Pounds (FKP). - """ - FKP - """ CFP Franc (XPF). """ @@ -3699,11 +3694,6 @@ enum CurrencyCode { """ FJD - """ - Gibraltar Pounds (GIP). - """ - GIP - """ Gambian Dalasi (GMD). """ @@ -3729,11 +3719,6 @@ enum CurrencyCode { """ GEL - """ - Guinean Franc (GNF). - """ - GNF - """ Haitian Gourde (HTG). """ @@ -3774,11 +3759,6 @@ enum CurrencyCode { """ ILS - """ - Iranian Rial (IRR). - """ - IRR - """ Iraqi Dinar (IQD). """ @@ -3814,11 +3794,6 @@ enum CurrencyCode { """ KES - """ - Kiribati Dollar (KID). - """ - KID - """ Kuwaiti Dinar (KWD). """ @@ -3854,11 +3829,6 @@ enum CurrencyCode { """ LRD - """ - Libyan Dinar (LYD). - """ - LYD - """ Lithuanian Litai (LTL). """ @@ -3889,11 +3859,6 @@ enum CurrencyCode { """ MVR - """ - Mauritanian Ouguiya (MRU). - """ - MRU - """ Mexican Pesos (MXN). """ @@ -4029,11 +3994,6 @@ enum CurrencyCode { """ WST - """ - Saint Helena Pounds (SHP). - """ - SHP - """ Saudi Riyal (SAR). """ @@ -4054,11 +4014,6 @@ enum CurrencyCode { """ SCR - """ - Sierra Leonean Leone (SLL). - """ - SLL - """ Singapore Dollars (SGD). """ @@ -4069,11 +4024,6 @@ enum CurrencyCode { """ SDG - """ - Somali Shilling (SOS). - """ - SOS - """ Syrian Pound (SYP). """ @@ -4134,21 +4084,11 @@ enum CurrencyCode { """ THB - """ - Tajikistani Somoni (TJS). - """ - TJS - """ Tanzanian Shilling (TZS). """ TZS - """ - Tongan Pa'anga (TOP). - """ - TOP - """ Trinidad and Tobago Dollars (TTD). """ @@ -4199,16 +4139,6 @@ enum CurrencyCode { """ VUV - """ - Venezuelan Bolivares (VEF). - """ - VEF - - """ - Venezuelan Bolivares (VES). - """ - VES - """ Vietnamese đồng (VND). """ @@ -4228,6 +4158,96 @@ enum CurrencyCode { Zambian Kwacha (ZMW). """ ZMW + + """ + Belarusian Ruble (BYN). + """ + BYN + + """ + Belarusian Ruble (BYR). + """ + BYR + + """ + Djiboutian Franc (DJF). + """ + DJF + + """ + Eritrean Nakfa (ERN). + """ + ERN + + """ + Falkland Islands Pounds (FKP). + """ + FKP + + """ + Gibraltar Pounds (GIP). + """ + GIP + + """ + Guinean Franc (GNF). + """ + GNF + + """ + Iranian Rial (IRR). + """ + IRR + + """ + Kiribati Dollar (KID). + """ + KID + + """ + Libyan Dinar (LYD). + """ + LYD + + """ + Mauritanian Ouguiya (MRU). + """ + MRU + + """ + Sierra Leonean Leone (SLL). + """ + SLL + + """ + Saint Helena Pounds (SHP). + """ + SHP + + """ + Somali Shilling (SOS). + """ + SOS + + """ + Tajikistani Somoni (TJS). + """ + TJS + + """ + Tongan Pa'anga (TOP). + """ + TOP + + """ + Venezuelan Bolivares (VEF). + """ + VEF + + """ + Venezuelan Bolivares (VES). + """ + VES } """ @@ -7355,6 +7375,8 @@ type Payment implements Node { """ A client-side generated token to identify a payment and perform idempotent operations. + For more information, refer to + [Idempotent requests](https://shopify.dev/concepts/about-apis/idempotent-requests). """ idempotencyKey: String @@ -8589,12 +8611,20 @@ type QueryRoot { """ customerAccessToken: String! ): Customer + + """ + Returns a specific node by ID. + """ node( """ The ID of the Node to return. """ id: ID! ): Node + + """ + Returns the list of nodes with the given IDs. + """ nodes( """ The IDs of the Nodes to return. @@ -9246,7 +9276,7 @@ input TokenizedPaymentInput { 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. + 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. For more information, refer to [Idempotent requests](https://shopify.dev/concepts/about-apis/idempotent-requests). """ idempotencyKey: String! @@ -9287,7 +9317,7 @@ input TokenizedPaymentInputV2 { 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. + 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. For more information, refer to [Idempotent requests](https://shopify.dev/concepts/about-apis/idempotent-requests). """ idempotencyKey: String! @@ -9328,7 +9358,7 @@ input TokenizedPaymentInputV3 { 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. + 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. For more information, refer to [Idempotent requests](https://shopify.dev/concepts/about-apis/idempotent-requests). """ idempotencyKey: String! @@ -9393,18 +9423,59 @@ type Transaction { test: Boolean! } +""" +The different kinds of order transactions. +""" enum TransactionKind { + """ + An authorization and capture performed together in a single step. + """ SALE + + """ + A transfer of the money that was reserved during the authorization stage. + """ CAPTURE + + """ + An amount reserved against the cardholder's funding source. + Money does not change hands until the authorization is captured. + """ AUTHORIZATION + + """ + An authorization for a payment taken with an EMV credit card reader. + """ EMV_AUTHORIZATION + + """ + Money returned to the customer when they have paid too much. + """ CHANGE } +""" +Transaction statuses describe the status of a transaction. +""" enum TransactionStatus { + """ + The transaction is pending. + """ PENDING + + """ + The transaction succeeded. + """ SUCCESS + + """ + The transaction failed. + """ FAILURE + + """ + There was an error while processing the transaction. + """ ERROR } diff --git a/framework/shopify/types.ts b/framework/shopify/types.ts deleted file mode 100644 index e7bcb2476..000000000 --- a/framework/shopify/types.ts +++ /dev/null @@ -1,43 +0,0 @@ -import * as Core from '@commerce/types' -import { CheckoutLineItem } from './schema' - -export type ShopifyCheckout = { - id: string - webUrl: string - lineItems: CheckoutLineItem[] -} - -export type Cart = Core.Cart & { - 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/shopify/types/cart.ts b/framework/shopify/types/cart.ts new file mode 100644 index 000000000..09410740a --- /dev/null +++ b/framework/shopify/types/cart.ts @@ -0,0 +1,32 @@ +import * as Core from '@commerce/types/cart' + +export * from '@commerce/types/cart' + +export type ShopifyCart = {} + +/** + * Extend core cart types + */ + +export type Cart = Core.Cart & { + lineItems: Core.LineItem[] + url?: string +} + +export type CartTypes = Core.CartTypes + +export type CartHooks = Core.CartHooks + +export type GetCartHook = CartHooks['getCart'] +export type AddItemHook = CartHooks['addItem'] +export type UpdateItemHook = CartHooks['updateItem'] +export type RemoveItemHook = CartHooks['removeItem'] + +export type CartSchema = Core.CartSchema + +export type CartHandlers = Core.CartHandlers + +export type GetCartHandler = CartHandlers['getCart'] +export type AddItemHandler = CartHandlers['addItem'] +export type UpdateItemHandler = CartHandlers['updateItem'] +export type RemoveItemHandler = CartHandlers['removeItem'] diff --git a/framework/shopify/types/checkout.ts b/framework/shopify/types/checkout.ts new file mode 100644 index 000000000..4e2412ef6 --- /dev/null +++ b/framework/shopify/types/checkout.ts @@ -0,0 +1 @@ +export * from '@commerce/types/checkout' diff --git a/framework/shopify/types/common.ts b/framework/shopify/types/common.ts new file mode 100644 index 000000000..b52c33a4d --- /dev/null +++ b/framework/shopify/types/common.ts @@ -0,0 +1 @@ +export * from '@commerce/types/common' diff --git a/framework/shopify/types/customer.ts b/framework/shopify/types/customer.ts new file mode 100644 index 000000000..427bc0b03 --- /dev/null +++ b/framework/shopify/types/customer.ts @@ -0,0 +1,5 @@ +import * as Core from '@commerce/types/customer' + +export * from '@commerce/types/customer' + +export type CustomerSchema = Core.CustomerSchema diff --git a/framework/shopify/types/index.ts b/framework/shopify/types/index.ts new file mode 100644 index 000000000..7ab0b7f64 --- /dev/null +++ b/framework/shopify/types/index.ts @@ -0,0 +1,25 @@ +import * as Cart from './cart' +import * as Checkout from './checkout' +import * as Common from './common' +import * as Customer from './customer' +import * as Login from './login' +import * as Logout from './logout' +import * as Page from './page' +import * as Product from './product' +import * as Signup from './signup' +import * as Site from './site' +import * as Wishlist from './wishlist' + +export type { + Cart, + Checkout, + Common, + Customer, + Login, + Logout, + Page, + Product, + Signup, + Site, + Wishlist, +} diff --git a/framework/shopify/types/login.ts b/framework/shopify/types/login.ts new file mode 100644 index 000000000..964ac89e2 --- /dev/null +++ b/framework/shopify/types/login.ts @@ -0,0 +1,8 @@ +import * as Core from '@commerce/types/login' +import type { CustomerAccessTokenCreateInput } from '../schema' + +export * from '@commerce/types/login' + +export type LoginOperation = Core.LoginOperation & { + variables: CustomerAccessTokenCreateInput +} diff --git a/framework/shopify/types/logout.ts b/framework/shopify/types/logout.ts new file mode 100644 index 000000000..9f0a466af --- /dev/null +++ b/framework/shopify/types/logout.ts @@ -0,0 +1 @@ +export * from '@commerce/types/logout' diff --git a/framework/shopify/types/page.ts b/framework/shopify/types/page.ts new file mode 100644 index 000000000..2bccfade2 --- /dev/null +++ b/framework/shopify/types/page.ts @@ -0,0 +1,11 @@ +import * as Core from '@commerce/types/page' +export * from '@commerce/types/page' + +export type Page = Core.Page + +export type PageTypes = { + page: Page +} + +export type GetAllPagesOperation = Core.GetAllPagesOperation +export type GetPageOperation = Core.GetPageOperation diff --git a/framework/shopify/types/product.ts b/framework/shopify/types/product.ts new file mode 100644 index 000000000..c776d58fa --- /dev/null +++ b/framework/shopify/types/product.ts @@ -0,0 +1 @@ +export * from '@commerce/types/product' diff --git a/framework/shopify/types/signup.ts b/framework/shopify/types/signup.ts new file mode 100644 index 000000000..58543c6f6 --- /dev/null +++ b/framework/shopify/types/signup.ts @@ -0,0 +1 @@ +export * from '@commerce/types/signup' diff --git a/framework/shopify/types/site.ts b/framework/shopify/types/site.ts new file mode 100644 index 000000000..bfef69cf9 --- /dev/null +++ b/framework/shopify/types/site.ts @@ -0,0 +1 @@ +export * from '@commerce/types/site' diff --git a/framework/shopify/types/wishlist.ts b/framework/shopify/types/wishlist.ts new file mode 100644 index 000000000..8907fbf82 --- /dev/null +++ b/framework/shopify/types/wishlist.ts @@ -0,0 +1 @@ +export * from '@commerce/types/wishlist' diff --git a/framework/shopify/utils/checkout-to-cart.ts b/framework/shopify/utils/checkout-to-cart.ts index 034ff11d7..e2531cc78 100644 --- a/framework/shopify/utils/checkout-to-cart.ts +++ b/framework/shopify/utils/checkout-to-cart.ts @@ -1,4 +1,4 @@ -import { Cart } from '../types' +import type { Cart } from '../types/cart' import { CommerceError } from '@commerce/utils/errors' import { @@ -27,12 +27,6 @@ export type CheckoutPayload = | CheckoutQuery const checkoutToCart = (checkoutPayload?: Maybe): Cart => { - if (!checkoutPayload) { - throw new CommerceError({ - message: 'Missing checkout payload from response', - }) - } - const checkout = checkoutPayload?.checkout throwUserErrors(checkoutPayload?.checkoutUserErrors) diff --git a/framework/shopify/utils/get-vendors.ts b/framework/shopify/utils/get-brands.ts similarity index 56% rename from framework/shopify/utils/get-vendors.ts rename to framework/shopify/utils/get-brands.ts index 24843f177..3065e4ae8 100644 --- a/framework/shopify/utils/get-vendors.ts +++ b/framework/shopify/utils/get-brands.ts @@ -1,5 +1,8 @@ +import { + GetAllProductVendorsQuery, + GetAllProductVendorsQueryVariables, +} from '../schema' import { ShopifyConfig } from '../api' -import fetchAllProducts from '../api/utils/fetch-all-products' import getAllProductVendors from './queries/get-all-product-vendors-query' export type Brand = { @@ -14,16 +17,17 @@ export type BrandEdge = { export type Brands = BrandEdge[] -const getVendors = async (config: ShopifyConfig): Promise => { - const vendors = await fetchAllProducts({ - config, - query: getAllProductVendors, +const getBrands = async (config: ShopifyConfig): Promise => { + const { data } = await config.fetch< + GetAllProductVendorsQuery, + GetAllProductVendorsQueryVariables + >(getAllProductVendors, { variables: { first: 250, }, }) - let vendorsStrings = vendors.map(({ node: { vendor } }) => vendor) + let vendorsStrings = data.products.edges.map(({ node: { vendor } }) => vendor) return [...new Set(vendorsStrings)].map((v) => { const id = v.replace(/\s+/g, '-').toLowerCase() @@ -37,4 +41,4 @@ const getVendors = async (config: ShopifyConfig): Promise => { }) } -export default getVendors +export default getBrands diff --git a/framework/shopify/utils/get-categories.ts b/framework/shopify/utils/get-categories.ts index 3884fe193..543ee2fa1 100644 --- a/framework/shopify/utils/get-categories.ts +++ b/framework/shopify/utils/get-categories.ts @@ -1,23 +1,32 @@ +import type { Category } from '../types/site' import { ShopifyConfig } from '../api' import { CollectionEdge } from '../schema' +import { normalizeCategory } from './normalize' import getSiteCollectionsQuery from './queries/get-all-collections-query' -import { Category } from '@commerce/types' -const getCategories = async (config: ShopifyConfig): Promise => { - const { data } = await config.fetch(getSiteCollectionsQuery, { - variables: { - first: 250, +const getCategories = async ({ + fetch, + locale, +}: ShopifyConfig): Promise => { + const { data } = await fetch( + getSiteCollectionsQuery, + { + variables: { + first: 250, + }, }, - }) + { + ...(locale && { + headers: { + 'Accept-Language': locale, + }, + }), + } + ) return ( - data.collections?.edges?.map( - ({ node: { id, title: name, handle } }: CollectionEdge) => ({ - id, - name, - slug: handle, - path: `/${handle}`, - }) + data.collections?.edges?.map(({ node }: CollectionEdge) => + normalizeCategory(node) ) ?? [] ) } diff --git a/framework/shopify/utils/get-search-variables.ts b/framework/shopify/utils/get-search-variables.ts index c1b40ae5d..f4863650d 100644 --- a/framework/shopify/utils/get-search-variables.ts +++ b/framework/shopify/utils/get-search-variables.ts @@ -1,26 +1,30 @@ import getSortVariables from './get-sort-variables' -import type { SearchProductsInput } from '../product/use-search' +import { SearchProductsBody } from '../types/product' export const getSearchVariables = ({ brandId, search, categoryId, sort, -}: SearchProductsInput) => { + locale, +}: SearchProductsBody) => { let query = '' if (search) { - query += `product_type:${search} OR title:${search} OR tag:${search}` + query += `product_type:${search} OR title:${search} OR tag:${search} ` } if (brandId) { - query += `${search ? ' AND ' : ''}vendor:${brandId}` + query += `${search ? 'AND ' : ''}vendor:${brandId}` } return { categoryId, query, ...getSortVariables(sort, !!categoryId), + ...(locale && { + locale, + }), } } diff --git a/framework/shopify/utils/index.ts b/framework/shopify/utils/index.ts index 61e5975d7..a8454ffca 100644 --- a/framework/shopify/utils/index.ts +++ b/framework/shopify/utils/index.ts @@ -1,7 +1,7 @@ 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 getBrands } from './get-brands' export { default as getCategories } from './get-categories' export { default as getCheckoutId } from './get-checkout-id' export { default as checkoutCreate } from './checkout-create' diff --git a/framework/shopify/utils/mutations/checkout-create.ts b/framework/shopify/utils/mutations/checkout-create.ts index ffbd555c7..7bff7e757 100644 --- a/framework/shopify/utils/mutations/checkout-create.ts +++ b/framework/shopify/utils/mutations/checkout-create.ts @@ -1,17 +1,19 @@ import { checkoutDetailsFragment } from '../queries/get-checkout-query' const checkoutCreateMutation = /* GraphQL */ ` - mutation { - checkoutCreate(input: {}) { + mutation checkoutCreate($input: CheckoutCreateInput = {}) { + checkoutCreate(input: $input) { checkoutUserErrors { code field message } checkout { - ${checkoutDetailsFragment} + ...checkoutDetails } } } + + ${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 index 2282c4e26..02f5b7107 100644 --- a/framework/shopify/utils/mutations/checkout-line-item-add.ts +++ b/framework/shopify/utils/mutations/checkout-line-item-add.ts @@ -1,7 +1,10 @@ import { checkoutDetailsFragment } from '../queries/get-checkout-query' const checkoutLineItemAddMutation = /* GraphQL */ ` - mutation($checkoutId: ID!, $lineItems: [CheckoutLineItemInput!]!) { + mutation checkoutLineItemAdd( + $checkoutId: ID! + $lineItems: [CheckoutLineItemInput!]! + ) { checkoutLineItemsAdd(checkoutId: $checkoutId, lineItems: $lineItems) { checkoutUserErrors { code @@ -9,9 +12,11 @@ const checkoutLineItemAddMutation = /* GraphQL */ ` message } checkout { - ${checkoutDetailsFragment} + ...checkoutDetails } } } + + ${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 index 8dea4ce08..30cb83028 100644 --- a/framework/shopify/utils/mutations/checkout-line-item-remove.ts +++ b/framework/shopify/utils/mutations/checkout-line-item-remove.ts @@ -1,7 +1,7 @@ import { checkoutDetailsFragment } from '../queries/get-checkout-query' const checkoutLineItemRemoveMutation = /* GraphQL */ ` - mutation($checkoutId: ID!, $lineItemIds: [ID!]!) { + mutation checkoutLineItemRemove($checkoutId: ID!, $lineItemIds: [ID!]!) { checkoutLineItemsRemove( checkoutId: $checkoutId lineItemIds: $lineItemIds @@ -12,9 +12,10 @@ const checkoutLineItemRemoveMutation = /* GraphQL */ ` message } checkout { - ${checkoutDetailsFragment} + ...checkoutDetails } } } + ${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 index 76254341e..fca617fb7 100644 --- a/framework/shopify/utils/mutations/checkout-line-item-update.ts +++ b/framework/shopify/utils/mutations/checkout-line-item-update.ts @@ -1,7 +1,10 @@ import { checkoutDetailsFragment } from '../queries/get-checkout-query' const checkoutLineItemUpdateMutation = /* GraphQL */ ` - mutation($checkoutId: ID!, $lineItems: [CheckoutLineItemUpdateInput!]!) { + mutation checkoutLineItemUpdate( + $checkoutId: ID! + $lineItems: [CheckoutLineItemUpdateInput!]! + ) { checkoutLineItemsUpdate(checkoutId: $checkoutId, lineItems: $lineItems) { checkoutUserErrors { code @@ -9,9 +12,11 @@ const checkoutLineItemUpdateMutation = /* GraphQL */ ` message } checkout { - ${checkoutDetailsFragment} + ...checkoutDetails } } } + + ${checkoutDetailsFragment} ` export default checkoutLineItemUpdateMutation diff --git a/framework/shopify/utils/normalize.ts b/framework/shopify/utils/normalize.ts index 4ebc3a1ae..e86872ef9 100644 --- a/framework/shopify/utils/normalize.ts +++ b/framework/shopify/utils/normalize.ts @@ -1,4 +1,7 @@ -import { Product } from '@commerce/types' +import type { Page } from '../types/page' +import type { Product } from '../types/product' +import type { Cart, LineItem } from '../types/cart' +import type { Category } from '../types/site' import { Product as ShopifyProduct, @@ -9,9 +12,11 @@ import { ProductVariantConnection, MoneyV2, ProductOption, + Page as ShopifyPage, + PageEdge, + Collection, } from '../schema' - -import type { Cart, LineItem } from '../types' +import { colorMap } from '@lib/colors' const money = ({ amount, currencyCode }: MoneyV2) => { return { @@ -28,15 +33,18 @@ const normalizeProductOption = ({ return { __typename: 'MultipleChoiceOption', id, - displayName, + displayName: displayName.toLowerCase(), values: values.map((value) => { let output: any = { label: value, } if (displayName.match(/colou?r/gi)) { - output = { - ...output, - hexColors: [value], + const mapedColor = colorMap[value.toLowerCase().replace(/ /g, '')] + if (mapedColor) { + output = { + ...output, + hexColors: [mapedColor], + } } } return output @@ -53,7 +61,16 @@ const normalizeProductImages = ({ edges }: ImageConnection) => const normalizeProductVariants = ({ edges }: ProductVariantConnection) => { return edges?.map( ({ - node: { id, selectedOptions, sku, title, priceV2, compareAtPriceV2 }, + node: { + id, + selectedOptions, + sku, + title, + priceV2, + compareAtPriceV2, + requiresShipping, + availableForSale, + }, }) => { return { id, @@ -61,7 +78,8 @@ const normalizeProductVariants = ({ edges }: ProductVariantConnection) => { sku: sku ?? id, price: +priceV2.amount, listPrice: +compareAtPriceV2?.amount, - requiresShipping: true, + requiresShipping, + availableForSale, options: selectedOptions.map(({ name, value }: SelectedOption) => { const options = normalizeProductOption({ id, @@ -75,22 +93,21 @@ const normalizeProductVariants = ({ edges }: ProductVariantConnection) => { ) } -export function normalizeProduct(productNode: ShopifyProduct): Product { - const { - id, - title: name, - vendor, - images, - variants, - description, - descriptionHtml, - handle, - priceRange, - options, - ...rest - } = productNode - - const product = { +export function normalizeProduct({ + id, + title: name, + vendor, + images, + variants, + description, + descriptionHtml, + handle, + priceRange, + options, + metafields, + ...rest +}: ShopifyProduct): Product { + return { id, name, vendor, @@ -108,13 +125,12 @@ export function normalizeProduct(productNode: ShopifyProduct): Product { ...(descriptionHtml && { descriptionHtml }), ...rest, } - - return product } export function normalizeCart(checkout: Checkout): Cart { return { id: checkout.id, + url: checkout.webUrl, customerId: '', email: '', createdAt: checkout.createdAt, @@ -131,7 +147,7 @@ export function normalizeCart(checkout: Checkout): Cart { } function normalizeLineItem({ - node: { id, title, variant, quantity, ...rest }, + node: { id, title, variant, quantity }, }: CheckoutLineItemEdge): LineItem { return { id, @@ -144,7 +160,7 @@ function normalizeLineItem({ sku: variant?.sku ?? '', name: variant?.title!, image: { - url: variant?.image?.originalSrc ?? '/product-img-placeholder.svg', + url: variant?.image?.originalSrc || '/product-img-placeholder.svg', }, requiresShipping: variant?.requiresShipping ?? false, price: variant?.priceV2?.amount, @@ -152,14 +168,29 @@ function normalizeLineItem({ }, path: String(variant?.product?.handle), discounts: [], - options: - // By default Shopify adds a default variant with default names, we're removing it. https://community.shopify.com/c/Shopify-APIs-SDKs/Adding-new-product-variant-is-automatically-adding-quot-Default/td-p/358095 - variant?.title == 'Default Title' - ? [] - : [ - { - value: variant?.title, - }, - ], + options: variant?.title == 'Default Title' ? [] : variant?.selectedOptions, } } + +export const normalizePage = ( + { title: name, handle, ...page }: ShopifyPage, + locale: string +): Page => ({ + ...page, + url: `/${locale}/${handle}`, + name, +}) + +export const normalizePages = (edges: PageEdge[], locale: string): Page[] => + edges?.map((edge) => normalizePage(edge.node, locale)) + +export const normalizeCategory = ({ + title: name, + handle, + id, +}: Collection): Category => ({ + id, + name, + slug: handle, + path: `/${handle}`, +}) diff --git a/framework/shopify/utils/queries/get-all-products-query.ts b/framework/shopify/utils/queries/get-all-products-query.ts index f48140d31..179cf9812 100644 --- a/framework/shopify/utils/queries/get-all-products-query.ts +++ b/framework/shopify/utils/queries/get-all-products-query.ts @@ -1,46 +1,38 @@ -export const productConnection = ` -pageInfo { - hasNextPage - hasPreviousPage -} -edges { - node { - id - title - vendor - handle - priceRange { - minVariantPrice { - amount - currencyCode - } +export const productConnectionFragment = /* GraphQL */ ` + fragment productConnection on ProductConnection { + pageInfo { + hasNextPage + hasPreviousPage } - images(first: 1) { - pageInfo { - hasNextPage - hasPreviousPage - } - edges { - node { - originalSrc - altText - width - height + edges { + node { + id + title + vendor + handle + 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 */ ` @@ -50,7 +42,16 @@ const getAllProductsQuery = /* GraphQL */ ` $sortKey: ProductSortKeys = RELEVANCE $reverse: Boolean = false ) { - ${productsFragment} + products( + first: $first + sortKey: $sortKey + reverse: $reverse + query: $query + ) { + ...productConnection + } } + + ${productConnectionFragment} ` export default getAllProductsQuery diff --git a/framework/shopify/utils/queries/get-checkout-query.ts b/framework/shopify/utils/queries/get-checkout-query.ts index d8758e321..9969e67c0 100644 --- a/framework/shopify/utils/queries/get-checkout-query.ts +++ b/framework/shopify/utils/queries/get-checkout-query.ts @@ -1,65 +1,70 @@ -export const checkoutDetailsFragment = ` - id - webUrl - subtotalPriceV2{ - amount - currencyCode - } - totalTaxV2 { - amount - currencyCode - } - totalPriceV2 { - amount - currencyCode - } - completedAt - createdAt - taxesIncluded - lineItems(first: 250) { - pageInfo { - hasNextPage - hasPreviousPage +export const checkoutDetailsFragment = /* GraphQL */ ` + fragment checkoutDetails on Checkout { + id + webUrl + subtotalPriceV2 { + amount + currencyCode } - edges { - node { - id - title - variant { + totalTaxV2 { + amount + currencyCode + } + totalPriceV2 { + amount + currencyCode + } + completedAt + createdAt + taxesIncluded + lineItems(first: 250) { + pageInfo { + hasNextPage + hasPreviousPage + } + edges { + node { id - sku title - image { - originalSrc - altText - width - height - } - priceV2{ - amount - currencyCode - } - compareAtPriceV2{ - amount - currencyCode - } - product { - handle + variant { + id + sku + title + selectedOptions { + name + value + } + image { + originalSrc + altText + width + height + } + priceV2 { + amount + currencyCode + } + compareAtPriceV2 { + amount + currencyCode + } + product { + handle + } } + quantity } - quantity } } } ` const getCheckoutQuery = /* GraphQL */ ` - query($checkoutId: ID!) { + query getCheckout($checkoutId: ID!) { node(id: $checkoutId) { - ... on Checkout { - ${checkoutDetailsFragment} - } + ...checkoutDetails } } + ${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 index 04766caa4..b773a7e65 100644 --- a/framework/shopify/utils/queries/get-collection-products-query.ts +++ b/framework/shopify/utils/queries/get-collection-products-query.ts @@ -1,4 +1,4 @@ -import { productConnection } from './get-all-products-query' +import { productConnectionFragment } from './get-all-products-query' const getCollectionProductsQuery = /* GraphQL */ ` query getProductsFromCollection( @@ -10,15 +10,12 @@ const getCollectionProductsQuery = /* GraphQL */ ` node(id: $categoryId) { id ... on Collection { - products( - first: $first - sortKey: $sortKey - reverse: $reverse - ) { - ${productConnection} + products(first: $first, sortKey: $sortKey, reverse: $reverse) { + ...productConnection } } } } + ${productConnectionFragment} ` export default getCollectionProductsQuery diff --git a/framework/shopify/utils/queries/get-page-query.ts b/framework/shopify/utils/queries/get-page-query.ts index 2ca79abd4..7939f0278 100644 --- a/framework/shopify/utils/queries/get-page-query.ts +++ b/framework/shopify/utils/queries/get-page-query.ts @@ -1,5 +1,5 @@ export const getPageQuery = /* GraphQL */ ` - query($id: ID!) { + query getPage($id: ID!) { node(id: $id) { id ... on Page { diff --git a/framework/shopify/utils/queries/get-product-query.ts b/framework/shopify/utils/queries/get-product-query.ts index 5c109901b..b2998a40a 100644 --- a/framework/shopify/utils/queries/get-product-query.ts +++ b/framework/shopify/utils/queries/get-product-query.ts @@ -3,6 +3,7 @@ const getProductQuery = /* GraphQL */ ` productByHandle(handle: $slug) { id handle + availableForSale title productType vendor @@ -33,6 +34,8 @@ const getProductQuery = /* GraphQL */ ` id title sku + availableForSale + requiresShipping selectedOptions { name value diff --git a/framework/shopify/utils/queries/get-site-info-query.ts b/framework/shopify/utils/queries/get-site-info-query.ts new file mode 100644 index 000000000..74215572a --- /dev/null +++ b/framework/shopify/utils/queries/get-site-info-query.ts @@ -0,0 +1,8 @@ +const getSiteInfoQuery = /* GraphQL */ ` + query getSiteInfo { + shop { + name + } + } +` +export default getSiteInfoQuery diff --git a/framework/shopify/utils/queries/index.ts b/framework/shopify/utils/queries/index.ts index e19be9c8c..953113491 100644 --- a/framework/shopify/utils/queries/index.ts +++ b/framework/shopify/utils/queries/index.ts @@ -8,3 +8,4 @@ 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' +export { default as getSiteInfoQuery } from './get-site-info-query' diff --git a/lib/api/commerce.ts b/lib/api/commerce.ts new file mode 100644 index 000000000..499137004 --- /dev/null +++ b/lib/api/commerce.ts @@ -0,0 +1,3 @@ +import { getCommerceApi } from '@framework/api' + +export default getCommerceApi() diff --git a/lib/colors.ts b/lib/colors.ts index 139cda23d..43947c322 100644 --- a/lib/colors.ts +++ b/lib/colors.ts @@ -42,7 +42,7 @@ function hexToRgb(hex: string = '') { return [r, g, b] } -const colorMap: Record = { +export const colorMap: Record = { aliceblue: '#F0F8FF', antiquewhite: '#FAEBD7', aqua: '#00FFFF', @@ -56,6 +56,8 @@ const colorMap: Record = { blueviolet: '#8A2BE2', brown: '#A52A2A', burlywood: '#DEB887', + burgandy: '#800020', + burgundy: '#800020', cadetblue: '#5F9EA0', chartreuse: '#7FFF00', chocolate: '#D2691E', @@ -177,6 +179,8 @@ const colorMap: Record = { slateblue: '#6A5ACD', slategray: '#708090', slategrey: '#708090', + spacegrey: '#65737e', + spacegray: '#65737e', snow: '#FFFAFA', springgreen: '#00FF7F', steelblue: '#4682B4', diff --git a/next.config.js b/next.config.js index b1e48cf1e..607d4eba8 100644 --- a/next.config.js +++ b/next.config.js @@ -20,13 +20,13 @@ module.exports = withCommerceConfig({ return [ (isBC || isShopify || isSwell || isVendure) && { source: '/checkout', - destination: '/api/bigcommerce/checkout', + destination: '/api/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=/', + destination: '/api/logout?redirect_to=/', }, // For Vendure, rewrite the local api url to the remote (external) api url. This is required // to make the session cookies work. diff --git a/package.json b/package.json index 5a9d40b79..85daa3158 100644 --- a/package.json +++ b/package.json @@ -9,6 +9,7 @@ "prettier-fix": "prettier --write .", "find:unused": "next-unused", "generate": "graphql-codegen", + "generate:shopify": "DOTENV_CONFIG_PATH=./.env.local graphql-codegen -r dotenv/config --config framework/shopify/codegen.json", "generate:vendure": "graphql-codegen --config framework/vendure/codegen.json", "generate:definitions": "node framework/bigcommerce/scripts/generate-definitions.js" }, diff --git a/pages/[...pages].tsx b/pages/[...pages].tsx index eae7dca39..c63963ef6 100644 --- a/pages/[...pages].tsx +++ b/pages/[...pages].tsx @@ -3,29 +3,31 @@ import type { GetStaticPropsContext, InferGetStaticPropsType, } from 'next' +import commerce from '@lib/api/commerce' import { Text } from '@components/ui' 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/common/get-page' -import getAllPages from '@framework/common/get-all-pages' -import getSiteInfo from '@framework/common/get-site-info' export async function getStaticProps({ preview, params, locale, + locales, }: GetStaticPropsContext<{ pages: string[] }>) { - const config = getConfig({ locale }) - const { pages } = await getAllPages({ preview, config }) - const { categories } = await getSiteInfo({ config, preview }) + const config = { locale, locales } + const { pages } = await commerce.getAllPages({ config, preview }) + const { categories } = await commerce.getSiteInfo({ config, preview }) const path = params?.pages.join('/') const slug = locale ? `${locale}/${path}` : path const pageItem = pages.find((p) => (p.url ? getSlug(p.url) === slug : false)) const data = pageItem && - (await getPage({ variables: { id: pageItem.id! }, config, preview })) + (await commerce.getPage({ + variables: { id: pageItem.id! }, + config, + preview, + })) const page = data?.page if (!page) { @@ -40,7 +42,8 @@ export async function getStaticProps({ } export async function getStaticPaths({ locales }: GetStaticPathsContext) { - const { pages } = await getAllPages() + const config = { locales } + const { pages } = await commerce.getAllPages({ config }) const [invalidPaths, log] = missingLocaleInPages() const paths = pages .map((page) => page.url) diff --git a/pages/api/bigcommerce/cart.ts b/pages/api/bigcommerce/cart.ts deleted file mode 100644 index 68ffc3b15..000000000 --- a/pages/api/bigcommerce/cart.ts +++ /dev/null @@ -1,3 +0,0 @@ -import cartApi from '@framework/api/cart' - -export default cartApi() diff --git a/pages/api/bigcommerce/catalog/products.ts b/pages/api/bigcommerce/catalog/products.ts deleted file mode 100644 index ac342c82a..000000000 --- a/pages/api/bigcommerce/catalog/products.ts +++ /dev/null @@ -1,3 +0,0 @@ -import catalogProductsApi from '@framework/api/catalog/products' - -export default catalogProductsApi() diff --git a/pages/api/bigcommerce/checkout.ts b/pages/api/bigcommerce/checkout.ts deleted file mode 100644 index bd754deab..000000000 --- a/pages/api/bigcommerce/checkout.ts +++ /dev/null @@ -1,3 +0,0 @@ -import checkoutApi from '@framework/api/checkout' - -export default checkoutApi() diff --git a/pages/api/bigcommerce/customers/index.ts b/pages/api/bigcommerce/customers/index.ts deleted file mode 100644 index 7b55d3aa8..000000000 --- a/pages/api/bigcommerce/customers/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -import customersApi from '@framework/api/customers' - -export default customersApi() diff --git a/pages/api/bigcommerce/customers/login.ts b/pages/api/bigcommerce/customers/login.ts deleted file mode 100644 index aac529751..000000000 --- a/pages/api/bigcommerce/customers/login.ts +++ /dev/null @@ -1,3 +0,0 @@ -import loginApi from '@framework/api/customers/login' - -export default loginApi() diff --git a/pages/api/bigcommerce/customers/logout.ts b/pages/api/bigcommerce/customers/logout.ts deleted file mode 100644 index e872ff95d..000000000 --- a/pages/api/bigcommerce/customers/logout.ts +++ /dev/null @@ -1,3 +0,0 @@ -import logoutApi from '@framework/api/customers/logout' - -export default logoutApi() diff --git a/pages/api/bigcommerce/customers/signup.ts b/pages/api/bigcommerce/customers/signup.ts deleted file mode 100644 index 59f2f840a..000000000 --- a/pages/api/bigcommerce/customers/signup.ts +++ /dev/null @@ -1,3 +0,0 @@ -import signupApi from '@framework/api/customers/signup' - -export default signupApi() diff --git a/pages/api/bigcommerce/wishlist.ts b/pages/api/bigcommerce/wishlist.ts deleted file mode 100644 index 0d6a895a5..000000000 --- a/pages/api/bigcommerce/wishlist.ts +++ /dev/null @@ -1,3 +0,0 @@ -import wishlistApi from '@framework/api/wishlist' - -export default wishlistApi() diff --git a/pages/api/cart.ts b/pages/api/cart.ts new file mode 100644 index 000000000..642891107 --- /dev/null +++ b/pages/api/cart.ts @@ -0,0 +1,4 @@ +import cartApi from '@framework/api/endpoints/cart' +import commerce from '@lib/api/commerce' + +export default cartApi(commerce) diff --git a/pages/api/catalog/products.ts b/pages/api/catalog/products.ts new file mode 100644 index 000000000..631bfd516 --- /dev/null +++ b/pages/api/catalog/products.ts @@ -0,0 +1,4 @@ +import productsApi from '@framework/api/endpoints/catalog/products' +import commerce from '@lib/api/commerce' + +export default productsApi(commerce) diff --git a/pages/api/checkout.ts b/pages/api/checkout.ts new file mode 100644 index 000000000..7bf0fd9aa --- /dev/null +++ b/pages/api/checkout.ts @@ -0,0 +1,4 @@ +import checkoutApi from '@framework/api/endpoints/checkout' +import commerce from '@lib/api/commerce' + +export default checkoutApi(commerce) diff --git a/pages/api/customer.ts b/pages/api/customer.ts new file mode 100644 index 000000000..0c86e76e5 --- /dev/null +++ b/pages/api/customer.ts @@ -0,0 +1,4 @@ +import customerApi from '@framework/api/endpoints/customer' +import commerce from '@lib/api/commerce' + +export default customerApi(commerce) diff --git a/pages/api/login.ts b/pages/api/login.ts new file mode 100644 index 000000000..9d0b6ae57 --- /dev/null +++ b/pages/api/login.ts @@ -0,0 +1,4 @@ +import loginApi from '@framework/api/endpoints/login' +import commerce from '@lib/api/commerce' + +export default loginApi(commerce) diff --git a/pages/api/logout.ts b/pages/api/logout.ts new file mode 100644 index 000000000..0cf0fc4d2 --- /dev/null +++ b/pages/api/logout.ts @@ -0,0 +1,4 @@ +import logoutApi from '@framework/api/endpoints/logout' +import commerce from '@lib/api/commerce' + +export default logoutApi(commerce) diff --git a/pages/api/signup.ts b/pages/api/signup.ts new file mode 100644 index 000000000..e19d67ee8 --- /dev/null +++ b/pages/api/signup.ts @@ -0,0 +1,4 @@ +import singupApi from '@framework/api/endpoints/signup' +import commerce from '@lib/api/commerce' + +export default singupApi(commerce) diff --git a/pages/api/wishlist.ts b/pages/api/wishlist.ts new file mode 100644 index 000000000..3b9681209 --- /dev/null +++ b/pages/api/wishlist.ts @@ -0,0 +1,4 @@ +import wishlistApi from '@framework/api/endpoints/wishlist' +import commerce from '@lib/api/commerce' + +export default wishlistApi(commerce) diff --git a/pages/cart.tsx b/pages/cart.tsx index c8deb1a02..dff4a201e 100644 --- a/pages/cart.tsx +++ b/pages/cart.tsx @@ -1,21 +1,20 @@ import type { GetStaticPropsContext } from 'next' -import { getConfig } from '@framework/api' -import getAllPages from '@framework/common/get-all-pages' import useCart from '@framework/cart/use-cart' import usePrice from '@framework/product/use-price' +import commerce from '@lib/api/commerce' import { Layout } from '@components/common' import { Button, Text } from '@components/ui' import { Bag, Cross, Check, MapPin, CreditCard } from '@components/icons' import { CartItem } from '@components/cart' -import getSiteInfo from '@framework/common/get-site-info' export async function getStaticProps({ preview, locale, + locales, }: GetStaticPropsContext) { - const config = getConfig({ locale }) - const { categories } = await getSiteInfo({ config, preview }) - const { pages } = await getAllPages({ config, preview }) + const config = { locale, locales } + const { pages } = await commerce.getAllPages({ config, preview }) + const { categories } = await commerce.getSiteInfo({ config, preview }) return { props: { pages, categories }, } diff --git a/pages/index.tsx b/pages/index.tsx index 3a466c606..02142f3b0 100644 --- a/pages/index.tsx +++ b/pages/index.tsx @@ -1,32 +1,29 @@ +import commerce from '@lib/api/commerce' 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/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, locale, + locales, }: GetStaticPropsContext) { - const config = getConfig({ locale }) - const { pages } = await getAllPages({ config, preview }) - const { categories } = await getSiteInfo({ config, preview }) - - const { products } = await getAllProducts({ + const config = { locale, locales } + const { products } = await commerce.getAllProducts({ variables: { first: 12 }, config, preview, }) + const { categories, brands } = await commerce.getSiteInfo({ config, preview }) + const { pages } = await commerce.getAllPages({ config, preview }) return { props: { products, categories, - brands: [], + brands, pages, }, revalidate: 14400, diff --git a/pages/orders.tsx b/pages/orders.tsx index ee93f3f7f..ddea62d05 100644 --- a/pages/orders.tsx +++ b/pages/orders.tsx @@ -1,18 +1,17 @@ import type { GetStaticPropsContext } from 'next' +import commerce from '@lib/api/commerce' import { Bag } from '@components/icons' -import { getConfig } from '@framework/api' import { Layout } from '@components/common' import { Container, Text } from '@components/ui' -import getAllPages from '@framework/common/get-all-pages' -import getSiteInfo from '@framework/common/get-site-info' export async function getStaticProps({ preview, locale, + locales, }: GetStaticPropsContext) { - const config = getConfig({ locale }) - const { categories } = await getSiteInfo({ config, preview }) - const { pages } = await getAllPages({ config, preview }) + const config = { locale, locales } + const { pages } = await commerce.getAllPages({ config, preview }) + const { categories } = await commerce.getSiteInfo({ config, preview }) return { props: { pages, categories }, diff --git a/pages/product/[slug].tsx b/pages/product/[slug].tsx index ac55dc4be..3b41216a8 100644 --- a/pages/product/[slug].tsx +++ b/pages/product/[slug].tsx @@ -4,28 +4,24 @@ import type { InferGetStaticPropsType, } from 'next' import { useRouter } from 'next/router' +import commerce from '@lib/api/commerce' import { Layout } from '@components/common' import { ProductView } from '@components/product' -import { getConfig } from '@framework/api' -import getProduct from '@framework/product/get-product' -import getAllPages from '@framework/common/get-all-pages' -import getAllProductPaths from '@framework/product/get-all-product-paths' -import getSiteInfo from '@framework/common/get-site-info' - export async function getStaticProps({ params, locale, + locales, preview, }: GetStaticPropsContext<{ slug: string }>) { - const config = getConfig({ locale }) - const { pages } = await getAllPages({ config, preview }) - const { product } = await getProduct({ + const config = { locale, locales } + const { pages } = await commerce.getAllPages({ config, preview }) + const { product } = await commerce.getProduct({ variables: { slug: params!.slug }, config, preview, }) - const { categories } = await getSiteInfo({ config, preview }) + const { categories } = await commerce.getSiteInfo({ config, preview }) if (!product) { throw new Error(`Product with slug '${params!.slug}' not found`) @@ -42,18 +38,18 @@ export async function getStaticProps({ } export async function getStaticPaths({ locales }: GetStaticPathsContext) { - const { products } = await getAllProductPaths() + const { products } = await commerce.getAllProductPaths() return { paths: locales ? locales.reduce((arr, locale) => { // Add a product path for every locale products.forEach((product) => { - arr.push(`/${locale}/product${product.node.path}`) + arr.push(`/${locale}/product${product.path}`) }) return arr }, []) - : products.map((product) => `/product${product.node.path}`), + : products.map((product) => `/product${product.path}`), fallback: 'blocking', } } diff --git a/pages/profile.tsx b/pages/profile.tsx index b1e8e6628..1f575c8f2 100644 --- a/pages/profile.tsx +++ b/pages/profile.tsx @@ -1,18 +1,18 @@ import type { GetStaticPropsContext } from 'next' -import { getConfig } from '@framework/api' -import getAllPages from '@framework/common/get-all-pages' import useCustomer from '@framework/customer/use-customer' +import commerce from '@lib/api/commerce' import { Layout } from '@components/common' import { Container, Text } from '@components/ui' -import getSiteInfo from '@framework/common/get-site-info' export async function getStaticProps({ preview, locale, + locales, }: GetStaticPropsContext) { - const config = getConfig({ locale }) - const { categories } = await getSiteInfo({ config, preview }) - const { pages } = await getAllPages({ config, preview }) + const config = { locale, locales } + const { pages } = await commerce.getAllPages({ config, preview }) + const { categories } = await commerce.getSiteInfo({ config, preview }) + return { props: { pages, categories }, } diff --git a/pages/search.tsx b/pages/search.tsx index 9a0330127..55c57c593 100644 --- a/pages/search.tsx +++ b/pages/search.tsx @@ -6,16 +6,23 @@ import { useRouter } from 'next/router' import { Layout } from '@components/common' import { ProductCard } from '@components/product' +import type { Product } from '@commerce/types/product' import { Container, Grid, Skeleton } from '@components/ui' -import { getConfig } from '@framework/api' import useSearch from '@framework/product/use-search' -import getAllPages from '@framework/common/get-all-pages' -import getSiteInfo from '@framework/common/get-site-info' - -import getSlug from '@lib/get-slug' +import commerce from '@lib/api/commerce' import rangeMap from '@lib/range-map' +import { + filterQuery, + getCategoryPath, + getDesignerPath, + useSearchMeta, +} from '@lib/search' + +// TODO(bc) Remove this. This should come from the API +import getSlug from '@lib/get-slug' + const SORT = Object.entries({ 'latest-desc': 'Latest arrivals', 'trending-desc': 'Trending', @@ -23,21 +30,14 @@ const SORT = Object.entries({ 'price-desc': 'Price: High to low', }) -import { - filterQuery, - getCategoryPath, - getDesignerPath, - useSearchMeta, -} from '@lib/search' -import { Product } from '@commerce/types' - export async function getStaticProps({ preview, locale, + locales, }: GetStaticPropsContext) { - const config = getConfig({ locale }) - const { pages } = await getAllPages({ config, preview }) - const { categories, brands } = await getSiteInfo({ config, preview }) + const config = { locale, locales } + const { pages } = await commerce.getAllPages({ config, preview }) + const { categories, brands } = await commerce.getSiteInfo({ config, preview }) return { props: { pages, @@ -55,7 +55,7 @@ export default function Search({ const [toggleFilter, setToggleFilter] = useState(false) const router = useRouter() - const { asPath } = router + const { asPath, locale } = router const { q, sort } = router.query // `q` can be included but because categories and designers can't be searched // in the same way of products, it's better to ignore the search input if one @@ -63,9 +63,7 @@ export default function Search({ const query = filterQuery({ sort }) const { pathname, category, brand } = useSearchMeta(asPath) - const activeCategory = categories.find( - (cat) => getSlug(cat.path) === category - ) + const activeCategory = categories.find((cat) => cat.slug === category) const activeBrand = brands.find( (b) => getSlug(b.node.path) === `brands/${brand}` )?.node @@ -75,6 +73,7 @@ export default function Search({ categoryId: activeCategory?.id, brandId: (activeBrand as any)?.entityId, sort: typeof sort === 'string' ? sort : '', + locale, }) const handleClick = (event: any, filter: string) => { diff --git a/pages/wishlist.tsx b/pages/wishlist.tsx index 0e6732ae2..2728e2984 100644 --- a/pages/wishlist.tsx +++ b/pages/wishlist.tsx @@ -1,17 +1,16 @@ import type { GetStaticPropsContext } from 'next' +import commerce from '@lib/api/commerce' import { Heart } from '@components/icons' -import { getConfig } from '@framework/api' import { Layout } from '@components/common' import { Text, Container } from '@components/ui' import { useCustomer } from '@framework/customer' import { WishlistCard } from '@components/wishlist' import useWishlist from '@framework/wishlist/use-wishlist' -import getAllPages from '@framework/common/get-all-pages' -import getSiteInfo from '@framework/common/get-site-info' export async function getStaticProps({ preview, locale, + locales, }: GetStaticPropsContext) { // Disabling page if Feature is not available if (!process.env.COMMERCE_WISHLIST_ENABLED) { @@ -20,9 +19,10 @@ export async function getStaticProps({ } } - const config = getConfig({ locale }) - const { categories } = await getSiteInfo({ config, preview }) - const { pages } = await getAllPages({ config, preview }) + const config = { locale, locales } + const { pages } = await commerce.getAllPages({ config, preview }) + const { categories } = await commerce.getSiteInfo({ config, preview }) + return { props: { pages, diff --git a/tsconfig.json b/tsconfig.json index 9e712fb18..96e4359e5 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/shopify"], + "@framework/*": ["framework/shopify/*"] } }, "include": ["next-env.d.ts", "**/*.d.ts", "**/*.ts", "**/*.tsx", "**/*.js"], - "exclude": ["node_modules"] + "exclude": ["node_modules", "framework/swell", "framework/vendure"] } From 0e804d09f913030b5ef850016b15cfcfd7b11430 Mon Sep 17 00:00:00 2001 From: Michael Bromley Date: Wed, 2 Jun 2021 16:46:38 +0200 Subject: [PATCH 251/261] Update Vendure provider to latest API changes (#352) Relates to #349 --- framework/vendure/.env.template | 3 + framework/vendure/api/cart/index.ts | 1 - framework/vendure/api/catalog/index.ts | 1 - framework/vendure/api/catalog/products.ts | 1 - framework/vendure/api/customers/index.ts | 1 - framework/vendure/api/customers/login.ts | 1 - framework/vendure/api/customers/logout.ts | 1 - framework/vendure/api/customers/signup.ts | 1 - framework/vendure/api/endpoints/cart/index.ts | 1 + .../vendure/api/endpoints/catalog/index.ts | 1 + .../vendure/api/endpoints/catalog/products.ts | 1 + .../api/{ => endpoints}/checkout/index.ts | 41 +- .../vendure/api/endpoints/customer/index.ts | 1 + .../vendure/api/endpoints/login/index.ts | 1 + .../vendure/api/endpoints/logout/index.ts | 1 + .../vendure/api/endpoints/signup/index.ts | 1 + .../vendure/api/endpoints/wishlist/index.tsx | 1 + framework/vendure/api/index.ts | 60 +-- .../vendure/api/operations/get-all-pages.ts | 41 ++ .../api/operations/get-all-product-paths.ts | 52 ++ .../api/operations/get-all-products.ts | 46 ++ .../api/operations/get-customer-wishlist.ts | 23 + framework/vendure/api/operations/get-page.ts | 45 ++ .../vendure/api/operations/get-product.ts | 69 +++ .../vendure/api/operations/get-site-info.ts | 50 ++ framework/vendure/api/operations/login.ts | 60 +++ .../vendure/api/utils/fetch-graphql-api.ts | 5 +- framework/vendure/api/wishlist/index.tsx | 2 - framework/vendure/auth/index.ts | 3 + framework/vendure/auth/use-login.tsx | 5 +- framework/vendure/auth/use-logout.tsx | 5 +- framework/vendure/auth/use-signup.tsx | 5 +- framework/vendure/cart/index.ts | 3 +- framework/vendure/cart/use-add-item.tsx | 8 +- framework/vendure/cart/use-cart-actions.tsx | 13 - framework/vendure/cart/use-cart.tsx | 15 +- framework/vendure/cart/use-remove-item.tsx | 26 +- framework/vendure/cart/use-update-item.tsx | 30 +- framework/vendure/common/get-all-pages.ts | 35 -- framework/vendure/common/get-page.ts | 40 -- framework/vendure/common/get-site-info.ts | 43 -- .../vendure/customer/get-customer-wishlist.ts | 18 - framework/vendure/customer/use-customer.tsx | 6 +- .../vendure/product/get-all-product-paths.ts | 48 -- framework/vendure/product/get-all-products.ts | 39 -- framework/vendure/product/get-product.ts | 64 --- framework/vendure/product/index.ts | 2 - framework/vendure/product/use-search.tsx | 15 +- framework/vendure/schema.d.ts | 487 +++++++++++------- framework/vendure/schema.graphql | 478 +++++++++++++---- framework/vendure/types.ts | 5 - framework/vendure/types/cart.ts | 1 + framework/vendure/types/checkout.ts | 1 + framework/vendure/types/common.ts | 1 + framework/vendure/types/customer.ts | 1 + framework/vendure/types/index.ts | 25 + framework/vendure/types/login.ts | 12 + framework/vendure/types/logout.ts | 1 + framework/vendure/types/page.ts | 1 + framework/vendure/types/product.ts | 1 + framework/vendure/types/signup.ts | 1 + framework/vendure/types/site.ts | 1 + framework/vendure/types/wishlist.ts | 1 + .../vendure/{lib => utils}/array-to-tree.ts | 0 .../{lib => utils}/fragments/cart-fragment.ts | 2 + .../fragments/search-result-fragment.ts | 0 .../mutations/add-item-to-order-mutation.ts | 0 .../mutations/adjust-order-line-mutation.ts | 0 .../mutations/log-in-mutation.ts | 0 .../mutations/log-out-mutation.ts | 0 .../mutations/remove-order-line-mutation.ts | 0 .../mutations/sign-up-mutation.ts | 0 framework/vendure/{lib => utils}/normalize.ts | 7 +- .../queries/active-customer-query.ts | 0 .../queries/get-all-product-paths-query.ts | 0 .../queries/get-all-products-query.ts | 0 .../{lib => utils}/queries/get-cart-query.ts | 0 .../queries/get-collections-query.ts | 0 .../queries/get-product-query.ts | 0 .../{lib => utils}/queries/search-query.ts | 0 framework/vendure/wishlist/use-wishlist.tsx | 2 +- 81 files changed, 1265 insertions(+), 698 deletions(-) delete mode 100644 framework/vendure/api/cart/index.ts delete mode 100644 framework/vendure/api/catalog/index.ts delete mode 100644 framework/vendure/api/catalog/products.ts delete mode 100644 framework/vendure/api/customers/index.ts delete mode 100644 framework/vendure/api/customers/login.ts delete mode 100644 framework/vendure/api/customers/logout.ts delete mode 100644 framework/vendure/api/customers/signup.ts create mode 100644 framework/vendure/api/endpoints/cart/index.ts create mode 100644 framework/vendure/api/endpoints/catalog/index.ts create mode 100644 framework/vendure/api/endpoints/catalog/products.ts rename framework/vendure/api/{ => endpoints}/checkout/index.ts (66%) create mode 100644 framework/vendure/api/endpoints/customer/index.ts create mode 100644 framework/vendure/api/endpoints/login/index.ts create mode 100644 framework/vendure/api/endpoints/logout/index.ts create mode 100644 framework/vendure/api/endpoints/signup/index.ts create mode 100644 framework/vendure/api/endpoints/wishlist/index.tsx create mode 100644 framework/vendure/api/operations/get-all-pages.ts create mode 100644 framework/vendure/api/operations/get-all-product-paths.ts create mode 100644 framework/vendure/api/operations/get-all-products.ts create mode 100644 framework/vendure/api/operations/get-customer-wishlist.ts create mode 100644 framework/vendure/api/operations/get-page.ts create mode 100644 framework/vendure/api/operations/get-product.ts create mode 100644 framework/vendure/api/operations/get-site-info.ts create mode 100644 framework/vendure/api/operations/login.ts delete mode 100644 framework/vendure/api/wishlist/index.tsx create mode 100644 framework/vendure/auth/index.ts delete mode 100644 framework/vendure/cart/use-cart-actions.tsx delete mode 100644 framework/vendure/common/get-all-pages.ts delete mode 100644 framework/vendure/common/get-page.ts delete mode 100644 framework/vendure/common/get-site-info.ts delete mode 100644 framework/vendure/customer/get-customer-wishlist.ts delete mode 100644 framework/vendure/product/get-all-product-paths.ts delete mode 100644 framework/vendure/product/get-all-products.ts delete mode 100644 framework/vendure/product/get-product.ts delete mode 100644 framework/vendure/types.ts create mode 100644 framework/vendure/types/cart.ts create mode 100644 framework/vendure/types/checkout.ts create mode 100644 framework/vendure/types/common.ts create mode 100644 framework/vendure/types/customer.ts create mode 100644 framework/vendure/types/index.ts create mode 100644 framework/vendure/types/login.ts create mode 100644 framework/vendure/types/logout.ts create mode 100644 framework/vendure/types/page.ts create mode 100644 framework/vendure/types/product.ts create mode 100644 framework/vendure/types/signup.ts create mode 100644 framework/vendure/types/site.ts create mode 100644 framework/vendure/types/wishlist.ts rename framework/vendure/{lib => utils}/array-to-tree.ts (100%) rename framework/vendure/{lib => utils}/fragments/cart-fragment.ts (91%) rename framework/vendure/{lib => utils}/fragments/search-result-fragment.ts (100%) rename framework/vendure/{lib => utils}/mutations/add-item-to-order-mutation.ts (100%) rename framework/vendure/{lib => utils}/mutations/adjust-order-line-mutation.ts (100%) rename framework/vendure/{lib => utils}/mutations/log-in-mutation.ts (100%) rename framework/vendure/{lib => utils}/mutations/log-out-mutation.ts (100%) rename framework/vendure/{lib => utils}/mutations/remove-order-line-mutation.ts (100%) rename framework/vendure/{lib => utils}/mutations/sign-up-mutation.ts (100%) rename framework/vendure/{lib => utils}/normalize.ts (89%) rename framework/vendure/{lib => utils}/queries/active-customer-query.ts (100%) rename framework/vendure/{lib => utils}/queries/get-all-product-paths-query.ts (100%) rename framework/vendure/{lib => utils}/queries/get-all-products-query.ts (100%) rename framework/vendure/{lib => utils}/queries/get-cart-query.ts (100%) rename framework/vendure/{lib => utils}/queries/get-collections-query.ts (100%) rename framework/vendure/{lib => utils}/queries/get-product-query.ts (100%) rename framework/vendure/{lib => utils}/queries/search-query.ts (100%) diff --git a/framework/vendure/.env.template b/framework/vendure/.env.template index d8f7f14b5..f4823038d 100644 --- a/framework/vendure/.env.template +++ b/framework/vendure/.env.template @@ -1 +1,4 @@ +COMMERCE_PROVIDER=vendure + NEXT_PUBLIC_VENDURE_SHOP_API_URL=http://localhost:3001/shop-api +NEXT_PUBLIC_VENDURE_LOCAL_URL=/vendure-shop-api diff --git a/framework/vendure/api/cart/index.ts b/framework/vendure/api/cart/index.ts deleted file mode 100644 index ea9b101e1..000000000 --- a/framework/vendure/api/cart/index.ts +++ /dev/null @@ -1 +0,0 @@ -export default function () {} diff --git a/framework/vendure/api/catalog/index.ts b/framework/vendure/api/catalog/index.ts deleted file mode 100644 index ea9b101e1..000000000 --- a/framework/vendure/api/catalog/index.ts +++ /dev/null @@ -1 +0,0 @@ -export default function () {} diff --git a/framework/vendure/api/catalog/products.ts b/framework/vendure/api/catalog/products.ts deleted file mode 100644 index ea9b101e1..000000000 --- a/framework/vendure/api/catalog/products.ts +++ /dev/null @@ -1 +0,0 @@ -export default function () {} diff --git a/framework/vendure/api/customers/index.ts b/framework/vendure/api/customers/index.ts deleted file mode 100644 index ea9b101e1..000000000 --- a/framework/vendure/api/customers/index.ts +++ /dev/null @@ -1 +0,0 @@ -export default function () {} diff --git a/framework/vendure/api/customers/login.ts b/framework/vendure/api/customers/login.ts deleted file mode 100644 index ea9b101e1..000000000 --- a/framework/vendure/api/customers/login.ts +++ /dev/null @@ -1 +0,0 @@ -export default function () {} diff --git a/framework/vendure/api/customers/logout.ts b/framework/vendure/api/customers/logout.ts deleted file mode 100644 index ea9b101e1..000000000 --- a/framework/vendure/api/customers/logout.ts +++ /dev/null @@ -1 +0,0 @@ -export default function () {} diff --git a/framework/vendure/api/customers/signup.ts b/framework/vendure/api/customers/signup.ts deleted file mode 100644 index ea9b101e1..000000000 --- a/framework/vendure/api/customers/signup.ts +++ /dev/null @@ -1 +0,0 @@ -export default function () {} diff --git a/framework/vendure/api/endpoints/cart/index.ts b/framework/vendure/api/endpoints/cart/index.ts new file mode 100644 index 000000000..491bf0ac9 --- /dev/null +++ b/framework/vendure/api/endpoints/cart/index.ts @@ -0,0 +1 @@ +export default function noopApi(...args: any[]): void {} diff --git a/framework/vendure/api/endpoints/catalog/index.ts b/framework/vendure/api/endpoints/catalog/index.ts new file mode 100644 index 000000000..491bf0ac9 --- /dev/null +++ b/framework/vendure/api/endpoints/catalog/index.ts @@ -0,0 +1 @@ +export default function noopApi(...args: any[]): void {} diff --git a/framework/vendure/api/endpoints/catalog/products.ts b/framework/vendure/api/endpoints/catalog/products.ts new file mode 100644 index 000000000..491bf0ac9 --- /dev/null +++ b/framework/vendure/api/endpoints/catalog/products.ts @@ -0,0 +1 @@ +export default function noopApi(...args: any[]): void {} diff --git a/framework/vendure/api/checkout/index.ts b/framework/vendure/api/endpoints/checkout/index.ts similarity index 66% rename from framework/vendure/api/checkout/index.ts rename to framework/vendure/api/endpoints/checkout/index.ts index 08b21f6a9..00c17f993 100644 --- a/framework/vendure/api/checkout/index.ts +++ b/framework/vendure/api/endpoints/checkout/index.ts @@ -1,6 +1,13 @@ import { NextApiHandler } from 'next' +import { CommerceAPI, createEndpoint, GetAPISchema } from '@commerce/api' +import { CheckoutSchema } from '@commerce/types/checkout' +import checkoutEndpoint from '@commerce/api/endpoints/checkout' -const checkoutApi = async (req: any, res: any, config: any) => { +const checkout: CheckoutEndpoint['handlers']['checkout'] = async ({ + req, + res, + config, +}) => { try { const html = ` @@ -37,27 +44,15 @@ const checkoutApi = async (req: any, res: any, config: any) => { } } -export function createApiHandler( - handler: any, - handlers: H, - defaultOptions: Options -) { - return function getApiHandler({ - config, - operations, - options, - }: { - config?: any - operations?: Partial - options?: Options extends {} ? Partial : never - } = {}): NextApiHandler { - const ops = { ...operations, ...handlers } - const opts = { ...defaultOptions, ...options } +export type CheckoutAPI = GetAPISchema - return function apiHandler(req, res) { - return handler(req, res, config, ops, opts) - } - } -} +export type CheckoutEndpoint = CheckoutAPI['endpoint'] -export default createApiHandler(checkoutApi, {}, {}) +export const handlers: CheckoutEndpoint['handlers'] = { checkout } + +const checkoutApi = createEndpoint({ + handler: checkoutEndpoint, + handlers, +}) + +export default checkoutApi diff --git a/framework/vendure/api/endpoints/customer/index.ts b/framework/vendure/api/endpoints/customer/index.ts new file mode 100644 index 000000000..491bf0ac9 --- /dev/null +++ b/framework/vendure/api/endpoints/customer/index.ts @@ -0,0 +1 @@ +export default function noopApi(...args: any[]): void {} diff --git a/framework/vendure/api/endpoints/login/index.ts b/framework/vendure/api/endpoints/login/index.ts new file mode 100644 index 000000000..491bf0ac9 --- /dev/null +++ b/framework/vendure/api/endpoints/login/index.ts @@ -0,0 +1 @@ +export default function noopApi(...args: any[]): void {} diff --git a/framework/vendure/api/endpoints/logout/index.ts b/framework/vendure/api/endpoints/logout/index.ts new file mode 100644 index 000000000..491bf0ac9 --- /dev/null +++ b/framework/vendure/api/endpoints/logout/index.ts @@ -0,0 +1 @@ +export default function noopApi(...args: any[]): void {} diff --git a/framework/vendure/api/endpoints/signup/index.ts b/framework/vendure/api/endpoints/signup/index.ts new file mode 100644 index 000000000..491bf0ac9 --- /dev/null +++ b/framework/vendure/api/endpoints/signup/index.ts @@ -0,0 +1 @@ +export default function noopApi(...args: any[]): void {} diff --git a/framework/vendure/api/endpoints/wishlist/index.tsx b/framework/vendure/api/endpoints/wishlist/index.tsx new file mode 100644 index 000000000..491bf0ac9 --- /dev/null +++ b/framework/vendure/api/endpoints/wishlist/index.tsx @@ -0,0 +1 @@ +export default function noopApi(...args: any[]): void {} diff --git a/framework/vendure/api/index.ts b/framework/vendure/api/index.ts index f6b06a10c..6762ee6aa 100644 --- a/framework/vendure/api/index.ts +++ b/framework/vendure/api/index.ts @@ -1,6 +1,16 @@ -import type { CommerceAPIConfig } from '@commerce/api' +import type { APIProvider, CommerceAPIConfig } from '@commerce/api' +import { CommerceAPI, getCommerceApi as commerceApi } from '@commerce/api' import fetchGraphqlApi from './utils/fetch-graphql-api' +import login from './operations/login' +import getAllPages from './operations/get-all-pages' +import getPage from './operations/get-page' +import getSiteInfo from './operations/get-site-info' +import getCustomerWishlist from './operations/get-customer-wishlist' +import getAllProductPaths from './operations/get-all-product-paths' +import getAllProducts from './operations/get-all-products' +import getProduct from './operations/get-product' + export interface VendureConfig extends CommerceAPIConfig {} const API_URL = process.env.NEXT_PUBLIC_VENDURE_SHOP_API_URL @@ -11,41 +21,33 @@ if (!API_URL) { ) } -export class Config { - private config: VendureConfig - - constructor(config: VendureConfig) { - 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 ONE_DAY = 60 * 60 * 24 -const config = new Config({ +const config: VendureConfig = { commerceUrl: API_URL, apiToken: '', cartCookie: '', customerCookie: '', cartCookieMaxAge: ONE_DAY * 30, fetch: fetchGraphqlApi, -}) - -export function getConfig(userConfig?: Partial) { - return config.getConfig(userConfig) } -export function setConfig(newConfig: Partial) { - return config.setConfig(newConfig) +const operations = { + login, + getAllPages, + getPage, + getSiteInfo, + getCustomerWishlist, + getAllProductPaths, + getAllProducts, + getProduct, +} + +export const provider = { config, operations } + +export type Provider = typeof provider + +export function getCommerceApi

    ( + customProvider: P = provider as any +): CommerceAPI

    { + return commerceApi(customProvider) } diff --git a/framework/vendure/api/operations/get-all-pages.ts b/framework/vendure/api/operations/get-all-pages.ts new file mode 100644 index 000000000..43170cda8 --- /dev/null +++ b/framework/vendure/api/operations/get-all-pages.ts @@ -0,0 +1,41 @@ +import { VendureConfig } from '../' +import { OperationContext } from '@commerce/api/operations' +import { Provider } from '../../../bigcommerce/api' + +export type Page = any + +export type GetAllPagesResult< + T extends { pages: any[] } = { pages: Page[] } +> = T + +export default function getAllPagesOperation({ + commerce, +}: OperationContext) { + async function getAllPages(opts?: { + config?: Partial + preview?: boolean + }): Promise + + async function getAllPages(opts: { + url: string + config?: Partial + preview?: boolean + }): Promise> + + async function getAllPages({ + config: cfg, + preview, + }: { + url?: string + config?: Partial + preview?: boolean + } = {}): Promise { + const config = commerce.getConfig(cfg) + + return { + pages: [], + } + } + + return getAllPages +} diff --git a/framework/vendure/api/operations/get-all-product-paths.ts b/framework/vendure/api/operations/get-all-product-paths.ts new file mode 100644 index 000000000..54ca3b136 --- /dev/null +++ b/framework/vendure/api/operations/get-all-product-paths.ts @@ -0,0 +1,52 @@ +import { OperationContext, OperationOptions } from '@commerce/api/operations' +import type { GetAllProductPathsQuery } from '../../schema' +import { Provider } from '../index' +import { getAllProductPathsQuery } from '../../utils/queries/get-all-product-paths-query' +import { GetAllProductPathsOperation } from '@commerce/types/product' +import { BigcommerceConfig } from '../../../bigcommerce/api' + +export type GetAllProductPathsResult = { + products: Array<{ node: { path: string } }> +} + +export default function getAllProductPathsOperation({ + commerce, +}: OperationContext) { + async function getAllProductPaths< + T extends GetAllProductPathsOperation + >(opts?: { + variables?: T['variables'] + config?: BigcommerceConfig + }): Promise + + async function getAllProductPaths( + opts: { + variables?: T['variables'] + config?: BigcommerceConfig + } & OperationOptions + ): Promise + + async function getAllProductPaths({ + query = getAllProductPathsQuery, + variables, + config: cfg, + }: { + query?: string + variables?: T['variables'] + config?: BigcommerceConfig + } = {}): Promise { + const config = commerce.getConfig(cfg) + // RecursivePartial forces the method to check for every prop in the data, which is + // required in case there's a custom `query` + const { data } = await config.fetch(query, { + variables, + }) + const products = data.products.items + + return { + products: products.map((p) => ({ path: `/${p.slug}` })), + } + } + + return getAllProductPaths +} diff --git a/framework/vendure/api/operations/get-all-products.ts b/framework/vendure/api/operations/get-all-products.ts new file mode 100644 index 000000000..68d4ce9b7 --- /dev/null +++ b/framework/vendure/api/operations/get-all-products.ts @@ -0,0 +1,46 @@ +import { Product } from '@commerce/types/product' +import { Provider, VendureConfig } from '../' +import { GetAllProductsQuery } from '../../schema' +import { normalizeSearchResult } from '../../utils/normalize' +import { getAllProductsQuery } from '../../utils/queries/get-all-products-query' +import { OperationContext } from '@commerce/api/operations' + +export type ProductVariables = { first?: number } + +export default function getAllProductsOperation({ + commerce, +}: OperationContext) { + async function getAllProducts(opts?: { + variables?: ProductVariables + config?: Partial + preview?: boolean + }): Promise<{ products: Product[] }> + + async function getAllProducts({ + query = getAllProductsQuery, + variables: { ...vars } = {}, + config: cfg, + }: { + query?: string + variables?: ProductVariables + config?: Partial + preview?: boolean + } = {}): Promise<{ products: Product[] | any[] }> { + const config = commerce.getConfig(cfg) + const variables = { + input: { + take: vars.first, + groupByProduct: true, + }, + } + const { data } = await config.fetch(query, { + variables, + }) + + return { + products: data.search.items.map((item) => normalizeSearchResult(item)), + } + } + + return getAllProducts +} diff --git a/framework/vendure/api/operations/get-customer-wishlist.ts b/framework/vendure/api/operations/get-customer-wishlist.ts new file mode 100644 index 000000000..0040ef36d --- /dev/null +++ b/framework/vendure/api/operations/get-customer-wishlist.ts @@ -0,0 +1,23 @@ +import { OperationContext } from '@commerce/api/operations' +import { Provider, VendureConfig } from '../' + +export default function getCustomerWishlistOperation({ + commerce, +}: OperationContext) { + async function getCustomerWishlist({ + config: cfg, + variables, + includeProducts, + }: { + url?: string + variables: any + config?: Partial + includeProducts?: boolean + }): Promise { + // Not implemented as Vendure does not ship with wishlist functionality at present + const config = commerce.getConfig(cfg) + return { wishlist: {} } + } + + return getCustomerWishlist +} diff --git a/framework/vendure/api/operations/get-page.ts b/framework/vendure/api/operations/get-page.ts new file mode 100644 index 000000000..59717dc84 --- /dev/null +++ b/framework/vendure/api/operations/get-page.ts @@ -0,0 +1,45 @@ +import { VendureConfig, Provider } from '../' +import { OperationContext } from '@commerce/api/operations' + +export type Page = any + +export type GetPageResult = T + +export type PageVariables = { + id: number +} + +export default function getPageOperation({ + commerce, +}: OperationContext) { + async function getPage(opts: { + url?: string + variables: PageVariables + config?: Partial + preview?: boolean + }): Promise + + async function getPage(opts: { + url: string + variables: V + config?: Partial + preview?: boolean + }): Promise> + + async function getPage({ + url, + variables, + config: cfg, + preview, + }: { + url?: string + variables: PageVariables + config?: Partial + preview?: boolean + }): Promise { + const config = commerce.getConfig(cfg) + return {} + } + + return getPage +} diff --git a/framework/vendure/api/operations/get-product.ts b/framework/vendure/api/operations/get-product.ts new file mode 100644 index 000000000..4ab9ed2d9 --- /dev/null +++ b/framework/vendure/api/operations/get-product.ts @@ -0,0 +1,69 @@ +import { Product } from '@commerce/types/product' +import { OperationContext } from '@commerce/api/operations' +import { Provider, VendureConfig } from '../' +import { GetProductQuery } from '../../schema' +import { getProductQuery } from '../../utils/queries/get-product-query' + +export default function getProductOperation({ + commerce, +}: OperationContext) { + async function getProduct({ + query = getProductQuery, + variables, + config: cfg, + }: { + query?: string + variables: { slug: string } + config?: Partial + preview?: boolean + }): Promise { + const config = commerce.getConfig(cfg) + + const locale = config.locale + const { data } = await config.fetch(query, { variables }) + const product = data.product + + if (product) { + const getOptionGroupName = (id: string): string => { + return product.optionGroups.find((og) => og.id === id)!.name + } + return { + product: { + id: product.id, + name: product.name, + description: product.description, + slug: product.slug, + images: product.assets.map((a) => ({ + url: a.preview, + alt: a.name, + })), + variants: product.variants.map((v) => ({ + id: v.id, + options: v.options.map((o) => ({ + // This __typename property is required in order for the correct + // variant selection to work, see `components/product/helpers.ts` + // `getVariant()` function. + __typename: 'MultipleChoiceOption', + id: o.id, + displayName: getOptionGroupName(o.groupId), + values: [{ label: o.name }], + })), + })), + price: { + value: product.variants[0].priceWithTax / 100, + currencyCode: product.variants[0].currencyCode, + }, + options: product.optionGroups.map((og) => ({ + id: og.id, + displayName: og.name, + values: og.options.map((o) => ({ label: o.name })), + })), + } as Product, + } + } + + return {} + } + + return getProduct +} diff --git a/framework/vendure/api/operations/get-site-info.ts b/framework/vendure/api/operations/get-site-info.ts new file mode 100644 index 000000000..acfcea424 --- /dev/null +++ b/framework/vendure/api/operations/get-site-info.ts @@ -0,0 +1,50 @@ +import { Provider, VendureConfig } from '../' +import { GetCollectionsQuery } from '../../schema' +import { arrayToTree } from '../../utils/array-to-tree' +import { getCollectionsQuery } from '../../utils/queries/get-collections-query' +import { OperationContext } from '@commerce/api/operations' +import { Category } from '@commerce/types/site' + +export type GetSiteInfoResult< + T extends { categories: any[]; brands: any[] } = { + categories: Category[] + brands: any[] + } +> = T + +export default function getSiteInfoOperation({ + commerce, +}: OperationContext) { + async function getSiteInfo({ + query = getCollectionsQuery, + variables, + config: cfg, + }: { + query?: string + variables?: any + config?: Partial + preview?: boolean + } = {}): Promise { + const config = commerce.getConfig(cfg) + // RecursivePartial forces the method to check for every prop in the data, which is + // required in case there's a custom `query` + const { data } = await config.fetch(query, { + variables, + }) + const collections = data.collections?.items.map((i) => ({ + ...i, + entityId: i.id, + path: i.slug, + productCount: i.productVariants.totalItems, + })) + const categories = arrayToTree(collections).children + const brands = [] as any[] + + return { + categories: categories ?? [], + brands, + } + } + + return getSiteInfo +} diff --git a/framework/vendure/api/operations/login.ts b/framework/vendure/api/operations/login.ts new file mode 100644 index 000000000..4ad408e0a --- /dev/null +++ b/framework/vendure/api/operations/login.ts @@ -0,0 +1,60 @@ +import type { ServerResponse } from 'http' +import type { + OperationContext, + OperationOptions, +} from '@commerce/api/operations' +import { ValidationError } from '@commerce/utils/errors' +import type { LoginOperation } from '../../types/login' +import type { LoginMutation } from '../../schema' +import { Provider, VendureConfig } from '..' +import { loginMutation } from '../../utils/mutations/log-in-mutation' + +export default function loginOperation({ + commerce, +}: OperationContext) { + async function login(opts: { + variables: T['variables'] + config?: Partial + res: ServerResponse + }): Promise + + async function login( + opts: { + variables: T['variables'] + config?: Partial + res: ServerResponse + } & OperationOptions + ): Promise + + async function login({ + query = loginMutation, + variables, + res: response, + config: cfg, + }: { + query?: string + variables: T['variables'] + res: ServerResponse + config?: Partial + }): Promise { + const config = commerce.getConfig(cfg) + + const { data, res } = await config.fetch(query, { + variables, + }) + switch (data.login.__typename) { + case 'NativeAuthStrategyError': + case 'InvalidCredentialsError': + case 'NotVerifiedError': + throw new ValidationError({ + code: data.login.errorCode, + message: data.login.message, + }) + } + return { + result: data.login.id, + } + } + + return login +} diff --git a/framework/vendure/api/utils/fetch-graphql-api.ts b/framework/vendure/api/utils/fetch-graphql-api.ts index f769123e4..64a02dde5 100644 --- a/framework/vendure/api/utils/fetch-graphql-api.ts +++ b/framework/vendure/api/utils/fetch-graphql-api.ts @@ -1,6 +1,6 @@ import { FetcherError } from '@commerce/utils/errors' import type { GraphQLFetcher } from '@commerce/api' -import { getConfig } from '..' +import { getCommerceApi } from '../' import fetch from './fetch' const fetchGraphqlApi: GraphQLFetcher = async ( @@ -8,12 +8,11 @@ const fetchGraphqlApi: GraphQLFetcher = async ( { variables, preview } = {}, fetchOptions ) => { - const config = getConfig() + const config = getCommerceApi().getConfig() const res = await fetch(config.commerceUrl, { ...fetchOptions, method: 'POST', headers: { - Authorization: `Bearer ${config.apiToken}`, ...fetchOptions?.headers, 'Content-Type': 'application/json', }, diff --git a/framework/vendure/api/wishlist/index.tsx b/framework/vendure/api/wishlist/index.tsx deleted file mode 100644 index a72856673..000000000 --- a/framework/vendure/api/wishlist/index.tsx +++ /dev/null @@ -1,2 +0,0 @@ -export type WishlistItem = { product: any; id: number } -export default function () {} diff --git a/framework/vendure/auth/index.ts b/framework/vendure/auth/index.ts new file mode 100644 index 000000000..36e757a89 --- /dev/null +++ b/framework/vendure/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/vendure/auth/use-login.tsx b/framework/vendure/auth/use-login.tsx index f0fc85cbc..f10e38d0f 100644 --- a/framework/vendure/auth/use-login.tsx +++ b/framework/vendure/auth/use-login.tsx @@ -1,14 +1,15 @@ import { useCallback } from 'react' import { MutationHook } from '@commerce/utils/types' import useLogin, { UseLogin } from '@commerce/auth/use-login' +import { LoginHook } from '../types/login' import { CommerceError, ValidationError } from '@commerce/utils/errors' import useCustomer from '../customer/use-customer' import { LoginMutation, LoginMutationVariables } from '../schema' -import { loginMutation } from '../lib/mutations/log-in-mutation' +import { loginMutation } from '../utils/mutations/log-in-mutation' export default useLogin as UseLogin -export const handler: MutationHook = { +export const handler: MutationHook = { fetchOptions: { query: loginMutation, }, diff --git a/framework/vendure/auth/use-logout.tsx b/framework/vendure/auth/use-logout.tsx index 93ba665b8..29bf5cb0d 100644 --- a/framework/vendure/auth/use-logout.tsx +++ b/framework/vendure/auth/use-logout.tsx @@ -3,11 +3,12 @@ import { MutationHook } from '@commerce/utils/types' import useLogout, { UseLogout } from '@commerce/auth/use-logout' import useCustomer from '../customer/use-customer' import { LogoutMutation } from '../schema' -import { logoutMutation } from '../lib/mutations/log-out-mutation' +import { logoutMutation } from '../utils/mutations/log-out-mutation' +import { LogoutHook } from '../types/logout' export default useLogout as UseLogout -export const handler: MutationHook = { +export const handler: MutationHook = { fetchOptions: { query: logoutMutation, }, diff --git a/framework/vendure/auth/use-signup.tsx b/framework/vendure/auth/use-signup.tsx index 816b95738..864b1a18a 100644 --- a/framework/vendure/auth/use-signup.tsx +++ b/framework/vendure/auth/use-signup.tsx @@ -8,7 +8,8 @@ import { SignupMutation, SignupMutationVariables, } from '../schema' -import { signupMutation } from '../lib/mutations/sign-up-mutation' +import { signupMutation } from '../utils/mutations/sign-up-mutation' +import { SignupHook } from '../types/signup' export default useSignup as UseSignup @@ -19,7 +20,7 @@ export type SignupInput = { password: string } -export const handler: MutationHook = { +export const handler: MutationHook = { fetchOptions: { query: signupMutation, }, diff --git a/framework/vendure/cart/index.ts b/framework/vendure/cart/index.ts index 43c6db2b7..3b8ba990e 100644 --- a/framework/vendure/cart/index.ts +++ b/framework/vendure/cart/index.ts @@ -1,5 +1,4 @@ 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' +export { default as useUpdateItem } from './use-update-item' diff --git a/framework/vendure/cart/use-add-item.tsx b/framework/vendure/cart/use-add-item.tsx index 42c5e5a63..88bff40e4 100644 --- a/framework/vendure/cart/use-add-item.tsx +++ b/framework/vendure/cart/use-add-item.tsx @@ -1,16 +1,16 @@ -import { Cart, CartItemBody } from '@commerce/types' import useAddItem, { UseAddItem } from '@commerce/cart/use-add-item' import { CommerceError } from '@commerce/utils/errors' import { MutationHook } from '@commerce/utils/types' import { useCallback } from 'react' import useCart from './use-cart' import { AddItemToOrderMutation } from '../schema' -import { normalizeCart } from '../lib/normalize' -import { addItemToOrderMutation } from '../lib/mutations/add-item-to-order-mutation' +import { normalizeCart } from '../utils/normalize' +import { addItemToOrderMutation } from '../utils/mutations/add-item-to-order-mutation' +import { AddItemHook } from '../types/cart' export default useAddItem as UseAddItem -export const handler: MutationHook = { +export const handler: MutationHook = { fetchOptions: { query: addItemToOrderMutation, }, diff --git a/framework/vendure/cart/use-cart-actions.tsx b/framework/vendure/cart/use-cart-actions.tsx deleted file mode 100644 index abb4a998e..000000000 --- a/framework/vendure/cart/use-cart-actions.tsx +++ /dev/null @@ -1,13 +0,0 @@ -import useAddItem from './use-add-item' -import useRemoveItem from './use-remove-item' -import useUpdateItem from './use-update-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 useCartActions() { - const addItem = useAddItem() - const updateItem = useUpdateItem() - const removeItem = useRemoveItem() - - return { addItem, updateItem, removeItem } -} diff --git a/framework/vendure/cart/use-cart.tsx b/framework/vendure/cart/use-cart.tsx index ee9975f87..400df0c8c 100644 --- a/framework/vendure/cart/use-cart.tsx +++ b/framework/vendure/cart/use-cart.tsx @@ -1,10 +1,10 @@ -import { Cart } from '@commerce/types' import { SWRHook } from '@commerce/utils/types' -import useCart, { FetchCartInput, UseCart } from '@commerce/cart/use-cart' +import useCart, { UseCart } from '@commerce/cart/use-cart' import { ActiveOrderQuery, CartFragment } from '../schema' -import { normalizeCart } from '../lib/normalize' +import { normalizeCart } from '../utils/normalize' import { useMemo } from 'react' -import { getCartQuery } from '../lib/queries/get-cart-query' +import { getCartQuery } from '../utils/queries/get-cart-query' +import { GetCartHook } from '../types/cart' export type CartResult = { activeOrder?: CartFragment @@ -15,12 +15,7 @@ export type CartResult = { export default useCart as UseCart -export const handler: SWRHook< - Cart | null, - {}, - FetchCartInput, - { isEmpty?: boolean } -> = { +export const handler: SWRHook = { fetchOptions: { query: getCartQuery, }, diff --git a/framework/vendure/cart/use-remove-item.tsx b/framework/vendure/cart/use-remove-item.tsx index f23f04d00..39855e1ac 100644 --- a/framework/vendure/cart/use-remove-item.tsx +++ b/framework/vendure/cart/use-remove-item.tsx @@ -1,25 +1,31 @@ import { useCallback } from 'react' -import { HookFetcherContext, MutationHookContext } from '@commerce/utils/types' +import { + HookFetcherContext, + MutationHook, + MutationHookContext, + SWRHook, +} from '@commerce/utils/types' import useRemoveItem, { UseRemoveItem } from '@commerce/cart/use-remove-item' import { CommerceError } from '@commerce/utils/errors' +import { Cart } from '@commerce/types/cart' import useCart from './use-cart' import { RemoveOrderLineMutation, RemoveOrderLineMutationVariables, } from '../schema' -import { Cart, LineItem, RemoveCartItemBody } from '@commerce/types' -import { normalizeCart } from '../lib/normalize' -import { removeOrderLineMutation } from '../lib/mutations/remove-order-line-mutation' +import { normalizeCart } from '../utils/normalize' +import { RemoveItemHook } from '../types/cart' +import { removeOrderLineMutation } from '../utils/mutations/remove-order-line-mutation' export default useRemoveItem as UseRemoveItem -export const handler = { +export const handler: MutationHook = { fetchOptions: { query: removeOrderLineMutation, }, - async fetcher({ input, options, fetch }: HookFetcherContext) { + async fetcher({ input, options, fetch }) { const variables: RemoveOrderLineMutationVariables = { - orderLineId: input.id, + orderLineId: input.itemId, } const { removeOrderLine } = await fetch({ ...options, @@ -31,14 +37,12 @@ export const handler = { } throw new CommerceError(removeOrderLine) }, - useHook: ({ - fetch, - }: MutationHookContext) => (ctx = {}) => { + useHook: ({ fetch }) => () => { const { mutate } = useCart() return useCallback( async function removeItem(input) { - const data = await fetch({ input }) + const data = await fetch({ input: { itemId: input.id } }) await mutate(data, false) return data }, diff --git a/framework/vendure/cart/use-update-item.tsx b/framework/vendure/cart/use-update-item.tsx index 4e871514e..d04de944a 100644 --- a/framework/vendure/cart/use-update-item.tsx +++ b/framework/vendure/cart/use-update-item.tsx @@ -1,20 +1,24 @@ import { useCallback } from 'react' -import { HookFetcherContext, MutationHookContext } from '@commerce/utils/types' +import { + HookFetcherContext, + MutationHook, + MutationHookContext, +} from '@commerce/utils/types' import { CommerceError, ValidationError } from '@commerce/utils/errors' import useUpdateItem, { UseUpdateItem } from '@commerce/cart/use-update-item' -import { - Cart, - CartItemBody, - LineItem, - UpdateCartItemBody, -} from '@commerce/types' +import { CartItemBody, LineItem } from '@commerce/types/cart' import useCart from './use-cart' import { AdjustOrderLineMutation, AdjustOrderLineMutationVariables, } from '../schema' -import { normalizeCart } from '../lib/normalize' -import { adjustOrderLineMutation } from '../lib/mutations/adjust-order-line-mutation' +import { normalizeCart } from '../utils/normalize' +import { adjustOrderLineMutation } from '../utils/mutations/adjust-order-line-mutation' +import { UpdateItemHook } from '../types/cart' + +export type UpdateItemActionInput = T extends LineItem + ? Partial + : UpdateItemHook['actionInput'] export default useUpdateItem as UseUpdateItem @@ -22,7 +26,7 @@ export const handler = { fetchOptions: { query: adjustOrderLineMutation, }, - async fetcher(context: HookFetcherContext>) { + async fetcher(context: HookFetcherContext) { const { input, options, fetch } = context const variables: AdjustOrderLineMutationVariables = { quantity: input.item.quantity || 1, @@ -38,9 +42,7 @@ export const handler = { } throw new CommerceError(adjustOrderLine) }, - useHook: ({ - fetch, - }: MutationHookContext>) => ( + useHook: ({ fetch }: MutationHookContext) => ( ctx: { item?: LineItem wait?: number @@ -50,7 +52,7 @@ export const handler = { const { mutate } = useCart() return useCallback( - async function addItem(input: Partial) { + async function addItem(input: UpdateItemActionInput) { const itemId = item?.id const productId = input.productId ?? item?.productId const variantId = input.productId ?? item?.variantId diff --git a/framework/vendure/common/get-all-pages.ts b/framework/vendure/common/get-all-pages.ts deleted file mode 100644 index 1200b02b1..000000000 --- a/framework/vendure/common/get-all-pages.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { getConfig, VendureConfig } from '../api' - -export type Page = any - -export type GetAllPagesResult< - T extends { pages: any[] } = { pages: Page[] } -> = T - -async function getAllPages(opts?: { - config?: VendureConfig - preview?: boolean -}): Promise - -async function getAllPages(opts: { - url: string - config?: VendureConfig - preview?: boolean -}): Promise> - -async function getAllPages({ - config, - preview, -}: { - url?: string - config?: VendureConfig - preview?: boolean -} = {}): Promise { - config = getConfig(config) - - return { - pages: [], - } -} - -export default getAllPages diff --git a/framework/vendure/common/get-page.ts b/framework/vendure/common/get-page.ts deleted file mode 100644 index 48a183630..000000000 --- a/framework/vendure/common/get-page.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { VendureConfig, getConfig } from '../api' - -export type Page = any - -export type GetPageResult = T - -export type PageVariables = { - id: number -} - -async function getPage(opts: { - url?: string - variables: PageVariables - config?: VendureConfig - preview?: boolean -}): Promise - -async function getPage(opts: { - url: string - variables: V - config?: VendureConfig - preview?: boolean -}): Promise> - -async function getPage({ - url, - variables, - config, - preview, -}: { - url?: string - variables: PageVariables - config?: VendureConfig - preview?: boolean -}): Promise { - config = getConfig(config) - return {} -} - -export default getPage diff --git a/framework/vendure/common/get-site-info.ts b/framework/vendure/common/get-site-info.ts deleted file mode 100644 index 99836c28b..000000000 --- a/framework/vendure/common/get-site-info.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { getConfig, VendureConfig } from '../api' -import { GetCollectionsQuery } from '../schema' -import { arrayToTree } from '../lib/array-to-tree' -import { getCollectionsQuery } from '../lib/queries/get-collections-query' -import { Category } from '@commerce/types' - -export type GetSiteInfoResult< - T extends { categories: any[]; brands: any[] } = { - categories: Category[] - brands: any[] - } -> = T - -async function getSiteInfo({ - query = getCollectionsQuery, - variables, - config, -}: { - query?: string - variables?: any - config?: VendureConfig - preview?: boolean -} = {}): Promise { - config = getConfig(config) - // RecursivePartial forces the method to check for every prop in the data, which is - // required in case there's a custom `query` - const { data } = await config.fetch(query, { variables }) - const collections = data.collections?.items.map((i) => ({ - ...i, - entityId: i.id, - path: i.slug, - productCount: i.productVariants.totalItems, - })) - const categories = arrayToTree(collections).children - const brands = [] as any[] - - return { - categories: categories ?? [], - brands, - } -} - -export default getSiteInfo diff --git a/framework/vendure/customer/get-customer-wishlist.ts b/framework/vendure/customer/get-customer-wishlist.ts deleted file mode 100644 index 81ec96956..000000000 --- a/framework/vendure/customer/get-customer-wishlist.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { getConfig, VendureConfig } from '../api' - -async function getCustomerWishlist({ - config, - variables, - includeProducts, -}: { - url?: string - variables: any - config?: VendureConfig - includeProducts?: boolean -}): Promise { - // Not implemented as Vendure does not ship with wishlist functionality at present - config = getConfig(config) - return { wishlist: {} } -} - -export default getCustomerWishlist diff --git a/framework/vendure/customer/use-customer.tsx b/framework/vendure/customer/use-customer.tsx index 4de821253..1d5a53d48 100644 --- a/framework/vendure/customer/use-customer.tsx +++ b/framework/vendure/customer/use-customer.tsx @@ -1,12 +1,12 @@ import { SWRHook } from '@commerce/utils/types' import useCustomer, { UseCustomer } from '@commerce/customer/use-customer' -import { Customer } from '@commerce/types' import { ActiveCustomerQuery } from '../schema' -import { activeCustomerQuery } from '../lib/queries/active-customer-query' +import { activeCustomerQuery } from '../utils/queries/active-customer-query' +import { CustomerHook } from '../types/customer' export default useCustomer as UseCustomer -export const handler: SWRHook = { +export const handler: SWRHook = { fetchOptions: { query: activeCustomerQuery, }, diff --git a/framework/vendure/product/get-all-product-paths.ts b/framework/vendure/product/get-all-product-paths.ts deleted file mode 100644 index dfbaff1b8..000000000 --- a/framework/vendure/product/get-all-product-paths.ts +++ /dev/null @@ -1,48 +0,0 @@ -import type { - GetAllProductPathsQuery, - GetAllProductPathsQueryVariables, -} from '../schema' -import { getConfig, VendureConfig } from '../api' -import { getAllProductPathsQuery } from '../lib/queries/get-all-product-paths-query' - -export type GetAllProductPathsResult = { - products: Array<{ node: { path: string } }> -} - -async function getAllProductPaths(opts?: { - variables?: GetAllProductPathsQueryVariables - config?: VendureConfig -}): Promise - -async function getAllProductPaths< - T extends { products: any[] }, - V = any ->(opts: { - query: string - variables?: V - config?: VendureConfig -}): Promise - -async function getAllProductPaths({ - query = getAllProductPathsQuery, - variables, - config, -}: { - query?: string - variables?: GetAllProductPathsQueryVariables - config?: VendureConfig -} = {}): Promise { - config = getConfig(config) - // RecursivePartial forces the method to check for every prop in the data, which is - // required in case there's a custom `query` - const { data } = await config.fetch(query, { - variables, - }) - const products = data.products.items - - return { - products: products.map((p) => ({ node: { path: `/${p.slug}` } })), - } -} - -export default getAllProductPaths diff --git a/framework/vendure/product/get-all-products.ts b/framework/vendure/product/get-all-products.ts deleted file mode 100644 index b292e0246..000000000 --- a/framework/vendure/product/get-all-products.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { Product } from '@commerce/types' -import { getConfig, VendureConfig } from '../api' -import { GetAllProductsQuery } from '../schema' -import { normalizeSearchResult } from '../lib/normalize' -import { getAllProductsQuery } from '../lib/queries/get-all-products-query' - -export type ProductVariables = { first?: number } - -async function getAllProducts(opts?: { - variables?: ProductVariables - config?: VendureConfig - preview?: boolean -}): Promise<{ products: Product[] }> - -async function getAllProducts({ - query = getAllProductsQuery, - variables: { ...vars } = {}, - config, -}: { - query?: string - variables?: ProductVariables - config?: VendureConfig - preview?: boolean -} = {}): Promise<{ products: Product[] | any[] }> { - config = getConfig(config) - const variables = { - input: { - take: vars.first, - groupByProduct: true, - }, - } - const { data } = await config.fetch(query, { variables }) - - return { - products: data.search.items.map((item) => normalizeSearchResult(item)), - } -} - -export default getAllProducts diff --git a/framework/vendure/product/get-product.ts b/framework/vendure/product/get-product.ts deleted file mode 100644 index 4427707bd..000000000 --- a/framework/vendure/product/get-product.ts +++ /dev/null @@ -1,64 +0,0 @@ -import { Product } from '@commerce/types' -import { getConfig, VendureConfig } from '../api' -import { GetProductQuery } from '../schema' -import { getProductQuery } from '../lib/queries/get-product-query' - -async function getProduct({ - query = getProductQuery, - variables, - config, -}: { - query?: string - variables: { slug: string } - config?: VendureConfig - preview?: boolean -}): Promise { - config = getConfig(config) - - const locale = config.locale - const { data } = await config.fetch(query, { variables }) - const product = data.product - - if (product) { - const getOptionGroupName = (id: string): string => { - return product.optionGroups.find((og) => og.id === id)!.name - } - return { - product: { - id: product.id, - name: product.name, - description: product.description, - slug: product.slug, - images: product.assets.map((a) => ({ - url: a.preview, - alt: a.name, - })), - variants: product.variants.map((v) => ({ - id: v.id, - options: v.options.map((o) => ({ - // This __typename property is required in order for the correct - // variant selection to work, see `components/product/helpers.ts` - // `getVariant()` function. - __typename: 'MultipleChoiceOption', - id: o.id, - displayName: getOptionGroupName(o.groupId), - values: [{ label: o.name }], - })), - })), - price: { - value: product.variants[0].priceWithTax / 100, - currencyCode: product.variants[0].currencyCode, - }, - options: product.optionGroups.map((og) => ({ - id: og.id, - displayName: og.name, - values: og.options.map((o) => ({ label: o.name })), - })), - } as Product, - } - } - - return {} -} - -export default getProduct diff --git a/framework/vendure/product/index.ts b/framework/vendure/product/index.ts index b290c189f..426a3edcd 100644 --- a/framework/vendure/product/index.ts +++ b/framework/vendure/product/index.ts @@ -1,4 +1,2 @@ export { default as usePrice } from './use-price' export { default as useSearch } from './use-search' -export { default as getProduct } from './get-product' -export { default as getAllProducts } from './get-all-products' diff --git a/framework/vendure/product/use-search.tsx b/framework/vendure/product/use-search.tsx index 00d9db36c..e34db2ac2 100644 --- a/framework/vendure/product/use-search.tsx +++ b/framework/vendure/product/use-search.tsx @@ -1,9 +1,10 @@ import { SWRHook } from '@commerce/utils/types' import useSearch, { UseSearch } from '@commerce/product/use-search' -import { Product } from '@commerce/types' +import { Product } from '@commerce/types/product' import { SearchQuery, SearchQueryVariables } from '../schema' -import { normalizeSearchResult } from '../lib/normalize' -import { searchQuery } from '../lib/queries/search-query' +import { normalizeSearchResult } from '../utils/normalize' +import { searchQuery } from '../utils/queries/search-query' +import { SearchProductsHook } from '../types/product' export default useSearch as UseSearch @@ -19,11 +20,7 @@ export type SearchProductsData = { found: boolean } -export const handler: SWRHook< - SearchProductsData, - SearchProductsInput, - SearchProductsInput -> = { +export const handler: SWRHook = { fetchOptions: { query: searchQuery, }, @@ -33,7 +30,7 @@ export const handler: SWRHook< const variables: SearchQueryVariables = { input: { term: input.search, - collectionId: input.categoryId, + collectionId: input.categoryId?.toString(), groupByProduct: true, // TODO: what is the "sort" value? }, diff --git a/framework/vendure/schema.d.ts b/framework/vendure/schema.d.ts index 78e821257..9d6b53c52 100644 --- a/framework/vendure/schema.d.ts +++ b/framework/vendure/schema.d.ts @@ -437,6 +437,13 @@ export type ProductVariantList = PaginatedList & { totalItems: Scalars['Int'] } +export type ProductVariantListOptions = { + skip?: Maybe + take?: Maybe + sort?: Maybe + filter?: Maybe +} + export enum GlobalFlag { True = 'TRUE', False = 'FALSE', @@ -463,6 +470,7 @@ export enum DeletionResult { * @docsCategory common */ export enum Permission { + Placeholder = 'Placeholder', /** Authenticated means simply that the user is logged in */ Authenticated = 'Authenticated', /** SuperAdmin has unrestricted access to all operations */ @@ -471,22 +479,24 @@ export enum Permission { Owner = 'Owner', /** Public means any unauthenticated user may perform the operation */ Public = 'Public', - /** Grants permission to create Catalog */ + /** Grants permission to update GlobalSettings */ + UpdateGlobalSettings = 'UpdateGlobalSettings', + /** Grants permission to create Products, Facets, Assets, Collections */ CreateCatalog = 'CreateCatalog', - /** Grants permission to read Catalog */ + /** Grants permission to read Products, Facets, Assets, Collections */ ReadCatalog = 'ReadCatalog', - /** Grants permission to update Catalog */ + /** Grants permission to update Products, Facets, Assets, Collections */ UpdateCatalog = 'UpdateCatalog', - /** Grants permission to delete Catalog */ + /** Grants permission to delete Products, Facets, Assets, Collections */ DeleteCatalog = 'DeleteCatalog', - /** Grants permission to create Customer */ - CreateCustomer = 'CreateCustomer', - /** Grants permission to read Customer */ - ReadCustomer = 'ReadCustomer', - /** Grants permission to update Customer */ - UpdateCustomer = 'UpdateCustomer', - /** Grants permission to delete Customer */ - DeleteCustomer = 'DeleteCustomer', + /** Grants permission to create PaymentMethods, ShippingMethods, TaxCategories, TaxRates, Zones, Countries, System & GlobalSettings */ + CreateSettings = 'CreateSettings', + /** Grants permission to read PaymentMethods, ShippingMethods, TaxCategories, TaxRates, Zones, Countries, System & GlobalSettings */ + ReadSettings = 'ReadSettings', + /** Grants permission to update PaymentMethods, ShippingMethods, TaxCategories, TaxRates, Zones, Countries, System & GlobalSettings */ + UpdateSettings = 'UpdateSettings', + /** Grants permission to delete PaymentMethods, ShippingMethods, TaxCategories, TaxRates, Zones, Countries, System & GlobalSettings */ + DeleteSettings = 'DeleteSettings', /** Grants permission to create Administrator */ CreateAdministrator = 'CreateAdministrator', /** Grants permission to read Administrator */ @@ -495,6 +505,62 @@ export enum Permission { UpdateAdministrator = 'UpdateAdministrator', /** Grants permission to delete Administrator */ DeleteAdministrator = 'DeleteAdministrator', + /** Grants permission to create Asset */ + CreateAsset = 'CreateAsset', + /** Grants permission to read Asset */ + ReadAsset = 'ReadAsset', + /** Grants permission to update Asset */ + UpdateAsset = 'UpdateAsset', + /** Grants permission to delete Asset */ + DeleteAsset = 'DeleteAsset', + /** Grants permission to create Channel */ + CreateChannel = 'CreateChannel', + /** Grants permission to read Channel */ + ReadChannel = 'ReadChannel', + /** Grants permission to update Channel */ + UpdateChannel = 'UpdateChannel', + /** Grants permission to delete Channel */ + DeleteChannel = 'DeleteChannel', + /** Grants permission to create Collection */ + CreateCollection = 'CreateCollection', + /** Grants permission to read Collection */ + ReadCollection = 'ReadCollection', + /** Grants permission to update Collection */ + UpdateCollection = 'UpdateCollection', + /** Grants permission to delete Collection */ + DeleteCollection = 'DeleteCollection', + /** Grants permission to create Country */ + CreateCountry = 'CreateCountry', + /** Grants permission to read Country */ + ReadCountry = 'ReadCountry', + /** Grants permission to update Country */ + UpdateCountry = 'UpdateCountry', + /** Grants permission to delete Country */ + DeleteCountry = 'DeleteCountry', + /** Grants permission to create Customer */ + CreateCustomer = 'CreateCustomer', + /** Grants permission to read Customer */ + ReadCustomer = 'ReadCustomer', + /** Grants permission to update Customer */ + UpdateCustomer = 'UpdateCustomer', + /** Grants permission to delete Customer */ + DeleteCustomer = 'DeleteCustomer', + /** Grants permission to create CustomerGroup */ + CreateCustomerGroup = 'CreateCustomerGroup', + /** Grants permission to read CustomerGroup */ + ReadCustomerGroup = 'ReadCustomerGroup', + /** Grants permission to update CustomerGroup */ + UpdateCustomerGroup = 'UpdateCustomerGroup', + /** Grants permission to delete CustomerGroup */ + DeleteCustomerGroup = 'DeleteCustomerGroup', + /** Grants permission to create Facet */ + CreateFacet = 'CreateFacet', + /** Grants permission to read Facet */ + ReadFacet = 'ReadFacet', + /** Grants permission to update Facet */ + UpdateFacet = 'UpdateFacet', + /** Grants permission to delete Facet */ + DeleteFacet = 'DeleteFacet', /** Grants permission to create Order */ CreateOrder = 'CreateOrder', /** Grants permission to read Order */ @@ -503,6 +569,22 @@ export enum Permission { UpdateOrder = 'UpdateOrder', /** Grants permission to delete Order */ DeleteOrder = 'DeleteOrder', + /** Grants permission to create PaymentMethod */ + CreatePaymentMethod = 'CreatePaymentMethod', + /** Grants permission to read PaymentMethod */ + ReadPaymentMethod = 'ReadPaymentMethod', + /** Grants permission to update PaymentMethod */ + UpdatePaymentMethod = 'UpdatePaymentMethod', + /** Grants permission to delete PaymentMethod */ + DeletePaymentMethod = 'DeletePaymentMethod', + /** Grants permission to create Product */ + CreateProduct = 'CreateProduct', + /** Grants permission to read Product */ + ReadProduct = 'ReadProduct', + /** Grants permission to update Product */ + UpdateProduct = 'UpdateProduct', + /** Grants permission to delete Product */ + DeleteProduct = 'DeleteProduct', /** Grants permission to create Promotion */ CreatePromotion = 'CreatePromotion', /** Grants permission to read Promotion */ @@ -511,14 +593,54 @@ export enum Permission { UpdatePromotion = 'UpdatePromotion', /** Grants permission to delete Promotion */ DeletePromotion = 'DeletePromotion', - /** Grants permission to create Settings */ - CreateSettings = 'CreateSettings', - /** Grants permission to read Settings */ - ReadSettings = 'ReadSettings', - /** Grants permission to update Settings */ - UpdateSettings = 'UpdateSettings', - /** Grants permission to delete Settings */ - DeleteSettings = 'DeleteSettings', + /** Grants permission to create ShippingMethod */ + CreateShippingMethod = 'CreateShippingMethod', + /** Grants permission to read ShippingMethod */ + ReadShippingMethod = 'ReadShippingMethod', + /** Grants permission to update ShippingMethod */ + UpdateShippingMethod = 'UpdateShippingMethod', + /** Grants permission to delete ShippingMethod */ + DeleteShippingMethod = 'DeleteShippingMethod', + /** Grants permission to create Tag */ + CreateTag = 'CreateTag', + /** Grants permission to read Tag */ + ReadTag = 'ReadTag', + /** Grants permission to update Tag */ + UpdateTag = 'UpdateTag', + /** Grants permission to delete Tag */ + DeleteTag = 'DeleteTag', + /** Grants permission to create TaxCategory */ + CreateTaxCategory = 'CreateTaxCategory', + /** Grants permission to read TaxCategory */ + ReadTaxCategory = 'ReadTaxCategory', + /** Grants permission to update TaxCategory */ + UpdateTaxCategory = 'UpdateTaxCategory', + /** Grants permission to delete TaxCategory */ + DeleteTaxCategory = 'DeleteTaxCategory', + /** Grants permission to create TaxRate */ + CreateTaxRate = 'CreateTaxRate', + /** Grants permission to read TaxRate */ + ReadTaxRate = 'ReadTaxRate', + /** Grants permission to update TaxRate */ + UpdateTaxRate = 'UpdateTaxRate', + /** Grants permission to delete TaxRate */ + DeleteTaxRate = 'DeleteTaxRate', + /** Grants permission to create System */ + CreateSystem = 'CreateSystem', + /** Grants permission to read System */ + ReadSystem = 'ReadSystem', + /** Grants permission to update System */ + UpdateSystem = 'UpdateSystem', + /** Grants permission to delete System */ + DeleteSystem = 'DeleteSystem', + /** Grants permission to create Zone */ + CreateZone = 'CreateZone', + /** Grants permission to read Zone */ + ReadZone = 'ReadZone', + /** Grants permission to update Zone */ + UpdateZone = 'UpdateZone', + /** Grants permission to delete Zone */ + DeleteZone = 'DeleteZone', } export enum SortOrder { @@ -734,10 +856,24 @@ export type DateOperators = { between?: Maybe } +/** + * Used to construct boolean expressions for filtering search results + * by FacetValue ID. Examples: + * + * * ID=1 OR ID=2: `{ facetValueFilters: [{ or: [1,2] }] }` + * * ID=1 AND ID=2: `{ facetValueFilters: [{ and: 1 }, { and: 2 }] }` + * * ID=1 AND (ID=2 OR ID=3): `{ facetValueFilters: [{ and: 1 }, { or: [2,3] }] }` + */ +export type FacetValueFilterInput = { + and?: Maybe + or?: Maybe> +} + export type SearchInput = { term?: Maybe facetValueIds?: Maybe> facetValueOperator?: Maybe + facetValueFilters?: Maybe> collectionId?: Maybe collectionSlug?: Maybe groupByProduct?: Maybe @@ -802,6 +938,7 @@ export type ShippingMethodQuote = { id: Scalars['ID'] price: Scalars['Int'] priceWithTax: Scalars['Int'] + code: Scalars['String'] name: Scalars['String'] description: Scalars['String'] /** Any optional metadata returned by the ShippingCalculator in the ShippingCalculationResult */ @@ -812,6 +949,8 @@ export type PaymentMethodQuote = { __typename?: 'PaymentMethodQuote' id: Scalars['ID'] code: Scalars['String'] + name: Scalars['String'] + description: Scalars['String'] isEligible: Scalars['Boolean'] eligibilityMessage?: Maybe } @@ -1307,6 +1446,13 @@ export type CustomerGroupCustomersArgs = { options?: Maybe } +export type CustomerListOptions = { + skip?: Maybe + take?: Maybe + sort?: Maybe + filter?: Maybe +} + export type Customer = Node & { __typename?: 'Customer' id: Scalars['ID'] @@ -1425,6 +1571,13 @@ export type HistoryEntryList = PaginatedList & { totalItems: Scalars['Int'] } +export type HistoryEntryListOptions = { + skip?: Maybe + take?: Maybe + sort?: Maybe + filter?: Maybe +} + /** * @description * Languages in the form of a ISO 639-1 language code with optional @@ -1777,12 +1930,7 @@ export type Order = Node & { * methods. */ surcharges: Array - /** - * Order-level adjustments to the order total, such as discounts from promotions - * @deprecated Use `discounts` instead - */ - adjustments: Array - discounts: Array + discounts: Array /** An array of all coupon codes applied to the Order */ couponCodes: Array /** Promotions applied to the order. Only gets populated after the payment process has completed. */ @@ -1861,7 +2009,16 @@ export type ShippingLine = { priceWithTax: Scalars['Int'] discountedPrice: Scalars['Int'] discountedPriceWithTax: Scalars['Int'] - discounts: Array + discounts: Array +} + +export type Discount = { + __typename?: 'Discount' + adjustmentSource: Scalars['String'] + type: AdjustmentType + description: Scalars['String'] + amount: Scalars['Int'] + amountWithTax: Scalars['Int'] } export type OrderItem = Node & { @@ -1894,8 +2051,6 @@ export type OrderItem = Node & { /** The proratedUnitPrice including tax */ proratedUnitPriceWithTax: Scalars['Int'] unitTax: Scalars['Int'] - /** @deprecated `unitPrice` is now always without tax */ - unitPriceIncludesTax: Scalars['Boolean'] taxRate: Scalars['Float'] adjustments: Array taxLines: Array @@ -1939,8 +2094,6 @@ export type OrderLine = Node & { proratedUnitPriceWithTax: Scalars['Int'] quantity: Scalars['Int'] items: Array - /** @deprecated Use `linePriceWithTax` instead */ - totalPrice: Scalars['Int'] taxRate: Scalars['Float'] /** The total price of the line excluding tax and discounts. */ linePrice: Scalars['Int'] @@ -1960,9 +2113,7 @@ export type OrderLine = Node & { proratedLinePriceWithTax: Scalars['Int'] /** The total tax on this line */ lineTax: Scalars['Int'] - /** @deprecated Use `discounts` instead */ - adjustments: Array - discounts: Array + discounts: Array taxLines: Array order: Order customFields?: Maybe @@ -2105,13 +2256,9 @@ export type SearchResult = { slug: Scalars['String'] productId: Scalars['ID'] productName: Scalars['String'] - /** @deprecated Use `productAsset.preview` instead */ - productPreview: Scalars['String'] productAsset?: Maybe productVariantId: Scalars['ID'] productVariantName: Scalars['String'] - /** @deprecated Use `productVariantAsset.preview` instead */ - productVariantPreview: Scalars['String'] productVariantAsset?: Maybe price: SearchResultPrice priceWithTax: SearchResultPrice @@ -2191,8 +2338,6 @@ export type ProductVariant = Node & { assets: Array price: Scalars['Int'] currencyCode: CurrencyCode - /** @deprecated price now always excludes tax */ - priceIncludesTax: Scalars['Boolean'] priceWithTax: Scalars['Int'] stockLevel: Scalars['String'] taxRateApplied: TaxRate @@ -2200,7 +2345,7 @@ export type ProductVariant = Node & { options: Array facetValues: Array translations: Array - customFields?: Maybe + customFields?: Maybe } export type ProductVariantTranslation = { @@ -2524,6 +2669,10 @@ export type NoActiveOrderError = ErrorResult & { message: Scalars['String'] } +export type AuthenticationInput = { + native?: Maybe +} + export type RegisterCustomerInput = { emailAddress: Scalars['String'] title?: Maybe @@ -2541,6 +2690,10 @@ export type UpdateCustomerInput = { customFields?: Maybe } +export type UpdateOrderInput = { + customFields?: Maybe +} + /** Passed as input to the `addPaymentToOrder` mutation. */ export type PaymentInput = { /** This field should correspond to the `code` property of a PaymentMethodHandler. */ @@ -2553,6 +2706,27 @@ export type PaymentInput = { metadata: Scalars['JSON'] } +export type CollectionListOptions = { + skip?: Maybe + take?: Maybe + sort?: Maybe + filter?: Maybe +} + +export type OrderListOptions = { + skip?: Maybe + take?: Maybe + sort?: Maybe + filter?: Maybe +} + +export type ProductListOptions = { + skip?: Maybe + take?: Maybe + sort?: Maybe + filter?: Maybe +} + export type UpdateOrderItemsResult = | Order | OrderModificationError @@ -2646,48 +2820,6 @@ export type AuthenticationResult = export type ActiveOrderResult = Order | NoActiveOrderError -export type CollectionListOptions = { - skip?: Maybe - take?: Maybe - sort?: Maybe - filter?: Maybe -} - -export type ProductListOptions = { - skip?: Maybe - take?: Maybe - sort?: Maybe - filter?: Maybe -} - -export type ProductVariantListOptions = { - skip?: Maybe - take?: Maybe - sort?: Maybe - filter?: Maybe -} - -export type CustomerListOptions = { - skip?: Maybe - take?: Maybe - sort?: Maybe - filter?: Maybe -} - -export type OrderListOptions = { - skip?: Maybe - take?: Maybe - sort?: Maybe - filter?: Maybe -} - -export type HistoryEntryListOptions = { - skip?: Maybe - take?: Maybe - sort?: Maybe - filter?: Maybe -} - export type CollectionFilterParameter = { createdAt?: Maybe updatedAt?: Maybe @@ -2734,9 +2866,9 @@ export type ProductVariantFilterParameter = { name?: Maybe price?: Maybe currencyCode?: Maybe - priceIncludesTax?: Maybe priceWithTax?: Maybe stockLevel?: Maybe + discountPrice?: Maybe } export type ProductVariantSortParameter = { @@ -2749,6 +2881,7 @@ export type ProductVariantSortParameter = { price?: Maybe priceWithTax?: Maybe stockLevel?: Maybe + discountPrice?: Maybe } export type CustomerFilterParameter = { @@ -2817,12 +2950,9 @@ export type HistoryEntrySortParameter = { updatedAt?: Maybe } -export type UpdateOrderInput = { - customFields?: Maybe -} - -export type AuthenticationInput = { - native?: Maybe +export type ProductVariantCustomFields = { + __typename?: 'ProductVariantCustomFields' + discountPrice?: Maybe } export type NativeAuthInput = { @@ -2846,14 +2976,19 @@ export type CartFragment = { __typename?: 'Order' } & Pick< lines: Array< { __typename?: 'OrderLine' } & Pick< OrderLine, - 'id' | 'quantity' | 'linePriceWithTax' | 'discountedLinePriceWithTax' + | 'id' + | 'quantity' + | 'linePriceWithTax' + | 'discountedLinePriceWithTax' + | 'unitPriceWithTax' + | 'discountedUnitPriceWithTax' > & { featuredAsset?: Maybe< { __typename?: 'Asset' } & Pick > discounts: Array< - { __typename?: 'Adjustment' } & Pick< - Adjustment, + { __typename?: 'Discount' } & Pick< + Discount, 'description' | 'amount' > > @@ -2886,51 +3021,6 @@ export type SearchResultFragment = { __typename?: 'SearchResult' } & Pick< | ({ __typename?: 'SinglePrice' } & Pick) } -export type LoginMutationVariables = Exact<{ - username: Scalars['String'] - password: Scalars['String'] -}> - -export type LoginMutation = { __typename?: 'Mutation' } & { - login: - | ({ __typename: 'CurrentUser' } & Pick) - | ({ __typename: 'InvalidCredentialsError' } & Pick< - InvalidCredentialsError, - 'errorCode' | 'message' - >) - | ({ __typename: 'NotVerifiedError' } & Pick< - NotVerifiedError, - 'errorCode' | 'message' - >) - | ({ __typename: 'NativeAuthStrategyError' } & Pick< - NativeAuthStrategyError, - 'errorCode' | 'message' - >) -} - -export type LogoutMutationVariables = Exact<{ [key: string]: never }> - -export type LogoutMutation = { __typename?: 'Mutation' } & { - logout: { __typename?: 'Success' } & Pick -} - -export type SignupMutationVariables = Exact<{ - input: RegisterCustomerInput -}> - -export type SignupMutation = { __typename?: 'Mutation' } & { - registerCustomerAccount: - | ({ __typename: 'Success' } & Pick) - | ({ __typename: 'MissingPasswordError' } & Pick< - MissingPasswordError, - 'errorCode' | 'message' - >) - | ({ __typename: 'NativeAuthStrategyError' } & Pick< - NativeAuthStrategyError, - 'errorCode' | 'message' - >) -} - export type AddItemToOrderMutationVariables = Exact<{ variantId: Scalars['ID'] quantity: Scalars['Int'] @@ -2957,25 +3047,6 @@ export type AddItemToOrderMutation = { __typename?: 'Mutation' } & { >) } -export type ActiveOrderQueryVariables = Exact<{ [key: string]: never }> - -export type ActiveOrderQuery = { __typename?: 'Query' } & { - activeOrder?: Maybe<{ __typename?: 'Order' } & CartFragment> -} - -export type RemoveOrderLineMutationVariables = Exact<{ - orderLineId: Scalars['ID'] -}> - -export type RemoveOrderLineMutation = { __typename?: 'Mutation' } & { - removeOrderLine: - | ({ __typename: 'Order' } & CartFragment) - | ({ __typename: 'OrderModificationError' } & Pick< - OrderModificationError, - 'errorCode' | 'message' - >) -} - export type AdjustOrderLineMutationVariables = Exact<{ orderLineId: Scalars['ID'] quantity: Scalars['Int'] @@ -3002,26 +3073,62 @@ export type AdjustOrderLineMutation = { __typename?: 'Mutation' } & { >) } -export type GetCollectionsQueryVariables = Exact<{ [key: string]: never }> +export type LoginMutationVariables = Exact<{ + username: Scalars['String'] + password: Scalars['String'] +}> -export type GetCollectionsQuery = { __typename?: 'Query' } & { - collections: { __typename?: 'CollectionList' } & { - items: Array< - { __typename?: 'Collection' } & Pick< - Collection, - 'id' | 'name' | 'description' | 'slug' - > & { - productVariants: { __typename?: 'ProductVariantList' } & Pick< - ProductVariantList, - 'totalItems' - > - parent?: Maybe<{ __typename?: 'Collection' } & Pick> - children?: Maybe< - Array<{ __typename?: 'Collection' } & Pick> - > - } - > - } +export type LoginMutation = { __typename?: 'Mutation' } & { + login: + | ({ __typename: 'CurrentUser' } & Pick) + | ({ __typename: 'InvalidCredentialsError' } & Pick< + InvalidCredentialsError, + 'errorCode' | 'message' + >) + | ({ __typename: 'NotVerifiedError' } & Pick< + NotVerifiedError, + 'errorCode' | 'message' + >) + | ({ __typename: 'NativeAuthStrategyError' } & Pick< + NativeAuthStrategyError, + 'errorCode' | 'message' + >) +} + +export type LogoutMutationVariables = Exact<{ [key: string]: never }> + +export type LogoutMutation = { __typename?: 'Mutation' } & { + logout: { __typename?: 'Success' } & Pick +} + +export type RemoveOrderLineMutationVariables = Exact<{ + orderLineId: Scalars['ID'] +}> + +export type RemoveOrderLineMutation = { __typename?: 'Mutation' } & { + removeOrderLine: + | ({ __typename: 'Order' } & CartFragment) + | ({ __typename: 'OrderModificationError' } & Pick< + OrderModificationError, + 'errorCode' | 'message' + >) +} + +export type SignupMutationVariables = Exact<{ + input: RegisterCustomerInput +}> + +export type SignupMutation = { __typename?: 'Mutation' } & { + registerCustomerAccount: + | ({ __typename: 'Success' } & Pick) + | ({ __typename: 'MissingPasswordError' } & Pick< + MissingPasswordError, + 'errorCode' | 'message' + >) + | ({ __typename: 'NativeAuthStrategyError' } & Pick< + NativeAuthStrategyError, + 'errorCode' | 'message' + >) } export type ActiveCustomerQueryVariables = Exact<{ [key: string]: never }> @@ -3055,6 +3162,34 @@ export type GetAllProductsQuery = { __typename?: 'Query' } & { } } +export type ActiveOrderQueryVariables = Exact<{ [key: string]: never }> + +export type ActiveOrderQuery = { __typename?: 'Query' } & { + activeOrder?: Maybe<{ __typename?: 'Order' } & CartFragment> +} + +export type GetCollectionsQueryVariables = Exact<{ [key: string]: never }> + +export type GetCollectionsQuery = { __typename?: 'Query' } & { + collections: { __typename?: 'CollectionList' } & { + items: Array< + { __typename?: 'Collection' } & Pick< + Collection, + 'id' | 'name' | 'description' | 'slug' + > & { + productVariants: { __typename?: 'ProductVariantList' } & Pick< + ProductVariantList, + 'totalItems' + > + parent?: Maybe<{ __typename?: 'Collection' } & Pick> + children?: Maybe< + Array<{ __typename?: 'Collection' } & Pick> + > + } + > + } +} + export type GetProductQueryVariables = Exact<{ slug: Scalars['String'] }> diff --git a/framework/vendure/schema.graphql b/framework/vendure/schema.graphql index 88812044e..326e2bca5 100644 --- a/framework/vendure/schema.graphql +++ b/framework/vendure/schema.graphql @@ -386,6 +386,13 @@ type ProductVariantList implements PaginatedList { totalItems: Int! } +input ProductVariantListOptions { + skip: Int + take: Int + sort: ProductVariantSortParameter + filter: ProductVariantFilterParameter +} + enum GlobalFlag { TRUE FALSE @@ -417,6 +424,8 @@ GraphQL resolvers via the {@link Allow} decorator. @docsCategory common """ enum Permission { + Placeholder + """ Authenticated means simply that the user is logged in """ @@ -438,44 +447,49 @@ enum Permission { Public """ - Grants permission to create Catalog + Grants permission to update GlobalSettings + """ + UpdateGlobalSettings + + """ + Grants permission to create Products, Facets, Assets, Collections """ CreateCatalog """ - Grants permission to read Catalog + Grants permission to read Products, Facets, Assets, Collections """ ReadCatalog """ - Grants permission to update Catalog + Grants permission to update Products, Facets, Assets, Collections """ UpdateCatalog """ - Grants permission to delete Catalog + Grants permission to delete Products, Facets, Assets, Collections """ DeleteCatalog """ - Grants permission to create Customer + Grants permission to create PaymentMethods, ShippingMethods, TaxCategories, TaxRates, Zones, Countries, System & GlobalSettings """ - CreateCustomer + CreateSettings """ - Grants permission to read Customer + Grants permission to read PaymentMethods, ShippingMethods, TaxCategories, TaxRates, Zones, Countries, System & GlobalSettings """ - ReadCustomer + ReadSettings """ - Grants permission to update Customer + Grants permission to update PaymentMethods, ShippingMethods, TaxCategories, TaxRates, Zones, Countries, System & GlobalSettings """ - UpdateCustomer + UpdateSettings """ - Grants permission to delete Customer + Grants permission to delete PaymentMethods, ShippingMethods, TaxCategories, TaxRates, Zones, Countries, System & GlobalSettings """ - DeleteCustomer + DeleteSettings """ Grants permission to create Administrator @@ -497,6 +511,146 @@ enum Permission { """ DeleteAdministrator + """ + Grants permission to create Asset + """ + CreateAsset + + """ + Grants permission to read Asset + """ + ReadAsset + + """ + Grants permission to update Asset + """ + UpdateAsset + + """ + Grants permission to delete Asset + """ + DeleteAsset + + """ + Grants permission to create Channel + """ + CreateChannel + + """ + Grants permission to read Channel + """ + ReadChannel + + """ + Grants permission to update Channel + """ + UpdateChannel + + """ + Grants permission to delete Channel + """ + DeleteChannel + + """ + Grants permission to create Collection + """ + CreateCollection + + """ + Grants permission to read Collection + """ + ReadCollection + + """ + Grants permission to update Collection + """ + UpdateCollection + + """ + Grants permission to delete Collection + """ + DeleteCollection + + """ + Grants permission to create Country + """ + CreateCountry + + """ + Grants permission to read Country + """ + ReadCountry + + """ + Grants permission to update Country + """ + UpdateCountry + + """ + Grants permission to delete Country + """ + DeleteCountry + + """ + Grants permission to create Customer + """ + CreateCustomer + + """ + Grants permission to read Customer + """ + ReadCustomer + + """ + Grants permission to update Customer + """ + UpdateCustomer + + """ + Grants permission to delete Customer + """ + DeleteCustomer + + """ + Grants permission to create CustomerGroup + """ + CreateCustomerGroup + + """ + Grants permission to read CustomerGroup + """ + ReadCustomerGroup + + """ + Grants permission to update CustomerGroup + """ + UpdateCustomerGroup + + """ + Grants permission to delete CustomerGroup + """ + DeleteCustomerGroup + + """ + Grants permission to create Facet + """ + CreateFacet + + """ + Grants permission to read Facet + """ + ReadFacet + + """ + Grants permission to update Facet + """ + UpdateFacet + + """ + Grants permission to delete Facet + """ + DeleteFacet + """ Grants permission to create Order """ @@ -517,6 +671,46 @@ enum Permission { """ DeleteOrder + """ + Grants permission to create PaymentMethod + """ + CreatePaymentMethod + + """ + Grants permission to read PaymentMethod + """ + ReadPaymentMethod + + """ + Grants permission to update PaymentMethod + """ + UpdatePaymentMethod + + """ + Grants permission to delete PaymentMethod + """ + DeletePaymentMethod + + """ + Grants permission to create Product + """ + CreateProduct + + """ + Grants permission to read Product + """ + ReadProduct + + """ + Grants permission to update Product + """ + UpdateProduct + + """ + Grants permission to delete Product + """ + DeleteProduct + """ Grants permission to create Promotion """ @@ -538,24 +732,124 @@ enum Permission { DeletePromotion """ - Grants permission to create Settings + Grants permission to create ShippingMethod """ - CreateSettings + CreateShippingMethod """ - Grants permission to read Settings + Grants permission to read ShippingMethod """ - ReadSettings + ReadShippingMethod """ - Grants permission to update Settings + Grants permission to update ShippingMethod """ - UpdateSettings + UpdateShippingMethod """ - Grants permission to delete Settings + Grants permission to delete ShippingMethod """ - DeleteSettings + DeleteShippingMethod + + """ + Grants permission to create Tag + """ + CreateTag + + """ + Grants permission to read Tag + """ + ReadTag + + """ + Grants permission to update Tag + """ + UpdateTag + + """ + Grants permission to delete Tag + """ + DeleteTag + + """ + Grants permission to create TaxCategory + """ + CreateTaxCategory + + """ + Grants permission to read TaxCategory + """ + ReadTaxCategory + + """ + Grants permission to update TaxCategory + """ + UpdateTaxCategory + + """ + Grants permission to delete TaxCategory + """ + DeleteTaxCategory + + """ + Grants permission to create TaxRate + """ + CreateTaxRate + + """ + Grants permission to read TaxRate + """ + ReadTaxRate + + """ + Grants permission to update TaxRate + """ + UpdateTaxRate + + """ + Grants permission to delete TaxRate + """ + DeleteTaxRate + + """ + Grants permission to create System + """ + CreateSystem + + """ + Grants permission to read System + """ + ReadSystem + + """ + Grants permission to update System + """ + UpdateSystem + + """ + Grants permission to delete System + """ + DeleteSystem + + """ + Grants permission to create Zone + """ + CreateZone + + """ + Grants permission to read Zone + """ + ReadZone + + """ + Grants permission to update Zone + """ + UpdateZone + + """ + Grants permission to delete Zone + """ + DeleteZone } enum SortOrder { @@ -789,10 +1083,24 @@ input DateOperators { between: DateRange } +""" +Used to construct boolean expressions for filtering search results +by FacetValue ID. Examples: + +* ID=1 OR ID=2: `{ facetValueFilters: [{ or: [1,2] }] }` +* ID=1 AND ID=2: `{ facetValueFilters: [{ and: 1 }, { and: 2 }] }` +* ID=1 AND (ID=2 OR ID=3): `{ facetValueFilters: [{ and: 1 }, { or: [2,3] }] }` +""" +input FacetValueFilterInput { + and: ID + or: [ID!] +} + input SearchInput { term: String facetValueIds: [ID!] facetValueOperator: LogicalOperator + facetValueFilters: [FacetValueFilterInput!] collectionId: ID collectionSlug: String groupByProduct: Boolean @@ -857,6 +1165,7 @@ type ShippingMethodQuote { id: ID! price: Int! priceWithTax: Int! + code: String! name: String! description: String! @@ -869,6 +1178,8 @@ type ShippingMethodQuote { type PaymentMethodQuote { id: ID! code: String! + name: String! + description: String! isEligible: Boolean! eligibilityMessage: String } @@ -1817,6 +2128,13 @@ type CustomerGroup implements Node { customers(options: CustomerListOptions): CustomerList! } +input CustomerListOptions { + skip: Int + take: Int + sort: CustomerSortParameter + filter: CustomerFilterParameter +} + type Customer implements Node { id: ID! createdAt: DateTime! @@ -1922,6 +2240,13 @@ type HistoryEntryList implements PaginatedList { totalItems: Int! } +input HistoryEntryListOptions { + skip: Int + take: Int + sort: HistoryEntrySortParameter + filter: HistoryEntryFilterParameter +} + """ @description Languages in the form of a ISO 639-1 language code with optional @@ -2751,12 +3076,7 @@ type Order implements Node { methods. """ surcharges: [Surcharge!]! - - """ - Order-level adjustments to the order total, such as discounts from promotions - """ - adjustments: [Adjustment!]! @deprecated(reason: "Use `discounts` instead") - discounts: [Adjustment!]! + discounts: [Discount!]! """ An array of all coupon codes applied to the Order @@ -2857,7 +3177,15 @@ type ShippingLine { priceWithTax: Int! discountedPrice: Int! discountedPriceWithTax: Int! - discounts: [Adjustment!]! + discounts: [Discount!]! +} + +type Discount { + adjustmentSource: String! + type: AdjustmentType! + description: String! + amount: Int! + amountWithTax: Int! } type OrderItem implements Node { @@ -2903,8 +3231,6 @@ type OrderItem implements Node { """ proratedUnitPriceWithTax: Int! unitTax: Int! - unitPriceIncludesTax: Boolean! - @deprecated(reason: "`unitPrice` is now always without tax") taxRate: Float! adjustments: [Adjustment!]! taxLines: [TaxLine!]! @@ -2967,7 +3293,6 @@ type OrderLine implements Node { proratedUnitPriceWithTax: Int! quantity: Int! items: [OrderItem!]! - totalPrice: Int! @deprecated(reason: "Use `linePriceWithTax` instead") taxRate: Float! """ @@ -3006,8 +3331,7 @@ type OrderLine implements Node { The total tax on this line """ lineTax: Int! - adjustments: [Adjustment!]! @deprecated(reason: "Use `discounts` instead") - discounts: [Adjustment!]! + discounts: [Discount!]! taxLines: [TaxLine!]! order: Order! customFields: JSON @@ -3137,13 +3461,9 @@ type SearchResult { slug: String! productId: ID! productName: String! - productPreview: String! - @deprecated(reason: "Use `productAsset.preview` instead") productAsset: SearchResultAsset productVariantId: ID! productVariantName: String! - productVariantPreview: String! - @deprecated(reason: "Use `productVariantAsset.preview` instead") productVariantAsset: SearchResultAsset price: SearchResultPrice! priceWithTax: SearchResultPrice! @@ -3229,8 +3549,6 @@ type ProductVariant implements Node { assets: [Asset!]! price: Int! currencyCode: CurrencyCode! - priceIncludesTax: Boolean! - @deprecated(reason: "price now always excludes tax") priceWithTax: Int! stockLevel: String! taxRateApplied: TaxRate! @@ -3238,7 +3556,7 @@ type ProductVariant implements Node { options: [ProductOption!]! facetValues: [FacetValue!]! translations: [ProductVariantTranslation!]! - customFields: JSON + customFields: ProductVariantCustomFields } type ProductVariantTranslation { @@ -3550,6 +3868,10 @@ type NoActiveOrderError implements ErrorResult { message: String! } +input AuthenticationInput { + native: NativeAuthInput +} + input RegisterCustomerInput { emailAddress: String! title: String @@ -3567,6 +3889,10 @@ input UpdateCustomerInput { customFields: JSON } +input UpdateOrderInput { + customFields: JSON +} + """ Passed as input to the `addPaymentToOrder` mutation. """ @@ -3584,6 +3910,27 @@ input PaymentInput { metadata: JSON! } +input CollectionListOptions { + skip: Int + take: Int + sort: CollectionSortParameter + filter: CollectionFilterParameter +} + +input OrderListOptions { + skip: Int + take: Int + sort: OrderSortParameter + filter: OrderFilterParameter +} + +input ProductListOptions { + skip: Int + take: Int + sort: ProductSortParameter + filter: ProductFilterParameter +} + union UpdateOrderItemsResult = Order | OrderModificationError @@ -3675,48 +4022,6 @@ union AuthenticationResult = union ActiveOrderResult = Order | NoActiveOrderError -input CollectionListOptions { - skip: Int - take: Int - sort: CollectionSortParameter - filter: CollectionFilterParameter -} - -input ProductListOptions { - skip: Int - take: Int - sort: ProductSortParameter - filter: ProductFilterParameter -} - -input ProductVariantListOptions { - skip: Int - take: Int - sort: ProductVariantSortParameter - filter: ProductVariantFilterParameter -} - -input CustomerListOptions { - skip: Int - take: Int - sort: CustomerSortParameter - filter: CustomerFilterParameter -} - -input OrderListOptions { - skip: Int - take: Int - sort: OrderSortParameter - filter: OrderFilterParameter -} - -input HistoryEntryListOptions { - skip: Int - take: Int - sort: HistoryEntrySortParameter - filter: HistoryEntryFilterParameter -} - input CollectionFilterParameter { createdAt: DateOperators updatedAt: DateOperators @@ -3763,9 +4068,9 @@ input ProductVariantFilterParameter { name: StringOperators price: NumberOperators currencyCode: StringOperators - priceIncludesTax: BooleanOperators priceWithTax: NumberOperators stockLevel: StringOperators + discountPrice: NumberOperators } input ProductVariantSortParameter { @@ -3778,6 +4083,7 @@ input ProductVariantSortParameter { price: SortOrder priceWithTax: SortOrder stockLevel: SortOrder + discountPrice: SortOrder } input CustomerFilterParameter { @@ -3846,12 +4152,8 @@ input HistoryEntrySortParameter { updatedAt: SortOrder } -input UpdateOrderInput { - customFields: JSON -} - -input AuthenticationInput { - native: NativeAuthInput +type ProductVariantCustomFields { + discountPrice: Int } input NativeAuthInput { diff --git a/framework/vendure/types.ts b/framework/vendure/types.ts deleted file mode 100644 index ed39b5493..000000000 --- a/framework/vendure/types.ts +++ /dev/null @@ -1,5 +0,0 @@ -import * as Core from '@commerce/types' - -export interface LineItem extends Core.LineItem { - options?: any[] -} diff --git a/framework/vendure/types/cart.ts b/framework/vendure/types/cart.ts new file mode 100644 index 000000000..6ed5c6c64 --- /dev/null +++ b/framework/vendure/types/cart.ts @@ -0,0 +1 @@ +export * from '@commerce/types/cart' diff --git a/framework/vendure/types/checkout.ts b/framework/vendure/types/checkout.ts new file mode 100644 index 000000000..4e2412ef6 --- /dev/null +++ b/framework/vendure/types/checkout.ts @@ -0,0 +1 @@ +export * from '@commerce/types/checkout' diff --git a/framework/vendure/types/common.ts b/framework/vendure/types/common.ts new file mode 100644 index 000000000..b52c33a4d --- /dev/null +++ b/framework/vendure/types/common.ts @@ -0,0 +1 @@ +export * from '@commerce/types/common' diff --git a/framework/vendure/types/customer.ts b/framework/vendure/types/customer.ts new file mode 100644 index 000000000..87c9afcc4 --- /dev/null +++ b/framework/vendure/types/customer.ts @@ -0,0 +1 @@ +export * from '@commerce/types/customer' diff --git a/framework/vendure/types/index.ts b/framework/vendure/types/index.ts new file mode 100644 index 000000000..7ab0b7f64 --- /dev/null +++ b/framework/vendure/types/index.ts @@ -0,0 +1,25 @@ +import * as Cart from './cart' +import * as Checkout from './checkout' +import * as Common from './common' +import * as Customer from './customer' +import * as Login from './login' +import * as Logout from './logout' +import * as Page from './page' +import * as Product from './product' +import * as Signup from './signup' +import * as Site from './site' +import * as Wishlist from './wishlist' + +export type { + Cart, + Checkout, + Common, + Customer, + Login, + Logout, + Page, + Product, + Signup, + Site, + Wishlist, +} diff --git a/framework/vendure/types/login.ts b/framework/vendure/types/login.ts new file mode 100644 index 000000000..16bae8f65 --- /dev/null +++ b/framework/vendure/types/login.ts @@ -0,0 +1,12 @@ +import * as Core from '@commerce/types/login' +import type { LoginMutationVariables } from '../schema' +import { LoginBody, LoginTypes } from '@commerce/types/login' + +export * from '@commerce/types/login' + +export type LoginHook = { + data: null + actionInput: LoginBody + fetcherInput: LoginBody + body: T['body'] +} diff --git a/framework/vendure/types/logout.ts b/framework/vendure/types/logout.ts new file mode 100644 index 000000000..9f0a466af --- /dev/null +++ b/framework/vendure/types/logout.ts @@ -0,0 +1 @@ +export * from '@commerce/types/logout' diff --git a/framework/vendure/types/page.ts b/framework/vendure/types/page.ts new file mode 100644 index 000000000..20ec8ea38 --- /dev/null +++ b/framework/vendure/types/page.ts @@ -0,0 +1 @@ +export * from '@commerce/types/page' diff --git a/framework/vendure/types/product.ts b/framework/vendure/types/product.ts new file mode 100644 index 000000000..c776d58fa --- /dev/null +++ b/framework/vendure/types/product.ts @@ -0,0 +1 @@ +export * from '@commerce/types/product' diff --git a/framework/vendure/types/signup.ts b/framework/vendure/types/signup.ts new file mode 100644 index 000000000..58543c6f6 --- /dev/null +++ b/framework/vendure/types/signup.ts @@ -0,0 +1 @@ +export * from '@commerce/types/signup' diff --git a/framework/vendure/types/site.ts b/framework/vendure/types/site.ts new file mode 100644 index 000000000..bfef69cf9 --- /dev/null +++ b/framework/vendure/types/site.ts @@ -0,0 +1 @@ +export * from '@commerce/types/site' diff --git a/framework/vendure/types/wishlist.ts b/framework/vendure/types/wishlist.ts new file mode 100644 index 000000000..8907fbf82 --- /dev/null +++ b/framework/vendure/types/wishlist.ts @@ -0,0 +1 @@ +export * from '@commerce/types/wishlist' diff --git a/framework/vendure/lib/array-to-tree.ts b/framework/vendure/utils/array-to-tree.ts similarity index 100% rename from framework/vendure/lib/array-to-tree.ts rename to framework/vendure/utils/array-to-tree.ts diff --git a/framework/vendure/lib/fragments/cart-fragment.ts b/framework/vendure/utils/fragments/cart-fragment.ts similarity index 91% rename from framework/vendure/lib/fragments/cart-fragment.ts rename to framework/vendure/utils/fragments/cart-fragment.ts index 36371e07c..54ac08912 100644 --- a/framework/vendure/lib/fragments/cart-fragment.ts +++ b/framework/vendure/utils/fragments/cart-fragment.ts @@ -17,6 +17,8 @@ export const cartFragment = /* GraphQL */ ` quantity linePriceWithTax discountedLinePriceWithTax + unitPriceWithTax + discountedUnitPriceWithTax featuredAsset { id preview diff --git a/framework/vendure/lib/fragments/search-result-fragment.ts b/framework/vendure/utils/fragments/search-result-fragment.ts similarity index 100% rename from framework/vendure/lib/fragments/search-result-fragment.ts rename to framework/vendure/utils/fragments/search-result-fragment.ts diff --git a/framework/vendure/lib/mutations/add-item-to-order-mutation.ts b/framework/vendure/utils/mutations/add-item-to-order-mutation.ts similarity index 100% rename from framework/vendure/lib/mutations/add-item-to-order-mutation.ts rename to framework/vendure/utils/mutations/add-item-to-order-mutation.ts diff --git a/framework/vendure/lib/mutations/adjust-order-line-mutation.ts b/framework/vendure/utils/mutations/adjust-order-line-mutation.ts similarity index 100% rename from framework/vendure/lib/mutations/adjust-order-line-mutation.ts rename to framework/vendure/utils/mutations/adjust-order-line-mutation.ts diff --git a/framework/vendure/lib/mutations/log-in-mutation.ts b/framework/vendure/utils/mutations/log-in-mutation.ts similarity index 100% rename from framework/vendure/lib/mutations/log-in-mutation.ts rename to framework/vendure/utils/mutations/log-in-mutation.ts diff --git a/framework/vendure/lib/mutations/log-out-mutation.ts b/framework/vendure/utils/mutations/log-out-mutation.ts similarity index 100% rename from framework/vendure/lib/mutations/log-out-mutation.ts rename to framework/vendure/utils/mutations/log-out-mutation.ts diff --git a/framework/vendure/lib/mutations/remove-order-line-mutation.ts b/framework/vendure/utils/mutations/remove-order-line-mutation.ts similarity index 100% rename from framework/vendure/lib/mutations/remove-order-line-mutation.ts rename to framework/vendure/utils/mutations/remove-order-line-mutation.ts diff --git a/framework/vendure/lib/mutations/sign-up-mutation.ts b/framework/vendure/utils/mutations/sign-up-mutation.ts similarity index 100% rename from framework/vendure/lib/mutations/sign-up-mutation.ts rename to framework/vendure/utils/mutations/sign-up-mutation.ts diff --git a/framework/vendure/lib/normalize.ts b/framework/vendure/utils/normalize.ts similarity index 89% rename from framework/vendure/lib/normalize.ts rename to framework/vendure/utils/normalize.ts index c64ff2136..09c1c6e42 100644 --- a/framework/vendure/lib/normalize.ts +++ b/framework/vendure/utils/normalize.ts @@ -1,4 +1,5 @@ -import { Cart, Product } from '@commerce/types' +import { Product } from '@commerce/types/product' +import { Cart } from '@commerce/types/cart' import { CartFragment, SearchResultFragment } from '../schema' export function normalizeSearchResult(item: SearchResultFragment): Product { @@ -43,8 +44,8 @@ export function normalizeCart(order: CartFragment): Cart { id: l.productVariant.id, name: l.productVariant.name, sku: l.productVariant.sku, - price: l.discountedLinePriceWithTax / 100, - listPrice: l.linePriceWithTax / 100, + price: l.discountedUnitPriceWithTax / 100, + listPrice: l.unitPriceWithTax / 100, image: { url: l.featuredAsset?.preview + '?preset=thumb' || '', }, diff --git a/framework/vendure/lib/queries/active-customer-query.ts b/framework/vendure/utils/queries/active-customer-query.ts similarity index 100% rename from framework/vendure/lib/queries/active-customer-query.ts rename to framework/vendure/utils/queries/active-customer-query.ts diff --git a/framework/vendure/lib/queries/get-all-product-paths-query.ts b/framework/vendure/utils/queries/get-all-product-paths-query.ts similarity index 100% rename from framework/vendure/lib/queries/get-all-product-paths-query.ts rename to framework/vendure/utils/queries/get-all-product-paths-query.ts diff --git a/framework/vendure/lib/queries/get-all-products-query.ts b/framework/vendure/utils/queries/get-all-products-query.ts similarity index 100% rename from framework/vendure/lib/queries/get-all-products-query.ts rename to framework/vendure/utils/queries/get-all-products-query.ts diff --git a/framework/vendure/lib/queries/get-cart-query.ts b/framework/vendure/utils/queries/get-cart-query.ts similarity index 100% rename from framework/vendure/lib/queries/get-cart-query.ts rename to framework/vendure/utils/queries/get-cart-query.ts diff --git a/framework/vendure/lib/queries/get-collections-query.ts b/framework/vendure/utils/queries/get-collections-query.ts similarity index 100% rename from framework/vendure/lib/queries/get-collections-query.ts rename to framework/vendure/utils/queries/get-collections-query.ts diff --git a/framework/vendure/lib/queries/get-product-query.ts b/framework/vendure/utils/queries/get-product-query.ts similarity index 100% rename from framework/vendure/lib/queries/get-product-query.ts rename to framework/vendure/utils/queries/get-product-query.ts diff --git a/framework/vendure/lib/queries/search-query.ts b/framework/vendure/utils/queries/search-query.ts similarity index 100% rename from framework/vendure/lib/queries/search-query.ts rename to framework/vendure/utils/queries/search-query.ts diff --git a/framework/vendure/wishlist/use-wishlist.tsx b/framework/vendure/wishlist/use-wishlist.tsx index d2ce9db5b..da941bf31 100644 --- a/framework/vendure/wishlist/use-wishlist.tsx +++ b/framework/vendure/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 +// Vendure doesn't have a built-in wishlist import { HookFetcher } from '@commerce/utils/types' import { Product } from '../schema' From 2d0c6e0c8a1f48d68a09a1c690df91f8f16fc66d Mon Sep 17 00:00:00 2001 From: cond0r Date: Mon, 7 Jun 2021 23:12:20 +0300 Subject: [PATCH 252/261] Add blocking fallback to pages (#357) * Update [...pages].tsx * Fix provider config overwrite * Shopify changes --- framework/commerce/config.js | 2 +- framework/shopify/api/operations/get-all-pages.ts | 4 +++- framework/shopify/api/operations/get-page.ts | 2 +- framework/shopify/product/use-search.tsx | 6 +++--- framework/shopify/utils/normalize.ts | 4 ++-- pages/[...pages].tsx | 12 ++++++++---- 6 files changed, 18 insertions(+), 12 deletions(-) diff --git a/framework/commerce/config.js b/framework/commerce/config.js index 48f0d526b..2658390ef 100644 --- a/framework/commerce/config.js +++ b/framework/commerce/config.js @@ -40,7 +40,7 @@ function withCommerceConfig(nextConfig = {}) { } const commerceNextConfig = require(path.join('../', name, 'next.config')) - const config = merge(commerceNextConfig, nextConfig) + const config = merge(nextConfig, commerceNextConfig) config.env = config.env || {} diff --git a/framework/shopify/api/operations/get-all-pages.ts b/framework/shopify/api/operations/get-all-pages.ts index ab0af9ff7..58bc6a94b 100644 --- a/framework/shopify/api/operations/get-all-pages.ts +++ b/framework/shopify/api/operations/get-all-pages.ts @@ -38,7 +38,9 @@ export default function getAllPagesOperation({ preview?: boolean query?: string } = {}): Promise { - const { fetch, locale, locales = ['en-US'] } = commerce.getConfig(config) + const { fetch, locale, locales = ['en-US', 'es'] } = commerce.getConfig( + config + ) const { data } = await fetch( query, diff --git a/framework/shopify/api/operations/get-page.ts b/framework/shopify/api/operations/get-page.ts index 67e135ebe..023ebeeb7 100644 --- a/framework/shopify/api/operations/get-page.ts +++ b/framework/shopify/api/operations/get-page.ts @@ -39,7 +39,7 @@ export default function getPageOperation({ config?: Partial preview?: boolean }): Promise { - const { fetch, locale = 'en-US' } = commerce.getConfig(config) + const { fetch, locale } = commerce.getConfig(config) const { data: { node: page }, diff --git a/framework/shopify/product/use-search.tsx b/framework/shopify/product/use-search.tsx index 9588b65a2..72dc8bb65 100644 --- a/framework/shopify/product/use-search.tsx +++ b/framework/shopify/product/use-search.tsx @@ -50,18 +50,18 @@ export const handler: SWRHook = { }) // filter on client when brandId & categoryId are set since is not available on collection product query products = brandId - ? data.node.products.edges.filter( + ? data.node?.products?.edges?.filter( ({ node: { vendor } }: ProductEdge) => vendor.replace(/\s+/g, '-').toLowerCase() === brandId ) - : data.node.products.edges + : data.node?.products?.edges } else { const data = await fetch({ query: options.query, method, variables, }) - products = data.products.edges + products = data.products?.edges } return { diff --git a/framework/shopify/utils/normalize.ts b/framework/shopify/utils/normalize.ts index e86872ef9..7a42ca085 100644 --- a/framework/shopify/utils/normalize.ts +++ b/framework/shopify/utils/normalize.ts @@ -174,14 +174,14 @@ function normalizeLineItem({ export const normalizePage = ( { title: name, handle, ...page }: ShopifyPage, - locale: string + locale: string = 'en-US' ): Page => ({ ...page, url: `/${locale}/${handle}`, name, }) -export const normalizePages = (edges: PageEdge[], locale: string): Page[] => +export const normalizePages = (edges: PageEdge[], locale?: string): Page[] => edges?.map((edge) => normalizePage(edge.node, locale)) export const normalizeCategory = ({ diff --git a/pages/[...pages].tsx b/pages/[...pages].tsx index c63963ef6..ab2f22d21 100644 --- a/pages/[...pages].tsx +++ b/pages/[...pages].tsx @@ -8,6 +8,7 @@ import { Text } from '@components/ui' import { Layout } from '@components/common' import getSlug from '@lib/get-slug' import { missingLocaleInPages } from '@lib/usage-warns' +import { useRouter } from 'next/router' export async function getStaticProps({ preview, @@ -28,6 +29,7 @@ export async function getStaticProps({ config, preview, })) + const page = data?.page if (!page) { @@ -58,16 +60,18 @@ export async function getStaticPaths({ locales }: GetStaticPathsContext) { return { paths, - // Fallback shouldn't be enabled here or otherwise this route - // will catch every page, even 404s, and we don't want that - fallback: false, + fallback: 'blocking', } } export default function Pages({ page, }: InferGetStaticPropsType) { - return ( + const router = useRouter() + + return router.isFallback ? ( +

    Loading...

    // TODO (BC) Add Skeleton Views + ) : (
    {page?.body && }
    From 685fb932db692e7a886a5da6cb919641e0df740a Mon Sep 17 00:00:00 2001 From: Bel Curcio Date: Wed, 9 Jun 2021 09:39:32 -0300 Subject: [PATCH 253/261] Adding revalidate to search - categories change too --- pages/search.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/pages/search.tsx b/pages/search.tsx index 55c57c593..c2121c0da 100644 --- a/pages/search.tsx +++ b/pages/search.tsx @@ -44,6 +44,7 @@ export async function getStaticProps({ categories, brands, }, + revalidate: 200, } } From 3b2bf654fef0d3f16c4bd2935e5054d26cdd320b Mon Sep 17 00:00:00 2001 From: Jakub Neander Date: Thu, 10 Jun 2021 08:46:28 +0200 Subject: [PATCH 254/261] Updated Saleor Provider (#356) * Initial work, copied from the Shopify provider * Added basis setup and type generation for the products queries * refactor: adjust the types * task: relax the Node.js constraint * fix: page/product properties * disable unknown fields * mention Saleor in the README * setup debugging for Next.js * Check nextjs-commerce bug if no images are added for a product * fix: client/server pecularities for env visibility Must prefix with `NEXT_PUBLIC_` so that the API URL is visible on the client * re: make search work with Saleor API (WIP) * task: update deps * task: move to Webpack 5.x * saleor: initial cart integration * update deps * saleor: shall the cart appear! * task: remove deprecated packages * saleor: adding/removing from the cart * saleor: preliminary signup process * saleor: fix the prices in the cart * update deps * update deps * Added the options for a variant to the product page * Mapped options to variants * Mapped options to variants * saleor: refine the auth process * saleor: remove unused code * saleor: handle customer find via refresh temporary solution * saleor: update deps * saleor: fix the session handling * saleor: fix the variants * saleor: simplify the naming for GraphQL statements * saleor: fix the type for collection * saleor: arrange the error codes * saleor: integrate collections * saleor: fix product sorting * saleor: set cookie location * saleor: update the schema * saleor: attach checkout to customer * saleor: fix the checkout flow * saleor: unify GraphQL naming approach * task: update deps * Add the env variables for saleor to the template * task: prettier * saleor: stub API for build/typescript compilation thanks @cond0r * task: temporarily disable for the `build` * saleor: refactor GraphQL queries * saleor: adjust the config * task: update dependencies * revert: Next.js to `10.0.9` * saleor: fix the checkout fetch query * task: update dependencies * saleor: adapt for displaying featured products * saleor: update the provider structure * saleor: make the home page representable * feature/cart: display the variant name (cond) Co-authored-by: Patryk Zawadzki Co-authored-by: royderks <10717410+royderks@users.noreply.github.com> --- .env.template | 3 + .prettierrc | 10 +- README.md | 3 +- assets/base.css | 1 - assets/components.css | 2 +- codegen.bigcommerce.json | 27 + codegen.json | 22 +- commerce.config.json | 3 +- components/cart/CartItem/CartItem.tsx | 8 +- components/common/Layout/Layout.tsx | 9 +- .../product/ProductCard/ProductCard.tsx | 4 +- .../product/ProductView/ProductView.tsx | 8 +- components/ui/Container/Container.tsx | 5 +- framework/commerce/config.js | 4 +- framework/commerce/new-provider.md | 59 +- framework/commerce/utils/define-property.ts | 22 +- framework/saleor/.env.template | 4 + framework/saleor/README.md | 19 + framework/saleor/api/cart.ts | 1 + framework/saleor/api/catalog/products.ts | 1 + framework/saleor/api/checkout.ts | 1 + framework/saleor/api/customers/index.ts | 1 + framework/saleor/api/customers/login.ts | 1 + framework/saleor/api/customers/logout.ts | 1 + framework/saleor/api/customers/signup.ts | 1 + framework/saleor/api/endpoints/cart.ts | 1 + .../saleor/api/endpoints/catalog/products.ts | 1 + .../saleor/api/endpoints/checkout/index.ts | 57 + framework/saleor/api/endpoints/customer.ts | 1 + framework/saleor/api/endpoints/login.ts | 1 + framework/saleor/api/endpoints/logout.ts | 1 + framework/saleor/api/endpoints/signup.ts | 1 + framework/saleor/api/endpoints/wishlist.ts | 1 + framework/saleor/api/index.ts | 49 + .../saleor/api/operations/get-all-pages.ts | 50 + .../api/operations/get-all-product-paths.ts | 46 + .../saleor/api/operations/get-all-products.ts | 67 + framework/saleor/api/operations/get-page.ts | 51 + .../saleor/api/operations/get-product.ts | 46 + .../saleor/api/operations/get-site-info.ts | 35 + framework/saleor/api/operations/index.ts | 7 + framework/saleor/api/operations/login.ts | 42 + .../saleor/api/utils/fetch-all-products.ts | 41 + .../saleor/api/utils/fetch-graphql-api.ts | 37 + framework/saleor/api/utils/fetch.ts | 2 + .../saleor/api/utils/is-allowed-method.ts | 22 + framework/saleor/api/wishlist.ts | 1 + framework/saleor/auth/use-login.tsx | 63 + framework/saleor/auth/use-logout.tsx | 41 + framework/saleor/auth/use-signup.tsx | 56 + framework/saleor/cart/index.ts | 4 + framework/saleor/cart/use-add-item.tsx | 54 + framework/saleor/cart/use-cart.tsx | 53 + framework/saleor/cart/use-remove-item.tsx | 39 + framework/saleor/cart/use-update-item.tsx | 99 + framework/saleor/commerce.config.json | 7 + framework/saleor/const.ts | 5 + framework/saleor/customer/index.ts | 1 + framework/saleor/customer/use-customer.tsx | 30 + framework/saleor/fetcher.ts | 20 + framework/saleor/index.tsx | 32 + framework/saleor/next.config.js | 8 + framework/saleor/product/use-price.tsx | 2 + framework/saleor/product/use-search.tsx | 74 + framework/saleor/provider.ts | 26 + framework/saleor/schema.d.ts | 11488 ++++++++++ framework/saleor/schema.graphql | 18973 ++++++++++++++++ framework/saleor/types.ts | 43 + framework/saleor/types/cart.ts | 32 + framework/saleor/utils/checkout-attach.ts | 12 + framework/saleor/utils/checkout-create.ts | 25 + framework/saleor/utils/checkout-to-cart.ts | 35 + framework/saleor/utils/customer-token.ts | 25 + .../utils/fragments/checkout-details.ts | 49 + framework/saleor/utils/fragments/index.ts | 2 + framework/saleor/utils/fragments/product.ts | 29 + framework/saleor/utils/get-categories.ts | 23 + framework/saleor/utils/get-checkout-id.ts | 9 + .../saleor/utils/get-search-variables.ts | 18 + framework/saleor/utils/get-sort-variables.ts | 30 + framework/saleor/utils/get-vendors.ts | 41 + .../saleor/utils/handle-fetch-response.ts | 27 + framework/saleor/utils/handle-login.ts | 35 + framework/saleor/utils/index.ts | 19 + .../saleor/utils/mutations/account-create.ts | 15 + .../saleor/utils/mutations/checkout-attach.ts | 12 + .../saleor/utils/mutations/checkout-create.ts | 17 + .../utils/mutations/checkout-line-add.ts | 17 + .../utils/mutations/checkout-line-remove.ts | 17 + .../utils/mutations/checkout-line-update.ts | 17 + framework/saleor/utils/mutations/index.ts | 8 + .../saleor/utils/mutations/session-create.ts | 14 + .../saleor/utils/mutations/session-destroy.ts | 10 + framework/saleor/utils/normalize.ts | 133 + .../saleor/utils/queries/checkout-one.ts | 12 + .../saleor/utils/queries/collection-many.ts | 13 + .../saleor/utils/queries/collection-one.ts | 13 + .../saleor/utils/queries/customer-current.ts | 11 + .../saleor/utils/queries/customer-one.ts | 7 + .../queries/get-all-product-vendors-query.ts | 16 + .../queries/get-all-products-paths-query.ts | 16 + framework/saleor/utils/queries/index.ts | 14 + framework/saleor/utils/queries/page-many.ts | 13 + framework/saleor/utils/queries/page-one.ts | 9 + .../saleor/utils/queries/product-many.ts | 15 + .../utils/queries/product-one-by-slug.ts | 43 + framework/saleor/utils/throw-user-errors.ts | 20 + framework/saleor/wishlist/use-add-item.tsx | 13 + framework/saleor/wishlist/use-remove-item.tsx | 17 + framework/saleor/wishlist/use-wishlist.tsx | 46 + next.config.js | 4 + package.json | 63 +- pages/index.tsx | 1 + tsconfig.json | 4 +- yarn.lock | 2934 ++- 115 files changed, 34182 insertions(+), 1671 deletions(-) create mode 100644 codegen.bigcommerce.json create mode 100644 framework/saleor/.env.template create mode 100644 framework/saleor/README.md create mode 100644 framework/saleor/api/cart.ts create mode 100644 framework/saleor/api/catalog/products.ts create mode 100644 framework/saleor/api/checkout.ts create mode 100644 framework/saleor/api/customers/index.ts create mode 100644 framework/saleor/api/customers/login.ts create mode 100644 framework/saleor/api/customers/logout.ts create mode 100644 framework/saleor/api/customers/signup.ts create mode 100644 framework/saleor/api/endpoints/cart.ts create mode 100644 framework/saleor/api/endpoints/catalog/products.ts create mode 100644 framework/saleor/api/endpoints/checkout/index.ts create mode 100644 framework/saleor/api/endpoints/customer.ts create mode 100644 framework/saleor/api/endpoints/login.ts create mode 100644 framework/saleor/api/endpoints/logout.ts create mode 100644 framework/saleor/api/endpoints/signup.ts create mode 100644 framework/saleor/api/endpoints/wishlist.ts create mode 100644 framework/saleor/api/index.ts create mode 100644 framework/saleor/api/operations/get-all-pages.ts create mode 100644 framework/saleor/api/operations/get-all-product-paths.ts create mode 100644 framework/saleor/api/operations/get-all-products.ts create mode 100644 framework/saleor/api/operations/get-page.ts create mode 100644 framework/saleor/api/operations/get-product.ts create mode 100644 framework/saleor/api/operations/get-site-info.ts create mode 100644 framework/saleor/api/operations/index.ts create mode 100644 framework/saleor/api/operations/login.ts create mode 100644 framework/saleor/api/utils/fetch-all-products.ts create mode 100644 framework/saleor/api/utils/fetch-graphql-api.ts create mode 100644 framework/saleor/api/utils/fetch.ts create mode 100644 framework/saleor/api/utils/is-allowed-method.ts create mode 100644 framework/saleor/api/wishlist.ts create mode 100644 framework/saleor/auth/use-login.tsx create mode 100644 framework/saleor/auth/use-logout.tsx create mode 100644 framework/saleor/auth/use-signup.tsx create mode 100644 framework/saleor/cart/index.ts create mode 100644 framework/saleor/cart/use-add-item.tsx create mode 100644 framework/saleor/cart/use-cart.tsx create mode 100644 framework/saleor/cart/use-remove-item.tsx create mode 100644 framework/saleor/cart/use-update-item.tsx create mode 100644 framework/saleor/commerce.config.json create mode 100644 framework/saleor/const.ts create mode 100644 framework/saleor/customer/index.ts create mode 100644 framework/saleor/customer/use-customer.tsx create mode 100644 framework/saleor/fetcher.ts create mode 100644 framework/saleor/index.tsx create mode 100644 framework/saleor/next.config.js create mode 100644 framework/saleor/product/use-price.tsx create mode 100644 framework/saleor/product/use-search.tsx create mode 100644 framework/saleor/provider.ts create mode 100644 framework/saleor/schema.d.ts create mode 100644 framework/saleor/schema.graphql create mode 100644 framework/saleor/types.ts create mode 100644 framework/saleor/types/cart.ts create mode 100644 framework/saleor/utils/checkout-attach.ts create mode 100644 framework/saleor/utils/checkout-create.ts create mode 100644 framework/saleor/utils/checkout-to-cart.ts create mode 100644 framework/saleor/utils/customer-token.ts create mode 100644 framework/saleor/utils/fragments/checkout-details.ts create mode 100644 framework/saleor/utils/fragments/index.ts create mode 100644 framework/saleor/utils/fragments/product.ts create mode 100644 framework/saleor/utils/get-categories.ts create mode 100644 framework/saleor/utils/get-checkout-id.ts create mode 100644 framework/saleor/utils/get-search-variables.ts create mode 100644 framework/saleor/utils/get-sort-variables.ts create mode 100644 framework/saleor/utils/get-vendors.ts create mode 100644 framework/saleor/utils/handle-fetch-response.ts create mode 100644 framework/saleor/utils/handle-login.ts create mode 100644 framework/saleor/utils/index.ts create mode 100644 framework/saleor/utils/mutations/account-create.ts create mode 100644 framework/saleor/utils/mutations/checkout-attach.ts create mode 100644 framework/saleor/utils/mutations/checkout-create.ts create mode 100644 framework/saleor/utils/mutations/checkout-line-add.ts create mode 100644 framework/saleor/utils/mutations/checkout-line-remove.ts create mode 100644 framework/saleor/utils/mutations/checkout-line-update.ts create mode 100644 framework/saleor/utils/mutations/index.ts create mode 100644 framework/saleor/utils/mutations/session-create.ts create mode 100644 framework/saleor/utils/mutations/session-destroy.ts create mode 100644 framework/saleor/utils/normalize.ts create mode 100644 framework/saleor/utils/queries/checkout-one.ts create mode 100644 framework/saleor/utils/queries/collection-many.ts create mode 100644 framework/saleor/utils/queries/collection-one.ts create mode 100644 framework/saleor/utils/queries/customer-current.ts create mode 100644 framework/saleor/utils/queries/customer-one.ts create mode 100644 framework/saleor/utils/queries/get-all-product-vendors-query.ts create mode 100644 framework/saleor/utils/queries/get-all-products-paths-query.ts create mode 100644 framework/saleor/utils/queries/index.ts create mode 100644 framework/saleor/utils/queries/page-many.ts create mode 100644 framework/saleor/utils/queries/page-one.ts create mode 100644 framework/saleor/utils/queries/product-many.ts create mode 100644 framework/saleor/utils/queries/product-one-by-slug.ts create mode 100644 framework/saleor/utils/throw-user-errors.ts create mode 100644 framework/saleor/wishlist/use-add-item.tsx create mode 100644 framework/saleor/wishlist/use-remove-item.tsx create mode 100644 framework/saleor/wishlist/use-wishlist.tsx diff --git a/.env.template b/.env.template index b68daaffe..c5543e4b1 100644 --- a/.env.template +++ b/.env.template @@ -13,3 +13,6 @@ NEXT_PUBLIC_SHOPIFY_STOREFRONT_ACCESS_TOKEN= NEXT_PUBLIC_SWELL_STORE_ID= NEXT_PUBLIC_SWELL_PUBLIC_KEY= + +NEXT_PUBLIC_SALEOR_API_URL= +NEXT_PUBLIC_SALEOR_CHANNEL= diff --git a/.prettierrc b/.prettierrc index e1076edfa..91990a859 100644 --- a/.prettierrc +++ b/.prettierrc @@ -2,5 +2,13 @@ "semi": false, "singleQuote": true, "tabWidth": 2, - "useTabs": false + "useTabs": false, + "overrides": [ + { + "files": ["framework/saleor/**/*"], + "options": { + "printWidth": 120 + } + } + ] } diff --git a/README.md b/README.md index 8f29734e5..225c4d535 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,7 @@ Demo live at: [demo.vercel.store](https://demo.vercel.store/) - Swell Demo: https://swell.vercel.store/ - BigCommerce Demo: https://bigcommerce.vercel.store/ - Vendure Demo: https://vendure.vercel.store +- Saleor Demo: https://saleor.vercel.store/ ## Features @@ -26,7 +27,7 @@ Demo live at: [demo.vercel.store](https://demo.vercel.store/) ## Integrations -Next.js Commerce integrates out-of-the-box with BigCommerce and Shopify. We plan to support all major ecommerce backends. +Next.js Commerce integrates out-of-the-box with BigCommerce, Shopify and Saleor. We plan to support all major ecommerce backends. ## Considerations diff --git a/assets/base.css b/assets/base.css index dfdaf1475..e63ea1aa4 100644 --- a/assets/base.css +++ b/assets/base.css @@ -127,4 +127,3 @@ a { opacity: 1; } } - diff --git a/assets/components.css b/assets/components.css index 8c4c5a357..ebebcc238 100644 --- a/assets/components.css +++ b/assets/components.css @@ -1,3 +1,3 @@ .fit { min-height: calc(100vh - 88px); -} \ No newline at end of file +} diff --git a/codegen.bigcommerce.json b/codegen.bigcommerce.json new file mode 100644 index 000000000..1f14e88ac --- /dev/null +++ b/codegen.bigcommerce.json @@ -0,0 +1,27 @@ +{ + "schema": { + "https://buybutton.store/graphql": { + "headers": { + "Authorization": "Bearer xzy" + } + } + }, + "documents": [ + { + "./framework/bigcommerce/api/**/*.ts": { + "noRequire": true + } + } + ], + "generates": { + "./framework/bigcommerce/schema.d.ts": { + "plugins": ["typescript", "typescript-operations"] + }, + "./framework/bigcommerce/schema.graphql": { + "plugins": ["schema-ast"] + } + }, + "hooks": { + "afterAllFileWrite": ["prettier --write"] + } +} diff --git a/codegen.json b/codegen.json index 1f14e88ac..d9a5c09ce 100644 --- a/codegen.json +++ b/codegen.json @@ -1,23 +1,29 @@ { "schema": { - "https://buybutton.store/graphql": { - "headers": { - "Authorization": "Bearer xzy" - } - } + "https://master.staging.saleor.cloud/graphql/": {} }, "documents": [ { - "./framework/bigcommerce/api/**/*.ts": { + "./framework/saleor/utils/queries/get-all-products-query.ts": { + "noRequire": true + } + }, + { + "./framework/saleor/utils/queries/get-all-products-paths-query.ts": { + "noRequire": true + } + }, + { + "./framework/saleor/utils/queries/get-products.ts": { "noRequire": true } } ], "generates": { - "./framework/bigcommerce/schema.d.ts": { + "./framework/saleor/schema.d.ts": { "plugins": ["typescript", "typescript-operations"] }, - "./framework/bigcommerce/schema.graphql": { + "./framework/saleor/schema.graphql": { "plugins": ["schema-ast"] } }, diff --git a/commerce.config.json b/commerce.config.json index a0e7afc5d..06b985504 100644 --- a/commerce.config.json +++ b/commerce.config.json @@ -1,5 +1,6 @@ { "features": { - "wishlist": true + "wishlist": false, + "customCheckout": false } } diff --git a/components/cart/CartItem/CartItem.tsx b/components/cart/CartItem/CartItem.tsx index bc614722f..d0f7b7dc3 100644 --- a/components/cart/CartItem/CartItem.tsx +++ b/components/cart/CartItem/CartItem.tsx @@ -108,10 +108,14 @@ const CartItem = ({
    closeSidebarIfPresent()} > - {item.name} +
    + {item.name} +
    + {item.variant ? {item.variant.name} : ""}
    {options && options.length > 0 ? ( diff --git a/components/common/Layout/Layout.tsx b/components/common/Layout/Layout.tsx index c5de5739a..c84c52693 100644 --- a/components/common/Layout/Layout.tsx +++ b/components/common/Layout/Layout.tsx @@ -49,13 +49,8 @@ const Layout: FC = ({ children, pageProps: { categories = [], ...pageProps }, }) => { - const { - displaySidebar, - displayModal, - closeSidebar, - closeModal, - modalView, - } = useUI() + const { displaySidebar, displayModal, closeSidebar, closeModal, modalView } = + useUI() const { acceptedCookies, onAcceptCookies } = useAcceptCookies() const { locale = 'en-US' } = useRouter() diff --git a/components/product/ProductCard/ProductCard.tsx b/components/product/ProductCard/ProductCard.tsx index c2e210367..69a6c4b66 100644 --- a/components/product/ProductCard/ProductCard.tsx +++ b/components/product/ProductCard/ProductCard.tsx @@ -10,7 +10,7 @@ interface Props { className?: string product: Product variant?: 'slim' | 'simple' - imgProps?: Omit + imgProps?: Omit } const placeholderImg = '/product-img-placeholder.svg' @@ -38,7 +38,7 @@ const ProductCard: FC = ({ alt={product.name || 'Product Image'} height={320} width={320} - layout="fixed" + layout="fixed" {...imgProps} /> )} diff --git a/components/product/ProductView/ProductView.tsx b/components/product/ProductView/ProductView.tsx index a9385b2f0..2a7fccb10 100644 --- a/components/product/ProductView/ProductView.tsx +++ b/components/product/ProductView/ProductView.tsx @@ -32,10 +32,11 @@ const ProductView: FC = ({ product }) => { useEffect(() => { // Selects the default option - product.variants[0].options?.forEach((v) => { + const options = product.variants[0].options || [] + options.forEach((v) => { setChoices((choices) => ({ ...choices, - [v.displayName.toLowerCase()]: v.values[0].label.toLowerCase(), + [v.displayName.toLowerCase()]: v.values[0]?.label.toLowerCase(), })) }) }, []) @@ -126,7 +127,8 @@ const ProductView: FC = ({ product }) => { setChoices((choices) => { return { ...choices, - [opt.displayName.toLowerCase()]: v.label.toLowerCase(), + [opt.displayName.toLowerCase()]: + v.label.toLowerCase(), } }) }} diff --git a/components/ui/Container/Container.tsx b/components/ui/Container/Container.tsx index 7b281a2e4..f88934122 100644 --- a/components/ui/Container/Container.tsx +++ b/components/ui/Container/Container.tsx @@ -13,9 +13,8 @@ const Container: FC = ({ children, className, el = 'div', clean }) => { 'mx-auto max-w-8xl px-6': !clean, }) - let Component: React.ComponentType< - React.HTMLAttributes - > = el as any + let Component: React.ComponentType> = + el as any return {children} } diff --git a/framework/commerce/config.js b/framework/commerce/config.js index 2658390ef..9e9799528 100644 --- a/framework/commerce/config.js +++ b/framework/commerce/config.js @@ -7,7 +7,7 @@ const fs = require('fs') const merge = require('deepmerge') const prettier = require('prettier') -const PROVIDERS = ['bigcommerce', 'shopify', 'swell', 'vendure'] +const PROVIDERS = ['bigcommerce', 'shopify', 'swell', 'vendure', 'saleor'] function getProviderName() { return ( @@ -18,6 +18,8 @@ function getProviderName() { ? 'shopify' : process.env.NEXT_PUBLIC_SWELL_STORE_ID ? 'swell' + : process.env.NEXT_PUBLIC_SALEOR_API_URL + ? 'saleor' : null) ) } diff --git a/framework/commerce/new-provider.md b/framework/commerce/new-provider.md index 511704af6..ac6692fbf 100644 --- a/framework/commerce/new-provider.md +++ b/framework/commerce/new-provider.md @@ -3,6 +3,7 @@ A commerce provider is a headless e-commerce platform that integrates with the [Commerce Framework](./README.md). Right now we have the following providers: - BigCommerce ([framework/bigcommerce](../bigcommerce)) +- Saleor ([framework/saleor](../saleor)) - Shopify ([framework/shopify](../shopify)) Adding a commerce provider means adding a new folder in `framework` with a folder structure like the next one: @@ -156,24 +157,26 @@ export const handler: SWRHook< const data = cartId ? await fetch(options) : null return data && normalizeCart(data) }, - useHook: ({ useData }) => (input) => { - const response = useData({ - swrOptions: { revalidateOnFocus: false, ...input?.swrOptions }, - }) + 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 + return useMemo( + () => + Object.create(response, { + isEmpty: { + get() { + return (response.data?.lineItems.length ?? 0) <= 0 + }, + enumerable: true, }, - enumerable: true, - }, - }), - [response] - ) - }, + }), + [response] + ) + }, } ``` @@ -217,18 +220,20 @@ export const handler: MutationHook = { return normalizeCart(data) }, - useHook: ({ fetch }) => () => { - const { mutate } = useCart() + useHook: + ({ fetch }) => + () => { + const { mutate } = useCart() - return useCallback( - async function addItem(input) { - const data = await fetch({ input }) - await mutate(data, false) - return data - }, - [fetch, mutate] - ) - }, + return useCallback( + async function addItem(input) { + const data = await fetch({ input }) + await mutate(data, false) + return data + }, + [fetch, mutate] + ) + }, } ``` diff --git a/framework/commerce/utils/define-property.ts b/framework/commerce/utils/define-property.ts index e89735226..875aaaa82 100644 --- a/framework/commerce/utils/define-property.ts +++ b/framework/commerce/utils/define-property.ts @@ -11,18 +11,16 @@ type InferValue = Desc extends { ? Record : never -type DefineProperty< - Prop extends PropertyKey, - Desc extends PropertyDescriptor -> = Desc extends { writable: any; set(val: any): any } - ? never - : Desc extends { writable: any; get(): any } - ? never - : Desc extends { writable: false } - ? Readonly> - : Desc extends { writable: true } - ? InferValue - : Readonly> +type DefineProperty = + Desc extends { writable: any; set(val: any): any } + ? never + : Desc extends { writable: any; get(): any } + ? never + : Desc extends { writable: false } + ? Readonly> + : Desc extends { writable: true } + ? InferValue + : Readonly> export default function defineProperty< Obj extends object, diff --git a/framework/saleor/.env.template b/framework/saleor/.env.template new file mode 100644 index 000000000..715fec861 --- /dev/null +++ b/framework/saleor/.env.template @@ -0,0 +1,4 @@ +COMMERCE_PROVIDER=saleor + +NEXT_SALEOR_API_URL= +NEXT_SALEOR_CHANNEL= diff --git a/framework/saleor/README.md b/framework/saleor/README.md new file mode 100644 index 000000000..1684ff6bc --- /dev/null +++ b/framework/saleor/README.md @@ -0,0 +1,19 @@ +## Saleor Provider + +**Demo:** TBD + +Before getting starter, a [Saleor](https://saleor.io/) account and store is required before using the provider. + +Next, copy the `.env.template` file in this directory to `.env.local` in the main directory (which will be ignored by Git): + +```bash +cp framework/saleor/.env.template .env.local +``` + +Then, set the environment variables in `.env.local` to match the ones from your store. + +## Contribute + +Our commitment to Open Source can be found [here](https://vercel.com/oss). + +If you find an issue with the provider or want a new feature, feel free to open a PR or [create a new issue](https://github.com/vercel/commerce/issues). diff --git a/framework/saleor/api/cart.ts b/framework/saleor/api/cart.ts new file mode 100644 index 000000000..ea9b101e1 --- /dev/null +++ b/framework/saleor/api/cart.ts @@ -0,0 +1 @@ +export default function () {} diff --git a/framework/saleor/api/catalog/products.ts b/framework/saleor/api/catalog/products.ts new file mode 100644 index 000000000..ea9b101e1 --- /dev/null +++ b/framework/saleor/api/catalog/products.ts @@ -0,0 +1 @@ +export default function () {} diff --git a/framework/saleor/api/checkout.ts b/framework/saleor/api/checkout.ts new file mode 100644 index 000000000..ea9b101e1 --- /dev/null +++ b/framework/saleor/api/checkout.ts @@ -0,0 +1 @@ +export default function () {} diff --git a/framework/saleor/api/customers/index.ts b/framework/saleor/api/customers/index.ts new file mode 100644 index 000000000..ea9b101e1 --- /dev/null +++ b/framework/saleor/api/customers/index.ts @@ -0,0 +1 @@ +export default function () {} diff --git a/framework/saleor/api/customers/login.ts b/framework/saleor/api/customers/login.ts new file mode 100644 index 000000000..ea9b101e1 --- /dev/null +++ b/framework/saleor/api/customers/login.ts @@ -0,0 +1 @@ +export default function () {} diff --git a/framework/saleor/api/customers/logout.ts b/framework/saleor/api/customers/logout.ts new file mode 100644 index 000000000..ea9b101e1 --- /dev/null +++ b/framework/saleor/api/customers/logout.ts @@ -0,0 +1 @@ +export default function () {} diff --git a/framework/saleor/api/customers/signup.ts b/framework/saleor/api/customers/signup.ts new file mode 100644 index 000000000..ea9b101e1 --- /dev/null +++ b/framework/saleor/api/customers/signup.ts @@ -0,0 +1 @@ +export default function () {} diff --git a/framework/saleor/api/endpoints/cart.ts b/framework/saleor/api/endpoints/cart.ts new file mode 100644 index 000000000..d09c976c3 --- /dev/null +++ b/framework/saleor/api/endpoints/cart.ts @@ -0,0 +1 @@ +export default function (_commerce: any) {} diff --git a/framework/saleor/api/endpoints/catalog/products.ts b/framework/saleor/api/endpoints/catalog/products.ts new file mode 100644 index 000000000..d09c976c3 --- /dev/null +++ b/framework/saleor/api/endpoints/catalog/products.ts @@ -0,0 +1 @@ +export default function (_commerce: any) {} diff --git a/framework/saleor/api/endpoints/checkout/index.ts b/framework/saleor/api/endpoints/checkout/index.ts new file mode 100644 index 000000000..f15672435 --- /dev/null +++ b/framework/saleor/api/endpoints/checkout/index.ts @@ -0,0 +1,57 @@ +import { CommerceAPI, GetAPISchema, createEndpoint } from '@commerce/api' +import checkoutEndpoint from '@commerce/api/endpoints/checkout' +import { CheckoutSchema } from '@commerce/types/checkout' + +export type CheckoutAPI = GetAPISchema + +export type CheckoutEndpoint = CheckoutAPI['endpoint'] + +const checkout: CheckoutEndpoint['handlers']['checkout'] = async ({ + req, + res, + config, +}) => { + try { + const html = ` + + + + + + Checkout + + +
    + + + +

    Checkout not yet implemented :(

    +

    + See #64 +

    +
    + + + ` + + res.status(200) + res.setHeader('Content-Type', 'text/html') + res.write(html) + res.end() + } catch (error) { + console.error(error) + + const message = 'An unexpected error ocurred' + + res.status(500).json({ data: null, errors: [{ message }] }) + } +} + +export const handlers: CheckoutEndpoint['handlers'] = { checkout } + +const checkoutApi = createEndpoint({ + handler: checkoutEndpoint, + handlers, +}) + +export default checkoutApi diff --git a/framework/saleor/api/endpoints/customer.ts b/framework/saleor/api/endpoints/customer.ts new file mode 100644 index 000000000..d09c976c3 --- /dev/null +++ b/framework/saleor/api/endpoints/customer.ts @@ -0,0 +1 @@ +export default function (_commerce: any) {} diff --git a/framework/saleor/api/endpoints/login.ts b/framework/saleor/api/endpoints/login.ts new file mode 100644 index 000000000..d09c976c3 --- /dev/null +++ b/framework/saleor/api/endpoints/login.ts @@ -0,0 +1 @@ +export default function (_commerce: any) {} diff --git a/framework/saleor/api/endpoints/logout.ts b/framework/saleor/api/endpoints/logout.ts new file mode 100644 index 000000000..d09c976c3 --- /dev/null +++ b/framework/saleor/api/endpoints/logout.ts @@ -0,0 +1 @@ +export default function (_commerce: any) {} diff --git a/framework/saleor/api/endpoints/signup.ts b/framework/saleor/api/endpoints/signup.ts new file mode 100644 index 000000000..d09c976c3 --- /dev/null +++ b/framework/saleor/api/endpoints/signup.ts @@ -0,0 +1 @@ +export default function (_commerce: any) {} diff --git a/framework/saleor/api/endpoints/wishlist.ts b/framework/saleor/api/endpoints/wishlist.ts new file mode 100644 index 000000000..d09c976c3 --- /dev/null +++ b/framework/saleor/api/endpoints/wishlist.ts @@ -0,0 +1 @@ +export default function (_commerce: any) {} diff --git a/framework/saleor/api/index.ts b/framework/saleor/api/index.ts new file mode 100644 index 000000000..5ae5f3a8a --- /dev/null +++ b/framework/saleor/api/index.ts @@ -0,0 +1,49 @@ +import type { CommerceAPIConfig } from '@commerce/api' + +import * as Const from '../const' + +if (!Const.API_URL) { + throw new Error(`The environment variable NEXT_SALEOR_API_URL is missing and it's required to access your store`) +} + +if (!Const.API_CHANNEL) { + throw new Error(`The environment variable NEXT_SALEOR_CHANNEL is missing and it's required to access your store`) +} + +import fetchGraphqlApi from './utils/fetch-graphql-api' + +export interface SaleorConfig extends CommerceAPIConfig { + storeChannel: string +} + +const config: SaleorConfig = { + locale: 'en-US', + commerceUrl: Const.API_URL, + apiToken: Const.SALEOR_TOKEN, + cartCookie: Const.CHECKOUT_ID_COOKIE, + cartCookieMaxAge: 60 * 60 * 24 * 30, + fetch: fetchGraphqlApi, + customerCookie: '', + storeChannel: Const.API_CHANNEL, +} + +import { + CommerceAPI, + getCommerceApi as commerceApi, +} from '@commerce/api' + +import * as operations from './operations' + +export interface ShopifyConfig extends CommerceAPIConfig {} + +export const provider = { config, operations } + +export type Provider = typeof provider + +export type SaleorAPI

    = CommerceAPI

    + +export function getCommerceApi

    ( + customProvider: P = provider as any +): SaleorAPI

    { + return commerceApi(customProvider) +} diff --git a/framework/saleor/api/operations/get-all-pages.ts b/framework/saleor/api/operations/get-all-pages.ts new file mode 100644 index 000000000..f3ed54e27 --- /dev/null +++ b/framework/saleor/api/operations/get-all-pages.ts @@ -0,0 +1,50 @@ +import type { OperationContext } from '@commerce/api/operations' + +import { QueryPagesArgs, PageCountableEdge } from '../../schema' +import type { SaleorConfig, Provider } from '..' +import * as Query from '../../utils/queries' + +export type Page = any + + export type GetAllPagesResult< + T extends { pages: any[] } = { pages: Page[] } + > = T + +export default function getAllPagesOperation({ + commerce, +}: OperationContext) { + + async function getAllPages({ + query = Query.PageMany, + config, + variables, + }: { + url?: string + config?: Partial + variables?: QueryPagesArgs + preview?: boolean + query?: string + } = {}): Promise { + const { fetch, locale, locales = ['en-US'] } = commerce.getConfig(config) + + const { data } = await fetch(query, { variables }, + { + ...(locale && { + headers: { + 'Accept-Language': locale, + }, + }), + } + ) + + const pages = data.pages?.edges?.map(({ node: { title: name, slug, ...node } }: PageCountableEdge) => ({ + ...node, + url: `/${locale}/${slug}`, + name, + })) + + return { pages } + } + + return getAllPages +} diff --git a/framework/saleor/api/operations/get-all-product-paths.ts b/framework/saleor/api/operations/get-all-product-paths.ts new file mode 100644 index 000000000..43ce7de94 --- /dev/null +++ b/framework/saleor/api/operations/get-all-product-paths.ts @@ -0,0 +1,46 @@ +import type { OperationContext } from '@commerce/api/operations' +import { + GetAllProductPathsQuery, + GetAllProductPathsQueryVariables, + ProductCountableEdge, +} from '../../schema' +import type { ShopifyConfig, Provider, SaleorConfig } from '..' + +import { getAllProductsPathsQuery } from '../../utils/queries' +import fetchAllProducts from '../utils/fetch-all-products' + +export type GetAllProductPathsResult = { + products: Array<{ path: string }> +} + +export default function getAllProductPathsOperation({ + commerce, +}: OperationContext) { + + async function getAllProductPaths({ + query, + config, + variables, + }: { + query?: string + config?: SaleorConfig + variables?: any + } = {}): Promise { + config = commerce.getConfig(config) + + const products = await fetchAllProducts({ + config, + query: getAllProductsPathsQuery, + variables, + }) + + return { + products: products?.map(({ node: { slug } }: ProductCountableEdge) => ({ + path: `/${slug}`, + })), + } + + } + + return getAllProductPaths +} diff --git a/framework/saleor/api/operations/get-all-products.ts b/framework/saleor/api/operations/get-all-products.ts new file mode 100644 index 000000000..a1a7ce0c9 --- /dev/null +++ b/framework/saleor/api/operations/get-all-products.ts @@ -0,0 +1,67 @@ +import type { OperationContext } from '@commerce/api/operations' +import { Product } from '@commerce/types/product' + +import { ProductCountableEdge } from '../../schema' +import type { Provider, SaleorConfig } from '..' +import { normalizeProduct } from '../../utils' + +import * as Query from '../../utils/queries' +import { GraphQLFetcherResult } from '@commerce/api' + +type ReturnType = { + products: Product[] +} + +export default function getAllProductsOperation({ + commerce, +}: OperationContext) { + async function getAllProducts({ + query = Query.ProductMany, + variables, + config, + featured, + }: { + query?: string + variables?: any + config?: Partial + preview?: boolean + featured?: boolean + } = {}): Promise { + const { fetch, locale } = commerce.getConfig(config) + + if (featured) { + variables = { ...variables, categoryId: 'Q29sbGVjdGlvbjo0' }; + query = Query.CollectionOne + } + + + const { data }: GraphQLFetcherResult = await fetch( + query, + { variables }, + { + ...(locale && { + headers: { + 'Accept-Language': locale, + }, + }), + } + ) + + if (featured) { + const products = data.collection.products?.edges?.map(({ node: p }: ProductCountableEdge) => normalizeProduct(p)) ?? [] + + return { + products, + } + } else { + const products = data.products?.edges?.map(({ node: p }: ProductCountableEdge) => normalizeProduct(p)) ?? [] + + return { + products, + } + } + + } + + return getAllProducts +} diff --git a/framework/saleor/api/operations/get-page.ts b/framework/saleor/api/operations/get-page.ts new file mode 100644 index 000000000..af2d5b8e6 --- /dev/null +++ b/framework/saleor/api/operations/get-page.ts @@ -0,0 +1,51 @@ +import type { OperationContext } from '@commerce/api/operations' +import type { Provider, SaleorConfig } from '..' +import { QueryPageArgs } from '../../schema' + +import * as Query from '../../utils/queries' + +export type Page = any + + export type GetPageResult = T + +export default function getPageOperation({ + commerce, +}: OperationContext) { + + async function getPage({ + query = Query.PageOne, + variables, + config, + }: { + query?: string + variables: QueryPageArgs, + config?: Partial + preview?: boolean + }): Promise { + const { fetch, locale = 'en-US' } = commerce.getConfig(config) + + const { + data: { page }, + } = await fetch(query, { variables }, + { + ...(locale && { + headers: { + 'Accept-Language': locale, + }, + }), + } + ) + + return { + page: page + ? { + ...page, + name: page.title, + url: `/${locale}/${page.slug}`, + } + : null, + } + } + + return getPage +} diff --git a/framework/saleor/api/operations/get-product.ts b/framework/saleor/api/operations/get-product.ts new file mode 100644 index 000000000..85fca934a --- /dev/null +++ b/framework/saleor/api/operations/get-product.ts @@ -0,0 +1,46 @@ +import type { OperationContext } from '@commerce/api/operations' +import { normalizeProduct, } from '../../utils' +import type { Provider, SaleorConfig } from '..' + +import * as Query from '../../utils/queries' + +type Variables = { + slug: string +} + +type ReturnType = { + product: any +} + +export default function getProductOperation({ + commerce, +}: OperationContext) { + async function getProduct({ + query = Query.ProductOneBySlug, + variables, + config: cfg, + }: { + query?: string + variables: Variables + config?: Partial + preview?: boolean + }): Promise { + const { fetch, locale } = commerce.getConfig(cfg) + + const { data } = await fetch(query, { variables }, + { + ...(locale && { + headers: { + 'Accept-Language': locale, + }, + }), + } + ) + + return { + product: data?.product ? normalizeProduct(data.product) : null, + } + } + + return getProduct +} diff --git a/framework/saleor/api/operations/get-site-info.ts b/framework/saleor/api/operations/get-site-info.ts new file mode 100644 index 000000000..eca0f2246 --- /dev/null +++ b/framework/saleor/api/operations/get-site-info.ts @@ -0,0 +1,35 @@ +import type { OperationContext } from '@commerce/api/operations' +import { Category } from '@commerce/types/site' +import type { SaleorConfig, Provider } from '..' + +import { getCategories, getVendors } from '../../utils' + +interface GetSiteInfoResult { + categories: Category[] + brands: any[] +} + +export default function getSiteInfoOperation({ commerce }: OperationContext) { + async function getSiteInfo({ + query, + config, + variables, + }: { + query?: string + config?: Partial + preview?: boolean + variables?: any + } = {}): Promise { + const cfg = commerce.getConfig(config) + + const categories = await getCategories(cfg) + const brands = await getVendors(cfg) + + return { + categories, + brands, + } + } + + return getSiteInfo +} diff --git a/framework/saleor/api/operations/index.ts b/framework/saleor/api/operations/index.ts new file mode 100644 index 000000000..7872a20b6 --- /dev/null +++ b/framework/saleor/api/operations/index.ts @@ -0,0 +1,7 @@ +export { default as getAllPages } from './get-all-pages' +export { default as getPage } from './get-page' +export { default as getAllProducts } from './get-all-products' +export { default as getAllProductPaths } from './get-all-product-paths' +export { default as getProduct } from './get-product' +export { default as getSiteInfo } from './get-site-info' +export { default as login } from './login' diff --git a/framework/saleor/api/operations/login.ts b/framework/saleor/api/operations/login.ts new file mode 100644 index 000000000..ca680b82c --- /dev/null +++ b/framework/saleor/api/operations/login.ts @@ -0,0 +1,42 @@ +import type { ServerResponse } from 'http' +import type { OperationContext } from '@commerce/api/operations' +import type { Provider, SaleorConfig } from '..' +import { + throwUserErrors, +} from '../../utils' + +import * as Mutation from '../../utils/mutations' + +export default function loginOperation({ + commerce, +}: OperationContext) { + async function login({ + query = Mutation.SessionCreate, + variables, + config, + }: { + query?: string + variables: any + res: ServerResponse + config?: SaleorConfig + }): Promise { + config = commerce.getConfig(config) + + const { data: { customerAccessTokenCreate } } = await config.fetch(query, { variables }) + + throwUserErrors(customerAccessTokenCreate?.customerUserErrors) + + const customerAccessToken = customerAccessTokenCreate?.customerAccessToken + const accessToken = customerAccessToken?.accessToken + + // if (accessToken) { + // setCustomerToken(accessToken) + // } + + return { + result: customerAccessToken?.accessToken, + } + } + + return login +} diff --git a/framework/saleor/api/utils/fetch-all-products.ts b/framework/saleor/api/utils/fetch-all-products.ts new file mode 100644 index 000000000..1cfb3157c --- /dev/null +++ b/framework/saleor/api/utils/fetch-all-products.ts @@ -0,0 +1,41 @@ +import { ProductCountableEdge } from '../../schema' +import { SaleorConfig } from '..' + +const fetchAllProducts = async ({ + config, + query, + variables, + acc = [], + cursor, +}: { + config: SaleorConfig + query: string + acc?: ProductCountableEdge[] + variables?: any + cursor?: string +}): Promise => { + const { data } = await config.fetch(query, { + variables: { ...variables, cursor }, + }) + + const edges: ProductCountableEdge[] = 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/saleor/api/utils/fetch-graphql-api.ts b/framework/saleor/api/utils/fetch-graphql-api.ts new file mode 100644 index 000000000..71199d661 --- /dev/null +++ b/framework/saleor/api/utils/fetch-graphql-api.ts @@ -0,0 +1,37 @@ +import type { GraphQLFetcher } from '@commerce/api' +import fetch from './fetch' + +import { API_URL } from '../../const' +import { getError } from '../../utils/handle-fetch-response' +import { getCommerceApi } from '..' +import { getToken } from '@framework/utils' + +const fetchGraphqlApi: GraphQLFetcher = async (query: string, { variables } = {}, fetchOptions) => { + const config = getCommerceApi().getConfig() + const token = getToken() + + const res = await fetch(API_URL!, { + ...fetchOptions, + method: 'POST', + headers: { + ...(token && { + Authorization: `Bearer ${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/saleor/api/utils/fetch.ts b/framework/saleor/api/utils/fetch.ts new file mode 100644 index 000000000..0b8367102 --- /dev/null +++ b/framework/saleor/api/utils/fetch.ts @@ -0,0 +1,2 @@ +import zeitFetch from '@vercel/fetch' +export default zeitFetch() diff --git a/framework/saleor/api/utils/is-allowed-method.ts b/framework/saleor/api/utils/is-allowed-method.ts new file mode 100644 index 000000000..cbaab2251 --- /dev/null +++ b/framework/saleor/api/utils/is-allowed-method.ts @@ -0,0 +1,22 @@ +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/saleor/api/wishlist.ts b/framework/saleor/api/wishlist.ts new file mode 100644 index 000000000..ea9b101e1 --- /dev/null +++ b/framework/saleor/api/wishlist.ts @@ -0,0 +1 @@ +export default function () {} diff --git a/framework/saleor/auth/use-login.tsx b/framework/saleor/auth/use-login.tsx new file mode 100644 index 000000000..2a31c932b --- /dev/null +++ b/framework/saleor/auth/use-login.tsx @@ -0,0 +1,63 @@ +import { useCallback } from 'react' + +import type { MutationHook } from '@commerce/utils/types' +import { CommerceError } from '@commerce/utils/errors' +import useCustomer from '../customer/use-customer' +import * as mutation from '../utils/mutations' +import { Mutation, MutationTokenCreateArgs } from '../schema' +import useLogin, { UseLogin } from '@commerce/auth/use-login' +import { setCSRFToken, setToken, throwUserErrors, checkoutAttach, getCheckoutId } from '../utils' +import { LoginHook } from '@commerce/types/login' + +export default useLogin as UseLogin + +export const handler: MutationHook = { + fetchOptions: { + query: mutation.SessionCreate, + }, + 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 { tokenCreate } = await fetch({ + ...options, + variables: { email, password }, + }) + + throwUserErrors(tokenCreate?.errors) + + const { token, csrfToken } = tokenCreate! + + if (token && csrfToken) { + setToken(token) + setCSRFToken(csrfToken) + + const { checkoutId } = getCheckoutId() + checkoutAttach(fetch, { + variables: { checkoutId }, + headers: { + Authorization: `JWT ${token}`, + }, + }) + } + + 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/saleor/auth/use-logout.tsx b/framework/saleor/auth/use-logout.tsx new file mode 100644 index 000000000..fe75df84b --- /dev/null +++ b/framework/saleor/auth/use-logout.tsx @@ -0,0 +1,41 @@ +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 * as mutation from '../utils/mutations' +import { setCSRFToken, setToken, setCheckoutToken } from '../utils/customer-token' +import { LogoutHook } from '@commerce/types/logout' + +export default useLogout as UseLogout + +export const handler: MutationHook = { + fetchOptions: { + query: mutation.SessionDestroy, + }, + async fetcher({ options, fetch }) { + await fetch({ + ...options, + variables: {}, + }) + + setToken() + setCSRFToken() + setCheckoutToken() + + 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/saleor/auth/use-signup.tsx b/framework/saleor/auth/use-signup.tsx new file mode 100644 index 000000000..d9e91b468 --- /dev/null +++ b/framework/saleor/auth/use-signup.tsx @@ -0,0 +1,56 @@ +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 { AccountRegisterInput, Mutation, MutationAccountRegisterArgs } from '../schema' + +import * as mutation from '../utils/mutations' +import { handleAutomaticLogin, throwUserErrors } from '../utils' +import { SignupHook } from '@commerce/types/signup' + +export default useSignup as UseSignup + +export const handler: MutationHook = { + fetchOptions: { + query: mutation.AccountCreate, + }, + 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 signup', + }) + } + + const { customerCreate } = await fetch({ + ...options, + variables: { + input: { + email, + password, + redirectUrl: 'https://localhost.com', + channel: 'default-channel' + }, + }, + }) + + throwUserErrors(customerCreate?.errors) + await handleAutomaticLogin(fetch, { email, password }) + + return null + }, + 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/saleor/cart/index.ts b/framework/saleor/cart/index.ts new file mode 100644 index 000000000..f6d36b443 --- /dev/null +++ b/framework/saleor/cart/index.ts @@ -0,0 +1,4 @@ +export { default as useCart } from './use-cart' +export { default as useAddItem } from './use-add-item' +export { default as useUpdateItem } from './use-update-item' +export { default as useRemoveItem } from './use-remove-item' diff --git a/framework/saleor/cart/use-add-item.tsx b/framework/saleor/cart/use-add-item.tsx new file mode 100644 index 000000000..3af368e70 --- /dev/null +++ b/framework/saleor/cart/use-add-item.tsx @@ -0,0 +1,54 @@ +import { useCallback } from 'react' +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 * as mutation from '../utils/mutations' + +import { getCheckoutId, checkoutToCart } from '../utils' + +import { Mutation, MutationCheckoutLinesAddArgs } from '../schema' +import { AddItemHook } from '@commerce/types/cart' + +export default useAddItem as UseAddItem + +export const handler: MutationHook = { + fetchOptions: { query: mutation.CheckoutLineAdd }, + 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 { checkoutLinesAdd } = await fetch({ + ...options, + variables: { + checkoutId: getCheckoutId().checkoutId, + lineItems: [ + { + variantId: item.variantId, + quantity: item.quantity ?? 1, + }, + ], + }, + }) + + return checkoutToCart(checkoutLinesAdd) + }, + 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/saleor/cart/use-cart.tsx b/framework/saleor/cart/use-cart.tsx new file mode 100644 index 000000000..ab80ea395 --- /dev/null +++ b/framework/saleor/cart/use-cart.tsx @@ -0,0 +1,53 @@ +import { useMemo } from 'react' +import useCommerceCart, { UseCart } from '@commerce/cart/use-cart' + +import { SWRHook } from '@commerce/utils/types' +import { checkoutCreate, checkoutToCart, getCheckoutId } from '../utils' +import * as query from '../utils/queries' +import { GetCartHook } from '@commerce/types/cart' + +export default useCommerceCart as UseCart + +export const handler: SWRHook = { + fetchOptions: { + query: query.CheckoutOne, + }, + async fetcher({ input: { cartId: checkoutId }, options, fetch }) { + let checkout + + if (checkoutId) { + const checkoutId = getCheckoutId().checkoutToken + const data = await fetch({ + ...options, + variables: { checkoutId }, + }) + + checkout = data + } + + 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 + }, + enumerable: true, + }, + }), + [response] + ) + }, +} diff --git a/framework/saleor/cart/use-remove-item.tsx b/framework/saleor/cart/use-remove-item.tsx new file mode 100644 index 000000000..81f9c122f --- /dev/null +++ b/framework/saleor/cart/use-remove-item.tsx @@ -0,0 +1,39 @@ +import { useCallback } from 'react' +import type { MutationHookContext, HookFetcherContext, MutationHook } from '@commerce/utils/types' +import useRemoveItem, { UseRemoveItem } from '@commerce/cart/use-remove-item' +import useCart from './use-cart' +import * as mutation from '../utils/mutations' +import { getCheckoutId, checkoutToCart } from '../utils' +import { Mutation, MutationCheckoutLineDeleteArgs } from '../schema' +import { LineItem, RemoveItemHook } from '../types/cart' + +export default useRemoveItem as UseRemoveItem + +export const handler = { + fetchOptions: { query: mutation.CheckoutLineDelete }, + async fetcher({ input: { itemId }, options, fetch }: HookFetcherContext) { + const data = await fetch({ + ...options, + variables: { + checkoutId: getCheckoutId().checkoutId, + lineId: itemId, + }, + }) + return checkoutToCart(data.checkoutLineDelete) + }, + useHook: ({ fetch }: MutationHookContext) => < + T extends LineItem | undefined = undefined + > () => { + const { mutate } = useCart() + + return useCallback( + async function removeItem(input) { + const data = await fetch({ input: { itemId: input.id } }) + await mutate(data, false) + + return data + }, + [fetch, mutate] + ); + }, +} diff --git a/framework/saleor/cart/use-update-item.tsx b/framework/saleor/cart/use-update-item.tsx new file mode 100644 index 000000000..361ae5cdf --- /dev/null +++ b/framework/saleor/cart/use-update-item.tsx @@ -0,0 +1,99 @@ +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, { UseUpdateItem } from '@commerce/cart/use-update-item' + +import useCart from './use-cart' +import { handler as removeItemHandler } from './use-remove-item' +import type { LineItem } from '../types' +import { checkoutToCart } from '../utils' +import { getCheckoutId } from '../utils' +import { Mutation, MutationCheckoutLinesUpdateArgs } from '../schema' + +import * as mutation from '../utils/mutations' + +import type { UpdateItemHook } from '../types/cart' + +export type UpdateItemActionInput = T extends LineItem + ? Partial + : UpdateItemHook['actionInput'] + +export default useUpdateItem as UseUpdateItem + +export const handler = { + fetchOptions: { query: mutation.CheckoutLineUpdate }, + 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 checkoutId = getCheckoutId().checkoutId + const { checkoutLinesUpdate } = await fetch({ + ...options, + variables: { + checkoutId, + lineItems: [ + { + variantId: item.variantId, + quantity: item.quantity, + }, + ], + }, + }) + + return checkoutToCart(checkoutLinesUpdate) + }, + useHook: ({ fetch }: MutationHookContext) => + ( + ctx: { + item?: T + wait?: number + } = {} + ) => { + const { item } = ctx + const { mutate } = useCart() as any + + return useCallback( + debounce(async (input: UpdateItemActionInput) => { + 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/saleor/commerce.config.json b/framework/saleor/commerce.config.json new file mode 100644 index 000000000..d5a1ac35d --- /dev/null +++ b/framework/saleor/commerce.config.json @@ -0,0 +1,7 @@ +{ + "provider": "saleor", + "features": { + "wishlist": false, + "customCheckout": true + } +} diff --git a/framework/saleor/const.ts b/framework/saleor/const.ts new file mode 100644 index 000000000..df348770d --- /dev/null +++ b/framework/saleor/const.ts @@ -0,0 +1,5 @@ +export const API_URL = process.env.NEXT_PUBLIC_SALEOR_API_URL +export const API_CHANNEL = process.env.NEXT_PUBLIC_SALEOR_CHANNEL +export const CHECKOUT_ID_COOKIE = 'saleor.CheckoutID' +export const SALEOR_TOKEN = 'saleor.Token' +export const SALEOR_CRSF_TOKEN = 'saleor.CSRFToken' diff --git a/framework/saleor/customer/index.ts b/framework/saleor/customer/index.ts new file mode 100644 index 000000000..6c903ecc5 --- /dev/null +++ b/framework/saleor/customer/index.ts @@ -0,0 +1 @@ +export { default as useCustomer } from './use-customer' diff --git a/framework/saleor/customer/use-customer.tsx b/framework/saleor/customer/use-customer.tsx new file mode 100644 index 000000000..1e0e63d5a --- /dev/null +++ b/framework/saleor/customer/use-customer.tsx @@ -0,0 +1,30 @@ +import useCustomer, { UseCustomer } from '@commerce/customer/use-customer' +import { CustomerHook } from '@commerce/types/customer' +import { SWRHook } from '@commerce/utils/types' + +import * as query from '../utils/queries' + +export default useCustomer as UseCustomer + +export const handler: SWRHook = { + fetchOptions: { + query: query.CustomerCurrent, + }, + async fetcher({ options, fetch }) { + const data = await fetch({ + ...options, + variables: {}, + }) + return data.me ?? null + }, + useHook: + ({ useData }) => + (input) => { + return useData({ + swrOptions: { + revalidateOnFocus: false, + ...input?.swrOptions, + }, + }) + }, +} diff --git a/framework/saleor/fetcher.ts b/framework/saleor/fetcher.ts new file mode 100644 index 000000000..9d3c0bf89 --- /dev/null +++ b/framework/saleor/fetcher.ts @@ -0,0 +1,20 @@ +import { Fetcher } from '@commerce/utils/types' +import { API_URL } from './const' +import { getToken, handleFetchResponse } from './utils' + +const fetcher: Fetcher = async ({ url = API_URL, method = 'POST', variables, query }) => { + const token = getToken() + + return handleFetchResponse( + await fetch(url!, { + method, + body: JSON.stringify({ query, variables }), + headers: { + Authorization: `JWT ${token}`, + 'Content-Type': 'application/json', + }, + }) + ) +} + +export default fetcher diff --git a/framework/saleor/index.tsx b/framework/saleor/index.tsx new file mode 100644 index 000000000..5c9e61ec8 --- /dev/null +++ b/framework/saleor/index.tsx @@ -0,0 +1,32 @@ +import * as React from 'react' +import { ReactNode } from 'react' + +import { CommerceConfig, CommerceProvider as CoreCommerceProvider, useCommerce as useCoreCommerce } from '@commerce' + +import { saleorProvider, SaleorProvider } from './provider' +import * as Const from './const' + +export { saleorProvider } +export type { SaleorProvider } + +export const saleorConfig: CommerceConfig = { + locale: 'en-us', + cartCookie: Const.CHECKOUT_ID_COOKIE, +} + +export type SaleorConfig = Partial + +export type SaleorProps = { + children?: ReactNode + locale: string +} & SaleorConfig + +export function CommerceProvider({ children, ...config }: SaleorProps) { + return ( + + {children} + + ) +} + +export const useCommerce = () => useCoreCommerce() diff --git a/framework/saleor/next.config.js b/framework/saleor/next.config.js new file mode 100644 index 000000000..397a37b2a --- /dev/null +++ b/framework/saleor/next.config.js @@ -0,0 +1,8 @@ +const commerce = require('./commerce.config.json') + +module.exports = { + commerce, + images: { + domains: [process.env.COMMERCE_IMAGE_HOST], + }, +} diff --git a/framework/saleor/product/use-price.tsx b/framework/saleor/product/use-price.tsx new file mode 100644 index 000000000..0174faf5e --- /dev/null +++ b/framework/saleor/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/saleor/product/use-search.tsx b/framework/saleor/product/use-search.tsx new file mode 100644 index 000000000..cc763c4b7 --- /dev/null +++ b/framework/saleor/product/use-search.tsx @@ -0,0 +1,74 @@ +import { SWRHook } from '@commerce/utils/types' +import { Product } from '@commerce/types/product' +import useSearch, { UseSearch } from '@commerce/product/use-search' + +import { ProductCountableEdge } from '../schema' +import { getSearchVariables, normalizeProduct } from '../utils' + +import * as query from '../utils/queries' +import { SearchProductsHook } from '@commerce/types/product' + +export default useSearch as UseSearch + +export type SearchProductsInput = { + search?: string + categoryId?: string | number + brandId?: string | number + sort?: string +} + +export type SearchProductsData = { + products: Product[] + found: boolean +} + +export const handler: SWRHook = { + fetchOptions: { + query: query.ProductMany, + }, + async fetcher({ input, options, fetch }) { + const { categoryId, brandId } = input + + const data = await fetch({ + query: categoryId ? query.CollectionOne : options.query, + method: options?.method, + variables: getSearchVariables(input), + }) + + let edges + + if (categoryId) { + edges = data.collection?.products?.edges ?? [] + // FIXME @zaiste, no `vendor` in Saleor + // if (brandId) { + // edges = edges.filter( + // ({ node: { vendor } }: ProductCountableEdge) => + // vendor.replace(/\s+/g, '-').toLowerCase() === brandId + // ) + // } + } else { + edges = data.products?.edges ?? [] + } + + return { + products: edges.map(({ node }: ProductCountableEdge) => 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/saleor/provider.ts b/framework/saleor/provider.ts new file mode 100644 index 000000000..2ca96475a --- /dev/null +++ b/framework/saleor/provider.ts @@ -0,0 +1,26 @@ +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 saleorProvider = { + locale: 'en-us', + cartCookie: '', + cartCookieToken: '', + fetcher, + cart: { useCart, useAddItem, useUpdateItem, useRemoveItem }, + customer: { useCustomer }, + products: { useSearch }, + auth: { useLogin, useLogout, useSignup }, +} + +export type SaleorProvider = typeof saleorProvider diff --git a/framework/saleor/schema.d.ts b/framework/saleor/schema.d.ts new file mode 100644 index 000000000..339e7269d --- /dev/null +++ b/framework/saleor/schema.d.ts @@ -0,0 +1,11488 @@ +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 + /** + * The `Date` scalar type represents a Date + * value as specified by + * [iso8601](https://en.wikipedia.org/wiki/ISO_8601). + */ + Date: any + /** + * The `DateTime` scalar type represents a DateTime + * value as specified by + * [iso8601](https://en.wikipedia.org/wiki/ISO_8601). + */ + DateTime: any + /** + * The `GenericScalar` scalar type represents a generic + * GraphQL scalar value that could be: + * String, Boolean, Int, Float, List or Object. + */ + GenericScalar: any + /** + * Allows use of a JSON String for input / output from the GraphQL schema. + * + * Use of this type is *not recommended* as you lose the benefits of having a defined, static + * schema (one of the key benefits of GraphQL). + */ + JSONString: any + /** + * Positive Decimal scalar implementation. + * + * Should be used in places where value must be positive. + */ + PositiveDecimal: any + UUID: any + /** Variables of this type must be set to null in mutations. They will be replaced with a filename from a following multipart part containing a binary file. See: https://github.com/jaydenseric/graphql-multipart-request-spec. */ + Upload: any + WeightScalar: any + /** Anything */ + _Any: any +} + +/** Create a new address for the customer. */ +export type AccountAddressCreate = { + __typename?: 'AccountAddressCreate' + /** A user instance for which the address was created. */ + user?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + accountErrors: Array + errors: Array + address?: Maybe

    +} + +/** Delete an address of the logged-in user. */ +export type AccountAddressDelete = { + __typename?: 'AccountAddressDelete' + /** A user instance for which the address was deleted. */ + user?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + accountErrors: Array + errors: Array + address?: Maybe
    +} + +/** Updates an address of the logged-in user. */ +export type AccountAddressUpdate = { + __typename?: 'AccountAddressUpdate' + /** A user object for which the address was edited. */ + user?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + accountErrors: Array + errors: Array + address?: Maybe
    +} + +/** Remove user account. */ +export type AccountDelete = { + __typename?: 'AccountDelete' + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + accountErrors: Array + errors: Array + user?: Maybe +} + +export type AccountError = { + __typename?: 'AccountError' + /** Name of a field that caused the error. A value of `null` indicates that the error isn't associated with a particular field. */ + field?: Maybe + /** The error message. */ + message?: Maybe + /** The error code. */ + code: AccountErrorCode + /** A type of address that causes the error. */ + addressType?: Maybe +} + +/** An enumeration. */ +export enum AccountErrorCode { + ActivateOwnAccount = 'ACTIVATE_OWN_ACCOUNT', + ActivateSuperuserAccount = 'ACTIVATE_SUPERUSER_ACCOUNT', + DuplicatedInputItem = 'DUPLICATED_INPUT_ITEM', + DeactivateOwnAccount = 'DEACTIVATE_OWN_ACCOUNT', + DeactivateSuperuserAccount = 'DEACTIVATE_SUPERUSER_ACCOUNT', + DeleteNonStaffUser = 'DELETE_NON_STAFF_USER', + DeleteOwnAccount = 'DELETE_OWN_ACCOUNT', + DeleteStaffAccount = 'DELETE_STAFF_ACCOUNT', + DeleteSuperuserAccount = 'DELETE_SUPERUSER_ACCOUNT', + GraphqlError = 'GRAPHQL_ERROR', + Inactive = 'INACTIVE', + Invalid = 'INVALID', + InvalidPassword = 'INVALID_PASSWORD', + LeftNotManageablePermission = 'LEFT_NOT_MANAGEABLE_PERMISSION', + InvalidCredentials = 'INVALID_CREDENTIALS', + NotFound = 'NOT_FOUND', + OutOfScopeUser = 'OUT_OF_SCOPE_USER', + OutOfScopeGroup = 'OUT_OF_SCOPE_GROUP', + OutOfScopePermission = 'OUT_OF_SCOPE_PERMISSION', + PasswordEntirelyNumeric = 'PASSWORD_ENTIRELY_NUMERIC', + PasswordTooCommon = 'PASSWORD_TOO_COMMON', + PasswordTooShort = 'PASSWORD_TOO_SHORT', + PasswordTooSimilar = 'PASSWORD_TOO_SIMILAR', + Required = 'REQUIRED', + Unique = 'UNIQUE', + JwtSignatureExpired = 'JWT_SIGNATURE_EXPIRED', + JwtInvalidToken = 'JWT_INVALID_TOKEN', + JwtDecodeError = 'JWT_DECODE_ERROR', + JwtMissingToken = 'JWT_MISSING_TOKEN', + JwtInvalidCsrfToken = 'JWT_INVALID_CSRF_TOKEN', + ChannelInactive = 'CHANNEL_INACTIVE', + MissingChannelSlug = 'MISSING_CHANNEL_SLUG', +} + +export type AccountInput = { + /** Given name. */ + firstName?: Maybe + /** Family name. */ + lastName?: Maybe + /** Billing address of the customer. */ + defaultBillingAddress?: Maybe + /** Shipping address of the customer. */ + defaultShippingAddress?: Maybe + /** User language code. */ + languageCode?: Maybe +} + +/** Register a new user. */ +export type AccountRegister = { + __typename?: 'AccountRegister' + /** Informs whether users need to confirm their email address. */ + requiresConfirmation?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + accountErrors: Array + errors: Array + user?: Maybe +} + +export type AccountRegisterInput = { + /** The email address of the user. */ + email: Scalars['String'] + /** Password. */ + password: Scalars['String'] + /** Base of frontend URL that will be needed to create confirmation URL. */ + redirectUrl?: Maybe + /** User language code. */ + languageCode?: Maybe + /** User public metadata. */ + metadata?: Maybe> + /** Slug of a channel which will be used to notify users. Optional when only one channel exists. */ + channel?: Maybe +} + +/** Sends an email with the account removal link for the logged-in user. */ +export type AccountRequestDeletion = { + __typename?: 'AccountRequestDeletion' + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + accountErrors: Array + errors: Array +} + +/** Sets a default address for the authenticated user. */ +export type AccountSetDefaultAddress = { + __typename?: 'AccountSetDefaultAddress' + /** An updated user instance. */ + user?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + accountErrors: Array + errors: Array +} + +/** Updates the account of the logged-in user. */ +export type AccountUpdate = { + __typename?: 'AccountUpdate' + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + accountErrors: Array + errors: Array + user?: Maybe +} + +/** Represents user address data. */ +export type Address = Node & { + __typename?: 'Address' + /** The ID of the object. */ + id: Scalars['ID'] + firstName: Scalars['String'] + lastName: Scalars['String'] + companyName: Scalars['String'] + streetAddress1: Scalars['String'] + streetAddress2: Scalars['String'] + city: Scalars['String'] + cityArea: Scalars['String'] + postalCode: Scalars['String'] + /** Shop's default country. */ + country: CountryDisplay + countryArea: Scalars['String'] + phone?: Maybe + /** Address is user's default shipping address. */ + isDefaultShippingAddress?: Maybe + /** Address is user's default billing address. */ + isDefaultBillingAddress?: Maybe +} + +/** Creates user address. */ +export type AddressCreate = { + __typename?: 'AddressCreate' + /** A user instance for which the address was created. */ + user?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + accountErrors: Array + errors: Array + address?: Maybe
    +} + +/** Deletes an address. */ +export type AddressDelete = { + __typename?: 'AddressDelete' + /** A user instance for which the address was deleted. */ + user?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + accountErrors: Array + errors: Array + address?: Maybe
    +} + +export type AddressInput = { + /** Given name. */ + firstName?: Maybe + /** Family name. */ + lastName?: Maybe + /** Company or organization. */ + companyName?: Maybe + /** Address. */ + streetAddress1?: Maybe + /** Address. */ + streetAddress2?: Maybe + /** City. */ + city?: Maybe + /** District. */ + cityArea?: Maybe + /** Postal code. */ + postalCode?: Maybe + /** Country. */ + country?: Maybe + /** State or province. */ + countryArea?: Maybe + /** Phone number. */ + phone?: Maybe +} + +/** Sets a default address for the given user. */ +export type AddressSetDefault = { + __typename?: 'AddressSetDefault' + /** An updated user instance. */ + user?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + accountErrors: Array + errors: Array +} + +/** An enumeration. */ +export enum AddressTypeEnum { + Billing = 'BILLING', + Shipping = 'SHIPPING', +} + +/** Updates an address. */ +export type AddressUpdate = { + __typename?: 'AddressUpdate' + /** A user object for which the address was edited. */ + user?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + accountErrors: Array + errors: Array + address?: Maybe
    +} + +export type AddressValidationData = { + __typename?: 'AddressValidationData' + countryCode?: Maybe + countryName?: Maybe + addressFormat?: Maybe + addressLatinFormat?: Maybe + allowedFields?: Maybe>> + requiredFields?: Maybe>> + upperFields?: Maybe>> + countryAreaType?: Maybe + countryAreaChoices?: Maybe>> + cityType?: Maybe + cityChoices?: Maybe>> + cityAreaType?: Maybe + cityAreaChoices?: Maybe>> + postalCodeType?: Maybe + postalCodeMatchers?: Maybe>> + postalCodeExamples?: Maybe>> + postalCodePrefix?: Maybe +} + +/** Represents allocation. */ +export type Allocation = Node & { + __typename?: 'Allocation' + /** The ID of the object. */ + id: Scalars['ID'] + /** Quantity allocated for orders. */ + quantity: Scalars['Int'] + /** The warehouse were items were allocated. */ + warehouse: Warehouse +} + +/** Represents app data. */ +export type App = Node & + ObjectWithMetadata & { + __typename?: 'App' + /** The ID of the object. */ + id: Scalars['ID'] + /** Name of the app. */ + name?: Maybe + /** The date and time when the app was created. */ + created?: Maybe + /** Determine if app will be set active or not. */ + isActive?: Maybe + /** List of the app's permissions. */ + permissions?: Maybe>> + /** Last 4 characters of the tokens. */ + tokens?: Maybe>> + /** List of private metadata items.Requires proper staff permissions to access. */ + privateMetadata: Array> + /** List of public metadata items. Can be accessed without permissions. */ + metadata: Array> + /** Type of the app. */ + type?: Maybe + /** List of webhooks assigned to this app. */ + webhooks?: Maybe>> + /** Description of this app. */ + aboutApp?: Maybe + /** Description of the data privacy defined for this app. */ + dataPrivacy?: Maybe + /** Url to details about the privacy policy on the app owner page. */ + dataPrivacyUrl?: Maybe + /** Homepage of the app. */ + homepageUrl?: Maybe + /** Support page for the app. */ + supportUrl?: Maybe + /** Url to iframe with the configuration for the app. */ + configurationUrl?: Maybe + /** Url to iframe with the app. */ + appUrl?: Maybe + /** Version number of the app. */ + version?: Maybe + /** JWT token used to authenticate by thridparty app. */ + accessToken?: Maybe + } + +/** Activate the app. */ +export type AppActivate = { + __typename?: 'AppActivate' + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + appErrors: Array + errors: Array + app?: Maybe +} + +export type AppCountableConnection = { + __typename?: 'AppCountableConnection' + /** Pagination data for this connection. */ + pageInfo: PageInfo + edges: Array + /** A total count of items in the collection. */ + totalCount?: Maybe +} + +export type AppCountableEdge = { + __typename?: 'AppCountableEdge' + /** The item at the end of the edge. */ + node: App + /** A cursor for use in pagination. */ + cursor: Scalars['String'] +} + +/** Creates a new app. */ +export type AppCreate = { + __typename?: 'AppCreate' + /** The newly created authentication token. */ + authToken?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + appErrors: Array + errors: Array + app?: Maybe +} + +/** Deactivate the app. */ +export type AppDeactivate = { + __typename?: 'AppDeactivate' + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + appErrors: Array + errors: Array + app?: Maybe +} + +/** Deletes an app. */ +export type AppDelete = { + __typename?: 'AppDelete' + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + appErrors: Array + errors: Array + app?: Maybe +} + +/** Delete failed installation. */ +export type AppDeleteFailedInstallation = { + __typename?: 'AppDeleteFailedInstallation' + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + appErrors: Array + errors: Array + appInstallation?: Maybe +} + +export type AppError = { + __typename?: 'AppError' + /** Name of a field that caused the error. A value of `null` indicates that the error isn't associated with a particular field. */ + field?: Maybe + /** The error message. */ + message?: Maybe + /** The error code. */ + code: AppErrorCode + /** List of permissions which causes the error. */ + permissions?: Maybe> +} + +/** An enumeration. */ +export enum AppErrorCode { + Forbidden = 'FORBIDDEN', + GraphqlError = 'GRAPHQL_ERROR', + Invalid = 'INVALID', + InvalidStatus = 'INVALID_STATUS', + InvalidPermission = 'INVALID_PERMISSION', + InvalidUrlFormat = 'INVALID_URL_FORMAT', + InvalidManifestFormat = 'INVALID_MANIFEST_FORMAT', + ManifestUrlCantConnect = 'MANIFEST_URL_CANT_CONNECT', + NotFound = 'NOT_FOUND', + Required = 'REQUIRED', + Unique = 'UNIQUE', + OutOfScopeApp = 'OUT_OF_SCOPE_APP', + OutOfScopePermission = 'OUT_OF_SCOPE_PERMISSION', +} + +/** Fetch and validate manifest. */ +export type AppFetchManifest = { + __typename?: 'AppFetchManifest' + manifest?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + appErrors: Array + errors: Array +} + +export type AppFilterInput = { + search?: Maybe + isActive?: Maybe + type?: Maybe +} + +export type AppInput = { + /** Name of the app. */ + name?: Maybe + /** List of permission code names to assign to this app. */ + permissions?: Maybe>> +} + +/** Install new app by using app manifest. */ +export type AppInstall = { + __typename?: 'AppInstall' + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + appErrors: Array + errors: Array + appInstallation?: Maybe +} + +export type AppInstallInput = { + /** Name of the app to install. */ + appName?: Maybe + /** Url to app's manifest in JSON format. */ + manifestUrl?: Maybe + /** Determine if app will be set active or not. */ + activateAfterInstallation?: Maybe + /** List of permission code names to assign to this app. */ + permissions?: Maybe>> +} + +/** Represents ongoing installation of app. */ +export type AppInstallation = Node & + Job & { + __typename?: 'AppInstallation' + appName: Scalars['String'] + manifestUrl: Scalars['String'] + /** The ID of the object. */ + id: Scalars['ID'] + /** Job status. */ + status: JobStatusEnum + /** Created date time of job in ISO 8601 format. */ + createdAt: Scalars['DateTime'] + /** Date time of job last update in ISO 8601 format. */ + updatedAt: Scalars['DateTime'] + /** Job message. */ + message?: Maybe + } + +/** Retry failed installation of new app. */ +export type AppRetryInstall = { + __typename?: 'AppRetryInstall' + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + appErrors: Array + errors: Array + appInstallation?: Maybe +} + +export enum AppSortField { + /** Sort apps by name. */ + Name = 'NAME', + /** Sort apps by creation date. */ + CreationDate = 'CREATION_DATE', +} + +export type AppSortingInput = { + /** Specifies the direction in which to sort products. */ + direction: OrderDirection + /** Sort apps by the selected field. */ + field: AppSortField +} + +/** Represents token data. */ +export type AppToken = Node & { + __typename?: 'AppToken' + /** Name of the authenticated token. */ + name?: Maybe + /** Last 4 characters of the token. */ + authToken?: Maybe + /** The ID of the object. */ + id: Scalars['ID'] +} + +/** Creates a new token. */ +export type AppTokenCreate = { + __typename?: 'AppTokenCreate' + /** The newly created authentication token. */ + authToken?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + appErrors: Array + errors: Array + appToken?: Maybe +} + +/** Deletes an authentication token assigned to app. */ +export type AppTokenDelete = { + __typename?: 'AppTokenDelete' + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + appErrors: Array + errors: Array + appToken?: Maybe +} + +export type AppTokenInput = { + /** Name of the token. */ + name?: Maybe + /** ID of app. */ + app: Scalars['ID'] +} + +/** Verify provided app token. */ +export type AppTokenVerify = { + __typename?: 'AppTokenVerify' + /** Determine if token is valid or not. */ + valid: Scalars['Boolean'] + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + appErrors: Array + errors: Array +} + +/** Enum determining type of your App. */ +export enum AppTypeEnum { + /** Local Saleor App. The app is fully manageable from dashboard. You can change assigned permissions, add webhooks, or authentication token */ + Local = 'LOCAL', + /** Third party external App. Installation is fully automated. Saleor uses a defined App manifest to gather all required information. */ + Thirdparty = 'THIRDPARTY', +} + +/** Updates an existing app. */ +export type AppUpdate = { + __typename?: 'AppUpdate' + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + appErrors: Array + errors: Array + app?: Maybe +} + +/** An enumeration. */ +export enum AreaUnitsEnum { + SqCm = 'SQ_CM', + SqM = 'SQ_M', + SqKm = 'SQ_KM', + SqFt = 'SQ_FT', + SqYd = 'SQ_YD', + SqInch = 'SQ_INCH', +} + +/** Assigns storefront's navigation menus. */ +export type AssignNavigation = { + __typename?: 'AssignNavigation' + /** Assigned navigation menu. */ + menu?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + menuErrors: Array + errors: Array +} + +/** Custom attribute of a product. Attributes can be assigned to products and variants at the product type level. */ +export type Attribute = Node & + ObjectWithMetadata & { + __typename?: 'Attribute' + /** The ID of the object. */ + id: Scalars['ID'] + productTypes: ProductTypeCountableConnection + productVariantTypes: ProductTypeCountableConnection + /** List of private metadata items.Requires proper staff permissions to access. */ + privateMetadata: Array> + /** List of public metadata items. Can be accessed without permissions. */ + metadata: Array> + /** The input type to use for entering attribute values in the dashboard. */ + inputType?: Maybe + /** The entity type which can be used as a reference. */ + entityType?: Maybe + /** Name of an attribute displayed in the interface. */ + name?: Maybe + /** Internal representation of an attribute name. */ + slug?: Maybe + /** The attribute type. */ + type?: Maybe + /** The unit of attribute values. */ + unit?: Maybe + /** List of attribute's values. */ + values?: Maybe>> + /** Whether the attribute requires values to be passed or not. */ + valueRequired: Scalars['Boolean'] + /** Whether the attribute should be visible or not in storefront. */ + visibleInStorefront: Scalars['Boolean'] + /** Whether the attribute can be filtered in storefront. */ + filterableInStorefront: Scalars['Boolean'] + /** Whether the attribute can be filtered in dashboard. */ + filterableInDashboard: Scalars['Boolean'] + /** Whether the attribute can be displayed in the admin product list. */ + availableInGrid: Scalars['Boolean'] + /** Returns translated attribute fields for the given language code. */ + translation?: Maybe + /** The position of the attribute in the storefront navigation (0 by default). */ + storefrontSearchPosition: Scalars['Int'] + } + +/** Custom attribute of a product. Attributes can be assigned to products and variants at the product type level. */ +export type AttributeProductTypesArgs = { + before?: Maybe + after?: Maybe + first?: Maybe + last?: Maybe +} + +/** Custom attribute of a product. Attributes can be assigned to products and variants at the product type level. */ +export type AttributeProductVariantTypesArgs = { + before?: Maybe + after?: Maybe + first?: Maybe + last?: Maybe +} + +/** Custom attribute of a product. Attributes can be assigned to products and variants at the product type level. */ +export type AttributeTranslationArgs = { + languageCode: LanguageCodeEnum +} + +/** Deletes attributes. */ +export type AttributeBulkDelete = { + __typename?: 'AttributeBulkDelete' + /** Returns how many objects were affected. */ + count: Scalars['Int'] + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + attributeErrors: Array + errors: Array +} + +export type AttributeCountableConnection = { + __typename?: 'AttributeCountableConnection' + /** Pagination data for this connection. */ + pageInfo: PageInfo + edges: Array + /** A total count of items in the collection. */ + totalCount?: Maybe +} + +export type AttributeCountableEdge = { + __typename?: 'AttributeCountableEdge' + /** The item at the end of the edge. */ + node: Attribute + /** A cursor for use in pagination. */ + cursor: Scalars['String'] +} + +/** Creates an attribute. */ +export type AttributeCreate = { + __typename?: 'AttributeCreate' + attribute?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + attributeErrors: Array + errors: Array +} + +export type AttributeCreateInput = { + /** The input type to use for entering attribute values in the dashboard. */ + inputType?: Maybe + /** The entity type which can be used as a reference. */ + entityType?: Maybe + /** Name of an attribute displayed in the interface. */ + name: Scalars['String'] + /** Internal representation of an attribute name. */ + slug?: Maybe + /** The attribute type. */ + type: AttributeTypeEnum + /** The unit of attribute values. */ + unit?: Maybe + /** List of attribute's values. */ + values?: Maybe>> + /** Whether the attribute requires values to be passed or not. */ + valueRequired?: Maybe + /** Whether the attribute is for variants only. */ + isVariantOnly?: Maybe + /** Whether the attribute should be visible or not in storefront. */ + visibleInStorefront?: Maybe + /** Whether the attribute can be filtered in storefront. */ + filterableInStorefront?: Maybe + /** Whether the attribute can be filtered in dashboard. */ + filterableInDashboard?: Maybe + /** The position of the attribute in the storefront navigation (0 by default). */ + storefrontSearchPosition?: Maybe + /** Whether the attribute can be displayed in the admin product list. */ + availableInGrid?: Maybe +} + +/** Deletes an attribute. */ +export type AttributeDelete = { + __typename?: 'AttributeDelete' + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + attributeErrors: Array + errors: Array + attribute?: Maybe +} + +/** An enumeration. */ +export enum AttributeEntityTypeEnum { + Page = 'PAGE', + Product = 'PRODUCT', +} + +export type AttributeError = { + __typename?: 'AttributeError' + /** Name of a field that caused the error. A value of `null` indicates that the error isn't associated with a particular field. */ + field?: Maybe + /** The error message. */ + message?: Maybe + /** The error code. */ + code: AttributeErrorCode +} + +/** An enumeration. */ +export enum AttributeErrorCode { + AlreadyExists = 'ALREADY_EXISTS', + GraphqlError = 'GRAPHQL_ERROR', + Invalid = 'INVALID', + NotFound = 'NOT_FOUND', + Required = 'REQUIRED', + Unique = 'UNIQUE', +} + +export type AttributeFilterInput = { + valueRequired?: Maybe + isVariantOnly?: Maybe + visibleInStorefront?: Maybe + filterableInStorefront?: Maybe + filterableInDashboard?: Maybe + availableInGrid?: Maybe + metadata?: Maybe>> + search?: Maybe + ids?: Maybe>> + type?: Maybe + inCollection?: Maybe + inCategory?: Maybe + /** Specifies the channel by which the data should be sorted. */ + channel?: Maybe +} + +export type AttributeInput = { + /** Internal representation of an attribute name. */ + slug: Scalars['String'] + /** Internal representation of a value (unique per attribute). */ + values?: Maybe>> + /** The range that the returned values should be in. */ + valuesRange?: Maybe +} + +/** An enumeration. */ +export enum AttributeInputTypeEnum { + Dropdown = 'DROPDOWN', + Multiselect = 'MULTISELECT', + File = 'FILE', + Reference = 'REFERENCE', + Numeric = 'NUMERIC', + RichText = 'RICH_TEXT', +} + +/** Reorder the values of an attribute. */ +export type AttributeReorderValues = { + __typename?: 'AttributeReorderValues' + /** Attribute from which values are reordered. */ + attribute?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + attributeErrors: Array + errors: Array +} + +export enum AttributeSortField { + /** Sort attributes by name */ + Name = 'NAME', + /** Sort attributes by slug */ + Slug = 'SLUG', + /** Sort attributes by the value required flag */ + ValueRequired = 'VALUE_REQUIRED', + /** Sort attributes by the variant only flag */ + IsVariantOnly = 'IS_VARIANT_ONLY', + /** Sort attributes by visibility in the storefront */ + VisibleInStorefront = 'VISIBLE_IN_STOREFRONT', + /** Sort attributes by the filterable in storefront flag */ + FilterableInStorefront = 'FILTERABLE_IN_STOREFRONT', + /** Sort attributes by the filterable in dashboard flag */ + FilterableInDashboard = 'FILTERABLE_IN_DASHBOARD', + /** Sort attributes by their position in storefront */ + StorefrontSearchPosition = 'STOREFRONT_SEARCH_POSITION', + /** Sort attributes based on whether they can be displayed or not in a product grid. */ + AvailableInGrid = 'AVAILABLE_IN_GRID', +} + +export type AttributeSortingInput = { + /** Specifies the direction in which to sort products. */ + direction: OrderDirection + /** Sort attributes by the selected field. */ + field: AttributeSortField +} + +export type AttributeTranslatableContent = Node & { + __typename?: 'AttributeTranslatableContent' + /** The ID of the object. */ + id: Scalars['ID'] + name: Scalars['String'] + /** Returns translated attribute fields for the given language code. */ + translation?: Maybe + /** Custom attribute of a product. */ + attribute?: Maybe +} + +export type AttributeTranslatableContentTranslationArgs = { + languageCode: LanguageCodeEnum +} + +/** Creates/Updates translations for attribute. */ +export type AttributeTranslate = { + __typename?: 'AttributeTranslate' + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + translationErrors: Array + errors: Array + attribute?: Maybe +} + +export type AttributeTranslation = Node & { + __typename?: 'AttributeTranslation' + /** The ID of the object. */ + id: Scalars['ID'] + name: Scalars['String'] + /** Translation language. */ + language: LanguageDisplay +} + +/** An enumeration. */ +export enum AttributeTypeEnum { + ProductType = 'PRODUCT_TYPE', + PageType = 'PAGE_TYPE', +} + +/** Updates attribute. */ +export type AttributeUpdate = { + __typename?: 'AttributeUpdate' + attribute?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + attributeErrors: Array + errors: Array +} + +export type AttributeUpdateInput = { + /** Name of an attribute displayed in the interface. */ + name?: Maybe + /** Internal representation of an attribute name. */ + slug?: Maybe + /** The unit of attribute values. */ + unit?: Maybe + /** IDs of values to be removed from this attribute. */ + removeValues?: Maybe>> + /** New values to be created for this attribute. */ + addValues?: Maybe>> + /** Whether the attribute requires values to be passed or not. */ + valueRequired?: Maybe + /** Whether the attribute is for variants only. */ + isVariantOnly?: Maybe + /** Whether the attribute should be visible or not in storefront. */ + visibleInStorefront?: Maybe + /** Whether the attribute can be filtered in storefront. */ + filterableInStorefront?: Maybe + /** Whether the attribute can be filtered in dashboard. */ + filterableInDashboard?: Maybe + /** The position of the attribute in the storefront navigation (0 by default). */ + storefrontSearchPosition?: Maybe + /** Whether the attribute can be displayed in the admin product list. */ + availableInGrid?: Maybe +} + +/** Represents a value of an attribute. */ +export type AttributeValue = Node & { + __typename?: 'AttributeValue' + /** The ID of the object. */ + id: Scalars['ID'] + /** Name of a value displayed in the interface. */ + name?: Maybe + /** Internal representation of a value (unique per attribute). */ + slug?: Maybe + /** Represents the value of the attribute value. */ + value?: Maybe + /** Returns translated attribute value fields for the given language code. */ + translation?: Maybe + /** The input type to use for entering attribute values in the dashboard. */ + inputType?: Maybe + /** The ID of the attribute reference. */ + reference?: Maybe + /** Represents file URL and content type (if attribute value is a file). */ + file?: Maybe + /** Represents the text (JSON) of the attribute value. */ + richText?: Maybe +} + +/** Represents a value of an attribute. */ +export type AttributeValueTranslationArgs = { + languageCode: LanguageCodeEnum +} + +/** Deletes values of attributes. */ +export type AttributeValueBulkDelete = { + __typename?: 'AttributeValueBulkDelete' + /** Returns how many objects were affected. */ + count: Scalars['Int'] + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + attributeErrors: Array + errors: Array +} + +/** Creates a value for an attribute. */ +export type AttributeValueCreate = { + __typename?: 'AttributeValueCreate' + /** The updated attribute. */ + attribute?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + attributeErrors: Array + errors: Array + attributeValue?: Maybe +} + +export type AttributeValueCreateInput = { + /** Name of a value displayed in the interface. */ + name: Scalars['String'] + /** Represents the value of the attribute value. */ + value?: Maybe + /** Represents the text (JSON) of the attribute value. */ + richText?: Maybe +} + +/** Deletes a value of an attribute. */ +export type AttributeValueDelete = { + __typename?: 'AttributeValueDelete' + /** The updated attribute. */ + attribute?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + attributeErrors: Array + errors: Array + attributeValue?: Maybe +} + +export type AttributeValueInput = { + /** ID of the selected attribute. */ + id?: Maybe + /** The value or slug of an attribute to resolve. If the passed value is non-existent, it will be created. */ + values?: Maybe>> + /** URL of the file attribute. Every time, a new value is created. */ + file?: Maybe + /** File content type. */ + contentType?: Maybe + /** List of entity IDs that will be used as references. */ + references?: Maybe> + /** Text content in JSON format. */ + richText?: Maybe +} + +export type AttributeValueTranslatableContent = Node & { + __typename?: 'AttributeValueTranslatableContent' + /** The ID of the object. */ + id: Scalars['ID'] + name: Scalars['String'] + /** Returns translated attribute value fields for the given language code. */ + translation?: Maybe + /** Represents a value of an attribute. */ + attributeValue?: Maybe +} + +export type AttributeValueTranslatableContentTranslationArgs = { + languageCode: LanguageCodeEnum +} + +/** Creates/Updates translations for attribute value. */ +export type AttributeValueTranslate = { + __typename?: 'AttributeValueTranslate' + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + translationErrors: Array + errors: Array + attributeValue?: Maybe +} + +export type AttributeValueTranslation = Node & { + __typename?: 'AttributeValueTranslation' + /** The ID of the object. */ + id: Scalars['ID'] + name: Scalars['String'] + richText?: Maybe + /** Translation language. */ + language: LanguageDisplay +} + +export type AttributeValueTranslationInput = { + name?: Maybe + richText?: Maybe +} + +/** Updates value of an attribute. */ +export type AttributeValueUpdate = { + __typename?: 'AttributeValueUpdate' + /** The updated attribute. */ + attribute?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + attributeErrors: Array + errors: Array + attributeValue?: Maybe +} + +export type BulkAttributeValueInput = { + /** ID of the selected attribute. */ + id?: Maybe + /** The value or slug of an attribute to resolve. If the passed value is non-existent, it will be created. */ + values: Array> +} + +export type BulkProductError = { + __typename?: 'BulkProductError' + /** Name of a field that caused the error. A value of `null` indicates that the error isn't associated with a particular field. */ + field?: Maybe + /** The error message. */ + message?: Maybe + /** The error code. */ + code: ProductErrorCode + /** List of attributes IDs which causes the error. */ + attributes?: Maybe> + /** List of attribute values IDs which causes the error. */ + values?: Maybe> + /** Index of an input list item that caused the error. */ + index?: Maybe + /** List of warehouse IDs which causes the error. */ + warehouses?: Maybe> + /** List of channel IDs which causes the error. */ + channels?: Maybe> +} + +export type BulkStockError = { + __typename?: 'BulkStockError' + /** Name of a field that caused the error. A value of `null` indicates that the error isn't associated with a particular field. */ + field?: Maybe + /** The error message. */ + message?: Maybe + /** The error code. */ + code: ProductErrorCode + /** List of attributes IDs which causes the error. */ + attributes?: Maybe> + /** List of attribute values IDs which causes the error. */ + values?: Maybe> + /** Index of an input list item that caused the error. */ + index?: Maybe +} + +export type CatalogueInput = { + /** Products related to the discount. */ + products?: Maybe>> + /** Categories related to the discount. */ + categories?: Maybe>> + /** Collections related to the discount. */ + collections?: Maybe>> +} + +/** Represents a single category of products. Categories allow to organize products in a tree-hierarchies which can be used for navigation in the storefront. */ +export type Category = Node & + ObjectWithMetadata & { + __typename?: 'Category' + /** The ID of the object. */ + id: Scalars['ID'] + seoTitle?: Maybe + seoDescription?: Maybe + name: Scalars['String'] + description?: Maybe + slug: Scalars['String'] + parent?: Maybe + level: Scalars['Int'] + /** List of private metadata items.Requires proper staff permissions to access. */ + privateMetadata: Array> + /** List of public metadata items. Can be accessed without permissions. */ + metadata: Array> + /** + * Description of the category (JSON). + * @deprecated Will be removed in Saleor 4.0. Use the `description` field instead. + */ + descriptionJson?: Maybe + /** List of ancestors of the category. */ + ancestors?: Maybe + /** List of products in the category. */ + products?: Maybe + /** List of children of the category. */ + children?: Maybe + backgroundImage?: Maybe + /** Returns translated category fields for the given language code. */ + translation?: Maybe + } + +/** Represents a single category of products. Categories allow to organize products in a tree-hierarchies which can be used for navigation in the storefront. */ +export type CategoryAncestorsArgs = { + before?: Maybe + after?: Maybe + first?: Maybe + last?: Maybe +} + +/** Represents a single category of products. Categories allow to organize products in a tree-hierarchies which can be used for navigation in the storefront. */ +export type CategoryProductsArgs = { + channel?: Maybe + before?: Maybe + after?: Maybe + first?: Maybe + last?: Maybe +} + +/** Represents a single category of products. Categories allow to organize products in a tree-hierarchies which can be used for navigation in the storefront. */ +export type CategoryChildrenArgs = { + before?: Maybe + after?: Maybe + first?: Maybe + last?: Maybe +} + +/** Represents a single category of products. Categories allow to organize products in a tree-hierarchies which can be used for navigation in the storefront. */ +export type CategoryBackgroundImageArgs = { + size?: Maybe +} + +/** Represents a single category of products. Categories allow to organize products in a tree-hierarchies which can be used for navigation in the storefront. */ +export type CategoryTranslationArgs = { + languageCode: LanguageCodeEnum +} + +/** Deletes categories. */ +export type CategoryBulkDelete = { + __typename?: 'CategoryBulkDelete' + /** Returns how many objects were affected. */ + count: Scalars['Int'] + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + productErrors: Array + errors: Array +} + +export type CategoryCountableConnection = { + __typename?: 'CategoryCountableConnection' + /** Pagination data for this connection. */ + pageInfo: PageInfo + edges: Array + /** A total count of items in the collection. */ + totalCount?: Maybe +} + +export type CategoryCountableEdge = { + __typename?: 'CategoryCountableEdge' + /** The item at the end of the edge. */ + node: Category + /** A cursor for use in pagination. */ + cursor: Scalars['String'] +} + +/** Creates a new category. */ +export type CategoryCreate = { + __typename?: 'CategoryCreate' + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + productErrors: Array + errors: Array + category?: Maybe +} + +/** Deletes a category. */ +export type CategoryDelete = { + __typename?: 'CategoryDelete' + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + productErrors: Array + errors: Array + category?: Maybe +} + +export type CategoryFilterInput = { + search?: Maybe + metadata?: Maybe>> + ids?: Maybe>> +} + +export type CategoryInput = { + /** Category description (JSON). */ + description?: Maybe + /** Category name. */ + name?: Maybe + /** Category slug. */ + slug?: Maybe + /** Search engine optimization fields. */ + seo?: Maybe + /** Background image file. */ + backgroundImage?: Maybe + /** Alt text for a product media. */ + backgroundImageAlt?: Maybe +} + +export enum CategorySortField { + /** Sort categories by name. */ + Name = 'NAME', + /** Sort categories by product count. */ + ProductCount = 'PRODUCT_COUNT', + /** Sort categories by subcategory count. */ + SubcategoryCount = 'SUBCATEGORY_COUNT', +} + +export type CategorySortingInput = { + /** Specifies the direction in which to sort products. */ + direction: OrderDirection + /** Specifies the channel in which to sort the data. */ + channel?: Maybe + /** Sort categories by the selected field. */ + field: CategorySortField +} + +export type CategoryTranslatableContent = Node & { + __typename?: 'CategoryTranslatableContent' + /** The ID of the object. */ + id: Scalars['ID'] + seoTitle?: Maybe + seoDescription?: Maybe + name: Scalars['String'] + description?: Maybe + /** + * Description of the category (JSON). + * @deprecated Will be removed in Saleor 4.0. Use the `description` field instead. + */ + descriptionJson?: Maybe + /** Returns translated category fields for the given language code. */ + translation?: Maybe + /** Represents a single category of products. */ + category?: Maybe +} + +export type CategoryTranslatableContentTranslationArgs = { + languageCode: LanguageCodeEnum +} + +/** Creates/Updates translations for Category. */ +export type CategoryTranslate = { + __typename?: 'CategoryTranslate' + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + translationErrors: Array + errors: Array + category?: Maybe +} + +export type CategoryTranslation = Node & { + __typename?: 'CategoryTranslation' + /** The ID of the object. */ + id: Scalars['ID'] + seoTitle?: Maybe + seoDescription?: Maybe + name: Scalars['String'] + description?: Maybe + /** Translation language. */ + language: LanguageDisplay + /** + * Translated description of the product (JSON). + * @deprecated Will be removed in Saleor 4.0. Use the `description` field instead. + */ + descriptionJson?: Maybe +} + +/** Updates a category. */ +export type CategoryUpdate = { + __typename?: 'CategoryUpdate' + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + productErrors: Array + errors: Array + category?: Maybe +} + +/** Represents channel. */ +export type Channel = Node & { + __typename?: 'Channel' + /** The ID of the object. */ + id: Scalars['ID'] + name: Scalars['String'] + isActive: Scalars['Boolean'] + slug: Scalars['String'] + currencyCode: Scalars['String'] + /** Whether a channel has associated orders. */ + hasOrders: Scalars['Boolean'] +} + +/** Activate a channel. */ +export type ChannelActivate = { + __typename?: 'ChannelActivate' + /** Activated channel. */ + channel?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + channelErrors: Array + errors: Array +} + +/** Creates new channel. */ +export type ChannelCreate = { + __typename?: 'ChannelCreate' + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + channelErrors: Array + errors: Array + channel?: Maybe +} + +export type ChannelCreateInput = { + /** isActive flag. */ + isActive?: Maybe + /** Name of the channel. */ + name: Scalars['String'] + /** Slug of the channel. */ + slug: Scalars['String'] + /** Currency of the channel. */ + currencyCode: Scalars['String'] + /** List of shipping zones to assign to the channel. */ + addShippingZones?: Maybe> +} + +/** Deactivate a channel. */ +export type ChannelDeactivate = { + __typename?: 'ChannelDeactivate' + /** Deactivated channel. */ + channel?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + channelErrors: Array + errors: Array +} + +/** Delete a channel. Orders associated with the deleted channel will be moved to the target channel. Checkouts, product availability, and pricing will be removed. */ +export type ChannelDelete = { + __typename?: 'ChannelDelete' + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + channelErrors: Array + errors: Array + channel?: Maybe +} + +export type ChannelDeleteInput = { + /** ID of channel to migrate orders from origin channel. */ + targetChannel: Scalars['ID'] +} + +export type ChannelError = { + __typename?: 'ChannelError' + /** Name of a field that caused the error. A value of `null` indicates that the error isn't associated with a particular field. */ + field?: Maybe + /** The error message. */ + message?: Maybe + /** The error code. */ + code: ChannelErrorCode + /** List of shipping zone IDs which causes the error. */ + shippingZones?: Maybe> +} + +/** An enumeration. */ +export enum ChannelErrorCode { + AlreadyExists = 'ALREADY_EXISTS', + GraphqlError = 'GRAPHQL_ERROR', + Invalid = 'INVALID', + NotFound = 'NOT_FOUND', + Required = 'REQUIRED', + Unique = 'UNIQUE', + ChannelTargetIdMustBeDifferent = 'CHANNEL_TARGET_ID_MUST_BE_DIFFERENT', + ChannelsCurrencyMustBeTheSame = 'CHANNELS_CURRENCY_MUST_BE_THE_SAME', + ChannelWithOrders = 'CHANNEL_WITH_ORDERS', + DuplicatedInputItem = 'DUPLICATED_INPUT_ITEM', +} + +/** Update a channel. */ +export type ChannelUpdate = { + __typename?: 'ChannelUpdate' + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + channelErrors: Array + errors: Array + channel?: Maybe +} + +export type ChannelUpdateInput = { + /** isActive flag. */ + isActive?: Maybe + /** Name of the channel. */ + name?: Maybe + /** Slug of the channel. */ + slug?: Maybe + /** List of shipping zones to assign to the channel. */ + addShippingZones?: Maybe> + /** List of shipping zones to unassign from the channel. */ + removeShippingZones?: Maybe> +} + +/** Checkout object. */ +export type Checkout = Node & + ObjectWithMetadata & { + __typename?: 'Checkout' + created: Scalars['DateTime'] + lastChange: Scalars['DateTime'] + user?: Maybe + channel: Channel + billingAddress?: Maybe
    + shippingAddress?: Maybe
    + note: Scalars['String'] + discount?: Maybe + discountName?: Maybe + translatedDiscountName?: Maybe + voucherCode?: Maybe + /** List of gift cards associated with this checkout. */ + giftCards?: Maybe>> + /** The ID of the object. */ + id: Scalars['ID'] + /** List of private metadata items.Requires proper staff permissions to access. */ + privateMetadata: Array> + /** List of public metadata items. Can be accessed without permissions. */ + metadata: Array> + /** Shipping methods that can be used with this order. */ + availableShippingMethods: Array> + /** List of available payment gateways. */ + availablePaymentGateways: Array + /** Email of a customer. */ + email: Scalars['String'] + /** Returns True, if checkout requires shipping. */ + isShippingRequired: Scalars['Boolean'] + /** The number of items purchased. */ + quantity: Scalars['Int'] + /** A list of checkout lines, each containing information about an item in the checkout. */ + lines?: Maybe>> + /** The price of the shipping, with all the taxes included. */ + shippingPrice?: Maybe + /** The shipping method related with checkout. */ + shippingMethod?: Maybe + /** The price of the checkout before shipping, with taxes included. */ + subtotalPrice?: Maybe + /** The checkout's token. */ + token: Scalars['UUID'] + /** The sum of the the checkout line prices, with all the taxes,shipping costs, and discounts included. */ + totalPrice?: Maybe + /** Checkout language code. */ + languageCode: LanguageCodeEnum + } + +/** Adds a gift card or a voucher to a checkout. */ +export type CheckoutAddPromoCode = { + __typename?: 'CheckoutAddPromoCode' + /** The checkout with the added gift card or voucher. */ + checkout?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + checkoutErrors: Array + errors: Array +} + +/** Update billing address in the existing checkout. */ +export type CheckoutBillingAddressUpdate = { + __typename?: 'CheckoutBillingAddressUpdate' + /** An updated checkout. */ + checkout?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + checkoutErrors: Array + errors: Array +} + +/** Completes the checkout. As a result a new order is created and a payment charge is made. This action requires a successful payment before it can be performed. In case additional confirmation step as 3D secure is required confirmationNeeded flag will be set to True and no order created until payment is confirmed with second call of this mutation. */ +export type CheckoutComplete = { + __typename?: 'CheckoutComplete' + /** Placed order. */ + order?: Maybe + /** Set to true if payment needs to be confirmed before checkout is complete. */ + confirmationNeeded: Scalars['Boolean'] + /** Confirmation data used to process additional authorization steps. */ + confirmationData?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + checkoutErrors: Array + errors: Array +} + +export type CheckoutCountableConnection = { + __typename?: 'CheckoutCountableConnection' + /** Pagination data for this connection. */ + pageInfo: PageInfo + edges: Array + /** A total count of items in the collection. */ + totalCount?: Maybe +} + +export type CheckoutCountableEdge = { + __typename?: 'CheckoutCountableEdge' + /** The item at the end of the edge. */ + node: Checkout + /** A cursor for use in pagination. */ + cursor: Scalars['String'] +} + +/** Create a new checkout. */ +export type CheckoutCreate = { + __typename?: 'CheckoutCreate' + /** Whether the checkout was created or the current active one was returned. Refer to checkoutLinesAdd and checkoutLinesUpdate to merge a cart with an active checkout.DEPRECATED: Will be removed in Saleor 4.0. Always returns True. */ + created?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + checkoutErrors: Array + errors: Array + checkout?: Maybe +} + +export type CheckoutCreateInput = { + /** Slug of a channel in which to create a checkout. */ + channel?: Maybe + /** A list of checkout lines, each containing information about an item in the checkout. */ + lines: Array> + /** The customer's email address. */ + email?: Maybe + /** The mailing address to where the checkout will be shipped. Note: the address will be ignored if the checkout doesn't contain shippable items. */ + shippingAddress?: Maybe + /** Billing address of the customer. */ + billingAddress?: Maybe + /** Checkout language code. */ + languageCode?: Maybe +} + +/** Sets the customer as the owner of the checkout. */ +export type CheckoutCustomerAttach = { + __typename?: 'CheckoutCustomerAttach' + /** An updated checkout. */ + checkout?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + checkoutErrors: Array + errors: Array +} + +/** Removes the user assigned as the owner of the checkout. */ +export type CheckoutCustomerDetach = { + __typename?: 'CheckoutCustomerDetach' + /** An updated checkout. */ + checkout?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + checkoutErrors: Array + errors: Array +} + +/** Updates email address in the existing checkout object. */ +export type CheckoutEmailUpdate = { + __typename?: 'CheckoutEmailUpdate' + /** An updated checkout. */ + checkout?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + checkoutErrors: Array + errors: Array +} + +export type CheckoutError = { + __typename?: 'CheckoutError' + /** Name of a field that caused the error. A value of `null` indicates that the error isn't associated with a particular field. */ + field?: Maybe + /** The error message. */ + message?: Maybe + /** The error code. */ + code: CheckoutErrorCode + /** List of varint IDs which causes the error. */ + variants?: Maybe> + /** A type of address that causes the error. */ + addressType?: Maybe +} + +/** An enumeration. */ +export enum CheckoutErrorCode { + BillingAddressNotSet = 'BILLING_ADDRESS_NOT_SET', + CheckoutNotFullyPaid = 'CHECKOUT_NOT_FULLY_PAID', + GraphqlError = 'GRAPHQL_ERROR', + ProductNotPublished = 'PRODUCT_NOT_PUBLISHED', + ProductUnavailableForPurchase = 'PRODUCT_UNAVAILABLE_FOR_PURCHASE', + InsufficientStock = 'INSUFFICIENT_STOCK', + Invalid = 'INVALID', + InvalidShippingMethod = 'INVALID_SHIPPING_METHOD', + NotFound = 'NOT_FOUND', + PaymentError = 'PAYMENT_ERROR', + QuantityGreaterThanLimit = 'QUANTITY_GREATER_THAN_LIMIT', + Required = 'REQUIRED', + ShippingAddressNotSet = 'SHIPPING_ADDRESS_NOT_SET', + ShippingMethodNotApplicable = 'SHIPPING_METHOD_NOT_APPLICABLE', + ShippingMethodNotSet = 'SHIPPING_METHOD_NOT_SET', + ShippingNotRequired = 'SHIPPING_NOT_REQUIRED', + TaxError = 'TAX_ERROR', + Unique = 'UNIQUE', + VoucherNotApplicable = 'VOUCHER_NOT_APPLICABLE', + ZeroQuantity = 'ZERO_QUANTITY', + MissingChannelSlug = 'MISSING_CHANNEL_SLUG', + ChannelInactive = 'CHANNEL_INACTIVE', + UnavailableVariantInChannel = 'UNAVAILABLE_VARIANT_IN_CHANNEL', +} + +/** Update language code in the existing checkout. */ +export type CheckoutLanguageCodeUpdate = { + __typename?: 'CheckoutLanguageCodeUpdate' + /** An updated checkout. */ + checkout?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + checkoutErrors: Array + errors: Array +} + +/** Represents an item in the checkout. */ +export type CheckoutLine = Node & { + __typename?: 'CheckoutLine' + /** The ID of the object. */ + id: Scalars['ID'] + variant: ProductVariant + quantity: Scalars['Int'] + /** The sum of the checkout line price, taxes and discounts. */ + totalPrice?: Maybe + /** Indicates whether the item need to be delivered. */ + requiresShipping?: Maybe +} + +export type CheckoutLineCountableConnection = { + __typename?: 'CheckoutLineCountableConnection' + /** Pagination data for this connection. */ + pageInfo: PageInfo + edges: Array + /** A total count of items in the collection. */ + totalCount?: Maybe +} + +export type CheckoutLineCountableEdge = { + __typename?: 'CheckoutLineCountableEdge' + /** The item at the end of the edge. */ + node: CheckoutLine + /** A cursor for use in pagination. */ + cursor: Scalars['String'] +} + +/** Deletes a CheckoutLine. */ +export type CheckoutLineDelete = { + __typename?: 'CheckoutLineDelete' + /** An updated checkout. */ + checkout?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + checkoutErrors: Array + errors: Array +} + +export type CheckoutLineInput = { + /** The number of items purchased. */ + quantity: Scalars['Int'] + /** ID of the product variant. */ + variantId: Scalars['ID'] +} + +/** Adds a checkout line to the existing checkout. */ +export type CheckoutLinesAdd = { + __typename?: 'CheckoutLinesAdd' + /** An updated checkout. */ + checkout?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + checkoutErrors: Array + errors: Array +} + +/** Updates checkout line in the existing checkout. */ +export type CheckoutLinesUpdate = { + __typename?: 'CheckoutLinesUpdate' + /** An updated checkout. */ + checkout?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + checkoutErrors: Array + errors: Array +} + +/** Create a new payment for given checkout. */ +export type CheckoutPaymentCreate = { + __typename?: 'CheckoutPaymentCreate' + /** Related checkout object. */ + checkout?: Maybe + /** A newly created payment. */ + payment?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + paymentErrors: Array + errors: Array +} + +/** Remove a gift card or a voucher from a checkout. */ +export type CheckoutRemovePromoCode = { + __typename?: 'CheckoutRemovePromoCode' + /** The checkout with the removed gift card or voucher. */ + checkout?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + checkoutErrors: Array + errors: Array +} + +/** Update shipping address in the existing checkout. */ +export type CheckoutShippingAddressUpdate = { + __typename?: 'CheckoutShippingAddressUpdate' + /** An updated checkout. */ + checkout?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + checkoutErrors: Array + errors: Array +} + +/** Updates the shipping address of the checkout. */ +export type CheckoutShippingMethodUpdate = { + __typename?: 'CheckoutShippingMethodUpdate' + /** An updated checkout. */ + checkout?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + checkoutErrors: Array + errors: Array +} + +export type ChoiceValue = { + __typename?: 'ChoiceValue' + raw?: Maybe + verbose?: Maybe +} + +/** Represents a collection of products. */ +export type Collection = Node & + ObjectWithMetadata & { + __typename?: 'Collection' + /** The ID of the object. */ + id: Scalars['ID'] + seoTitle?: Maybe + seoDescription?: Maybe + name: Scalars['String'] + description?: Maybe + slug: Scalars['String'] + /** List of private metadata items.Requires proper staff permissions to access. */ + privateMetadata: Array> + /** List of public metadata items. Can be accessed without permissions. */ + metadata: Array> + /** + * Description of the collection (JSON). + * @deprecated Will be removed in Saleor 4.0. Use the `description` field instead. + */ + descriptionJson?: Maybe + /** List of products in this collection. */ + products?: Maybe + backgroundImage?: Maybe + /** Returns translated collection fields for the given language code. */ + translation?: Maybe + /** List of channels in which the collection is available. */ + channelListings?: Maybe> + } + +/** Represents a collection of products. */ +export type CollectionProductsArgs = { + filter?: Maybe + sortBy?: Maybe + before?: Maybe + after?: Maybe + first?: Maybe + last?: Maybe +} + +/** Represents a collection of products. */ +export type CollectionBackgroundImageArgs = { + size?: Maybe +} + +/** Represents a collection of products. */ +export type CollectionTranslationArgs = { + languageCode: LanguageCodeEnum +} + +/** Adds products to a collection. */ +export type CollectionAddProducts = { + __typename?: 'CollectionAddProducts' + /** Collection to which products will be added. */ + collection?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + collectionErrors: Array + errors: Array +} + +/** Deletes collections. */ +export type CollectionBulkDelete = { + __typename?: 'CollectionBulkDelete' + /** Returns how many objects were affected. */ + count: Scalars['Int'] + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + collectionErrors: Array + errors: Array +} + +/** Represents collection channel listing. */ +export type CollectionChannelListing = Node & { + __typename?: 'CollectionChannelListing' + /** The ID of the object. */ + id: Scalars['ID'] + publicationDate?: Maybe + isPublished: Scalars['Boolean'] + channel: Channel +} + +export type CollectionChannelListingError = { + __typename?: 'CollectionChannelListingError' + /** Name of a field that caused the error. A value of `null` indicates that the error isn't associated with a particular field. */ + field?: Maybe + /** The error message. */ + message?: Maybe + /** The error code. */ + code: ProductErrorCode + /** List of attributes IDs which causes the error. */ + attributes?: Maybe> + /** List of attribute values IDs which causes the error. */ + values?: Maybe> + /** List of channels IDs which causes the error. */ + channels?: Maybe> +} + +/** Manage collection's availability in channels. */ +export type CollectionChannelListingUpdate = { + __typename?: 'CollectionChannelListingUpdate' + /** An updated collection instance. */ + collection?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + collectionChannelListingErrors: Array + errors: Array +} + +export type CollectionChannelListingUpdateInput = { + /** List of channels to which the collection should be assigned. */ + addChannels?: Maybe> + /** List of channels from which the collection should be unassigned. */ + removeChannels?: Maybe> +} + +export type CollectionCountableConnection = { + __typename?: 'CollectionCountableConnection' + /** Pagination data for this connection. */ + pageInfo: PageInfo + edges: Array + /** A total count of items in the collection. */ + totalCount?: Maybe +} + +export type CollectionCountableEdge = { + __typename?: 'CollectionCountableEdge' + /** The item at the end of the edge. */ + node: Collection + /** A cursor for use in pagination. */ + cursor: Scalars['String'] +} + +/** Creates a new collection. */ +export type CollectionCreate = { + __typename?: 'CollectionCreate' + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + collectionErrors: Array + errors: Array + collection?: Maybe +} + +export type CollectionCreateInput = { + /** Informs whether a collection is published. */ + isPublished?: Maybe + /** Name of the collection. */ + name?: Maybe + /** Slug of the collection. */ + slug?: Maybe + /** Description of the collection (JSON). */ + description?: Maybe + /** Background image file. */ + backgroundImage?: Maybe + /** Alt text for an image. */ + backgroundImageAlt?: Maybe + /** Search engine optimization fields. */ + seo?: Maybe + /** Publication date. ISO 8601 standard. */ + publicationDate?: Maybe + /** List of products to be added to the collection. */ + products?: Maybe>> +} + +/** Deletes a collection. */ +export type CollectionDelete = { + __typename?: 'CollectionDelete' + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + collectionErrors: Array + errors: Array + collection?: Maybe +} + +export type CollectionError = { + __typename?: 'CollectionError' + /** Name of a field that caused the error. A value of `null` indicates that the error isn't associated with a particular field. */ + field?: Maybe + /** The error message. */ + message?: Maybe + /** List of products IDs which causes the error. */ + products?: Maybe> + /** The error code. */ + code: CollectionErrorCode +} + +/** An enumeration. */ +export enum CollectionErrorCode { + DuplicatedInputItem = 'DUPLICATED_INPUT_ITEM', + GraphqlError = 'GRAPHQL_ERROR', + Invalid = 'INVALID', + NotFound = 'NOT_FOUND', + Required = 'REQUIRED', + Unique = 'UNIQUE', + CannotManageProductWithoutVariant = 'CANNOT_MANAGE_PRODUCT_WITHOUT_VARIANT', +} + +export type CollectionFilterInput = { + published?: Maybe + search?: Maybe + metadata?: Maybe>> + ids?: Maybe>> + /** Specifies the channel by which the data should be sorted. */ + channel?: Maybe +} + +export type CollectionInput = { + /** Informs whether a collection is published. */ + isPublished?: Maybe + /** Name of the collection. */ + name?: Maybe + /** Slug of the collection. */ + slug?: Maybe + /** Description of the collection (JSON). */ + description?: Maybe + /** Background image file. */ + backgroundImage?: Maybe + /** Alt text for an image. */ + backgroundImageAlt?: Maybe + /** Search engine optimization fields. */ + seo?: Maybe + /** Publication date. ISO 8601 standard. */ + publicationDate?: Maybe +} + +export enum CollectionPublished { + Published = 'PUBLISHED', + Hidden = 'HIDDEN', +} + +/** Remove products from a collection. */ +export type CollectionRemoveProducts = { + __typename?: 'CollectionRemoveProducts' + /** Collection from which products will be removed. */ + collection?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + collectionErrors: Array + errors: Array +} + +/** Reorder the products of a collection. */ +export type CollectionReorderProducts = { + __typename?: 'CollectionReorderProducts' + /** Collection from which products are reordered. */ + collection?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + collectionErrors: Array + errors: Array +} + +export enum CollectionSortField { + /** Sort collections by name. */ + Name = 'NAME', + /** Sort collections by availability. */ + Availability = 'AVAILABILITY', + /** Sort collections by product count. */ + ProductCount = 'PRODUCT_COUNT', + /** Sort collections by publication date. */ + PublicationDate = 'PUBLICATION_DATE', +} + +export type CollectionSortingInput = { + /** Specifies the direction in which to sort products. */ + direction: OrderDirection + /** Specifies the channel in which to sort the data. */ + channel?: Maybe + /** Sort collections by the selected field. */ + field: CollectionSortField +} + +export type CollectionTranslatableContent = Node & { + __typename?: 'CollectionTranslatableContent' + /** The ID of the object. */ + id: Scalars['ID'] + seoTitle?: Maybe + seoDescription?: Maybe + name: Scalars['String'] + description?: Maybe + /** + * Description of the collection (JSON). + * @deprecated Will be removed in Saleor 4.0. Use the `description` field instead. + */ + descriptionJson?: Maybe + /** Returns translated collection fields for the given language code. */ + translation?: Maybe + /** Represents a collection of products. */ + collection?: Maybe +} + +export type CollectionTranslatableContentTranslationArgs = { + languageCode: LanguageCodeEnum +} + +/** Creates/Updates translations for collection. */ +export type CollectionTranslate = { + __typename?: 'CollectionTranslate' + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + translationErrors: Array + errors: Array + collection?: Maybe +} + +export type CollectionTranslation = Node & { + __typename?: 'CollectionTranslation' + /** The ID of the object. */ + id: Scalars['ID'] + seoTitle?: Maybe + seoDescription?: Maybe + name: Scalars['String'] + description?: Maybe + /** Translation language. */ + language: LanguageDisplay + /** + * Translated description of the product (JSON). + * @deprecated Will be removed in Saleor 4.0. Use the `description` field instead. + */ + descriptionJson?: Maybe +} + +/** Updates a collection. */ +export type CollectionUpdate = { + __typename?: 'CollectionUpdate' + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + collectionErrors: Array + errors: Array + collection?: Maybe +} + +/** Stores information about a single configuration field. */ +export type ConfigurationItem = { + __typename?: 'ConfigurationItem' + /** Name of the field. */ + name: Scalars['String'] + /** Current value of the field. */ + value?: Maybe + /** Type of the field. */ + type?: Maybe + /** Help text for the field. */ + helpText?: Maybe + /** Label for the field. */ + label?: Maybe +} + +export type ConfigurationItemInput = { + /** Name of the field to update. */ + name: Scalars['String'] + /** Value of the given field to update. */ + value?: Maybe +} + +/** An enumeration. */ +export enum ConfigurationTypeFieldEnum { + String = 'STRING', + Multiline = 'MULTILINE', + Boolean = 'BOOLEAN', + Secret = 'SECRET', + Password = 'PASSWORD', + Secretmultiline = 'SECRETMULTILINE', + Output = 'OUTPUT', +} + +/** Confirm user account with token sent by email during registration. */ +export type ConfirmAccount = { + __typename?: 'ConfirmAccount' + /** An activated user account. */ + user?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + accountErrors: Array + errors: Array +} + +/** Confirm the email change of the logged-in user. */ +export type ConfirmEmailChange = { + __typename?: 'ConfirmEmailChange' + /** A user instance with a new email. */ + user?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + accountErrors: Array + errors: Array +} + +/** An enumeration. */ +export enum CountryCode { + Af = 'AF', + Ax = 'AX', + Al = 'AL', + Dz = 'DZ', + As = 'AS', + Ad = 'AD', + Ao = 'AO', + Ai = 'AI', + Aq = 'AQ', + Ag = 'AG', + Ar = 'AR', + Am = 'AM', + Aw = 'AW', + Au = 'AU', + At = 'AT', + Az = 'AZ', + Bs = 'BS', + Bh = 'BH', + Bd = 'BD', + Bb = 'BB', + By = 'BY', + Be = 'BE', + Bz = 'BZ', + Bj = 'BJ', + Bm = 'BM', + Bt = 'BT', + Bo = 'BO', + Bq = 'BQ', + Ba = 'BA', + Bw = 'BW', + Bv = 'BV', + Br = 'BR', + Io = 'IO', + Bn = 'BN', + Bg = 'BG', + Bf = 'BF', + Bi = 'BI', + Cv = 'CV', + Kh = 'KH', + Cm = 'CM', + Ca = 'CA', + Ky = 'KY', + Cf = 'CF', + Td = 'TD', + Cl = 'CL', + Cn = 'CN', + Cx = 'CX', + Cc = 'CC', + Co = 'CO', + Km = 'KM', + Cg = 'CG', + Cd = 'CD', + Ck = 'CK', + Cr = 'CR', + Ci = 'CI', + Hr = 'HR', + Cu = 'CU', + Cw = 'CW', + Cy = 'CY', + Cz = 'CZ', + Dk = 'DK', + Dj = 'DJ', + Dm = 'DM', + Do = 'DO', + Ec = 'EC', + Eg = 'EG', + Sv = 'SV', + Gq = 'GQ', + Er = 'ER', + Ee = 'EE', + Sz = 'SZ', + Et = 'ET', + Eu = 'EU', + Fk = 'FK', + Fo = 'FO', + Fj = 'FJ', + Fi = 'FI', + Fr = 'FR', + Gf = 'GF', + Pf = 'PF', + Tf = 'TF', + Ga = 'GA', + Gm = 'GM', + Ge = 'GE', + De = 'DE', + Gh = 'GH', + Gi = 'GI', + Gr = 'GR', + Gl = 'GL', + Gd = 'GD', + Gp = 'GP', + Gu = 'GU', + Gt = 'GT', + Gg = 'GG', + Gn = 'GN', + Gw = 'GW', + Gy = 'GY', + Ht = 'HT', + Hm = 'HM', + Va = 'VA', + Hn = 'HN', + Hk = 'HK', + Hu = 'HU', + Is = 'IS', + In = 'IN', + Id = 'ID', + Ir = 'IR', + Iq = 'IQ', + Ie = 'IE', + Im = 'IM', + Il = 'IL', + It = 'IT', + Jm = 'JM', + Jp = 'JP', + Je = 'JE', + Jo = 'JO', + Kz = 'KZ', + Ke = 'KE', + Ki = 'KI', + Kw = 'KW', + Kg = 'KG', + La = 'LA', + Lv = 'LV', + Lb = 'LB', + Ls = 'LS', + Lr = 'LR', + Ly = 'LY', + Li = 'LI', + Lt = 'LT', + Lu = 'LU', + Mo = 'MO', + Mg = 'MG', + Mw = 'MW', + My = 'MY', + Mv = 'MV', + Ml = 'ML', + Mt = 'MT', + Mh = 'MH', + Mq = 'MQ', + Mr = 'MR', + Mu = 'MU', + Yt = 'YT', + Mx = 'MX', + Fm = 'FM', + Md = 'MD', + Mc = 'MC', + Mn = 'MN', + Me = 'ME', + Ms = 'MS', + Ma = 'MA', + Mz = 'MZ', + Mm = 'MM', + Na = 'NA', + Nr = 'NR', + Np = 'NP', + Nl = 'NL', + Nc = 'NC', + Nz = 'NZ', + Ni = 'NI', + Ne = 'NE', + Ng = 'NG', + Nu = 'NU', + Nf = 'NF', + Kp = 'KP', + Mk = 'MK', + Mp = 'MP', + No = 'NO', + Om = 'OM', + Pk = 'PK', + Pw = 'PW', + Ps = 'PS', + Pa = 'PA', + Pg = 'PG', + Py = 'PY', + Pe = 'PE', + Ph = 'PH', + Pn = 'PN', + Pl = 'PL', + Pt = 'PT', + Pr = 'PR', + Qa = 'QA', + Re = 'RE', + Ro = 'RO', + Ru = 'RU', + Rw = 'RW', + Bl = 'BL', + Sh = 'SH', + Kn = 'KN', + Lc = 'LC', + Mf = 'MF', + Pm = 'PM', + Vc = 'VC', + Ws = 'WS', + Sm = 'SM', + St = 'ST', + Sa = 'SA', + Sn = 'SN', + Rs = 'RS', + Sc = 'SC', + Sl = 'SL', + Sg = 'SG', + Sx = 'SX', + Sk = 'SK', + Si = 'SI', + Sb = 'SB', + So = 'SO', + Za = 'ZA', + Gs = 'GS', + Kr = 'KR', + Ss = 'SS', + Es = 'ES', + Lk = 'LK', + Sd = 'SD', + Sr = 'SR', + Sj = 'SJ', + Se = 'SE', + Ch = 'CH', + Sy = 'SY', + Tw = 'TW', + Tj = 'TJ', + Tz = 'TZ', + Th = 'TH', + Tl = 'TL', + Tg = 'TG', + Tk = 'TK', + To = 'TO', + Tt = 'TT', + Tn = 'TN', + Tr = 'TR', + Tm = 'TM', + Tc = 'TC', + Tv = 'TV', + Ug = 'UG', + Ua = 'UA', + Ae = 'AE', + Gb = 'GB', + Um = 'UM', + Us = 'US', + Uy = 'UY', + Uz = 'UZ', + Vu = 'VU', + Ve = 'VE', + Vn = 'VN', + Vg = 'VG', + Vi = 'VI', + Wf = 'WF', + Eh = 'EH', + Ye = 'YE', + Zm = 'ZM', + Zw = 'ZW', +} + +export type CountryDisplay = { + __typename?: 'CountryDisplay' + /** Country code. */ + code: Scalars['String'] + /** Country name. */ + country: Scalars['String'] + /** Country tax. */ + vat?: Maybe +} + +/** Create JWT token. */ +export type CreateToken = { + __typename?: 'CreateToken' + /** JWT token, required to authenticate. */ + token?: Maybe + /** JWT refresh token, required to re-generate access token. */ + refreshToken?: Maybe + /** CSRF token required to re-generate access token. */ + csrfToken?: Maybe + /** A user instance. */ + user?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + accountErrors: Array + errors: Array +} + +export type CreditCard = { + __typename?: 'CreditCard' + /** Card brand. */ + brand: Scalars['String'] + /** First 4 digits of the card number. */ + firstDigits?: Maybe + /** Last 4 digits of the card number. */ + lastDigits: Scalars['String'] + /** Two-digit number representing the card’s expiration month. */ + expMonth?: Maybe + /** Four-digit number representing the card’s expiration year. */ + expYear?: Maybe +} + +/** Deletes customers. */ +export type CustomerBulkDelete = { + __typename?: 'CustomerBulkDelete' + /** Returns how many objects were affected. */ + count: Scalars['Int'] + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + accountErrors: Array + errors: Array +} + +/** Creates a new customer. */ +export type CustomerCreate = { + __typename?: 'CustomerCreate' + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + accountErrors: Array + errors: Array + user?: Maybe +} + +/** Deletes a customer. */ +export type CustomerDelete = { + __typename?: 'CustomerDelete' + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + accountErrors: Array + errors: Array + user?: Maybe +} + +/** History log of the customer. */ +export type CustomerEvent = Node & { + __typename?: 'CustomerEvent' + /** The ID of the object. */ + id: Scalars['ID'] + /** Date when event happened at in ISO 8601 format. */ + date?: Maybe + /** Customer event type. */ + type?: Maybe + /** User who performed the action. */ + user?: Maybe + /** Content of the event. */ + message?: Maybe + /** Number of objects concerned by the event. */ + count?: Maybe + /** The concerned order. */ + order?: Maybe + /** The concerned order line. */ + orderLine?: Maybe +} + +/** An enumeration. */ +export enum CustomerEventsEnum { + AccountCreated = 'ACCOUNT_CREATED', + PasswordResetLinkSent = 'PASSWORD_RESET_LINK_SENT', + PasswordReset = 'PASSWORD_RESET', + EmailChangedRequest = 'EMAIL_CHANGED_REQUEST', + PasswordChanged = 'PASSWORD_CHANGED', + EmailChanged = 'EMAIL_CHANGED', + PlacedOrder = 'PLACED_ORDER', + NoteAddedToOrder = 'NOTE_ADDED_TO_ORDER', + DigitalLinkDownloaded = 'DIGITAL_LINK_DOWNLOADED', + CustomerDeleted = 'CUSTOMER_DELETED', + NameAssigned = 'NAME_ASSIGNED', + EmailAssigned = 'EMAIL_ASSIGNED', + NoteAdded = 'NOTE_ADDED', +} + +export type CustomerFilterInput = { + dateJoined?: Maybe + numberOfOrders?: Maybe + placedOrders?: Maybe + search?: Maybe +} + +export type CustomerInput = { + /** Billing address of the customer. */ + defaultBillingAddress?: Maybe + /** Shipping address of the customer. */ + defaultShippingAddress?: Maybe + /** Given name. */ + firstName?: Maybe + /** Family name. */ + lastName?: Maybe + /** The unique email address of the user. */ + email?: Maybe + /** User account is active. */ + isActive?: Maybe + /** A note about the user. */ + note?: Maybe + /** User language code. */ + languageCode?: Maybe +} + +/** Updates an existing customer. */ +export type CustomerUpdate = { + __typename?: 'CustomerUpdate' + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + accountErrors: Array + errors: Array + user?: Maybe +} + +export type DateRangeInput = { + /** Start date. */ + gte?: Maybe + /** End date. */ + lte?: Maybe +} + +export type DateTimeRangeInput = { + /** Start date. */ + gte?: Maybe + /** End date. */ + lte?: Maybe +} + +/** Deactivate all JWT tokens of the currently authenticated user. */ +export type DeactivateAllUserTokens = { + __typename?: 'DeactivateAllUserTokens' + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + accountErrors: Array + errors: Array +} + +/** Delete metadata of an object. */ +export type DeleteMetadata = { + __typename?: 'DeleteMetadata' + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + metadataErrors: Array + errors: Array + item?: Maybe +} + +/** Delete object's private metadata. */ +export type DeletePrivateMetadata = { + __typename?: 'DeletePrivateMetadata' + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + metadataErrors: Array + errors: Array + item?: Maybe +} + +export type DigitalContent = Node & + ObjectWithMetadata & { + __typename?: 'DigitalContent' + useDefaultSettings: Scalars['Boolean'] + automaticFulfillment: Scalars['Boolean'] + contentFile: Scalars['String'] + maxDownloads?: Maybe + urlValidDays?: Maybe + /** List of URLs for the digital variant. */ + urls?: Maybe>> + /** The ID of the object. */ + id: Scalars['ID'] + /** List of private metadata items.Requires proper staff permissions to access. */ + privateMetadata: Array> + /** List of public metadata items. Can be accessed without permissions. */ + metadata: Array> + /** Product variant assigned to digital content. */ + productVariant: ProductVariant + } + +export type DigitalContentCountableConnection = { + __typename?: 'DigitalContentCountableConnection' + /** Pagination data for this connection. */ + pageInfo: PageInfo + edges: Array + /** A total count of items in the collection. */ + totalCount?: Maybe +} + +export type DigitalContentCountableEdge = { + __typename?: 'DigitalContentCountableEdge' + /** The item at the end of the edge. */ + node: DigitalContent + /** A cursor for use in pagination. */ + cursor: Scalars['String'] +} + +/** Create new digital content. This mutation must be sent as a `multipart` request. More detailed specs of the upload format can be found here: https://github.com/jaydenseric/graphql-multipart-request-spec */ +export type DigitalContentCreate = { + __typename?: 'DigitalContentCreate' + variant?: Maybe + content?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + productErrors: Array + errors: Array +} + +/** Remove digital content assigned to given variant. */ +export type DigitalContentDelete = { + __typename?: 'DigitalContentDelete' + variant?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + productErrors: Array + errors: Array +} + +export type DigitalContentInput = { + /** Use default digital content settings for this product. */ + useDefaultSettings: Scalars['Boolean'] + /** Determines how many times a download link can be accessed by a customer. */ + maxDownloads?: Maybe + /** Determines for how many days a download link is active since it was generated. */ + urlValidDays?: Maybe + /** Overwrite default automatic_fulfillment setting for variant. */ + automaticFulfillment?: Maybe +} + +/** Update digital content. */ +export type DigitalContentUpdate = { + __typename?: 'DigitalContentUpdate' + variant?: Maybe + content?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + productErrors: Array + errors: Array +} + +export type DigitalContentUploadInput = { + /** Use default digital content settings for this product. */ + useDefaultSettings: Scalars['Boolean'] + /** Determines how many times a download link can be accessed by a customer. */ + maxDownloads?: Maybe + /** Determines for how many days a download link is active since it was generated. */ + urlValidDays?: Maybe + /** Overwrite default automatic_fulfillment setting for variant. */ + automaticFulfillment?: Maybe + /** Represents an file in a multipart request. */ + contentFile: Scalars['Upload'] +} + +export type DigitalContentUrl = Node & { + __typename?: 'DigitalContentUrl' + content: DigitalContent + created: Scalars['DateTime'] + downloadNum: Scalars['Int'] + /** The ID of the object. */ + id: Scalars['ID'] + /** URL for digital content. */ + url?: Maybe + /** UUID of digital content. */ + token: Scalars['UUID'] +} + +/** Generate new URL to digital content. */ +export type DigitalContentUrlCreate = { + __typename?: 'DigitalContentUrlCreate' + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + productErrors: Array + errors: Array + digitalContentUrl?: Maybe +} + +export type DigitalContentUrlCreateInput = { + /** Digital content ID which URL will belong to. */ + content: Scalars['ID'] +} + +export type DiscountError = { + __typename?: 'DiscountError' + /** Name of a field that caused the error. A value of `null` indicates that the error isn't associated with a particular field. */ + field?: Maybe + /** The error message. */ + message?: Maybe + /** List of products IDs which causes the error. */ + products?: Maybe> + /** The error code. */ + code: DiscountErrorCode + /** List of channels IDs which causes the error. */ + channels?: Maybe> +} + +/** An enumeration. */ +export enum DiscountErrorCode { + AlreadyExists = 'ALREADY_EXISTS', + GraphqlError = 'GRAPHQL_ERROR', + Invalid = 'INVALID', + NotFound = 'NOT_FOUND', + Required = 'REQUIRED', + Unique = 'UNIQUE', + CannotManageProductWithoutVariant = 'CANNOT_MANAGE_PRODUCT_WITHOUT_VARIANT', + DuplicatedInputItem = 'DUPLICATED_INPUT_ITEM', +} + +export enum DiscountStatusEnum { + Active = 'ACTIVE', + Expired = 'EXPIRED', + Scheduled = 'SCHEDULED', +} + +export enum DiscountValueTypeEnum { + Fixed = 'FIXED', + Percentage = 'PERCENTAGE', +} + +/** An enumeration. */ +export enum DistanceUnitsEnum { + Cm = 'CM', + M = 'M', + Km = 'KM', + Ft = 'FT', + Yd = 'YD', + Inch = 'INCH', +} + +/** Represents shop's domain. */ +export type Domain = { + __typename?: 'Domain' + /** The host name of the domain. */ + host: Scalars['String'] + /** Inform if SSL is enabled. */ + sslEnabled: Scalars['Boolean'] + /** Shop's absolute URL. */ + url: Scalars['String'] +} + +/** Deletes draft orders. */ +export type DraftOrderBulkDelete = { + __typename?: 'DraftOrderBulkDelete' + /** Returns how many objects were affected. */ + count: Scalars['Int'] + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + orderErrors: Array + errors: Array +} + +/** Completes creating an order. */ +export type DraftOrderComplete = { + __typename?: 'DraftOrderComplete' + /** Completed order. */ + order?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + orderErrors: Array + errors: Array +} + +/** Creates a new draft order. */ +export type DraftOrderCreate = { + __typename?: 'DraftOrderCreate' + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + orderErrors: Array + errors: Array + order?: Maybe +} + +export type DraftOrderCreateInput = { + /** Billing address of the customer. */ + billingAddress?: Maybe + user?: Maybe + /** Email address of the customer. */ + userEmail?: Maybe + /** Discount amount for the order. */ + discount?: Maybe + /** Shipping address of the customer. */ + shippingAddress?: Maybe + /** ID of a selected shipping method. */ + shippingMethod?: Maybe + /** ID of the voucher associated with the order. */ + voucher?: Maybe + /** A note from a customer. Visible by customers in the order summary. */ + customerNote?: Maybe + /** ID of the channel associated with the order. */ + channel?: Maybe + /** URL of a view where users should be redirected to see the order details. URL in RFC 1808 format. */ + redirectUrl?: Maybe + /** Variant line input consisting of variant ID and quantity of products. */ + lines?: Maybe>> +} + +/** Deletes a draft order. */ +export type DraftOrderDelete = { + __typename?: 'DraftOrderDelete' + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + orderErrors: Array + errors: Array + order?: Maybe +} + +export type DraftOrderInput = { + /** Billing address of the customer. */ + billingAddress?: Maybe + user?: Maybe + /** Email address of the customer. */ + userEmail?: Maybe + /** Discount amount for the order. */ + discount?: Maybe + /** Shipping address of the customer. */ + shippingAddress?: Maybe + /** ID of a selected shipping method. */ + shippingMethod?: Maybe + /** ID of the voucher associated with the order. */ + voucher?: Maybe + /** A note from a customer. Visible by customers in the order summary. */ + customerNote?: Maybe + /** ID of the channel associated with the order. */ + channel?: Maybe + /** URL of a view where users should be redirected to see the order details. URL in RFC 1808 format. */ + redirectUrl?: Maybe +} + +/** Deletes order lines. */ +export type DraftOrderLinesBulkDelete = { + __typename?: 'DraftOrderLinesBulkDelete' + /** Returns how many objects were affected. */ + count: Scalars['Int'] + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + orderErrors: Array + errors: Array +} + +/** Updates a draft order. */ +export type DraftOrderUpdate = { + __typename?: 'DraftOrderUpdate' + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + orderErrors: Array + errors: Array + order?: Maybe +} + +export type ExportError = { + __typename?: 'ExportError' + /** Name of a field that caused the error. A value of `null` indicates that the error isn't associated with a particular field. */ + field?: Maybe + /** The error message. */ + message?: Maybe + /** The error code. */ + code: ExportErrorCode +} + +/** An enumeration. */ +export enum ExportErrorCode { + Invalid = 'INVALID', + NotFound = 'NOT_FOUND', + Required = 'REQUIRED', +} + +/** History log of export file. */ +export type ExportEvent = Node & { + __typename?: 'ExportEvent' + /** The ID of the object. */ + id: Scalars['ID'] + /** Date when event happened at in ISO 8601 format. */ + date: Scalars['DateTime'] + /** Export event type. */ + type: ExportEventsEnum + /** User who performed the action. */ + user?: Maybe + /** App which performed the action. */ + app?: Maybe + /** Content of the event. */ + message: Scalars['String'] +} + +/** An enumeration. */ +export enum ExportEventsEnum { + ExportPending = 'EXPORT_PENDING', + ExportSuccess = 'EXPORT_SUCCESS', + ExportFailed = 'EXPORT_FAILED', + ExportDeleted = 'EXPORT_DELETED', + ExportedFileSent = 'EXPORTED_FILE_SENT', + ExportFailedInfoSent = 'EXPORT_FAILED_INFO_SENT', +} + +/** Represents a job data of exported file. */ +export type ExportFile = Node & + Job & { + __typename?: 'ExportFile' + /** The ID of the object. */ + id: Scalars['ID'] + user?: Maybe + app?: Maybe + /** Job status. */ + status: JobStatusEnum + /** Created date time of job in ISO 8601 format. */ + createdAt: Scalars['DateTime'] + /** Date time of job last update in ISO 8601 format. */ + updatedAt: Scalars['DateTime'] + /** Job message. */ + message?: Maybe + /** The URL of field to download. */ + url?: Maybe + /** List of events associated with the export. */ + events?: Maybe> + } + +export type ExportFileCountableConnection = { + __typename?: 'ExportFileCountableConnection' + /** Pagination data for this connection. */ + pageInfo: PageInfo + edges: Array + /** A total count of items in the collection. */ + totalCount?: Maybe +} + +export type ExportFileCountableEdge = { + __typename?: 'ExportFileCountableEdge' + /** The item at the end of the edge. */ + node: ExportFile + /** A cursor for use in pagination. */ + cursor: Scalars['String'] +} + +export type ExportFileFilterInput = { + createdAt?: Maybe + updatedAt?: Maybe + status?: Maybe + user?: Maybe + app?: Maybe +} + +export enum ExportFileSortField { + /** Sort export file by status. */ + Status = 'STATUS', + /** Sort export file by created at. */ + CreatedAt = 'CREATED_AT', + /** Sort export file by updated at. */ + UpdatedAt = 'UPDATED_AT', +} + +export type ExportFileSortingInput = { + /** Specifies the direction in which to sort products. */ + direction: OrderDirection + /** Sort export file by the selected field. */ + field: ExportFileSortField +} + +export type ExportInfoInput = { + /** List of attribute ids witch should be exported. */ + attributes?: Maybe> + /** List of warehouse ids witch should be exported. */ + warehouses?: Maybe> + /** List of channels ids which should be exported. */ + channels?: Maybe> + /** List of product fields witch should be exported. */ + fields?: Maybe> +} + +/** Export products to csv file. */ +export type ExportProducts = { + __typename?: 'ExportProducts' + /** The newly created export file job which is responsible for export data. */ + exportFile?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + exportErrors: Array + errors: Array +} + +export type ExportProductsInput = { + /** Determine which products should be exported. */ + scope: ExportScope + /** Filtering options for products. */ + filter?: Maybe + /** List of products IDS to export. */ + ids?: Maybe> + /** Input with info about fields which should be exported. */ + exportInfo?: Maybe + /** Type of exported file. */ + fileType: FileTypesEnum +} + +export enum ExportScope { + /** Export all products. */ + All = 'ALL', + /** Export products with given ids. */ + Ids = 'IDS', + /** Export the filtered products. */ + Filter = 'FILTER', +} + +export type ExternalAuthentication = { + __typename?: 'ExternalAuthentication' + /** ID of external authentication plugin. */ + id: Scalars['String'] + /** Name of external authentication plugin. */ + name?: Maybe +} + +/** Prepare external authentication url for user by custom plugin. */ +export type ExternalAuthenticationUrl = { + __typename?: 'ExternalAuthenticationUrl' + /** The data returned by authentication plugin. */ + authenticationData?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + accountErrors: Array + errors: Array +} + +/** Logout user by custom plugin. */ +export type ExternalLogout = { + __typename?: 'ExternalLogout' + /** The data returned by authentication plugin. */ + logoutData?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + accountErrors: Array + errors: Array +} + +/** Obtain external access tokens for user by custom plugin. */ +export type ExternalObtainAccessTokens = { + __typename?: 'ExternalObtainAccessTokens' + /** The token, required to authenticate. */ + token?: Maybe + /** The refresh token, required to re-generate external access token. */ + refreshToken?: Maybe + /** CSRF token required to re-generate external access token. */ + csrfToken?: Maybe + /** A user instance. */ + user?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + accountErrors: Array + errors: Array +} + +/** Refresh user's access by custom plugin. */ +export type ExternalRefresh = { + __typename?: 'ExternalRefresh' + /** The token, required to authenticate. */ + token?: Maybe + /** The refresh token, required to re-generate external access token. */ + refreshToken?: Maybe + /** CSRF token required to re-generate external access token. */ + csrfToken?: Maybe + /** A user instance. */ + user?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + accountErrors: Array + errors: Array +} + +/** Verify external authentication data by plugin. */ +export type ExternalVerify = { + __typename?: 'ExternalVerify' + /** User assigned to data. */ + user?: Maybe + /** Determine if authentication data is valid or not. */ + isValid: Scalars['Boolean'] + /** External data. */ + verifyData?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + accountErrors: Array + errors: Array +} + +export type File = { + __typename?: 'File' + /** The URL of the file. */ + url: Scalars['String'] + /** Content type of the file. */ + contentType?: Maybe +} + +/** An enumeration. */ +export enum FileTypesEnum { + Csv = 'CSV', + Xlsx = 'XLSX', +} + +/** Upload a file. This mutation must be sent as a `multipart` request. More detailed specs of the upload format can be found here: https://github.com/jaydenseric/graphql-multipart-request-spec */ +export type FileUpload = { + __typename?: 'FileUpload' + uploadedFile?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + uploadErrors: Array + errors: Array +} + +/** Represents order fulfillment. */ +export type Fulfillment = Node & + ObjectWithMetadata & { + __typename?: 'Fulfillment' + /** The ID of the object. */ + id: Scalars['ID'] + fulfillmentOrder: Scalars['Int'] + status: FulfillmentStatus + trackingNumber: Scalars['String'] + created: Scalars['DateTime'] + /** List of private metadata items.Requires proper staff permissions to access. */ + privateMetadata: Array> + /** List of public metadata items. Can be accessed without permissions. */ + metadata: Array> + /** List of lines for the fulfillment. */ + lines?: Maybe>> + /** User-friendly fulfillment status. */ + statusDisplay?: Maybe + /** Warehouse from fulfillment was fulfilled. */ + warehouse?: Maybe + } + +/** Cancels existing fulfillment and optionally restocks items. */ +export type FulfillmentCancel = { + __typename?: 'FulfillmentCancel' + /** A canceled fulfillment. */ + fulfillment?: Maybe + /** Order which fulfillment was cancelled. */ + order?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + orderErrors: Array + errors: Array +} + +export type FulfillmentCancelInput = { + /** ID of warehouse where items will be restock. */ + warehouseId: Scalars['ID'] +} + +/** Represents line of the fulfillment. */ +export type FulfillmentLine = Node & { + __typename?: 'FulfillmentLine' + /** The ID of the object. */ + id: Scalars['ID'] + quantity: Scalars['Int'] + orderLine?: Maybe +} + +/** Refund products. */ +export type FulfillmentRefundProducts = { + __typename?: 'FulfillmentRefundProducts' + /** A refunded fulfillment. */ + fulfillment?: Maybe + /** Order which fulfillment was refunded. */ + order?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + orderErrors: Array + errors: Array +} + +/** Return products. */ +export type FulfillmentReturnProducts = { + __typename?: 'FulfillmentReturnProducts' + /** A return fulfillment. */ + returnFulfillment?: Maybe + /** A replace fulfillment. */ + replaceFulfillment?: Maybe + /** Order which fulfillment was returned. */ + order?: Maybe + /** A draft order which was created for products with replace flag. */ + replaceOrder?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + orderErrors: Array + errors: Array +} + +/** An enumeration. */ +export enum FulfillmentStatus { + /** Fulfilled */ + Fulfilled = 'FULFILLED', + /** Refunded */ + Refunded = 'REFUNDED', + /** Returned */ + Returned = 'RETURNED', + /** Replaced */ + Replaced = 'REPLACED', + /** Refunded and returned */ + RefundedAndReturned = 'REFUNDED_AND_RETURNED', + /** Canceled */ + Canceled = 'CANCELED', +} + +/** Updates a fulfillment for an order. */ +export type FulfillmentUpdateTracking = { + __typename?: 'FulfillmentUpdateTracking' + /** A fulfillment with updated tracking. */ + fulfillment?: Maybe + /** Order for which fulfillment was updated. */ + order?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + orderErrors: Array + errors: Array +} + +export type FulfillmentUpdateTrackingInput = { + /** Fulfillment tracking number. */ + trackingNumber?: Maybe + /** If true, send an email notification to the customer. */ + notifyCustomer?: Maybe +} + +/** Payment gateway client configuration key and value pair. */ +export type GatewayConfigLine = { + __typename?: 'GatewayConfigLine' + /** Gateway config key. */ + field: Scalars['String'] + /** Gateway config value for key. */ + value?: Maybe +} + +/** A gift card is a prepaid electronic payment card accepted in stores. They can be used during checkout by providing a valid gift card codes. */ +export type GiftCard = Node & { + __typename?: 'GiftCard' + /** Gift card code. */ + code?: Maybe + /** The customer who bought a gift card. */ + user?: Maybe + created: Scalars['DateTime'] + startDate: Scalars['Date'] + endDate?: Maybe + lastUsedOn?: Maybe + isActive: Scalars['Boolean'] + initialBalance?: Maybe + currentBalance?: Maybe + /** The ID of the object. */ + id: Scalars['ID'] + /** Code in format which allows displaying in a user interface. */ + displayCode?: Maybe +} + +/** Activate a gift card. */ +export type GiftCardActivate = { + __typename?: 'GiftCardActivate' + /** A gift card to activate. */ + giftCard?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + giftCardErrors: Array + errors: Array +} + +export type GiftCardCountableConnection = { + __typename?: 'GiftCardCountableConnection' + /** Pagination data for this connection. */ + pageInfo: PageInfo + edges: Array + /** A total count of items in the collection. */ + totalCount?: Maybe +} + +export type GiftCardCountableEdge = { + __typename?: 'GiftCardCountableEdge' + /** The item at the end of the edge. */ + node: GiftCard + /** A cursor for use in pagination. */ + cursor: Scalars['String'] +} + +/** Creates a new gift card. */ +export type GiftCardCreate = { + __typename?: 'GiftCardCreate' + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + giftCardErrors: Array + errors: Array + giftCard?: Maybe +} + +export type GiftCardCreateInput = { + /** Start date of the gift card in ISO 8601 format. */ + startDate?: Maybe + /** End date of the gift card in ISO 8601 format. */ + endDate?: Maybe + /** Value of the gift card. */ + balance?: Maybe + /** The customer's email of the gift card buyer. */ + userEmail?: Maybe + /** Code to use the gift card. */ + code?: Maybe +} + +/** Deactivate a gift card. */ +export type GiftCardDeactivate = { + __typename?: 'GiftCardDeactivate' + /** A gift card to deactivate. */ + giftCard?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + giftCardErrors: Array + errors: Array +} + +export type GiftCardError = { + __typename?: 'GiftCardError' + /** Name of a field that caused the error. A value of `null` indicates that the error isn't associated with a particular field. */ + field?: Maybe + /** The error message. */ + message?: Maybe + /** The error code. */ + code: GiftCardErrorCode +} + +/** An enumeration. */ +export enum GiftCardErrorCode { + AlreadyExists = 'ALREADY_EXISTS', + GraphqlError = 'GRAPHQL_ERROR', + Invalid = 'INVALID', + NotFound = 'NOT_FOUND', + Required = 'REQUIRED', + Unique = 'UNIQUE', +} + +/** Update a gift card. */ +export type GiftCardUpdate = { + __typename?: 'GiftCardUpdate' + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + giftCardErrors: Array + errors: Array + giftCard?: Maybe +} + +export type GiftCardUpdateInput = { + /** Start date of the gift card in ISO 8601 format. */ + startDate?: Maybe + /** End date of the gift card in ISO 8601 format. */ + endDate?: Maybe + /** Value of the gift card. */ + balance?: Maybe + /** The customer's email of the gift card buyer. */ + userEmail?: Maybe +} + +/** Represents permission group data. */ +export type Group = Node & { + __typename?: 'Group' + /** The ID of the object. */ + id: Scalars['ID'] + name: Scalars['String'] + /** List of group permissions */ + permissions?: Maybe>> + /** List of group users */ + users?: Maybe>> + /** True, if the currently authenticated user has rights to manage a group. */ + userCanManage: Scalars['Boolean'] +} + +export type GroupCountableConnection = { + __typename?: 'GroupCountableConnection' + /** Pagination data for this connection. */ + pageInfo: PageInfo + edges: Array + /** A total count of items in the collection. */ + totalCount?: Maybe +} + +export type GroupCountableEdge = { + __typename?: 'GroupCountableEdge' + /** The item at the end of the edge. */ + node: Group + /** A cursor for use in pagination. */ + cursor: Scalars['String'] +} + +/** Represents an image. */ +export type Image = { + __typename?: 'Image' + /** The URL of the image. */ + url: Scalars['String'] + /** Alt text for an image. */ + alt?: Maybe +} + +export type IntRangeInput = { + /** Value greater than or equal to. */ + gte?: Maybe + /** Value less than or equal to. */ + lte?: Maybe +} + +/** Represents an Invoice. */ +export type Invoice = ObjectWithMetadata & + Job & + Node & { + __typename?: 'Invoice' + /** The ID of the object. */ + id: Scalars['ID'] + /** List of public metadata items. Can be accessed without permissions. */ + metadata: Array> + /** Job status. */ + status: JobStatusEnum + number?: Maybe + externalUrl?: Maybe + /** List of private metadata items.Requires proper staff permissions to access. */ + privateMetadata: Array> + /** Created date time of job in ISO 8601 format. */ + createdAt: Scalars['DateTime'] + /** Date time of job last update in ISO 8601 format. */ + updatedAt: Scalars['DateTime'] + /** Job message. */ + message?: Maybe + /** URL to download an invoice. */ + url?: Maybe + } + +/** Creates a ready to send invoice. */ +export type InvoiceCreate = { + __typename?: 'InvoiceCreate' + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + invoiceErrors: Array + errors: Array + invoice?: Maybe +} + +export type InvoiceCreateInput = { + /** Invoice number. */ + number: Scalars['String'] + /** URL of an invoice to download. */ + url: Scalars['String'] +} + +/** Deletes an invoice. */ +export type InvoiceDelete = { + __typename?: 'InvoiceDelete' + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + invoiceErrors: Array + errors: Array + invoice?: Maybe +} + +export type InvoiceError = { + __typename?: 'InvoiceError' + /** Name of a field that caused the error. A value of `null` indicates that the error isn't associated with a particular field. */ + field?: Maybe + /** The error message. */ + message?: Maybe + /** The error code. */ + code: InvoiceErrorCode +} + +/** An enumeration. */ +export enum InvoiceErrorCode { + Required = 'REQUIRED', + NotReady = 'NOT_READY', + UrlNotSet = 'URL_NOT_SET', + EmailNotSet = 'EMAIL_NOT_SET', + NumberNotSet = 'NUMBER_NOT_SET', + NotFound = 'NOT_FOUND', + InvalidStatus = 'INVALID_STATUS', +} + +/** Request an invoice for the order using plugin. */ +export type InvoiceRequest = { + __typename?: 'InvoiceRequest' + /** Order related to an invoice. */ + order?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + invoiceErrors: Array + errors: Array + invoice?: Maybe +} + +/** Requests deletion of an invoice. */ +export type InvoiceRequestDelete = { + __typename?: 'InvoiceRequestDelete' + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + invoiceErrors: Array + errors: Array + invoice?: Maybe +} + +/** Send an invoice notification to the customer. */ +export type InvoiceSendNotification = { + __typename?: 'InvoiceSendNotification' + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + invoiceErrors: Array + errors: Array + invoice?: Maybe +} + +/** Updates an invoice. */ +export type InvoiceUpdate = { + __typename?: 'InvoiceUpdate' + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + invoiceErrors: Array + errors: Array + invoice?: Maybe +} + +export type Job = { + /** Job status. */ + status: JobStatusEnum + /** Created date time of job in ISO 8601 format. */ + createdAt: Scalars['DateTime'] + /** Date time of job last update in ISO 8601 format. */ + updatedAt: Scalars['DateTime'] + /** Job message. */ + message?: Maybe +} + +/** An enumeration. */ +export enum JobStatusEnum { + Pending = 'PENDING', + Success = 'SUCCESS', + Failed = 'FAILED', + Deleted = 'DELETED', +} + +/** An enumeration. */ +export enum LanguageCodeEnum { + Ar = 'AR', + Az = 'AZ', + Bg = 'BG', + Bn = 'BN', + Ca = 'CA', + Cs = 'CS', + Da = 'DA', + De = 'DE', + El = 'EL', + En = 'EN', + Es = 'ES', + EsCo = 'ES_CO', + Et = 'ET', + Fa = 'FA', + Fi = 'FI', + Fr = 'FR', + Hi = 'HI', + Hu = 'HU', + Hy = 'HY', + Id = 'ID', + Is = 'IS', + It = 'IT', + Ja = 'JA', + Ka = 'KA', + Km = 'KM', + Ko = 'KO', + Lt = 'LT', + Mn = 'MN', + My = 'MY', + Nb = 'NB', + Nl = 'NL', + Pl = 'PL', + Pt = 'PT', + PtBr = 'PT_BR', + Ro = 'RO', + Ru = 'RU', + Sk = 'SK', + Sl = 'SL', + Sq = 'SQ', + Sr = 'SR', + Sv = 'SV', + Sw = 'SW', + Ta = 'TA', + Th = 'TH', + Tr = 'TR', + Uk = 'UK', + Vi = 'VI', + ZhHans = 'ZH_HANS', + ZhHant = 'ZH_HANT', +} + +export type LanguageDisplay = { + __typename?: 'LanguageDisplay' + /** ISO 639 representation of the language name. */ + code: LanguageCodeEnum + /** Full name of the language. */ + language: Scalars['String'] +} + +export type LimitInfo = { + __typename?: 'LimitInfo' + /** Defines the current resource usage. */ + currentUsage: Limits + /** Defines the allowed maximum resource usage, null means unlimited. */ + allowedUsage: Limits +} + +export type Limits = { + __typename?: 'Limits' + channels?: Maybe + orders?: Maybe + productVariants?: Maybe + staffUsers?: Maybe + warehouses?: Maybe +} + +/** The manifest definition. */ +export type Manifest = { + __typename?: 'Manifest' + identifier: Scalars['String'] + version: Scalars['String'] + name: Scalars['String'] + about?: Maybe + permissions?: Maybe>> + appUrl?: Maybe + configurationUrl?: Maybe + tokenTargetUrl?: Maybe + dataPrivacy?: Maybe + dataPrivacyUrl?: Maybe + homepageUrl?: Maybe + supportUrl?: Maybe +} + +export type Margin = { + __typename?: 'Margin' + start?: Maybe + stop?: Maybe +} + +/** An enumeration. */ +export enum MeasurementUnitsEnum { + Cm = 'CM', + M = 'M', + Km = 'KM', + Ft = 'FT', + Yd = 'YD', + Inch = 'INCH', + SqCm = 'SQ_CM', + SqM = 'SQ_M', + SqKm = 'SQ_KM', + SqFt = 'SQ_FT', + SqYd = 'SQ_YD', + SqInch = 'SQ_INCH', + CubicMillimeter = 'CUBIC_MILLIMETER', + CubicCentimeter = 'CUBIC_CENTIMETER', + CubicDecimeter = 'CUBIC_DECIMETER', + CubicMeter = 'CUBIC_METER', + Liter = 'LITER', + CubicFoot = 'CUBIC_FOOT', + CubicInch = 'CUBIC_INCH', + CubicYard = 'CUBIC_YARD', + Qt = 'QT', + Pint = 'PINT', + FlOz = 'FL_OZ', + AcreIn = 'ACRE_IN', + AcreFt = 'ACRE_FT', + G = 'G', + Lb = 'LB', + Oz = 'OZ', + Kg = 'KG', + Tonne = 'TONNE', +} + +/** Represents a single menu - an object that is used to help navigate through the store. */ +export type Menu = Node & + ObjectWithMetadata & { + __typename?: 'Menu' + /** The ID of the object. */ + id: Scalars['ID'] + name: Scalars['String'] + slug: Scalars['String'] + /** List of private metadata items.Requires proper staff permissions to access. */ + privateMetadata: Array> + /** List of public metadata items. Can be accessed without permissions. */ + metadata: Array> + items?: Maybe>> + } + +/** Deletes menus. */ +export type MenuBulkDelete = { + __typename?: 'MenuBulkDelete' + /** Returns how many objects were affected. */ + count: Scalars['Int'] + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + menuErrors: Array + errors: Array +} + +export type MenuCountableConnection = { + __typename?: 'MenuCountableConnection' + /** Pagination data for this connection. */ + pageInfo: PageInfo + edges: Array + /** A total count of items in the collection. */ + totalCount?: Maybe +} + +export type MenuCountableEdge = { + __typename?: 'MenuCountableEdge' + /** The item at the end of the edge. */ + node: Menu + /** A cursor for use in pagination. */ + cursor: Scalars['String'] +} + +/** Creates a new Menu. */ +export type MenuCreate = { + __typename?: 'MenuCreate' + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + menuErrors: Array + errors: Array + menu?: Maybe +} + +export type MenuCreateInput = { + /** Name of the menu. */ + name: Scalars['String'] + /** Slug of the menu. Will be generated if not provided. */ + slug?: Maybe + /** List of menu items. */ + items?: Maybe>> +} + +/** Deletes a menu. */ +export type MenuDelete = { + __typename?: 'MenuDelete' + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + menuErrors: Array + errors: Array + menu?: Maybe +} + +export type MenuError = { + __typename?: 'MenuError' + /** Name of a field that caused the error. A value of `null` indicates that the error isn't associated with a particular field. */ + field?: Maybe + /** The error message. */ + message?: Maybe + /** The error code. */ + code: MenuErrorCode +} + +/** An enumeration. */ +export enum MenuErrorCode { + CannotAssignNode = 'CANNOT_ASSIGN_NODE', + GraphqlError = 'GRAPHQL_ERROR', + Invalid = 'INVALID', + InvalidMenuItem = 'INVALID_MENU_ITEM', + NoMenuItemProvided = 'NO_MENU_ITEM_PROVIDED', + NotFound = 'NOT_FOUND', + Required = 'REQUIRED', + TooManyMenuItems = 'TOO_MANY_MENU_ITEMS', + Unique = 'UNIQUE', +} + +export type MenuFilterInput = { + search?: Maybe + slug?: Maybe>> + metadata?: Maybe>> +} + +export type MenuInput = { + /** Name of the menu. */ + name?: Maybe + /** Slug of the menu. */ + slug?: Maybe +} + +/** Represents a single item of the related menu. Can store categories, collection or pages. */ +export type MenuItem = Node & + ObjectWithMetadata & { + __typename?: 'MenuItem' + /** The ID of the object. */ + id: Scalars['ID'] + name: Scalars['String'] + menu: Menu + parent?: Maybe + category?: Maybe + collection?: Maybe + page?: Maybe + level: Scalars['Int'] + /** List of private metadata items.Requires proper staff permissions to access. */ + privateMetadata: Array> + /** List of public metadata items. Can be accessed without permissions. */ + metadata: Array> + children?: Maybe>> + /** URL to the menu item. */ + url?: Maybe + /** Returns translated menu item fields for the given language code. */ + translation?: Maybe + } + +/** Represents a single item of the related menu. Can store categories, collection or pages. */ +export type MenuItemTranslationArgs = { + languageCode: LanguageCodeEnum +} + +/** Deletes menu items. */ +export type MenuItemBulkDelete = { + __typename?: 'MenuItemBulkDelete' + /** Returns how many objects were affected. */ + count: Scalars['Int'] + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + menuErrors: Array + errors: Array +} + +export type MenuItemCountableConnection = { + __typename?: 'MenuItemCountableConnection' + /** Pagination data for this connection. */ + pageInfo: PageInfo + edges: Array + /** A total count of items in the collection. */ + totalCount?: Maybe +} + +export type MenuItemCountableEdge = { + __typename?: 'MenuItemCountableEdge' + /** The item at the end of the edge. */ + node: MenuItem + /** A cursor for use in pagination. */ + cursor: Scalars['String'] +} + +/** Creates a new menu item. */ +export type MenuItemCreate = { + __typename?: 'MenuItemCreate' + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + menuErrors: Array + errors: Array + menuItem?: Maybe +} + +export type MenuItemCreateInput = { + /** Name of the menu item. */ + name: Scalars['String'] + /** URL of the pointed item. */ + url?: Maybe + /** Category to which item points. */ + category?: Maybe + /** Collection to which item points. */ + collection?: Maybe + /** Page to which item points. */ + page?: Maybe + /** Menu to which item belongs. */ + menu: Scalars['ID'] + /** ID of the parent menu. If empty, menu will be top level menu. */ + parent?: Maybe +} + +/** Deletes a menu item. */ +export type MenuItemDelete = { + __typename?: 'MenuItemDelete' + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + menuErrors: Array + errors: Array + menuItem?: Maybe +} + +export type MenuItemFilterInput = { + search?: Maybe + metadata?: Maybe>> +} + +export type MenuItemInput = { + /** Name of the menu item. */ + name?: Maybe + /** URL of the pointed item. */ + url?: Maybe + /** Category to which item points. */ + category?: Maybe + /** Collection to which item points. */ + collection?: Maybe + /** Page to which item points. */ + page?: Maybe +} + +/** Moves items of menus. */ +export type MenuItemMove = { + __typename?: 'MenuItemMove' + /** Assigned menu to move within. */ + menu?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + menuErrors: Array + errors: Array +} + +export type MenuItemMoveInput = { + /** The menu item ID to move. */ + itemId: Scalars['ID'] + /** ID of the parent menu. If empty, menu will be top level menu. */ + parentId?: Maybe + /** The new relative sorting position of the item (from -inf to +inf). 1 moves the item one position forward, -1 moves the item one position backward, 0 leaves the item unchanged. */ + sortOrder?: Maybe +} + +export type MenuItemSortingInput = { + /** Specifies the direction in which to sort products. */ + direction: OrderDirection + /** Sort menu items by the selected field. */ + field: MenuItemsSortField +} + +export type MenuItemTranslatableContent = Node & { + __typename?: 'MenuItemTranslatableContent' + /** The ID of the object. */ + id: Scalars['ID'] + name: Scalars['String'] + /** Returns translated menu item fields for the given language code. */ + translation?: Maybe + /** Represents a single item of the related menu. Can store categories, collection or pages. */ + menuItem?: Maybe +} + +export type MenuItemTranslatableContentTranslationArgs = { + languageCode: LanguageCodeEnum +} + +/** Creates/Updates translations for Menu Item. */ +export type MenuItemTranslate = { + __typename?: 'MenuItemTranslate' + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + translationErrors: Array + errors: Array + menuItem?: Maybe +} + +export type MenuItemTranslation = Node & { + __typename?: 'MenuItemTranslation' + /** The ID of the object. */ + id: Scalars['ID'] + name: Scalars['String'] + /** Translation language. */ + language: LanguageDisplay +} + +/** Updates a menu item. */ +export type MenuItemUpdate = { + __typename?: 'MenuItemUpdate' + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + menuErrors: Array + errors: Array + menuItem?: Maybe +} + +export enum MenuItemsSortField { + /** Sort menu items by name. */ + Name = 'NAME', +} + +export enum MenuSortField { + /** Sort menus by name. */ + Name = 'NAME', + /** Sort menus by items count. */ + ItemsCount = 'ITEMS_COUNT', +} + +export type MenuSortingInput = { + /** Specifies the direction in which to sort products. */ + direction: OrderDirection + /** Sort menus by the selected field. */ + field: MenuSortField +} + +/** Updates a menu. */ +export type MenuUpdate = { + __typename?: 'MenuUpdate' + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + menuErrors: Array + errors: Array + menu?: Maybe +} + +export type MetadataError = { + __typename?: 'MetadataError' + /** Name of a field that caused the error. A value of `null` indicates that the error isn't associated with a particular field. */ + field?: Maybe + /** The error message. */ + message?: Maybe + /** The error code. */ + code: MetadataErrorCode +} + +/** An enumeration. */ +export enum MetadataErrorCode { + GraphqlError = 'GRAPHQL_ERROR', + Invalid = 'INVALID', + NotFound = 'NOT_FOUND', + Required = 'REQUIRED', +} + +export type MetadataInput = { + /** Key of a metadata item. */ + key: Scalars['String'] + /** Value of a metadata item. */ + value: Scalars['String'] +} + +export type MetadataItem = { + __typename?: 'MetadataItem' + /** Key of a metadata item. */ + key: Scalars['String'] + /** Value of a metadata item. */ + value: Scalars['String'] +} + +/** Represents amount of money in specific currency. */ +export type Money = { + __typename?: 'Money' + /** Currency code. */ + currency: Scalars['String'] + /** Amount of money. */ + amount: Scalars['Float'] +} + +/** Represents a range of amounts of money. */ +export type MoneyRange = { + __typename?: 'MoneyRange' + /** Lower bound of a price range. */ + start?: Maybe + /** Upper bound of a price range. */ + stop?: Maybe +} + +export type MoveProductInput = { + /** The ID of the product to move. */ + productId: Scalars['ID'] + /** The relative sorting position of the product (from -inf to +inf) starting from the first given product's actual position.1 moves the item one position forward, -1 moves the item one position backward, 0 leaves the item unchanged. */ + sortOrder?: Maybe +} + +export type Mutation = { + __typename?: 'Mutation' + /** Creates a new webhook subscription. */ + webhookCreate?: Maybe + /** Deletes a webhook subscription. */ + webhookDelete?: Maybe + /** Updates a webhook subscription. */ + webhookUpdate?: Maybe + /** Creates new warehouse. */ + createWarehouse?: Maybe + /** Updates given warehouse. */ + updateWarehouse?: Maybe + /** Deletes selected warehouse. */ + deleteWarehouse?: Maybe + /** Add shipping zone to given warehouse. */ + assignWarehouseShippingZone?: Maybe + /** Remove shipping zone from given warehouse. */ + unassignWarehouseShippingZone?: Maybe + /** Creates a new staff notification recipient. */ + staffNotificationRecipientCreate?: Maybe + /** Updates a staff notification recipient. */ + staffNotificationRecipientUpdate?: Maybe + /** Delete staff notification recipient. */ + staffNotificationRecipientDelete?: Maybe + /** Updates site domain of the shop. */ + shopDomainUpdate?: Maybe + /** Updates shop settings. */ + shopSettingsUpdate?: Maybe + /** Fetch tax rates. */ + shopFetchTaxRates?: Maybe + /** Creates/Updates translations for Shop Settings. */ + shopSettingsTranslate?: Maybe + /** Update the shop's address. If the `null` value is passed, the currently selected address will be deleted. */ + shopAddressUpdate?: Maybe + /** Update shop order settings. */ + orderSettingsUpdate?: Maybe + /** Manage shipping method's availability in channels. */ + shippingMethodChannelListingUpdate?: Maybe + /** Creates a new shipping price. */ + shippingPriceCreate?: Maybe + /** Deletes a shipping price. */ + shippingPriceDelete?: Maybe + /** Deletes shipping prices. */ + shippingPriceBulkDelete?: Maybe + /** Updates a new shipping price. */ + shippingPriceUpdate?: Maybe + /** Creates/Updates translations for shipping method. */ + shippingPriceTranslate?: Maybe + /** Exclude products from shipping price. */ + shippingPriceExcludeProducts?: Maybe + /** Remove product from excluded list for shipping price. */ + shippingPriceRemoveProductFromExclude?: Maybe + /** Creates a new shipping zone. */ + shippingZoneCreate?: Maybe + /** Deletes a shipping zone. */ + shippingZoneDelete?: Maybe + /** Deletes shipping zones. */ + shippingZoneBulkDelete?: Maybe + /** Updates a new shipping zone. */ + shippingZoneUpdate?: Maybe + /** Assign attributes to a given product type. */ + productAttributeAssign?: Maybe + /** Un-assign attributes from a given product type. */ + productAttributeUnassign?: Maybe + /** Creates a new category. */ + categoryCreate?: Maybe + /** Deletes a category. */ + categoryDelete?: Maybe + /** Deletes categories. */ + categoryBulkDelete?: Maybe + /** Updates a category. */ + categoryUpdate?: Maybe + /** Creates/Updates translations for Category. */ + categoryTranslate?: Maybe + /** Adds products to a collection. */ + collectionAddProducts?: Maybe + /** Creates a new collection. */ + collectionCreate?: Maybe + /** Deletes a collection. */ + collectionDelete?: Maybe + /** Reorder the products of a collection. */ + collectionReorderProducts?: Maybe + /** Deletes collections. */ + collectionBulkDelete?: Maybe + /** Remove products from a collection. */ + collectionRemoveProducts?: Maybe + /** Updates a collection. */ + collectionUpdate?: Maybe + /** Creates/Updates translations for collection. */ + collectionTranslate?: Maybe + /** Manage collection's availability in channels. */ + collectionChannelListingUpdate?: Maybe + /** Creates a new product. */ + productCreate?: Maybe + /** Deletes a product. */ + productDelete?: Maybe + /** Deletes products. */ + productBulkDelete?: Maybe + /** Updates an existing product. */ + productUpdate?: Maybe + /** Creates/Updates translations for Product. */ + productTranslate?: Maybe + /** Manage product's availability in channels. */ + productChannelListingUpdate?: Maybe + /** Create a media object (image or video URL) associated with product. For image, this mutation must be sent as a `multipart` request. More detailed specs of the upload format can be found here: https://github.com/jaydenseric/graphql-multipart-request-spec */ + productMediaCreate?: Maybe + /** Reorder the variants of a product. Mutation updates updated_at on product and triggers PRODUCT_UPDATED webhook. */ + productVariantReorder?: Maybe + /** Deletes a product media. */ + productMediaDelete?: Maybe + /** Deletes product media. */ + productMediaBulkDelete?: Maybe + /** Changes ordering of the product media. */ + productMediaReorder?: Maybe + /** Updates a product media. */ + productMediaUpdate?: Maybe + /** Creates a new product type. */ + productTypeCreate?: Maybe + /** Deletes a product type. */ + productTypeDelete?: Maybe + /** Deletes product types. */ + productTypeBulkDelete?: Maybe + /** Updates an existing product type. */ + productTypeUpdate?: Maybe + /** Reorder the attributes of a product type. */ + productTypeReorderAttributes?: Maybe + /** Reorder product attribute values. */ + productReorderAttributeValues?: Maybe + /** Create new digital content. This mutation must be sent as a `multipart` request. More detailed specs of the upload format can be found here: https://github.com/jaydenseric/graphql-multipart-request-spec */ + digitalContentCreate?: Maybe + /** Remove digital content assigned to given variant. */ + digitalContentDelete?: Maybe + /** Update digital content. */ + digitalContentUpdate?: Maybe + /** Generate new URL to digital content. */ + digitalContentUrlCreate?: Maybe + /** Creates a new variant for a product. */ + productVariantCreate?: Maybe + /** Deletes a product variant. */ + productVariantDelete?: Maybe + /** Creates product variants for a given product. */ + productVariantBulkCreate?: Maybe + /** Deletes product variants. */ + productVariantBulkDelete?: Maybe + /** Creates stocks for product variant. */ + productVariantStocksCreate?: Maybe + /** Delete stocks from product variant. */ + productVariantStocksDelete?: Maybe + /** Update stocks for product variant. */ + productVariantStocksUpdate?: Maybe + /** Updates an existing variant for product. */ + productVariantUpdate?: Maybe + /** Set default variant for a product. Mutation triggers PRODUCT_UPDATED webhook. */ + productVariantSetDefault?: Maybe + /** Creates/Updates translations for Product Variant. */ + productVariantTranslate?: Maybe + /** Manage product variant prices in channels. */ + productVariantChannelListingUpdate?: Maybe + /** Reorder product variant attribute values. */ + productVariantReorderAttributeValues?: Maybe + /** Assign an media to a product variant. */ + variantMediaAssign?: Maybe + /** Unassign an media from a product variant. */ + variantMediaUnassign?: Maybe + /** Captures the authorized payment amount. */ + paymentCapture?: Maybe + /** Refunds the captured payment amount. */ + paymentRefund?: Maybe + /** Voids the authorized payment. */ + paymentVoid?: Maybe + /** Initializes payment process when it is required by gateway. */ + paymentInitialize?: Maybe + /** Creates a new page. */ + pageCreate?: Maybe + /** Deletes a page. */ + pageDelete?: Maybe + /** Deletes pages. */ + pageBulkDelete?: Maybe + /** Publish pages. */ + pageBulkPublish?: Maybe + /** Updates an existing page. */ + pageUpdate?: Maybe + /** Creates/Updates translations for Page. */ + pageTranslate?: Maybe + /** Create a new page type. */ + pageTypeCreate?: Maybe + /** Update page type. */ + pageTypeUpdate?: Maybe + /** Delete a page type. */ + pageTypeDelete?: Maybe + /** Delete page types. */ + pageTypeBulkDelete?: Maybe + /** Assign attributes to a given page type. */ + pageAttributeAssign?: Maybe + /** Unassign attributes from a given page type. */ + pageAttributeUnassign?: Maybe + /** Reorder the attributes of a page type. */ + pageTypeReorderAttributes?: Maybe + /** Reorder page attribute values. */ + pageReorderAttributeValues?: Maybe + /** Completes creating an order. */ + draftOrderComplete?: Maybe + /** Creates a new draft order. */ + draftOrderCreate?: Maybe + /** Deletes a draft order. */ + draftOrderDelete?: Maybe + /** Deletes draft orders. */ + draftOrderBulkDelete?: Maybe + /** Deletes order lines. */ + draftOrderLinesBulkDelete?: Maybe + /** Updates a draft order. */ + draftOrderUpdate?: Maybe + /** Adds note to the order. */ + orderAddNote?: Maybe + /** Cancel an order. */ + orderCancel?: Maybe + /** Capture an order. */ + orderCapture?: Maybe + /** Confirms an unconfirmed order by changing status to unfulfilled. */ + orderConfirm?: Maybe + /** Creates new fulfillments for an order. */ + orderFulfill?: Maybe + /** Cancels existing fulfillment and optionally restocks items. */ + orderFulfillmentCancel?: Maybe + /** Updates a fulfillment for an order. */ + orderFulfillmentUpdateTracking?: Maybe + /** Refund products. */ + orderFulfillmentRefundProducts?: Maybe + /** Return products. */ + orderFulfillmentReturnProducts?: Maybe + /** Create order lines for an order. */ + orderLinesCreate?: Maybe + /** Deletes an order line from an order. */ + orderLineDelete?: Maybe + /** Updates an order line of an order. */ + orderLineUpdate?: Maybe + /** Adds discount to the order. */ + orderDiscountAdd?: Maybe + /** Update discount for the order. */ + orderDiscountUpdate?: Maybe + /** Remove discount from the order. */ + orderDiscountDelete?: Maybe + /** Update discount for the order line. */ + orderLineDiscountUpdate?: Maybe + /** Remove discount applied to the order line. */ + orderLineDiscountRemove?: Maybe + /** Mark order as manually paid. */ + orderMarkAsPaid?: Maybe + /** Refund an order. */ + orderRefund?: Maybe + /** Updates an order. */ + orderUpdate?: Maybe + /** Updates a shipping method of the order. */ + orderUpdateShipping?: Maybe + /** Void an order. */ + orderVoid?: Maybe + /** Cancels orders. */ + orderBulkCancel?: Maybe + /** Delete metadata of an object. */ + deleteMetadata?: Maybe + /** Delete object's private metadata. */ + deletePrivateMetadata?: Maybe + /** Updates metadata of an object. */ + updateMetadata?: Maybe + /** Updates private metadata of an object. */ + updatePrivateMetadata?: Maybe + /** Assigns storefront's navigation menus. */ + assignNavigation?: Maybe + /** Creates a new Menu. */ + menuCreate?: Maybe + /** Deletes a menu. */ + menuDelete?: Maybe + /** Deletes menus. */ + menuBulkDelete?: Maybe + /** Updates a menu. */ + menuUpdate?: Maybe + /** Creates a new menu item. */ + menuItemCreate?: Maybe + /** Deletes a menu item. */ + menuItemDelete?: Maybe + /** Deletes menu items. */ + menuItemBulkDelete?: Maybe + /** Updates a menu item. */ + menuItemUpdate?: Maybe + /** Creates/Updates translations for Menu Item. */ + menuItemTranslate?: Maybe + /** Moves items of menus. */ + menuItemMove?: Maybe + /** Request an invoice for the order using plugin. */ + invoiceRequest?: Maybe + /** Requests deletion of an invoice. */ + invoiceRequestDelete?: Maybe + /** Creates a ready to send invoice. */ + invoiceCreate?: Maybe + /** Deletes an invoice. */ + invoiceDelete?: Maybe + /** Updates an invoice. */ + invoiceUpdate?: Maybe + /** Send an invoice notification to the customer. */ + invoiceSendNotification?: Maybe + /** Activate a gift card. */ + giftCardActivate?: Maybe + /** Creates a new gift card. */ + giftCardCreate?: Maybe + /** Deactivate a gift card. */ + giftCardDeactivate?: Maybe + /** Update a gift card. */ + giftCardUpdate?: Maybe + /** Update plugin configuration. */ + pluginUpdate?: Maybe + /** Creates a new sale. */ + saleCreate?: Maybe + /** Deletes a sale. */ + saleDelete?: Maybe + /** Deletes sales. */ + saleBulkDelete?: Maybe + /** Updates a sale. */ + saleUpdate?: Maybe + /** Adds products, categories, collections to a voucher. */ + saleCataloguesAdd?: Maybe + /** Removes products, categories, collections from a sale. */ + saleCataloguesRemove?: Maybe + /** Creates/updates translations for a sale. */ + saleTranslate?: Maybe + /** Manage sale's availability in channels. */ + saleChannelListingUpdate?: Maybe + /** Creates a new voucher. */ + voucherCreate?: Maybe + /** Deletes a voucher. */ + voucherDelete?: Maybe + /** Deletes vouchers. */ + voucherBulkDelete?: Maybe + /** Updates a voucher. */ + voucherUpdate?: Maybe + /** Adds products, categories, collections to a voucher. */ + voucherCataloguesAdd?: Maybe + /** Removes products, categories, collections from a voucher. */ + voucherCataloguesRemove?: Maybe + /** Creates/Updates translations for Voucher. */ + voucherTranslate?: Maybe + /** Manage voucher's availability in channels. */ + voucherChannelListingUpdate?: Maybe + /** Export products to csv file. */ + exportProducts?: Maybe + /** Upload a file. This mutation must be sent as a `multipart` request. More detailed specs of the upload format can be found here: https://github.com/jaydenseric/graphql-multipart-request-spec */ + fileUpload?: Maybe + /** Adds a gift card or a voucher to a checkout. */ + checkoutAddPromoCode?: Maybe + /** Update billing address in the existing checkout. */ + checkoutBillingAddressUpdate?: Maybe + /** Completes the checkout. As a result a new order is created and a payment charge is made. This action requires a successful payment before it can be performed. In case additional confirmation step as 3D secure is required confirmationNeeded flag will be set to True and no order created until payment is confirmed with second call of this mutation. */ + checkoutComplete?: Maybe + /** Create a new checkout. */ + checkoutCreate?: Maybe + /** Sets the customer as the owner of the checkout. */ + checkoutCustomerAttach?: Maybe + /** Removes the user assigned as the owner of the checkout. */ + checkoutCustomerDetach?: Maybe + /** Updates email address in the existing checkout object. */ + checkoutEmailUpdate?: Maybe + /** Deletes a CheckoutLine. */ + checkoutLineDelete?: Maybe + /** Adds a checkout line to the existing checkout. */ + checkoutLinesAdd?: Maybe + /** Updates checkout line in the existing checkout. */ + checkoutLinesUpdate?: Maybe + /** Remove a gift card or a voucher from a checkout. */ + checkoutRemovePromoCode?: Maybe + /** Create a new payment for given checkout. */ + checkoutPaymentCreate?: Maybe + /** Update shipping address in the existing checkout. */ + checkoutShippingAddressUpdate?: Maybe + /** Updates the shipping address of the checkout. */ + checkoutShippingMethodUpdate?: Maybe + /** Update language code in the existing checkout. */ + checkoutLanguageCodeUpdate?: Maybe + /** Creates new channel. */ + channelCreate?: Maybe + /** Update a channel. */ + channelUpdate?: Maybe + /** Delete a channel. Orders associated with the deleted channel will be moved to the target channel. Checkouts, product availability, and pricing will be removed. */ + channelDelete?: Maybe + /** Activate a channel. */ + channelActivate?: Maybe + /** Deactivate a channel. */ + channelDeactivate?: Maybe + /** Creates an attribute. */ + attributeCreate?: Maybe + /** Deletes an attribute. */ + attributeDelete?: Maybe + /** Updates attribute. */ + attributeUpdate?: Maybe + /** Creates/Updates translations for attribute. */ + attributeTranslate?: Maybe + /** Deletes attributes. */ + attributeBulkDelete?: Maybe + /** Deletes values of attributes. */ + attributeValueBulkDelete?: Maybe + /** Creates a value for an attribute. */ + attributeValueCreate?: Maybe + /** Deletes a value of an attribute. */ + attributeValueDelete?: Maybe + /** Updates value of an attribute. */ + attributeValueUpdate?: Maybe + /** Creates/Updates translations for attribute value. */ + attributeValueTranslate?: Maybe + /** Reorder the values of an attribute. */ + attributeReorderValues?: Maybe + /** Creates a new app. */ + appCreate?: Maybe + /** Updates an existing app. */ + appUpdate?: Maybe + /** Deletes an app. */ + appDelete?: Maybe + /** Creates a new token. */ + appTokenCreate?: Maybe + /** Deletes an authentication token assigned to app. */ + appTokenDelete?: Maybe + /** Verify provided app token. */ + appTokenVerify?: Maybe + /** Install new app by using app manifest. */ + appInstall?: Maybe + /** Retry failed installation of new app. */ + appRetryInstall?: Maybe + /** Delete failed installation. */ + appDeleteFailedInstallation?: Maybe + /** Fetch and validate manifest. */ + appFetchManifest?: Maybe + /** Activate the app. */ + appActivate?: Maybe + /** Deactivate the app. */ + appDeactivate?: Maybe + /** Create JWT token. */ + tokenCreate?: Maybe + /** Refresh JWT token. Mutation tries to take refreshToken from the input.If it fails it will try to take refreshToken from the http-only cookie -refreshToken. csrfToken is required when refreshToken is provided as a cookie. */ + tokenRefresh?: Maybe + /** Verify JWT token. */ + tokenVerify?: Maybe + /** Deactivate all JWT tokens of the currently authenticated user. */ + tokensDeactivateAll?: Maybe + /** Prepare external authentication url for user by custom plugin. */ + externalAuthenticationUrl?: Maybe + /** Obtain external access tokens for user by custom plugin. */ + externalObtainAccessTokens?: Maybe + /** Refresh user's access by custom plugin. */ + externalRefresh?: Maybe + /** Logout user by custom plugin. */ + externalLogout?: Maybe + /** Verify external authentication data by plugin. */ + externalVerify?: Maybe + /** Sends an email with the account password modification link. */ + requestPasswordReset?: Maybe + /** Confirm user account with token sent by email during registration. */ + confirmAccount?: Maybe + /** Sets the user's password from the token sent by email using the RequestPasswordReset mutation. */ + setPassword?: Maybe + /** Change the password of the logged in user. */ + passwordChange?: Maybe + /** Request email change of the logged in user. */ + requestEmailChange?: Maybe + /** Confirm the email change of the logged-in user. */ + confirmEmailChange?: Maybe + /** Create a new address for the customer. */ + accountAddressCreate?: Maybe + /** Updates an address of the logged-in user. */ + accountAddressUpdate?: Maybe + /** Delete an address of the logged-in user. */ + accountAddressDelete?: Maybe + /** Sets a default address for the authenticated user. */ + accountSetDefaultAddress?: Maybe + /** Register a new user. */ + accountRegister?: Maybe + /** Updates the account of the logged-in user. */ + accountUpdate?: Maybe + /** Sends an email with the account removal link for the logged-in user. */ + accountRequestDeletion?: Maybe + /** Remove user account. */ + accountDelete?: Maybe + /** Creates user address. */ + addressCreate?: Maybe + /** Updates an address. */ + addressUpdate?: Maybe + /** Deletes an address. */ + addressDelete?: Maybe + /** Sets a default address for the given user. */ + addressSetDefault?: Maybe + /** Creates a new customer. */ + customerCreate?: Maybe + /** Updates an existing customer. */ + customerUpdate?: Maybe + /** Deletes a customer. */ + customerDelete?: Maybe + /** Deletes customers. */ + customerBulkDelete?: Maybe + /** Creates a new staff user. */ + staffCreate?: Maybe + /** Updates an existing staff user. */ + staffUpdate?: Maybe + /** Deletes a staff user. */ + staffDelete?: Maybe + /** Deletes staff users. */ + staffBulkDelete?: Maybe + /** Create a user avatar. Only for staff members. This mutation must be sent as a `multipart` request. More detailed specs of the upload format can be found here: https://github.com/jaydenseric/graphql-multipart-request-spec */ + userAvatarUpdate?: Maybe + /** Deletes a user avatar. Only for staff members. */ + userAvatarDelete?: Maybe + /** Activate or deactivate users. */ + userBulkSetActive?: Maybe + /** Create new permission group. */ + permissionGroupCreate?: Maybe + /** Update permission group. */ + permissionGroupUpdate?: Maybe + /** Delete permission group. */ + permissionGroupDelete?: Maybe +} + +export type MutationWebhookCreateArgs = { + input: WebhookCreateInput +} + +export type MutationWebhookDeleteArgs = { + id: Scalars['ID'] +} + +export type MutationWebhookUpdateArgs = { + id: Scalars['ID'] + input: WebhookUpdateInput +} + +export type MutationCreateWarehouseArgs = { + input: WarehouseCreateInput +} + +export type MutationUpdateWarehouseArgs = { + id: Scalars['ID'] + input: WarehouseUpdateInput +} + +export type MutationDeleteWarehouseArgs = { + id: Scalars['ID'] +} + +export type MutationAssignWarehouseShippingZoneArgs = { + id: Scalars['ID'] + shippingZoneIds: Array +} + +export type MutationUnassignWarehouseShippingZoneArgs = { + id: Scalars['ID'] + shippingZoneIds: Array +} + +export type MutationStaffNotificationRecipientCreateArgs = { + input: StaffNotificationRecipientInput +} + +export type MutationStaffNotificationRecipientUpdateArgs = { + id: Scalars['ID'] + input: StaffNotificationRecipientInput +} + +export type MutationStaffNotificationRecipientDeleteArgs = { + id: Scalars['ID'] +} + +export type MutationShopDomainUpdateArgs = { + input?: Maybe +} + +export type MutationShopSettingsUpdateArgs = { + input: ShopSettingsInput +} + +export type MutationShopSettingsTranslateArgs = { + input: ShopSettingsTranslationInput + languageCode: LanguageCodeEnum +} + +export type MutationShopAddressUpdateArgs = { + input?: Maybe +} + +export type MutationOrderSettingsUpdateArgs = { + input: OrderSettingsUpdateInput +} + +export type MutationShippingMethodChannelListingUpdateArgs = { + id: Scalars['ID'] + input: ShippingMethodChannelListingInput +} + +export type MutationShippingPriceCreateArgs = { + input: ShippingPriceInput +} + +export type MutationShippingPriceDeleteArgs = { + id: Scalars['ID'] +} + +export type MutationShippingPriceBulkDeleteArgs = { + ids: Array> +} + +export type MutationShippingPriceUpdateArgs = { + id: Scalars['ID'] + input: ShippingPriceInput +} + +export type MutationShippingPriceTranslateArgs = { + id: Scalars['ID'] + input: ShippingPriceTranslationInput + languageCode: LanguageCodeEnum +} + +export type MutationShippingPriceExcludeProductsArgs = { + id: Scalars['ID'] + input: ShippingPriceExcludeProductsInput +} + +export type MutationShippingPriceRemoveProductFromExcludeArgs = { + id: Scalars['ID'] + products: Array> +} + +export type MutationShippingZoneCreateArgs = { + input: ShippingZoneCreateInput +} + +export type MutationShippingZoneDeleteArgs = { + id: Scalars['ID'] +} + +export type MutationShippingZoneBulkDeleteArgs = { + ids: Array> +} + +export type MutationShippingZoneUpdateArgs = { + id: Scalars['ID'] + input: ShippingZoneUpdateInput +} + +export type MutationProductAttributeAssignArgs = { + operations: Array> + productTypeId: Scalars['ID'] +} + +export type MutationProductAttributeUnassignArgs = { + attributeIds: Array> + productTypeId: Scalars['ID'] +} + +export type MutationCategoryCreateArgs = { + input: CategoryInput + parent?: Maybe +} + +export type MutationCategoryDeleteArgs = { + id: Scalars['ID'] +} + +export type MutationCategoryBulkDeleteArgs = { + ids: Array> +} + +export type MutationCategoryUpdateArgs = { + id: Scalars['ID'] + input: CategoryInput +} + +export type MutationCategoryTranslateArgs = { + id: Scalars['ID'] + input: TranslationInput + languageCode: LanguageCodeEnum +} + +export type MutationCollectionAddProductsArgs = { + collectionId: Scalars['ID'] + products: Array> +} + +export type MutationCollectionCreateArgs = { + input: CollectionCreateInput +} + +export type MutationCollectionDeleteArgs = { + id: Scalars['ID'] +} + +export type MutationCollectionReorderProductsArgs = { + collectionId: Scalars['ID'] + moves: Array> +} + +export type MutationCollectionBulkDeleteArgs = { + ids: Array> +} + +export type MutationCollectionRemoveProductsArgs = { + collectionId: Scalars['ID'] + products: Array> +} + +export type MutationCollectionUpdateArgs = { + id: Scalars['ID'] + input: CollectionInput +} + +export type MutationCollectionTranslateArgs = { + id: Scalars['ID'] + input: TranslationInput + languageCode: LanguageCodeEnum +} + +export type MutationCollectionChannelListingUpdateArgs = { + id: Scalars['ID'] + input: CollectionChannelListingUpdateInput +} + +export type MutationProductCreateArgs = { + input: ProductCreateInput +} + +export type MutationProductDeleteArgs = { + id: Scalars['ID'] +} + +export type MutationProductBulkDeleteArgs = { + ids: Array> +} + +export type MutationProductUpdateArgs = { + id: Scalars['ID'] + input: ProductInput +} + +export type MutationProductTranslateArgs = { + id: Scalars['ID'] + input: TranslationInput + languageCode: LanguageCodeEnum +} + +export type MutationProductChannelListingUpdateArgs = { + id: Scalars['ID'] + input: ProductChannelListingUpdateInput +} + +export type MutationProductMediaCreateArgs = { + input: ProductMediaCreateInput +} + +export type MutationProductVariantReorderArgs = { + moves: Array> + productId: Scalars['ID'] +} + +export type MutationProductMediaDeleteArgs = { + id: Scalars['ID'] +} + +export type MutationProductMediaBulkDeleteArgs = { + ids: Array> +} + +export type MutationProductMediaReorderArgs = { + mediaIds: Array> + productId: Scalars['ID'] +} + +export type MutationProductMediaUpdateArgs = { + id: Scalars['ID'] + input: ProductMediaUpdateInput +} + +export type MutationProductTypeCreateArgs = { + input: ProductTypeInput +} + +export type MutationProductTypeDeleteArgs = { + id: Scalars['ID'] +} + +export type MutationProductTypeBulkDeleteArgs = { + ids: Array> +} + +export type MutationProductTypeUpdateArgs = { + id: Scalars['ID'] + input: ProductTypeInput +} + +export type MutationProductTypeReorderAttributesArgs = { + moves: Array> + productTypeId: Scalars['ID'] + type: ProductAttributeType +} + +export type MutationProductReorderAttributeValuesArgs = { + attributeId: Scalars['ID'] + moves: Array> + productId: Scalars['ID'] +} + +export type MutationDigitalContentCreateArgs = { + input: DigitalContentUploadInput + variantId: Scalars['ID'] +} + +export type MutationDigitalContentDeleteArgs = { + variantId: Scalars['ID'] +} + +export type MutationDigitalContentUpdateArgs = { + input: DigitalContentInput + variantId: Scalars['ID'] +} + +export type MutationDigitalContentUrlCreateArgs = { + input: DigitalContentUrlCreateInput +} + +export type MutationProductVariantCreateArgs = { + input: ProductVariantCreateInput +} + +export type MutationProductVariantDeleteArgs = { + id: Scalars['ID'] +} + +export type MutationProductVariantBulkCreateArgs = { + product: Scalars['ID'] + variants: Array> +} + +export type MutationProductVariantBulkDeleteArgs = { + ids: Array> +} + +export type MutationProductVariantStocksCreateArgs = { + stocks: Array + variantId: Scalars['ID'] +} + +export type MutationProductVariantStocksDeleteArgs = { + variantId: Scalars['ID'] + warehouseIds?: Maybe> +} + +export type MutationProductVariantStocksUpdateArgs = { + stocks: Array + variantId: Scalars['ID'] +} + +export type MutationProductVariantUpdateArgs = { + id: Scalars['ID'] + input: ProductVariantInput +} + +export type MutationProductVariantSetDefaultArgs = { + productId: Scalars['ID'] + variantId: Scalars['ID'] +} + +export type MutationProductVariantTranslateArgs = { + id: Scalars['ID'] + input: NameTranslationInput + languageCode: LanguageCodeEnum +} + +export type MutationProductVariantChannelListingUpdateArgs = { + id: Scalars['ID'] + input: Array +} + +export type MutationProductVariantReorderAttributeValuesArgs = { + attributeId: Scalars['ID'] + moves: Array> + variantId: Scalars['ID'] +} + +export type MutationVariantMediaAssignArgs = { + mediaId: Scalars['ID'] + variantId: Scalars['ID'] +} + +export type MutationVariantMediaUnassignArgs = { + mediaId: Scalars['ID'] + variantId: Scalars['ID'] +} + +export type MutationPaymentCaptureArgs = { + amount?: Maybe + paymentId: Scalars['ID'] +} + +export type MutationPaymentRefundArgs = { + amount?: Maybe + paymentId: Scalars['ID'] +} + +export type MutationPaymentVoidArgs = { + paymentId: Scalars['ID'] +} + +export type MutationPaymentInitializeArgs = { + channel?: Maybe + gateway: Scalars['String'] + paymentData?: Maybe +} + +export type MutationPageCreateArgs = { + input: PageCreateInput +} + +export type MutationPageDeleteArgs = { + id: Scalars['ID'] +} + +export type MutationPageBulkDeleteArgs = { + ids: Array> +} + +export type MutationPageBulkPublishArgs = { + ids: Array> + isPublished: Scalars['Boolean'] +} + +export type MutationPageUpdateArgs = { + id: Scalars['ID'] + input: PageInput +} + +export type MutationPageTranslateArgs = { + id: Scalars['ID'] + input: PageTranslationInput + languageCode: LanguageCodeEnum +} + +export type MutationPageTypeCreateArgs = { + input: PageTypeCreateInput +} + +export type MutationPageTypeUpdateArgs = { + id?: Maybe + input: PageTypeUpdateInput +} + +export type MutationPageTypeDeleteArgs = { + id: Scalars['ID'] +} + +export type MutationPageTypeBulkDeleteArgs = { + ids: Array +} + +export type MutationPageAttributeAssignArgs = { + attributeIds: Array + pageTypeId: Scalars['ID'] +} + +export type MutationPageAttributeUnassignArgs = { + attributeIds: Array + pageTypeId: Scalars['ID'] +} + +export type MutationPageTypeReorderAttributesArgs = { + moves: Array + pageTypeId: Scalars['ID'] +} + +export type MutationPageReorderAttributeValuesArgs = { + attributeId: Scalars['ID'] + moves: Array> + pageId: Scalars['ID'] +} + +export type MutationDraftOrderCompleteArgs = { + id: Scalars['ID'] +} + +export type MutationDraftOrderCreateArgs = { + input: DraftOrderCreateInput +} + +export type MutationDraftOrderDeleteArgs = { + id: Scalars['ID'] +} + +export type MutationDraftOrderBulkDeleteArgs = { + ids: Array> +} + +export type MutationDraftOrderLinesBulkDeleteArgs = { + ids: Array> +} + +export type MutationDraftOrderUpdateArgs = { + id: Scalars['ID'] + input: DraftOrderInput +} + +export type MutationOrderAddNoteArgs = { + order: Scalars['ID'] + input: OrderAddNoteInput +} + +export type MutationOrderCancelArgs = { + id: Scalars['ID'] +} + +export type MutationOrderCaptureArgs = { + amount: Scalars['PositiveDecimal'] + id: Scalars['ID'] +} + +export type MutationOrderConfirmArgs = { + id: Scalars['ID'] +} + +export type MutationOrderFulfillArgs = { + input: OrderFulfillInput + order?: Maybe +} + +export type MutationOrderFulfillmentCancelArgs = { + id: Scalars['ID'] + input: FulfillmentCancelInput +} + +export type MutationOrderFulfillmentUpdateTrackingArgs = { + id: Scalars['ID'] + input: FulfillmentUpdateTrackingInput +} + +export type MutationOrderFulfillmentRefundProductsArgs = { + input: OrderRefundProductsInput + order: Scalars['ID'] +} + +export type MutationOrderFulfillmentReturnProductsArgs = { + input: OrderReturnProductsInput + order: Scalars['ID'] +} + +export type MutationOrderLinesCreateArgs = { + id: Scalars['ID'] + input: Array> +} + +export type MutationOrderLineDeleteArgs = { + id: Scalars['ID'] +} + +export type MutationOrderLineUpdateArgs = { + id: Scalars['ID'] + input: OrderLineInput +} + +export type MutationOrderDiscountAddArgs = { + input: OrderDiscountCommonInput + orderId: Scalars['ID'] +} + +export type MutationOrderDiscountUpdateArgs = { + discountId: Scalars['ID'] + input: OrderDiscountCommonInput +} + +export type MutationOrderDiscountDeleteArgs = { + discountId: Scalars['ID'] +} + +export type MutationOrderLineDiscountUpdateArgs = { + input: OrderDiscountCommonInput + orderLineId: Scalars['ID'] +} + +export type MutationOrderLineDiscountRemoveArgs = { + orderLineId: Scalars['ID'] +} + +export type MutationOrderMarkAsPaidArgs = { + id: Scalars['ID'] + transactionReference?: Maybe +} + +export type MutationOrderRefundArgs = { + amount: Scalars['PositiveDecimal'] + id: Scalars['ID'] +} + +export type MutationOrderUpdateArgs = { + id: Scalars['ID'] + input: OrderUpdateInput +} + +export type MutationOrderUpdateShippingArgs = { + order: Scalars['ID'] + input?: Maybe +} + +export type MutationOrderVoidArgs = { + id: Scalars['ID'] +} + +export type MutationOrderBulkCancelArgs = { + ids: Array> +} + +export type MutationDeleteMetadataArgs = { + id: Scalars['ID'] + keys: Array +} + +export type MutationDeletePrivateMetadataArgs = { + id: Scalars['ID'] + keys: Array +} + +export type MutationUpdateMetadataArgs = { + id: Scalars['ID'] + input: Array +} + +export type MutationUpdatePrivateMetadataArgs = { + id: Scalars['ID'] + input: Array +} + +export type MutationAssignNavigationArgs = { + menu?: Maybe + navigationType: NavigationType +} + +export type MutationMenuCreateArgs = { + input: MenuCreateInput +} + +export type MutationMenuDeleteArgs = { + id: Scalars['ID'] +} + +export type MutationMenuBulkDeleteArgs = { + ids: Array> +} + +export type MutationMenuUpdateArgs = { + id: Scalars['ID'] + input: MenuInput +} + +export type MutationMenuItemCreateArgs = { + input: MenuItemCreateInput +} + +export type MutationMenuItemDeleteArgs = { + id: Scalars['ID'] +} + +export type MutationMenuItemBulkDeleteArgs = { + ids: Array> +} + +export type MutationMenuItemUpdateArgs = { + id: Scalars['ID'] + input: MenuItemInput +} + +export type MutationMenuItemTranslateArgs = { + id: Scalars['ID'] + input: NameTranslationInput + languageCode: LanguageCodeEnum +} + +export type MutationMenuItemMoveArgs = { + menu: Scalars['ID'] + moves: Array> +} + +export type MutationInvoiceRequestArgs = { + number?: Maybe + orderId: Scalars['ID'] +} + +export type MutationInvoiceRequestDeleteArgs = { + id: Scalars['ID'] +} + +export type MutationInvoiceCreateArgs = { + input: InvoiceCreateInput + orderId: Scalars['ID'] +} + +export type MutationInvoiceDeleteArgs = { + id: Scalars['ID'] +} + +export type MutationInvoiceUpdateArgs = { + id: Scalars['ID'] + input: UpdateInvoiceInput +} + +export type MutationInvoiceSendNotificationArgs = { + id: Scalars['ID'] +} + +export type MutationGiftCardActivateArgs = { + id: Scalars['ID'] +} + +export type MutationGiftCardCreateArgs = { + input: GiftCardCreateInput +} + +export type MutationGiftCardDeactivateArgs = { + id: Scalars['ID'] +} + +export type MutationGiftCardUpdateArgs = { + id: Scalars['ID'] + input: GiftCardUpdateInput +} + +export type MutationPluginUpdateArgs = { + channel?: Maybe + id: Scalars['ID'] + input: PluginUpdateInput +} + +export type MutationSaleCreateArgs = { + input: SaleInput +} + +export type MutationSaleDeleteArgs = { + id: Scalars['ID'] +} + +export type MutationSaleBulkDeleteArgs = { + ids: Array> +} + +export type MutationSaleUpdateArgs = { + id: Scalars['ID'] + input: SaleInput +} + +export type MutationSaleCataloguesAddArgs = { + id: Scalars['ID'] + input: CatalogueInput +} + +export type MutationSaleCataloguesRemoveArgs = { + id: Scalars['ID'] + input: CatalogueInput +} + +export type MutationSaleTranslateArgs = { + id: Scalars['ID'] + input: NameTranslationInput + languageCode: LanguageCodeEnum +} + +export type MutationSaleChannelListingUpdateArgs = { + id: Scalars['ID'] + input: SaleChannelListingInput +} + +export type MutationVoucherCreateArgs = { + input: VoucherInput +} + +export type MutationVoucherDeleteArgs = { + id: Scalars['ID'] +} + +export type MutationVoucherBulkDeleteArgs = { + ids: Array> +} + +export type MutationVoucherUpdateArgs = { + id: Scalars['ID'] + input: VoucherInput +} + +export type MutationVoucherCataloguesAddArgs = { + id: Scalars['ID'] + input: CatalogueInput +} + +export type MutationVoucherCataloguesRemoveArgs = { + id: Scalars['ID'] + input: CatalogueInput +} + +export type MutationVoucherTranslateArgs = { + id: Scalars['ID'] + input: NameTranslationInput + languageCode: LanguageCodeEnum +} + +export type MutationVoucherChannelListingUpdateArgs = { + id: Scalars['ID'] + input: VoucherChannelListingInput +} + +export type MutationExportProductsArgs = { + input: ExportProductsInput +} + +export type MutationFileUploadArgs = { + file: Scalars['Upload'] +} + +export type MutationCheckoutAddPromoCodeArgs = { + checkoutId: Scalars['ID'] + promoCode: Scalars['String'] +} + +export type MutationCheckoutBillingAddressUpdateArgs = { + billingAddress: AddressInput + checkoutId: Scalars['ID'] +} + +export type MutationCheckoutCompleteArgs = { + checkoutId: Scalars['ID'] + paymentData?: Maybe + redirectUrl?: Maybe + storeSource?: Maybe +} + +export type MutationCheckoutCreateArgs = { + input: CheckoutCreateInput +} + +export type MutationCheckoutCustomerAttachArgs = { + checkoutId: Scalars['ID'] +} + +export type MutationCheckoutCustomerDetachArgs = { + checkoutId: Scalars['ID'] +} + +export type MutationCheckoutEmailUpdateArgs = { + checkoutId?: Maybe + email: Scalars['String'] +} + +export type MutationCheckoutLineDeleteArgs = { + checkoutId: Scalars['ID'] + lineId?: Maybe +} + +export type MutationCheckoutLinesAddArgs = { + checkoutId: Scalars['ID'] + lines: Array> +} + +export type MutationCheckoutLinesUpdateArgs = { + checkoutId: Scalars['ID'] + lines: Array> +} + +export type MutationCheckoutRemovePromoCodeArgs = { + checkoutId: Scalars['ID'] + promoCode: Scalars['String'] +} + +export type MutationCheckoutPaymentCreateArgs = { + checkoutId: Scalars['ID'] + input: PaymentInput +} + +export type MutationCheckoutShippingAddressUpdateArgs = { + checkoutId: Scalars['ID'] + shippingAddress: AddressInput +} + +export type MutationCheckoutShippingMethodUpdateArgs = { + checkoutId?: Maybe + shippingMethodId: Scalars['ID'] +} + +export type MutationCheckoutLanguageCodeUpdateArgs = { + checkoutId: Scalars['ID'] + languageCode: LanguageCodeEnum +} + +export type MutationChannelCreateArgs = { + input: ChannelCreateInput +} + +export type MutationChannelUpdateArgs = { + id: Scalars['ID'] + input: ChannelUpdateInput +} + +export type MutationChannelDeleteArgs = { + id: Scalars['ID'] + input?: Maybe +} + +export type MutationChannelActivateArgs = { + id: Scalars['ID'] +} + +export type MutationChannelDeactivateArgs = { + id: Scalars['ID'] +} + +export type MutationAttributeCreateArgs = { + input: AttributeCreateInput +} + +export type MutationAttributeDeleteArgs = { + id: Scalars['ID'] +} + +export type MutationAttributeUpdateArgs = { + id: Scalars['ID'] + input: AttributeUpdateInput +} + +export type MutationAttributeTranslateArgs = { + id: Scalars['ID'] + input: NameTranslationInput + languageCode: LanguageCodeEnum +} + +export type MutationAttributeBulkDeleteArgs = { + ids: Array> +} + +export type MutationAttributeValueBulkDeleteArgs = { + ids: Array> +} + +export type MutationAttributeValueCreateArgs = { + attribute: Scalars['ID'] + input: AttributeValueCreateInput +} + +export type MutationAttributeValueDeleteArgs = { + id: Scalars['ID'] +} + +export type MutationAttributeValueUpdateArgs = { + id: Scalars['ID'] + input: AttributeValueCreateInput +} + +export type MutationAttributeValueTranslateArgs = { + id: Scalars['ID'] + input: AttributeValueTranslationInput + languageCode: LanguageCodeEnum +} + +export type MutationAttributeReorderValuesArgs = { + attributeId: Scalars['ID'] + moves: Array> +} + +export type MutationAppCreateArgs = { + input: AppInput +} + +export type MutationAppUpdateArgs = { + id: Scalars['ID'] + input: AppInput +} + +export type MutationAppDeleteArgs = { + id: Scalars['ID'] +} + +export type MutationAppTokenCreateArgs = { + input: AppTokenInput +} + +export type MutationAppTokenDeleteArgs = { + id: Scalars['ID'] +} + +export type MutationAppTokenVerifyArgs = { + token: Scalars['String'] +} + +export type MutationAppInstallArgs = { + input: AppInstallInput +} + +export type MutationAppRetryInstallArgs = { + activateAfterInstallation?: Maybe + id: Scalars['ID'] +} + +export type MutationAppDeleteFailedInstallationArgs = { + id: Scalars['ID'] +} + +export type MutationAppFetchManifestArgs = { + manifestUrl: Scalars['String'] +} + +export type MutationAppActivateArgs = { + id: Scalars['ID'] +} + +export type MutationAppDeactivateArgs = { + id: Scalars['ID'] +} + +export type MutationTokenCreateArgs = { + email: Scalars['String'] + password: Scalars['String'] +} + +export type MutationTokenRefreshArgs = { + csrfToken?: Maybe + refreshToken?: Maybe +} + +export type MutationTokenVerifyArgs = { + token: Scalars['String'] +} + +export type MutationExternalAuthenticationUrlArgs = { + input: Scalars['JSONString'] + pluginId: Scalars['String'] +} + +export type MutationExternalObtainAccessTokensArgs = { + input: Scalars['JSONString'] + pluginId: Scalars['String'] +} + +export type MutationExternalRefreshArgs = { + input: Scalars['JSONString'] + pluginId: Scalars['String'] +} + +export type MutationExternalLogoutArgs = { + input: Scalars['JSONString'] + pluginId: Scalars['String'] +} + +export type MutationExternalVerifyArgs = { + input: Scalars['JSONString'] + pluginId: Scalars['String'] +} + +export type MutationRequestPasswordResetArgs = { + channel?: Maybe + email: Scalars['String'] + redirectUrl: Scalars['String'] +} + +export type MutationConfirmAccountArgs = { + email: Scalars['String'] + token: Scalars['String'] +} + +export type MutationSetPasswordArgs = { + email: Scalars['String'] + password: Scalars['String'] + token: Scalars['String'] +} + +export type MutationPasswordChangeArgs = { + newPassword: Scalars['String'] + oldPassword: Scalars['String'] +} + +export type MutationRequestEmailChangeArgs = { + channel?: Maybe + newEmail: Scalars['String'] + password: Scalars['String'] + redirectUrl: Scalars['String'] +} + +export type MutationConfirmEmailChangeArgs = { + channel?: Maybe + token: Scalars['String'] +} + +export type MutationAccountAddressCreateArgs = { + input: AddressInput + type?: Maybe +} + +export type MutationAccountAddressUpdateArgs = { + id: Scalars['ID'] + input: AddressInput +} + +export type MutationAccountAddressDeleteArgs = { + id: Scalars['ID'] +} + +export type MutationAccountSetDefaultAddressArgs = { + id: Scalars['ID'] + type: AddressTypeEnum +} + +export type MutationAccountRegisterArgs = { + input: AccountRegisterInput +} + +export type MutationAccountUpdateArgs = { + input: AccountInput +} + +export type MutationAccountRequestDeletionArgs = { + channel?: Maybe + redirectUrl: Scalars['String'] +} + +export type MutationAccountDeleteArgs = { + token: Scalars['String'] +} + +export type MutationAddressCreateArgs = { + input: AddressInput + userId: Scalars['ID'] +} + +export type MutationAddressUpdateArgs = { + id: Scalars['ID'] + input: AddressInput +} + +export type MutationAddressDeleteArgs = { + id: Scalars['ID'] +} + +export type MutationAddressSetDefaultArgs = { + addressId: Scalars['ID'] + type: AddressTypeEnum + userId: Scalars['ID'] +} + +export type MutationCustomerCreateArgs = { + input: UserCreateInput +} + +export type MutationCustomerUpdateArgs = { + id: Scalars['ID'] + input: CustomerInput +} + +export type MutationCustomerDeleteArgs = { + id: Scalars['ID'] +} + +export type MutationCustomerBulkDeleteArgs = { + ids: Array> +} + +export type MutationStaffCreateArgs = { + input: StaffCreateInput +} + +export type MutationStaffUpdateArgs = { + id: Scalars['ID'] + input: StaffUpdateInput +} + +export type MutationStaffDeleteArgs = { + id: Scalars['ID'] +} + +export type MutationStaffBulkDeleteArgs = { + ids: Array> +} + +export type MutationUserAvatarUpdateArgs = { + image: Scalars['Upload'] +} + +export type MutationUserBulkSetActiveArgs = { + ids: Array> + isActive: Scalars['Boolean'] +} + +export type MutationPermissionGroupCreateArgs = { + input: PermissionGroupCreateInput +} + +export type MutationPermissionGroupUpdateArgs = { + id: Scalars['ID'] + input: PermissionGroupUpdateInput +} + +export type MutationPermissionGroupDeleteArgs = { + id: Scalars['ID'] +} + +export type NameTranslationInput = { + name?: Maybe +} + +export enum NavigationType { + /** Main storefront navigation. */ + Main = 'MAIN', + /** Secondary storefront navigation. */ + Secondary = 'SECONDARY', +} + +/** An object with an ID */ +export type Node = { + /** The ID of the object. */ + id: Scalars['ID'] +} + +export type ObjectWithMetadata = { + /** List of private metadata items.Requires proper staff permissions to access. */ + privateMetadata: Array> + /** List of public metadata items. Can be accessed without permissions. */ + metadata: Array> +} + +/** Represents an order in the shop. */ +export type Order = Node & + ObjectWithMetadata & { + __typename?: 'Order' + /** The ID of the object. */ + id: Scalars['ID'] + created: Scalars['DateTime'] + status: OrderStatus + user?: Maybe + trackingClientId: Scalars['String'] + billingAddress?: Maybe
    + shippingAddress?: Maybe
    + shippingMethod?: Maybe + shippingMethodName?: Maybe + channel: Channel + /** Total price of shipping. */ + shippingPrice: TaxedMoney + shippingTaxRate: Scalars['Float'] + token: Scalars['String'] + voucher?: Maybe + /** List of user gift cards. */ + giftCards?: Maybe>> + displayGrossPrices: Scalars['Boolean'] + customerNote: Scalars['String'] + weight?: Maybe + redirectUrl?: Maybe + /** List of private metadata items.Requires proper staff permissions to access. */ + privateMetadata: Array> + /** List of public metadata items. Can be accessed without permissions. */ + metadata: Array> + /** List of shipments for the order. */ + fulfillments: Array> + /** List of order lines. */ + lines: Array> + /** List of actions that can be performed in the current state of an order. */ + actions: Array> + /** Shipping methods that can be used with this order. */ + availableShippingMethods?: Maybe>> + /** List of order invoices. */ + invoices?: Maybe>> + /** User-friendly number of an order. */ + number?: Maybe + /** The ID of the order that was the base for this order. */ + original?: Maybe + /** The order origin. */ + origin: OrderOriginEnum + /** Informs if an order is fully paid. */ + isPaid: Scalars['Boolean'] + /** Internal payment status. */ + paymentStatus: PaymentChargeStatusEnum + /** User-friendly payment status. */ + paymentStatusDisplay: Scalars['String'] + /** List of payments for the order. */ + payments?: Maybe>> + /** Total amount of the order. */ + total: TaxedMoney + /** Undiscounted total amount of the order. */ + undiscountedTotal: TaxedMoney + /** The sum of line prices not including shipping. */ + subtotal: TaxedMoney + /** User-friendly order status. */ + statusDisplay?: Maybe + /** Informs whether a draft order can be finalized(turned into a regular order). */ + canFinalize: Scalars['Boolean'] + /** Amount authorized for the order. */ + totalAuthorized: Money + /** Amount captured by payment. */ + totalCaptured: Money + /** List of events associated with the order. */ + events?: Maybe>> + /** The difference between the paid and the order total amount. */ + totalBalance: Money + /** Email address of the customer. */ + userEmail?: Maybe + /** Returns True, if order requires shipping. */ + isShippingRequired: Scalars['Boolean'] + /** @deprecated Use the `languageCodeEnum` field to fetch the language code. This field will be removed in Saleor 4.0. */ + languageCode: Scalars['String'] + /** Order language code. */ + languageCodeEnum: LanguageCodeEnum + /** + * Returns applied discount. + * @deprecated Use discounts field. This field will be removed in Saleor 4.0. + */ + discount?: Maybe + /** + * Discount name. + * @deprecated Use discounts field. This field will be removed in Saleor 4.0. + */ + discountName?: Maybe + /** + * Translated discount name. + * @deprecated Use discounts field. This field will be removed in Saleor 4.0. + */ + translatedDiscountName?: Maybe + /** List of all discounts assigned to the order. */ + discounts?: Maybe> + } + +export enum OrderAction { + /** Represents the capture action. */ + Capture = 'CAPTURE', + /** Represents a mark-as-paid action. */ + MarkAsPaid = 'MARK_AS_PAID', + /** Represents a refund action. */ + Refund = 'REFUND', + /** Represents a void action. */ + Void = 'VOID', +} + +/** Adds note to the order. */ +export type OrderAddNote = { + __typename?: 'OrderAddNote' + /** Order with the note added. */ + order?: Maybe + /** Order note created. */ + event?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + orderErrors: Array + errors: Array +} + +export type OrderAddNoteInput = { + /** Note message. */ + message: Scalars['String'] +} + +/** Cancels orders. */ +export type OrderBulkCancel = { + __typename?: 'OrderBulkCancel' + /** Returns how many objects were affected. */ + count: Scalars['Int'] + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + orderErrors: Array + errors: Array +} + +/** Cancel an order. */ +export type OrderCancel = { + __typename?: 'OrderCancel' + /** Canceled order. */ + order?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + orderErrors: Array + errors: Array +} + +/** Capture an order. */ +export type OrderCapture = { + __typename?: 'OrderCapture' + /** Captured order. */ + order?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + orderErrors: Array + errors: Array +} + +/** Confirms an unconfirmed order by changing status to unfulfilled. */ +export type OrderConfirm = { + __typename?: 'OrderConfirm' + order?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + orderErrors: Array + errors: Array +} + +export type OrderCountableConnection = { + __typename?: 'OrderCountableConnection' + /** Pagination data for this connection. */ + pageInfo: PageInfo + edges: Array + /** A total count of items in the collection. */ + totalCount?: Maybe +} + +export type OrderCountableEdge = { + __typename?: 'OrderCountableEdge' + /** The item at the end of the edge. */ + node: Order + /** A cursor for use in pagination. */ + cursor: Scalars['String'] +} + +export enum OrderDirection { + /** Specifies an ascending sort order. */ + Asc = 'ASC', + /** Specifies a descending sort order. */ + Desc = 'DESC', +} + +/** Contains all details related to the applied discount to the order. */ +export type OrderDiscount = Node & { + __typename?: 'OrderDiscount' + /** The ID of the object. */ + id: Scalars['ID'] + type: OrderDiscountType + /** Type of the discount: fixed or percent */ + valueType: DiscountValueTypeEnum + /** Value of the discount. Can store fixed value or percent value */ + value: Scalars['PositiveDecimal'] + name?: Maybe + translatedName?: Maybe + /** Explanation for the applied discount. */ + reason?: Maybe + /** Returns amount of discount. */ + amount: Money +} + +/** Adds discount to the order. */ +export type OrderDiscountAdd = { + __typename?: 'OrderDiscountAdd' + /** Order which has been discounted. */ + order?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + orderErrors: Array + errors: Array +} + +export type OrderDiscountCommonInput = { + /** Type of the discount: fixed or percent */ + valueType: DiscountValueTypeEnum + /** Value of the discount. Can store fixed value or percent value */ + value: Scalars['PositiveDecimal'] + /** Explanation for the applied discount. */ + reason?: Maybe +} + +/** Remove discount from the order. */ +export type OrderDiscountDelete = { + __typename?: 'OrderDiscountDelete' + /** Order which has removed discount. */ + order?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + orderErrors: Array + errors: Array +} + +/** An enumeration. */ +export enum OrderDiscountType { + /** Voucher */ + Voucher = 'VOUCHER', + /** Manual */ + Manual = 'MANUAL', +} + +/** Update discount for the order. */ +export type OrderDiscountUpdate = { + __typename?: 'OrderDiscountUpdate' + /** Order which has been discounted. */ + order?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + orderErrors: Array + errors: Array +} + +export type OrderDraftFilterInput = { + customer?: Maybe + created?: Maybe + search?: Maybe + metadata?: Maybe>> + channels?: Maybe>> +} + +export type OrderError = { + __typename?: 'OrderError' + /** Name of a field that caused the error. A value of `null` indicates that the error isn't associated with a particular field. */ + field?: Maybe + /** The error message. */ + message?: Maybe + /** The error code. */ + code: OrderErrorCode + /** Warehouse ID which causes the error. */ + warehouse?: Maybe + /** Order line ID which causes the error. */ + orderLine?: Maybe + /** List of product variants that are associated with the error */ + variants?: Maybe> + /** A type of address that causes the error. */ + addressType?: Maybe +} + +/** An enumeration. */ +export enum OrderErrorCode { + BillingAddressNotSet = 'BILLING_ADDRESS_NOT_SET', + CannotCancelFulfillment = 'CANNOT_CANCEL_FULFILLMENT', + CannotCancelOrder = 'CANNOT_CANCEL_ORDER', + CannotDelete = 'CANNOT_DELETE', + CannotDiscount = 'CANNOT_DISCOUNT', + CannotRefund = 'CANNOT_REFUND', + CaptureInactivePayment = 'CAPTURE_INACTIVE_PAYMENT', + NotEditable = 'NOT_EDITABLE', + FulfillOrderLine = 'FULFILL_ORDER_LINE', + GraphqlError = 'GRAPHQL_ERROR', + Invalid = 'INVALID', + ProductNotPublished = 'PRODUCT_NOT_PUBLISHED', + ProductUnavailableForPurchase = 'PRODUCT_UNAVAILABLE_FOR_PURCHASE', + NotFound = 'NOT_FOUND', + OrderNoShippingAddress = 'ORDER_NO_SHIPPING_ADDRESS', + PaymentError = 'PAYMENT_ERROR', + PaymentMissing = 'PAYMENT_MISSING', + Required = 'REQUIRED', + ShippingMethodNotApplicable = 'SHIPPING_METHOD_NOT_APPLICABLE', + ShippingMethodRequired = 'SHIPPING_METHOD_REQUIRED', + TaxError = 'TAX_ERROR', + Unique = 'UNIQUE', + VoidInactivePayment = 'VOID_INACTIVE_PAYMENT', + ZeroQuantity = 'ZERO_QUANTITY', + InvalidQuantity = 'INVALID_QUANTITY', + InsufficientStock = 'INSUFFICIENT_STOCK', + DuplicatedInputItem = 'DUPLICATED_INPUT_ITEM', + NotAvailableInChannel = 'NOT_AVAILABLE_IN_CHANNEL', + ChannelInactive = 'CHANNEL_INACTIVE', +} + +/** History log of the order. */ +export type OrderEvent = Node & { + __typename?: 'OrderEvent' + /** The ID of the object. */ + id: Scalars['ID'] + /** Date when event happened at in ISO 8601 format. */ + date?: Maybe + /** Order event type. */ + type?: Maybe + /** User who performed the action. */ + user?: Maybe + /** Content of the event. */ + message?: Maybe + /** Email of the customer. */ + email?: Maybe + /** Type of an email sent to the customer. */ + emailType?: Maybe + /** Amount of money. */ + amount?: Maybe + /** The payment ID from the payment gateway. */ + paymentId?: Maybe + /** The payment gateway of the payment. */ + paymentGateway?: Maybe + /** Number of items. */ + quantity?: Maybe + /** Composed ID of the Fulfillment. */ + composedId?: Maybe + /** User-friendly number of an order. */ + orderNumber?: Maybe + /** Number of an invoice related to the order. */ + invoiceNumber?: Maybe + /** List of oversold lines names. */ + oversoldItems?: Maybe>> + /** The concerned lines. */ + lines?: Maybe>> + /** The lines fulfilled. */ + fulfilledItems?: Maybe>> + /** The warehouse were items were restocked. */ + warehouse?: Maybe + /** The transaction reference of captured payment. */ + transactionReference?: Maybe + /** Define if shipping costs were included to the refund. */ + shippingCostsIncluded?: Maybe + /** The order which is related to this order. */ + relatedOrder?: Maybe + /** The discount applied to the order. */ + discount?: Maybe +} + +export type OrderEventCountableConnection = { + __typename?: 'OrderEventCountableConnection' + /** Pagination data for this connection. */ + pageInfo: PageInfo + edges: Array + /** A total count of items in the collection. */ + totalCount?: Maybe +} + +export type OrderEventCountableEdge = { + __typename?: 'OrderEventCountableEdge' + /** The item at the end of the edge. */ + node: OrderEvent + /** A cursor for use in pagination. */ + cursor: Scalars['String'] +} + +export type OrderEventDiscountObject = { + __typename?: 'OrderEventDiscountObject' + /** Type of the discount: fixed or percent. */ + valueType: DiscountValueTypeEnum + /** Value of the discount. Can store fixed value or percent value. */ + value: Scalars['PositiveDecimal'] + /** Explanation for the applied discount. */ + reason?: Maybe + /** Returns amount of discount. */ + amount?: Maybe + /** Type of the discount: fixed or percent. */ + oldValueType?: Maybe + /** Value of the discount. Can store fixed value or percent value. */ + oldValue?: Maybe + /** Returns amount of discount. */ + oldAmount?: Maybe +} + +export type OrderEventOrderLineObject = { + __typename?: 'OrderEventOrderLineObject' + /** The variant quantity. */ + quantity?: Maybe + /** The order line. */ + orderLine?: Maybe + /** The variant name. */ + itemName?: Maybe + /** The discount applied to the order line. */ + discount?: Maybe +} + +/** An enumeration. */ +export enum OrderEventsEmailsEnum { + PaymentConfirmation = 'PAYMENT_CONFIRMATION', + Confirmed = 'CONFIRMED', + ShippingConfirmation = 'SHIPPING_CONFIRMATION', + TrackingUpdated = 'TRACKING_UPDATED', + OrderConfirmation = 'ORDER_CONFIRMATION', + OrderCancel = 'ORDER_CANCEL', + OrderRefund = 'ORDER_REFUND', + FulfillmentConfirmation = 'FULFILLMENT_CONFIRMATION', + DigitalLinks = 'DIGITAL_LINKS', +} + +/** An enumeration. */ +export enum OrderEventsEnum { + DraftCreated = 'DRAFT_CREATED', + DraftCreatedFromReplace = 'DRAFT_CREATED_FROM_REPLACE', + AddedProducts = 'ADDED_PRODUCTS', + RemovedProducts = 'REMOVED_PRODUCTS', + Placed = 'PLACED', + PlacedFromDraft = 'PLACED_FROM_DRAFT', + OversoldItems = 'OVERSOLD_ITEMS', + Canceled = 'CANCELED', + OrderMarkedAsPaid = 'ORDER_MARKED_AS_PAID', + OrderFullyPaid = 'ORDER_FULLY_PAID', + OrderReplacementCreated = 'ORDER_REPLACEMENT_CREATED', + OrderDiscountAdded = 'ORDER_DISCOUNT_ADDED', + OrderDiscountAutomaticallyUpdated = 'ORDER_DISCOUNT_AUTOMATICALLY_UPDATED', + OrderDiscountUpdated = 'ORDER_DISCOUNT_UPDATED', + OrderDiscountDeleted = 'ORDER_DISCOUNT_DELETED', + OrderLineDiscountUpdated = 'ORDER_LINE_DISCOUNT_UPDATED', + OrderLineDiscountRemoved = 'ORDER_LINE_DISCOUNT_REMOVED', + UpdatedAddress = 'UPDATED_ADDRESS', + EmailSent = 'EMAIL_SENT', + Confirmed = 'CONFIRMED', + PaymentAuthorized = 'PAYMENT_AUTHORIZED', + PaymentCaptured = 'PAYMENT_CAPTURED', + ExternalServiceNotification = 'EXTERNAL_SERVICE_NOTIFICATION', + PaymentRefunded = 'PAYMENT_REFUNDED', + PaymentVoided = 'PAYMENT_VOIDED', + PaymentFailed = 'PAYMENT_FAILED', + InvoiceRequested = 'INVOICE_REQUESTED', + InvoiceGenerated = 'INVOICE_GENERATED', + InvoiceUpdated = 'INVOICE_UPDATED', + InvoiceSent = 'INVOICE_SENT', + FulfillmentCanceled = 'FULFILLMENT_CANCELED', + FulfillmentRestockedItems = 'FULFILLMENT_RESTOCKED_ITEMS', + FulfillmentFulfilledItems = 'FULFILLMENT_FULFILLED_ITEMS', + FulfillmentRefunded = 'FULFILLMENT_REFUNDED', + FulfillmentReturned = 'FULFILLMENT_RETURNED', + FulfillmentReplaced = 'FULFILLMENT_REPLACED', + TrackingUpdated = 'TRACKING_UPDATED', + NoteAdded = 'NOTE_ADDED', + Other = 'OTHER', +} + +export type OrderFilterInput = { + paymentStatus?: Maybe>> + status?: Maybe>> + customer?: Maybe + created?: Maybe + search?: Maybe + metadata?: Maybe>> + channels?: Maybe>> +} + +/** Creates new fulfillments for an order. */ +export type OrderFulfill = { + __typename?: 'OrderFulfill' + /** List of created fulfillments. */ + fulfillments?: Maybe>> + /** Fulfilled order. */ + order?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + orderErrors: Array + errors: Array +} + +export type OrderFulfillInput = { + /** List of items informing how to fulfill the order. */ + lines: Array + /** If true, send an email notification to the customer. */ + notifyCustomer?: Maybe +} + +export type OrderFulfillLineInput = { + /** The ID of the order line. */ + orderLineId?: Maybe + /** List of stock items to create. */ + stocks: Array +} + +export type OrderFulfillStockInput = { + /** The number of line items to be fulfilled from given warehouse. */ + quantity: Scalars['Int'] + /** ID of the warehouse from which the item will be fulfilled. */ + warehouse: Scalars['ID'] +} + +/** Represents order line of particular order. */ +export type OrderLine = Node & { + __typename?: 'OrderLine' + /** The ID of the object. */ + id: Scalars['ID'] + productName: Scalars['String'] + variantName: Scalars['String'] + productSku: Scalars['String'] + isShippingRequired: Scalars['Boolean'] + quantity: Scalars['Int'] + quantityFulfilled: Scalars['Int'] + unitDiscountReason?: Maybe + taxRate: Scalars['Float'] + digitalContentUrl?: Maybe + /** The main thumbnail for the ordered product. */ + thumbnail?: Maybe + /** Price of the single item in the order line. */ + unitPrice: TaxedMoney + /** Price of the single item in the order line without applied an order line discount. */ + undiscountedUnitPrice: TaxedMoney + /** The discount applied to the single order line. */ + unitDiscount: Money + /** Value of the discount. Can store fixed value or percent value */ + unitDiscountValue: Scalars['PositiveDecimal'] + /** Price of the order line. */ + totalPrice: TaxedMoney + /** A purchased product variant. Note: this field may be null if the variant has been removed from stock at all. */ + variant?: Maybe + /** Product name in the customer's language */ + translatedProductName: Scalars['String'] + /** Variant name in the customer's language */ + translatedVariantName: Scalars['String'] + /** List of allocations across warehouses. */ + allocations?: Maybe> + /** Type of the discount: fixed or percent */ + unitDiscountType?: Maybe +} + +/** Represents order line of particular order. */ +export type OrderLineThumbnailArgs = { + size?: Maybe +} + +export type OrderLineCreateInput = { + /** Number of variant items ordered. */ + quantity: Scalars['Int'] + /** Product variant ID. */ + variantId: Scalars['ID'] +} + +/** Deletes an order line from an order. */ +export type OrderLineDelete = { + __typename?: 'OrderLineDelete' + /** A related order. */ + order?: Maybe + /** An order line that was deleted. */ + orderLine?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + orderErrors: Array + errors: Array +} + +/** Remove discount applied to the order line. */ +export type OrderLineDiscountRemove = { + __typename?: 'OrderLineDiscountRemove' + /** Order line which has removed discount. */ + orderLine?: Maybe + /** Order which is related to line which has removed discount. */ + order?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + orderErrors: Array + errors: Array +} + +/** Update discount for the order line. */ +export type OrderLineDiscountUpdate = { + __typename?: 'OrderLineDiscountUpdate' + /** Order line which has been discounted. */ + orderLine?: Maybe + /** Order which is related to the discounted line. */ + order?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + orderErrors: Array + errors: Array +} + +export type OrderLineInput = { + /** Number of variant items ordered. */ + quantity: Scalars['Int'] +} + +/** Updates an order line of an order. */ +export type OrderLineUpdate = { + __typename?: 'OrderLineUpdate' + /** Related order. */ + order?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + orderErrors: Array + errors: Array + orderLine?: Maybe +} + +/** Create order lines for an order. */ +export type OrderLinesCreate = { + __typename?: 'OrderLinesCreate' + /** Related order. */ + order?: Maybe + /** List of added order lines. */ + orderLines?: Maybe> + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + orderErrors: Array + errors: Array +} + +/** Mark order as manually paid. */ +export type OrderMarkAsPaid = { + __typename?: 'OrderMarkAsPaid' + /** Order marked as paid. */ + order?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + orderErrors: Array + errors: Array +} + +/** An enumeration. */ +export enum OrderOriginEnum { + Checkout = 'CHECKOUT', + Draft = 'DRAFT', + Reissue = 'REISSUE', +} + +/** Refund an order. */ +export type OrderRefund = { + __typename?: 'OrderRefund' + /** A refunded order. */ + order?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + orderErrors: Array + errors: Array +} + +export type OrderRefundFulfillmentLineInput = { + /** The ID of the fulfillment line to refund. */ + fulfillmentLineId: Scalars['ID'] + /** The number of items to be refunded. */ + quantity: Scalars['Int'] +} + +export type OrderRefundLineInput = { + /** The ID of the order line to refund. */ + orderLineId: Scalars['ID'] + /** The number of items to be refunded. */ + quantity: Scalars['Int'] +} + +export type OrderRefundProductsInput = { + /** List of unfulfilled lines to refund. */ + orderLines?: Maybe> + /** List of fulfilled lines to refund. */ + fulfillmentLines?: Maybe> + /** The total amount of refund when the value is provided manually. */ + amountToRefund?: Maybe + /** If true, Saleor will refund shipping costs. If amountToRefund is providedincludeShippingCosts will be ignored. */ + includeShippingCosts?: Maybe +} + +export type OrderReturnFulfillmentLineInput = { + /** The ID of the fulfillment line to return. */ + fulfillmentLineId: Scalars['ID'] + /** The number of items to be returned. */ + quantity: Scalars['Int'] + /** Determines, if the line should be added to replace order. */ + replace?: Maybe +} + +export type OrderReturnLineInput = { + /** The ID of the order line to return. */ + orderLineId: Scalars['ID'] + /** The number of items to be returned. */ + quantity: Scalars['Int'] + /** Determines, if the line should be added to replace order. */ + replace?: Maybe +} + +export type OrderReturnProductsInput = { + /** List of unfulfilled lines to return. */ + orderLines?: Maybe> + /** List of fulfilled lines to return. */ + fulfillmentLines?: Maybe> + /** The total amount of refund when the value is provided manually. */ + amountToRefund?: Maybe + /** If true, Saleor will refund shipping costs. If amountToRefund is providedincludeShippingCosts will be ignored. */ + includeShippingCosts?: Maybe + /** If true, Saleor will call refund action for all lines. */ + refund?: Maybe +} + +/** Order related settings from site settings. */ +export type OrderSettings = { + __typename?: 'OrderSettings' + automaticallyConfirmAllNewOrders: Scalars['Boolean'] +} + +export type OrderSettingsError = { + __typename?: 'OrderSettingsError' + /** Name of a field that caused the error. A value of `null` indicates that the error isn't associated with a particular field. */ + field?: Maybe + /** The error message. */ + message?: Maybe + /** The error code. */ + code: OrderSettingsErrorCode +} + +/** An enumeration. */ +export enum OrderSettingsErrorCode { + Invalid = 'INVALID', +} + +/** Update shop order settings. */ +export type OrderSettingsUpdate = { + __typename?: 'OrderSettingsUpdate' + /** Order settings. */ + orderSettings?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + orderSettingsErrors: Array + errors: Array +} + +export type OrderSettingsUpdateInput = { + /** When disabled, all new orders from checkout will be marked as unconfirmed. When enabled orders from checkout will become unfulfilled immediately. */ + automaticallyConfirmAllNewOrders: Scalars['Boolean'] +} + +export enum OrderSortField { + /** Sort orders by number. */ + Number = 'NUMBER', + /** Sort orders by creation date. */ + CreationDate = 'CREATION_DATE', + /** Sort orders by customer. */ + Customer = 'CUSTOMER', + /** Sort orders by payment. */ + Payment = 'PAYMENT', + /** Sort orders by fulfillment status. */ + FulfillmentStatus = 'FULFILLMENT_STATUS', +} + +export type OrderSortingInput = { + /** Specifies the direction in which to sort products. */ + direction: OrderDirection + /** Sort orders by the selected field. */ + field: OrderSortField +} + +/** An enumeration. */ +export enum OrderStatus { + /** Draft */ + Draft = 'DRAFT', + /** Unconfirmed */ + Unconfirmed = 'UNCONFIRMED', + /** Unfulfilled */ + Unfulfilled = 'UNFULFILLED', + /** Partially fulfilled */ + PartiallyFulfilled = 'PARTIALLY_FULFILLED', + /** Partially returned */ + PartiallyReturned = 'PARTIALLY_RETURNED', + /** Returned */ + Returned = 'RETURNED', + /** Fulfilled */ + Fulfilled = 'FULFILLED', + /** Canceled */ + Canceled = 'CANCELED', +} + +export enum OrderStatusFilter { + ReadyToFulfill = 'READY_TO_FULFILL', + ReadyToCapture = 'READY_TO_CAPTURE', + Unfulfilled = 'UNFULFILLED', + Unconfirmed = 'UNCONFIRMED', + PartiallyFulfilled = 'PARTIALLY_FULFILLED', + Fulfilled = 'FULFILLED', + Canceled = 'CANCELED', +} + +/** Updates an order. */ +export type OrderUpdate = { + __typename?: 'OrderUpdate' + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + orderErrors: Array + errors: Array + order?: Maybe +} + +export type OrderUpdateInput = { + /** Billing address of the customer. */ + billingAddress?: Maybe + /** Email address of the customer. */ + userEmail?: Maybe + /** Shipping address of the customer. */ + shippingAddress?: Maybe +} + +/** Updates a shipping method of the order. */ +export type OrderUpdateShipping = { + __typename?: 'OrderUpdateShipping' + /** Order with updated shipping method. */ + order?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + orderErrors: Array + errors: Array +} + +export type OrderUpdateShippingInput = { + /** ID of the selected shipping method. */ + shippingMethod?: Maybe +} + +/** Void an order. */ +export type OrderVoid = { + __typename?: 'OrderVoid' + /** A voided order. */ + order?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + orderErrors: Array + errors: Array +} + +/** A static page that can be manually added by a shop operator through the dashboard. */ +export type Page = Node & + ObjectWithMetadata & { + __typename?: 'Page' + /** The ID of the object. */ + id: Scalars['ID'] + seoTitle?: Maybe + seoDescription?: Maybe + title: Scalars['String'] + content?: Maybe + publicationDate?: Maybe + isPublished: Scalars['Boolean'] + slug: Scalars['String'] + pageType: PageType + created: Scalars['DateTime'] + /** List of private metadata items.Requires proper staff permissions to access. */ + privateMetadata: Array> + /** List of public metadata items. Can be accessed without permissions. */ + metadata: Array> + /** + * Content of the page (JSON). + * @deprecated Will be removed in Saleor 4.0. Use the `content` field instead. + */ + contentJson: Scalars['JSONString'] + /** Returns translated page fields for the given language code. */ + translation?: Maybe + /** List of attributes assigned to this product. */ + attributes: Array + } + +/** A static page that can be manually added by a shop operator through the dashboard. */ +export type PageTranslationArgs = { + languageCode: LanguageCodeEnum +} + +/** Assign attributes to a given page type. */ +export type PageAttributeAssign = { + __typename?: 'PageAttributeAssign' + /** The updated page type. */ + pageType?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + pageErrors: Array + errors: Array +} + +/** Unassign attributes from a given page type. */ +export type PageAttributeUnassign = { + __typename?: 'PageAttributeUnassign' + /** The updated page type. */ + pageType?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + pageErrors: Array + errors: Array +} + +/** Deletes pages. */ +export type PageBulkDelete = { + __typename?: 'PageBulkDelete' + /** Returns how many objects were affected. */ + count: Scalars['Int'] + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + pageErrors: Array + errors: Array +} + +/** Publish pages. */ +export type PageBulkPublish = { + __typename?: 'PageBulkPublish' + /** Returns how many objects were affected. */ + count: Scalars['Int'] + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + pageErrors: Array + errors: Array +} + +export type PageCountableConnection = { + __typename?: 'PageCountableConnection' + /** Pagination data for this connection. */ + pageInfo: PageInfo + edges: Array + /** A total count of items in the collection. */ + totalCount?: Maybe +} + +export type PageCountableEdge = { + __typename?: 'PageCountableEdge' + /** The item at the end of the edge. */ + node: Page + /** A cursor for use in pagination. */ + cursor: Scalars['String'] +} + +/** Creates a new page. */ +export type PageCreate = { + __typename?: 'PageCreate' + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + pageErrors: Array + errors: Array + page?: Maybe +} + +export type PageCreateInput = { + /** Page internal name. */ + slug?: Maybe + /** Page title. */ + title?: Maybe + /** Page content in JSON format. */ + content?: Maybe + /** List of attributes. */ + attributes?: Maybe> + /** Determines if page is visible in the storefront. */ + isPublished?: Maybe + /** Publication date. ISO 8601 standard. */ + publicationDate?: Maybe + /** Search engine optimization fields. */ + seo?: Maybe + /** ID of the page type that page belongs to. */ + pageType: Scalars['ID'] +} + +/** Deletes a page. */ +export type PageDelete = { + __typename?: 'PageDelete' + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + pageErrors: Array + errors: Array + page?: Maybe +} + +export type PageError = { + __typename?: 'PageError' + /** Name of a field that caused the error. A value of `null` indicates that the error isn't associated with a particular field. */ + field?: Maybe + /** The error message. */ + message?: Maybe + /** The error code. */ + code: PageErrorCode + /** List of attributes IDs which causes the error. */ + attributes?: Maybe> + /** List of attribute values IDs which causes the error. */ + values?: Maybe> +} + +/** An enumeration. */ +export enum PageErrorCode { + GraphqlError = 'GRAPHQL_ERROR', + Invalid = 'INVALID', + NotFound = 'NOT_FOUND', + Required = 'REQUIRED', + Unique = 'UNIQUE', + DuplicatedInputItem = 'DUPLICATED_INPUT_ITEM', + AttributeAlreadyAssigned = 'ATTRIBUTE_ALREADY_ASSIGNED', +} + +export type PageFilterInput = { + search?: Maybe + metadata?: Maybe>> + pageTypes?: Maybe>> +} + +/** The Relay compliant `PageInfo` type, containing data necessary to paginate this connection. */ +export type PageInfo = { + __typename?: 'PageInfo' + /** When paginating forwards, are there more items? */ + hasNextPage: Scalars['Boolean'] + /** When paginating backwards, are there more items? */ + hasPreviousPage: Scalars['Boolean'] + /** When paginating backwards, the cursor to continue. */ + startCursor?: Maybe + /** When paginating forwards, the cursor to continue. */ + endCursor?: Maybe +} + +export type PageInput = { + /** Page internal name. */ + slug?: Maybe + /** Page title. */ + title?: Maybe + /** Page content in JSON format. */ + content?: Maybe + /** List of attributes. */ + attributes?: Maybe> + /** Determines if page is visible in the storefront. */ + isPublished?: Maybe + /** Publication date. ISO 8601 standard. */ + publicationDate?: Maybe + /** Search engine optimization fields. */ + seo?: Maybe +} + +/** Reorder page attribute values. */ +export type PageReorderAttributeValues = { + __typename?: 'PageReorderAttributeValues' + /** Page from which attribute values are reordered. */ + page?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + pageErrors: Array + errors: Array +} + +export enum PageSortField { + /** Sort pages by title. */ + Title = 'TITLE', + /** Sort pages by slug. */ + Slug = 'SLUG', + /** Sort pages by visibility. */ + Visibility = 'VISIBILITY', + /** Sort pages by creation date. */ + CreationDate = 'CREATION_DATE', + /** Sort pages by publication date. */ + PublicationDate = 'PUBLICATION_DATE', +} + +export type PageSortingInput = { + /** Specifies the direction in which to sort products. */ + direction: OrderDirection + /** Sort pages by the selected field. */ + field: PageSortField +} + +export type PageTranslatableContent = Node & { + __typename?: 'PageTranslatableContent' + /** The ID of the object. */ + id: Scalars['ID'] + seoTitle?: Maybe + seoDescription?: Maybe + title: Scalars['String'] + content?: Maybe + /** + * Content of the page (JSON). + * @deprecated Will be removed in Saleor 4.0. Use the `content` field instead. + */ + contentJson?: Maybe + /** Returns translated page fields for the given language code. */ + translation?: Maybe + /** ('A static page that can be manually added by a shop operator ', 'through the dashboard.') */ + page?: Maybe +} + +export type PageTranslatableContentTranslationArgs = { + languageCode: LanguageCodeEnum +} + +/** Creates/Updates translations for Page. */ +export type PageTranslate = { + __typename?: 'PageTranslate' + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + translationErrors: Array + errors: Array + page?: Maybe +} + +export type PageTranslation = Node & { + __typename?: 'PageTranslation' + /** The ID of the object. */ + id: Scalars['ID'] + seoTitle?: Maybe + seoDescription?: Maybe + title: Scalars['String'] + content?: Maybe + /** Translation language. */ + language: LanguageDisplay + /** + * Translated description of the page (JSON). + * @deprecated Will be removed in Saleor 4.0. Use the `content` field instead. + */ + contentJson?: Maybe +} + +export type PageTranslationInput = { + seoTitle?: Maybe + seoDescription?: Maybe + title?: Maybe + content?: Maybe +} + +/** Represents a type of page. It defines what attributes are available to pages of this type. */ +export type PageType = Node & + ObjectWithMetadata & { + __typename?: 'PageType' + /** The ID of the object. */ + id: Scalars['ID'] + name: Scalars['String'] + slug: Scalars['String'] + /** List of private metadata items.Requires proper staff permissions to access. */ + privateMetadata: Array> + /** List of public metadata items. Can be accessed without permissions. */ + metadata: Array> + /** Page attributes of that page type. */ + attributes?: Maybe>> + /** Attributes that can be assigned to the page type. */ + availableAttributes?: Maybe + /** Whether page type has pages assigned. */ + hasPages?: Maybe + } + +/** Represents a type of page. It defines what attributes are available to pages of this type. */ +export type PageTypeAvailableAttributesArgs = { + filter?: Maybe + before?: Maybe + after?: Maybe + first?: Maybe + last?: Maybe +} + +/** Delete page types. */ +export type PageTypeBulkDelete = { + __typename?: 'PageTypeBulkDelete' + /** Returns how many objects were affected. */ + count: Scalars['Int'] + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + pageErrors: Array + errors: Array +} + +export type PageTypeCountableConnection = { + __typename?: 'PageTypeCountableConnection' + /** Pagination data for this connection. */ + pageInfo: PageInfo + edges: Array + /** A total count of items in the collection. */ + totalCount?: Maybe +} + +export type PageTypeCountableEdge = { + __typename?: 'PageTypeCountableEdge' + /** The item at the end of the edge. */ + node: PageType + /** A cursor for use in pagination. */ + cursor: Scalars['String'] +} + +/** Create a new page type. */ +export type PageTypeCreate = { + __typename?: 'PageTypeCreate' + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + pageErrors: Array + errors: Array + pageType?: Maybe +} + +export type PageTypeCreateInput = { + /** Name of the page type. */ + name?: Maybe + /** Page type slug. */ + slug?: Maybe + /** List of attribute IDs to be assigned to the page type. */ + addAttributes?: Maybe> +} + +/** Delete a page type. */ +export type PageTypeDelete = { + __typename?: 'PageTypeDelete' + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + pageErrors: Array + errors: Array + pageType?: Maybe +} + +export type PageTypeFilterInput = { + search?: Maybe +} + +/** Reorder the attributes of a page type. */ +export type PageTypeReorderAttributes = { + __typename?: 'PageTypeReorderAttributes' + /** Page type from which attributes are reordered. */ + pageType?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + pageErrors: Array + errors: Array +} + +export enum PageTypeSortField { + /** Sort page types by name. */ + Name = 'NAME', + /** Sort page types by slug. */ + Slug = 'SLUG', +} + +export type PageTypeSortingInput = { + /** Specifies the direction in which to sort products. */ + direction: OrderDirection + /** Sort page types by the selected field. */ + field: PageTypeSortField +} + +/** Update page type. */ +export type PageTypeUpdate = { + __typename?: 'PageTypeUpdate' + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + pageErrors: Array + errors: Array + pageType?: Maybe +} + +export type PageTypeUpdateInput = { + /** Name of the page type. */ + name?: Maybe + /** Page type slug. */ + slug?: Maybe + /** List of attribute IDs to be assigned to the page type. */ + addAttributes?: Maybe> + /** List of attribute IDs to be assigned to the page type. */ + removeAttributes?: Maybe> +} + +/** Updates an existing page. */ +export type PageUpdate = { + __typename?: 'PageUpdate' + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + pageErrors: Array + errors: Array + page?: Maybe +} + +/** Change the password of the logged in user. */ +export type PasswordChange = { + __typename?: 'PasswordChange' + /** A user instance with a new password. */ + user?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + accountErrors: Array + errors: Array +} + +/** Represents a payment of a given type. */ +export type Payment = Node & { + __typename?: 'Payment' + /** The ID of the object. */ + id: Scalars['ID'] + gateway: Scalars['String'] + isActive: Scalars['Boolean'] + created: Scalars['DateTime'] + modified: Scalars['DateTime'] + token: Scalars['String'] + checkout?: Maybe + order?: Maybe + paymentMethodType: Scalars['String'] + customerIpAddress?: Maybe + /** Internal payment status. */ + chargeStatus: PaymentChargeStatusEnum + /** List of actions that can be performed in the current state of a payment. */ + actions: Array> + /** Total amount of the payment. */ + total?: Maybe + /** Total amount captured for this payment. */ + capturedAmount?: Maybe + /** List of all transactions within this payment. */ + transactions?: Maybe>> + /** Maximum amount of money that can be captured. */ + availableCaptureAmount?: Maybe + /** Maximum amount of money that can be refunded. */ + availableRefundAmount?: Maybe + /** The details of the card used for this payment. */ + creditCard?: Maybe +} + +/** Captures the authorized payment amount. */ +export type PaymentCapture = { + __typename?: 'PaymentCapture' + /** Updated payment. */ + payment?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + paymentErrors: Array + errors: Array +} + +/** An enumeration. */ +export enum PaymentChargeStatusEnum { + NotCharged = 'NOT_CHARGED', + Pending = 'PENDING', + PartiallyCharged = 'PARTIALLY_CHARGED', + FullyCharged = 'FULLY_CHARGED', + PartiallyRefunded = 'PARTIALLY_REFUNDED', + FullyRefunded = 'FULLY_REFUNDED', + Refused = 'REFUSED', + Cancelled = 'CANCELLED', +} + +export type PaymentCountableConnection = { + __typename?: 'PaymentCountableConnection' + /** Pagination data for this connection. */ + pageInfo: PageInfo + edges: Array + /** A total count of items in the collection. */ + totalCount?: Maybe +} + +export type PaymentCountableEdge = { + __typename?: 'PaymentCountableEdge' + /** The item at the end of the edge. */ + node: Payment + /** A cursor for use in pagination. */ + cursor: Scalars['String'] +} + +export type PaymentError = { + __typename?: 'PaymentError' + /** Name of a field that caused the error. A value of `null` indicates that the error isn't associated with a particular field. */ + field?: Maybe + /** The error message. */ + message?: Maybe + /** The error code. */ + code: PaymentErrorCode +} + +/** An enumeration. */ +export enum PaymentErrorCode { + BillingAddressNotSet = 'BILLING_ADDRESS_NOT_SET', + GraphqlError = 'GRAPHQL_ERROR', + Invalid = 'INVALID', + NotFound = 'NOT_FOUND', + Required = 'REQUIRED', + Unique = 'UNIQUE', + PartialPaymentNotAllowed = 'PARTIAL_PAYMENT_NOT_ALLOWED', + ShippingAddressNotSet = 'SHIPPING_ADDRESS_NOT_SET', + InvalidShippingMethod = 'INVALID_SHIPPING_METHOD', + ShippingMethodNotSet = 'SHIPPING_METHOD_NOT_SET', + PaymentError = 'PAYMENT_ERROR', + NotSupportedGateway = 'NOT_SUPPORTED_GATEWAY', + ChannelInactive = 'CHANNEL_INACTIVE', +} + +export type PaymentFilterInput = { + checkouts?: Maybe>> +} + +/** Available payment gateway backend with configuration necessary to setup client. */ +export type PaymentGateway = { + __typename?: 'PaymentGateway' + /** Payment gateway name. */ + name: Scalars['String'] + /** Payment gateway ID. */ + id: Scalars['ID'] + /** Payment gateway client configuration. */ + config: Array + /** Payment gateway supported currencies. */ + currencies: Array> +} + +/** Initializes payment process when it is required by gateway. */ +export type PaymentInitialize = { + __typename?: 'PaymentInitialize' + initializedPayment?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + paymentErrors: Array + errors: Array +} + +/** Server-side data generated by a payment gateway. Optional step when the payment provider requires an additional action to initialize payment session. */ +export type PaymentInitialized = { + __typename?: 'PaymentInitialized' + /** ID of a payment gateway. */ + gateway: Scalars['String'] + /** Payment gateway name. */ + name: Scalars['String'] + /** Initialized data by gateway. */ + data?: Maybe +} + +export type PaymentInput = { + /** A gateway to use with that payment. */ + gateway: Scalars['String'] + /** Client-side generated payment token, representing customer's billing data in a secure manner. */ + token?: Maybe + /** Total amount of the transaction, including all taxes and discounts. If no amount is provided, the checkout total will be used. */ + amount?: Maybe + /** URL of a storefront view where user should be redirected after requiring additional actions. Payment with additional actions will not be finished if this field is not provided. */ + returnUrl?: Maybe +} + +/** Refunds the captured payment amount. */ +export type PaymentRefund = { + __typename?: 'PaymentRefund' + /** Updated payment. */ + payment?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + paymentErrors: Array + errors: Array +} + +/** Represents a payment source stored for user in payment gateway, such as credit card. */ +export type PaymentSource = { + __typename?: 'PaymentSource' + /** Payment gateway name. */ + gateway: Scalars['String'] + /** Stored credit card details if available. */ + creditCardInfo?: Maybe +} + +/** Voids the authorized payment. */ +export type PaymentVoid = { + __typename?: 'PaymentVoid' + /** Updated payment. */ + payment?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + paymentErrors: Array + errors: Array +} + +/** Represents a permission object in a friendly form. */ +export type Permission = { + __typename?: 'Permission' + /** Internal code for permission. */ + code: PermissionEnum + /** Describe action(s) allowed to do by permission. */ + name: Scalars['String'] +} + +/** An enumeration. */ +export enum PermissionEnum { + ManageUsers = 'MANAGE_USERS', + ManageStaff = 'MANAGE_STAFF', + ManageApps = 'MANAGE_APPS', + ManageChannels = 'MANAGE_CHANNELS', + ManageDiscounts = 'MANAGE_DISCOUNTS', + ManagePlugins = 'MANAGE_PLUGINS', + ManageGiftCard = 'MANAGE_GIFT_CARD', + ManageMenus = 'MANAGE_MENUS', + ManageOrders = 'MANAGE_ORDERS', + ManagePages = 'MANAGE_PAGES', + ManagePageTypesAndAttributes = 'MANAGE_PAGE_TYPES_AND_ATTRIBUTES', + ManageProducts = 'MANAGE_PRODUCTS', + ManageProductTypesAndAttributes = 'MANAGE_PRODUCT_TYPES_AND_ATTRIBUTES', + ManageShipping = 'MANAGE_SHIPPING', + ManageSettings = 'MANAGE_SETTINGS', + ManageTranslations = 'MANAGE_TRANSLATIONS', + ManageCheckouts = 'MANAGE_CHECKOUTS', +} + +/** Create new permission group. */ +export type PermissionGroupCreate = { + __typename?: 'PermissionGroupCreate' + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + permissionGroupErrors: Array + errors: Array + group?: Maybe +} + +export type PermissionGroupCreateInput = { + /** List of permission code names to assign to this group. */ + addPermissions?: Maybe> + /** List of users to assign to this group. */ + addUsers?: Maybe> + /** Group name. */ + name: Scalars['String'] +} + +/** Delete permission group. */ +export type PermissionGroupDelete = { + __typename?: 'PermissionGroupDelete' + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + permissionGroupErrors: Array + errors: Array + group?: Maybe +} + +export type PermissionGroupError = { + __typename?: 'PermissionGroupError' + /** Name of a field that caused the error. A value of `null` indicates that the error isn't associated with a particular field. */ + field?: Maybe + /** The error message. */ + message?: Maybe + /** The error code. */ + code: PermissionGroupErrorCode + /** List of permissions which causes the error. */ + permissions?: Maybe> + /** List of user IDs which causes the error. */ + users?: Maybe> +} + +/** An enumeration. */ +export enum PermissionGroupErrorCode { + AssignNonStaffMember = 'ASSIGN_NON_STAFF_MEMBER', + DuplicatedInputItem = 'DUPLICATED_INPUT_ITEM', + CannotRemoveFromLastGroup = 'CANNOT_REMOVE_FROM_LAST_GROUP', + LeftNotManageablePermission = 'LEFT_NOT_MANAGEABLE_PERMISSION', + OutOfScopePermission = 'OUT_OF_SCOPE_PERMISSION', + OutOfScopeUser = 'OUT_OF_SCOPE_USER', + Required = 'REQUIRED', + Unique = 'UNIQUE', +} + +export type PermissionGroupFilterInput = { + search?: Maybe +} + +export enum PermissionGroupSortField { + /** Sort permission group accounts by name. */ + Name = 'NAME', +} + +export type PermissionGroupSortingInput = { + /** Specifies the direction in which to sort products. */ + direction: OrderDirection + /** Sort permission group by the selected field. */ + field: PermissionGroupSortField +} + +/** Update permission group. */ +export type PermissionGroupUpdate = { + __typename?: 'PermissionGroupUpdate' + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + permissionGroupErrors: Array + errors: Array + group?: Maybe +} + +export type PermissionGroupUpdateInput = { + /** List of permission code names to assign to this group. */ + addPermissions?: Maybe> + /** List of users to assign to this group. */ + addUsers?: Maybe> + /** Group name. */ + name?: Maybe + /** List of permission code names to unassign from this group. */ + removePermissions?: Maybe> + /** List of users to unassign from this group. */ + removeUsers?: Maybe> +} + +/** Plugin. */ +export type Plugin = { + __typename?: 'Plugin' + /** Identifier of the plugin. */ + id: Scalars['ID'] + /** Name of the plugin. */ + name: Scalars['String'] + /** Description of the plugin. */ + description: Scalars['String'] + /** Global configuration of the plugin (not channel-specific). */ + globalConfiguration?: Maybe + /** Channel-specific plugin configuration. */ + channelConfigurations: Array +} + +/** Stores information about a configuration of plugin. */ +export type PluginConfiguration = { + __typename?: 'PluginConfiguration' + /** Determines if plugin is active or not. */ + active: Scalars['Boolean'] + /** The channel to which the plugin configuration is assigned to. */ + channel?: Maybe + /** Configuration of the plugin. */ + configuration?: Maybe>> +} + +export enum PluginConfigurationType { + PerChannel = 'PER_CHANNEL', + Global = 'GLOBAL', +} + +export type PluginCountableConnection = { + __typename?: 'PluginCountableConnection' + /** Pagination data for this connection. */ + pageInfo: PageInfo + edges: Array + /** A total count of items in the collection. */ + totalCount?: Maybe +} + +export type PluginCountableEdge = { + __typename?: 'PluginCountableEdge' + /** The item at the end of the edge. */ + node: Plugin + /** A cursor for use in pagination. */ + cursor: Scalars['String'] +} + +export type PluginError = { + __typename?: 'PluginError' + /** Name of a field that caused the error. A value of `null` indicates that the error isn't associated with a particular field. */ + field?: Maybe + /** The error message. */ + message?: Maybe + /** The error code. */ + code: PluginErrorCode +} + +/** An enumeration. */ +export enum PluginErrorCode { + GraphqlError = 'GRAPHQL_ERROR', + Invalid = 'INVALID', + PluginMisconfigured = 'PLUGIN_MISCONFIGURED', + NotFound = 'NOT_FOUND', + Required = 'REQUIRED', + Unique = 'UNIQUE', +} + +export type PluginFilterInput = { + statusInChannels?: Maybe + search?: Maybe + type?: Maybe +} + +export enum PluginSortField { + Name = 'NAME', + IsActive = 'IS_ACTIVE', +} + +export type PluginSortingInput = { + /** Specifies the direction in which to sort products. */ + direction: OrderDirection + /** Sort plugins by the selected field. */ + field: PluginSortField +} + +export type PluginStatusInChannelsInput = { + active: Scalars['Boolean'] + channels: Array +} + +/** Update plugin configuration. */ +export type PluginUpdate = { + __typename?: 'PluginUpdate' + plugin?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + pluginsErrors: Array + errors: Array +} + +export type PluginUpdateInput = { + /** Indicates whether the plugin should be enabled. */ + active?: Maybe + /** Configuration of the plugin. */ + configuration?: Maybe>> +} + +/** An enumeration. */ +export enum PostalCodeRuleInclusionTypeEnum { + Include = 'INCLUDE', + Exclude = 'EXCLUDE', +} + +export type PriceRangeInput = { + /** Price greater than or equal to. */ + gte?: Maybe + /** Price less than or equal to. */ + lte?: Maybe +} + +/** Represents an individual item for sale in the storefront. */ +export type Product = Node & + ObjectWithMetadata & { + __typename?: 'Product' + /** The ID of the object. */ + id: Scalars['ID'] + seoTitle?: Maybe + seoDescription?: Maybe + name: Scalars['String'] + description?: Maybe + productType: ProductType + slug: Scalars['String'] + category?: Maybe + updatedAt?: Maybe + chargeTaxes: Scalars['Boolean'] + weight?: Maybe + defaultVariant?: Maybe + rating?: Maybe + /** List of private metadata items.Requires proper staff permissions to access. */ + privateMetadata: Array> + /** List of public metadata items. Can be accessed without permissions. */ + metadata: Array> + /** + * Description of the product (JSON). + * @deprecated Will be removed in Saleor 4.0. Use the `description` field instead. + */ + descriptionJson?: Maybe + /** The main thumbnail for a product. */ + thumbnail?: Maybe + /** Lists the storefront product's pricing, the current price and discounts, only meant for displaying. */ + pricing?: Maybe + /** Whether the product is in stock and visible or not. */ + isAvailable?: Maybe + /** A type of tax. Assigned by enabled tax gateway */ + taxType?: Maybe + /** List of attributes assigned to this product. */ + attributes: Array + /** List of availability in channels for the product. */ + channelListings?: Maybe> + /** Get a single product media by ID. */ + mediaById: ProductMedia + /** + * Get a single product image by ID. + * @deprecated Will be removed in Saleor 4.0. Use the `mediaById` field instead. + */ + imageById?: Maybe + /** List of variants for the product. */ + variants?: Maybe>> + /** List of media for the product. */ + media?: Maybe> + /** + * List of images for the product. + * @deprecated Will be removed in Saleor 4.0. Use the `media` field instead. + */ + images?: Maybe>> + /** List of collections for the product. */ + collections?: Maybe>> + /** Returns translated product fields for the given language code. */ + translation?: Maybe + /** Date when product is available for purchase. */ + availableForPurchase?: Maybe + /** Whether the product is available for purchase. */ + isAvailableForPurchase?: Maybe + } + +/** Represents an individual item for sale in the storefront. */ +export type ProductThumbnailArgs = { + size?: Maybe +} + +/** Represents an individual item for sale in the storefront. */ +export type ProductPricingArgs = { + address?: Maybe +} + +/** Represents an individual item for sale in the storefront. */ +export type ProductIsAvailableArgs = { + address?: Maybe +} + +/** Represents an individual item for sale in the storefront. */ +export type ProductMediaByIdArgs = { + id?: Maybe +} + +/** Represents an individual item for sale in the storefront. */ +export type ProductImageByIdArgs = { + id?: Maybe +} + +/** Represents an individual item for sale in the storefront. */ +export type ProductTranslationArgs = { + languageCode: LanguageCodeEnum +} + +/** Assign attributes to a given product type. */ +export type ProductAttributeAssign = { + __typename?: 'ProductAttributeAssign' + /** The updated product type. */ + productType?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + productErrors: Array + errors: Array +} + +export type ProductAttributeAssignInput = { + /** The ID of the attribute to assign. */ + id: Scalars['ID'] + /** The attribute type to be assigned as. */ + type: ProductAttributeType +} + +export enum ProductAttributeType { + Product = 'PRODUCT', + Variant = 'VARIANT', +} + +/** Un-assign attributes from a given product type. */ +export type ProductAttributeUnassign = { + __typename?: 'ProductAttributeUnassign' + /** The updated product type. */ + productType?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + productErrors: Array + errors: Array +} + +/** Deletes products. */ +export type ProductBulkDelete = { + __typename?: 'ProductBulkDelete' + /** Returns how many objects were affected. */ + count: Scalars['Int'] + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + productErrors: Array + errors: Array +} + +/** Represents product channel listing. */ +export type ProductChannelListing = Node & { + __typename?: 'ProductChannelListing' + /** The ID of the object. */ + id: Scalars['ID'] + publicationDate?: Maybe + isPublished: Scalars['Boolean'] + channel: Channel + visibleInListings: Scalars['Boolean'] + availableForPurchase?: Maybe + /** The price of the cheapest variant (including discounts). */ + discountedPrice?: Maybe + /** Purchase cost of product. */ + purchaseCost?: Maybe + /** Range of margin percentage value. */ + margin?: Maybe + /** Whether the product is available for purchase. */ + isAvailableForPurchase?: Maybe + /** Lists the storefront product's pricing, the current price and discounts, only meant for displaying. */ + pricing?: Maybe +} + +/** Represents product channel listing. */ +export type ProductChannelListingPricingArgs = { + address?: Maybe +} + +export type ProductChannelListingAddInput = { + /** ID of a channel. */ + channelId: Scalars['ID'] + /** Determines if object is visible to customers. */ + isPublished?: Maybe + /** Publication date. ISO 8601 standard. */ + publicationDate?: Maybe + /** Determines if product is visible in product listings (doesn't apply to product collections). */ + visibleInListings?: Maybe + /** Determine if product should be available for purchase. */ + isAvailableForPurchase?: Maybe + /** A start date from which a product will be available for purchase. When not set and isAvailable is set to True, the current day is assumed. */ + availableForPurchaseDate?: Maybe + /** List of variants to which the channel should be assigned. */ + addVariants?: Maybe> + /** List of variants from which the channel should be unassigned. */ + removeVariants?: Maybe> +} + +export type ProductChannelListingError = { + __typename?: 'ProductChannelListingError' + /** Name of a field that caused the error. A value of `null` indicates that the error isn't associated with a particular field. */ + field?: Maybe + /** The error message. */ + message?: Maybe + /** The error code. */ + code: ProductErrorCode + /** List of attributes IDs which causes the error. */ + attributes?: Maybe> + /** List of attribute values IDs which causes the error. */ + values?: Maybe> + /** List of channels IDs which causes the error. */ + channels?: Maybe> + /** List of variants IDs which causes the error. */ + variants?: Maybe> +} + +/** Manage product's availability in channels. */ +export type ProductChannelListingUpdate = { + __typename?: 'ProductChannelListingUpdate' + /** An updated product instance. */ + product?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + productChannelListingErrors: Array + errors: Array +} + +export type ProductChannelListingUpdateInput = { + /** List of channels to which the product should be assigned or updated. */ + updateChannels?: Maybe> + /** List of channels from which the product should be unassigned. */ + removeChannels?: Maybe> +} + +export type ProductCountableConnection = { + __typename?: 'ProductCountableConnection' + /** Pagination data for this connection. */ + pageInfo: PageInfo + edges: Array + /** A total count of items in the collection. */ + totalCount?: Maybe +} + +export type ProductCountableEdge = { + __typename?: 'ProductCountableEdge' + /** The item at the end of the edge. */ + node: Product + /** A cursor for use in pagination. */ + cursor: Scalars['String'] +} + +/** Creates a new product. */ +export type ProductCreate = { + __typename?: 'ProductCreate' + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + productErrors: Array + errors: Array + product?: Maybe +} + +export type ProductCreateInput = { + /** List of attributes. */ + attributes?: Maybe> + /** ID of the product's category. */ + category?: Maybe + /** Determine if taxes are being charged for the product. */ + chargeTaxes?: Maybe + /** List of IDs of collections that the product belongs to. */ + collections?: Maybe> + /** Product description (JSON). */ + description?: Maybe + /** Product name. */ + name?: Maybe + /** Product slug. */ + slug?: Maybe + /** Tax rate for enabled tax gateway. */ + taxCode?: Maybe + /** Search engine optimization fields. */ + seo?: Maybe + /** Weight of the Product. */ + weight?: Maybe + /** Defines the product rating value. */ + rating?: Maybe + /** ID of the type that product belongs to. */ + productType: Scalars['ID'] +} + +/** Deletes a product. */ +export type ProductDelete = { + __typename?: 'ProductDelete' + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + productErrors: Array + errors: Array + product?: Maybe +} + +export type ProductError = { + __typename?: 'ProductError' + /** Name of a field that caused the error. A value of `null` indicates that the error isn't associated with a particular field. */ + field?: Maybe + /** The error message. */ + message?: Maybe + /** The error code. */ + code: ProductErrorCode + /** List of attributes IDs which causes the error. */ + attributes?: Maybe> + /** List of attribute values IDs which causes the error. */ + values?: Maybe> +} + +/** An enumeration. */ +export enum ProductErrorCode { + AlreadyExists = 'ALREADY_EXISTS', + AttributeAlreadyAssigned = 'ATTRIBUTE_ALREADY_ASSIGNED', + AttributeCannotBeAssigned = 'ATTRIBUTE_CANNOT_BE_ASSIGNED', + AttributeVariantsDisabled = 'ATTRIBUTE_VARIANTS_DISABLED', + DuplicatedInputItem = 'DUPLICATED_INPUT_ITEM', + GraphqlError = 'GRAPHQL_ERROR', + Invalid = 'INVALID', + ProductWithoutCategory = 'PRODUCT_WITHOUT_CATEGORY', + NotProductsImage = 'NOT_PRODUCTS_IMAGE', + NotProductsVariant = 'NOT_PRODUCTS_VARIANT', + NotFound = 'NOT_FOUND', + Required = 'REQUIRED', + Unique = 'UNIQUE', + VariantNoDigitalContent = 'VARIANT_NO_DIGITAL_CONTENT', + CannotManageProductWithoutVariant = 'CANNOT_MANAGE_PRODUCT_WITHOUT_VARIANT', + ProductNotAssignedToChannel = 'PRODUCT_NOT_ASSIGNED_TO_CHANNEL', + UnsupportedMediaProvider = 'UNSUPPORTED_MEDIA_PROVIDER', +} + +export enum ProductFieldEnum { + Name = 'NAME', + Description = 'DESCRIPTION', + ProductType = 'PRODUCT_TYPE', + Category = 'CATEGORY', + ProductWeight = 'PRODUCT_WEIGHT', + Collections = 'COLLECTIONS', + ChargeTaxes = 'CHARGE_TAXES', + ProductMedia = 'PRODUCT_MEDIA', + VariantSku = 'VARIANT_SKU', + VariantWeight = 'VARIANT_WEIGHT', + VariantMedia = 'VARIANT_MEDIA', +} + +export type ProductFilterInput = { + isPublished?: Maybe + collections?: Maybe>> + categories?: Maybe>> + hasCategory?: Maybe + attributes?: Maybe>> + stockAvailability?: Maybe + stocks?: Maybe + search?: Maybe + metadata?: Maybe>> + price?: Maybe + minimalPrice?: Maybe + productTypes?: Maybe>> + ids?: Maybe>> + /** Specifies the channel by which the data should be sorted. */ + channel?: Maybe +} + +/** Represents a product image. */ +export type ProductImage = { + __typename?: 'ProductImage' + /** The ID of the image. */ + id: Scalars['ID'] + /** The alt text of the image. */ + alt?: Maybe + /** The new relative sorting position of the item (from -inf to +inf). 1 moves the item one position forward, -1 moves the item one position backward, 0 leaves the item unchanged. */ + sortOrder?: Maybe + /** The URL of the image. */ + url: Scalars['String'] +} + +/** Represents a product image. */ +export type ProductImageUrlArgs = { + size?: Maybe +} + +export type ProductInput = { + /** List of attributes. */ + attributes?: Maybe> + /** ID of the product's category. */ + category?: Maybe + /** Determine if taxes are being charged for the product. */ + chargeTaxes?: Maybe + /** List of IDs of collections that the product belongs to. */ + collections?: Maybe> + /** Product description (JSON). */ + description?: Maybe + /** Product name. */ + name?: Maybe + /** Product slug. */ + slug?: Maybe + /** Tax rate for enabled tax gateway. */ + taxCode?: Maybe + /** Search engine optimization fields. */ + seo?: Maybe + /** Weight of the Product. */ + weight?: Maybe + /** Defines the product rating value. */ + rating?: Maybe +} + +/** Represents a product media. */ +export type ProductMedia = Node & { + __typename?: 'ProductMedia' + /** The ID of the object. */ + id: Scalars['ID'] + sortOrder?: Maybe + alt: Scalars['String'] + type: ProductMediaType + oembedData: Scalars['JSONString'] + /** The URL of the media. */ + url: Scalars['String'] +} + +/** Represents a product media. */ +export type ProductMediaUrlArgs = { + size?: Maybe +} + +/** Deletes product media. */ +export type ProductMediaBulkDelete = { + __typename?: 'ProductMediaBulkDelete' + /** Returns how many objects were affected. */ + count: Scalars['Int'] + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + productErrors: Array + errors: Array +} + +/** Create a media object (image or video URL) associated with product. For image, this mutation must be sent as a `multipart` request. More detailed specs of the upload format can be found here: https://github.com/jaydenseric/graphql-multipart-request-spec */ +export type ProductMediaCreate = { + __typename?: 'ProductMediaCreate' + product?: Maybe + media?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + productErrors: Array + errors: Array +} + +export type ProductMediaCreateInput = { + /** Alt text for a product media. */ + alt?: Maybe + /** Represents an image file in a multipart request. */ + image?: Maybe + /** ID of an product. */ + product: Scalars['ID'] + /** Represents an URL to an external media. */ + mediaUrl?: Maybe +} + +/** Deletes a product media. */ +export type ProductMediaDelete = { + __typename?: 'ProductMediaDelete' + product?: Maybe + media?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + productErrors: Array + errors: Array +} + +/** Changes ordering of the product media. */ +export type ProductMediaReorder = { + __typename?: 'ProductMediaReorder' + product?: Maybe + media?: Maybe> + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + productErrors: Array + errors: Array +} + +/** An enumeration. */ +export enum ProductMediaType { + /** An uploaded image or an URL to an image */ + Image = 'IMAGE', + /** A URL to an external video */ + Video = 'VIDEO', +} + +/** Updates a product media. */ +export type ProductMediaUpdate = { + __typename?: 'ProductMediaUpdate' + product?: Maybe + media?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + productErrors: Array + errors: Array +} + +export type ProductMediaUpdateInput = { + /** Alt text for a product media. */ + alt?: Maybe +} + +export type ProductOrder = { + /** Specifies the direction in which to sort products. */ + direction: OrderDirection + /** Specifies the channel in which to sort the data. */ + channel?: Maybe + /** + * Sort product by the selected attribute's values. + * Note: this doesn't take translations into account yet. + */ + attributeId?: Maybe + /** Sort products by the selected field. */ + field?: Maybe +} + +export enum ProductOrderField { + /** Sort products by name. */ + Name = 'NAME', + /** Sort products by rank. Note: This option is available only with the `search` filter. */ + Rank = 'RANK', + /** Sort products by price. */ + Price = 'PRICE', + /** Sort products by a minimal price of a product's variant. */ + MinimalPrice = 'MINIMAL_PRICE', + /** Sort products by update date. */ + Date = 'DATE', + /** Sort products by type. */ + Type = 'TYPE', + /** Sort products by publication status. */ + Published = 'PUBLISHED', + /** Sort products by publication date. */ + PublicationDate = 'PUBLICATION_DATE', + /** Sort products by collection. Note: This option is available only for the `Collection.products` query. */ + Collection = 'COLLECTION', + /** Sort products by rating. */ + Rating = 'RATING', +} + +/** Represents availability of a product in the storefront. */ +export type ProductPricingInfo = { + __typename?: 'ProductPricingInfo' + /** Whether it is in sale or not. */ + onSale?: Maybe + /** The discount amount if in sale (null otherwise). */ + discount?: Maybe + /** The discount amount in the local currency. */ + discountLocalCurrency?: Maybe + /** The discounted price range of the product variants. */ + priceRange?: Maybe + /** The undiscounted price range of the product variants. */ + priceRangeUndiscounted?: Maybe + /** The discounted price range of the product variants in the local currency. */ + priceRangeLocalCurrency?: Maybe +} + +/** Reorder product attribute values. */ +export type ProductReorderAttributeValues = { + __typename?: 'ProductReorderAttributeValues' + /** Product from which attribute values are reordered. */ + product?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + productErrors: Array + errors: Array +} + +export type ProductStockFilterInput = { + warehouseIds?: Maybe> + quantity?: Maybe +} + +export type ProductTranslatableContent = Node & { + __typename?: 'ProductTranslatableContent' + /** The ID of the object. */ + id: Scalars['ID'] + seoTitle?: Maybe + seoDescription?: Maybe + name: Scalars['String'] + description?: Maybe + /** + * Description of the product (JSON). + * @deprecated Will be removed in Saleor 4.0. Use the `description` field instead. + */ + descriptionJson?: Maybe + /** Returns translated product fields for the given language code. */ + translation?: Maybe + /** Represents an individual item for sale in the storefront. */ + product?: Maybe +} + +export type ProductTranslatableContentTranslationArgs = { + languageCode: LanguageCodeEnum +} + +/** Creates/Updates translations for Product. */ +export type ProductTranslate = { + __typename?: 'ProductTranslate' + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + translationErrors: Array + errors: Array + product?: Maybe +} + +export type ProductTranslation = Node & { + __typename?: 'ProductTranslation' + /** The ID of the object. */ + id: Scalars['ID'] + seoTitle?: Maybe + seoDescription?: Maybe + name: Scalars['String'] + description?: Maybe + /** Translation language. */ + language: LanguageDisplay + /** + * Translated description of the product (JSON). + * @deprecated Will be removed in Saleor 4.0. Use the `description` field instead. + */ + descriptionJson?: Maybe +} + +/** Represents a type of product. It defines what attributes are available to products of this type. */ +export type ProductType = Node & + ObjectWithMetadata & { + __typename?: 'ProductType' + /** The ID of the object. */ + id: Scalars['ID'] + name: Scalars['String'] + slug: Scalars['String'] + hasVariants: Scalars['Boolean'] + isShippingRequired: Scalars['Boolean'] + isDigital: Scalars['Boolean'] + weight?: Maybe + /** List of private metadata items.Requires proper staff permissions to access. */ + privateMetadata: Array> + /** List of public metadata items. Can be accessed without permissions. */ + metadata: Array> + /** + * List of products of this type. + * @deprecated Will be removed in Saleor 4.0. Use the top-level `products` query with the `productTypes` filter. + */ + products?: Maybe + /** A type of tax. Assigned by enabled tax gateway */ + taxType?: Maybe + /** Variant attributes of that product type. */ + variantAttributes?: Maybe>> + /** Product attributes of that product type. */ + productAttributes?: Maybe>> + availableAttributes?: Maybe + } + +/** Represents a type of product. It defines what attributes are available to products of this type. */ +export type ProductTypeProductsArgs = { + channel?: Maybe + before?: Maybe + after?: Maybe + first?: Maybe + last?: Maybe +} + +/** Represents a type of product. It defines what attributes are available to products of this type. */ +export type ProductTypeVariantAttributesArgs = { + variantSelection?: Maybe +} + +/** Represents a type of product. It defines what attributes are available to products of this type. */ +export type ProductTypeAvailableAttributesArgs = { + filter?: Maybe + before?: Maybe + after?: Maybe + first?: Maybe + last?: Maybe +} + +/** Deletes product types. */ +export type ProductTypeBulkDelete = { + __typename?: 'ProductTypeBulkDelete' + /** Returns how many objects were affected. */ + count: Scalars['Int'] + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + productErrors: Array + errors: Array +} + +export enum ProductTypeConfigurable { + Configurable = 'CONFIGURABLE', + Simple = 'SIMPLE', +} + +export type ProductTypeCountableConnection = { + __typename?: 'ProductTypeCountableConnection' + /** Pagination data for this connection. */ + pageInfo: PageInfo + edges: Array + /** A total count of items in the collection. */ + totalCount?: Maybe +} + +export type ProductTypeCountableEdge = { + __typename?: 'ProductTypeCountableEdge' + /** The item at the end of the edge. */ + node: ProductType + /** A cursor for use in pagination. */ + cursor: Scalars['String'] +} + +/** Creates a new product type. */ +export type ProductTypeCreate = { + __typename?: 'ProductTypeCreate' + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + productErrors: Array + errors: Array + productType?: Maybe +} + +/** Deletes a product type. */ +export type ProductTypeDelete = { + __typename?: 'ProductTypeDelete' + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + productErrors: Array + errors: Array + productType?: Maybe +} + +export enum ProductTypeEnum { + Digital = 'DIGITAL', + Shippable = 'SHIPPABLE', +} + +export type ProductTypeFilterInput = { + search?: Maybe + configurable?: Maybe + productType?: Maybe + metadata?: Maybe>> + ids?: Maybe>> +} + +export type ProductTypeInput = { + /** Name of the product type. */ + name?: Maybe + /** Product type slug. */ + slug?: Maybe + /** Determines if product of this type has multiple variants. This option mainly simplifies product management in the dashboard. There is always at least one variant created under the hood. */ + hasVariants?: Maybe + /** List of attributes shared among all product variants. */ + productAttributes?: Maybe>> + /** List of attributes used to distinguish between different variants of a product. */ + variantAttributes?: Maybe>> + /** Determines if shipping is required for products of this variant. */ + isShippingRequired?: Maybe + /** Determines if products are digital. */ + isDigital?: Maybe + /** Weight of the ProductType items. */ + weight?: Maybe + /** Tax rate for enabled tax gateway. */ + taxCode?: Maybe +} + +/** Reorder the attributes of a product type. */ +export type ProductTypeReorderAttributes = { + __typename?: 'ProductTypeReorderAttributes' + /** Product type from which attributes are reordered. */ + productType?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + productErrors: Array + errors: Array +} + +export enum ProductTypeSortField { + /** Sort products by name. */ + Name = 'NAME', + /** Sort products by type. */ + Digital = 'DIGITAL', + /** Sort products by shipping. */ + ShippingRequired = 'SHIPPING_REQUIRED', +} + +export type ProductTypeSortingInput = { + /** Specifies the direction in which to sort products. */ + direction: OrderDirection + /** Sort product types by the selected field. */ + field: ProductTypeSortField +} + +/** Updates an existing product type. */ +export type ProductTypeUpdate = { + __typename?: 'ProductTypeUpdate' + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + productErrors: Array + errors: Array + productType?: Maybe +} + +/** Updates an existing product. */ +export type ProductUpdate = { + __typename?: 'ProductUpdate' + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + productErrors: Array + errors: Array + product?: Maybe +} + +/** Represents a version of a product such as different size or color. */ +export type ProductVariant = Node & + ObjectWithMetadata & { + __typename?: 'ProductVariant' + /** The ID of the object. */ + id: Scalars['ID'] + name: Scalars['String'] + sku: Scalars['String'] + product: Product + trackInventory: Scalars['Boolean'] + weight?: Maybe + /** List of private metadata items.Requires proper staff permissions to access. */ + privateMetadata: Array> + /** List of public metadata items. Can be accessed without permissions. */ + metadata: Array> + /** List of price information in channels for the product. */ + channelListings?: Maybe> + /** Lists the storefront variant's pricing, the current price and discounts, only meant for displaying. */ + pricing?: Maybe + /** List of attributes assigned to this variant. */ + attributes: Array + /** Cost price of the variant. */ + costPrice?: Maybe + /** Gross margin percentage value. */ + margin?: Maybe + /** Total quantity ordered. */ + quantityOrdered?: Maybe + /** Total revenue generated by a variant in given period of time. Note: this field should be queried using `reportProductSales` query as it uses optimizations suitable for such calculations. */ + revenue?: Maybe + /** + * List of images for the product variant. + * @deprecated Will be removed in Saleor 4.0. Use the `media` instead. + */ + images?: Maybe>> + /** List of media for the product variant. */ + media?: Maybe> + /** Returns translated product variant fields for the given language code. */ + translation?: Maybe + /** Digital content for the product variant. */ + digitalContent?: Maybe + /** Stocks for the product variant. */ + stocks?: Maybe>> + /** Quantity of a product available for sale in one checkout. */ + quantityAvailable: Scalars['Int'] + } + +/** Represents a version of a product such as different size or color. */ +export type ProductVariantPricingArgs = { + address?: Maybe +} + +/** Represents a version of a product such as different size or color. */ +export type ProductVariantAttributesArgs = { + variantSelection?: Maybe +} + +/** Represents a version of a product such as different size or color. */ +export type ProductVariantRevenueArgs = { + period?: Maybe +} + +/** Represents a version of a product such as different size or color. */ +export type ProductVariantTranslationArgs = { + languageCode: LanguageCodeEnum +} + +/** Represents a version of a product such as different size or color. */ +export type ProductVariantStocksArgs = { + address?: Maybe + countryCode?: Maybe +} + +/** Represents a version of a product such as different size or color. */ +export type ProductVariantQuantityAvailableArgs = { + address?: Maybe + countryCode?: Maybe +} + +/** Creates product variants for a given product. */ +export type ProductVariantBulkCreate = { + __typename?: 'ProductVariantBulkCreate' + /** Returns how many objects were created. */ + count: Scalars['Int'] + /** List of the created variants. */ + productVariants: Array + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + bulkProductErrors: Array + errors: Array +} + +export type ProductVariantBulkCreateInput = { + /** List of attributes specific to this variant. */ + attributes: Array> + /** Stock keeping unit. */ + sku: Scalars['String'] + /** Determines if the inventory of this variant should be tracked. If false, the quantity won't change when customers buy this item. */ + trackInventory?: Maybe + /** Weight of the Product Variant. */ + weight?: Maybe + /** Stocks of a product available for sale. */ + stocks?: Maybe> + /** List of prices assigned to channels. */ + channelListings?: Maybe> +} + +/** Deletes product variants. */ +export type ProductVariantBulkDelete = { + __typename?: 'ProductVariantBulkDelete' + /** Returns how many objects were affected. */ + count: Scalars['Int'] + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + productErrors: Array + errors: Array +} + +/** Represents product varaint channel listing. */ +export type ProductVariantChannelListing = Node & { + __typename?: 'ProductVariantChannelListing' + /** The ID of the object. */ + id: Scalars['ID'] + channel: Channel + price?: Maybe + /** Cost price of the variant. */ + costPrice?: Maybe + /** Gross margin percentage value. */ + margin?: Maybe +} + +export type ProductVariantChannelListingAddInput = { + /** ID of a channel. */ + channelId: Scalars['ID'] + /** Price of the particular variant in channel. */ + price: Scalars['PositiveDecimal'] + /** Cost price of the variant in channel. */ + costPrice?: Maybe +} + +/** Manage product variant prices in channels. */ +export type ProductVariantChannelListingUpdate = { + __typename?: 'ProductVariantChannelListingUpdate' + /** An updated product variant instance. */ + variant?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + productChannelListingErrors: Array + errors: Array +} + +export type ProductVariantCountableConnection = { + __typename?: 'ProductVariantCountableConnection' + /** Pagination data for this connection. */ + pageInfo: PageInfo + edges: Array + /** A total count of items in the collection. */ + totalCount?: Maybe +} + +export type ProductVariantCountableEdge = { + __typename?: 'ProductVariantCountableEdge' + /** The item at the end of the edge. */ + node: ProductVariant + /** A cursor for use in pagination. */ + cursor: Scalars['String'] +} + +/** Creates a new variant for a product. */ +export type ProductVariantCreate = { + __typename?: 'ProductVariantCreate' + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + productErrors: Array + errors: Array + productVariant?: Maybe +} + +export type ProductVariantCreateInput = { + /** List of attributes specific to this variant. */ + attributes: Array> + /** Stock keeping unit. */ + sku?: Maybe + /** Determines if the inventory of this variant should be tracked. If false, the quantity won't change when customers buy this item. */ + trackInventory?: Maybe + /** Weight of the Product Variant. */ + weight?: Maybe + /** Product ID of which type is the variant. */ + product: Scalars['ID'] + /** Stocks of a product available for sale. */ + stocks?: Maybe> +} + +/** Deletes a product variant. */ +export type ProductVariantDelete = { + __typename?: 'ProductVariantDelete' + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + productErrors: Array + errors: Array + productVariant?: Maybe +} + +export type ProductVariantFilterInput = { + search?: Maybe + sku?: Maybe>> + metadata?: Maybe>> +} + +export type ProductVariantInput = { + /** List of attributes specific to this variant. */ + attributes?: Maybe>> + /** Stock keeping unit. */ + sku?: Maybe + /** Determines if the inventory of this variant should be tracked. If false, the quantity won't change when customers buy this item. */ + trackInventory?: Maybe + /** Weight of the Product Variant. */ + weight?: Maybe +} + +/** Reorder the variants of a product. Mutation updates updated_at on product and triggers PRODUCT_UPDATED webhook. */ +export type ProductVariantReorder = { + __typename?: 'ProductVariantReorder' + product?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + productErrors: Array + errors: Array +} + +/** Reorder product variant attribute values. */ +export type ProductVariantReorderAttributeValues = { + __typename?: 'ProductVariantReorderAttributeValues' + /** Product variant from which attribute values are reordered. */ + productVariant?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + productErrors: Array + errors: Array +} + +/** Set default variant for a product. Mutation triggers PRODUCT_UPDATED webhook. */ +export type ProductVariantSetDefault = { + __typename?: 'ProductVariantSetDefault' + product?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + productErrors: Array + errors: Array +} + +/** Creates stocks for product variant. */ +export type ProductVariantStocksCreate = { + __typename?: 'ProductVariantStocksCreate' + /** Updated product variant. */ + productVariant?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + bulkStockErrors: Array + errors: Array +} + +/** Delete stocks from product variant. */ +export type ProductVariantStocksDelete = { + __typename?: 'ProductVariantStocksDelete' + /** Updated product variant. */ + productVariant?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + stockErrors: Array + errors: Array +} + +/** Update stocks for product variant. */ +export type ProductVariantStocksUpdate = { + __typename?: 'ProductVariantStocksUpdate' + /** Updated product variant. */ + productVariant?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + bulkStockErrors: Array + errors: Array +} + +export type ProductVariantTranslatableContent = Node & { + __typename?: 'ProductVariantTranslatableContent' + /** The ID of the object. */ + id: Scalars['ID'] + name: Scalars['String'] + /** Returns translated product variant fields for the given language code. */ + translation?: Maybe + /** Represents a version of a product such as different size or color. */ + productVariant?: Maybe +} + +export type ProductVariantTranslatableContentTranslationArgs = { + languageCode: LanguageCodeEnum +} + +/** Creates/Updates translations for Product Variant. */ +export type ProductVariantTranslate = { + __typename?: 'ProductVariantTranslate' + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + translationErrors: Array + errors: Array + productVariant?: Maybe +} + +export type ProductVariantTranslation = Node & { + __typename?: 'ProductVariantTranslation' + /** The ID of the object. */ + id: Scalars['ID'] + name: Scalars['String'] + /** Translation language. */ + language: LanguageDisplay +} + +/** Updates an existing variant for product. */ +export type ProductVariantUpdate = { + __typename?: 'ProductVariantUpdate' + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + productErrors: Array + errors: Array + productVariant?: Maybe +} + +export type PublishableChannelListingInput = { + /** ID of a channel. */ + channelId: Scalars['ID'] + /** Determines if object is visible to customers. */ + isPublished?: Maybe + /** Publication date. ISO 8601 standard. */ + publicationDate?: Maybe +} + +export type Query = { + __typename?: 'Query' + /** Look up a webhook by ID. */ + webhook?: Maybe + /** List of all available webhook events. */ + webhookEvents?: Maybe>> + /** Retrieve a sample payload for a given webhook event based on real data. It can be useful for some integrations where sample payload is required. */ + webhookSamplePayload?: Maybe + /** Look up a warehouse by ID. */ + warehouse?: Maybe + /** List of warehouses. */ + warehouses?: Maybe + /** Returns a list of all translatable items of a given kind. */ + translations?: Maybe + translation?: Maybe + /** Look up a stock by ID */ + stock?: Maybe + /** List of stocks. */ + stocks?: Maybe + /** Return information about the shop. */ + shop: Shop + /** Order related settings from site settings. */ + orderSettings?: Maybe + /** Look up a shipping zone by ID. */ + shippingZone?: Maybe + /** List of the shop's shipping zones. */ + shippingZones?: Maybe + /** Look up digital content by ID. */ + digitalContent?: Maybe + /** List of digital content. */ + digitalContents?: Maybe + /** List of the shop's categories. */ + categories?: Maybe + /** Look up a category by ID or slug. */ + category?: Maybe + /** Look up a collection by ID. */ + collection?: Maybe + /** List of the shop's collections. */ + collections?: Maybe + /** Look up a product by ID. */ + product?: Maybe + /** List of the shop's products. */ + products?: Maybe + /** Look up a product type by ID. */ + productType?: Maybe + /** List of the shop's product types. */ + productTypes?: Maybe + /** Look up a product variant by ID or SKU. */ + productVariant?: Maybe + /** List of product variants. */ + productVariants?: Maybe + /** List of top selling products. */ + reportProductSales?: Maybe + /** Look up a payment by ID. */ + payment?: Maybe + /** List of payments. */ + payments?: Maybe + /** Look up a page by ID or slug. */ + page?: Maybe + /** List of the shop's pages. */ + pages?: Maybe + /** Look up a page type by ID. */ + pageType?: Maybe + /** List of the page types. */ + pageTypes?: Maybe + /** List of activity events to display on homepage (at the moment it only contains order-events). */ + homepageEvents?: Maybe + /** Look up an order by ID. */ + order?: Maybe + /** List of orders. */ + orders?: Maybe + /** List of draft orders. */ + draftOrders?: Maybe + /** Return the total sales amount from a specific period. */ + ordersTotal?: Maybe + /** Look up an order by token. */ + orderByToken?: Maybe + /** Look up a navigation menu by ID or name. */ + menu?: Maybe + /** List of the storefront's menus. */ + menus?: Maybe + /** Look up a menu item by ID. */ + menuItem?: Maybe + /** List of the storefronts's menu items. */ + menuItems?: Maybe + /** Look up a gift card by ID. */ + giftCard?: Maybe + /** List of gift cards. */ + giftCards?: Maybe + /** Look up a plugin by ID. */ + plugin?: Maybe + /** List of plugins. */ + plugins?: Maybe + /** Look up a sale by ID. */ + sale?: Maybe + /** List of the shop's sales. */ + sales?: Maybe + /** Look up a voucher by ID. */ + voucher?: Maybe + /** List of the shop's vouchers. */ + vouchers?: Maybe + /** Look up a export file by ID. */ + exportFile?: Maybe + /** List of export files. */ + exportFiles?: Maybe + /** List of all tax rates available from tax gateway. */ + taxTypes?: Maybe>> + /** Look up a checkout by token and slug of channel. */ + checkout?: Maybe + /** List of checkouts. */ + checkouts?: Maybe + /** Look up a checkout line by ID. */ + checkoutLine?: Maybe + /** List of checkout lines. */ + checkoutLines?: Maybe + /** Look up a channel by ID. */ + channel?: Maybe + /** List of all channels. */ + channels?: Maybe> + /** List of the shop's attributes. */ + attributes?: Maybe + /** Look up an attribute by ID. */ + attribute?: Maybe + /** List of all apps installations */ + appsInstallations: Array + /** List of the apps. */ + apps?: Maybe + /** Look up an app by ID. If ID is not provided, return the currently authenticated app. */ + app?: Maybe + /** Returns address validation rules. */ + addressValidationRules?: Maybe + /** Look up an address by ID. */ + address?: Maybe
    + /** List of the shop's customers. */ + customers?: Maybe + /** List of permission groups. */ + permissionGroups?: Maybe + /** Look up permission group by ID. */ + permissionGroup?: Maybe + /** Return the currently authenticated user. */ + me?: Maybe + /** List of the shop's staff users. */ + staffUsers?: Maybe + /** Look up a user by ID or email address. */ + user?: Maybe + _entities?: Maybe>> + _service?: Maybe<_Service> +} + +export type QueryWebhookArgs = { + id: Scalars['ID'] +} + +export type QueryWebhookSamplePayloadArgs = { + eventType: WebhookSampleEventTypeEnum +} + +export type QueryWarehouseArgs = { + id: Scalars['ID'] +} + +export type QueryWarehousesArgs = { + filter?: Maybe + sortBy?: Maybe + before?: Maybe + after?: Maybe + first?: Maybe + last?: Maybe +} + +export type QueryTranslationsArgs = { + kind: TranslatableKinds + before?: Maybe + after?: Maybe + first?: Maybe + last?: Maybe +} + +export type QueryTranslationArgs = { + id: Scalars['ID'] + kind: TranslatableKinds +} + +export type QueryStockArgs = { + id: Scalars['ID'] +} + +export type QueryStocksArgs = { + filter?: Maybe + before?: Maybe + after?: Maybe + first?: Maybe + last?: Maybe +} + +export type QueryShippingZoneArgs = { + id: Scalars['ID'] + channel?: Maybe +} + +export type QueryShippingZonesArgs = { + filter?: Maybe + channel?: Maybe + before?: Maybe + after?: Maybe + first?: Maybe + last?: Maybe +} + +export type QueryDigitalContentArgs = { + id: Scalars['ID'] +} + +export type QueryDigitalContentsArgs = { + before?: Maybe + after?: Maybe + first?: Maybe + last?: Maybe +} + +export type QueryCategoriesArgs = { + filter?: Maybe + sortBy?: Maybe + level?: Maybe + before?: Maybe + after?: Maybe + first?: Maybe + last?: Maybe +} + +export type QueryCategoryArgs = { + id?: Maybe + slug?: Maybe +} + +export type QueryCollectionArgs = { + id?: Maybe + slug?: Maybe + channel?: Maybe +} + +export type QueryCollectionsArgs = { + filter?: Maybe + sortBy?: Maybe + channel?: Maybe + before?: Maybe + after?: Maybe + first?: Maybe + last?: Maybe +} + +export type QueryProductArgs = { + id?: Maybe + slug?: Maybe + channel?: Maybe +} + +export type QueryProductsArgs = { + filter?: Maybe + sortBy?: Maybe + channel?: Maybe + before?: Maybe + after?: Maybe + first?: Maybe + last?: Maybe +} + +export type QueryProductTypeArgs = { + id: Scalars['ID'] +} + +export type QueryProductTypesArgs = { + filter?: Maybe + sortBy?: Maybe + before?: Maybe + after?: Maybe + first?: Maybe + last?: Maybe +} + +export type QueryProductVariantArgs = { + id?: Maybe + sku?: Maybe + channel?: Maybe +} + +export type QueryProductVariantsArgs = { + ids?: Maybe>> + channel?: Maybe + filter?: Maybe + before?: Maybe + after?: Maybe + first?: Maybe + last?: Maybe +} + +export type QueryReportProductSalesArgs = { + period: ReportingPeriod + channel: Scalars['String'] + before?: Maybe + after?: Maybe + first?: Maybe + last?: Maybe +} + +export type QueryPaymentArgs = { + id: Scalars['ID'] +} + +export type QueryPaymentsArgs = { + filter?: Maybe + before?: Maybe + after?: Maybe + first?: Maybe + last?: Maybe +} + +export type QueryPageArgs = { + id?: Maybe + slug?: Maybe +} + +export type QueryPagesArgs = { + sortBy?: Maybe + filter?: Maybe + before?: Maybe + after?: Maybe + first?: Maybe + last?: Maybe +} + +export type QueryPageTypeArgs = { + id: Scalars['ID'] +} + +export type QueryPageTypesArgs = { + sortBy?: Maybe + filter?: Maybe + before?: Maybe + after?: Maybe + first?: Maybe + last?: Maybe +} + +export type QueryHomepageEventsArgs = { + before?: Maybe + after?: Maybe + first?: Maybe + last?: Maybe +} + +export type QueryOrderArgs = { + id: Scalars['ID'] +} + +export type QueryOrdersArgs = { + sortBy?: Maybe + filter?: Maybe + channel?: Maybe + before?: Maybe + after?: Maybe + first?: Maybe + last?: Maybe +} + +export type QueryDraftOrdersArgs = { + sortBy?: Maybe + filter?: Maybe + before?: Maybe + after?: Maybe + first?: Maybe + last?: Maybe +} + +export type QueryOrdersTotalArgs = { + period?: Maybe + channel?: Maybe +} + +export type QueryOrderByTokenArgs = { + token: Scalars['UUID'] +} + +export type QueryMenuArgs = { + channel?: Maybe + id?: Maybe + name?: Maybe + slug?: Maybe +} + +export type QueryMenusArgs = { + channel?: Maybe + sortBy?: Maybe + filter?: Maybe + before?: Maybe + after?: Maybe + first?: Maybe + last?: Maybe +} + +export type QueryMenuItemArgs = { + id: Scalars['ID'] + channel?: Maybe +} + +export type QueryMenuItemsArgs = { + channel?: Maybe + sortBy?: Maybe + filter?: Maybe + before?: Maybe + after?: Maybe + first?: Maybe + last?: Maybe +} + +export type QueryGiftCardArgs = { + id: Scalars['ID'] +} + +export type QueryGiftCardsArgs = { + before?: Maybe + after?: Maybe + first?: Maybe + last?: Maybe +} + +export type QueryPluginArgs = { + id: Scalars['ID'] +} + +export type QueryPluginsArgs = { + filter?: Maybe + sortBy?: Maybe + before?: Maybe + after?: Maybe + first?: Maybe + last?: Maybe +} + +export type QuerySaleArgs = { + id: Scalars['ID'] + channel?: Maybe +} + +export type QuerySalesArgs = { + filter?: Maybe + sortBy?: Maybe + query?: Maybe + channel?: Maybe + before?: Maybe + after?: Maybe + first?: Maybe + last?: Maybe +} + +export type QueryVoucherArgs = { + id: Scalars['ID'] + channel?: Maybe +} + +export type QueryVouchersArgs = { + filter?: Maybe + sortBy?: Maybe + query?: Maybe + channel?: Maybe + before?: Maybe + after?: Maybe + first?: Maybe + last?: Maybe +} + +export type QueryExportFileArgs = { + id: Scalars['ID'] +} + +export type QueryExportFilesArgs = { + filter?: Maybe + sortBy?: Maybe + before?: Maybe + after?: Maybe + first?: Maybe + last?: Maybe +} + +export type QueryCheckoutArgs = { + token?: Maybe +} + +export type QueryCheckoutsArgs = { + channel?: Maybe + before?: Maybe + after?: Maybe + first?: Maybe + last?: Maybe +} + +export type QueryCheckoutLineArgs = { + id?: Maybe +} + +export type QueryCheckoutLinesArgs = { + before?: Maybe + after?: Maybe + first?: Maybe + last?: Maybe +} + +export type QueryChannelArgs = { + id?: Maybe +} + +export type QueryAttributesArgs = { + filter?: Maybe + sortBy?: Maybe + before?: Maybe + after?: Maybe + first?: Maybe + last?: Maybe +} + +export type QueryAttributeArgs = { + id?: Maybe + slug?: Maybe +} + +export type QueryAppsArgs = { + filter?: Maybe + sortBy?: Maybe + before?: Maybe + after?: Maybe + first?: Maybe + last?: Maybe +} + +export type QueryAppArgs = { + id?: Maybe +} + +export type QueryAddressValidationRulesArgs = { + countryCode: CountryCode + countryArea?: Maybe + city?: Maybe + cityArea?: Maybe +} + +export type QueryAddressArgs = { + id: Scalars['ID'] +} + +export type QueryCustomersArgs = { + filter?: Maybe + sortBy?: Maybe + before?: Maybe + after?: Maybe + first?: Maybe + last?: Maybe +} + +export type QueryPermissionGroupsArgs = { + filter?: Maybe + sortBy?: Maybe + before?: Maybe + after?: Maybe + first?: Maybe + last?: Maybe +} + +export type QueryPermissionGroupArgs = { + id: Scalars['ID'] +} + +export type QueryStaffUsersArgs = { + filter?: Maybe + sortBy?: Maybe + before?: Maybe + after?: Maybe + first?: Maybe + last?: Maybe +} + +export type QueryUserArgs = { + id?: Maybe + email?: Maybe +} + +export type Query_EntitiesArgs = { + representations?: Maybe>> +} + +/** Represents a reduced VAT rate for a particular type of goods. */ +export type ReducedRate = { + __typename?: 'ReducedRate' + /** Reduced VAT rate in percent. */ + rate: Scalars['Float'] + /** A type of goods. */ + rateType: TaxRateType +} + +/** Refresh JWT token. Mutation tries to take refreshToken from the input.If it fails it will try to take refreshToken from the http-only cookie -refreshToken. csrfToken is required when refreshToken is provided as a cookie. */ +export type RefreshToken = { + __typename?: 'RefreshToken' + /** JWT token, required to authenticate. */ + token?: Maybe + /** A user instance. */ + user?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + accountErrors: Array + errors: Array +} + +export type ReorderInput = { + /** The ID of the item to move. */ + id: Scalars['ID'] + /** The new relative sorting position of the item (from -inf to +inf). 1 moves the item one position forward, -1 moves the item one position backward, 0 leaves the item unchanged. */ + sortOrder?: Maybe +} + +export enum ReportingPeriod { + Today = 'TODAY', + ThisMonth = 'THIS_MONTH', +} + +/** Request email change of the logged in user. */ +export type RequestEmailChange = { + __typename?: 'RequestEmailChange' + /** A user instance. */ + user?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + accountErrors: Array + errors: Array +} + +/** Sends an email with the account password modification link. */ +export type RequestPasswordReset = { + __typename?: 'RequestPasswordReset' + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + accountErrors: Array + errors: Array +} + +/** Sales allow creating discounts for categories, collections or products and are visible to all the customers. */ +export type Sale = Node & { + __typename?: 'Sale' + /** The ID of the object. */ + id: Scalars['ID'] + name: Scalars['String'] + type: SaleType + startDate: Scalars['DateTime'] + endDate?: Maybe + /** List of categories this sale applies to. */ + categories?: Maybe + /** List of collections this sale applies to. */ + collections?: Maybe + /** List of products this sale applies to. */ + products?: Maybe + /** Returns translated sale fields for the given language code. */ + translation?: Maybe + /** List of channels available for the sale. */ + channelListings?: Maybe> + /** Sale value. */ + discountValue?: Maybe + /** Currency code for sale. */ + currency?: Maybe +} + +/** Sales allow creating discounts for categories, collections or products and are visible to all the customers. */ +export type SaleCategoriesArgs = { + before?: Maybe + after?: Maybe + first?: Maybe + last?: Maybe +} + +/** Sales allow creating discounts for categories, collections or products and are visible to all the customers. */ +export type SaleCollectionsArgs = { + before?: Maybe + after?: Maybe + first?: Maybe + last?: Maybe +} + +/** Sales allow creating discounts for categories, collections or products and are visible to all the customers. */ +export type SaleProductsArgs = { + before?: Maybe + after?: Maybe + first?: Maybe + last?: Maybe +} + +/** Sales allow creating discounts for categories, collections or products and are visible to all the customers. */ +export type SaleTranslationArgs = { + languageCode: LanguageCodeEnum +} + +/** Adds products, categories, collections to a voucher. */ +export type SaleAddCatalogues = { + __typename?: 'SaleAddCatalogues' + /** Sale of which catalogue IDs will be modified. */ + sale?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + discountErrors: Array + errors: Array +} + +/** Deletes sales. */ +export type SaleBulkDelete = { + __typename?: 'SaleBulkDelete' + /** Returns how many objects were affected. */ + count: Scalars['Int'] + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + discountErrors: Array + errors: Array +} + +/** Represents sale channel listing. */ +export type SaleChannelListing = Node & { + __typename?: 'SaleChannelListing' + /** The ID of the object. */ + id: Scalars['ID'] + channel: Channel + discountValue: Scalars['Float'] + currency: Scalars['String'] +} + +export type SaleChannelListingAddInput = { + /** ID of a channel. */ + channelId: Scalars['ID'] + /** The value of the discount. */ + discountValue: Scalars['PositiveDecimal'] +} + +export type SaleChannelListingInput = { + /** List of channels to which the sale should be assigned. */ + addChannels?: Maybe> + /** List of channels from which the sale should be unassigned. */ + removeChannels?: Maybe> +} + +/** Manage sale's availability in channels. */ +export type SaleChannelListingUpdate = { + __typename?: 'SaleChannelListingUpdate' + /** An updated sale instance. */ + sale?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + discountErrors: Array + errors: Array +} + +export type SaleCountableConnection = { + __typename?: 'SaleCountableConnection' + /** Pagination data for this connection. */ + pageInfo: PageInfo + edges: Array + /** A total count of items in the collection. */ + totalCount?: Maybe +} + +export type SaleCountableEdge = { + __typename?: 'SaleCountableEdge' + /** The item at the end of the edge. */ + node: Sale + /** A cursor for use in pagination. */ + cursor: Scalars['String'] +} + +/** Creates a new sale. */ +export type SaleCreate = { + __typename?: 'SaleCreate' + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + discountErrors: Array + errors: Array + sale?: Maybe +} + +/** Deletes a sale. */ +export type SaleDelete = { + __typename?: 'SaleDelete' + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + discountErrors: Array + errors: Array + sale?: Maybe +} + +export type SaleFilterInput = { + status?: Maybe>> + saleType?: Maybe + started?: Maybe + search?: Maybe +} + +export type SaleInput = { + /** Voucher name. */ + name?: Maybe + /** Fixed or percentage. */ + type?: Maybe + /** Value of the voucher. */ + value?: Maybe + /** Products related to the discount. */ + products?: Maybe>> + /** Categories related to the discount. */ + categories?: Maybe>> + /** Collections related to the discount. */ + collections?: Maybe>> + /** Start date of the voucher in ISO 8601 format. */ + startDate?: Maybe + /** End date of the voucher in ISO 8601 format. */ + endDate?: Maybe +} + +/** Removes products, categories, collections from a sale. */ +export type SaleRemoveCatalogues = { + __typename?: 'SaleRemoveCatalogues' + /** Sale of which catalogue IDs will be modified. */ + sale?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + discountErrors: Array + errors: Array +} + +export enum SaleSortField { + /** Sort sales by name. */ + Name = 'NAME', + /** Sort sales by start date. */ + StartDate = 'START_DATE', + /** Sort sales by end date. */ + EndDate = 'END_DATE', + /** Sort sales by value. */ + Value = 'VALUE', + /** Sort sales by type. */ + Type = 'TYPE', +} + +export type SaleSortingInput = { + /** Specifies the direction in which to sort products. */ + direction: OrderDirection + /** Specifies the channel in which to sort the data. */ + channel?: Maybe + /** Sort sales by the selected field. */ + field: SaleSortField +} + +export type SaleTranslatableContent = Node & { + __typename?: 'SaleTranslatableContent' + /** The ID of the object. */ + id: Scalars['ID'] + name: Scalars['String'] + /** Returns translated sale fields for the given language code. */ + translation?: Maybe + /** Sales allow creating discounts for categories, collections or products and are visible to all the customers. */ + sale?: Maybe +} + +export type SaleTranslatableContentTranslationArgs = { + languageCode: LanguageCodeEnum +} + +/** Creates/updates translations for a sale. */ +export type SaleTranslate = { + __typename?: 'SaleTranslate' + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + translationErrors: Array + errors: Array + sale?: Maybe +} + +export type SaleTranslation = Node & { + __typename?: 'SaleTranslation' + /** The ID of the object. */ + id: Scalars['ID'] + name?: Maybe + /** Translation language. */ + language: LanguageDisplay +} + +/** An enumeration. */ +export enum SaleType { + /** fixed */ + Fixed = 'FIXED', + /** % */ + Percentage = 'PERCENTAGE', +} + +/** Updates a sale. */ +export type SaleUpdate = { + __typename?: 'SaleUpdate' + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + discountErrors: Array + errors: Array + sale?: Maybe +} + +/** Represents a custom attribute. */ +export type SelectedAttribute = { + __typename?: 'SelectedAttribute' + /** Name of an attribute displayed in the interface. */ + attribute: Attribute + /** Values of an attribute. */ + values: Array> +} + +export type SeoInput = { + /** SEO title. */ + title?: Maybe + /** SEO description. */ + description?: Maybe +} + +/** Sets the user's password from the token sent by email using the RequestPasswordReset mutation. */ +export type SetPassword = { + __typename?: 'SetPassword' + /** JWT token, required to authenticate. */ + token?: Maybe + /** JWT refresh token, required to re-generate access token. */ + refreshToken?: Maybe + /** CSRF token required to re-generate access token. */ + csrfToken?: Maybe + /** A user instance. */ + user?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + accountErrors: Array + errors: Array +} + +export type ShippingError = { + __typename?: 'ShippingError' + /** Name of a field that caused the error. A value of `null` indicates that the error isn't associated with a particular field. */ + field?: Maybe + /** The error message. */ + message?: Maybe + /** The error code. */ + code: ShippingErrorCode + /** List of warehouse IDs which causes the error. */ + warehouses?: Maybe> + /** List of channels IDs which causes the error. */ + channels?: Maybe> +} + +/** An enumeration. */ +export enum ShippingErrorCode { + AlreadyExists = 'ALREADY_EXISTS', + GraphqlError = 'GRAPHQL_ERROR', + Invalid = 'INVALID', + MaxLessThanMin = 'MAX_LESS_THAN_MIN', + NotFound = 'NOT_FOUND', + Required = 'REQUIRED', + Unique = 'UNIQUE', + DuplicatedInputItem = 'DUPLICATED_INPUT_ITEM', +} + +/** Shipping method are the methods you'll use to get customer's orders to them. They are directly exposed to the customers. */ +export type ShippingMethod = Node & + ObjectWithMetadata & { + __typename?: 'ShippingMethod' + /** The ID of the object. */ + id: Scalars['ID'] + name: Scalars['String'] + description?: Maybe + minimumOrderWeight?: Maybe + maximumOrderWeight?: Maybe + maximumDeliveryDays?: Maybe + minimumDeliveryDays?: Maybe + /** List of private metadata items.Requires proper staff permissions to access. */ + privateMetadata: Array> + /** List of public metadata items. Can be accessed without permissions. */ + metadata: Array> + /** Type of the shipping method. */ + type?: Maybe + /** Returns translated shipping method fields for the given language code. */ + translation?: Maybe + /** List of channels available for the method. */ + channelListings?: Maybe> + /** The price of the cheapest variant (including discounts). */ + price?: Maybe + /** The price of the cheapest variant (including discounts). */ + maximumOrderPrice?: Maybe + /** The price of the cheapest variant (including discounts). */ + minimumOrderPrice?: Maybe + /** Postal code ranges rule of exclusion or inclusion of the shipping method. */ + postalCodeRules?: Maybe>> + /** List of excluded products for the shipping method. */ + excludedProducts?: Maybe + } + +/** Shipping method are the methods you'll use to get customer's orders to them. They are directly exposed to the customers. */ +export type ShippingMethodTranslationArgs = { + languageCode: LanguageCodeEnum +} + +/** Shipping method are the methods you'll use to get customer's orders to them. They are directly exposed to the customers. */ +export type ShippingMethodExcludedProductsArgs = { + before?: Maybe + after?: Maybe + first?: Maybe + last?: Maybe +} + +/** Represents shipping method channel listing. */ +export type ShippingMethodChannelListing = Node & { + __typename?: 'ShippingMethodChannelListing' + /** The ID of the object. */ + id: Scalars['ID'] + channel: Channel + minimumOrderPrice?: Maybe + maximumOrderPrice?: Maybe + price?: Maybe +} + +export type ShippingMethodChannelListingAddInput = { + /** ID of a channel. */ + channelId: Scalars['ID'] + /** Shipping price of the shipping method in this channel. */ + price?: Maybe + /** Minimum order price to use this shipping method. */ + minimumOrderPrice?: Maybe + /** Maximum order price to use this shipping method. */ + maximumOrderPrice?: Maybe +} + +export type ShippingMethodChannelListingInput = { + /** List of channels to which the shipping method should be assigned. */ + addChannels?: Maybe> + /** List of channels from which the shipping method should be unassigned. */ + removeChannels?: Maybe> +} + +/** Manage shipping method's availability in channels. */ +export type ShippingMethodChannelListingUpdate = { + __typename?: 'ShippingMethodChannelListingUpdate' + /** An updated shipping method instance. */ + shippingMethod?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + shippingErrors: Array + errors: Array +} + +/** Represents shipping method postal code rule. */ +export type ShippingMethodPostalCodeRule = Node & { + __typename?: 'ShippingMethodPostalCodeRule' + /** Start address range. */ + start?: Maybe + /** End address range. */ + end?: Maybe + /** Inclusion type of the postal code rule. */ + inclusionType?: Maybe + /** The ID of the object. */ + id: Scalars['ID'] +} + +export type ShippingMethodTranslatableContent = Node & { + __typename?: 'ShippingMethodTranslatableContent' + /** The ID of the object. */ + id: Scalars['ID'] + name: Scalars['String'] + description?: Maybe + /** Returns translated shipping method fields for the given language code. */ + translation?: Maybe + /** Shipping method are the methods you'll use to get customer's orders to them. They are directly exposed to the customers. */ + shippingMethod?: Maybe +} + +export type ShippingMethodTranslatableContentTranslationArgs = { + languageCode: LanguageCodeEnum +} + +export type ShippingMethodTranslation = Node & { + __typename?: 'ShippingMethodTranslation' + /** The ID of the object. */ + id: Scalars['ID'] + name?: Maybe + description?: Maybe + /** Translation language. */ + language: LanguageDisplay +} + +/** An enumeration. */ +export enum ShippingMethodTypeEnum { + Price = 'PRICE', + Weight = 'WEIGHT', +} + +export type ShippingPostalCodeRulesCreateInputRange = { + /** Start range of the postal code. */ + start: Scalars['String'] + /** End range of the postal code. */ + end?: Maybe +} + +/** Deletes shipping prices. */ +export type ShippingPriceBulkDelete = { + __typename?: 'ShippingPriceBulkDelete' + /** Returns how many objects were affected. */ + count: Scalars['Int'] + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + shippingErrors: Array + errors: Array +} + +/** Creates a new shipping price. */ +export type ShippingPriceCreate = { + __typename?: 'ShippingPriceCreate' + /** A shipping zone to which the shipping method belongs. */ + shippingZone?: Maybe + shippingMethod?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + shippingErrors: Array + errors: Array +} + +/** Deletes a shipping price. */ +export type ShippingPriceDelete = { + __typename?: 'ShippingPriceDelete' + /** A shipping method to delete. */ + shippingMethod?: Maybe + /** A shipping zone to which the shipping method belongs. */ + shippingZone?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + shippingErrors: Array + errors: Array +} + +/** Exclude products from shipping price. */ +export type ShippingPriceExcludeProducts = { + __typename?: 'ShippingPriceExcludeProducts' + /** A shipping method with new list of excluded products. */ + shippingMethod?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + shippingErrors: Array + errors: Array +} + +export type ShippingPriceExcludeProductsInput = { + /** List of products which will be excluded. */ + products: Array> +} + +export type ShippingPriceInput = { + /** Name of the shipping method. */ + name?: Maybe + /** Shipping method description (JSON). */ + description?: Maybe + /** Minimum order weight to use this shipping method. */ + minimumOrderWeight?: Maybe + /** Maximum order weight to use this shipping method. */ + maximumOrderWeight?: Maybe + /** Maximum number of days for delivery. */ + maximumDeliveryDays?: Maybe + /** Minimal number of days for delivery. */ + minimumDeliveryDays?: Maybe + /** Shipping type: price or weight based. */ + type?: Maybe + /** Shipping zone this method belongs to. */ + shippingZone?: Maybe + /** Postal code rules to add. */ + addPostalCodeRules?: Maybe> + /** Postal code rules to delete. */ + deletePostalCodeRules?: Maybe> + /** Inclusion type for currently assigned postal code rules. */ + inclusionType?: Maybe +} + +/** Remove product from excluded list for shipping price. */ +export type ShippingPriceRemoveProductFromExclude = { + __typename?: 'ShippingPriceRemoveProductFromExclude' + /** A shipping method with new list of excluded products. */ + shippingMethod?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + shippingErrors: Array + errors: Array +} + +/** Creates/Updates translations for shipping method. */ +export type ShippingPriceTranslate = { + __typename?: 'ShippingPriceTranslate' + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + translationErrors: Array + errors: Array + shippingMethod?: Maybe +} + +export type ShippingPriceTranslationInput = { + name?: Maybe + /** Translated shipping method description (JSON). */ + description?: Maybe +} + +/** Updates a new shipping price. */ +export type ShippingPriceUpdate = { + __typename?: 'ShippingPriceUpdate' + /** A shipping zone to which the shipping method belongs. */ + shippingZone?: Maybe + shippingMethod?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + shippingErrors: Array + errors: Array +} + +/** Represents a shipping zone in the shop. Zones are the concept used only for grouping shipping methods in the dashboard, and are never exposed to the customers directly. */ +export type ShippingZone = Node & + ObjectWithMetadata & { + __typename?: 'ShippingZone' + /** The ID of the object. */ + id: Scalars['ID'] + name: Scalars['String'] + default: Scalars['Boolean'] + /** List of private metadata items.Requires proper staff permissions to access. */ + privateMetadata: Array> + /** List of public metadata items. Can be accessed without permissions. */ + metadata: Array> + /** Lowest and highest prices for the shipping. */ + priceRange?: Maybe + /** List of countries available for the method. */ + countries?: Maybe>> + /** List of shipping methods available for orders shipped to countries within this shipping zone. */ + shippingMethods?: Maybe>> + /** List of warehouses for shipping zone. */ + warehouses: Array + /** List of channels for shipping zone. */ + channels: Array + /** Description of a shipping zone. */ + description?: Maybe + } + +/** Deletes shipping zones. */ +export type ShippingZoneBulkDelete = { + __typename?: 'ShippingZoneBulkDelete' + /** Returns how many objects were affected. */ + count: Scalars['Int'] + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + shippingErrors: Array + errors: Array +} + +export type ShippingZoneCountableConnection = { + __typename?: 'ShippingZoneCountableConnection' + /** Pagination data for this connection. */ + pageInfo: PageInfo + edges: Array + /** A total count of items in the collection. */ + totalCount?: Maybe +} + +export type ShippingZoneCountableEdge = { + __typename?: 'ShippingZoneCountableEdge' + /** The item at the end of the edge. */ + node: ShippingZone + /** A cursor for use in pagination. */ + cursor: Scalars['String'] +} + +/** Creates a new shipping zone. */ +export type ShippingZoneCreate = { + __typename?: 'ShippingZoneCreate' + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + shippingErrors: Array + errors: Array + shippingZone?: Maybe +} + +export type ShippingZoneCreateInput = { + /** Shipping zone's name. Visible only to the staff. */ + name?: Maybe + /** Description of the shipping zone. */ + description?: Maybe + /** List of countries in this shipping zone. */ + countries?: Maybe>> + /** Default shipping zone will be used for countries not covered by other zones. */ + default?: Maybe + /** List of warehouses to assign to a shipping zone */ + addWarehouses?: Maybe>> + /** List of channels to assign to the shipping zone. */ + addChannels?: Maybe> +} + +/** Deletes a shipping zone. */ +export type ShippingZoneDelete = { + __typename?: 'ShippingZoneDelete' + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + shippingErrors: Array + errors: Array + shippingZone?: Maybe +} + +export type ShippingZoneFilterInput = { + search?: Maybe + channels?: Maybe>> +} + +/** Updates a new shipping zone. */ +export type ShippingZoneUpdate = { + __typename?: 'ShippingZoneUpdate' + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + shippingErrors: Array + errors: Array + shippingZone?: Maybe +} + +export type ShippingZoneUpdateInput = { + /** Shipping zone's name. Visible only to the staff. */ + name?: Maybe + /** Description of the shipping zone. */ + description?: Maybe + /** List of countries in this shipping zone. */ + countries?: Maybe>> + /** Default shipping zone will be used for countries not covered by other zones. */ + default?: Maybe + /** List of warehouses to assign to a shipping zone */ + addWarehouses?: Maybe>> + /** List of channels to assign to the shipping zone. */ + addChannels?: Maybe> + /** List of warehouses to unassign from a shipping zone */ + removeWarehouses?: Maybe>> + /** List of channels to unassign from the shipping zone. */ + removeChannels?: Maybe> +} + +/** Represents a shop resource containing general shop data and configuration. */ +export type Shop = { + __typename?: 'Shop' + /** List of available payment gateways. */ + availablePaymentGateways: Array + /** List of available external authentications. */ + availableExternalAuthentications: Array + /** Shipping methods that are available for the shop. */ + availableShippingMethods?: Maybe>> + /** List of countries available in the shop. */ + countries: Array + /** Shop's default country. */ + defaultCountry?: Maybe + /** Default shop's email sender's name. */ + defaultMailSenderName?: Maybe + /** Default shop's email sender's address. */ + defaultMailSenderAddress?: Maybe + /** Shop's description. */ + description?: Maybe + /** Shop's domain data. */ + domain: Domain + /** List of the shops's supported languages. */ + languages: Array> + /** Shop's name. */ + name: Scalars['String'] + /** List of available permissions. */ + permissions: Array> + /** List of possible phone prefixes. */ + phonePrefixes: Array> + /** Header text. */ + headerText?: Maybe + /** Include taxes in prices. */ + includeTaxesInPrices: Scalars['Boolean'] + /** Display prices with tax in store. */ + displayGrossPrices: Scalars['Boolean'] + /** Charge taxes on shipping. */ + chargeTaxesOnShipping: Scalars['Boolean'] + /** Enable inventory tracking. */ + trackInventoryByDefault?: Maybe + /** Default weight unit. */ + defaultWeightUnit?: Maybe + /** Returns translated shop fields for the given language code. */ + translation?: Maybe + /** Enable automatic fulfillment for all digital products. */ + automaticFulfillmentDigitalProducts?: Maybe + /** Default number of max downloads per digital content URL. */ + defaultDigitalMaxDownloads?: Maybe + /** Default number of days which digital content URL will be valid. */ + defaultDigitalUrlValidDays?: Maybe + /** Company address. */ + companyAddress?: Maybe
    + /** URL of a view where customers can set their password. */ + customerSetPasswordUrl?: Maybe + /** List of staff notification recipients. */ + staffNotificationRecipients?: Maybe>> + /** Resource limitations and current usage if any set for a shop */ + limits: LimitInfo + /** Saleor API version. */ + version: Scalars['String'] +} + +/** Represents a shop resource containing general shop data and configuration. */ +export type ShopAvailablePaymentGatewaysArgs = { + currency?: Maybe + channel?: Maybe +} + +/** Represents a shop resource containing general shop data and configuration. */ +export type ShopAvailableShippingMethodsArgs = { + channel: Scalars['String'] + address?: Maybe +} + +/** Represents a shop resource containing general shop data and configuration. */ +export type ShopCountriesArgs = { + languageCode?: Maybe +} + +/** Represents a shop resource containing general shop data and configuration. */ +export type ShopTranslationArgs = { + languageCode: LanguageCodeEnum +} + +/** Update the shop's address. If the `null` value is passed, the currently selected address will be deleted. */ +export type ShopAddressUpdate = { + __typename?: 'ShopAddressUpdate' + /** Updated shop. */ + shop?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + shopErrors: Array + errors: Array +} + +/** Updates site domain of the shop. */ +export type ShopDomainUpdate = { + __typename?: 'ShopDomainUpdate' + /** Updated shop. */ + shop?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + shopErrors: Array + errors: Array +} + +export type ShopError = { + __typename?: 'ShopError' + /** Name of a field that caused the error. A value of `null` indicates that the error isn't associated with a particular field. */ + field?: Maybe + /** The error message. */ + message?: Maybe + /** The error code. */ + code: ShopErrorCode +} + +/** An enumeration. */ +export enum ShopErrorCode { + AlreadyExists = 'ALREADY_EXISTS', + CannotFetchTaxRates = 'CANNOT_FETCH_TAX_RATES', + GraphqlError = 'GRAPHQL_ERROR', + Invalid = 'INVALID', + NotFound = 'NOT_FOUND', + Required = 'REQUIRED', + Unique = 'UNIQUE', +} + +/** Fetch tax rates. */ +export type ShopFetchTaxRates = { + __typename?: 'ShopFetchTaxRates' + /** Updated shop. */ + shop?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + shopErrors: Array + errors: Array +} + +export type ShopSettingsInput = { + /** Header text. */ + headerText?: Maybe + /** SEO description. */ + description?: Maybe + /** Include taxes in prices. */ + includeTaxesInPrices?: Maybe + /** Display prices with tax in store. */ + displayGrossPrices?: Maybe + /** Charge taxes on shipping. */ + chargeTaxesOnShipping?: Maybe + /** Enable inventory tracking. */ + trackInventoryByDefault?: Maybe + /** Default weight unit. */ + defaultWeightUnit?: Maybe + /** Enable automatic fulfillment for all digital products. */ + automaticFulfillmentDigitalProducts?: Maybe + /** Default number of max downloads per digital content URL. */ + defaultDigitalMaxDownloads?: Maybe + /** Default number of days which digital content URL will be valid. */ + defaultDigitalUrlValidDays?: Maybe + /** Default email sender's name. */ + defaultMailSenderName?: Maybe + /** Default email sender's address. */ + defaultMailSenderAddress?: Maybe + /** URL of a view where customers can set their password. */ + customerSetPasswordUrl?: Maybe +} + +/** Creates/Updates translations for Shop Settings. */ +export type ShopSettingsTranslate = { + __typename?: 'ShopSettingsTranslate' + /** Updated shop. */ + shop?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + translationErrors: Array + errors: Array +} + +export type ShopSettingsTranslationInput = { + headerText?: Maybe + description?: Maybe +} + +/** Updates shop settings. */ +export type ShopSettingsUpdate = { + __typename?: 'ShopSettingsUpdate' + /** Updated shop. */ + shop?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + shopErrors: Array + errors: Array +} + +export type ShopTranslation = Node & { + __typename?: 'ShopTranslation' + /** The ID of the object. */ + id: Scalars['ID'] + headerText: Scalars['String'] + description: Scalars['String'] + /** Translation language. */ + language: LanguageDisplay +} + +export type SiteDomainInput = { + /** Domain name for shop. */ + domain?: Maybe + /** Shop site name. */ + name?: Maybe +} + +/** Deletes staff users. */ +export type StaffBulkDelete = { + __typename?: 'StaffBulkDelete' + /** Returns how many objects were affected. */ + count: Scalars['Int'] + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + staffErrors: Array + errors: Array +} + +/** Creates a new staff user. */ +export type StaffCreate = { + __typename?: 'StaffCreate' + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + staffErrors: Array + errors: Array + user?: Maybe +} + +export type StaffCreateInput = { + /** Given name. */ + firstName?: Maybe + /** Family name. */ + lastName?: Maybe + /** The unique email address of the user. */ + email?: Maybe + /** User account is active. */ + isActive?: Maybe + /** A note about the user. */ + note?: Maybe + /** List of permission group IDs to which user should be assigned. */ + addGroups?: Maybe> + /** URL of a view where users should be redirected to set the password. URL in RFC 1808 format. */ + redirectUrl?: Maybe +} + +/** Deletes a staff user. */ +export type StaffDelete = { + __typename?: 'StaffDelete' + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + staffErrors: Array + errors: Array + user?: Maybe +} + +export type StaffError = { + __typename?: 'StaffError' + /** Name of a field that caused the error. A value of `null` indicates that the error isn't associated with a particular field. */ + field?: Maybe + /** The error message. */ + message?: Maybe + /** The error code. */ + code: AccountErrorCode + /** A type of address that causes the error. */ + addressType?: Maybe + /** List of permissions which causes the error. */ + permissions?: Maybe> + /** List of permission group IDs which cause the error. */ + groups?: Maybe> + /** List of user IDs which causes the error. */ + users?: Maybe> +} + +export enum StaffMemberStatus { + /** User account has been activated. */ + Active = 'ACTIVE', + /** User account has not been activated yet. */ + Deactivated = 'DEACTIVATED', +} + +/** Represents a recipient of email notifications send by Saleor, such as notifications about new orders. Notifications can be assigned to staff users or arbitrary email addresses. */ +export type StaffNotificationRecipient = Node & { + __typename?: 'StaffNotificationRecipient' + /** Returns a user subscribed to email notifications. */ + user?: Maybe + /** Determines if a notification active. */ + active?: Maybe + /** The ID of the object. */ + id: Scalars['ID'] + /** Returns email address of a user subscribed to email notifications. */ + email?: Maybe +} + +/** Creates a new staff notification recipient. */ +export type StaffNotificationRecipientCreate = { + __typename?: 'StaffNotificationRecipientCreate' + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + shopErrors: Array + errors: Array + staffNotificationRecipient?: Maybe +} + +/** Delete staff notification recipient. */ +export type StaffNotificationRecipientDelete = { + __typename?: 'StaffNotificationRecipientDelete' + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + shopErrors: Array + errors: Array + staffNotificationRecipient?: Maybe +} + +export type StaffNotificationRecipientInput = { + /** The ID of the user subscribed to email notifications.. */ + user?: Maybe + /** Email address of a user subscribed to email notifications. */ + email?: Maybe + /** Determines if a notification active. */ + active?: Maybe +} + +/** Updates a staff notification recipient. */ +export type StaffNotificationRecipientUpdate = { + __typename?: 'StaffNotificationRecipientUpdate' + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + shopErrors: Array + errors: Array + staffNotificationRecipient?: Maybe +} + +/** Updates an existing staff user. */ +export type StaffUpdate = { + __typename?: 'StaffUpdate' + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + staffErrors: Array + errors: Array + user?: Maybe +} + +export type StaffUpdateInput = { + /** Given name. */ + firstName?: Maybe + /** Family name. */ + lastName?: Maybe + /** The unique email address of the user. */ + email?: Maybe + /** User account is active. */ + isActive?: Maybe + /** A note about the user. */ + note?: Maybe + /** List of permission group IDs to which user should be assigned. */ + addGroups?: Maybe> + /** List of permission group IDs from which user should be unassigned. */ + removeGroups?: Maybe> +} + +export type StaffUserInput = { + status?: Maybe + search?: Maybe +} + +/** Represents stock. */ +export type Stock = Node & { + __typename?: 'Stock' + warehouse: Warehouse + productVariant: ProductVariant + /** Quantity of a product in the warehouse's possession, including the allocated stock that is waiting for shipment. */ + quantity: Scalars['Int'] + /** The ID of the object. */ + id: Scalars['ID'] + /** Quantity allocated for orders */ + quantityAllocated: Scalars['Int'] +} + +export enum StockAvailability { + InStock = 'IN_STOCK', + OutOfStock = 'OUT_OF_STOCK', +} + +export type StockCountableConnection = { + __typename?: 'StockCountableConnection' + /** Pagination data for this connection. */ + pageInfo: PageInfo + edges: Array + /** A total count of items in the collection. */ + totalCount?: Maybe +} + +export type StockCountableEdge = { + __typename?: 'StockCountableEdge' + /** The item at the end of the edge. */ + node: Stock + /** A cursor for use in pagination. */ + cursor: Scalars['String'] +} + +export type StockError = { + __typename?: 'StockError' + /** Name of a field that caused the error. A value of `null` indicates that the error isn't associated with a particular field. */ + field?: Maybe + /** The error message. */ + message?: Maybe + /** The error code. */ + code: StockErrorCode +} + +/** An enumeration. */ +export enum StockErrorCode { + AlreadyExists = 'ALREADY_EXISTS', + GraphqlError = 'GRAPHQL_ERROR', + Invalid = 'INVALID', + NotFound = 'NOT_FOUND', + Required = 'REQUIRED', + Unique = 'UNIQUE', +} + +export type StockFilterInput = { + quantity?: Maybe + search?: Maybe +} + +export type StockInput = { + /** Warehouse in which stock is located. */ + warehouse: Scalars['ID'] + /** Quantity of items available for sell. */ + quantity: Scalars['Int'] +} + +/** An enumeration. */ +export enum TaxRateType { + Accommodation = 'ACCOMMODATION', + AdmissionToCulturalEvents = 'ADMISSION_TO_CULTURAL_EVENTS', + AdmissionToEntertainmentEvents = 'ADMISSION_TO_ENTERTAINMENT_EVENTS', + AdmissionToSportingEvents = 'ADMISSION_TO_SPORTING_EVENTS', + Advertising = 'ADVERTISING', + AgriculturalSupplies = 'AGRICULTURAL_SUPPLIES', + BabyFoodstuffs = 'BABY_FOODSTUFFS', + Bikes = 'BIKES', + Books = 'BOOKS', + ChildrensClothing = 'CHILDRENS_CLOTHING', + DomesticFuel = 'DOMESTIC_FUEL', + DomesticServices = 'DOMESTIC_SERVICES', + EBooks = 'E_BOOKS', + Foodstuffs = 'FOODSTUFFS', + Hotels = 'HOTELS', + Medical = 'MEDICAL', + Newspapers = 'NEWSPAPERS', + PassengerTransport = 'PASSENGER_TRANSPORT', + Pharmaceuticals = 'PHARMACEUTICALS', + PropertyRenovations = 'PROPERTY_RENOVATIONS', + Restaurants = 'RESTAURANTS', + SocialHousing = 'SOCIAL_HOUSING', + Standard = 'STANDARD', + Water = 'WATER', + Wine = 'WINE', +} + +/** Representation of tax types fetched from tax gateway. */ +export type TaxType = { + __typename?: 'TaxType' + /** Description of the tax type. */ + description?: Maybe + /** External tax code used to identify given tax group. */ + taxCode?: Maybe +} + +/** Represents a monetary value with taxes. In cases where taxes were not applied, net and gross values will be equal. */ +export type TaxedMoney = { + __typename?: 'TaxedMoney' + /** Currency code. */ + currency: Scalars['String'] + /** Amount of money including taxes. */ + gross: Money + /** Amount of money without taxes. */ + net: Money + /** Amount of taxes. */ + tax: Money +} + +/** Represents a range of monetary values. */ +export type TaxedMoneyRange = { + __typename?: 'TaxedMoneyRange' + /** Lower bound of a price range. */ + start?: Maybe + /** Upper bound of a price range. */ + stop?: Maybe +} + +/** An object representing a single payment. */ +export type Transaction = Node & { + __typename?: 'Transaction' + /** The ID of the object. */ + id: Scalars['ID'] + created: Scalars['DateTime'] + payment: Payment + token: Scalars['String'] + kind: TransactionKind + isSuccess: Scalars['Boolean'] + error?: Maybe + gatewayResponse: Scalars['JSONString'] + /** Total amount of the transaction. */ + amount?: Maybe +} + +/** An enumeration. */ +export enum TransactionKind { + /** External reference */ + External = 'EXTERNAL', + /** Authorization */ + Auth = 'AUTH', + /** Pending */ + Pending = 'PENDING', + /** Action to confirm */ + ActionToConfirm = 'ACTION_TO_CONFIRM', + /** Refund */ + Refund = 'REFUND', + /** Refund in progress */ + RefundOngoing = 'REFUND_ONGOING', + /** Capture */ + Capture = 'CAPTURE', + /** Void */ + Void = 'VOID', + /** Confirm */ + Confirm = 'CONFIRM', + /** Cancel */ + Cancel = 'CANCEL', +} + +export type TranslatableItem = + | ProductTranslatableContent + | CollectionTranslatableContent + | CategoryTranslatableContent + | AttributeTranslatableContent + | AttributeValueTranslatableContent + | ProductVariantTranslatableContent + | PageTranslatableContent + | ShippingMethodTranslatableContent + | SaleTranslatableContent + | VoucherTranslatableContent + | MenuItemTranslatableContent + +export type TranslatableItemConnection = { + __typename?: 'TranslatableItemConnection' + /** Pagination data for this connection. */ + pageInfo: PageInfo + edges: Array + /** A total count of items in the collection. */ + totalCount?: Maybe +} + +export type TranslatableItemEdge = { + __typename?: 'TranslatableItemEdge' + /** The item at the end of the edge. */ + node: TranslatableItem + /** A cursor for use in pagination. */ + cursor: Scalars['String'] +} + +export enum TranslatableKinds { + Attribute = 'ATTRIBUTE', + AttributeValue = 'ATTRIBUTE_VALUE', + Category = 'CATEGORY', + Collection = 'COLLECTION', + MenuItem = 'MENU_ITEM', + Page = 'PAGE', + Product = 'PRODUCT', + Sale = 'SALE', + ShippingMethod = 'SHIPPING_METHOD', + Variant = 'VARIANT', + Voucher = 'VOUCHER', +} + +export type TranslationError = { + __typename?: 'TranslationError' + /** Name of a field that caused the error. A value of `null` indicates that the error isn't associated with a particular field. */ + field?: Maybe + /** The error message. */ + message?: Maybe + /** The error code. */ + code: TranslationErrorCode +} + +/** An enumeration. */ +export enum TranslationErrorCode { + GraphqlError = 'GRAPHQL_ERROR', + NotFound = 'NOT_FOUND', + Required = 'REQUIRED', +} + +export type TranslationInput = { + seoTitle?: Maybe + seoDescription?: Maybe + name?: Maybe + description?: Maybe +} + +export type UpdateInvoiceInput = { + /** Invoice number */ + number?: Maybe + /** URL of an invoice to download. */ + url?: Maybe +} + +/** Updates metadata of an object. */ +export type UpdateMetadata = { + __typename?: 'UpdateMetadata' + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + metadataErrors: Array + errors: Array + item?: Maybe +} + +/** Updates private metadata of an object. */ +export type UpdatePrivateMetadata = { + __typename?: 'UpdatePrivateMetadata' + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + metadataErrors: Array + errors: Array + item?: Maybe +} + +export type UploadError = { + __typename?: 'UploadError' + /** Name of a field that caused the error. A value of `null` indicates that the error isn't associated with a particular field. */ + field?: Maybe + /** The error message. */ + message?: Maybe + /** The error code. */ + code: UploadErrorCode +} + +/** An enumeration. */ +export enum UploadErrorCode { + GraphqlError = 'GRAPHQL_ERROR', +} + +/** Represents user data. */ +export type User = Node & + ObjectWithMetadata & { + __typename?: 'User' + /** The ID of the object. */ + id: Scalars['ID'] + lastLogin?: Maybe + email: Scalars['String'] + firstName: Scalars['String'] + lastName: Scalars['String'] + isStaff: Scalars['Boolean'] + isActive: Scalars['Boolean'] + /** A note about the customer. */ + note?: Maybe + dateJoined: Scalars['DateTime'] + defaultShippingAddress?: Maybe
    + defaultBillingAddress?: Maybe
    + /** List of private metadata items.Requires proper staff permissions to access. */ + privateMetadata: Array> + /** List of public metadata items. Can be accessed without permissions. */ + metadata: Array> + /** List of all user's addresses. */ + addresses?: Maybe>> + /** + * Returns the last open checkout of this user. + * @deprecated Will be removed in Saleor 4.0. Use the `checkout_tokens` field to fetch the user checkouts. + */ + checkout?: Maybe + /** Returns the checkout UUID's assigned to this user. */ + checkoutTokens?: Maybe> + /** List of the user gift cards. */ + giftCards?: Maybe + /** List of user's orders. */ + orders?: Maybe + /** List of user's permissions. */ + userPermissions?: Maybe>> + /** List of user's permission groups. */ + permissionGroups?: Maybe>> + /** List of user's permission groups which user can manage. */ + editableGroups?: Maybe>> + avatar?: Maybe + /** List of events associated with the user. */ + events?: Maybe>> + /** List of stored payment sources. */ + storedPaymentSources?: Maybe>> + /** User language code. */ + languageCode: LanguageCodeEnum + } + +/** Represents user data. */ +export type UserCheckoutTokensArgs = { + channel?: Maybe +} + +/** Represents user data. */ +export type UserGiftCardsArgs = { + before?: Maybe + after?: Maybe + first?: Maybe + last?: Maybe +} + +/** Represents user data. */ +export type UserOrdersArgs = { + before?: Maybe + after?: Maybe + first?: Maybe + last?: Maybe +} + +/** Represents user data. */ +export type UserAvatarArgs = { + size?: Maybe +} + +/** Represents user data. */ +export type UserStoredPaymentSourcesArgs = { + channel?: Maybe +} + +/** Deletes a user avatar. Only for staff members. */ +export type UserAvatarDelete = { + __typename?: 'UserAvatarDelete' + /** An updated user instance. */ + user?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + accountErrors: Array + errors: Array +} + +/** Create a user avatar. Only for staff members. This mutation must be sent as a `multipart` request. More detailed specs of the upload format can be found here: https://github.com/jaydenseric/graphql-multipart-request-spec */ +export type UserAvatarUpdate = { + __typename?: 'UserAvatarUpdate' + /** An updated user instance. */ + user?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + accountErrors: Array + errors: Array +} + +/** Activate or deactivate users. */ +export type UserBulkSetActive = { + __typename?: 'UserBulkSetActive' + /** Returns how many objects were affected. */ + count: Scalars['Int'] + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + accountErrors: Array + errors: Array +} + +export type UserCountableConnection = { + __typename?: 'UserCountableConnection' + /** Pagination data for this connection. */ + pageInfo: PageInfo + edges: Array + /** A total count of items in the collection. */ + totalCount?: Maybe +} + +export type UserCountableEdge = { + __typename?: 'UserCountableEdge' + /** The item at the end of the edge. */ + node: User + /** A cursor for use in pagination. */ + cursor: Scalars['String'] +} + +export type UserCreateInput = { + /** Billing address of the customer. */ + defaultBillingAddress?: Maybe + /** Shipping address of the customer. */ + defaultShippingAddress?: Maybe + /** Given name. */ + firstName?: Maybe + /** Family name. */ + lastName?: Maybe + /** The unique email address of the user. */ + email?: Maybe + /** User account is active. */ + isActive?: Maybe + /** A note about the user. */ + note?: Maybe + /** User language code. */ + languageCode?: Maybe + /** URL of a view where users should be redirected to set the password. URL in RFC 1808 format. */ + redirectUrl?: Maybe + /** Slug of a channel which will be used for notify user. Optional when only one channel exists. */ + channel?: Maybe +} + +export type UserPermission = { + __typename?: 'UserPermission' + /** Internal code for permission. */ + code: PermissionEnum + /** Describe action(s) allowed to do by permission. */ + name: Scalars['String'] + /** List of user permission groups which contains this permission. */ + sourcePermissionGroups?: Maybe> +} + +export type UserPermissionSourcePermissionGroupsArgs = { + userId: Scalars['ID'] +} + +export enum UserSortField { + /** Sort users by first name. */ + FirstName = 'FIRST_NAME', + /** Sort users by last name. */ + LastName = 'LAST_NAME', + /** Sort users by email. */ + Email = 'EMAIL', + /** Sort users by order count. */ + OrderCount = 'ORDER_COUNT', +} + +export type UserSortingInput = { + /** Specifies the direction in which to sort products. */ + direction: OrderDirection + /** Sort users by the selected field. */ + field: UserSortField +} + +/** Represents a VAT rate for a country. */ +export type Vat = { + __typename?: 'VAT' + /** Country code. */ + countryCode: Scalars['String'] + /** Standard VAT rate in percent. */ + standardRate?: Maybe + /** Country's VAT rate exceptions for specific types of goods. */ + reducedRates: Array> +} + +export enum VariantAttributeScope { + All = 'ALL', + VariantSelection = 'VARIANT_SELECTION', + NotVariantSelection = 'NOT_VARIANT_SELECTION', +} + +/** Assign an media to a product variant. */ +export type VariantMediaAssign = { + __typename?: 'VariantMediaAssign' + productVariant?: Maybe + media?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + productErrors: Array + errors: Array +} + +/** Unassign an media from a product variant. */ +export type VariantMediaUnassign = { + __typename?: 'VariantMediaUnassign' + productVariant?: Maybe + media?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + productErrors: Array + errors: Array +} + +/** Represents availability of a variant in the storefront. */ +export type VariantPricingInfo = { + __typename?: 'VariantPricingInfo' + /** Whether it is in sale or not. */ + onSale?: Maybe + /** The discount amount if in sale (null otherwise). */ + discount?: Maybe + /** The discount amount in the local currency. */ + discountLocalCurrency?: Maybe + /** The price, with any discount subtracted. */ + price?: Maybe + /** The price without any discount. */ + priceUndiscounted?: Maybe + /** The discounted price in the local currency. */ + priceLocalCurrency?: Maybe +} + +/** Verify JWT token. */ +export type VerifyToken = { + __typename?: 'VerifyToken' + /** User assigned to token. */ + user?: Maybe + /** Determine if token is valid or not. */ + isValid: Scalars['Boolean'] + /** JWT payload. */ + payload?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + accountErrors: Array + errors: Array +} + +/** An enumeration. */ +export enum VolumeUnitsEnum { + CubicMillimeter = 'CUBIC_MILLIMETER', + CubicCentimeter = 'CUBIC_CENTIMETER', + CubicDecimeter = 'CUBIC_DECIMETER', + CubicMeter = 'CUBIC_METER', + Liter = 'LITER', + CubicFoot = 'CUBIC_FOOT', + CubicInch = 'CUBIC_INCH', + CubicYard = 'CUBIC_YARD', + Qt = 'QT', + Pint = 'PINT', + FlOz = 'FL_OZ', + AcreIn = 'ACRE_IN', + AcreFt = 'ACRE_FT', +} + +/** Vouchers allow giving discounts to particular customers on categories, collections or specific products. They can be used during checkout by providing valid voucher codes. */ +export type Voucher = Node & { + __typename?: 'Voucher' + /** The ID of the object. */ + id: Scalars['ID'] + name?: Maybe + /** Determines a type of voucher. */ + type: VoucherTypeEnum + code: Scalars['String'] + usageLimit?: Maybe + used: Scalars['Int'] + startDate: Scalars['DateTime'] + endDate?: Maybe + applyOncePerOrder: Scalars['Boolean'] + applyOncePerCustomer: Scalars['Boolean'] + /** Determines a type of discount for voucher - value or percentage */ + discountValueType: DiscountValueTypeEnum + minCheckoutItemsQuantity?: Maybe + /** List of categories this voucher applies to. */ + categories?: Maybe + /** List of collections this voucher applies to. */ + collections?: Maybe + /** List of products this voucher applies to. */ + products?: Maybe + /** List of countries available for the shipping voucher. */ + countries?: Maybe>> + /** Returns translated voucher fields for the given language code. */ + translation?: Maybe + /** Voucher value. */ + discountValue?: Maybe + /** Currency code for voucher. */ + currency?: Maybe + /** Minimum order value to apply voucher. */ + minSpent?: Maybe + /** List of availability in channels for the voucher. */ + channelListings?: Maybe> +} + +/** Vouchers allow giving discounts to particular customers on categories, collections or specific products. They can be used during checkout by providing valid voucher codes. */ +export type VoucherCategoriesArgs = { + before?: Maybe + after?: Maybe + first?: Maybe + last?: Maybe +} + +/** Vouchers allow giving discounts to particular customers on categories, collections or specific products. They can be used during checkout by providing valid voucher codes. */ +export type VoucherCollectionsArgs = { + before?: Maybe + after?: Maybe + first?: Maybe + last?: Maybe +} + +/** Vouchers allow giving discounts to particular customers on categories, collections or specific products. They can be used during checkout by providing valid voucher codes. */ +export type VoucherProductsArgs = { + before?: Maybe + after?: Maybe + first?: Maybe + last?: Maybe +} + +/** Vouchers allow giving discounts to particular customers on categories, collections or specific products. They can be used during checkout by providing valid voucher codes. */ +export type VoucherTranslationArgs = { + languageCode: LanguageCodeEnum +} + +/** Adds products, categories, collections to a voucher. */ +export type VoucherAddCatalogues = { + __typename?: 'VoucherAddCatalogues' + /** Voucher of which catalogue IDs will be modified. */ + voucher?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + discountErrors: Array + errors: Array +} + +/** Deletes vouchers. */ +export type VoucherBulkDelete = { + __typename?: 'VoucherBulkDelete' + /** Returns how many objects were affected. */ + count: Scalars['Int'] + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + discountErrors: Array + errors: Array +} + +/** Represents voucher channel listing. */ +export type VoucherChannelListing = Node & { + __typename?: 'VoucherChannelListing' + /** The ID of the object. */ + id: Scalars['ID'] + channel: Channel + discountValue: Scalars['Float'] + currency: Scalars['String'] + minSpent?: Maybe +} + +export type VoucherChannelListingAddInput = { + /** ID of a channel. */ + channelId: Scalars['ID'] + /** Value of the voucher. */ + discountValue?: Maybe + /** Min purchase amount required to apply the voucher. */ + minAmountSpent?: Maybe +} + +export type VoucherChannelListingInput = { + /** List of channels to which the voucher should be assigned. */ + addChannels?: Maybe> + /** List of channels from which the voucher should be unassigned. */ + removeChannels?: Maybe> +} + +/** Manage voucher's availability in channels. */ +export type VoucherChannelListingUpdate = { + __typename?: 'VoucherChannelListingUpdate' + /** An updated voucher instance. */ + voucher?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + discountErrors: Array + errors: Array +} + +export type VoucherCountableConnection = { + __typename?: 'VoucherCountableConnection' + /** Pagination data for this connection. */ + pageInfo: PageInfo + edges: Array + /** A total count of items in the collection. */ + totalCount?: Maybe +} + +export type VoucherCountableEdge = { + __typename?: 'VoucherCountableEdge' + /** The item at the end of the edge. */ + node: Voucher + /** A cursor for use in pagination. */ + cursor: Scalars['String'] +} + +/** Creates a new voucher. */ +export type VoucherCreate = { + __typename?: 'VoucherCreate' + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + discountErrors: Array + errors: Array + voucher?: Maybe +} + +/** Deletes a voucher. */ +export type VoucherDelete = { + __typename?: 'VoucherDelete' + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + discountErrors: Array + errors: Array + voucher?: Maybe +} + +export enum VoucherDiscountType { + Fixed = 'FIXED', + Percentage = 'PERCENTAGE', + Shipping = 'SHIPPING', +} + +export type VoucherFilterInput = { + status?: Maybe>> + timesUsed?: Maybe + discountType?: Maybe>> + started?: Maybe + search?: Maybe +} + +export type VoucherInput = { + /** Voucher type: PRODUCT, CATEGORY SHIPPING or ENTIRE_ORDER. */ + type?: Maybe + /** Voucher name. */ + name?: Maybe + /** Code to use the voucher. */ + code?: Maybe + /** Start date of the voucher in ISO 8601 format. */ + startDate?: Maybe + /** End date of the voucher in ISO 8601 format. */ + endDate?: Maybe + /** Choices: fixed or percentage. */ + discountValueType?: Maybe + /** Products discounted by the voucher. */ + products?: Maybe>> + /** Collections discounted by the voucher. */ + collections?: Maybe>> + /** Categories discounted by the voucher. */ + categories?: Maybe>> + /** Minimal quantity of checkout items required to apply the voucher. */ + minCheckoutItemsQuantity?: Maybe + /** Country codes that can be used with the shipping voucher. */ + countries?: Maybe>> + /** Voucher should be applied to the cheapest item or entire order. */ + applyOncePerOrder?: Maybe + /** Voucher should be applied once per customer. */ + applyOncePerCustomer?: Maybe + /** Limit number of times this voucher can be used in total. */ + usageLimit?: Maybe +} + +/** Removes products, categories, collections from a voucher. */ +export type VoucherRemoveCatalogues = { + __typename?: 'VoucherRemoveCatalogues' + /** Voucher of which catalogue IDs will be modified. */ + voucher?: Maybe + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + discountErrors: Array + errors: Array +} + +export enum VoucherSortField { + /** Sort vouchers by code. */ + Code = 'CODE', + /** Sort vouchers by start date. */ + StartDate = 'START_DATE', + /** Sort vouchers by end date. */ + EndDate = 'END_DATE', + /** Sort vouchers by value. */ + Value = 'VALUE', + /** Sort vouchers by type. */ + Type = 'TYPE', + /** Sort vouchers by usage limit. */ + UsageLimit = 'USAGE_LIMIT', + /** Sort vouchers by minimum spent amount. */ + MinimumSpentAmount = 'MINIMUM_SPENT_AMOUNT', +} + +export type VoucherSortingInput = { + /** Specifies the direction in which to sort products. */ + direction: OrderDirection + /** Specifies the channel in which to sort the data. */ + channel?: Maybe + /** Sort vouchers by the selected field. */ + field: VoucherSortField +} + +export type VoucherTranslatableContent = Node & { + __typename?: 'VoucherTranslatableContent' + /** The ID of the object. */ + id: Scalars['ID'] + name?: Maybe + /** Returns translated voucher fields for the given language code. */ + translation?: Maybe + /** Vouchers allow giving discounts to particular customers on categories, collections or specific products. They can be used during checkout by providing valid voucher codes. */ + voucher?: Maybe +} + +export type VoucherTranslatableContentTranslationArgs = { + languageCode: LanguageCodeEnum +} + +/** Creates/Updates translations for Voucher. */ +export type VoucherTranslate = { + __typename?: 'VoucherTranslate' + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + translationErrors: Array + errors: Array + voucher?: Maybe +} + +export type VoucherTranslation = Node & { + __typename?: 'VoucherTranslation' + /** The ID of the object. */ + id: Scalars['ID'] + name?: Maybe + /** Translation language. */ + language: LanguageDisplay +} + +export enum VoucherTypeEnum { + Shipping = 'SHIPPING', + EntireOrder = 'ENTIRE_ORDER', + SpecificProduct = 'SPECIFIC_PRODUCT', +} + +/** Updates a voucher. */ +export type VoucherUpdate = { + __typename?: 'VoucherUpdate' + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + discountErrors: Array + errors: Array + voucher?: Maybe +} + +/** Represents warehouse. */ +export type Warehouse = Node & + ObjectWithMetadata & { + __typename?: 'Warehouse' + /** The ID of the object. */ + id: Scalars['ID'] + name: Scalars['String'] + slug: Scalars['String'] + companyName: Scalars['String'] + shippingZones: ShippingZoneCountableConnection + address: Address + email: Scalars['String'] + /** List of private metadata items.Requires proper staff permissions to access. */ + privateMetadata: Array> + /** List of public metadata items. Can be accessed without permissions. */ + metadata: Array> + } + +/** Represents warehouse. */ +export type WarehouseShippingZonesArgs = { + before?: Maybe + after?: Maybe + first?: Maybe + last?: Maybe +} + +export type WarehouseAddressInput = { + /** Address. */ + streetAddress1: Scalars['String'] + /** Address. */ + streetAddress2?: Maybe + /** City. */ + city: Scalars['String'] + /** District. */ + cityArea?: Maybe + /** Postal code. */ + postalCode?: Maybe + /** Country. */ + country: CountryCode + /** State or province. */ + countryArea?: Maybe + /** Phone number. */ + phone?: Maybe +} + +export type WarehouseCountableConnection = { + __typename?: 'WarehouseCountableConnection' + /** Pagination data for this connection. */ + pageInfo: PageInfo + edges: Array + /** A total count of items in the collection. */ + totalCount?: Maybe +} + +export type WarehouseCountableEdge = { + __typename?: 'WarehouseCountableEdge' + /** The item at the end of the edge. */ + node: Warehouse + /** A cursor for use in pagination. */ + cursor: Scalars['String'] +} + +/** Creates new warehouse. */ +export type WarehouseCreate = { + __typename?: 'WarehouseCreate' + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + warehouseErrors: Array + errors: Array + warehouse?: Maybe +} + +export type WarehouseCreateInput = { + /** Warehouse slug. */ + slug?: Maybe + /** Company name. */ + companyName?: Maybe + /** The email address of the warehouse. */ + email?: Maybe + /** Warehouse name. */ + name: Scalars['String'] + /** Address of the warehouse. */ + address: WarehouseAddressInput + /** Shipping zones supported by the warehouse. */ + shippingZones?: Maybe>> +} + +/** Deletes selected warehouse. */ +export type WarehouseDelete = { + __typename?: 'WarehouseDelete' + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + warehouseErrors: Array + errors: Array + warehouse?: Maybe +} + +export type WarehouseError = { + __typename?: 'WarehouseError' + /** Name of a field that caused the error. A value of `null` indicates that the error isn't associated with a particular field. */ + field?: Maybe + /** The error message. */ + message?: Maybe + /** The error code. */ + code: WarehouseErrorCode +} + +/** An enumeration. */ +export enum WarehouseErrorCode { + AlreadyExists = 'ALREADY_EXISTS', + GraphqlError = 'GRAPHQL_ERROR', + Invalid = 'INVALID', + NotFound = 'NOT_FOUND', + Required = 'REQUIRED', + Unique = 'UNIQUE', +} + +export type WarehouseFilterInput = { + search?: Maybe + ids?: Maybe>> +} + +/** Add shipping zone to given warehouse. */ +export type WarehouseShippingZoneAssign = { + __typename?: 'WarehouseShippingZoneAssign' + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + warehouseErrors: Array + errors: Array + warehouse?: Maybe +} + +/** Remove shipping zone from given warehouse. */ +export type WarehouseShippingZoneUnassign = { + __typename?: 'WarehouseShippingZoneUnassign' + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + warehouseErrors: Array + errors: Array + warehouse?: Maybe +} + +export enum WarehouseSortField { + /** Sort warehouses by name. */ + Name = 'NAME', +} + +export type WarehouseSortingInput = { + /** Specifies the direction in which to sort products. */ + direction: OrderDirection + /** Sort warehouses by the selected field. */ + field: WarehouseSortField +} + +/** Updates given warehouse. */ +export type WarehouseUpdate = { + __typename?: 'WarehouseUpdate' + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + warehouseErrors: Array + errors: Array + warehouse?: Maybe +} + +export type WarehouseUpdateInput = { + /** Warehouse slug. */ + slug?: Maybe + /** Company name. */ + companyName?: Maybe + /** The email address of the warehouse. */ + email?: Maybe + /** Warehouse name. */ + name?: Maybe + /** Address of the warehouse. */ + address?: Maybe +} + +/** Webhook. */ +export type Webhook = Node & { + __typename?: 'Webhook' + name: Scalars['String'] + targetUrl: Scalars['String'] + isActive: Scalars['Boolean'] + secretKey?: Maybe + /** The ID of the object. */ + id: Scalars['ID'] + /** List of webhook events. */ + events: Array + app: App +} + +/** Creates a new webhook subscription. */ +export type WebhookCreate = { + __typename?: 'WebhookCreate' + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + webhookErrors: Array + errors: Array + webhook?: Maybe +} + +export type WebhookCreateInput = { + /** The name of the webhook. */ + name?: Maybe + /** The url to receive the payload. */ + targetUrl?: Maybe + /** The events that webhook wants to subscribe. */ + events?: Maybe>> + /** ID of the app to which webhook belongs. */ + app?: Maybe + /** Determine if webhook will be set active or not. */ + isActive?: Maybe + /** The secret key used to create a hash signature with each payload. */ + secretKey?: Maybe +} + +/** Deletes a webhook subscription. */ +export type WebhookDelete = { + __typename?: 'WebhookDelete' + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + webhookErrors: Array + errors: Array + webhook?: Maybe +} + +export type WebhookError = { + __typename?: 'WebhookError' + /** Name of a field that caused the error. A value of `null` indicates that the error isn't associated with a particular field. */ + field?: Maybe + /** The error message. */ + message?: Maybe + /** The error code. */ + code: WebhookErrorCode +} + +/** An enumeration. */ +export enum WebhookErrorCode { + GraphqlError = 'GRAPHQL_ERROR', + Invalid = 'INVALID', + NotFound = 'NOT_FOUND', + Required = 'REQUIRED', + Unique = 'UNIQUE', +} + +/** Webhook event. */ +export type WebhookEvent = { + __typename?: 'WebhookEvent' + /** Internal name of the event type. */ + eventType: WebhookEventTypeEnum + /** Display name of the event. */ + name: Scalars['String'] +} + +/** Enum determining type of webhook. */ +export enum WebhookEventTypeEnum { + /** All the events. */ + AnyEvents = 'ANY_EVENTS', + /** A new order is placed. */ + OrderCreated = 'ORDER_CREATED', + /** An order is confirmed (status change unconfirmed -> unfulfilled) by a staff user using the OrderConfirm mutation. It also triggers when the user completes the checkout and the shop setting `automatically_confirm_all_new_orders` is enabled. */ + OrderConfirmed = 'ORDER_CONFIRMED', + /** Payment is made and an order is fully paid. */ + OrderFullyPaid = 'ORDER_FULLY_PAID', + /** An order is updated; triggered for all changes related to an order; covers all other order webhooks, except for ORDER_CREATED. */ + OrderUpdated = 'ORDER_UPDATED', + /** An order is cancelled. */ + OrderCancelled = 'ORDER_CANCELLED', + /** An order is fulfilled. */ + OrderFulfilled = 'ORDER_FULFILLED', + /** An invoice for order requested. */ + InvoiceRequested = 'INVOICE_REQUESTED', + /** An invoice is deleted. */ + InvoiceDeleted = 'INVOICE_DELETED', + /** Invoice has been sent. */ + InvoiceSent = 'INVOICE_SENT', + /** A new customer account is created. */ + CustomerCreated = 'CUSTOMER_CREATED', + /** A customer account is updated. */ + CustomerUpdated = 'CUSTOMER_UPDATED', + /** A new product is created. */ + ProductCreated = 'PRODUCT_CREATED', + /** A product is updated. */ + ProductUpdated = 'PRODUCT_UPDATED', + /** A product is deleted. */ + ProductDeleted = 'PRODUCT_DELETED', + /** A new product variant is created. */ + ProductVariantCreated = 'PRODUCT_VARIANT_CREATED', + /** A product variant is updated. */ + ProductVariantUpdated = 'PRODUCT_VARIANT_UPDATED', + /** A product variant is deleted. */ + ProductVariantDeleted = 'PRODUCT_VARIANT_DELETED', + /** A new checkout is created. */ + CheckoutCreated = 'CHECKOUT_CREATED', + /** A checkout is updated. It also triggers all updates related to the checkout. */ + CheckoutUpdated = 'CHECKOUT_UPDATED', + /** A new fulfillment is created. */ + FulfillmentCreated = 'FULFILLMENT_CREATED', + /** User notification triggered. */ + NotifyUser = 'NOTIFY_USER', + /** A new page is created. */ + PageCreated = 'PAGE_CREATED', + /** A page is updated. */ + PageUpdated = 'PAGE_UPDATED', + /** A page is deleted. */ + PageDeleted = 'PAGE_DELETED', +} + +/** An enumeration. */ +export enum WebhookSampleEventTypeEnum { + OrderCreated = 'ORDER_CREATED', + OrderConfirmed = 'ORDER_CONFIRMED', + OrderFullyPaid = 'ORDER_FULLY_PAID', + OrderUpdated = 'ORDER_UPDATED', + OrderCancelled = 'ORDER_CANCELLED', + OrderFulfilled = 'ORDER_FULFILLED', + InvoiceRequested = 'INVOICE_REQUESTED', + InvoiceDeleted = 'INVOICE_DELETED', + InvoiceSent = 'INVOICE_SENT', + CustomerCreated = 'CUSTOMER_CREATED', + CustomerUpdated = 'CUSTOMER_UPDATED', + ProductCreated = 'PRODUCT_CREATED', + ProductUpdated = 'PRODUCT_UPDATED', + ProductDeleted = 'PRODUCT_DELETED', + ProductVariantCreated = 'PRODUCT_VARIANT_CREATED', + ProductVariantUpdated = 'PRODUCT_VARIANT_UPDATED', + ProductVariantDeleted = 'PRODUCT_VARIANT_DELETED', + CheckoutCreated = 'CHECKOUT_CREATED', + CheckoutUpdated = 'CHECKOUT_UPDATED', + FulfillmentCreated = 'FULFILLMENT_CREATED', + NotifyUser = 'NOTIFY_USER', + PageCreated = 'PAGE_CREATED', + PageUpdated = 'PAGE_UPDATED', + PageDeleted = 'PAGE_DELETED', +} + +/** Updates a webhook subscription. */ +export type WebhookUpdate = { + __typename?: 'WebhookUpdate' + /** @deprecated Use errors field instead. This field will be removed in Saleor 4.0. */ + webhookErrors: Array + errors: Array + webhook?: Maybe +} + +export type WebhookUpdateInput = { + /** The new name of the webhook. */ + name?: Maybe + /** The url to receive the payload. */ + targetUrl?: Maybe + /** The events that webhook wants to subscribe. */ + events?: Maybe>> + /** ID of the app to which webhook belongs. */ + app?: Maybe + /** Determine if webhook will be set active or not. */ + isActive?: Maybe + /** Use to create a hash signature with each payload. */ + secretKey?: Maybe +} + +/** Represents weight value in a specific weight unit. */ +export type Weight = { + __typename?: 'Weight' + /** Weight unit. */ + unit: WeightUnitsEnum + /** Weight value. */ + value: Scalars['Float'] +} + +/** An enumeration. */ +export enum WeightUnitsEnum { + G = 'G', + Lb = 'LB', + Oz = 'OZ', + Kg = 'KG', + Tonne = 'TONNE', +} + +export type _Entity = + | Address + | User + | Group + | App + | ProductVariant + | Product + | ProductType + | Collection + | Category + | ProductMedia + | ProductImage + | PageType + +export type _Service = { + __typename?: '_Service' + sdl?: Maybe +} + +export type GetAllProductPathsQueryVariables = Exact<{ + first?: Maybe + cursor?: Maybe + channel?: Maybe +}> + +export type GetAllProductPathsQuery = { __typename?: 'Query' } & { + products?: Maybe< + { __typename?: 'ProductCountableConnection' } & { + pageInfo: { __typename?: 'PageInfo' } & Pick + edges: Array< + { __typename?: 'ProductCountableEdge' } & Pick & { + node: { __typename?: 'Product' } & Pick + } + > + } + > +} + +export type ProductConnectionFragment = { + __typename?: 'ProductCountableConnection' +} & { + pageInfo: { __typename?: 'PageInfo' } & Pick + edges: Array< + { __typename?: 'ProductCountableEdge' } & { + node: { __typename?: 'Product' } & Pick & { + pricing?: Maybe< + { __typename?: 'ProductPricingInfo' } & { + priceRange?: Maybe< + { __typename?: 'TaxedMoneyRange' } & { + start?: Maybe< + { __typename?: 'TaxedMoney' } & { + net: { __typename?: 'Money' } & Pick + } + > + } + > + } + > + media?: Maybe>> + } + } + > +} + +export type GetAllProductsQueryVariables = Exact<{ + first?: Maybe + filter?: Maybe + sortBy?: Maybe + channel?: Maybe +}> + +export type GetAllProductsQuery = { __typename?: 'Query' } & { + products?: Maybe<{ __typename?: 'ProductCountableConnection' } & ProductConnectionFragment> +} diff --git a/framework/saleor/schema.graphql b/framework/saleor/schema.graphql new file mode 100644 index 000000000..de2858641 --- /dev/null +++ b/framework/saleor/schema.graphql @@ -0,0 +1,18973 @@ +""" +Create a new address for the customer. +""" +type AccountAddressCreate { + """ + A user instance for which the address was created. + """ + user: User + accountErrors: [AccountError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [AccountError!]! + address: Address +} + +""" +Delete an address of the logged-in user. +""" +type AccountAddressDelete { + """ + A user instance for which the address was deleted. + """ + user: User + accountErrors: [AccountError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [AccountError!]! + address: Address +} + +""" +Updates an address of the logged-in user. +""" +type AccountAddressUpdate { + """ + A user object for which the address was edited. + """ + user: User + accountErrors: [AccountError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [AccountError!]! + address: Address +} + +""" +Remove user account. +""" +type AccountDelete { + accountErrors: [AccountError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [AccountError!]! + user: User +} + +type AccountError { + """ + Name of a field that caused the error. A value of `null` indicates that the error isn't associated with a particular field. + """ + field: String + + """ + The error message. + """ + message: String + + """ + The error code. + """ + code: AccountErrorCode! + + """ + A type of address that causes the error. + """ + addressType: AddressTypeEnum +} + +""" +An enumeration. +""" +enum AccountErrorCode { + ACTIVATE_OWN_ACCOUNT + ACTIVATE_SUPERUSER_ACCOUNT + DUPLICATED_INPUT_ITEM + DEACTIVATE_OWN_ACCOUNT + DEACTIVATE_SUPERUSER_ACCOUNT + DELETE_NON_STAFF_USER + DELETE_OWN_ACCOUNT + DELETE_STAFF_ACCOUNT + DELETE_SUPERUSER_ACCOUNT + GRAPHQL_ERROR + INACTIVE + INVALID + INVALID_PASSWORD + LEFT_NOT_MANAGEABLE_PERMISSION + INVALID_CREDENTIALS + NOT_FOUND + OUT_OF_SCOPE_USER + OUT_OF_SCOPE_GROUP + OUT_OF_SCOPE_PERMISSION + PASSWORD_ENTIRELY_NUMERIC + PASSWORD_TOO_COMMON + PASSWORD_TOO_SHORT + PASSWORD_TOO_SIMILAR + REQUIRED + UNIQUE + JWT_SIGNATURE_EXPIRED + JWT_INVALID_TOKEN + JWT_DECODE_ERROR + JWT_MISSING_TOKEN + JWT_INVALID_CSRF_TOKEN + CHANNEL_INACTIVE + MISSING_CHANNEL_SLUG +} + +input AccountInput { + """ + Given name. + """ + firstName: String + + """ + Family name. + """ + lastName: String + + """ + Billing address of the customer. + """ + defaultBillingAddress: AddressInput + + """ + Shipping address of the customer. + """ + defaultShippingAddress: AddressInput + + """ + User language code. + """ + languageCode: LanguageCodeEnum +} + +""" +Register a new user. +""" +type AccountRegister { + """ + Informs whether users need to confirm their email address. + """ + requiresConfirmation: Boolean + accountErrors: [AccountError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [AccountError!]! + user: User +} + +input AccountRegisterInput { + """ + The email address of the user. + """ + email: String! + + """ + Password. + """ + password: String! + + """ + Base of frontend URL that will be needed to create confirmation URL. + """ + redirectUrl: String + + """ + User language code. + """ + languageCode: LanguageCodeEnum + + """ + User public metadata. + """ + metadata: [MetadataInput!] + + """ + Slug of a channel which will be used to notify users. Optional when only one channel exists. + """ + channel: String +} + +""" +Sends an email with the account removal link for the logged-in user. +""" +type AccountRequestDeletion { + accountErrors: [AccountError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [AccountError!]! +} + +""" +Sets a default address for the authenticated user. +""" +type AccountSetDefaultAddress { + """ + An updated user instance. + """ + user: User + accountErrors: [AccountError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [AccountError!]! +} + +""" +Updates the account of the logged-in user. +""" +type AccountUpdate { + accountErrors: [AccountError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [AccountError!]! + user: User +} + +""" +Represents user address data. +""" +type Address implements Node { + """ + The ID of the object. + """ + id: ID! + firstName: String! + lastName: String! + companyName: String! + streetAddress1: String! + streetAddress2: String! + city: String! + cityArea: String! + postalCode: String! + + """ + Shop's default country. + """ + country: CountryDisplay! + countryArea: String! + phone: String + + """ + Address is user's default shipping address. + """ + isDefaultShippingAddress: Boolean + + """ + Address is user's default billing address. + """ + isDefaultBillingAddress: Boolean +} + +""" +Creates user address. +""" +type AddressCreate { + """ + A user instance for which the address was created. + """ + user: User + accountErrors: [AccountError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [AccountError!]! + address: Address +} + +""" +Deletes an address. +""" +type AddressDelete { + """ + A user instance for which the address was deleted. + """ + user: User + accountErrors: [AccountError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [AccountError!]! + address: Address +} + +input AddressInput { + """ + Given name. + """ + firstName: String + + """ + Family name. + """ + lastName: String + + """ + Company or organization. + """ + companyName: String + + """ + Address. + """ + streetAddress1: String + + """ + Address. + """ + streetAddress2: String + + """ + City. + """ + city: String + + """ + District. + """ + cityArea: String + + """ + Postal code. + """ + postalCode: String + + """ + Country. + """ + country: CountryCode + + """ + State or province. + """ + countryArea: String + + """ + Phone number. + """ + phone: String +} + +""" +Sets a default address for the given user. +""" +type AddressSetDefault { + """ + An updated user instance. + """ + user: User + accountErrors: [AccountError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [AccountError!]! +} + +""" +An enumeration. +""" +enum AddressTypeEnum { + BILLING + SHIPPING +} + +""" +Updates an address. +""" +type AddressUpdate { + """ + A user object for which the address was edited. + """ + user: User + accountErrors: [AccountError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [AccountError!]! + address: Address +} + +type AddressValidationData { + countryCode: String + countryName: String + addressFormat: String + addressLatinFormat: String + allowedFields: [String] + requiredFields: [String] + upperFields: [String] + countryAreaType: String + countryAreaChoices: [ChoiceValue] + cityType: String + cityChoices: [ChoiceValue] + cityAreaType: String + cityAreaChoices: [ChoiceValue] + postalCodeType: String + postalCodeMatchers: [String] + postalCodeExamples: [String] + postalCodePrefix: String +} + +""" +Represents allocation. +""" +type Allocation implements Node { + """ + The ID of the object. + """ + id: ID! + + """ + Quantity allocated for orders. + """ + quantity: Int! + + """ + The warehouse were items were allocated. + """ + warehouse: Warehouse! +} + +""" +Represents app data. +""" +type App implements Node & ObjectWithMetadata { + """ + The ID of the object. + """ + id: ID! + + """ + Name of the app. + """ + name: String + + """ + The date and time when the app was created. + """ + created: DateTime + + """ + Determine if app will be set active or not. + """ + isActive: Boolean + + """ + List of the app's permissions. + """ + permissions: [Permission] + + """ + Last 4 characters of the tokens. + """ + tokens: [AppToken] + + """ + List of private metadata items.Requires proper staff permissions to access. + """ + privateMetadata: [MetadataItem]! + + """ + List of public metadata items. Can be accessed without permissions. + """ + metadata: [MetadataItem]! + + """ + Type of the app. + """ + type: AppTypeEnum + + """ + List of webhooks assigned to this app. + """ + webhooks: [Webhook] + + """ + Description of this app. + """ + aboutApp: String + + """ + Description of the data privacy defined for this app. + """ + dataPrivacy: String + + """ + Url to details about the privacy policy on the app owner page. + """ + dataPrivacyUrl: String + + """ + Homepage of the app. + """ + homepageUrl: String + + """ + Support page for the app. + """ + supportUrl: String + + """ + Url to iframe with the configuration for the app. + """ + configurationUrl: String + + """ + Url to iframe with the app. + """ + appUrl: String + + """ + Version number of the app. + """ + version: String + + """ + JWT token used to authenticate by thridparty app. + """ + accessToken: String +} + +""" +Activate the app. +""" +type AppActivate { + appErrors: [AppError!]! @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [AppError!]! + app: App +} + +type AppCountableConnection { + """ + Pagination data for this connection. + """ + pageInfo: PageInfo! + edges: [AppCountableEdge!]! + + """ + A total count of items in the collection. + """ + totalCount: Int +} + +type AppCountableEdge { + """ + The item at the end of the edge. + """ + node: App! + + """ + A cursor for use in pagination. + """ + cursor: String! +} + +""" +Creates a new app. +""" +type AppCreate { + """ + The newly created authentication token. + """ + authToken: String + appErrors: [AppError!]! @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [AppError!]! + app: App +} + +""" +Deactivate the app. +""" +type AppDeactivate { + appErrors: [AppError!]! @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [AppError!]! + app: App +} + +""" +Deletes an app. +""" +type AppDelete { + appErrors: [AppError!]! @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [AppError!]! + app: App +} + +""" +Delete failed installation. +""" +type AppDeleteFailedInstallation { + appErrors: [AppError!]! @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [AppError!]! + appInstallation: AppInstallation +} + +type AppError { + """ + Name of a field that caused the error. A value of `null` indicates that the error isn't associated with a particular field. + """ + field: String + + """ + The error message. + """ + message: String + + """ + The error code. + """ + code: AppErrorCode! + + """ + List of permissions which causes the error. + """ + permissions: [PermissionEnum!] +} + +""" +An enumeration. +""" +enum AppErrorCode { + FORBIDDEN + GRAPHQL_ERROR + INVALID + INVALID_STATUS + INVALID_PERMISSION + INVALID_URL_FORMAT + INVALID_MANIFEST_FORMAT + MANIFEST_URL_CANT_CONNECT + NOT_FOUND + REQUIRED + UNIQUE + OUT_OF_SCOPE_APP + OUT_OF_SCOPE_PERMISSION +} + +""" +Fetch and validate manifest. +""" +type AppFetchManifest { + manifest: Manifest + appErrors: [AppError!]! @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [AppError!]! +} + +input AppFilterInput { + search: String + isActive: Boolean + type: AppTypeEnum +} + +input AppInput { + """ + Name of the app. + """ + name: String + + """ + List of permission code names to assign to this app. + """ + permissions: [PermissionEnum] +} + +""" +Install new app by using app manifest. +""" +type AppInstall { + appErrors: [AppError!]! @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [AppError!]! + appInstallation: AppInstallation +} + +input AppInstallInput { + """ + Name of the app to install. + """ + appName: String + + """ + Url to app's manifest in JSON format. + """ + manifestUrl: String + + """ + Determine if app will be set active or not. + """ + activateAfterInstallation: Boolean = true + + """ + List of permission code names to assign to this app. + """ + permissions: [PermissionEnum] +} + +""" +Represents ongoing installation of app. +""" +type AppInstallation implements Node & Job { + appName: String! + manifestUrl: String! + + """ + The ID of the object. + """ + id: ID! + + """ + Job status. + """ + status: JobStatusEnum! + + """ + Created date time of job in ISO 8601 format. + """ + createdAt: DateTime! + + """ + Date time of job last update in ISO 8601 format. + """ + updatedAt: DateTime! + + """ + Job message. + """ + message: String +} + +""" +Retry failed installation of new app. +""" +type AppRetryInstall { + appErrors: [AppError!]! @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [AppError!]! + appInstallation: AppInstallation +} + +enum AppSortField { + """ + Sort apps by name. + """ + NAME + + """ + Sort apps by creation date. + """ + CREATION_DATE +} + +input AppSortingInput { + """ + Specifies the direction in which to sort products. + """ + direction: OrderDirection! + + """ + Sort apps by the selected field. + """ + field: AppSortField! +} + +""" +Represents token data. +""" +type AppToken implements Node { + """ + Name of the authenticated token. + """ + name: String + + """ + Last 4 characters of the token. + """ + authToken: String + + """ + The ID of the object. + """ + id: ID! +} + +""" +Creates a new token. +""" +type AppTokenCreate { + """ + The newly created authentication token. + """ + authToken: String + appErrors: [AppError!]! @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [AppError!]! + appToken: AppToken +} + +""" +Deletes an authentication token assigned to app. +""" +type AppTokenDelete { + appErrors: [AppError!]! @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [AppError!]! + appToken: AppToken +} + +input AppTokenInput { + """ + Name of the token. + """ + name: String + + """ + ID of app. + """ + app: ID! +} + +""" +Verify provided app token. +""" +type AppTokenVerify { + """ + Determine if token is valid or not. + """ + valid: Boolean! + appErrors: [AppError!]! @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [AppError!]! +} + +""" +Enum determining type of your App. +""" +enum AppTypeEnum { + """ + Local Saleor App. The app is fully manageable from dashboard. You can change assigned permissions, add webhooks, or authentication token + """ + LOCAL + + """ + Third party external App. Installation is fully automated. Saleor uses a defined App manifest to gather all required information. + """ + THIRDPARTY +} + +""" +Updates an existing app. +""" +type AppUpdate { + appErrors: [AppError!]! @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [AppError!]! + app: App +} + +""" +An enumeration. +""" +enum AreaUnitsEnum { + SQ_CM + SQ_M + SQ_KM + SQ_FT + SQ_YD + SQ_INCH +} + +""" +Assigns storefront's navigation menus. +""" +type AssignNavigation { + """ + Assigned navigation menu. + """ + menu: Menu + menuErrors: [MenuError!]! @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [MenuError!]! +} + +""" +Custom attribute of a product. Attributes can be assigned to products and variants at the product type level. +""" +type Attribute implements Node & ObjectWithMetadata { + """ + The ID of the object. + """ + id: ID! + productTypes(before: String, after: String, first: Int, last: Int): ProductTypeCountableConnection! + productVariantTypes(before: String, after: String, first: Int, last: Int): ProductTypeCountableConnection! + + """ + List of private metadata items.Requires proper staff permissions to access. + """ + privateMetadata: [MetadataItem]! + + """ + List of public metadata items. Can be accessed without permissions. + """ + metadata: [MetadataItem]! + + """ + The input type to use for entering attribute values in the dashboard. + """ + inputType: AttributeInputTypeEnum + + """ + The entity type which can be used as a reference. + """ + entityType: AttributeEntityTypeEnum + + """ + Name of an attribute displayed in the interface. + """ + name: String + + """ + Internal representation of an attribute name. + """ + slug: String + + """ + The attribute type. + """ + type: AttributeTypeEnum + + """ + The unit of attribute values. + """ + unit: MeasurementUnitsEnum + + """ + List of attribute's values. + """ + values: [AttributeValue] + + """ + Whether the attribute requires values to be passed or not. + """ + valueRequired: Boolean! + + """ + Whether the attribute should be visible or not in storefront. + """ + visibleInStorefront: Boolean! + + """ + Whether the attribute can be filtered in storefront. + """ + filterableInStorefront: Boolean! + + """ + Whether the attribute can be filtered in dashboard. + """ + filterableInDashboard: Boolean! + + """ + Whether the attribute can be displayed in the admin product list. + """ + availableInGrid: Boolean! + + """ + Returns translated attribute fields for the given language code. + """ + translation( + """ + A language code to return the translation for attribute. + """ + languageCode: LanguageCodeEnum! + ): AttributeTranslation + + """ + The position of the attribute in the storefront navigation (0 by default). + """ + storefrontSearchPosition: Int! +} + +""" +Deletes attributes. +""" +type AttributeBulkDelete { + """ + Returns how many objects were affected. + """ + count: Int! + attributeErrors: [AttributeError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [AttributeError!]! +} + +type AttributeCountableConnection { + """ + Pagination data for this connection. + """ + pageInfo: PageInfo! + edges: [AttributeCountableEdge!]! + + """ + A total count of items in the collection. + """ + totalCount: Int +} + +type AttributeCountableEdge { + """ + The item at the end of the edge. + """ + node: Attribute! + + """ + A cursor for use in pagination. + """ + cursor: String! +} + +""" +Creates an attribute. +""" +type AttributeCreate { + attribute: Attribute + attributeErrors: [AttributeError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [AttributeError!]! +} + +input AttributeCreateInput { + """ + The input type to use for entering attribute values in the dashboard. + """ + inputType: AttributeInputTypeEnum + + """ + The entity type which can be used as a reference. + """ + entityType: AttributeEntityTypeEnum + + """ + Name of an attribute displayed in the interface. + """ + name: String! + + """ + Internal representation of an attribute name. + """ + slug: String + + """ + The attribute type. + """ + type: AttributeTypeEnum! + + """ + The unit of attribute values. + """ + unit: MeasurementUnitsEnum + + """ + List of attribute's values. + """ + values: [AttributeValueCreateInput] + + """ + Whether the attribute requires values to be passed or not. + """ + valueRequired: Boolean + + """ + Whether the attribute is for variants only. + """ + isVariantOnly: Boolean + + """ + Whether the attribute should be visible or not in storefront. + """ + visibleInStorefront: Boolean + + """ + Whether the attribute can be filtered in storefront. + """ + filterableInStorefront: Boolean + + """ + Whether the attribute can be filtered in dashboard. + """ + filterableInDashboard: Boolean + + """ + The position of the attribute in the storefront navigation (0 by default). + """ + storefrontSearchPosition: Int + + """ + Whether the attribute can be displayed in the admin product list. + """ + availableInGrid: Boolean +} + +""" +Deletes an attribute. +""" +type AttributeDelete { + attributeErrors: [AttributeError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [AttributeError!]! + attribute: Attribute +} + +""" +An enumeration. +""" +enum AttributeEntityTypeEnum { + PAGE + PRODUCT +} + +type AttributeError { + """ + Name of a field that caused the error. A value of `null` indicates that the error isn't associated with a particular field. + """ + field: String + + """ + The error message. + """ + message: String + + """ + The error code. + """ + code: AttributeErrorCode! +} + +""" +An enumeration. +""" +enum AttributeErrorCode { + ALREADY_EXISTS + GRAPHQL_ERROR + INVALID + NOT_FOUND + REQUIRED + UNIQUE +} + +input AttributeFilterInput { + valueRequired: Boolean + isVariantOnly: Boolean + visibleInStorefront: Boolean + filterableInStorefront: Boolean + filterableInDashboard: Boolean + availableInGrid: Boolean + metadata: [MetadataInput] + search: String + ids: [ID] + type: AttributeTypeEnum + inCollection: ID + inCategory: ID + + """ + Specifies the channel by which the data should be sorted. + """ + channel: String +} + +input AttributeInput { + """ + Internal representation of an attribute name. + """ + slug: String! + + """ + Internal representation of a value (unique per attribute). + """ + values: [String] + + """ + The range that the returned values should be in. + """ + valuesRange: IntRangeInput +} + +""" +An enumeration. +""" +enum AttributeInputTypeEnum { + DROPDOWN + MULTISELECT + FILE + REFERENCE + NUMERIC + RICH_TEXT +} + +""" +Reorder the values of an attribute. +""" +type AttributeReorderValues { + """ + Attribute from which values are reordered. + """ + attribute: Attribute + attributeErrors: [AttributeError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [AttributeError!]! +} + +enum AttributeSortField { + """ + Sort attributes by name + """ + NAME + + """ + Sort attributes by slug + """ + SLUG + + """ + Sort attributes by the value required flag + """ + VALUE_REQUIRED + + """ + Sort attributes by the variant only flag + """ + IS_VARIANT_ONLY + + """ + Sort attributes by visibility in the storefront + """ + VISIBLE_IN_STOREFRONT + + """ + Sort attributes by the filterable in storefront flag + """ + FILTERABLE_IN_STOREFRONT + + """ + Sort attributes by the filterable in dashboard flag + """ + FILTERABLE_IN_DASHBOARD + + """ + Sort attributes by their position in storefront + """ + STOREFRONT_SEARCH_POSITION + + """ + Sort attributes based on whether they can be displayed or not in a product grid. + """ + AVAILABLE_IN_GRID +} + +input AttributeSortingInput { + """ + Specifies the direction in which to sort products. + """ + direction: OrderDirection! + + """ + Sort attributes by the selected field. + """ + field: AttributeSortField! +} + +type AttributeTranslatableContent implements Node { + """ + The ID of the object. + """ + id: ID! + name: String! + + """ + Returns translated attribute fields for the given language code. + """ + translation( + """ + A language code to return the translation for attribute. + """ + languageCode: LanguageCodeEnum! + ): AttributeTranslation + + """ + Custom attribute of a product. + """ + attribute: Attribute +} + +""" +Creates/Updates translations for attribute. +""" +type AttributeTranslate { + translationErrors: [TranslationError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [TranslationError!]! + attribute: Attribute +} + +type AttributeTranslation implements Node { + """ + The ID of the object. + """ + id: ID! + name: String! + + """ + Translation language. + """ + language: LanguageDisplay! +} + +""" +An enumeration. +""" +enum AttributeTypeEnum { + PRODUCT_TYPE + PAGE_TYPE +} + +""" +Updates attribute. +""" +type AttributeUpdate { + attribute: Attribute + attributeErrors: [AttributeError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [AttributeError!]! +} + +input AttributeUpdateInput { + """ + Name of an attribute displayed in the interface. + """ + name: String + + """ + Internal representation of an attribute name. + """ + slug: String + + """ + The unit of attribute values. + """ + unit: MeasurementUnitsEnum + + """ + IDs of values to be removed from this attribute. + """ + removeValues: [ID] + + """ + New values to be created for this attribute. + """ + addValues: [AttributeValueCreateInput] + + """ + Whether the attribute requires values to be passed or not. + """ + valueRequired: Boolean + + """ + Whether the attribute is for variants only. + """ + isVariantOnly: Boolean + + """ + Whether the attribute should be visible or not in storefront. + """ + visibleInStorefront: Boolean + + """ + Whether the attribute can be filtered in storefront. + """ + filterableInStorefront: Boolean + + """ + Whether the attribute can be filtered in dashboard. + """ + filterableInDashboard: Boolean + + """ + The position of the attribute in the storefront navigation (0 by default). + """ + storefrontSearchPosition: Int + + """ + Whether the attribute can be displayed in the admin product list. + """ + availableInGrid: Boolean +} + +""" +Represents a value of an attribute. +""" +type AttributeValue implements Node { + """ + The ID of the object. + """ + id: ID! + + """ + Name of a value displayed in the interface. + """ + name: String + + """ + Internal representation of a value (unique per attribute). + """ + slug: String + + """ + Represents the value of the attribute value. + """ + value: String + + """ + Returns translated attribute value fields for the given language code. + """ + translation( + """ + A language code to return the translation for attribute value. + """ + languageCode: LanguageCodeEnum! + ): AttributeValueTranslation + + """ + The input type to use for entering attribute values in the dashboard. + """ + inputType: AttributeInputTypeEnum + + """ + The ID of the attribute reference. + """ + reference: ID + + """ + Represents file URL and content type (if attribute value is a file). + """ + file: File + + """ + Represents the text (JSON) of the attribute value. + """ + richText: JSONString +} + +""" +Deletes values of attributes. +""" +type AttributeValueBulkDelete { + """ + Returns how many objects were affected. + """ + count: Int! + attributeErrors: [AttributeError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [AttributeError!]! +} + +""" +Creates a value for an attribute. +""" +type AttributeValueCreate { + """ + The updated attribute. + """ + attribute: Attribute + attributeErrors: [AttributeError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [AttributeError!]! + attributeValue: AttributeValue +} + +input AttributeValueCreateInput { + """ + Name of a value displayed in the interface. + """ + name: String! + + """ + Represents the value of the attribute value. + """ + value: String + + """ + Represents the text (JSON) of the attribute value. + """ + richText: JSONString +} + +""" +Deletes a value of an attribute. +""" +type AttributeValueDelete { + """ + The updated attribute. + """ + attribute: Attribute + attributeErrors: [AttributeError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [AttributeError!]! + attributeValue: AttributeValue +} + +input AttributeValueInput { + """ + ID of the selected attribute. + """ + id: ID + + """ + The value or slug of an attribute to resolve. If the passed value is non-existent, it will be created. + """ + values: [String] + + """ + URL of the file attribute. Every time, a new value is created. + """ + file: String + + """ + File content type. + """ + contentType: String + + """ + List of entity IDs that will be used as references. + """ + references: [ID!] + + """ + Text content in JSON format. + """ + richText: JSONString +} + +type AttributeValueTranslatableContent implements Node { + """ + The ID of the object. + """ + id: ID! + name: String! + + """ + Returns translated attribute value fields for the given language code. + """ + translation( + """ + A language code to return the translation for attribute value. + """ + languageCode: LanguageCodeEnum! + ): AttributeValueTranslation + + """ + Represents a value of an attribute. + """ + attributeValue: AttributeValue +} + +""" +Creates/Updates translations for attribute value. +""" +type AttributeValueTranslate { + translationErrors: [TranslationError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [TranslationError!]! + attributeValue: AttributeValue +} + +type AttributeValueTranslation implements Node { + """ + The ID of the object. + """ + id: ID! + name: String! + richText: JSONString + + """ + Translation language. + """ + language: LanguageDisplay! +} + +input AttributeValueTranslationInput { + name: String + richText: JSONString +} + +""" +Updates value of an attribute. +""" +type AttributeValueUpdate { + """ + The updated attribute. + """ + attribute: Attribute + attributeErrors: [AttributeError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [AttributeError!]! + attributeValue: AttributeValue +} + +input BulkAttributeValueInput { + """ + ID of the selected attribute. + """ + id: ID + + """ + The value or slug of an attribute to resolve. If the passed value is non-existent, it will be created. + """ + values: [String]! +} + +type BulkProductError { + """ + Name of a field that caused the error. A value of `null` indicates that the error isn't associated with a particular field. + """ + field: String + + """ + The error message. + """ + message: String + + """ + The error code. + """ + code: ProductErrorCode! + + """ + List of attributes IDs which causes the error. + """ + attributes: [ID!] + + """ + List of attribute values IDs which causes the error. + """ + values: [ID!] + + """ + Index of an input list item that caused the error. + """ + index: Int + + """ + List of warehouse IDs which causes the error. + """ + warehouses: [ID!] + + """ + List of channel IDs which causes the error. + """ + channels: [ID!] +} + +type BulkStockError { + """ + Name of a field that caused the error. A value of `null` indicates that the error isn't associated with a particular field. + """ + field: String + + """ + The error message. + """ + message: String + + """ + The error code. + """ + code: ProductErrorCode! + + """ + List of attributes IDs which causes the error. + """ + attributes: [ID!] + + """ + List of attribute values IDs which causes the error. + """ + values: [ID!] + + """ + Index of an input list item that caused the error. + """ + index: Int +} + +input CatalogueInput { + """ + Products related to the discount. + """ + products: [ID] + + """ + Categories related to the discount. + """ + categories: [ID] + + """ + Collections related to the discount. + """ + collections: [ID] +} + +""" +Represents a single category of products. Categories allow to organize products in a tree-hierarchies which can be used for navigation in the storefront. +""" +type Category implements Node & ObjectWithMetadata { + """ + The ID of the object. + """ + id: ID! + seoTitle: String + seoDescription: String + name: String! + description: JSONString + slug: String! + parent: Category + level: Int! + + """ + List of private metadata items.Requires proper staff permissions to access. + """ + privateMetadata: [MetadataItem]! + + """ + List of public metadata items. Can be accessed without permissions. + """ + metadata: [MetadataItem]! + + """ + Description of the category (JSON). + """ + descriptionJson: JSONString @deprecated(reason: "Will be removed in Saleor 4.0. Use the `description` field instead.") + + """ + List of ancestors of the category. + """ + ancestors( + """ + Return the elements in the list that come before the specified cursor. + """ + before: String + + """ + Return the elements in the list that come after the specified cursor. + """ + after: String + + """ + Return the first n elements from the list. + """ + first: Int + + """ + Return the last n elements from the list. + """ + last: Int + ): CategoryCountableConnection + + """ + List of products in the category. + """ + products( + """ + Slug of a channel for which the data should be returned. + """ + channel: String + + """ + Return the elements in the list that come before the specified cursor. + """ + before: String + + """ + Return the elements in the list that come after the specified cursor. + """ + after: String + + """ + Return the first n elements from the list. + """ + first: Int + + """ + Return the last n elements from the list. + """ + last: Int + ): ProductCountableConnection + + """ + List of children of the category. + """ + children( + """ + Return the elements in the list that come before the specified cursor. + """ + before: String + + """ + Return the elements in the list that come after the specified cursor. + """ + after: String + + """ + Return the first n elements from the list. + """ + first: Int + + """ + Return the last n elements from the list. + """ + last: Int + ): CategoryCountableConnection + backgroundImage( + """ + Size of the image. + """ + size: Int + ): Image + + """ + Returns translated category fields for the given language code. + """ + translation( + """ + A language code to return the translation for category. + """ + languageCode: LanguageCodeEnum! + ): CategoryTranslation +} + +""" +Deletes categories. +""" +type CategoryBulkDelete { + """ + Returns how many objects were affected. + """ + count: Int! + productErrors: [ProductError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [ProductError!]! +} + +type CategoryCountableConnection { + """ + Pagination data for this connection. + """ + pageInfo: PageInfo! + edges: [CategoryCountableEdge!]! + + """ + A total count of items in the collection. + """ + totalCount: Int +} + +type CategoryCountableEdge { + """ + The item at the end of the edge. + """ + node: Category! + + """ + A cursor for use in pagination. + """ + cursor: String! +} + +""" +Creates a new category. +""" +type CategoryCreate { + productErrors: [ProductError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [ProductError!]! + category: Category +} + +""" +Deletes a category. +""" +type CategoryDelete { + productErrors: [ProductError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [ProductError!]! + category: Category +} + +input CategoryFilterInput { + search: String + metadata: [MetadataInput] + ids: [ID] +} + +input CategoryInput { + """ + Category description (JSON). + """ + description: JSONString + + """ + Category name. + """ + name: String + + """ + Category slug. + """ + slug: String + + """ + Search engine optimization fields. + """ + seo: SeoInput + + """ + Background image file. + """ + backgroundImage: Upload + + """ + Alt text for a product media. + """ + backgroundImageAlt: String +} + +enum CategorySortField { + """ + Sort categories by name. + """ + NAME + + """ + Sort categories by product count. + """ + PRODUCT_COUNT + + """ + Sort categories by subcategory count. + """ + SUBCATEGORY_COUNT +} + +input CategorySortingInput { + """ + Specifies the direction in which to sort products. + """ + direction: OrderDirection! + + """ + Specifies the channel in which to sort the data. + """ + channel: String + + """ + Sort categories by the selected field. + """ + field: CategorySortField! +} + +type CategoryTranslatableContent implements Node { + """ + The ID of the object. + """ + id: ID! + seoTitle: String + seoDescription: String + name: String! + description: JSONString + + """ + Description of the category (JSON). + """ + descriptionJson: JSONString @deprecated(reason: "Will be removed in Saleor 4.0. Use the `description` field instead.") + + """ + Returns translated category fields for the given language code. + """ + translation( + """ + A language code to return the translation for category. + """ + languageCode: LanguageCodeEnum! + ): CategoryTranslation + + """ + Represents a single category of products. + """ + category: Category +} + +""" +Creates/Updates translations for Category. +""" +type CategoryTranslate { + translationErrors: [TranslationError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [TranslationError!]! + category: Category +} + +type CategoryTranslation implements Node { + """ + The ID of the object. + """ + id: ID! + seoTitle: String + seoDescription: String + name: String! + description: JSONString + + """ + Translation language. + """ + language: LanguageDisplay! + + """ + Translated description of the product (JSON). + """ + descriptionJson: JSONString @deprecated(reason: "Will be removed in Saleor 4.0. Use the `description` field instead.") +} + +""" +Updates a category. +""" +type CategoryUpdate { + productErrors: [ProductError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [ProductError!]! + category: Category +} + +""" +Represents channel. +""" +type Channel implements Node { + """ + The ID of the object. + """ + id: ID! + name: String! + isActive: Boolean! + slug: String! + currencyCode: String! + + """ + Whether a channel has associated orders. + """ + hasOrders: Boolean! +} + +""" +Activate a channel. +""" +type ChannelActivate { + """ + Activated channel. + """ + channel: Channel + channelErrors: [ChannelError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [ChannelError!]! +} + +""" +Creates new channel. +""" +type ChannelCreate { + channelErrors: [ChannelError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [ChannelError!]! + channel: Channel +} + +input ChannelCreateInput { + """ + isActive flag. + """ + isActive: Boolean + + """ + Name of the channel. + """ + name: String! + + """ + Slug of the channel. + """ + slug: String! + + """ + Currency of the channel. + """ + currencyCode: String! + + """ + List of shipping zones to assign to the channel. + """ + addShippingZones: [ID!] +} + +""" +Deactivate a channel. +""" +type ChannelDeactivate { + """ + Deactivated channel. + """ + channel: Channel + channelErrors: [ChannelError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [ChannelError!]! +} + +""" +Delete a channel. Orders associated with the deleted channel will be moved to the target channel. Checkouts, product availability, and pricing will be removed. +""" +type ChannelDelete { + channelErrors: [ChannelError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [ChannelError!]! + channel: Channel +} + +input ChannelDeleteInput { + """ + ID of channel to migrate orders from origin channel. + """ + targetChannel: ID! +} + +type ChannelError { + """ + Name of a field that caused the error. A value of `null` indicates that the error isn't associated with a particular field. + """ + field: String + + """ + The error message. + """ + message: String + + """ + The error code. + """ + code: ChannelErrorCode! + + """ + List of shipping zone IDs which causes the error. + """ + shippingZones: [ID!] +} + +""" +An enumeration. +""" +enum ChannelErrorCode { + ALREADY_EXISTS + GRAPHQL_ERROR + INVALID + NOT_FOUND + REQUIRED + UNIQUE + CHANNEL_TARGET_ID_MUST_BE_DIFFERENT + CHANNELS_CURRENCY_MUST_BE_THE_SAME + CHANNEL_WITH_ORDERS + DUPLICATED_INPUT_ITEM +} + +""" +Update a channel. +""" +type ChannelUpdate { + channelErrors: [ChannelError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [ChannelError!]! + channel: Channel +} + +input ChannelUpdateInput { + """ + isActive flag. + """ + isActive: Boolean + + """ + Name of the channel. + """ + name: String + + """ + Slug of the channel. + """ + slug: String + + """ + List of shipping zones to assign to the channel. + """ + addShippingZones: [ID!] + + """ + List of shipping zones to unassign from the channel. + """ + removeShippingZones: [ID!] +} + +""" +Checkout object. +""" +type Checkout implements Node & ObjectWithMetadata { + created: DateTime! + lastChange: DateTime! + user: User + channel: Channel! + billingAddress: Address + shippingAddress: Address + note: String! + discount: Money + discountName: String + translatedDiscountName: String + voucherCode: String + + """ + List of gift cards associated with this checkout. + """ + giftCards: [GiftCard] + + """ + The ID of the object. + """ + id: ID! + + """ + List of private metadata items.Requires proper staff permissions to access. + """ + privateMetadata: [MetadataItem]! + + """ + List of public metadata items. Can be accessed without permissions. + """ + metadata: [MetadataItem]! + + """ + Shipping methods that can be used with this order. + """ + availableShippingMethods: [ShippingMethod]! + + """ + List of available payment gateways. + """ + availablePaymentGateways: [PaymentGateway!]! + + """ + Email of a customer. + """ + email: String! + + """ + Returns True, if checkout requires shipping. + """ + isShippingRequired: Boolean! + + """ + The number of items purchased. + """ + quantity: Int! + + """ + A list of checkout lines, each containing information about an item in the checkout. + """ + lines: [CheckoutLine] + + """ + The price of the shipping, with all the taxes included. + """ + shippingPrice: TaxedMoney + + """ + The shipping method related with checkout. + """ + shippingMethod: ShippingMethod + + """ + The price of the checkout before shipping, with taxes included. + """ + subtotalPrice: TaxedMoney + + """ + The checkout's token. + """ + token: UUID! + + """ + The sum of the the checkout line prices, with all the taxes,shipping costs, and discounts included. + """ + totalPrice: TaxedMoney + + """ + Checkout language code. + """ + languageCode: LanguageCodeEnum! +} + +""" +Adds a gift card or a voucher to a checkout. +""" +type CheckoutAddPromoCode { + """ + The checkout with the added gift card or voucher. + """ + checkout: Checkout + checkoutErrors: [CheckoutError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [CheckoutError!]! +} + +""" +Update billing address in the existing checkout. +""" +type CheckoutBillingAddressUpdate { + """ + An updated checkout. + """ + checkout: Checkout + checkoutErrors: [CheckoutError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [CheckoutError!]! +} + +""" +Completes the checkout. As a result a new order is created and a payment charge is made. This action requires a successful payment before it can be performed. In case additional confirmation step as 3D secure is required confirmationNeeded flag will be set to True and no order created until payment is confirmed with second call of this mutation. +""" +type CheckoutComplete { + """ + Placed order. + """ + order: Order + + """ + Set to true if payment needs to be confirmed before checkout is complete. + """ + confirmationNeeded: Boolean! + + """ + Confirmation data used to process additional authorization steps. + """ + confirmationData: JSONString + checkoutErrors: [CheckoutError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [CheckoutError!]! +} + +type CheckoutCountableConnection { + """ + Pagination data for this connection. + """ + pageInfo: PageInfo! + edges: [CheckoutCountableEdge!]! + + """ + A total count of items in the collection. + """ + totalCount: Int +} + +type CheckoutCountableEdge { + """ + The item at the end of the edge. + """ + node: Checkout! + + """ + A cursor for use in pagination. + """ + cursor: String! +} + +""" +Create a new checkout. +""" +type CheckoutCreate { + """ + Whether the checkout was created or the current active one was returned. Refer to checkoutLinesAdd and checkoutLinesUpdate to merge a cart with an active checkout.DEPRECATED: Will be removed in Saleor 4.0. Always returns True. + """ + created: Boolean + checkoutErrors: [CheckoutError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [CheckoutError!]! + checkout: Checkout +} + +input CheckoutCreateInput { + """ + Slug of a channel in which to create a checkout. + """ + channel: String + + """ + A list of checkout lines, each containing information about an item in the checkout. + """ + lines: [CheckoutLineInput]! + + """ + The customer's email address. + """ + email: String + + """ + The mailing address to where the checkout will be shipped. Note: the address will be ignored if the checkout doesn't contain shippable items. + """ + shippingAddress: AddressInput + + """ + Billing address of the customer. + """ + billingAddress: AddressInput + + """ + Checkout language code. + """ + languageCode: LanguageCodeEnum +} + +""" +Sets the customer as the owner of the checkout. +""" +type CheckoutCustomerAttach { + """ + An updated checkout. + """ + checkout: Checkout + checkoutErrors: [CheckoutError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [CheckoutError!]! +} + +""" +Removes the user assigned as the owner of the checkout. +""" +type CheckoutCustomerDetach { + """ + An updated checkout. + """ + checkout: Checkout + checkoutErrors: [CheckoutError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [CheckoutError!]! +} + +""" +Updates email address in the existing checkout object. +""" +type CheckoutEmailUpdate { + """ + An updated checkout. + """ + checkout: Checkout + checkoutErrors: [CheckoutError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [CheckoutError!]! +} + +type CheckoutError { + """ + Name of a field that caused the error. A value of `null` indicates that the error isn't associated with a particular field. + """ + field: String + + """ + The error message. + """ + message: String + + """ + The error code. + """ + code: CheckoutErrorCode! + + """ + List of varint IDs which causes the error. + """ + variants: [ID!] + + """ + A type of address that causes the error. + """ + addressType: AddressTypeEnum +} + +""" +An enumeration. +""" +enum CheckoutErrorCode { + BILLING_ADDRESS_NOT_SET + CHECKOUT_NOT_FULLY_PAID + GRAPHQL_ERROR + PRODUCT_NOT_PUBLISHED + PRODUCT_UNAVAILABLE_FOR_PURCHASE + INSUFFICIENT_STOCK + INVALID + INVALID_SHIPPING_METHOD + NOT_FOUND + PAYMENT_ERROR + QUANTITY_GREATER_THAN_LIMIT + REQUIRED + SHIPPING_ADDRESS_NOT_SET + SHIPPING_METHOD_NOT_APPLICABLE + SHIPPING_METHOD_NOT_SET + SHIPPING_NOT_REQUIRED + TAX_ERROR + UNIQUE + VOUCHER_NOT_APPLICABLE + ZERO_QUANTITY + MISSING_CHANNEL_SLUG + CHANNEL_INACTIVE + UNAVAILABLE_VARIANT_IN_CHANNEL +} + +""" +Update language code in the existing checkout. +""" +type CheckoutLanguageCodeUpdate { + """ + An updated checkout. + """ + checkout: Checkout + checkoutErrors: [CheckoutError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [CheckoutError!]! +} + +""" +Represents an item in the checkout. +""" +type CheckoutLine implements Node { + """ + The ID of the object. + """ + id: ID! + variant: ProductVariant! + quantity: Int! + + """ + The sum of the checkout line price, taxes and discounts. + """ + totalPrice: TaxedMoney + + """ + Indicates whether the item need to be delivered. + """ + requiresShipping: Boolean +} + +type CheckoutLineCountableConnection { + """ + Pagination data for this connection. + """ + pageInfo: PageInfo! + edges: [CheckoutLineCountableEdge!]! + + """ + A total count of items in the collection. + """ + totalCount: Int +} + +type CheckoutLineCountableEdge { + """ + The item at the end of the edge. + """ + node: CheckoutLine! + + """ + A cursor for use in pagination. + """ + cursor: String! +} + +""" +Deletes a CheckoutLine. +""" +type CheckoutLineDelete { + """ + An updated checkout. + """ + checkout: Checkout + checkoutErrors: [CheckoutError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [CheckoutError!]! +} + +input CheckoutLineInput { + """ + The number of items purchased. + """ + quantity: Int! + + """ + ID of the product variant. + """ + variantId: ID! +} + +""" +Adds a checkout line to the existing checkout. +""" +type CheckoutLinesAdd { + """ + An updated checkout. + """ + checkout: Checkout + checkoutErrors: [CheckoutError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [CheckoutError!]! +} + +""" +Updates checkout line in the existing checkout. +""" +type CheckoutLinesUpdate { + """ + An updated checkout. + """ + checkout: Checkout + checkoutErrors: [CheckoutError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [CheckoutError!]! +} + +""" +Create a new payment for given checkout. +""" +type CheckoutPaymentCreate { + """ + Related checkout object. + """ + checkout: Checkout + + """ + A newly created payment. + """ + payment: Payment + paymentErrors: [PaymentError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [PaymentError!]! +} + +""" +Remove a gift card or a voucher from a checkout. +""" +type CheckoutRemovePromoCode { + """ + The checkout with the removed gift card or voucher. + """ + checkout: Checkout + checkoutErrors: [CheckoutError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [CheckoutError!]! +} + +""" +Update shipping address in the existing checkout. +""" +type CheckoutShippingAddressUpdate { + """ + An updated checkout. + """ + checkout: Checkout + checkoutErrors: [CheckoutError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [CheckoutError!]! +} + +""" +Updates the shipping address of the checkout. +""" +type CheckoutShippingMethodUpdate { + """ + An updated checkout. + """ + checkout: Checkout + checkoutErrors: [CheckoutError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [CheckoutError!]! +} + +type ChoiceValue { + raw: String + verbose: String +} + +""" +Represents a collection of products. +""" +type Collection implements Node & ObjectWithMetadata { + """ + The ID of the object. + """ + id: ID! + seoTitle: String + seoDescription: String + name: String! + description: JSONString + slug: String! + + """ + List of private metadata items.Requires proper staff permissions to access. + """ + privateMetadata: [MetadataItem]! + + """ + List of public metadata items. Can be accessed without permissions. + """ + metadata: [MetadataItem]! + + """ + Description of the collection (JSON). + """ + descriptionJson: JSONString @deprecated(reason: "Will be removed in Saleor 4.0. Use the `description` field instead.") + + """ + List of products in this collection. + """ + products( + """ + Filtering options for products. + """ + filter: ProductFilterInput + + """ + Sort products. + """ + sortBy: ProductOrder + + """ + Return the elements in the list that come before the specified cursor. + """ + before: String + + """ + Return the elements in the list that come after the specified cursor. + """ + after: String + + """ + Return the first n elements from the list. + """ + first: Int + + """ + Return the last n elements from the list. + """ + last: Int + ): ProductCountableConnection + backgroundImage( + """ + Size of the image. + """ + size: Int + ): Image + + """ + Returns translated collection fields for the given language code. + """ + translation( + """ + A language code to return the translation for collection. + """ + languageCode: LanguageCodeEnum! + ): CollectionTranslation + + """ + List of channels in which the collection is available. + """ + channelListings: [CollectionChannelListing!] +} + +""" +Adds products to a collection. +""" +type CollectionAddProducts { + """ + Collection to which products will be added. + """ + collection: Collection + collectionErrors: [CollectionError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [CollectionError!]! +} + +""" +Deletes collections. +""" +type CollectionBulkDelete { + """ + Returns how many objects were affected. + """ + count: Int! + collectionErrors: [CollectionError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [CollectionError!]! +} + +""" +Represents collection channel listing. +""" +type CollectionChannelListing implements Node { + """ + The ID of the object. + """ + id: ID! + publicationDate: Date + isPublished: Boolean! + channel: Channel! +} + +type CollectionChannelListingError { + """ + Name of a field that caused the error. A value of `null` indicates that the error isn't associated with a particular field. + """ + field: String + + """ + The error message. + """ + message: String + + """ + The error code. + """ + code: ProductErrorCode! + + """ + List of attributes IDs which causes the error. + """ + attributes: [ID!] + + """ + List of attribute values IDs which causes the error. + """ + values: [ID!] + + """ + List of channels IDs which causes the error. + """ + channels: [ID!] +} + +""" +Manage collection's availability in channels. +""" +type CollectionChannelListingUpdate { + """ + An updated collection instance. + """ + collection: Collection + collectionChannelListingErrors: [CollectionChannelListingError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [CollectionChannelListingError!]! +} + +input CollectionChannelListingUpdateInput { + """ + List of channels to which the collection should be assigned. + """ + addChannels: [PublishableChannelListingInput!] + + """ + List of channels from which the collection should be unassigned. + """ + removeChannels: [ID!] +} + +type CollectionCountableConnection { + """ + Pagination data for this connection. + """ + pageInfo: PageInfo! + edges: [CollectionCountableEdge!]! + + """ + A total count of items in the collection. + """ + totalCount: Int +} + +type CollectionCountableEdge { + """ + The item at the end of the edge. + """ + node: Collection! + + """ + A cursor for use in pagination. + """ + cursor: String! +} + +""" +Creates a new collection. +""" +type CollectionCreate { + collectionErrors: [CollectionError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [CollectionError!]! + collection: Collection +} + +input CollectionCreateInput { + """ + Informs whether a collection is published. + """ + isPublished: Boolean + + """ + Name of the collection. + """ + name: String + + """ + Slug of the collection. + """ + slug: String + + """ + Description of the collection (JSON). + """ + description: JSONString + + """ + Background image file. + """ + backgroundImage: Upload + + """ + Alt text for an image. + """ + backgroundImageAlt: String + + """ + Search engine optimization fields. + """ + seo: SeoInput + + """ + Publication date. ISO 8601 standard. + """ + publicationDate: Date + + """ + List of products to be added to the collection. + """ + products: [ID] +} + +""" +Deletes a collection. +""" +type CollectionDelete { + collectionErrors: [CollectionError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [CollectionError!]! + collection: Collection +} + +type CollectionError { + """ + Name of a field that caused the error. A value of `null` indicates that the error isn't associated with a particular field. + """ + field: String + + """ + The error message. + """ + message: String + + """ + List of products IDs which causes the error. + """ + products: [ID!] + + """ + The error code. + """ + code: CollectionErrorCode! +} + +""" +An enumeration. +""" +enum CollectionErrorCode { + DUPLICATED_INPUT_ITEM + GRAPHQL_ERROR + INVALID + NOT_FOUND + REQUIRED + UNIQUE + CANNOT_MANAGE_PRODUCT_WITHOUT_VARIANT +} + +input CollectionFilterInput { + published: CollectionPublished + search: String + metadata: [MetadataInput] + ids: [ID] + + """ + Specifies the channel by which the data should be sorted. + """ + channel: String +} + +input CollectionInput { + """ + Informs whether a collection is published. + """ + isPublished: Boolean + + """ + Name of the collection. + """ + name: String + + """ + Slug of the collection. + """ + slug: String + + """ + Description of the collection (JSON). + """ + description: JSONString + + """ + Background image file. + """ + backgroundImage: Upload + + """ + Alt text for an image. + """ + backgroundImageAlt: String + + """ + Search engine optimization fields. + """ + seo: SeoInput + + """ + Publication date. ISO 8601 standard. + """ + publicationDate: Date +} + +enum CollectionPublished { + PUBLISHED + HIDDEN +} + +""" +Remove products from a collection. +""" +type CollectionRemoveProducts { + """ + Collection from which products will be removed. + """ + collection: Collection + collectionErrors: [CollectionError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [CollectionError!]! +} + +""" +Reorder the products of a collection. +""" +type CollectionReorderProducts { + """ + Collection from which products are reordered. + """ + collection: Collection + collectionErrors: [CollectionError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [CollectionError!]! +} + +enum CollectionSortField { + """ + Sort collections by name. + """ + NAME + + """ + Sort collections by availability. + """ + AVAILABILITY + + """ + Sort collections by product count. + """ + PRODUCT_COUNT + + """ + Sort collections by publication date. + """ + PUBLICATION_DATE +} + +input CollectionSortingInput { + """ + Specifies the direction in which to sort products. + """ + direction: OrderDirection! + + """ + Specifies the channel in which to sort the data. + """ + channel: String + + """ + Sort collections by the selected field. + """ + field: CollectionSortField! +} + +type CollectionTranslatableContent implements Node { + """ + The ID of the object. + """ + id: ID! + seoTitle: String + seoDescription: String + name: String! + description: JSONString + + """ + Description of the collection (JSON). + """ + descriptionJson: JSONString @deprecated(reason: "Will be removed in Saleor 4.0. Use the `description` field instead.") + + """ + Returns translated collection fields for the given language code. + """ + translation( + """ + A language code to return the translation for collection. + """ + languageCode: LanguageCodeEnum! + ): CollectionTranslation + + """ + Represents a collection of products. + """ + collection: Collection +} + +""" +Creates/Updates translations for collection. +""" +type CollectionTranslate { + translationErrors: [TranslationError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [TranslationError!]! + collection: Collection +} + +type CollectionTranslation implements Node { + """ + The ID of the object. + """ + id: ID! + seoTitle: String + seoDescription: String + name: String! + description: JSONString + + """ + Translation language. + """ + language: LanguageDisplay! + + """ + Translated description of the product (JSON). + """ + descriptionJson: JSONString @deprecated(reason: "Will be removed in Saleor 4.0. Use the `description` field instead.") +} + +""" +Updates a collection. +""" +type CollectionUpdate { + collectionErrors: [CollectionError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [CollectionError!]! + collection: Collection +} + +""" +Stores information about a single configuration field. +""" +type ConfigurationItem { + """ + Name of the field. + """ + name: String! + + """ + Current value of the field. + """ + value: String + + """ + Type of the field. + """ + type: ConfigurationTypeFieldEnum + + """ + Help text for the field. + """ + helpText: String + + """ + Label for the field. + """ + label: String +} + +input ConfigurationItemInput { + """ + Name of the field to update. + """ + name: String! + + """ + Value of the given field to update. + """ + value: String +} + +""" +An enumeration. +""" +enum ConfigurationTypeFieldEnum { + STRING + MULTILINE + BOOLEAN + SECRET + PASSWORD + SECRETMULTILINE + OUTPUT +} + +""" +Confirm user account with token sent by email during registration. +""" +type ConfirmAccount { + """ + An activated user account. + """ + user: User + accountErrors: [AccountError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [AccountError!]! +} + +""" +Confirm the email change of the logged-in user. +""" +type ConfirmEmailChange { + """ + A user instance with a new email. + """ + user: User + accountErrors: [AccountError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [AccountError!]! +} + +""" +An enumeration. +""" +enum CountryCode { + AF + AX + AL + DZ + AS + AD + AO + AI + AQ + AG + AR + AM + AW + AU + AT + AZ + BS + BH + BD + BB + BY + BE + BZ + BJ + BM + BT + BO + BQ + BA + BW + BV + BR + IO + BN + BG + BF + BI + CV + KH + CM + CA + KY + CF + TD + CL + CN + CX + CC + CO + KM + CG + CD + CK + CR + CI + HR + CU + CW + CY + CZ + DK + DJ + DM + DO + EC + EG + SV + GQ + ER + EE + SZ + ET + EU + FK + FO + FJ + FI + FR + GF + PF + TF + GA + GM + GE + DE + GH + GI + GR + GL + GD + GP + GU + GT + GG + GN + GW + GY + HT + HM + VA + HN + HK + HU + IS + IN + ID + IR + IQ + IE + IM + IL + IT + JM + JP + JE + JO + KZ + KE + KI + KW + KG + LA + LV + LB + LS + LR + LY + LI + LT + LU + MO + MG + MW + MY + MV + ML + MT + MH + MQ + MR + MU + YT + MX + FM + MD + MC + MN + ME + MS + MA + MZ + MM + NA + NR + NP + NL + NC + NZ + NI + NE + NG + NU + NF + KP + MK + MP + NO + OM + PK + PW + PS + PA + PG + PY + PE + PH + PN + PL + PT + PR + QA + RE + RO + RU + RW + BL + SH + KN + LC + MF + PM + VC + WS + SM + ST + SA + SN + RS + SC + SL + SG + SX + SK + SI + SB + SO + ZA + GS + KR + SS + ES + LK + SD + SR + SJ + SE + CH + SY + TW + TJ + TZ + TH + TL + TG + TK + TO + TT + TN + TR + TM + TC + TV + UG + UA + AE + GB + UM + US + UY + UZ + VU + VE + VN + VG + VI + WF + EH + YE + ZM + ZW +} + +type CountryDisplay { + """ + Country code. + """ + code: String! + + """ + Country name. + """ + country: String! + + """ + Country tax. + """ + vat: VAT +} + +""" +Create JWT token. +""" +type CreateToken { + """ + JWT token, required to authenticate. + """ + token: String + + """ + JWT refresh token, required to re-generate access token. + """ + refreshToken: String + + """ + CSRF token required to re-generate access token. + """ + csrfToken: String + + """ + A user instance. + """ + user: User + accountErrors: [AccountError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [AccountError!]! +} + +type CreditCard { + """ + Card brand. + """ + brand: String! + + """ + First 4 digits of the card number. + """ + firstDigits: String + + """ + Last 4 digits of the card number. + """ + lastDigits: String! + + """ + Two-digit number representing the card’s expiration month. + """ + expMonth: Int + + """ + Four-digit number representing the card’s expiration year. + """ + expYear: Int +} + +""" +Deletes customers. +""" +type CustomerBulkDelete { + """ + Returns how many objects were affected. + """ + count: Int! + accountErrors: [AccountError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [AccountError!]! +} + +""" +Creates a new customer. +""" +type CustomerCreate { + accountErrors: [AccountError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [AccountError!]! + user: User +} + +""" +Deletes a customer. +""" +type CustomerDelete { + accountErrors: [AccountError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [AccountError!]! + user: User +} + +""" +History log of the customer. +""" +type CustomerEvent implements Node { + """ + The ID of the object. + """ + id: ID! + + """ + Date when event happened at in ISO 8601 format. + """ + date: DateTime + + """ + Customer event type. + """ + type: CustomerEventsEnum + + """ + User who performed the action. + """ + user: User + + """ + Content of the event. + """ + message: String + + """ + Number of objects concerned by the event. + """ + count: Int + + """ + The concerned order. + """ + order: Order + + """ + The concerned order line. + """ + orderLine: OrderLine +} + +""" +An enumeration. +""" +enum CustomerEventsEnum { + ACCOUNT_CREATED + PASSWORD_RESET_LINK_SENT + PASSWORD_RESET + EMAIL_CHANGED_REQUEST + PASSWORD_CHANGED + EMAIL_CHANGED + PLACED_ORDER + NOTE_ADDED_TO_ORDER + DIGITAL_LINK_DOWNLOADED + CUSTOMER_DELETED + NAME_ASSIGNED + EMAIL_ASSIGNED + NOTE_ADDED +} + +input CustomerFilterInput { + dateJoined: DateRangeInput + numberOfOrders: IntRangeInput + placedOrders: DateRangeInput + search: String +} + +input CustomerInput { + """ + Billing address of the customer. + """ + defaultBillingAddress: AddressInput + + """ + Shipping address of the customer. + """ + defaultShippingAddress: AddressInput + + """ + Given name. + """ + firstName: String + + """ + Family name. + """ + lastName: String + + """ + The unique email address of the user. + """ + email: String + + """ + User account is active. + """ + isActive: Boolean + + """ + A note about the user. + """ + note: String + + """ + User language code. + """ + languageCode: LanguageCodeEnum +} + +""" +Updates an existing customer. +""" +type CustomerUpdate { + accountErrors: [AccountError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [AccountError!]! + user: User +} + +""" +The `Date` scalar type represents a Date +value as specified by +[iso8601](https://en.wikipedia.org/wiki/ISO_8601). +""" +scalar Date + +input DateRangeInput { + """ + Start date. + """ + gte: Date + + """ + End date. + """ + lte: Date +} + +""" +The `DateTime` scalar type represents a DateTime +value as specified by +[iso8601](https://en.wikipedia.org/wiki/ISO_8601). +""" +scalar DateTime + +input DateTimeRangeInput { + """ + Start date. + """ + gte: DateTime + + """ + End date. + """ + lte: DateTime +} + +""" +Deactivate all JWT tokens of the currently authenticated user. +""" +type DeactivateAllUserTokens { + accountErrors: [AccountError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [AccountError!]! +} + +""" +Delete metadata of an object. +""" +type DeleteMetadata { + metadataErrors: [MetadataError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [MetadataError!]! + item: ObjectWithMetadata +} + +""" +Delete object's private metadata. +""" +type DeletePrivateMetadata { + metadataErrors: [MetadataError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [MetadataError!]! + item: ObjectWithMetadata +} + +type DigitalContent implements Node & ObjectWithMetadata { + useDefaultSettings: Boolean! + automaticFulfillment: Boolean! + contentFile: String! + maxDownloads: Int + urlValidDays: Int + + """ + List of URLs for the digital variant. + """ + urls: [DigitalContentUrl] + + """ + The ID of the object. + """ + id: ID! + + """ + List of private metadata items.Requires proper staff permissions to access. + """ + privateMetadata: [MetadataItem]! + + """ + List of public metadata items. Can be accessed without permissions. + """ + metadata: [MetadataItem]! + + """ + Product variant assigned to digital content. + """ + productVariant: ProductVariant! +} + +type DigitalContentCountableConnection { + """ + Pagination data for this connection. + """ + pageInfo: PageInfo! + edges: [DigitalContentCountableEdge!]! + + """ + A total count of items in the collection. + """ + totalCount: Int +} + +type DigitalContentCountableEdge { + """ + The item at the end of the edge. + """ + node: DigitalContent! + + """ + A cursor for use in pagination. + """ + cursor: String! +} + +""" +Create new digital content. This mutation must be sent as a `multipart` request. More detailed specs of the upload format can be found here: https://github.com/jaydenseric/graphql-multipart-request-spec +""" +type DigitalContentCreate { + variant: ProductVariant + content: DigitalContent + productErrors: [ProductError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [ProductError!]! +} + +""" +Remove digital content assigned to given variant. +""" +type DigitalContentDelete { + variant: ProductVariant + productErrors: [ProductError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [ProductError!]! +} + +input DigitalContentInput { + """ + Use default digital content settings for this product. + """ + useDefaultSettings: Boolean! + + """ + Determines how many times a download link can be accessed by a customer. + """ + maxDownloads: Int + + """ + Determines for how many days a download link is active since it was generated. + """ + urlValidDays: Int + + """ + Overwrite default automatic_fulfillment setting for variant. + """ + automaticFulfillment: Boolean +} + +""" +Update digital content. +""" +type DigitalContentUpdate { + variant: ProductVariant + content: DigitalContent + productErrors: [ProductError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [ProductError!]! +} + +input DigitalContentUploadInput { + """ + Use default digital content settings for this product. + """ + useDefaultSettings: Boolean! + + """ + Determines how many times a download link can be accessed by a customer. + """ + maxDownloads: Int + + """ + Determines for how many days a download link is active since it was generated. + """ + urlValidDays: Int + + """ + Overwrite default automatic_fulfillment setting for variant. + """ + automaticFulfillment: Boolean + + """ + Represents an file in a multipart request. + """ + contentFile: Upload! +} + +type DigitalContentUrl implements Node { + content: DigitalContent! + created: DateTime! + downloadNum: Int! + + """ + The ID of the object. + """ + id: ID! + + """ + URL for digital content. + """ + url: String + + """ + UUID of digital content. + """ + token: UUID! +} + +""" +Generate new URL to digital content. +""" +type DigitalContentUrlCreate { + productErrors: [ProductError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [ProductError!]! + digitalContentUrl: DigitalContentUrl +} + +input DigitalContentUrlCreateInput { + """ + Digital content ID which URL will belong to. + """ + content: ID! +} + +type DiscountError { + """ + Name of a field that caused the error. A value of `null` indicates that the error isn't associated with a particular field. + """ + field: String + + """ + The error message. + """ + message: String + + """ + List of products IDs which causes the error. + """ + products: [ID!] + + """ + The error code. + """ + code: DiscountErrorCode! + + """ + List of channels IDs which causes the error. + """ + channels: [ID!] +} + +""" +An enumeration. +""" +enum DiscountErrorCode { + ALREADY_EXISTS + GRAPHQL_ERROR + INVALID + NOT_FOUND + REQUIRED + UNIQUE + CANNOT_MANAGE_PRODUCT_WITHOUT_VARIANT + DUPLICATED_INPUT_ITEM +} + +enum DiscountStatusEnum { + ACTIVE + EXPIRED + SCHEDULED +} + +enum DiscountValueTypeEnum { + FIXED + PERCENTAGE +} + +""" +An enumeration. +""" +enum DistanceUnitsEnum { + CM + M + KM + FT + YD + INCH +} + +""" +Represents shop's domain. +""" +type Domain { + """ + The host name of the domain. + """ + host: String! + + """ + Inform if SSL is enabled. + """ + sslEnabled: Boolean! + + """ + Shop's absolute URL. + """ + url: String! +} + +""" +Deletes draft orders. +""" +type DraftOrderBulkDelete { + """ + Returns how many objects were affected. + """ + count: Int! + orderErrors: [OrderError!]! @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [OrderError!]! +} + +""" +Completes creating an order. +""" +type DraftOrderComplete { + """ + Completed order. + """ + order: Order + orderErrors: [OrderError!]! @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [OrderError!]! +} + +""" +Creates a new draft order. +""" +type DraftOrderCreate { + orderErrors: [OrderError!]! @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [OrderError!]! + order: Order +} + +input DraftOrderCreateInput { + """ + Billing address of the customer. + """ + billingAddress: AddressInput + user: ID + + """ + Email address of the customer. + """ + userEmail: String + + """ + Discount amount for the order. + """ + discount: PositiveDecimal + + """ + Shipping address of the customer. + """ + shippingAddress: AddressInput + + """ + ID of a selected shipping method. + """ + shippingMethod: ID + + """ + ID of the voucher associated with the order. + """ + voucher: ID + + """ + A note from a customer. Visible by customers in the order summary. + """ + customerNote: String + + """ + ID of the channel associated with the order. + """ + channel: ID + + """ + URL of a view where users should be redirected to see the order details. URL in RFC 1808 format. + """ + redirectUrl: String + + """ + Variant line input consisting of variant ID and quantity of products. + """ + lines: [OrderLineCreateInput] +} + +""" +Deletes a draft order. +""" +type DraftOrderDelete { + orderErrors: [OrderError!]! @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [OrderError!]! + order: Order +} + +input DraftOrderInput { + """ + Billing address of the customer. + """ + billingAddress: AddressInput + user: ID + + """ + Email address of the customer. + """ + userEmail: String + + """ + Discount amount for the order. + """ + discount: PositiveDecimal + + """ + Shipping address of the customer. + """ + shippingAddress: AddressInput + + """ + ID of a selected shipping method. + """ + shippingMethod: ID + + """ + ID of the voucher associated with the order. + """ + voucher: ID + + """ + A note from a customer. Visible by customers in the order summary. + """ + customerNote: String + + """ + ID of the channel associated with the order. + """ + channel: ID + + """ + URL of a view where users should be redirected to see the order details. URL in RFC 1808 format. + """ + redirectUrl: String +} + +""" +Deletes order lines. +""" +type DraftOrderLinesBulkDelete { + """ + Returns how many objects were affected. + """ + count: Int! + orderErrors: [OrderError!]! @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [OrderError!]! +} + +""" +Updates a draft order. +""" +type DraftOrderUpdate { + orderErrors: [OrderError!]! @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [OrderError!]! + order: Order +} + +type ExportError { + """ + Name of a field that caused the error. A value of `null` indicates that the error isn't associated with a particular field. + """ + field: String + + """ + The error message. + """ + message: String + + """ + The error code. + """ + code: ExportErrorCode! +} + +""" +An enumeration. +""" +enum ExportErrorCode { + INVALID + NOT_FOUND + REQUIRED +} + +""" +History log of export file. +""" +type ExportEvent implements Node { + """ + The ID of the object. + """ + id: ID! + + """ + Date when event happened at in ISO 8601 format. + """ + date: DateTime! + + """ + Export event type. + """ + type: ExportEventsEnum! + + """ + User who performed the action. + """ + user: User + + """ + App which performed the action. + """ + app: App + + """ + Content of the event. + """ + message: String! +} + +""" +An enumeration. +""" +enum ExportEventsEnum { + EXPORT_PENDING + EXPORT_SUCCESS + EXPORT_FAILED + EXPORT_DELETED + EXPORTED_FILE_SENT + EXPORT_FAILED_INFO_SENT +} + +""" +Represents a job data of exported file. +""" +type ExportFile implements Node & Job { + """ + The ID of the object. + """ + id: ID! + user: User + app: App + + """ + Job status. + """ + status: JobStatusEnum! + + """ + Created date time of job in ISO 8601 format. + """ + createdAt: DateTime! + + """ + Date time of job last update in ISO 8601 format. + """ + updatedAt: DateTime! + + """ + Job message. + """ + message: String + + """ + The URL of field to download. + """ + url: String + + """ + List of events associated with the export. + """ + events: [ExportEvent!] +} + +type ExportFileCountableConnection { + """ + Pagination data for this connection. + """ + pageInfo: PageInfo! + edges: [ExportFileCountableEdge!]! + + """ + A total count of items in the collection. + """ + totalCount: Int +} + +type ExportFileCountableEdge { + """ + The item at the end of the edge. + """ + node: ExportFile! + + """ + A cursor for use in pagination. + """ + cursor: String! +} + +input ExportFileFilterInput { + createdAt: DateTimeRangeInput + updatedAt: DateTimeRangeInput + status: JobStatusEnum + user: String + app: String +} + +enum ExportFileSortField { + """ + Sort export file by status. + """ + STATUS + + """ + Sort export file by created at. + """ + CREATED_AT + + """ + Sort export file by updated at. + """ + UPDATED_AT +} + +input ExportFileSortingInput { + """ + Specifies the direction in which to sort products. + """ + direction: OrderDirection! + + """ + Sort export file by the selected field. + """ + field: ExportFileSortField! +} + +input ExportInfoInput { + """ + List of attribute ids witch should be exported. + """ + attributes: [ID!] + + """ + List of warehouse ids witch should be exported. + """ + warehouses: [ID!] + + """ + List of channels ids which should be exported. + """ + channels: [ID!] + + """ + List of product fields witch should be exported. + """ + fields: [ProductFieldEnum!] +} + +""" +Export products to csv file. +""" +type ExportProducts { + """ + The newly created export file job which is responsible for export data. + """ + exportFile: ExportFile + exportErrors: [ExportError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [ExportError!]! +} + +input ExportProductsInput { + """ + Determine which products should be exported. + """ + scope: ExportScope! + + """ + Filtering options for products. + """ + filter: ProductFilterInput + + """ + List of products IDS to export. + """ + ids: [ID!] + + """ + Input with info about fields which should be exported. + """ + exportInfo: ExportInfoInput + + """ + Type of exported file. + """ + fileType: FileTypesEnum! +} + +enum ExportScope { + """ + Export all products. + """ + ALL + + """ + Export products with given ids. + """ + IDS + + """ + Export the filtered products. + """ + FILTER +} + +type ExternalAuthentication { + """ + ID of external authentication plugin. + """ + id: String! + + """ + Name of external authentication plugin. + """ + name: String +} + +""" +Prepare external authentication url for user by custom plugin. +""" +type ExternalAuthenticationUrl { + """ + The data returned by authentication plugin. + """ + authenticationData: JSONString + accountErrors: [AccountError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [AccountError!]! +} + +""" +Logout user by custom plugin. +""" +type ExternalLogout { + """ + The data returned by authentication plugin. + """ + logoutData: JSONString + accountErrors: [AccountError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [AccountError!]! +} + +""" +Obtain external access tokens for user by custom plugin. +""" +type ExternalObtainAccessTokens { + """ + The token, required to authenticate. + """ + token: String + + """ + The refresh token, required to re-generate external access token. + """ + refreshToken: String + + """ + CSRF token required to re-generate external access token. + """ + csrfToken: String + + """ + A user instance. + """ + user: User + accountErrors: [AccountError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [AccountError!]! +} + +""" +Refresh user's access by custom plugin. +""" +type ExternalRefresh { + """ + The token, required to authenticate. + """ + token: String + + """ + The refresh token, required to re-generate external access token. + """ + refreshToken: String + + """ + CSRF token required to re-generate external access token. + """ + csrfToken: String + + """ + A user instance. + """ + user: User + accountErrors: [AccountError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [AccountError!]! +} + +""" +Verify external authentication data by plugin. +""" +type ExternalVerify { + """ + User assigned to data. + """ + user: User + + """ + Determine if authentication data is valid or not. + """ + isValid: Boolean! + + """ + External data. + """ + verifyData: JSONString + accountErrors: [AccountError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [AccountError!]! +} + +type File { + """ + The URL of the file. + """ + url: String! + + """ + Content type of the file. + """ + contentType: String +} + +""" +An enumeration. +""" +enum FileTypesEnum { + CSV + XLSX +} + +""" +Upload a file. This mutation must be sent as a `multipart` request. More detailed specs of the upload format can be found here: https://github.com/jaydenseric/graphql-multipart-request-spec +""" +type FileUpload { + uploadedFile: File + uploadErrors: [UploadError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [UploadError!]! +} + +""" +Represents order fulfillment. +""" +type Fulfillment implements Node & ObjectWithMetadata { + """ + The ID of the object. + """ + id: ID! + fulfillmentOrder: Int! + status: FulfillmentStatus! + trackingNumber: String! + created: DateTime! + + """ + List of private metadata items.Requires proper staff permissions to access. + """ + privateMetadata: [MetadataItem]! + + """ + List of public metadata items. Can be accessed without permissions. + """ + metadata: [MetadataItem]! + + """ + List of lines for the fulfillment. + """ + lines: [FulfillmentLine] + + """ + User-friendly fulfillment status. + """ + statusDisplay: String + + """ + Warehouse from fulfillment was fulfilled. + """ + warehouse: Warehouse +} + +""" +Cancels existing fulfillment and optionally restocks items. +""" +type FulfillmentCancel { + """ + A canceled fulfillment. + """ + fulfillment: Fulfillment + + """ + Order which fulfillment was cancelled. + """ + order: Order + orderErrors: [OrderError!]! @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [OrderError!]! +} + +input FulfillmentCancelInput { + """ + ID of warehouse where items will be restock. + """ + warehouseId: ID! +} + +""" +Represents line of the fulfillment. +""" +type FulfillmentLine implements Node { + """ + The ID of the object. + """ + id: ID! + quantity: Int! + orderLine: OrderLine +} + +""" +Refund products. +""" +type FulfillmentRefundProducts { + """ + A refunded fulfillment. + """ + fulfillment: Fulfillment + + """ + Order which fulfillment was refunded. + """ + order: Order + orderErrors: [OrderError!]! @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [OrderError!]! +} + +""" +Return products. +""" +type FulfillmentReturnProducts { + """ + A return fulfillment. + """ + returnFulfillment: Fulfillment + + """ + A replace fulfillment. + """ + replaceFulfillment: Fulfillment + + """ + Order which fulfillment was returned. + """ + order: Order + + """ + A draft order which was created for products with replace flag. + """ + replaceOrder: Order + orderErrors: [OrderError!]! @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [OrderError!]! +} + +""" +An enumeration. +""" +enum FulfillmentStatus { + """ + Fulfilled + """ + FULFILLED + + """ + Refunded + """ + REFUNDED + + """ + Returned + """ + RETURNED + + """ + Replaced + """ + REPLACED + + """ + Refunded and returned + """ + REFUNDED_AND_RETURNED + + """ + Canceled + """ + CANCELED +} + +""" +Updates a fulfillment for an order. +""" +type FulfillmentUpdateTracking { + """ + A fulfillment with updated tracking. + """ + fulfillment: Fulfillment + + """ + Order for which fulfillment was updated. + """ + order: Order + orderErrors: [OrderError!]! @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [OrderError!]! +} + +input FulfillmentUpdateTrackingInput { + """ + Fulfillment tracking number. + """ + trackingNumber: String + + """ + If true, send an email notification to the customer. + """ + notifyCustomer: Boolean = false +} + +""" +Payment gateway client configuration key and value pair. +""" +type GatewayConfigLine { + """ + Gateway config key. + """ + field: String! + + """ + Gateway config value for key. + """ + value: String +} + +""" +The `GenericScalar` scalar type represents a generic +GraphQL scalar value that could be: +String, Boolean, Int, Float, List or Object. +""" +scalar GenericScalar + +""" +A gift card is a prepaid electronic payment card accepted in stores. They can be used during checkout by providing a valid gift card codes. +""" +type GiftCard implements Node { + """ + Gift card code. + """ + code: String + + """ + The customer who bought a gift card. + """ + user: User + created: DateTime! + startDate: Date! + endDate: Date + lastUsedOn: DateTime + isActive: Boolean! + initialBalance: Money + currentBalance: Money + + """ + The ID of the object. + """ + id: ID! + + """ + Code in format which allows displaying in a user interface. + """ + displayCode: String +} + +""" +Activate a gift card. +""" +type GiftCardActivate { + """ + A gift card to activate. + """ + giftCard: GiftCard + giftCardErrors: [GiftCardError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [GiftCardError!]! +} + +type GiftCardCountableConnection { + """ + Pagination data for this connection. + """ + pageInfo: PageInfo! + edges: [GiftCardCountableEdge!]! + + """ + A total count of items in the collection. + """ + totalCount: Int +} + +type GiftCardCountableEdge { + """ + The item at the end of the edge. + """ + node: GiftCard! + + """ + A cursor for use in pagination. + """ + cursor: String! +} + +""" +Creates a new gift card. +""" +type GiftCardCreate { + giftCardErrors: [GiftCardError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [GiftCardError!]! + giftCard: GiftCard +} + +input GiftCardCreateInput { + """ + Start date of the gift card in ISO 8601 format. + """ + startDate: Date + + """ + End date of the gift card in ISO 8601 format. + """ + endDate: Date + + """ + Value of the gift card. + """ + balance: PositiveDecimal + + """ + The customer's email of the gift card buyer. + """ + userEmail: String + + """ + Code to use the gift card. + """ + code: String +} + +""" +Deactivate a gift card. +""" +type GiftCardDeactivate { + """ + A gift card to deactivate. + """ + giftCard: GiftCard + giftCardErrors: [GiftCardError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [GiftCardError!]! +} + +type GiftCardError { + """ + Name of a field that caused the error. A value of `null` indicates that the error isn't associated with a particular field. + """ + field: String + + """ + The error message. + """ + message: String + + """ + The error code. + """ + code: GiftCardErrorCode! +} + +""" +An enumeration. +""" +enum GiftCardErrorCode { + ALREADY_EXISTS + GRAPHQL_ERROR + INVALID + NOT_FOUND + REQUIRED + UNIQUE +} + +""" +Update a gift card. +""" +type GiftCardUpdate { + giftCardErrors: [GiftCardError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [GiftCardError!]! + giftCard: GiftCard +} + +input GiftCardUpdateInput { + """ + Start date of the gift card in ISO 8601 format. + """ + startDate: Date + + """ + End date of the gift card in ISO 8601 format. + """ + endDate: Date + + """ + Value of the gift card. + """ + balance: PositiveDecimal + + """ + The customer's email of the gift card buyer. + """ + userEmail: String +} + +""" +Represents permission group data. +""" +type Group implements Node { + """ + The ID of the object. + """ + id: ID! + name: String! + + """ + List of group permissions + """ + permissions: [Permission] + + """ + List of group users + """ + users: [User] + + """ + True, if the currently authenticated user has rights to manage a group. + """ + userCanManage: Boolean! +} + +type GroupCountableConnection { + """ + Pagination data for this connection. + """ + pageInfo: PageInfo! + edges: [GroupCountableEdge!]! + + """ + A total count of items in the collection. + """ + totalCount: Int +} + +type GroupCountableEdge { + """ + The item at the end of the edge. + """ + node: Group! + + """ + A cursor for use in pagination. + """ + cursor: String! +} + +""" +Represents an image. +""" +type Image { + """ + The URL of the image. + """ + url: String! + + """ + Alt text for an image. + """ + alt: String +} + +input IntRangeInput { + """ + Value greater than or equal to. + """ + gte: Int + + """ + Value less than or equal to. + """ + lte: Int +} + +""" +Represents an Invoice. +""" +type Invoice implements ObjectWithMetadata & Job & Node { + """ + The ID of the object. + """ + id: ID! + + """ + List of public metadata items. Can be accessed without permissions. + """ + metadata: [MetadataItem]! + + """ + Job status. + """ + status: JobStatusEnum! + number: String + externalUrl: String + + """ + List of private metadata items.Requires proper staff permissions to access. + """ + privateMetadata: [MetadataItem]! + + """ + Created date time of job in ISO 8601 format. + """ + createdAt: DateTime! + + """ + Date time of job last update in ISO 8601 format. + """ + updatedAt: DateTime! + + """ + Job message. + """ + message: String + + """ + URL to download an invoice. + """ + url: String +} + +""" +Creates a ready to send invoice. +""" +type InvoiceCreate { + invoiceErrors: [InvoiceError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [InvoiceError!]! + invoice: Invoice +} + +input InvoiceCreateInput { + """ + Invoice number. + """ + number: String! + + """ + URL of an invoice to download. + """ + url: String! +} + +""" +Deletes an invoice. +""" +type InvoiceDelete { + invoiceErrors: [InvoiceError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [InvoiceError!]! + invoice: Invoice +} + +type InvoiceError { + """ + Name of a field that caused the error. A value of `null` indicates that the error isn't associated with a particular field. + """ + field: String + + """ + The error message. + """ + message: String + + """ + The error code. + """ + code: InvoiceErrorCode! +} + +""" +An enumeration. +""" +enum InvoiceErrorCode { + REQUIRED + NOT_READY + URL_NOT_SET + EMAIL_NOT_SET + NUMBER_NOT_SET + NOT_FOUND + INVALID_STATUS +} + +""" +Request an invoice for the order using plugin. +""" +type InvoiceRequest { + """ + Order related to an invoice. + """ + order: Order + invoiceErrors: [InvoiceError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [InvoiceError!]! + invoice: Invoice +} + +""" +Requests deletion of an invoice. +""" +type InvoiceRequestDelete { + invoiceErrors: [InvoiceError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [InvoiceError!]! + invoice: Invoice +} + +""" +Send an invoice notification to the customer. +""" +type InvoiceSendNotification { + invoiceErrors: [InvoiceError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [InvoiceError!]! + invoice: Invoice +} + +""" +Updates an invoice. +""" +type InvoiceUpdate { + invoiceErrors: [InvoiceError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [InvoiceError!]! + invoice: Invoice +} + +""" +Allows use of a JSON String for input / output from the GraphQL schema. + +Use of this type is *not recommended* as you lose the benefits of having a defined, static +schema (one of the key benefits of GraphQL). +""" +scalar JSONString + +interface Job { + """ + Job status. + """ + status: JobStatusEnum! + + """ + Created date time of job in ISO 8601 format. + """ + createdAt: DateTime! + + """ + Date time of job last update in ISO 8601 format. + """ + updatedAt: DateTime! + + """ + Job message. + """ + message: String +} + +""" +An enumeration. +""" +enum JobStatusEnum { + PENDING + SUCCESS + FAILED + DELETED +} + +""" +An enumeration. +""" +enum LanguageCodeEnum { + AR + AZ + BG + BN + CA + CS + DA + DE + EL + EN + ES + ES_CO + ET + FA + FI + FR + HI + HU + HY + ID + IS + IT + JA + KA + KM + KO + LT + MN + MY + NB + NL + PL + PT + PT_BR + RO + RU + SK + SL + SQ + SR + SV + SW + TA + TH + TR + UK + VI + ZH_HANS + ZH_HANT +} + +type LanguageDisplay { + """ + ISO 639 representation of the language name. + """ + code: LanguageCodeEnum! + + """ + Full name of the language. + """ + language: String! +} + +type LimitInfo { + """ + Defines the current resource usage. + """ + currentUsage: Limits! + + """ + Defines the allowed maximum resource usage, null means unlimited. + """ + allowedUsage: Limits! +} + +type Limits { + channels: Int + orders: Int + productVariants: Int + staffUsers: Int + warehouses: Int +} + +""" +The manifest definition. +""" +type Manifest { + identifier: String! + version: String! + name: String! + about: String + permissions: [Permission] + appUrl: String + configurationUrl: String + tokenTargetUrl: String + dataPrivacy: String + dataPrivacyUrl: String + homepageUrl: String + supportUrl: String +} + +type Margin { + start: Int + stop: Int +} + +""" +An enumeration. +""" +enum MeasurementUnitsEnum { + CM + M + KM + FT + YD + INCH + SQ_CM + SQ_M + SQ_KM + SQ_FT + SQ_YD + SQ_INCH + CUBIC_MILLIMETER + CUBIC_CENTIMETER + CUBIC_DECIMETER + CUBIC_METER + LITER + CUBIC_FOOT + CUBIC_INCH + CUBIC_YARD + QT + PINT + FL_OZ + ACRE_IN + ACRE_FT + G + LB + OZ + KG + TONNE +} + +""" +Represents a single menu - an object that is used to help navigate through the store. +""" +type Menu implements Node & ObjectWithMetadata { + """ + The ID of the object. + """ + id: ID! + name: String! + slug: String! + + """ + List of private metadata items.Requires proper staff permissions to access. + """ + privateMetadata: [MetadataItem]! + + """ + List of public metadata items. Can be accessed without permissions. + """ + metadata: [MetadataItem]! + items: [MenuItem] +} + +""" +Deletes menus. +""" +type MenuBulkDelete { + """ + Returns how many objects were affected. + """ + count: Int! + menuErrors: [MenuError!]! @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [MenuError!]! +} + +type MenuCountableConnection { + """ + Pagination data for this connection. + """ + pageInfo: PageInfo! + edges: [MenuCountableEdge!]! + + """ + A total count of items in the collection. + """ + totalCount: Int +} + +type MenuCountableEdge { + """ + The item at the end of the edge. + """ + node: Menu! + + """ + A cursor for use in pagination. + """ + cursor: String! +} + +""" +Creates a new Menu. +""" +type MenuCreate { + menuErrors: [MenuError!]! @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [MenuError!]! + menu: Menu +} + +input MenuCreateInput { + """ + Name of the menu. + """ + name: String! + + """ + Slug of the menu. Will be generated if not provided. + """ + slug: String + + """ + List of menu items. + """ + items: [MenuItemInput] +} + +""" +Deletes a menu. +""" +type MenuDelete { + menuErrors: [MenuError!]! @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [MenuError!]! + menu: Menu +} + +type MenuError { + """ + Name of a field that caused the error. A value of `null` indicates that the error isn't associated with a particular field. + """ + field: String + + """ + The error message. + """ + message: String + + """ + The error code. + """ + code: MenuErrorCode! +} + +""" +An enumeration. +""" +enum MenuErrorCode { + CANNOT_ASSIGN_NODE + GRAPHQL_ERROR + INVALID + INVALID_MENU_ITEM + NO_MENU_ITEM_PROVIDED + NOT_FOUND + REQUIRED + TOO_MANY_MENU_ITEMS + UNIQUE +} + +input MenuFilterInput { + search: String + slug: [String] + metadata: [MetadataInput] +} + +input MenuInput { + """ + Name of the menu. + """ + name: String + + """ + Slug of the menu. + """ + slug: String +} + +""" +Represents a single item of the related menu. Can store categories, collection or pages. +""" +type MenuItem implements Node & ObjectWithMetadata { + """ + The ID of the object. + """ + id: ID! + name: String! + menu: Menu! + parent: MenuItem + category: Category + collection: Collection + page: Page + level: Int! + + """ + List of private metadata items.Requires proper staff permissions to access. + """ + privateMetadata: [MetadataItem]! + + """ + List of public metadata items. Can be accessed without permissions. + """ + metadata: [MetadataItem]! + children: [MenuItem] + + """ + URL to the menu item. + """ + url: String + + """ + Returns translated menu item fields for the given language code. + """ + translation( + """ + A language code to return the translation for menu item. + """ + languageCode: LanguageCodeEnum! + ): MenuItemTranslation +} + +""" +Deletes menu items. +""" +type MenuItemBulkDelete { + """ + Returns how many objects were affected. + """ + count: Int! + menuErrors: [MenuError!]! @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [MenuError!]! +} + +type MenuItemCountableConnection { + """ + Pagination data for this connection. + """ + pageInfo: PageInfo! + edges: [MenuItemCountableEdge!]! + + """ + A total count of items in the collection. + """ + totalCount: Int +} + +type MenuItemCountableEdge { + """ + The item at the end of the edge. + """ + node: MenuItem! + + """ + A cursor for use in pagination. + """ + cursor: String! +} + +""" +Creates a new menu item. +""" +type MenuItemCreate { + menuErrors: [MenuError!]! @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [MenuError!]! + menuItem: MenuItem +} + +input MenuItemCreateInput { + """ + Name of the menu item. + """ + name: String! + + """ + URL of the pointed item. + """ + url: String + + """ + Category to which item points. + """ + category: ID + + """ + Collection to which item points. + """ + collection: ID + + """ + Page to which item points. + """ + page: ID + + """ + Menu to which item belongs. + """ + menu: ID! + + """ + ID of the parent menu. If empty, menu will be top level menu. + """ + parent: ID +} + +""" +Deletes a menu item. +""" +type MenuItemDelete { + menuErrors: [MenuError!]! @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [MenuError!]! + menuItem: MenuItem +} + +input MenuItemFilterInput { + search: String + metadata: [MetadataInput] +} + +input MenuItemInput { + """ + Name of the menu item. + """ + name: String + + """ + URL of the pointed item. + """ + url: String + + """ + Category to which item points. + """ + category: ID + + """ + Collection to which item points. + """ + collection: ID + + """ + Page to which item points. + """ + page: ID +} + +""" +Moves items of menus. +""" +type MenuItemMove { + """ + Assigned menu to move within. + """ + menu: Menu + menuErrors: [MenuError!]! @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [MenuError!]! +} + +input MenuItemMoveInput { + """ + The menu item ID to move. + """ + itemId: ID! + + """ + ID of the parent menu. If empty, menu will be top level menu. + """ + parentId: ID + + """ + The new relative sorting position of the item (from -inf to +inf). 1 moves the item one position forward, -1 moves the item one position backward, 0 leaves the item unchanged. + """ + sortOrder: Int +} + +input MenuItemSortingInput { + """ + Specifies the direction in which to sort products. + """ + direction: OrderDirection! + + """ + Sort menu items by the selected field. + """ + field: MenuItemsSortField! +} + +type MenuItemTranslatableContent implements Node { + """ + The ID of the object. + """ + id: ID! + name: String! + + """ + Returns translated menu item fields for the given language code. + """ + translation( + """ + A language code to return the translation for menu item. + """ + languageCode: LanguageCodeEnum! + ): MenuItemTranslation + + """ + Represents a single item of the related menu. Can store categories, collection or pages. + """ + menuItem: MenuItem +} + +""" +Creates/Updates translations for Menu Item. +""" +type MenuItemTranslate { + translationErrors: [TranslationError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [TranslationError!]! + menuItem: MenuItem +} + +type MenuItemTranslation implements Node { + """ + The ID of the object. + """ + id: ID! + name: String! + + """ + Translation language. + """ + language: LanguageDisplay! +} + +""" +Updates a menu item. +""" +type MenuItemUpdate { + menuErrors: [MenuError!]! @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [MenuError!]! + menuItem: MenuItem +} + +enum MenuItemsSortField { + """ + Sort menu items by name. + """ + NAME +} + +enum MenuSortField { + """ + Sort menus by name. + """ + NAME + + """ + Sort menus by items count. + """ + ITEMS_COUNT +} + +input MenuSortingInput { + """ + Specifies the direction in which to sort products. + """ + direction: OrderDirection! + + """ + Sort menus by the selected field. + """ + field: MenuSortField! +} + +""" +Updates a menu. +""" +type MenuUpdate { + menuErrors: [MenuError!]! @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [MenuError!]! + menu: Menu +} + +type MetadataError { + """ + Name of a field that caused the error. A value of `null` indicates that the error isn't associated with a particular field. + """ + field: String + + """ + The error message. + """ + message: String + + """ + The error code. + """ + code: MetadataErrorCode! +} + +""" +An enumeration. +""" +enum MetadataErrorCode { + GRAPHQL_ERROR + INVALID + NOT_FOUND + REQUIRED +} + +input MetadataInput { + """ + Key of a metadata item. + """ + key: String! + + """ + Value of a metadata item. + """ + value: String! +} + +type MetadataItem { + """ + Key of a metadata item. + """ + key: String! + + """ + Value of a metadata item. + """ + value: String! +} + +""" +Represents amount of money in specific currency. +""" +type Money { + """ + Currency code. + """ + currency: String! + + """ + Amount of money. + """ + amount: Float! +} + +""" +Represents a range of amounts of money. +""" +type MoneyRange { + """ + Lower bound of a price range. + """ + start: Money + + """ + Upper bound of a price range. + """ + stop: Money +} + +input MoveProductInput { + """ + The ID of the product to move. + """ + productId: ID! + + """ + The relative sorting position of the product (from -inf to +inf) starting from the first given product's actual position.1 moves the item one position forward, -1 moves the item one position backward, 0 leaves the item unchanged. + """ + sortOrder: Int +} + +type Mutation { + """ + Creates a new webhook subscription. + """ + webhookCreate( + """ + Fields required to create a webhook. + """ + input: WebhookCreateInput! + ): WebhookCreate + + """ + Deletes a webhook subscription. + """ + webhookDelete( + """ + ID of a webhook to delete. + """ + id: ID! + ): WebhookDelete + + """ + Updates a webhook subscription. + """ + webhookUpdate( + """ + ID of a webhook to update. + """ + id: ID! + + """ + Fields required to update a webhook. + """ + input: WebhookUpdateInput! + ): WebhookUpdate + + """ + Creates new warehouse. + """ + createWarehouse( + """ + Fields required to create warehouse. + """ + input: WarehouseCreateInput! + ): WarehouseCreate + + """ + Updates given warehouse. + """ + updateWarehouse( + """ + ID of a warehouse to update. + """ + id: ID! + + """ + Fields required to update warehouse. + """ + input: WarehouseUpdateInput! + ): WarehouseUpdate + + """ + Deletes selected warehouse. + """ + deleteWarehouse( + """ + ID of a warehouse to delete. + """ + id: ID! + ): WarehouseDelete + + """ + Add shipping zone to given warehouse. + """ + assignWarehouseShippingZone( + """ + ID of a warehouse to update. + """ + id: ID! + + """ + List of shipping zone IDs. + """ + shippingZoneIds: [ID!]! + ): WarehouseShippingZoneAssign + + """ + Remove shipping zone from given warehouse. + """ + unassignWarehouseShippingZone( + """ + ID of a warehouse to update. + """ + id: ID! + + """ + List of shipping zone IDs. + """ + shippingZoneIds: [ID!]! + ): WarehouseShippingZoneUnassign + + """ + Creates a new staff notification recipient. + """ + staffNotificationRecipientCreate( + """ + Fields required to create a staff notification recipient. + """ + input: StaffNotificationRecipientInput! + ): StaffNotificationRecipientCreate + + """ + Updates a staff notification recipient. + """ + staffNotificationRecipientUpdate( + """ + ID of a staff notification recipient to update. + """ + id: ID! + + """ + Fields required to update a staff notification recipient. + """ + input: StaffNotificationRecipientInput! + ): StaffNotificationRecipientUpdate + + """ + Delete staff notification recipient. + """ + staffNotificationRecipientDelete( + """ + ID of a staff notification recipient to delete. + """ + id: ID! + ): StaffNotificationRecipientDelete + + """ + Updates site domain of the shop. + """ + shopDomainUpdate( + """ + Fields required to update site. + """ + input: SiteDomainInput + ): ShopDomainUpdate + + """ + Updates shop settings. + """ + shopSettingsUpdate( + """ + Fields required to update shop settings. + """ + input: ShopSettingsInput! + ): ShopSettingsUpdate + + """ + Fetch tax rates. + """ + shopFetchTaxRates: ShopFetchTaxRates + + """ + Creates/Updates translations for Shop Settings. + """ + shopSettingsTranslate( + """ + Fields required to update shop settings translations. + """ + input: ShopSettingsTranslationInput! + + """ + Translation language code. + """ + languageCode: LanguageCodeEnum! + ): ShopSettingsTranslate + + """ + Update the shop's address. If the `null` value is passed, the currently selected address will be deleted. + """ + shopAddressUpdate( + """ + Fields required to update shop address. + """ + input: AddressInput + ): ShopAddressUpdate + + """ + Update shop order settings. + """ + orderSettingsUpdate( + """ + Fields required to update shop order settings. + """ + input: OrderSettingsUpdateInput! + ): OrderSettingsUpdate + + """ + Manage shipping method's availability in channels. + """ + shippingMethodChannelListingUpdate( + """ + ID of a shipping method to update. + """ + id: ID! + + """ + Fields required to update shipping method channel listings. + """ + input: ShippingMethodChannelListingInput! + ): ShippingMethodChannelListingUpdate + + """ + Creates a new shipping price. + """ + shippingPriceCreate( + """ + Fields required to create a shipping price. + """ + input: ShippingPriceInput! + ): ShippingPriceCreate + + """ + Deletes a shipping price. + """ + shippingPriceDelete( + """ + ID of a shipping price to delete. + """ + id: ID! + ): ShippingPriceDelete + + """ + Deletes shipping prices. + """ + shippingPriceBulkDelete( + """ + List of shipping price IDs to delete. + """ + ids: [ID]! + ): ShippingPriceBulkDelete + + """ + Updates a new shipping price. + """ + shippingPriceUpdate( + """ + ID of a shipping price to update. + """ + id: ID! + + """ + Fields required to update a shipping price. + """ + input: ShippingPriceInput! + ): ShippingPriceUpdate + + """ + Creates/Updates translations for shipping method. + """ + shippingPriceTranslate( + """ + Shipping method ID. + """ + id: ID! + input: ShippingPriceTranslationInput! + + """ + Translation language code. + """ + languageCode: LanguageCodeEnum! + ): ShippingPriceTranslate + + """ + Exclude products from shipping price. + """ + shippingPriceExcludeProducts( + """ + ID of a shipping price. + """ + id: ID! + + """ + Exclude products input. + """ + input: ShippingPriceExcludeProductsInput! + ): ShippingPriceExcludeProducts + + """ + Remove product from excluded list for shipping price. + """ + shippingPriceRemoveProductFromExclude( + """ + ID of a shipping price. + """ + id: ID! + + """ + List of products which will be removed from excluded list. + """ + products: [ID]! + ): ShippingPriceRemoveProductFromExclude + + """ + Creates a new shipping zone. + """ + shippingZoneCreate( + """ + Fields required to create a shipping zone. + """ + input: ShippingZoneCreateInput! + ): ShippingZoneCreate + + """ + Deletes a shipping zone. + """ + shippingZoneDelete( + """ + ID of a shipping zone to delete. + """ + id: ID! + ): ShippingZoneDelete + + """ + Deletes shipping zones. + """ + shippingZoneBulkDelete( + """ + List of shipping zone IDs to delete. + """ + ids: [ID]! + ): ShippingZoneBulkDelete + + """ + Updates a new shipping zone. + """ + shippingZoneUpdate( + """ + ID of a shipping zone to update. + """ + id: ID! + + """ + Fields required to update a shipping zone. + """ + input: ShippingZoneUpdateInput! + ): ShippingZoneUpdate + + """ + Assign attributes to a given product type. + """ + productAttributeAssign( + """ + The operations to perform. + """ + operations: [ProductAttributeAssignInput]! + + """ + ID of the product type to assign the attributes into. + """ + productTypeId: ID! + ): ProductAttributeAssign + + """ + Un-assign attributes from a given product type. + """ + productAttributeUnassign( + """ + The IDs of the attributes to unassign. + """ + attributeIds: [ID]! + + """ + ID of the product type from which the attributes should be unassigned. + """ + productTypeId: ID! + ): ProductAttributeUnassign + + """ + Creates a new category. + """ + categoryCreate( + """ + Fields required to create a category. + """ + input: CategoryInput! + + """ + ID of the parent category. If empty, category will be top level category. + """ + parent: ID + ): CategoryCreate + + """ + Deletes a category. + """ + categoryDelete( + """ + ID of a category to delete. + """ + id: ID! + ): CategoryDelete + + """ + Deletes categories. + """ + categoryBulkDelete( + """ + List of category IDs to delete. + """ + ids: [ID]! + ): CategoryBulkDelete + + """ + Updates a category. + """ + categoryUpdate( + """ + ID of a category to update. + """ + id: ID! + + """ + Fields required to update a category. + """ + input: CategoryInput! + ): CategoryUpdate + + """ + Creates/Updates translations for Category. + """ + categoryTranslate( + """ + Category ID. + """ + id: ID! + input: TranslationInput! + + """ + Translation language code. + """ + languageCode: LanguageCodeEnum! + ): CategoryTranslate + + """ + Adds products to a collection. + """ + collectionAddProducts( + """ + ID of a collection. + """ + collectionId: ID! + + """ + List of product IDs. + """ + products: [ID]! + ): CollectionAddProducts + + """ + Creates a new collection. + """ + collectionCreate( + """ + Fields required to create a collection. + """ + input: CollectionCreateInput! + ): CollectionCreate + + """ + Deletes a collection. + """ + collectionDelete( + """ + ID of a collection to delete. + """ + id: ID! + ): CollectionDelete + + """ + Reorder the products of a collection. + """ + collectionReorderProducts( + """ + ID of a collection. + """ + collectionId: ID! + + """ + The collection products position operations. + """ + moves: [MoveProductInput]! + ): CollectionReorderProducts + + """ + Deletes collections. + """ + collectionBulkDelete( + """ + List of collection IDs to delete. + """ + ids: [ID]! + ): CollectionBulkDelete + + """ + Remove products from a collection. + """ + collectionRemoveProducts( + """ + ID of a collection. + """ + collectionId: ID! + + """ + List of product IDs. + """ + products: [ID]! + ): CollectionRemoveProducts + + """ + Updates a collection. + """ + collectionUpdate( + """ + ID of a collection to update. + """ + id: ID! + + """ + Fields required to update a collection. + """ + input: CollectionInput! + ): CollectionUpdate + + """ + Creates/Updates translations for collection. + """ + collectionTranslate( + """ + Collection ID. + """ + id: ID! + input: TranslationInput! + + """ + Translation language code. + """ + languageCode: LanguageCodeEnum! + ): CollectionTranslate + + """ + Manage collection's availability in channels. + """ + collectionChannelListingUpdate( + """ + ID of a collection to update. + """ + id: ID! + + """ + Fields required to create or update collection channel listings. + """ + input: CollectionChannelListingUpdateInput! + ): CollectionChannelListingUpdate + + """ + Creates a new product. + """ + productCreate( + """ + Fields required to create a product. + """ + input: ProductCreateInput! + ): ProductCreate + + """ + Deletes a product. + """ + productDelete( + """ + ID of a product to delete. + """ + id: ID! + ): ProductDelete + + """ + Deletes products. + """ + productBulkDelete( + """ + List of product IDs to delete. + """ + ids: [ID]! + ): ProductBulkDelete + + """ + Updates an existing product. + """ + productUpdate( + """ + ID of a product to update. + """ + id: ID! + + """ + Fields required to update a product. + """ + input: ProductInput! + ): ProductUpdate + + """ + Creates/Updates translations for Product. + """ + productTranslate( + """ + Product ID. + """ + id: ID! + input: TranslationInput! + + """ + Translation language code. + """ + languageCode: LanguageCodeEnum! + ): ProductTranslate + + """ + Manage product's availability in channels. + """ + productChannelListingUpdate( + """ + ID of a product to update. + """ + id: ID! + + """ + Fields required to create or update product channel listings. + """ + input: ProductChannelListingUpdateInput! + ): ProductChannelListingUpdate + + """ + Create a media object (image or video URL) associated with product. For image, this mutation must be sent as a `multipart` request. More detailed specs of the upload format can be found here: https://github.com/jaydenseric/graphql-multipart-request-spec + """ + productMediaCreate( + """ + Fields required to create a product media. + """ + input: ProductMediaCreateInput! + ): ProductMediaCreate + + """ + Reorder the variants of a product. Mutation updates updated_at on product and triggers PRODUCT_UPDATED webhook. + """ + productVariantReorder( + """ + The list of variant reordering operations. + """ + moves: [ReorderInput]! + + """ + Id of product that variants order will be altered. + """ + productId: ID! + ): ProductVariantReorder + + """ + Deletes a product media. + """ + productMediaDelete( + """ + ID of a product media to delete. + """ + id: ID! + ): ProductMediaDelete + + """ + Deletes product media. + """ + productMediaBulkDelete( + """ + List of product media IDs to delete. + """ + ids: [ID]! + ): ProductMediaBulkDelete + + """ + Changes ordering of the product media. + """ + productMediaReorder( + """ + IDs of a product media in the desired order. + """ + mediaIds: [ID]! + + """ + ID of product that media order will be altered. + """ + productId: ID! + ): ProductMediaReorder + + """ + Updates a product media. + """ + productMediaUpdate( + """ + ID of a product media to update. + """ + id: ID! + + """ + Fields required to update a product media. + """ + input: ProductMediaUpdateInput! + ): ProductMediaUpdate + + """ + Creates a new product type. + """ + productTypeCreate( + """ + Fields required to create a product type. + """ + input: ProductTypeInput! + ): ProductTypeCreate + + """ + Deletes a product type. + """ + productTypeDelete( + """ + ID of a product type to delete. + """ + id: ID! + ): ProductTypeDelete + + """ + Deletes product types. + """ + productTypeBulkDelete( + """ + List of product type IDs to delete. + """ + ids: [ID]! + ): ProductTypeBulkDelete + + """ + Updates an existing product type. + """ + productTypeUpdate( + """ + ID of a product type to update. + """ + id: ID! + + """ + Fields required to update a product type. + """ + input: ProductTypeInput! + ): ProductTypeUpdate + + """ + Reorder the attributes of a product type. + """ + productTypeReorderAttributes( + """ + The list of attribute reordering operations. + """ + moves: [ReorderInput]! + + """ + ID of a product type. + """ + productTypeId: ID! + + """ + The attribute type to reorder. + """ + type: ProductAttributeType! + ): ProductTypeReorderAttributes + + """ + Reorder product attribute values. + """ + productReorderAttributeValues( + """ + ID of an attribute. + """ + attributeId: ID! + + """ + The list of reordering operations for given attribute values. + """ + moves: [ReorderInput]! + + """ + ID of a product. + """ + productId: ID! + ): ProductReorderAttributeValues + + """ + Create new digital content. This mutation must be sent as a `multipart` request. More detailed specs of the upload format can be found here: https://github.com/jaydenseric/graphql-multipart-request-spec + """ + digitalContentCreate( + """ + Fields required to create a digital content. + """ + input: DigitalContentUploadInput! + + """ + ID of a product variant to upload digital content. + """ + variantId: ID! + ): DigitalContentCreate + + """ + Remove digital content assigned to given variant. + """ + digitalContentDelete( + """ + ID of a product variant with digital content to remove. + """ + variantId: ID! + ): DigitalContentDelete + + """ + Update digital content. + """ + digitalContentUpdate( + """ + Fields required to update a digital content. + """ + input: DigitalContentInput! + + """ + ID of a product variant with digital content to update. + """ + variantId: ID! + ): DigitalContentUpdate + + """ + Generate new URL to digital content. + """ + digitalContentUrlCreate( + """ + Fields required to create a new url. + """ + input: DigitalContentUrlCreateInput! + ): DigitalContentUrlCreate + + """ + Creates a new variant for a product. + """ + productVariantCreate( + """ + Fields required to create a product variant. + """ + input: ProductVariantCreateInput! + ): ProductVariantCreate + + """ + Deletes a product variant. + """ + productVariantDelete( + """ + ID of a product variant to delete. + """ + id: ID! + ): ProductVariantDelete + + """ + Creates product variants for a given product. + """ + productVariantBulkCreate( + """ + ID of the product to create the variants for. + """ + product: ID! + + """ + Input list of product variants to create. + """ + variants: [ProductVariantBulkCreateInput]! + ): ProductVariantBulkCreate + + """ + Deletes product variants. + """ + productVariantBulkDelete( + """ + List of product variant IDs to delete. + """ + ids: [ID]! + ): ProductVariantBulkDelete + + """ + Creates stocks for product variant. + """ + productVariantStocksCreate( + """ + Input list of stocks to create. + """ + stocks: [StockInput!]! + + """ + ID of a product variant for which stocks will be created. + """ + variantId: ID! + ): ProductVariantStocksCreate + + """ + Delete stocks from product variant. + """ + productVariantStocksDelete( + """ + ID of product variant for which stocks will be deleted. + """ + variantId: ID! + warehouseIds: [ID!] + ): ProductVariantStocksDelete + + """ + Update stocks for product variant. + """ + productVariantStocksUpdate( + """ + Input list of stocks to create. + """ + stocks: [StockInput!]! + + """ + ID of a product variant for which stocks will be created. + """ + variantId: ID! + ): ProductVariantStocksUpdate + + """ + Updates an existing variant for product. + """ + productVariantUpdate( + """ + ID of a product variant to update. + """ + id: ID! + + """ + Fields required to update a product variant. + """ + input: ProductVariantInput! + ): ProductVariantUpdate + + """ + Set default variant for a product. Mutation triggers PRODUCT_UPDATED webhook. + """ + productVariantSetDefault( + """ + Id of a product that will have the default variant set. + """ + productId: ID! + + """ + Id of a variant that will be set as default. + """ + variantId: ID! + ): ProductVariantSetDefault + + """ + Creates/Updates translations for Product Variant. + """ + productVariantTranslate( + """ + Product Variant ID. + """ + id: ID! + input: NameTranslationInput! + + """ + Translation language code. + """ + languageCode: LanguageCodeEnum! + ): ProductVariantTranslate + + """ + Manage product variant prices in channels. + """ + productVariantChannelListingUpdate( + """ + ID of a product variant to update. + """ + id: ID! + + """ + ('List of fields required to create or upgrade product variant ', 'channel listings.') + """ + input: [ProductVariantChannelListingAddInput!]! + ): ProductVariantChannelListingUpdate + + """ + Reorder product variant attribute values. + """ + productVariantReorderAttributeValues( + """ + ID of an attribute. + """ + attributeId: ID! + + """ + The list of reordering operations for given attribute values. + """ + moves: [ReorderInput]! + + """ + ID of a product variant. + """ + variantId: ID! + ): ProductVariantReorderAttributeValues + + """ + Assign an media to a product variant. + """ + variantMediaAssign( + """ + ID of a product media to assign to a variant. + """ + mediaId: ID! + + """ + ID of a product variant. + """ + variantId: ID! + ): VariantMediaAssign + + """ + Unassign an media from a product variant. + """ + variantMediaUnassign( + """ + ID of a product media to unassign from a variant. + """ + mediaId: ID! + + """ + ID of a product variant. + """ + variantId: ID! + ): VariantMediaUnassign + + """ + Captures the authorized payment amount. + """ + paymentCapture( + """ + Transaction amount. + """ + amount: PositiveDecimal + + """ + Payment ID. + """ + paymentId: ID! + ): PaymentCapture + + """ + Refunds the captured payment amount. + """ + paymentRefund( + """ + Transaction amount. + """ + amount: PositiveDecimal + + """ + Payment ID. + """ + paymentId: ID! + ): PaymentRefund + + """ + Voids the authorized payment. + """ + paymentVoid( + """ + Payment ID. + """ + paymentId: ID! + ): PaymentVoid + + """ + Initializes payment process when it is required by gateway. + """ + paymentInitialize( + """ + Slug of a channel for which the data should be returned. + """ + channel: String + + """ + A gateway name used to initialize the payment. + """ + gateway: String! + + """ + Client-side generated data required to initialize the payment. + """ + paymentData: JSONString + ): PaymentInitialize + + """ + Creates a new page. + """ + pageCreate( + """ + Fields required to create a page. + """ + input: PageCreateInput! + ): PageCreate + + """ + Deletes a page. + """ + pageDelete( + """ + ID of a page to delete. + """ + id: ID! + ): PageDelete + + """ + Deletes pages. + """ + pageBulkDelete( + """ + List of page IDs to delete. + """ + ids: [ID]! + ): PageBulkDelete + + """ + Publish pages. + """ + pageBulkPublish( + """ + List of page IDs to (un)publish. + """ + ids: [ID]! + + """ + Determine if pages will be published or not. + """ + isPublished: Boolean! + ): PageBulkPublish + + """ + Updates an existing page. + """ + pageUpdate( + """ + ID of a page to update. + """ + id: ID! + + """ + Fields required to update a page. + """ + input: PageInput! + ): PageUpdate + + """ + Creates/Updates translations for Page. + """ + pageTranslate( + """ + Page ID. + """ + id: ID! + input: PageTranslationInput! + + """ + Translation language code. + """ + languageCode: LanguageCodeEnum! + ): PageTranslate + + """ + Create a new page type. + """ + pageTypeCreate( + """ + Fields required to create page type. + """ + input: PageTypeCreateInput! + ): PageTypeCreate + + """ + Update page type. + """ + pageTypeUpdate( + """ + ID of the page type to update. + """ + id: ID + + """ + Fields required to update page type. + """ + input: PageTypeUpdateInput! + ): PageTypeUpdate + + """ + Delete a page type. + """ + pageTypeDelete( + """ + ID of the page type to delete. + """ + id: ID! + ): PageTypeDelete + + """ + Delete page types. + """ + pageTypeBulkDelete( + """ + List of page type IDs to delete + """ + ids: [ID!]! + ): PageTypeBulkDelete + + """ + Assign attributes to a given page type. + """ + pageAttributeAssign( + """ + The IDs of the attributes to assign. + """ + attributeIds: [ID!]! + + """ + ID of the page type to assign the attributes into. + """ + pageTypeId: ID! + ): PageAttributeAssign + + """ + Unassign attributes from a given page type. + """ + pageAttributeUnassign( + """ + The IDs of the attributes to unassign. + """ + attributeIds: [ID!]! + + """ + ID of the page type from which the attributes should be unassign. + """ + pageTypeId: ID! + ): PageAttributeUnassign + + """ + Reorder the attributes of a page type. + """ + pageTypeReorderAttributes( + """ + The list of attribute reordering operations. + """ + moves: [ReorderInput!]! + + """ + ID of a page type. + """ + pageTypeId: ID! + ): PageTypeReorderAttributes + + """ + Reorder page attribute values. + """ + pageReorderAttributeValues( + """ + ID of an attribute. + """ + attributeId: ID! + + """ + The list of reordering operations for given attribute values. + """ + moves: [ReorderInput]! + + """ + ID of a page. + """ + pageId: ID! + ): PageReorderAttributeValues + + """ + Completes creating an order. + """ + draftOrderComplete( + """ + ID of the order that will be completed. + """ + id: ID! + ): DraftOrderComplete + + """ + Creates a new draft order. + """ + draftOrderCreate( + """ + Fields required to create an order. + """ + input: DraftOrderCreateInput! + ): DraftOrderCreate + + """ + Deletes a draft order. + """ + draftOrderDelete( + """ + ID of a draft order to delete. + """ + id: ID! + ): DraftOrderDelete + + """ + Deletes draft orders. + """ + draftOrderBulkDelete( + """ + List of draft order IDs to delete. + """ + ids: [ID]! + ): DraftOrderBulkDelete + + """ + Deletes order lines. + """ + draftOrderLinesBulkDelete( + """ + List of order lines IDs to delete. + """ + ids: [ID]! + ): DraftOrderLinesBulkDelete + + """ + Updates a draft order. + """ + draftOrderUpdate( + """ + ID of a draft order to update. + """ + id: ID! + + """ + Fields required to update an order. + """ + input: DraftOrderInput! + ): DraftOrderUpdate + + """ + Adds note to the order. + """ + orderAddNote( + """ + ID of the order to add a note for. + """ + order: ID! + + """ + Fields required to create a note for the order. + """ + input: OrderAddNoteInput! + ): OrderAddNote + + """ + Cancel an order. + """ + orderCancel( + """ + ID of the order to cancel. + """ + id: ID! + ): OrderCancel + + """ + Capture an order. + """ + orderCapture( + """ + Amount of money to capture. + """ + amount: PositiveDecimal! + + """ + ID of the order to capture. + """ + id: ID! + ): OrderCapture + + """ + Confirms an unconfirmed order by changing status to unfulfilled. + """ + orderConfirm( + """ + ID of an order to confirm. + """ + id: ID! + ): OrderConfirm + + """ + Creates new fulfillments for an order. + """ + orderFulfill( + """ + Fields required to create an fulfillment. + """ + input: OrderFulfillInput! + + """ + ID of the order to be fulfilled. + """ + order: ID + ): OrderFulfill + + """ + Cancels existing fulfillment and optionally restocks items. + """ + orderFulfillmentCancel( + """ + ID of an fulfillment to cancel. + """ + id: ID! + + """ + Fields required to cancel an fulfillment. + """ + input: FulfillmentCancelInput! + ): FulfillmentCancel + + """ + Updates a fulfillment for an order. + """ + orderFulfillmentUpdateTracking( + """ + ID of an fulfillment to update. + """ + id: ID! + + """ + Fields required to update an fulfillment. + """ + input: FulfillmentUpdateTrackingInput! + ): FulfillmentUpdateTracking + + """ + Refund products. + """ + orderFulfillmentRefundProducts( + """ + Fields required to create an refund fulfillment. + """ + input: OrderRefundProductsInput! + + """ + ID of the order to be refunded. + """ + order: ID! + ): FulfillmentRefundProducts + + """ + Return products. + """ + orderFulfillmentReturnProducts( + """ + Fields required to return products. + """ + input: OrderReturnProductsInput! + + """ + ID of the order to be returned. + """ + order: ID! + ): FulfillmentReturnProducts + + """ + Create order lines for an order. + """ + orderLinesCreate( + """ + ID of the order to add the lines to. + """ + id: ID! + + """ + Fields required to add order lines. + """ + input: [OrderLineCreateInput]! + ): OrderLinesCreate + + """ + Deletes an order line from an order. + """ + orderLineDelete( + """ + ID of the order line to delete. + """ + id: ID! + ): OrderLineDelete + + """ + Updates an order line of an order. + """ + orderLineUpdate( + """ + ID of the order line to update. + """ + id: ID! + + """ + Fields required to update an order line. + """ + input: OrderLineInput! + ): OrderLineUpdate + + """ + Adds discount to the order. + """ + orderDiscountAdd( + """ + Fields required to create a discount for the order. + """ + input: OrderDiscountCommonInput! + + """ + ID of an order to discount. + """ + orderId: ID! + ): OrderDiscountAdd + + """ + Update discount for the order. + """ + orderDiscountUpdate( + """ + ID of a discount to update. + """ + discountId: ID! + + """ + Fields required to update a discount for the order. + """ + input: OrderDiscountCommonInput! + ): OrderDiscountUpdate + + """ + Remove discount from the order. + """ + orderDiscountDelete( + """ + ID of a discount to remove. + """ + discountId: ID! + ): OrderDiscountDelete + + """ + Update discount for the order line. + """ + orderLineDiscountUpdate( + """ + Fields required to update price for the order line. + """ + input: OrderDiscountCommonInput! + + """ + ID of a order line to update price + """ + orderLineId: ID! + ): OrderLineDiscountUpdate + + """ + Remove discount applied to the order line. + """ + orderLineDiscountRemove( + """ + ID of a order line to remove its discount + """ + orderLineId: ID! + ): OrderLineDiscountRemove + + """ + Mark order as manually paid. + """ + orderMarkAsPaid( + """ + ID of the order to mark paid. + """ + id: ID! + + """ + The external transaction reference. + """ + transactionReference: String + ): OrderMarkAsPaid + + """ + Refund an order. + """ + orderRefund( + """ + Amount of money to refund. + """ + amount: PositiveDecimal! + + """ + ID of the order to refund. + """ + id: ID! + ): OrderRefund + + """ + Updates an order. + """ + orderUpdate( + """ + ID of an order to update. + """ + id: ID! + + """ + Fields required to update an order. + """ + input: OrderUpdateInput! + ): OrderUpdate + + """ + Updates a shipping method of the order. + """ + orderUpdateShipping( + """ + ID of the order to update a shipping method. + """ + order: ID! + + """ + Fields required to change shipping method of the order. + """ + input: OrderUpdateShippingInput + ): OrderUpdateShipping + + """ + Void an order. + """ + orderVoid( + """ + ID of the order to void. + """ + id: ID! + ): OrderVoid + + """ + Cancels orders. + """ + orderBulkCancel( + """ + List of orders IDs to cancel. + """ + ids: [ID]! + ): OrderBulkCancel + + """ + Delete metadata of an object. + """ + deleteMetadata( + """ + ID of an object to update. + """ + id: ID! + + """ + Metadata keys to delete. + """ + keys: [String!]! + ): DeleteMetadata + + """ + Delete object's private metadata. + """ + deletePrivateMetadata( + """ + ID of an object to update. + """ + id: ID! + + """ + Metadata keys to delete. + """ + keys: [String!]! + ): DeletePrivateMetadata + + """ + Updates metadata of an object. + """ + updateMetadata( + """ + ID of an object to update. + """ + id: ID! + + """ + Fields required to update the object's metadata. + """ + input: [MetadataInput!]! + ): UpdateMetadata + + """ + Updates private metadata of an object. + """ + updatePrivateMetadata( + """ + ID of an object to update. + """ + id: ID! + + """ + Fields required to update the object's metadata. + """ + input: [MetadataInput!]! + ): UpdatePrivateMetadata + + """ + Assigns storefront's navigation menus. + """ + assignNavigation( + """ + ID of the menu. + """ + menu: ID + + """ + Type of the navigation bar to assign the menu to. + """ + navigationType: NavigationType! + ): AssignNavigation + + """ + Creates a new Menu. + """ + menuCreate( + """ + Fields required to create a menu. + """ + input: MenuCreateInput! + ): MenuCreate + + """ + Deletes a menu. + """ + menuDelete( + """ + ID of a menu to delete. + """ + id: ID! + ): MenuDelete + + """ + Deletes menus. + """ + menuBulkDelete( + """ + List of menu IDs to delete. + """ + ids: [ID]! + ): MenuBulkDelete + + """ + Updates a menu. + """ + menuUpdate( + """ + ID of a menu to update. + """ + id: ID! + + """ + Fields required to update a menu. + """ + input: MenuInput! + ): MenuUpdate + + """ + Creates a new menu item. + """ + menuItemCreate( + """ + Fields required to update a menu item. Only one of `url`, `category`, `page`, `collection` is allowed per item. + """ + input: MenuItemCreateInput! + ): MenuItemCreate + + """ + Deletes a menu item. + """ + menuItemDelete( + """ + ID of a menu item to delete. + """ + id: ID! + ): MenuItemDelete + + """ + Deletes menu items. + """ + menuItemBulkDelete( + """ + List of menu item IDs to delete. + """ + ids: [ID]! + ): MenuItemBulkDelete + + """ + Updates a menu item. + """ + menuItemUpdate( + """ + ID of a menu item to update. + """ + id: ID! + + """ + Fields required to update a menu item. Only one of `url`, `category`, `page`, `collection` is allowed per item. + """ + input: MenuItemInput! + ): MenuItemUpdate + + """ + Creates/Updates translations for Menu Item. + """ + menuItemTranslate( + """ + Menu Item ID. + """ + id: ID! + input: NameTranslationInput! + + """ + Translation language code. + """ + languageCode: LanguageCodeEnum! + ): MenuItemTranslate + + """ + Moves items of menus. + """ + menuItemMove( + """ + ID of the menu. + """ + menu: ID! + + """ + The menu position data. + """ + moves: [MenuItemMoveInput]! + ): MenuItemMove + + """ + Request an invoice for the order using plugin. + """ + invoiceRequest( + """ + Invoice number, if not provided it will be generated. + """ + number: String + + """ + ID of the order related to invoice. + """ + orderId: ID! + ): InvoiceRequest + + """ + Requests deletion of an invoice. + """ + invoiceRequestDelete( + """ + ID of an invoice to request the deletion. + """ + id: ID! + ): InvoiceRequestDelete + + """ + Creates a ready to send invoice. + """ + invoiceCreate( + """ + Fields required when creating an invoice. + """ + input: InvoiceCreateInput! + + """ + ID of the order related to invoice. + """ + orderId: ID! + ): InvoiceCreate + + """ + Deletes an invoice. + """ + invoiceDelete( + """ + ID of an invoice to delete. + """ + id: ID! + ): InvoiceDelete + + """ + Updates an invoice. + """ + invoiceUpdate( + """ + ID of an invoice to update. + """ + id: ID! + + """ + Fields to use when updating an invoice. + """ + input: UpdateInvoiceInput! + ): InvoiceUpdate + + """ + Send an invoice notification to the customer. + """ + invoiceSendNotification( + """ + ID of an invoice to be sent. + """ + id: ID! + ): InvoiceSendNotification + + """ + Activate a gift card. + """ + giftCardActivate( + """ + ID of a gift card to activate. + """ + id: ID! + ): GiftCardActivate + + """ + Creates a new gift card. + """ + giftCardCreate( + """ + Fields required to create a gift card. + """ + input: GiftCardCreateInput! + ): GiftCardCreate + + """ + Deactivate a gift card. + """ + giftCardDeactivate( + """ + ID of a gift card to deactivate. + """ + id: ID! + ): GiftCardDeactivate + + """ + Update a gift card. + """ + giftCardUpdate( + """ + ID of a gift card to update. + """ + id: ID! + + """ + Fields required to update a gift card. + """ + input: GiftCardUpdateInput! + ): GiftCardUpdate + + """ + Update plugin configuration. + """ + pluginUpdate( + """ + ID of a channel for which the data should be modified. + """ + channel: ID + + """ + ID of plugin to update. + """ + id: ID! + + """ + Fields required to update a plugin configuration. + """ + input: PluginUpdateInput! + ): PluginUpdate + + """ + Creates a new sale. + """ + saleCreate( + """ + Fields required to create a sale. + """ + input: SaleInput! + ): SaleCreate + + """ + Deletes a sale. + """ + saleDelete( + """ + ID of a sale to delete. + """ + id: ID! + ): SaleDelete + + """ + Deletes sales. + """ + saleBulkDelete( + """ + List of sale IDs to delete. + """ + ids: [ID]! + ): SaleBulkDelete + + """ + Updates a sale. + """ + saleUpdate( + """ + ID of a sale to update. + """ + id: ID! + + """ + Fields required to update a sale. + """ + input: SaleInput! + ): SaleUpdate + + """ + Adds products, categories, collections to a voucher. + """ + saleCataloguesAdd( + """ + ID of a sale. + """ + id: ID! + + """ + Fields required to modify catalogue IDs of sale. + """ + input: CatalogueInput! + ): SaleAddCatalogues + + """ + Removes products, categories, collections from a sale. + """ + saleCataloguesRemove( + """ + ID of a sale. + """ + id: ID! + + """ + Fields required to modify catalogue IDs of sale. + """ + input: CatalogueInput! + ): SaleRemoveCatalogues + + """ + Creates/updates translations for a sale. + """ + saleTranslate( + """ + Voucher ID. + """ + id: ID! + input: NameTranslationInput! + + """ + Translation language code. + """ + languageCode: LanguageCodeEnum! + ): SaleTranslate + + """ + Manage sale's availability in channels. + """ + saleChannelListingUpdate( + """ + ID of a sale to update. + """ + id: ID! + + """ + Fields required to update sale channel listings. + """ + input: SaleChannelListingInput! + ): SaleChannelListingUpdate + + """ + Creates a new voucher. + """ + voucherCreate( + """ + Fields required to create a voucher. + """ + input: VoucherInput! + ): VoucherCreate + + """ + Deletes a voucher. + """ + voucherDelete( + """ + ID of a voucher to delete. + """ + id: ID! + ): VoucherDelete + + """ + Deletes vouchers. + """ + voucherBulkDelete( + """ + List of voucher IDs to delete. + """ + ids: [ID]! + ): VoucherBulkDelete + + """ + Updates a voucher. + """ + voucherUpdate( + """ + ID of a voucher to update. + """ + id: ID! + + """ + Fields required to update a voucher. + """ + input: VoucherInput! + ): VoucherUpdate + + """ + Adds products, categories, collections to a voucher. + """ + voucherCataloguesAdd( + """ + ID of a voucher. + """ + id: ID! + + """ + Fields required to modify catalogue IDs of voucher. + """ + input: CatalogueInput! + ): VoucherAddCatalogues + + """ + Removes products, categories, collections from a voucher. + """ + voucherCataloguesRemove( + """ + ID of a voucher. + """ + id: ID! + + """ + Fields required to modify catalogue IDs of voucher. + """ + input: CatalogueInput! + ): VoucherRemoveCatalogues + + """ + Creates/Updates translations for Voucher. + """ + voucherTranslate( + """ + Voucher ID. + """ + id: ID! + input: NameTranslationInput! + + """ + Translation language code. + """ + languageCode: LanguageCodeEnum! + ): VoucherTranslate + + """ + Manage voucher's availability in channels. + """ + voucherChannelListingUpdate( + """ + ID of a voucher to update. + """ + id: ID! + + """ + Fields required to update voucher channel listings. + """ + input: VoucherChannelListingInput! + ): VoucherChannelListingUpdate + + """ + Export products to csv file. + """ + exportProducts( + """ + Fields required to export product data + """ + input: ExportProductsInput! + ): ExportProducts + + """ + Upload a file. This mutation must be sent as a `multipart` request. More detailed specs of the upload format can be found here: https://github.com/jaydenseric/graphql-multipart-request-spec + """ + fileUpload( + """ + Represents a file in a multipart request. + """ + file: Upload! + ): FileUpload + + """ + Adds a gift card or a voucher to a checkout. + """ + checkoutAddPromoCode( + """ + Checkout ID. + """ + checkoutId: ID! + + """ + Gift card code or voucher code. + """ + promoCode: String! + ): CheckoutAddPromoCode + + """ + Update billing address in the existing checkout. + """ + checkoutBillingAddressUpdate( + """ + The billing address of the checkout. + """ + billingAddress: AddressInput! + + """ + ID of the checkout. + """ + checkoutId: ID! + ): CheckoutBillingAddressUpdate + + """ + Completes the checkout. As a result a new order is created and a payment charge is made. This action requires a successful payment before it can be performed. In case additional confirmation step as 3D secure is required confirmationNeeded flag will be set to True and no order created until payment is confirmed with second call of this mutation. + """ + checkoutComplete( + """ + Checkout ID. + """ + checkoutId: ID! + + """ + Client-side generated data required to finalize the payment. + """ + paymentData: JSONString + + """ + URL of a view where users should be redirected to see the order details. URL in RFC 1808 format. + """ + redirectUrl: String + + """ + Determines whether to store the payment source for future usage. + """ + storeSource: Boolean = false + ): CheckoutComplete + + """ + Create a new checkout. + """ + checkoutCreate( + """ + Fields required to create checkout. + """ + input: CheckoutCreateInput! + ): CheckoutCreate + + """ + Sets the customer as the owner of the checkout. + """ + checkoutCustomerAttach( + """ + ID of the checkout. + """ + checkoutId: ID! + ): CheckoutCustomerAttach + + """ + Removes the user assigned as the owner of the checkout. + """ + checkoutCustomerDetach( + """ + Checkout ID. + """ + checkoutId: ID! + ): CheckoutCustomerDetach + + """ + Updates email address in the existing checkout object. + """ + checkoutEmailUpdate( + """ + Checkout ID. + """ + checkoutId: ID + + """ + email. + """ + email: String! + ): CheckoutEmailUpdate + + """ + Deletes a CheckoutLine. + """ + checkoutLineDelete( + """ + The ID of the checkout. + """ + checkoutId: ID! + + """ + ID of the checkout line to delete. + """ + lineId: ID + ): CheckoutLineDelete + + """ + Adds a checkout line to the existing checkout. + """ + checkoutLinesAdd( + """ + The ID of the checkout. + """ + checkoutId: ID! + + """ + A list of checkout lines, each containing information about an item in the checkout. + """ + lines: [CheckoutLineInput]! + ): CheckoutLinesAdd + + """ + Updates checkout line in the existing checkout. + """ + checkoutLinesUpdate( + """ + The ID of the checkout. + """ + checkoutId: ID! + + """ + A list of checkout lines, each containing information about an item in the checkout. + """ + lines: [CheckoutLineInput]! + ): CheckoutLinesUpdate + + """ + Remove a gift card or a voucher from a checkout. + """ + checkoutRemovePromoCode( + """ + Checkout ID. + """ + checkoutId: ID! + + """ + Gift card code or voucher code. + """ + promoCode: String! + ): CheckoutRemovePromoCode + + """ + Create a new payment for given checkout. + """ + checkoutPaymentCreate( + """ + Checkout ID. + """ + checkoutId: ID! + + """ + Data required to create a new payment. + """ + input: PaymentInput! + ): CheckoutPaymentCreate + + """ + Update shipping address in the existing checkout. + """ + checkoutShippingAddressUpdate( + """ + ID of the checkout. + """ + checkoutId: ID! + + """ + The mailing address to where the checkout will be shipped. + """ + shippingAddress: AddressInput! + ): CheckoutShippingAddressUpdate + + """ + Updates the shipping address of the checkout. + """ + checkoutShippingMethodUpdate( + """ + Checkout ID. + """ + checkoutId: ID + + """ + Shipping method. + """ + shippingMethodId: ID! + ): CheckoutShippingMethodUpdate + + """ + Update language code in the existing checkout. + """ + checkoutLanguageCodeUpdate( + """ + ID of the checkout. + """ + checkoutId: ID! + + """ + New language code. + """ + languageCode: LanguageCodeEnum! + ): CheckoutLanguageCodeUpdate + + """ + Creates new channel. + """ + channelCreate( + """ + Fields required to create channel. + """ + input: ChannelCreateInput! + ): ChannelCreate + + """ + Update a channel. + """ + channelUpdate( + """ + ID of a channel to update. + """ + id: ID! + + """ + Fields required to update a channel. + """ + input: ChannelUpdateInput! + ): ChannelUpdate + + """ + Delete a channel. Orders associated with the deleted channel will be moved to the target channel. Checkouts, product availability, and pricing will be removed. + """ + channelDelete( + """ + ID of a channel to delete. + """ + id: ID! + + """ + Fields required to delete a channel. + """ + input: ChannelDeleteInput + ): ChannelDelete + + """ + Activate a channel. + """ + channelActivate( + """ + ID of the channel to activate. + """ + id: ID! + ): ChannelActivate + + """ + Deactivate a channel. + """ + channelDeactivate( + """ + ID of the channel to deactivate. + """ + id: ID! + ): ChannelDeactivate + + """ + Creates an attribute. + """ + attributeCreate( + """ + Fields required to create an attribute. + """ + input: AttributeCreateInput! + ): AttributeCreate + + """ + Deletes an attribute. + """ + attributeDelete( + """ + ID of an attribute to delete. + """ + id: ID! + ): AttributeDelete + + """ + Updates attribute. + """ + attributeUpdate( + """ + ID of an attribute to update. + """ + id: ID! + + """ + Fields required to update an attribute. + """ + input: AttributeUpdateInput! + ): AttributeUpdate + + """ + Creates/Updates translations for attribute. + """ + attributeTranslate( + """ + Attribute ID. + """ + id: ID! + input: NameTranslationInput! + + """ + Translation language code. + """ + languageCode: LanguageCodeEnum! + ): AttributeTranslate + + """ + Deletes attributes. + """ + attributeBulkDelete( + """ + List of attribute IDs to delete. + """ + ids: [ID]! + ): AttributeBulkDelete + + """ + Deletes values of attributes. + """ + attributeValueBulkDelete( + """ + List of attribute value IDs to delete. + """ + ids: [ID]! + ): AttributeValueBulkDelete + + """ + Creates a value for an attribute. + """ + attributeValueCreate( + """ + Attribute to which value will be assigned. + """ + attribute: ID! + + """ + Fields required to create an AttributeValue. + """ + input: AttributeValueCreateInput! + ): AttributeValueCreate + + """ + Deletes a value of an attribute. + """ + attributeValueDelete( + """ + ID of a value to delete. + """ + id: ID! + ): AttributeValueDelete + + """ + Updates value of an attribute. + """ + attributeValueUpdate( + """ + ID of an AttributeValue to update. + """ + id: ID! + + """ + Fields required to update an AttributeValue. + """ + input: AttributeValueCreateInput! + ): AttributeValueUpdate + + """ + Creates/Updates translations for attribute value. + """ + attributeValueTranslate( + """ + Attribute Value ID. + """ + id: ID! + input: AttributeValueTranslationInput! + + """ + Translation language code. + """ + languageCode: LanguageCodeEnum! + ): AttributeValueTranslate + + """ + Reorder the values of an attribute. + """ + attributeReorderValues( + """ + ID of an attribute. + """ + attributeId: ID! + + """ + The list of reordering operations for given attribute values. + """ + moves: [ReorderInput]! + ): AttributeReorderValues + + """ + Creates a new app. + """ + appCreate( + """ + Fields required to create a new app. + """ + input: AppInput! + ): AppCreate + + """ + Updates an existing app. + """ + appUpdate( + """ + ID of an app to update. + """ + id: ID! + + """ + Fields required to update an existing app. + """ + input: AppInput! + ): AppUpdate + + """ + Deletes an app. + """ + appDelete( + """ + ID of an app to delete. + """ + id: ID! + ): AppDelete + + """ + Creates a new token. + """ + appTokenCreate( + """ + Fields required to create a new auth token. + """ + input: AppTokenInput! + ): AppTokenCreate + + """ + Deletes an authentication token assigned to app. + """ + appTokenDelete( + """ + ID of an auth token to delete. + """ + id: ID! + ): AppTokenDelete + + """ + Verify provided app token. + """ + appTokenVerify( + """ + App token to verify. + """ + token: String! + ): AppTokenVerify + + """ + Install new app by using app manifest. + """ + appInstall( + """ + Fields required to install a new app. + """ + input: AppInstallInput! + ): AppInstall + + """ + Retry failed installation of new app. + """ + appRetryInstall( + """ + Determine if app will be set active or not. + """ + activateAfterInstallation: Boolean = true + + """ + ID of failed installation. + """ + id: ID! + ): AppRetryInstall + + """ + Delete failed installation. + """ + appDeleteFailedInstallation( + """ + ID of failed installation to delete. + """ + id: ID! + ): AppDeleteFailedInstallation + + """ + Fetch and validate manifest. + """ + appFetchManifest(manifestUrl: String!): AppFetchManifest + + """ + Activate the app. + """ + appActivate( + """ + ID of app to activate. + """ + id: ID! + ): AppActivate + + """ + Deactivate the app. + """ + appDeactivate( + """ + ID of app to deactivate. + """ + id: ID! + ): AppDeactivate + + """ + Create JWT token. + """ + tokenCreate( + """ + Email of a user. + """ + email: String! + + """ + Password of a user. + """ + password: String! + ): CreateToken + + """ + Refresh JWT token. Mutation tries to take refreshToken from the input.If it fails it will try to take refreshToken from the http-only cookie -refreshToken. csrfToken is required when refreshToken is provided as a cookie. + """ + tokenRefresh( + """ + CSRF token required to refresh token. This argument is required when refreshToken is provided as a cookie. + """ + csrfToken: String + + """ + Refresh token. + """ + refreshToken: String + ): RefreshToken + + """ + Verify JWT token. + """ + tokenVerify( + """ + JWT token to validate. + """ + token: String! + ): VerifyToken + + """ + Deactivate all JWT tokens of the currently authenticated user. + """ + tokensDeactivateAll: DeactivateAllUserTokens + + """ + Prepare external authentication url for user by custom plugin. + """ + externalAuthenticationUrl( + """ + The data required by plugin to create external authentication url. + """ + input: JSONString! + + """ + The ID of the authentication plugin. + """ + pluginId: String! + ): ExternalAuthenticationUrl + + """ + Obtain external access tokens for user by custom plugin. + """ + externalObtainAccessTokens( + """ + The data required by plugin to create authentication data. + """ + input: JSONString! + + """ + The ID of the authentication plugin. + """ + pluginId: String! + ): ExternalObtainAccessTokens + + """ + Refresh user's access by custom plugin. + """ + externalRefresh( + """ + The data required by plugin to proceed the refresh process. + """ + input: JSONString! + + """ + The ID of the authentication plugin. + """ + pluginId: String! + ): ExternalRefresh + + """ + Logout user by custom plugin. + """ + externalLogout( + """ + The data required by plugin to proceed the logout process. + """ + input: JSONString! + + """ + The ID of the authentication plugin. + """ + pluginId: String! + ): ExternalLogout + + """ + Verify external authentication data by plugin. + """ + externalVerify( + """ + The data required by plugin to proceed the verification. + """ + input: JSONString! + + """ + The ID of the authentication plugin. + """ + pluginId: String! + ): ExternalVerify + + """ + Sends an email with the account password modification link. + """ + requestPasswordReset( + """ + Slug of a channel which will be used for notify user. Optional when only one channel exists. + """ + channel: String + + """ + Email of the user that will be used for password recovery. + """ + email: String! + + """ + URL of a view where users should be redirected to reset the password. URL in RFC 1808 format. + """ + redirectUrl: String! + ): RequestPasswordReset + + """ + Confirm user account with token sent by email during registration. + """ + confirmAccount( + """ + E-mail of the user performing account confirmation. + """ + email: String! + + """ + A one-time token required to confirm the account. + """ + token: String! + ): ConfirmAccount + + """ + Sets the user's password from the token sent by email using the RequestPasswordReset mutation. + """ + setPassword( + """ + Email of a user. + """ + email: String! + + """ + Password of a user. + """ + password: String! + + """ + A one-time token required to set the password. + """ + token: String! + ): SetPassword + + """ + Change the password of the logged in user. + """ + passwordChange( + """ + New user password. + """ + newPassword: String! + + """ + Current user password. + """ + oldPassword: String! + ): PasswordChange + + """ + Request email change of the logged in user. + """ + requestEmailChange( + """ + Slug of a channel which will be used to notify users. Optional when only one channel exists. + """ + channel: String + + """ + New user email. + """ + newEmail: String! + + """ + User password. + """ + password: String! + + """ + URL of a view where users should be redirected to update the email address. URL in RFC 1808 format. + """ + redirectUrl: String! + ): RequestEmailChange + + """ + Confirm the email change of the logged-in user. + """ + confirmEmailChange( + """ + Slug of a channel which will be used to notify users. Optional when only one channel exists. + """ + channel: String + + """ + A one-time token required to change the email. + """ + token: String! + ): ConfirmEmailChange + + """ + Create a new address for the customer. + """ + accountAddressCreate( + """ + Fields required to create address. + """ + input: AddressInput! + + """ + A type of address. If provided, the new address will be automatically assigned as the customer's default address of that type. + """ + type: AddressTypeEnum + ): AccountAddressCreate + + """ + Updates an address of the logged-in user. + """ + accountAddressUpdate( + """ + ID of the address to update. + """ + id: ID! + + """ + Fields required to update the address. + """ + input: AddressInput! + ): AccountAddressUpdate + + """ + Delete an address of the logged-in user. + """ + accountAddressDelete( + """ + ID of the address to delete. + """ + id: ID! + ): AccountAddressDelete + + """ + Sets a default address for the authenticated user. + """ + accountSetDefaultAddress( + """ + ID of the address to set as default. + """ + id: ID! + + """ + The type of address. + """ + type: AddressTypeEnum! + ): AccountSetDefaultAddress + + """ + Register a new user. + """ + accountRegister( + """ + Fields required to create a user. + """ + input: AccountRegisterInput! + ): AccountRegister + + """ + Updates the account of the logged-in user. + """ + accountUpdate( + """ + Fields required to update the account of the logged-in user. + """ + input: AccountInput! + ): AccountUpdate + + """ + Sends an email with the account removal link for the logged-in user. + """ + accountRequestDeletion( + """ + Slug of a channel which will be used to notify users. Optional when only one channel exists. + """ + channel: String + + """ + URL of a view where users should be redirected to delete their account. URL in RFC 1808 format. + """ + redirectUrl: String! + ): AccountRequestDeletion + + """ + Remove user account. + """ + accountDelete( + """ + A one-time token required to remove account. Sent by email using AccountRequestDeletion mutation. + """ + token: String! + ): AccountDelete + + """ + Creates user address. + """ + addressCreate( + """ + Fields required to create address. + """ + input: AddressInput! + + """ + ID of a user to create address for. + """ + userId: ID! + ): AddressCreate + + """ + Updates an address. + """ + addressUpdate( + """ + ID of the address to update. + """ + id: ID! + + """ + Fields required to update the address. + """ + input: AddressInput! + ): AddressUpdate + + """ + Deletes an address. + """ + addressDelete( + """ + ID of the address to delete. + """ + id: ID! + ): AddressDelete + + """ + Sets a default address for the given user. + """ + addressSetDefault( + """ + ID of the address. + """ + addressId: ID! + + """ + The type of address. + """ + type: AddressTypeEnum! + + """ + ID of the user to change the address for. + """ + userId: ID! + ): AddressSetDefault + + """ + Creates a new customer. + """ + customerCreate( + """ + Fields required to create a customer. + """ + input: UserCreateInput! + ): CustomerCreate + + """ + Updates an existing customer. + """ + customerUpdate( + """ + ID of a customer to update. + """ + id: ID! + + """ + Fields required to update a customer. + """ + input: CustomerInput! + ): CustomerUpdate + + """ + Deletes a customer. + """ + customerDelete( + """ + ID of a customer to delete. + """ + id: ID! + ): CustomerDelete + + """ + Deletes customers. + """ + customerBulkDelete( + """ + List of user IDs to delete. + """ + ids: [ID]! + ): CustomerBulkDelete + + """ + Creates a new staff user. + """ + staffCreate( + """ + Fields required to create a staff user. + """ + input: StaffCreateInput! + ): StaffCreate + + """ + Updates an existing staff user. + """ + staffUpdate( + """ + ID of a staff user to update. + """ + id: ID! + + """ + Fields required to update a staff user. + """ + input: StaffUpdateInput! + ): StaffUpdate + + """ + Deletes a staff user. + """ + staffDelete( + """ + ID of a staff user to delete. + """ + id: ID! + ): StaffDelete + + """ + Deletes staff users. + """ + staffBulkDelete( + """ + List of user IDs to delete. + """ + ids: [ID]! + ): StaffBulkDelete + + """ + Create a user avatar. Only for staff members. This mutation must be sent as a `multipart` request. More detailed specs of the upload format can be found here: https://github.com/jaydenseric/graphql-multipart-request-spec + """ + userAvatarUpdate( + """ + Represents an image file in a multipart request. + """ + image: Upload! + ): UserAvatarUpdate + + """ + Deletes a user avatar. Only for staff members. + """ + userAvatarDelete: UserAvatarDelete + + """ + Activate or deactivate users. + """ + userBulkSetActive( + """ + List of user IDs to (de)activate). + """ + ids: [ID]! + + """ + Determine if users will be set active or not. + """ + isActive: Boolean! + ): UserBulkSetActive + + """ + Create new permission group. + """ + permissionGroupCreate( + """ + Input fields to create permission group. + """ + input: PermissionGroupCreateInput! + ): PermissionGroupCreate + + """ + Update permission group. + """ + permissionGroupUpdate( + """ + ID of the group to update. + """ + id: ID! + + """ + Input fields to create permission group. + """ + input: PermissionGroupUpdateInput! + ): PermissionGroupUpdate + + """ + Delete permission group. + """ + permissionGroupDelete( + """ + ID of the group to delete. + """ + id: ID! + ): PermissionGroupDelete +} + +input NameTranslationInput { + name: String +} + +enum NavigationType { + """ + Main storefront navigation. + """ + MAIN + + """ + Secondary storefront navigation. + """ + SECONDARY +} + +""" +An object with an ID +""" +interface Node { + """ + The ID of the object. + """ + id: ID! +} + +interface ObjectWithMetadata { + """ + List of private metadata items.Requires proper staff permissions to access. + """ + privateMetadata: [MetadataItem]! + + """ + List of public metadata items. Can be accessed without permissions. + """ + metadata: [MetadataItem]! +} + +""" +Represents an order in the shop. +""" +type Order implements Node & ObjectWithMetadata { + """ + The ID of the object. + """ + id: ID! + created: DateTime! + status: OrderStatus! + user: User + trackingClientId: String! + billingAddress: Address + shippingAddress: Address + shippingMethod: ShippingMethod + shippingMethodName: String + channel: Channel! + + """ + Total price of shipping. + """ + shippingPrice: TaxedMoney! + shippingTaxRate: Float! + token: String! + voucher: Voucher + + """ + List of user gift cards. + """ + giftCards: [GiftCard] + displayGrossPrices: Boolean! + customerNote: String! + weight: Weight + redirectUrl: String + + """ + List of private metadata items.Requires proper staff permissions to access. + """ + privateMetadata: [MetadataItem]! + + """ + List of public metadata items. Can be accessed without permissions. + """ + metadata: [MetadataItem]! + + """ + List of shipments for the order. + """ + fulfillments: [Fulfillment]! + + """ + List of order lines. + """ + lines: [OrderLine]! + + """ + List of actions that can be performed in the current state of an order. + """ + actions: [OrderAction]! + + """ + Shipping methods that can be used with this order. + """ + availableShippingMethods: [ShippingMethod] + + """ + List of order invoices. + """ + invoices: [Invoice] + + """ + User-friendly number of an order. + """ + number: String + + """ + The ID of the order that was the base for this order. + """ + original: ID + + """ + The order origin. + """ + origin: OrderOriginEnum! + + """ + Informs if an order is fully paid. + """ + isPaid: Boolean! + + """ + Internal payment status. + """ + paymentStatus: PaymentChargeStatusEnum! + + """ + User-friendly payment status. + """ + paymentStatusDisplay: String! + + """ + List of payments for the order. + """ + payments: [Payment] + + """ + Total amount of the order. + """ + total: TaxedMoney! + + """ + Undiscounted total amount of the order. + """ + undiscountedTotal: TaxedMoney! + + """ + The sum of line prices not including shipping. + """ + subtotal: TaxedMoney! + + """ + User-friendly order status. + """ + statusDisplay: String + + """ + Informs whether a draft order can be finalized(turned into a regular order). + """ + canFinalize: Boolean! + + """ + Amount authorized for the order. + """ + totalAuthorized: Money! + + """ + Amount captured by payment. + """ + totalCaptured: Money! + + """ + List of events associated with the order. + """ + events: [OrderEvent] + + """ + The difference between the paid and the order total amount. + """ + totalBalance: Money! + + """ + Email address of the customer. + """ + userEmail: String + + """ + Returns True, if order requires shipping. + """ + isShippingRequired: Boolean! + languageCode: String! + @deprecated( + reason: "Use the `languageCodeEnum` field to fetch the language code. This field will be removed in Saleor 4.0." + ) + + """ + Order language code. + """ + languageCodeEnum: LanguageCodeEnum! + + """ + Returns applied discount. + """ + discount: Money @deprecated(reason: "Use discounts field. This field will be removed in Saleor 4.0.") + + """ + Discount name. + """ + discountName: String @deprecated(reason: "Use discounts field. This field will be removed in Saleor 4.0.") + + """ + Translated discount name. + """ + translatedDiscountName: String @deprecated(reason: "Use discounts field. This field will be removed in Saleor 4.0.") + + """ + List of all discounts assigned to the order. + """ + discounts: [OrderDiscount!] +} + +enum OrderAction { + """ + Represents the capture action. + """ + CAPTURE + + """ + Represents a mark-as-paid action. + """ + MARK_AS_PAID + + """ + Represents a refund action. + """ + REFUND + + """ + Represents a void action. + """ + VOID +} + +""" +Adds note to the order. +""" +type OrderAddNote { + """ + Order with the note added. + """ + order: Order + + """ + Order note created. + """ + event: OrderEvent + orderErrors: [OrderError!]! @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [OrderError!]! +} + +input OrderAddNoteInput { + """ + Note message. + """ + message: String! +} + +""" +Cancels orders. +""" +type OrderBulkCancel { + """ + Returns how many objects were affected. + """ + count: Int! + orderErrors: [OrderError!]! @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [OrderError!]! +} + +""" +Cancel an order. +""" +type OrderCancel { + """ + Canceled order. + """ + order: Order + orderErrors: [OrderError!]! @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [OrderError!]! +} + +""" +Capture an order. +""" +type OrderCapture { + """ + Captured order. + """ + order: Order + orderErrors: [OrderError!]! @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [OrderError!]! +} + +""" +Confirms an unconfirmed order by changing status to unfulfilled. +""" +type OrderConfirm { + order: Order + orderErrors: [OrderError!]! @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [OrderError!]! +} + +type OrderCountableConnection { + """ + Pagination data for this connection. + """ + pageInfo: PageInfo! + edges: [OrderCountableEdge!]! + + """ + A total count of items in the collection. + """ + totalCount: Int +} + +type OrderCountableEdge { + """ + The item at the end of the edge. + """ + node: Order! + + """ + A cursor for use in pagination. + """ + cursor: String! +} + +enum OrderDirection { + """ + Specifies an ascending sort order. + """ + ASC + + """ + Specifies a descending sort order. + """ + DESC +} + +""" +Contains all details related to the applied discount to the order. +""" +type OrderDiscount implements Node { + """ + The ID of the object. + """ + id: ID! + type: OrderDiscountType! + + """ + Type of the discount: fixed or percent + """ + valueType: DiscountValueTypeEnum! + + """ + Value of the discount. Can store fixed value or percent value + """ + value: PositiveDecimal! + name: String + translatedName: String + + """ + Explanation for the applied discount. + """ + reason: String + + """ + Returns amount of discount. + """ + amount: Money! +} + +""" +Adds discount to the order. +""" +type OrderDiscountAdd { + """ + Order which has been discounted. + """ + order: Order + orderErrors: [OrderError!]! @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [OrderError!]! +} + +input OrderDiscountCommonInput { + """ + Type of the discount: fixed or percent + """ + valueType: DiscountValueTypeEnum! + + """ + Value of the discount. Can store fixed value or percent value + """ + value: PositiveDecimal! + + """ + Explanation for the applied discount. + """ + reason: String +} + +""" +Remove discount from the order. +""" +type OrderDiscountDelete { + """ + Order which has removed discount. + """ + order: Order + orderErrors: [OrderError!]! @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [OrderError!]! +} + +""" +An enumeration. +""" +enum OrderDiscountType { + """ + Voucher + """ + VOUCHER + + """ + Manual + """ + MANUAL +} + +""" +Update discount for the order. +""" +type OrderDiscountUpdate { + """ + Order which has been discounted. + """ + order: Order + orderErrors: [OrderError!]! @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [OrderError!]! +} + +input OrderDraftFilterInput { + customer: String + created: DateRangeInput + search: String + metadata: [MetadataInput] + channels: [ID] +} + +type OrderError { + """ + Name of a field that caused the error. A value of `null` indicates that the error isn't associated with a particular field. + """ + field: String + + """ + The error message. + """ + message: String + + """ + The error code. + """ + code: OrderErrorCode! + + """ + Warehouse ID which causes the error. + """ + warehouse: ID + + """ + Order line ID which causes the error. + """ + orderLine: ID + + """ + List of product variants that are associated with the error + """ + variants: [ID!] + + """ + A type of address that causes the error. + """ + addressType: AddressTypeEnum +} + +""" +An enumeration. +""" +enum OrderErrorCode { + BILLING_ADDRESS_NOT_SET + CANNOT_CANCEL_FULFILLMENT + CANNOT_CANCEL_ORDER + CANNOT_DELETE + CANNOT_DISCOUNT + CANNOT_REFUND + CAPTURE_INACTIVE_PAYMENT + NOT_EDITABLE + FULFILL_ORDER_LINE + GRAPHQL_ERROR + INVALID + PRODUCT_NOT_PUBLISHED + PRODUCT_UNAVAILABLE_FOR_PURCHASE + NOT_FOUND + ORDER_NO_SHIPPING_ADDRESS + PAYMENT_ERROR + PAYMENT_MISSING + REQUIRED + SHIPPING_METHOD_NOT_APPLICABLE + SHIPPING_METHOD_REQUIRED + TAX_ERROR + UNIQUE + VOID_INACTIVE_PAYMENT + ZERO_QUANTITY + INVALID_QUANTITY + INSUFFICIENT_STOCK + DUPLICATED_INPUT_ITEM + NOT_AVAILABLE_IN_CHANNEL + CHANNEL_INACTIVE +} + +""" +History log of the order. +""" +type OrderEvent implements Node { + """ + The ID of the object. + """ + id: ID! + + """ + Date when event happened at in ISO 8601 format. + """ + date: DateTime + + """ + Order event type. + """ + type: OrderEventsEnum + + """ + User who performed the action. + """ + user: User + + """ + Content of the event. + """ + message: String + + """ + Email of the customer. + """ + email: String + + """ + Type of an email sent to the customer. + """ + emailType: OrderEventsEmailsEnum + + """ + Amount of money. + """ + amount: Float + + """ + The payment ID from the payment gateway. + """ + paymentId: String + + """ + The payment gateway of the payment. + """ + paymentGateway: String + + """ + Number of items. + """ + quantity: Int + + """ + Composed ID of the Fulfillment. + """ + composedId: String + + """ + User-friendly number of an order. + """ + orderNumber: String + + """ + Number of an invoice related to the order. + """ + invoiceNumber: String + + """ + List of oversold lines names. + """ + oversoldItems: [String] + + """ + The concerned lines. + """ + lines: [OrderEventOrderLineObject] + + """ + The lines fulfilled. + """ + fulfilledItems: [FulfillmentLine] + + """ + The warehouse were items were restocked. + """ + warehouse: Warehouse + + """ + The transaction reference of captured payment. + """ + transactionReference: String + + """ + Define if shipping costs were included to the refund. + """ + shippingCostsIncluded: Boolean + + """ + The order which is related to this order. + """ + relatedOrder: Order + + """ + The discount applied to the order. + """ + discount: OrderEventDiscountObject +} + +type OrderEventCountableConnection { + """ + Pagination data for this connection. + """ + pageInfo: PageInfo! + edges: [OrderEventCountableEdge!]! + + """ + A total count of items in the collection. + """ + totalCount: Int +} + +type OrderEventCountableEdge { + """ + The item at the end of the edge. + """ + node: OrderEvent! + + """ + A cursor for use in pagination. + """ + cursor: String! +} + +type OrderEventDiscountObject { + """ + Type of the discount: fixed or percent. + """ + valueType: DiscountValueTypeEnum! + + """ + Value of the discount. Can store fixed value or percent value. + """ + value: PositiveDecimal! + + """ + Explanation for the applied discount. + """ + reason: String + + """ + Returns amount of discount. + """ + amount: Money + + """ + Type of the discount: fixed or percent. + """ + oldValueType: DiscountValueTypeEnum + + """ + Value of the discount. Can store fixed value or percent value. + """ + oldValue: PositiveDecimal + + """ + Returns amount of discount. + """ + oldAmount: Money +} + +type OrderEventOrderLineObject { + """ + The variant quantity. + """ + quantity: Int + + """ + The order line. + """ + orderLine: OrderLine + + """ + The variant name. + """ + itemName: String + + """ + The discount applied to the order line. + """ + discount: OrderEventDiscountObject +} + +""" +An enumeration. +""" +enum OrderEventsEmailsEnum { + PAYMENT_CONFIRMATION + CONFIRMED + SHIPPING_CONFIRMATION + TRACKING_UPDATED + ORDER_CONFIRMATION + ORDER_CANCEL + ORDER_REFUND + FULFILLMENT_CONFIRMATION + DIGITAL_LINKS +} + +""" +An enumeration. +""" +enum OrderEventsEnum { + DRAFT_CREATED + DRAFT_CREATED_FROM_REPLACE + ADDED_PRODUCTS + REMOVED_PRODUCTS + PLACED + PLACED_FROM_DRAFT + OVERSOLD_ITEMS + CANCELED + ORDER_MARKED_AS_PAID + ORDER_FULLY_PAID + ORDER_REPLACEMENT_CREATED + ORDER_DISCOUNT_ADDED + ORDER_DISCOUNT_AUTOMATICALLY_UPDATED + ORDER_DISCOUNT_UPDATED + ORDER_DISCOUNT_DELETED + ORDER_LINE_DISCOUNT_UPDATED + ORDER_LINE_DISCOUNT_REMOVED + UPDATED_ADDRESS + EMAIL_SENT + CONFIRMED + PAYMENT_AUTHORIZED + PAYMENT_CAPTURED + EXTERNAL_SERVICE_NOTIFICATION + PAYMENT_REFUNDED + PAYMENT_VOIDED + PAYMENT_FAILED + INVOICE_REQUESTED + INVOICE_GENERATED + INVOICE_UPDATED + INVOICE_SENT + FULFILLMENT_CANCELED + FULFILLMENT_RESTOCKED_ITEMS + FULFILLMENT_FULFILLED_ITEMS + FULFILLMENT_REFUNDED + FULFILLMENT_RETURNED + FULFILLMENT_REPLACED + TRACKING_UPDATED + NOTE_ADDED + OTHER +} + +input OrderFilterInput { + paymentStatus: [PaymentChargeStatusEnum] + status: [OrderStatusFilter] + customer: String + created: DateRangeInput + search: String + metadata: [MetadataInput] + channels: [ID] +} + +""" +Creates new fulfillments for an order. +""" +type OrderFulfill { + """ + List of created fulfillments. + """ + fulfillments: [Fulfillment] + + """ + Fulfilled order. + """ + order: Order + orderErrors: [OrderError!]! @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [OrderError!]! +} + +input OrderFulfillInput { + """ + List of items informing how to fulfill the order. + """ + lines: [OrderFulfillLineInput!]! + + """ + If true, send an email notification to the customer. + """ + notifyCustomer: Boolean +} + +input OrderFulfillLineInput { + """ + The ID of the order line. + """ + orderLineId: ID + + """ + List of stock items to create. + """ + stocks: [OrderFulfillStockInput!]! +} + +input OrderFulfillStockInput { + """ + The number of line items to be fulfilled from given warehouse. + """ + quantity: Int! + + """ + ID of the warehouse from which the item will be fulfilled. + """ + warehouse: ID! +} + +""" +Represents order line of particular order. +""" +type OrderLine implements Node { + """ + The ID of the object. + """ + id: ID! + productName: String! + variantName: String! + productSku: String! + isShippingRequired: Boolean! + quantity: Int! + quantityFulfilled: Int! + unitDiscountReason: String + taxRate: Float! + digitalContentUrl: DigitalContentUrl + + """ + The main thumbnail for the ordered product. + """ + thumbnail( + """ + Size of thumbnail. + """ + size: Int + ): Image + + """ + Price of the single item in the order line. + """ + unitPrice: TaxedMoney! + + """ + Price of the single item in the order line without applied an order line discount. + """ + undiscountedUnitPrice: TaxedMoney! + + """ + The discount applied to the single order line. + """ + unitDiscount: Money! + + """ + Value of the discount. Can store fixed value or percent value + """ + unitDiscountValue: PositiveDecimal! + + """ + Price of the order line. + """ + totalPrice: TaxedMoney! + + """ + A purchased product variant. Note: this field may be null if the variant has been removed from stock at all. + """ + variant: ProductVariant + + """ + Product name in the customer's language + """ + translatedProductName: String! + + """ + Variant name in the customer's language + """ + translatedVariantName: String! + + """ + List of allocations across warehouses. + """ + allocations: [Allocation!] + + """ + Type of the discount: fixed or percent + """ + unitDiscountType: DiscountValueTypeEnum +} + +input OrderLineCreateInput { + """ + Number of variant items ordered. + """ + quantity: Int! + + """ + Product variant ID. + """ + variantId: ID! +} + +""" +Deletes an order line from an order. +""" +type OrderLineDelete { + """ + A related order. + """ + order: Order + + """ + An order line that was deleted. + """ + orderLine: OrderLine + orderErrors: [OrderError!]! @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [OrderError!]! +} + +""" +Remove discount applied to the order line. +""" +type OrderLineDiscountRemove { + """ + Order line which has removed discount. + """ + orderLine: OrderLine + + """ + Order which is related to line which has removed discount. + """ + order: Order + orderErrors: [OrderError!]! @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [OrderError!]! +} + +""" +Update discount for the order line. +""" +type OrderLineDiscountUpdate { + """ + Order line which has been discounted. + """ + orderLine: OrderLine + + """ + Order which is related to the discounted line. + """ + order: Order + orderErrors: [OrderError!]! @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [OrderError!]! +} + +input OrderLineInput { + """ + Number of variant items ordered. + """ + quantity: Int! +} + +""" +Updates an order line of an order. +""" +type OrderLineUpdate { + """ + Related order. + """ + order: Order + orderErrors: [OrderError!]! @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [OrderError!]! + orderLine: OrderLine +} + +""" +Create order lines for an order. +""" +type OrderLinesCreate { + """ + Related order. + """ + order: Order + + """ + List of added order lines. + """ + orderLines: [OrderLine!] + orderErrors: [OrderError!]! @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [OrderError!]! +} + +""" +Mark order as manually paid. +""" +type OrderMarkAsPaid { + """ + Order marked as paid. + """ + order: Order + orderErrors: [OrderError!]! @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [OrderError!]! +} + +""" +An enumeration. +""" +enum OrderOriginEnum { + CHECKOUT + DRAFT + REISSUE +} + +""" +Refund an order. +""" +type OrderRefund { + """ + A refunded order. + """ + order: Order + orderErrors: [OrderError!]! @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [OrderError!]! +} + +input OrderRefundFulfillmentLineInput { + """ + The ID of the fulfillment line to refund. + """ + fulfillmentLineId: ID! + + """ + The number of items to be refunded. + """ + quantity: Int! +} + +input OrderRefundLineInput { + """ + The ID of the order line to refund. + """ + orderLineId: ID! + + """ + The number of items to be refunded. + """ + quantity: Int! +} + +input OrderRefundProductsInput { + """ + List of unfulfilled lines to refund. + """ + orderLines: [OrderRefundLineInput!] + + """ + List of fulfilled lines to refund. + """ + fulfillmentLines: [OrderRefundFulfillmentLineInput!] + + """ + The total amount of refund when the value is provided manually. + """ + amountToRefund: PositiveDecimal + + """ + If true, Saleor will refund shipping costs. If amountToRefund is providedincludeShippingCosts will be ignored. + """ + includeShippingCosts: Boolean = false +} + +input OrderReturnFulfillmentLineInput { + """ + The ID of the fulfillment line to return. + """ + fulfillmentLineId: ID! + + """ + The number of items to be returned. + """ + quantity: Int! + + """ + Determines, if the line should be added to replace order. + """ + replace: Boolean = false +} + +input OrderReturnLineInput { + """ + The ID of the order line to return. + """ + orderLineId: ID! + + """ + The number of items to be returned. + """ + quantity: Int! + + """ + Determines, if the line should be added to replace order. + """ + replace: Boolean = false +} + +input OrderReturnProductsInput { + """ + List of unfulfilled lines to return. + """ + orderLines: [OrderReturnLineInput!] + + """ + List of fulfilled lines to return. + """ + fulfillmentLines: [OrderReturnFulfillmentLineInput!] + + """ + The total amount of refund when the value is provided manually. + """ + amountToRefund: PositiveDecimal + + """ + If true, Saleor will refund shipping costs. If amountToRefund is providedincludeShippingCosts will be ignored. + """ + includeShippingCosts: Boolean = false + + """ + If true, Saleor will call refund action for all lines. + """ + refund: Boolean = false +} + +""" +Order related settings from site settings. +""" +type OrderSettings { + automaticallyConfirmAllNewOrders: Boolean! +} + +type OrderSettingsError { + """ + Name of a field that caused the error. A value of `null` indicates that the error isn't associated with a particular field. + """ + field: String + + """ + The error message. + """ + message: String + + """ + The error code. + """ + code: OrderSettingsErrorCode! +} + +""" +An enumeration. +""" +enum OrderSettingsErrorCode { + INVALID +} + +""" +Update shop order settings. +""" +type OrderSettingsUpdate { + """ + Order settings. + """ + orderSettings: OrderSettings + orderSettingsErrors: [OrderSettingsError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [OrderSettingsError!]! +} + +input OrderSettingsUpdateInput { + """ + When disabled, all new orders from checkout will be marked as unconfirmed. When enabled orders from checkout will become unfulfilled immediately. + """ + automaticallyConfirmAllNewOrders: Boolean! +} + +enum OrderSortField { + """ + Sort orders by number. + """ + NUMBER + + """ + Sort orders by creation date. + """ + CREATION_DATE + + """ + Sort orders by customer. + """ + CUSTOMER + + """ + Sort orders by payment. + """ + PAYMENT + + """ + Sort orders by fulfillment status. + """ + FULFILLMENT_STATUS +} + +input OrderSortingInput { + """ + Specifies the direction in which to sort products. + """ + direction: OrderDirection! + + """ + Sort orders by the selected field. + """ + field: OrderSortField! +} + +""" +An enumeration. +""" +enum OrderStatus { + """ + Draft + """ + DRAFT + + """ + Unconfirmed + """ + UNCONFIRMED + + """ + Unfulfilled + """ + UNFULFILLED + + """ + Partially fulfilled + """ + PARTIALLY_FULFILLED + + """ + Partially returned + """ + PARTIALLY_RETURNED + + """ + Returned + """ + RETURNED + + """ + Fulfilled + """ + FULFILLED + + """ + Canceled + """ + CANCELED +} + +enum OrderStatusFilter { + READY_TO_FULFILL + READY_TO_CAPTURE + UNFULFILLED + UNCONFIRMED + PARTIALLY_FULFILLED + FULFILLED + CANCELED +} + +""" +Updates an order. +""" +type OrderUpdate { + orderErrors: [OrderError!]! @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [OrderError!]! + order: Order +} + +input OrderUpdateInput { + """ + Billing address of the customer. + """ + billingAddress: AddressInput + + """ + Email address of the customer. + """ + userEmail: String + + """ + Shipping address of the customer. + """ + shippingAddress: AddressInput +} + +""" +Updates a shipping method of the order. +""" +type OrderUpdateShipping { + """ + Order with updated shipping method. + """ + order: Order + orderErrors: [OrderError!]! @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [OrderError!]! +} + +input OrderUpdateShippingInput { + """ + ID of the selected shipping method. + """ + shippingMethod: ID +} + +""" +Void an order. +""" +type OrderVoid { + """ + A voided order. + """ + order: Order + orderErrors: [OrderError!]! @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [OrderError!]! +} + +""" +A static page that can be manually added by a shop operator through the dashboard. +""" +type Page implements Node & ObjectWithMetadata { + """ + The ID of the object. + """ + id: ID! + seoTitle: String + seoDescription: String + title: String! + content: JSONString + publicationDate: Date + isPublished: Boolean! + slug: String! + pageType: PageType! + created: DateTime! + + """ + List of private metadata items.Requires proper staff permissions to access. + """ + privateMetadata: [MetadataItem]! + + """ + List of public metadata items. Can be accessed without permissions. + """ + metadata: [MetadataItem]! + + """ + Content of the page (JSON). + """ + contentJson: JSONString! @deprecated(reason: "Will be removed in Saleor 4.0. Use the `content` field instead.") + + """ + Returns translated page fields for the given language code. + """ + translation( + """ + A language code to return the translation for page. + """ + languageCode: LanguageCodeEnum! + ): PageTranslation + + """ + List of attributes assigned to this product. + """ + attributes: [SelectedAttribute!]! +} + +""" +Assign attributes to a given page type. +""" +type PageAttributeAssign { + """ + The updated page type. + """ + pageType: PageType + pageErrors: [PageError!]! @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [PageError!]! +} + +""" +Unassign attributes from a given page type. +""" +type PageAttributeUnassign { + """ + The updated page type. + """ + pageType: PageType + pageErrors: [PageError!]! @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [PageError!]! +} + +""" +Deletes pages. +""" +type PageBulkDelete { + """ + Returns how many objects were affected. + """ + count: Int! + pageErrors: [PageError!]! @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [PageError!]! +} + +""" +Publish pages. +""" +type PageBulkPublish { + """ + Returns how many objects were affected. + """ + count: Int! + pageErrors: [PageError!]! @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [PageError!]! +} + +type PageCountableConnection { + """ + Pagination data for this connection. + """ + pageInfo: PageInfo! + edges: [PageCountableEdge!]! + + """ + A total count of items in the collection. + """ + totalCount: Int +} + +type PageCountableEdge { + """ + The item at the end of the edge. + """ + node: Page! + + """ + A cursor for use in pagination. + """ + cursor: String! +} + +""" +Creates a new page. +""" +type PageCreate { + pageErrors: [PageError!]! @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [PageError!]! + page: Page +} + +input PageCreateInput { + """ + Page internal name. + """ + slug: String + + """ + Page title. + """ + title: String + + """ + Page content in JSON format. + """ + content: JSONString + + """ + List of attributes. + """ + attributes: [AttributeValueInput!] + + """ + Determines if page is visible in the storefront. + """ + isPublished: Boolean + + """ + Publication date. ISO 8601 standard. + """ + publicationDate: String + + """ + Search engine optimization fields. + """ + seo: SeoInput + + """ + ID of the page type that page belongs to. + """ + pageType: ID! +} + +""" +Deletes a page. +""" +type PageDelete { + pageErrors: [PageError!]! @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [PageError!]! + page: Page +} + +type PageError { + """ + Name of a field that caused the error. A value of `null` indicates that the error isn't associated with a particular field. + """ + field: String + + """ + The error message. + """ + message: String + + """ + The error code. + """ + code: PageErrorCode! + + """ + List of attributes IDs which causes the error. + """ + attributes: [ID!] + + """ + List of attribute values IDs which causes the error. + """ + values: [ID!] +} + +""" +An enumeration. +""" +enum PageErrorCode { + GRAPHQL_ERROR + INVALID + NOT_FOUND + REQUIRED + UNIQUE + DUPLICATED_INPUT_ITEM + ATTRIBUTE_ALREADY_ASSIGNED +} + +input PageFilterInput { + search: String + metadata: [MetadataInput] + pageTypes: [ID] +} + +""" +The Relay compliant `PageInfo` type, containing data necessary to paginate this connection. +""" +type PageInfo { + """ + When paginating forwards, are there more items? + """ + hasNextPage: Boolean! + + """ + When paginating backwards, are there more items? + """ + hasPreviousPage: Boolean! + + """ + When paginating backwards, the cursor to continue. + """ + startCursor: String + + """ + When paginating forwards, the cursor to continue. + """ + endCursor: String +} + +input PageInput { + """ + Page internal name. + """ + slug: String + + """ + Page title. + """ + title: String + + """ + Page content in JSON format. + """ + content: JSONString + + """ + List of attributes. + """ + attributes: [AttributeValueInput!] + + """ + Determines if page is visible in the storefront. + """ + isPublished: Boolean + + """ + Publication date. ISO 8601 standard. + """ + publicationDate: String + + """ + Search engine optimization fields. + """ + seo: SeoInput +} + +""" +Reorder page attribute values. +""" +type PageReorderAttributeValues { + """ + Page from which attribute values are reordered. + """ + page: Page + pageErrors: [PageError!]! @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [PageError!]! +} + +enum PageSortField { + """ + Sort pages by title. + """ + TITLE + + """ + Sort pages by slug. + """ + SLUG + + """ + Sort pages by visibility. + """ + VISIBILITY + + """ + Sort pages by creation date. + """ + CREATION_DATE + + """ + Sort pages by publication date. + """ + PUBLICATION_DATE +} + +input PageSortingInput { + """ + Specifies the direction in which to sort products. + """ + direction: OrderDirection! + + """ + Sort pages by the selected field. + """ + field: PageSortField! +} + +type PageTranslatableContent implements Node { + """ + The ID of the object. + """ + id: ID! + seoTitle: String + seoDescription: String + title: String! + content: JSONString + + """ + Content of the page (JSON). + """ + contentJson: JSONString @deprecated(reason: "Will be removed in Saleor 4.0. Use the `content` field instead.") + + """ + Returns translated page fields for the given language code. + """ + translation( + """ + A language code to return the translation for page. + """ + languageCode: LanguageCodeEnum! + ): PageTranslation + + """ + ('A static page that can be manually added by a shop operator ', 'through the dashboard.') + """ + page: Page +} + +""" +Creates/Updates translations for Page. +""" +type PageTranslate { + translationErrors: [TranslationError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [TranslationError!]! + page: PageTranslatableContent +} + +type PageTranslation implements Node { + """ + The ID of the object. + """ + id: ID! + seoTitle: String + seoDescription: String + title: String! + content: JSONString + + """ + Translation language. + """ + language: LanguageDisplay! + + """ + Translated description of the page (JSON). + """ + contentJson: JSONString @deprecated(reason: "Will be removed in Saleor 4.0. Use the `content` field instead.") +} + +input PageTranslationInput { + seoTitle: String + seoDescription: String + title: String + content: JSONString +} + +""" +Represents a type of page. It defines what attributes are available to pages of this type. +""" +type PageType implements Node & ObjectWithMetadata { + """ + The ID of the object. + """ + id: ID! + name: String! + slug: String! + + """ + List of private metadata items.Requires proper staff permissions to access. + """ + privateMetadata: [MetadataItem]! + + """ + List of public metadata items. Can be accessed without permissions. + """ + metadata: [MetadataItem]! + + """ + Page attributes of that page type. + """ + attributes: [Attribute] + + """ + Attributes that can be assigned to the page type. + """ + availableAttributes( + filter: AttributeFilterInput + + """ + Return the elements in the list that come before the specified cursor. + """ + before: String + + """ + Return the elements in the list that come after the specified cursor. + """ + after: String + + """ + Return the first n elements from the list. + """ + first: Int + + """ + Return the last n elements from the list. + """ + last: Int + ): AttributeCountableConnection + + """ + Whether page type has pages assigned. + """ + hasPages: Boolean +} + +""" +Delete page types. +""" +type PageTypeBulkDelete { + """ + Returns how many objects were affected. + """ + count: Int! + pageErrors: [PageError!]! @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [PageError!]! +} + +type PageTypeCountableConnection { + """ + Pagination data for this connection. + """ + pageInfo: PageInfo! + edges: [PageTypeCountableEdge!]! + + """ + A total count of items in the collection. + """ + totalCount: Int +} + +type PageTypeCountableEdge { + """ + The item at the end of the edge. + """ + node: PageType! + + """ + A cursor for use in pagination. + """ + cursor: String! +} + +""" +Create a new page type. +""" +type PageTypeCreate { + pageErrors: [PageError!]! @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [PageError!]! + pageType: PageType +} + +input PageTypeCreateInput { + """ + Name of the page type. + """ + name: String + + """ + Page type slug. + """ + slug: String + + """ + List of attribute IDs to be assigned to the page type. + """ + addAttributes: [ID!] +} + +""" +Delete a page type. +""" +type PageTypeDelete { + pageErrors: [PageError!]! @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [PageError!]! + pageType: PageType +} + +input PageTypeFilterInput { + search: String +} + +""" +Reorder the attributes of a page type. +""" +type PageTypeReorderAttributes { + """ + Page type from which attributes are reordered. + """ + pageType: PageType + pageErrors: [PageError!]! @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [PageError!]! +} + +enum PageTypeSortField { + """ + Sort page types by name. + """ + NAME + + """ + Sort page types by slug. + """ + SLUG +} + +input PageTypeSortingInput { + """ + Specifies the direction in which to sort products. + """ + direction: OrderDirection! + + """ + Sort page types by the selected field. + """ + field: PageTypeSortField! +} + +""" +Update page type. +""" +type PageTypeUpdate { + pageErrors: [PageError!]! @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [PageError!]! + pageType: PageType +} + +input PageTypeUpdateInput { + """ + Name of the page type. + """ + name: String + + """ + Page type slug. + """ + slug: String + + """ + List of attribute IDs to be assigned to the page type. + """ + addAttributes: [ID!] + + """ + List of attribute IDs to be assigned to the page type. + """ + removeAttributes: [ID!] +} + +""" +Updates an existing page. +""" +type PageUpdate { + pageErrors: [PageError!]! @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [PageError!]! + page: Page +} + +""" +Change the password of the logged in user. +""" +type PasswordChange { + """ + A user instance with a new password. + """ + user: User + accountErrors: [AccountError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [AccountError!]! +} + +""" +Represents a payment of a given type. +""" +type Payment implements Node { + """ + The ID of the object. + """ + id: ID! + gateway: String! + isActive: Boolean! + created: DateTime! + modified: DateTime! + token: String! + checkout: Checkout + order: Order + paymentMethodType: String! + customerIpAddress: String + + """ + Internal payment status. + """ + chargeStatus: PaymentChargeStatusEnum! + + """ + List of actions that can be performed in the current state of a payment. + """ + actions: [OrderAction]! + + """ + Total amount of the payment. + """ + total: Money + + """ + Total amount captured for this payment. + """ + capturedAmount: Money + + """ + List of all transactions within this payment. + """ + transactions: [Transaction] + + """ + Maximum amount of money that can be captured. + """ + availableCaptureAmount: Money + + """ + Maximum amount of money that can be refunded. + """ + availableRefundAmount: Money + + """ + The details of the card used for this payment. + """ + creditCard: CreditCard +} + +""" +Captures the authorized payment amount. +""" +type PaymentCapture { + """ + Updated payment. + """ + payment: Payment + paymentErrors: [PaymentError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [PaymentError!]! +} + +""" +An enumeration. +""" +enum PaymentChargeStatusEnum { + NOT_CHARGED + PENDING + PARTIALLY_CHARGED + FULLY_CHARGED + PARTIALLY_REFUNDED + FULLY_REFUNDED + REFUSED + CANCELLED +} + +type PaymentCountableConnection { + """ + Pagination data for this connection. + """ + pageInfo: PageInfo! + edges: [PaymentCountableEdge!]! + + """ + A total count of items in the collection. + """ + totalCount: Int +} + +type PaymentCountableEdge { + """ + The item at the end of the edge. + """ + node: Payment! + + """ + A cursor for use in pagination. + """ + cursor: String! +} + +type PaymentError { + """ + Name of a field that caused the error. A value of `null` indicates that the error isn't associated with a particular field. + """ + field: String + + """ + The error message. + """ + message: String + + """ + The error code. + """ + code: PaymentErrorCode! +} + +""" +An enumeration. +""" +enum PaymentErrorCode { + BILLING_ADDRESS_NOT_SET + GRAPHQL_ERROR + INVALID + NOT_FOUND + REQUIRED + UNIQUE + PARTIAL_PAYMENT_NOT_ALLOWED + SHIPPING_ADDRESS_NOT_SET + INVALID_SHIPPING_METHOD + SHIPPING_METHOD_NOT_SET + PAYMENT_ERROR + NOT_SUPPORTED_GATEWAY + CHANNEL_INACTIVE +} + +input PaymentFilterInput { + checkouts: [ID] +} + +""" +Available payment gateway backend with configuration necessary to setup client. +""" +type PaymentGateway { + """ + Payment gateway name. + """ + name: String! + + """ + Payment gateway ID. + """ + id: ID! + + """ + Payment gateway client configuration. + """ + config: [GatewayConfigLine!]! + + """ + Payment gateway supported currencies. + """ + currencies: [String]! +} + +""" +Initializes payment process when it is required by gateway. +""" +type PaymentInitialize { + initializedPayment: PaymentInitialized + paymentErrors: [PaymentError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [PaymentError!]! +} + +""" +Server-side data generated by a payment gateway. Optional step when the payment provider requires an additional action to initialize payment session. +""" +type PaymentInitialized { + """ + ID of a payment gateway. + """ + gateway: String! + + """ + Payment gateway name. + """ + name: String! + + """ + Initialized data by gateway. + """ + data: JSONString +} + +input PaymentInput { + """ + A gateway to use with that payment. + """ + gateway: String! + + """ + Client-side generated payment token, representing customer's billing data in a secure manner. + """ + token: String + + """ + Total amount of the transaction, including all taxes and discounts. If no amount is provided, the checkout total will be used. + """ + amount: PositiveDecimal + + """ + URL of a storefront view where user should be redirected after requiring additional actions. Payment with additional actions will not be finished if this field is not provided. + """ + returnUrl: String +} + +""" +Refunds the captured payment amount. +""" +type PaymentRefund { + """ + Updated payment. + """ + payment: Payment + paymentErrors: [PaymentError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [PaymentError!]! +} + +""" +Represents a payment source stored for user in payment gateway, such as credit card. +""" +type PaymentSource { + """ + Payment gateway name. + """ + gateway: String! + + """ + Stored credit card details if available. + """ + creditCardInfo: CreditCard +} + +""" +Voids the authorized payment. +""" +type PaymentVoid { + """ + Updated payment. + """ + payment: Payment + paymentErrors: [PaymentError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [PaymentError!]! +} + +""" +Represents a permission object in a friendly form. +""" +type Permission { + """ + Internal code for permission. + """ + code: PermissionEnum! + + """ + Describe action(s) allowed to do by permission. + """ + name: String! +} + +""" +An enumeration. +""" +enum PermissionEnum { + MANAGE_USERS + MANAGE_STAFF + MANAGE_APPS + MANAGE_CHANNELS + MANAGE_DISCOUNTS + MANAGE_PLUGINS + MANAGE_GIFT_CARD + MANAGE_MENUS + MANAGE_ORDERS + MANAGE_PAGES + MANAGE_PAGE_TYPES_AND_ATTRIBUTES + MANAGE_PRODUCTS + MANAGE_PRODUCT_TYPES_AND_ATTRIBUTES + MANAGE_SHIPPING + MANAGE_SETTINGS + MANAGE_TRANSLATIONS + MANAGE_CHECKOUTS +} + +""" +Create new permission group. +""" +type PermissionGroupCreate { + permissionGroupErrors: [PermissionGroupError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [PermissionGroupError!]! + group: Group +} + +input PermissionGroupCreateInput { + """ + List of permission code names to assign to this group. + """ + addPermissions: [PermissionEnum!] + + """ + List of users to assign to this group. + """ + addUsers: [ID!] + + """ + Group name. + """ + name: String! +} + +""" +Delete permission group. +""" +type PermissionGroupDelete { + permissionGroupErrors: [PermissionGroupError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [PermissionGroupError!]! + group: Group +} + +type PermissionGroupError { + """ + Name of a field that caused the error. A value of `null` indicates that the error isn't associated with a particular field. + """ + field: String + + """ + The error message. + """ + message: String + + """ + The error code. + """ + code: PermissionGroupErrorCode! + + """ + List of permissions which causes the error. + """ + permissions: [PermissionEnum!] + + """ + List of user IDs which causes the error. + """ + users: [ID!] +} + +""" +An enumeration. +""" +enum PermissionGroupErrorCode { + ASSIGN_NON_STAFF_MEMBER + DUPLICATED_INPUT_ITEM + CANNOT_REMOVE_FROM_LAST_GROUP + LEFT_NOT_MANAGEABLE_PERMISSION + OUT_OF_SCOPE_PERMISSION + OUT_OF_SCOPE_USER + REQUIRED + UNIQUE +} + +input PermissionGroupFilterInput { + search: String +} + +enum PermissionGroupSortField { + """ + Sort permission group accounts by name. + """ + NAME +} + +input PermissionGroupSortingInput { + """ + Specifies the direction in which to sort products. + """ + direction: OrderDirection! + + """ + Sort permission group by the selected field. + """ + field: PermissionGroupSortField! +} + +""" +Update permission group. +""" +type PermissionGroupUpdate { + permissionGroupErrors: [PermissionGroupError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [PermissionGroupError!]! + group: Group +} + +input PermissionGroupUpdateInput { + """ + List of permission code names to assign to this group. + """ + addPermissions: [PermissionEnum!] + + """ + List of users to assign to this group. + """ + addUsers: [ID!] + + """ + Group name. + """ + name: String + + """ + List of permission code names to unassign from this group. + """ + removePermissions: [PermissionEnum!] + + """ + List of users to unassign from this group. + """ + removeUsers: [ID!] +} + +""" +Plugin. +""" +type Plugin { + """ + Identifier of the plugin. + """ + id: ID! + + """ + Name of the plugin. + """ + name: String! + + """ + Description of the plugin. + """ + description: String! + + """ + Global configuration of the plugin (not channel-specific). + """ + globalConfiguration: PluginConfiguration + + """ + Channel-specific plugin configuration. + """ + channelConfigurations: [PluginConfiguration!]! +} + +""" +Stores information about a configuration of plugin. +""" +type PluginConfiguration { + """ + Determines if plugin is active or not. + """ + active: Boolean! + + """ + The channel to which the plugin configuration is assigned to. + """ + channel: Channel + + """ + Configuration of the plugin. + """ + configuration: [ConfigurationItem] +} + +enum PluginConfigurationType { + PER_CHANNEL + GLOBAL +} + +type PluginCountableConnection { + """ + Pagination data for this connection. + """ + pageInfo: PageInfo! + edges: [PluginCountableEdge!]! + + """ + A total count of items in the collection. + """ + totalCount: Int +} + +type PluginCountableEdge { + """ + The item at the end of the edge. + """ + node: Plugin! + + """ + A cursor for use in pagination. + """ + cursor: String! +} + +type PluginError { + """ + Name of a field that caused the error. A value of `null` indicates that the error isn't associated with a particular field. + """ + field: String + + """ + The error message. + """ + message: String + + """ + The error code. + """ + code: PluginErrorCode! +} + +""" +An enumeration. +""" +enum PluginErrorCode { + GRAPHQL_ERROR + INVALID + PLUGIN_MISCONFIGURED + NOT_FOUND + REQUIRED + UNIQUE +} + +input PluginFilterInput { + statusInChannels: PluginStatusInChannelsInput + search: String + type: PluginConfigurationType +} + +enum PluginSortField { + NAME + IS_ACTIVE +} + +input PluginSortingInput { + """ + Specifies the direction in which to sort products. + """ + direction: OrderDirection! + + """ + Sort plugins by the selected field. + """ + field: PluginSortField! +} + +input PluginStatusInChannelsInput { + active: Boolean! + channels: [ID!]! +} + +""" +Update plugin configuration. +""" +type PluginUpdate { + plugin: Plugin + pluginsErrors: [PluginError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [PluginError!]! +} + +input PluginUpdateInput { + """ + Indicates whether the plugin should be enabled. + """ + active: Boolean + + """ + Configuration of the plugin. + """ + configuration: [ConfigurationItemInput] +} + +""" +Positive Decimal scalar implementation. + +Should be used in places where value must be positive. +""" +scalar PositiveDecimal + +""" +An enumeration. +""" +enum PostalCodeRuleInclusionTypeEnum { + INCLUDE + EXCLUDE +} + +input PriceRangeInput { + """ + Price greater than or equal to. + """ + gte: Float + + """ + Price less than or equal to. + """ + lte: Float +} + +""" +Represents an individual item for sale in the storefront. +""" +type Product implements Node & ObjectWithMetadata { + """ + The ID of the object. + """ + id: ID! + seoTitle: String + seoDescription: String + name: String! + description: JSONString + productType: ProductType! + slug: String! + category: Category + updatedAt: DateTime + chargeTaxes: Boolean! + weight: Weight + defaultVariant: ProductVariant + rating: Float + + """ + List of private metadata items.Requires proper staff permissions to access. + """ + privateMetadata: [MetadataItem]! + + """ + List of public metadata items. Can be accessed without permissions. + """ + metadata: [MetadataItem]! + + """ + Description of the product (JSON). + """ + descriptionJson: JSONString @deprecated(reason: "Will be removed in Saleor 4.0. Use the `description` field instead.") + + """ + The main thumbnail for a product. + """ + thumbnail( + """ + Size of thumbnail. + """ + size: Int + ): Image + + """ + Lists the storefront product's pricing, the current price and discounts, only meant for displaying. + """ + pricing( + """ + Destination address used to find warehouses where stock availability for this product is checked. If address is empty, uses `Shop.companyAddress` or fallbacks to server's `settings.DEFAULT_COUNTRY` configuration. + """ + address: AddressInput + ): ProductPricingInfo + + """ + Whether the product is in stock and visible or not. + """ + isAvailable( + """ + Destination address used to find warehouses where stock availability for this product is checked. If address is empty, uses `Shop.companyAddress` or fallbacks to server's `settings.DEFAULT_COUNTRY` configuration. + """ + address: AddressInput + ): Boolean + + """ + A type of tax. Assigned by enabled tax gateway + """ + taxType: TaxType + + """ + List of attributes assigned to this product. + """ + attributes: [SelectedAttribute!]! + + """ + List of availability in channels for the product. + """ + channelListings: [ProductChannelListing!] + + """ + Get a single product media by ID. + """ + mediaById( + """ + ID of a product media. + """ + id: ID + ): ProductMedia! + + """ + Get a single product image by ID. + """ + imageById( + """ + ID of a product image. + """ + id: ID + ): ProductImage @deprecated(reason: "Will be removed in Saleor 4.0. Use the `mediaById` field instead.") + + """ + List of variants for the product. + """ + variants: [ProductVariant] + + """ + List of media for the product. + """ + media: [ProductMedia!] + + """ + List of images for the product. + """ + images: [ProductImage] @deprecated(reason: "Will be removed in Saleor 4.0. Use the `media` field instead.") + + """ + List of collections for the product. + """ + collections: [Collection] + + """ + Returns translated product fields for the given language code. + """ + translation( + """ + A language code to return the translation for product. + """ + languageCode: LanguageCodeEnum! + ): ProductTranslation + + """ + Date when product is available for purchase. + """ + availableForPurchase: Date + + """ + Whether the product is available for purchase. + """ + isAvailableForPurchase: Boolean +} + +""" +Assign attributes to a given product type. +""" +type ProductAttributeAssign { + """ + The updated product type. + """ + productType: ProductType + productErrors: [ProductError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [ProductError!]! +} + +input ProductAttributeAssignInput { + """ + The ID of the attribute to assign. + """ + id: ID! + + """ + The attribute type to be assigned as. + """ + type: ProductAttributeType! +} + +enum ProductAttributeType { + PRODUCT + VARIANT +} + +""" +Un-assign attributes from a given product type. +""" +type ProductAttributeUnassign { + """ + The updated product type. + """ + productType: ProductType + productErrors: [ProductError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [ProductError!]! +} + +""" +Deletes products. +""" +type ProductBulkDelete { + """ + Returns how many objects were affected. + """ + count: Int! + productErrors: [ProductError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [ProductError!]! +} + +""" +Represents product channel listing. +""" +type ProductChannelListing implements Node { + """ + The ID of the object. + """ + id: ID! + publicationDate: Date + isPublished: Boolean! + channel: Channel! + visibleInListings: Boolean! + availableForPurchase: Date + + """ + The price of the cheapest variant (including discounts). + """ + discountedPrice: Money + + """ + Purchase cost of product. + """ + purchaseCost: MoneyRange + + """ + Range of margin percentage value. + """ + margin: Margin + + """ + Whether the product is available for purchase. + """ + isAvailableForPurchase: Boolean + + """ + Lists the storefront product's pricing, the current price and discounts, only meant for displaying. + """ + pricing( + """ + Destination address used to find warehouses where stock availability for this product is checked. If address is empty, uses `Shop.companyAddress` or fallbacks to server's `settings.DEFAULT_COUNTRY` configuration. + """ + address: AddressInput + ): ProductPricingInfo +} + +input ProductChannelListingAddInput { + """ + ID of a channel. + """ + channelId: ID! + + """ + Determines if object is visible to customers. + """ + isPublished: Boolean + + """ + Publication date. ISO 8601 standard. + """ + publicationDate: Date + + """ + Determines if product is visible in product listings (doesn't apply to product collections). + """ + visibleInListings: Boolean + + """ + Determine if product should be available for purchase. + """ + isAvailableForPurchase: Boolean + + """ + A start date from which a product will be available for purchase. When not set and isAvailable is set to True, the current day is assumed. + """ + availableForPurchaseDate: Date + + """ + List of variants to which the channel should be assigned. + """ + addVariants: [ID!] + + """ + List of variants from which the channel should be unassigned. + """ + removeVariants: [ID!] +} + +type ProductChannelListingError { + """ + Name of a field that caused the error. A value of `null` indicates that the error isn't associated with a particular field. + """ + field: String + + """ + The error message. + """ + message: String + + """ + The error code. + """ + code: ProductErrorCode! + + """ + List of attributes IDs which causes the error. + """ + attributes: [ID!] + + """ + List of attribute values IDs which causes the error. + """ + values: [ID!] + + """ + List of channels IDs which causes the error. + """ + channels: [ID!] + + """ + List of variants IDs which causes the error. + """ + variants: [ID!] +} + +""" +Manage product's availability in channels. +""" +type ProductChannelListingUpdate { + """ + An updated product instance. + """ + product: Product + productChannelListingErrors: [ProductChannelListingError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [ProductChannelListingError!]! +} + +input ProductChannelListingUpdateInput { + """ + List of channels to which the product should be assigned or updated. + """ + updateChannels: [ProductChannelListingAddInput!] + + """ + List of channels from which the product should be unassigned. + """ + removeChannels: [ID!] +} + +type ProductCountableConnection { + """ + Pagination data for this connection. + """ + pageInfo: PageInfo! + edges: [ProductCountableEdge!]! + + """ + A total count of items in the collection. + """ + totalCount: Int +} + +type ProductCountableEdge { + """ + The item at the end of the edge. + """ + node: Product! + + """ + A cursor for use in pagination. + """ + cursor: String! +} + +""" +Creates a new product. +""" +type ProductCreate { + productErrors: [ProductError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [ProductError!]! + product: Product +} + +input ProductCreateInput { + """ + List of attributes. + """ + attributes: [AttributeValueInput!] + + """ + ID of the product's category. + """ + category: ID + + """ + Determine if taxes are being charged for the product. + """ + chargeTaxes: Boolean + + """ + List of IDs of collections that the product belongs to. + """ + collections: [ID!] + + """ + Product description (JSON). + """ + description: JSONString + + """ + Product name. + """ + name: String + + """ + Product slug. + """ + slug: String + + """ + Tax rate for enabled tax gateway. + """ + taxCode: String + + """ + Search engine optimization fields. + """ + seo: SeoInput + + """ + Weight of the Product. + """ + weight: WeightScalar + + """ + Defines the product rating value. + """ + rating: Float + + """ + ID of the type that product belongs to. + """ + productType: ID! +} + +""" +Deletes a product. +""" +type ProductDelete { + productErrors: [ProductError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [ProductError!]! + product: Product +} + +type ProductError { + """ + Name of a field that caused the error. A value of `null` indicates that the error isn't associated with a particular field. + """ + field: String + + """ + The error message. + """ + message: String + + """ + The error code. + """ + code: ProductErrorCode! + + """ + List of attributes IDs which causes the error. + """ + attributes: [ID!] + + """ + List of attribute values IDs which causes the error. + """ + values: [ID!] +} + +""" +An enumeration. +""" +enum ProductErrorCode { + ALREADY_EXISTS + ATTRIBUTE_ALREADY_ASSIGNED + ATTRIBUTE_CANNOT_BE_ASSIGNED + ATTRIBUTE_VARIANTS_DISABLED + DUPLICATED_INPUT_ITEM + GRAPHQL_ERROR + INVALID + PRODUCT_WITHOUT_CATEGORY + NOT_PRODUCTS_IMAGE + NOT_PRODUCTS_VARIANT + NOT_FOUND + REQUIRED + UNIQUE + VARIANT_NO_DIGITAL_CONTENT + CANNOT_MANAGE_PRODUCT_WITHOUT_VARIANT + PRODUCT_NOT_ASSIGNED_TO_CHANNEL + UNSUPPORTED_MEDIA_PROVIDER +} + +enum ProductFieldEnum { + NAME + DESCRIPTION + PRODUCT_TYPE + CATEGORY + PRODUCT_WEIGHT + COLLECTIONS + CHARGE_TAXES + PRODUCT_MEDIA + VARIANT_SKU + VARIANT_WEIGHT + VARIANT_MEDIA +} + +input ProductFilterInput { + isPublished: Boolean + collections: [ID] + categories: [ID] + hasCategory: Boolean + attributes: [AttributeInput] + stockAvailability: StockAvailability + stocks: ProductStockFilterInput + search: String + metadata: [MetadataInput] + price: PriceRangeInput + minimalPrice: PriceRangeInput + productTypes: [ID] + ids: [ID] + + """ + Specifies the channel by which the data should be sorted. + """ + channel: String +} + +""" +Represents a product image. +""" +type ProductImage { + """ + The ID of the image. + """ + id: ID! + + """ + The alt text of the image. + """ + alt: String + + """ + The new relative sorting position of the item (from -inf to +inf). 1 moves the item one position forward, -1 moves the item one position backward, 0 leaves the item unchanged. + """ + sortOrder: Int + + """ + The URL of the image. + """ + url( + """ + Size of the image. + """ + size: Int + ): String! +} + +input ProductInput { + """ + List of attributes. + """ + attributes: [AttributeValueInput!] + + """ + ID of the product's category. + """ + category: ID + + """ + Determine if taxes are being charged for the product. + """ + chargeTaxes: Boolean + + """ + List of IDs of collections that the product belongs to. + """ + collections: [ID!] + + """ + Product description (JSON). + """ + description: JSONString + + """ + Product name. + """ + name: String + + """ + Product slug. + """ + slug: String + + """ + Tax rate for enabled tax gateway. + """ + taxCode: String + + """ + Search engine optimization fields. + """ + seo: SeoInput + + """ + Weight of the Product. + """ + weight: WeightScalar + + """ + Defines the product rating value. + """ + rating: Float +} + +""" +Represents a product media. +""" +type ProductMedia implements Node { + """ + The ID of the object. + """ + id: ID! + sortOrder: Int + alt: String! + type: ProductMediaType! + oembedData: JSONString! + + """ + The URL of the media. + """ + url( + """ + Size of the image. + """ + size: Int + ): String! +} + +""" +Deletes product media. +""" +type ProductMediaBulkDelete { + """ + Returns how many objects were affected. + """ + count: Int! + productErrors: [ProductError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [ProductError!]! +} + +""" +Create a media object (image or video URL) associated with product. For image, this mutation must be sent as a `multipart` request. More detailed specs of the upload format can be found here: https://github.com/jaydenseric/graphql-multipart-request-spec +""" +type ProductMediaCreate { + product: Product + media: ProductMedia + productErrors: [ProductError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [ProductError!]! +} + +input ProductMediaCreateInput { + """ + Alt text for a product media. + """ + alt: String + + """ + Represents an image file in a multipart request. + """ + image: Upload + + """ + ID of an product. + """ + product: ID! + + """ + Represents an URL to an external media. + """ + mediaUrl: String +} + +""" +Deletes a product media. +""" +type ProductMediaDelete { + product: Product + media: ProductMedia + productErrors: [ProductError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [ProductError!]! +} + +""" +Changes ordering of the product media. +""" +type ProductMediaReorder { + product: Product + media: [ProductMedia!] + productErrors: [ProductError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [ProductError!]! +} + +""" +An enumeration. +""" +enum ProductMediaType { + """ + An uploaded image or an URL to an image + """ + IMAGE + + """ + A URL to an external video + """ + VIDEO +} + +""" +Updates a product media. +""" +type ProductMediaUpdate { + product: Product + media: ProductMedia + productErrors: [ProductError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [ProductError!]! +} + +input ProductMediaUpdateInput { + """ + Alt text for a product media. + """ + alt: String +} + +input ProductOrder { + """ + Specifies the direction in which to sort products. + """ + direction: OrderDirection! + + """ + Specifies the channel in which to sort the data. + """ + channel: String + + """ + Sort product by the selected attribute's values. + Note: this doesn't take translations into account yet. + """ + attributeId: ID + + """ + Sort products by the selected field. + """ + field: ProductOrderField +} + +enum ProductOrderField { + """ + Sort products by name. + """ + NAME + + """ + Sort products by rank. Note: This option is available only with the `search` filter. + """ + RANK + + """ + Sort products by price. + """ + PRICE + + """ + Sort products by a minimal price of a product's variant. + """ + MINIMAL_PRICE + + """ + Sort products by update date. + """ + DATE + + """ + Sort products by type. + """ + TYPE + + """ + Sort products by publication status. + """ + PUBLISHED + + """ + Sort products by publication date. + """ + PUBLICATION_DATE + + """ + Sort products by collection. Note: This option is available only for the `Collection.products` query. + """ + COLLECTION + + """ + Sort products by rating. + """ + RATING +} + +""" +Represents availability of a product in the storefront. +""" +type ProductPricingInfo { + """ + Whether it is in sale or not. + """ + onSale: Boolean + + """ + The discount amount if in sale (null otherwise). + """ + discount: TaxedMoney + + """ + The discount amount in the local currency. + """ + discountLocalCurrency: TaxedMoney + + """ + The discounted price range of the product variants. + """ + priceRange: TaxedMoneyRange + + """ + The undiscounted price range of the product variants. + """ + priceRangeUndiscounted: TaxedMoneyRange + + """ + The discounted price range of the product variants in the local currency. + """ + priceRangeLocalCurrency: TaxedMoneyRange +} + +""" +Reorder product attribute values. +""" +type ProductReorderAttributeValues { + """ + Product from which attribute values are reordered. + """ + product: Product + productErrors: [ProductError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [ProductError!]! +} + +input ProductStockFilterInput { + warehouseIds: [ID!] + quantity: IntRangeInput +} + +type ProductTranslatableContent implements Node { + """ + The ID of the object. + """ + id: ID! + seoTitle: String + seoDescription: String + name: String! + description: JSONString + + """ + Description of the product (JSON). + """ + descriptionJson: JSONString @deprecated(reason: "Will be removed in Saleor 4.0. Use the `description` field instead.") + + """ + Returns translated product fields for the given language code. + """ + translation( + """ + A language code to return the translation for product. + """ + languageCode: LanguageCodeEnum! + ): ProductTranslation + + """ + Represents an individual item for sale in the storefront. + """ + product: Product +} + +""" +Creates/Updates translations for Product. +""" +type ProductTranslate { + translationErrors: [TranslationError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [TranslationError!]! + product: Product +} + +type ProductTranslation implements Node { + """ + The ID of the object. + """ + id: ID! + seoTitle: String + seoDescription: String + name: String! + description: JSONString + + """ + Translation language. + """ + language: LanguageDisplay! + + """ + Translated description of the product (JSON). + """ + descriptionJson: JSONString @deprecated(reason: "Will be removed in Saleor 4.0. Use the `description` field instead.") +} + +""" +Represents a type of product. It defines what attributes are available to products of this type. +""" +type ProductType implements Node & ObjectWithMetadata { + """ + The ID of the object. + """ + id: ID! + name: String! + slug: String! + hasVariants: Boolean! + isShippingRequired: Boolean! + isDigital: Boolean! + weight: Weight + + """ + List of private metadata items.Requires proper staff permissions to access. + """ + privateMetadata: [MetadataItem]! + + """ + List of public metadata items. Can be accessed without permissions. + """ + metadata: [MetadataItem]! + + """ + List of products of this type. + """ + products( + """ + Slug of a channel for which the data should be returned. + """ + channel: String + + """ + Return the elements in the list that come before the specified cursor. + """ + before: String + + """ + Return the elements in the list that come after the specified cursor. + """ + after: String + + """ + Return the first n elements from the list. + """ + first: Int + + """ + Return the last n elements from the list. + """ + last: Int + ): ProductCountableConnection + @deprecated( + reason: "Will be removed in Saleor 4.0. Use the top-level `products` query with the `productTypes` filter." + ) + + """ + A type of tax. Assigned by enabled tax gateway + """ + taxType: TaxType + + """ + Variant attributes of that product type. + """ + variantAttributes( + """ + Define scope of returned attributes. + """ + variantSelection: VariantAttributeScope + ): [Attribute] + + """ + Product attributes of that product type. + """ + productAttributes: [Attribute] + availableAttributes( + filter: AttributeFilterInput + + """ + Return the elements in the list that come before the specified cursor. + """ + before: String + + """ + Return the elements in the list that come after the specified cursor. + """ + after: String + + """ + Return the first n elements from the list. + """ + first: Int + + """ + Return the last n elements from the list. + """ + last: Int + ): AttributeCountableConnection +} + +""" +Deletes product types. +""" +type ProductTypeBulkDelete { + """ + Returns how many objects were affected. + """ + count: Int! + productErrors: [ProductError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [ProductError!]! +} + +enum ProductTypeConfigurable { + CONFIGURABLE + SIMPLE +} + +type ProductTypeCountableConnection { + """ + Pagination data for this connection. + """ + pageInfo: PageInfo! + edges: [ProductTypeCountableEdge!]! + + """ + A total count of items in the collection. + """ + totalCount: Int +} + +type ProductTypeCountableEdge { + """ + The item at the end of the edge. + """ + node: ProductType! + + """ + A cursor for use in pagination. + """ + cursor: String! +} + +""" +Creates a new product type. +""" +type ProductTypeCreate { + productErrors: [ProductError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [ProductError!]! + productType: ProductType +} + +""" +Deletes a product type. +""" +type ProductTypeDelete { + productErrors: [ProductError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [ProductError!]! + productType: ProductType +} + +enum ProductTypeEnum { + DIGITAL + SHIPPABLE +} + +input ProductTypeFilterInput { + search: String + configurable: ProductTypeConfigurable + productType: ProductTypeEnum + metadata: [MetadataInput] + ids: [ID] +} + +input ProductTypeInput { + """ + Name of the product type. + """ + name: String + + """ + Product type slug. + """ + slug: String + + """ + Determines if product of this type has multiple variants. This option mainly simplifies product management in the dashboard. There is always at least one variant created under the hood. + """ + hasVariants: Boolean + + """ + List of attributes shared among all product variants. + """ + productAttributes: [ID] + + """ + List of attributes used to distinguish between different variants of a product. + """ + variantAttributes: [ID] + + """ + Determines if shipping is required for products of this variant. + """ + isShippingRequired: Boolean + + """ + Determines if products are digital. + """ + isDigital: Boolean + + """ + Weight of the ProductType items. + """ + weight: WeightScalar + + """ + Tax rate for enabled tax gateway. + """ + taxCode: String +} + +""" +Reorder the attributes of a product type. +""" +type ProductTypeReorderAttributes { + """ + Product type from which attributes are reordered. + """ + productType: ProductType + productErrors: [ProductError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [ProductError!]! +} + +enum ProductTypeSortField { + """ + Sort products by name. + """ + NAME + + """ + Sort products by type. + """ + DIGITAL + + """ + Sort products by shipping. + """ + SHIPPING_REQUIRED +} + +input ProductTypeSortingInput { + """ + Specifies the direction in which to sort products. + """ + direction: OrderDirection! + + """ + Sort product types by the selected field. + """ + field: ProductTypeSortField! +} + +""" +Updates an existing product type. +""" +type ProductTypeUpdate { + productErrors: [ProductError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [ProductError!]! + productType: ProductType +} + +""" +Updates an existing product. +""" +type ProductUpdate { + productErrors: [ProductError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [ProductError!]! + product: Product +} + +""" +Represents a version of a product such as different size or color. +""" +type ProductVariant implements Node & ObjectWithMetadata { + """ + The ID of the object. + """ + id: ID! + name: String! + sku: String! + product: Product! + trackInventory: Boolean! + weight: Weight + + """ + List of private metadata items.Requires proper staff permissions to access. + """ + privateMetadata: [MetadataItem]! + + """ + List of public metadata items. Can be accessed without permissions. + """ + metadata: [MetadataItem]! + + """ + List of price information in channels for the product. + """ + channelListings: [ProductVariantChannelListing!] + + """ + Lists the storefront variant's pricing, the current price and discounts, only meant for displaying. + """ + pricing( + """ + Destination address used to find warehouses where stock availability for this product is checked. If address is empty, uses `Shop.companyAddress` or fallbacks to server's `settings.DEFAULT_COUNTRY` configuration. + """ + address: AddressInput + ): VariantPricingInfo + + """ + List of attributes assigned to this variant. + """ + attributes( + """ + Define scope of returned attributes. + """ + variantSelection: VariantAttributeScope + ): [SelectedAttribute!]! + + """ + Cost price of the variant. + """ + costPrice: Money + + """ + Gross margin percentage value. + """ + margin: Int + + """ + Total quantity ordered. + """ + quantityOrdered: Int + + """ + Total revenue generated by a variant in given period of time. Note: this field should be queried using `reportProductSales` query as it uses optimizations suitable for such calculations. + """ + revenue(period: ReportingPeriod): TaxedMoney + + """ + List of images for the product variant. + """ + images: [ProductImage] @deprecated(reason: "Will be removed in Saleor 4.0. Use the `media` instead.") + + """ + List of media for the product variant. + """ + media: [ProductMedia!] + + """ + Returns translated product variant fields for the given language code. + """ + translation( + """ + A language code to return the translation for product variant. + """ + languageCode: LanguageCodeEnum! + ): ProductVariantTranslation + + """ + Digital content for the product variant. + """ + digitalContent: DigitalContent + + """ + Stocks for the product variant. + """ + stocks( + """ + Destination address used to find warehouses where stock availability for this product is checked. If address is empty, uses `Shop.companyAddress` or fallbacks to server's `settings.DEFAULT_COUNTRY` configuration. + """ + address: AddressInput + + """ + DEPRECATED: use `address` argument instead. This argument will be removed in Saleor 4.0. Two-letter ISO 3166-1 country code. + """ + countryCode: CountryCode + ): [Stock] + + """ + Quantity of a product available for sale in one checkout. + """ + quantityAvailable( + """ + Destination address used to find warehouses where stock availability for this product is checked. If address is empty, uses `Shop.companyAddress` or fallbacks to server's `settings.DEFAULT_COUNTRY` configuration. + """ + address: AddressInput + + """ + DEPRECATED: use `address` argument instead. This argument will be removed in Saleor 4.0.Two-letter ISO 3166-1 country code. When provided, the exact quantity from a warehouse operating in shipping zones that contain this country will be returned. Otherwise, it will return the maximum quantity from all shipping zones. + """ + countryCode: CountryCode + ): Int! +} + +""" +Creates product variants for a given product. +""" +type ProductVariantBulkCreate { + """ + Returns how many objects were created. + """ + count: Int! + + """ + List of the created variants. + """ + productVariants: [ProductVariant!]! + bulkProductErrors: [BulkProductError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [BulkProductError!]! +} + +input ProductVariantBulkCreateInput { + """ + List of attributes specific to this variant. + """ + attributes: [BulkAttributeValueInput]! + + """ + Stock keeping unit. + """ + sku: String! + + """ + Determines if the inventory of this variant should be tracked. If false, the quantity won't change when customers buy this item. + """ + trackInventory: Boolean + + """ + Weight of the Product Variant. + """ + weight: WeightScalar + + """ + Stocks of a product available for sale. + """ + stocks: [StockInput!] + + """ + List of prices assigned to channels. + """ + channelListings: [ProductVariantChannelListingAddInput!] +} + +""" +Deletes product variants. +""" +type ProductVariantBulkDelete { + """ + Returns how many objects were affected. + """ + count: Int! + productErrors: [ProductError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [ProductError!]! +} + +""" +Represents product varaint channel listing. +""" +type ProductVariantChannelListing implements Node { + """ + The ID of the object. + """ + id: ID! + channel: Channel! + price: Money + + """ + Cost price of the variant. + """ + costPrice: Money + + """ + Gross margin percentage value. + """ + margin: Int +} + +input ProductVariantChannelListingAddInput { + """ + ID of a channel. + """ + channelId: ID! + + """ + Price of the particular variant in channel. + """ + price: PositiveDecimal! + + """ + Cost price of the variant in channel. + """ + costPrice: PositiveDecimal +} + +""" +Manage product variant prices in channels. +""" +type ProductVariantChannelListingUpdate { + """ + An updated product variant instance. + """ + variant: ProductVariant + productChannelListingErrors: [ProductChannelListingError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [ProductChannelListingError!]! +} + +type ProductVariantCountableConnection { + """ + Pagination data for this connection. + """ + pageInfo: PageInfo! + edges: [ProductVariantCountableEdge!]! + + """ + A total count of items in the collection. + """ + totalCount: Int +} + +type ProductVariantCountableEdge { + """ + The item at the end of the edge. + """ + node: ProductVariant! + + """ + A cursor for use in pagination. + """ + cursor: String! +} + +""" +Creates a new variant for a product. +""" +type ProductVariantCreate { + productErrors: [ProductError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [ProductError!]! + productVariant: ProductVariant +} + +input ProductVariantCreateInput { + """ + List of attributes specific to this variant. + """ + attributes: [AttributeValueInput]! + + """ + Stock keeping unit. + """ + sku: String + + """ + Determines if the inventory of this variant should be tracked. If false, the quantity won't change when customers buy this item. + """ + trackInventory: Boolean + + """ + Weight of the Product Variant. + """ + weight: WeightScalar + + """ + Product ID of which type is the variant. + """ + product: ID! + + """ + Stocks of a product available for sale. + """ + stocks: [StockInput!] +} + +""" +Deletes a product variant. +""" +type ProductVariantDelete { + productErrors: [ProductError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [ProductError!]! + productVariant: ProductVariant +} + +input ProductVariantFilterInput { + search: String + sku: [String] + metadata: [MetadataInput] +} + +input ProductVariantInput { + """ + List of attributes specific to this variant. + """ + attributes: [AttributeValueInput] + + """ + Stock keeping unit. + """ + sku: String + + """ + Determines if the inventory of this variant should be tracked. If false, the quantity won't change when customers buy this item. + """ + trackInventory: Boolean + + """ + Weight of the Product Variant. + """ + weight: WeightScalar +} + +""" +Reorder the variants of a product. Mutation updates updated_at on product and triggers PRODUCT_UPDATED webhook. +""" +type ProductVariantReorder { + product: Product + productErrors: [ProductError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [ProductError!]! +} + +""" +Reorder product variant attribute values. +""" +type ProductVariantReorderAttributeValues { + """ + Product variant from which attribute values are reordered. + """ + productVariant: ProductVariant + productErrors: [ProductError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [ProductError!]! +} + +""" +Set default variant for a product. Mutation triggers PRODUCT_UPDATED webhook. +""" +type ProductVariantSetDefault { + product: Product + productErrors: [ProductError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [ProductError!]! +} + +""" +Creates stocks for product variant. +""" +type ProductVariantStocksCreate { + """ + Updated product variant. + """ + productVariant: ProductVariant + bulkStockErrors: [BulkStockError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [BulkStockError!]! +} + +""" +Delete stocks from product variant. +""" +type ProductVariantStocksDelete { + """ + Updated product variant. + """ + productVariant: ProductVariant + stockErrors: [StockError!]! @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [StockError!]! +} + +""" +Update stocks for product variant. +""" +type ProductVariantStocksUpdate { + """ + Updated product variant. + """ + productVariant: ProductVariant + bulkStockErrors: [BulkStockError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [BulkStockError!]! +} + +type ProductVariantTranslatableContent implements Node { + """ + The ID of the object. + """ + id: ID! + name: String! + + """ + Returns translated product variant fields for the given language code. + """ + translation( + """ + A language code to return the translation for product variant. + """ + languageCode: LanguageCodeEnum! + ): ProductVariantTranslation + + """ + Represents a version of a product such as different size or color. + """ + productVariant: ProductVariant +} + +""" +Creates/Updates translations for Product Variant. +""" +type ProductVariantTranslate { + translationErrors: [TranslationError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [TranslationError!]! + productVariant: ProductVariant +} + +type ProductVariantTranslation implements Node { + """ + The ID of the object. + """ + id: ID! + name: String! + + """ + Translation language. + """ + language: LanguageDisplay! +} + +""" +Updates an existing variant for product. +""" +type ProductVariantUpdate { + productErrors: [ProductError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [ProductError!]! + productVariant: ProductVariant +} + +input PublishableChannelListingInput { + """ + ID of a channel. + """ + channelId: ID! + + """ + Determines if object is visible to customers. + """ + isPublished: Boolean + + """ + Publication date. ISO 8601 standard. + """ + publicationDate: Date +} + +type Query { + """ + Look up a webhook by ID. + """ + webhook( + """ + ID of the webhook. + """ + id: ID! + ): Webhook + + """ + List of all available webhook events. + """ + webhookEvents: [WebhookEvent] + + """ + Retrieve a sample payload for a given webhook event based on real data. It can be useful for some integrations where sample payload is required. + """ + webhookSamplePayload( + """ + Name of the requested event type. + """ + eventType: WebhookSampleEventTypeEnum! + ): JSONString + + """ + Look up a warehouse by ID. + """ + warehouse( + """ + ID of an warehouse + """ + id: ID! + ): Warehouse + + """ + List of warehouses. + """ + warehouses( + filter: WarehouseFilterInput + sortBy: WarehouseSortingInput + + """ + Return the elements in the list that come before the specified cursor. + """ + before: String + + """ + Return the elements in the list that come after the specified cursor. + """ + after: String + + """ + Return the first n elements from the list. + """ + first: Int + + """ + Return the last n elements from the list. + """ + last: Int + ): WarehouseCountableConnection + + """ + Returns a list of all translatable items of a given kind. + """ + translations( + """ + Kind of objects to retrieve. + """ + kind: TranslatableKinds! + + """ + Return the elements in the list that come before the specified cursor. + """ + before: String + + """ + Return the elements in the list that come after the specified cursor. + """ + after: String + + """ + Return the first n elements from the list. + """ + first: Int + + """ + Return the last n elements from the list. + """ + last: Int + ): TranslatableItemConnection + translation( + """ + ID of the object to retrieve. + """ + id: ID! + + """ + Kind of the object to retrieve. + """ + kind: TranslatableKinds! + ): TranslatableItem + + """ + Look up a stock by ID + """ + stock( + """ + ID of an warehouse + """ + id: ID! + ): Stock + + """ + List of stocks. + """ + stocks( + filter: StockFilterInput + + """ + Return the elements in the list that come before the specified cursor. + """ + before: String + + """ + Return the elements in the list that come after the specified cursor. + """ + after: String + + """ + Return the first n elements from the list. + """ + first: Int + + """ + Return the last n elements from the list. + """ + last: Int + ): StockCountableConnection + + """ + Return information about the shop. + """ + shop: Shop! + + """ + Order related settings from site settings. + """ + orderSettings: OrderSettings + + """ + Look up a shipping zone by ID. + """ + shippingZone( + """ + ID of the shipping zone. + """ + id: ID! + + """ + Slug of a channel for which the data should be returned. + """ + channel: String + ): ShippingZone + + """ + List of the shop's shipping zones. + """ + shippingZones( + """ + Filtering options for shipping zones. + """ + filter: ShippingZoneFilterInput + + """ + Slug of a channel for which the data should be returned. + """ + channel: String + + """ + Return the elements in the list that come before the specified cursor. + """ + before: String + + """ + Return the elements in the list that come after the specified cursor. + """ + after: String + + """ + Return the first n elements from the list. + """ + first: Int + + """ + Return the last n elements from the list. + """ + last: Int + ): ShippingZoneCountableConnection + + """ + Look up digital content by ID. + """ + digitalContent( + """ + ID of the digital content. + """ + id: ID! + ): DigitalContent + + """ + List of digital content. + """ + digitalContents( + """ + Return the elements in the list that come before the specified cursor. + """ + before: String + + """ + Return the elements in the list that come after the specified cursor. + """ + after: String + + """ + Return the first n elements from the list. + """ + first: Int + + """ + Return the last n elements from the list. + """ + last: Int + ): DigitalContentCountableConnection + + """ + List of the shop's categories. + """ + categories( + """ + Filtering options for categories. + """ + filter: CategoryFilterInput + + """ + Sort categories. + """ + sortBy: CategorySortingInput + + """ + Filter categories by the nesting level in the category tree. + """ + level: Int + + """ + Return the elements in the list that come before the specified cursor. + """ + before: String + + """ + Return the elements in the list that come after the specified cursor. + """ + after: String + + """ + Return the first n elements from the list. + """ + first: Int + + """ + Return the last n elements from the list. + """ + last: Int + ): CategoryCountableConnection + + """ + Look up a category by ID or slug. + """ + category( + """ + ID of the category. + """ + id: ID + + """ + Slug of the category + """ + slug: String + ): Category + + """ + Look up a collection by ID. + """ + collection( + """ + ID of the collection. + """ + id: ID + + """ + Slug of the category + """ + slug: String + + """ + Slug of a channel for which the data should be returned. + """ + channel: String + ): Collection + + """ + List of the shop's collections. + """ + collections( + """ + Filtering options for collections. + """ + filter: CollectionFilterInput + + """ + Sort collections. + """ + sortBy: CollectionSortingInput + + """ + Slug of a channel for which the data should be returned. + """ + channel: String + + """ + Return the elements in the list that come before the specified cursor. + """ + before: String + + """ + Return the elements in the list that come after the specified cursor. + """ + after: String + + """ + Return the first n elements from the list. + """ + first: Int + + """ + Return the last n elements from the list. + """ + last: Int + ): CollectionCountableConnection + + """ + Look up a product by ID. + """ + product( + """ + ID of the product. + """ + id: ID + + """ + Slug of the product. + """ + slug: String + + """ + Slug of a channel for which the data should be returned. + """ + channel: String + ): Product + + """ + List of the shop's products. + """ + products( + """ + Filtering options for products. + """ + filter: ProductFilterInput + + """ + Sort products. + """ + sortBy: ProductOrder + + """ + Slug of a channel for which the data should be returned. + """ + channel: String + + """ + Return the elements in the list that come before the specified cursor. + """ + before: String + + """ + Return the elements in the list that come after the specified cursor. + """ + after: String + + """ + Return the first n elements from the list. + """ + first: Int + + """ + Return the last n elements from the list. + """ + last: Int + ): ProductCountableConnection + + """ + Look up a product type by ID. + """ + productType( + """ + ID of the product type. + """ + id: ID! + ): ProductType + + """ + List of the shop's product types. + """ + productTypes( + """ + Filtering options for product types. + """ + filter: ProductTypeFilterInput + + """ + Sort product types. + """ + sortBy: ProductTypeSortingInput + + """ + Return the elements in the list that come before the specified cursor. + """ + before: String + + """ + Return the elements in the list that come after the specified cursor. + """ + after: String + + """ + Return the first n elements from the list. + """ + first: Int + + """ + Return the last n elements from the list. + """ + last: Int + ): ProductTypeCountableConnection + + """ + Look up a product variant by ID or SKU. + """ + productVariant( + """ + ID of the product variant. + """ + id: ID + + """ + Sku of the product variant. + """ + sku: String + + """ + Slug of a channel for which the data should be returned. + """ + channel: String + ): ProductVariant + + """ + List of product variants. + """ + productVariants( + """ + Filter product variants by given IDs. + """ + ids: [ID] + + """ + Slug of a channel for which the data should be returned. + """ + channel: String + + """ + Filtering options for product variant. + """ + filter: ProductVariantFilterInput + + """ + Return the elements in the list that come before the specified cursor. + """ + before: String + + """ + Return the elements in the list that come after the specified cursor. + """ + after: String + + """ + Return the first n elements from the list. + """ + first: Int + + """ + Return the last n elements from the list. + """ + last: Int + ): ProductVariantCountableConnection + + """ + List of top selling products. + """ + reportProductSales( + """ + Span of time. + """ + period: ReportingPeriod! + + """ + Slug of a channel for which the data should be returned. + """ + channel: String! + + """ + Return the elements in the list that come before the specified cursor. + """ + before: String + + """ + Return the elements in the list that come after the specified cursor. + """ + after: String + + """ + Return the first n elements from the list. + """ + first: Int + + """ + Return the last n elements from the list. + """ + last: Int + ): ProductVariantCountableConnection + + """ + Look up a payment by ID. + """ + payment( + """ + ID of the payment. + """ + id: ID! + ): Payment + + """ + List of payments. + """ + payments( + """ + Filtering options for payments. + """ + filter: PaymentFilterInput + + """ + Return the elements in the list that come before the specified cursor. + """ + before: String + + """ + Return the elements in the list that come after the specified cursor. + """ + after: String + + """ + Return the first n elements from the list. + """ + first: Int + + """ + Return the last n elements from the list. + """ + last: Int + ): PaymentCountableConnection + + """ + Look up a page by ID or slug. + """ + page( + """ + ID of the page. + """ + id: ID + + """ + The slug of the page. + """ + slug: String + ): Page + + """ + List of the shop's pages. + """ + pages( + """ + Sort pages. + """ + sortBy: PageSortingInput + + """ + Filtering options for pages. + """ + filter: PageFilterInput + + """ + Return the elements in the list that come before the specified cursor. + """ + before: String + + """ + Return the elements in the list that come after the specified cursor. + """ + after: String + + """ + Return the first n elements from the list. + """ + first: Int + + """ + Return the last n elements from the list. + """ + last: Int + ): PageCountableConnection + + """ + Look up a page type by ID. + """ + pageType( + """ + ID of the page type. + """ + id: ID! + ): PageType + + """ + List of the page types. + """ + pageTypes( + """ + Sort page types. + """ + sortBy: PageTypeSortingInput + + """ + Filtering options for page types. + """ + filter: PageTypeFilterInput + + """ + Return the elements in the list that come before the specified cursor. + """ + before: String + + """ + Return the elements in the list that come after the specified cursor. + """ + after: String + + """ + Return the first n elements from the list. + """ + first: Int + + """ + Return the last n elements from the list. + """ + last: Int + ): PageTypeCountableConnection + + """ + List of activity events to display on homepage (at the moment it only contains order-events). + """ + homepageEvents( + """ + Return the elements in the list that come before the specified cursor. + """ + before: String + + """ + Return the elements in the list that come after the specified cursor. + """ + after: String + + """ + Return the first n elements from the list. + """ + first: Int + + """ + Return the last n elements from the list. + """ + last: Int + ): OrderEventCountableConnection + + """ + Look up an order by ID. + """ + order( + """ + ID of an order. + """ + id: ID! + ): Order + + """ + List of orders. + """ + orders( + """ + Sort orders. + """ + sortBy: OrderSortingInput + + """ + Filtering options for orders. + """ + filter: OrderFilterInput + + """ + Slug of a channel for which the data should be returned. + """ + channel: String + + """ + Return the elements in the list that come before the specified cursor. + """ + before: String + + """ + Return the elements in the list that come after the specified cursor. + """ + after: String + + """ + Return the first n elements from the list. + """ + first: Int + + """ + Return the last n elements from the list. + """ + last: Int + ): OrderCountableConnection + + """ + List of draft orders. + """ + draftOrders( + """ + Sort draft orders. + """ + sortBy: OrderSortingInput + + """ + Filtering options for draft orders. + """ + filter: OrderDraftFilterInput + + """ + Return the elements in the list that come before the specified cursor. + """ + before: String + + """ + Return the elements in the list that come after the specified cursor. + """ + after: String + + """ + Return the first n elements from the list. + """ + first: Int + + """ + Return the last n elements from the list. + """ + last: Int + ): OrderCountableConnection + + """ + Return the total sales amount from a specific period. + """ + ordersTotal( + """ + A period of time. + """ + period: ReportingPeriod + + """ + Slug of a channel for which the data should be returned. + """ + channel: String + ): TaxedMoney + + """ + Look up an order by token. + """ + orderByToken( + """ + The order's token. + """ + token: UUID! + ): Order + + """ + Look up a navigation menu by ID or name. + """ + menu( + """ + Slug of a channel for which the data should be returned. + """ + channel: String + + """ + ID of the menu. + """ + id: ID + + """ + The menu's name. + """ + name: String + + """ + The menu's slug. + """ + slug: String + ): Menu + + """ + List of the storefront's menus. + """ + menus( + """ + Slug of a channel for which the data should be returned. + """ + channel: String + + """ + Sort menus. + """ + sortBy: MenuSortingInput + + """ + Filtering options for menus. + """ + filter: MenuFilterInput + + """ + Return the elements in the list that come before the specified cursor. + """ + before: String + + """ + Return the elements in the list that come after the specified cursor. + """ + after: String + + """ + Return the first n elements from the list. + """ + first: Int + + """ + Return the last n elements from the list. + """ + last: Int + ): MenuCountableConnection + + """ + Look up a menu item by ID. + """ + menuItem( + """ + ID of the menu item. + """ + id: ID! + + """ + Slug of a channel for which the data should be returned. + """ + channel: String + ): MenuItem + + """ + List of the storefronts's menu items. + """ + menuItems( + """ + Slug of a channel for which the data should be returned. + """ + channel: String + + """ + Sort menus items. + """ + sortBy: MenuItemSortingInput + + """ + Filtering options for menu items. + """ + filter: MenuItemFilterInput + + """ + Return the elements in the list that come before the specified cursor. + """ + before: String + + """ + Return the elements in the list that come after the specified cursor. + """ + after: String + + """ + Return the first n elements from the list. + """ + first: Int + + """ + Return the last n elements from the list. + """ + last: Int + ): MenuItemCountableConnection + + """ + Look up a gift card by ID. + """ + giftCard( + """ + ID of the gift card. + """ + id: ID! + ): GiftCard + + """ + List of gift cards. + """ + giftCards( + """ + Return the elements in the list that come before the specified cursor. + """ + before: String + + """ + Return the elements in the list that come after the specified cursor. + """ + after: String + + """ + Return the first n elements from the list. + """ + first: Int + + """ + Return the last n elements from the list. + """ + last: Int + ): GiftCardCountableConnection + + """ + Look up a plugin by ID. + """ + plugin( + """ + ID of the plugin. + """ + id: ID! + ): Plugin + + """ + List of plugins. + """ + plugins( + """ + Filtering options for plugins. + """ + filter: PluginFilterInput + + """ + Sort plugins. + """ + sortBy: PluginSortingInput + + """ + Return the elements in the list that come before the specified cursor. + """ + before: String + + """ + Return the elements in the list that come after the specified cursor. + """ + after: String + + """ + Return the first n elements from the list. + """ + first: Int + + """ + Return the last n elements from the list. + """ + last: Int + ): PluginCountableConnection + + """ + Look up a sale by ID. + """ + sale( + """ + ID of the sale. + """ + id: ID! + + """ + Slug of a channel for which the data should be returned. + """ + channel: String + ): Sale + + """ + List of the shop's sales. + """ + sales( + """ + Filtering options for sales. + """ + filter: SaleFilterInput + + """ + Sort sales. + """ + sortBy: SaleSortingInput + + """ + Search sales by name, value or type. + """ + query: String + + """ + Slug of a channel for which the data should be returned. + """ + channel: String + + """ + Return the elements in the list that come before the specified cursor. + """ + before: String + + """ + Return the elements in the list that come after the specified cursor. + """ + after: String + + """ + Return the first n elements from the list. + """ + first: Int + + """ + Return the last n elements from the list. + """ + last: Int + ): SaleCountableConnection + + """ + Look up a voucher by ID. + """ + voucher( + """ + ID of the voucher. + """ + id: ID! + + """ + Slug of a channel for which the data should be returned. + """ + channel: String + ): Voucher + + """ + List of the shop's vouchers. + """ + vouchers( + """ + Filtering options for vouchers. + """ + filter: VoucherFilterInput + + """ + Sort voucher. + """ + sortBy: VoucherSortingInput + + """ + Search vouchers by name or code. + """ + query: String + + """ + Slug of a channel for which the data should be returned. + """ + channel: String + + """ + Return the elements in the list that come before the specified cursor. + """ + before: String + + """ + Return the elements in the list that come after the specified cursor. + """ + after: String + + """ + Return the first n elements from the list. + """ + first: Int + + """ + Return the last n elements from the list. + """ + last: Int + ): VoucherCountableConnection + + """ + Look up a export file by ID. + """ + exportFile( + """ + ID of the export file job. + """ + id: ID! + ): ExportFile + + """ + List of export files. + """ + exportFiles( + """ + Filtering options for export files. + """ + filter: ExportFileFilterInput + + """ + Sort export files. + """ + sortBy: ExportFileSortingInput + + """ + Return the elements in the list that come before the specified cursor. + """ + before: String + + """ + Return the elements in the list that come after the specified cursor. + """ + after: String + + """ + Return the first n elements from the list. + """ + first: Int + + """ + Return the last n elements from the list. + """ + last: Int + ): ExportFileCountableConnection + + """ + List of all tax rates available from tax gateway. + """ + taxTypes: [TaxType] + + """ + Look up a checkout by token and slug of channel. + """ + checkout( + """ + The checkout's token. + """ + token: UUID + ): Checkout + + """ + List of checkouts. + """ + checkouts( + """ + Slug of a channel for which the data should be returned. + """ + channel: String + + """ + Return the elements in the list that come before the specified cursor. + """ + before: String + + """ + Return the elements in the list that come after the specified cursor. + """ + after: String + + """ + Return the first n elements from the list. + """ + first: Int + + """ + Return the last n elements from the list. + """ + last: Int + ): CheckoutCountableConnection + + """ + Look up a checkout line by ID. + """ + checkoutLine( + """ + ID of the checkout line. + """ + id: ID + ): CheckoutLine + + """ + List of checkout lines. + """ + checkoutLines( + """ + Return the elements in the list that come before the specified cursor. + """ + before: String + + """ + Return the elements in the list that come after the specified cursor. + """ + after: String + + """ + Return the first n elements from the list. + """ + first: Int + + """ + Return the last n elements from the list. + """ + last: Int + ): CheckoutLineCountableConnection + + """ + Look up a channel by ID. + """ + channel( + """ + ID of the channel. + """ + id: ID + ): Channel + + """ + List of all channels. + """ + channels: [Channel!] + + """ + List of the shop's attributes. + """ + attributes( + """ + Filtering options for attributes. + """ + filter: AttributeFilterInput + + """ + Sorting options for attributes. + """ + sortBy: AttributeSortingInput + + """ + Return the elements in the list that come before the specified cursor. + """ + before: String + + """ + Return the elements in the list that come after the specified cursor. + """ + after: String + + """ + Return the first n elements from the list. + """ + first: Int + + """ + Return the last n elements from the list. + """ + last: Int + ): AttributeCountableConnection + + """ + Look up an attribute by ID. + """ + attribute( + """ + ID of the attribute. + """ + id: ID + + """ + Slug of the attribute. + """ + slug: String + ): Attribute + + """ + List of all apps installations + """ + appsInstallations: [AppInstallation!]! + + """ + List of the apps. + """ + apps( + """ + Filtering options for apps. + """ + filter: AppFilterInput + + """ + Sort apps. + """ + sortBy: AppSortingInput + + """ + Return the elements in the list that come before the specified cursor. + """ + before: String + + """ + Return the elements in the list that come after the specified cursor. + """ + after: String + + """ + Return the first n elements from the list. + """ + first: Int + + """ + Return the last n elements from the list. + """ + last: Int + ): AppCountableConnection + + """ + Look up an app by ID. If ID is not provided, return the currently authenticated app. + """ + app( + """ + ID of the app. + """ + id: ID + ): App + + """ + Returns address validation rules. + """ + addressValidationRules( + """ + Two-letter ISO 3166-1 country code. + """ + countryCode: CountryCode! + + """ + Designation of a region, province or state. + """ + countryArea: String + + """ + City or a town name. + """ + city: String + + """ + Sublocality like a district. + """ + cityArea: String + ): AddressValidationData + + """ + Look up an address by ID. + """ + address( + """ + ID of an address. + """ + id: ID! + ): Address + + """ + List of the shop's customers. + """ + customers( + """ + Filtering options for customers. + """ + filter: CustomerFilterInput + + """ + Sort customers. + """ + sortBy: UserSortingInput + + """ + Return the elements in the list that come before the specified cursor. + """ + before: String + + """ + Return the elements in the list that come after the specified cursor. + """ + after: String + + """ + Return the first n elements from the list. + """ + first: Int + + """ + Return the last n elements from the list. + """ + last: Int + ): UserCountableConnection + + """ + List of permission groups. + """ + permissionGroups( + """ + Filtering options for permission groups. + """ + filter: PermissionGroupFilterInput + + """ + Sort permission groups. + """ + sortBy: PermissionGroupSortingInput + + """ + Return the elements in the list that come before the specified cursor. + """ + before: String + + """ + Return the elements in the list that come after the specified cursor. + """ + after: String + + """ + Return the first n elements from the list. + """ + first: Int + + """ + Return the last n elements from the list. + """ + last: Int + ): GroupCountableConnection + + """ + Look up permission group by ID. + """ + permissionGroup( + """ + ID of the group. + """ + id: ID! + ): Group + + """ + Return the currently authenticated user. + """ + me: User + + """ + List of the shop's staff users. + """ + staffUsers( + """ + Filtering options for staff users. + """ + filter: StaffUserInput + + """ + Sort staff users. + """ + sortBy: UserSortingInput + + """ + Return the elements in the list that come before the specified cursor. + """ + before: String + + """ + Return the elements in the list that come after the specified cursor. + """ + after: String + + """ + Return the first n elements from the list. + """ + first: Int + + """ + Return the last n elements from the list. + """ + last: Int + ): UserCountableConnection + + """ + Look up a user by ID or email address. + """ + user( + """ + ID of the user. + """ + id: ID + + """ + Email address of the user. + """ + email: String + ): User + _entities(representations: [_Any]): [_Entity] + _service: _Service +} + +""" +Represents a reduced VAT rate for a particular type of goods. +""" +type ReducedRate { + """ + Reduced VAT rate in percent. + """ + rate: Float! + + """ + A type of goods. + """ + rateType: TaxRateType! +} + +""" +Refresh JWT token. Mutation tries to take refreshToken from the input.If it fails it will try to take refreshToken from the http-only cookie -refreshToken. csrfToken is required when refreshToken is provided as a cookie. +""" +type RefreshToken { + """ + JWT token, required to authenticate. + """ + token: String + + """ + A user instance. + """ + user: User + accountErrors: [AccountError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [AccountError!]! +} + +input ReorderInput { + """ + The ID of the item to move. + """ + id: ID! + + """ + The new relative sorting position of the item (from -inf to +inf). 1 moves the item one position forward, -1 moves the item one position backward, 0 leaves the item unchanged. + """ + sortOrder: Int +} + +enum ReportingPeriod { + TODAY + THIS_MONTH +} + +""" +Request email change of the logged in user. +""" +type RequestEmailChange { + """ + A user instance. + """ + user: User + accountErrors: [AccountError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [AccountError!]! +} + +""" +Sends an email with the account password modification link. +""" +type RequestPasswordReset { + accountErrors: [AccountError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [AccountError!]! +} + +""" +Sales allow creating discounts for categories, collections or products and are visible to all the customers. +""" +type Sale implements Node { + """ + The ID of the object. + """ + id: ID! + name: String! + type: SaleType! + startDate: DateTime! + endDate: DateTime + + """ + List of categories this sale applies to. + """ + categories( + """ + Return the elements in the list that come before the specified cursor. + """ + before: String + + """ + Return the elements in the list that come after the specified cursor. + """ + after: String + + """ + Return the first n elements from the list. + """ + first: Int + + """ + Return the last n elements from the list. + """ + last: Int + ): CategoryCountableConnection + + """ + List of collections this sale applies to. + """ + collections( + """ + Return the elements in the list that come before the specified cursor. + """ + before: String + + """ + Return the elements in the list that come after the specified cursor. + """ + after: String + + """ + Return the first n elements from the list. + """ + first: Int + + """ + Return the last n elements from the list. + """ + last: Int + ): CollectionCountableConnection + + """ + List of products this sale applies to. + """ + products( + """ + Return the elements in the list that come before the specified cursor. + """ + before: String + + """ + Return the elements in the list that come after the specified cursor. + """ + after: String + + """ + Return the first n elements from the list. + """ + first: Int + + """ + Return the last n elements from the list. + """ + last: Int + ): ProductCountableConnection + + """ + Returns translated sale fields for the given language code. + """ + translation( + """ + A language code to return the translation for sale. + """ + languageCode: LanguageCodeEnum! + ): SaleTranslation + + """ + List of channels available for the sale. + """ + channelListings: [SaleChannelListing!] + + """ + Sale value. + """ + discountValue: Float + + """ + Currency code for sale. + """ + currency: String +} + +""" +Adds products, categories, collections to a voucher. +""" +type SaleAddCatalogues { + """ + Sale of which catalogue IDs will be modified. + """ + sale: Sale + discountErrors: [DiscountError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [DiscountError!]! +} + +""" +Deletes sales. +""" +type SaleBulkDelete { + """ + Returns how many objects were affected. + """ + count: Int! + discountErrors: [DiscountError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [DiscountError!]! +} + +""" +Represents sale channel listing. +""" +type SaleChannelListing implements Node { + """ + The ID of the object. + """ + id: ID! + channel: Channel! + discountValue: Float! + currency: String! +} + +input SaleChannelListingAddInput { + """ + ID of a channel. + """ + channelId: ID! + + """ + The value of the discount. + """ + discountValue: PositiveDecimal! +} + +input SaleChannelListingInput { + """ + List of channels to which the sale should be assigned. + """ + addChannels: [SaleChannelListingAddInput!] + + """ + List of channels from which the sale should be unassigned. + """ + removeChannels: [ID!] +} + +""" +Manage sale's availability in channels. +""" +type SaleChannelListingUpdate { + """ + An updated sale instance. + """ + sale: Sale + discountErrors: [DiscountError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [DiscountError!]! +} + +type SaleCountableConnection { + """ + Pagination data for this connection. + """ + pageInfo: PageInfo! + edges: [SaleCountableEdge!]! + + """ + A total count of items in the collection. + """ + totalCount: Int +} + +type SaleCountableEdge { + """ + The item at the end of the edge. + """ + node: Sale! + + """ + A cursor for use in pagination. + """ + cursor: String! +} + +""" +Creates a new sale. +""" +type SaleCreate { + discountErrors: [DiscountError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [DiscountError!]! + sale: Sale +} + +""" +Deletes a sale. +""" +type SaleDelete { + discountErrors: [DiscountError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [DiscountError!]! + sale: Sale +} + +input SaleFilterInput { + status: [DiscountStatusEnum] + saleType: DiscountValueTypeEnum + started: DateTimeRangeInput + search: String +} + +input SaleInput { + """ + Voucher name. + """ + name: String + + """ + Fixed or percentage. + """ + type: DiscountValueTypeEnum + + """ + Value of the voucher. + """ + value: PositiveDecimal + + """ + Products related to the discount. + """ + products: [ID] + + """ + Categories related to the discount. + """ + categories: [ID] + + """ + Collections related to the discount. + """ + collections: [ID] + + """ + Start date of the voucher in ISO 8601 format. + """ + startDate: DateTime + + """ + End date of the voucher in ISO 8601 format. + """ + endDate: DateTime +} + +""" +Removes products, categories, collections from a sale. +""" +type SaleRemoveCatalogues { + """ + Sale of which catalogue IDs will be modified. + """ + sale: Sale + discountErrors: [DiscountError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [DiscountError!]! +} + +enum SaleSortField { + """ + Sort sales by name. + """ + NAME + + """ + Sort sales by start date. + """ + START_DATE + + """ + Sort sales by end date. + """ + END_DATE + + """ + Sort sales by value. + """ + VALUE + + """ + Sort sales by type. + """ + TYPE +} + +input SaleSortingInput { + """ + Specifies the direction in which to sort products. + """ + direction: OrderDirection! + + """ + Specifies the channel in which to sort the data. + """ + channel: String + + """ + Sort sales by the selected field. + """ + field: SaleSortField! +} + +type SaleTranslatableContent implements Node { + """ + The ID of the object. + """ + id: ID! + name: String! + + """ + Returns translated sale fields for the given language code. + """ + translation( + """ + A language code to return the translation for sale. + """ + languageCode: LanguageCodeEnum! + ): SaleTranslation + + """ + Sales allow creating discounts for categories, collections or products and are visible to all the customers. + """ + sale: Sale +} + +""" +Creates/updates translations for a sale. +""" +type SaleTranslate { + translationErrors: [TranslationError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [TranslationError!]! + sale: Sale +} + +type SaleTranslation implements Node { + """ + The ID of the object. + """ + id: ID! + name: String + + """ + Translation language. + """ + language: LanguageDisplay! +} + +""" +An enumeration. +""" +enum SaleType { + """ + fixed + """ + FIXED + + """ + % + """ + PERCENTAGE +} + +""" +Updates a sale. +""" +type SaleUpdate { + discountErrors: [DiscountError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [DiscountError!]! + sale: Sale +} + +""" +Represents a custom attribute. +""" +type SelectedAttribute { + """ + Name of an attribute displayed in the interface. + """ + attribute: Attribute! + + """ + Values of an attribute. + """ + values: [AttributeValue]! +} + +input SeoInput { + """ + SEO title. + """ + title: String + + """ + SEO description. + """ + description: String +} + +""" +Sets the user's password from the token sent by email using the RequestPasswordReset mutation. +""" +type SetPassword { + """ + JWT token, required to authenticate. + """ + token: String + + """ + JWT refresh token, required to re-generate access token. + """ + refreshToken: String + + """ + CSRF token required to re-generate access token. + """ + csrfToken: String + + """ + A user instance. + """ + user: User + accountErrors: [AccountError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [AccountError!]! +} + +type ShippingError { + """ + Name of a field that caused the error. A value of `null` indicates that the error isn't associated with a particular field. + """ + field: String + + """ + The error message. + """ + message: String + + """ + The error code. + """ + code: ShippingErrorCode! + + """ + List of warehouse IDs which causes the error. + """ + warehouses: [ID!] + + """ + List of channels IDs which causes the error. + """ + channels: [ID!] +} + +""" +An enumeration. +""" +enum ShippingErrorCode { + ALREADY_EXISTS + GRAPHQL_ERROR + INVALID + MAX_LESS_THAN_MIN + NOT_FOUND + REQUIRED + UNIQUE + DUPLICATED_INPUT_ITEM +} + +""" +Shipping method are the methods you'll use to get customer's orders to them. They are directly exposed to the customers. +""" +type ShippingMethod implements Node & ObjectWithMetadata { + """ + The ID of the object. + """ + id: ID! + name: String! + description: JSONString + minimumOrderWeight: Weight + maximumOrderWeight: Weight + maximumDeliveryDays: Int + minimumDeliveryDays: Int + + """ + List of private metadata items.Requires proper staff permissions to access. + """ + privateMetadata: [MetadataItem]! + + """ + List of public metadata items. Can be accessed without permissions. + """ + metadata: [MetadataItem]! + + """ + Type of the shipping method. + """ + type: ShippingMethodTypeEnum + + """ + Returns translated shipping method fields for the given language code. + """ + translation( + """ + A language code to return the translation for shipping method. + """ + languageCode: LanguageCodeEnum! + ): ShippingMethodTranslation + + """ + List of channels available for the method. + """ + channelListings: [ShippingMethodChannelListing!] + + """ + The price of the cheapest variant (including discounts). + """ + price: Money + + """ + The price of the cheapest variant (including discounts). + """ + maximumOrderPrice: Money + + """ + The price of the cheapest variant (including discounts). + """ + minimumOrderPrice: Money + + """ + Postal code ranges rule of exclusion or inclusion of the shipping method. + """ + postalCodeRules: [ShippingMethodPostalCodeRule] + + """ + List of excluded products for the shipping method. + """ + excludedProducts( + """ + Return the elements in the list that come before the specified cursor. + """ + before: String + + """ + Return the elements in the list that come after the specified cursor. + """ + after: String + + """ + Return the first n elements from the list. + """ + first: Int + + """ + Return the last n elements from the list. + """ + last: Int + ): ProductCountableConnection +} + +""" +Represents shipping method channel listing. +""" +type ShippingMethodChannelListing implements Node { + """ + The ID of the object. + """ + id: ID! + channel: Channel! + minimumOrderPrice: Money + maximumOrderPrice: Money + price: Money +} + +input ShippingMethodChannelListingAddInput { + """ + ID of a channel. + """ + channelId: ID! + + """ + Shipping price of the shipping method in this channel. + """ + price: PositiveDecimal + + """ + Minimum order price to use this shipping method. + """ + minimumOrderPrice: PositiveDecimal + + """ + Maximum order price to use this shipping method. + """ + maximumOrderPrice: PositiveDecimal +} + +input ShippingMethodChannelListingInput { + """ + List of channels to which the shipping method should be assigned. + """ + addChannels: [ShippingMethodChannelListingAddInput!] + + """ + List of channels from which the shipping method should be unassigned. + """ + removeChannels: [ID!] +} + +""" +Manage shipping method's availability in channels. +""" +type ShippingMethodChannelListingUpdate { + """ + An updated shipping method instance. + """ + shippingMethod: ShippingMethod + shippingErrors: [ShippingError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [ShippingError!]! +} + +""" +Represents shipping method postal code rule. +""" +type ShippingMethodPostalCodeRule implements Node { + """ + Start address range. + """ + start: String + + """ + End address range. + """ + end: String + + """ + Inclusion type of the postal code rule. + """ + inclusionType: PostalCodeRuleInclusionTypeEnum + + """ + The ID of the object. + """ + id: ID! +} + +type ShippingMethodTranslatableContent implements Node { + """ + The ID of the object. + """ + id: ID! + name: String! + description: JSONString + + """ + Returns translated shipping method fields for the given language code. + """ + translation( + """ + A language code to return the translation for shipping method. + """ + languageCode: LanguageCodeEnum! + ): ShippingMethodTranslation + + """ + Shipping method are the methods you'll use to get customer's orders to them. They are directly exposed to the customers. + """ + shippingMethod: ShippingMethod +} + +type ShippingMethodTranslation implements Node { + """ + The ID of the object. + """ + id: ID! + name: String + description: JSONString + + """ + Translation language. + """ + language: LanguageDisplay! +} + +""" +An enumeration. +""" +enum ShippingMethodTypeEnum { + PRICE + WEIGHT +} + +input ShippingPostalCodeRulesCreateInputRange { + """ + Start range of the postal code. + """ + start: String! + + """ + End range of the postal code. + """ + end: String +} + +""" +Deletes shipping prices. +""" +type ShippingPriceBulkDelete { + """ + Returns how many objects were affected. + """ + count: Int! + shippingErrors: [ShippingError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [ShippingError!]! +} + +""" +Creates a new shipping price. +""" +type ShippingPriceCreate { + """ + A shipping zone to which the shipping method belongs. + """ + shippingZone: ShippingZone + shippingMethod: ShippingMethod + shippingErrors: [ShippingError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [ShippingError!]! +} + +""" +Deletes a shipping price. +""" +type ShippingPriceDelete { + """ + A shipping method to delete. + """ + shippingMethod: ShippingMethod + + """ + A shipping zone to which the shipping method belongs. + """ + shippingZone: ShippingZone + shippingErrors: [ShippingError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [ShippingError!]! +} + +""" +Exclude products from shipping price. +""" +type ShippingPriceExcludeProducts { + """ + A shipping method with new list of excluded products. + """ + shippingMethod: ShippingMethod + shippingErrors: [ShippingError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [ShippingError!]! +} + +input ShippingPriceExcludeProductsInput { + """ + List of products which will be excluded. + """ + products: [ID]! +} + +input ShippingPriceInput { + """ + Name of the shipping method. + """ + name: String + + """ + Shipping method description (JSON). + """ + description: JSONString + + """ + Minimum order weight to use this shipping method. + """ + minimumOrderWeight: WeightScalar + + """ + Maximum order weight to use this shipping method. + """ + maximumOrderWeight: WeightScalar + + """ + Maximum number of days for delivery. + """ + maximumDeliveryDays: Int + + """ + Minimal number of days for delivery. + """ + minimumDeliveryDays: Int + + """ + Shipping type: price or weight based. + """ + type: ShippingMethodTypeEnum + + """ + Shipping zone this method belongs to. + """ + shippingZone: ID + + """ + Postal code rules to add. + """ + addPostalCodeRules: [ShippingPostalCodeRulesCreateInputRange!] + + """ + Postal code rules to delete. + """ + deletePostalCodeRules: [ID!] + + """ + Inclusion type for currently assigned postal code rules. + """ + inclusionType: PostalCodeRuleInclusionTypeEnum +} + +""" +Remove product from excluded list for shipping price. +""" +type ShippingPriceRemoveProductFromExclude { + """ + A shipping method with new list of excluded products. + """ + shippingMethod: ShippingMethod + shippingErrors: [ShippingError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [ShippingError!]! +} + +""" +Creates/Updates translations for shipping method. +""" +type ShippingPriceTranslate { + translationErrors: [TranslationError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [TranslationError!]! + shippingMethod: ShippingMethod +} + +input ShippingPriceTranslationInput { + name: String + + """ + Translated shipping method description (JSON). + """ + description: JSONString +} + +""" +Updates a new shipping price. +""" +type ShippingPriceUpdate { + """ + A shipping zone to which the shipping method belongs. + """ + shippingZone: ShippingZone + shippingMethod: ShippingMethod + shippingErrors: [ShippingError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [ShippingError!]! +} + +""" +Represents a shipping zone in the shop. Zones are the concept used only for grouping shipping methods in the dashboard, and are never exposed to the customers directly. +""" +type ShippingZone implements Node & ObjectWithMetadata { + """ + The ID of the object. + """ + id: ID! + name: String! + default: Boolean! + + """ + List of private metadata items.Requires proper staff permissions to access. + """ + privateMetadata: [MetadataItem]! + + """ + List of public metadata items. Can be accessed without permissions. + """ + metadata: [MetadataItem]! + + """ + Lowest and highest prices for the shipping. + """ + priceRange: MoneyRange + + """ + List of countries available for the method. + """ + countries: [CountryDisplay] + + """ + List of shipping methods available for orders shipped to countries within this shipping zone. + """ + shippingMethods: [ShippingMethod] + + """ + List of warehouses for shipping zone. + """ + warehouses: [Warehouse!]! + + """ + List of channels for shipping zone. + """ + channels: [Channel!]! + + """ + Description of a shipping zone. + """ + description: String +} + +""" +Deletes shipping zones. +""" +type ShippingZoneBulkDelete { + """ + Returns how many objects were affected. + """ + count: Int! + shippingErrors: [ShippingError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [ShippingError!]! +} + +type ShippingZoneCountableConnection { + """ + Pagination data for this connection. + """ + pageInfo: PageInfo! + edges: [ShippingZoneCountableEdge!]! + + """ + A total count of items in the collection. + """ + totalCount: Int +} + +type ShippingZoneCountableEdge { + """ + The item at the end of the edge. + """ + node: ShippingZone! + + """ + A cursor for use in pagination. + """ + cursor: String! +} + +""" +Creates a new shipping zone. +""" +type ShippingZoneCreate { + shippingErrors: [ShippingError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [ShippingError!]! + shippingZone: ShippingZone +} + +input ShippingZoneCreateInput { + """ + Shipping zone's name. Visible only to the staff. + """ + name: String + + """ + Description of the shipping zone. + """ + description: String + + """ + List of countries in this shipping zone. + """ + countries: [String] + + """ + Default shipping zone will be used for countries not covered by other zones. + """ + default: Boolean + + """ + List of warehouses to assign to a shipping zone + """ + addWarehouses: [ID] + + """ + List of channels to assign to the shipping zone. + """ + addChannels: [ID!] +} + +""" +Deletes a shipping zone. +""" +type ShippingZoneDelete { + shippingErrors: [ShippingError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [ShippingError!]! + shippingZone: ShippingZone +} + +input ShippingZoneFilterInput { + search: String + channels: [ID] +} + +""" +Updates a new shipping zone. +""" +type ShippingZoneUpdate { + shippingErrors: [ShippingError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [ShippingError!]! + shippingZone: ShippingZone +} + +input ShippingZoneUpdateInput { + """ + Shipping zone's name. Visible only to the staff. + """ + name: String + + """ + Description of the shipping zone. + """ + description: String + + """ + List of countries in this shipping zone. + """ + countries: [String] + + """ + Default shipping zone will be used for countries not covered by other zones. + """ + default: Boolean + + """ + List of warehouses to assign to a shipping zone + """ + addWarehouses: [ID] + + """ + List of channels to assign to the shipping zone. + """ + addChannels: [ID!] + + """ + List of warehouses to unassign from a shipping zone + """ + removeWarehouses: [ID] + + """ + List of channels to unassign from the shipping zone. + """ + removeChannels: [ID!] +} + +""" +Represents a shop resource containing general shop data and configuration. +""" +type Shop { + """ + List of available payment gateways. + """ + availablePaymentGateways( + """ + DEPRECATED: use `channel` argument instead. This argument will be removed in Saleor 4.0.A currency for which gateways will be returned. + """ + currency: String + + """ + Slug of a channel for which the data should be returned. + """ + channel: String + ): [PaymentGateway!]! + + """ + List of available external authentications. + """ + availableExternalAuthentications: [ExternalAuthentication!]! + + """ + Shipping methods that are available for the shop. + """ + availableShippingMethods( + """ + Slug of a channel for which the data should be returned. + """ + channel: String! + + """ + Address for which available shipping methods should be returned. + """ + address: AddressInput + ): [ShippingMethod] + + """ + List of countries available in the shop. + """ + countries( + """ + A language code to return the translation for. + """ + languageCode: LanguageCodeEnum + ): [CountryDisplay!]! + + """ + Shop's default country. + """ + defaultCountry: CountryDisplay + + """ + Default shop's email sender's name. + """ + defaultMailSenderName: String + + """ + Default shop's email sender's address. + """ + defaultMailSenderAddress: String + + """ + Shop's description. + """ + description: String + + """ + Shop's domain data. + """ + domain: Domain! + + """ + List of the shops's supported languages. + """ + languages: [LanguageDisplay]! + + """ + Shop's name. + """ + name: String! + + """ + List of available permissions. + """ + permissions: [Permission]! + + """ + List of possible phone prefixes. + """ + phonePrefixes: [String]! + + """ + Header text. + """ + headerText: String + + """ + Include taxes in prices. + """ + includeTaxesInPrices: Boolean! + + """ + Display prices with tax in store. + """ + displayGrossPrices: Boolean! + + """ + Charge taxes on shipping. + """ + chargeTaxesOnShipping: Boolean! + + """ + Enable inventory tracking. + """ + trackInventoryByDefault: Boolean + + """ + Default weight unit. + """ + defaultWeightUnit: WeightUnitsEnum + + """ + Returns translated shop fields for the given language code. + """ + translation( + """ + A language code to return the translation for shop. + """ + languageCode: LanguageCodeEnum! + ): ShopTranslation + + """ + Enable automatic fulfillment for all digital products. + """ + automaticFulfillmentDigitalProducts: Boolean + + """ + Default number of max downloads per digital content URL. + """ + defaultDigitalMaxDownloads: Int + + """ + Default number of days which digital content URL will be valid. + """ + defaultDigitalUrlValidDays: Int + + """ + Company address. + """ + companyAddress: Address + + """ + URL of a view where customers can set their password. + """ + customerSetPasswordUrl: String + + """ + List of staff notification recipients. + """ + staffNotificationRecipients: [StaffNotificationRecipient] + + """ + Resource limitations and current usage if any set for a shop + """ + limits: LimitInfo! + + """ + Saleor API version. + """ + version: String! +} + +""" +Update the shop's address. If the `null` value is passed, the currently selected address will be deleted. +""" +type ShopAddressUpdate { + """ + Updated shop. + """ + shop: Shop + shopErrors: [ShopError!]! @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [ShopError!]! +} + +""" +Updates site domain of the shop. +""" +type ShopDomainUpdate { + """ + Updated shop. + """ + shop: Shop + shopErrors: [ShopError!]! @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [ShopError!]! +} + +type ShopError { + """ + Name of a field that caused the error. A value of `null` indicates that the error isn't associated with a particular field. + """ + field: String + + """ + The error message. + """ + message: String + + """ + The error code. + """ + code: ShopErrorCode! +} + +""" +An enumeration. +""" +enum ShopErrorCode { + ALREADY_EXISTS + CANNOT_FETCH_TAX_RATES + GRAPHQL_ERROR + INVALID + NOT_FOUND + REQUIRED + UNIQUE +} + +""" +Fetch tax rates. +""" +type ShopFetchTaxRates { + """ + Updated shop. + """ + shop: Shop + shopErrors: [ShopError!]! @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [ShopError!]! +} + +input ShopSettingsInput { + """ + Header text. + """ + headerText: String + + """ + SEO description. + """ + description: String + + """ + Include taxes in prices. + """ + includeTaxesInPrices: Boolean + + """ + Display prices with tax in store. + """ + displayGrossPrices: Boolean + + """ + Charge taxes on shipping. + """ + chargeTaxesOnShipping: Boolean + + """ + Enable inventory tracking. + """ + trackInventoryByDefault: Boolean + + """ + Default weight unit. + """ + defaultWeightUnit: WeightUnitsEnum + + """ + Enable automatic fulfillment for all digital products. + """ + automaticFulfillmentDigitalProducts: Boolean + + """ + Default number of max downloads per digital content URL. + """ + defaultDigitalMaxDownloads: Int + + """ + Default number of days which digital content URL will be valid. + """ + defaultDigitalUrlValidDays: Int + + """ + Default email sender's name. + """ + defaultMailSenderName: String + + """ + Default email sender's address. + """ + defaultMailSenderAddress: String + + """ + URL of a view where customers can set their password. + """ + customerSetPasswordUrl: String +} + +""" +Creates/Updates translations for Shop Settings. +""" +type ShopSettingsTranslate { + """ + Updated shop. + """ + shop: Shop + translationErrors: [TranslationError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [TranslationError!]! +} + +input ShopSettingsTranslationInput { + headerText: String + description: String +} + +""" +Updates shop settings. +""" +type ShopSettingsUpdate { + """ + Updated shop. + """ + shop: Shop + shopErrors: [ShopError!]! @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [ShopError!]! +} + +type ShopTranslation implements Node { + """ + The ID of the object. + """ + id: ID! + headerText: String! + description: String! + + """ + Translation language. + """ + language: LanguageDisplay! +} + +input SiteDomainInput { + """ + Domain name for shop. + """ + domain: String + + """ + Shop site name. + """ + name: String +} + +""" +Deletes staff users. +""" +type StaffBulkDelete { + """ + Returns how many objects were affected. + """ + count: Int! + staffErrors: [StaffError!]! @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [StaffError!]! +} + +""" +Creates a new staff user. +""" +type StaffCreate { + staffErrors: [StaffError!]! @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [StaffError!]! + user: User +} + +input StaffCreateInput { + """ + Given name. + """ + firstName: String + + """ + Family name. + """ + lastName: String + + """ + The unique email address of the user. + """ + email: String + + """ + User account is active. + """ + isActive: Boolean + + """ + A note about the user. + """ + note: String + + """ + List of permission group IDs to which user should be assigned. + """ + addGroups: [ID!] + + """ + URL of a view where users should be redirected to set the password. URL in RFC 1808 format. + """ + redirectUrl: String +} + +""" +Deletes a staff user. +""" +type StaffDelete { + staffErrors: [StaffError!]! @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [StaffError!]! + user: User +} + +type StaffError { + """ + Name of a field that caused the error. A value of `null` indicates that the error isn't associated with a particular field. + """ + field: String + + """ + The error message. + """ + message: String + + """ + The error code. + """ + code: AccountErrorCode! + + """ + A type of address that causes the error. + """ + addressType: AddressTypeEnum + + """ + List of permissions which causes the error. + """ + permissions: [PermissionEnum!] + + """ + List of permission group IDs which cause the error. + """ + groups: [ID!] + + """ + List of user IDs which causes the error. + """ + users: [ID!] +} + +enum StaffMemberStatus { + """ + User account has been activated. + """ + ACTIVE + + """ + User account has not been activated yet. + """ + DEACTIVATED +} + +""" +Represents a recipient of email notifications send by Saleor, such as notifications about new orders. Notifications can be assigned to staff users or arbitrary email addresses. +""" +type StaffNotificationRecipient implements Node { + """ + Returns a user subscribed to email notifications. + """ + user: User + + """ + Determines if a notification active. + """ + active: Boolean + + """ + The ID of the object. + """ + id: ID! + + """ + Returns email address of a user subscribed to email notifications. + """ + email: String +} + +""" +Creates a new staff notification recipient. +""" +type StaffNotificationRecipientCreate { + shopErrors: [ShopError!]! @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [ShopError!]! + staffNotificationRecipient: StaffNotificationRecipient +} + +""" +Delete staff notification recipient. +""" +type StaffNotificationRecipientDelete { + shopErrors: [ShopError!]! @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [ShopError!]! + staffNotificationRecipient: StaffNotificationRecipient +} + +input StaffNotificationRecipientInput { + """ + The ID of the user subscribed to email notifications.. + """ + user: ID + + """ + Email address of a user subscribed to email notifications. + """ + email: String + + """ + Determines if a notification active. + """ + active: Boolean +} + +""" +Updates a staff notification recipient. +""" +type StaffNotificationRecipientUpdate { + shopErrors: [ShopError!]! @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [ShopError!]! + staffNotificationRecipient: StaffNotificationRecipient +} + +""" +Updates an existing staff user. +""" +type StaffUpdate { + staffErrors: [StaffError!]! @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [StaffError!]! + user: User +} + +input StaffUpdateInput { + """ + Given name. + """ + firstName: String + + """ + Family name. + """ + lastName: String + + """ + The unique email address of the user. + """ + email: String + + """ + User account is active. + """ + isActive: Boolean + + """ + A note about the user. + """ + note: String + + """ + List of permission group IDs to which user should be assigned. + """ + addGroups: [ID!] + + """ + List of permission group IDs from which user should be unassigned. + """ + removeGroups: [ID!] +} + +input StaffUserInput { + status: StaffMemberStatus + search: String +} + +""" +Represents stock. +""" +type Stock implements Node { + warehouse: Warehouse! + productVariant: ProductVariant! + + """ + Quantity of a product in the warehouse's possession, including the allocated stock that is waiting for shipment. + """ + quantity: Int! + + """ + The ID of the object. + """ + id: ID! + + """ + Quantity allocated for orders + """ + quantityAllocated: Int! +} + +enum StockAvailability { + IN_STOCK + OUT_OF_STOCK +} + +type StockCountableConnection { + """ + Pagination data for this connection. + """ + pageInfo: PageInfo! + edges: [StockCountableEdge!]! + + """ + A total count of items in the collection. + """ + totalCount: Int +} + +type StockCountableEdge { + """ + The item at the end of the edge. + """ + node: Stock! + + """ + A cursor for use in pagination. + """ + cursor: String! +} + +type StockError { + """ + Name of a field that caused the error. A value of `null` indicates that the error isn't associated with a particular field. + """ + field: String + + """ + The error message. + """ + message: String + + """ + The error code. + """ + code: StockErrorCode! +} + +""" +An enumeration. +""" +enum StockErrorCode { + ALREADY_EXISTS + GRAPHQL_ERROR + INVALID + NOT_FOUND + REQUIRED + UNIQUE +} + +input StockFilterInput { + quantity: Float + search: String +} + +input StockInput { + """ + Warehouse in which stock is located. + """ + warehouse: ID! + + """ + Quantity of items available for sell. + """ + quantity: Int! +} + +""" +An enumeration. +""" +enum TaxRateType { + ACCOMMODATION + ADMISSION_TO_CULTURAL_EVENTS + ADMISSION_TO_ENTERTAINMENT_EVENTS + ADMISSION_TO_SPORTING_EVENTS + ADVERTISING + AGRICULTURAL_SUPPLIES + BABY_FOODSTUFFS + BIKES + BOOKS + CHILDRENS_CLOTHING + DOMESTIC_FUEL + DOMESTIC_SERVICES + E_BOOKS + FOODSTUFFS + HOTELS + MEDICAL + NEWSPAPERS + PASSENGER_TRANSPORT + PHARMACEUTICALS + PROPERTY_RENOVATIONS + RESTAURANTS + SOCIAL_HOUSING + STANDARD + WATER + WINE +} + +""" +Representation of tax types fetched from tax gateway. +""" +type TaxType { + """ + Description of the tax type. + """ + description: String + + """ + External tax code used to identify given tax group. + """ + taxCode: String +} + +""" +Represents a monetary value with taxes. In cases where taxes were not applied, net and gross values will be equal. +""" +type TaxedMoney { + """ + Currency code. + """ + currency: String! + + """ + Amount of money including taxes. + """ + gross: Money! + + """ + Amount of money without taxes. + """ + net: Money! + + """ + Amount of taxes. + """ + tax: Money! +} + +""" +Represents a range of monetary values. +""" +type TaxedMoneyRange { + """ + Lower bound of a price range. + """ + start: TaxedMoney + + """ + Upper bound of a price range. + """ + stop: TaxedMoney +} + +""" +An object representing a single payment. +""" +type Transaction implements Node { + """ + The ID of the object. + """ + id: ID! + created: DateTime! + payment: Payment! + token: String! + kind: TransactionKind! + isSuccess: Boolean! + error: String + gatewayResponse: JSONString! + + """ + Total amount of the transaction. + """ + amount: Money +} + +""" +An enumeration. +""" +enum TransactionKind { + """ + External reference + """ + EXTERNAL + + """ + Authorization + """ + AUTH + + """ + Pending + """ + PENDING + + """ + Action to confirm + """ + ACTION_TO_CONFIRM + + """ + Refund + """ + REFUND + + """ + Refund in progress + """ + REFUND_ONGOING + + """ + Capture + """ + CAPTURE + + """ + Void + """ + VOID + + """ + Confirm + """ + CONFIRM + + """ + Cancel + """ + CANCEL +} + +union TranslatableItem = + ProductTranslatableContent + | CollectionTranslatableContent + | CategoryTranslatableContent + | AttributeTranslatableContent + | AttributeValueTranslatableContent + | ProductVariantTranslatableContent + | PageTranslatableContent + | ShippingMethodTranslatableContent + | SaleTranslatableContent + | VoucherTranslatableContent + | MenuItemTranslatableContent + +type TranslatableItemConnection { + """ + Pagination data for this connection. + """ + pageInfo: PageInfo! + edges: [TranslatableItemEdge!]! + + """ + A total count of items in the collection. + """ + totalCount: Int +} + +type TranslatableItemEdge { + """ + The item at the end of the edge. + """ + node: TranslatableItem! + + """ + A cursor for use in pagination. + """ + cursor: String! +} + +enum TranslatableKinds { + ATTRIBUTE + ATTRIBUTE_VALUE + CATEGORY + COLLECTION + MENU_ITEM + PAGE + PRODUCT + SALE + SHIPPING_METHOD + VARIANT + VOUCHER +} + +type TranslationError { + """ + Name of a field that caused the error. A value of `null` indicates that the error isn't associated with a particular field. + """ + field: String + + """ + The error message. + """ + message: String + + """ + The error code. + """ + code: TranslationErrorCode! +} + +""" +An enumeration. +""" +enum TranslationErrorCode { + GRAPHQL_ERROR + NOT_FOUND + REQUIRED +} + +input TranslationInput { + seoTitle: String + seoDescription: String + name: String + description: JSONString +} + +scalar UUID + +input UpdateInvoiceInput { + """ + Invoice number + """ + number: String + + """ + URL of an invoice to download. + """ + url: String +} + +""" +Updates metadata of an object. +""" +type UpdateMetadata { + metadataErrors: [MetadataError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [MetadataError!]! + item: ObjectWithMetadata +} + +""" +Updates private metadata of an object. +""" +type UpdatePrivateMetadata { + metadataErrors: [MetadataError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [MetadataError!]! + item: ObjectWithMetadata +} + +""" +Variables of this type must be set to null in mutations. They will be replaced with a filename from a following multipart part containing a binary file. See: https://github.com/jaydenseric/graphql-multipart-request-spec. +""" +scalar Upload + +type UploadError { + """ + Name of a field that caused the error. A value of `null` indicates that the error isn't associated with a particular field. + """ + field: String + + """ + The error message. + """ + message: String + + """ + The error code. + """ + code: UploadErrorCode! +} + +""" +An enumeration. +""" +enum UploadErrorCode { + GRAPHQL_ERROR +} + +""" +Represents user data. +""" +type User implements Node & ObjectWithMetadata { + """ + The ID of the object. + """ + id: ID! + lastLogin: DateTime + email: String! + firstName: String! + lastName: String! + isStaff: Boolean! + isActive: Boolean! + + """ + A note about the customer. + """ + note: String + dateJoined: DateTime! + defaultShippingAddress: Address + defaultBillingAddress: Address + + """ + List of private metadata items.Requires proper staff permissions to access. + """ + privateMetadata: [MetadataItem]! + + """ + List of public metadata items. Can be accessed without permissions. + """ + metadata: [MetadataItem]! + + """ + List of all user's addresses. + """ + addresses: [Address] + + """ + Returns the last open checkout of this user. + """ + checkout: Checkout + @deprecated(reason: "Will be removed in Saleor 4.0. Use the `checkout_tokens` field to fetch the user checkouts.") + + """ + Returns the checkout UUID's assigned to this user. + """ + checkoutTokens( + """ + Slug of a channel for which the data should be returned. + """ + channel: String + ): [UUID!] + + """ + List of the user gift cards. + """ + giftCards( + """ + Return the elements in the list that come before the specified cursor. + """ + before: String + + """ + Return the elements in the list that come after the specified cursor. + """ + after: String + + """ + Return the first n elements from the list. + """ + first: Int + + """ + Return the last n elements from the list. + """ + last: Int + ): GiftCardCountableConnection + + """ + List of user's orders. + """ + orders( + """ + Return the elements in the list that come before the specified cursor. + """ + before: String + + """ + Return the elements in the list that come after the specified cursor. + """ + after: String + + """ + Return the first n elements from the list. + """ + first: Int + + """ + Return the last n elements from the list. + """ + last: Int + ): OrderCountableConnection + + """ + List of user's permissions. + """ + userPermissions: [UserPermission] + + """ + List of user's permission groups. + """ + permissionGroups: [Group] + + """ + List of user's permission groups which user can manage. + """ + editableGroups: [Group] + avatar( + """ + Size of the avatar. + """ + size: Int + ): Image + + """ + List of events associated with the user. + """ + events: [CustomerEvent] + + """ + List of stored payment sources. + """ + storedPaymentSources( + """ + Slug of a channel for which the data should be returned. + """ + channel: String + ): [PaymentSource] + + """ + User language code. + """ + languageCode: LanguageCodeEnum! +} + +""" +Deletes a user avatar. Only for staff members. +""" +type UserAvatarDelete { + """ + An updated user instance. + """ + user: User + accountErrors: [AccountError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [AccountError!]! +} + +""" +Create a user avatar. Only for staff members. This mutation must be sent as a `multipart` request. More detailed specs of the upload format can be found here: https://github.com/jaydenseric/graphql-multipart-request-spec +""" +type UserAvatarUpdate { + """ + An updated user instance. + """ + user: User + accountErrors: [AccountError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [AccountError!]! +} + +""" +Activate or deactivate users. +""" +type UserBulkSetActive { + """ + Returns how many objects were affected. + """ + count: Int! + accountErrors: [AccountError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [AccountError!]! +} + +type UserCountableConnection { + """ + Pagination data for this connection. + """ + pageInfo: PageInfo! + edges: [UserCountableEdge!]! + + """ + A total count of items in the collection. + """ + totalCount: Int +} + +type UserCountableEdge { + """ + The item at the end of the edge. + """ + node: User! + + """ + A cursor for use in pagination. + """ + cursor: String! +} + +input UserCreateInput { + """ + Billing address of the customer. + """ + defaultBillingAddress: AddressInput + + """ + Shipping address of the customer. + """ + defaultShippingAddress: AddressInput + + """ + Given name. + """ + firstName: String + + """ + Family name. + """ + lastName: String + + """ + The unique email address of the user. + """ + email: String + + """ + User account is active. + """ + isActive: Boolean + + """ + A note about the user. + """ + note: String + + """ + User language code. + """ + languageCode: LanguageCodeEnum + + """ + URL of a view where users should be redirected to set the password. URL in RFC 1808 format. + """ + redirectUrl: String + + """ + Slug of a channel which will be used for notify user. Optional when only one channel exists. + """ + channel: String +} + +type UserPermission { + """ + Internal code for permission. + """ + code: PermissionEnum! + + """ + Describe action(s) allowed to do by permission. + """ + name: String! + + """ + List of user permission groups which contains this permission. + """ + sourcePermissionGroups( + """ + ID of user whose groups should be returned. + """ + userId: ID! + ): [Group!] +} + +enum UserSortField { + """ + Sort users by first name. + """ + FIRST_NAME + + """ + Sort users by last name. + """ + LAST_NAME + + """ + Sort users by email. + """ + EMAIL + + """ + Sort users by order count. + """ + ORDER_COUNT +} + +input UserSortingInput { + """ + Specifies the direction in which to sort products. + """ + direction: OrderDirection! + + """ + Sort users by the selected field. + """ + field: UserSortField! +} + +""" +Represents a VAT rate for a country. +""" +type VAT { + """ + Country code. + """ + countryCode: String! + + """ + Standard VAT rate in percent. + """ + standardRate: Float + + """ + Country's VAT rate exceptions for specific types of goods. + """ + reducedRates: [ReducedRate]! +} + +enum VariantAttributeScope { + ALL + VARIANT_SELECTION + NOT_VARIANT_SELECTION +} + +""" +Assign an media to a product variant. +""" +type VariantMediaAssign { + productVariant: ProductVariant + media: ProductMedia + productErrors: [ProductError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [ProductError!]! +} + +""" +Unassign an media from a product variant. +""" +type VariantMediaUnassign { + productVariant: ProductVariant + media: ProductMedia + productErrors: [ProductError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [ProductError!]! +} + +""" +Represents availability of a variant in the storefront. +""" +type VariantPricingInfo { + """ + Whether it is in sale or not. + """ + onSale: Boolean + + """ + The discount amount if in sale (null otherwise). + """ + discount: TaxedMoney + + """ + The discount amount in the local currency. + """ + discountLocalCurrency: TaxedMoney + + """ + The price, with any discount subtracted. + """ + price: TaxedMoney + + """ + The price without any discount. + """ + priceUndiscounted: TaxedMoney + + """ + The discounted price in the local currency. + """ + priceLocalCurrency: TaxedMoney +} + +""" +Verify JWT token. +""" +type VerifyToken { + """ + User assigned to token. + """ + user: User + + """ + Determine if token is valid or not. + """ + isValid: Boolean! + + """ + JWT payload. + """ + payload: GenericScalar + accountErrors: [AccountError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [AccountError!]! +} + +""" +An enumeration. +""" +enum VolumeUnitsEnum { + CUBIC_MILLIMETER + CUBIC_CENTIMETER + CUBIC_DECIMETER + CUBIC_METER + LITER + CUBIC_FOOT + CUBIC_INCH + CUBIC_YARD + QT + PINT + FL_OZ + ACRE_IN + ACRE_FT +} + +""" +Vouchers allow giving discounts to particular customers on categories, collections or specific products. They can be used during checkout by providing valid voucher codes. +""" +type Voucher implements Node { + """ + The ID of the object. + """ + id: ID! + name: String + + """ + Determines a type of voucher. + """ + type: VoucherTypeEnum! + code: String! + usageLimit: Int + used: Int! + startDate: DateTime! + endDate: DateTime + applyOncePerOrder: Boolean! + applyOncePerCustomer: Boolean! + + """ + Determines a type of discount for voucher - value or percentage + """ + discountValueType: DiscountValueTypeEnum! + minCheckoutItemsQuantity: Int + + """ + List of categories this voucher applies to. + """ + categories( + """ + Return the elements in the list that come before the specified cursor. + """ + before: String + + """ + Return the elements in the list that come after the specified cursor. + """ + after: String + + """ + Return the first n elements from the list. + """ + first: Int + + """ + Return the last n elements from the list. + """ + last: Int + ): CategoryCountableConnection + + """ + List of collections this voucher applies to. + """ + collections( + """ + Return the elements in the list that come before the specified cursor. + """ + before: String + + """ + Return the elements in the list that come after the specified cursor. + """ + after: String + + """ + Return the first n elements from the list. + """ + first: Int + + """ + Return the last n elements from the list. + """ + last: Int + ): CollectionCountableConnection + + """ + List of products this voucher applies to. + """ + products( + """ + Return the elements in the list that come before the specified cursor. + """ + before: String + + """ + Return the elements in the list that come after the specified cursor. + """ + after: String + + """ + Return the first n elements from the list. + """ + first: Int + + """ + Return the last n elements from the list. + """ + last: Int + ): ProductCountableConnection + + """ + List of countries available for the shipping voucher. + """ + countries: [CountryDisplay] + + """ + Returns translated voucher fields for the given language code. + """ + translation( + """ + A language code to return the translation for voucher. + """ + languageCode: LanguageCodeEnum! + ): VoucherTranslation + + """ + Voucher value. + """ + discountValue: Float + + """ + Currency code for voucher. + """ + currency: String + + """ + Minimum order value to apply voucher. + """ + minSpent: Money + + """ + List of availability in channels for the voucher. + """ + channelListings: [VoucherChannelListing!] +} + +""" +Adds products, categories, collections to a voucher. +""" +type VoucherAddCatalogues { + """ + Voucher of which catalogue IDs will be modified. + """ + voucher: Voucher + discountErrors: [DiscountError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [DiscountError!]! +} + +""" +Deletes vouchers. +""" +type VoucherBulkDelete { + """ + Returns how many objects were affected. + """ + count: Int! + discountErrors: [DiscountError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [DiscountError!]! +} + +""" +Represents voucher channel listing. +""" +type VoucherChannelListing implements Node { + """ + The ID of the object. + """ + id: ID! + channel: Channel! + discountValue: Float! + currency: String! + minSpent: Money +} + +input VoucherChannelListingAddInput { + """ + ID of a channel. + """ + channelId: ID! + + """ + Value of the voucher. + """ + discountValue: PositiveDecimal + + """ + Min purchase amount required to apply the voucher. + """ + minAmountSpent: PositiveDecimal +} + +input VoucherChannelListingInput { + """ + List of channels to which the voucher should be assigned. + """ + addChannels: [VoucherChannelListingAddInput!] + + """ + List of channels from which the voucher should be unassigned. + """ + removeChannels: [ID!] +} + +""" +Manage voucher's availability in channels. +""" +type VoucherChannelListingUpdate { + """ + An updated voucher instance. + """ + voucher: Voucher + discountErrors: [DiscountError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [DiscountError!]! +} + +type VoucherCountableConnection { + """ + Pagination data for this connection. + """ + pageInfo: PageInfo! + edges: [VoucherCountableEdge!]! + + """ + A total count of items in the collection. + """ + totalCount: Int +} + +type VoucherCountableEdge { + """ + The item at the end of the edge. + """ + node: Voucher! + + """ + A cursor for use in pagination. + """ + cursor: String! +} + +""" +Creates a new voucher. +""" +type VoucherCreate { + discountErrors: [DiscountError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [DiscountError!]! + voucher: Voucher +} + +""" +Deletes a voucher. +""" +type VoucherDelete { + discountErrors: [DiscountError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [DiscountError!]! + voucher: Voucher +} + +enum VoucherDiscountType { + FIXED + PERCENTAGE + SHIPPING +} + +input VoucherFilterInput { + status: [DiscountStatusEnum] + timesUsed: IntRangeInput + discountType: [VoucherDiscountType] + started: DateTimeRangeInput + search: String +} + +input VoucherInput { + """ + Voucher type: PRODUCT, CATEGORY SHIPPING or ENTIRE_ORDER. + """ + type: VoucherTypeEnum + + """ + Voucher name. + """ + name: String + + """ + Code to use the voucher. + """ + code: String + + """ + Start date of the voucher in ISO 8601 format. + """ + startDate: DateTime + + """ + End date of the voucher in ISO 8601 format. + """ + endDate: DateTime + + """ + Choices: fixed or percentage. + """ + discountValueType: DiscountValueTypeEnum + + """ + Products discounted by the voucher. + """ + products: [ID] + + """ + Collections discounted by the voucher. + """ + collections: [ID] + + """ + Categories discounted by the voucher. + """ + categories: [ID] + + """ + Minimal quantity of checkout items required to apply the voucher. + """ + minCheckoutItemsQuantity: Int + + """ + Country codes that can be used with the shipping voucher. + """ + countries: [String] + + """ + Voucher should be applied to the cheapest item or entire order. + """ + applyOncePerOrder: Boolean + + """ + Voucher should be applied once per customer. + """ + applyOncePerCustomer: Boolean + + """ + Limit number of times this voucher can be used in total. + """ + usageLimit: Int +} + +""" +Removes products, categories, collections from a voucher. +""" +type VoucherRemoveCatalogues { + """ + Voucher of which catalogue IDs will be modified. + """ + voucher: Voucher + discountErrors: [DiscountError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [DiscountError!]! +} + +enum VoucherSortField { + """ + Sort vouchers by code. + """ + CODE + + """ + Sort vouchers by start date. + """ + START_DATE + + """ + Sort vouchers by end date. + """ + END_DATE + + """ + Sort vouchers by value. + """ + VALUE + + """ + Sort vouchers by type. + """ + TYPE + + """ + Sort vouchers by usage limit. + """ + USAGE_LIMIT + + """ + Sort vouchers by minimum spent amount. + """ + MINIMUM_SPENT_AMOUNT +} + +input VoucherSortingInput { + """ + Specifies the direction in which to sort products. + """ + direction: OrderDirection! + + """ + Specifies the channel in which to sort the data. + """ + channel: String + + """ + Sort vouchers by the selected field. + """ + field: VoucherSortField! +} + +type VoucherTranslatableContent implements Node { + """ + The ID of the object. + """ + id: ID! + name: String + + """ + Returns translated voucher fields for the given language code. + """ + translation( + """ + A language code to return the translation for voucher. + """ + languageCode: LanguageCodeEnum! + ): VoucherTranslation + + """ + Vouchers allow giving discounts to particular customers on categories, collections or specific products. They can be used during checkout by providing valid voucher codes. + """ + voucher: Voucher +} + +""" +Creates/Updates translations for Voucher. +""" +type VoucherTranslate { + translationErrors: [TranslationError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [TranslationError!]! + voucher: Voucher +} + +type VoucherTranslation implements Node { + """ + The ID of the object. + """ + id: ID! + name: String + + """ + Translation language. + """ + language: LanguageDisplay! +} + +enum VoucherTypeEnum { + SHIPPING + ENTIRE_ORDER + SPECIFIC_PRODUCT +} + +""" +Updates a voucher. +""" +type VoucherUpdate { + discountErrors: [DiscountError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [DiscountError!]! + voucher: Voucher +} + +""" +Represents warehouse. +""" +type Warehouse implements Node & ObjectWithMetadata { + """ + The ID of the object. + """ + id: ID! + name: String! + slug: String! + companyName: String! + shippingZones(before: String, after: String, first: Int, last: Int): ShippingZoneCountableConnection! + address: Address! + email: String! + + """ + List of private metadata items.Requires proper staff permissions to access. + """ + privateMetadata: [MetadataItem]! + + """ + List of public metadata items. Can be accessed without permissions. + """ + metadata: [MetadataItem]! +} + +input WarehouseAddressInput { + """ + Address. + """ + streetAddress1: String! + + """ + Address. + """ + streetAddress2: String + + """ + City. + """ + city: String! + + """ + District. + """ + cityArea: String + + """ + Postal code. + """ + postalCode: String + + """ + Country. + """ + country: CountryCode! + + """ + State or province. + """ + countryArea: String + + """ + Phone number. + """ + phone: String +} + +type WarehouseCountableConnection { + """ + Pagination data for this connection. + """ + pageInfo: PageInfo! + edges: [WarehouseCountableEdge!]! + + """ + A total count of items in the collection. + """ + totalCount: Int +} + +type WarehouseCountableEdge { + """ + The item at the end of the edge. + """ + node: Warehouse! + + """ + A cursor for use in pagination. + """ + cursor: String! +} + +""" +Creates new warehouse. +""" +type WarehouseCreate { + warehouseErrors: [WarehouseError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [WarehouseError!]! + warehouse: Warehouse +} + +input WarehouseCreateInput { + """ + Warehouse slug. + """ + slug: String + + """ + Company name. + """ + companyName: String + + """ + The email address of the warehouse. + """ + email: String + + """ + Warehouse name. + """ + name: String! + + """ + Address of the warehouse. + """ + address: WarehouseAddressInput! + + """ + Shipping zones supported by the warehouse. + """ + shippingZones: [ID] +} + +""" +Deletes selected warehouse. +""" +type WarehouseDelete { + warehouseErrors: [WarehouseError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [WarehouseError!]! + warehouse: Warehouse +} + +type WarehouseError { + """ + Name of a field that caused the error. A value of `null` indicates that the error isn't associated with a particular field. + """ + field: String + + """ + The error message. + """ + message: String + + """ + The error code. + """ + code: WarehouseErrorCode! +} + +""" +An enumeration. +""" +enum WarehouseErrorCode { + ALREADY_EXISTS + GRAPHQL_ERROR + INVALID + NOT_FOUND + REQUIRED + UNIQUE +} + +input WarehouseFilterInput { + search: String + ids: [ID] +} + +""" +Add shipping zone to given warehouse. +""" +type WarehouseShippingZoneAssign { + warehouseErrors: [WarehouseError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [WarehouseError!]! + warehouse: Warehouse +} + +""" +Remove shipping zone from given warehouse. +""" +type WarehouseShippingZoneUnassign { + warehouseErrors: [WarehouseError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [WarehouseError!]! + warehouse: Warehouse +} + +enum WarehouseSortField { + """ + Sort warehouses by name. + """ + NAME +} + +input WarehouseSortingInput { + """ + Specifies the direction in which to sort products. + """ + direction: OrderDirection! + + """ + Sort warehouses by the selected field. + """ + field: WarehouseSortField! +} + +""" +Updates given warehouse. +""" +type WarehouseUpdate { + warehouseErrors: [WarehouseError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [WarehouseError!]! + warehouse: Warehouse +} + +input WarehouseUpdateInput { + """ + Warehouse slug. + """ + slug: String + + """ + Company name. + """ + companyName: String + + """ + The email address of the warehouse. + """ + email: String + + """ + Warehouse name. + """ + name: String + + """ + Address of the warehouse. + """ + address: WarehouseAddressInput +} + +""" +Webhook. +""" +type Webhook implements Node { + name: String! + targetUrl: String! + isActive: Boolean! + secretKey: String + + """ + The ID of the object. + """ + id: ID! + + """ + List of webhook events. + """ + events: [WebhookEvent!]! + app: App! +} + +""" +Creates a new webhook subscription. +""" +type WebhookCreate { + webhookErrors: [WebhookError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [WebhookError!]! + webhook: Webhook +} + +input WebhookCreateInput { + """ + The name of the webhook. + """ + name: String + + """ + The url to receive the payload. + """ + targetUrl: String + + """ + The events that webhook wants to subscribe. + """ + events: [WebhookEventTypeEnum] + + """ + ID of the app to which webhook belongs. + """ + app: ID + + """ + Determine if webhook will be set active or not. + """ + isActive: Boolean + + """ + The secret key used to create a hash signature with each payload. + """ + secretKey: String +} + +""" +Deletes a webhook subscription. +""" +type WebhookDelete { + webhookErrors: [WebhookError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [WebhookError!]! + webhook: Webhook +} + +type WebhookError { + """ + Name of a field that caused the error. A value of `null` indicates that the error isn't associated with a particular field. + """ + field: String + + """ + The error message. + """ + message: String + + """ + The error code. + """ + code: WebhookErrorCode! +} + +""" +An enumeration. +""" +enum WebhookErrorCode { + GRAPHQL_ERROR + INVALID + NOT_FOUND + REQUIRED + UNIQUE +} + +""" +Webhook event. +""" +type WebhookEvent { + """ + Internal name of the event type. + """ + eventType: WebhookEventTypeEnum! + + """ + Display name of the event. + """ + name: String! +} + +""" +Enum determining type of webhook. +""" +enum WebhookEventTypeEnum { + """ + All the events. + """ + ANY_EVENTS + + """ + A new order is placed. + """ + ORDER_CREATED + + """ + An order is confirmed (status change unconfirmed -> unfulfilled) by a staff user using the OrderConfirm mutation. It also triggers when the user completes the checkout and the shop setting `automatically_confirm_all_new_orders` is enabled. + """ + ORDER_CONFIRMED + + """ + Payment is made and an order is fully paid. + """ + ORDER_FULLY_PAID + + """ + An order is updated; triggered for all changes related to an order; covers all other order webhooks, except for ORDER_CREATED. + """ + ORDER_UPDATED + + """ + An order is cancelled. + """ + ORDER_CANCELLED + + """ + An order is fulfilled. + """ + ORDER_FULFILLED + + """ + An invoice for order requested. + """ + INVOICE_REQUESTED + + """ + An invoice is deleted. + """ + INVOICE_DELETED + + """ + Invoice has been sent. + """ + INVOICE_SENT + + """ + A new customer account is created. + """ + CUSTOMER_CREATED + + """ + A customer account is updated. + """ + CUSTOMER_UPDATED + + """ + A new product is created. + """ + PRODUCT_CREATED + + """ + A product is updated. + """ + PRODUCT_UPDATED + + """ + A product is deleted. + """ + PRODUCT_DELETED + + """ + A new product variant is created. + """ + PRODUCT_VARIANT_CREATED + + """ + A product variant is updated. + """ + PRODUCT_VARIANT_UPDATED + + """ + A product variant is deleted. + """ + PRODUCT_VARIANT_DELETED + + """ + A new checkout is created. + """ + CHECKOUT_CREATED + + """ + A checkout is updated. It also triggers all updates related to the checkout. + """ + CHECKOUT_UPDATED + + """ + A new fulfillment is created. + """ + FULFILLMENT_CREATED + + """ + User notification triggered. + """ + NOTIFY_USER + + """ + A new page is created. + """ + PAGE_CREATED + + """ + A page is updated. + """ + PAGE_UPDATED + + """ + A page is deleted. + """ + PAGE_DELETED +} + +""" +An enumeration. +""" +enum WebhookSampleEventTypeEnum { + ORDER_CREATED + ORDER_CONFIRMED + ORDER_FULLY_PAID + ORDER_UPDATED + ORDER_CANCELLED + ORDER_FULFILLED + INVOICE_REQUESTED + INVOICE_DELETED + INVOICE_SENT + CUSTOMER_CREATED + CUSTOMER_UPDATED + PRODUCT_CREATED + PRODUCT_UPDATED + PRODUCT_DELETED + PRODUCT_VARIANT_CREATED + PRODUCT_VARIANT_UPDATED + PRODUCT_VARIANT_DELETED + CHECKOUT_CREATED + CHECKOUT_UPDATED + FULFILLMENT_CREATED + NOTIFY_USER + PAGE_CREATED + PAGE_UPDATED + PAGE_DELETED +} + +""" +Updates a webhook subscription. +""" +type WebhookUpdate { + webhookErrors: [WebhookError!]! + @deprecated(reason: "Use errors field instead. This field will be removed in Saleor 4.0.") + errors: [WebhookError!]! + webhook: Webhook +} + +input WebhookUpdateInput { + """ + The new name of the webhook. + """ + name: String + + """ + The url to receive the payload. + """ + targetUrl: String + + """ + The events that webhook wants to subscribe. + """ + events: [WebhookEventTypeEnum] + + """ + ID of the app to which webhook belongs. + """ + app: ID + + """ + Determine if webhook will be set active or not. + """ + isActive: Boolean + + """ + Use to create a hash signature with each payload. + """ + secretKey: String +} + +""" +Represents weight value in a specific weight unit. +""" +type Weight { + """ + Weight unit. + """ + unit: WeightUnitsEnum! + + """ + Weight value. + """ + value: Float! +} + +scalar WeightScalar + +""" +An enumeration. +""" +enum WeightUnitsEnum { + G + LB + OZ + KG + TONNE +} + +""" +Anything +""" +scalar _Any + +union _Entity = + Address + | User + | Group + | App + | ProductVariant + | Product + | ProductType + | Collection + | Category + | ProductMedia + | ProductImage + | PageType + +type _Service { + sdl: String +} diff --git a/framework/saleor/types.ts b/framework/saleor/types.ts new file mode 100644 index 000000000..2025b8898 --- /dev/null +++ b/framework/saleor/types.ts @@ -0,0 +1,43 @@ +import type { Cart as CoreCart } from '@commerce/types' +import { CheckoutLine } from './schema' + +export type SaleorCheckout = { + id: string + webUrl: string + lineItems: CheckoutLine[] +} + +export type Cart = CoreCart.Cart & { + lineItems: LineItem[] +} +export interface LineItem extends CoreCart.LineItem { + options?: any[] +} + +/** + * Cart mutations + */ + +export type OptionSelections = { + option_id: number + option_value: number | string +} + +export type CartItemBody = CoreCart.CartItemBody & { + productId: string // The product id is always required for BC + optionSelections?: OptionSelections +} + +// export type GetCartHandlerBody = CoreCart.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/saleor/types/cart.ts b/framework/saleor/types/cart.ts new file mode 100644 index 000000000..1f4ba61df --- /dev/null +++ b/framework/saleor/types/cart.ts @@ -0,0 +1,32 @@ +import * as Core from '@commerce/types/cart' + +export * from '@commerce/types/cart' + +export type SaleorCart = {} + +/** + * Extend core cart types + */ + +export type Cart = Core.Cart & { + lineItems: Core.LineItem[] + url?: string +} + +export type CartTypes = Core.CartTypes + +export type CartHooks = Core.CartHooks + +export type GetCartHook = CartHooks['getCart'] +export type AddItemHook = CartHooks['addItem'] +export type UpdateItemHook = CartHooks['updateItem'] +export type RemoveItemHook = CartHooks['removeItem'] + +export type CartSchema = Core.CartSchema + +export type CartHandlers = Core.CartHandlers + +export type GetCartHandler = CartHandlers['getCart'] +export type AddItemHandler = CartHandlers['addItem'] +export type UpdateItemHandler = CartHandlers['updateItem'] +export type RemoveItemHandler = CartHandlers['removeItem'] diff --git a/framework/saleor/utils/checkout-attach.ts b/framework/saleor/utils/checkout-attach.ts new file mode 100644 index 000000000..476c73e77 --- /dev/null +++ b/framework/saleor/utils/checkout-attach.ts @@ -0,0 +1,12 @@ +import * as mutation from './mutations' +import { CheckoutCustomerAttach } from '../schema' + +export const checkoutAttach = async (fetch: any, { variables, headers }: any): Promise => { + const data = await fetch({ + query: mutation.CheckoutAttach, + variables, + headers, + }) + + return data +} diff --git a/framework/saleor/utils/checkout-create.ts b/framework/saleor/utils/checkout-create.ts new file mode 100644 index 000000000..c1b6e4023 --- /dev/null +++ b/framework/saleor/utils/checkout-create.ts @@ -0,0 +1,25 @@ +import Cookies from 'js-cookie' + +import * as mutation from './mutations' +import { CheckoutCreate } from '../schema' +import { CHECKOUT_ID_COOKIE } from '@framework/const' + +export const checkoutCreate = async (fetch: any): Promise => { + const data = await fetch({ query: mutation.CheckoutCreate }) + const checkout = data.checkoutCreate?.checkout + const checkoutId = checkout?.id + const checkoutToken = checkout?.token + + const value = `${checkoutId}:${checkoutToken}` + + if (checkoutId) { + const options = { + expires: 60 * 60 * 24 * 30, + } + Cookies.set(CHECKOUT_ID_COOKIE, value, options) + } + + return checkout +} + +export default checkoutCreate diff --git a/framework/saleor/utils/checkout-to-cart.ts b/framework/saleor/utils/checkout-to-cart.ts new file mode 100644 index 000000000..638ca815e --- /dev/null +++ b/framework/saleor/utils/checkout-to-cart.ts @@ -0,0 +1,35 @@ +import { Cart } from '../types' +import { CommerceError } from '@commerce/utils/errors' + +import { CheckoutLinesAdd, CheckoutLinesUpdate, CheckoutCreate, CheckoutError, Checkout, Maybe, CheckoutLineDelete } from '../schema' + +import { normalizeCart } from './normalize' +import throwUserErrors from './throw-user-errors' + +export type CheckoutQuery = { + checkout: Checkout + errors?: Array +} + +export type CheckoutPayload = CheckoutLinesAdd | CheckoutLinesUpdate | CheckoutCreate | CheckoutQuery | CheckoutLineDelete + +const checkoutToCart = (checkoutPayload?: Maybe): Cart => { + if (!checkoutPayload) { + throw new CommerceError({ + message: 'Missing checkout payload from response', + }) + } + + const checkout = checkoutPayload?.checkout + throwUserErrors(checkoutPayload?.errors) + + if (!checkout) { + throw new CommerceError({ + message: 'Missing checkout object from response', + }) + } + + return normalizeCart(checkout) +} + +export default checkoutToCart diff --git a/framework/saleor/utils/customer-token.ts b/framework/saleor/utils/customer-token.ts new file mode 100644 index 000000000..dd15fbe25 --- /dev/null +++ b/framework/saleor/utils/customer-token.ts @@ -0,0 +1,25 @@ +import Cookies, { CookieAttributes } from 'js-cookie' +import * as Const from '../const' + +export const getToken = () => Cookies.get(Const.SALEOR_TOKEN) +export const setToken = (token?: string, options?: CookieAttributes) => { + setCookie(Const.SALEOR_TOKEN, token, options) +} + +export const getCSRFToken = () => Cookies.get(Const.SALEOR_CRSF_TOKEN) +export const setCSRFToken = (token?: string, options?: CookieAttributes) => { + setCookie(Const.SALEOR_CRSF_TOKEN, token, options) +} + +export const getCheckoutToken = () => Cookies.get(Const.CHECKOUT_ID_COOKIE) +export const setCheckoutToken = (token?: string, options?: CookieAttributes) => { + setCookie(Const.CHECKOUT_ID_COOKIE, token, options) +} + +const setCookie = (name: string, token?: string, options?: CookieAttributes) => { + if (!token) { + Cookies.remove(name) + } else { + Cookies.set(name, token, options ?? { expires: 60 * 60 * 24 * 30 }) + } +} diff --git a/framework/saleor/utils/fragments/checkout-details.ts b/framework/saleor/utils/fragments/checkout-details.ts new file mode 100644 index 000000000..437c24777 --- /dev/null +++ b/framework/saleor/utils/fragments/checkout-details.ts @@ -0,0 +1,49 @@ +export const CheckoutDetails = /* GraphQL */ ` + fragment CheckoutDetails on Checkout { + id + token + created + totalPrice { + currency + gross { + amount + } + } + subtotalPrice { + currency + gross { + amount + } + } + + lines { + id + variant { + id + name + sku + product { + name + slug + } + media { + url + } + pricing { + price { + gross { + amount + } + } + } + } + quantity + totalPrice { + currency + gross { + amount + } + } + } + } +` diff --git a/framework/saleor/utils/fragments/index.ts b/framework/saleor/utils/fragments/index.ts new file mode 100644 index 000000000..6c0c88950 --- /dev/null +++ b/framework/saleor/utils/fragments/index.ts @@ -0,0 +1,2 @@ +export { ProductConnection } from './product' +export { CheckoutDetails } from './checkout-details' diff --git a/framework/saleor/utils/fragments/product.ts b/framework/saleor/utils/fragments/product.ts new file mode 100644 index 000000000..1ea59c02d --- /dev/null +++ b/framework/saleor/utils/fragments/product.ts @@ -0,0 +1,29 @@ +export const ProductConnection = /* GraphQL */ ` + fragment ProductConnection on ProductCountableConnection { + pageInfo { + hasNextPage + hasPreviousPage + } + edges { + node { + id + name + description + slug + pricing { + priceRange { + start { + net { + amount + } + } + } + } + media { + url + alt + } + } + } + } +` diff --git a/framework/saleor/utils/get-categories.ts b/framework/saleor/utils/get-categories.ts new file mode 100644 index 000000000..990c0a404 --- /dev/null +++ b/framework/saleor/utils/get-categories.ts @@ -0,0 +1,23 @@ +import { Category } from '@commerce/types/site' +import { SaleorConfig } from '../api' +import { CollectionCountableEdge } from '../schema' +import * as query from './queries' + +const getCategories = async (config: SaleorConfig): Promise => { + const { data } = await config.fetch(query.CollectionMany, { + variables: { + first: 100, + }, + }) + + return ( + data.collections?.edges?.map(({ node: { id, name, slug } }: CollectionCountableEdge) => ({ + id, + name, + slug, + path: `/${slug}`, + })) ?? [] + ) +} + +export default getCategories diff --git a/framework/saleor/utils/get-checkout-id.ts b/framework/saleor/utils/get-checkout-id.ts new file mode 100644 index 000000000..de495a9ad --- /dev/null +++ b/framework/saleor/utils/get-checkout-id.ts @@ -0,0 +1,9 @@ +import Cookies from 'js-cookie' +import { CHECKOUT_ID_COOKIE } from '../const' + +const getCheckoutId = (id?: string) => { + const r = Cookies.get(CHECKOUT_ID_COOKIE)?.split(':') || [] + return { checkoutId: r[0], checkoutToken: r[1] } +} + +export default getCheckoutId diff --git a/framework/saleor/utils/get-search-variables.ts b/framework/saleor/utils/get-search-variables.ts new file mode 100644 index 000000000..5adf938e8 --- /dev/null +++ b/framework/saleor/utils/get-search-variables.ts @@ -0,0 +1,18 @@ +import { getSortVariables } from './get-sort-variables' +import type { SearchProductsInput } from '../product/use-search' + +export const getSearchVariables = ({ brandId, search, categoryId, sort }: SearchProductsInput) => { + const sortBy = { + field: 'NAME', + direction: 'ASC', + ...getSortVariables(sort, !!categoryId), + channel: 'default-channel', + } + return { + categoryId, + filter: { search }, + sortBy, + } +} + +export default getSearchVariables diff --git a/framework/saleor/utils/get-sort-variables.ts b/framework/saleor/utils/get-sort-variables.ts new file mode 100644 index 000000000..fe040a0a5 --- /dev/null +++ b/framework/saleor/utils/get-sort-variables.ts @@ -0,0 +1,30 @@ +export const getSortVariables = (sort?: string, isCategory: boolean = false) => { + let output = {} + switch (sort) { + case 'price-asc': + output = { + field: 'PRICE', + direction: 'ASC', + } + break + case 'price-desc': + output = { + field: 'PRICE', + direction: 'DESC', + } + break + case 'trending-desc': + output = { + field: 'RANK', + direction: 'DESC', + } + break + case 'latest-desc': + output = { + field: 'DATE', + direction: 'DESC', + } + break + } + return output +} diff --git a/framework/saleor/utils/get-vendors.ts b/framework/saleor/utils/get-vendors.ts new file mode 100644 index 000000000..caae555a8 --- /dev/null +++ b/framework/saleor/utils/get-vendors.ts @@ -0,0 +1,41 @@ +import { SaleorConfig } from '../api' + +export type Brand = { + entityId: string + name: string + path: string +} + +export type BrandEdge = { + node: Brand +} + +export type Brands = BrandEdge[] + +// TODO: Find a way to get vendors from meta +const getVendors = async (config: SaleorConfig): Promise => { + // const vendors = await fetchAllProducts({ + // config, + // query: getAllProductVendors, + // variables: { + // first: 100, + // }, + // }) + + // let vendorsStrings = vendors.map(({ node: { vendor } }) => vendor) + + // return [...new Set(vendorsStrings)].map((v) => { + // const id = v.replace(/\s+/g, '-').toLowerCase() + // return { + // node: { + // entityId: id, + // name: v, + // path: `brands/${id}`, + // }, + // } + // }) + + return [] +} + +export default getVendors diff --git a/framework/saleor/utils/handle-fetch-response.ts b/framework/saleor/utils/handle-fetch-response.ts new file mode 100644 index 000000000..6a2b5f57b --- /dev/null +++ b/framework/saleor/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 Saleor 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/saleor/utils/handle-login.ts b/framework/saleor/utils/handle-login.ts new file mode 100644 index 000000000..4ef390174 --- /dev/null +++ b/framework/saleor/utils/handle-login.ts @@ -0,0 +1,35 @@ +import { FetcherOptions } from '@commerce/utils/types' +import { CreateToken, Mutation, MutationTokenCreateArgs } from '../schema' +import { setToken, setCSRFToken } from './customer-token' +import * as mutation from './mutations' +import throwUserErrors from './throw-user-errors' + +const handleLogin = (data: CreateToken) => { + throwUserErrors(data?.errors) + + const token = data?.token + + if (token) { + setToken(token) + setCSRFToken(token) + } + + return token +} + +export const handleAutomaticLogin = async ( + fetch: (options: FetcherOptions) => Promise, + input: MutationTokenCreateArgs +) => { + try { + const { tokenCreate } = await fetch({ + query: mutation.SessionCreate, + variables: { ...input }, + }) + handleLogin(tokenCreate!) + } catch (error) { + // + } +} + +export default handleLogin diff --git a/framework/saleor/utils/index.ts b/framework/saleor/utils/index.ts new file mode 100644 index 000000000..de81eea67 --- /dev/null +++ b/framework/saleor/utils/index.ts @@ -0,0 +1,19 @@ +export { getSortVariables } from './get-sort-variables' + +export { default as handleFetchResponse } from './handle-fetch-response' +export { default as getSearchVariables } from './get-search-variables' +export { default as getVendors } from './get-vendors' +export { default as getCategories } from './get-categories' +export { default as getCheckoutId } from './get-checkout-id' + +export { default as checkoutCreate } from './checkout-create' +export { checkoutAttach } from './checkout-attach' + +export { default as checkoutToCart } from './checkout-to-cart' +export { default as handleLogin, handleAutomaticLogin } from './handle-login' +export { default as throwUserErrors } from './throw-user-errors' + +export * from './queries' +export * from './mutations' +export * from './normalize' +export * from './customer-token' diff --git a/framework/saleor/utils/mutations/account-create.ts b/framework/saleor/utils/mutations/account-create.ts new file mode 100644 index 000000000..f50fe6ddd --- /dev/null +++ b/framework/saleor/utils/mutations/account-create.ts @@ -0,0 +1,15 @@ +export const AccountCreate = /* GraphQL */ ` + mutation AccountCreate($input: AccountRegisterInput!) { + accountRegister(input: $input) { + errors { + code + field + message + } + user { + email + isActive + } + } + } +` diff --git a/framework/saleor/utils/mutations/checkout-attach.ts b/framework/saleor/utils/mutations/checkout-attach.ts new file mode 100644 index 000000000..435be0582 --- /dev/null +++ b/framework/saleor/utils/mutations/checkout-attach.ts @@ -0,0 +1,12 @@ +export const CheckoutAttach = /* GraphQl */ ` + mutation CheckoutAttach($checkoutId: ID!) { + checkoutCustomerAttach(checkoutId: $checkoutId) { + errors { + message + } + checkout { + id + } + } + } +` diff --git a/framework/saleor/utils/mutations/checkout-create.ts b/framework/saleor/utils/mutations/checkout-create.ts new file mode 100644 index 000000000..3cfe9d480 --- /dev/null +++ b/framework/saleor/utils/mutations/checkout-create.ts @@ -0,0 +1,17 @@ +import * as fragment from '../fragments' + +export const CheckoutCreate = /* GraphQL */ ` + mutation CheckoutCreate { + checkoutCreate(input: { email: "customer@example.com", lines: [], channel: "default-channel" }) { + errors { + code + field + message + } + checkout { + ...CheckoutDetails + } + } + } + ${fragment.CheckoutDetails} +` diff --git a/framework/saleor/utils/mutations/checkout-line-add.ts b/framework/saleor/utils/mutations/checkout-line-add.ts new file mode 100644 index 000000000..e7b8e0a27 --- /dev/null +++ b/framework/saleor/utils/mutations/checkout-line-add.ts @@ -0,0 +1,17 @@ +import * as fragment from '../fragments' + +export const CheckoutLineAdd = /* GraphQL */ ` + mutation CheckoutLineAdd($checkoutId: ID!, $lineItems: [CheckoutLineInput!]!) { + checkoutLinesAdd(checkoutId: $checkoutId, lines: $lineItems) { + errors { + code + field + message + } + checkout { + ...CheckoutDetails + } + } + } + ${fragment.CheckoutDetails} +` diff --git a/framework/saleor/utils/mutations/checkout-line-remove.ts b/framework/saleor/utils/mutations/checkout-line-remove.ts new file mode 100644 index 000000000..191ef54aa --- /dev/null +++ b/framework/saleor/utils/mutations/checkout-line-remove.ts @@ -0,0 +1,17 @@ +import * as fragment from '../fragments' + +export const CheckoutLineDelete = /* GraphQL */ ` + mutation CheckoutLineDelete($checkoutId: ID!, $lineId: ID!) { + checkoutLineDelete(checkoutId: $checkoutId, lineId: $lineId) { + errors { + code + field + message + } + checkout { + ...CheckoutDetails + } + } + } + ${fragment.CheckoutDetails} +` diff --git a/framework/saleor/utils/mutations/checkout-line-update.ts b/framework/saleor/utils/mutations/checkout-line-update.ts new file mode 100644 index 000000000..50019d6ef --- /dev/null +++ b/framework/saleor/utils/mutations/checkout-line-update.ts @@ -0,0 +1,17 @@ +import * as fragment from '../fragments' + +export const CheckoutLineUpdate = /* GraphQL */ ` + mutation CheckoutLineUpdate($checkoutId: ID!, $lineItems: [CheckoutLineInput!]!) { + checkoutLinesUpdate(checkoutId: $checkoutId, lines: $lineItems) { + errors { + code + field + message + } + checkout { + ...CheckoutDetails + } + } + } + ${fragment.CheckoutDetails} +` diff --git a/framework/saleor/utils/mutations/index.ts b/framework/saleor/utils/mutations/index.ts new file mode 100644 index 000000000..a1f3d6089 --- /dev/null +++ b/framework/saleor/utils/mutations/index.ts @@ -0,0 +1,8 @@ +export { AccountCreate } from './account-create' +export { CheckoutCreate } from './checkout-create' +export { CheckoutLineAdd } from './checkout-line-add' +export { CheckoutLineUpdate } from './checkout-line-update' +export { CheckoutLineDelete } from './checkout-line-remove' +export { SessionCreate } from './session-create' +export { SessionDestroy } from './session-destroy' +export { CheckoutAttach } from './checkout-attach' diff --git a/framework/saleor/utils/mutations/session-create.ts b/framework/saleor/utils/mutations/session-create.ts new file mode 100644 index 000000000..d3c5a513d --- /dev/null +++ b/framework/saleor/utils/mutations/session-create.ts @@ -0,0 +1,14 @@ +export const SessionCreate = /* GraphQL */ ` + mutation SessionCreate($email: String!, $password: String!) { + tokenCreate(email: $email, password: $password) { + token + refreshToken + csrfToken + errors { + code + field + message + } + } + } +` diff --git a/framework/saleor/utils/mutations/session-destroy.ts b/framework/saleor/utils/mutations/session-destroy.ts new file mode 100644 index 000000000..def3a04ad --- /dev/null +++ b/framework/saleor/utils/mutations/session-destroy.ts @@ -0,0 +1,10 @@ +export const SessionDestroy = /* GraphQL */ ` + mutation SessionDestroy { + tokensDeactivateAll { + errors { + field + message + } + } + } +` diff --git a/framework/saleor/utils/normalize.ts b/framework/saleor/utils/normalize.ts new file mode 100644 index 000000000..56091db15 --- /dev/null +++ b/framework/saleor/utils/normalize.ts @@ -0,0 +1,133 @@ +import { Product } from '@commerce/types/product' + +import { Product as SaleorProduct, Checkout, CheckoutLine, Money, ProductVariant } from '../schema' + +import type { Cart, LineItem } from '../types' + +// TODO: Check nextjs-commerce bug if no images are added for a product +const placeholderImg = '/product-img-placeholder.svg' + +const money = ({ amount, currency }: Money) => { + return { + value: +amount, + currencyCode: currency || 'USD', + } +} + +const normalizeProductOptions = (options: ProductVariant[]) => { + return options + ?.map((option) => option?.attributes) + .flat(1) + .reduce((acc, x) => { + if (acc.find(({ displayName }: any) => displayName === x.attribute.name)) { + return acc.map((opt: any) => { + return opt.displayName === x.attribute.name + ? { + ...opt, + values: [ + ...opt.values, + ...x.values.map((value: any) => ({ + label: value?.name, + })), + ], + } + : opt + }) + } + + return acc.concat({ + __typename: 'MultipleChoiceOption', + displayName: x.attribute.name, + variant: 'size', + values: x.values.map((value: any) => ({ + label: value?.name, + })), + }) + }, []) +} + +const normalizeProductVariants = (variants: ProductVariant[]) => { + return variants?.map((variant) => { + const { id, sku, name, pricing } = variant + const price = pricing?.price?.net && money(pricing.price.net)?.value + + return { + id, + name, + sku: sku ?? id, + price, + listPrice: price, + requiresShipping: true, + options: normalizeProductOptions([variant]), + } + }) +} + +export function normalizeProduct(productNode: SaleorProduct): Product { + const { id, name, media = [], variants, description, slug, pricing, ...rest } = productNode + + const product = { + id, + name, + vendor: '', + description: description ? JSON.parse(description)?.blocks[0]?.data.text : '', + path: `/${slug}`, + slug: slug?.replace(/^\/+|\/+$/g, ''), + price: (pricing?.priceRange?.start?.net && money(pricing.priceRange.start.net)) || { + value: 0, + currencyCode: 'USD', + }, + // TODO: Check nextjs-commerce bug if no images are added for a product + images: media?.length ? media : [{ url: placeholderImg }], + variants: variants && variants.length > 0 ? normalizeProductVariants(variants as ProductVariant[]) : [], + options: variants && variants.length > 0 ? normalizeProductOptions(variants as ProductVariant[]) : [], + ...rest, + } + + return product as Product +} + +export function normalizeCart(checkout: Checkout): Cart { + const lines = checkout.lines as CheckoutLine[] + const lineItems: LineItem[] = lines.length > 0 ? lines?.map(normalizeLineItem) : [] + + return { + id: checkout.id, + customerId: '', + email: '', + createdAt: checkout.created, + currency: { + code: checkout.totalPrice?.currency!, + }, + taxesIncluded: false, + lineItems, + lineItemsSubtotalPrice: checkout.subtotalPrice?.gross?.amount!, + subtotalPrice: checkout.subtotalPrice?.gross?.amount!, + totalPrice: checkout.totalPrice?.gross.amount!, + discounts: [], + } +} + +function normalizeLineItem({ id, variant, quantity }: CheckoutLine): LineItem { + return { + id, + variantId: String(variant?.id), + productId: String(variant?.id), + name: `${variant.product.name}`, + quantity, + variant: { + id: String(variant?.id), + sku: variant?.sku ?? '', + name: variant?.name!, + image: { + url: variant?.media![0] ? variant?.media![0].url : placeholderImg, + }, + requiresShipping: false, + price: variant?.pricing?.price?.gross.amount!, + listPrice: 0, + }, + path: String(variant?.product?.slug), + discounts: [], + options: [], + } +} diff --git a/framework/saleor/utils/queries/checkout-one.ts b/framework/saleor/utils/queries/checkout-one.ts new file mode 100644 index 000000000..ce4823671 --- /dev/null +++ b/framework/saleor/utils/queries/checkout-one.ts @@ -0,0 +1,12 @@ +import * as fragment from '../fragments' + +export const CheckoutOne = /* GraphQL */ ` + query CheckoutOne($checkoutId: UUID!) { + checkout(token: $checkoutId) { + ... on Checkout { + ...CheckoutDetails + } + } + } + ${fragment.CheckoutDetails} +` diff --git a/framework/saleor/utils/queries/collection-many.ts b/framework/saleor/utils/queries/collection-many.ts new file mode 100644 index 000000000..b556e3faf --- /dev/null +++ b/framework/saleor/utils/queries/collection-many.ts @@ -0,0 +1,13 @@ +export const CollectionMany = /* GraphQL */ ` + query CollectionMany($first: Int!, $channel: String = "default-channel") { + collections(first: $first, channel: $channel) { + edges { + node { + id + name + slug + } + } + } + } +` diff --git a/framework/saleor/utils/queries/collection-one.ts b/framework/saleor/utils/queries/collection-one.ts new file mode 100644 index 000000000..c2e593f51 --- /dev/null +++ b/framework/saleor/utils/queries/collection-one.ts @@ -0,0 +1,13 @@ +import * as fragment from '../fragments' + +export const CollectionOne = /* GraphQL */ ` + query getProductsFromCollection($categoryId: ID!, $first: Int = 100, $channel: String = "default-channel") { + collection(id: $categoryId, channel: $channel) { + id + products(first: $first) { + ...ProductConnection + } + } + } + ${fragment.ProductConnection} +` diff --git a/framework/saleor/utils/queries/customer-current.ts b/framework/saleor/utils/queries/customer-current.ts new file mode 100644 index 000000000..796545198 --- /dev/null +++ b/framework/saleor/utils/queries/customer-current.ts @@ -0,0 +1,11 @@ +export const CustomerCurrent = /* GraphQL */ ` + query CustomerCurrent { + me { + id + email + firstName + lastName + dateJoined + } + } +` diff --git a/framework/saleor/utils/queries/customer-one.ts b/framework/saleor/utils/queries/customer-one.ts new file mode 100644 index 000000000..d35b3f5ff --- /dev/null +++ b/framework/saleor/utils/queries/customer-one.ts @@ -0,0 +1,7 @@ +export const CustomerOne = /* GraphQL */ ` + query CustomerOne($customerAccessToken: String!) { + customer(customerAccessToken: $customerAccessToken) { + id + } + } +` diff --git a/framework/saleor/utils/queries/get-all-product-vendors-query.ts b/framework/saleor/utils/queries/get-all-product-vendors-query.ts new file mode 100644 index 000000000..7d0f01614 --- /dev/null +++ b/framework/saleor/utils/queries/get-all-product-vendors-query.ts @@ -0,0 +1,16 @@ +export const getAllProductVendors = /* GraphQL */ ` + query getAllProductVendors($first: Int = 250, $cursor: String) { + products(first: $first, after: $cursor) { + pageInfo { + hasNextPage + hasPreviousPage + } + edges { + node { + vendor + } + cursor + } + } + } +` diff --git a/framework/saleor/utils/queries/get-all-products-paths-query.ts b/framework/saleor/utils/queries/get-all-products-paths-query.ts new file mode 100644 index 000000000..d9acb82cf --- /dev/null +++ b/framework/saleor/utils/queries/get-all-products-paths-query.ts @@ -0,0 +1,16 @@ +export const getAllProductsPathsQuery = /* GraphQL */ ` + query getAllProductPaths($first: Int = 100, $cursor: String, $channel: String = "default-channel") { + products(first: $first, after: $cursor, channel: $channel) { + pageInfo { + hasNextPage + hasPreviousPage + } + edges { + node { + slug + } + cursor + } + } + } +` diff --git a/framework/saleor/utils/queries/index.ts b/framework/saleor/utils/queries/index.ts new file mode 100644 index 000000000..542c46f7c --- /dev/null +++ b/framework/saleor/utils/queries/index.ts @@ -0,0 +1,14 @@ +export { CollectionMany } from './collection-many' +export { ProductOneBySlug } from './product-one-by-slug' +export { ProductMany } from './product-many' +export { CollectionOne } from './collection-one' +export { CheckoutOne } from './checkout-one' +export { PageMany } from './page-many' +export { PageOne } from './page-one' +export { CustomerCurrent } from './customer-current' + +// getCustomerIdQuery +export { CustomerOne } from './customer-one' + +export { getAllProductsPathsQuery } from './get-all-products-paths-query' +export { getAllProductVendors } from './get-all-product-vendors-query' diff --git a/framework/saleor/utils/queries/page-many.ts b/framework/saleor/utils/queries/page-many.ts new file mode 100644 index 000000000..94bba696d --- /dev/null +++ b/framework/saleor/utils/queries/page-many.ts @@ -0,0 +1,13 @@ +export const PageMany = /* GraphQL */ ` + query PageMany($first: Int = 100) { + pages(first: $first) { + edges { + node { + id + title + slug + } + } + } + } +` diff --git a/framework/saleor/utils/queries/page-one.ts b/framework/saleor/utils/queries/page-one.ts new file mode 100644 index 000000000..6d9789a9e --- /dev/null +++ b/framework/saleor/utils/queries/page-one.ts @@ -0,0 +1,9 @@ +export const PageOne = /* GraphQL */ ` + query PageOne($id: ID!) { + page(id: $id) { + id + title + slug + } + } +` diff --git a/framework/saleor/utils/queries/product-many.ts b/framework/saleor/utils/queries/product-many.ts new file mode 100644 index 000000000..7e0aa9a07 --- /dev/null +++ b/framework/saleor/utils/queries/product-many.ts @@ -0,0 +1,15 @@ +import * as fragment from '../fragments' + +export const ProductMany = /* GraphQL */ ` + query ProductMany( + $first: Int = 100 + $filter: ProductFilterInput + $sortBy: ProductOrder + $channel: String = "default-channel" + ) { + products(first: $first, channel: $channel, filter: $filter, sortBy: $sortBy) { + ...ProductConnection + } + } + ${fragment.ProductConnection} +` diff --git a/framework/saleor/utils/queries/product-one-by-slug.ts b/framework/saleor/utils/queries/product-one-by-slug.ts new file mode 100644 index 000000000..e9169f05e --- /dev/null +++ b/framework/saleor/utils/queries/product-one-by-slug.ts @@ -0,0 +1,43 @@ +export const ProductOneBySlug = /* GraphQL */ ` + query ProductOneBySlug($slug: String!, $channel: String = "default-channel") { + product(slug: $slug, channel: $channel) { + id + slug + name + description + pricing { + priceRange { + start { + net { + amount + } + } + } + } + variants { + id + name + attributes { + attribute { + name + } + values { + name + } + } + pricing { + price { + net { + amount + currency + } + } + } + } + media { + url + alt + } + } + } +` diff --git a/framework/saleor/utils/throw-user-errors.ts b/framework/saleor/utils/throw-user-errors.ts new file mode 100644 index 000000000..2991d78a6 --- /dev/null +++ b/framework/saleor/utils/throw-user-errors.ts @@ -0,0 +1,20 @@ +import { ValidationError } from '@commerce/utils/errors' + +import { CheckoutError, CheckoutErrorCode, AppError, AccountError, AccountErrorCode } from '../schema' + +export type UserErrors = Array + +export type UserErrorCode = CheckoutErrorCode | AccountErrorCode | null | undefined + +export const throwUserErrors = (errors?: UserErrors) => { + if (errors && errors.length) { + throw new ValidationError({ + errors: errors.map(({ code, message }) => ({ + code: code ?? 'validation_error', + message: message || '', + })), + }) + } +} + +export default throwUserErrors diff --git a/framework/saleor/wishlist/use-add-item.tsx b/framework/saleor/wishlist/use-add-item.tsx new file mode 100644 index 000000000..75f067c3a --- /dev/null +++ b/framework/saleor/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/saleor/wishlist/use-remove-item.tsx b/framework/saleor/wishlist/use-remove-item.tsx new file mode 100644 index 000000000..a2d3a8a05 --- /dev/null +++ b/framework/saleor/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/saleor/wishlist/use-wishlist.tsx b/framework/saleor/wishlist/use-wishlist.tsx new file mode 100644 index 000000000..cdd9a643d --- /dev/null +++ b/framework/saleor/wishlist/use-wishlist.tsx @@ -0,0 +1,46 @@ +// TODO: replace this hook and other wishlist hooks with a handler, or remove them if +// Saleor 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) diff --git a/next.config.js b/next.config.js index 607d4eba8..77d586e6c 100644 --- a/next.config.js +++ b/next.config.js @@ -7,10 +7,14 @@ const { const provider = commerce.provider || getProviderName() const isBC = provider === 'bigcommerce' const isShopify = provider === 'shopify' +const isSaleor = provider === 'saleor' const isSwell = provider === 'swell' const isVendure = provider === 'vendure' module.exports = withCommerceConfig({ + future: { + webpack5: true, + }, commerce, i18n: { locales: ['en-US', 'es'], diff --git a/package.json b/package.json index 85daa3158..5034d7e0c 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "nextjs-commerce", "version": "1.0.0", "scripts": { - "dev": "next dev", + "dev": "NODE_OPTIONS='--inspect' next dev", "build": "next build", "start": "next start", "analyze": "BUNDLE_ANALYZE=both yarn build", @@ -16,66 +16,63 @@ "sideEffects": false, "license": "MIT", "engines": { - "node": "14.x" + "node": ">=14.x" }, "dependencies": { - "@reach/portal": "^0.11.2", + "@reach/portal": "^0.15.0", "@vercel/fetch": "^6.1.0", - "autoprefixer": "^10.2.4", + "autoprefixer": "^10.2.6", "body-scroll-lock": "^3.1.5", "bowser": "^2.11.0", - "classnames": "^2.2.6", + "classnames": "^2.3.1", "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", + "keen-slider": "^5.4.1", "lodash.debounce": "^4.0.8", "lodash.random": "^3.2.0", "lodash.throttle": "^4.1.1", - "next": "^10.0.9-canary.5", - "next-seo": "^4.11.0", - "next-themes": "^0.0.4", - "postcss": "^8.2.8", - "postcss-nesting": "^7.0.1", - "react": "^17.0.1", - "react-dom": "^17.0.1", + "next": "10.0.9-canary.5", + "next-seo": "^4.24.0", + "next-themes": "^0.0.14", + "postcss": "^8.3.0", + "postcss-nesting": "^8.0.1", + "react": "^17.0.2", + "react-dom": "^17.0.2", "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.4" + "swr": "^0.5.6", + "tabbable": "^5.2.0", + "tailwindcss": "^2.1.2" }, "devDependencies": { - "@graphql-codegen/cli": "^1.20.0", - "@graphql-codegen/schema-ast": "^1.18.1", - "@graphql-codegen/typescript": "^1.19.0", - "@graphql-codegen/typescript-operations": "^1.17.13", - "@manifoldco/swagger-to-ts": "^2.1.0", - "@next/bundle-analyzer": "^10.0.1", - "@tailwindcss/jit": "^0.1.3", + "@graphql-codegen/cli": "^1.21.5", + "@graphql-codegen/schema-ast": "^1.18.3", + "@graphql-codegen/typescript": "^1.22.1", + "@graphql-codegen/typescript-operations": "^1.18.0", + "@next/bundle-analyzer": "^10.2.3", "@types/body-scroll-lock": "^2.6.1", - "@types/classnames": "^2.2.10", "@types/cookie": "^0.4.0", "@types/js-cookie": "^2.2.6", "@types/lodash.debounce": "^4.0.6", "@types/lodash.random": "^3.2.6", "@types/lodash.throttle": "^4.1.6", - "@types/node": "^14.14.16", - "@types/react": "^17.0.0", + "@types/node": "^15.6.1", + "@types/react": "^17.0.8", "@types/shopify-buy": "^2.10.5", "deepmerge": "^4.2.2", - "graphql": "^15.4.0", - "husky": "^4.3.8", - "lint-staged": "^10.5.3", - "next-unused": "^0.0.3", - "postcss-flexbugs-fixes": "^4.2.1", + "graphql": "^15.5.0", + "husky": "^6.0.0", + "lint-staged": "^11.0.0", + "next-unused": "^0.0.6", + "postcss-flexbugs-fixes": "^5.0.2", "postcss-preset-env": "^6.7.0", - "prettier": "^2.2.1", - "typescript": "^4.0.3" + "prettier": "^2.3.0", + "typescript": "4.2.4" }, "husky": { "hooks": { diff --git a/pages/index.tsx b/pages/index.tsx index 02142f3b0..3f1b6502a 100644 --- a/pages/index.tsx +++ b/pages/index.tsx @@ -15,6 +15,7 @@ export async function getStaticProps({ variables: { first: 12 }, config, preview, + featured: true }) const { categories, brands } = await commerce.getSiteInfo({ config, preview }) const { pages } = await commerce.getAllPages({ config, preview }) diff --git a/tsconfig.json b/tsconfig.json index 96e4359e5..ba333b642 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/saleor"], + "@framework/*": ["framework/saleor/*"] } }, "include": ["next-env.d.ts", "**/*.d.ts", "**/*.ts", "**/*.tsx", "**/*.js"], diff --git a/yarn.lock b/yarn.lock index 1b1fce30e..9dbfca574 100644 --- a/yarn.lock +++ b/yarn.lock @@ -23,33 +23,38 @@ dependencies: "@babel/highlight" "^7.12.13" +"@babel/compat-data@^7.14.4": + version "7.14.4" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.14.4.tgz#45720fe0cecf3fd42019e1d12cc3d27fadc98d58" + integrity sha512-i2wXrWQNkH6JplJQGn3Rd2I4Pij8GdHkXwHMxm+zV5YG/Jci+bCNrWZEWC4o+umiDkRrRs4dVzH3X4GP7vyjQQ== + "@babel/core@^7.0.0": - version "7.12.16" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.12.16.tgz#8c6ba456b23b680a6493ddcfcd9d3c3ad51cab7c" - integrity sha512-t/hHIB504wWceOeaOoONOhu+gX+hpjfeN6YRBT209X/4sibZQfSF1I0HFRRlBe97UZZosGx5XwUg1ZgNbelmNw== + version "7.14.3" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.14.3.tgz#5395e30405f0776067fbd9cf0884f15bfb770a38" + integrity sha512-jB5AmTKOCSJIZ72sd78ECEhuPiDMKlQdDI/4QRI6lzYATx5SSogS1oQA2AoPecRCknm30gHi2l+QVvNUu3wZAg== dependencies: "@babel/code-frame" "^7.12.13" - "@babel/generator" "^7.12.15" - "@babel/helper-module-transforms" "^7.12.13" - "@babel/helpers" "^7.12.13" - "@babel/parser" "^7.12.16" + "@babel/generator" "^7.14.3" + "@babel/helper-compilation-targets" "^7.13.16" + "@babel/helper-module-transforms" "^7.14.2" + "@babel/helpers" "^7.14.0" + "@babel/parser" "^7.14.3" "@babel/template" "^7.12.13" - "@babel/traverse" "^7.12.13" - "@babel/types" "^7.12.13" + "@babel/traverse" "^7.14.2" + "@babel/types" "^7.14.2" convert-source-map "^1.7.0" debug "^4.1.0" - gensync "^1.0.0-beta.1" + gensync "^1.0.0-beta.2" json5 "^2.1.2" - lodash "^4.17.19" - semver "^5.4.1" + semver "^6.3.0" source-map "^0.5.0" -"@babel/generator@^7.12.13", "@babel/generator@^7.12.15", "@babel/generator@^7.5.0": - version "7.12.15" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.12.15.tgz#4617b5d0b25cc572474cc1aafee1edeaf9b5368f" - integrity sha512-6F2xHxBiFXWNSGb7vyCUTBF8RCLY66rS0zEPcP8t/nQyXjha5EuK4z7H5o7fWG8B4M7y6mqVWq1J+1PuwRhecQ== +"@babel/generator@^7.12.13", "@babel/generator@^7.14.2", "@babel/generator@^7.14.3", "@babel/generator@^7.5.0": + version "7.14.3" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.14.3.tgz#0c2652d91f7bddab7cccc6ba8157e4f40dcedb91" + integrity sha512-bn0S6flG/j0xtQdz3hsjJ624h3W0r3llttBMfyHX3YrZ/KtLYr15bjA0FXkgW7FpvrDuTuElXeVjiKlYRpnOFA== dependencies: - "@babel/types" "^7.12.13" + "@babel/types" "^7.14.2" jsesc "^2.5.1" source-map "^0.5.0" @@ -60,25 +65,36 @@ dependencies: "@babel/types" "^7.12.13" -"@babel/helper-create-class-features-plugin@^7.12.13": - version "7.12.16" - resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.12.16.tgz#955d5099fd093e5afb05542190f8022105082c61" - integrity sha512-KbSEj8l9zYkMVHpQqM3wJNxS1d9h3U9vm/uE5tpjMbaj3lTp+0noe3KPsV5dSD9jxKnf9jO9Ip9FX5PKNZCKow== +"@babel/helper-compilation-targets@^7.13.16", "@babel/helper-compilation-targets@^7.14.4": + version "7.14.4" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.14.4.tgz#33ebd0ffc34248051ee2089350a929ab02f2a516" + integrity sha512-JgdzOYZ/qGaKTVkn5qEDV/SXAh8KcyUVkCoSWGN8T3bwrgd6m+/dJa2kVGi6RJYJgEYPBdZ84BZp9dUjNWkBaA== dependencies: - "@babel/helper-function-name" "^7.12.13" - "@babel/helper-member-expression-to-functions" "^7.12.16" + "@babel/compat-data" "^7.14.4" + "@babel/helper-validator-option" "^7.12.17" + browserslist "^4.16.6" + semver "^6.3.0" + +"@babel/helper-create-class-features-plugin@^7.13.0": + version "7.14.4" + resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.14.4.tgz#abf888d836a441abee783c75229279748705dc42" + integrity sha512-idr3pthFlDCpV+p/rMgGLGYIVtazeatrSOQk8YzO2pAepIjQhCN3myeihVg58ax2bbbGK9PUE1reFi7axOYIOw== + dependencies: + "@babel/helper-annotate-as-pure" "^7.12.13" + "@babel/helper-function-name" "^7.14.2" + "@babel/helper-member-expression-to-functions" "^7.13.12" "@babel/helper-optimise-call-expression" "^7.12.13" - "@babel/helper-replace-supers" "^7.12.13" + "@babel/helper-replace-supers" "^7.14.4" "@babel/helper-split-export-declaration" "^7.12.13" -"@babel/helper-function-name@^7.12.13": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.12.13.tgz#93ad656db3c3c2232559fd7b2c3dbdcbe0eb377a" - integrity sha512-TZvmPn0UOqmvi5G4vvw0qZTpVptGkB1GL61R6lKvrSdIxGm5Pky7Q3fpKiIkQCAtRCBUwB0PaThlx9vebCDSwA== +"@babel/helper-function-name@^7.12.13", "@babel/helper-function-name@^7.14.2": + version "7.14.2" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.14.2.tgz#397688b590760b6ef7725b5f0860c82427ebaac2" + integrity sha512-NYZlkZRydxw+YT56IlhIcS8PAhb+FEUiOzuhFTfqDyPmzAhRge6ua0dQYT/Uh0t/EDHq05/i+e5M2d4XvjgarQ== dependencies: "@babel/helper-get-function-arity" "^7.12.13" "@babel/template" "^7.12.13" - "@babel/types" "^7.12.13" + "@babel/types" "^7.14.2" "@babel/helper-get-function-arity@^7.12.13": version "7.12.13" @@ -87,34 +103,33 @@ dependencies: "@babel/types" "^7.12.13" -"@babel/helper-member-expression-to-functions@^7.12.13", "@babel/helper-member-expression-to-functions@^7.12.16": - version "7.12.16" - resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.12.16.tgz#41e0916b99f8d5f43da4f05d85f4930fa3d62b22" - integrity sha512-zYoZC1uvebBFmj1wFAlXwt35JLEgecefATtKp20xalwEK8vHAixLBXTGxNrVGEmTT+gzOThUgr8UEdgtalc1BQ== +"@babel/helper-member-expression-to-functions@^7.13.12": + version "7.13.12" + resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.13.12.tgz#dfe368f26d426a07299d8d6513821768216e6d72" + integrity sha512-48ql1CLL59aKbU94Y88Xgb2VFy7a95ykGRbJJaaVv+LX5U8wFpLfiGXJJGUozsmA1oEh/o5Bp60Voq7ACyA/Sw== dependencies: - "@babel/types" "^7.12.13" + "@babel/types" "^7.13.12" -"@babel/helper-module-imports@^7.12.13": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.12.13.tgz#ec67e4404f41750463e455cc3203f6a32e93fcb0" - integrity sha512-NGmfvRp9Rqxy0uHSSVP+SRIW1q31a7Ji10cLBcqSDUngGentY4FRiHOFZFE1CLU5eiL0oE8reH7Tg1y99TDM/g== +"@babel/helper-module-imports@^7.13.12": + version "7.13.12" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.13.12.tgz#c6a369a6f3621cb25da014078684da9196b61977" + integrity sha512-4cVvR2/1B693IuOvSI20xqqa/+bl7lqAMR59R4iu39R9aOX8/JoYY1sFaNvUMyMBGnHdwvJgUrzNLoUZxXypxA== dependencies: - "@babel/types" "^7.12.13" + "@babel/types" "^7.13.12" -"@babel/helper-module-transforms@^7.12.13": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.12.13.tgz#01afb052dcad2044289b7b20beb3fa8bd0265bea" - integrity sha512-acKF7EjqOR67ASIlDTupwkKM1eUisNAjaSduo5Cz+793ikfnpe7p4Q7B7EWU2PCoSTPWsQkR7hRUWEIZPiVLGA== +"@babel/helper-module-transforms@^7.14.0", "@babel/helper-module-transforms@^7.14.2": + version "7.14.2" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.14.2.tgz#ac1cc30ee47b945e3e0c4db12fa0c5389509dfe5" + integrity sha512-OznJUda/soKXv0XhpvzGWDnml4Qnwp16GN+D/kZIdLsWoHj05kyu8Rm5kXmMef+rVJZ0+4pSGLkeixdqNUATDA== dependencies: - "@babel/helper-module-imports" "^7.12.13" - "@babel/helper-replace-supers" "^7.12.13" - "@babel/helper-simple-access" "^7.12.13" + "@babel/helper-module-imports" "^7.13.12" + "@babel/helper-replace-supers" "^7.13.12" + "@babel/helper-simple-access" "^7.13.12" "@babel/helper-split-export-declaration" "^7.12.13" - "@babel/helper-validator-identifier" "^7.12.11" + "@babel/helper-validator-identifier" "^7.14.0" "@babel/template" "^7.12.13" - "@babel/traverse" "^7.12.13" - "@babel/types" "^7.12.13" - lodash "^4.17.19" + "@babel/traverse" "^7.14.2" + "@babel/types" "^7.14.2" "@babel/helper-optimise-call-expression@^7.12.13": version "7.12.13" @@ -123,27 +138,27 @@ dependencies: "@babel/types" "^7.12.13" -"@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.8.0": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.12.13.tgz#174254d0f2424d8aefb4dd48057511247b0a9eeb" - integrity sha512-C+10MXCXJLiR6IeG9+Wiejt9jmtFpxUc3MQqCmPY8hfCjyUGl9kT+B2okzEZrtykiwrc4dbCPdDoz0A/HQbDaA== +"@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.13.0", "@babel/helper-plugin-utils@^7.8.0": + version "7.13.0" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.13.0.tgz#806526ce125aed03373bc416a828321e3a6a33af" + integrity sha512-ZPafIPSwzUlAoWT8DKs1W2VyF2gOWthGd5NGFMsBcMMol+ZhK+EQY/e6V96poa6PA/Bh+C9plWN0hXO1uB8AfQ== -"@babel/helper-replace-supers@^7.12.13": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.12.13.tgz#00ec4fb6862546bd3d0aff9aac56074277173121" - integrity sha512-pctAOIAMVStI2TMLhozPKbf5yTEXc0OJa0eENheb4w09SrgOWEs+P4nTOZYJQCqs8JlErGLDPDJTiGIp3ygbLg== +"@babel/helper-replace-supers@^7.12.13", "@babel/helper-replace-supers@^7.13.12", "@babel/helper-replace-supers@^7.14.4": + version "7.14.4" + resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.14.4.tgz#b2ab16875deecfff3ddfcd539bc315f72998d836" + integrity sha512-zZ7uHCWlxfEAAOVDYQpEf/uyi1dmeC7fX4nCf2iz9drnCwi1zvwXL3HwWWNXUQEJ1k23yVn3VbddiI9iJEXaTQ== dependencies: - "@babel/helper-member-expression-to-functions" "^7.12.13" + "@babel/helper-member-expression-to-functions" "^7.13.12" "@babel/helper-optimise-call-expression" "^7.12.13" - "@babel/traverse" "^7.12.13" - "@babel/types" "^7.12.13" + "@babel/traverse" "^7.14.2" + "@babel/types" "^7.14.4" -"@babel/helper-simple-access@^7.12.13": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.12.13.tgz#8478bcc5cacf6aa1672b251c1d2dde5ccd61a6c4" - integrity sha512-0ski5dyYIHEfwpWGx5GPWhH35j342JaflmCeQmsPWcrOQDtCN6C1zKAVRFVbK53lPW2c9TsuLLSUDf0tIGJ5hA== +"@babel/helper-simple-access@^7.13.12": + version "7.13.12" + resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.13.12.tgz#dd6c538afb61819d205a012c31792a39c7a5eaf6" + integrity sha512-7FEjbrx5SL9cWvXioDbnlYTppcZGuCY6ow3/D5vMggb2Ywgu4dMrpTJX0JdQAIcRRUElOIxF3yEooa9gUb9ZbA== dependencies: - "@babel/types" "^7.12.13" + "@babel/types" "^7.13.12" "@babel/helper-skip-transparent-expression-wrappers@^7.12.1": version "7.12.1" @@ -159,55 +174,62 @@ dependencies: "@babel/types" "^7.12.13" -"@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/helper-validator-identifier@^7.12.11", "@babel/helper-validator-identifier@^7.14.0": + version "7.14.0" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.0.tgz#d26cad8a47c65286b15df1547319a5d0bcf27288" + integrity sha512-V3ts7zMSu5lfiwWDVWzRDGIN+lnCEUdaXgtVHJgLb1rGaA6jMrtB9EmE7L18foXJIE8Un/A/h6NJfGQp/e1J4A== -"@babel/helpers@^7.12.13": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.12.13.tgz#3c75e993632e4dadc0274eae219c73eb7645ba47" - integrity sha512-oohVzLRZ3GQEk4Cjhfs9YkJA4TdIDTObdBEZGrd6F/T0GPSnuV6l22eMcxlvcvzVIPH3VTtxbseudM1zIE+rPQ== +"@babel/helper-validator-option@^7.12.17": + version "7.12.17" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.12.17.tgz#d1fbf012e1a79b7eebbfdc6d270baaf8d9eb9831" + integrity sha512-TopkMDmLzq8ngChwRlyjR6raKD6gMSae4JdYDB8bByKreQgG0RBTuKe9LRxW3wFtUnjxOPRKBDwEH6Mg5KeDfw== + +"@babel/helpers@^7.14.0": + version "7.14.0" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.14.0.tgz#ea9b6be9478a13d6f961dbb5f36bf75e2f3b8f62" + integrity sha512-+ufuXprtQ1D1iZTO/K9+EBRn+qPWMJjZSw/S0KlFrxCw4tkrzv9grgpDHkY9MeQTjTY8i2sp7Jep8DfU6tN9Mg== dependencies: "@babel/template" "^7.12.13" - "@babel/traverse" "^7.12.13" - "@babel/types" "^7.12.13" + "@babel/traverse" "^7.14.0" + "@babel/types" "^7.14.0" "@babel/highlight@^7.10.4", "@babel/highlight@^7.12.13": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.12.13.tgz#8ab538393e00370b26271b01fa08f7f27f2e795c" - integrity sha512-kocDQvIbgMKlWxXe9fof3TQ+gkIPOUSEYhJjqUjvKMez3krV7vbzYCDq39Oj11UAVK7JqPVGQPlgE85dPNlQww== + version "7.14.0" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.14.0.tgz#3197e375711ef6bf834e67d0daec88e4f46113cf" + integrity sha512-YSCOwxvTYEIMSGaBQb5kDDsCopDdiUGsqpatp3fOlI4+2HQSkTmEVWnVuySdAC5EWCqSWWTv0ib63RjR7dTBdg== dependencies: - "@babel/helper-validator-identifier" "^7.12.11" + "@babel/helper-validator-identifier" "^7.14.0" chalk "^2.0.0" js-tokens "^4.0.0" -"@babel/parser@7.12.13": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.12.13.tgz#3ee7be4131fe657ba9143d5c5b3a9f253fdb75e9" - integrity sha512-z7n7ybOUzaRc3wwqLpAX8UFIXsrVXUJhtNGBwAnLz6d1KUapqyq7ad2La8gZ6CXhHmGAIL32cop8Tst4/PNWLw== - -"@babel/parser@^7.0.0", "@babel/parser@^7.12.13", "@babel/parser@^7.12.16": +"@babel/parser@7.12.16": version "7.12.16" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.12.16.tgz#cc31257419d2c3189d394081635703f549fc1ed4" integrity sha512-c/+u9cqV6F0+4Hpq01jnJO+GLp2DdT63ppz9Xa+6cHaajM9VFzK/iDXiKK65YtpeVwu+ctfS6iqlMqRgQRzeCw== +"@babel/parser@^7.0.0", "@babel/parser@^7.12.13", "@babel/parser@^7.14.2", "@babel/parser@^7.14.3": + version "7.14.4" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.14.4.tgz#a5c560d6db6cd8e6ed342368dea8039232cbab18" + integrity sha512-ArliyUsWDUqEGfWcmzpGUzNfLxTdTp6WU4IuP6QFSp9gGfWS6boxFCkJSJ/L4+RG8z/FnIU3WxCk6hPL9SSWeA== + "@babel/plugin-proposal-class-properties@^7.0.0": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.12.13.tgz#3d2ce350367058033c93c098e348161d6dc0d8c8" - integrity sha512-8SCJ0Ddrpwv4T7Gwb33EmW1V9PY5lggTO+A8WjyIwxrSHDUyBw4MtF96ifn1n8H806YlxbVCoKXbbmzD6RD+cA== + version "7.13.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.13.0.tgz#146376000b94efd001e57a40a88a525afaab9f37" + integrity sha512-KnTDjFNC1g+45ka0myZNvSBFLhNCLN+GeGYLDEA8Oq7MZ6yMgfLoIRh86GRT0FjtJhZw8JyUskP9uvj5pHM9Zg== dependencies: - "@babel/helper-create-class-features-plugin" "^7.12.13" - "@babel/helper-plugin-utils" "^7.12.13" + "@babel/helper-create-class-features-plugin" "^7.13.0" + "@babel/helper-plugin-utils" "^7.13.0" "@babel/plugin-proposal-object-rest-spread@^7.0.0": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.12.13.tgz#f93f3116381ff94bc676fdcb29d71045cd1ec011" - integrity sha512-WvA1okB/0OS/N3Ldb3sziSrXg6sRphsBgqiccfcQq7woEn5wQLNX82Oc4PlaFcdwcWHuQXAtb8ftbS8Fbsg/sg== + version "7.14.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.14.4.tgz#0e2b4de419915dc0b409378e829412e2031777c4" + integrity sha512-AYosOWBlyyXEagrPRfLJ1enStufsr7D1+ddpj8OLi9k7B6+NdZ0t/9V7Fh+wJ4g2Jol8z2JkgczYqtWrZd4vbA== dependencies: - "@babel/helper-plugin-utils" "^7.12.13" - "@babel/plugin-syntax-object-rest-spread" "^7.8.0" - "@babel/plugin-transform-parameters" "^7.12.13" + "@babel/compat-data" "^7.14.4" + "@babel/helper-compilation-targets" "^7.14.4" + "@babel/helper-plugin-utils" "^7.13.0" + "@babel/plugin-syntax-object-rest-spread" "^7.8.3" + "@babel/plugin-transform-parameters" "^7.14.2" "@babel/plugin-syntax-class-properties@^7.0.0": version "7.12.13" @@ -230,7 +252,7 @@ dependencies: "@babel/helper-plugin-utils" "^7.12.13" -"@babel/plugin-syntax-object-rest-spread@^7.0.0", "@babel/plugin-syntax-object-rest-spread@^7.8.0": +"@babel/plugin-syntax-object-rest-spread@^7.0.0", "@babel/plugin-syntax-object-rest-spread@^7.8.3": 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== @@ -238,11 +260,11 @@ "@babel/helper-plugin-utils" "^7.8.0" "@babel/plugin-transform-arrow-functions@^7.0.0": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.12.13.tgz#eda5670b282952100c229f8a3bd49e0f6a72e9fe" - integrity sha512-tBtuN6qtCTd+iHzVZVOMNp+L04iIJBpqkdY42tWbmjIT5wvR2kx7gxMBsyhQtFzHwBbyGi9h8J8r9HgnOpQHxg== + version "7.13.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.13.0.tgz#10a59bebad52d637a027afa692e8d5ceff5e3dae" + integrity sha512-96lgJagobeVmazXFaDrbmCLQxBysKu7U6Do3mLsx27gf5Dk85ezysrs2BZUpXD703U/Su1xTBDxxar2oa4jAGg== dependencies: - "@babel/helper-plugin-utils" "^7.12.13" + "@babel/helper-plugin-utils" "^7.13.0" "@babel/plugin-transform-block-scoped-functions@^7.0.0": version "7.12.13" @@ -252,53 +274,53 @@ "@babel/helper-plugin-utils" "^7.12.13" "@babel/plugin-transform-block-scoping@^7.0.0": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.12.13.tgz#f36e55076d06f41dfd78557ea039c1b581642e61" - integrity sha512-Pxwe0iqWJX4fOOM2kEZeUuAxHMWb9nK+9oh5d11bsLoB0xMg+mkDpt0eYuDZB7ETrY9bbcVlKUGTOGWy7BHsMQ== + version "7.14.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.14.4.tgz#caf140b0b2e2462c509553d140e6d0abefb61ed8" + integrity sha512-5KdpkGxsZlTk+fPleDtGKsA+pon28+ptYmMO8GBSa5fHERCJWAzj50uAfCKBqq42HO+Zot6JF1x37CRprwmN4g== dependencies: - "@babel/helper-plugin-utils" "^7.12.13" + "@babel/helper-plugin-utils" "^7.13.0" "@babel/plugin-transform-classes@^7.0.0": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.12.13.tgz#9728edc1838b5d62fc93ad830bd523b1fcb0e1f6" - integrity sha512-cqZlMlhCC1rVnxE5ZGMtIb896ijL90xppMiuWXcwcOAuFczynpd3KYemb91XFFPi3wJSe/OcrX9lXoowatkkxA== + version "7.14.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.14.4.tgz#a83c15503fc71a0f99e876fdce7dadbc6575ec3a" + integrity sha512-p73t31SIj6y94RDVX57rafVjttNr8MvKEgs5YFatNB/xC68zM3pyosuOEcQmYsYlyQaGY9R7rAULVRcat5FKJQ== dependencies: "@babel/helper-annotate-as-pure" "^7.12.13" - "@babel/helper-function-name" "^7.12.13" + "@babel/helper-function-name" "^7.14.2" "@babel/helper-optimise-call-expression" "^7.12.13" - "@babel/helper-plugin-utils" "^7.12.13" - "@babel/helper-replace-supers" "^7.12.13" + "@babel/helper-plugin-utils" "^7.13.0" + "@babel/helper-replace-supers" "^7.14.4" "@babel/helper-split-export-declaration" "^7.12.13" globals "^11.1.0" "@babel/plugin-transform-computed-properties@^7.0.0": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.12.13.tgz#6a210647a3d67f21f699cfd2a01333803b27339d" - integrity sha512-dDfuROUPGK1mTtLKyDPUavmj2b6kFu82SmgpztBFEO974KMjJT+Ytj3/oWsTUMBmgPcp9J5Pc1SlcAYRpJ2hRA== + version "7.13.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.13.0.tgz#845c6e8b9bb55376b1fa0b92ef0bdc8ea06644ed" + integrity sha512-RRqTYTeZkZAz8WbieLTvKUEUxZlUTdmL5KGMyZj7FnMfLNKV4+r5549aORG/mgojRmFlQMJDUupwAMiF2Q7OUg== dependencies: - "@babel/helper-plugin-utils" "^7.12.13" + "@babel/helper-plugin-utils" "^7.13.0" "@babel/plugin-transform-destructuring@^7.0.0": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.12.13.tgz#fc56c5176940c5b41735c677124d1d20cecc9aeb" - integrity sha512-Dn83KykIFzjhA3FDPA1z4N+yfF3btDGhjnJwxIj0T43tP0flCujnU8fKgEkf0C1biIpSv9NZegPBQ1J6jYkwvQ== + version "7.14.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.14.4.tgz#acbec502e9951f30f4441eaca1d2f29efade59ed" + integrity sha512-JyywKreTCGTUsL1OKu1A3ms/R1sTP0WxbpXlALeGzF53eB3bxtNkYdMj9SDgK7g6ImPy76J5oYYKoTtQImlhQA== dependencies: - "@babel/helper-plugin-utils" "^7.12.13" + "@babel/helper-plugin-utils" "^7.13.0" "@babel/plugin-transform-flow-strip-types@^7.0.0": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.12.13.tgz#b439c43116dc60fb45b7efd2e1db91897b7c8f4b" - integrity sha512-39/t9HtN+Jlc7EEY6oCSCf3kRrKIl2JULOGPnHZiaRjoYZEFaDXDZI32uE2NosQRh8o6N9B+8iGvDK7ToJhJaw== + version "7.13.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.13.0.tgz#58177a48c209971e8234e99906cb6bd1122addd3" + integrity sha512-EXAGFMJgSX8gxWD7PZtW/P6M+z74jpx3wm/+9pn+c2dOawPpBkUX7BrfyPvo6ZpXbgRIEuwgwDb/MGlKvu2pOg== dependencies: - "@babel/helper-plugin-utils" "^7.12.13" + "@babel/helper-plugin-utils" "^7.13.0" "@babel/plugin-syntax-flow" "^7.12.13" "@babel/plugin-transform-for-of@^7.0.0": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.12.13.tgz#561ff6d74d9e1c8879cb12dbaf4a14cd29d15cf6" - integrity sha512-xCbdgSzXYmHGyVX3+BsQjcd4hv4vA/FDy7Kc8eOpzKmBBPEOTurt0w5fCRQaGl+GSBORKgJdstQ1rHl4jbNseQ== + version "7.13.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.13.0.tgz#c799f881a8091ac26b54867a845c3e97d2696062" + integrity sha512-IHKT00mwUVYE0zzbkDgNRP6SRzvfGCYsOxIRz8KsiaaHCcT9BWIkO+H9QRJseHBLOGBZkHUdHiqj6r0POsdytg== dependencies: - "@babel/helper-plugin-utils" "^7.12.13" + "@babel/helper-plugin-utils" "^7.13.0" "@babel/plugin-transform-function-name@^7.0.0": version "7.12.13" @@ -323,13 +345,13 @@ "@babel/helper-plugin-utils" "^7.12.13" "@babel/plugin-transform-modules-commonjs@^7.0.0": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.12.13.tgz#5043b870a784a8421fa1fd9136a24f294da13e50" - integrity sha512-OGQoeVXVi1259HjuoDnsQMlMkT9UkZT9TpXAsqWplS/M0N1g3TJAn/ByOCeQu7mfjc5WpSsRU+jV1Hd89ts0kQ== + version "7.14.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.14.0.tgz#52bc199cb581e0992edba0f0f80356467587f161" + integrity sha512-EX4QePlsTaRZQmw9BsoPeyh5OCtRGIhwfLquhxGp5e32w+dyL8htOcDwamlitmNFK6xBZYlygjdye9dbd9rUlQ== dependencies: - "@babel/helper-module-transforms" "^7.12.13" - "@babel/helper-plugin-utils" "^7.12.13" - "@babel/helper-simple-access" "^7.12.13" + "@babel/helper-module-transforms" "^7.14.0" + "@babel/helper-plugin-utils" "^7.13.0" + "@babel/helper-simple-access" "^7.13.12" babel-plugin-dynamic-import-node "^2.3.3" "@babel/plugin-transform-object-super@^7.0.0": @@ -340,12 +362,12 @@ "@babel/helper-plugin-utils" "^7.12.13" "@babel/helper-replace-supers" "^7.12.13" -"@babel/plugin-transform-parameters@^7.0.0", "@babel/plugin-transform-parameters@^7.12.13": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.12.13.tgz#461e76dfb63c2dfd327b8a008a9e802818ce9853" - integrity sha512-e7QqwZalNiBRHCpJg/P8s/VJeSRYgmtWySs1JwvfwPqhBbiWfOcHDKdeAi6oAyIimoKWBlwc8oTgbZHdhCoVZA== +"@babel/plugin-transform-parameters@^7.0.0", "@babel/plugin-transform-parameters@^7.14.2": + version "7.14.2" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.14.2.tgz#e4290f72e0e9e831000d066427c4667098decc31" + integrity sha512-NxoVmA3APNCC1JdMXkdYXuQS+EMdqy0vIwyDHeKHiJKRxmp1qGSdb0JLEIoPRhkx6H/8Qi3RJ3uqOCYw8giy9A== dependencies: - "@babel/helper-plugin-utils" "^7.12.13" + "@babel/helper-plugin-utils" "^7.13.0" "@babel/plugin-transform-property-literals@^7.0.0": version "7.12.13" @@ -355,22 +377,22 @@ "@babel/helper-plugin-utils" "^7.12.13" "@babel/plugin-transform-react-display-name@^7.0.0": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.12.13.tgz#c28effd771b276f4647411c9733dbb2d2da954bd" - integrity sha512-MprESJzI9O5VnJZrL7gg1MpdqmiFcUv41Jc7SahxYsNP2kDkFqClxxTZq+1Qv4AFCamm+GXMRDQINNn+qrxmiA== + version "7.14.2" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.14.2.tgz#2e854544d42ab3bb9c21f84e153d62e800fbd593" + integrity sha512-zCubvP+jjahpnFJvPaHPiGVfuVUjXHhFvJKQdNnsmSsiU9kR/rCZ41jHc++tERD2zV+p7Hr6is+t5b6iWTCqSw== dependencies: - "@babel/helper-plugin-utils" "^7.12.13" + "@babel/helper-plugin-utils" "^7.13.0" "@babel/plugin-transform-react-jsx@^7.0.0": - version "7.12.16" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.12.16.tgz#07c341e02a3e4066b00413534f30c42519923230" - integrity sha512-dNu0vAbIk8OkqJfGtYF6ADk6jagoyAl+Ks5aoltbAlfoKv8d6yooi3j+kObeSQaCj9PgN6KMZPB90wWyek5TmQ== + version "7.14.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.14.3.tgz#0e26597805cf0862da735f264550933c38babb66" + integrity sha512-uuxuoUNVhdgYzERiHHFkE4dWoJx+UFVyuAl0aqN8P2/AKFHwqgUC5w2+4/PjpKXJsFgBlYAFXlUmDQ3k3DUkXw== dependencies: "@babel/helper-annotate-as-pure" "^7.12.13" - "@babel/helper-module-imports" "^7.12.13" - "@babel/helper-plugin-utils" "^7.12.13" + "@babel/helper-module-imports" "^7.13.12" + "@babel/helper-plugin-utils" "^7.13.0" "@babel/plugin-syntax-jsx" "^7.12.13" - "@babel/types" "^7.12.13" + "@babel/types" "^7.14.2" "@babel/plugin-transform-shorthand-properties@^7.0.0": version "7.12.13" @@ -380,19 +402,19 @@ "@babel/helper-plugin-utils" "^7.12.13" "@babel/plugin-transform-spread@^7.0.0": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.12.13.tgz#ca0d5645abbd560719c354451b849f14df4a7949" - integrity sha512-dUCrqPIowjqk5pXsx1zPftSq4sT0aCeZVAxhdgs3AMgyaDmoUT0G+5h3Dzja27t76aUEIJWlFgPJqJ/d4dbTtg== + version "7.13.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.13.0.tgz#84887710e273c1815ace7ae459f6f42a5d31d5fd" + integrity sha512-V6vkiXijjzYeFmQTr3dBxPtZYLPcUfY34DebOU27jIl2M/Y8Egm52Hw82CSjjPqd54GTlJs5x+CR7HeNr24ckg== dependencies: - "@babel/helper-plugin-utils" "^7.12.13" + "@babel/helper-plugin-utils" "^7.13.0" "@babel/helper-skip-transparent-expression-wrappers" "^7.12.1" "@babel/plugin-transform-template-literals@^7.0.0": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.12.13.tgz#655037b07ebbddaf3b7752f55d15c2fd6f5aa865" - integrity sha512-arIKlWYUgmNsF28EyfmiQHJLJFlAJNYkuQO10jL46ggjBpeb2re1P9K9YGxNJB45BqTbaslVysXDYm/g3sN/Qg== + version "7.13.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.13.0.tgz#a36049127977ad94438dee7443598d1cefdf409d" + integrity sha512-d67umW6nlfmr1iehCcBv69eSUSySk1EsIS8aTDX4Xo9qajAh6mYtcl4kJrBkGXuxZPEgVr7RVfAvNW6YQkd4Mw== dependencies: - "@babel/helper-plugin-utils" "^7.12.13" + "@babel/helper-plugin-utils" "^7.13.0" "@babel/runtime@7.12.5": version "7.12.5" @@ -408,17 +430,10 @@ 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" - integrity sha512-8+3UMPBrjFa/6TtKi/7sehPKqfAm4g6K+YQjyyFOLUTxzOngcRZTlAVY8sc2CORJYqdHQY8gRPHmn+qo15rCBw== - 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== +"@babel/runtime@^7.0.0", "@babel/runtime@^7.12.13", "@babel/runtime@^7.14.0": + version "7.14.0" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.14.0.tgz#46794bc20b612c5f75e62dd071e24dfd95f1cbe6" + integrity sha512-JELkvo/DlpNdJ7dlyw/eY7E0suy5i5GQH+Vlxaq1nsNJ+H7f4Vtv3jMeCEgRhZZQFXTjldYfQgv2qmM6M1v5wA== dependencies: regenerator-runtime "^0.13.4" @@ -431,7 +446,7 @@ "@babel/parser" "^7.12.13" "@babel/types" "^7.12.13" -"@babel/traverse@7.12.13", "@babel/traverse@^7.0.0", "@babel/traverse@^7.12.13": +"@babel/traverse@7.12.13": version "7.12.13" resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.12.13.tgz#689f0e4b4c08587ad26622832632735fb8c4e0c0" integrity sha512-3Zb4w7eE/OslI0fTp8c7b286/cQps3+vdLW3UcwC8VSJC6GbKn55aeVVu2QJNuCDoeKyptLOFrPq8WqZZBodyA== @@ -446,7 +461,21 @@ globals "^11.1.0" lodash "^4.17.19" -"@babel/types@7.12.13", "@babel/types@^7.0.0", "@babel/types@^7.12.1", "@babel/types@^7.12.13": +"@babel/traverse@^7.0.0", "@babel/traverse@^7.14.0", "@babel/traverse@^7.14.2": + version "7.14.2" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.14.2.tgz#9201a8d912723a831c2679c7ebbf2fe1416d765b" + integrity sha512-TsdRgvBFHMyHOOzcP9S6QU0QQtjxlRpEYOy3mcCO5RgmC305ki42aSAmfZEMSSYBla2oZ9BMqYlncBaKmD/7iA== + dependencies: + "@babel/code-frame" "^7.12.13" + "@babel/generator" "^7.14.2" + "@babel/helper-function-name" "^7.14.2" + "@babel/helper-split-export-declaration" "^7.12.13" + "@babel/parser" "^7.14.2" + "@babel/types" "^7.14.2" + debug "^4.1.0" + globals "^11.1.0" + +"@babel/types@7.12.13": version "7.12.13" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.12.13.tgz#8be1aa8f2c876da11a9cf650c0ecf656913ad611" integrity sha512-oKrdZTld2im1z8bDwTOQvUbxKwE+854zc16qWZQlcTqMN00pWxHQ4ZeOq0yDMnisOpRykH2/5Qqcrk/OlbAjiQ== @@ -464,6 +493,14 @@ lodash "^4.17.13" to-fast-properties "^2.0.0" +"@babel/types@^7.0.0", "@babel/types@^7.12.1", "@babel/types@^7.12.13", "@babel/types@^7.13.12", "@babel/types@^7.14.0", "@babel/types@^7.14.2", "@babel/types@^7.14.4": + version "7.14.4" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.14.4.tgz#bfd6980108168593b38b3eb48a24aa026b919bc0" + integrity sha512-lCj4aIs0xUefJFQnwwQv2Bxg7Omd6bgquZ6LGC+gGMh6/s5qDVfjuCMlDmYQ15SLsWHd9n+X3E75lKIhl5Lkiw== + dependencies: + "@babel/helper-validator-identifier" "^7.14.0" + 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" @@ -486,36 +523,34 @@ dependencies: purgecss "^3.1.3" -"@graphql-codegen/cli@^1.20.0": - version "1.20.1" - resolved "https://registry.yarnpkg.com/@graphql-codegen/cli/-/cli-1.20.1.tgz#3b42eddb4ddbfc6ad37d0a838267165f77342e14" - integrity sha512-jT5aMxIniER/gg0/sfx+BPmvI2ZAncQ6ZT/xkiFvXcYMiL9tDiAcVYJTmXcRdMTEIZnlzw3rhE4VPYiw1KqruQ== +"@graphql-codegen/cli@^1.21.5": + version "1.21.5" + resolved "https://registry.yarnpkg.com/@graphql-codegen/cli/-/cli-1.21.5.tgz#b9041553747cfb2dee7c3473a2e2461ec3e7ada5" + integrity sha512-w3SovNJ9qtMhFLAdPZeCdGvHXDgfdb53mueWDTyncOt04m+tohVnY4qExvyKLTN5zlGxrA/5ubp2x8Az0xQarA== 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" + "@graphql-codegen/core" "1.17.10" + "@graphql-codegen/plugin-helpers" "^1.18.7" + "@graphql-tools/apollo-engine-loader" "^6.2.5" + "@graphql-tools/code-file-loader" "^6.3.1" + "@graphql-tools/git-loader" "^6.2.6" + "@graphql-tools/github-loader" "^6.2.5" + "@graphql-tools/graphql-file-loader" "^6.2.7" + "@graphql-tools/json-file-loader" "^6.2.6" + "@graphql-tools/load" "^6.2.8" + "@graphql-tools/prisma-loader" "^6.3.0" + "@graphql-tools/url-loader" "^6.10.1" + "@graphql-tools/utils" "^7.9.1" ansi-escapes "^4.3.1" - camel-case "^4.1.2" chalk "^4.1.0" - chokidar "^3.4.3" + change-case-all "1.0.14" + chokidar "^3.5.1" common-tags "^1.8.0" - constant-case "^3.0.3" cosmiconfig "^7.0.0" debounce "^1.2.0" - dependency-graph "^0.10.0" + dependency-graph "^0.11.0" detect-indent "^6.0.0" glob "^7.1.6" - graphql-config "^3.2.0" - indent-string "^4.0.0" + graphql-config "^3.3.0" inquirer "^7.3.3" is-glob "^4.0.1" json-to-pretty-yaml "^1.2.2" @@ -523,93 +558,84 @@ 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" string-env-interpolation "^1.0.1" ts-log "^2.2.3" - tslib "~2.1.0" - upper-case "^2.0.2" + tslib "~2.2.0" valid-url "^1.0.9" wrap-ansi "^7.0.0" yaml "^1.10.0" - yargs "^16.1.1" + yargs "^17.0.0" -"@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== +"@graphql-codegen/core@1.17.10": + version "1.17.10" + resolved "https://registry.yarnpkg.com/@graphql-codegen/core/-/core-1.17.10.tgz#3b85b5bc2e84fcacbd25fced5af47a4bb2d7a8bd" + integrity sha512-RA3umgVDs/RI/+ztHh+H4GfJxrJUfWJQqoAkMfX4qPTVO5qsy3R4vPudE0oP8w+kFbL8dFsRfAAPUZxI4jV/hQ== 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.7" + "@graphql-tools/merge" "^6.2.14" + "@graphql-tools/utils" "^7.9.1" + tslib "~2.2.0" -"@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== +"@graphql-codegen/plugin-helpers@^1.18.7": + version "1.18.7" + resolved "https://registry.yarnpkg.com/@graphql-codegen/plugin-helpers/-/plugin-helpers-1.18.7.tgz#465af3e5b02de89e49ddc76ad2546b880fe240f2" + integrity sha512-8ICOrXlsvyL1dpVz8C9b7H31d4DJpDd75WfjMn6Xjqz81Ah8xDn1Bi+7YXRCCILCBmvI94k6fi8qpsIVhFBBjQ== dependencies: - "@graphql-tools/utils" "^6" - camel-case "4.1.1" + "@graphql-tools/utils" "^7.9.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" + lodash "~4.17.0" + tslib "~2.2.0" -"@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.14" - resolved "https://registry.yarnpkg.com/@graphql-codegen/typescript-operations/-/typescript-operations-1.17.14.tgz#69b4bee4d66f2ea7e288f1be889e08946ef3452a" - integrity sha512-jf1KnkA0i5hQNwc7bdMg5G6305DMSeTGDJSDoFryA2Tt9czWxY78m10/6GueUWo3zP6FIEhW1QRSve8ewTKEMg== - dependencies: - "@graphql-codegen/plugin-helpers" "^1.18.2" - "@graphql-codegen/typescript" "^1.20.1" - "@graphql-codegen/visitor-plugin-common" "^1.18.1" - auto-bind "~4.0.0" - tslib "~2.1.0" - -"@graphql-codegen/typescript@^1.19.0", "@graphql-codegen/typescript@^1.20.1": - version "1.21.0" - resolved "https://registry.yarnpkg.com/@graphql-codegen/typescript/-/typescript-1.21.0.tgz#301b1851cd278bedd1f49e1b3d654f4dc0af2943" - integrity sha512-23YttnZ+87dA/3lbCvPKdsrpEOx142dCT9xSh6XkSeyCvn+vUtETN2MhamCYB87G7Nu2EcLDFKDZjgXH73f4fg== - dependencies: - "@graphql-codegen/plugin-helpers" "^1.18.2" - "@graphql-codegen/visitor-plugin-common" "^1.18.3" - auto-bind "~4.0.0" - tslib "~2.1.0" - -"@graphql-codegen/visitor-plugin-common@^1.18.1", "@graphql-codegen/visitor-plugin-common@^1.18.3": +"@graphql-codegen/schema-ast@^1.18.3": version "1.18.3" - resolved "https://registry.yarnpkg.com/@graphql-codegen/visitor-plugin-common/-/visitor-plugin-common-1.18.3.tgz#9d2c4449c3bdaffe3e782e2321fe0cb998b8a91d" - integrity sha512-6xJzt8hszCTKt3rTlcCURpuiAFuaiaZgStlVeRE1OrKEDiY1T3vwF3/7TonhfnEjqBWtZdMmXvNx3ArXkRUV4w== + resolved "https://registry.yarnpkg.com/@graphql-codegen/schema-ast/-/schema-ast-1.18.3.tgz#7ba7422df716ff2038b1281c503e5751a8414ef2" + integrity sha512-D0uheH039ztSG3mboW5enmyaFwTcevLSR8yNrdN+NEKoQJJoDWsb9P/G6NTdFu5Bb03IvNhIFTpG1ttWtRP/aQ== dependencies: - "@graphql-codegen/plugin-helpers" "^1.18.2" + "@graphql-codegen/plugin-helpers" "^1.18.7" + "@graphql-tools/utils" "^7.9.1" + tslib "~2.2.0" + +"@graphql-codegen/typescript-operations@^1.18.0": + version "1.18.0" + resolved "https://registry.yarnpkg.com/@graphql-codegen/typescript-operations/-/typescript-operations-1.18.0.tgz#04c007df476948ff972daed69c73a77a922c8968" + integrity sha512-Q4b+jySBgU39uYzSWQcHBn/q5j/gs2yUQGNiCXhV8IIHDJJNR0Zfb2ywY6AMwT7N3rgXmFuIzKAA++xBf2yKRw== + dependencies: + "@graphql-codegen/plugin-helpers" "^1.18.7" + "@graphql-codegen/typescript" "^1.22.1" + "@graphql-codegen/visitor-plugin-common" "1.21.0" + auto-bind "~4.0.0" + tslib "~2.2.0" + +"@graphql-codegen/typescript@^1.22.1": + version "1.22.1" + resolved "https://registry.yarnpkg.com/@graphql-codegen/typescript/-/typescript-1.22.1.tgz#9a2e215d4cf095d942c1671db4bad78b619b11ce" + integrity sha512-3f/siciXrhhMdcs9qcxnwWXETsAhZNNiUOlr6IUEm82kVx5xvFuxc0KZZE88w3iEVJXE7xYo1oWmrttvkQP4Aw== + dependencies: + "@graphql-codegen/plugin-helpers" "^1.18.7" + "@graphql-codegen/visitor-plugin-common" "1.21.0" + auto-bind "~4.0.0" + tslib "~2.2.0" + +"@graphql-codegen/visitor-plugin-common@1.21.0": + version "1.21.0" + resolved "https://registry.yarnpkg.com/@graphql-codegen/visitor-plugin-common/-/visitor-plugin-common-1.21.0.tgz#1cb59a8ce9a9d6486f859a254645e162c6736cfb" + integrity sha512-gw6mUCOpKwJ4aR+wnUXureQi4dV6jezEiXvX0CEZdpqBIGAJ4G8h7CKyGW66lBzvaoLCB7siOF86UJO3dw5ctg== + dependencies: + "@graphql-codegen/plugin-helpers" "^1.18.7" "@graphql-tools/optimize" "^1.0.1" - "@graphql-tools/relay-operation-optimizer" "^6" + "@graphql-tools/relay-operation-optimizer" "^6.3.0" array.prototype.flatmap "^1.2.4" auto-bind "~4.0.0" - dependency-graph "^0.10.0" + change-case-all "1.0.14" + dependency-graph "^0.11.0" graphql-tag "^2.11.0" parse-filepath "^1.0.2" - pascal-case "^3.1.1" - tslib "~2.1.0" + tslib "~2.2.0" -"@graphql-tools/apollo-engine-loader@^6": +"@graphql-tools/apollo-engine-loader@^6.2.5": 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== @@ -618,39 +644,39 @@ 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== +"@graphql-tools/batch-execute@^7.1.2": + version "7.1.2" + resolved "https://registry.yarnpkg.com/@graphql-tools/batch-execute/-/batch-execute-7.1.2.tgz#35ba09a1e0f80f34f1ce111d23c40f039d4403a0" + integrity sha512-IuR2SB2MnC2ztA/XeTMTfWcA0Wy7ZH5u+nDkDNLAdX+AaSyDnsQS35sCmHqG0VOGTl7rzoyBWLCKGwSJplgtwg== dependencies: - "@graphql-tools/utils" "^7.0.0" + "@graphql-tools/utils" "^7.7.0" dataloader "2.0.0" - is-promise "4.0.0" - tslib "~2.0.1" + tslib "~2.2.0" + value-or-promise "1.0.6" -"@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== +"@graphql-tools/code-file-loader@^6.3.1": + version "6.3.1" + resolved "https://registry.yarnpkg.com/@graphql-tools/code-file-loader/-/code-file-loader-6.3.1.tgz#42dfd4db5b968acdb453382f172ec684fa0c34ed" + integrity sha512-ZJimcm2ig+avgsEOWWVvAaxZrXXhiiSZyYYOJi0hk9wh5BxZcLUNKkTp6EFnZE/jmGUwuos3pIjUD3Hwi3Bwhg== dependencies: - "@graphql-tools/graphql-tag-pluck" "^6.2.6" + "@graphql-tools/graphql-tag-pluck" "^6.5.1" "@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.10" - resolved "https://registry.yarnpkg.com/@graphql-tools/delegate/-/delegate-7.0.10.tgz#f87ac85a2dbd03b5b3aabf347f4479fabe8ceac3" - integrity sha512-6Di9ia5ohoDvrHuhj2cak1nJGhIefJmUsd3WKZcJ2nu2yZAFawWMxGvQImqv3N7iyaWKiVhrrK8Roi/JrYhdKg== - 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.1.0" -"@graphql-tools/git-loader@^6": +"@graphql-tools/delegate@^7.0.1", "@graphql-tools/delegate@^7.1.5": + version "7.1.5" + resolved "https://registry.yarnpkg.com/@graphql-tools/delegate/-/delegate-7.1.5.tgz#0b027819b7047eff29bacbd5032e34a3d64bd093" + integrity sha512-bQu+hDd37e+FZ0CQGEEczmRSfQRnnXeUxI/0miDV+NV/zCbEdIJj5tYFNrKT03W6wgdqx8U06d8L23LxvGri/g== + dependencies: + "@ardatan/aggregate-error" "0.0.6" + "@graphql-tools/batch-execute" "^7.1.2" + "@graphql-tools/schema" "^7.1.5" + "@graphql-tools/utils" "^7.7.1" + dataloader "2.0.0" + tslib "~2.2.0" + value-or-promise "1.0.6" + +"@graphql-tools/git-loader@^6.2.6": version "6.2.6" resolved "https://registry.yarnpkg.com/@graphql-tools/git-loader/-/git-loader-6.2.6.tgz#c2226f4b8f51f1c05c9ab2649ba32d49c68cd077" integrity sha512-ooQTt2CaG47vEYPP3CPD+nbA0F+FYQXfzrB1Y1ABN9K3d3O2RK3g8qwslzZaI8VJQthvKwt0A95ZeE4XxteYfw== @@ -659,7 +685,7 @@ "@graphql-tools/utils" "^7.0.0" tslib "~2.1.0" -"@graphql-tools/github-loader@^6": +"@graphql-tools/github-loader@^6.2.5": 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== @@ -669,7 +695,7 @@ cross-fetch "3.0.6" tslib "~2.0.1" -"@graphql-tools/graphql-file-loader@^6", "@graphql-tools/graphql-file-loader@^6.0.0": +"@graphql-tools/graphql-file-loader@^6.0.0", "@graphql-tools/graphql-file-loader@^6.2.7": version "6.2.7" resolved "https://registry.yarnpkg.com/@graphql-tools/graphql-file-loader/-/graphql-file-loader-6.2.7.tgz#d3720f2c4f4bb90eb2a03a7869a780c61945e143" integrity sha512-5k2SNz0W87tDcymhEMZMkd6/vs6QawDyjQXWtqkuLTBF3vxjxPD1I4dwHoxgWPIjjANhXybvulD7E+St/7s9TQ== @@ -678,26 +704,26 @@ "@graphql-tools/utils" "^7.0.0" tslib "~2.1.0" -"@graphql-tools/graphql-tag-pluck@^6.2.6": - version "6.4.2" - resolved "https://registry.yarnpkg.com/@graphql-tools/graphql-tag-pluck/-/graphql-tag-pluck-6.4.2.tgz#dec07d184ae133b4d582f4febcdd8430de167191" - integrity sha512-IXfFjJEIHDkjFP4LPwNpwr3bLJ9Ak1+E5vQqm5zuj24DH2Sfdx4m9wI2opiFLShcQuFpTlHIplU5PVY0Ipo8nw== +"@graphql-tools/graphql-tag-pluck@^6.2.6", "@graphql-tools/graphql-tag-pluck@^6.5.1": + version "6.5.1" + resolved "https://registry.yarnpkg.com/@graphql-tools/graphql-tag-pluck/-/graphql-tag-pluck-6.5.1.tgz#5fb227dbb1e19f4b037792b50f646f16a2d4c686" + integrity sha512-7qkm82iFmcpb8M6/yRgzjShtW6Qu2OlCSZp8uatA3J0eMl87TxyJoUmL3M3UMMOSundAK8GmoyNVFUrueueV5Q== dependencies: - "@babel/parser" "7.12.13" + "@babel/parser" "7.12.16" "@babel/traverse" "7.12.13" "@babel/types" "7.12.13" "@graphql-tools/utils" "^7.0.0" tslib "~2.1.0" "@graphql-tools/import@^6.2.6": - version "6.2.6" - resolved "https://registry.yarnpkg.com/@graphql-tools/import/-/import-6.2.6.tgz#c5f899f0b87e9fe0523b889be8a59cb30aa164ad" - integrity sha512-/0H/bDjNK1MnKonk8fMbB7wIYU6QLCwbQOHtSHbFJ4j2qki5CqfAxpF+fGX6KovDtkdigcgRMvSKKi14oiuHPA== + version "6.3.1" + resolved "https://registry.yarnpkg.com/@graphql-tools/import/-/import-6.3.1.tgz#731c47ab6c6ac9f7994d75c76b6c2fa127d2d483" + integrity sha512-1szR19JI6WPibjYurMLdadHKZoG9C//8I/FZ0Dt4vJSbrMdVNp8WFxg4QnZrDeMG4MzZc90etsyF5ofKjcC+jw== dependencies: resolve-from "5.0.0" - tslib "~2.1.0" + tslib "~2.2.0" -"@graphql-tools/json-file-loader@^6", "@graphql-tools/json-file-loader@^6.0.0": +"@graphql-tools/json-file-loader@^6.0.0", "@graphql-tools/json-file-loader@^6.2.6": 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== @@ -705,29 +731,29 @@ "@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== +"@graphql-tools/load@^6.0.0", "@graphql-tools/load@^6.2.8": + version "6.2.8" + resolved "https://registry.yarnpkg.com/@graphql-tools/load/-/load-6.2.8.tgz#16900fb6e75e1d075cad8f7ea439b334feb0b96a" + integrity sha512-JpbyXOXd8fJXdBh2ta0Q4w8ia6uK5FHzrTNmcvYBvflFuWly2LDTk2abbSl81zKkzswQMEd2UIYghXELRg8eTA== dependencies: - "@graphql-tools/merge" "^6.2.5" - "@graphql-tools/utils" "^7.0.0" - globby "11.0.1" + "@graphql-tools/merge" "^6.2.12" + "@graphql-tools/utils" "^7.5.0" + globby "11.0.3" import-from "3.0.0" is-glob "4.0.1" - p-limit "3.0.2" - tslib "~2.0.1" + p-limit "3.1.0" + tslib "~2.2.0" 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.7" - resolved "https://registry.yarnpkg.com/@graphql-tools/merge/-/merge-6.2.7.tgz#c389bfa405d8d7562a05f794ede4254875e67f75" - integrity sha512-9acgDkkYeAHpuqhOa3E63NZPCX/iWo819Q320sCCMkydF1xgx0qCRYz/V03xPdpQETKRqBG2i2N2csneeEYYig== +"@graphql-tools/merge@^6.0.0", "@graphql-tools/merge@^6.2.12", "@graphql-tools/merge@^6.2.14": + version "6.2.14" + resolved "https://registry.yarnpkg.com/@graphql-tools/merge/-/merge-6.2.14.tgz#694e2a2785ba47558e5665687feddd2935e9d94e" + integrity sha512-RWT4Td0ROJai2eR66NHejgf8UwnXJqZxXgDWDI+7hua5vNA2OW8Mf9K1Wav1ZkjWnuRp4ztNtkZGie5ISw55ow== dependencies: "@graphql-tools/schema" "^7.0.0" - "@graphql-tools/utils" "^7.0.0" - tslib "~2.1.0" + "@graphql-tools/utils" "^7.7.0" + tslib "~2.2.0" "@graphql-tools/optimize@^1.0.1": version "1.0.1" @@ -736,36 +762,34 @@ 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== +"@graphql-tools/prisma-loader@^6.3.0": + version "6.3.0" + resolved "https://registry.yarnpkg.com/@graphql-tools/prisma-loader/-/prisma-loader-6.3.0.tgz#c907e17751ff2b26e7c2bc75d0913ebf03f970da" + integrity sha512-9V3W/kzsFBmUQqOsd96V4a4k7Didz66yh/IK89B1/rrvy9rYj+ULjEqR73x9BYZ+ww9FV8yP8LasWAJwWaqqJQ== dependencies: - "@graphql-tools/url-loader" "^6.3.1" + "@graphql-tools/url-loader" "^6.8.2" "@graphql-tools/utils" "^7.0.0" "@types/http-proxy-agent" "^2.0.2" - "@types/js-yaml" "^3.12.5" + "@types/js-yaml" "^4.0.0" "@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" + debug "^4.3.1" 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" + js-yaml "^4.0.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" + tslib "~2.1.0" yaml-ast-parser "^0.0.43" -"@graphql-tools/relay-operation-optimizer@^6": +"@graphql-tools/relay-operation-optimizer@^6.3.0": 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== @@ -774,65 +798,59 @@ relay-compiler "10.1.0" tslib "~2.0.1" -"@graphql-tools/schema@^7.0.0", "@graphql-tools/schema@^7.1.2": - version "7.1.3" - resolved "https://registry.yarnpkg.com/@graphql-tools/schema/-/schema-7.1.3.tgz#d816400da51fbac1f0086e35540ab63b5e30e858" - integrity sha512-ZY76hmcJlF1iyg3Im0sQ3ASRkiShjgv102vLTVcH22lEGJeCaCyyS/GF1eUHom418S60bS8Th6+autRUxfBiBg== +"@graphql-tools/schema@^7.0.0", "@graphql-tools/schema@^7.1.5": + version "7.1.5" + resolved "https://registry.yarnpkg.com/@graphql-tools/schema/-/schema-7.1.5.tgz#07b24e52b182e736a6b77c829fc48b84d89aa711" + integrity sha512-uyn3HSNSckf4mvQSq0Q07CPaVZMNFCYEVxroApOaw802m9DcZPgf9XVPy/gda5GWj9AhbijfRYVTZQgHnJ4CXA== dependencies: "@graphql-tools/utils" "^7.1.2" - tslib "~2.1.0" + tslib "~2.2.0" + value-or-promise "1.0.6" -"@graphql-tools/url-loader@^6", "@graphql-tools/url-loader@^6.0.0", "@graphql-tools/url-loader@^6.3.1": - version "6.8.0" - resolved "https://registry.yarnpkg.com/@graphql-tools/url-loader/-/url-loader-6.8.0.tgz#932a71db7ef8c807f9a601ba538fecb763524acc" - integrity sha512-x4f93UnH7kNr9iHFpJHL6kYWogRFlxMEnXybHS9xNCFd08+ftMO22bUb8esnFsyNrtMMlkLtshDSyNb3LbIMQg== +"@graphql-tools/url-loader@^6.0.0", "@graphql-tools/url-loader@^6.10.1", "@graphql-tools/url-loader@^6.8.2": + version "6.10.1" + resolved "https://registry.yarnpkg.com/@graphql-tools/url-loader/-/url-loader-6.10.1.tgz#dc741e4299e0e7ddf435eba50a1f713b3e763b33" + integrity sha512-DSDrbhQIv7fheQ60pfDpGD256ixUQIR6Hhf9Z5bRjVkXOCvO5XrkwoWLiU7iHL81GB1r0Ba31bf+sl+D4nyyfw== dependencies: "@graphql-tools/delegate" "^7.0.1" - "@graphql-tools/utils" "^7.1.5" + "@graphql-tools/utils" "^7.9.0" "@graphql-tools/wrap" "^7.0.4" - "@types/websocket" "1.0.1" - cross-fetch "3.0.6" - eventsource "1.0.7" + "@microsoft/fetch-event-source" "2.0.1" + "@types/websocket" "1.0.2" + abort-controller "3.0.0" + cross-fetch "3.1.4" extract-files "9.0.0" - graphql-upload "^11.0.0" - graphql-ws "4.1.0" + form-data "4.0.0" + graphql-ws "^4.4.1" is-promise "4.0.0" - isomorphic-form-data "2.0.0" isomorphic-ws "4.0.1" - sse-z "0.3.0" + lodash "4.17.21" + meros "1.1.4" + subscriptions-transport-ws "^0.9.18" sync-fetch "0.3.0" - tslib "~2.1.0" + tslib "~2.2.0" valid-url "1.0.9" - ws "7.4.2" + ws "7.4.5" -"@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.5" - resolved "https://registry.yarnpkg.com/@graphql-tools/utils/-/utils-7.2.5.tgz#d7f3fca326bbac34de664773d75634bf588ba2db" - integrity sha512-S9RUkPimq+5eEDohDjiq/JCPUsiZblKRG8ve+diUwF1f8+r6FV2xGXrOt0qhQJiMxIO+BOK3DU9c+U3tX9Jo0w== +"@graphql-tools/utils@^7.0.0", "@graphql-tools/utils@^7.1.0", "@graphql-tools/utils@^7.1.2", "@graphql-tools/utils@^7.5.0", "@graphql-tools/utils@^7.7.0", "@graphql-tools/utils@^7.7.1", "@graphql-tools/utils@^7.8.1", "@graphql-tools/utils@^7.9.0", "@graphql-tools/utils@^7.9.1": + version "7.10.0" + resolved "https://registry.yarnpkg.com/@graphql-tools/utils/-/utils-7.10.0.tgz#07a4cb5d1bec1ff1dc1d47a935919ee6abd38699" + integrity sha512-d334r6bo9mxdSqZW6zWboEnnOOFRrAPVQJ7LkU8/6grglrbcu6WhwCLzHb90E94JI3TD3ricC3YGbUqIi9Xg0w== dependencies: "@ardatan/aggregate-error" "0.0.6" camel-case "4.1.2" - tslib "~2.1.0" + tslib "~2.2.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== + version "7.0.8" + resolved "https://registry.yarnpkg.com/@graphql-tools/wrap/-/wrap-7.0.8.tgz#ad41e487135ca3ea1ae0ea04bb3f596177fb4f50" + integrity sha512-1NDUymworsOlb53Qfh7fonDi2STvqCtbeE68ntKY9K/Ju/be2ZNxrFSbrBHwnxWcN9PjISNnLcAyJ1L5tCUyhg== 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" + "@graphql-tools/delegate" "^7.1.5" + "@graphql-tools/schema" "^7.1.5" + "@graphql-tools/utils" "^7.8.1" + tslib "~2.2.0" + value-or-promise "1.0.6" "@hapi/accept@5.0.1": version "5.0.1" @@ -843,36 +861,31 @@ "@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== + version "9.1.2" + resolved "https://registry.yarnpkg.com/@hapi/boom/-/boom-9.1.2.tgz#48bd41d67437164a2d636e3b5bc954f8c8dc5e38" + integrity sha512-uJEJtiNHzKw80JpngDGBCGAmWjBtzxDCz17A9NO2zCi8LLBlb5Frpq4pXwyN+2JQMod4pKz5BALwyneCgDg89Q== 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== + version "9.2.0" + resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-9.2.0.tgz#f3933a44e365864f4dad5db94158106d511e8131" + integrity sha512-sqKVVVOe5ivCaXDWivIJYVSaEgdQK9ul7a4Kity5Iw7u9+wBAPbX1RMSnLLmp7O4Vzj0WOWwMAJsTL00xwaNug== "@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" +"@microsoft/fetch-event-source@2.0.1": + version "2.0.1" + resolved "https://registry.yarnpkg.com/@microsoft/fetch-event-source/-/fetch-event-source-2.0.1.tgz#9ceecc94b49fbaa15666e38ae8587f64acce007d" + integrity sha512-W6CLUJ2eBMw3Rec70qrsEW0jOm/3twwJv21mrmj2yORiaVmVYGS4sSS5yUwvQc1ZlDLYGPnClVWmUUMagKNsfA== -"@next/bundle-analyzer@^10.0.1": - version "10.0.6" - resolved "https://registry.yarnpkg.com/@next/bundle-analyzer/-/bundle-analyzer-10.0.6.tgz#e39b45f7d08a5e913c870d5bc0b666bf5a230f37" - integrity sha512-zwl08fz784t0tpJFTUpoYTcPUQ3SqIEb2M+3Lyv2rMXeQ8AsRru7bSvTdW1P15ENWDDF2AovJptAoohjfutViQ== +"@next/bundle-analyzer@^10.2.3": + version "10.2.3" + resolved "https://registry.yarnpkg.com/@next/bundle-analyzer/-/bundle-analyzer-10.2.3.tgz#6526e31f46cd48145986dc3bf911ff693e2acdf7" + integrity sha512-vEfQhGWgJugZOlSUlj3DZWs/KsK0SO2SPKoHSZ7KkzpruKzc/e45G0oUh0rffzdhasMQZM1TuSBkxO+1UcnDNw== dependencies: webpack-bundle-analyzer "4.3.0" @@ -908,25 +921,25 @@ resolved "https://registry.yarnpkg.com/@next/react-refresh-utils/-/react-refresh-utils-10.0.9-canary.5.tgz#5ece6594ec08b48bc319d8f171d9c46a7beb04ba" integrity sha512-47Y2GO+PezgJF4t41/VOEmIpUe66bbzbh/jO+doldwoPiLPxrSfOMpAnlJLpm5keHquBJMCIQbwDtmSpNvPkTg== -"@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== +"@nodelib/fs.scandir@2.1.5": + version "2.1.5" + resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" + integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== dependencies: - "@nodelib/fs.stat" "2.0.4" + "@nodelib/fs.stat" "2.0.5" 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.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" + integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== "@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== + version "1.2.7" + resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.7.tgz#94c23db18ee4653e129abd26fb06f870ac9e1ee2" + integrity sha512-BTIhocbPBSrRmHxOAJFtR18oLhxTtAFDAvL8hY1S3iU8k+E60W/YFs4jrixGzQjMpF4qPXxIQHcjVD9dz1C2QA== dependencies: - "@nodelib/fs.scandir" "2.1.4" + "@nodelib/fs.scandir" "2.1.5" fastq "^1.6.0" "@opentelemetry/api@0.14.0": @@ -941,27 +954,26 @@ 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== +"@polka/url@^1.0.0-next.15": + version "1.0.0-next.15" + resolved "https://registry.yarnpkg.com/@polka/url/-/url-1.0.0-next.15.tgz#6a9d143f7f4f49db2d782f9e1c8839a29b43ae23" + integrity sha512-15spi3V28QdevleWBNXE4pIls3nFZmBbUGrW9IVPwiQczuSb9n76TCB4bsk8TSel+I1OkHEdPhu5QKMfY6rQHA== -"@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== +"@reach/portal@^0.15.0": + version "0.15.0" + resolved "https://registry.yarnpkg.com/@reach/portal/-/portal-0.15.0.tgz#b137582a1ecc4e04c60ce9a9c672dd2d23a2f1cc" + integrity sha512-Aulqjk/PIRu+R7yhINYAAYfYh++ZdC30qwHDWDtGk2cmTEJT7m9AlvBX+W7T+Q3Ux6Wy5f37eV+TTGid1CcjFw== dependencies: - "@reach/utils" "0.11.2" - tslib "^2.0.0" + "@reach/utils" "0.15.0" + tslib "^2.1.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== +"@reach/utils@0.15.0": + version "0.15.0" + resolved "https://registry.yarnpkg.com/@reach/utils/-/utils-0.15.0.tgz#5b183d668f9bb900b2dec7a33c028a2a828d27b2" + integrity sha512-JHHN7T5ucFiuQbqkgv8ECbRWKfRiJxrO/xHR3fHf+f2C7mVs/KkJHhYtovS1iEapR4silygX9PY0+QUmHPOTYw== dependencies: - "@types/warning" "^3.0.0" - tslib "^2.0.0" - warning "^4.0.3" + tiny-warning "^1.0.3" + tslib "^2.1.0" "@samverschueren/stream-to-observable@^0.3.0": version "0.3.1" @@ -982,19 +994,6 @@ dependencies: defer-to-connect "^1.0.1" -"@tailwindcss/jit@^0.1.3": - version "0.1.3" - resolved "https://registry.yarnpkg.com/@tailwindcss/jit/-/jit-0.1.3.tgz#50390d9ac95fee78ed23a7e2320ef20bd4a35354" - integrity sha512-7VAvHKNLJxbGWRKxo2Z+beiodag7vWPx8b/+Egd5fve4zFihsngeNt6RwQFnll+almjppRYefRC5Py5v5K+6vg== - dependencies: - chokidar "^3.5.1" - dlv "^1.1.3" - fast-glob "^3.2.5" - lodash.topath "^4.5.2" - object-hash "^2.1.1" - postcss-selector-parser "^6.0.4" - quick-lru "^5.1.1" - "@tootallnate/once@1": version "1.1.2" resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-1.1.2.tgz#ccb91445360179a04e7fe6aff78c00ffc1eeaf82" @@ -1010,11 +1009,6 @@ resolved "https://registry.yarnpkg.com/@types/body-scroll-lock/-/body-scroll-lock-2.6.1.tgz#0dbd2b6ad2f4cfcece7102d6cf8630ce95508ee0" integrity sha512-PPFm/2A6LfKmSpvMg58gHtSqwwMChbcKKGhSCRIhY4MyFzhY8moAN6HrTCpOeZQUqkFdTFfMqr7njeqGLKt72Q== -"@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" @@ -1032,10 +1026,10 @@ 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/js-yaml@^4.0.0": + version "4.0.1" + resolved "https://registry.yarnpkg.com/@types/js-yaml/-/js-yaml-4.0.1.tgz#5544730b65a480b18ace6b6ce914e519cec2d43b" + integrity sha512-xdOvNmXmrZqqPy3kuCQ+fz6wA0xU5pji9cd1nDrflWaAWtYLLGk5ykW0H6yg5TVyehHP1pfmuuSaZkhP+kspVA== "@types/json-stable-stringify@^1.0.32": version "1.0.32" @@ -1043,9 +1037,9 @@ 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== + version "8.5.1" + resolved "https://registry.yarnpkg.com/@types/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz#56958cb2d80f6d74352bd2e501a018e2506a8a84" + integrity sha512-rNAPdomlIUX0i0cg2+I+Q1wOUr531zHBQ+cV/28PJ39bSPKjahatZZ2LMuhiguETkCgLVzfruw/ZvNMNkKoSzw== dependencies: "@types/node" "*" @@ -1071,20 +1065,15 @@ "@types/lodash" "*" "@types/lodash@*": - version "4.14.168" - resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.168.tgz#fe24632e79b7ade3f132891afff86caa5e5ce008" - integrity sha512-oVfRvqHV/V6D1yifJbVRU3TMp8OT6o6BG+U9MkwuJ3U8/CsDHvalRpsxBqivn71ztOFZBTfJMvETbqHiaNSj7Q== + version "4.14.170" + resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.170.tgz#0d67711d4bf7f4ca5147e9091b847479b87925d6" + integrity sha512-bpcvu/MKHHeYX+qeEN8GE7DIravODWdACVA1ctevD8CN24RhPZIKMn9ntfAsrvLfSX3cR5RrBKAbYm9bGs0A+Q== "@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" @@ -1092,21 +1081,16 @@ dependencies: "@types/node" "*" -"@types/node@*", "@types/node@^14.14.16": - version "14.14.27" - resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.27.tgz#c7127f8da0498993e13b1a42faf1303d3110d2f2" - integrity sha512-Ecfmo4YDQPwuqTCl1yBxLV5ihKfRlkBmzUEDcfIRvDxOTGQEeikr317Ln7Gcv0tjA8dVgKI3rniqW2G1OyKDng== +"@types/node@*", "@types/node@^15.6.1": + version "15.12.1" + resolved "https://registry.yarnpkg.com/@types/node/-/node-15.12.1.tgz#9b60797dee1895383a725f828a869c86c6caa5c2" + integrity sha512-zyxJM8I1c9q5sRMtVF+zdd13Jt6RU4r4qfhTd7lQubyThvLfx6yYekWSQjGCGV2Tkecgxnlpl/DNlb6Hg+dmEw== "@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" @@ -1117,43 +1101,57 @@ 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.2" - resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.2.tgz#3de24c4efef902dd9795a49c75f760cbe4f7a5a8" - integrity sha512-Xt40xQsrkdvjn1EyWe1Bc0dJLcil/9x2vAuW7ya+PuQip4UYUaXyhzWmAbwRsdMgwOFHpfp7/FFZebDU6Y8VHA== +"@types/react@^17.0.8": + version "17.0.9" + resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.9.tgz#1147fb520024a62c9b3841f5cb4db89b73ddb87f" + integrity sha512-2Cw7FvevpJxQrCb+k5t6GH1KIvmadj5uBbjPaLlJB/nZWUj56e1ZqcD6zsoMFB47MsJUTFl9RJ132A7hb3QFJA== dependencies: "@types/prop-types" "*" + "@types/scheduler" "*" csstype "^3.0.2" +"@types/scheduler@*": + version "0.16.1" + resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.1.tgz#18845205e86ff0038517aab7a18a62a6b9f71275" + integrity sha512-EaCxbanVeyxDRTQBkdLb3Bvl/HK7PBK6UJjsSixB0iHKoWxE5uu2Q/DgtpOhPIojN0Zl1whvOd7PoHs2P0s5eA== + "@types/shopify-buy@^2.10.5": version "2.10.5" resolved "https://registry.yarnpkg.com/@types/shopify-buy/-/shopify-buy-2.10.5.tgz#c7184b792989a968af879224e8990cde4db45519" integrity sha512-12Le/iXPynrONntux/OaXf9+yx0zbMBKhwywdej9mfR8YhXB82pPZYzU3o6j8cjK1uCQ/wWkqLTftpaXpeMKig== -"@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== +"@types/websocket@1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@types/websocket/-/websocket-1.0.2.tgz#d2855c6a312b7da73ed16ba6781815bf30c6187a" + integrity sha512-B5m9aq7cbbD/5/jThEr33nUY8WEfVi6A2YKCTOvw5Ldy7mtsOkqRvGjnzy6g7iMMDsgu7xREuCzqATLDLQVKcQ== 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== +"@typescript-eslint/types@4.26.0": + version "4.26.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.26.0.tgz#7c6732c0414f0a69595f4f846ebe12616243d546" + integrity sha512-rADNgXl1kS/EKnDr3G+m7fB9yeJNnR9kF7xMiXL6mSIWpr3Wg5MhxyfEXy/IlYthsqwBqHOr22boFbf/u6O88A== + +"@typescript-eslint/typescript-estree@^4.8.2": + version "4.26.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.26.0.tgz#aea17a40e62dc31c63d5b1bbe9a75783f2ce7109" + integrity sha512-GHUgahPcm9GfBuy3TzdsizCcPjKOAauG9xkz9TR8kOdssz2Iz9jRCSQm6+aVFa23d5NcSpo1GdHGSQKe0tlcbg== dependencies: - debug "^4.1.1" - eslint-visitor-keys "^1.1.0" - glob "^7.1.6" + "@typescript-eslint/types" "4.26.0" + "@typescript-eslint/visitor-keys" "4.26.0" + debug "^4.3.1" + globby "^11.0.3" is-glob "^4.0.1" - lodash "^4.17.15" - semver "^7.3.2" - tsutils "^3.17.1" + semver "^7.3.5" + tsutils "^3.21.0" + +"@typescript-eslint/visitor-keys@4.26.0": + version "4.26.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.26.0.tgz#26d2583169222815be4dcd1da4fe5459bc3bcc23" + integrity sha512-cw4j8lH38V1ycGBbF+aFiLUls9Z0Bw8QschP3mkth50BbWzgFS33ISIgBzUMuQ2IdahoEv/rXstr8Zhlz4B1Zg== + dependencies: + "@typescript-eslint/types" "4.26.0" + eslint-visitor-keys "^2.0.0" "@vercel/fetch-cached-dns@^2.0.1": version "2.0.1" @@ -1193,6 +1191,13 @@ 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" @@ -1208,9 +1213,9 @@ acorn-walk@^7.0.0: integrity sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA== acorn-walk@^8.0.0: - version "8.0.2" - resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.0.2.tgz#d4632bfc63fd93d0f15fd05ea0e984ffd3f5a8c3" - integrity sha512-+bpA9MJsHdZ4bgfDcpk0ozQyhhVct7rzOmO0s1IIr0AGGgKBljss8n2zp11rRP2wid5VGeh04CgeKzgat5/25A== + version "8.1.0" + resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.1.0.tgz#d3c6a9faf00987a5e2b9bdb506c2aa76cd707f83" + integrity sha512-mjmzmv12YIG/G8JQdQuz2MUDShEJ6teYpT5bmWA4q7iwoGen8xtt3twF3OvzIUl+Q06aWIjvnwQUKvQ6TtMRjg== acorn@^7.0.0: version "7.4.1" @@ -1218,9 +1223,9 @@ acorn@^7.0.0: integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== acorn@^8.0.4: - version "8.0.5" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.0.5.tgz#a3bfb872a74a6a7f661bc81b9849d9cac12601b7" - integrity sha512-v+DieK/HJkJOpFBETDJioequtc3PfxsWMaxIdIwujtF7FEV/MAyDQLlm6/zPvr7Mix07mLh6ccVwIsloceodlg== + version "8.3.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.3.0.tgz#1193f9b96c4e8232f00b11a9edff81b2c8b98b88" + integrity sha512-tqPKHZ5CaBJw0Xmy0ZZvLs1qTV+BNFSyvn77ASXkpBNfIRk8ev26fKrD9iLGwGA9zedPao52GSHzq8lyZG0NUw== agent-base@6: version "6.0.2" @@ -1244,16 +1249,6 @@ aggregate-error@^3.0.0: clean-stack "^2.0.0" indent-string "^4.0.0" -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" @@ -1270,11 +1265,11 @@ ansi-escapes@^3.0.0: integrity sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ== ansi-escapes@^4.2.1, ansi-escapes@^4.3.0, 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== + version "4.3.2" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e" + integrity sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ== dependencies: - type-fest "^0.11.0" + type-fest "^0.21.3" ansi-regex@^2.0.0: version "2.1.1" @@ -1316,9 +1311,9 @@ any-observable@^0.3.0: 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== + version "3.1.2" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716" + integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg== dependencies: normalize-path "^3.0.0" picomatch "^2.0.4" @@ -1333,19 +1328,17 @@ arg@^4.1.0: 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" +argparse@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" + integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== 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== + version "3.1.0" + resolved "https://registry.yarnpkg.com/array-includes-with-glob/-/array-includes-with-glob-3.1.0.tgz#f04e8172f231ab8261e52bfe9756b65c08b87ab9" + integrity sha512-/PZEKASyXWmUTkNhuxnmqybv1CmIdY5rp3axLy3Dv6SYfaBb+EgS7Nl991mquHT1N2u0YAnE3IOafVNRM6Y9dw== dependencies: - "@babel/runtime" "^7.13.10" + "@babel/runtime" "^7.14.0" matcher "^4.0.0" array-union@^2.1.0: @@ -1363,11 +1356,6 @@ array.prototype.flatmap@^1.2.4: 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" @@ -1391,7 +1379,7 @@ assert@^1.1.1: object-assign "^4.1.1" util "0.10.3" -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: +ast-module-types@^2.3.2, ast-module-types@^2.4.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== @@ -1406,6 +1394,11 @@ astral-regex@^2.0.0: resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-2.0.0.tgz#483143c567aeed4785759c0865786dc77d7d2e31" integrity sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ== +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" @@ -1435,15 +1428,15 @@ 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== +autoprefixer@^10.2.6: + version "10.2.6" + resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-10.2.6.tgz#aadd9ec34e1c98d403e01950038049f0eb252949" + integrity sha512-8lChSmdU6dCNMCQopIf4Pe5kipkAGj/fvTMslCsih0uHpOrXOPUEVOmYMMqmw3cekQkSD7EhIeuYl5y0BLdKqg== dependencies: - browserslist "^4.16.1" - caniuse-lite "^1.0.30001181" - colorette "^1.2.1" - fraction.js "^4.0.13" + browserslist "^4.16.6" + caniuse-lite "^1.0.30001230" + colorette "^1.2.2" + fraction.js "^4.1.1" normalize-range "^0.1.2" postcss-value-parser "^4.1.0" @@ -1478,9 +1471,9 @@ babel-plugin-syntax-trailing-function-commas@^7.0.0-beta.0: integrity sha512-Xj9XuRuz3nTSbaTXWv3itLOcxyF4oPD8douBBmj7U9BBC6nEBYfyOJYQMf/8PJAFotC62UY5dFfIGEPr7WswzQ== 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== + version "3.4.0" + resolved "https://registry.yarnpkg.com/babel-preset-fbjs/-/babel-preset-fbjs-3.4.0.tgz#38a14e5a7a3b285a3f3a86552d650dca5cf6111c" + integrity sha512-9ywCsCvo1ojrw0b+XYk7aFvTH6D9064t0RIL1rtMf3nsa02Xw41MS7sZw216Im35xj/UY0PDBQsa1brUDDF1Ow== dependencies: "@babel/plugin-proposal-class-properties" "^7.0.0" "@babel/plugin-proposal-object-rest-spread" "^7.0.0" @@ -1510,10 +1503,15 @@ babel-preset-fbjs@^3.3.0: "@babel/plugin-transform-template-literals" "^7.0.0" babel-plugin-syntax-trailing-function-commas "^7.0.0-beta.0" +backo2@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/backo2/-/backo2-1.0.2.tgz#31ab1ac8b129363463e35b3ebb69f4dfcfba7947" + integrity sha1-MasayLEpNjRj41s+u2n038+6eUc= + 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= + version "1.0.2" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" + integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== base64-js@^1.0.2, base64-js@^1.3.1: version "1.5.1" @@ -1530,7 +1528,7 @@ binary-extensions@^2.0.0: resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== -bl@^4.0.3: +bl@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/bl/-/bl-4.1.0.tgz#451535264182bec2fbbc83a62ab98cf11d9f7b3a" integrity sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w== @@ -1539,20 +1537,15 @@ bl@^4.0.3: 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.11.9: - version "4.11.9" - resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.9.tgz#26d556829458f9d1e81fc48952493d0ba3507828" - integrity sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw== + version "4.12.0" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.12.0.tgz#775b3f278efbb9718eec7361f483fb36fbbfea88" + integrity sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA== 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== + version "5.2.0" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.2.0.tgz#358860674396c6997771a9d051fcc1b57d4ae002" + integrity sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw== body-scroll-lock@^3.1.5: version "3.1.5" @@ -1656,16 +1649,16 @@ browserslist@4.16.1: escalade "^3.1.1" node-releases "^1.1.69" -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== +browserslist@^4.12.0, browserslist@^4.16.6, browserslist@^4.6.4: + version "4.16.6" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.16.6.tgz#d7901277a5a88e554ed305b183ec9b0c08f66fa2" + integrity sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ== dependencies: - caniuse-lite "^1.0.30001181" - colorette "^1.2.1" - electron-to-chromium "^1.3.649" + caniuse-lite "^1.0.30001219" + colorette "^1.2.2" + electron-to-chromium "^1.3.723" escalade "^3.1.1" - node-releases "^1.1.70" + node-releases "^1.1.71" bser@2.1.1: version "2.1.1" @@ -1719,13 +1712,6 @@ builtin-status-codes@^3.0.0: resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8" integrity sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug= -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" @@ -1757,14 +1743,6 @@ callsites@^3.0.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" @@ -1778,24 +1756,24 @@ camelcase-css@^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.0.0, camelcase@^5.3.1: +camelcase@^5.0.0: version "5.3.1" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== -caniuse-lite@^1.0.30000981, caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001173, caniuse-lite@^1.0.30001179, caniuse-lite@^1.0.30001181: - version "1.0.30001185" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001185.tgz#3482a407d261da04393e2f0d61eefbc53be43b95" - integrity sha512-Fpi4kVNtNvJ15H0F6vwmXtb3tukv3Zg3qhKkOGUq7KJ1J6b9kf4dnNgtEAFXhRsJo0gNj9W60+wBvn0JcTvdTg== +caniuse-lite@^1.0.30000981, caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001173, caniuse-lite@^1.0.30001179, caniuse-lite@^1.0.30001219, caniuse-lite@^1.0.30001230: + version "1.0.30001234" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001234.tgz#8fc2e709e3b0679d7af7f073a1c661155c39b975" + integrity sha512-a3gjUVKkmwLdNysa1xkUAwN2VfJUJyVW47rsi3aCbkRCtbHAfo+rOsCqVw29G6coQ8gzAPb5XBXwiGHwme3isA== + +capital-case@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/capital-case/-/capital-case-1.0.4.tgz#9d130292353c9249f6b00fa5852bee38a717e669" + integrity sha512-ds37W8CytHgwnhGGTi88pcPyR15qoNkOpYwmMMfnWqqWgESapLqvDx6huFjQ5vqWSn2Z06173XNA7LtMOeUh1A== + dependencies: + no-case "^3.0.4" + tslib "^2.0.3" + upper-case-first "^2.0.2" chalk@2.4.2, chalk@^2.0.0, chalk@^2.3.0, chalk@^2.4.1, chalk@^2.4.2: version "2.4.2" @@ -1825,20 +1803,54 @@ chalk@^1.0.0, chalk@^1.1.3: strip-ansi "^3.0.0" supports-color "^2.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== +chalk@^4.0.0, chalk@^4.1.0, chalk@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.1.tgz#c80b3fab28bf6371e6863325eee67e618b77e6ad" + integrity sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg== dependencies: ansi-styles "^4.1.0" supports-color "^7.1.0" +change-case-all@1.0.14: + version "1.0.14" + resolved "https://registry.yarnpkg.com/change-case-all/-/change-case-all-1.0.14.tgz#bac04da08ad143278d0ac3dda7eccd39280bfba1" + integrity sha512-CWVm2uT7dmSHdO/z1CXT/n47mWonyypzBbuCy5tN7uMg22BsfkhwT6oHmFCAk+gL1LOOxhdbB9SZz3J1KTY3gA== + dependencies: + change-case "^4.1.2" + is-lower-case "^2.0.2" + is-upper-case "^2.0.2" + lower-case "^2.0.2" + lower-case-first "^2.0.2" + sponge-case "^1.0.1" + swap-case "^2.0.2" + title-case "^3.0.3" + upper-case "^2.0.2" + upper-case-first "^2.0.2" + +change-case@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/change-case/-/change-case-4.1.2.tgz#fedfc5f136045e2398c0410ee441f95704641e12" + integrity sha512-bSxY2ws9OtviILG1EiY5K7NNxkqg/JnRnFxLtKQ96JaviiIxi7djMrSd0ECT9AC+lttClmYwKw53BWpOMblo7A== + dependencies: + camel-case "^4.1.2" + capital-case "^1.0.4" + constant-case "^3.0.4" + dot-case "^3.0.4" + header-case "^2.0.4" + no-case "^3.0.4" + param-case "^3.0.4" + pascal-case "^3.1.2" + path-case "^3.0.4" + sentence-case "^3.0.4" + snake-case "^3.0.4" + tslib "^2.0.3" + 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.5.1, chokidar@^3.4.3, chokidar@^3.5.1: +chokidar@3.5.1, chokidar@^3.5.1: version "3.5.1" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.1.tgz#ee9ce7bbebd2b79f49f304799d5468e31e14e68a" integrity sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw== @@ -1853,11 +1865,6 @@ chokidar@3.5.1, chokidar@^3.4.3, chokidar@^3.5.1: optionalDependencies: fsevents "~2.3.1" -ci-info@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46" - integrity sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ== - 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" @@ -1866,11 +1873,16 @@ cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: inherits "^2.0.1" safe-buffer "^5.0.1" -classnames@2.2.6, 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== +classnames@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.3.1.tgz#dfcfa3891e306ec1dad105d0e88f4417b8535e8e" + integrity sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA== + clean-stack@^2.0.0: version "2.2.0" resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b" @@ -1891,9 +1903,9 @@ cli-cursor@^3.1.0: 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== + version "2.6.0" + resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.6.0.tgz#36c7dc98fb6a9a76bd6238ec3f77e2425627e939" + integrity sha512-t+4/y50K/+4xcCRosKkA7W4gTr1MySvLV0q+PxmG7FJ5g+66ChKurYjxBCjHggHH3HA5Hh9cy+lcUGWDqVH+4Q== cli-truncate@^0.2.1: version "0.2.1" @@ -1976,9 +1988,9 @@ color-name@^1.0.0, color-name@~1.1.4: 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== + version "1.5.5" + resolved "https://registry.yarnpkg.com/color-string/-/color-string-1.5.5.tgz#65474a8f0e7439625f3d27a6a19d89fc45223014" + integrity sha512-jgIoum0OfQfq9Whcfc2z/VhCNcmQjWbey6qBX0vqt7YICflUmBCh9E9CiQD5GSJ+Uehixm3NUwHVhqUAWRivZg== dependencies: color-name "^1.0.0" simple-swizzle "^0.2.2" @@ -1991,24 +2003,19 @@ color@^3.1.3: 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== - -colorette@^1.2.2: +colorette@^1.2.1, colorette@^1.2.2: version "1.2.2" resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.2.2.tgz#cbcc79d5e99caea2dbf10eb3a26fd8b3e6acfa94" integrity sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w== -combined-stream@^1.0.6, combined-stream@^1.0.8: +combined-stream@^1.0.8: 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.3, commander@^2.8.1: +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== @@ -2018,16 +2025,16 @@ commander@^4.0.0: resolved "https://registry.yarnpkg.com/commander/-/commander-4.1.1.tgz#9fd602bd936294e9e9ef46a3f4d6964044b18068" integrity sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA== -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.0.0, commander@^6.2.0: +commander@^6.0.0, commander@^6.2.0, commander@^6.2.1: version "6.2.1" resolved "https://registry.yarnpkg.com/commander/-/commander-6.2.1.tgz#0792eb682dfbc325999bb2b84fddddba110ac73c" integrity sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA== +commander@^7.2.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-7.2.0.tgz#a36cb57d0b501ce108e4d20559a150a391d97ab7" + integrity sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw== + 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" @@ -2038,11 +2045,6 @@ commondir@^1.0.1: resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" integrity sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs= -compare-versions@^3.6.0: - version "3.6.0" - resolved "https://registry.yarnpkg.com/compare-versions/-/compare-versions-3.6.0.tgz#1a5689913685e5a87637b8d3ffca75514ec41d62" - integrity sha512-W6Af2Iw1z4CB7q4uU4hv646dW9GQuBM+YpC0UvUCWSD8w90SJjp+ujJuXaEMtAXBtSqGfMPuFOVn4/+FlaqfBA== - concat-map@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" @@ -2053,16 +2055,7 @@ console-browserify@^1.1.0: resolved "https://registry.yarnpkg.com/console-browserify/-/console-browserify-1.2.0.tgz#67063cef57ceb6cf4993a2ab3a55840ae8c49336" integrity sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA== -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: +constant-case@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/constant-case/-/constant-case-3.0.4.tgz#3b84a9aeaf4cf31ec45e6bf5de91bdfb0589faf1" integrity sha512-I2hSBi7Vvs7BEuJDr5dDHfzb/Ruj3FyvFyh7KLilAjNQw3Be+xgqUBA2W6scVEcL0hL1dwPRtIqEPVUCKkSsyQ== @@ -2100,18 +2093,7 @@ cosmiconfig-toml-loader@1.0.0: 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: +cosmiconfig@7.0.0, cosmiconfig@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-7.0.0.tgz#ef9b44d773959cae63ddecd122de23853b60f8d3" integrity sha512-pondGvTuVYDk++upghXJabWzL6Kxu6f26ljFw64Swq9v6sQPUL3EUlVDV56diOjpCayKihL6hVe8exIACU4XcA== @@ -2158,14 +2140,21 @@ create-require@^1.1.0: 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: +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" -cross-spawn@^7.0.0: +cross-fetch@3.1.4, cross-fetch@^3.0.4, cross-fetch@^3.0.6: + version "3.1.4" + resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-3.1.4.tgz#9723f3a3a247bf8b89039f3a380a9244e8fa2f39" + integrity sha512-1eAtFWdIubi6T4XPy6ei9iUFoKpUkIF971QLN8lIvvvwueI65+Nw5haMNKUwfJxabqlIIDODJKGrQ66gxC0PbQ== + dependencies: + node-fetch "2.6.1" + +cross-spawn@^7.0.3: version "7.0.3" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== @@ -2255,9 +2244,9 @@ cssnano-simple@1.2.2: 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== + version "3.0.8" + resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.0.8.tgz#d2266a792729fb227cd216fb572f43728e1ad340" + integrity sha512-jXKhWqXPmlUeoQnF/EhTtTl4C9SnrxSH/jZUih3jmO6lBKr99rP3/+FmrMj4EFpOXzMtXHAZkd3x0E6h6Fgflw== data-uri-to-buffer@3.0.1: version "3.0.1" @@ -2275,9 +2264,9 @@ date-fns@^1.27.2: 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== + version "1.2.1" + resolved "https://registry.yarnpkg.com/debounce/-/debounce-1.2.1.tgz#38881d8f4166a5c5848020c11827b834bcb3e0a5" + integrity sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug== debug@2: version "2.6.9" @@ -2293,7 +2282,7 @@ 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, debug@^4.2.0, debug@^4.2.1: +debug@4, debug@^4.0.0, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1: version "4.3.1" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.1.tgz#f0d229c505e0c6d8c49ac553d1b13dc183f6b2ee" integrity sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ== @@ -2307,23 +2296,15 @@ debug@^3.1.0: 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: +decamelize@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= -decomment@^0.9.2: - version "0.9.3" - resolved "https://registry.yarnpkg.com/decomment/-/decomment-0.9.3.tgz#b913f32e5fe1113848f516caa5c7afefa9544d38" - integrity sha512-5skH5BfUL3n09RDmMVaHS1QGCiZRnl2nArUwmsE9JRY93Ueh3tihYl5wIrDdAuXnoFhxVis/DmRWREO2c6DG3w== +decomment@^0.9.3: + version "0.9.4" + resolved "https://registry.yarnpkg.com/decomment/-/decomment-0.9.4.tgz#fa40335bd90e3826d5c1984276e390525ff856d5" + integrity sha512-8eNlhyI5cSU4UbBlrtagWpR03dqXcE5IR9zpe7PnO6UzReXDskucsD8usgrzUmQ6qJ3N82aws/p/mu/jqbURWw== dependencies: esprima "4.0.1" @@ -2388,20 +2369,20 @@ depd@~1.1.2: resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak= -dependency-graph@^0.10.0: - version "0.10.0" - resolved "https://registry.yarnpkg.com/dependency-graph/-/dependency-graph-0.10.0.tgz#dfebe384f1f36faf7782be203a7a71102a6335a6" - integrity sha512-c9amUgpgxSi1bE5/sbLwcs5diLD0ygCQYmhfM5H1s5VH1mCsYkcmAL3CcNdv4kdSw6JuMoHeDGzLgj/gAXdWVg== +dependency-graph@^0.11.0: + version "0.11.0" + resolved "https://registry.yarnpkg.com/dependency-graph/-/dependency-graph-0.11.0.tgz#ac0ce7ed68a54da22165a85e97a01d53f5eb2e27" + integrity sha512-JeMq7fEshyepOWDfcfHK06N3MhyPhz++vtqWhMT5O9A3K42rdsEDpfdVqjaqaAhsw6a+ZqeDvQVtD0hFHQWrzg== -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== +dependency-tree@^8.0.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/dependency-tree/-/dependency-tree-8.1.0.tgz#1b896a0418bd7ba3e6d55c39bb664452a001579f" + integrity sha512-YKFK+1KXJOqVpsW6MkrIl/DyiW+KVG25V8NfRs27ANe+oSeCkQx2ROW1mBpp1bcm++5zj3Xv8wyFxHgX6TbM1w== dependencies: commander "^2.20.3" - debug "^4.2.1" - filing-cabinet "^2.6.0" - precinct "^6.3.1" + debug "^4.3.1" + filing-cabinet "^3.0.0" + precinct "^7.0.0" typescript "^3.9.7" dequal@2.0.2: @@ -2418,17 +2399,17 @@ des.js@^1.0.0: 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== + version "6.1.0" + resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-6.1.0.tgz#592485ebbbf6b3b1ab2be175c8393d04ca0d57e6" + integrity sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA== -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== +detective-amd@^3.0.1: + version "3.1.0" + resolved "https://registry.yarnpkg.com/detective-amd/-/detective-amd-3.1.0.tgz#92daee3214a0ca4522646cf333cac90a3fca6373" + integrity sha512-G7wGWT6f0VErjUkE2utCm7IUshT7nBh7aBBH2VBOiY9Dqy2DMens5iiOvYCuhstoIxRKLrnOvVAz4/EyPIAjnw== dependencies: ast-module-types "^2.7.0" - escodegen "^1.8.0" + escodegen "^2.0.0" get-amd-module-type "^3.0.0" node-source-walk "^4.0.0" @@ -2440,7 +2421,7 @@ detective-cjs@^3.1.1: ast-module-types "^2.4.0" node-source-walk "^4.0.0" -detective-es6@^2.1.0: +detective-es6@^2.1.0, detective-es6@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/detective-es6/-/detective-es6-2.2.0.tgz#8f2baba3f8cd90a5cfd748f5ac436f0158ed2585" integrity sha512-fSpNY0SLER7/sVgQZ1NxJPwmc9uCTzNgdkQDhAaj8NPYwr7Qji9QBcmbNvtMCnuuOGMuKn3O7jv0An+/WRWJZQ== @@ -2456,15 +2437,15 @@ detective-less@^1.0.2: 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== +detective-postcss@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/detective-postcss/-/detective-postcss-4.0.0.tgz#24e69b465e5fefe7a6afd05f7e894e34595dbf51" + integrity sha512-Fwc/g9VcrowODIAeKRWZfVA/EufxYL7XfuqJQFroBKGikKX83d2G7NFw6kDlSYGG3LNQIyVa+eWv1mqre+v4+A== dependencies: debug "^4.1.1" is-url "^1.2.4" - postcss "^7.0.2" - postcss-values-parser "^1.5.0" + postcss "^8.1.7" + postcss-values-parser "^2.0.1" detective-sass@^3.0.1: version "3.0.1" @@ -2489,15 +2470,25 @@ detective-stylus@^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== +detective-typescript@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/detective-typescript/-/detective-typescript-6.0.0.tgz#394062118d7c7da53425647ca41e0081169aa2b3" + integrity sha512-vTidcSDK3QostdbrH2Rwf9FhvrgJ4oIaVw5jbolgruTejexk6nNa9DShGpuS8CFVDb1IP86jct5BaZt1wSxpkA== dependencies: - "@typescript-eslint/typescript-estree" "^2.29.0" - ast-module-types "^2.6.0" + "@typescript-eslint/typescript-estree" "^4.8.2" + ast-module-types "^2.7.1" node-source-walk "^4.2.0" - typescript "^3.8.3" + typescript "^3.9.7" + +detective-typescript@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/detective-typescript/-/detective-typescript-7.0.0.tgz#8c8917f2e51d9e4ee49821abf759ff512dd897f2" + integrity sha512-y/Ev98AleGvl43YKTNcA2Q+lyFmsmCfTTNWy4cjEJxoLkbobcXtRS0Kvx06daCgr2GdtlwLfNzL553BkktfJoA== + dependencies: + "@typescript-eslint/typescript-estree" "^4.8.2" + ast-module-types "^2.7.1" + node-source-walk "^4.2.0" + typescript "^3.9.7" detective@^5.2.0: version "5.2.0" @@ -2508,13 +2499,6 @@ detective@^5.2.0: 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" - didyoumean@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/didyoumean/-/didyoumean-1.2.1.tgz#e92edfdada6537d484d73c0172fd1eba0c4976ff" @@ -2551,7 +2535,7 @@ domain-browser@^1.1.1: resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.2.0.tgz#3d31f50191a6749dd1375a7f522e823d42e54eda" integrity sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA== -dot-case@^3.0.3: +dot-case@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/dot-case/-/dot-case-3.0.4.tgz#9b2b670d00a431667a8a75ba29cd1b98809ce751" integrity sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w== @@ -2568,9 +2552,9 @@ dot-object@^2.1.4: glob "^7.1.5" 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== + version "8.6.0" + resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-8.6.0.tgz#061af664d19f7f4d8fc6e4ff9b584ce237adcb8b" + integrity sha512-IrPdXQsk2BbzvCBGBOTmmSH5SodmqZNt4ERAZDmW4CT+tL8VtvinqywuANaFu4bOMWki16nqf0e4oC0QIaDr/g== duplexer3@^0.1.4: version "0.1.4" @@ -2589,10 +2573,10 @@ ecdsa-sig-formatter@1.0.11: dependencies: safe-buffer "^5.0.1" -electron-to-chromium@^1.3.634, electron-to-chromium@^1.3.649: - version "1.3.663" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.663.tgz#dd54adfd8d7f0e01b80d236c6e232efbaa0c686c" - integrity sha512-xkVkzHj6k3oRRGlmdgUCCLSLhtFYHDCTH7SeK+LJdJjnsLcrdbpr8EYmfMQhez3V/KPO5UScSpzQ0feYX6Qoyw== +electron-to-chromium@^1.3.634, electron-to-chromium@^1.3.723: + version "1.3.749" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.749.tgz#0ecebc529ceb49dd2a7c838ae425236644c3439a" + integrity sha512-F+v2zxZgw/fMwPz/VUGIggG4ZndDsYy0vlpthi3tjmDZlcfbhN5mYW0evXUsBr2sUtuDANFtle410A9u/sd/4A== elegant-spinner@^1.0.1: version "1.0.1" @@ -2639,7 +2623,7 @@ end-of-stream@^1.1.0: dependencies: once "^1.4.0" -enhanced-resolve@^4.0.0, enhanced-resolve@^4.1.0: +enhanced-resolve@^4.0.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== @@ -2648,6 +2632,14 @@ enhanced-resolve@^4.0.0, enhanced-resolve@^4.1.0: memory-fs "^0.5.0" tapable "^1.0.0" +enhanced-resolve@^5.3.2: + version "5.8.2" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.8.2.tgz#15ddc779345cbb73e97c611cd00c01c1e7bf4d8b" + integrity sha512-F27oB3WuHDzvR2DOGNTaYy0D5o0cnrv8TeI482VM4kYgQd/FT9lUQwuNsJ0oOHtBUq7eiW5ytqzp7nBFknL+GA== + 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" @@ -2670,24 +2662,26 @@ error-ex@^1.3.1: is-arrayish "^0.2.1" es-abstract@^1.18.0-next.1: - version "1.18.0-next.2" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.18.0-next.2.tgz#088101a55f0541f595e7e057199e27ddc8f3a5c2" - integrity sha512-Ih4ZMFHEtZupnUh6497zEL4y2+w8+1ljnCyaTa+adcoafI1GOvMwFlDjBLfWR7y9VLfrjRJe9ocuHY1PSR9jjw== + version "1.18.3" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.18.3.tgz#25c4c3380a27aa203c44b2b685bba94da31b63e0" + integrity sha512-nQIr12dxV7SSxE6r6f1l3DtAeEYdsGpps13dR0TwJg1S8gyp4ZPgy3FZcHBgbiQqnoqSTb+oC+kO4UQ0C/J8vw== dependencies: call-bind "^1.0.2" es-to-primitive "^1.2.1" function-bind "^1.1.1" - get-intrinsic "^1.0.2" + get-intrinsic "^1.1.1" has "^1.0.3" - has-symbols "^1.0.1" - is-callable "^1.2.2" + has-symbols "^1.0.2" + is-callable "^1.2.3" is-negative-zero "^2.0.1" - is-regex "^1.1.1" - object-inspect "^1.9.0" + is-regex "^1.1.3" + is-string "^1.0.6" + object-inspect "^1.10.3" object-keys "^1.1.1" object.assign "^4.1.2" - string.prototype.trimend "^1.0.3" - string.prototype.trimstart "^1.0.3" + string.prototype.trimend "^1.0.4" + string.prototype.trimstart "^1.0.4" + unbox-primitive "^1.0.1" es-to-primitive@^1.2.1: version "1.2.1" @@ -2713,32 +2707,32 @@ escape-string-regexp@^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" - integrity sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw== +escodegen@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-2.0.0.tgz#5e32b12833e8aa8fa35e1bf0befa89380484c7dd" + integrity sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw== dependencies: esprima "^4.0.1" - estraverse "^4.2.0" + estraverse "^5.2.0" esutils "^2.0.2" optionator "^0.8.1" optionalDependencies: source-map "~0.6.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== +eslint-visitor-keys@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz#f65328259305927392c938ed44eb0a5c9b2bd303" + integrity sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw== 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== -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" @@ -2750,17 +2744,20 @@ etag@1.8.1: resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc= -events@^3.0.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/events/-/events-3.2.0.tgz#93b87c18f8efcd4202a461aec4dfc0556b639379" - integrity sha512-/46HWwbfCX2xTawVfkKLGxMifJYQBWMwY1mjywRtb4c9x8l5NP3KoJtnIOiL1hfdRkIuYhETxQlo62IF8tcnlg== +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== -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" +eventemitter3@^3.1.0: + version "3.1.2" + resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-3.1.2.tgz#2d3d48f9c346698fce83a85d7d664e98535df6e7" + integrity sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q== + +events@^3.0.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" + integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3: version "1.0.3" @@ -2770,19 +2767,19 @@ evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3: md5.js "^1.3.4" safe-buffer "^5.1.1" -execa@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/execa/-/execa-4.1.0.tgz#4e5491ad1572f2f17a77d388c6c857135b22847a" - integrity sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA== +execa@^5.0.0: + version "5.1.1" + resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" + integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg== dependencies: - cross-spawn "^7.0.0" - get-stream "^5.0.0" - human-signals "^1.1.1" + cross-spawn "^7.0.3" + get-stream "^6.0.0" + human-signals "^2.1.0" is-stream "^2.0.0" merge-stream "^2.0.0" - npm-run-path "^4.0.0" - onetime "^5.1.0" - signal-exit "^3.0.2" + npm-run-path "^4.0.1" + onetime "^5.1.2" + signal-exit "^3.0.3" strip-final-newline "^2.0.0" external-editor@^3.0.3: @@ -2799,11 +2796,6 @@ extract-files@9.0.0, extract-files@^9.0.0: resolved "https://registry.yarnpkg.com/extract-files/-/extract-files-9.0.0.tgz#8a7744f2437f81f5ed3250ed9f1550de902fe54a" integrity sha512-CvdFfHkC95B4bBBk36hcEmvdR2awOdhhVUYH6S/zrVj3477zven/fJMYg7121h4T1xHZC+tetUpubpAhxwI7hQ== -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, fast-glob@^3.2.5: version "3.2.5" resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.5.tgz#7939af2a656de79a4f1901903ee8adcaa7cb9661" @@ -2816,20 +2808,15 @@ fast-glob@^3.1.1, fast-glob@^3.2.5: 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.1" - resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.10.1.tgz#8b8f2ac8bf3632d67afcd65dac248d5fdc45385e" - integrity sha512-AWuv6Ery3pM+dY7LYS8YIaCiQvUaos9OB1RyNgaOWnaX+Tik7Onvcsf8x8c+YtDeT0maYLniBip2hox5KtEXXA== + version "1.11.0" + resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.11.0.tgz#bb9fb955a07130a918eb63c1f5161cc32a5d0858" + integrity sha512-7Eczs8gIPDrVzT+EksYBcupqMyxSHXXrHOLRRxU2/DicV8789MRBRR8+Hc2uWzUupOs4YS4JzBmBxjjCVBxD/g== dependencies: reusify "^1.0.4" @@ -2873,36 +2860,31 @@ figures@^2.0.0: dependencies: escape-string-regexp "^1.0.5" -figures@^3.0.0, figures@^3.2.0: +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== +filing-cabinet@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/filing-cabinet/-/filing-cabinet-3.0.0.tgz#08f9ceec5134f4a662926dd45b8a26eca1b5f622" + integrity sha512-o8Qac5qxZ1uVidR4Sd7ZQbbqObFZlqXU4xu1suAYg9PQPcQFNTzOmxQa/MehIDMgIvXHTb42mWPNV9l3eHBPSw== dependencies: app-module-path "^2.2.0" - commander "^2.13.0" - debug "^4.1.1" - decomment "^0.9.2" - enhanced-resolve "^4.1.0" + commander "^2.20.3" + debug "^4.3.1" + decomment "^0.9.3" + enhanced-resolve "^5.3.2" is-relative-path "^1.0.2" - module-definition "^3.0.0" - module-lookup-amd "^6.1.0" - resolve "^1.11.1" + module-definition "^3.3.1" + module-lookup-amd "^7.0.0" + resolve "^1.19.0" resolve-dependency-path "^2.0.0" sass-lookup "^3.0.0" stylus-lookup "^3.0.1" - typescript "^3.0.3" + typescript "^3.9.7" fill-range@^7.0.1: version "7.0.1" @@ -2928,60 +2910,33 @@ find-up@^4.0.0, find-up@^4.1.0: 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-versions@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/find-versions/-/find-versions-4.0.0.tgz#3c57e573bf97769b8cb8df16934b627915da4965" - integrity sha512-wgpWy002tA+wgmO27buH/9KzyEOQnKsG/R0yrcjPT9BOFm0zRBVQbZ95nRGXWMywS8YR5knRbpohio0bcJABxQ== - dependencies: - semver-regex "^3.1.2" - -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== -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== +form-data@4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452" + integrity sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww== dependencies: asynckit "^0.4.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== +form-data@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-3.0.1.tgz#ebd53791b78356a99af9a300d4282c4d5eb9755f" + integrity sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.8" + 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== +fraction.js@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/fraction.js/-/fraction.js-4.1.1.tgz#ac4e520473dae67012d618aab91eda09bcb400ff" + integrity sha512-MHOhvvxHTfRFpF1geTK9czMIZ6xclsEor2wkIGYYq+PxcQqT7vStJqjhe6S1TenZrMZzo+wlqOufBDVepUEgPg== fs-extra@^9.1.0: version "9.1.0" @@ -3008,7 +2963,7 @@ function-bind@^1.1.1: resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== -gensync@^1.0.0-beta.1: +gensync@^1.0.0-beta.2: 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== @@ -3026,7 +2981,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.2: +get-intrinsic@^1.0.2, get-intrinsic@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.1.tgz#15f59f376f855c446963948f0d24cd3637b4abc6" integrity sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q== @@ -3054,17 +3009,37 @@ get-stream@^4.1.0: dependencies: pump "^3.0.0" -get-stream@^5.0.0, get-stream@^5.1.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" +get-stream@^6.0.0: + version "6.0.1" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" + integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== + +glob-base@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/glob-base/-/glob-base-0.3.0.tgz#dbb164f6221b1c0b1ccf82aea328b497df0ea3c4" + integrity sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q= + dependencies: + glob-parent "^2.0.0" + is-glob "^2.0.0" + +glob-parent@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-2.0.0.tgz#81383d72db054fcccf5336daa902f182f6edbb28" + integrity sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg= + dependencies: + is-glob "^2.0.0" + 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== + version "5.1.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" + integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== dependencies: is-glob "^4.0.1" @@ -3074,9 +3049,9 @@ glob-to-regexp@^0.4.1: integrity sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw== 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== + version "7.1.7" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.7.tgz#3b193e9233f01d42d0b3f78294bbeeb418f94a90" + integrity sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ== dependencies: fs.realpath "^1.0.0" inflight "^1.0.4" @@ -3090,10 +3065,10 @@ globals@^11.1.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== +globby@11.0.3, globby@^11.0.3: + version "11.0.3" + resolved "https://registry.yarnpkg.com/globby/-/globby-11.0.3.tgz#9b1f0cb523e171dd1ad8c7b2a9fb4b644b9593cb" + integrity sha512-ffdmosjA807y7+lA1NM0jELARVmYul/715xiILEjo3hBLPTcirgQNnXECn5g3mtR8TOLCVbkfua1Hpen25/Xcg== dependencies: array-union "^2.1.0" dir-glob "^3.0.1" @@ -3126,15 +3101,15 @@ 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.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.4: version "4.2.6" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.6.tgz#ff040b2b0853b23c3d31027523706f1885d76bee" integrity sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ== -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== +graphql-config@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/graphql-config/-/graphql-config-3.3.0.tgz#24c3672a427cb67c0c717ca3b9d70e9f0c9e752b" + integrity sha512-mSQIsPMssr7QrgqhnjI+CyVH6oQgCrgS6irHsTvwf7RFDRnR2k9kqpQOQgVoOytBSn0DOYryS0w0SAg9xor/Jw== dependencies: "@endemolshinegroup/cosmiconfig-typescript-loader" "3.0.2" "@graphql-tools/graphql-file-loader" "^6.0.0" @@ -3142,12 +3117,11 @@ graphql-config@^3.2.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" + "@graphql-tools/utils" "^7.0.0" + cosmiconfig "7.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" @@ -3159,27 +3133,18 @@ graphql-request@^3.3.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== + version "2.12.4" + resolved "https://registry.yarnpkg.com/graphql-tag/-/graphql-tag-2.12.4.tgz#d34066688a4f09e72d6f4663c74211e9b4b7c4bf" + integrity sha512-VV1U4O+9x99EkNpNmCUV5RZwq6MnK4+pGbRYWG+lA/m3uo7TSqJF81OkcOP148gFP6fzdl7JWYBrwWVTS9jXww== dependencies: - busboy "^0.3.1" - fs-capacitor "^6.1.0" - http-errors "^1.7.3" - isobject "^4.0.0" - object-path "^0.11.4" + tslib "^2.1.0" -graphql-ws@4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/graphql-ws/-/graphql-ws-4.1.0.tgz#cebe281474b5501d7be66210fb5711633b27fd78" - integrity sha512-DxJP1y2YzCqVLy7DrQN0iuR2l48vMOBWukX2d/J9aN2o5x9un5psIIq/2UFRh91UGARmfvPH86y1p4qbC1dITg== +graphql-ws@^4.4.1: + version "4.8.0" + resolved "https://registry.yarnpkg.com/graphql-ws/-/graphql-ws-4.8.0.tgz#4b0a82fa1ad00a3baa1cae980032dcaaad08b339" + integrity sha512-0jk0c7GPfAlQfA7xZ4CKlLvFF4JBPYbczIHIXl/tk/fXoCLzmrmwQ/HNwOoOHfFMS3usbD1nt77k67pgXx2BYQ== -graphql@^15.4.0: +graphql@^15.5.0: version "15.5.0" resolved "https://registry.yarnpkg.com/graphql/-/graphql-15.5.0.tgz#39d19494dbe69d1ea719915b578bf920344a69d5" integrity sha512-OmaM7y0kaK31NKG31q4YbD2beNYa6jBBKtMFT6gLYJljHLJr42IqJ8KX08u3Li/0ifzTU5HjmoOOrwa5BRLeDA== @@ -3198,11 +3163,6 @@ gzip-size@^6.0.0: dependencies: duplexer "^0.1.2" -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" @@ -3210,6 +3170,11 @@ has-ansi@^2.0.0: dependencies: ansi-regex "^2.0.0" +has-bigints@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.1.tgz#64fe6acb020673e3b78db035a5af69aa9d07b113" + integrity sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA== + has-flag@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" @@ -3220,10 +3185,10 @@ has-flag@^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-symbols@^1.0.1, has-symbols@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.2.tgz#165d3070c00309752a1236a479331e3ac56f1423" + integrity sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw== has@^1.0.3: version "1.0.3" @@ -3254,6 +3219,14 @@ he@1.2.0: resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== +header-case@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/header-case/-/header-case-2.0.4.tgz#5a42e63b55177349cf405beb8d775acabb92c063" + integrity sha512-H/vuk5TEEVZwrR0lp2zed9OCo1uAILMlx0JEMgC26rzyJJ3N1v6XkwHHXJQdR2doSjcGPM6OKPYoJgf0plJ11Q== + dependencies: + capital-case "^1.0.4" + tslib "^2.0.3" + hmac-drbg@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" @@ -3263,11 +3236,6 @@ hmac-drbg@^1.0.1: 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" @@ -3289,17 +3257,6 @@ http-errors@1.7.3: 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" @@ -3322,10 +3279,10 @@ https-proxy-agent@^5.0.0: agent-base "6" debug "4" -human-signals@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-1.1.1.tgz#c5b1cd14f50aeae09ab6c59fe63ba3395fe4dfa3" - integrity sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw== +human-signals@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" + integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== humanize-ms@^1.2.1: version "1.2.1" @@ -3334,21 +3291,10 @@ humanize-ms@^1.2.1: dependencies: ms "^2.0.0" -husky@^4.3.8: - version "4.3.8" - resolved "https://registry.yarnpkg.com/husky/-/husky-4.3.8.tgz#31144060be963fd6850e5cc8f019a1dfe194296d" - integrity sha512-LCqqsB0PzJQ/AlCgfrfzRe3e3+NvmefAdKQhRYpxS4u6clblBoDdzzvHi8fmxKRzvMxPY/1WZWzomPZww0Anow== - dependencies: - chalk "^4.0.0" - ci-info "^2.0.0" - compare-versions "^3.6.0" - cosmiconfig "^7.0.0" - find-versions "^4.0.0" - opencollective-postinstall "^2.0.2" - pkg-dir "^5.0.0" - please-upgrade-node "^3.2.0" - slash "^3.0.0" - which-pm-runs "^1.0.0" +husky@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/husky/-/husky-6.0.0.tgz#810f11869adf51604c32ea577edbc377d7f9319e" + integrity sha512-SQS2gDTB7tBN486QSoKPKQItZw97BMOd+Kdb6ghfpBc0yXyzrddI0oDV5MkDAbuB4X2mO3/nj60TRMcYxwzZeQ== iconv-lite@0.4.24, iconv-lite@^0.4.24: version "0.4.24" @@ -3377,7 +3323,7 @@ immutable@~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: +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== @@ -3472,6 +3418,11 @@ is-arrayish@^0.3.1: resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.3.2.tgz#4574a2ae56f7ab206896fb431eaeed066fdf8f03" integrity sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ== +is-bigint@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.0.2.tgz#ffb381442503235ad245ea89e45b3dbff040ee5a" + integrity sha512-0JV5+SOCQkIdzjBK9buARcV804Ddu7A0Qet6sHi3FimE9ne6m4BGQZfRn+NZiXbBk4F4XmHfDZIipLj9pX8dSA== + 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" @@ -3479,22 +3430,39 @@ is-binary-path@~2.1.0: dependencies: binary-extensions "^2.0.0" -is-callable@^1.1.4, is-callable@^1.2.2: +is-boolean-object@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.1.1.tgz#3c0878f035cb821228d350d2e1e36719716a3de8" + integrity sha512-bXdQWkECBUIAcCkeH1unwJLIpZYaa5VvuygSyS/c2lf719mTKZDU5UdDRlpd01UjADgmW8RfqaP+mRaVPdr/Ng== + dependencies: + call-bind "^1.0.2" + +is-callable@^1.1.4, is-callable@^1.2.3: version "1.2.3" resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.3.tgz#8b1e0500b73a1d76c70487636f368e519de8db8e" integrity sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ== is-core-module@^2.2.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== + version "2.4.0" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.4.0.tgz#8e9fc8e15027b011418026e98f0e6f4d86305cc1" + integrity sha512-6A2fkfq1rfeQZjxrZJGerpLCTHRNEBiSgnu0+obeJpEPZRUooHgsizvzv0ZjJwOz3iWIHdJtVWJ/tmPr3D21/A== 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== + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.4.tgz#550cfcc03afada05eea3dd30981c7b09551f73e5" + integrity sha512-/b4ZVsG7Z5XVtIxs/h9W8nvfLgSAyKYdtGWQLbqy6jA1icmgjf8WCoTKgeS4wy5tYaPePouzFMANbnj94c2Z+A== + +is-dotfile@^1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/is-dotfile/-/is-dotfile-1.0.3.tgz#a6a2f32ffd2dfb04f5ca25ecd0f6b83cf798a1e1" + integrity sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE= + +is-extglob@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-1.0.0.tgz#ac468177c4943405a092fc8f29760c6ffc6206c0" + integrity sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA= is-extglob@^2.1.1: version "2.1.1" @@ -3525,16 +3493,35 @@ is-glob@4.0.1, is-glob@^4.0.1, is-glob@~4.0.1: dependencies: is-extglob "^2.1.1" +is-glob@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-2.0.1.tgz#d096f926a3ded5600f3fdfd91198cb0888c2d863" + integrity sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM= + dependencies: + is-extglob "^1.0.0" + 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-lower-case@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/is-lower-case/-/is-lower-case-2.0.2.tgz#1c0884d3012c841556243483aa5d522f47396d2a" + integrity sha512-bVcMJy4X5Og6VZfdOZstSexlEy20Sr0k/p/b2IlQJlfdKAQuMpiv5w2Ccxb8sKdRUNAG1PnHVHjFSdRDVS6NlQ== + dependencies: + tslib "^2.0.3" + is-negative-zero@^2.0.1: 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-object@^1.0.4: + version "1.0.5" + resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.5.tgz#6edfaeed7950cff19afedce9fbfca9ee6dd289eb" + integrity sha512-RU0lI/n95pMoUKu9v1BZP5MBcZuNSVJkMkAG2dJqC4z2GlkGUNeH68SuHuBKBD/XFe+LHZ+f9BKkLET60Niedw== + is-number@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" @@ -3552,11 +3539,6 @@ is-observable@^1.1.0: 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" @@ -3567,13 +3549,13 @@ is-promise@^2.1.0: 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.2" - resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.2.tgz#81c8ebde4db142f2cf1c53fc86d6a45788266251" - integrity sha512-axvdhb5pdhEVThqJzYXwMlVuZwC+FF2DpcOhTS+y/8jVq4trxyPgfcwIxIKiyeuLlSQYKkmUaPQJ8ZE4yNKXDg== +is-regex@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.3.tgz#d029f9aff6448b93ebbe3f33dac71511fdcbef9f" + integrity sha512-qSVXFz28HM7y+IWX6vLCsexdlvzT1PJNFSBuaQLQ5o0IEw8UDYW6/2+eCMVyIsbM8CNLX2a/QWmSpyxYEHY7CQ== dependencies: call-bind "^1.0.2" - has-symbols "^1.0.1" + has-symbols "^1.0.2" is-regexp@^1.0.0: version "1.0.0" @@ -3602,12 +3584,17 @@ is-stream@^2.0.0: resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.0.tgz#bde9c32680d6fae04129d6ac9d921ce7815f78e3" integrity sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw== -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== +is-string@^1.0.5, is-string@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.6.tgz#3fe5d5992fb0d93404f32584d4b0179a71b54a5f" + integrity sha512-2gdzbKUuqtQ3lYNrUTQYoClPhm7oQu4UdpSZMp1/DGgkHBT8E2Z1l0yMdb6D4zNAxwDiMv8MdulKROJGNl0Q0w== + +is-symbol@^1.0.2, is-symbol@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.4.tgz#a6dac93b635b063ca6872236de88910a57af139c" + integrity sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg== dependencies: - has-symbols "^1.0.1" + has-symbols "^1.0.2" is-unc-path@^1.0.0: version "1.0.0" @@ -3616,6 +3603,18 @@ is-unc-path@^1.0.0: dependencies: unc-path-regex "^0.1.2" +is-unicode-supported@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7" + integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== + +is-upper-case@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/is-upper-case/-/is-upper-case-2.0.2.tgz#f1105ced1fe4de906a5f39553e7d3803fd804649" + integrity sha512-44pxmxAvnnAOwBg4tHPnkfvgjPwbc5QIsSstNU+YcJ1ovxVzCWpSGosPJOZh/a1tdl81fbgnLc9LLv+x2ywbPQ== + dependencies: + tslib "^2.0.3" + is-url@^1.2.4: version "1.2.4" resolved "https://registry.yarnpkg.com/is-url/-/is-url-1.2.4.tgz#04a4df46d28c4cff3d73d01ff06abeb318a1aa52" @@ -3643,11 +3642,6 @@ isobject@^2.0.0: 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, isomorphic-fetch@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/isomorphic-fetch/-/isomorphic-fetch-3.0.0.tgz#0267b005049046d2421207215d45d6a262b8b8b4" @@ -3656,18 +3650,16 @@ isomorphic-fetch@3.0.0, isomorphic-fetch@^3.0.0: 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== +iterall@^1.2.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/iterall/-/iterall-1.3.0.tgz#afcb08492e2915cbd8a0884eb93a8c94d0d72fea" + integrity sha512-QZ9qOMdF+QLHxy1QIpUHUU1D5pS2CG2P69LF6L6CPjPYA/XMOmKV3PZpawHoAjHNyB0swdVTRxdYT4tbBbxqwg== + jest-worker@24.9.0: version "24.9.0" resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-24.9.0.tgz#5dbfdb5b2d322e98567898238a9697bcce67b3e5" @@ -3686,13 +3678,12 @@ js-cookie@^2.2.1: 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== +js-yaml@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" + integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== dependencies: - argparse "^1.0.7" - esprima "^4.0.0" + argparse "^2.0.1" jsesc@^2.5.1: version "2.5.2" @@ -3709,11 +3700,6 @@ json-parse-even-better-errors@^2.3.0: 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-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" @@ -3790,10 +3776,10 @@ jws@^3.2.2: jwa "^1.4.1" safe-buffer "^5.0.1" -keen-slider@^5.2.4: - version "5.4.0" - resolved "https://registry.yarnpkg.com/keen-slider/-/keen-slider-5.4.0.tgz#e5a949e2bb237d7d6b068458dcda59ae9c415254" - integrity sha512-gN+lYpaj4vgJr0fIKtJVy/xG2CnjHiY4lixllp32x6LW8QlT1gD4qmzclFBwMn1/LPvnM2UhOFSgAOmBIhPtAQ== +keen-slider@^5.4.1: + version "5.4.1" + resolved "https://registry.yarnpkg.com/keen-slider/-/keen-slider-5.4.1.tgz#a6444b8afd28da1d15d7f769d531c2e00414bde0" + integrity sha512-CRBQDs7sQRxDRdQbHECuV2+IETD6UGp1bqnyNlbGM4trW9ObUTY39DWl/dLGh91x8qEepkCiYAO+w0B9gjEtkg== keyv@^3.0.0: version "3.1.0" @@ -3802,11 +3788,6 @@ keyv@^3.0.0: 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== - latest-version@5.1.0: version "5.1.0" resolved "https://registry.yarnpkg.com/latest-version/-/latest-version-5.1.0.tgz#119dfe908fe38d15dfa43ecd13fa12ec8832face" @@ -3835,22 +3816,22 @@ lines-and-columns@^1.1.6: resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.1.6.tgz#1c00c743b433cd0a4e80758f7b64a57440d9ff00" integrity sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA= -lint-staged@^10.5.3: - version "10.5.4" - resolved "https://registry.yarnpkg.com/lint-staged/-/lint-staged-10.5.4.tgz#cd153b5f0987d2371fc1d2847a409a2fe705b665" - integrity sha512-EechC3DdFic/TdOPgj/RB3FicqE6932LTHCUm0Y2fsD9KGlLB+RwJl2q1IYBIvEsKzDOgn0D4gll+YxG5RsrKg== +lint-staged@^11.0.0: + version "11.0.0" + resolved "https://registry.yarnpkg.com/lint-staged/-/lint-staged-11.0.0.tgz#24d0a95aa316ba28e257f5c4613369a75a10c712" + integrity sha512-3rsRIoyaE8IphSUtO1RVTFl1e0SLBtxxUOPBtHxQgBHS5/i6nqvjcUfNioMa4BU9yGnPzbO+xkfLtXtxBpCzjw== dependencies: - chalk "^4.1.0" + chalk "^4.1.1" cli-truncate "^2.1.0" - commander "^6.2.0" + commander "^7.2.0" cosmiconfig "^7.0.0" - debug "^4.2.0" + debug "^4.3.1" dedent "^0.7.0" enquirer "^2.3.6" - execa "^4.1.0" - listr2 "^3.2.2" - log-symbols "^4.0.0" - micromatch "^4.0.2" + execa "^5.0.0" + listr2 "^3.8.2" + log-symbols "^4.1.0" + micromatch "^4.0.4" normalize-path "^3.0.0" please-upgrade-node "^3.2.0" string-argv "0.3.1" @@ -3885,18 +3866,16 @@ listr-verbose-renderer@^0.5.0: date-fns "^1.27.2" figures "^2.0.0" -listr2@^3.2.2: - version "3.3.1" - resolved "https://registry.yarnpkg.com/listr2/-/listr2-3.3.1.tgz#87b57cc0b8541fa794b814c8bcb76f1211cfbf5c" - integrity sha512-8Zoxe7s/8nNr4bJ8bdAduHD8uJce+exmMmUWTXlq0WuUdffnH3muisHPHPFtW2vvOfohIsq7FGCaguUxN/h3Iw== +listr2@^3.8.2: + version "3.9.0" + resolved "https://registry.yarnpkg.com/listr2/-/listr2-3.9.0.tgz#27f23c91ba4fdf513b0682bf604bc6b0ab36b6c1" + integrity sha512-+JxQt7Vi4WEWgJsxmOEX9lDbCumrb3mrEYIeE1VI7I4lf2rXE4v9pq3RMVNp+a9s6mCgc/IsF0ppHsLrx2BEAw== dependencies: - chalk "^4.1.0" cli-truncate "^2.1.0" - figures "^3.2.0" - indent-string "^4.0.0" + colorette "^1.2.2" log-update "^4.0.0" p-map "^4.0.0" - rxjs "^6.6.3" + rxjs "^6.6.7" through "^2.3.8" wrap-ansi "^7.0.0" @@ -3940,18 +3919,6 @@ locate-path@^5.0.0: 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" @@ -4027,21 +3994,6 @@ lodash.sortby@^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" @@ -4062,16 +4014,11 @@ lodash.uniq@^4.5.0: resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M= -lodash@4.17.21, lodash@^4.17.21: +lodash@4.17.21, lodash@^4.17.13, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.21, lodash@~4.17.0: 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" - 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" @@ -4079,12 +4026,13 @@ log-symbols@^1.0.2: 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== +log-symbols@^4.0.0, log-symbols@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.1.0.tgz#3fbdbb95b4683ac9fc785111e792e558d4abd503" + integrity sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg== dependencies: - chalk "^4.0.0" + chalk "^4.1.0" + is-unicode-supported "^0.1.0" log-update@^2.3.0: version "2.3.0" @@ -4112,14 +4060,14 @@ loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.4.0: 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== +lower-case-first@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/lower-case-first/-/lower-case-first-2.0.2.tgz#64c2324a2250bf7c37c5901e76a5b5309301160b" + integrity sha512-EVm/rR94FJTZi3zefZ82fLWab+GX14LJN4HrWBcuo6Evmsl9hEfnqxgcHCKb9q+mNf6EVdsjx/qucYFIIB84pg== dependencies: - tslib "^1.10.0" + tslib "^2.0.3" -lower-case@^2.0.1, lower-case@^2.0.2: +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== @@ -4150,42 +4098,34 @@ lru-cache@^6.0.0: 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== +madge@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/madge/-/madge-4.0.2.tgz#56a3aff8021a5844f8713e0789f6ee94095f2f41" + integrity sha512-l5bnA2dvyk0azLKDbOTCI+wDZ6nB007PhvPdmiYlPmqwVi49JPbhQrH/t4u8E6Akp3gwji1GZuA+v/F5q6yoWQ== dependencies: chalk "^4.1.0" - commander "^5.1.0" + commander "^6.2.1" commondir "^1.0.1" debug "^4.0.1" - dependency-tree "^7.2.2" - detective-amd "^3.0.0" + dependency-tree "^8.0.0" + detective-amd "^3.0.1" detective-cjs "^3.1.1" detective-es6 "^2.1.0" detective-less "^1.0.2" - detective-postcss "^3.0.1" + detective-postcss "^4.0.0" detective-sass "^3.0.1" detective-scss "^2.0.1" detective-stylus "^1.0.0" - detective-typescript "^5.8.0" + detective-typescript "^7.0.0" graphviz "0.0.9" ora "^5.1.0" pluralize "^8.0.0" - precinct "^6.3.1" + precinct "^7.0.0" pretty-ms "^7.0.0" rc "^1.2.7" typescript "^3.9.5" walkdir "^0.4.1" -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" @@ -4203,16 +4143,6 @@ map-cache@^0.2.0: 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== - matcher@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/matcher/-/matcher-4.0.0.tgz#a42a05a09aaed92e2d241eb91fddac689461ea51" @@ -4237,23 +4167,6 @@ memory-fs@^0.5.0: 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-stream@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" @@ -4264,13 +4177,18 @@ merge2@^1.3.0: 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== +meros@1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/meros/-/meros-1.1.4.tgz#c17994d3133db8b23807f62bec7f0cb276cfd948" + integrity sha512-E9ZXfK9iQfG9s73ars9qvvvbSIkJZF5yOo9j4tcwM5tN8mUKfj/EKN5PzOr3ZH0y5wL7dLAHw3RVEfpQV9Q7VQ== + +micromatch@^4.0.0, micromatch@^4.0.2, micromatch@^4.0.4: + version "4.0.4" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.4.tgz#896d519dfe9db25fce94ceb7a500919bf881ebf9" + integrity sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg== dependencies: braces "^3.0.1" - picomatch "^2.0.5" + picomatch "^2.2.3" miller-rabin@^4.0.0: version "4.0.1" @@ -4280,22 +4198,22 @@ miller-rabin@^4.0.0: 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-db@1.48.0: + version "1.48.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.48.0.tgz#e35b31045dd7eada3aaad537ed88a33afbef2d1d" + integrity sha512-FM3QwxV+TnZYQ2aRqhlKBMHxk10lTbMt3bBkMAp54ddrNeVSfcQYOOKuGuy3Ddrm38I04If834fOUSq1yzslJQ== 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== + version "2.1.31" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.31.tgz#a00d76b74317c61f9c2db2218b8e9f8e9c5c9e6b" + integrity sha512-XGZnNzm3QvgKxa8dpzyhFTHmpP3l5YNusmne07VUOXxou9CqUqYa/HBy124RqtVh/O2pECas/MOcsDgpilPOPg== dependencies: - mime-db "1.45.0" + mime-db "1.48.0" mime@^2.3.1: - version "2.5.0" - resolved "https://registry.yarnpkg.com/mime/-/mime-2.5.0.tgz#2b4af934401779806ee98026bb42e8c1ae1876b1" - integrity sha512-ft3WayFSFUVBuJj7BMLKAQcSlItKtfjsKDDsii3rqFDAZ7t11zRe8ASw/GlmivGwVUYtwkQrxiGGpL6gFvB0ag== + version "2.5.2" + resolved "https://registry.yarnpkg.com/mime/-/mime-2.5.2.tgz#6e3dc6cc2b9510643830e5f19d5cb753da5eeabe" + integrity sha512-tqkh47FzKeCPD2PUiPB6pkbMzsCasjxAfC62/Wap5qrUWcb+sFasXUC5I3gYM5iBM8v/Qpn4UK0x+j0iHyFPDg== mimic-fn@^1.0.0: version "1.2.0" @@ -4312,11 +4230,6 @@ mimic-response@^1.0.0, mimic-response@^1.0.1: resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b" integrity sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ== -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== - 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" @@ -4334,15 +4247,6 @@ minimatch@3.0.4, minimatch@^3.0.4: 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.5: version "1.2.5" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" @@ -4354,11 +4258,11 @@ mkdirp@^1.0.4: integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== modern-normalize@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/modern-normalize/-/modern-normalize-1.0.0.tgz#539d84a1e141338b01b346f3e27396d0ed17601e" - integrity sha512-1lM+BMLGuDfsdwf3rsgBSrxJwAZHFIrQ8YR61xIqdHo0uNKI9M52wNpHSrliZATJp51On6JD0AfRxd4YGSU0lw== + version "1.1.0" + resolved "https://registry.yarnpkg.com/modern-normalize/-/modern-normalize-1.1.0.tgz#da8e80140d9221426bd4f725c6e11283d34f90b7" + integrity sha512-2lMlY1Yc1+CUy0gw4H95uNN7vjbpoED7NNRSBHE25nWfLBdmMzFCsPshlzbxHz+gYMcBEUN8V4pU16prcdPSgA== -module-definition@^3.0.0, module-definition@^3.3.0: +module-definition@^3.3.1: version "3.3.1" resolved "https://registry.yarnpkg.com/module-definition/-/module-definition-3.3.1.tgz#fedef71667713e36988b93d0626a4fe7b35aebfc" integrity sha512-kLidGPwQ2yq484nSD+D3JoJp4Etc0Ox9P0L34Pu/cU4X4HcG7k7p62XI5BBuvURWMRX3RPyuhOcBHbKus+UH4A== @@ -4366,17 +4270,16 @@ module-definition@^3.0.0, module-definition@^3.3.0: 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== +module-lookup-amd@^7.0.0: + version "7.0.1" + resolved "https://registry.yarnpkg.com/module-lookup-amd/-/module-lookup-amd-7.0.1.tgz#d67c1a93f2ff8e38b8774b99a638e9a4395774b2" + integrity sha512-w9mCNlj0S8qviuHzpakaLVc+/7q50jl9a/kmJ/n8bmXQZgDPkQHnPBb8MUOYh3WpAYkXuNc2c+khsozhIp/amQ== dependencies: commander "^2.8.1" debug "^4.1.0" - file-exists-dazinatorfork "^1.0.2" - find "^0.3.0" + glob "^7.1.6" requirejs "^2.3.5" - requirejs-config-file "^3.1.1" + requirejs-config-file "^4.0.0" ms@2.0.0: version "2.0.0" @@ -4398,10 +4301,10 @@ mute-stream@0.0.8: resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d" integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA== -nanoid@^3.1.16, nanoid@^3.1.20: - version "3.1.20" - resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.20.tgz#badc263c6b1dcf14b71efaa85f6ab4c1d6cfc788" - integrity sha512-a1cQNyczgKbLX9jwbS/+d7W8fX/RfgYR7lVWwWOGIPNgK2m0MWvrGF6/m4kk6U3QcFMnZf3RIhL0v2Jgh/0Uxw== +nanoid@^3.1.16, nanoid@^3.1.23: + version "3.1.23" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.23.tgz#f744086ce7c2bc47ee0a8472574d5c78e4183a81" + integrity sha512-FiB0kzdP0FFVGDKlRLEQ1BgDzU87dy5NnzjeW9YZNt+/c3+q82EQDUwniSAUxp/F0gFNI1ZhKU1FqYsMuqZVnw== native-url@0.3.4: version "0.3.4" @@ -4410,25 +4313,26 @@ native-url@0.3.4: dependencies: querystring "^0.2.0" -next-seo@^4.11.0: - version "4.19.0" - resolved "https://registry.yarnpkg.com/next-seo/-/next-seo-4.19.0.tgz#b3be79a544e420dbbf1e4fcff98dad9790f15e36" - integrity sha512-+jgXd1UW0XKLiBMrumjPDANeV82mTHTxGZJwU6T1mlNougKpXINlDgIHkN30sM2eDXh+xXOURj99WN2Tm9K6rg== +next-seo@^4.24.0: + version "4.24.0" + resolved "https://registry.yarnpkg.com/next-seo/-/next-seo-4.24.0.tgz#7c0447da00b8574dcda5c6979771a7f6efd24f55" + integrity sha512-9VQXfXAelhE+hAWzJ4azigQaW3FPX0kU0eYKFQXKsQjgY7AWtukjRGXls0oSIk8khhDJwmCt46EwsO9n5DDW6Q== -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-themes@^0.0.14: + version "0.0.14" + resolved "https://registry.yarnpkg.com/next-themes/-/next-themes-0.0.14.tgz#2b9861990bc453149e23d8e6ef1a25a119e36675" + integrity sha512-x09OaM+wg3SIlEjOv8B21aw/E36jxTtfW3Dm/DPwMsSMluGt7twe1LigA6nc+mXP1u0qu9MxBaIrPPH6UTiKnA== -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== +next-unused@^0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/next-unused/-/next-unused-0.0.6.tgz#dbefa300bf5586e33d5bfde909130fb19ab04a64" + integrity sha512-dHFNNBanFq4wvYrULtsjfWyZ6BzOnr5VYI9EYMGAZYF2vkAhFpj2JOuT5Wu2o3LbFSG92PmAZnSUF/LstF82pA== dependencies: - madge "^3.8.0" + madge "^4.0.1" ts-loader "^7.0.0" + typescript "^4.2.3" -next@^10.0.9-canary.5: +next@10.0.9-canary.5: version "10.0.9-canary.5" resolved "https://registry.yarnpkg.com/next/-/next-10.0.9-canary.5.tgz#969dfb3b4646736db1144fb965d4af3e83fa6ff2" integrity sha512-wIqEpQe9gKxwBZZHQgDGuztNlfv6/opIjf6nFYf7Iimw4SnNprPJWpEKrqF3JVxMoLawI6tafMwsYg1TQNZM7A== @@ -4471,7 +4375,7 @@ next@^10.0.9-canary.5: vm-browserify "1.1.2" watchpack "2.1.1" -no-case@^3.0.3, no-case@^3.0.4: +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== @@ -4532,10 +4436,10 @@ node-libs-browser@^2.2.1: util "^0.11.0" vm-browserify "^1.0.1" -node-releases@^1.1.69, node-releases@^1.1.70: - version "1.1.70" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.70.tgz#66e0ed0273aa65666d7fe78febe7634875426a08" - integrity sha512-Slf2s69+2/uAD79pVVQo8uSiC34+g8GWY8UH2Qtqv34ZfhYrxpYpfzs9Js9d6O0mbDmALuxaTlplnBTnSELcrw== +node-releases@^1.1.69, node-releases@^1.1.71: + version "1.1.72" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.72.tgz#14802ab6b1039a79a0c7d662b610a5bbd76eacbe" + integrity sha512-LLUo+PpH3dU6XizX3iVoubUNheF/owjXCZZ5yACDxNnPtgFuludV1ZL3ayK1kVep42Rmm0+R9/Y60NQbZ2bifw== node-source-walk@^4.0.0, node-source-walk@^4.2.0: version "4.2.0" @@ -4544,16 +4448,6 @@ node-source-walk@^4.0.0, node-source-walk@^4.2.0: dependencies: "@babel/parser" "^7.0.0" -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" @@ -4572,11 +4466,11 @@ normalize-range@^0.1.2: 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== + version "4.5.1" + resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-4.5.1.tgz#0dd90cf1288ee1d1313b87081c9a5932ee48518a" + integrity sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA== -npm-run-path@^4.0.0: +npm-run-path@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== @@ -4604,14 +4498,14 @@ object-assign@^4.1.0, object-assign@^4.1.1: integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= object-hash@^2.1.1: - 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== + version "2.2.0" + resolved "https://registry.yarnpkg.com/object-hash/-/object-hash-2.2.0.tgz#5ad518581eefc443bd763472b8ff2e9c2c0d54a5" + integrity sha512-gScRMn0bS5fH+IuwyIFgnh9zBdo4DV+6GhygmWM9HyNJSgS0hScp1f5vjtm7oIIOiT9trXrShAkLFSc2IqKNgw== -object-inspect@^1.9.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-inspect@^1.10.3: + version "1.10.3" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.10.3.tgz#c2aa7d2d09f50c99375704f7a0adf24c5782d369" + integrity sha512-e5mCJlSH7poANfC8z8S9s9S2IN5/4Zb3aZ33f5s8YqoazCFzNLloLU8r5VCG+G7WoqLvAAZoVMcy3tp/3X0Plw== object-keys-normalizer@1.0.1: version "1.0.1" @@ -4640,11 +4534,6 @@ object-merge-advanced@12.0.3: 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" - integrity sha512-jgSbThcoR/s+XumvGMTMf81QVBmah+/Q7K7YduKeKVWL7N111unR2d6pZZarSk6kY/caeNxUDyxOvMWyzoU2eg== - object.assign@^4.1.0, object.assign@^4.1.2: version "4.1.2" resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.2.tgz#0ed54a342eceb37b38ff76eb831a0e788cb63940" @@ -4669,18 +4558,13 @@ onetime@^2.0.0: dependencies: mimic-fn "^1.0.0" -onetime@^5.1.0: +onetime@^5.1.0, onetime@^5.1.2: 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" -opencollective-postinstall@^2.0.2: - version "2.0.3" - resolved "https://registry.yarnpkg.com/opencollective-postinstall/-/opencollective-postinstall-2.0.3.tgz#7a0fff978f6dbfa4d006238fbac98ed4198c3259" - integrity sha512-8AV/sCtuzUeTo8gQK5qDZzARrulB3egtLzFgteqB2tcT4Mw7B8Kt7JcDHmltjz6FOAHsvTevk70gZEbhM4ZS9Q== - opener@^1.5.2: version "1.5.2" resolved "https://registry.yarnpkg.com/opener/-/opener-1.5.2.tgz#5d37e1f35077b9dcac4301372271afdeb2a13598" @@ -4699,26 +4583,20 @@ optionator@^0.8.1: word-wrap "~1.2.3" ora@^5.1.0: - version "5.3.0" - resolved "https://registry.yarnpkg.com/ora/-/ora-5.3.0.tgz#fb832899d3a1372fe71c8b2c534bbfe74961bb6f" - integrity sha512-zAKMgGXUim0Jyd6CXK9lraBnD3H5yPGBPPOkC23a2BG6hsm4Zu6OQSjQuEtV0BHDf4aKHcUFvJiGRrFuW3MG8g== + version "5.4.0" + resolved "https://registry.yarnpkg.com/ora/-/ora-5.4.0.tgz#42eda4855835b9cd14d33864c97a3c95a3f56bf4" + integrity sha512-1StwyXQGoU6gdjYkyVcqOLnVlbKj+6yPNNOxJVgpt9t4eksKjiriiHuxktLYkgllwk+D6MbC4ihH84L1udRXPg== dependencies: - bl "^4.0.3" + bl "^4.1.0" chalk "^4.1.0" cli-cursor "^3.1.0" cli-spinners "^2.5.0" is-interactive "^1.0.0" - log-symbols "^4.0.0" + is-unicode-supported "^0.1.0" + log-symbols "^4.1.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-browserify@^0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/os-browserify/-/os-browserify-0.3.0.tgz#854373c7f5c2315914fc9bfc6bd8238fdda1ec27" @@ -4734,14 +4612,7 @@ 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: - 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== @@ -4762,13 +4633,6 @@ p-locate@^4.1.0: 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" @@ -4801,13 +4665,13 @@ pako@~1.0.5: resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.11.tgz#6c9599d340d54dfd3946380252a35705a6b992bf" integrity sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw== -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== +param-case@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/param-case/-/param-case-3.0.4.tgz#7d17fe4aa12bde34d4a77d91acfb6219caad01c5" + integrity sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A== dependencies: - dot-case "^3.0.3" - tslib "^1.10.0" + dot-case "^3.0.4" + tslib "^2.0.3" parent-module@^1.0.0: version "1.0.1" @@ -4836,6 +4700,16 @@ parse-filepath@^1.0.2: map-cache "^0.2.0" path-root "^0.1.1" +parse-glob@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/parse-glob/-/parse-glob-3.0.4.tgz#b2c376cfb11f35513badd173ef0bb6e3a388391c" + integrity sha1-ssN2z7EfNVE7rdFz7wu246OIORw= + dependencies: + glob-base "^0.3.0" + is-dotfile "^1.0.0" + is-extglob "^1.0.0" + is-glob "^2.0.0" + parse-json@^5.0.0: version "5.2.0" resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd" @@ -4851,15 +4725,7 @@ parse-ms@^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: +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== @@ -4877,6 +4743,14 @@ path-browserify@1.0.1: resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-1.0.1.tgz#d98454a9c3753d5790860f16f68867b9e46be1fd" integrity sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g== +path-case@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/path-case/-/path-case-3.0.4.tgz#9168645334eb942658375c56f80b4c0cb5f82c6f" + integrity sha512-qO4qCFjXqVTrcbPt/hQfhTQ+VhFsqNKOPtytgNKkKxSoEp3XPUQ8ObFuePylOIok5gjn69ry8XiULxCwot3Wfg== + dependencies: + dot-case "^3.0.4" + tslib "^2.0.3" + path-exists@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" @@ -4893,9 +4767,9 @@ path-key@^3.0.0, path-key@^3.1.0: integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== 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== + version "1.0.7" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" + integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== path-root-regex@^0.1.0: version "0.1.2" @@ -4915,9 +4789,9 @@ path-type@^4.0.0: 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== + version "3.1.2" + resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.1.2.tgz#dd822aa0887580e52f1a039dc3eda108efae3075" + integrity sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA== dependencies: create-hash "^1.1.2" create-hmac "^1.1.4" @@ -4925,15 +4799,10 @@ pbkdf2@^3.0.3: safe-buffer "^5.0.1" sha.js "^2.4.8" -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== +picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.3: + version "2.3.0" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.0.tgz#f1f061de8f6a4bf022892e2d128234fb98302972" + integrity sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw== pkg-dir@^4.1.0: version "4.2.0" @@ -4942,13 +4811,6 @@ pkg-dir@^4.1.0: 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" @@ -5070,12 +4932,10 @@ postcss-env-function@^2.0.2: 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-flexbugs-fixes@^5.0.2: + version "5.0.2" + resolved "https://registry.yarnpkg.com/postcss-flexbugs-fixes/-/postcss-flexbugs-fixes-5.0.2.tgz#2028e145313074fc9abe276cb7ca14e5401eb49d" + integrity sha512-18f9voByak7bTktR2QgDveglpn9DTbBWPUzSOe9g0N4WR/2eSt6Vrcbf0hmspvMI6YWGywz6B9f7jzpFNJJgnQ== postcss-focus-visible@^4.0.0: version "4.0.0" @@ -5124,11 +4984,10 @@ postcss-image-set-function@^3.0.1: 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== + version "3.0.4" + resolved "https://registry.yarnpkg.com/postcss-initial/-/postcss-initial-3.0.4.tgz#9d32069a10531fe2ecafa0b6ac750ee0bc7efc53" + integrity sha512-3RLn6DIpMsK1l5UUy9jxQvoDeUN4gP939tDcKUHD/kM8SGSKbFAnvkpFpj3Bhtz3HGk1jWY5ZNWX6mPta5M9fg== dependencies: - lodash.template "^4.5.0" postcss "^7.0.2" postcss-js@^3.0.3: @@ -5162,20 +5021,25 @@ postcss-media-minmax@^4.0.0: dependencies: postcss "^7.0.2" -postcss-nested@^5.0.5: +postcss-nested@5.0.5: version "5.0.5" resolved "https://registry.yarnpkg.com/postcss-nested/-/postcss-nested-5.0.5.tgz#f0a107d33a9fab11d7637205f5321e27223e3603" integrity sha512-GSRXYz5bccobpTzLQZXOnSOfKl6TwVr5CyAQJUPub4nuRJSOECK5AqurxVgmtxP48p0Kc/ndY/YyS1yqldX0Ew== dependencies: postcss-selector-parser "^6.0.4" -postcss-nesting@^7.0.0, postcss-nesting@^7.0.1: +postcss-nesting@^7.0.0: 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-nesting@^8.0.1: + version "8.0.1" + resolved "https://registry.yarnpkg.com/postcss-nesting/-/postcss-nesting-8.0.1.tgz#4a8ab3c540a0f138fd3f5d2ee65e4a24d1888024" + integrity sha512-cHPNhW5VvRQjszFDxmy16mis9qFQqQLBNw6KVmueLqqE3M182ZAk9+QoxGqbGVryzLVhannw2B5Yhosqq522fA== + 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" @@ -5282,13 +5146,11 @@ postcss-selector-parser@^5.0.0-rc.3, postcss-selector-parser@^5.0.0-rc.4: uniq "^1.0.1" 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== + version "6.0.6" + resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.6.tgz#2c5bba8174ac2f6981ab631a42ab0ee54af332ea" + integrity sha512-9LXrvaaX3+mcv5xkg5kFwqSzSH1JIObIx51PrndZwlmznwXRfxMddDvo9gve3gVR8ZTKgoFDdWkbRFmEhT4PMg== 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: @@ -5301,15 +5163,6 @@ postcss-value-parser@^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" @@ -5338,7 +5191,7 @@ postcss@^6.0.9: source-map "^0.6.1" supports-color "^5.4.0" -postcss@^7.0.14, postcss@^7.0.17, postcss@^7.0.2, postcss@^7.0.26, postcss@^7.0.32, postcss@^7.0.5, postcss@^7.0.6: +postcss@^7.0.14, postcss@^7.0.17, postcss@^7.0.2, 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== @@ -5347,41 +5200,32 @@ 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: - version "8.2.6" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.2.6.tgz#5d69a974543b45f87e464bc4c3e392a97d6be9fe" - integrity sha512-xpB8qYxgPuly166AGlpRjUdEYtmOWx2iCwGmrv4vqZL9YPVviDVPZPRXxnXr6xPZOdxQ9lp3ZBFCRgWJ7LE3Sg== - dependencies: - colorette "^1.2.1" - nanoid "^3.1.20" - source-map "^0.6.1" - -postcss@^8.2.8: - version "8.2.8" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.2.8.tgz#0b90f9382efda424c4f0f69a2ead6f6830d08ece" - integrity sha512-1F0Xb2T21xET7oQV9eKuctbM9S7BC0fetoHCc4H13z0PT6haiRLP4T0ZY4XWh7iLP0usgqykT6p9B2RtOf4FPw== +postcss@^8.1.6, postcss@^8.1.7, postcss@^8.2.1, postcss@^8.3.0: + version "8.3.0" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.3.0.tgz#b1a713f6172ca427e3f05ef1303de8b65683325f" + integrity sha512-+ogXpdAjWGa+fdYY5BQ96V/6tAo+TdSSIMP5huJBIygdWwKtVoB5JWZ7yUd4xZ8r+8Kvvx4nyg/PQ071H4UtcQ== dependencies: colorette "^1.2.2" - nanoid "^3.1.20" - source-map "^0.6.1" + nanoid "^3.1.23" + source-map-js "^0.6.2" -precinct@^6.3.1: - version "6.3.1" - resolved "https://registry.yarnpkg.com/precinct/-/precinct-6.3.1.tgz#8ad735a8afdfc48b56ed39c9ad3bf999b6b928dc" - integrity sha512-JAwyLCgTylWminoD7V0VJwMElWmwrVSR6r9HaPWCoswkB4iFzX7aNtO7VBfAVPy+NhmjKb8IF8UmlWJXzUkOIQ== +precinct@^7.0.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/precinct/-/precinct-7.1.0.tgz#a0311e0b59029647eaf57c2d30b8efa9c85d129a" + integrity sha512-I1RkW5PX51/q6Xl39//D7x9NgaKNGHpR5DCNaoxP/b2+KbzzXDNhauJUMV17KSYkJA41CSpwYUPRtRoNxbshWA== dependencies: commander "^2.20.3" - debug "^4.1.1" - detective-amd "^3.0.0" + debug "^4.3.1" + detective-amd "^3.0.1" detective-cjs "^3.1.1" - detective-es6 "^2.1.0" + detective-es6 "^2.2.0" detective-less "^1.0.2" - detective-postcss "^3.0.1" + detective-postcss "^4.0.0" 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" + detective-typescript "^6.0.0" + module-definition "^3.3.1" node-source-walk "^4.2.0" prelude-ls@~1.1.2: @@ -5394,10 +5238,10 @@ 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.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.2.1.tgz#795a1a78dd52f073da0cd42b21f9c91381923ff5" - integrity sha512-PqyhM2yCjg/oKkFPtTGUojv7gnZAoG80ttl45O6x2Ug/rMJw4wcc9k6aaf2hibP7BGVCCM33gZoGjyvt9mm16Q== +prettier@^2.3.0: + version "2.3.1" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.3.1.tgz#76903c3f8c4449bc9ac597acefa24dc5ad4cbea6" + integrity sha512-p+vNbgpLjif/+D+DwAZAbndtRrR0md0MwfmOVN9N+2RgyACMT+7tfaRnT+WDPkqnuVwleyuBIG2XBxKDme3hPA== pretty-hrtime@^1.0.3: version "1.0.3" @@ -5497,25 +5341,20 @@ querystring-es3@^0.2.0: resolved "https://registry.yarnpkg.com/querystring-es3/-/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73" integrity sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM= -querystring@0.2.0, querystring@^0.2.0: +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== +querystring@^0.2.0: + version "0.2.1" + resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.1.tgz#40d77615bb09d16902a85c3e38aa8b5ed761c2dd" + integrity sha512-wkvS7mL/JMugcup3/rMitHmd9ecIGd2lhFhK9N3UUQ450h66d1r3Y9nvXzQAW1Lq+wyx61k/1pfKS5KuKiyEbg== queue-microtask@^1.2.2: - version "1.2.2" - resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.2.tgz#abf64491e6ecf0f38a6502403d4cda04f372dfd3" - integrity sha512-dB15eXv3p2jDlbOiNLyMabYg1/sXvppd8DP2J3EOCQ0AkuSXCW2tP7mnVouVLJKgUMY6yP0kcQDVpLCN13h4Xg== - -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== + version "1.2.3" + resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" + integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== quick-lru@^5.1.1: version "5.1.1" @@ -5557,14 +5396,14 @@ rc@^1.2.7, rc@^1.2.8: minimist "^1.2.0" strip-json-comments "~2.0.1" -react-dom@^17.0.1: - version "17.0.1" - resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-17.0.1.tgz#1de2560474ec9f0e334285662ede52dbc5426fc6" - integrity sha512-6eV150oJZ9U2t9svnsspTMrWNyHc6chX0KzDeAOXftRa8bNeOKTTfCJ7KorIwenkHd2xqVTBTCZd79yk/lx/Ug== +react-dom@^17.0.2: + version "17.0.2" + resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-17.0.2.tgz#ecffb6845e3ad8dbfcdc498f0d0a939736502c23" + integrity sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA== dependencies: loose-envify "^1.1.0" object-assign "^4.1.1" - scheduler "^0.20.1" + scheduler "^0.20.2" react-is@16.13.1, react-is@^16.8.1: version "16.13.1" @@ -5586,33 +5425,14 @@ react-ticker@^1.2.2: resolved "https://registry.yarnpkg.com/react-ticker/-/react-ticker-1.2.2.tgz#12cda5ff8266c6fe90ffcd8c58e12ba1596ddf24" integrity sha512-PXUujoPJvajxwOfosuuujlrBUrjgGp4FB4haWFOI25ujhMppW4SuLkiOdQ9AylrWN3yTHWdk2kbQWe3n9SjFGA== -react@^17.0.1: - version "17.0.1" - resolved "https://registry.yarnpkg.com/react/-/react-17.0.1.tgz#6e0600416bd57574e3f86d92edba3d9008726127" - integrity sha512-lG9c9UuMHdcAexXtigOZLX8exLWkW0Ku29qPRU8uhF2R9BN96dLCt0psvzPLlHc5OWkgymP3qwTRgbnw5BKx3w== +react@^17.0.2: + version "17.0.2" + resolved "https://registry.yarnpkg.com/react/-/react-17.0.2.tgz#d0b5cc516d29eb3eee383f75b62864cfb6800037" + integrity sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA== dependencies: loose-envify "^1.1.0" object-assign "^4.1.1" -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.2, readable-stream@^2.3.3, readable-stream@^2.3.6: version "2.3.7" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" @@ -5642,14 +5462,6 @@ readdirp@~3.5.0: 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.8: version "2.1.8" resolved "https://registry.yarnpkg.com/reduce-css-calc/-/reduce-css-calc-2.1.8.tgz#7ef8761a28d614980dc0c982f772c93f7a99de03" @@ -5737,13 +5549,12 @@ require-main-filename@^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== +requirejs-config-file@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/requirejs-config-file/-/requirejs-config-file-4.0.0.tgz#4244da5dd1f59874038cc1091d078d620abb6ebc" + integrity sha512-jnIre8cbWOyvr8a5F2KuqBnY+SDA4NXr/hzEZJG79Mxm2WiFQz2dzhC8ibtPJS7zkmBEl1mxSwp5HhC1W4qpxw== dependencies: esprima "^4.0.0" - make-dir "^2.1.0" stringify-object "^3.2.1" requirejs@^2.3.5: @@ -5751,11 +5562,6 @@ requirejs@^2.3.5: 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" @@ -5771,7 +5577,7 @@ resolve-from@^4.0.0: resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== -resolve@^1.10.0, resolve@^1.11.1, resolve@^1.20.0: +resolve@^1.19.0, resolve@^1.20.0: version "1.20.0" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.20.0.tgz#629a013fb3f70755d6f0b7935cc1c2c5378b1975" integrity sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A== @@ -5832,10 +5638,10 @@ run-parallel@^1.1.9: dependencies: queue-microtask "^1.2.2" -rxjs@^6.3.3, rxjs@^6.6.0, rxjs@^6.6.3: - version "6.6.3" - resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.6.3.tgz#8ca84635c4daa900c0d3967a6ee7ac60271ee552" - integrity sha512-trsQc+xYYXZ3urjOiJOuCOa5N3jAZ3eiSpQB5hIT8zGlL2QfnHLJ2r7GMkBGuIausdJN1OneaI6gQlsqNHHmZQ== +rxjs@^6.3.3, rxjs@^6.6.0, rxjs@^6.6.7: + version "6.6.7" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.6.7.tgz#90ac018acabf491bf65044235d5863c4dab804c9" + integrity sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ== dependencies: tslib "^1.9.0" @@ -5861,10 +5667,10 @@ sass-lookup@^3.0.0: dependencies: commander "^2.16.0" -scheduler@^0.20.1: - version "0.20.1" - resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.20.1.tgz#da0b907e24026b01181ecbc75efdc7f27b5a000c" - integrity sha512-LKTe+2xNJBNxu/QhHvDR14wUXHRQbVY5ZOYpOGWRzhydZUqrLb2JBvLPY7cAqFmqrWuDED0Mjk7013SZiOz6Bw== +scheduler@^0.20.2: + version "0.20.2" + resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.20.2.tgz#4baee39436e34aa93b4874bddcbf0fe8b8b50e91" + integrity sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ== dependencies: loose-envify "^1.1.0" object-assign "^4.1.1" @@ -5879,28 +5685,32 @@ semver-compare@^1.0.0: resolved "https://registry.yarnpkg.com/semver-compare/-/semver-compare-1.0.0.tgz#0dee216a1c941ab37e9efb1788f6afc5ff5537fc" integrity sha1-De4hahyUGrN+nvsXiPavxf9VN/w= -semver-regex@^3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/semver-regex/-/semver-regex-3.1.2.tgz#34b4c0d361eef262e07199dbef316d0f2ab11807" - integrity sha512-bXWyL6EAKOJa81XG1OZ/Yyuq+oT0b2YLlxx7c+mrdYPaPbnj6WgVULXhinMIeZGufuUBu/eVRqXEhiv4imfwxA== - -"semver@2 || 3 || 4 || 5", semver@^5.4.1, semver@^5.6.0: +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: +semver@^6.0.0, semver@^6.2.0, semver@^6.3.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== +semver@^7.3.5: + version "7.3.5" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7" + integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ== dependencies: lru-cache "^6.0.0" +sentence-case@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/sentence-case/-/sentence-case-3.0.4.tgz#3645a7b8c117c787fde8702056225bb62a45131f" + integrity sha512-8LS0JInaQMCRoQ7YUytAo/xUu5W2XnQxV2HI/6uM6U7CITS1RqPElr30V6uIqyMKM9lJGRVFy5/4CuzcixNYSg== + dependencies: + no-case "^3.0.4" + tslib "^2.0.3" + upper-case-first "^2.0.2" + set-blocking@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" @@ -5916,11 +5726,6 @@ setprototypeof@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" @@ -5951,7 +5756,7 @@ shopify-buy@^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.2: +signal-exit@^3.0.2, signal-exit@^3.0.3: version "3.0.3" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c" integrity sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA== @@ -5969,11 +5774,11 @@ simple-swizzle@^0.2.2: is-arrayish "^0.3.1" sirv@^1.0.7: - version "1.0.11" - resolved "https://registry.yarnpkg.com/sirv/-/sirv-1.0.11.tgz#81c19a29202048507d6ec0d8ba8910fda52eb5a4" - integrity sha512-SR36i3/LSWja7AJNRBz4fF/Xjpn7lQFI30tZ434dIy+bitLYSP+ZEenHg36i23V2SGEz+kqjksg0uOGZ5LPiqg== + version "1.0.12" + resolved "https://registry.yarnpkg.com/sirv/-/sirv-1.0.12.tgz#d816c882b35489b3c63290e2f455ae3eccd5f652" + integrity sha512-+jQoCxndz7L2tqQL4ZyzfDhky0W/4ZJip3XoOuxyQWnAwMxindLl3Xv1qT4x1YX/re0leShvTm8Uk0kQspGhBg== dependencies: - "@polka/url" "^1.0.0-next.9" + "@polka/url" "^1.0.0-next.15" mime "^2.3.1" totalist "^1.0.0" @@ -6005,6 +5810,19 @@ slice-ansi@^4.0.0: astral-regex "^2.0.0" is-fullwidth-code-point "^3.0.0" +snake-case@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/snake-case/-/snake-case-3.0.4.tgz#4f2bbd568e9935abdfd593f34c691dadb49c452c" + integrity sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg== + dependencies: + dot-case "^3.0.4" + tslib "^2.0.3" + +source-map-js@^0.6.2: + version "0.6.2" + resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-0.6.2.tgz#0bb5de631b41cfbda6cfba8bd05a80efdfd2385e" + integrity sha512-/3GptzWzu0+0MBQFrDKzw/DvvMTUORvgY6k6jd/VS6iCR4RDTKWH6v6WPwQoUO8667uQEf9Oe38DxAYWY5F/Ug== + 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" @@ -6035,41 +5853,12 @@ source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.1: resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== -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== +sponge-case@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/sponge-case/-/sponge-case-1.0.1.tgz#260833b86453883d974f84854cdb63aecc5aef4c" + integrity sha512-dblb9Et4DAtiZ5YSUZHLl4XhH4uK80GhAZrVXdN4O2P4gQ40Wa5UIOPUHlA/nFd2PLblBZWUioLMMAVrgpoYcA== 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== + tslib "^2.0.3" stacktrace-parser@0.1.10: version "0.1.10" @@ -6117,11 +5906,6 @@ stream-parser@^0.3.1: dependencies: debug "2" -streamsearch@0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/streamsearch/-/streamsearch-0.1.2.tgz#808b9d0e56fc273d809ba57338e929919a1a9f1a" - integrity sha1-gIudDlb8Jz2Am6VzOOkpkZoanxo= - string-argv@0.3.1: version "0.3.1" resolved "https://registry.yarnpkg.com/string-argv/-/string-argv-0.3.1.tgz#95e2fbec0427ae19184935f816d74aaa4c5c19da" @@ -6155,28 +5939,28 @@ string-width@^2.1.1: 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== + version "4.2.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.2.tgz#dafd4f9559a7585cfba529c6a0a4f73488ebd4c5" + integrity sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA== dependencies: emoji-regex "^8.0.0" is-fullwidth-code-point "^3.0.0" strip-ansi "^6.0.0" -string.prototype.trimend@^1.0.3: - 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== +string.prototype.trimend@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz#e75ae90c2942c63504686c18b287b4a0b1a45f80" + integrity sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A== dependencies: - call-bind "^1.0.0" + call-bind "^1.0.2" define-properties "^1.1.3" -string.prototype.trimstart@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.3.tgz#9b4cb590e123bb36564401d59824298de50fd5aa" - integrity sha512-oBIBUy5lea5tt0ovtOFiEQaBkoBBkyJhZXzJYrSmDo5IUUqbOPvVezuRs/agBIdZ2p2Eo1FD6bD9USyBLfl3xg== +string.prototype.trimstart@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz#b36399af4ab2999b4c9c648bd7a3fb2bb26feeed" + integrity sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw== dependencies: - call-bind "^1.0.0" + call-bind "^1.0.2" define-properties "^1.1.3" string_decoder@^1.0.0, string_decoder@^1.1.1: @@ -6228,13 +6012,6 @@ strip-final-newline@^2.0.0: resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== -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" @@ -6272,6 +6049,17 @@ stylus-lookup@^3.0.1: commander "^2.8.1" debug "^4.1.0" +subscriptions-transport-ws@^0.9.18: + version "0.9.18" + resolved "https://registry.yarnpkg.com/subscriptions-transport-ws/-/subscriptions-transport-ws-0.9.18.tgz#bcf02320c911fbadb054f7f928e51c6041a37b97" + integrity sha512-tztzcBTNoEbuErsVQpTN2xUNN/efAZXyCyL5m3x4t6SKrEiTL2N8SaKWBFWM4u56pL79ULif3zjyeq+oV+nOaA== + dependencies: + backo2 "^1.0.2" + eventemitter3 "^3.1.0" + iterall "^1.2.1" + symbol-observable "^1.0.4" + ws "^5.2.0" + supports-color@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" @@ -6298,6 +6086,13 @@ supports-color@^7.1.0: dependencies: has-flag "^4.0.0" +swap-case@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/swap-case/-/swap-case-2.0.2.tgz#671aedb3c9c137e2985ef51c51f9e98445bf70d9" + integrity sha512-kc6S2YS/2yXbtkSMunBtKdah4VFETZ8Oh6ONSmSd9bRxhqTrtARUCBUiWXH3xVPpvR7tz2CSnkuXVE42EcGnMw== + dependencies: + tslib "^2.0.3" + 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" @@ -6311,14 +6106,14 @@ swell-js@^4.0.0-next.0: 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" - integrity sha512-SKGxcAfyijj/lE5ja5zVMDqJNudASH3WZPRUakDVOePTM18FnsXgugndjl9BSRwj+jokFCulMDe7F2pQL+VhEw== +swr@^0.5.6: + version "0.5.6" + resolved "https://registry.yarnpkg.com/swr/-/swr-0.5.6.tgz#70bfe9bc9d7ac49a064be4a0f4acf57982e55a31" + integrity sha512-Bmx3L4geMZjYT5S2Z6EE6/5Cx6v1Ka0LhqZKq8d6WL2eu9y6gHWz3dUzfIK/ymZVHVfwT/EweFXiYGgfifei3w== dependencies: dequal "2.0.2" -symbol-observable@^1.1.0: +symbol-observable@^1.0.4, 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== @@ -6331,34 +6126,41 @@ 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== +tabbable@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/tabbable/-/tabbable-5.2.0.tgz#4fba60991d8bb89d06e5d9455c92b453acf88fb2" + integrity sha512-0uyt8wbP0P3T4rrsfYg/5Rg3cIJ8Shl1RJ54QMqYxm1TLdWqJD1u6+RQjr2Lor3wmfT7JRHkirIwy99ydBsyPg== -tailwindcss@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/tailwindcss/-/tailwindcss-2.0.4.tgz#cf13e62738c3a27065664e449d93b66ee2945506" - integrity sha512-WhgR0oiBxGOZ9jY0yVfaJCHnckR7U74Fs/BMsYxGdwGJQ5Hd/HlaKD26bEJFZOvYScJo0QcUj2ImldzedsG7Bw== +tailwindcss@^2.1.2: + version "2.1.4" + resolved "https://registry.yarnpkg.com/tailwindcss/-/tailwindcss-2.1.4.tgz#ee8a1b8ccc140db61960b6738f968a8a1c4cd1f8" + integrity sha512-fh1KImDLg6se/Suaelju/5oFbqq1b0ntagmGLu0aG9LlnNPGHgO1n/4E57CbKcCtyz/VYnvVXUiWmfyfBBZQ6g== dependencies: "@fullhuman/postcss-purgecss" "^3.1.3" bytes "^3.0.0" chalk "^4.1.0" + chokidar "^3.5.1" color "^3.1.3" detective "^5.2.0" didyoumean "^1.2.1" + dlv "^1.1.3" + fast-glob "^3.2.5" fs-extra "^9.1.0" html-tags "^3.1.0" lodash "^4.17.21" + lodash.topath "^4.5.2" modern-normalize "^1.0.0" node-emoji "^1.8.1" + normalize-path "^3.0.0" object-hash "^2.1.1" + parse-glob "^3.0.4" postcss-functions "^3" postcss-js "^3.0.3" - postcss-nested "^5.0.5" + postcss-nested "5.0.5" postcss-selector-parser "^6.0.4" postcss-value-parser "^4.1.0" pretty-hrtime "^1.0.3" + quick-lru "^5.1.1" reduce-css-calc "^2.1.8" resolve "^1.20.0" @@ -6367,6 +6169,11 @@ tapable@^1.0.0: resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.1.3.tgz#a1fccc06b58db61fd7a45da2da44f5f3a3e67ba2" integrity sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA== +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" @@ -6384,6 +6191,18 @@ timers-browserify@^2.0.4: dependencies: setimmediate "^1.0.4" +tiny-warning@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/tiny-warning/-/tiny-warning-1.0.3.tgz#94a30db453df4c643d0fd566060d60a875d84754" + integrity sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA== + +title-case@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/title-case/-/title-case-3.0.3.tgz#bc689b46f02e411f1d1e1d081f7c3deca0489982" + integrity sha512-e1zGYRvbffpcHIrnuqT0Dh+gEJtDaxDSoG4JAIpq4oDFyooziLBIiYQv0GBT4FUAnUop5uZ1hiIAj7oAF6sOCA== + dependencies: + tslib "^2.0.3" + tmp@^0.0.33: version "0.0.33" resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" @@ -6430,16 +6249,6 @@ tr46@^1.0.1: 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= - -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" @@ -6473,25 +6282,30 @@ ts-pnp@^1.1.6: 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: +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, tslib@^2.0.3, tslib@^2.1.0, tslib@~2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.2.0.tgz#fb2c475977e35e241311ede2693cee1ec6698f5c" + integrity sha512-gS9GVHRU+RGn5KQM2rllAlR3dU6m7AcpJKdtH8gFvQiC4Otgk98XnmMU+nZenHt/+VhnBPWwgrJsyrdcw6i23w== 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.20.0" - resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.20.0.tgz#ea03ea45462e146b53d70ce0893de453ff24f698" - integrity sha512-RYbuQuvkhuqVeXweWT3tJLKOEJ/UUw9GjNEZGWdrLLlM+611o1gwLHBpxoFJKKl25fLprp2eVthtKs5JOrNeXg== +tslib@~2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.1.0.tgz#da60860f1c2ecaa5703ab7d39bc05b6bf988b97a" + integrity sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A== + +tsutils@^3.21.0: + version "3.21.0" + resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.21.0.tgz#b48717d394cea6c1e096983eed58e9d61715b623" + integrity sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA== dependencies: tslib "^1.8.1" @@ -6507,45 +6321,45 @@ type-check@~0.3.2: 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.21.3: + version "0.21.3" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37" + integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w== 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== +typescript@4.2.4: + version "4.2.4" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.2.4.tgz#8610b59747de028fda898a8aef0e103f156d0961" + integrity sha512-V+evlYHZnQkaz8TRBuxTA92yZBPotr5H+WhQ7bD3hZUndx5tGOa1fuCgeSjxAzM1RiN5IzvadIXTVefuuwZCRg== -typescript@^3.0.3, typescript@^3.8.3, typescript@^3.9.5, typescript@^3.9.7: +typescript@^3.9.5, typescript@^3.9.7: version "3.9.9" resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.9.9.tgz#e69905c54bc0681d0518bd4d587cc6f2d0b1a674" integrity sha512-kdMjTiekY+z/ubJCATUPlRDl39vXYiMV9iyeMuEuXZh2we6zz80uovNN2WlAxmmdE/Z/YQe+EbOEXB5RHEED3w== -typescript@^4.0.3: - version "4.1.5" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.1.5.tgz#123a3b214aaff3be32926f0d8f1f6e704eb89a72" - integrity sha512-6OSu9PTIzmn9TCDiovULTnET6BgXtDYL4Gg4szY+cGsc3JP1dQL8qvE8kShTRx1NIw4Q9IBHlwODjkjWEtMUyA== +typescript@^4.2.3: + version "4.3.2" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.3.2.tgz#399ab18aac45802d6f2498de5054fcbbe716a805" + integrity sha512-zZ4hShnmnoVnAHpVHWpTcxdv7dWP60S2FsydQLV8V5PbS3FifjWFFRiHSWpDJahly88PRyV5teTSLoq4eG7mKw== ua-parser-js@^0.7.18: - version "0.7.24" - resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.24.tgz#8d3ecea46ed4f1f1d63ec25f17d8568105dc027c" - integrity sha512-yo+miGzQx5gakzVK3QFfN0/L9uVhosXBBO7qmnk7c2iw1IhL212wfA3zbnI54B0obGwC/5NWub/iT9sReMx+Fw== + version "0.7.28" + resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.28.tgz#8ba04e653f35ce210239c64661685bf9121dec31" + integrity sha512-6Gurc1n//gjp9eQNXjD9O3M/sMwVtN5S8Lv9bvOYBfKfDNiIIhqiyi01vMBO45u4zkDE420w/e0se7Vs+sIg+g== + +unbox-primitive@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.1.tgz#085e215625ec3162574dc8859abee78a59b14471" + integrity sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw== + dependencies: + function-bind "^1.1.1" + has-bigints "^1.0.1" + has-symbols "^1.0.2" + which-boxed-primitive "^1.0.2" unc-path-regex@^0.1.2: version "0.1.2" @@ -6574,27 +6388,20 @@ unpipe@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== +upper-case-first@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/upper-case-first/-/upper-case-first-2.0.2.tgz#992c3273f882abd19d1e02894cc147117f844324" + integrity sha512-514ppYHBaKwfJRK/pNC6c/OxfGa0obSnAl106u97Ed0I625Nin96KAjttZF6ZL3e1XLtphxnqrOi9iWgm+u+bg== dependencies: - tslib "^1.10.0" + tslib "^2.0.3" -upper-case@^2.0.1, upper-case@^2.0.2: +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" - 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" @@ -6602,14 +6409,6 @@ url-parse-lax@^3.0.0: 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" - url@^0.11.0: version "0.11.0" resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1" @@ -6631,11 +6430,11 @@ util-deprecate@^1.0.1, util-deprecate@^1.0.2, util-deprecate@~1.0.1: 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== + version "3.1.0" + resolved "https://registry.yarnpkg.com/util-nonempty/-/util-nonempty-3.1.0.tgz#927a9472ead1817afca159b209e5806523b752d3" + integrity sha512-OSZlWoCL74Go83Qw/aeZgSmFZnp9d06bF77b1eAOKipkPWhvxjRYB2nmKiGspoVjkJJEJimzxAgBFUQiUV/oZQ== dependencies: - "@babel/runtime" "^7.13.10" + "@babel/runtime" "^7.14.0" lodash.isplainobject "^4.0.6" util@0.10.3: @@ -6657,13 +6456,10 @@ valid-url@1.0.9, valid-url@^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" +value-or-promise@1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/value-or-promise/-/value-or-promise-1.0.6.tgz#218aa4794aa2ee24dcf48a29aba4413ed584747f" + integrity sha512-9r0wQsWD8z/BxPOvnwbPf05ZvFngXyouE9EKB+5GbYix+BYnAwrIChCUyFIinfbf2FL/U71z+CPpbnmTdxrwBg== vm-browserify@1.1.2, vm-browserify@^1.0.1: version "1.1.2" @@ -6675,13 +6471,6 @@ walkdir@^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.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.1.1.tgz#e99630550fca07df9f90a06056987baa40a689c7" @@ -6718,9 +6507,9 @@ webpack-bundle-analyzer@4.3.0: ws "^7.3.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== + version "3.6.2" + resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-3.6.2.tgz#dced24f37f2624ed0281725d51d0e2e3fe677f8c" + integrity sha512-bJlen0FcuU/0EMLrdbJ7zOnW6ITZLrZMIarMUVmdKtsGvZna8vxKYaexICWPfZ8qwf9fzNq+UEIZrnSaApt6RA== whatwg-url@^7.0.0: version "7.1.0" @@ -6731,16 +6520,22 @@ whatwg-url@^7.0.0: tr46 "^1.0.1" webidl-conversions "^4.0.2" +which-boxed-primitive@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz#13757bc89b209b049fe5d86430e21cf40a89a8e6" + integrity sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg== + dependencies: + is-bigint "^1.0.1" + is-boolean-object "^1.1.0" + is-number-object "^1.0.4" + is-string "^1.0.5" + is-symbol "^1.0.3" + 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= - which@^2.0.1: version "2.0.2" resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" @@ -6784,15 +6579,22 @@ wrappy@1: resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= -ws@7.4.2: - 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== +ws@7.4.5: + version "7.4.5" + resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.5.tgz#a484dd851e9beb6fdb420027e3885e8ce48986c1" + integrity sha512-xzyu3hFvomRfXKH8vOFMU3OguG6oOvhXMo3xsGy3xWExqaM2dxBbVxuD99O7m3ZUFMvvscsZDqxfgMaRr/Nr1g== + +ws@^5.2.0: + version "5.2.2" + resolved "https://registry.yarnpkg.com/ws/-/ws-5.2.2.tgz#dffef14866b8e8dc9133582514d1befaf96e980f" + integrity sha512-jaHFD6PFv6UgoIVda6qZllptQsMlDEJkTQcybzzXDYM1XO9Y8em691FGMPmM46WGyLU4z9KMgQN+qrux/nhlHA== + dependencies: + async-limiter "~1.0.0" ws@^7.3.1: - version "7.4.3" - resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.3.tgz#1f9643de34a543b8edb124bdcbc457ae55a6e5cd" - integrity sha512-hr6vCR76GsossIRsr8OLR9acVVm1jyfEWvhbNjtgPOrfvAlKzvyeg/P6r8RuDjRyrcQoPQT7K0DGEPc7Ae6jzA== + version "7.4.6" + resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.6.tgz#5654ca8ecdeee47c33a9a4bf6d28e2be2980377c" + integrity sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A== xtend@^4.0.0, xtend@^4.0.2: version "4.0.2" @@ -6800,14 +6602,14 @@ xtend@^4.0.0, xtend@^4.0.2: 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== + version "4.0.3" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.3.tgz#b5f259c82cd6e336921efd7bfd8bf560de9eeedf" + integrity sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ== 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== + version "5.0.8" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" + integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== yallist@^3.0.2: version "3.1.1" @@ -6824,12 +6626,12 @@ yaml-ast-parser@^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== +yaml@^1.10.0: + version "1.10.2" + resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b" + integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== -yargs-parser@^18.1.2, yargs-parser@^18.1.3: +yargs-parser@^18.1.2: version "18.1.3" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-18.1.3.tgz#be68c4975c6b2abf469236b0c870362fab09a7b0" integrity sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ== @@ -6838,9 +6640,9 @@ yargs-parser@^18.1.2, yargs-parser@^18.1.3: 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== + version "20.2.7" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.7.tgz#61df85c113edfb5a7a4e36eb8aa60ef423cbc90a" + integrity sha512-FiNkvbeHzB/syOjIUxFDCnhSfzAL8R5vs40MgLFBorXACCOAEaWu0gRZl14vG8MR9AOJIZbmkjhusqBYZ3HTHw== yargs@^15.3.1: version "15.4.1" @@ -6859,10 +6661,10 @@ yargs@^15.3.1: 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== +yargs@^17.0.0: + version "17.0.1" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.0.1.tgz#6a1ced4ed5ee0b388010ba9fd67af83b9362e0bb" + integrity sha512-xBBulfCc8Y6gLFcrPvtqKz9hz8SO0l1Ni8GgDekvBX2ro0HRQImDGnikfc33cgzcYUSncapnNcZDjVFIH3f6KQ== dependencies: cliui "^7.0.2" escalade "^3.1.1" From ddd4631ade9a6c980cac3ffc78074e486e756951 Mon Sep 17 00:00:00 2001 From: Luis Alvarez Date: Thu, 10 Jun 2021 01:52:09 -0500 Subject: [PATCH 255/261] Exclude prop --- pages/index.tsx | 3 ++- tsconfig.json | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/pages/index.tsx b/pages/index.tsx index 3f1b6502a..c4f453803 100644 --- a/pages/index.tsx +++ b/pages/index.tsx @@ -15,7 +15,8 @@ export async function getStaticProps({ variables: { first: 12 }, config, preview, - featured: true + // Saleor provider only + ...({ featured: true } as any), }) const { categories, brands } = await commerce.getSiteInfo({ config, preview }) const { pages } = await commerce.getAllPages({ config, preview }) diff --git a/tsconfig.json b/tsconfig.json index ba333b642..96e4359e5 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -22,8 +22,8 @@ "@components/*": ["components/*"], "@commerce": ["framework/commerce"], "@commerce/*": ["framework/commerce/*"], - "@framework": ["framework/saleor"], - "@framework/*": ["framework/saleor/*"] + "@framework": ["framework/shopify"], + "@framework/*": ["framework/shopify/*"] } }, "include": ["next-env.d.ts", "**/*.d.ts", "**/*.ts", "**/*.tsx", "**/*.js"], From 4d85b43a3006d9db270da80ac9b6b543af337160 Mon Sep 17 00:00:00 2001 From: ghoskin Date: Mon, 14 Jun 2021 13:37:18 -0700 Subject: [PATCH 256/261] Update Swell Provider (#359) * fix update cart item * update types * update checkout * update get-page, cleanup types * revert change to incorrect file * cleanup Co-authored-by: Greg Hoskin --- framework/swell/api/checkout/index.ts | 20 ------ framework/swell/api/customers/login.ts | 1 - framework/swell/api/endpoints/cart.ts | 1 + .../swell/api/endpoints/catalog/products.ts | 1 + .../swell/api/endpoints/checkout/index.ts | 30 +++++++++ framework/swell/api/endpoints/customer.ts | 1 + framework/swell/api/endpoints/login.ts | 1 + framework/swell/api/endpoints/logout.ts | 1 + framework/swell/api/endpoints/signup.ts | 1 + framework/swell/api/endpoints/wishlist.ts | 1 + framework/swell/api/index.ts | 59 ++++++++--------- .../swell/api/operations/get-all-pages.ts | 45 +++++++++++++ .../api/operations/get-all-product-paths.ts | 48 ++++++++++++++ .../swell/api/operations/get-all-products.ts | 43 +++++++++++++ framework/swell/api/operations/get-page.ts | 63 ++++++++++++++----- framework/swell/api/operations/get-product.ts | 33 ++++++++++ .../swell/api/operations/get-site-info.ts | 37 +++++++++++ framework/swell/api/operations/login.ts | 46 ++++++++++++++ .../swell/api/utils/create-api-handler.ts | 58 ----------------- framework/swell/auth/use-login.tsx | 4 +- framework/swell/auth/use-logout.tsx | 3 +- framework/swell/auth/use-signup.tsx | 10 +-- framework/swell/cart/use-add-item.tsx | 6 +- framework/swell/cart/use-cart.tsx | 4 +- framework/swell/cart/use-remove-item.tsx | 60 ++++++------------ framework/swell/cart/use-update-item.tsx | 33 +++++----- framework/swell/cart/utils/checkout-create.ts | 2 +- framework/swell/cart/utils/fetcher.ts | 33 ---------- framework/swell/common/get-all-pages.ts | 37 ----------- framework/swell/common/get-page.ts | 33 ---------- framework/swell/common/get-site-info.ts | 31 --------- framework/swell/customer/use-customer.tsx | 27 +------- .../swell/product/get-all-collections.ts | 28 --------- .../swell/product/get-all-product-paths.ts | 39 ------------ framework/swell/product/get-all-products.ts | 36 ----------- framework/swell/product/get-product.ts | 32 ---------- framework/swell/product/index.ts | 2 + framework/swell/product/use-search.tsx | 18 +----- framework/swell/provider.ts | 9 ++- framework/swell/types.ts | 30 +++------ framework/swell/types/cart.ts | 1 + framework/swell/types/checkout.ts | 1 + framework/swell/types/common.ts | 1 + framework/swell/types/customer.ts | 1 + framework/swell/types/index.ts | 25 ++++++++ framework/swell/types/login.ts | 11 ++++ framework/swell/types/logout.ts | 1 + framework/swell/types/page.ts | 1 + framework/swell/types/product.ts | 1 + framework/swell/types/signup.ts | 1 + framework/swell/types/site.ts | 1 + framework/swell/types/wishlist.ts | 1 + framework/swell/utils/get-categories.ts | 2 +- framework/swell/utils/normalize.ts | 33 ++++++---- .../swell/swell-js.d.ts => swell-js.d.ts | 0 55 files changed, 503 insertions(+), 545 deletions(-) delete mode 100644 framework/swell/api/checkout/index.ts delete mode 100644 framework/swell/api/customers/login.ts create mode 100644 framework/swell/api/endpoints/cart.ts create mode 100644 framework/swell/api/endpoints/catalog/products.ts create mode 100644 framework/swell/api/endpoints/checkout/index.ts create mode 100644 framework/swell/api/endpoints/customer.ts create mode 100644 framework/swell/api/endpoints/login.ts create mode 100644 framework/swell/api/endpoints/logout.ts create mode 100644 framework/swell/api/endpoints/signup.ts create mode 100644 framework/swell/api/endpoints/wishlist.ts create mode 100644 framework/swell/api/operations/get-all-pages.ts create mode 100644 framework/swell/api/operations/get-all-product-paths.ts create mode 100644 framework/swell/api/operations/get-all-products.ts create mode 100644 framework/swell/api/operations/get-product.ts create mode 100644 framework/swell/api/operations/get-site-info.ts create mode 100644 framework/swell/api/operations/login.ts delete mode 100644 framework/swell/api/utils/create-api-handler.ts delete mode 100644 framework/swell/cart/utils/fetcher.ts delete mode 100644 framework/swell/common/get-all-pages.ts delete mode 100644 framework/swell/common/get-page.ts delete mode 100644 framework/swell/common/get-site-info.ts delete mode 100644 framework/swell/product/get-all-collections.ts delete mode 100644 framework/swell/product/get-all-product-paths.ts delete mode 100644 framework/swell/product/get-all-products.ts delete mode 100644 framework/swell/product/get-product.ts create mode 100644 framework/swell/product/index.ts create mode 100644 framework/swell/types/cart.ts create mode 100644 framework/swell/types/checkout.ts create mode 100644 framework/swell/types/common.ts create mode 100644 framework/swell/types/customer.ts create mode 100644 framework/swell/types/index.ts create mode 100644 framework/swell/types/login.ts create mode 100644 framework/swell/types/logout.ts create mode 100644 framework/swell/types/page.ts create mode 100644 framework/swell/types/product.ts create mode 100644 framework/swell/types/signup.ts create mode 100644 framework/swell/types/site.ts create mode 100644 framework/swell/types/wishlist.ts rename framework/swell/swell-js.d.ts => swell-js.d.ts (100%) diff --git a/framework/swell/api/checkout/index.ts b/framework/swell/api/checkout/index.ts deleted file mode 100644 index 0759e2abc..000000000 --- a/framework/swell/api/checkout/index.ts +++ /dev/null @@ -1,20 +0,0 @@ -import createApiHandler, { SwellApiHandler } from '../utils/create-api-handler' - -import { SWELL_CHECKOUT_URL_COOKIE } from '../../const' - -import { getConfig } from '..' - -const checkoutApi: SwellApiHandler = async (req, res, config) => { - config = getConfig() - - const { cookies } = req - const checkoutUrl = cookies[SWELL_CHECKOUT_URL_COOKIE] - - if (checkoutUrl) { - res.redirect(checkoutUrl) - } else { - res.redirect('/cart') - } -} - -export default createApiHandler(checkoutApi, {}, {}) diff --git a/framework/swell/api/customers/login.ts b/framework/swell/api/customers/login.ts deleted file mode 100644 index ea9b101e1..000000000 --- a/framework/swell/api/customers/login.ts +++ /dev/null @@ -1 +0,0 @@ -export default function () {} diff --git a/framework/swell/api/endpoints/cart.ts b/framework/swell/api/endpoints/cart.ts new file mode 100644 index 000000000..d09c976c3 --- /dev/null +++ b/framework/swell/api/endpoints/cart.ts @@ -0,0 +1 @@ +export default function (_commerce: any) {} diff --git a/framework/swell/api/endpoints/catalog/products.ts b/framework/swell/api/endpoints/catalog/products.ts new file mode 100644 index 000000000..d09c976c3 --- /dev/null +++ b/framework/swell/api/endpoints/catalog/products.ts @@ -0,0 +1 @@ +export default function (_commerce: any) {} diff --git a/framework/swell/api/endpoints/checkout/index.ts b/framework/swell/api/endpoints/checkout/index.ts new file mode 100644 index 000000000..ab17a3767 --- /dev/null +++ b/framework/swell/api/endpoints/checkout/index.ts @@ -0,0 +1,30 @@ +import { CommerceAPI, createEndpoint, GetAPISchema } from '@commerce/api' +import { CheckoutSchema } from '@commerce/types/checkout' +import { SWELL_CHECKOUT_URL_COOKIE } from '../../../const' +import checkoutEndpoint from '@commerce/api/endpoints/checkout' + +const checkout: CheckoutEndpoint['handlers']['checkout'] = async ({ + req, + res, + config, +}) => { + const { cookies } = req + const checkoutUrl = cookies[SWELL_CHECKOUT_URL_COOKIE] + + if (checkoutUrl) { + res.redirect(checkoutUrl) + } else { + res.redirect('/cart') + } +} +export const handlers: CheckoutEndpoint['handlers'] = { checkout } + +export type CheckoutAPI = GetAPISchema +export type CheckoutEndpoint = CheckoutAPI['endpoint'] + +const checkoutApi = createEndpoint({ + handler: checkoutEndpoint, + handlers, +}) + +export default checkoutApi diff --git a/framework/swell/api/endpoints/customer.ts b/framework/swell/api/endpoints/customer.ts new file mode 100644 index 000000000..d09c976c3 --- /dev/null +++ b/framework/swell/api/endpoints/customer.ts @@ -0,0 +1 @@ +export default function (_commerce: any) {} diff --git a/framework/swell/api/endpoints/login.ts b/framework/swell/api/endpoints/login.ts new file mode 100644 index 000000000..d09c976c3 --- /dev/null +++ b/framework/swell/api/endpoints/login.ts @@ -0,0 +1 @@ +export default function (_commerce: any) {} diff --git a/framework/swell/api/endpoints/logout.ts b/framework/swell/api/endpoints/logout.ts new file mode 100644 index 000000000..d09c976c3 --- /dev/null +++ b/framework/swell/api/endpoints/logout.ts @@ -0,0 +1 @@ +export default function (_commerce: any) {} diff --git a/framework/swell/api/endpoints/signup.ts b/framework/swell/api/endpoints/signup.ts new file mode 100644 index 000000000..d09c976c3 --- /dev/null +++ b/framework/swell/api/endpoints/signup.ts @@ -0,0 +1 @@ +export default function (_commerce: any) {} diff --git a/framework/swell/api/endpoints/wishlist.ts b/framework/swell/api/endpoints/wishlist.ts new file mode 100644 index 000000000..d09c976c3 --- /dev/null +++ b/framework/swell/api/endpoints/wishlist.ts @@ -0,0 +1 @@ +export default function (_commerce: any) {} diff --git a/framework/swell/api/index.ts b/framework/swell/api/index.ts index 1494af9c7..463c42fae 100644 --- a/framework/swell/api/index.ts +++ b/framework/swell/api/index.ts @@ -1,5 +1,8 @@ -import type { CommerceAPIConfig } from '@commerce/api' - +import { + CommerceAPI, + CommerceAPIConfig, + getCommerceApi as commerceApi, +} from '@commerce/api' import { SWELL_CHECKOUT_ID_COOKIE, SWELL_CUSTOMER_TOKEN_COOKIE, @@ -7,31 +10,19 @@ import { } from '../const' import fetchApi from './utils/fetch-swell-api' +import login from './operations/login' +import getAllPages from './operations/get-all-pages' +import getPage from './operations/get-page' +import getSiteInfo from './operations/get-site-info' +import getAllProductPaths from './operations/get-all-product-paths' +import getAllProducts from './operations/get-all-products' +import getProduct from './operations/get-product' export interface SwellConfig extends CommerceAPIConfig { fetch: any } -export class Config { - private config: SwellConfig - - constructor(config: SwellConfig) { - 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({ +const config: SwellConfig = { locale: 'en-US', commerceUrl: '', apiToken: ''!, @@ -39,12 +30,24 @@ const config = new Config({ cartCookieMaxAge: SWELL_COOKIE_EXPIRE, fetch: fetchApi, customerCookie: SWELL_CUSTOMER_TOKEN_COOKIE, -}) - -export function getConfig(userConfig?: Partial) { - return config.getConfig(userConfig) } -export function setConfig(newConfig: Partial) { - return config.setConfig(newConfig) +const operations = { + login, + getAllPages, + getPage, + getSiteInfo, + getAllProductPaths, + getAllProducts, + getProduct, +} + +export const provider = { config, operations } + +export type Provider = typeof provider + +export function getCommerceApi

    ( + customProvider: P = provider as any +): CommerceAPI

    { + return commerceApi(customProvider) } diff --git a/framework/swell/api/operations/get-all-pages.ts b/framework/swell/api/operations/get-all-pages.ts new file mode 100644 index 000000000..6abaa155c --- /dev/null +++ b/framework/swell/api/operations/get-all-pages.ts @@ -0,0 +1,45 @@ +import { Provider, SwellConfig } from '..' +import type { OperationContext } from '@commerce/api/operations' +import type { Page } from '../../types/page' + +export type GetAllPagesResult< + T extends { pages: any[] } = { pages: Page[] } +> = T + +export default function getAllPagesOperation({ + commerce, +}: OperationContext) { + async function getAllPages(opts?: { + config?: Partial + preview?: boolean + }): Promise + + async function getAllPages(opts: { + url: string + config?: Partial + preview?: boolean + }): Promise> + + async function getAllPages({ + config: cfg, + preview, + }: { + url?: string + config?: Partial + preview?: boolean + } = {}): Promise { + const config = commerce.getConfig(cfg) + 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, + } + } + + return getAllPages +} diff --git a/framework/swell/api/operations/get-all-product-paths.ts b/framework/swell/api/operations/get-all-product-paths.ts new file mode 100644 index 000000000..4d95253e8 --- /dev/null +++ b/framework/swell/api/operations/get-all-product-paths.ts @@ -0,0 +1,48 @@ +import { SwellProduct } from '../../types' +import { SwellConfig, Provider } from '..' +import { OperationContext, OperationOptions } from '@commerce/api/operations' +import { GetAllProductPathsOperation } from '@commerce/types/product' + +export default function getAllProductPathsOperation({ + commerce, +}: OperationContext) { + async function getAllProductPaths< + T extends GetAllProductPathsOperation + >(opts?: { + variables?: T['variables'] + config?: SwellConfig + }): Promise + + async function getAllProductPaths( + opts: { + variables?: T['variables'] + config?: SwellConfig + } & OperationOptions + ): Promise + + async function getAllProductPaths({ + variables, + config: cfg, + }: { + query?: string + variables?: T['variables'] + config?: SwellConfig + } = {}): Promise { + const config = commerce.getConfig(cfg) + // RecursivePartial forces the method to check for every prop in the data, which is + // required in case there's a custom `query` + const { results } = await config.fetch('products', 'list', [ + { + limit: variables?.first, + }, + ]) + + return { + products: results?.map(({ slug: handle }: SwellProduct) => ({ + path: `/${handle}`, + })), + } + } + + return getAllProductPaths +} diff --git a/framework/swell/api/operations/get-all-products.ts b/framework/swell/api/operations/get-all-products.ts new file mode 100644 index 000000000..7e8e99a5c --- /dev/null +++ b/framework/swell/api/operations/get-all-products.ts @@ -0,0 +1,43 @@ +import { normalizeProduct } from '../../utils/normalize' +import { SwellProduct } from '../../types' +import { Product } from '@commerce/types/product' +import { Provider, SwellConfig } from '../' +import { OperationContext } from '@commerce/api/operations' + +export type ProductVariables = { first?: number } + +export default function getAllProductsOperation({ + commerce, +}: OperationContext) { + async function getAllProducts(opts?: { + variables?: ProductVariables + config?: Partial + preview?: boolean + }): Promise<{ products: Product[] }> + + async function getAllProducts({ + config: cfg, + variables = { first: 250 }, + }: { + query?: string + variables?: ProductVariables + config?: Partial + preview?: boolean + } = {}): Promise<{ products: Product[] | any[] }> { + const config = commerce.getConfig(cfg) + const { results } = await config.fetch('products', 'list', [ + { + limit: variables.first, + }, + ]) + const products = results.map((product: SwellProduct) => + normalizeProduct(product) + ) + + return { + products, + } + } + + return getAllProducts +} diff --git a/framework/swell/api/operations/get-page.ts b/framework/swell/api/operations/get-page.ts index b04002dda..99fbac04d 100644 --- a/framework/swell/api/operations/get-page.ts +++ b/framework/swell/api/operations/get-page.ts @@ -1,25 +1,54 @@ import { Page } from '../../schema' -import { SwellConfig, getConfig } from '..' +import { SwellConfig, Provider } from '..' +import { OperationContext, OperationOptions } from '@commerce/api/operations' +import { GetPageOperation } from '../../types/page' export type GetPageResult = T export type PageVariables = { - id: string + id: number } -async function getPage({ - url, - variables, - config, - preview, -}: { - url?: string - variables: PageVariables - config?: SwellConfig - preview?: boolean -}): Promise { - config = getConfig(config) - return {} -} +export default function getPageOperation({ + commerce, +}: OperationContext) { + async function getPage(opts: { + variables: T['variables'] + config?: Partial + preview?: boolean + }): Promise -export default getPage + async function getPage( + opts: { + variables: T['variables'] + config?: Partial + preview?: boolean + } & OperationOptions + ): Promise + + async function getPage({ + variables, + config, + }: { + query?: string + variables: T['variables'] + config?: Partial + preview?: boolean + }): Promise { + const { fetch, locale = 'en-US' } = commerce.getConfig(config) + const id = variables.id + const result = await fetch('content', 'get', ['pages', id]) + const page = result + + return { + page: page + ? { + ...page, + url: `/${locale}/${page.slug}`, + } + : null, + } + } + + return getPage +} diff --git a/framework/swell/api/operations/get-product.ts b/framework/swell/api/operations/get-product.ts new file mode 100644 index 000000000..c9a3d6f1d --- /dev/null +++ b/framework/swell/api/operations/get-product.ts @@ -0,0 +1,33 @@ +import { normalizeProduct } from '../../utils' + +import { Product } from '@commerce/types/product' +import { OperationContext } from '@commerce/api/operations' +import { Provider, SwellConfig } from '../' + +export default function getProductOperation({ + commerce, +}: OperationContext) { + async function getProduct({ + variables, + config: cfg, + }: { + query?: string + variables: { slug: string } + config?: Partial + preview?: boolean + }): Promise { + const config = commerce.getConfig(cfg) + + const product = await config.fetch('products', 'get', [variables.slug]) + + if (product && product.variants) { + product.variants = product.variants?.results + } + + return { + product: product ? normalizeProduct(product) : null, + } + } + + return getProduct +} diff --git a/framework/swell/api/operations/get-site-info.ts b/framework/swell/api/operations/get-site-info.ts new file mode 100644 index 000000000..36fcebf01 --- /dev/null +++ b/framework/swell/api/operations/get-site-info.ts @@ -0,0 +1,37 @@ +import getCategories from '../../utils/get-categories' +import getVendors, { Brands } from '../../utils/get-vendors' +import { Provider, SwellConfig } from '../' +import { OperationContext } from '@commerce/api/operations' +import { Category } from '@commerce/types/site' + +export type GetSiteInfoResult< + T extends { categories: any[]; brands: any[] } = { + categories: Category[] + brands: Brands + } +> = T + +export default function getSiteInfoOperation({ + commerce, +}: OperationContext) { + async function getSiteInfo({ + variables, + config: cfg, + }: { + query?: string + variables?: any + config?: Partial + preview?: boolean + } = {}): Promise { + const config = commerce.getConfig(cfg) + const categories = await getCategories(config) + const brands = await getVendors(config) + + return { + categories, + brands, + } + } + + return getSiteInfo +} diff --git a/framework/swell/api/operations/login.ts b/framework/swell/api/operations/login.ts new file mode 100644 index 000000000..33e1e2948 --- /dev/null +++ b/framework/swell/api/operations/login.ts @@ -0,0 +1,46 @@ +import type { ServerResponse } from 'http' +import type { + OperationContext, + OperationOptions, +} from '@commerce/api/operations' +import type { LoginOperation } from '../../types/login' +import { Provider, SwellConfig } from '..' + +export default function loginOperation({ + commerce, +}: OperationContext) { + async function login(opts: { + variables: T['variables'] + config?: Partial + res: ServerResponse + }): Promise + + async function login( + opts: { + variables: T['variables'] + config?: Partial + res: ServerResponse + } & OperationOptions + ): Promise + + async function login({ + variables, + res: response, + config: cfg, + }: { + query?: string + variables: T['variables'] + res: ServerResponse + config?: Partial + }): Promise { + const config = commerce.getConfig(cfg) + + const { data } = await config.fetch('account', 'login', [variables]) + + return { + result: data, + } + } + + return login +} diff --git a/framework/swell/api/utils/create-api-handler.ts b/framework/swell/api/utils/create-api-handler.ts deleted file mode 100644 index bd40a7ee4..000000000 --- a/framework/swell/api/utils/create-api-handler.ts +++ /dev/null @@ -1,58 +0,0 @@ -import type { NextApiHandler, NextApiRequest, NextApiResponse } from 'next' -import { SwellConfig, getConfig } from '..' - -export type SwellApiHandler< - T = any, - H extends SwellHandlers = {}, - Options extends {} = {} -> = ( - req: NextApiRequest, - res: NextApiResponse>, - config: SwellConfig, - handlers: H, - // Custom configs that may be used by a particular handler - options: Options -) => void | Promise - -export type SwellHandler = (options: { - req: NextApiRequest - res: NextApiResponse> - config: SwellConfig - body: Body -}) => void | Promise - -export type SwellHandlers = { - [k: string]: SwellHandler -} - -export type SwellApiResponse = { - data: T | null - errors?: { message: string; code?: string }[] -} - -export default function createApiHandler< - T = any, - H extends SwellHandlers = {}, - Options extends {} = {} ->( - handler: SwellApiHandler, - handlers: H, - defaultOptions: Options -) { - return function getApiHandler({ - config, - operations, - options, - }: { - config?: SwellConfig - 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/auth/use-login.tsx b/framework/swell/auth/use-login.tsx index 57c3ce921..587163d97 100644 --- a/framework/swell/auth/use-login.tsx +++ b/framework/swell/auth/use-login.tsx @@ -3,12 +3,12 @@ import type { MutationHook } from '@commerce/utils/types' import { CommerceError, ValidationError } from '@commerce/utils/errors' import useCustomer from '../customer/use-customer' import { - CustomerAccessTokenCreateInput, CustomerUserError, Mutation, MutationCheckoutCreateArgs, } from '../schema' import useLogin, { UseLogin } from '@commerce/auth/use-login' +import { LoginHook } from '../types/login' import { setCustomerToken } from '../utils' export default useLogin as UseLogin @@ -22,7 +22,7 @@ const getErrorMessage = ({ code, message }: CustomerUserError) => { return message } -export const handler: MutationHook = { +export const handler: MutationHook = { fetchOptions: { query: 'account', method: 'login', diff --git a/framework/swell/auth/use-logout.tsx b/framework/swell/auth/use-logout.tsx index ae17ba74e..7dc7411ec 100644 --- a/framework/swell/auth/use-logout.tsx +++ b/framework/swell/auth/use-logout.tsx @@ -3,10 +3,11 @@ import type { MutationHook } from '@commerce/utils/types' import useLogout, { UseLogout } from '@commerce/auth/use-logout' import useCustomer from '../customer/use-customer' import { getCustomerToken, setCustomerToken } from '../utils/customer-token' +import { LogoutHook } from '../types/logout' export default useLogout as UseLogout -export const handler: MutationHook = { +export const handler: MutationHook = { fetchOptions: { query: 'account', method: 'logout', diff --git a/framework/swell/auth/use-signup.tsx b/framework/swell/auth/use-signup.tsx index d417122fc..674b9861f 100644 --- a/framework/swell/auth/use-signup.tsx +++ b/framework/swell/auth/use-signup.tsx @@ -3,18 +3,12 @@ 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 { SignupHook } from '../types/signup' import handleLogin from '../utils/handle-login' export default useSignup as UseSignup -export const handler: MutationHook< - null, - {}, - CustomerCreateInput, - CustomerCreateInput -> = { +export const handler: MutationHook = { fetchOptions: { query: 'account', method: 'create', diff --git a/framework/swell/cart/use-add-item.tsx b/framework/swell/cart/use-add-item.tsx index 990514d42..e324a44d9 100644 --- a/framework/swell/cart/use-add-item.tsx +++ b/framework/swell/cart/use-add-item.tsx @@ -2,14 +2,14 @@ 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 { checkoutToCart } from './utils' import { getCheckoutId } from '../utils' import { useCallback } from 'react' +import { AddItemHook } from '../types/cart' export default useAddItem as UseAddItem -export const handler: MutationHook = { +export const handler: MutationHook = { fetchOptions: { query: 'cart', method: 'addItem', @@ -24,7 +24,7 @@ export const handler: MutationHook = { }) } const variables: { - product_id: string + product_id: string | undefined variant_id?: string checkoutId?: string quantity?: number diff --git a/framework/swell/cart/use-cart.tsx b/framework/swell/cart/use-cart.tsx index 531286ee6..885f889f5 100644 --- a/framework/swell/cart/use-cart.tsx +++ b/framework/swell/cart/use-cart.tsx @@ -1,13 +1,13 @@ 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' +import type { GetCartHook } from '@commerce/types/cart' 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-remove-item.tsx b/framework/swell/cart/use-remove-item.tsx index 8dc1ea713..7ef3af7cd 100644 --- a/framework/swell/cart/use-remove-item.tsx +++ b/framework/swell/cart/use-remove-item.tsx @@ -1,29 +1,21 @@ 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 useRemoveItem, { UseRemoveItem } from '@commerce/cart/use-remove-item' +import type { Cart, LineItem, RemoveItemHook } from '@commerce/types/cart' import useCart from './use-cart' import { checkoutToCart } from './utils' -import { Cart, LineItem } from '../types' -import { RemoveCartItemBody } from '@commerce/types' export type RemoveItemFn = T extends LineItem - ? (input?: RemoveItemInput) => Promise - : (input: RemoveItemInput) => Promise + ? (input?: RemoveItemActionInput) => Promise + : (input: RemoveItemActionInput) => Promise -export type RemoveItemInput = T extends LineItem - ? Partial - : RemoveItemInputBase +export type RemoveItemActionInput = T extends LineItem + ? Partial + : RemoveItemHook['actionInput'] export default useRemoveItem as UseRemoveItem @@ -36,36 +28,22 @@ export const handler = { input: { itemId }, options, fetch, - }: HookFetcherContext) { - const response = await fetch({ - ...options, - variables: [itemId], - }) + }: HookFetcherContext) { + const response = await fetch({ ...options, variables: [itemId] }) + return checkoutToCart(response) }, - useHook: ({ - fetch, - }: MutationHookContext) => < - T extends LineItem | undefined = undefined - >( - ctx: { item?: T } = {} - ) => { - const { item } = ctx + useHook: ({ fetch }: MutationHookContext) => () => { 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', - }) - } + return useCallback( + async function removeItem(input) { + const data = await fetch({ input: { itemId: input.id } }) + await mutate(data, false) - const data = await fetch({ input: { itemId } }) - await mutate(data, false) - return data - } - - return useCallback(removeItem as RemoveItemFn, [fetch, mutate]) + return data + }, + [fetch, mutate] + ) }, } diff --git a/framework/swell/cart/use-update-item.tsx b/framework/swell/cart/use-update-item.tsx index b1031b2e7..631a394f6 100644 --- a/framework/swell/cart/use-update-item.tsx +++ b/framework/swell/cart/use-update-item.tsx @@ -2,25 +2,30 @@ import { useCallback } from 'react' import debounce from 'lodash.debounce' import type { HookFetcherContext, + MutationHook, MutationHookContext, } from '@commerce/utils/types' import { ValidationError } from '@commerce/utils/errors' -import useUpdateItem, { - UpdateItemInput as UpdateItemInputBase, - UseUpdateItem, -} from '@commerce/cart/use-update-item' - +// import useUpdateItem, { +// UpdateItemInput as UpdateItemInputBase, +// UseUpdateItem, +// } from '@commerce/cart/use-update-item' +import useUpdateItem, { 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 { CartItemBody, LineItem } from '@commerce/types/cart' import { checkoutToCart } from './utils' - -export type UpdateItemInput = T extends LineItem - ? Partial> - : UpdateItemInputBase +import { UpdateItemHook } from '../types/cart' +// export type UpdateItemInput = T extends LineItem +// ? Partial> +// : UpdateItemInputBase export default useUpdateItem as UseUpdateItem +export type UpdateItemActionInput = T extends LineItem + ? Partial + : UpdateItemHook['actionInput'] + export const handler = { fetchOptions: { query: 'cart', @@ -30,7 +35,7 @@ export const handler = { input: { itemId, item }, options, fetch, - }: HookFetcherContext) { + }: 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) { @@ -52,9 +57,7 @@ export const handler = { return checkoutToCart(response) }, - useHook: ({ - fetch, - }: MutationHookContext) => < + useHook: ({ fetch }: MutationHookContext) => < T extends LineItem | undefined = undefined >( ctx: { @@ -66,7 +69,7 @@ export const handler = { const { mutate, data: cartData } = useCart() as any return useCallback( - debounce(async (input: UpdateItemInput) => { + debounce(async (input: UpdateItemActionInput) => { const firstLineItem = cartData.lineItems[0] const itemId = item?.id || firstLineItem.id const productId = item?.productId || firstLineItem.productId diff --git a/framework/swell/cart/utils/checkout-create.ts b/framework/swell/cart/utils/checkout-create.ts index 5ee3833c5..a4b82d849 100644 --- a/framework/swell/cart/utils/checkout-create.ts +++ b/framework/swell/cart/utils/checkout-create.ts @@ -9,7 +9,7 @@ export const checkoutCreate = async (fetch: any) => { }) if (!cart) { - const cart = await fetch({ + await fetch({ query: 'cart', method: 'setItems', variables: [[]], diff --git a/framework/swell/cart/utils/fetcher.ts b/framework/swell/cart/utils/fetcher.ts deleted file mode 100644 index 2e7ae15d3..000000000 --- a/framework/swell/cart/utils/fetcher.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { HookFetcherFn } from '@commerce/utils/types' -import { Cart } from '@commerce/types' -// 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 }, - fetch, -}) => { - let checkout - - // if (checkoutId) { - const data = await fetch({ - query: 'cart', - method: 'get', - // variables: { category: categoryId }, - }) - // checkout = data.node - // } - - // if (checkout?.completedAt || !checkoutId) { - // checkout = await checkoutCreate(fetch) - // } - - // TODO: Fix this type - // return checkoutToCart({ checkout } as any) - return normalizeCart(data) -} - -export default fetcher diff --git a/framework/swell/common/get-all-pages.ts b/framework/swell/common/get-all-pages.ts deleted file mode 100644 index 8d0b9cf36..000000000 --- a/framework/swell/common/get-all-pages.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { getConfig, SwellConfig } from '../api' - -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: SwellConfig - preview?: boolean -}): Promise => { - let { config, variables = { first: 250 } } = options ?? {} - config = getConfig(config) - 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 } -} - -export default getAllPages diff --git a/framework/swell/common/get-page.ts b/framework/swell/common/get-page.ts deleted file mode 100644 index dca317a19..000000000 --- a/framework/swell/common/get-page.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { getConfig, SwellConfig } from '../api' -import { Page } from './get-all-pages' - -type Variables = { - id: string -} - -export type GetPageResult = T - -const getPage = async (options: { - variables: Variables - config: SwellConfig - preview?: boolean -}): Promise => { - let { config, variables } = options ?? {} - - config = getConfig(config) - const { locale } = config - const { id } = variables - const result = await config.fetch('content', 'get', ['pages', id]) - const page = result - - return { - page: page - ? { - ...page, - url: `/${locale}/${page.slug}`, - } - : null, - } -} - -export default getPage diff --git a/framework/swell/common/get-site-info.ts b/framework/swell/common/get-site-info.ts deleted file mode 100644 index c7a06c52e..000000000 --- a/framework/swell/common/get-site-info.ts +++ /dev/null @@ -1,31 +0,0 @@ -import getCategories from '../utils/get-categories' -import getVendors, { Brands } from '../utils/get-vendors' -import { Category } from '@commerce/types' -import { getConfig, SwellConfig } from '../api' - -export type GetSiteInfoResult< - T extends { categories: any[]; brands: any[] } = { - categories: Category[] - brands: Brands - } -> = T - -const getSiteInfo = async (options?: { - variables?: any - config: SwellConfig - 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/customer/use-customer.tsx b/framework/swell/customer/use-customer.tsx index 632065d5a..50e85d3f6 100644 --- a/framework/swell/customer/use-customer.tsx +++ b/framework/swell/customer/use-customer.tsx @@ -1,11 +1,11 @@ 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 type { CustomerHook } from '../types/customer' export default useCustomer as UseCustomer -export const handler: SWRHook = { +export const handler: SWRHook = { fetchOptions: { query: 'account', method: 'get', @@ -25,26 +25,3 @@ 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/product/get-all-collections.ts b/framework/swell/product/get-all-collections.ts deleted file mode 100644 index 6b82ce449..000000000 --- a/framework/swell/product/get-all-collections.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { CollectionEdge } from '../schema' -import { getConfig, SwellConfig } from '../api' - -const getAllCollections = async (options?: { - variables?: any - config: SwellConfig - preview?: boolean -}) => { - let { config, variables = { limit: 25 } } = options ?? {} - config = getConfig(config) - - const response = await config.fetch('categories', 'list', { variables }) - const edges = response.results ?? [] - - 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 deleted file mode 100644 index 933eb73bc..000000000 --- a/framework/swell/product/get-all-product-paths.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { SwellProduct } from '../types' -import { getConfig, SwellConfig } from '../api' - -type ProductPath = { - path: string -} - -export type ProductPathNode = { - node: ProductPath -} - -type ReturnType = { - products: ProductPathNode[] -} - -const getAllProductPaths = async (options?: { - variables?: any - config?: SwellConfig - preview?: boolean -}): Promise => { - let { config, variables = [{ limit: 100 }] } = options ?? {} - config = getConfig(config) - - const { results } = await config.fetch('products', 'list', [ - { - limit: variables.first, - }, - ]) - - return { - products: results?.map(({ slug: handle }: SwellProduct) => ({ - node: { - path: `/${handle}`, - }, - })), - } -} - -export default getAllProductPaths diff --git a/framework/swell/product/get-all-products.ts b/framework/swell/product/get-all-products.ts deleted file mode 100644 index c0746efca..000000000 --- a/framework/swell/product/get-all-products.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { getConfig, SwellConfig } from '../api' -import { normalizeProduct } from '../utils/normalize' -import { Product } from '@commerce/types' -import { SwellProduct } from '../types' - -type Variables = { - first?: number - field?: string -} - -type ReturnType = { - products: Product[] -} - -const getAllProducts = async (options: { - variables?: Variables - config?: SwellConfig - preview?: boolean -}): Promise => { - let { config, variables = { first: 250 } } = options ?? {} - config = getConfig(config) - const { results } = await config.fetch('products', 'list', [ - { - limit: variables.first, - }, - ]) - const products = results.map((product: SwellProduct) => - normalizeProduct(product) - ) - - return { - products, - } -} - -export default getAllProducts diff --git a/framework/swell/product/get-product.ts b/framework/swell/product/get-product.ts deleted file mode 100644 index 0d75a57cd..000000000 --- a/framework/swell/product/get-product.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { GraphQLFetcherResult } from '@commerce/api' -import { getConfig, SwellConfig } from '../api' -import { normalizeProduct } from '../utils' - -type Variables = { - slug: string -} - -type ReturnType = { - product: any -} - -const getProduct = async (options: { - variables: Variables - config: SwellConfig - preview?: boolean -}): Promise => { - let { config, variables } = options ?? {} - config = getConfig(config) - - const product = await config.fetch('products', 'get', [variables.slug]) - - if (product && product.variants) { - product.variants = product.variants?.results - } - - return { - product: product ? normalizeProduct(product) : null, - } -} - -export default getProduct diff --git a/framework/swell/product/index.ts b/framework/swell/product/index.ts new file mode 100644 index 000000000..426a3edcd --- /dev/null +++ b/framework/swell/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/swell/product/use-search.tsx b/framework/swell/product/use-search.tsx index ce116caa3..bdcca3ff2 100644 --- a/framework/swell/product/use-search.tsx +++ b/framework/swell/product/use-search.tsx @@ -1,11 +1,8 @@ import { SWRHook } from '@commerce/utils/types' import useSearch, { UseSearch } from '@commerce/product/use-search' - import { normalizeProduct } from '../utils' - -import { Product } from '@commerce/types' - import { SwellProduct } from '../types' +import type { SearchProductsHook } from '../types/product' export default useSearch as UseSearch @@ -16,18 +13,9 @@ export type SearchProductsInput = { sort?: string } -export type SearchProductsData = { - products: Product[] - found: boolean -} - -export const handler: SWRHook< - SearchProductsData, - SearchProductsInput, - SearchProductsInput -> = { +export const handler: SWRHook = { fetchOptions: { - query: 'products', // String(Math.random()), + query: 'products', method: 'list', }, async fetcher({ input, options, fetch }) { diff --git a/framework/swell/provider.ts b/framework/swell/provider.ts index 0bcbd7888..aa7be31d4 100644 --- a/framework/swell/provider.ts +++ b/framework/swell/provider.ts @@ -1,3 +1,5 @@ +import { Provider } from '@commerce' + import { SWELL_CHECKOUT_URL_COOKIE, STORE_DOMAIN } from './const' import { handler as useCart } from './cart/use-cart' @@ -14,18 +16,15 @@ import { handler as useSignup } from './auth/use-signup' import fetcher from './fetcher' -export const swellProvider = { +export const swellProvider: Provider = { locale: 'en-us', cartCookie: SWELL_CHECKOUT_URL_COOKIE, - storeDomain: STORE_DOMAIN, + // storeDomain: STORE_DOMAIN, fetcher, cart: { useCart, useAddItem, useUpdateItem, useRemoveItem }, customer: { useCustomer }, products: { useSearch }, auth: { useLogin, useLogout, useSignup }, - features: { - wishlist: false, - }, } export type SwellProvider = typeof swellProvider diff --git a/framework/swell/types.ts b/framework/swell/types.ts index 71848d4a4..ad8ee3b68 100644 --- a/framework/swell/types.ts +++ b/framework/swell/types.ts @@ -1,4 +1,5 @@ -import * as Core from '@commerce/types' +import * as Core from '@commerce/types/cart' +import { Customer } from '@commerce/types' import { CheckoutLineItem } from './schema' export type SwellImage = { @@ -43,12 +44,18 @@ export type SwellVariant = { name: string price?: number stock_status?: string + __type?: 'MultipleChoiceOption' | undefined +} + +export interface SwellProductOptionValue { + id: string + label: string + hexColors?: string[] } export interface ProductOptionValue { label: string hexColors?: string[] - id: string } export type ProductOptions = { @@ -73,10 +80,7 @@ export interface SwellProduct { variants: any[] } -export interface SwellCustomer extends Core.Customer { - first_name: string - last_name: string -} +export type SwellCustomer = any export type SwellCheckout = { id: string @@ -106,17 +110,3 @@ 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/types/cart.ts b/framework/swell/types/cart.ts new file mode 100644 index 000000000..6ed5c6c64 --- /dev/null +++ b/framework/swell/types/cart.ts @@ -0,0 +1 @@ +export * from '@commerce/types/cart' diff --git a/framework/swell/types/checkout.ts b/framework/swell/types/checkout.ts new file mode 100644 index 000000000..4e2412ef6 --- /dev/null +++ b/framework/swell/types/checkout.ts @@ -0,0 +1 @@ +export * from '@commerce/types/checkout' diff --git a/framework/swell/types/common.ts b/framework/swell/types/common.ts new file mode 100644 index 000000000..b52c33a4d --- /dev/null +++ b/framework/swell/types/common.ts @@ -0,0 +1 @@ +export * from '@commerce/types/common' diff --git a/framework/swell/types/customer.ts b/framework/swell/types/customer.ts new file mode 100644 index 000000000..87c9afcc4 --- /dev/null +++ b/framework/swell/types/customer.ts @@ -0,0 +1 @@ +export * from '@commerce/types/customer' diff --git a/framework/swell/types/index.ts b/framework/swell/types/index.ts new file mode 100644 index 000000000..7ab0b7f64 --- /dev/null +++ b/framework/swell/types/index.ts @@ -0,0 +1,25 @@ +import * as Cart from './cart' +import * as Checkout from './checkout' +import * as Common from './common' +import * as Customer from './customer' +import * as Login from './login' +import * as Logout from './logout' +import * as Page from './page' +import * as Product from './product' +import * as Signup from './signup' +import * as Site from './site' +import * as Wishlist from './wishlist' + +export type { + Cart, + Checkout, + Common, + Customer, + Login, + Logout, + Page, + Product, + Signup, + Site, + Wishlist, +} diff --git a/framework/swell/types/login.ts b/framework/swell/types/login.ts new file mode 100644 index 000000000..ab11a420a --- /dev/null +++ b/framework/swell/types/login.ts @@ -0,0 +1,11 @@ +import * as Core from '@commerce/types/login' +import { LoginBody, LoginTypes } from '@commerce/types/login' + +export * from '@commerce/types/login' + +export type LoginHook = { + data: null + actionInput: LoginBody + fetcherInput: LoginBody + body: T['body'] +} diff --git a/framework/swell/types/logout.ts b/framework/swell/types/logout.ts new file mode 100644 index 000000000..9f0a466af --- /dev/null +++ b/framework/swell/types/logout.ts @@ -0,0 +1 @@ +export * from '@commerce/types/logout' diff --git a/framework/swell/types/page.ts b/framework/swell/types/page.ts new file mode 100644 index 000000000..20ec8ea38 --- /dev/null +++ b/framework/swell/types/page.ts @@ -0,0 +1 @@ +export * from '@commerce/types/page' diff --git a/framework/swell/types/product.ts b/framework/swell/types/product.ts new file mode 100644 index 000000000..c776d58fa --- /dev/null +++ b/framework/swell/types/product.ts @@ -0,0 +1 @@ +export * from '@commerce/types/product' diff --git a/framework/swell/types/signup.ts b/framework/swell/types/signup.ts new file mode 100644 index 000000000..58543c6f6 --- /dev/null +++ b/framework/swell/types/signup.ts @@ -0,0 +1 @@ +export * from '@commerce/types/signup' diff --git a/framework/swell/types/site.ts b/framework/swell/types/site.ts new file mode 100644 index 000000000..bfef69cf9 --- /dev/null +++ b/framework/swell/types/site.ts @@ -0,0 +1 @@ +export * from '@commerce/types/site' diff --git a/framework/swell/types/wishlist.ts b/framework/swell/types/wishlist.ts new file mode 100644 index 000000000..8907fbf82 --- /dev/null +++ b/framework/swell/types/wishlist.ts @@ -0,0 +1 @@ +export * from '@commerce/types/wishlist' diff --git a/framework/swell/utils/get-categories.ts b/framework/swell/utils/get-categories.ts index acf33a5b9..ab38bae96 100644 --- a/framework/swell/utils/get-categories.ts +++ b/framework/swell/utils/get-categories.ts @@ -1,5 +1,5 @@ import { SwellConfig } from '../api' -import { Category } from '@commerce/types' +import { Category } from '../types/site' const getCategories = async (config: SwellConfig): Promise => { const data = await config.fetch('categories', 'get') diff --git a/framework/swell/utils/normalize.ts b/framework/swell/utils/normalize.ts index b0cfb6193..2306f0662 100644 --- a/framework/swell/utils/normalize.ts +++ b/framework/swell/utils/normalize.ts @@ -1,6 +1,6 @@ -import { Product, Customer } from '@commerce/types' - -import { MoneyV2, ProductOption } from '../schema' +import { Customer } from '../types/customer' +import { Product, ProductOption } from '../types/product' +import { MoneyV2 } from '../schema' import type { Cart, @@ -10,6 +10,7 @@ import type { SwellImage, SwellVariant, ProductOptionValue, + SwellProductOptionValue, SwellCart, LineItem, } from '../types' @@ -21,8 +22,13 @@ const money = ({ amount, currencyCode }: MoneyV2) => { } } +type swellProductOption = { + id: string + name: string + values: any[] +} + type normalizedProductOption = { - __typename?: string id: string displayName: string values: ProductOptionValue[] @@ -32,11 +38,11 @@ const normalizeProductOption = ({ id, name: displayName = '', values = [], -}: ProductOption) => { +}: swellProductOption): ProductOption => { let returnValues = values.map((value) => { let output: any = { label: value.name, - id: value?.id || id, + // id: value?.id || id, } if (displayName.match(/colou?r/gi)) { output = { @@ -68,7 +74,7 @@ const normalizeProductImages = (images: SwellImage[]) => { const normalizeProductVariants = ( variants: SwellVariant[], - productOptions: normalizedProductOption[] + productOptions: swellProductOption[] ) => { return variants?.map( ({ id, name, price, option_value_ids: optionValueIds = [] }) => { @@ -79,22 +85,22 @@ const normalizeProductVariants = ( const options = optionValueIds.map((id) => { const matchingOption = productOptions.find((option) => { return option.values.find( - (value: ProductOptionValue) => value.id == id + (value: SwellProductOptionValue) => value.id == id ) }) return normalizeProductOption({ id, - name: matchingOption?.displayName ?? '', + name: matchingOption?.name ?? '', values, }) }) return { id, - name, + // name, // sku: sku ?? id, - price: price ?? null, - listPrice: price ?? null, + // price: price ?? null, + // listPrice: price ?? null, // requiresShipping: true, options, } @@ -116,11 +122,12 @@ export function normalizeProduct(swellProduct: SwellProduct): Product { } = swellProduct // ProductView accesses variants for each product const emptyVariants = [{ options: [], id, name }] + const productOptions = options ? options.map((o) => normalizeProductOption(o)) : [] const productVariants = variants - ? normalizeProductVariants(variants, productOptions) + ? normalizeProductVariants(variants, options) : [] const productImages = normalizeProductImages(images) diff --git a/framework/swell/swell-js.d.ts b/swell-js.d.ts similarity index 100% rename from framework/swell/swell-js.d.ts rename to swell-js.d.ts From b9cb71be6a1c4ddfad0548d68c00b0696153fdd5 Mon Sep 17 00:00:00 2001 From: Mirek Mencel Date: Tue, 15 Jun 2021 00:09:33 +0200 Subject: [PATCH 257/261] Fix Saleor's Demo link (#362) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 225c4d535..84807bcf6 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ Demo live at: [demo.vercel.store](https://demo.vercel.store/) - Swell Demo: https://swell.vercel.store/ - BigCommerce Demo: https://bigcommerce.vercel.store/ - Vendure Demo: https://vendure.vercel.store -- Saleor Demo: https://saleor.vercel.store/ +- Saleor Demo: https://saleorcommerce.vercel.store/ ## Features From 3c9b90f453d77efe369c62220eb1a4480a45aec3 Mon Sep 17 00:00:00 2001 From: Mirek Mencel Date: Tue, 15 Jun 2021 00:19:38 +0200 Subject: [PATCH 258/261] Fix Saleor's Demo link #2 (#363) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 84807bcf6..189192216 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ Demo live at: [demo.vercel.store](https://demo.vercel.store/) - Swell Demo: https://swell.vercel.store/ - BigCommerce Demo: https://bigcommerce.vercel.store/ - Vendure Demo: https://vendure.vercel.store -- Saleor Demo: https://saleorcommerce.vercel.store/ +- Saleor Demo: https://saleor-commerce.vercel.app/ ## Features From 78cc378a72c5b27db34b3903281b045520513c19 Mon Sep 17 00:00:00 2001 From: B Date: Tue, 15 Jun 2021 20:23:17 -0300 Subject: [PATCH 259/261] New Release (#371) * Custom Checkout Progress * Updates to Checkout * Custom Checkout Progress * Adding tabs * Adding Collapse * Adding Collapse * Improving Sidebar Scroll * Modif footer * Changes * More design updates * sidebar cart * More design updates * More design updates * More design updates * More design updates * Types * Types * Design Updates * More changes * More changes * More changes * Changes * Changes * Changes * New tailwind required changes * Sidebar Styling issues with Mobile * Latest changes - Normalizing cart * Styling Fixes * New changes * Changes * latest * Refactor and Renaming some UI Props * Adding Quantity Component * Adding Rating Component * Rating Component * More updates * User Select disabled, plus hidding horizontal scroll bars * Changes * Adding ProductOptions Component and more helpers * Styling updates * Styling updates * Fix for slim tags * Missmatch with RightArrow * Footer updates and some styles * Latest Updates * Latest Updates * Latest Updates * Removing Portal, since it's not needed. We might add it later I'd rather not to. * Removing Portal, since it's not needed. We might add it later I'd rather not to. * Sam backdrop filter * General UI Improvements * General UI Improvements * Search now with Geist Colors * Now with Geist Colors * Changes * Scroll for Mobile on IOs devises * LoadingDots Working (: * Changes * More Changes * Perf changes * More perf changes * Fade to the Nametags in the ProductCard * changes * Search issue ui * Search issue ui * Make sure to only refresh navbar and modals when required * Index revalidate * Fixed image issue * hide album scroll on windows * Fix scrollbar * Changing * Adding 404 with Layout * Removing Toast * Adding Assets * Adding Assets * Progress with LocalProvider * New productTag * Only images for the drop * changes * Empty SWRhooks * Adding Local Provider * Working local * Working view of a LocalProvider * More updates * Changes * Removed react-ticker * default to local if no env available * default to local if no env available * add missing `@` to css import * rewrite search rewrites to multiple pages * allow requests in getStaticProps to execute in parallel * make type import explicit * add a tsconfig.js file * use local provider in tsconfig.js * avoid a circular dependency * Saleor was not in the providers list * avoid circular dependency in bigcommerce * Adding more to the Local Provider (#366) * Adding more data * Adding more data * optimize assets (#370) * Optimize assets (#372) * optimize assets * remove assets * remove assets * cart enabled * Adding saleor * Changes with Webpack * Changes Co-authored-by: Luis Alvarez Co-authored-by: Tobias Koppers Co-authored-by: Shu Ding --- README.md | 8 +- assets/base.css | 54 +- components/auth/ForgotPassword.tsx | 2 +- components/auth/LoginView.tsx | 2 +- components/auth/SignUpView.tsx | 4 +- components/cart/CartItem/CartItem.module.css | 16 +- components/cart/CartItem/CartItem.tsx | 178 +- .../CartSidebarView.module.css | 10 +- .../cart/CartSidebarView/CartSidebarView.tsx | 98 +- .../CheckoutSidebarView.module.css | 7 + .../CheckoutSidebarView.tsx | 89 + .../checkout/CheckoutSidebarView/index.ts | 1 + .../PaymentMethodView.module.css | 17 + .../PaymentMethodView/PaymentMethodView.tsx | 84 + .../checkout/PaymentMethodView/index.ts | 1 + .../PaymentWidget/PaymentWidget.module.css | 4 + .../checkout/PaymentWidget/PaymentWidget.tsx | 29 + components/checkout/PaymentWidget/index.ts | 1 + .../ShippingView/ShippingView.module.css | 21 + .../checkout/ShippingView/ShippingView.tsx | 78 + components/checkout/ShippingView/index.ts | 1 + .../ShippingWidget/ShippingWidget.module.css | 4 + .../ShippingWidget/ShippingWidget.tsx | 33 + components/checkout/ShippingWidget/index.ts | 1 + components/common/Avatar/Avatar.tsx | 2 +- .../common/FeatureBar/FeatureBar.module.css | 4 +- components/common/Footer/Footer.module.css | 4 + components/common/Footer/Footer.tsx | 76 +- .../HomeAllProductsGrid.tsx | 4 +- .../common/I18nWidget/I18nWidget.module.css | 20 +- components/common/I18nWidget/I18nWidget.tsx | 2 +- components/common/Layout/Layout.tsx | 75 +- components/common/Navbar/Navbar.module.css | 16 +- components/common/Navbar/Navbar.tsx | 13 +- .../common/Searchbar/Searchbar.module.css | 16 +- components/common/Searchbar/Searchbar.tsx | 43 +- .../SidebarLayout/SidebarLayout.module.css | 20 + .../common/SidebarLayout/SidebarLayout.tsx | 50 + components/common/SidebarLayout/index.ts | 1 + .../common/UserNav/DropdownMenu.module.css | 10 +- components/common/UserNav/DropdownMenu.tsx | 2 +- components/common/UserNav/UserNav.module.css | 4 +- components/common/UserNav/UserNav.tsx | 32 +- .../icons/{RightArrow.tsx => ArrowRight.tsx} | 7 +- components/icons/ChevronDown.tsx | 20 + components/icons/ChevronLeft.tsx | 20 + components/icons/ChevronRight.tsx | 20 + components/icons/CreditCard.tsx | 1 + components/icons/Star.tsx | 16 + components/icons/index.ts | 12 +- .../ProductCard/ProductCard.module.css | 190 +- .../product/ProductCard/ProductCard.tsx | 164 +- .../product/ProductOptions/ProductOptions.tsx | 50 + components/product/ProductOptions/index.ts | 1 + .../ProductSidebar/ProductSidebar.module.css | 84 + .../product/ProductSidebar/ProductSidebar.tsx | 87 + components/product/ProductSidebar/index.ts | 1 + .../ProductSlider/ProductSlider.module.css | 126 +- .../product/ProductSlider/ProductSlider.tsx | 87 +- .../ProductSliderControl.module.css | 29 + .../ProductSliderControl.tsx | 31 + .../product/ProductSliderControl/index.ts | 1 + .../product/ProductTag/ProductTag.module.css | 30 + components/product/ProductTag/ProductTag.tsx | 36 + components/product/ProductTag/index.ts | 1 + .../ProductView/ProductView.module.css | 106 +- .../product/ProductView/ProductView.tsx | 208 +- components/product/Swatch/Swatch.module.css | 12 +- components/product/Swatch/Swatch.tsx | 86 +- components/product/helpers.ts | 16 +- components/product/index.ts | 1 + components/search.tsx | 439 + components/ui/Button/Button.module.css | 26 +- components/ui/Button/Button.tsx | 3 +- components/ui/Collapse/Collapse.module.css | 25 + components/ui/Collapse/Collapse.tsx | 46 + components/ui/Collapse/index.ts | 2 + components/ui/Container/Container.tsx | 9 +- components/ui/Grid/Grid.module.css | 44 +- components/ui/Grid/Grid.tsx | 4 +- components/ui/Hero/Hero.module.css | 27 +- components/ui/Hero/Hero.tsx | 22 +- components/ui/Input/Input.module.css | 2 +- components/ui/Input/Input.tsx | 4 +- .../ui/LoadingDots/LoadingDots.module.css | 29 +- components/ui/LoadingDots/LoadingDots.tsx | 6 +- components/ui/Marquee/Marquee.module.css | 20 +- components/ui/Marquee/Marquee.tsx | 22 +- components/ui/Modal/Modal.module.css | 11 +- components/ui/Modal/Modal.tsx | 53 +- components/ui/Quantity/Quantity.module.css | 27 + components/ui/Quantity/Quantity.tsx | 62 + components/ui/Quantity/index.ts | 2 + components/ui/Rating/Rating.module.css | 0 components/ui/Rating/Rating.tsx | 27 + components/ui/Rating/index.ts | 2 + components/ui/Sidebar/Sidebar.module.css | 13 +- components/ui/Sidebar/Sidebar.tsx | 49 +- components/ui/Skeleton/Skeleton.module.css | 16 +- components/ui/Skeleton/Skeleton.tsx | 12 +- components/ui/Text/Text.module.css | 6 +- components/ui/Text/Text.tsx | 7 +- components/ui/context.tsx | 109 +- components/ui/index.ts | 3 + .../WishlistButton/WishlistButton.module.css | 33 + .../WishlistButton/WishlistButton.tsx | 10 +- .../WishlistCard/WishlistCard.module.css | 2 +- framework/bigcommerce/api/index.ts | 8 +- .../api/utils/fetch-graphql-api.ts | 58 +- .../bigcommerce/api/utils/fetch-store-api.ts | 94 +- framework/bigcommerce/index.tsx | 3 +- framework/commerce/api/index.ts | 25 +- framework/commerce/config.js | 35 +- framework/commerce/new-provider.md | 3 +- framework/commerce/types/cart.ts | 20 +- framework/commerce/types/product.ts | 2 +- framework/local/.env.template | 1 + framework/local/README.md | 1 + framework/local/api/endpoints/cart/index.ts | 1 + .../local/api/endpoints/catalog/index.ts | 1 + .../local/api/endpoints/catalog/products.ts | 1 + .../local/api/endpoints/checkout/index.ts | 1 + .../local/api/endpoints/customer/index.ts | 1 + framework/local/api/endpoints/login/index.ts | 1 + framework/local/api/endpoints/logout/index.ts | 1 + framework/local/api/endpoints/signup/index.ts | 1 + .../local/api/endpoints/wishlist/index.tsx | 1 + framework/local/api/index.ts | 42 + .../local/api/operations/get-all-pages.ts | 19 + .../api/operations/get-all-product-paths.ts | 15 + .../local/api/operations/get-all-products.ts | 25 + .../api/operations/get-customer-wishlist.ts | 6 + framework/local/api/operations/get-page.ts | 13 + framework/local/api/operations/get-product.ts | 26 + .../local/api/operations/get-site-info.ts | 43 + framework/local/api/operations/index.ts | 6 + framework/local/api/utils/fetch-local.ts | 34 + framework/local/api/utils/fetch.ts | 3 + framework/local/auth/index.ts | 3 + framework/local/auth/use-login.tsx | 16 + framework/local/auth/use-logout.tsx | 17 + framework/local/auth/use-signup.tsx | 19 + framework/local/cart/index.ts | 4 + framework/local/cart/use-add-item.tsx | 17 + framework/local/cart/use-cart.tsx | 42 + framework/local/cart/use-remove-item.tsx | 18 + framework/local/cart/use-update-item.tsx | 18 + framework/local/commerce.config.json | 6 + framework/local/customer/index.ts | 1 + framework/local/customer/use-customer.tsx | 15 + framework/local/data.json | 235 + framework/local/fetcher.ts | 11 + framework/local/index.tsx | 32 + framework/local/next.config.js | 8 + framework/local/product/index.ts | 2 + framework/local/product/use-price.tsx | 2 + framework/local/product/use-search.tsx | 17 + framework/local/provider.ts | 21 + framework/local/wishlist/use-add-item.tsx | 13 + framework/local/wishlist/use-remove-item.tsx | 17 + framework/local/wishlist/use-wishlist.tsx | 43 + .../saleor/api/utils/fetch-graphql-api.ts | 2 +- .../shopify/api/operations/get-site-info.ts | 10 +- .../shopify/api/utils/fetch-graphql-api.ts | 47 +- framework/shopify/index.tsx | 3 +- .../shopify/utils/handle-fetch-response.ts | 2 +- framework/shopify/utils/normalize.ts | 1 + .../swell/api/operations/get-site-info.ts | 4 +- framework/vendure/auth/use-logout.tsx | 24 +- lib/search-props.tsx | 27 + next.config.js | 14 - package-lock.json | 11033 ++++++++++++++++ package.json | 6 +- pages/404.tsx | 35 + pages/[...pages].tsx | 13 +- pages/cart.tsx | 22 +- pages/index.tsx | 35 +- pages/orders.tsx | 8 +- pages/product/[slug].tsx | 26 +- pages/profile.tsx | 6 +- pages/search.tsx | 469 +- pages/search/[category].tsx | 16 + pages/search/designers/[name].tsx | 16 + pages/search/designers/[name]/[category].tsx | 16 + pages/wishlist.tsx | 8 +- public/assets/drop-shirt-0.png | Bin 0 -> 157663 bytes public/assets/drop-shirt-1.png | Bin 0 -> 260517 bytes public/assets/drop-shirt-2.png | Bin 0 -> 244812 bytes public/assets/drop-shirt.png | Bin 0 -> 157663 bytes public/assets/lightweight-jacket-0.png | Bin 0 -> 507021 bytes public/assets/lightweight-jacket-1.png | Bin 0 -> 476841 bytes public/assets/lightweight-jacket-2.png | Bin 0 -> 353198 bytes public/assets/t-shirt-0.png | Bin 0 -> 415845 bytes public/assets/t-shirt-1.png | Bin 0 -> 337401 bytes public/assets/t-shirt-2.png | Bin 0 -> 429830 bytes public/assets/t-shirt-3.png | Bin 0 -> 666930 bytes public/assets/t-shirt-4.png | Bin 0 -> 364452 bytes public/jacket.png | Bin 772153 -> 0 bytes tailwind.config.js | 24 +- tsconfig.js | 57 + tsconfig.json | 13 +- yarn.lock | 848 +- 202 files changed, 15406 insertions(+), 2201 deletions(-) create mode 100644 components/checkout/CheckoutSidebarView/CheckoutSidebarView.module.css create mode 100644 components/checkout/CheckoutSidebarView/CheckoutSidebarView.tsx create mode 100644 components/checkout/CheckoutSidebarView/index.ts create mode 100644 components/checkout/PaymentMethodView/PaymentMethodView.module.css create mode 100644 components/checkout/PaymentMethodView/PaymentMethodView.tsx create mode 100644 components/checkout/PaymentMethodView/index.ts create mode 100644 components/checkout/PaymentWidget/PaymentWidget.module.css create mode 100644 components/checkout/PaymentWidget/PaymentWidget.tsx create mode 100644 components/checkout/PaymentWidget/index.ts create mode 100644 components/checkout/ShippingView/ShippingView.module.css create mode 100644 components/checkout/ShippingView/ShippingView.tsx create mode 100644 components/checkout/ShippingView/index.ts create mode 100644 components/checkout/ShippingWidget/ShippingWidget.module.css create mode 100644 components/checkout/ShippingWidget/ShippingWidget.tsx create mode 100644 components/checkout/ShippingWidget/index.ts create mode 100644 components/common/SidebarLayout/SidebarLayout.module.css create mode 100644 components/common/SidebarLayout/SidebarLayout.tsx create mode 100644 components/common/SidebarLayout/index.ts rename components/icons/{RightArrow.tsx => ArrowRight.tsx} (79%) create mode 100644 components/icons/ChevronDown.tsx create mode 100644 components/icons/ChevronLeft.tsx create mode 100644 components/icons/ChevronRight.tsx create mode 100644 components/icons/Star.tsx create mode 100644 components/product/ProductOptions/ProductOptions.tsx create mode 100644 components/product/ProductOptions/index.ts create mode 100644 components/product/ProductSidebar/ProductSidebar.module.css create mode 100644 components/product/ProductSidebar/ProductSidebar.tsx create mode 100644 components/product/ProductSidebar/index.ts create mode 100644 components/product/ProductSliderControl/ProductSliderControl.module.css create mode 100644 components/product/ProductSliderControl/ProductSliderControl.tsx create mode 100644 components/product/ProductSliderControl/index.ts create mode 100644 components/product/ProductTag/ProductTag.module.css create mode 100644 components/product/ProductTag/ProductTag.tsx create mode 100644 components/product/ProductTag/index.ts create mode 100644 components/search.tsx create mode 100644 components/ui/Collapse/Collapse.module.css create mode 100644 components/ui/Collapse/Collapse.tsx create mode 100644 components/ui/Collapse/index.ts create mode 100644 components/ui/Quantity/Quantity.module.css create mode 100644 components/ui/Quantity/Quantity.tsx create mode 100644 components/ui/Quantity/index.ts create mode 100644 components/ui/Rating/Rating.module.css create mode 100644 components/ui/Rating/Rating.tsx create mode 100644 components/ui/Rating/index.ts create mode 100644 components/wishlist/WishlistButton/WishlistButton.module.css create mode 100644 framework/local/.env.template create mode 100644 framework/local/README.md create mode 100644 framework/local/api/endpoints/cart/index.ts create mode 100644 framework/local/api/endpoints/catalog/index.ts create mode 100644 framework/local/api/endpoints/catalog/products.ts create mode 100644 framework/local/api/endpoints/checkout/index.ts create mode 100644 framework/local/api/endpoints/customer/index.ts create mode 100644 framework/local/api/endpoints/login/index.ts create mode 100644 framework/local/api/endpoints/logout/index.ts create mode 100644 framework/local/api/endpoints/signup/index.ts create mode 100644 framework/local/api/endpoints/wishlist/index.tsx create mode 100644 framework/local/api/index.ts create mode 100644 framework/local/api/operations/get-all-pages.ts create mode 100644 framework/local/api/operations/get-all-product-paths.ts create mode 100644 framework/local/api/operations/get-all-products.ts create mode 100644 framework/local/api/operations/get-customer-wishlist.ts create mode 100644 framework/local/api/operations/get-page.ts create mode 100644 framework/local/api/operations/get-product.ts create mode 100644 framework/local/api/operations/get-site-info.ts create mode 100644 framework/local/api/operations/index.ts create mode 100644 framework/local/api/utils/fetch-local.ts create mode 100644 framework/local/api/utils/fetch.ts create mode 100644 framework/local/auth/index.ts create mode 100644 framework/local/auth/use-login.tsx create mode 100644 framework/local/auth/use-logout.tsx create mode 100644 framework/local/auth/use-signup.tsx create mode 100644 framework/local/cart/index.ts create mode 100644 framework/local/cart/use-add-item.tsx create mode 100644 framework/local/cart/use-cart.tsx create mode 100644 framework/local/cart/use-remove-item.tsx create mode 100644 framework/local/cart/use-update-item.tsx create mode 100644 framework/local/commerce.config.json create mode 100644 framework/local/customer/index.ts create mode 100644 framework/local/customer/use-customer.tsx create mode 100644 framework/local/data.json create mode 100644 framework/local/fetcher.ts create mode 100644 framework/local/index.tsx create mode 100644 framework/local/next.config.js create mode 100644 framework/local/product/index.ts create mode 100644 framework/local/product/use-price.tsx create mode 100644 framework/local/product/use-search.tsx create mode 100644 framework/local/provider.ts create mode 100644 framework/local/wishlist/use-add-item.tsx create mode 100644 framework/local/wishlist/use-remove-item.tsx create mode 100644 framework/local/wishlist/use-wishlist.tsx create mode 100644 lib/search-props.tsx create mode 100644 package-lock.json create mode 100644 pages/404.tsx create mode 100644 pages/search/[category].tsx create mode 100644 pages/search/designers/[name].tsx create mode 100644 pages/search/designers/[name]/[category].tsx create mode 100644 public/assets/drop-shirt-0.png create mode 100644 public/assets/drop-shirt-1.png create mode 100644 public/assets/drop-shirt-2.png create mode 100644 public/assets/drop-shirt.png create mode 100644 public/assets/lightweight-jacket-0.png create mode 100644 public/assets/lightweight-jacket-1.png create mode 100644 public/assets/lightweight-jacket-2.png create mode 100644 public/assets/t-shirt-0.png create mode 100644 public/assets/t-shirt-1.png create mode 100644 public/assets/t-shirt-2.png create mode 100644 public/assets/t-shirt-3.png create mode 100644 public/assets/t-shirt-4.png delete mode 100644 public/jacket.png create mode 100644 tsconfig.js diff --git a/README.md b/README.md index 189192216..7c69eb09d 100644 --- a/README.md +++ b/README.md @@ -64,6 +64,11 @@ That's it! Every provider defines the features that it supports under `framework/{provider}/commerce.config.json` +#### Features Available + +- wishlist +- customCheckout + #### 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) @@ -73,7 +78,8 @@ Every provider defines the features that it supports under `framework/{provider} ```json { "features": { - "wishlist": false + "wishlist": false, + "customCheckout": true } } ``` diff --git a/assets/base.css b/assets/base.css index e63ea1aa4..00081f459 100644 --- a/assets/base.css +++ b/assets/base.css @@ -15,21 +15,28 @@ --cyan: #22b8cf; --green: #37b679; --red: #da3c3c; - --pink: #e64980; --purple: #f81ce5; --blue: #0070f3; - --violet: #5f3dc4; - --violet-light: #7048e8; - --accents-0: #f8f9fa; - --accents-1: #f1f3f5; - --accents-2: #e9ecef; - --accents-3: #dee2e6; - --accents-4: #ced4da; - --accents-5: #adb5bd; - --accents-6: #868e96; - --accents-7: #495057; - --accents-8: #343a40; - --accents-9: #212529; + + --pink: #ff0080; + --pink-light: #ff379c; + + --magenta: #eb367f; + + --violet: #7928ca; + --violet-dark: #4c2889; + + --accent-0: #fff; + --accent-1: #fafafa; + --accent-2: #eaeaea; + --accent-3: #999999; + --accent-4: #888888; + --accent-5: #666666; + --accent-6: #444444; + --accent-7: #333333; + --accent-8: #111111; + --accent-9: #000; + --font-sans: -apple-system, system-ui, BlinkMacSystemFont, 'Helvetica Neue', 'Helvetica', sans-serif; } @@ -48,16 +55,16 @@ --text-primary: white; --text-secondary: black; - --accents-0: #212529; - --accents-1: #343a40; - --accents-2: #495057; - --accents-3: #868e96; - --accents-4: #adb5bd; - --accents-5: #ced4da; - --accents-6: #dee2e6; - --accents-7: #e9ecef; - --accents-8: #f1f3f5; - --accents-9: #f8f9fa; + --accent-9: #fff; + --accent-8: #fafafa; + --accent-7: #eaeaea; + --accent-6: #999999; + --accent-5: #888888; + --accent-4: #666666; + --accent-3: #444444; + --accent-2: #333333; + --accent-1: #111111; + --accent-0: #000; } *, @@ -84,6 +91,7 @@ body { -moz-osx-font-smoothing: grayscale; background-color: var(--primary); color: var(--text-primary); + overscroll-behavior-x: none; } body { diff --git a/components/auth/ForgotPassword.tsx b/components/auth/ForgotPassword.tsx index 597ee328e..dbac371c7 100644 --- a/components/auth/ForgotPassword.tsx +++ b/components/auth/ForgotPassword.tsx @@ -61,7 +61,7 @@ const ForgotPassword: FC = () => {

    - Do you have an account? + Do you have an account? {` `} = () => { Log In - Do you have an account? + Do you have an account? {` `} { const { closeSidebarIfPresent } = useUI() + const [removing, setRemoving] = useState(false) + const [quantity, setQuantity] = useState(item.quantity) + const removeItem = useRemoveItem() + const updateItem = useUpdateItem({ item }) const { price } = usePrice({ amount: item.variant.price * item.quantity, @@ -33,48 +40,28 @@ const CartItem = ({ currencyCode, }) - const updateItem = useUpdateItem({ item }) - const removeItem = useRemoveItem() - const [quantity, setQuantity] = useState(item.quantity) - const [removing, setRemoving] = useState(false) + const handleChange = async ({ + target: { value }, + }: ChangeEvent) => { + setQuantity(Number(value)) + await updateItem({ quantity: Number(value) }) + } - const updateQuantity = async (val: number) => { + const increaseQuantity = async (n = 1) => { + const val = Number(quantity) + n + setQuantity(val) await updateItem({ quantity: val }) } - const handleQuantity = (e: ChangeEvent) => { - const val = !e.target.value ? '' : Number(e.target.value) - - if (!val || (Number.isInteger(val) && val >= 0)) { - setQuantity(val) - } - } - const handleBlur = () => { - const val = Number(quantity) - - if (val !== item.quantity) { - updateQuantity(val) - } - } - const increaseQuantity = (n = 1) => { - const val = Number(quantity) + n - - if (Number.isInteger(val) && val >= 0) { - setQuantity(val) - updateQuantity(val) - } - } const handleRemove = async () => { setRemoving(true) - 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(item) } catch (error) { setRemoving(false) } } + // TODO: Add a type for this const options = (item as any).options @@ -87,79 +74,76 @@ const CartItem = ({ return (
  • -
    - - closeSidebarIfPresent()} - className={s.productImage} - width={150} - height={150} - src={item.variant.image!.url} - alt={item.variant.image!.altText} - unoptimized - /> - -
    -
    - - closeSidebarIfPresent()} - > -
    +
    + + closeSidebarIfPresent()} + className={s.productImage} + width={150} + height={150} + src={item.variant.image!.url} + alt={item.variant.image!.altText} + unoptimized + /> + +
    +
    + + closeSidebarIfPresent()} > {item.name} + + + {options && options.length > 0 && ( +
    + {options.map((option: ItemOption, i: number) => ( +
    + {option.name} + {option.name === 'Color' ? ( + + ) : ( + + {option.value} + + )} + {i === options.length - 1 ? '' : } +
    + ))}
    - {item.variant ? {item.variant.name} : ""} - - - {options && options.length > 0 ? ( -
    - {options.map((option: ItemOption, i: number) => ( - - {option.value} - {i === options.length - 1 ? '' : ', '} - - ))} -
    - ) : null} -
    - - - + )} + {variant === 'display' && ( +
    {quantity}x
    + )} +
    +
    + {price}
    -
    - {price} - -
    + {variant === 'default' && ( + increaseQuantity(1)} + decrease={() => increaseQuantity(-1)} + /> + )}
  • ) } diff --git a/components/cart/CartSidebarView/CartSidebarView.module.css b/components/cart/CartSidebarView/CartSidebarView.module.css index 9b94021ad..c9ffbed50 100644 --- a/components/cart/CartSidebarView/CartSidebarView.module.css +++ b/components/cart/CartSidebarView/CartSidebarView.module.css @@ -1,15 +1,11 @@ .root { - @apply h-full flex flex-col; + min-height: 100vh; } .root.empty { @apply bg-secondary text-secondary; } -.root.success { - @apply bg-green text-white; -} - -.root.error { - @apply bg-red text-white; +.lineItemsList { + @apply py-4 space-y-6 sm:py-0 sm:space-y-0 sm:divide-y sm:divide-accent-2 border-accent-2; } diff --git a/components/cart/CartSidebarView/CartSidebarView.tsx b/components/cart/CartSidebarView/CartSidebarView.tsx index 326390327..128b928a8 100644 --- a/components/cart/CartSidebarView/CartSidebarView.tsx +++ b/components/cart/CartSidebarView/CartSidebarView.tsx @@ -1,17 +1,17 @@ -import { FC } from 'react' import cn from 'classnames' import Link from 'next/link' -import CartItem from '../CartItem' +import { FC } from 'react' import s from './CartSidebarView.module.css' -import { Button } from '@components/ui' -import { UserNav } from '@components/common' +import CartItem from '../CartItem' +import { Button, Text } from '@components/ui' 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' +import SidebarLayout from '@components/common/SidebarLayout' const CartSidebarView: FC = () => { - const { closeSidebar } = useUI() + const { closeSidebar, setSidebarView } = useUI() const { data, isLoading, isEmpty } = useCart() const { price: subTotal } = usePrice( @@ -27,33 +27,18 @@ const CartSidebarView: FC = () => { } ) const handleClose = () => closeSidebar() + const goToCheckout = () => setSidebarView('CHECKOUT_VIEW') const error = null const success = null return ( -
    -
    -
    -
    - -
    -
    - -
    -
    -
    - {isLoading || isEmpty ? (
    @@ -62,7 +47,7 @@ const CartSidebarView: FC = () => {

    Your cart is empty

    -

    +

    Biscuit oat cake wafer icing ice cream tiramisu pudding cupcake.

    @@ -89,14 +74,11 @@ const CartSidebarView: FC = () => { <>
    -

    + My Cart -

    + -
      +
        {data!.lineItems.map((item: any) => ( {
    -
    -
    -
      -
    • - Subtotal - {subTotal} -
    • -
    • - Taxes - Calculated at checkout -
    • -
    • - Estimated Shipping - FREE -
    • -
    -
    - Total - {total} -
    +
    +
      +
    • + Subtotal + {subTotal} +
    • +
    • + Taxes + Calculated at checkout +
    • +
    • + Shipping + FREE +
    • +
    +
    + Total + {total} +
    +
    + {process.env.COMMERCE_CUSTOMCHECKOUT_ENABLED ? ( + + ) : ( + + )}
    -
    )} -
    + ) } diff --git a/components/checkout/CheckoutSidebarView/CheckoutSidebarView.module.css b/components/checkout/CheckoutSidebarView/CheckoutSidebarView.module.css new file mode 100644 index 000000000..34c1b487c --- /dev/null +++ b/components/checkout/CheckoutSidebarView/CheckoutSidebarView.module.css @@ -0,0 +1,7 @@ +.root { + min-height: calc(100vh - 322px); +} + +.lineItemsList { + @apply py-4 space-y-6 sm:py-0 sm:space-y-0 sm:divide-y sm:divide-accent-2 border-accent-2; +} diff --git a/components/checkout/CheckoutSidebarView/CheckoutSidebarView.tsx b/components/checkout/CheckoutSidebarView/CheckoutSidebarView.tsx new file mode 100644 index 000000000..fb562e7af --- /dev/null +++ b/components/checkout/CheckoutSidebarView/CheckoutSidebarView.tsx @@ -0,0 +1,89 @@ +import cn from 'classnames' +import Link from 'next/link' +import { FC } from 'react' +import CartItem from '@components/cart/CartItem' +import { Button, Text } from '@components/ui' +import { useUI } from '@components/ui/context' +import useCart from '@framework/cart/use-cart' +import usePrice from '@framework/product/use-price' +import ShippingWidget from '../ShippingWidget' +import PaymentWidget from '../PaymentWidget' +import SidebarLayout from '@components/common/SidebarLayout' +import s from './CheckoutSidebarView.module.css' + +const CheckoutSidebarView: FC = () => { + const { setSidebarView } = useUI() + const { data } = useCart() + + const { price: subTotal } = usePrice( + data && { + amount: Number(data.subtotalPrice), + currencyCode: data.currency.code, + } + ) + const { price: total } = usePrice( + data && { + amount: Number(data.totalPrice), + currencyCode: data.currency.code, + } + ) + + return ( + setSidebarView('CART_VIEW')} + > +
    + + Checkout + + + setSidebarView('PAYMENT_VIEW')} /> + setSidebarView('SHIPPING_VIEW')} /> + +
      + {data!.lineItems.map((item: any) => ( + + ))} +
    +
    + +
    +
      +
    • + Subtotal + {subTotal} +
    • +
    • + Taxes + Calculated at checkout +
    • +
    • + Shipping + FREE +
    • +
    +
    + Total + {total} +
    +
    + {/* Once data is correcly filled */} + {/* */} + +
    +
    +
    + ) +} + +export default CheckoutSidebarView diff --git a/components/checkout/CheckoutSidebarView/index.ts b/components/checkout/CheckoutSidebarView/index.ts new file mode 100644 index 000000000..168bc58f4 --- /dev/null +++ b/components/checkout/CheckoutSidebarView/index.ts @@ -0,0 +1 @@ +export { default } from './CheckoutSidebarView' diff --git a/components/checkout/PaymentMethodView/PaymentMethodView.module.css b/components/checkout/PaymentMethodView/PaymentMethodView.module.css new file mode 100644 index 000000000..f3880c72c --- /dev/null +++ b/components/checkout/PaymentMethodView/PaymentMethodView.module.css @@ -0,0 +1,17 @@ +.fieldset { + @apply flex flex-col my-3; +} + +.fieldset .label { + @apply text-accent-7 uppercase text-xs font-medium mb-2; +} + +.fieldset .input, +.fieldset .select { + @apply p-2 border border-accent-2 w-full text-sm font-normal; +} + +.fieldset .input:focus, +.fieldset .select:focus { + @apply outline-none shadow-outline-normal; +} diff --git a/components/checkout/PaymentMethodView/PaymentMethodView.tsx b/components/checkout/PaymentMethodView/PaymentMethodView.tsx new file mode 100644 index 000000000..a5f6f4b51 --- /dev/null +++ b/components/checkout/PaymentMethodView/PaymentMethodView.tsx @@ -0,0 +1,84 @@ +import { FC } from 'react' +import cn from 'classnames' +import { Button, Text } from '@components/ui' +import { useUI } from '@components/ui/context' +import s from './PaymentMethodView.module.css' +import SidebarLayout from '@components/common/SidebarLayout' + +const PaymentMethodView: FC = () => { + const { setSidebarView } = useUI() + + return ( + setSidebarView('CHECKOUT_VIEW')}> +
    + Payment Method +
    +
    + + +
    +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    +
    +
    +
    + + +
    +
    + + +
    +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    +
    + + +
    +
    + + +
    +
    +
    + + +
    +
    +
    +
    + +
    +
    + ) +} + +export default PaymentMethodView diff --git a/components/checkout/PaymentMethodView/index.ts b/components/checkout/PaymentMethodView/index.ts new file mode 100644 index 000000000..951b3c318 --- /dev/null +++ b/components/checkout/PaymentMethodView/index.ts @@ -0,0 +1 @@ +export { default } from './PaymentMethodView' diff --git a/components/checkout/PaymentWidget/PaymentWidget.module.css b/components/checkout/PaymentWidget/PaymentWidget.module.css new file mode 100644 index 000000000..38dcab0c0 --- /dev/null +++ b/components/checkout/PaymentWidget/PaymentWidget.module.css @@ -0,0 +1,4 @@ +.root { + @apply border border-accent-2 px-6 py-5 mb-4 text-center + flex items-center cursor-pointer hover:border-accent-4; +} diff --git a/components/checkout/PaymentWidget/PaymentWidget.tsx b/components/checkout/PaymentWidget/PaymentWidget.tsx new file mode 100644 index 000000000..e1892934e --- /dev/null +++ b/components/checkout/PaymentWidget/PaymentWidget.tsx @@ -0,0 +1,29 @@ +import { FC } from 'react' +import s from './PaymentWidget.module.css' +import { ChevronRight, CreditCard } from '@components/icons' + +interface ComponentProps { + onClick?: () => any +} + +const PaymentWidget: FC = ({ onClick }) => { + /* Shipping Address + Only available with checkout set to true - + This means that the provider does offer checkout functionality. */ + return ( +
    +
    + + + Add Payment Method + + {/* VISA #### #### #### 2345 */} +
    +
    + +
    +
    + ) +} + +export default PaymentWidget diff --git a/components/checkout/PaymentWidget/index.ts b/components/checkout/PaymentWidget/index.ts new file mode 100644 index 000000000..18cadea57 --- /dev/null +++ b/components/checkout/PaymentWidget/index.ts @@ -0,0 +1 @@ +export { default } from './PaymentWidget' diff --git a/components/checkout/ShippingView/ShippingView.module.css b/components/checkout/ShippingView/ShippingView.module.css new file mode 100644 index 000000000..157d3174e --- /dev/null +++ b/components/checkout/ShippingView/ShippingView.module.css @@ -0,0 +1,21 @@ +.fieldset { + @apply flex flex-col my-3; +} + +.fieldset .label { + @apply text-accent-7 uppercase text-xs font-medium mb-2; +} + +.fieldset .input, +.fieldset .select { + @apply p-2 border border-accent-2 w-full text-sm font-normal; +} + +.fieldset .input:focus, +.fieldset .select:focus { + @apply outline-none shadow-outline-normal; +} + +.radio { + @apply bg-black; +} diff --git a/components/checkout/ShippingView/ShippingView.tsx b/components/checkout/ShippingView/ShippingView.tsx new file mode 100644 index 000000000..1d03a2aac --- /dev/null +++ b/components/checkout/ShippingView/ShippingView.tsx @@ -0,0 +1,78 @@ +import { FC } from 'react' +import cn from 'classnames' +import s from './ShippingView.module.css' +import Button from '@components/ui/Button' +import { useUI } from '@components/ui/context' +import SidebarLayout from '@components/common/SidebarLayout' + +const PaymentMethodView: FC = () => { + const { setSidebarView } = useUI() + + return ( + setSidebarView('CHECKOUT_VIEW')}> +
    +

    + Shipping +

    +
    +
    + + Same as billing address +
    +
    + + + Use a different shipping address + +
    +
    +
    +
    + + +
    +
    + + +
    +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    +
    + + +
    +
    + + +
    +
    +
    + + +
    +
    +
    +
    + +
    +
    + ) +} + +export default PaymentMethodView diff --git a/components/checkout/ShippingView/index.ts b/components/checkout/ShippingView/index.ts new file mode 100644 index 000000000..428e7e4fe --- /dev/null +++ b/components/checkout/ShippingView/index.ts @@ -0,0 +1 @@ +export { default } from './ShippingView' diff --git a/components/checkout/ShippingWidget/ShippingWidget.module.css b/components/checkout/ShippingWidget/ShippingWidget.module.css new file mode 100644 index 000000000..38dcab0c0 --- /dev/null +++ b/components/checkout/ShippingWidget/ShippingWidget.module.css @@ -0,0 +1,4 @@ +.root { + @apply border border-accent-2 px-6 py-5 mb-4 text-center + flex items-center cursor-pointer hover:border-accent-4; +} diff --git a/components/checkout/ShippingWidget/ShippingWidget.tsx b/components/checkout/ShippingWidget/ShippingWidget.tsx new file mode 100644 index 000000000..b072178b0 --- /dev/null +++ b/components/checkout/ShippingWidget/ShippingWidget.tsx @@ -0,0 +1,33 @@ +import { FC } from 'react' +import s from './ShippingWidget.module.css' +import { ChevronRight, MapPin } from '@components/icons' +import cn from 'classnames' + +interface ComponentProps { + onClick?: () => any +} + +const ShippingWidget: FC = ({ onClick }) => { + /* Shipping Address + Only available with checkout set to true - + This means that the provider does offer checkout functionality. */ + return ( +
    +
    + + + Add Shipping Address + + {/* + 1046 Kearny Street.
    + San Franssisco, California +
    */} +
    +
    + +
    +
    + ) +} + +export default ShippingWidget diff --git a/components/checkout/ShippingWidget/index.ts b/components/checkout/ShippingWidget/index.ts new file mode 100644 index 000000000..88e6dca4b --- /dev/null +++ b/components/checkout/ShippingWidget/index.ts @@ -0,0 +1 @@ +export { default } from './ShippingWidget' diff --git a/components/common/Avatar/Avatar.tsx b/components/common/Avatar/Avatar.tsx index f78aa1d01..663538450 100644 --- a/components/common/Avatar/Avatar.tsx +++ b/components/common/Avatar/Avatar.tsx @@ -14,7 +14,7 @@ const Avatar: FC = ({}) => {
    {/* Add an image - We're generating a gradient as placeholder */}
    diff --git a/components/common/FeatureBar/FeatureBar.module.css b/components/common/FeatureBar/FeatureBar.module.css index 419fd4b08..a3cb61cd2 100644 --- a/components/common/FeatureBar/FeatureBar.module.css +++ b/components/common/FeatureBar/FeatureBar.module.css @@ -1,9 +1,7 @@ .root { @apply text-center p-6 bg-primary text-sm flex-row justify-center items-center font-medium fixed bottom-0 w-full z-30 transition-all duration-300 ease-out; -} -@screen md { - .root { + @screen md { @apply flex text-left; } } diff --git a/components/common/Footer/Footer.module.css b/components/common/Footer/Footer.module.css index 259318ecf..2ba492086 100644 --- a/components/common/Footer/Footer.module.css +++ b/components/common/Footer/Footer.module.css @@ -1,3 +1,7 @@ +.root { + @apply border-t border-accent-2; +} + .link { & > svg { @apply transform duration-75 ease-linear; diff --git a/components/common/Footer/Footer.tsx b/components/common/Footer/Footer.tsx index 4190815ec..04b80404e 100644 --- a/components/common/Footer/Footer.tsx +++ b/components/common/Footer/Footer.tsx @@ -15,65 +15,50 @@ interface Props { pages?: Page[] } -const LEGAL_PAGES = ['terms-of-use', 'shipping-returns', 'privacy-policy'] +const links = [ + { + name: 'Home', + url: '/', + }, +] const Footer: FC = ({ className, pages }) => { - const { sitePages, legalPages } = usePages(pages) - const rootClassName = cn(className) + const { sitePages } = usePages(pages) + const rootClassName = cn(s.root, className) return (
    -
    +
    -
    - +
    -
    - -
    -
    +
    @@ -81,12 +66,12 @@ const Footer: FC = ({ className, pages }) => {
    -
    +
    © 2020 ACME, Inc. All rights reserved.
    -
    - Crafted by +
    + Created by = ({ className, pages }) => { className="text-primary" > @@ -109,34 +94,21 @@ const Footer: FC = ({ className, pages }) => { function usePages(pages?: Page[]) { const { locale } = useRouter() const sitePages: Page[] = [] - const legalPages: Page[] = [] if (pages) { pages.forEach((page) => { const slug = page.url && getSlug(page.url) - if (!slug) return if (locale && !slug.startsWith(`${locale}/`)) return - - if (isLegalPage(slug, locale)) { - legalPages.push(page) - } else { - sitePages.push(page) - } + sitePages.push(page) }) } return { sitePages: sitePages.sort(bySortOrder), - legalPages: legalPages.sort(bySortOrder), } } -const isLegalPage = (slug: string, locale?: string) => - locale - ? LEGAL_PAGES.some((p) => `${locale}/${p}` === slug) - : LEGAL_PAGES.includes(slug) - // Sort pages by the sort order assigned in the BC dashboard function bySortOrder(a: Page, b: Page) { return (a.sort_order ?? 0) - (b.sort_order ?? 0) diff --git a/components/common/HomeAllProductsGrid/HomeAllProductsGrid.tsx b/components/common/HomeAllProductsGrid/HomeAllProductsGrid.tsx index 8d8ea1adf..0a40bff2e 100644 --- a/components/common/HomeAllProductsGrid/HomeAllProductsGrid.tsx +++ b/components/common/HomeAllProductsGrid/HomeAllProductsGrid.tsx @@ -28,7 +28,7 @@ const HomeAllProductsGrid: FC = ({ {categories.map((cat: any) => ( -
  • +
  • {cat.name} @@ -42,7 +42,7 @@ const HomeAllProductsGrid: FC = ({
  • {brands.flatMap(({ node }: any) => ( -
  • +
  • {node.name} diff --git a/components/common/I18nWidget/I18nWidget.module.css b/components/common/I18nWidget/I18nWidget.module.css index f100fd475..269aa5f61 100644 --- a/components/common/I18nWidget/I18nWidget.module.css +++ b/components/common/I18nWidget/I18nWidget.module.css @@ -3,11 +3,11 @@ } .button { - @apply h-10 px-2 rounded-md border border-accents-2 flex items-center justify-center; + @apply h-10 px-2 rounded-md border border-accent-2 flex items-center justify-center transition-colors ease-linear; } .button:hover { - @apply border-accents-4 shadow-sm; + @apply border-accent-3 shadow-sm; } .button:focus { @@ -16,16 +16,14 @@ .dropdownMenu { @apply fixed right-0 top-12 mt-2 origin-top-right outline-none bg-primary z-40 w-full h-full; -} -@screen lg { - .dropdownMenu { - @apply absolute border border-accents-1 shadow-lg w-56 h-auto; + @screen lg { + @apply absolute border border-accent-1 shadow-lg w-56 h-auto; } } -@screen md { - .closeButton { +.closeButton { + @screen md { @apply hidden; } } @@ -36,9 +34,13 @@ } .item:hover { - @apply bg-accents-1; + @apply bg-accent-1; } .icon { + transition: transform 0.2s ease; +} + +.icon.active { transform: rotate(180deg); } diff --git a/components/common/I18nWidget/I18nWidget.tsx b/components/common/I18nWidget/I18nWidget.tsx index fbe67a4c1..58135f12a 100644 --- a/components/common/I18nWidget/I18nWidget.tsx +++ b/components/common/I18nWidget/I18nWidget.tsx @@ -59,7 +59,7 @@ const I18nWidget: FC = () => { /> {options && ( - + )} diff --git a/components/common/Layout/Layout.tsx b/components/common/Layout/Layout.tsx index c84c52693..ff6d72aaf 100644 --- a/components/common/Layout/Layout.tsx +++ b/components/common/Layout/Layout.tsx @@ -1,15 +1,19 @@ -import React, { FC } from 'react' -import { useRouter } from 'next/router' -import dynamic from 'next/dynamic' import cn from 'classnames' -import type { Page } from '@commerce/types/page' -import type { Category } from '@commerce/types/site' +import React, { FC } from 'react' +import dynamic from 'next/dynamic' +import { useRouter } from 'next/router' import { CommerceProvider } from '@framework' -import { useAcceptCookies } from '@lib/hooks/useAcceptCookies' import { useUI } from '@components/ui/context' +import type { Page } from '@commerce/types/page' import { Navbar, Footer } from '@components/common' -import { Sidebar, Button, Modal, LoadingDots } from '@components/ui' +import type { Category } from '@commerce/types/site' +import ShippingView from '@components/checkout/ShippingView' import CartSidebarView from '@components/cart/CartSidebarView' +import { useAcceptCookies } from '@lib/hooks/useAcceptCookies' +import { Sidebar, Button, Modal, LoadingDots } from '@components/ui' +import PaymentMethodView from '@components/checkout/PaymentMethodView' +import CheckoutSidebarView from '@components/checkout/CheckoutSidebarView' + import LoginView from '@components/auth/LoginView' import s from './Layout.module.css' @@ -45,15 +49,53 @@ interface Props { } } +const ModalView: FC<{ modalView: string; closeModal(): any }> = ({ + modalView, + closeModal, +}) => { + return ( + + {modalView === 'LOGIN_VIEW' && } + {modalView === 'SIGNUP_VIEW' && } + {modalView === 'FORGOT_VIEW' && } + + ) +} + +const ModalUI: FC = () => { + const { displayModal, closeModal, modalView } = useUI() + return displayModal ? ( + + ) : null +} + +const SidebarView: FC<{ sidebarView: string; closeSidebar(): any }> = ({ + sidebarView, + closeSidebar, +}) => { + return ( + + {sidebarView === 'CART_VIEW' && } + {sidebarView === 'CHECKOUT_VIEW' && } + {sidebarView === 'PAYMENT_VIEW' && } + {sidebarView === 'SHIPPING_VIEW' && } + + ) +} + +const SidebarUI: FC = () => { + const { displaySidebar, closeSidebar, sidebarView } = useUI() + return displaySidebar ? ( + + ) : null +} + const Layout: FC = ({ children, pageProps: { categories = [], ...pageProps }, }) => { - const { displaySidebar, displayModal, closeSidebar, closeModal, modalView } = - useUI() const { acceptedCookies, onAcceptCookies } = useAcceptCookies() const { locale = 'en-US' } = useRouter() - const navBarlinks = categories.slice(0, 2).map((c) => ({ label: c.name, href: `/search/${c.slug}`, @@ -65,17 +107,8 @@ const Layout: FC = ({
    {children}
    - - - {modalView === 'LOGIN_VIEW' && } - {modalView === 'SIGNUP_VIEW' && } - {modalView === 'FORGOT_VIEW' && } - - - - - - + +
  • logout()} > Logout diff --git a/components/common/UserNav/UserNav.module.css b/components/common/UserNav/UserNav.module.css index cd1a6ce1f..92f62c10d 100644 --- a/components/common/UserNav/UserNav.module.css +++ b/components/common/UserNav/UserNav.module.css @@ -10,7 +10,7 @@ @apply mr-6 cursor-pointer relative transition ease-in-out duration-100 flex items-center outline-none text-primary; &:hover { - @apply text-accents-6 transition scale-110 duration-100; + @apply text-accent-6 transition scale-110 duration-100; } &:last-child { @@ -24,7 +24,7 @@ } .bagCount { - @apply border border-accents-1 bg-secondary text-secondary absolute rounded-full right-3 top-3 flex items-center justify-center font-bold text-xs; + @apply border border-accent-1 bg-secondary text-secondary absolute rounded-full right-3 top-3 flex items-center justify-center font-bold text-xs; padding-left: 2.5px; padding-right: 2.5px; min-width: 1.25rem; diff --git a/components/common/UserNav/UserNav.tsx b/components/common/UserNav/UserNav.tsx index 83422a8cf..16e7279bb 100644 --- a/components/common/UserNav/UserNav.tsx +++ b/components/common/UserNav/UserNav.tsx @@ -24,21 +24,21 @@ const UserNav: FC = ({ className }) => { return ( ) } diff --git a/components/icons/RightArrow.tsx b/components/icons/ArrowRight.tsx similarity index 79% rename from components/icons/RightArrow.tsx rename to components/icons/ArrowRight.tsx index b7a1579c8..e644951d9 100644 --- a/components/icons/RightArrow.tsx +++ b/components/icons/ArrowRight.tsx @@ -1,23 +1,22 @@ -const RightArrow = ({ ...props }) => { +const ArrowRight = ({ ...props }) => { return ( { ) } -export default RightArrow +export default ArrowRight diff --git a/components/icons/ChevronDown.tsx b/components/icons/ChevronDown.tsx new file mode 100644 index 000000000..542e8056d --- /dev/null +++ b/components/icons/ChevronDown.tsx @@ -0,0 +1,20 @@ +const ChevronDown = ({ ...props }) => { + return ( + + + + ) +} + +export default ChevronDown diff --git a/components/icons/ChevronLeft.tsx b/components/icons/ChevronLeft.tsx new file mode 100644 index 000000000..4efb6a522 --- /dev/null +++ b/components/icons/ChevronLeft.tsx @@ -0,0 +1,20 @@ +const ChevronLeft = ({ ...props }) => { + return ( + + + + ) +} + +export default ChevronLeft diff --git a/components/icons/ChevronRight.tsx b/components/icons/ChevronRight.tsx new file mode 100644 index 000000000..d72b77a32 --- /dev/null +++ b/components/icons/ChevronRight.tsx @@ -0,0 +1,20 @@ +const ChevronUp = ({ ...props }) => { + return ( + + + + ) +} + +export default ChevronUp diff --git a/components/icons/CreditCard.tsx b/components/icons/CreditCard.tsx index 85504d8ba..958c31193 100644 --- a/components/icons/CreditCard.tsx +++ b/components/icons/CreditCard.tsx @@ -10,6 +10,7 @@ const CreditCard = ({ ...props }) => { strokeLinejoin="round" fill="none" shapeRendering="geometricPrecision" + {...props} > diff --git a/components/icons/Star.tsx b/components/icons/Star.tsx new file mode 100644 index 000000000..d98f55e1d --- /dev/null +++ b/components/icons/Star.tsx @@ -0,0 +1,16 @@ +const Star = ({ ...props }) => { + return ( + + + + ) +} + +export default Star diff --git a/components/icons/index.ts b/components/icons/index.ts index 1f2089085..97eef6d58 100644 --- a/components/icons/index.ts +++ b/components/icons/index.ts @@ -2,17 +2,21 @@ export { default as Bag } from './Bag' export { default as Heart } from './Heart' export { default as Trash } from './Trash' export { default as Cross } from './Cross' -export { default as ArrowLeft } from './ArrowLeft' export { default as Plus } from './Plus' export { default as Minus } from './Minus' export { default as Check } from './Check' export { default as Sun } from './Sun' export { default as Moon } from './Moon' export { default as Github } from './Github' -export { default as DoubleChevron } from './DoubleChevron' -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 Star } from './Star' +export { default as ArrowLeft } from './ArrowLeft' +export { default as ArrowRight } from './ArrowRight' export { default as CreditCard } from './CreditCard' +export { default as ChevronUp } from './ChevronUp' +export { default as ChevronLeft } from './ChevronLeft' +export { default as ChevronDown } from './ChevronDown' +export { default as ChevronRight } from './ChevronRight' +export { default as DoubleChevron } from './DoubleChevron' diff --git a/components/product/ProductCard/ProductCard.module.css b/components/product/ProductCard/ProductCard.module.css index 1484cfaa4..d5d441fea 100644 --- a/components/product/ProductCard/ProductCard.module.css +++ b/components/product/ProductCard/ProductCard.module.css @@ -1,136 +1,114 @@ .root { @apply relative max-h-full w-full box-border overflow-hidden bg-no-repeat bg-center bg-cover transition-transform - ease-linear cursor-pointer; + ease-linear cursor-pointer inline-block bg-accent-1; height: 100% !important; +} - &:hover { - & .squareBg:before { - transform: scale(0.98); - } - - & .productImage { - transform: scale(1.2625); - } - - & .productTitle > span, - & .productPrice, - & .wishlistButton { - @apply bg-secondary text-secondary; - } - - &:nth-child(6n + 1) .productTitle > span, - &:nth-child(6n + 1) .productPrice, - &:nth-child(6n + 1) .wishlistButton { - @apply bg-violet text-white; - } - - &:nth-child(6n + 5) .productTitle > span, - &:nth-child(6n + 5) .productPrice, - &:nth-child(6n + 5) .wishlistButton { - @apply bg-blue text-white; - } - - &:nth-child(6n + 3) .productTitle > span, - &:nth-child(6n + 3) .productPrice, - &:nth-child(6n + 3) .wishlistButton { - @apply bg-pink text-white; - } - - &:nth-child(6n + 6) .productTitle > span, - &:nth-child(6n + 6) .productPrice, - &:nth-child(6n + 6) .wishlistButton { - @apply bg-cyan text-white; - } +.root:hover { + & .productImage { + transform: scale(1.2625); } - &:nth-child(6n + 1) .squareBg { - @apply bg-violet; + & .header .name span, + & .header .price, + & .wishlistButton { + @apply bg-secondary text-secondary; } - &:nth-child(6n + 5) .squareBg { - @apply bg-blue; + &:nth-child(6n + 1) .header .name span, + &:nth-child(6n + 1) .header .price, + &:nth-child(6n + 1) .wishlistButton { + @apply bg-violet text-white; } - &:nth-child(6n + 3) .squareBg { - @apply bg-pink; + &:nth-child(6n + 5) .header .name span, + &:nth-child(6n + 5) .header .price, + &:nth-child(6n + 5) .wishlistButton { + @apply bg-blue text-white; } - &:nth-child(6n + 6) .squareBg { - @apply bg-cyan; + &:nth-child(6n + 3) .header .name span, + &:nth-child(6n + 3) .header .price, + &:nth-child(6n + 3) .wishlistButton { + @apply bg-pink text-white; + } + + &:nth-child(6n + 6) .header .name span, + &:nth-child(6n + 6) .header .price, + &:nth-child(6n + 6) .wishlistButton { + @apply bg-cyan text-white; } } -.squareBg, -.productTitle > span, -.productPrice, -.wishlistButton { - @apply transition-colors ease-in-out duration-500; +.header { + @apply transition-colors ease-in-out duration-500 + absolute top-0 left-0 z-20 pr-16; } -.squareBg { - @apply transition-colors absolute inset-0 z-0; - background-color: #212529; -} - -.squareBg:before { - @apply transition ease-in-out duration-500 bg-repeat-space w-full h-full block; - background-image: url('/bg-products.svg'); - content: ''; -} - -.simple { - & .squareBg { - @apply bg-accents-0 !important; - background-image: url('/bg-products.svg'); - } - - & .productTitle { - @apply pt-2; - font-size: 1rem; - - & span { - @apply leading-extra-loose; - } - } - - & .productPrice { - @apply text-sm; - } -} - -.productTitle { - @apply pt-0 max-w-full w-full leading-extra-loose; +.header .name { + @apply pt-0 max-w-full w-full leading-extra-loose + transition-colors ease-in-out duration-500; font-size: 2rem; letter-spacing: 0.4px; - - & span { - @apply py-4 px-6 bg-primary text-primary font-bold; - font-size: inherit; - letter-spacing: inherit; - box-decoration-break: clone; - -webkit-box-decoration-break: clone; - } } -.productPrice { - @apply py-4 px-6 bg-primary text-primary font-semibold inline-block text-sm leading-6; - letter-spacing: 0.4px; +.header .name span { + @apply py-4 px-6 bg-primary text-primary font-bold + transition-colors ease-in-out duration-500; + font-size: inherit; + letter-spacing: inherit; + box-decoration-break: clone; + -webkit-box-decoration-break: clone; } -.wishlistButton { - @apply w-10 h-10 flex ml-auto items-center justify-center bg-primary text-primary font-semibold text-xs leading-6 cursor-pointer; +.header .price { + @apply pt-2 px-6 pb-4 text-sm bg-primary text-accent-9 + font-semibold inline-block tracking-wide + transition-colors ease-in-out duration-500; } .imageContainer { - @apply flex items-center justify-center; - overflow: hidden; - - & > div { - min-width: 100%; - } + @apply flex items-center justify-center overflow-hidden; } -.productImage { - @apply transform transition-transform duration-500 object-cover scale-120; +.imageContainer > div { + min-width: 100%; +} + +.imageContainer .productImage { + @apply transform transition-transform duration-500 + object-cover scale-120; +} + +.root .wishlistButton { + @apply top-0 right-0 z-30 absolute; +} + +/* Variant Simple */ +.simple .header .name { + @apply pt-2 text-lg leading-10 -mt-1; +} + +.simple .header .price { + @apply text-sm; +} + +/* Variant Slim */ +.slim { + @apply bg-transparent relative overflow-hidden + box-border; +} + +.slim .header { + @apply absolute inset-0 flex items-center justify-end mr-8 z-20; +} + +.slim span { + @apply bg-accent-9 text-accent-0 inline-block p-3 + font-bold text-xl break-words; +} + +.root:global(.secondary) .header span { + @apply bg-accent-0 text-accent-9; } diff --git a/components/product/ProductCard/ProductCard.tsx b/components/product/ProductCard/ProductCard.tsx index 69a6c4b66..febb14b28 100644 --- a/components/product/ProductCard/ProductCard.tsx +++ b/components/product/ProductCard/ProductCard.tsx @@ -5,58 +5,98 @@ import type { Product } from '@commerce/types/product' 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 ProductTag from '../ProductTag' interface Props { className?: string product: Product - variant?: 'slim' | 'simple' - imgProps?: Omit + noNameTag?: boolean + imgProps?: Omit + variant?: 'default' | 'slim' | 'simple' } const placeholderImg = '/product-img-placeholder.svg' const ProductCard: FC = ({ - className, product, - variant, imgProps, + className, + noNameTag = false, + variant = 'default', ...props -}) => ( - - - {variant === 'slim' ? ( -
    -
    - - {product.name} - -
    - {product?.images && ( - {product.name - )} -
    - ) : ( - <> -
    -
    -
    -

    - {product.name} -

    - - {product.price.value} -   - {product.price.currencyCode} - +}) => { + const { price } = usePrice({ + amount: product.price.value, + baseAmount: product.price.retailPrice, + currencyCode: product.price.currencyCode!, + }) + + const rootClassName = cn( + s.root, + { [s.slim]: variant === 'slim', [s.simple]: variant === 'simple' }, + className + ) + + return ( + + + {variant === 'slim' && ( + <> +
    + {product.name}
    + {product?.images && ( + {product.name + )} + + )} + + {variant === 'simple' && ( + <> + {process.env.COMMERCE_WISHLIST_ENABLED && ( + + )} + {!noNameTag && ( +
    +

    + {product.name} +

    +
    + {`${price} ${product.price?.currencyCode}`} +
    +
    + )} +
    + {product?.images && ( + {product.name + )} +
    + + )} + + {variant === 'default' && ( + <> {process.env.COMMERCE_WISHLIST_ENABLED && ( = ({ variant={product.variants[0] as any} /> )} -
    -
    - {product?.images && ( - {product.name - )} -
    - - )} -
    - -) + +
    + {product?.images && ( + {product.name + )} +
    + + )} + + + ) +} export default ProductCard diff --git a/components/product/ProductOptions/ProductOptions.tsx b/components/product/ProductOptions/ProductOptions.tsx new file mode 100644 index 000000000..9261406bc --- /dev/null +++ b/components/product/ProductOptions/ProductOptions.tsx @@ -0,0 +1,50 @@ +import { Swatch } from '@components/product' +import type { ProductOption } from '@commerce/types/product' +import { SelectedOptions } from '../helpers' +import React from 'react' +interface ProductOptionsProps { + options: ProductOption[] + selectedOptions: SelectedOptions + setSelectedOptions: React.Dispatch> +} + +const ProductOptions: React.FC = React.memo( + ({ options, selectedOptions, setSelectedOptions }) => { + return ( +
    + {options.map((opt) => ( +
    +

    + {opt.displayName} +

    +
    + {opt.values.map((v, i: number) => { + const active = selectedOptions[opt.displayName.toLowerCase()] + return ( + { + setSelectedOptions((selectedOptions) => { + return { + ...selectedOptions, + [opt.displayName.toLowerCase()]: + v.label.toLowerCase(), + } + }) + }} + /> + ) + })} +
    +
    + ))} +
    + ) + } +) + +export default ProductOptions diff --git a/components/product/ProductOptions/index.ts b/components/product/ProductOptions/index.ts new file mode 100644 index 000000000..252415ab7 --- /dev/null +++ b/components/product/ProductOptions/index.ts @@ -0,0 +1 @@ +export { default } from './ProductOptions' diff --git a/components/product/ProductSidebar/ProductSidebar.module.css b/components/product/ProductSidebar/ProductSidebar.module.css new file mode 100644 index 000000000..b6ecc2b77 --- /dev/null +++ b/components/product/ProductSidebar/ProductSidebar.module.css @@ -0,0 +1,84 @@ +.root { + @apply relative grid items-start gap-1 grid-cols-1 overflow-x-hidden; + min-height: auto; +} + +.main { + @apply relative px-0 pb-0 box-border flex flex-col col-span-1; + min-height: 500px; +} + +.header { + @apply transition-colors ease-in-out duration-500 + absolute top-0 left-0 z-20 pr-16; +} + +.header .name { + @apply pt-0 max-w-full w-full leading-extra-loose; + font-size: 2rem; + letter-spacing: 0.4px; +} + +.header .name span { + @apply py-4 px-6 bg-primary text-primary font-bold; + font-size: inherit; + letter-spacing: inherit; + box-decoration-break: clone; + -webkit-box-decoration-break: clone; +} + +.header .price { + @apply pt-2 px-6 pb-4 text-sm bg-primary text-accent-9 + font-semibold inline-block tracking-wide; +} + +.sidebar { + @apply flex flex-col col-span-1 mx-auto max-w-8xl px-6 py-6 w-full h-full; +} + +.sliderContainer { + @apply flex items-center justify-center overflow-x-hidden bg-violet; +} + +.imageContainer { + @apply text-center; +} + +.imageContainer > div, +.imageContainer > div > div { + @apply h-full; +} + +.sliderContainer .img { + @apply w-full h-auto max-h-full object-cover; +} + +.button { + width: 100%; +} + +.wishlistButton { + @apply absolute z-30 top-0 right-0; +} + +.relatedProductsGrid { + @apply grid grid-cols-2 py-2 gap-2 md:grid-cols-4 md:gap-7; +} + +@screen lg { + .root { + @apply grid-cols-12; + } + + .main { + @apply mx-0 col-span-8; + } + + .sidebar { + @apply col-span-4 py-6; + } + + .imageContainer { + max-height: 600px; + } +} diff --git a/components/product/ProductSidebar/ProductSidebar.tsx b/components/product/ProductSidebar/ProductSidebar.tsx new file mode 100644 index 000000000..d339859a2 --- /dev/null +++ b/components/product/ProductSidebar/ProductSidebar.tsx @@ -0,0 +1,87 @@ +import s from './ProductSidebar.module.css' +import { useAddItem } from '@framework/cart' +import { FC, useEffect, useState } from 'react' +import { ProductOptions } from '@components/product' +import type { Product } from '@commerce/types/product' +import { Button, Text, Rating, Collapse, useUI } from '@components/ui' +import { + getProductVariant, + selectDefaultOptionFromProduct, + SelectedOptions, +} from '../helpers' + +interface ProductSidebarProps { + product: Product + className?: string +} + +const ProductSidebar: FC = ({ product, className }) => { + const addItem = useAddItem() + const { openSidebar } = useUI() + const [loading, setLoading] = useState(false) + const [selectedOptions, setSelectedOptions] = useState({}) + + useEffect(() => { + selectDefaultOptionFromProduct(product, setSelectedOptions) + }, []) + + const variant = getProductVariant(product, selectedOptions) + const addToCart = async () => { + setLoading(true) + try { + await addItem({ + productId: String(product.id), + variantId: String(variant ? variant.id : product.variants[0].id), + }) + openSidebar() + setLoading(false) + } catch (err) { + setLoading(false) + } + } + + return ( +
    + + +
    + +
    36 reviews
    +
    +
    + +
    +
    + + This is a limited edition production run. Printing starts when the + drop ends. + + + This is a limited edition production run. Printing starts when the + drop ends. Reminder: Bad Boys For Life. Shipping may take 10+ days due + to COVID-19. + +
    +
    + ) +} + +export default ProductSidebar diff --git a/components/product/ProductSidebar/index.ts b/components/product/ProductSidebar/index.ts new file mode 100644 index 000000000..7e00359c4 --- /dev/null +++ b/components/product/ProductSidebar/index.ts @@ -0,0 +1 @@ +export { default } from './ProductSidebar' diff --git a/components/product/ProductSlider/ProductSlider.module.css b/components/product/ProductSlider/ProductSlider.module.css index 259d15801..8d7265eb8 100644 --- a/components/product/ProductSlider/ProductSlider.module.css +++ b/components/product/ProductSlider/ProductSlider.module.css @@ -1,82 +1,64 @@ .root { - @apply relative w-full h-full; + @apply relative w-full h-full select-none; + overflow: hidden; +} + +.slider { + @apply relative h-full transition-opacity duration-150; + opacity: 0; +} + +.slider.show { + opacity: 1; +} + +.thumb { + @apply transition-transform transition-colors + ease-linear duration-75 overflow-hidden inline-block + cursor-pointer h-full; + width: 125px; + width: calc(100% / 3); +} + +.thumb.selected { + @apply bg-white; +} + +.thumb img { + height: 85% !important; +} + +.album { + width: 100%; + height: 100%; + @apply bg-violet-dark; + box-sizing: content-box; overflow-y: hidden; + overflow-x: auto; + white-space: nowrap; + height: 125px; + scrollbar-width: none; } -.leftControl, -.rightControl { - @apply absolute top-1/2 -translate-x-1/2 z-20 w-16 h-16 flex items-center justify-center bg-hover-1 rounded-full; +/* Hide scrollbar for Chrome, Safari and Opera */ +.album::-webkit-scrollbar { + display: none; } -.leftControl:hover, -.rightControl:hover { - @apply bg-hover-2; -} +@screen md { + .thumb:hover { + transform: scale(1.02); + background-color: rgba(255, 255, 255, 0.08); + } -.leftControl:hover, -.rightControl:hover { - @apply outline-none shadow-outline-normal; -} + .thumb.selected { + @apply bg-white; + } -.leftControl { - @apply bg-cover left-10; - background-image: url('public/cursor-left.png'); - - @screen md { - @apply left-6; + .album { + height: 182px; + } + .thumb { + width: 235px; } } - -.rightControl { - @apply bg-cover right-10; - background-image: url('public/cursor-right.png'); - - @screen md { - @apply right-6; - } -} - -.control { - @apply opacity-0 transition duration-150; -} - -.root:hover .control { - @apply opacity-100; -} - -.positionIndicatorsContainer { - @apply hidden; - - @screen sm { - @apply block absolute bottom-6 left-1/2; - transform: translateX(-50%); - } -} - -.positionIndicator { - @apply rounded-full p-2; -} - -.dot { - @apply bg-hover-1 transition w-3 h-3 rounded-full; -} - -.positionIndicator:hover .dot { - @apply bg-hover-2; -} - -.positionIndicator:focus { - @apply outline-none; -} - -.positionIndicator:focus .dot { - @apply shadow-outline-normal; -} - -.positionIndicatorActive .dot { - @apply bg-white; -} - -.positionIndicatorActive:hover .dot { - @apply bg-white; -} diff --git a/components/product/ProductSlider/ProductSlider.tsx b/components/product/ProductSlider/ProductSlider.tsx index 02244f5ba..8c3441906 100644 --- a/components/product/ProductSlider/ProductSlider.tsx +++ b/components/product/ProductSlider/ProductSlider.tsx @@ -8,20 +8,42 @@ import React, { useEffect, } from 'react' import cn from 'classnames' - +import { a } from '@react-spring/web' import s from './ProductSlider.module.css' +import ProductSliderControl from '../ProductSliderControl' -const ProductSlider: FC = ({ children }) => { +interface ProductSliderProps { + children: React.ReactNode[] + className?: string +} + +const ProductSlider: React.FC = ({ + children, + className = '', +}) => { const [currentSlide, setCurrentSlide] = useState(0) const [isMounted, setIsMounted] = useState(false) const sliderContainerRef = useRef(null) + const thumbsContainerRef = useRef(null) const [ref, slider] = useKeenSlider({ loop: true, slidesPerView: 1, mounted: () => setIsMounted(true), slideChanged(s) { - setCurrentSlide(s.details().relativeSlide) + const slideNumber = s.details().relativeSlide + setCurrentSlide(slideNumber) + + if (thumbsContainerRef.current) { + const $el = document.getElementById( + `thumb-${s.details().relativeSlide}` + ) + if (slideNumber >= 3) { + thumbsContainerRef.current.scrollLeft = $el!.offsetLeft + } else { + thumbsContainerRef.current.scrollLeft = 0 + } + } }, }) @@ -59,23 +81,16 @@ const ProductSlider: FC = ({ children }) => { } }, []) + const onPrev = React.useCallback(() => slider.prev(), [slider]) + const onNext = React.useCallback(() => slider.next(), [slider]) + return ( -
    - - ) + + + {slider && + Children.map(children, (child, idx) => { + if (isValidElement(child)) { + return { + ...child, + props: { + ...child.props, + className: cn(child.props.className, s.thumb, { + [s.selected]: currentSlide === idx, + }), + id: `thumb-${idx}`, + onClick: () => { + slider.moveToSlideRelative(idx) + }, + }, + } + } + return child })} -
    - )} +
    ) } diff --git a/components/product/ProductSliderControl/ProductSliderControl.module.css b/components/product/ProductSliderControl/ProductSliderControl.module.css new file mode 100644 index 000000000..c744e7598 --- /dev/null +++ b/components/product/ProductSliderControl/ProductSliderControl.module.css @@ -0,0 +1,29 @@ +.control { + @apply bg-violet absolute bottom-10 right-10 flex flex-row + border-accent-0 border text-accent-0 z-30 shadow-xl select-none; + height: 48px; +} + +.leftControl, +.rightControl { + @apply px-9 cursor-pointer; + transition: background-color 0.2s ease; +} + +.leftControl:hover, +.rightControl:hover { + background-color: var(--violet-dark); +} + +.leftControl:focus, +.rightControl:focus { + @apply outline-none; +} + +.rightControl { + @apply border-l border-accent-0; +} + +.leftControl { + margin-right: -1px; +} diff --git a/components/product/ProductSliderControl/ProductSliderControl.tsx b/components/product/ProductSliderControl/ProductSliderControl.tsx new file mode 100644 index 000000000..4e767b5db --- /dev/null +++ b/components/product/ProductSliderControl/ProductSliderControl.tsx @@ -0,0 +1,31 @@ +import cn from 'classnames' +import React from 'react' +import s from './ProductSliderControl.module.css' +import { ArrowLeft, ArrowRight } from '@components/icons' + +interface ProductSliderControl { + onPrev: React.MouseEventHandler + onNext: React.MouseEventHandler +} + +const ProductSliderControl: React.FC = React.memo( + ({ onPrev, onNext }) => ( +
    + + +
    + ) +) +export default ProductSliderControl diff --git a/components/product/ProductSliderControl/index.ts b/components/product/ProductSliderControl/index.ts new file mode 100644 index 000000000..5b63c466f --- /dev/null +++ b/components/product/ProductSliderControl/index.ts @@ -0,0 +1 @@ +export { default } from './ProductSliderControl' diff --git a/components/product/ProductTag/ProductTag.module.css b/components/product/ProductTag/ProductTag.module.css new file mode 100644 index 000000000..faf2fd97f --- /dev/null +++ b/components/product/ProductTag/ProductTag.module.css @@ -0,0 +1,30 @@ +.root { + @apply transition-colors ease-in-out duration-500 + absolute top-0 left-0 z-20 pr-16; +} + +.root .name { + @apply pt-0 max-w-full w-full leading-extra-loose; + font-size: 2rem; + letter-spacing: 0.4px; + line-height: 2.2em; +} + +.root .name span { + @apply py-4 px-6 bg-primary text-primary font-bold; + min-height: 70px; + font-size: inherit; + letter-spacing: inherit; + box-decoration-break: clone; + -webkit-box-decoration-break: clone; +} + +.root .name span.fontsizing { + display: flex; + padding-top: 1.5rem; +} + +.root .price { + @apply pt-2 px-6 pb-4 text-sm bg-primary text-accent-9 + font-semibold inline-block tracking-wide; +} diff --git a/components/product/ProductTag/ProductTag.tsx b/components/product/ProductTag/ProductTag.tsx new file mode 100644 index 000000000..2bc80b878 --- /dev/null +++ b/components/product/ProductTag/ProductTag.tsx @@ -0,0 +1,36 @@ +import cn from 'classnames' +import { inherits } from 'util' +import s from './ProductTag.module.css' + +interface ProductTagProps { + className?: string + name: string + price: string + fontSize?: number +} + +const ProductTag: React.FC = ({ + name, + price, + className = '', + fontSize = 32, +}) => { + return ( +
    +

    + + {name} + +

    +
    {price}
    +
    + ) +} + +export default ProductTag diff --git a/components/product/ProductTag/index.ts b/components/product/ProductTag/index.ts new file mode 100644 index 000000000..cb345e8bd --- /dev/null +++ b/components/product/ProductTag/index.ts @@ -0,0 +1 @@ +export { default } from './ProductTag' diff --git a/components/product/ProductView/ProductView.module.css b/components/product/ProductView/ProductView.module.css index 6545d611b..0b3ebf564 100644 --- a/components/product/ProductView/ProductView.module.css +++ b/components/product/ProductView/ProductView.module.css @@ -1,96 +1,60 @@ .root { - @apply relative grid items-start gap-8 grid-cols-1 overflow-x-hidden; - - @screen lg { - @apply grid-cols-12; - } + @apply relative grid items-start gap-1 grid-cols-1 overflow-x-hidden; + min-height: auto; } -.productDisplay { - @apply relative flex px-0 pb-0 box-border col-span-1 bg-violet; - min-height: 600px; - - @screen md { - min-height: 700px; - } - - @screen lg { - margin-right: -2rem; - margin-left: -2rem; - @apply mx-0 col-span-6; - min-height: 100%; - height: 100%; - } -} - -.squareBg { - @apply absolute inset-0 bg-violet z-0 h-full; -} - -.nameBox { - @apply absolute top-6 left-0 z-20 pr-16; - - @screen lg { - @apply left-6 pr-16; - } - - & .name { - @apply px-6 py-2 bg-primary text-primary font-bold; - font-size: 2rem; - letter-spacing: 0.4px; - } - - & .price { - @apply px-6 py-2 pb-4 bg-primary text-primary font-bold inline-block tracking-wide; - } - - @screen lg { - & .name, - & .price { - @apply bg-violet-light text-white; - } - } +.main { + @apply relative px-0 pb-0 box-border flex flex-col col-span-1; + min-height: 500px; } .sidebar { - @apply flex flex-col col-span-1 mx-auto max-w-8xl px-6 w-full h-full; - - @screen lg { - @apply col-span-6 py-24 justify-between; - } + @apply flex flex-col col-span-1 mx-auto max-w-8xl px-6 py-6 w-full h-full; } .sliderContainer { - @apply absolute z-10 inset-0 flex items-center justify-center overflow-x-hidden; + @apply flex items-center justify-center overflow-x-hidden bg-violet; } .imageContainer { - & > div { - @apply h-full; - & > div { - @apply h-full; - } - } + @apply text-center; } -.img { +.imageContainer > div, +.imageContainer > div > div { + @apply h-full; +} + +.sliderContainer .img { @apply w-full h-auto max-h-full object-cover; } .button { - text-align: center; width: 100%; - max-width: 300px; - - @screen sm { - min-width: 300px; - } } .wishlistButton { - @apply absolute z-30 top-6 right-0 bg-primary text-primary w-10 h-10 flex items-center justify-center font-semibold leading-6 cursor-pointer; + @apply absolute z-30 top-0 right-0; +} - @screen lg { - @apply right-12 text-white bg-violet; +.relatedProductsGrid { + @apply grid grid-cols-2 py-2 gap-2 md:grid-cols-4 md:gap-7; +} + +@screen lg { + .root { + @apply grid-cols-12; + } + + .main { + @apply mx-0 col-span-8; + } + + .sidebar { + @apply col-span-4 py-6; + } + + .imageContainer { + max-height: 600px; } } diff --git a/components/product/ProductView/ProductView.tsx b/components/product/ProductView/ProductView.tsx index 2a7fccb10..f689030d6 100644 --- a/components/product/ProductView/ProductView.tsx +++ b/components/product/ProductView/ProductView.tsx @@ -1,64 +1,90 @@ import cn from 'classnames' import Image from 'next/image' import { NextSeo } from 'next-seo' -import { FC, useEffect, useState } from 'react' import s from './ProductView.module.css' -import { Swatch, ProductSlider } from '@components/product' -import { Button, Container, Text, useUI } from '@components/ui' +import { FC } from 'react' import type { Product } from '@commerce/types/product' import usePrice from '@framework/product/use-price' -import { useAddItem } from '@framework/cart' -import { getVariant, SelectedOptions } from '../helpers' -import WishlistButton from '@components/wishlist/WishlistButton' - -interface Props { - children?: any +import { WishlistButton } from '@components/wishlist' +import { ProductSlider, ProductCard } from '@components/product' +import { Container, Text } from '@components/ui' +import ProductSidebar from '../ProductSidebar' +import ProductTag from '../ProductTag' +interface ProductViewProps { product: Product - className?: string + relatedProducts: Product[] } -const ProductView: FC = ({ product }) => { - // TODO: fix this missing argument issue - /* @ts-ignore */ - const addItem = useAddItem() +const ProductView: FC = ({ product, relatedProducts }) => { const { price } = usePrice({ amount: product.price.value, baseAmount: product.price.retailPrice, currencyCode: product.price.currencyCode!, }) - const { openSidebar } = useUI() - const [loading, setLoading] = useState(false) - const [choices, setChoices] = useState({}) - - useEffect(() => { - // Selects the default option - const options = product.variants[0].options || [] - options.forEach((v) => { - setChoices((choices) => ({ - ...choices, - [v.displayName.toLowerCase()]: v.values[0]?.label.toLowerCase(), - })) - }) - }, []) - - const variant = getVariant(product, choices) - - const addToCart = async () => { - setLoading(true) - try { - await addItem({ - productId: String(product.id), - variantId: String(variant ? variant.id : product.variants[0].id), - }) - openSidebar() - setLoading(false) - } catch (err) { - setLoading(false) - } - } return ( - + <> + +
    +
    + +
    + + {product.images.map((image, i) => ( +
    + {image.alt +
    + ))} +
    +
    + {process.env.COMMERCE_WISHLIST_ENABLED && ( + + )} +
    + + +
    +
    +
    + Related Products +
    + {relatedProducts.map((p) => ( +
    + +
    + ))} +
    +
    +
    = ({ product }) => { ], }} /> -
    -
    -
    -

    {product.name}

    -
    - {price} - {` `} - {product.price?.currencyCode} -
    -
    - -
    - - {product.images.map((image, i) => ( -
    - {image.alt -
    - ))} -
    -
    -
    -
    -
    - {product.options?.map((opt) => ( -
    -

    {opt.displayName}

    -
    - {opt.values.map((v, i: number) => { - const active = (choices as any)[ - opt.displayName.toLowerCase() - ] - - return ( - { - setChoices((choices) => { - return { - ...choices, - [opt.displayName.toLowerCase()]: - v.label.toLowerCase(), - } - }) - }} - /> - ) - })} -
    -
    - ))} - -
    - -
    -
    -
    - -
    -
    - {process.env.COMMERCE_WISHLIST_ENABLED && ( - - )} -
    -
    + ) } diff --git a/components/product/Swatch/Swatch.module.css b/components/product/Swatch/Swatch.module.css index ede13267b..79a69e548 100644 --- a/components/product/Swatch/Swatch.module.css +++ b/components/product/Swatch/Swatch.module.css @@ -1,11 +1,13 @@ .swatch { box-sizing: border-box; - composes: root from 'components/ui/Button/Button.module.css'; - @apply h-12 w-12 bg-primary text-primary rounded-full mr-3 inline-flex + composes: root from '@components/ui/Button/Button.module.css'; + @apply h-10 w-10 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; + p-0 shadow-none border-accent-3 border box-border select-none; margin-right: calc(0.75rem - 1px); overflow: hidden; + width: 48px; + height: 48px; } .swatch::before, @@ -35,7 +37,7 @@ } .active { - @apply border-accents-9 border-2; + @apply border-accent-9 border-2; padding-right: 1px; padding-left: 1px; } @@ -46,7 +48,7 @@ } .active.textLabel { - @apply border-accents-9 border-2; + @apply border-accent-9 border-2; padding-right: calc(1rem - 1px); padding-left: calc(1rem - 1px); } diff --git a/components/product/Swatch/Swatch.tsx b/components/product/Swatch/Swatch.tsx index bb8abf3d1..d04e77a78 100644 --- a/components/product/Swatch/Swatch.tsx +++ b/components/product/Swatch/Swatch.tsx @@ -1,5 +1,5 @@ import cn from 'classnames' -import { FC } from 'react' +import React from 'react' import s from './Swatch.module.css' import { Check } from '@components/icons' import Button, { ButtonProps } from '@components/ui/Button' @@ -13,48 +13,50 @@ interface SwatchProps { label?: string | null } -const Swatch: FC & SwatchProps> = ({ - className, - color = '', - label = null, - variant = 'size', - active, - ...props -}) => { - variant = variant?.toLowerCase() +const Swatch: React.FC & SwatchProps> = React.memo( + ({ + active, + className, + color = '', + label = null, + variant = 'size', + ...props + }) => { + variant = variant?.toLowerCase() - if (label) { - label = label?.toLowerCase() + if (label) { + label = label?.toLowerCase() + } + + const swatchClassName = cn( + s.swatch, + { + [s.color]: color, + [s.active]: active, + [s.size]: variant === 'size', + [s.dark]: color ? isDark(color) : false, + [s.textLabel]: !color && label && label.length > 3, + }, + className + ) + + return ( + + ) } - - const swatchClassName = cn( - s.swatch, - { - [s.active]: active, - [s.size]: variant === 'size', - [s.color]: color, - [s.dark]: color ? isDark(color) : false, - [s.textLabel]: !color && label && label.length > 3, - }, - className - ) - - return ( - - ) -} +) export default Swatch diff --git a/components/product/helpers.ts b/components/product/helpers.ts index 19ec2a171..d3fbd5ef5 100644 --- a/components/product/helpers.ts +++ b/components/product/helpers.ts @@ -1,7 +1,8 @@ import type { Product } from '@commerce/types/product' export type SelectedOptions = Record +import { Dispatch, SetStateAction } from 'react' -export function getVariant(product: Product, opts: SelectedOptions) { +export function getProductVariant(product: Product, opts: SelectedOptions) { const variant = product.variants.find((variant) => { return Object.entries(opts).every(([key, value]) => variant.options.find((option) => { @@ -16,3 +17,16 @@ export function getVariant(product: Product, opts: SelectedOptions) { }) return variant } + +export function selectDefaultOptionFromProduct( + product: Product, + updater: Dispatch> +) { + // Selects the default option + product.variants[0].options?.forEach((v) => { + updater((choices) => ({ + ...choices, + [v.displayName.toLowerCase()]: v.values[0].label.toLowerCase(), + })) + }) +} diff --git a/components/product/index.ts b/components/product/index.ts index 82ac6c548..8b70f8e2e 100644 --- a/components/product/index.ts +++ b/components/product/index.ts @@ -2,3 +2,4 @@ export { default as Swatch } from './Swatch' export { default as ProductView } from './ProductView' export { default as ProductCard } from './ProductCard' export { default as ProductSlider } from './ProductSlider' +export { default as ProductOptions } from './ProductOptions' diff --git a/components/search.tsx b/components/search.tsx new file mode 100644 index 000000000..10fd5df68 --- /dev/null +++ b/components/search.tsx @@ -0,0 +1,439 @@ +import cn from 'classnames' +import type { SearchPropsType } from '@lib/search-props' +import Link from 'next/link' +import { useState } from 'react' +import { useRouter } from 'next/router' + +import { Layout } from '@components/common' +import { ProductCard } from '@components/product' +import type { Product } from '@commerce/types/product' +import { Container, Grid, Skeleton } from '@components/ui' + +import useSearch from '@framework/product/use-search' + +import getSlug from '@lib/get-slug' +import rangeMap from '@lib/range-map' + +const SORT = Object.entries({ + 'trending-desc': 'Trending', + 'latest-desc': 'Latest arrivals', + 'price-asc': 'Price: Low to high', + 'price-desc': 'Price: High to low', +}) + +import { + filterQuery, + getCategoryPath, + getDesignerPath, + useSearchMeta, +} from '@lib/search' + +export default function Search({ categories, brands }: SearchPropsType) { + const [activeFilter, setActiveFilter] = useState('') + const [toggleFilter, setToggleFilter] = useState(false) + + const router = useRouter() + const { asPath, locale } = router + const { q, sort } = router.query + // `q` can be included but because categories and designers can't be searched + // in the same way of products, it's better to ignore the search input if one + // of those is selected + const query = filterQuery({ sort }) + + const { pathname, category, brand } = useSearchMeta(asPath) + const activeCategory = categories.find((cat: any) => cat.slug === category) + const activeBrand = brands.find( + (b: any) => getSlug(b.node.path) === `brands/${brand}` + )?.node + + const { data } = useSearch({ + search: typeof q === 'string' ? q : '', + categoryId: activeCategory?.id, + brandId: (activeBrand as any)?.entityId, + sort: typeof sort === 'string' ? sort : '', + locale, + }) + + const handleClick = (event: any, filter: string) => { + if (filter !== activeFilter) { + setToggleFilter(true) + } else { + setToggleFilter(!toggleFilter) + } + setActiveFilter(filter) + } + + return ( + +
    +
    + {/* Categories */} +
    +
    + + + +
    + +
    + + {/* Designs */} +
    +
    + + + +
    + +
    +
    + {/* Products */} +
    + {(q || activeCategory || activeBrand) && ( +
    + {data ? ( + <> + + Showing {data.products.length} results{' '} + {q && ( + <> + for "{q}" + + )} + + + {q ? ( + <> + There are no products that match "{q}" + + ) : ( + <> + There are no products that match the selected category. + + )} + + + ) : q ? ( + <> + Searching for: "{q}" + + ) : ( + <>Searching... + )} +
    + )} + {data ? ( +
    + {data.products.map((product: Product) => ( + + ))} +
    + ) : ( +
    + {rangeMap(12, (i) => ( + +
    + + ))} +
    + )}{' '} +
    + + {/* Sort */} +
    +
    +
    + + + +
    + +
    +
    +
    + + ) +} + +Search.Layout = Layout diff --git a/components/ui/Button/Button.module.css b/components/ui/Button/Button.module.css index 5b563f496..2ac7544f7 100644 --- a/components/ui/Button/Button.module.css +++ b/components/ui/Button/Button.module.css @@ -1,9 +1,14 @@ .root { - @apply bg-secondary text-accents-1 cursor-pointer inline-flex px-10 rounded-sm leading-6 transition ease-in-out duration-150 shadow-sm font-semibold text-center justify-center uppercase py-4 border border-transparent items-center; + @apply bg-accent-9 text-accent-0 cursor-pointer inline-flex + px-10 py-5 leading-6 transition ease-in-out duration-150 + shadow-sm text-center justify-center uppercase + border border-transparent items-center text-sm font-semibold + tracking-wide; + max-height: 64px; } .root:hover { - @apply bg-accents-0 text-primary border border-secondary; + @apply border-accent-9 bg-accent-6; } .root:focus { @@ -11,22 +16,33 @@ } .root[data-active] { - @apply bg-gray-600; + @apply bg-accent-6; } .loading { - @apply bg-accents-1 text-accents-3 border-accents-2 cursor-not-allowed; + @apply bg-accent-1 text-accent-3 border-accent-2 cursor-not-allowed; } .slim { @apply py-2 transform-none normal-case; } +.ghost { + @apply border border-accent-2 bg-accent-0 text-accent-9 text-sm; +} + +.ghost:hover { + @apply border-accent-9 bg-accent-9 text-accent-0; +} + .disabled, .disabled:hover { - @apply text-accents-4 border-accents-2 bg-accents-1 cursor-not-allowed; + @apply text-accent-4 border-accent-2 bg-accent-1 cursor-not-allowed; filter: grayscale(1); -webkit-transform: translateZ(0); -webkit-perspective: 1000; -webkit-backface-visibility: hidden; } + +.progress { +} diff --git a/components/ui/Button/Button.tsx b/components/ui/Button/Button.tsx index ca5db36a6..b29fb432a 100644 --- a/components/ui/Button/Button.tsx +++ b/components/ui/Button/Button.tsx @@ -12,7 +12,7 @@ import { LoadingDots } from '@components/ui' export interface ButtonProps extends ButtonHTMLAttributes { href?: string className?: string - variant?: 'flat' | 'slim' + variant?: 'flat' | 'slim' | 'ghost' active?: boolean type?: 'submit' | 'reset' | 'button' Component?: string | JSXElementConstructor @@ -39,6 +39,7 @@ const Button: React.FC = forwardRef((props, buttonRef) => { const rootClassName = cn( s.root, { + [s.ghost]: variant === 'ghost', [s.slim]: variant === 'slim', [s.loading]: loading, [s.disabled]: disabled, diff --git a/components/ui/Collapse/Collapse.module.css b/components/ui/Collapse/Collapse.module.css new file mode 100644 index 000000000..fb4a82a90 --- /dev/null +++ b/components/ui/Collapse/Collapse.module.css @@ -0,0 +1,25 @@ +.root { + @apply border-b border-accent-2 py-4 flex flex-col outline-none; +} + +.header { + @apply flex flex-row items-center; +} + +.header .label { + @apply text-base font-medium; +} + +.content { + @apply pt-3 overflow-hidden pl-8; +} + +.icon { + @apply mr-3 text-accent-6; + margin-left: -6px; + transition: transform 0.2s ease; +} + +.icon.open { + transform: rotate(90deg); +} diff --git a/components/ui/Collapse/Collapse.tsx b/components/ui/Collapse/Collapse.tsx new file mode 100644 index 000000000..b2f9525ac --- /dev/null +++ b/components/ui/Collapse/Collapse.tsx @@ -0,0 +1,46 @@ +import cn from 'classnames' +import React, { FC, ReactNode, useState } from 'react' +import s from './Collapse.module.css' +import { ChevronRight } from '@components/icons' +import { useSpring, a } from '@react-spring/web' +import useMeasure from 'react-use-measure' + +export interface CollapseProps { + title: string + children: ReactNode +} + +const Collapse: FC = React.memo(({ title, children }) => { + const [isActive, setActive] = useState(false) + const [ref, { height: viewHeight }] = useMeasure() + + const animProps = useSpring({ + height: isActive ? viewHeight : 0, + config: { tension: 250, friction: 32, clamp: true, duration: 150 }, + opacity: isActive ? 1 : 0, + }) + + const toggle = () => setActive((x) => !x) + + return ( +
    +
    + + {title} +
    + +
    + {children} +
    +
    +
    + ) +}) + +export default Collapse diff --git a/components/ui/Collapse/index.ts b/components/ui/Collapse/index.ts new file mode 100644 index 000000000..1e584a53b --- /dev/null +++ b/components/ui/Collapse/index.ts @@ -0,0 +1,2 @@ +export { default } from './Collapse' +export * from './Collapse' diff --git a/components/ui/Container/Container.tsx b/components/ui/Container/Container.tsx index f88934122..538b1cac7 100644 --- a/components/ui/Container/Container.tsx +++ b/components/ui/Container/Container.tsx @@ -1,14 +1,19 @@ import cn from 'classnames' import React, { FC } from 'react' -interface Props { +interface ContainerProps { className?: string children?: any el?: HTMLElement clean?: boolean } -const Container: FC = ({ children, className, el = 'div', clean }) => { +const Container: FC = ({ + children, + className, + el = 'div', + clean, +}) => { const rootClassName = cn(className, { 'mx-auto max-w-8xl px-6': !clean, }) diff --git a/components/ui/Grid/Grid.module.css b/components/ui/Grid/Grid.module.css index 9b331be8f..27e4c5b19 100644 --- a/components/ui/Grid/Grid.module.css +++ b/components/ui/Grid/Grid.module.css @@ -1,7 +1,9 @@ .root { - --row-height: calc(100vh - 88px); @apply grid grid-cols-1 gap-0; - min-height: var(--row-height); + + @screen lg { + @apply grid-cols-3 grid-rows-2; + } & > * { @apply row-span-1 bg-transparent box-border overflow-hidden; @@ -15,17 +17,6 @@ } } -@screen lg { - .root { - @apply grid-cols-3 grid-rows-2; - } - - .root & > * { - @apply col-span-1; - height: inherit; - } -} - .default { & > * { @apply bg-transparent; @@ -34,9 +25,17 @@ .layoutNormal { @apply gap-3; +} - & > * { - min-height: 325px; +@screen md { + .layoutNormal > * { + max-height: min-content !important; + } +} + +@screen lg { + .layoutNormal > * { + max-height: 400px; } } @@ -52,13 +51,12 @@ } &.filled { - & > *:nth-child(6n + 1), - & > *:nth-child(6n + 5) { + & > *:nth-child(6n + 1) { @apply bg-violet; } - & > *:nth-child(6n + 5) { - @apply bg-blue; + & > *:nth-child(6n + 2) { + @apply bg-accent-8; } & > *:nth-child(6n + 3) { @@ -83,12 +81,12 @@ } &.filled { - & > *:nth-child(6n + 2) { - @apply bg-blue; + & > *:nth-child(6n + 1) { + @apply bg-violet; } - & > *:nth-child(6n + 4) { - @apply bg-violet; + & > *:nth-child(6n + 2) { + @apply bg-accent-8; } & > *:nth-child(6n + 3) { diff --git a/components/ui/Grid/Grid.tsx b/components/ui/Grid/Grid.tsx index 8ca247609..55ca78277 100644 --- a/components/ui/Grid/Grid.tsx +++ b/components/ui/Grid/Grid.tsx @@ -2,14 +2,14 @@ import cn from 'classnames' import { FC, ReactNode, Component } from 'react' import s from './Grid.module.css' -interface Props { +interface GridProps { className?: string children?: ReactNode[] | Component[] | any[] layout?: 'A' | 'B' | 'C' | 'D' | 'normal' variant?: 'default' | 'filled' } -const Grid: FC = ({ +const Grid: FC = ({ className, layout = 'A', children, diff --git a/components/ui/Hero/Hero.module.css b/components/ui/Hero/Hero.module.css index c2032c8ae..a0f1798f5 100644 --- a/components/ui/Hero/Hero.module.css +++ b/components/ui/Hero/Hero.module.css @@ -1,9 +1,30 @@ .root { - @apply mx-auto grid grid-cols-1 py-32 gap-4; + @apply flex flex-col py-16 mx-auto; } -@screen md { +.title { + @apply text-accent-0 font-extrabold text-4xl leading-none tracking-tight; +} + +.description { + @apply mt-4 text-xl leading-8 text-accent-2 mb-1 lg:max-w-4xl; +} + +@screen lg { .root { - @apply grid-cols-2; + @apply flex-row items-start justify-center py-32; + } + .title { + @apply text-5xl max-w-xl text-right leading-10 -mt-3; + line-height: 3.5rem; + } + .description { + @apply mt-0 ml-6; + } +} + +@screen xl { + .title { + @apply text-6xl; } } diff --git a/components/ui/Hero/Hero.tsx b/components/ui/Hero/Hero.tsx index 1802f9ee8..58d13e5de 100644 --- a/components/ui/Hero/Hero.tsx +++ b/components/ui/Hero/Hero.tsx @@ -1,30 +1,26 @@ import React, { FC } from 'react' import { Container } from '@components/ui' -import { RightArrow } from '@components/icons' +import { ArrowRight } from '@components/icons' import s from './Hero.module.css' import Link from 'next/link' -interface Props { +interface HeroProps { className?: string headline: string description: string } -const Hero: FC = ({ headline, description }) => { +const Hero: FC = ({ headline, description }) => { return ( -
    +
    -

    - {headline} -

    -
    -

    - {description} -

    +

    {headline}

    +
    +

    {description}

    - + Read it here - +
    diff --git a/components/ui/Input/Input.module.css b/components/ui/Input/Input.module.css index 9daee1418..34507f445 100644 --- a/components/ui/Input/Input.module.css +++ b/components/ui/Input/Input.module.css @@ -1,5 +1,5 @@ .root { - @apply bg-primary py-2 px-6 w-full appearance-none transition duration-150 ease-in-out pr-10 border border-accents-3 text-accents-6; + @apply bg-primary py-2 px-6 w-full appearance-none transition duration-150 ease-in-out pr-10 border border-accent-3 text-accent-6; } .root:focus { diff --git a/components/ui/Input/Input.tsx b/components/ui/Input/Input.tsx index dc2f04a8d..e630728b2 100644 --- a/components/ui/Input/Input.tsx +++ b/components/ui/Input/Input.tsx @@ -2,12 +2,12 @@ import cn from 'classnames' import s from './Input.module.css' import React, { InputHTMLAttributes } from 'react' -export interface Props extends InputHTMLAttributes { +export interface InputProps extends InputHTMLAttributes { className?: string onChange?: (...args: any[]) => any } -const Input: React.FC = (props) => { +const Input: React.FC = (props) => { const { className, children, onChange, ...rest } = props const rootClassName = cn(s.root, {}, className) diff --git a/components/ui/LoadingDots/LoadingDots.module.css b/components/ui/LoadingDots/LoadingDots.module.css index 88ce77ec6..6054de3c7 100644 --- a/components/ui/LoadingDots/LoadingDots.module.css +++ b/components/ui/LoadingDots/LoadingDots.module.css @@ -1,22 +1,23 @@ .root { @apply inline-flex text-center items-center leading-7; +} - & span { - @apply bg-accents-6 rounded-full h-2 w-2; - animation-name: blink; - animation-duration: 1.4s; - animation-iteration-count: infinite; - animation-fill-mode: both; - margin: 0 2px; +.root .dot { + @apply rounded-full h-2 w-2; + background-color: currentColor; + animation-name: blink; + animation-duration: 1.4s; + animation-iteration-count: infinite; + animation-fill-mode: both; + margin: 0 2px; +} - &:nth-of-type(2) { - animation-delay: 0.2s; - } +.root .dot:nth-of-type(2) { + animation-delay: 0.2s; +} - &:nth-of-type(3) { - animation-delay: 0.4s; - } - } +.root .dot::nth-of-type(3) { + animation-delay: 0.4s; } @keyframes blink { diff --git a/components/ui/LoadingDots/LoadingDots.tsx b/components/ui/LoadingDots/LoadingDots.tsx index 10e5bbae1..27ce9f25f 100644 --- a/components/ui/LoadingDots/LoadingDots.tsx +++ b/components/ui/LoadingDots/LoadingDots.tsx @@ -3,9 +3,9 @@ import s from './LoadingDots.module.css' const LoadingDots: React.FC = () => { return ( - - - + + + ) } diff --git a/components/ui/Marquee/Marquee.module.css b/components/ui/Marquee/Marquee.module.css index 1fabc2ca8..e5ecb16ef 100644 --- a/components/ui/Marquee/Marquee.module.css +++ b/components/ui/Marquee/Marquee.module.css @@ -1,22 +1,22 @@ .root { - @apply w-full relative; - height: 320px; - min-width: 100%; + @apply w-full min-w-full relative flex flex-row items-center overflow-hidden py-0; + max-height: 320px; } -.container { - @apply flex flex-row items-center; +.root > div { + max-height: 320px; + padding: 0; + margin: 0; } -.container > * { - @apply relative flex-1 px-16 py-4 h-full; - min-height: 320px; +.root > div > * > *:nth-child(2) * { + max-height: 100%; } .primary { - @apply bg-white; + @apply bg-accent-0; } .secondary { - @apply bg-black; + @apply bg-accent-9; } diff --git a/components/ui/Marquee/Marquee.tsx b/components/ui/Marquee/Marquee.tsx index 163f29a34..ce5ec2338 100644 --- a/components/ui/Marquee/Marquee.tsx +++ b/components/ui/Marquee/Marquee.tsx @@ -1,15 +1,15 @@ import cn from 'classnames' import s from './Marquee.module.css' -import { FC, ReactNode, Component } from 'react' -import Ticker from 'react-ticker' +import { FC, ReactNode, Component, Children } from 'react' +import { default as FastMarquee } from 'react-fast-marquee' -interface Props { +interface MarqueeProps { className?: string children?: ReactNode[] | Component[] | any[] variant?: 'primary' | 'secondary' } -const Marquee: FC = ({ +const Marquee: FC = ({ className = '', children, variant = 'primary', @@ -24,11 +24,15 @@ const Marquee: FC = ({ ) return ( -
    - - {() =>
    {children}
    } -
    -
    + + {Children.map(children, (child) => ({ + ...child, + props: { + ...child.props, + className: cn(child.props.className, `${variant}`), + }, + }))} + ) } diff --git a/components/ui/Modal/Modal.module.css b/components/ui/Modal/Modal.module.css index 693bc2d37..f30d7c90a 100644 --- a/components/ui/Modal/Modal.module.css +++ b/components/ui/Modal/Modal.module.css @@ -1,12 +1,17 @@ .root { - @apply fixed bg-primary text-primary flex items-center inset-0 z-50 justify-center; - background-color: rgba(0, 0, 0, 0.35); + @apply fixed bg-black bg-opacity-40 flex items-center inset-0 z-50 justify-center; + backdrop-filter: blur(0.8px); + -webkit-backdrop-filter: blur(0.8px); } .modal { - @apply bg-primary p-12 border border-accents-2 relative; + @apply bg-primary p-12 border border-accent-2 relative; } .modal:focus { @apply outline-none; } + +.close { + @apply hover:text-accent-5 transition ease-in-out duration-150 focus:outline-none absolute right-0 top-0 m-6; +} diff --git a/components/ui/Modal/Modal.tsx b/components/ui/Modal/Modal.tsx index 300a99192..bb42b3d1b 100644 --- a/components/ui/Modal/Modal.tsx +++ b/components/ui/Modal/Modal.tsx @@ -1,22 +1,20 @@ import { FC, useRef, useEffect, useCallback } from 'react' -import Portal from '@reach/portal' import s from './Modal.module.css' +import FocusTrap from '@lib/focus-trap' import { Cross } from '@components/icons' import { disableBodyScroll, - enableBodyScroll, clearAllBodyScrollLocks, + enableBodyScroll, } from 'body-scroll-lock' -import FocusTrap from '@lib/focus-trap' -interface Props { +interface ModalProps { className?: string children?: any - open?: boolean onClose: () => void onEnter?: () => void | null } -const Modal: FC = ({ children, open, onClose, onEnter = null }) => { +const Modal: FC = ({ children, onClose }) => { const ref = useRef() as React.MutableRefObject const handleKey = useCallback( @@ -30,36 +28,31 @@ const Modal: FC = ({ children, open, onClose, onEnter = null }) => { useEffect(() => { if (ref.current) { - if (open) { - disableBodyScroll(ref.current) - window.addEventListener('keydown', handleKey) - } else { - enableBodyScroll(ref.current) - } + disableBodyScroll(ref.current, { reserveScrollBarGap: true }) + window.addEventListener('keydown', handleKey) } return () => { - window.removeEventListener('keydown', handleKey) + if (ref && ref.current) { + enableBodyScroll(ref.current) + } clearAllBodyScrollLocks() + window.removeEventListener('keydown', handleKey) } - }, [open, handleKey]) + }, [handleKey]) return ( - - {open ? ( -
    -
    - - {children} -
    -
    - ) : null} -
    +
    +
    + + {children} +
    +
    ) } diff --git a/components/ui/Quantity/Quantity.module.css b/components/ui/Quantity/Quantity.module.css new file mode 100644 index 000000000..fa60cc56e --- /dev/null +++ b/components/ui/Quantity/Quantity.module.css @@ -0,0 +1,27 @@ +.actions { + @apply flex p-1 border-accent-2 border items-center justify-center + w-12 text-accent-7; + transition-property: border-color, background, color, transform, box-shadow; + + transition-duration: 0.15s; + transition-timing-function: ease; + user-select: none; +} + +.actions:hover { + @apply border bg-accent-1 border-accent-3 text-accent-9; + transition: border-color; + z-index: 10; +} + +.actions:focus { + @apply outline-none; +} + +.actions:disabled { + @apply cursor-not-allowed; +} + +.input { + @apply bg-transparent px-4 w-full h-full focus:outline-none select-none pointer-events-auto; +} diff --git a/components/ui/Quantity/Quantity.tsx b/components/ui/Quantity/Quantity.tsx new file mode 100644 index 000000000..abde145aa --- /dev/null +++ b/components/ui/Quantity/Quantity.tsx @@ -0,0 +1,62 @@ +import React, { FC } from 'react' +import s from './Quantity.module.css' +import { Cross, Plus, Minus } from '@components/icons' +import cn from 'classnames' +export interface QuantityProps { + value: number + increase: () => any + decrease: () => any + handleRemove: React.MouseEventHandler + handleChange: React.ChangeEventHandler + max?: number +} + +const Quantity: FC = ({ + value, + increase, + decrease, + handleChange, + handleRemove, + max = 6, +}) => { + return ( +
    + + + + +
    + ) +} + +export default Quantity diff --git a/components/ui/Quantity/index.ts b/components/ui/Quantity/index.ts new file mode 100644 index 000000000..5ee880cc9 --- /dev/null +++ b/components/ui/Quantity/index.ts @@ -0,0 +1,2 @@ +export { default } from './Quantity' +export * from './Quantity' diff --git a/components/ui/Rating/Rating.module.css b/components/ui/Rating/Rating.module.css new file mode 100644 index 000000000..e69de29bb diff --git a/components/ui/Rating/Rating.tsx b/components/ui/Rating/Rating.tsx new file mode 100644 index 000000000..259e642ea --- /dev/null +++ b/components/ui/Rating/Rating.tsx @@ -0,0 +1,27 @@ +import React, { FC } from 'react' +import rangeMap from '@lib/range-map' +import { Star } from '@components/icons' +import cn from 'classnames' + +export interface RatingProps { + value: number +} + +const Quantity: React.FC = React.memo(({ value = 5 }) => { + return ( +
    + {rangeMap(5, (i) => ( + = Math.floor(value), + })} + > + + + ))} +
    + ) +}) + +export default Quantity diff --git a/components/ui/Rating/index.ts b/components/ui/Rating/index.ts new file mode 100644 index 000000000..1354efb25 --- /dev/null +++ b/components/ui/Rating/index.ts @@ -0,0 +1,2 @@ +export { default } from './Rating' +export * from './Rating' diff --git a/components/ui/Sidebar/Sidebar.module.css b/components/ui/Sidebar/Sidebar.module.css index b9ba054e2..f6a49387f 100644 --- a/components/ui/Sidebar/Sidebar.module.css +++ b/components/ui/Sidebar/Sidebar.module.css @@ -1,3 +1,14 @@ .root { - @apply fixed inset-0 overflow-hidden h-full z-50; + @apply fixed inset-0 h-full z-50 box-border; +} + +.sidebar { + @apply h-full flex flex-col text-base bg-accent-0 shadow-xl overflow-y-auto overflow-x-hidden; + -webkit-overflow-scrolling: touch !important; +} + +.backdrop { + @apply absolute inset-0 bg-black bg-opacity-40 duration-100 ease-linear; + backdrop-filter: blur(0.8px); + -webkit-backdrop-filter: blur(0.8px); } diff --git a/components/ui/Sidebar/Sidebar.tsx b/components/ui/Sidebar/Sidebar.tsx index a0d5e8339..ce0eeefe2 100644 --- a/components/ui/Sidebar/Sidebar.tsx +++ b/components/ui/Sidebar/Sidebar.tsx @@ -1,54 +1,45 @@ -import s from './Sidebar.module.css' -import Portal from '@reach/portal' import { FC, useEffect, useRef } from 'react' +import s from './Sidebar.module.css' +import cn from 'classnames' import { disableBodyScroll, enableBodyScroll, clearAllBodyScrollLocks, } from 'body-scroll-lock' -interface Props { +interface SidebarProps { children: any - open: boolean onClose: () => void } -const Sidebar: FC = ({ children, open = false, onClose }) => { +const Sidebar: FC = ({ children, onClose }) => { const ref = useRef() as React.MutableRefObject useEffect(() => { if (ref.current) { - if (open) { - disableBodyScroll(ref.current) - } else { - enableBodyScroll(ref.current) - } + disableBodyScroll(ref.current, { reserveScrollBarGap: true }) } return () => { + if (ref && ref.current) { + enableBodyScroll(ref.current) + } clearAllBodyScrollLocks() } - }, [open]) + }, []) return ( - - {open ? ( -
    -
    -
    -
    -
    -
    - {children} -
    -
    -
    +
    +
    +
    +
    +
    +
    + {children} +
    -
    - ) : null} - +
  • +
    +
    ) } diff --git a/components/ui/Skeleton/Skeleton.module.css b/components/ui/Skeleton/Skeleton.module.css index 5a852562b..37c164de7 100644 --- a/components/ui/Skeleton/Skeleton.module.css +++ b/components/ui/Skeleton/Skeleton.module.css @@ -2,10 +2,10 @@ @apply block; background-image: linear-gradient( 270deg, - var(--accents-1), - var(--accents-2), - var(--accents-2), - var(--accents-1) + var(--accent-0), + var(--accent-2), + var(--accent-0), + var(--accent-1) ); background-size: 400% 100%; animation: loading 8s ease-in-out infinite; @@ -28,10 +28,10 @@ z-index: 100; background-image: linear-gradient( 270deg, - var(--accents-1), - var(--accents-2), - var(--accents-2), - var(--accents-1) + var(--accent-0), + var(--accent-2), + var(--accent-0), + var(--accent-1) ); background-size: 400% 100%; animation: loading 8s ease-in-out infinite; diff --git a/components/ui/Skeleton/Skeleton.tsx b/components/ui/Skeleton/Skeleton.tsx index 153024f18..9cef2c1ac 100644 --- a/components/ui/Skeleton/Skeleton.tsx +++ b/components/ui/Skeleton/Skeleton.tsx @@ -3,17 +3,17 @@ import cn from 'classnames' import px from '@lib/to-pixels' import s from './Skeleton.module.css' -interface Props { - width?: string | number - height?: string | number - boxHeight?: string | number - style?: CSSProperties +interface SkeletonProps { show?: boolean block?: boolean className?: string + style?: CSSProperties + width?: string | number + height?: string | number + boxHeight?: string | number } -const Skeleton: React.FC = ({ +const Skeleton: React.FC = ({ style, width, height, diff --git a/components/ui/Text/Text.module.css b/components/ui/Text/Text.module.css index bbdfb6a05..f572fdf18 100644 --- a/components/ui/Text/Text.module.css +++ b/components/ui/Text/Text.module.css @@ -1,9 +1,9 @@ .body { - @apply text-lg leading-7 font-medium max-w-6xl mx-auto; + @apply text-base leading-7 max-w-6xl mx-auto; } .heading { - @apply text-5xl mb-12; + @apply text-5xl pt-1 pb-2 font-semibold tracking-wide cursor-pointer mb-2; } .pageHeading { @@ -11,5 +11,5 @@ } .sectionHeading { - @apply pt-1 pb-2 font-semibold leading-7 tracking-wider uppercase border-b border-accents-2 mb-3; + @apply pt-1 pb-2 text-2xl font-bold tracking-wide cursor-pointer mb-2; } diff --git a/components/ui/Text/Text.tsx b/components/ui/Text/Text.tsx index 51e1cce15..6106c209a 100644 --- a/components/ui/Text/Text.tsx +++ b/components/ui/Text/Text.tsx @@ -6,22 +6,24 @@ import React, { import cn from 'classnames' import s from './Text.module.css' -interface Props { +interface TextProps { variant?: Variant className?: string style?: CSSProperties children?: React.ReactNode | any html?: string + onClick?: () => any } type Variant = 'heading' | 'body' | 'pageHeading' | 'sectionHeading' -const Text: FunctionComponent = ({ +const Text: FunctionComponent = ({ style, className = '', variant = 'body', children, html, + onClick, }) => { const componentsMap: { [P in Variant]: React.ComponentType | string @@ -56,6 +58,7 @@ const Text: FunctionComponent = ({ }, className )} + onClick={onClick} style={style} {...htmlContentProps} > diff --git a/components/ui/context.tsx b/components/ui/context.tsx index f66adb9d7..ca2bfd7ed 100644 --- a/components/ui/context.tsx +++ b/components/ui/context.tsx @@ -1,13 +1,12 @@ -import React, { FC, useMemo } from 'react' +import React, { FC, useCallback, useMemo } from 'react' import { ThemeProvider } from 'next-themes' export interface State { displaySidebar: boolean displayDropdown: boolean displayModal: boolean - displayToast: boolean + sidebarView: string modalView: string - toastText: string userAvatar: string } @@ -16,8 +15,7 @@ const initialState = { displayDropdown: false, displayModal: false, modalView: 'LOGIN_VIEW', - displayToast: false, - toastText: '', + sidebarView: 'CART_VIEW', userAvatar: '', } @@ -28,16 +26,6 @@ type Action = | { type: 'CLOSE_SIDEBAR' } - | { - type: 'OPEN_TOAST' - } - | { - type: 'CLOSE_TOAST' - } - | { - type: 'SET_TOAST_TEXT' - text: ToastText - } | { type: 'OPEN_DROPDOWN' } @@ -54,6 +42,10 @@ type Action = type: 'SET_MODAL_VIEW' view: MODAL_VIEWS } + | { + type: 'SET_SIDEBAR_VIEW' + view: SIDEBAR_VIEWS + } | { type: 'SET_USER_AVATAR' value: string @@ -65,7 +57,8 @@ type MODAL_VIEWS = | 'FORGOT_VIEW' | 'NEW_SHIPPING_ADDRESS' | 'NEW_PAYMENT_METHOD' -type ToastText = string + +type SIDEBAR_VIEWS = 'CART_VIEW' | 'CHECKOUT_VIEW' | 'PAYMENT_METHOD_VIEW' export const UIContext = React.createContext(initialState) @@ -110,28 +103,16 @@ function uiReducer(state: State, action: Action) { displayModal: false, } } - case 'OPEN_TOAST': { - return { - ...state, - displayToast: true, - } - } - case 'CLOSE_TOAST': { - return { - ...state, - displayToast: false, - } - } case 'SET_MODAL_VIEW': { return { ...state, modalView: action.view, } } - case 'SET_TOAST_TEXT': { + case 'SET_SIDEBAR_VIEW': { return { ...state, - toastText: action.text, + sidebarView: action.view, } } case 'SET_USER_AVATAR': { @@ -146,29 +127,58 @@ function uiReducer(state: State, action: Action) { export const UIProvider: FC = (props) => { const [state, dispatch] = React.useReducer(uiReducer, initialState) - const openSidebar = () => dispatch({ type: 'OPEN_SIDEBAR' }) - const closeSidebar = () => dispatch({ type: 'CLOSE_SIDEBAR' }) - const toggleSidebar = () => - state.displaySidebar - ? dispatch({ type: 'CLOSE_SIDEBAR' }) - : dispatch({ type: 'OPEN_SIDEBAR' }) - const closeSidebarIfPresent = () => - state.displaySidebar && dispatch({ type: 'CLOSE_SIDEBAR' }) + const openSidebar = useCallback( + () => dispatch({ type: 'OPEN_SIDEBAR' }), + [dispatch] + ) + const closeSidebar = useCallback( + () => dispatch({ type: 'CLOSE_SIDEBAR' }), + [dispatch] + ) + const toggleSidebar = useCallback( + () => + state.displaySidebar + ? dispatch({ type: 'CLOSE_SIDEBAR' }) + : dispatch({ type: 'OPEN_SIDEBAR' }), + [dispatch, state.displaySidebar] + ) + const closeSidebarIfPresent = useCallback( + () => state.displaySidebar && dispatch({ type: 'CLOSE_SIDEBAR' }), + [dispatch, state.displaySidebar] + ) - const openDropdown = () => dispatch({ type: 'OPEN_DROPDOWN' }) - const closeDropdown = () => dispatch({ type: 'CLOSE_DROPDOWN' }) + const openDropdown = useCallback( + () => dispatch({ type: 'OPEN_DROPDOWN' }), + [dispatch] + ) + const closeDropdown = useCallback( + () => dispatch({ type: 'CLOSE_DROPDOWN' }), + [dispatch] + ) - const openModal = () => dispatch({ type: 'OPEN_MODAL' }) - const closeModal = () => dispatch({ type: 'CLOSE_MODAL' }) + const openModal = useCallback( + () => dispatch({ type: 'OPEN_MODAL' }), + [dispatch] + ) + const closeModal = useCallback( + () => dispatch({ type: 'CLOSE_MODAL' }), + [dispatch] + ) - const openToast = () => dispatch({ type: 'OPEN_TOAST' }) - const closeToast = () => dispatch({ type: 'CLOSE_TOAST' }) + const setUserAvatar = useCallback( + (value: string) => dispatch({ type: 'SET_USER_AVATAR', value }), + [dispatch] + ) - const setUserAvatar = (value: string) => - dispatch({ type: 'SET_USER_AVATAR', value }) + const setModalView = useCallback( + (view: MODAL_VIEWS) => dispatch({ type: 'SET_MODAL_VIEW', view }), + [dispatch] + ) - const setModalView = (view: MODAL_VIEWS) => - dispatch({ type: 'SET_MODAL_VIEW', view }) + const setSidebarView = useCallback( + (view: SIDEBAR_VIEWS) => dispatch({ type: 'SET_SIDEBAR_VIEW', view }), + [dispatch] + ) const value = useMemo( () => ({ @@ -182,8 +192,7 @@ export const UIProvider: FC = (props) => { openModal, closeModal, setModalView, - openToast, - closeToast, + setSidebarView, setUserAvatar, }), [state] diff --git a/components/ui/index.ts b/components/ui/index.ts index f2a293200..47bdbd9ff 100644 --- a/components/ui/index.ts +++ b/components/ui/index.ts @@ -10,4 +10,7 @@ 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 { default as Collapse } from './Collapse' +export { default as Quantity } from './Quantity' +export { default as Rating } from './Rating' export { useUI } from './context' diff --git a/components/wishlist/WishlistButton/WishlistButton.module.css b/components/wishlist/WishlistButton/WishlistButton.module.css new file mode 100644 index 000000000..3bdf1e710 --- /dev/null +++ b/components/wishlist/WishlistButton/WishlistButton.module.css @@ -0,0 +1,33 @@ +.root { + transition-duration: 0.2s; + transition-timing-function: ease; + transition-property: color, background-color, opacity; + @apply p-3 text-accent-9 flex items-center + justify-center font-semibold cursor-pointer + bg-accent-0 text-sm; +} + +.root:focus { + @apply outline-none; +} + +.icon { + transition-duration: 0.2s; + transition-timing-function: ease; + transition-property: transform, fill; + color: currentColor; +} + +.icon.loading { + fill: var(--pink-light); +} + +.icon.inWishlist { + fill: var(--pink); +} + +@screen lg { + .root { + @apply p-4; + } +} diff --git a/components/wishlist/WishlistButton/WishlistButton.tsx b/components/wishlist/WishlistButton/WishlistButton.tsx index 5841de11e..a48eac170 100644 --- a/components/wishlist/WishlistButton/WishlistButton.tsx +++ b/components/wishlist/WishlistButton/WishlistButton.tsx @@ -6,6 +6,7 @@ import useAddItem from '@framework/wishlist/use-add-item' import useCustomer from '@framework/customer/use-customer' import useWishlist from '@framework/wishlist/use-wishlist' import useRemoveItem from '@framework/wishlist/use-remove-item' +import s from './WishlistButton.module.css' import type { Product, ProductVariant } from '@commerce/types/product' type Props = { @@ -66,11 +67,16 @@ const WishlistButton: FC = ({ return ( ) } diff --git a/components/wishlist/WishlistCard/WishlistCard.module.css b/components/wishlist/WishlistCard/WishlistCard.module.css index 879184dac..cd0237d3b 100644 --- a/components/wishlist/WishlistCard/WishlistCard.module.css +++ b/components/wishlist/WishlistCard/WishlistCard.module.css @@ -1,5 +1,5 @@ .root { - @apply grid grid-cols-12 w-full gap-6 px-3 py-6 border-b border-accents-2 transition duration-100 ease-in-out; + @apply grid grid-cols-12 w-full gap-6 px-3 py-6 border-b border-accent-2 transition duration-100 ease-in-out; &:nth-child(3n + 1) { & .productBg { diff --git a/framework/bigcommerce/api/index.ts b/framework/bigcommerce/api/index.ts index 300f1087b..f28f2a1f4 100644 --- a/framework/bigcommerce/api/index.ts +++ b/framework/bigcommerce/api/index.ts @@ -4,8 +4,8 @@ import { CommerceAPIConfig, getCommerceApi as commerceApi, } from '@commerce/api' -import fetchGraphqlApi from './utils/fetch-graphql-api' -import fetchStoreApi from './utils/fetch-store-api' +import createFetchGraphqlApi from './utils/fetch-graphql-api' +import createFetchStoreApi from './utils/fetch-store-api' import type { CartAPI } from './endpoints/cart' import type { CustomerAPI } from './endpoints/customer' @@ -68,14 +68,14 @@ const config: BigcommerceConfig = { customerCookie: 'SHOP_TOKEN', cartCookie: process.env.BIGCOMMERCE_CART_COOKIE ?? 'bc_cartId', cartCookieMaxAge: ONE_DAY * 30, - fetch: fetchGraphqlApi, + fetch: createFetchGraphqlApi(() => getCommerceApi().getConfig()), applyLocale: true, // REST API only storeApiUrl: STORE_API_URL, storeApiToken: STORE_API_TOKEN, storeApiClientId: STORE_API_CLIENT_ID, storeChannelId: STORE_CHANNEL_ID, - storeApiFetch: fetchStoreApi, + storeApiFetch: createFetchStoreApi(() => getCommerceApi().getConfig()), } const operations = { diff --git a/framework/bigcommerce/api/utils/fetch-graphql-api.ts b/framework/bigcommerce/api/utils/fetch-graphql-api.ts index 7dc39f987..8cc76c067 100644 --- a/framework/bigcommerce/api/utils/fetch-graphql-api.ts +++ b/framework/bigcommerce/api/utils/fetch-graphql-api.ts @@ -1,38 +1,36 @@ import { FetcherError } from '@commerce/utils/errors' import type { GraphQLFetcher } from '@commerce/api' -import { provider } from '..' +import type { BigcommerceConfig } from '../index' import fetch from './fetch' -const fetchGraphqlApi: GraphQLFetcher = async ( - query: string, - { variables, preview } = {}, - fetchOptions -) => { - // log.warn(query) - const { config } = provider - const res = await fetch(config.commerceUrl + (preview ? '/preview' : ''), { - ...fetchOptions, - method: 'POST', - headers: { - Authorization: `Bearer ${config.apiToken}`, - ...fetchOptions?.headers, - 'Content-Type': 'application/json', - }, - body: JSON.stringify({ - query, - variables, - }), - }) - - const json = await res.json() - if (json.errors) { - throw new FetcherError({ - errors: json.errors ?? [{ message: 'Failed to fetch Bigcommerce API' }], - status: res.status, +const fetchGraphqlApi: (getConfig: () => BigcommerceConfig) => GraphQLFetcher = + (getConfig) => + async (query: string, { variables, preview } = {}, fetchOptions) => { + // log.warn(query) + const config = getConfig() + const res = await fetch(config.commerceUrl + (preview ? '/preview' : ''), { + ...fetchOptions, + method: 'POST', + headers: { + Authorization: `Bearer ${config.apiToken}`, + ...fetchOptions?.headers, + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + query, + variables, + }), }) + + const json = await res.json() + if (json.errors) { + throw new FetcherError({ + errors: json.errors ?? [{ message: 'Failed to fetch Bigcommerce API' }], + status: res.status, + }) + } + + return { data: json.data, res } } - return { data: json.data, res } -} - export default fetchGraphqlApi diff --git a/framework/bigcommerce/api/utils/fetch-store-api.ts b/framework/bigcommerce/api/utils/fetch-store-api.ts index a00b3777a..1e44b28f9 100644 --- a/framework/bigcommerce/api/utils/fetch-store-api.ts +++ b/framework/bigcommerce/api/utils/fetch-store-api.ts @@ -1,56 +1,56 @@ import type { RequestInit, Response } from '@vercel/fetch' -import { provider } from '..' +import type { BigcommerceConfig } from '../index' import { BigcommerceApiError, BigcommerceNetworkError } from './errors' import fetch from './fetch' -export default async function fetchStoreApi( - endpoint: string, - options?: RequestInit -): Promise { - const { config } = provider - let res: Response +const fetchStoreApi = + (getConfig: () => BigcommerceConfig) => + async (endpoint: string, options?: RequestInit): Promise => { + const config = getConfig() + let res: Response - try { - res = await fetch(config.storeApiUrl + endpoint, { - ...options, - headers: { - ...options?.headers, - 'Content-Type': 'application/json', - 'X-Auth-Token': config.storeApiToken, - 'X-Auth-Client': config.storeApiClientId, - }, - }) - } catch (error) { - throw new BigcommerceNetworkError( - `Fetch to Bigcommerce failed: ${error.message}` - ) + try { + res = await fetch(config.storeApiUrl + endpoint, { + ...options, + headers: { + ...options?.headers, + 'Content-Type': 'application/json', + 'X-Auth-Token': config.storeApiToken, + 'X-Auth-Client': config.storeApiClientId, + }, + }) + } catch (error) { + throw new BigcommerceNetworkError( + `Fetch to Bigcommerce failed: ${error.message}` + ) + } + + const contentType = res.headers.get('Content-Type') + const isJSON = contentType?.includes('application/json') + + if (!res.ok) { + const data = isJSON ? await res.json() : await getTextOrNull(res) + const headers = getRawHeaders(res) + const msg = `Big Commerce API error (${ + res.status + }) \nHeaders: ${JSON.stringify(headers, null, 2)}\n${ + typeof data === 'string' ? data : JSON.stringify(data, null, 2) + }` + + throw new BigcommerceApiError(msg, res, data) + } + + if (res.status !== 204 && !isJSON) { + throw new BigcommerceApiError( + `Fetch to Bigcommerce API failed, expected JSON content but found: ${contentType}`, + res + ) + } + + // If something was removed, the response will be empty + return res.status === 204 ? null : await res.json() } - - const contentType = res.headers.get('Content-Type') - const isJSON = contentType?.includes('application/json') - - if (!res.ok) { - const data = isJSON ? await res.json() : await getTextOrNull(res) - const headers = getRawHeaders(res) - const msg = `Big Commerce API error (${ - res.status - }) \nHeaders: ${JSON.stringify(headers, null, 2)}\n${ - typeof data === 'string' ? data : JSON.stringify(data, null, 2) - }` - - throw new BigcommerceApiError(msg, res, data) - } - - if (res.status !== 204 && !isJSON) { - throw new BigcommerceApiError( - `Fetch to Bigcommerce API failed, expected JSON content but found: ${contentType}`, - res - ) - } - - // If something was removed, the response will be empty - return res.status === 204 ? null : await res.json() -} +export default fetchStoreApi function getRawHeaders(res: Response) { const headers: { [key: string]: string } = {} diff --git a/framework/bigcommerce/index.tsx b/framework/bigcommerce/index.tsx index b35785ed2..024e54b56 100644 --- a/framework/bigcommerce/index.tsx +++ b/framework/bigcommerce/index.tsx @@ -4,7 +4,8 @@ import { CommerceProvider as CoreCommerceProvider, useCommerce as useCoreCommerce, } from '@commerce' -import { bigcommerceProvider, BigcommerceProvider } from './provider' +import { bigcommerceProvider } from './provider' +import type { BigcommerceProvider } from './provider' export { bigcommerceProvider } export type { BigcommerceProvider } diff --git a/framework/commerce/api/index.ts b/framework/commerce/api/index.ts index 8b44bea33..32fe8cf80 100644 --- a/framework/commerce/api/index.ts +++ b/framework/commerce/api/index.ts @@ -72,9 +72,8 @@ export type APIProvider = { operations: APIOperations } -export type CommerceAPI< - P extends APIProvider = APIProvider -> = CommerceAPICore

    & AllOperations

    +export type CommerceAPI

    = + CommerceAPICore

    & AllOperations

    export class CommerceAPICore

    { constructor(readonly provider: P) {} @@ -134,17 +133,17 @@ export function getEndpoint< } } -export const createEndpoint = >( - endpoint: API['endpoint'] -) =>

    ( - commerce: CommerceAPI

    , - context?: Partial & { - config?: P['config'] - options?: API['schema']['endpoint']['options'] +export const createEndpoint = + >(endpoint: API['endpoint']) => +

    ( + commerce: CommerceAPI

    , + context?: Partial & { + config?: P['config'] + options?: API['schema']['endpoint']['options'] + } + ): NextApiHandler => { + return getEndpoint(commerce, { ...endpoint, ...context }) } -): NextApiHandler => { - return getEndpoint(commerce, { ...endpoint, ...context }) -} export interface CommerceAPIConfig { locale?: string diff --git a/framework/commerce/config.js b/framework/commerce/config.js index 9e9799528..1ba522a1c 100644 --- a/framework/commerce/config.js +++ b/framework/commerce/config.js @@ -7,7 +7,14 @@ const fs = require('fs') const merge = require('deepmerge') const prettier = require('prettier') -const PROVIDERS = ['bigcommerce', 'shopify', 'swell', 'vendure', 'saleor'] +const PROVIDERS = [ + 'bigcommerce', + 'saleor', + 'shopify', + 'swell', + 'vendure', + 'local', +] function getProviderName() { return ( @@ -18,9 +25,7 @@ function getProviderName() { ? 'shopify' : process.env.NEXT_PUBLIC_SWELL_STORE_ID ? 'swell' - : process.env.NEXT_PUBLIC_SALEOR_API_URL - ? 'saleor' - : null) + : 'local') ) } @@ -52,27 +57,11 @@ function withCommerceConfig(nextConfig = {}) { // Update paths in `tsconfig.json` to point to the selected provider if (config.commerce.updateTSConfig !== false) { - const tsconfigPath = path.join(process.cwd(), 'tsconfig.json') - const tsconfig = require(tsconfigPath) - - tsconfig.compilerOptions.paths['@framework'] = [`framework/${name}`] - tsconfig.compilerOptions.paths['@framework/*'] = [`framework/${name}/*`] - - // When running for production it may be useful to exclude the other providers - // from TS checking - if (process.env.VERCEL) { - const exclude = tsconfig.exclude.filter( - (item) => !item.startsWith('framework/') - ) - - tsconfig.exclude = PROVIDERS.reduce((exclude, current) => { - if (current !== name) exclude.push(`framework/${current}`) - return exclude - }, exclude) - } + const staticTsconfigPath = path.join(process.cwd(), 'tsconfig.json') + const tsconfig = require('../../tsconfig.js') fs.writeFileSync( - tsconfigPath, + staticTsconfigPath, prettier.format(JSON.stringify(tsconfig), { parser: 'json' }) ) } diff --git a/framework/commerce/new-provider.md b/framework/commerce/new-provider.md index ac6692fbf..8c2feeab2 100644 --- a/framework/commerce/new-provider.md +++ b/framework/commerce/new-provider.md @@ -58,7 +58,8 @@ import { CommerceProvider as CoreCommerceProvider, useCommerce as useCoreCommerce, } from '@commerce' -import { bigcommerceProvider, BigcommerceProvider } from './provider' +import { bigcommerceProvider } from './provider' +import type { BigcommerceProvider } from './provider' export { bigcommerceProvider } export type { BigcommerceProvider } diff --git a/framework/commerce/types/cart.ts b/framework/commerce/types/cart.ts index 7826f9b2d..e4af878de 100644 --- a/framework/commerce/types/cart.ts +++ b/framework/commerce/types/cart.ts @@ -165,15 +165,13 @@ export type AddItemHandler = AddItemHook & { body: { cartId: string } } -export type UpdateItemHandler< - T extends CartTypes = CartTypes -> = UpdateItemHook & { - data: T['cart'] - body: { cartId: string } -} +export type UpdateItemHandler = + UpdateItemHook & { + data: T['cart'] + body: { cartId: string } + } -export type RemoveItemHandler< - T extends CartTypes = CartTypes -> = RemoveItemHook & { - body: { cartId: string } -} +export type RemoveItemHandler = + RemoveItemHook & { + body: { cartId: string } + } diff --git a/framework/commerce/types/product.ts b/framework/commerce/types/product.ts index a12e332b4..6a68d8ad1 100644 --- a/framework/commerce/types/product.ts +++ b/framework/commerce/types/product.ts @@ -5,7 +5,7 @@ export type ProductImage = { export type ProductPrice = { value: number - currencyCode?: 'USD' | 'ARS' | string + currencyCode?: 'USD' | 'EUR' | 'ARS' | string retailPrice?: number salePrice?: number listPrice?: number diff --git a/framework/local/.env.template b/framework/local/.env.template new file mode 100644 index 000000000..873eea7e7 --- /dev/null +++ b/framework/local/.env.template @@ -0,0 +1 @@ +COMMERCE_PROVIDER=local \ No newline at end of file diff --git a/framework/local/README.md b/framework/local/README.md new file mode 100644 index 000000000..a3bc1db32 --- /dev/null +++ b/framework/local/README.md @@ -0,0 +1 @@ +# Next.js Local Provider diff --git a/framework/local/api/endpoints/cart/index.ts b/framework/local/api/endpoints/cart/index.ts new file mode 100644 index 000000000..491bf0ac9 --- /dev/null +++ b/framework/local/api/endpoints/cart/index.ts @@ -0,0 +1 @@ +export default function noopApi(...args: any[]): void {} diff --git a/framework/local/api/endpoints/catalog/index.ts b/framework/local/api/endpoints/catalog/index.ts new file mode 100644 index 000000000..491bf0ac9 --- /dev/null +++ b/framework/local/api/endpoints/catalog/index.ts @@ -0,0 +1 @@ +export default function noopApi(...args: any[]): void {} diff --git a/framework/local/api/endpoints/catalog/products.ts b/framework/local/api/endpoints/catalog/products.ts new file mode 100644 index 000000000..491bf0ac9 --- /dev/null +++ b/framework/local/api/endpoints/catalog/products.ts @@ -0,0 +1 @@ +export default function noopApi(...args: any[]): void {} diff --git a/framework/local/api/endpoints/checkout/index.ts b/framework/local/api/endpoints/checkout/index.ts new file mode 100644 index 000000000..491bf0ac9 --- /dev/null +++ b/framework/local/api/endpoints/checkout/index.ts @@ -0,0 +1 @@ +export default function noopApi(...args: any[]): void {} diff --git a/framework/local/api/endpoints/customer/index.ts b/framework/local/api/endpoints/customer/index.ts new file mode 100644 index 000000000..491bf0ac9 --- /dev/null +++ b/framework/local/api/endpoints/customer/index.ts @@ -0,0 +1 @@ +export default function noopApi(...args: any[]): void {} diff --git a/framework/local/api/endpoints/login/index.ts b/framework/local/api/endpoints/login/index.ts new file mode 100644 index 000000000..491bf0ac9 --- /dev/null +++ b/framework/local/api/endpoints/login/index.ts @@ -0,0 +1 @@ +export default function noopApi(...args: any[]): void {} diff --git a/framework/local/api/endpoints/logout/index.ts b/framework/local/api/endpoints/logout/index.ts new file mode 100644 index 000000000..491bf0ac9 --- /dev/null +++ b/framework/local/api/endpoints/logout/index.ts @@ -0,0 +1 @@ +export default function noopApi(...args: any[]): void {} diff --git a/framework/local/api/endpoints/signup/index.ts b/framework/local/api/endpoints/signup/index.ts new file mode 100644 index 000000000..491bf0ac9 --- /dev/null +++ b/framework/local/api/endpoints/signup/index.ts @@ -0,0 +1 @@ +export default function noopApi(...args: any[]): void {} diff --git a/framework/local/api/endpoints/wishlist/index.tsx b/framework/local/api/endpoints/wishlist/index.tsx new file mode 100644 index 000000000..491bf0ac9 --- /dev/null +++ b/framework/local/api/endpoints/wishlist/index.tsx @@ -0,0 +1 @@ +export default function noopApi(...args: any[]): void {} diff --git a/framework/local/api/index.ts b/framework/local/api/index.ts new file mode 100644 index 000000000..9f403d2b3 --- /dev/null +++ b/framework/local/api/index.ts @@ -0,0 +1,42 @@ +import type { CommerceAPI, CommerceAPIConfig } from '@commerce/api' +import { getCommerceApi as commerceApi } from '@commerce/api' +import createFetcher from './utils/fetch-local' + +import getAllPages from './operations/get-all-pages' +import getPage from './operations/get-page' +import getSiteInfo from './operations/get-site-info' +import getCustomerWishlist from './operations/get-customer-wishlist' +import getAllProductPaths from './operations/get-all-product-paths' +import getAllProducts from './operations/get-all-products' +import getProduct from './operations/get-product' + +export interface LocalConfig extends CommerceAPIConfig {} +const config: LocalConfig = { + commerceUrl: '', + apiToken: '', + cartCookie: '', + customerCookie: '', + cartCookieMaxAge: 2592000, + fetch: createFetcher(() => getCommerceApi().getConfig()), +} + +const operations = { + getAllPages, + getPage, + getSiteInfo, + getCustomerWishlist, + getAllProductPaths, + getAllProducts, + getProduct, +} + +export const provider = { config, operations } + +export type Provider = typeof provider +export type LocalAPI

    = CommerceAPI

    + +export function getCommerceApi

    ( + customProvider: P = provider as any +): LocalAPI

    { + return commerceApi(customProvider as any) +} diff --git a/framework/local/api/operations/get-all-pages.ts b/framework/local/api/operations/get-all-pages.ts new file mode 100644 index 000000000..b258fe70a --- /dev/null +++ b/framework/local/api/operations/get-all-pages.ts @@ -0,0 +1,19 @@ +export type Page = { url: string } +export type GetAllPagesResult = { pages: Page[] } +import type { LocalConfig } from '../index' + +export default function getAllPagesOperation() { + function getAllPages({ + config, + preview, + }: { + url?: string + config?: Partial + preview?: boolean + }): Promise { + return Promise.resolve({ + pages: [], + }) + } + return getAllPages +} diff --git a/framework/local/api/operations/get-all-product-paths.ts b/framework/local/api/operations/get-all-product-paths.ts new file mode 100644 index 000000000..fff24e791 --- /dev/null +++ b/framework/local/api/operations/get-all-product-paths.ts @@ -0,0 +1,15 @@ +import data from '../../data.json' + +export type GetAllProductPathsResult = { + products: Array<{ path: string }> +} + +export default function getAllProductPathsOperation() { + function getAllProductPaths(): Promise { + return Promise.resolve({ + products: data.products.map(({ path }) => ({ path })), + }) + } + + return getAllProductPaths +} diff --git a/framework/local/api/operations/get-all-products.ts b/framework/local/api/operations/get-all-products.ts new file mode 100644 index 000000000..21a04559d --- /dev/null +++ b/framework/local/api/operations/get-all-products.ts @@ -0,0 +1,25 @@ +import { Product } from '@commerce/types/product' +import { GetAllProductsOperation } from '@commerce/types/product' +import type { OperationContext } from '@commerce/api/operations' +import type { LocalConfig, Provider } from '../index' +import data from '../../data.json' + +export default function getAllProductsOperation({ + commerce, +}: OperationContext) { + async function getAllProducts({ + query = '', + variables, + config, + }: { + query?: string + variables?: T['variables'] + config?: Partial + preview?: boolean + } = {}): Promise<{ products: Product[] | any[] }> { + return { + products: data.products, + } + } + return getAllProducts +} diff --git a/framework/local/api/operations/get-customer-wishlist.ts b/framework/local/api/operations/get-customer-wishlist.ts new file mode 100644 index 000000000..8c34b9e87 --- /dev/null +++ b/framework/local/api/operations/get-customer-wishlist.ts @@ -0,0 +1,6 @@ +export default function getCustomerWishlistOperation() { + function getCustomerWishlist(): any { + return { wishlist: {} } + } + return getCustomerWishlist +} diff --git a/framework/local/api/operations/get-page.ts b/framework/local/api/operations/get-page.ts new file mode 100644 index 000000000..b0cfdf58f --- /dev/null +++ b/framework/local/api/operations/get-page.ts @@ -0,0 +1,13 @@ +export type Page = any +export type GetPageResult = { page?: Page } + +export type PageVariables = { + id: number +} + +export default function getPageOperation() { + function getPage(): Promise { + return Promise.resolve({}) + } + return getPage +} diff --git a/framework/local/api/operations/get-product.ts b/framework/local/api/operations/get-product.ts new file mode 100644 index 000000000..690b1aab9 --- /dev/null +++ b/framework/local/api/operations/get-product.ts @@ -0,0 +1,26 @@ +import type { LocalConfig } from '../index' +import { Product } from '@commerce/types/product' +import { GetProductOperation } from '@commerce/types/product' +import data from '../../data.json' +import type { OperationContext } from '@commerce/api/operations' + +export default function getProductOperation({ + commerce, +}: OperationContext) { + async function getProduct({ + query = '', + variables, + config, + }: { + query?: string + variables?: T['variables'] + config?: Partial + preview?: boolean + } = {}): Promise { + return { + product: data.products.find(({ slug }) => slug === variables!.slug), + } + } + + return getProduct +} diff --git a/framework/local/api/operations/get-site-info.ts b/framework/local/api/operations/get-site-info.ts new file mode 100644 index 000000000..d43ed8359 --- /dev/null +++ b/framework/local/api/operations/get-site-info.ts @@ -0,0 +1,43 @@ +import { OperationContext } from '@commerce/api/operations' +import { Category } from '@commerce/types/site' +import { LocalConfig } from '../index' + +export type GetSiteInfoResult< + T extends { categories: any[]; brands: any[] } = { + categories: Category[] + brands: any[] + } +> = T + +export default function getSiteInfoOperation({}: OperationContext) { + function getSiteInfo({ + query, + variables, + config: cfg, + }: { + query?: string + variables?: any + config?: Partial + preview?: boolean + } = {}): Promise { + return Promise.resolve({ + categories: [ + { + id: 'new-arrivals', + name: 'New Arrivals', + slug: 'new-arrivals', + path: '/new-arrivals', + }, + { + id: 'featured', + name: 'Featured', + slug: 'featured', + path: '/featured', + }, + ], + brands: [], + }) + } + + return getSiteInfo +} diff --git a/framework/local/api/operations/index.ts b/framework/local/api/operations/index.ts new file mode 100644 index 000000000..086fdf83a --- /dev/null +++ b/framework/local/api/operations/index.ts @@ -0,0 +1,6 @@ +export { default as getPage } from './get-page' +export { default as getSiteInfo } from './get-site-info' +export { default as getAllPages } from './get-all-pages' +export { default as getProduct } from './get-product' +export { default as getAllProducts } from './get-all-products' +export { default as getAllProductPaths } from './get-all-product-paths' diff --git a/framework/local/api/utils/fetch-local.ts b/framework/local/api/utils/fetch-local.ts new file mode 100644 index 000000000..aa85cf27b --- /dev/null +++ b/framework/local/api/utils/fetch-local.ts @@ -0,0 +1,34 @@ +import { FetcherError } from '@commerce/utils/errors' +import type { GraphQLFetcher } from '@commerce/api' +import type { LocalConfig } from '../index' +import fetch from './fetch' + +const fetchGraphqlApi: (getConfig: () => LocalConfig) => GraphQLFetcher = + (getConfig) => + async (query: string, { variables, preview } = {}, fetchOptions) => { + const config = getConfig() + const res = await fetch(config.commerceUrl, { + ...fetchOptions, + method: 'POST', + headers: { + ...fetchOptions?.headers, + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + query, + variables, + }), + }) + + const json = await res.json() + if (json.errors) { + throw new FetcherError({ + errors: json.errors ?? [{ message: 'Failed to fetch for API' }], + status: res.status, + }) + } + + return { data: json.data, res } + } + +export default fetchGraphqlApi diff --git a/framework/local/api/utils/fetch.ts b/framework/local/api/utils/fetch.ts new file mode 100644 index 000000000..9d9fff3ed --- /dev/null +++ b/framework/local/api/utils/fetch.ts @@ -0,0 +1,3 @@ +import zeitFetch from '@vercel/fetch' + +export default zeitFetch() diff --git a/framework/local/auth/index.ts b/framework/local/auth/index.ts new file mode 100644 index 000000000..36e757a89 --- /dev/null +++ b/framework/local/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/local/auth/use-login.tsx b/framework/local/auth/use-login.tsx new file mode 100644 index 000000000..28351dc7f --- /dev/null +++ b/framework/local/auth/use-login.tsx @@ -0,0 +1,16 @@ +import { MutationHook } from '@commerce/utils/types' +import useLogin, { UseLogin } from '@commerce/auth/use-login' + +export default useLogin as UseLogin + +export const handler: MutationHook = { + fetchOptions: { + query: '', + }, + async fetcher() { + return null + }, + useHook: () => () => { + return async function () {} + }, +} diff --git a/framework/local/auth/use-logout.tsx b/framework/local/auth/use-logout.tsx new file mode 100644 index 000000000..9b3fc3e44 --- /dev/null +++ b/framework/local/auth/use-logout.tsx @@ -0,0 +1,17 @@ +import { MutationHook } from '@commerce/utils/types' +import useLogout, { UseLogout } from '@commerce/auth/use-logout' + +export default useLogout as UseLogout + +export const handler: MutationHook = { + fetchOptions: { + query: '', + }, + async fetcher() { + return null + }, + useHook: + ({ fetch }) => + () => + async () => {}, +} diff --git a/framework/local/auth/use-signup.tsx b/framework/local/auth/use-signup.tsx new file mode 100644 index 000000000..e9ad13458 --- /dev/null +++ b/framework/local/auth/use-signup.tsx @@ -0,0 +1,19 @@ +import { useCallback } from 'react' +import useCustomer from '../customer/use-customer' +import { MutationHook } from '@commerce/utils/types' +import useSignup, { UseSignup } from '@commerce/auth/use-signup' + +export default useSignup as UseSignup + +export const handler: MutationHook = { + fetchOptions: { + query: '', + }, + async fetcher() { + return null + }, + useHook: + ({ fetch }) => + () => + () => {}, +} diff --git a/framework/local/cart/index.ts b/framework/local/cart/index.ts new file mode 100644 index 000000000..3b8ba990e --- /dev/null +++ b/framework/local/cart/index.ts @@ -0,0 +1,4 @@ +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 useUpdateItem } from './use-update-item' diff --git a/framework/local/cart/use-add-item.tsx b/framework/local/cart/use-add-item.tsx new file mode 100644 index 000000000..7f3d1061f --- /dev/null +++ b/framework/local/cart/use-add-item.tsx @@ -0,0 +1,17 @@ +import useAddItem, { UseAddItem } from '@commerce/cart/use-add-item' +import { MutationHook } from '@commerce/utils/types' + +export default useAddItem as UseAddItem +export const handler: MutationHook = { + fetchOptions: { + query: '', + }, + async fetcher({ input, options, fetch }) {}, + useHook: + ({ fetch }) => + () => { + return async function addItem() { + return {} + } + }, +} diff --git a/framework/local/cart/use-cart.tsx b/framework/local/cart/use-cart.tsx new file mode 100644 index 000000000..b3e509a21 --- /dev/null +++ b/framework/local/cart/use-cart.tsx @@ -0,0 +1,42 @@ +import { useMemo } from 'react' +import { SWRHook } from '@commerce/utils/types' +import useCart, { UseCart } from '@commerce/cart/use-cart' + +export default useCart as UseCart + +export const handler: SWRHook = { + fetchOptions: { + query: '', + }, + async fetcher() { + return { + id: '', + createdAt: '', + currency: { code: '' }, + taxesIncluded: '', + lineItems: [], + lineItemsSubtotalPrice: '', + subtotalPrice: 0, + totalPrice: 0, + } + }, + useHook: + ({ useData }) => + (input) => { + return useMemo( + () => + Object.create( + {}, + { + isEmpty: { + get() { + return true + }, + enumerable: true, + }, + } + ), + [] + ) + }, +} diff --git a/framework/local/cart/use-remove-item.tsx b/framework/local/cart/use-remove-item.tsx new file mode 100644 index 000000000..b4ed583b8 --- /dev/null +++ b/framework/local/cart/use-remove-item.tsx @@ -0,0 +1,18 @@ +import { MutationHook } from '@commerce/utils/types' +import useRemoveItem, { UseRemoveItem } from '@commerce/cart/use-remove-item' + +export default useRemoveItem as UseRemoveItem + +export const handler: MutationHook = { + fetchOptions: { + query: '', + }, + async fetcher({ input, options, fetch }) {}, + useHook: + ({ fetch }) => + () => { + return async function removeItem(input) { + return {} + } + }, +} diff --git a/framework/local/cart/use-update-item.tsx b/framework/local/cart/use-update-item.tsx new file mode 100644 index 000000000..06d703f70 --- /dev/null +++ b/framework/local/cart/use-update-item.tsx @@ -0,0 +1,18 @@ +import { MutationHook } from '@commerce/utils/types' +import useUpdateItem, { UseUpdateItem } from '@commerce/cart/use-update-item' + +export default useUpdateItem as UseUpdateItem + +export const handler: MutationHook = { + fetchOptions: { + query: '', + }, + async fetcher({ input, options, fetch }) {}, + useHook: + ({ fetch }) => + () => { + return async function addItem() { + return {} + } + }, +} diff --git a/framework/local/commerce.config.json b/framework/local/commerce.config.json new file mode 100644 index 000000000..5a0376a31 --- /dev/null +++ b/framework/local/commerce.config.json @@ -0,0 +1,6 @@ +{ + "provider": "local", + "features": { + "wishlist": false + } +} diff --git a/framework/local/customer/index.ts b/framework/local/customer/index.ts new file mode 100644 index 000000000..6c903ecc5 --- /dev/null +++ b/framework/local/customer/index.ts @@ -0,0 +1 @@ +export { default as useCustomer } from './use-customer' diff --git a/framework/local/customer/use-customer.tsx b/framework/local/customer/use-customer.tsx new file mode 100644 index 000000000..41757cd0d --- /dev/null +++ b/framework/local/customer/use-customer.tsx @@ -0,0 +1,15 @@ +import { SWRHook } from '@commerce/utils/types' +import useCustomer, { UseCustomer } from '@commerce/customer/use-customer' + +export default useCustomer as UseCustomer +export const handler: SWRHook = { + fetchOptions: { + query: '', + }, + async fetcher({ input, options, fetch }) {}, + useHook: () => () => { + return async function addItem() { + return {} + } + }, +} diff --git a/framework/local/data.json b/framework/local/data.json new file mode 100644 index 000000000..18c8ee718 --- /dev/null +++ b/framework/local/data.json @@ -0,0 +1,235 @@ +{ + "products": [ + { + "id": "Z2lkOi8vc2hvcGlmeS9Qcm9kdWN0LzU0NDczMjUwMjQ0MjA=", + "name": "New Short Sleeve T-Shirt", + "vendor": "Next.js", + "path": "/new-short-sleeve-t-shirt", + "slug": "new-short-sleeve-t-shirt", + "price": { "value": 25, "currencyCode": "USD" }, + "descriptionHtml": "

    Show off your love for Next.js and Vercel with this unique, limited edition t-shirt. This design is part of a limited run, numbered drop at the June 2021 Next.js Conf. It features a unique, handcrafted triangle design. Get it while supplies last – only 200 of these shirts will be made! All proceeds will be donated to charity.

    ", + "images": [ + { + "url": "/assets/drop-shirt-0.png", + "altText": "Shirt", + "width": 1000, + "height": 1000 + }, + { + "url": "/assets/drop-shirt-1.png", + "altText": "Shirt", + "width": 1000, + "height": 1000 + }, + { + "url": "/assets/drop-shirt-2.png", + "altText": "Shirt", + "width": 1000, + "height": 1000 + } + ], + "variants": [ + { + "id": "Z2lkOi8vc2hvcGlmeS9Qcm9kdWN0LzU0NDczMjUwMjQ0MjAss=", + "options": [ + { + "__typename": "MultipleChoiceOption", + "id": "asd", + "displayName": "Size", + "values": [ + { + "label": "XL" + } + ] + } + ] + } + ], + "options": [ + { + "id": "option-color", + "displayName": "Color", + "values": [ + { + "label": "color", + "hexColors": ["#222"] + } + ] + }, + { + "id": "option-size", + "displayName": "Size", + "values": [ + { + "label": "S" + }, + { + "label": "M" + }, + { + "label": "L" + } + ] + } + ] + }, + { + "id": "Z2lkOi8vc2hvcGlmeS9Qcm9ksdWN0LzU0NDczMjUwMjQ0MjA=", + "name": "Lightweight Jacket", + "vendor": "Next.js", + "path": "/lightweight-jacket", + "slug": "lightweight-jacket", + "price": { "value": 249.99, "currencyCode": "USD" }, + "descriptionHtml": "

    Show off your love for Next.js and Vercel with this unique, limited edition t-shirt. This design is part of a limited run, numbered drop at the June 2021 Next.js Conf. It features a unique, handcrafted triangle design. Get it while supplies last – only 200 of these shirts will be made! All proceeds will be donated to charity.

    ", + "images": [ + { + "url": "/assets/lightweight-jacket-0.png", + "altText": "Lightweight Jacket", + "width": 1000, + "height": 1000 + }, + { + "url": "/assets/lightweight-jacket-1.png", + "altText": "Lightweight Jacket", + "width": 1000, + "height": 1000 + }, + { + "url": "/assets/lightweight-jacket-2.png", + "altText": "Lightweight Jacket", + "width": 1000, + "height": 1000 + } + ], + "variants": [ + { + "id": "Z2lkOid8vc2hvcGlmeS9Qcm9kdWN0LzU0NDczMjUwMjQ0MjAss=", + "options": [ + { + "__typename": "MultipleChoiceOption", + "id": "asd", + "displayName": "Size", + "values": [ + { + "label": "XL" + } + ] + } + ] + } + ], + "options": [ + { + "id": "option-color", + "displayName": "Color", + "values": [ + { + "label": "color", + "hexColors": ["#222"] + } + ] + }, + { + "id": "option-size", + "displayName": "Size", + "values": [ + { + "label": "S" + }, + { + "label": "M" + }, + { + "label": "L" + } + ] + } + ] + }, + { + "id": "Z2lkOis8vc2hvcGlmsddeS9Qcm9kdWN0LzU0NDczMjUwMjQ0MjA=", + "name": "Shirt", + "vendor": "Next.js", + "path": "/shirt", + "slug": "shirt", + "price": { "value": 25, "currencyCode": "USD" }, + "descriptionHtml": "

    Show off your love for Next.js and Vercel with this unique, limited edition t-shirt. This design is part of a limited run, numbered drop at the June 2021 Next.js Conf. It features a unique, handcrafted triangle design. Get it while supplies last – only 200 of these shirts will be made! All proceeds will be donated to charity.

    ", + "images": [ + { + "url": "/assets/t-shirt-0.png", + "altText": "Shirt", + "width": 1000, + "height": 1000 + }, + { + "url": "/assets/t-shirt-1.png", + "altText": "Shirt", + "width": 1000, + "height": 1000 + }, + { + "url": "/assets/t-shirt-2.png", + "altText": "Shirt", + "width": 1000, + "height": 1000 + }, + { + "url": "/assets/t-shirt-3.png", + "altText": "Shirt", + "width": 1000, + "height": 1000 + }, + { + "url": "/assets/t-shirt-4.png", + "altText": "Shirt", + "width": 1000, + "height": 1000 + } + ], + "variants": [ + { + "id": "Z2lkOi8vc2hvcGlmeS9Qcms9kdWN0LzU0NDczMjUwMjQ0MjAss=", + "options": [ + { + "__typename": "MultipleChoiceOption", + "id": "asd", + "displayName": "Size", + "values": [ + { + "label": "XL" + } + ] + } + ] + } + ], + "options": [ + { + "id": "option-color", + "displayName": "Color", + "values": [ + { + "label": "color", + "hexColors": ["#222"] + } + ] + }, + { + "id": "option-size", + "displayName": "Size", + "values": [ + { + "label": "S" + }, + { + "label": "M" + }, + { + "label": "L" + } + ] + } + ] + } + ] +} diff --git a/framework/local/fetcher.ts b/framework/local/fetcher.ts new file mode 100644 index 000000000..69943d1df --- /dev/null +++ b/framework/local/fetcher.ts @@ -0,0 +1,11 @@ +import { Fetcher } from '@commerce/utils/types' + +export const fetcher: Fetcher = async () => { + console.log('FETCHER') + const res = await fetch('./data.json') + if (res.ok) { + const { data } = await res.json() + return data + } + throw res +} diff --git a/framework/local/index.tsx b/framework/local/index.tsx new file mode 100644 index 000000000..2ec304f63 --- /dev/null +++ b/framework/local/index.tsx @@ -0,0 +1,32 @@ +import * as React from 'react' +import { ReactNode } from 'react' +import { localProvider } from './provider' +import { + CommerceConfig, + CommerceProvider as CoreCommerceProvider, + useCommerce as useCoreCommerce, +} from '@commerce' + +export const localConfig: CommerceConfig = { + locale: 'en-us', + cartCookie: 'session', +} + +export function CommerceProvider({ + children, + ...config +}: { + children?: ReactNode + locale: string +} & Partial) { + return ( + + {children} + + ) +} + +export const useCommerce = () => useCoreCommerce() diff --git a/framework/local/next.config.js b/framework/local/next.config.js new file mode 100644 index 000000000..ce46b706f --- /dev/null +++ b/framework/local/next.config.js @@ -0,0 +1,8 @@ +const commerce = require('./commerce.config.json') + +module.exports = { + commerce, + images: { + domains: ['localhost'], + }, +} diff --git a/framework/local/product/index.ts b/framework/local/product/index.ts new file mode 100644 index 000000000..426a3edcd --- /dev/null +++ b/framework/local/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/local/product/use-price.tsx b/framework/local/product/use-price.tsx new file mode 100644 index 000000000..0174faf5e --- /dev/null +++ b/framework/local/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/local/product/use-search.tsx b/framework/local/product/use-search.tsx new file mode 100644 index 000000000..30e699537 --- /dev/null +++ b/framework/local/product/use-search.tsx @@ -0,0 +1,17 @@ +import { SWRHook } from '@commerce/utils/types' +import useSearch, { UseSearch } from '@commerce/product/use-search' +export default useSearch as UseSearch + +export const handler: SWRHook = { + fetchOptions: { + query: '', + }, + async fetcher({ input, options, fetch }) {}, + useHook: () => () => { + return { + data: { + products: [], + }, + } + }, +} diff --git a/framework/local/provider.ts b/framework/local/provider.ts new file mode 100644 index 000000000..e6a2b0a21 --- /dev/null +++ b/framework/local/provider.ts @@ -0,0 +1,21 @@ +import { fetcher } from './fetcher' +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' + +export type Provider = typeof localProvider +export const localProvider = { + locale: 'en-us', + cartCookie: 'session', + fetcher: fetcher, + cart: { useCart, useAddItem, useUpdateItem, useRemoveItem }, + customer: { useCustomer }, + products: { useSearch }, + auth: { useLogin, useLogout, useSignup }, +} diff --git a/framework/local/wishlist/use-add-item.tsx b/framework/local/wishlist/use-add-item.tsx new file mode 100644 index 000000000..75f067c3a --- /dev/null +++ b/framework/local/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/local/wishlist/use-remove-item.tsx b/framework/local/wishlist/use-remove-item.tsx new file mode 100644 index 000000000..a2d3a8a05 --- /dev/null +++ b/framework/local/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/local/wishlist/use-wishlist.tsx b/framework/local/wishlist/use-wishlist.tsx new file mode 100644 index 000000000..9fe0e758f --- /dev/null +++ b/framework/local/wishlist/use-wishlist.tsx @@ -0,0 +1,43 @@ +import { HookFetcher } from '@commerce/utils/types' +import type { Product } from '@commerce/types/product' + +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) diff --git a/framework/saleor/api/utils/fetch-graphql-api.ts b/framework/saleor/api/utils/fetch-graphql-api.ts index 71199d661..3145409ad 100644 --- a/framework/saleor/api/utils/fetch-graphql-api.ts +++ b/framework/saleor/api/utils/fetch-graphql-api.ts @@ -4,7 +4,7 @@ import fetch from './fetch' import { API_URL } from '../../const' import { getError } from '../../utils/handle-fetch-response' import { getCommerceApi } from '..' -import { getToken } from '@framework/utils' +import { getToken } from '../../utils/index' const fetchGraphqlApi: GraphQLFetcher = async (query: string, { variables } = {}, fetchOptions) => { const config = getCommerceApi().getConfig() diff --git a/framework/shopify/api/operations/get-site-info.ts b/framework/shopify/api/operations/get-site-info.ts index 27b63b0f9..7f51d1d5c 100644 --- a/framework/shopify/api/operations/get-site-info.ts +++ b/framework/shopify/api/operations/get-site-info.ts @@ -35,9 +35,9 @@ export default function getSiteInfoOperation({ } = {}): Promise { const cfg = commerce.getConfig(config) - const categories = await getCategories(cfg) - const brands = await getBrands(cfg) - /* + const categoriesPromise = getCategories(cfg) + const brandsPromise = getBrands(cfg) + /* const { fetch, locale } = cfg const { data } = await fetch( query, @@ -53,8 +53,8 @@ export default function getSiteInfoOperation({ */ return { - categories, - brands, + categories: await categoriesPromise, + brands: await brandsPromise, } } diff --git a/framework/shopify/api/utils/fetch-graphql-api.ts b/framework/shopify/api/utils/fetch-graphql-api.ts index 321cba2aa..c45d57e70 100644 --- a/framework/shopify/api/utils/fetch-graphql-api.ts +++ b/framework/shopify/api/utils/fetch-graphql-api.ts @@ -9,26 +9,37 @@ const fetchGraphqlApi: GraphQLFetcher = async ( { 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, - }), - }) + try { + 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() + const { data, errors, status } = await res.json() - if (errors) { - throw getError(errors, status) + if (errors) { + throw getError(errors, status) + } + + return { data, res } + } catch (err) { + throw getError( + [ + { + message: `${err} \n Most likely related to an unexpected output. e.g the store might be protected with password or not available.`, + }, + ], + 500 + ) } - - return { data, res } } export default fetchGraphqlApi diff --git a/framework/shopify/index.tsx b/framework/shopify/index.tsx index 13ff9d1f8..46ed106c5 100644 --- a/framework/shopify/index.tsx +++ b/framework/shopify/index.tsx @@ -7,7 +7,8 @@ import { useCommerce as useCoreCommerce, } from '@commerce' -import { shopifyProvider, ShopifyProvider } from './provider' +import { shopifyProvider } from './provider' +import type { ShopifyProvider } from './provider' import { SHOPIFY_CHECKOUT_ID_COOKIE } from './const' export { shopifyProvider } diff --git a/framework/shopify/utils/handle-fetch-response.ts b/framework/shopify/utils/handle-fetch-response.ts index 8d7427d91..91d362d7d 100644 --- a/framework/shopify/utils/handle-fetch-response.ts +++ b/framework/shopify/utils/handle-fetch-response.ts @@ -1,6 +1,6 @@ import { FetcherError } from '@commerce/utils/errors' -export function getError(errors: any[], status: number) { +export function getError(errors: any[] | null, status: number) { errors = errors ?? [{ message: 'Failed to fetch Shopify API' }] return new FetcherError({ errors, status }) } diff --git a/framework/shopify/utils/normalize.ts b/framework/shopify/utils/normalize.ts index 7a42ca085..96262f418 100644 --- a/framework/shopify/utils/normalize.ts +++ b/framework/shopify/utils/normalize.ts @@ -86,6 +86,7 @@ const normalizeProductVariants = ({ edges }: ProductVariantConnection) => { name, values: [value], }) + return options }), } diff --git a/framework/swell/api/operations/get-site-info.ts b/framework/swell/api/operations/get-site-info.ts index 36fcebf01..ffb0c1542 100644 --- a/framework/swell/api/operations/get-site-info.ts +++ b/framework/swell/api/operations/get-site-info.ts @@ -1,8 +1,8 @@ import getCategories from '../../utils/get-categories' import getVendors, { Brands } from '../../utils/get-vendors' import { Provider, SwellConfig } from '../' -import { OperationContext } from '@commerce/api/operations' -import { Category } from '@commerce/types/site' +import type { OperationContext } from '@commerce/api/operations' +import type { Category } from '@commerce/types/site' export type GetSiteInfoResult< T extends { categories: any[]; brands: any[] } = { diff --git a/framework/vendure/auth/use-logout.tsx b/framework/vendure/auth/use-logout.tsx index 29bf5cb0d..be1b18586 100644 --- a/framework/vendure/auth/use-logout.tsx +++ b/framework/vendure/auth/use-logout.tsx @@ -18,16 +18,18 @@ export const handler: MutationHook = { }) return null }, - useHook: ({ fetch }) => () => { - const { mutate } = useCustomer() + useHook: + ({ fetch }) => + () => { + const { mutate } = useCustomer() - return useCallback( - async function logout() { - const data = await fetch() - await mutate(null, false) - return data - }, - [fetch, mutate] - ) - }, + return useCallback( + async function logout() { + const data = await fetch() + await mutate(null, false) + return data + }, + [fetch, mutate] + ) + }, } diff --git a/lib/search-props.tsx b/lib/search-props.tsx new file mode 100644 index 000000000..6910e0d83 --- /dev/null +++ b/lib/search-props.tsx @@ -0,0 +1,27 @@ +import type { GetStaticPropsContext, InferGetStaticPropsType } from 'next' + +import commerce from '@lib/api/commerce' + +export async function getSearchStaticProps({ + preview, + locale, + locales, +}: GetStaticPropsContext) { + const config = { locale, locales } + const pagesPromise = commerce.getAllPages({ config, preview }) + const siteInfoPromise = commerce.getSiteInfo({ config, preview }) + const { pages } = await pagesPromise + const { categories, brands } = await siteInfoPromise + return { + props: { + pages, + categories, + brands, + }, + revalidate: 200, + } +} + +export type SearchPropsType = InferGetStaticPropsType< + typeof getSearchStaticProps +> diff --git a/next.config.js b/next.config.js index 77d586e6c..19f5938f2 100644 --- a/next.config.js +++ b/next.config.js @@ -39,20 +39,6 @@ module.exports = withCommerceConfig({ source: `${process.env.NEXT_PUBLIC_VENDURE_LOCAL_URL}/:path*`, destination: `${process.env.NEXT_PUBLIC_VENDURE_SHOP_API_URL}/:path*`, }, - // 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(Boolean) }, }) diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 000000000..5acd15ea0 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,11033 @@ +{ + "name": "nextjs-commerce", + "version": "1.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@ardatan/aggregate-error": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/@ardatan/aggregate-error/-/aggregate-error-0.0.6.tgz", + "integrity": "sha512-vyrkEHG1jrukmzTPtyWB4NLPauUw5bQeg4uhn8f+1SSynmrOcyvlb1GKQjjgoBzElLdfXCRYX8UnBlhklOHYRQ==", + "dev": true, + "requires": { + "tslib": "~2.0.1" + }, + "dependencies": { + "tslib": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.3.tgz", + "integrity": "sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ==", + "dev": true + } + } + }, + "@babel/code-frame": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.13.tgz", + "integrity": "sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g==", + "dev": true, + "requires": { + "@babel/highlight": "^7.12.13" + } + }, + "@babel/compat-data": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.14.5.tgz", + "integrity": "sha512-kixrYn4JwfAVPa0f2yfzc2AWti6WRRyO3XjWW5PJAvtE11qhSayrrcrEnee05KAtNaPC+EwehE8Qt1UedEVB8w==", + "dev": true + }, + "@babel/core": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.14.5.tgz", + "integrity": "sha512-RN/AwP2DJmQTZSfiDaD+JQQ/J99KsIpOCfBE5pL+5jJSt7nI3nYGoAXZu+ffYSQ029NLs2DstZb+eR81uuARgg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.14.5", + "@babel/generator": "^7.14.5", + "@babel/helper-compilation-targets": "^7.14.5", + "@babel/helper-module-transforms": "^7.14.5", + "@babel/helpers": "^7.14.5", + "@babel/parser": "^7.14.5", + "@babel/template": "^7.14.5", + "@babel/traverse": "^7.14.5", + "@babel/types": "^7.14.5", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.1.2", + "semver": "^6.3.0", + "source-map": "^0.5.0" + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.14.5.tgz", + "integrity": "sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw==", + "dev": true, + "requires": { + "@babel/highlight": "^7.14.5" + } + }, + "@babel/generator": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.14.5.tgz", + "integrity": "sha512-y3rlP+/G25OIX3mYKKIOlQRcqj7YgrvHxOLbVmyLJ9bPmi5ttvUmpydVjcFjZphOktWuA7ovbx91ECloWTfjIA==", + "dev": true, + "requires": { + "@babel/types": "^7.14.5", + "jsesc": "^2.5.1", + "source-map": "^0.5.0" + } + }, + "@babel/helper-function-name": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.14.5.tgz", + "integrity": "sha512-Gjna0AsXWfFvrAuX+VKcN/aNNWonizBj39yGwUzVDVTlMYJMK2Wp6xdpy72mfArFq5uK+NOuexfzZlzI1z9+AQ==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.14.5", + "@babel/template": "^7.14.5", + "@babel/types": "^7.14.5" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.14.5.tgz", + "integrity": "sha512-hprxVPu6e5Kdp2puZUmvOGjaLv9TCe58E/Fl6hRq4YiVQxIcNvuq6uTM2r1mT/oPskuS9CgR+I94sqAYv0NGKA==", + "dev": true, + "requires": { + "@babel/types": "^7.14.5" + } + }, + "@babel/parser": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.14.5.tgz", + "integrity": "sha512-TM8C+xtH/9n1qzX+JNHi7AN2zHMTiPUtspO0ZdHflW8KaskkALhMmuMHb4bCmNdv9VAPzJX3/bXqkVLnAvsPfg==", + "dev": true + }, + "@babel/template": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.14.5.tgz", + "integrity": "sha512-6Z3Po85sfxRGachLULUhOmvAaOo7xCvqGQtxINai2mEGPFm6pQ4z5QInFnUrRpfoSV60BnjyF5F3c+15fxFV1g==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.14.5", + "@babel/parser": "^7.14.5", + "@babel/types": "^7.14.5" + } + }, + "@babel/traverse": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.14.5.tgz", + "integrity": "sha512-G3BiS15vevepdmFqmUc9X+64y0viZYygubAMO8SvBmKARuF6CPSZtH4Ng9vi/lrWlZFGe3FWdXNy835akH8Glg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.14.5", + "@babel/generator": "^7.14.5", + "@babel/helper-function-name": "^7.14.5", + "@babel/helper-hoist-variables": "^7.14.5", + "@babel/helper-split-export-declaration": "^7.14.5", + "@babel/parser": "^7.14.5", + "@babel/types": "^7.14.5", + "debug": "^4.1.0", + "globals": "^11.1.0" + } + }, + "@babel/types": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.5.tgz", + "integrity": "sha512-M/NzBpEL95I5Hh4dwhin5JlE7EzO5PHMAuzjxss3tiOBD46KfQvVedN/3jEPZvdRvtsK2222XfdHogNIttFgcg==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.14.5", + "to-fast-properties": "^2.0.0" + } + }, + "json5": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", + "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + } + } + }, + "@babel/generator": { + "version": "7.12.15", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.12.15.tgz", + "integrity": "sha512-6F2xHxBiFXWNSGb7vyCUTBF8RCLY66rS0zEPcP8t/nQyXjha5EuK4z7H5o7fWG8B4M7y6mqVWq1J+1PuwRhecQ==", + "dev": true, + "requires": { + "@babel/types": "^7.12.13", + "jsesc": "^2.5.1", + "source-map": "^0.5.0" + }, + "dependencies": { + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + } + } + }, + "@babel/helper-annotate-as-pure": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.14.5.tgz", + "integrity": "sha512-EivH9EgBIb+G8ij1B2jAwSH36WnGvkQSEC6CkX/6v6ZFlw5fVOHvsgGF4uiEHO2GzMvunZb6tDLQEQSdrdocrA==", + "dev": true, + "requires": { + "@babel/types": "^7.14.5" + }, + "dependencies": { + "@babel/types": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.5.tgz", + "integrity": "sha512-M/NzBpEL95I5Hh4dwhin5JlE7EzO5PHMAuzjxss3tiOBD46KfQvVedN/3jEPZvdRvtsK2222XfdHogNIttFgcg==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.14.5", + "to-fast-properties": "^2.0.0" + } + } + } + }, + "@babel/helper-compilation-targets": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.14.5.tgz", + "integrity": "sha512-v+QtZqXEiOnpO6EYvlImB6zCD2Lel06RzOPzmkz/D/XgQiUu3C/Jb1LOqSt/AIA34TYi/Q+KlT8vTQrgdxkbLw==", + "dev": true, + "requires": { + "@babel/compat-data": "^7.14.5", + "@babel/helper-validator-option": "^7.14.5", + "browserslist": "^4.16.6", + "semver": "^6.3.0" + }, + "dependencies": { + "browserslist": { + "version": "4.16.6", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.6.tgz", + "integrity": "sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ==", + "dev": true, + "requires": { + "caniuse-lite": "^1.0.30001219", + "colorette": "^1.2.2", + "electron-to-chromium": "^1.3.723", + "escalade": "^3.1.1", + "node-releases": "^1.1.71" + } + }, + "caniuse-lite": { + "version": "1.0.30001236", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001236.tgz", + "integrity": "sha512-o0PRQSrSCGJKCPZcgMzl5fUaj5xHe8qA2m4QRvnyY4e1lITqoNkr7q/Oh1NcpGSy0Th97UZ35yoKcINPoq7YOQ==", + "dev": true + }, + "colorette": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.2.tgz", + "integrity": "sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==", + "dev": true + }, + "electron-to-chromium": { + "version": "1.3.752", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.752.tgz", + "integrity": "sha512-2Tg+7jSl3oPxgsBsWKh5H83QazTkmWG/cnNwJplmyZc7KcN61+I10oUgaXSVk/NwfvN3BdkKDR4FYuRBQQ2v0A==", + "dev": true + }, + "node-releases": { + "version": "1.1.73", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.73.tgz", + "integrity": "sha512-uW7fodD6pyW2FZNZnp/Z3hvWKeEW1Y8R1+1CnErE8cXFXzl5blBOoVB41CvMer6P6Q0S5FXDwcHgFd1Wj0U9zg==", + "dev": true + } + } + }, + "@babel/helper-create-class-features-plugin": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.14.5.tgz", + "integrity": "sha512-Uq9z2e7ZtcnDMirRqAGLRaLwJn+Lrh388v5ETrR3pALJnElVh2zqQmdbz4W2RUJYohAPh2mtyPUgyMHMzXMncQ==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.14.5", + "@babel/helper-function-name": "^7.14.5", + "@babel/helper-member-expression-to-functions": "^7.14.5", + "@babel/helper-optimise-call-expression": "^7.14.5", + "@babel/helper-replace-supers": "^7.14.5", + "@babel/helper-split-export-declaration": "^7.14.5" + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.14.5.tgz", + "integrity": "sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw==", + "dev": true, + "requires": { + "@babel/highlight": "^7.14.5" + } + }, + "@babel/helper-function-name": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.14.5.tgz", + "integrity": "sha512-Gjna0AsXWfFvrAuX+VKcN/aNNWonizBj39yGwUzVDVTlMYJMK2Wp6xdpy72mfArFq5uK+NOuexfzZlzI1z9+AQ==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.14.5", + "@babel/template": "^7.14.5", + "@babel/types": "^7.14.5" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.14.5.tgz", + "integrity": "sha512-hprxVPu6e5Kdp2puZUmvOGjaLv9TCe58E/Fl6hRq4YiVQxIcNvuq6uTM2r1mT/oPskuS9CgR+I94sqAYv0NGKA==", + "dev": true, + "requires": { + "@babel/types": "^7.14.5" + } + }, + "@babel/parser": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.14.5.tgz", + "integrity": "sha512-TM8C+xtH/9n1qzX+JNHi7AN2zHMTiPUtspO0ZdHflW8KaskkALhMmuMHb4bCmNdv9VAPzJX3/bXqkVLnAvsPfg==", + "dev": true + }, + "@babel/template": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.14.5.tgz", + "integrity": "sha512-6Z3Po85sfxRGachLULUhOmvAaOo7xCvqGQtxINai2mEGPFm6pQ4z5QInFnUrRpfoSV60BnjyF5F3c+15fxFV1g==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.14.5", + "@babel/parser": "^7.14.5", + "@babel/types": "^7.14.5" + } + }, + "@babel/types": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.5.tgz", + "integrity": "sha512-M/NzBpEL95I5Hh4dwhin5JlE7EzO5PHMAuzjxss3tiOBD46KfQvVedN/3jEPZvdRvtsK2222XfdHogNIttFgcg==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.14.5", + "to-fast-properties": "^2.0.0" + } + } + } + }, + "@babel/helper-function-name": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.12.13.tgz", + "integrity": "sha512-TZvmPn0UOqmvi5G4vvw0qZTpVptGkB1GL61R6lKvrSdIxGm5Pky7Q3fpKiIkQCAtRCBUwB0PaThlx9vebCDSwA==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.12.13", + "@babel/template": "^7.12.13", + "@babel/types": "^7.12.13" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.14.5.tgz", + "integrity": "sha512-I1Db4Shst5lewOM4V+ZKJzQ0JGGaZ6VY1jYvMghRjqs6DWgxLCIyFt30GlnKkfUeFLpJt2vzbMVEXVSXlIFYUg==", + "dev": true, + "requires": { + "@babel/types": "^7.14.5" + }, + "dependencies": { + "@babel/types": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.5.tgz", + "integrity": "sha512-M/NzBpEL95I5Hh4dwhin5JlE7EzO5PHMAuzjxss3tiOBD46KfQvVedN/3jEPZvdRvtsK2222XfdHogNIttFgcg==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.14.5", + "to-fast-properties": "^2.0.0" + } + } + } + }, + "@babel/helper-hoist-variables": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.14.5.tgz", + "integrity": "sha512-R1PXiz31Uc0Vxy4OEOm07x0oSjKAdPPCh3tPivn/Eo8cvz6gveAeuyUUPB21Hoiif0uoPQSSdhIPS3352nvdyQ==", + "dev": true, + "requires": { + "@babel/types": "^7.14.5" + }, + "dependencies": { + "@babel/types": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.5.tgz", + "integrity": "sha512-M/NzBpEL95I5Hh4dwhin5JlE7EzO5PHMAuzjxss3tiOBD46KfQvVedN/3jEPZvdRvtsK2222XfdHogNIttFgcg==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.14.5", + "to-fast-properties": "^2.0.0" + } + } + } + }, + "@babel/helper-member-expression-to-functions": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.14.5.tgz", + "integrity": "sha512-UxUeEYPrqH1Q/k0yRku1JE7dyfyehNwT6SVkMHvYvPDv4+uu627VXBckVj891BO8ruKBkiDoGnZf4qPDD8abDQ==", + "dev": true, + "requires": { + "@babel/types": "^7.14.5" + }, + "dependencies": { + "@babel/types": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.5.tgz", + "integrity": "sha512-M/NzBpEL95I5Hh4dwhin5JlE7EzO5PHMAuzjxss3tiOBD46KfQvVedN/3jEPZvdRvtsK2222XfdHogNIttFgcg==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.14.5", + "to-fast-properties": "^2.0.0" + } + } + } + }, + "@babel/helper-module-imports": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.14.5.tgz", + "integrity": "sha512-SwrNHu5QWS84XlHwGYPDtCxcA0hrSlL2yhWYLgeOc0w7ccOl2qv4s/nARI0aYZW+bSwAL5CukeXA47B/1NKcnQ==", + "dev": true, + "requires": { + "@babel/types": "^7.14.5" + }, + "dependencies": { + "@babel/types": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.5.tgz", + "integrity": "sha512-M/NzBpEL95I5Hh4dwhin5JlE7EzO5PHMAuzjxss3tiOBD46KfQvVedN/3jEPZvdRvtsK2222XfdHogNIttFgcg==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.14.5", + "to-fast-properties": "^2.0.0" + } + } + } + }, + "@babel/helper-module-transforms": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.14.5.tgz", + "integrity": "sha512-iXpX4KW8LVODuAieD7MzhNjmM6dzYY5tfRqT+R9HDXWl0jPn/djKmA+G9s/2C2T9zggw5tK1QNqZ70USfedOwA==", + "dev": true, + "requires": { + "@babel/helper-module-imports": "^7.14.5", + "@babel/helper-replace-supers": "^7.14.5", + "@babel/helper-simple-access": "^7.14.5", + "@babel/helper-split-export-declaration": "^7.14.5", + "@babel/helper-validator-identifier": "^7.14.5", + "@babel/template": "^7.14.5", + "@babel/traverse": "^7.14.5", + "@babel/types": "^7.14.5" + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.14.5.tgz", + "integrity": "sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw==", + "dev": true, + "requires": { + "@babel/highlight": "^7.14.5" + } + }, + "@babel/generator": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.14.5.tgz", + "integrity": "sha512-y3rlP+/G25OIX3mYKKIOlQRcqj7YgrvHxOLbVmyLJ9bPmi5ttvUmpydVjcFjZphOktWuA7ovbx91ECloWTfjIA==", + "dev": true, + "requires": { + "@babel/types": "^7.14.5", + "jsesc": "^2.5.1", + "source-map": "^0.5.0" + } + }, + "@babel/helper-function-name": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.14.5.tgz", + "integrity": "sha512-Gjna0AsXWfFvrAuX+VKcN/aNNWonizBj39yGwUzVDVTlMYJMK2Wp6xdpy72mfArFq5uK+NOuexfzZlzI1z9+AQ==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.14.5", + "@babel/template": "^7.14.5", + "@babel/types": "^7.14.5" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.14.5.tgz", + "integrity": "sha512-hprxVPu6e5Kdp2puZUmvOGjaLv9TCe58E/Fl6hRq4YiVQxIcNvuq6uTM2r1mT/oPskuS9CgR+I94sqAYv0NGKA==", + "dev": true, + "requires": { + "@babel/types": "^7.14.5" + } + }, + "@babel/parser": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.14.5.tgz", + "integrity": "sha512-TM8C+xtH/9n1qzX+JNHi7AN2zHMTiPUtspO0ZdHflW8KaskkALhMmuMHb4bCmNdv9VAPzJX3/bXqkVLnAvsPfg==", + "dev": true + }, + "@babel/template": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.14.5.tgz", + "integrity": "sha512-6Z3Po85sfxRGachLULUhOmvAaOo7xCvqGQtxINai2mEGPFm6pQ4z5QInFnUrRpfoSV60BnjyF5F3c+15fxFV1g==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.14.5", + "@babel/parser": "^7.14.5", + "@babel/types": "^7.14.5" + } + }, + "@babel/traverse": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.14.5.tgz", + "integrity": "sha512-G3BiS15vevepdmFqmUc9X+64y0viZYygubAMO8SvBmKARuF6CPSZtH4Ng9vi/lrWlZFGe3FWdXNy835akH8Glg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.14.5", + "@babel/generator": "^7.14.5", + "@babel/helper-function-name": "^7.14.5", + "@babel/helper-hoist-variables": "^7.14.5", + "@babel/helper-split-export-declaration": "^7.14.5", + "@babel/parser": "^7.14.5", + "@babel/types": "^7.14.5", + "debug": "^4.1.0", + "globals": "^11.1.0" + } + }, + "@babel/types": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.5.tgz", + "integrity": "sha512-M/NzBpEL95I5Hh4dwhin5JlE7EzO5PHMAuzjxss3tiOBD46KfQvVedN/3jEPZvdRvtsK2222XfdHogNIttFgcg==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.14.5", + "to-fast-properties": "^2.0.0" + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + } + } + }, + "@babel/helper-optimise-call-expression": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.14.5.tgz", + "integrity": "sha512-IqiLIrODUOdnPU9/F8ib1Fx2ohlgDhxnIDU7OEVi+kAbEZcyiF7BLU8W6PfvPi9LzztjS7kcbzbmL7oG8kD6VA==", + "dev": true, + "requires": { + "@babel/types": "^7.14.5" + }, + "dependencies": { + "@babel/types": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.5.tgz", + "integrity": "sha512-M/NzBpEL95I5Hh4dwhin5JlE7EzO5PHMAuzjxss3tiOBD46KfQvVedN/3jEPZvdRvtsK2222XfdHogNIttFgcg==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.14.5", + "to-fast-properties": "^2.0.0" + } + } + } + }, + "@babel/helper-plugin-utils": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.14.5.tgz", + "integrity": "sha512-/37qQCE3K0vvZKwoK4XU/irIJQdIfCJuhU5eKnNxpFDsOkgFaUAwbv+RYw6eYgsC0E4hS7r5KqGULUogqui0fQ==", + "dev": true + }, + "@babel/helper-replace-supers": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.14.5.tgz", + "integrity": "sha512-3i1Qe9/8x/hCHINujn+iuHy+mMRLoc77b2nI9TB0zjH1hvn9qGlXjWlggdwUcju36PkPCy/lpM7LLUdcTyH4Ow==", + "dev": true, + "requires": { + "@babel/helper-member-expression-to-functions": "^7.14.5", + "@babel/helper-optimise-call-expression": "^7.14.5", + "@babel/traverse": "^7.14.5", + "@babel/types": "^7.14.5" + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.14.5.tgz", + "integrity": "sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw==", + "dev": true, + "requires": { + "@babel/highlight": "^7.14.5" + } + }, + "@babel/generator": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.14.5.tgz", + "integrity": "sha512-y3rlP+/G25OIX3mYKKIOlQRcqj7YgrvHxOLbVmyLJ9bPmi5ttvUmpydVjcFjZphOktWuA7ovbx91ECloWTfjIA==", + "dev": true, + "requires": { + "@babel/types": "^7.14.5", + "jsesc": "^2.5.1", + "source-map": "^0.5.0" + } + }, + "@babel/helper-function-name": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.14.5.tgz", + "integrity": "sha512-Gjna0AsXWfFvrAuX+VKcN/aNNWonizBj39yGwUzVDVTlMYJMK2Wp6xdpy72mfArFq5uK+NOuexfzZlzI1z9+AQ==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.14.5", + "@babel/template": "^7.14.5", + "@babel/types": "^7.14.5" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.14.5.tgz", + "integrity": "sha512-hprxVPu6e5Kdp2puZUmvOGjaLv9TCe58E/Fl6hRq4YiVQxIcNvuq6uTM2r1mT/oPskuS9CgR+I94sqAYv0NGKA==", + "dev": true, + "requires": { + "@babel/types": "^7.14.5" + } + }, + "@babel/parser": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.14.5.tgz", + "integrity": "sha512-TM8C+xtH/9n1qzX+JNHi7AN2zHMTiPUtspO0ZdHflW8KaskkALhMmuMHb4bCmNdv9VAPzJX3/bXqkVLnAvsPfg==", + "dev": true + }, + "@babel/template": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.14.5.tgz", + "integrity": "sha512-6Z3Po85sfxRGachLULUhOmvAaOo7xCvqGQtxINai2mEGPFm6pQ4z5QInFnUrRpfoSV60BnjyF5F3c+15fxFV1g==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.14.5", + "@babel/parser": "^7.14.5", + "@babel/types": "^7.14.5" + } + }, + "@babel/traverse": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.14.5.tgz", + "integrity": "sha512-G3BiS15vevepdmFqmUc9X+64y0viZYygubAMO8SvBmKARuF6CPSZtH4Ng9vi/lrWlZFGe3FWdXNy835akH8Glg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.14.5", + "@babel/generator": "^7.14.5", + "@babel/helper-function-name": "^7.14.5", + "@babel/helper-hoist-variables": "^7.14.5", + "@babel/helper-split-export-declaration": "^7.14.5", + "@babel/parser": "^7.14.5", + "@babel/types": "^7.14.5", + "debug": "^4.1.0", + "globals": "^11.1.0" + } + }, + "@babel/types": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.5.tgz", + "integrity": "sha512-M/NzBpEL95I5Hh4dwhin5JlE7EzO5PHMAuzjxss3tiOBD46KfQvVedN/3jEPZvdRvtsK2222XfdHogNIttFgcg==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.14.5", + "to-fast-properties": "^2.0.0" + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + } + } + }, + "@babel/helper-simple-access": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.14.5.tgz", + "integrity": "sha512-nfBN9xvmCt6nrMZjfhkl7i0oTV3yxR4/FztsbOASyTvVcoYd0TRHh7eMLdlEcCqobydC0LAF3LtC92Iwxo0wyw==", + "dev": true, + "requires": { + "@babel/types": "^7.14.5" + }, + "dependencies": { + "@babel/types": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.5.tgz", + "integrity": "sha512-M/NzBpEL95I5Hh4dwhin5JlE7EzO5PHMAuzjxss3tiOBD46KfQvVedN/3jEPZvdRvtsK2222XfdHogNIttFgcg==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.14.5", + "to-fast-properties": "^2.0.0" + } + } + } + }, + "@babel/helper-skip-transparent-expression-wrappers": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.14.5.tgz", + "integrity": "sha512-dmqZB7mrb94PZSAOYtr+ZN5qt5owZIAgqtoTuqiFbHFtxgEcmQlRJVI+bO++fciBunXtB6MK7HrzrfcAzIz2NQ==", + "dev": true, + "requires": { + "@babel/types": "^7.14.5" + }, + "dependencies": { + "@babel/types": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.5.tgz", + "integrity": "sha512-M/NzBpEL95I5Hh4dwhin5JlE7EzO5PHMAuzjxss3tiOBD46KfQvVedN/3jEPZvdRvtsK2222XfdHogNIttFgcg==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.14.5", + "to-fast-properties": "^2.0.0" + } + } + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.13.tgz", + "integrity": "sha512-tCJDltF83htUtXx5NLcaDqRmknv652ZWCHyoTETf1CXYJdPC7nohZohjUgieXhv0hTJdRf2FjDueFehdNucpzg==", + "dev": true, + "requires": { + "@babel/types": "^7.12.13" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz", + "integrity": "sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg==" + }, + "@babel/helper-validator-option": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.14.5.tgz", + "integrity": "sha512-OX8D5eeX4XwcroVW45NMvoYaIuFI+GQpA2a8Gi+X/U/cDUIRsV37qQfF905F0htTRCREQIB4KqPeaveRJUl3Ow==", + "dev": true + }, + "@babel/helpers": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.14.5.tgz", + "integrity": "sha512-xtcWOuN9VL6nApgVHtq3PPcQv5qFBJzoSZzJ/2c0QK/IP/gxVcoWSNQwFEGvmbQsuS9rhYqjILDGGXcTkA705Q==", + "dev": true, + "requires": { + "@babel/template": "^7.14.5", + "@babel/traverse": "^7.14.5", + "@babel/types": "^7.14.5" + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.14.5.tgz", + "integrity": "sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw==", + "dev": true, + "requires": { + "@babel/highlight": "^7.14.5" + } + }, + "@babel/generator": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.14.5.tgz", + "integrity": "sha512-y3rlP+/G25OIX3mYKKIOlQRcqj7YgrvHxOLbVmyLJ9bPmi5ttvUmpydVjcFjZphOktWuA7ovbx91ECloWTfjIA==", + "dev": true, + "requires": { + "@babel/types": "^7.14.5", + "jsesc": "^2.5.1", + "source-map": "^0.5.0" + } + }, + "@babel/helper-function-name": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.14.5.tgz", + "integrity": "sha512-Gjna0AsXWfFvrAuX+VKcN/aNNWonizBj39yGwUzVDVTlMYJMK2Wp6xdpy72mfArFq5uK+NOuexfzZlzI1z9+AQ==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.14.5", + "@babel/template": "^7.14.5", + "@babel/types": "^7.14.5" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.14.5.tgz", + "integrity": "sha512-hprxVPu6e5Kdp2puZUmvOGjaLv9TCe58E/Fl6hRq4YiVQxIcNvuq6uTM2r1mT/oPskuS9CgR+I94sqAYv0NGKA==", + "dev": true, + "requires": { + "@babel/types": "^7.14.5" + } + }, + "@babel/parser": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.14.5.tgz", + "integrity": "sha512-TM8C+xtH/9n1qzX+JNHi7AN2zHMTiPUtspO0ZdHflW8KaskkALhMmuMHb4bCmNdv9VAPzJX3/bXqkVLnAvsPfg==", + "dev": true + }, + "@babel/template": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.14.5.tgz", + "integrity": "sha512-6Z3Po85sfxRGachLULUhOmvAaOo7xCvqGQtxINai2mEGPFm6pQ4z5QInFnUrRpfoSV60BnjyF5F3c+15fxFV1g==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.14.5", + "@babel/parser": "^7.14.5", + "@babel/types": "^7.14.5" + } + }, + "@babel/traverse": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.14.5.tgz", + "integrity": "sha512-G3BiS15vevepdmFqmUc9X+64y0viZYygubAMO8SvBmKARuF6CPSZtH4Ng9vi/lrWlZFGe3FWdXNy835akH8Glg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.14.5", + "@babel/generator": "^7.14.5", + "@babel/helper-function-name": "^7.14.5", + "@babel/helper-hoist-variables": "^7.14.5", + "@babel/helper-split-export-declaration": "^7.14.5", + "@babel/parser": "^7.14.5", + "@babel/types": "^7.14.5", + "debug": "^4.1.0", + "globals": "^11.1.0" + } + }, + "@babel/types": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.5.tgz", + "integrity": "sha512-M/NzBpEL95I5Hh4dwhin5JlE7EzO5PHMAuzjxss3tiOBD46KfQvVedN/3jEPZvdRvtsK2222XfdHogNIttFgcg==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.14.5", + "to-fast-properties": "^2.0.0" + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + } + } + }, + "@babel/highlight": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz", + "integrity": "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==", + "requires": { + "@babel/helper-validator-identifier": "^7.14.5", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "@babel/parser": { + "version": "7.12.16", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.16.tgz", + "integrity": "sha512-c/+u9cqV6F0+4Hpq01jnJO+GLp2DdT63ppz9Xa+6cHaajM9VFzK/iDXiKK65YtpeVwu+ctfS6iqlMqRgQRzeCw==", + "dev": true + }, + "@babel/plugin-proposal-class-properties": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.14.5.tgz", + "integrity": "sha512-q/PLpv5Ko4dVc1LYMpCY7RVAAO4uk55qPwrIuJ5QJ8c6cVuAmhu7I/49JOppXL6gXf7ZHzpRVEUZdYoPLM04Gg==", + "dev": true, + "requires": { + "@babel/helper-create-class-features-plugin": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5" + } + }, + "@babel/plugin-proposal-object-rest-spread": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.14.5.tgz", + "integrity": "sha512-VzMyY6PWNPPT3pxc5hi9LloKNr4SSrVCg7Yr6aZpW4Ym07r7KqSU/QXYwjXLVxqwSv0t/XSXkFoKBPUkZ8vb2A==", + "dev": true, + "requires": { + "@babel/compat-data": "^7.14.5", + "@babel/helper-compilation-targets": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-transform-parameters": "^7.14.5" + } + }, + "@babel/plugin-syntax-class-properties": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", + "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.12.13" + } + }, + "@babel/plugin-syntax-flow": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.14.5.tgz", + "integrity": "sha512-9WK5ZwKCdWHxVuU13XNT6X73FGmutAXeor5lGFq6qhOFtMFUF4jkbijuyUdZZlpYq6E2hZeZf/u3959X9wsv0Q==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" + } + }, + "@babel/plugin-syntax-jsx": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.14.5.tgz", + "integrity": "sha512-ohuFIsOMXJnbOMRfX7/w7LocdR6R7whhuRD4ax8IipLcLPlZGJKkBxgHp++U4N/vKyU16/YDQr2f5seajD3jIw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" + } + }, + "@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-transform-arrow-functions": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.14.5.tgz", + "integrity": "sha512-KOnO0l4+tD5IfOdi4x8C1XmEIRWUjNRV8wc6K2vz/3e8yAOoZZvsRXRRIF/yo/MAOFb4QjtAw9xSxMXbSMRy8A==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" + } + }, + "@babel/plugin-transform-block-scoped-functions": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.14.5.tgz", + "integrity": "sha512-dtqWqdWZ5NqBX3KzsVCWfQI3A53Ft5pWFCT2eCVUftWZgjc5DpDponbIF1+c+7cSGk2wN0YK7HGL/ezfRbpKBQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" + } + }, + "@babel/plugin-transform-block-scoping": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.14.5.tgz", + "integrity": "sha512-LBYm4ZocNgoCqyxMLoOnwpsmQ18HWTQvql64t3GvMUzLQrNoV1BDG0lNftC8QKYERkZgCCT/7J5xWGObGAyHDw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" + } + }, + "@babel/plugin-transform-classes": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.14.5.tgz", + "integrity": "sha512-J4VxKAMykM06K/64z9rwiL6xnBHgB1+FVspqvlgCdwD1KUbQNfszeKVVOMh59w3sztHYIZDgnhOC4WbdEfHFDA==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.14.5", + "@babel/helper-function-name": "^7.14.5", + "@babel/helper-optimise-call-expression": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-replace-supers": "^7.14.5", + "@babel/helper-split-export-declaration": "^7.14.5", + "globals": "^11.1.0" + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.14.5.tgz", + "integrity": "sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw==", + "dev": true, + "requires": { + "@babel/highlight": "^7.14.5" + } + }, + "@babel/helper-function-name": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.14.5.tgz", + "integrity": "sha512-Gjna0AsXWfFvrAuX+VKcN/aNNWonizBj39yGwUzVDVTlMYJMK2Wp6xdpy72mfArFq5uK+NOuexfzZlzI1z9+AQ==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.14.5", + "@babel/template": "^7.14.5", + "@babel/types": "^7.14.5" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.14.5.tgz", + "integrity": "sha512-hprxVPu6e5Kdp2puZUmvOGjaLv9TCe58E/Fl6hRq4YiVQxIcNvuq6uTM2r1mT/oPskuS9CgR+I94sqAYv0NGKA==", + "dev": true, + "requires": { + "@babel/types": "^7.14.5" + } + }, + "@babel/parser": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.14.5.tgz", + "integrity": "sha512-TM8C+xtH/9n1qzX+JNHi7AN2zHMTiPUtspO0ZdHflW8KaskkALhMmuMHb4bCmNdv9VAPzJX3/bXqkVLnAvsPfg==", + "dev": true + }, + "@babel/template": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.14.5.tgz", + "integrity": "sha512-6Z3Po85sfxRGachLULUhOmvAaOo7xCvqGQtxINai2mEGPFm6pQ4z5QInFnUrRpfoSV60BnjyF5F3c+15fxFV1g==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.14.5", + "@babel/parser": "^7.14.5", + "@babel/types": "^7.14.5" + } + }, + "@babel/types": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.5.tgz", + "integrity": "sha512-M/NzBpEL95I5Hh4dwhin5JlE7EzO5PHMAuzjxss3tiOBD46KfQvVedN/3jEPZvdRvtsK2222XfdHogNIttFgcg==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.14.5", + "to-fast-properties": "^2.0.0" + } + } + } + }, + "@babel/plugin-transform-computed-properties": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.14.5.tgz", + "integrity": "sha512-pWM+E4283UxaVzLb8UBXv4EIxMovU4zxT1OPnpHJcmnvyY9QbPPTKZfEj31EUvG3/EQRbYAGaYEUZ4yWOBC2xg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" + } + }, + "@babel/plugin-transform-destructuring": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.14.5.tgz", + "integrity": "sha512-wU9tYisEbRMxqDezKUqC9GleLycCRoUsai9ddlsq54r8QRLaeEhc+d+9DqCG+kV9W2GgQjTZESPTpn5bAFMDww==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" + } + }, + "@babel/plugin-transform-flow-strip-types": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.14.5.tgz", + "integrity": "sha512-KhcolBKfXbvjwI3TV7r7TkYm8oNXHNBqGOy6JDVwtecFaRoKYsUUqJdS10q0YDKW1c6aZQgO+Ys3LfGkox8pXA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/plugin-syntax-flow": "^7.14.5" + } + }, + "@babel/plugin-transform-for-of": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.14.5.tgz", + "integrity": "sha512-CfmqxSUZzBl0rSjpoQSFoR9UEj3HzbGuGNL21/iFTmjb5gFggJp3ph0xR1YBhexmLoKRHzgxuFvty2xdSt6gTA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" + } + }, + "@babel/plugin-transform-function-name": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.14.5.tgz", + "integrity": "sha512-vbO6kv0fIzZ1GpmGQuvbwwm+O4Cbm2NrPzwlup9+/3fdkuzo1YqOZcXw26+YUJB84Ja7j9yURWposEHLYwxUfQ==", + "dev": true, + "requires": { + "@babel/helper-function-name": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5" + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.14.5.tgz", + "integrity": "sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw==", + "dev": true, + "requires": { + "@babel/highlight": "^7.14.5" + } + }, + "@babel/helper-function-name": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.14.5.tgz", + "integrity": "sha512-Gjna0AsXWfFvrAuX+VKcN/aNNWonizBj39yGwUzVDVTlMYJMK2Wp6xdpy72mfArFq5uK+NOuexfzZlzI1z9+AQ==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.14.5", + "@babel/template": "^7.14.5", + "@babel/types": "^7.14.5" + } + }, + "@babel/parser": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.14.5.tgz", + "integrity": "sha512-TM8C+xtH/9n1qzX+JNHi7AN2zHMTiPUtspO0ZdHflW8KaskkALhMmuMHb4bCmNdv9VAPzJX3/bXqkVLnAvsPfg==", + "dev": true + }, + "@babel/template": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.14.5.tgz", + "integrity": "sha512-6Z3Po85sfxRGachLULUhOmvAaOo7xCvqGQtxINai2mEGPFm6pQ4z5QInFnUrRpfoSV60BnjyF5F3c+15fxFV1g==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.14.5", + "@babel/parser": "^7.14.5", + "@babel/types": "^7.14.5" + } + }, + "@babel/types": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.5.tgz", + "integrity": "sha512-M/NzBpEL95I5Hh4dwhin5JlE7EzO5PHMAuzjxss3tiOBD46KfQvVedN/3jEPZvdRvtsK2222XfdHogNIttFgcg==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.14.5", + "to-fast-properties": "^2.0.0" + } + } + } + }, + "@babel/plugin-transform-literals": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.14.5.tgz", + "integrity": "sha512-ql33+epql2F49bi8aHXxvLURHkxJbSmMKl9J5yHqg4PLtdE6Uc48CH1GS6TQvZ86eoB/ApZXwm7jlA+B3kra7A==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" + } + }, + "@babel/plugin-transform-member-expression-literals": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.14.5.tgz", + "integrity": "sha512-WkNXxH1VXVTKarWFqmso83xl+2V3Eo28YY5utIkbsmXoItO8Q3aZxN4BTS2k0hz9dGUloHK26mJMyQEYfkn/+Q==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" + } + }, + "@babel/plugin-transform-modules-commonjs": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.14.5.tgz", + "integrity": "sha512-en8GfBtgnydoao2PS+87mKyw62k02k7kJ9ltbKe0fXTHrQmG6QZZflYuGI1VVG7sVpx4E1n7KBpNlPb8m78J+A==", + "dev": true, + "requires": { + "@babel/helper-module-transforms": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-simple-access": "^7.14.5", + "babel-plugin-dynamic-import-node": "^2.3.3" + } + }, + "@babel/plugin-transform-object-super": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.14.5.tgz", + "integrity": "sha512-MKfOBWzK0pZIrav9z/hkRqIk/2bTv9qvxHzPQc12RcVkMOzpIKnFCNYJip00ssKWYkd8Sf5g0Wr7pqJ+cmtuFg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-replace-supers": "^7.14.5" + } + }, + "@babel/plugin-transform-parameters": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.14.5.tgz", + "integrity": "sha512-Tl7LWdr6HUxTmzQtzuU14SqbgrSKmaR77M0OKyq4njZLQTPfOvzblNKyNkGwOfEFCEx7KeYHQHDI0P3F02IVkA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" + } + }, + "@babel/plugin-transform-property-literals": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.14.5.tgz", + "integrity": "sha512-r1uilDthkgXW8Z1vJz2dKYLV1tuw2xsbrp3MrZmD99Wh9vsfKoob+JTgri5VUb/JqyKRXotlOtwgu4stIYCmnw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" + } + }, + "@babel/plugin-transform-react-display-name": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.14.5.tgz", + "integrity": "sha512-07aqY1ChoPgIxsuDviptRpVkWCSbXWmzQqcgy65C6YSFOfPFvb/DX3bBRHh7pCd/PMEEYHYWUTSVkCbkVainYQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" + } + }, + "@babel/plugin-transform-react-jsx": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.14.5.tgz", + "integrity": "sha512-7RylxNeDnxc1OleDm0F5Q/BSL+whYRbOAR+bwgCxIr0L32v7UFh/pz1DLMZideAUxKT6eMoS2zQH6fyODLEi8Q==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.14.5", + "@babel/helper-module-imports": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/plugin-syntax-jsx": "^7.14.5", + "@babel/types": "^7.14.5" + }, + "dependencies": { + "@babel/types": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.5.tgz", + "integrity": "sha512-M/NzBpEL95I5Hh4dwhin5JlE7EzO5PHMAuzjxss3tiOBD46KfQvVedN/3jEPZvdRvtsK2222XfdHogNIttFgcg==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.14.5", + "to-fast-properties": "^2.0.0" + } + } + } + }, + "@babel/plugin-transform-shorthand-properties": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.14.5.tgz", + "integrity": "sha512-xLucks6T1VmGsTB+GWK5Pl9Jl5+nRXD1uoFdA5TSO6xtiNjtXTjKkmPdFXVLGlK5A2/or/wQMKfmQ2Y0XJfn5g==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" + } + }, + "@babel/plugin-transform-spread": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.14.5.tgz", + "integrity": "sha512-/3iqoQdiWergnShZYl0xACb4ADeYCJ7X/RgmwtXshn6cIvautRPAFzhd58frQlokLO6Jb4/3JXvmm6WNTPtiTw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.14.5" + } + }, + "@babel/plugin-transform-template-literals": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.14.5.tgz", + "integrity": "sha512-22btZeURqiepOfuy/VkFr+zStqlujWaarpMErvay7goJS6BWwdd6BY9zQyDLDa4x2S3VugxFb162IZ4m/S/+Gg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" + } + }, + "@babel/runtime": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.14.5.tgz", + "integrity": "sha512-121rumjddw9c3NCQ55KGkyE1h/nzWhU/owjhw0l4mQrkzz4x9SGS1X8gFLraHwX7td3Yo4QTL+qj0NcIzN87BA==", + "requires": { + "regenerator-runtime": "^0.13.4" + } + }, + "@babel/template": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.13.tgz", + "integrity": "sha512-/7xxiGA57xMo/P2GVvdEumr8ONhFOhfgq2ihK3h1e6THqzTAkHbkXgB0xI9yeTfIUoH3+oAeHhqm/I43OTbbjA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.12.13", + "@babel/parser": "^7.12.13", + "@babel/types": "^7.12.13" + } + }, + "@babel/traverse": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.13.tgz", + "integrity": "sha512-3Zb4w7eE/OslI0fTp8c7b286/cQps3+vdLW3UcwC8VSJC6GbKn55aeVVu2QJNuCDoeKyptLOFrPq8WqZZBodyA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.12.13", + "@babel/generator": "^7.12.13", + "@babel/helper-function-name": "^7.12.13", + "@babel/helper-split-export-declaration": "^7.12.13", + "@babel/parser": "^7.12.13", + "@babel/types": "^7.12.13", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.19" + } + }, + "@babel/types": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.13.tgz", + "integrity": "sha512-oKrdZTld2im1z8bDwTOQvUbxKwE+854zc16qWZQlcTqMN00pWxHQ4ZeOq0yDMnisOpRykH2/5Qqcrk/OlbAjiQ==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.12.11", + "lodash": "^4.17.19", + "to-fast-properties": "^2.0.0" + } + }, + "@csstools/convert-colors": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@csstools/convert-colors/-/convert-colors-1.4.0.tgz", + "integrity": "sha512-5a6wqoJV/xEdbRNKVo6I4hO3VjyDq//8q2f9I6PBAvMesJHFauXDorcNCsr9RzvsZnaWi5NYCcfyqP1QeFHFbw==", + "dev": true + }, + "@endemolshinegroup/cosmiconfig-typescript-loader": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@endemolshinegroup/cosmiconfig-typescript-loader/-/cosmiconfig-typescript-loader-3.0.2.tgz", + "integrity": "sha512-QRVtqJuS1mcT56oHpVegkKBlgtWjXw/gHNWO3eL9oyB5Sc7HBoc2OLG/nYpVfT/Jejvo3NUrD0Udk7XgoyDKkA==", + "dev": true, + "requires": { + "lodash.get": "^4", + "make-error": "^1", + "ts-node": "^9", + "tslib": "^2" + } + }, + "@fullhuman/postcss-purgecss": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@fullhuman/postcss-purgecss/-/postcss-purgecss-3.1.3.tgz", + "integrity": "sha512-kwOXw8fZ0Lt1QmeOOrd+o4Ibvp4UTEBFQbzvWldjlKv5n+G9sXfIPn1hh63IQIL8K8vbvv1oYMJiIUbuy9bGaA==", + "requires": { + "purgecss": "^3.1.3" + } + }, + "@graphql-codegen/cli": { + "version": "1.21.5", + "dev": true, + "requires": { + "@graphql-codegen/core": "1.17.10", + "@graphql-codegen/plugin-helpers": "^1.18.7", + "@graphql-tools/apollo-engine-loader": "^6.2.5", + "@graphql-tools/code-file-loader": "^6.3.1", + "@graphql-tools/git-loader": "^6.2.6", + "@graphql-tools/github-loader": "^6.2.5", + "@graphql-tools/graphql-file-loader": "^6.2.7", + "@graphql-tools/json-file-loader": "^6.2.6", + "@graphql-tools/load": "^6.2.8", + "@graphql-tools/prisma-loader": "^6.3.0", + "@graphql-tools/url-loader": "^6.10.1", + "@graphql-tools/utils": "^7.9.1", + "ansi-escapes": "^4.3.1", + "chalk": "^4.1.0", + "change-case-all": "1.0.14", + "chokidar": "^3.5.1", + "common-tags": "^1.8.0", + "cosmiconfig": "^7.0.0", + "debounce": "^1.2.0", + "dependency-graph": "^0.11.0", + "detect-indent": "^6.0.0", + "glob": "^7.1.6", + "graphql-config": "^3.3.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", + "minimatch": "^3.0.4", + "mkdirp": "^1.0.4", + "string-env-interpolation": "^1.0.1", + "ts-log": "^2.2.3", + "tslib": "~2.2.0", + "valid-url": "^1.0.9", + "wrap-ansi": "^7.0.0", + "yaml": "^1.10.0", + "yargs": "^17.0.0" + }, + "dependencies": { + "@graphql-tools/utils": { + "version": "7.10.0", + "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-7.10.0.tgz", + "integrity": "sha512-d334r6bo9mxdSqZW6zWboEnnOOFRrAPVQJ7LkU8/6grglrbcu6WhwCLzHb90E94JI3TD3ricC3YGbUqIi9Xg0w==", + "dev": true, + "requires": { + "@ardatan/aggregate-error": "0.0.6", + "camel-case": "4.1.2", + "tslib": "~2.2.0" + } + } + } + }, + "@graphql-codegen/core": { + "version": "1.17.10", + "resolved": "https://registry.npmjs.org/@graphql-codegen/core/-/core-1.17.10.tgz", + "integrity": "sha512-RA3umgVDs/RI/+ztHh+H4GfJxrJUfWJQqoAkMfX4qPTVO5qsy3R4vPudE0oP8w+kFbL8dFsRfAAPUZxI4jV/hQ==", + "dev": true, + "requires": { + "@graphql-codegen/plugin-helpers": "^1.18.7", + "@graphql-tools/merge": "^6.2.14", + "@graphql-tools/utils": "^7.9.1", + "tslib": "~2.2.0" + }, + "dependencies": { + "@graphql-tools/utils": { + "version": "7.10.0", + "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-7.10.0.tgz", + "integrity": "sha512-d334r6bo9mxdSqZW6zWboEnnOOFRrAPVQJ7LkU8/6grglrbcu6WhwCLzHb90E94JI3TD3ricC3YGbUqIi9Xg0w==", + "dev": true, + "requires": { + "@ardatan/aggregate-error": "0.0.6", + "camel-case": "4.1.2", + "tslib": "~2.2.0" + } + } + } + }, + "@graphql-codegen/plugin-helpers": { + "version": "1.18.7", + "resolved": "https://registry.npmjs.org/@graphql-codegen/plugin-helpers/-/plugin-helpers-1.18.7.tgz", + "integrity": "sha512-8ICOrXlsvyL1dpVz8C9b7H31d4DJpDd75WfjMn6Xjqz81Ah8xDn1Bi+7YXRCCILCBmvI94k6fi8qpsIVhFBBjQ==", + "dev": true, + "requires": { + "@graphql-tools/utils": "^7.9.1", + "common-tags": "1.8.0", + "import-from": "3.0.0", + "lodash": "~4.17.0", + "tslib": "~2.2.0" + }, + "dependencies": { + "@graphql-tools/utils": { + "version": "7.10.0", + "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-7.10.0.tgz", + "integrity": "sha512-d334r6bo9mxdSqZW6zWboEnnOOFRrAPVQJ7LkU8/6grglrbcu6WhwCLzHb90E94JI3TD3ricC3YGbUqIi9Xg0w==", + "dev": true, + "requires": { + "@ardatan/aggregate-error": "0.0.6", + "camel-case": "4.1.2", + "tslib": "~2.2.0" + } + } + } + }, + "@graphql-codegen/schema-ast": { + "version": "1.18.3", + "dev": true, + "requires": { + "@graphql-codegen/plugin-helpers": "^1.18.7", + "@graphql-tools/utils": "^7.9.1", + "tslib": "~2.2.0" + }, + "dependencies": { + "@graphql-tools/utils": { + "version": "7.10.0", + "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-7.10.0.tgz", + "integrity": "sha512-d334r6bo9mxdSqZW6zWboEnnOOFRrAPVQJ7LkU8/6grglrbcu6WhwCLzHb90E94JI3TD3ricC3YGbUqIi9Xg0w==", + "dev": true, + "requires": { + "@ardatan/aggregate-error": "0.0.6", + "camel-case": "4.1.2", + "tslib": "~2.2.0" + } + }, + "tslib": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.2.0.tgz", + "integrity": "sha512-gS9GVHRU+RGn5KQM2rllAlR3dU6m7AcpJKdtH8gFvQiC4Otgk98XnmMU+nZenHt/+VhnBPWwgrJsyrdcw6i23w==", + "dev": true + } + } + }, + "@graphql-codegen/typescript": { + "version": "1.22.1", + "resolved": "https://registry.npmjs.org/@graphql-codegen/typescript/-/typescript-1.22.1.tgz", + "integrity": "sha512-3f/siciXrhhMdcs9qcxnwWXETsAhZNNiUOlr6IUEm82kVx5xvFuxc0KZZE88w3iEVJXE7xYo1oWmrttvkQP4Aw==", + "dev": true, + "requires": { + "@graphql-codegen/plugin-helpers": "^1.18.7", + "@graphql-codegen/visitor-plugin-common": "1.21.0", + "auto-bind": "~4.0.0", + "tslib": "~2.2.0" + } + }, + "@graphql-codegen/typescript-operations": { + "version": "1.18.0", + "dev": true, + "requires": { + "@graphql-codegen/plugin-helpers": "^1.18.7", + "@graphql-codegen/typescript": "^1.22.1", + "@graphql-codegen/visitor-plugin-common": "1.21.0", + "auto-bind": "~4.0.0", + "tslib": "~2.2.0" + }, + "dependencies": { + "tslib": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.2.0.tgz", + "integrity": "sha512-gS9GVHRU+RGn5KQM2rllAlR3dU6m7AcpJKdtH8gFvQiC4Otgk98XnmMU+nZenHt/+VhnBPWwgrJsyrdcw6i23w==", + "dev": true + } + } + }, + "@graphql-codegen/visitor-plugin-common": { + "version": "1.21.0", + "resolved": "https://registry.npmjs.org/@graphql-codegen/visitor-plugin-common/-/visitor-plugin-common-1.21.0.tgz", + "integrity": "sha512-gw6mUCOpKwJ4aR+wnUXureQi4dV6jezEiXvX0CEZdpqBIGAJ4G8h7CKyGW66lBzvaoLCB7siOF86UJO3dw5ctg==", + "dev": true, + "requires": { + "@graphql-codegen/plugin-helpers": "^1.18.7", + "@graphql-tools/optimize": "^1.0.1", + "@graphql-tools/relay-operation-optimizer": "^6.3.0", + "array.prototype.flatmap": "^1.2.4", + "auto-bind": "~4.0.0", + "change-case-all": "1.0.14", + "dependency-graph": "^0.11.0", + "graphql-tag": "^2.11.0", + "parse-filepath": "^1.0.2", + "tslib": "~2.2.0" + } + }, + "@graphql-tools/apollo-engine-loader": { + "version": "6.2.5", + "resolved": "https://registry.npmjs.org/@graphql-tools/apollo-engine-loader/-/apollo-engine-loader-6.2.5.tgz", + "integrity": "sha512-CE4uef6PyxtSG+7OnLklIr2BZZDgjO89ZXK47EKdY7jQy/BQD/9o+8SxPsgiBc+2NsDJH2I6P/nqoaJMOEat6g==", + "dev": true, + "requires": { + "@graphql-tools/utils": "^7.0.0", + "cross-fetch": "3.0.6", + "tslib": "~2.0.1" + }, + "dependencies": { + "tslib": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.3.tgz", + "integrity": "sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ==", + "dev": true + } + } + }, + "@graphql-tools/batch-execute": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/@graphql-tools/batch-execute/-/batch-execute-7.1.2.tgz", + "integrity": "sha512-IuR2SB2MnC2ztA/XeTMTfWcA0Wy7ZH5u+nDkDNLAdX+AaSyDnsQS35sCmHqG0VOGTl7rzoyBWLCKGwSJplgtwg==", + "dev": true, + "requires": { + "@graphql-tools/utils": "^7.7.0", + "dataloader": "2.0.0", + "tslib": "~2.2.0", + "value-or-promise": "1.0.6" + }, + "dependencies": { + "@graphql-tools/utils": { + "version": "7.10.0", + "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-7.10.0.tgz", + "integrity": "sha512-d334r6bo9mxdSqZW6zWboEnnOOFRrAPVQJ7LkU8/6grglrbcu6WhwCLzHb90E94JI3TD3ricC3YGbUqIi9Xg0w==", + "dev": true, + "requires": { + "@ardatan/aggregate-error": "0.0.6", + "camel-case": "4.1.2", + "tslib": "~2.2.0" + } + } + } + }, + "@graphql-tools/code-file-loader": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/@graphql-tools/code-file-loader/-/code-file-loader-6.3.1.tgz", + "integrity": "sha512-ZJimcm2ig+avgsEOWWVvAaxZrXXhiiSZyYYOJi0hk9wh5BxZcLUNKkTp6EFnZE/jmGUwuos3pIjUD3Hwi3Bwhg==", + "dev": true, + "requires": { + "@graphql-tools/graphql-tag-pluck": "^6.5.1", + "@graphql-tools/utils": "^7.0.0", + "tslib": "~2.1.0" + }, + "dependencies": { + "tslib": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.1.0.tgz", + "integrity": "sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A==", + "dev": true + } + } + }, + "@graphql-tools/delegate": { + "version": "7.1.5", + "resolved": "https://registry.npmjs.org/@graphql-tools/delegate/-/delegate-7.1.5.tgz", + "integrity": "sha512-bQu+hDd37e+FZ0CQGEEczmRSfQRnnXeUxI/0miDV+NV/zCbEdIJj5tYFNrKT03W6wgdqx8U06d8L23LxvGri/g==", + "dev": true, + "requires": { + "@ardatan/aggregate-error": "0.0.6", + "@graphql-tools/batch-execute": "^7.1.2", + "@graphql-tools/schema": "^7.1.5", + "@graphql-tools/utils": "^7.7.1", + "dataloader": "2.0.0", + "tslib": "~2.2.0", + "value-or-promise": "1.0.6" + }, + "dependencies": { + "@graphql-tools/utils": { + "version": "7.10.0", + "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-7.10.0.tgz", + "integrity": "sha512-d334r6bo9mxdSqZW6zWboEnnOOFRrAPVQJ7LkU8/6grglrbcu6WhwCLzHb90E94JI3TD3ricC3YGbUqIi9Xg0w==", + "dev": true, + "requires": { + "@ardatan/aggregate-error": "0.0.6", + "camel-case": "4.1.2", + "tslib": "~2.2.0" + } + } + } + }, + "@graphql-tools/git-loader": { + "version": "6.2.6", + "resolved": "https://registry.npmjs.org/@graphql-tools/git-loader/-/git-loader-6.2.6.tgz", + "integrity": "sha512-ooQTt2CaG47vEYPP3CPD+nbA0F+FYQXfzrB1Y1ABN9K3d3O2RK3g8qwslzZaI8VJQthvKwt0A95ZeE4XxteYfw==", + "dev": true, + "requires": { + "@graphql-tools/graphql-tag-pluck": "^6.2.6", + "@graphql-tools/utils": "^7.0.0", + "tslib": "~2.1.0" + }, + "dependencies": { + "tslib": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.1.0.tgz", + "integrity": "sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A==", + "dev": true + } + } + }, + "@graphql-tools/github-loader": { + "version": "6.2.5", + "resolved": "https://registry.npmjs.org/@graphql-tools/github-loader/-/github-loader-6.2.5.tgz", + "integrity": "sha512-DLuQmYeNNdPo8oWus8EePxWCfCAyUXPZ/p1PWqjrX/NGPyH2ZObdqtDAfRHztljt0F/qkBHbGHCEk2TKbRZTRw==", + "dev": true, + "requires": { + "@graphql-tools/graphql-tag-pluck": "^6.2.6", + "@graphql-tools/utils": "^7.0.0", + "cross-fetch": "3.0.6", + "tslib": "~2.0.1" + }, + "dependencies": { + "tslib": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.3.tgz", + "integrity": "sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ==", + "dev": true + } + } + }, + "@graphql-tools/graphql-file-loader": { + "version": "6.2.7", + "resolved": "https://registry.npmjs.org/@graphql-tools/graphql-file-loader/-/graphql-file-loader-6.2.7.tgz", + "integrity": "sha512-5k2SNz0W87tDcymhEMZMkd6/vs6QawDyjQXWtqkuLTBF3vxjxPD1I4dwHoxgWPIjjANhXybvulD7E+St/7s9TQ==", + "dev": true, + "requires": { + "@graphql-tools/import": "^6.2.6", + "@graphql-tools/utils": "^7.0.0", + "tslib": "~2.1.0" + }, + "dependencies": { + "tslib": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.1.0.tgz", + "integrity": "sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A==", + "dev": true + } + } + }, + "@graphql-tools/graphql-tag-pluck": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/@graphql-tools/graphql-tag-pluck/-/graphql-tag-pluck-6.5.1.tgz", + "integrity": "sha512-7qkm82iFmcpb8M6/yRgzjShtW6Qu2OlCSZp8uatA3J0eMl87TxyJoUmL3M3UMMOSundAK8GmoyNVFUrueueV5Q==", + "dev": true, + "requires": { + "@babel/parser": "7.12.16", + "@babel/traverse": "7.12.13", + "@babel/types": "7.12.13", + "@graphql-tools/utils": "^7.0.0", + "tslib": "~2.1.0" + }, + "dependencies": { + "tslib": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.1.0.tgz", + "integrity": "sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A==", + "dev": true + } + } + }, + "@graphql-tools/import": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/@graphql-tools/import/-/import-6.3.1.tgz", + "integrity": "sha512-1szR19JI6WPibjYurMLdadHKZoG9C//8I/FZ0Dt4vJSbrMdVNp8WFxg4QnZrDeMG4MzZc90etsyF5ofKjcC+jw==", + "dev": true, + "requires": { + "resolve-from": "5.0.0", + "tslib": "~2.2.0" + } + }, + "@graphql-tools/json-file-loader": { + "version": "6.2.6", + "resolved": "https://registry.npmjs.org/@graphql-tools/json-file-loader/-/json-file-loader-6.2.6.tgz", + "integrity": "sha512-CnfwBSY5926zyb6fkDBHnlTblHnHI4hoBALFYXnrg0Ev4yWU8B04DZl/pBRUc459VNgO2x8/mxGIZj2hPJG1EA==", + "dev": true, + "requires": { + "@graphql-tools/utils": "^7.0.0", + "tslib": "~2.0.1" + }, + "dependencies": { + "tslib": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.3.tgz", + "integrity": "sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ==", + "dev": true + } + } + }, + "@graphql-tools/load": { + "version": "6.2.8", + "resolved": "https://registry.npmjs.org/@graphql-tools/load/-/load-6.2.8.tgz", + "integrity": "sha512-JpbyXOXd8fJXdBh2ta0Q4w8ia6uK5FHzrTNmcvYBvflFuWly2LDTk2abbSl81zKkzswQMEd2UIYghXELRg8eTA==", + "dev": true, + "requires": { + "@graphql-tools/merge": "^6.2.12", + "@graphql-tools/utils": "^7.5.0", + "globby": "11.0.3", + "import-from": "3.0.0", + "is-glob": "4.0.1", + "p-limit": "3.1.0", + "tslib": "~2.2.0", + "unixify": "1.0.0", + "valid-url": "1.0.9" + }, + "dependencies": { + "@graphql-tools/utils": { + "version": "7.10.0", + "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-7.10.0.tgz", + "integrity": "sha512-d334r6bo9mxdSqZW6zWboEnnOOFRrAPVQJ7LkU8/6grglrbcu6WhwCLzHb90E94JI3TD3ricC3YGbUqIi9Xg0w==", + "dev": true, + "requires": { + "@ardatan/aggregate-error": "0.0.6", + "camel-case": "4.1.2", + "tslib": "~2.2.0" + } + } + } + }, + "@graphql-tools/merge": { + "version": "6.2.14", + "resolved": "https://registry.npmjs.org/@graphql-tools/merge/-/merge-6.2.14.tgz", + "integrity": "sha512-RWT4Td0ROJai2eR66NHejgf8UwnXJqZxXgDWDI+7hua5vNA2OW8Mf9K1Wav1ZkjWnuRp4ztNtkZGie5ISw55ow==", + "dev": true, + "requires": { + "@graphql-tools/schema": "^7.0.0", + "@graphql-tools/utils": "^7.7.0", + "tslib": "~2.2.0" + }, + "dependencies": { + "@graphql-tools/utils": { + "version": "7.10.0", + "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-7.10.0.tgz", + "integrity": "sha512-d334r6bo9mxdSqZW6zWboEnnOOFRrAPVQJ7LkU8/6grglrbcu6WhwCLzHb90E94JI3TD3ricC3YGbUqIi9Xg0w==", + "dev": true, + "requires": { + "@ardatan/aggregate-error": "0.0.6", + "camel-case": "4.1.2", + "tslib": "~2.2.0" + } + } + } + }, + "@graphql-tools/optimize": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@graphql-tools/optimize/-/optimize-1.0.1.tgz", + "integrity": "sha512-cRlUNsbErYoBtzzS6zXahXeTBZGPVlPHXCpnEZ0XiK/KY/sQL96cyzak0fM/Gk6qEI9/l32MYEICjasiBQrl5w==", + "dev": true, + "requires": { + "tslib": "~2.0.1" + }, + "dependencies": { + "tslib": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.3.tgz", + "integrity": "sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ==", + "dev": true + } + } + }, + "@graphql-tools/prisma-loader": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/@graphql-tools/prisma-loader/-/prisma-loader-6.3.0.tgz", + "integrity": "sha512-9V3W/kzsFBmUQqOsd96V4a4k7Didz66yh/IK89B1/rrvy9rYj+ULjEqR73x9BYZ+ww9FV8yP8LasWAJwWaqqJQ==", + "dev": true, + "requires": { + "@graphql-tools/url-loader": "^6.8.2", + "@graphql-tools/utils": "^7.0.0", + "@types/http-proxy-agent": "^2.0.2", + "@types/js-yaml": "^4.0.0", + "@types/json-stable-stringify": "^1.0.32", + "@types/jsonwebtoken": "^8.5.0", + "chalk": "^4.1.0", + "debug": "^4.3.1", + "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": "^4.0.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.1.0", + "yaml-ast-parser": "^0.0.43" + }, + "dependencies": { + "tslib": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.1.0.tgz", + "integrity": "sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A==", + "dev": true + } + } + }, + "@graphql-tools/relay-operation-optimizer": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/@graphql-tools/relay-operation-optimizer/-/relay-operation-optimizer-6.3.0.tgz", + "integrity": "sha512-Or3UgRvkY9Fq1AAx7q38oPqFmTepLz7kp6wDHKyR0ceG7AvHv5En22R12mAeISInbhff4Rpwgf6cE8zHRu6bCw==", + "dev": true, + "requires": { + "@graphql-tools/utils": "^7.1.0", + "relay-compiler": "10.1.0", + "tslib": "~2.0.1" + }, + "dependencies": { + "tslib": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.3.tgz", + "integrity": "sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ==", + "dev": true + } + } + }, + "@graphql-tools/schema": { + "version": "7.1.5", + "resolved": "https://registry.npmjs.org/@graphql-tools/schema/-/schema-7.1.5.tgz", + "integrity": "sha512-uyn3HSNSckf4mvQSq0Q07CPaVZMNFCYEVxroApOaw802m9DcZPgf9XVPy/gda5GWj9AhbijfRYVTZQgHnJ4CXA==", + "dev": true, + "requires": { + "@graphql-tools/utils": "^7.1.2", + "tslib": "~2.2.0", + "value-or-promise": "1.0.6" + } + }, + "@graphql-tools/url-loader": { + "version": "6.10.1", + "resolved": "https://registry.npmjs.org/@graphql-tools/url-loader/-/url-loader-6.10.1.tgz", + "integrity": "sha512-DSDrbhQIv7fheQ60pfDpGD256ixUQIR6Hhf9Z5bRjVkXOCvO5XrkwoWLiU7iHL81GB1r0Ba31bf+sl+D4nyyfw==", + "dev": true, + "requires": { + "@graphql-tools/delegate": "^7.0.1", + "@graphql-tools/utils": "^7.9.0", + "@graphql-tools/wrap": "^7.0.4", + "@microsoft/fetch-event-source": "2.0.1", + "@types/websocket": "1.0.2", + "abort-controller": "3.0.0", + "cross-fetch": "3.1.4", + "extract-files": "9.0.0", + "form-data": "4.0.0", + "graphql-ws": "^4.4.1", + "is-promise": "4.0.0", + "isomorphic-ws": "4.0.1", + "lodash": "4.17.21", + "meros": "1.1.4", + "subscriptions-transport-ws": "^0.9.18", + "sync-fetch": "0.3.0", + "tslib": "~2.2.0", + "valid-url": "1.0.9", + "ws": "7.4.5" + }, + "dependencies": { + "@graphql-tools/utils": { + "version": "7.10.0", + "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-7.10.0.tgz", + "integrity": "sha512-d334r6bo9mxdSqZW6zWboEnnOOFRrAPVQJ7LkU8/6grglrbcu6WhwCLzHb90E94JI3TD3ricC3YGbUqIi9Xg0w==", + "dev": true, + "requires": { + "@ardatan/aggregate-error": "0.0.6", + "camel-case": "4.1.2", + "tslib": "~2.2.0" + } + }, + "cross-fetch": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.4.tgz", + "integrity": "sha512-1eAtFWdIubi6T4XPy6ei9iUFoKpUkIF971QLN8lIvvvwueI65+Nw5haMNKUwfJxabqlIIDODJKGrQ66gxC0PbQ==", + "dev": true, + "requires": { + "node-fetch": "2.6.1" + } + }, + "lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + } + } + }, + "@graphql-tools/utils": { + "version": "7.2.5", + "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-7.2.5.tgz", + "integrity": "sha512-S9RUkPimq+5eEDohDjiq/JCPUsiZblKRG8ve+diUwF1f8+r6FV2xGXrOt0qhQJiMxIO+BOK3DU9c+U3tX9Jo0w==", + "dev": true, + "requires": { + "@ardatan/aggregate-error": "0.0.6", + "camel-case": "4.1.2", + "tslib": "~2.1.0" + }, + "dependencies": { + "tslib": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.1.0.tgz", + "integrity": "sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A==", + "dev": true + } + } + }, + "@graphql-tools/wrap": { + "version": "7.0.8", + "resolved": "https://registry.npmjs.org/@graphql-tools/wrap/-/wrap-7.0.8.tgz", + "integrity": "sha512-1NDUymworsOlb53Qfh7fonDi2STvqCtbeE68ntKY9K/Ju/be2ZNxrFSbrBHwnxWcN9PjISNnLcAyJ1L5tCUyhg==", + "dev": true, + "requires": { + "@graphql-tools/delegate": "^7.1.5", + "@graphql-tools/schema": "^7.1.5", + "@graphql-tools/utils": "^7.8.1", + "tslib": "~2.2.0", + "value-or-promise": "1.0.6" + }, + "dependencies": { + "@graphql-tools/utils": { + "version": "7.10.0", + "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-7.10.0.tgz", + "integrity": "sha512-d334r6bo9mxdSqZW6zWboEnnOOFRrAPVQJ7LkU8/6grglrbcu6WhwCLzHb90E94JI3TD3ricC3YGbUqIi9Xg0w==", + "dev": true, + "requires": { + "@ardatan/aggregate-error": "0.0.6", + "camel-case": "4.1.2", + "tslib": "~2.2.0" + } + } + } + }, + "@hapi/accept": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@hapi/accept/-/accept-5.0.1.tgz", + "integrity": "sha512-fMr4d7zLzsAXo28PRRQPXR1o2Wmu+6z+VY1UzDp0iFo13Twj8WePakwXBiqn3E1aAlTpSNzCXdnnQXFhst8h8Q==", + "requires": { + "@hapi/boom": "9.x.x", + "@hapi/hoek": "9.x.x" + } + }, + "@hapi/boom": { + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/@hapi/boom/-/boom-9.1.2.tgz", + "integrity": "sha512-uJEJtiNHzKw80JpngDGBCGAmWjBtzxDCz17A9NO2zCi8LLBlb5Frpq4pXwyN+2JQMod4pKz5BALwyneCgDg89Q==", + "requires": { + "@hapi/hoek": "9.x.x" + } + }, + "@hapi/hoek": { + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.2.0.tgz", + "integrity": "sha512-sqKVVVOe5ivCaXDWivIJYVSaEgdQK9ul7a4Kity5Iw7u9+wBAPbX1RMSnLLmp7O4Vzj0WOWwMAJsTL00xwaNug==" + }, + "@iarna/toml": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/@iarna/toml/-/toml-2.2.5.tgz", + "integrity": "sha512-trnsAYxU3xnS1gPHPyU961coFyLkh4gAD/0zQ5mymY4yOZ+CYvsPqUbOFSw0aDM4y0tV7tiFxL/1XfXPNC6IPg==", + "dev": true + }, + "@microsoft/fetch-event-source": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@microsoft/fetch-event-source/-/fetch-event-source-2.0.1.tgz", + "integrity": "sha512-W6CLUJ2eBMw3Rec70qrsEW0jOm/3twwJv21mrmj2yORiaVmVYGS4sSS5yUwvQc1ZlDLYGPnClVWmUUMagKNsfA==", + "dev": true + }, + "@next/bundle-analyzer": { + "version": "10.2.3", + "dev": true, + "requires": { + "webpack-bundle-analyzer": "4.3.0" + } + }, + "@next/env": { + "version": "10.0.9-canary.5", + "resolved": "https://registry.npmjs.org/@next/env/-/env-10.0.9-canary.5.tgz", + "integrity": "sha512-5Sos4xVdjckm2iJwRxLkshIzUMr32lDyYMnBXRJ7PhFbITrgXUrV0d4XKDken8Yu8L11QDvDUKnpqGeBhFaL/A==" + }, + "@next/polyfill-module": { + "version": "10.0.9-canary.5", + "resolved": "https://registry.npmjs.org/@next/polyfill-module/-/polyfill-module-10.0.9-canary.5.tgz", + "integrity": "sha512-CbnMly7rGj6MelgzrHxxTANO9whsq7VM4mAH/3lFbO9sNK9lWFuJaMAwYtVJfYGd8ySjDFdpQsGlpW2ovzJZBA==" + }, + "@next/react-dev-overlay": { + "version": "10.0.9-canary.5", + "resolved": "https://registry.npmjs.org/@next/react-dev-overlay/-/react-dev-overlay-10.0.9-canary.5.tgz", + "integrity": "sha512-d0cFQvLe28ujAbWdv5CpJo03dpqmyNhXqUn+Dkpeybo1IEV68Arr0Me++ofIJvUxZV3isDBKHoyN6xFmgkYgSQ==", + "requires": { + "@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" + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", + "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", + "requires": { + "@babel/highlight": "^7.10.4" + } + }, + "chalk": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", + "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "classnames": { + "version": "2.2.6", + "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.2.6.tgz", + "integrity": "sha512-JR/iSQOSt+LQIWwrwEzJ9uk0xfN3mTVYMwt1Ir5mUcSN6pU+V4zQFFaJsclJbPuAUQH+yfWef6tm7l1quW3C8Q==" + }, + "source-map": { + "version": "0.8.0-beta.0", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.8.0-beta.0.tgz", + "integrity": "sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==", + "requires": { + "whatwg-url": "^7.0.0" + } + } + } + }, + "@next/react-refresh-utils": { + "version": "10.0.9-canary.5", + "resolved": "https://registry.npmjs.org/@next/react-refresh-utils/-/react-refresh-utils-10.0.9-canary.5.tgz", + "integrity": "sha512-47Y2GO+PezgJF4t41/VOEmIpUe66bbzbh/jO+doldwoPiLPxrSfOMpAnlJLpm5keHquBJMCIQbwDtmSpNvPkTg==" + }, + "@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "requires": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + } + }, + "@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==" + }, + "@nodelib/fs.walk": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.7.tgz", + "integrity": "sha512-BTIhocbPBSrRmHxOAJFtR18oLhxTtAFDAvL8hY1S3iU8k+E60W/YFs4jrixGzQjMpF4qPXxIQHcjVD9dz1C2QA==", + "requires": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + } + }, + "@opentelemetry/api": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-0.14.0.tgz", + "integrity": "sha512-L7RMuZr5LzMmZiQSQDy9O1jo0q+DaLy6XpYJfIGfYSfoJA5qzYwUP3sP1uMIQ549DvxAgM3ng85EaPTM/hUHwQ==", + "requires": { + "@opentelemetry/context-base": "^0.14.0" + } + }, + "@opentelemetry/context-base": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/context-base/-/context-base-0.14.0.tgz", + "integrity": "sha512-sDOAZcYwynHFTbLo6n8kIbLiVF3a3BLkrmehJUyEbT9F+Smbi47kLGS2gG2g0fjBLR/Lr1InPD7kXL7FaTqEkw==" + }, + "@polka/url": { + "version": "1.0.0-next.15", + "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.15.tgz", + "integrity": "sha512-15spi3V28QdevleWBNXE4pIls3nFZmBbUGrW9IVPwiQczuSb9n76TCB4bsk8TSel+I1OkHEdPhu5QKMfY6rQHA==", + "dev": true + }, + "@react-spring/animated": { + "version": "9.2.1", + "resolved": "https://registry.npmjs.org/@react-spring/animated/-/animated-9.2.1.tgz", + "integrity": "sha512-UAa74fsxWWQ6+3U1xdPBHVOBvvRYpSFs8Eo/I0msq7GxO4r7/muU/9loihKj5SfT3OW7hG9rnLEKQFImD7XUNw==", + "requires": { + "@react-spring/shared": "~9.2.0", + "@react-spring/types": "~9.2.0" + } + }, + "@react-spring/core": { + "version": "9.2.1", + "resolved": "https://registry.npmjs.org/@react-spring/core/-/core-9.2.1.tgz", + "integrity": "sha512-c4cu77//wZGO3URAob3+NynINDFos57wgVYcQHQYGOCLYwPzg6NVFf8ERfqzuFMeMgrvCkns7HZOxshPC/wzag==", + "requires": { + "@react-spring/animated": "~9.2.0", + "@react-spring/shared": "~9.2.0", + "@react-spring/types": "~9.2.0" + } + }, + "@react-spring/rafz": { + "version": "9.2.3", + "resolved": "https://registry.npmjs.org/@react-spring/rafz/-/rafz-9.2.3.tgz", + "integrity": "sha512-ThBI3HWp1Y82uRSFVpoykwgM3M9s3SJD6ilKKp9C2OTPcGhWiRGt1IMjzKPwB+F1NX3psbPTt30Bev8WzA/DQQ==" + }, + "@react-spring/shared": { + "version": "9.2.3", + "resolved": "https://registry.npmjs.org/@react-spring/shared/-/shared-9.2.3.tgz", + "integrity": "sha512-MehdmKao1oUAwSEJo8BXOz1OGgsSav/dimD1Vz920hirShj9s/I4zKnWtkdK92xQ4n35D/xD3hATHkXbt/WSvg==", + "requires": { + "@react-spring/rafz": "~9.2.0", + "@react-spring/types": "~9.2.0" + } + }, + "@react-spring/types": { + "version": "9.2.3", + "resolved": "https://registry.npmjs.org/@react-spring/types/-/types-9.2.3.tgz", + "integrity": "sha512-G7AWUJavwsvvvprnYmqUXE5N1XKINktc8V72ipvkFTE3DD3GApYpX/ORNmieJljKJYvBSBzpRSIzk2qELUs30Q==" + }, + "@react-spring/web": { + "version": "9.2.1", + "requires": { + "@react-spring/animated": "~9.2.0", + "@react-spring/core": "~9.2.0", + "@react-spring/shared": "~9.2.0", + "@react-spring/types": "~9.2.0" + } + }, + "@samverschueren/stream-to-observable": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@samverschueren/stream-to-observable/-/stream-to-observable-0.3.1.tgz", + "integrity": "sha512-c/qwwcHyafOQuVQJj0IlBjf5yYgBI7YPJ77k4fOJYesb41jio65eaJODRUmfYKhTOFBrIZ66kgvGPlNbjuoRdQ==", + "dev": true, + "requires": { + "any-observable": "^0.3.0" + } + }, + "@sindresorhus/is": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", + "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==", + "dev": true + }, + "@szmarczak/http-timer": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz", + "integrity": "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==", + "dev": true, + "requires": { + "defer-to-connect": "^1.0.1" + } + }, + "@tootallnate/once": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", + "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", + "dev": true + }, + "@types/async-retry": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@types/async-retry/-/async-retry-1.2.1.tgz", + "integrity": "sha512-yMQ6CVgICWtyFNBqJT3zqOc+TnqqEPLo4nKJNPFwcialiylil38Ie6q1ENeFTjvaLOkVim9K5LisHgAKJWidGQ==" + }, + "@types/body-scroll-lock": { + "version": "2.6.1", + "dev": true + }, + "@types/cookie": { + "version": "0.4.0", + "dev": true + }, + "@types/http-proxy-agent": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@types/http-proxy-agent/-/http-proxy-agent-2.0.2.tgz", + "integrity": "sha512-2S6IuBRhqUnH1/AUx9k8KWtY3Esg4eqri946MnxTG5HwehF1S5mqLln8fcyMiuQkY72p2gH3W+rIPqp5li0LyQ==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/js-cookie": { + "version": "2.2.6", + "dev": true + }, + "@types/js-yaml": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-4.0.1.tgz", + "integrity": "sha512-xdOvNmXmrZqqPy3kuCQ+fz6wA0xU5pji9cd1nDrflWaAWtYLLGk5ykW0H6yg5TVyehHP1pfmuuSaZkhP+kspVA==", + "dev": true + }, + "@types/json-stable-stringify": { + "version": "1.0.32", + "resolved": "https://registry.npmjs.org/@types/json-stable-stringify/-/json-stable-stringify-1.0.32.tgz", + "integrity": "sha512-q9Q6+eUEGwQkv4Sbst3J4PNgDOvpuVuKj79Hl/qnmBMEIPzB5QoFRUtjcgcg2xNUZyYUGXBk5wYIBKHt0A+Mxw==", + "dev": true + }, + "@types/jsonwebtoken": { + "version": "8.5.1", + "resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz", + "integrity": "sha512-rNAPdomlIUX0i0cg2+I+Q1wOUr531zHBQ+cV/28PJ39bSPKjahatZZ2LMuhiguETkCgLVzfruw/ZvNMNkKoSzw==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/lodash": { + "version": "4.14.168", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.168.tgz", + "integrity": "sha512-oVfRvqHV/V6D1yifJbVRU3TMp8OT6o6BG+U9MkwuJ3U8/CsDHvalRpsxBqivn71ztOFZBTfJMvETbqHiaNSj7Q==", + "dev": true + }, + "@types/lodash.debounce": { + "version": "4.0.6", + "dev": true, + "requires": { + "@types/lodash": "*" + } + }, + "@types/lodash.random": { + "version": "3.2.6", + "dev": true, + "requires": { + "@types/lodash": "*" + } + }, + "@types/lodash.throttle": { + "version": "4.1.6", + "dev": true, + "requires": { + "@types/lodash": "*" + } + }, + "@types/lru-cache": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/@types/lru-cache/-/lru-cache-4.1.1.tgz", + "integrity": "sha512-8mNEUG6diOrI6pMqOHrHPDBB1JsrpedeMK9AWGzVCQ7StRRribiT9BRvUmF8aUws9iBbVlgVekOT5Sgzc1MTKw==" + }, + "@types/node": { + "version": "15.12.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-15.12.1.tgz", + "integrity": "sha512-zyxJM8I1c9q5sRMtVF+zdd13Jt6RU4r4qfhTd7lQubyThvLfx6yYekWSQjGCGV2Tkecgxnlpl/DNlb6Hg+dmEw==" + }, + "@types/node-fetch": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.3.2.tgz", + "integrity": "sha512-yW0EOebSsQme9yKu09XbdDfle4/SmWZMK4dfteWcSLCYNQQcF+YOv0kIrvm+9pO11/ghA4E6A+RNQqvYj4Nr3A==", + "requires": { + "@types/node": "*" + } + }, + "@types/parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==", + "dev": true + }, + "@types/prop-types": { + "version": "15.7.3", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.3.tgz", + "integrity": "sha512-KfRL3PuHmqQLOG+2tGpRO26Ctg+Cq1E01D2DMriKEATHgWLfeNDmq9e29Q9WIky0dQ3NPkd1mzYH8Lm936Z9qw==", + "dev": true + }, + "@types/react": { + "version": "17.0.9", + "dev": true, + "requires": { + "@types/prop-types": "*", + "@types/scheduler": "*", + "csstype": "^3.0.2" + } + }, + "@types/scheduler": { + "version": "0.16.1", + "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.1.tgz", + "integrity": "sha512-EaCxbanVeyxDRTQBkdLb3Bvl/HK7PBK6UJjsSixB0iHKoWxE5uu2Q/DgtpOhPIojN0Zl1whvOd7PoHs2P0s5eA==", + "dev": true + }, + "@types/shopify-buy": { + "version": "2.10.5", + "dev": true + }, + "@types/websocket": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@types/websocket/-/websocket-1.0.2.tgz", + "integrity": "sha512-B5m9aq7cbbD/5/jThEr33nUY8WEfVi6A2YKCTOvw5Ldy7mtsOkqRvGjnzy6g7iMMDsgu7xREuCzqATLDLQVKcQ==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@typescript-eslint/types": { + "version": "4.26.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.26.1.tgz", + "integrity": "sha512-STyMPxR3cS+LaNvS8yK15rb8Y0iL0tFXq0uyl6gY45glyI7w0CsyqyEXl/Fa0JlQy+pVANeK3sbwPneCbWE7yg==", + "dev": true + }, + "@typescript-eslint/typescript-estree": { + "version": "4.26.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.26.1.tgz", + "integrity": "sha512-l3ZXob+h0NQzz80lBGaykdScYaiEbFqznEs99uwzm8fPHhDjwaBFfQkjUC/slw6Sm7npFL8qrGEAMxcfBsBJUg==", + "dev": true, + "requires": { + "@typescript-eslint/types": "4.26.1", + "@typescript-eslint/visitor-keys": "4.26.1", + "debug": "^4.3.1", + "globby": "^11.0.3", + "is-glob": "^4.0.1", + "semver": "^7.3.5", + "tsutils": "^3.21.0" + }, + "dependencies": { + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + } + } + }, + "@typescript-eslint/visitor-keys": { + "version": "4.26.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.26.1.tgz", + "integrity": "sha512-IGouNSSd+6x/fHtYRyLOM6/C+QxMDzWlDtN41ea+flWuSF9g02iqcIlX8wM53JkfljoIjP0U+yp7SiTS1onEkw==", + "dev": true, + "requires": { + "@typescript-eslint/types": "4.26.1", + "eslint-visitor-keys": "^2.0.0" + } + }, + "@vercel/fetch": { + "version": "6.1.0", + "requires": { + "@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" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, + "@vercel/fetch-cached-dns": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@vercel/fetch-cached-dns/-/fetch-cached-dns-2.0.1.tgz", + "integrity": "sha512-4a2IoekfGUgV/dinAB7Tx5oqA+Pg9I/6x/t8n/yduHmdclP5EdWTN4gPrwOKVECKVn2pV1VxAT8q4toSzwa2Eg==", + "requires": { + "@types/node-fetch": "2.3.2", + "@zeit/dns-cached-resolve": "2.1.0" + } + }, + "@vercel/fetch-retry": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/@vercel/fetch-retry/-/fetch-retry-5.0.3.tgz", + "integrity": "sha512-DIIoBY92r+sQ6iHSf5WjKiYvkdsDIMPWKYATlE0KcUAj2RV6SZK9UWpUzBRKsofXqedOqpVjrI0IE6AWL7JRtg==", + "requires": { + "async-retry": "^1.3.1", + "debug": "^3.1.0" + }, + "dependencies": { + "async-retry": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/async-retry/-/async-retry-1.3.1.tgz", + "integrity": "sha512-aiieFW/7h3hY0Bq5d+ktDBejxuwR78vRu9hDUdR8rNhSaQ29VzPL4AoIRG7D/c7tdenwOcKvgPM6tIxB3cB6HA==", + "requires": { + "retry": "0.12.0" + } + }, + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "requires": { + "ms": "^2.1.1" + } + } + } + }, + "@zeit/dns-cached-resolve": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@zeit/dns-cached-resolve/-/dns-cached-resolve-2.1.0.tgz", + "integrity": "sha512-KD2zyRZEBNs9PJ3/ob7zx0CvR4wM0oV4G5s5gFfPwmM74GpFbUN2pAAivP2AXnUrJ14Nkh8NumNKOzOyc4LbFQ==", + "requires": { + "@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" + }, + "dependencies": { + "@types/node": { + "version": "10.12.18", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.12.18.tgz", + "integrity": "sha512-fh+pAqt4xRzPfqA6eh3Z2y6fyZavRIumvjhaCL753+TVkGKGhpPeyrJG2JftD0T9q4GF00KjefsQ+PQNDdWQaQ==" + } + } + }, + "abort-controller": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", + "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", + "dev": true, + "requires": { + "event-target-shim": "^5.0.0" + } + }, + "acorn": { + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.4.0.tgz", + "integrity": "sha512-ULr0LDaEqQrMFGyQ3bhJkLsbtrQ8QibAseGZeaSUiT/6zb9IvIkomWHJIvgvwad+hinRAgsI51JcWk2yvwyL+w==", + "dev": true + }, + "acorn-node": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/acorn-node/-/acorn-node-1.8.2.tgz", + "integrity": "sha512-8mt+fslDufLYntIoPAaIMUe/lrbrehIiwmR3t2k9LljIzoigEPF27eLk2hy8zSGzmR/ogr7zbRKINMo1u0yh5A==", + "requires": { + "acorn": "^7.0.0", + "acorn-walk": "^7.0.0", + "xtend": "^4.0.2" + }, + "dependencies": { + "acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==" + }, + "acorn-walk": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", + "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==" + } + } + }, + "acorn-walk": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.1.0.tgz", + "integrity": "sha512-mjmzmv12YIG/G8JQdQuz2MUDShEJ6teYpT5bmWA4q7iwoGen8xtt3twF3OvzIUl+Q06aWIjvnwQUKvQ6TtMRjg==", + "dev": true + }, + "agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "dev": true, + "requires": { + "debug": "4" + } + }, + "agentkeepalive": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-3.4.1.tgz", + "integrity": "sha512-MPIwsZU9PP9kOrZpyu2042kYA8Fdt/AedQYkYXucHgF9QoD9dXVp0ypuGnHXSR0hTstBxdt85Xkh4JolYfK5wg==", + "requires": { + "humanize-ms": "^1.2.1" + } + }, + "aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "dev": true, + "requires": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + }, + "dependencies": { + "indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true + } + } + }, + "anser": { + "version": "1.4.9", + "resolved": "https://registry.npmjs.org/anser/-/anser-1.4.9.tgz", + "integrity": "sha512-AI+BjTeGt2+WFk4eWcqbQ7snZpDBt8SaLlj0RT2h5xfdWaiy51OjYvqwMrNzJLGy8iOAL6nKDITWO+rd4MkYEA==" + }, + "ansi-colors": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "dev": true + }, + "ansi-escapes": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.1.tgz", + "integrity": "sha512-JWF7ocqNrp8u9oqpgV+wH5ftbt+cfvv+PTjOvKLT3AdYly/LmORARfEVT1iyjwN+4MqE5UmVKoAdIBqeoCHgLA==", + "dev": true, + "requires": { + "type-fest": "^0.11.0" + } + }, + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==" + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "requires": { + "color-convert": "^2.0.1" + }, + "dependencies": { + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "requires": { + "color-name": "~1.1.4" + } + } + } + }, + "any-observable": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/any-observable/-/any-observable-0.3.0.tgz", + "integrity": "sha512-/FQM1EDkTsf63Ub2C6O7GuYFDsSXUwsaZDurV0np41ocwq0jthUAYCmhBX9f+KwlaCgIuWyr/4WlUQUBfKfZog==", + "dev": true + }, + "anymatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "app-module-path": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/app-module-path/-/app-module-path-2.2.0.tgz", + "integrity": "sha1-ZBqlXft9am8KgUHEucCqULbCTdU=", + "dev": true + }, + "arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true + }, + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "array-includes-with-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/array-includes-with-glob/-/array-includes-with-glob-3.1.0.tgz", + "integrity": "sha512-/PZEKASyXWmUTkNhuxnmqybv1CmIdY5rp3axLy3Dv6SYfaBb+EgS7Nl991mquHT1N2u0YAnE3IOafVNRM6Y9dw==", + "requires": { + "@babel/runtime": "^7.14.0", + "matcher": "^4.0.0" + } + }, + "array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true + }, + "array.prototype.flatmap": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.2.4.tgz", + "integrity": "sha512-r9Z0zYoxqHz60vvQbWEdXIEtCwHF0yxaWfno9qzXeNHvfyl3BZqygmGzb84dsubyaXLH4husF+NFgMSdpZhk2Q==", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "es-abstract": "^1.18.0-next.1", + "function-bind": "^1.1.1" + } + }, + "asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=", + "dev": true + }, + "asn1.js": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz", + "integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==", + "requires": { + "bn.js": "^4.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0", + "safer-buffer": "^2.1.0" + }, + "dependencies": { + "bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" + } + } + }, + "assert": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/assert/-/assert-1.5.0.tgz", + "integrity": "sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA==", + "requires": { + "object-assign": "^4.1.1", + "util": "0.10.3" + }, + "dependencies": { + "inherits": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", + "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=" + }, + "util": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", + "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", + "requires": { + "inherits": "2.0.1" + } + } + } + }, + "ast-module-types": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/ast-module-types/-/ast-module-types-2.7.1.tgz", + "integrity": "sha512-Rnnx/4Dus6fn7fTqdeLEAn5vUll5w7/vts0RN608yFa6si/rDOUonlIIiwugHBFWjylHjxm9owoSZn71KwG4gw==", + "dev": true + }, + "ast-types": { + "version": "0.13.2", + "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.13.2.tgz", + "integrity": "sha512-uWMHxJxtfj/1oZClOxDEV1sQ1HCDkA4MG8Gr69KKeBjEVH0R84WlejZ0y2DcwyBlpAEMltmVYkVgqfLFb2oyiA==" + }, + "astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "dev": true + }, + "async-retry": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/async-retry/-/async-retry-1.2.3.tgz", + "integrity": "sha512-tfDb02Th6CE6pJUF2gjW5ZVjsgwlucVXOEQMvEX9JgSJMs9gAX+Nz3xRuJBKuUYjTSYORqvDBORdAQ3LU59g7Q==", + "requires": { + "retry": "0.12.0" + } + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", + "dev": true + }, + "at-least-node": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", + "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==" + }, + "auto-bind": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/auto-bind/-/auto-bind-4.0.0.tgz", + "integrity": "sha512-Hdw8qdNiqdJ8LqT0iK0sVzkFbzg6fhnQqqfWhBDxcHZvU75+B+ayzTy8x+k5Ix0Y92XOhOUlx74ps+bA6BeYMQ==", + "dev": true + }, + "autoprefixer": { + "version": "10.2.6", + "requires": { + "browserslist": "^4.16.6", + "caniuse-lite": "^1.0.30001230", + "colorette": "^1.2.2", + "fraction.js": "^4.1.1", + "normalize-range": "^0.1.2", + "postcss-value-parser": "^4.1.0" + }, + "dependencies": { + "browserslist": { + "version": "4.16.6", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.6.tgz", + "integrity": "sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ==", + "requires": { + "caniuse-lite": "^1.0.30001219", + "colorette": "^1.2.2", + "electron-to-chromium": "^1.3.723", + "escalade": "^3.1.1", + "node-releases": "^1.1.71" + } + }, + "caniuse-lite": { + "version": "1.0.30001234", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001234.tgz", + "integrity": "sha512-a3gjUVKkmwLdNysa1xkUAwN2VfJUJyVW47rsi3aCbkRCtbHAfo+rOsCqVw29G6coQ8gzAPb5XBXwiGHwme3isA==" + }, + "colorette": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.2.tgz", + "integrity": "sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==" + }, + "electron-to-chromium": { + "version": "1.3.752", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.752.tgz", + "integrity": "sha512-2Tg+7jSl3oPxgsBsWKh5H83QazTkmWG/cnNwJplmyZc7KcN61+I10oUgaXSVk/NwfvN3BdkKDR4FYuRBQQ2v0A==" + }, + "node-releases": { + "version": "1.1.73", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.73.tgz", + "integrity": "sha512-uW7fodD6pyW2FZNZnp/Z3hvWKeEW1Y8R1+1CnErE8cXFXzl5blBOoVB41CvMer6P6Q0S5FXDwcHgFd1Wj0U9zg==" + } + } + }, + "babel-plugin-dynamic-import-node": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz", + "integrity": "sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ==", + "dev": true, + "requires": { + "object.assign": "^4.1.0" + } + }, + "babel-plugin-syntax-jsx": { + "version": "6.18.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz", + "integrity": "sha1-CvMqmm4Tyno/1QaeYtew9Y0NiUY=" + }, + "babel-plugin-syntax-trailing-function-commas": { + "version": "7.0.0-beta.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-7.0.0-beta.0.tgz", + "integrity": "sha512-Xj9XuRuz3nTSbaTXWv3itLOcxyF4oPD8douBBmj7U9BBC6nEBYfyOJYQMf/8PJAFotC62UY5dFfIGEPr7WswzQ==", + "dev": true + }, + "babel-preset-fbjs": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/babel-preset-fbjs/-/babel-preset-fbjs-3.4.0.tgz", + "integrity": "sha512-9ywCsCvo1ojrw0b+XYk7aFvTH6D9064t0RIL1rtMf3nsa02Xw41MS7sZw216Im35xj/UY0PDBQsa1brUDDF1Ow==", + "dev": true, + "requires": { + "@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" + } + }, + "backo2": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz", + "integrity": "sha1-MasayLEpNjRj41s+u2n038+6eUc=", + "dev": true + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + }, + "base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" + }, + "big.js": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", + "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==" + }, + "binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==" + }, + "bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "dev": true, + "requires": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + }, + "dependencies": { + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + } + } + }, + "bn.js": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", + "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==" + }, + "body-scroll-lock": { + "version": "3.1.5" + }, + "bowser": { + "version": "2.11.0" + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "requires": { + "fill-range": "^7.0.1" + } + }, + "brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=" + }, + "browserify-aes": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", + "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", + "requires": { + "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": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", + "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", + "requires": { + "browserify-aes": "^1.0.4", + "browserify-des": "^1.0.0", + "evp_bytestokey": "^1.0.0" + } + }, + "browserify-des": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", + "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", + "requires": { + "cipher-base": "^1.0.1", + "des.js": "^1.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "browserify-rsa": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.1.0.tgz", + "integrity": "sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog==", + "requires": { + "bn.js": "^5.0.0", + "randombytes": "^2.0.1" + } + }, + "browserify-sign": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.1.tgz", + "integrity": "sha512-/vrA5fguVAKKAVTNJjgSm1tRQDHUU6DbwO9IROu/0WAzC8PKhucDSh18J0RMvVeHAn5puMd+QHC2erPRNf8lmg==", + "requires": { + "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" + }, + "dependencies": { + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + } + } + }, + "browserify-zlib": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", + "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", + "requires": { + "pako": "~1.0.5" + } + }, + "bser": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", + "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", + "dev": true, + "requires": { + "node-int64": "^0.4.0" + } + }, + "buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "dev": true, + "requires": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "buffer-equal-constant-time": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", + "integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk=", + "dev": true + }, + "buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", + "dev": true + }, + "buffer-xor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", + "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=" + }, + "builtin-status-codes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", + "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=" + }, + "bytes": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", + "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==" + }, + "cacheable-request": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz", + "integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==", + "dev": true, + "requires": { + "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" + }, + "dependencies": { + "get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "lowercase-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", + "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", + "dev": true + } + } + }, + "call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "dev": true, + "requires": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + } + }, + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true + }, + "camel-case": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.2.tgz", + "integrity": "sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==", + "dev": true, + "requires": { + "pascal-case": "^3.1.2", + "tslib": "^2.0.3" + } + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + }, + "camelcase-css": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", + "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==" + }, + "caniuse-lite": { + "version": "1.0.30001185", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001185.tgz", + "integrity": "sha512-Fpi4kVNtNvJ15H0F6vwmXtb3tukv3Zg3qhKkOGUq7KJ1J6b9kf4dnNgtEAFXhRsJo0gNj9W60+wBvn0JcTvdTg==" + }, + "capital-case": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/capital-case/-/capital-case-1.0.4.tgz", + "integrity": "sha512-ds37W8CytHgwnhGGTi88pcPyR15qoNkOpYwmMMfnWqqWgESapLqvDx6huFjQ5vqWSn2Z06173XNA7LtMOeUh1A==", + "dev": true, + "requires": { + "no-case": "^3.0.4", + "tslib": "^2.0.3", + "upper-case-first": "^2.0.2" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "change-case": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/change-case/-/change-case-4.1.2.tgz", + "integrity": "sha512-bSxY2ws9OtviILG1EiY5K7NNxkqg/JnRnFxLtKQ96JaviiIxi7djMrSd0ECT9AC+lttClmYwKw53BWpOMblo7A==", + "dev": true, + "requires": { + "camel-case": "^4.1.2", + "capital-case": "^1.0.4", + "constant-case": "^3.0.4", + "dot-case": "^3.0.4", + "header-case": "^2.0.4", + "no-case": "^3.0.4", + "param-case": "^3.0.4", + "pascal-case": "^3.1.2", + "path-case": "^3.0.4", + "sentence-case": "^3.0.4", + "snake-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "change-case-all": { + "version": "1.0.14", + "resolved": "https://registry.npmjs.org/change-case-all/-/change-case-all-1.0.14.tgz", + "integrity": "sha512-CWVm2uT7dmSHdO/z1CXT/n47mWonyypzBbuCy5tN7uMg22BsfkhwT6oHmFCAk+gL1LOOxhdbB9SZz3J1KTY3gA==", + "dev": true, + "requires": { + "change-case": "^4.1.2", + "is-lower-case": "^2.0.2", + "is-upper-case": "^2.0.2", + "lower-case": "^2.0.2", + "lower-case-first": "^2.0.2", + "sponge-case": "^1.0.1", + "swap-case": "^2.0.2", + "title-case": "^3.0.3", + "upper-case": "^2.0.2", + "upper-case-first": "^2.0.2" + } + }, + "chardet": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", + "dev": true + }, + "chokidar": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.1.tgz", + "integrity": "sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw==", + "requires": { + "anymatch": "~3.1.1", + "braces": "~3.0.2", + "fsevents": "~2.3.1", + "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" + } + }, + "cipher-base": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", + "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "classnames": { + "version": "2.3.1" + }, + "clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "dev": true + }, + "cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dev": true, + "requires": { + "restore-cursor": "^3.1.0" + } + }, + "cli-spinners": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.6.0.tgz", + "integrity": "sha512-t+4/y50K/+4xcCRosKkA7W4gTr1MySvLV0q+PxmG7FJ5g+66ChKurYjxBCjHggHH3HA5Hh9cy+lcUGWDqVH+4Q==", + "dev": true + }, + "cli-truncate": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz", + "integrity": "sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==", + "dev": true, + "requires": { + "slice-ansi": "^3.0.0", + "string-width": "^4.2.0" + } + }, + "cli-width": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz", + "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==", + "dev": true + }, + "cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=", + "dev": true + }, + "clone-response": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", + "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=", + "dev": true, + "requires": { + "mimic-response": "^1.0.0" + } + }, + "code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", + "dev": true + }, + "color": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/color/-/color-3.1.3.tgz", + "integrity": "sha512-xgXAcTHa2HeFCGLE9Xs/R82hujGtu9Jd9x4NW3T34+OMs7VoPsjwzRczKHvTAHeJwWFwX5j15+MgAppE8ztObQ==", + "requires": { + "color-convert": "^1.9.1", + "color-string": "^1.5.4" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "requires": { + "color-name": "1.1.3" + }, + "dependencies": { + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + } + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "color-string": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.5.5.tgz", + "integrity": "sha512-jgIoum0OfQfq9Whcfc2z/VhCNcmQjWbey6qBX0vqt7YICflUmBCh9E9CiQD5GSJ+Uehixm3NUwHVhqUAWRivZg==", + "requires": { + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" + } + }, + "colorette": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.1.tgz", + "integrity": "sha512-puCDz0CzydiSYOrnXpz/PKd69zRrribezjtE9yd4zvytoRc8+RY/KJPvtPFKZS3E3wP6neGyMe0vOTlHO5L3Pw==" + }, + "combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "commander": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz", + "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==" + }, + "common-tags": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.0.tgz", + "integrity": "sha512-6P6g0uetGpW/sdyUy/iQQCbFF0kWVMSIVSyYz7Zgjcgh8mgw8PQzDNZeyZ5DQ2gM7LBoZPHmnjz8rUthkBG5tw==", + "dev": true + }, + "commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=" + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "console-browserify": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz", + "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==" + }, + "constant-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/constant-case/-/constant-case-3.0.4.tgz", + "integrity": "sha512-I2hSBi7Vvs7BEuJDr5dDHfzb/Ruj3FyvFyh7KLilAjNQw3Be+xgqUBA2W6scVEcL0hL1dwPRtIqEPVUCKkSsyQ==", + "dev": true, + "requires": { + "no-case": "^3.0.4", + "tslib": "^2.0.3", + "upper-case": "^2.0.2" + } + }, + "constants-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", + "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=" + }, + "convert-source-map": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", + "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", + "requires": { + "safe-buffer": "~5.1.1" + }, + "dependencies": { + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + } + } + }, + "cookie": { + "version": "0.4.1" + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "cosmiconfig": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.0.tgz", + "integrity": "sha512-pondGvTuVYDk++upghXJabWzL6Kxu6f26ljFw64Swq9v6sQPUL3EUlVDV56diOjpCayKihL6hVe8exIACU4XcA==", + "dev": true, + "requires": { + "@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" + } + }, + "cosmiconfig-toml-loader": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig-toml-loader/-/cosmiconfig-toml-loader-1.0.0.tgz", + "integrity": "sha512-H/2gurFWVi7xXvCyvsWRLCMekl4tITJcX0QEsDMpzxtuxDyM59xLatYNg4s/k9AA/HdtCYfj2su8mgA0GSDLDA==", + "dev": true, + "requires": { + "@iarna/toml": "^2.2.5" + } + }, + "create-ecdh": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz", + "integrity": "sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==", + "requires": { + "bn.js": "^4.1.0", + "elliptic": "^6.5.3" + }, + "dependencies": { + "bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" + } + } + }, + "create-hash": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", + "requires": { + "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": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "requires": { + "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": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "dev": true + }, + "cross-fetch": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.0.6.tgz", + "integrity": "sha512-KBPUbqgFjzWlVcURG+Svp9TlhA5uliYtiNx/0r8nv0pdypeQCRJ9IaSIc3q/x3q8t3F75cHuwxVql1HFGHCNJQ==", + "dev": true, + "requires": { + "node-fetch": "2.6.1" + } + }, + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "crypto-browserify": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", + "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", + "requires": { + "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": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/css-blank-pseudo/-/css-blank-pseudo-0.1.4.tgz", + "integrity": "sha512-LHz35Hr83dnFeipc7oqFDmsjHdljj3TQtxGGiNWSOsTLIAubSm4TEz8qCaKFpk7idaQ1GfWscF4E6mgpBysA1w==", + "dev": true, + "requires": { + "postcss": "^7.0.5" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "dependencies": { + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "postcss": { + "version": "7.0.36", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.36.tgz", + "integrity": "sha512-BebJSIUMwJHRH0HAQoxN4u1CN86glsrwsW0q7T+/m44eXOUAxSNdHRkNZPYz5vVUbg17hFgOQDE7fZk7li3pZw==", + "dev": true, + "requires": { + "chalk": "^2.4.2", + "source-map": "^0.6.1", + "supports-color": "^6.1.0" + } + }, + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "css-has-pseudo": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/css-has-pseudo/-/css-has-pseudo-0.10.0.tgz", + "integrity": "sha512-Z8hnfsZu4o/kt+AuFzeGpLVhFOGO9mluyHBaA2bA8aCGTwah5sT3WV/fTHH8UNZUytOIImuGPrl/prlb4oX4qQ==", + "dev": true, + "requires": { + "postcss": "^7.0.6", + "postcss-selector-parser": "^5.0.0-rc.4" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "dependencies": { + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "postcss": { + "version": "7.0.36", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.36.tgz", + "integrity": "sha512-BebJSIUMwJHRH0HAQoxN4u1CN86glsrwsW0q7T+/m44eXOUAxSNdHRkNZPYz5vVUbg17hFgOQDE7fZk7li3pZw==", + "dev": true, + "requires": { + "chalk": "^2.4.2", + "source-map": "^0.6.1", + "supports-color": "^6.1.0" + } + }, + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "css-prefers-color-scheme": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/css-prefers-color-scheme/-/css-prefers-color-scheme-3.1.1.tgz", + "integrity": "sha512-MTu6+tMs9S3EUqzmqLXEcgNRbNkkD/TGFvowpeoWJn5Vfq7FMgsmRQs9X5NXAURiOBmOxm/lLjsDNXDE6k9bhg==", + "dev": true, + "requires": { + "postcss": "^7.0.5" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "dependencies": { + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "postcss": { + "version": "7.0.36", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.36.tgz", + "integrity": "sha512-BebJSIUMwJHRH0HAQoxN4u1CN86glsrwsW0q7T+/m44eXOUAxSNdHRkNZPYz5vVUbg17hFgOQDE7fZk7li3pZw==", + "dev": true, + "requires": { + "chalk": "^2.4.2", + "source-map": "^0.6.1", + "supports-color": "^6.1.0" + } + }, + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "css-unit-converter": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/css-unit-converter/-/css-unit-converter-1.1.2.tgz", + "integrity": "sha512-IiJwMC8rdZE0+xiEZHeru6YoONC4rfPMqGm2W85jMIbkFvv5nFTwJVFHam2eFrN6txmoUYFAFXiv8ICVeTO0MA==" + }, + "css.escape": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz", + "integrity": "sha1-QuJ9T6BK4y+TGktNQZH6nN3ul8s=" + }, + "cssdb": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/cssdb/-/cssdb-4.4.0.tgz", + "integrity": "sha512-LsTAR1JPEM9TpGhl/0p3nQecC2LJ0kD8X5YARu1hk/9I1gril5vDtMZyNxcEpxxDj34YNck/ucjuoUd66K03oQ==", + "dev": true + }, + "cssesc": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-2.0.0.tgz", + "integrity": "sha512-MsCAG1z9lPdoO/IUMLSBWBSVxVtJ1395VGIQ+Fc2gNdkQ1hNDnQdw3YhA71WJCBW1vdwA0cAnk/DnW6bqoEUYg==", + "dev": true + }, + "cssnano-preset-simple": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/cssnano-preset-simple/-/cssnano-preset-simple-1.2.2.tgz", + "integrity": "sha512-gtvrcRSGtP3hA/wS8mFVinFnQdEsEpm3v4I/s/KmNjpdWaThV/4E5EojAzFXxyT5OCSRPLlHR9iQexAqKHlhGQ==", + "requires": { + "caniuse-lite": "^1.0.30001179", + "postcss": "^7.0.32" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "dependencies": { + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "postcss": { + "version": "7.0.36", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.36.tgz", + "integrity": "sha512-BebJSIUMwJHRH0HAQoxN4u1CN86glsrwsW0q7T+/m44eXOUAxSNdHRkNZPYz5vVUbg17hFgOQDE7fZk7li3pZw==", + "requires": { + "chalk": "^2.4.2", + "source-map": "^0.6.1", + "supports-color": "^6.1.0" + } + }, + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "cssnano-simple": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/cssnano-simple/-/cssnano-simple-1.2.2.tgz", + "integrity": "sha512-4slyYc1w4JhSbhVX5xi9G0aQ42JnRyPg+7l7cqoNyoIDzfWx40Rq3JQZnoAWDu60A4AvKVp9ln/YSUOdhDX68g==", + "requires": { + "cssnano-preset-simple": "1.2.2", + "postcss": "^7.0.32" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "dependencies": { + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "postcss": { + "version": "7.0.36", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.36.tgz", + "integrity": "sha512-BebJSIUMwJHRH0HAQoxN4u1CN86glsrwsW0q7T+/m44eXOUAxSNdHRkNZPYz5vVUbg17hFgOQDE7fZk7li3pZw==", + "requires": { + "chalk": "^2.4.2", + "source-map": "^0.6.1", + "supports-color": "^6.1.0" + } + }, + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "csstype": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.6.tgz", + "integrity": "sha512-+ZAmfyWMT7TiIlzdqJgjMb7S4f1beorDbWbsocyK4RaiqA5RTX3K14bnBWmmA9QEM0gRdsjyyrEmcyga8Zsxmw==", + "dev": true + }, + "data-uri-to-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-3.0.1.tgz", + "integrity": "sha512-WboRycPNsVw3B3TL559F7kuBUM4d8CgMEvk6xEJlOp7OBPjt6G7z8WMWlD2rOFZLk6OYfFIUGsCOWzcQH9K2og==" + }, + "dataloader": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dataloader/-/dataloader-2.0.0.tgz", + "integrity": "sha512-YzhyDAwA4TaQIhM5go+vCLmU0UikghC/t9DTQYZR2M/UvZ1MdOhPezSDZcjj9uqQJOMqjLcpWtyW2iNINdlatQ==", + "dev": true + }, + "date-fns": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-1.30.1.tgz", + "integrity": "sha512-hBSVCvSmWC+QypYObzwGOd9wqdDpOt+0wl0KbU+R+uuZBS1jN8VsD1ss3irQDknRj5NvxiTF6oj/nDRnN/UQNw==", + "dev": true + }, + "debounce": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/debounce/-/debounce-1.2.0.tgz", + "integrity": "sha512-mYtLl1xfZLi1m4RtQYlZgJUNQjl4ZxVnHzIR8nLLgi4q1YT8o/WM+MK/f8yfcc9s5Ir5zRaPZyZU6xs1Syoocg==" + }, + "debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + }, + "dependencies": { + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + } + } + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true + }, + "decomment": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/decomment/-/decomment-0.9.4.tgz", + "integrity": "sha512-8eNlhyI5cSU4UbBlrtagWpR03dqXcE5IR9zpe7PnO6UzReXDskucsD8usgrzUmQ6qJ3N82aws/p/mu/jqbURWw==", + "dev": true, + "requires": { + "esprima": "4.0.1" + } + }, + "decompress-response": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", + "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", + "dev": true, + "requires": { + "mimic-response": "^1.0.0" + } + }, + "dedent": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", + "integrity": "sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=", + "dev": true + }, + "deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "dev": true + }, + "deep-is": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", + "dev": true + }, + "deepmerge": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", + "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==" + }, + "defaults": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz", + "integrity": "sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=", + "dev": true, + "requires": { + "clone": "^1.0.2" + } + }, + "defer-to-connect": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz", + "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==", + "dev": true + }, + "define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "dev": true, + "requires": { + "object-keys": "^1.0.12" + } + }, + "defined": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz", + "integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=" + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", + "dev": true + }, + "depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" + }, + "dependency-graph": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/dependency-graph/-/dependency-graph-0.11.0.tgz", + "integrity": "sha512-JeMq7fEshyepOWDfcfHK06N3MhyPhz++vtqWhMT5O9A3K42rdsEDpfdVqjaqaAhsw6a+ZqeDvQVtD0hFHQWrzg==", + "dev": true + }, + "dependency-tree": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/dependency-tree/-/dependency-tree-8.1.1.tgz", + "integrity": "sha512-bl5U16VQpaYxD0xvcnCH/dTctCiWnsVWymh9dNjbm4T00Hm21flu1VLnNueKCj7+3uusbcJhKKKtiWrpU0I+Nw==", + "dev": true, + "requires": { + "commander": "^2.20.3", + "debug": "^4.3.1", + "filing-cabinet": "^3.0.0", + "precinct": "^8.0.0", + "typescript": "^3.9.7" + }, + "dependencies": { + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + }, + "precinct": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/precinct/-/precinct-8.1.0.tgz", + "integrity": "sha512-oeZBR9IdER42Ef6Rz11z1oOUqicsI5J1Qffj6tYghKLhxN2UnHy7uE1axxNr0VZRevPK2HWkROk36uXrbJwHFA==", + "dev": true, + "requires": { + "commander": "^2.20.3", + "debug": "^4.3.1", + "detective-amd": "^3.0.1", + "detective-cjs": "^3.1.1", + "detective-es6": "^2.2.0", + "detective-less": "^1.0.2", + "detective-postcss": "^4.0.0", + "detective-sass": "^3.0.1", + "detective-scss": "^2.0.1", + "detective-stylus": "^1.0.0", + "detective-typescript": "^7.0.0", + "module-definition": "^3.3.1", + "node-source-walk": "^4.2.0" + } + }, + "typescript": { + "version": "3.9.9", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.9.tgz", + "integrity": "sha512-kdMjTiekY+z/ubJCATUPlRDl39vXYiMV9iyeMuEuXZh2we6zz80uovNN2WlAxmmdE/Z/YQe+EbOEXB5RHEED3w==", + "dev": true + } + } + }, + "dequal": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.2.tgz", + "integrity": "sha512-q9K8BlJVxK7hQYqa6XISGmBZbtQQWVXSrRrWreHC94rMt1QL/Impruc+7p2CYSYuVIUr+YCt6hjrs1kkdJRTug==" + }, + "des.js": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz", + "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==", + "requires": { + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" + } + }, + "detect-indent": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.0.0.tgz", + "integrity": "sha512-oSyFlqaTHCItVRGK5RmrmjB+CmaMOW7IaNA/kdxqhoa6d17j/5ce9O9eWXmV/KEdRwqpQA+Vqe8a8Bsybu4YnA==", + "dev": true + }, + "detective": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/detective/-/detective-5.2.0.tgz", + "integrity": "sha512-6SsIx+nUUbuK0EthKjv0zrdnajCCXVYGmbYYiYjFVpzcjwEs/JMDZ8tPRG29J/HhN56t3GJp2cGSWDRjjot8Pg==", + "requires": { + "acorn-node": "^1.6.1", + "defined": "^1.0.0", + "minimist": "^1.1.1" + } + }, + "detective-amd": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/detective-amd/-/detective-amd-3.1.0.tgz", + "integrity": "sha512-G7wGWT6f0VErjUkE2utCm7IUshT7nBh7aBBH2VBOiY9Dqy2DMens5iiOvYCuhstoIxRKLrnOvVAz4/EyPIAjnw==", + "dev": true, + "requires": { + "ast-module-types": "^2.7.0", + "escodegen": "^2.0.0", + "get-amd-module-type": "^3.0.0", + "node-source-walk": "^4.0.0" + } + }, + "detective-cjs": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/detective-cjs/-/detective-cjs-3.1.1.tgz", + "integrity": "sha512-JQtNTBgFY6h8uT6pgph5QpV3IyxDv+z3qPk/FZRDT9TlFfm5dnRtpH39WtQEr1khqsUxVqXzKjZHpdoQvQbllg==", + "dev": true, + "requires": { + "ast-module-types": "^2.4.0", + "node-source-walk": "^4.0.0" + } + }, + "detective-es6": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/detective-es6/-/detective-es6-2.2.0.tgz", + "integrity": "sha512-fSpNY0SLER7/sVgQZ1NxJPwmc9uCTzNgdkQDhAaj8NPYwr7Qji9QBcmbNvtMCnuuOGMuKn3O7jv0An+/WRWJZQ==", + "dev": true, + "requires": { + "node-source-walk": "^4.0.0" + } + }, + "detective-less": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/detective-less/-/detective-less-1.0.2.tgz", + "integrity": "sha512-Rps1xDkEEBSq3kLdsdnHZL1x2S4NGDcbrjmd4q+PykK5aJwDdP5MBgrJw1Xo+kyUHuv3JEzPqxr+Dj9ryeDRTA==", + "dev": true, + "requires": { + "debug": "^4.0.0", + "gonzales-pe": "^4.2.3", + "node-source-walk": "^4.0.0" + } + }, + "detective-postcss": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/detective-postcss/-/detective-postcss-4.0.0.tgz", + "integrity": "sha512-Fwc/g9VcrowODIAeKRWZfVA/EufxYL7XfuqJQFroBKGikKX83d2G7NFw6kDlSYGG3LNQIyVa+eWv1mqre+v4+A==", + "dev": true, + "requires": { + "debug": "^4.1.1", + "is-url": "^1.2.4", + "postcss": "^8.1.7", + "postcss-values-parser": "^2.0.1" + }, + "dependencies": { + "colorette": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.2.tgz", + "integrity": "sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==", + "dev": true + }, + "postcss": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.3.2.tgz", + "integrity": "sha512-y1FK/AWdZlBF5lusS5j5l4/vF67+vQZt1SXPVJ32y1kRGDQyrs1zk32hG1cInRTu14P0V+orPz+ifwW/7rR4bg==", + "dev": true, + "requires": { + "colorette": "^1.2.2", + "nanoid": "^3.1.23", + "source-map-js": "^0.6.2" + } + } + } + }, + "detective-sass": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/detective-sass/-/detective-sass-3.0.1.tgz", + "integrity": "sha512-oSbrBozRjJ+QFF4WJFbjPQKeakoaY1GiR380NPqwdbWYd5wfl5cLWv0l6LsJVqrgWfFN1bjFqSeo32Nxza8Lbw==", + "dev": true, + "requires": { + "debug": "^4.1.1", + "gonzales-pe": "^4.2.3", + "node-source-walk": "^4.0.0" + } + }, + "detective-scss": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/detective-scss/-/detective-scss-2.0.1.tgz", + "integrity": "sha512-VveyXW4WQE04s05KlJ8K0bG34jtHQVgTc9InspqoQxvnelj/rdgSAy7i2DXAazyQNFKlWSWbS+Ro2DWKFOKTPQ==", + "dev": true, + "requires": { + "debug": "^4.1.1", + "gonzales-pe": "^4.2.3", + "node-source-walk": "^4.0.0" + } + }, + "detective-stylus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/detective-stylus/-/detective-stylus-1.0.0.tgz", + "integrity": "sha1-UK7n24uruZA4HwEMY/q7pbWOVM0=", + "dev": true + }, + "detective-typescript": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/detective-typescript/-/detective-typescript-7.0.0.tgz", + "integrity": "sha512-y/Ev98AleGvl43YKTNcA2Q+lyFmsmCfTTNWy4cjEJxoLkbobcXtRS0Kvx06daCgr2GdtlwLfNzL553BkktfJoA==", + "dev": true, + "requires": { + "@typescript-eslint/typescript-estree": "^4.8.2", + "ast-module-types": "^2.7.1", + "node-source-walk": "^4.2.0", + "typescript": "^3.9.7" + }, + "dependencies": { + "typescript": { + "version": "3.9.9", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.9.tgz", + "integrity": "sha512-kdMjTiekY+z/ubJCATUPlRDl39vXYiMV9iyeMuEuXZh2we6zz80uovNN2WlAxmmdE/Z/YQe+EbOEXB5RHEED3w==", + "dev": true + } + } + }, + "didyoumean": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.1.tgz", + "integrity": "sha1-6S7f2tplN9SE1zwBcv0eugxJdv8=" + }, + "diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true + }, + "diffie-hellman": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", + "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", + "requires": { + "bn.js": "^4.1.0", + "miller-rabin": "^4.0.0", + "randombytes": "^2.0.0" + }, + "dependencies": { + "bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" + } + } + }, + "dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "requires": { + "path-type": "^4.0.0" + } + }, + "dlv": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", + "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==" + }, + "domain-browser": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", + "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==" + }, + "dot-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", + "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==", + "dev": true, + "requires": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "dot-object": { + "version": "2.1.4", + "requires": { + "commander": "^4.0.0", + "glob": "^7.1.5" + }, + "dependencies": { + "commander": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", + "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==" + } + } + }, + "dotenv": { + "version": "8.6.0", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.6.0.tgz", + "integrity": "sha512-IrPdXQsk2BbzvCBGBOTmmSH5SodmqZNt4ERAZDmW4CT+tL8VtvinqywuANaFu4bOMWki16nqf0e4oC0QIaDr/g==", + "dev": true + }, + "duplexer": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", + "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==", + "dev": true + }, + "duplexer3": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", + "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=", + "dev": true + }, + "ecdsa-sig-formatter": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", + "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", + "dev": true, + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "electron-to-chromium": { + "version": "1.3.663", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.663.tgz", + "integrity": "sha512-xkVkzHj6k3oRRGlmdgUCCLSLhtFYHDCTH7SeK+LJdJjnsLcrdbpr8EYmfMQhez3V/KPO5UScSpzQ0feYX6Qoyw==" + }, + "elegant-spinner": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/elegant-spinner/-/elegant-spinner-1.0.1.tgz", + "integrity": "sha1-2wQ1IcldfjA/2PNFvtwzSc+wcp4=", + "dev": true + }, + "elliptic": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", + "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", + "requires": { + "bn.js": "^4.11.9", + "brorand": "^1.1.0", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.1", + "inherits": "^2.0.4", + "minimalistic-assert": "^1.0.1", + "minimalistic-crypto-utils": "^1.0.1" + }, + "dependencies": { + "bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" + } + } + }, + "email-validator": { + "version": "2.0.4" + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "emojis-list": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz", + "integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=" + }, + "end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dev": true, + "requires": { + "once": "^1.4.0" + } + }, + "enhanced-resolve": { + "version": "5.8.2", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.8.2.tgz", + "integrity": "sha512-F27oB3WuHDzvR2DOGNTaYy0D5o0cnrv8TeI482VM4kYgQd/FT9lUQwuNsJ0oOHtBUq7eiW5ytqzp7nBFknL+GA==", + "dev": true, + "requires": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + } + }, + "enquirer": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", + "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", + "dev": true, + "requires": { + "ansi-colors": "^4.1.1" + } + }, + "errno": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz", + "integrity": "sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==", + "dev": true, + "requires": { + "prr": "~1.0.1" + } + }, + "error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "requires": { + "is-arrayish": "^0.2.1" + } + }, + "es-abstract": { + "version": "1.18.3", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.3.tgz", + "integrity": "sha512-nQIr12dxV7SSxE6r6f1l3DtAeEYdsGpps13dR0TwJg1S8gyp4ZPgy3FZcHBgbiQqnoqSTb+oC+kO4UQ0C/J8vw==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "get-intrinsic": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.2", + "is-callable": "^1.2.3", + "is-negative-zero": "^2.0.1", + "is-regex": "^1.1.3", + "is-string": "^1.0.6", + "object-inspect": "^1.10.3", + "object-keys": "^1.1.1", + "object.assign": "^4.1.2", + "string.prototype.trimend": "^1.0.4", + "string.prototype.trimstart": "^1.0.4", + "unbox-primitive": "^1.0.1" + } + }, + "es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==" + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + }, + "escodegen": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.0.0.tgz", + "integrity": "sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw==", + "dev": true, + "requires": { + "esprima": "^4.0.1", + "estraverse": "^5.2.0", + "esutils": "^2.0.2", + "optionator": "^0.8.1", + "source-map": "~0.6.1" + } + }, + "eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "dev": true + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true + }, + "estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "dev": true + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==" + }, + "etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" + }, + "event-target-shim": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", + "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", + "dev": true + }, + "eventemitter3": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.2.tgz", + "integrity": "sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q==", + "dev": true + }, + "events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==" + }, + "evp_bytestokey": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", + "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", + "requires": { + "md5.js": "^1.3.4", + "safe-buffer": "^5.1.1" + } + }, + "execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + }, + "dependencies": { + "is-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", + "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==", + "dev": true + } + } + }, + "external-editor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", + "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", + "dev": true, + "requires": { + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" + } + }, + "extract-files": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/extract-files/-/extract-files-9.0.0.tgz", + "integrity": "sha512-CvdFfHkC95B4bBBk36hcEmvdR2awOdhhVUYH6S/zrVj3477zven/fJMYg7121h4T1xHZC+tetUpubpAhxwI7hQ==", + "dev": true + }, + "fast-glob": { + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.5.tgz", + "integrity": "sha512-2DtFcgT68wiTTiwZ2hNdJfcHNke9XOfnwmBRWXhmeKM8rF0TGwmC/Qto3S7RoZKp5cilZbxzO5iTNTQsJ+EeDg==", + "requires": { + "@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-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true + }, + "fastq": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.11.0.tgz", + "integrity": "sha512-7Eczs8gIPDrVzT+EksYBcupqMyxSHXXrHOLRRxU2/DicV8789MRBRR8+Hc2uWzUupOs4YS4JzBmBxjjCVBxD/g==", + "requires": { + "reusify": "^1.0.4" + } + }, + "fb-watchman": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.1.tgz", + "integrity": "sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg==", + "dev": true, + "requires": { + "bser": "2.1.1" + } + }, + "fbjs": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/fbjs/-/fbjs-3.0.0.tgz", + "integrity": "sha512-dJd4PiDOFuhe7vk4F80Mba83Vr2QuK86FoxtgPmzBqEJahncp+13YCmfoa53KHCo6OnlXLG7eeMWPfB5CrpVKg==", + "dev": true, + "requires": { + "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" + } + }, + "fbjs-css-vars": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/fbjs-css-vars/-/fbjs-css-vars-1.0.2.tgz", + "integrity": "sha512-b2XGFAFdWZWg0phtAWLHCk836A1Xann+I+Dgd3Gk64MHKZO44FfoD1KxyvbSh0qZsIoXQGGlVztIY+oitJPpRQ==", + "dev": true + }, + "figures": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", + "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.5" + } + }, + "filing-cabinet": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/filing-cabinet/-/filing-cabinet-3.0.0.tgz", + "integrity": "sha512-o8Qac5qxZ1uVidR4Sd7ZQbbqObFZlqXU4xu1suAYg9PQPcQFNTzOmxQa/MehIDMgIvXHTb42mWPNV9l3eHBPSw==", + "dev": true, + "requires": { + "app-module-path": "^2.2.0", + "commander": "^2.20.3", + "debug": "^4.3.1", + "decomment": "^0.9.3", + "enhanced-resolve": "^5.3.2", + "is-relative-path": "^1.0.2", + "module-definition": "^3.3.1", + "module-lookup-amd": "^7.0.0", + "resolve": "^1.19.0", + "resolve-dependency-path": "^2.0.0", + "sass-lookup": "^3.0.0", + "stylus-lookup": "^3.0.1", + "typescript": "^3.9.7" + }, + "dependencies": { + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + }, + "typescript": { + "version": "3.9.9", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.9.tgz", + "integrity": "sha512-kdMjTiekY+z/ubJCATUPlRDl39vXYiMV9iyeMuEuXZh2we6zz80uovNN2WlAxmmdE/Z/YQe+EbOEXB5RHEED3w==", + "dev": true + } + } + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "find-cache-dir": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.1.tgz", + "integrity": "sha512-t2GDMt3oGC/v+BMwzmllWDuJF/xcDtE5j/fCGbqDD7OLuJkj0cfh1YSA5VKPvwMeLFLNDBkwOKZ2X85jGLVftQ==", + "requires": { + "commondir": "^1.0.1", + "make-dir": "^3.0.2", + "pkg-dir": "^4.1.0" + } + }, + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "flatten": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/flatten/-/flatten-1.0.3.tgz", + "integrity": "sha512-dVsPA/UwQ8+2uoFe5GHtiBMu48dWLTdsuEd7CKGlZlD78r1TTWBvDuFaFGKCo/ZfEr95Uk56vZoX86OsHkUeIg==", + "dev": true + }, + "form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dev": true, + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + } + }, + "fraction.js": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.1.1.tgz", + "integrity": "sha512-MHOhvvxHTfRFpF1geTK9czMIZ6xclsEor2wkIGYYq+PxcQqT7vStJqjhe6S1TenZrMZzo+wlqOufBDVepUEgPg==" + }, + "fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "requires": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + }, + "fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "optional": true + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true + }, + "get-amd-module-type": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/get-amd-module-type/-/get-amd-module-type-3.0.0.tgz", + "integrity": "sha512-99Q7COuACPfVt18zH9N4VAMyb81S6TUgJm2NgV6ERtkh9VIkAaByZkW530wl3lLN5KTtSrK9jVLxYsoP5hQKsw==", + "dev": true, + "requires": { + "ast-module-types": "^2.3.2", + "node-source-walk": "^4.0.0" + } + }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true + }, + "get-intrinsic": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", + "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", + "dev": true, + "requires": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1" + } + }, + "get-orientation": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/get-orientation/-/get-orientation-1.1.2.tgz", + "integrity": "sha512-/pViTfifW+gBbh/RnlFYHINvELT9Znt+SYyDKAUL6uV6By019AK/s+i9XP4jSwq7lwP38Fd8HVeTxym3+hkwmQ==", + "requires": { + "stream-parser": "^0.3.1" + } + }, + "get-own-enumerable-property-symbols": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz", + "integrity": "sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==", + "dev": true + }, + "get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "dev": true + }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "requires": { + "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" + } + }, + "glob-base": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", + "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", + "requires": { + "glob-parent": "^2.0.0", + "is-glob": "^2.0.0" + }, + "dependencies": { + "glob-parent": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", + "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", + "requires": { + "is-glob": "^2.0.0" + } + }, + "is-glob": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", + "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", + "requires": { + "is-extglob": "^1.0.0" + } + } + } + }, + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "requires": { + "is-glob": "^4.0.1" + } + }, + "glob-to-regexp": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==" + }, + "globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true + }, + "globby": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.3.tgz", + "integrity": "sha512-ffdmosjA807y7+lA1NM0jELARVmYul/715xiILEjo3hBLPTcirgQNnXECn5g3mtR8TOLCVbkfua1Hpen25/Xcg==", + "dev": true, + "requires": { + "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": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/gonzales-pe/-/gonzales-pe-4.3.0.tgz", + "integrity": "sha512-otgSPpUmdWJ43VXyiNgEYE4luzHCL2pz4wQ0OnDluC6Eg4Ko3Vexy/SrSynglw/eR+OhkzmqFCZa/OFa/RgAOQ==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + }, + "got": { + "version": "9.6.0", + "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz", + "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==", + "dev": true, + "requires": { + "@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" + }, + "dependencies": { + "get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + } + } + }, + "graceful-fs": { + "version": "4.2.6", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz", + "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==" + }, + "graphql": { + "version": "15.5.0", + "dev": true + }, + "graphql-config": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/graphql-config/-/graphql-config-3.3.0.tgz", + "integrity": "sha512-mSQIsPMssr7QrgqhnjI+CyVH6oQgCrgS6irHsTvwf7RFDRnR2k9kqpQOQgVoOytBSn0DOYryS0w0SAg9xor/Jw==", + "dev": true, + "requires": { + "@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": "^7.0.0", + "cosmiconfig": "7.0.0", + "cosmiconfig-toml-loader": "1.0.0", + "minimatch": "3.0.4", + "string-env-interpolation": "1.0.1" + } + }, + "graphql-request": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/graphql-request/-/graphql-request-3.4.0.tgz", + "integrity": "sha512-acrTzidSlwAj8wBNO7Q/UQHS8T+z5qRGquCQRv9J1InwR01BBWV9ObnoE+JS5nCCEj8wSGS0yrDXVDoRiKZuOg==", + "dev": true, + "requires": { + "cross-fetch": "^3.0.6", + "extract-files": "^9.0.0", + "form-data": "^3.0.0" + }, + "dependencies": { + "form-data": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", + "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", + "dev": true, + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + } + } + } + }, + "graphql-tag": { + "version": "2.12.4", + "resolved": "https://registry.npmjs.org/graphql-tag/-/graphql-tag-2.12.4.tgz", + "integrity": "sha512-VV1U4O+9x99EkNpNmCUV5RZwq6MnK4+pGbRYWG+lA/m3uo7TSqJF81OkcOP148gFP6fzdl7JWYBrwWVTS9jXww==", + "dev": true, + "requires": { + "tslib": "^2.1.0" + } + }, + "graphql-ws": { + "version": "4.9.0", + "resolved": "https://registry.npmjs.org/graphql-ws/-/graphql-ws-4.9.0.tgz", + "integrity": "sha512-sHkK9+lUm20/BGawNEWNtVAeJzhZeBg21VmvmLoT5NdGVeZWv5PdIhkcayQIAgjSyyQ17WMKmbDijIPG2On+Ag==", + "dev": true + }, + "graphviz": { + "version": "0.0.9", + "resolved": "https://registry.npmjs.org/graphviz/-/graphviz-0.0.9.tgz", + "integrity": "sha512-SmoY2pOtcikmMCqCSy2NO1YsRfu9OO0wpTlOYW++giGjfX1a6gax/m1Fo8IdUd0/3H15cTOfR1SMKwohj4LKsg==", + "dev": true, + "requires": { + "temp": "~0.4.0" + } + }, + "gzip-size": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-6.0.0.tgz", + "integrity": "sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q==", + "dev": true, + "requires": { + "duplexer": "^0.1.2" + } + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + } + } + }, + "has-bigints": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz", + "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" + }, + "has-symbols": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", + "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", + "dev": true + }, + "hash-base": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", + "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", + "requires": { + "inherits": "^2.0.4", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + }, + "dependencies": { + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + } + } + }, + "hash.js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "requires": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==" + }, + "header-case": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/header-case/-/header-case-2.0.4.tgz", + "integrity": "sha512-H/vuk5TEEVZwrR0lp2zed9OCo1uAILMlx0JEMgC26rzyJJ3N1v6XkwHHXJQdR2doSjcGPM6OKPYoJgf0plJ11Q==", + "dev": true, + "requires": { + "capital-case": "^1.0.4", + "tslib": "^2.0.3" + } + }, + "hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", + "requires": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "html-tags": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-3.1.0.tgz", + "integrity": "sha512-1qYz89hW3lFDEazhjW0yVAV87lw8lVkrJocr72XmBkMKsoSVJCQx3W8BXsC7hO2qAt8BoVjYjtAcZ9perqGnNg==" + }, + "http-cache-semantics": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", + "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==", + "dev": true + }, + "http-errors": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.3.tgz", + "integrity": "sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw==", + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.4", + "setprototypeof": "1.1.1", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.0" + } + }, + "http-proxy-agent": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", + "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", + "dev": true, + "requires": { + "@tootallnate/once": "1", + "agent-base": "6", + "debug": "4" + } + }, + "https-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", + "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=" + }, + "https-proxy-agent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", + "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", + "dev": true, + "requires": { + "agent-base": "6", + "debug": "4" + } + }, + "human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "dev": true + }, + "humanize-ms": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", + "integrity": "sha1-xG4xWaKT9riW2ikxbYtv6Lt5u+0=", + "requires": { + "ms": "^2.0.0" + } + }, + "husky": { + "version": "6.0.0", + "dev": true + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" + }, + "ignore": { + "version": "5.1.8", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", + "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", + "dev": true + }, + "immutability-helper": { + "version": "3.1.1" + }, + "immutable": { + "version": "3.7.6", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-3.7.6.tgz", + "integrity": "sha1-E7TTyxK++hVIKib+Gy665kAHHks=", + "dev": true + }, + "import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "dependencies": { + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true + } + } + }, + "import-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/import-from/-/import-from-3.0.0.tgz", + "integrity": "sha512-CiuXOFFSzkU5x/CR0+z7T91Iht4CXgfCxVOFRhh2Zyhg5wOpWvvDLQUsWl+gcN+QscYBjez8hDCt85O7RLDttQ==", + "dev": true, + "requires": { + "resolve-from": "^5.0.0" + } + }, + "indent-string": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-3.2.0.tgz", + "integrity": "sha1-Sl/W0nzDMvN+VBmlBNu4NxBckok=", + "dev": true + }, + "indexes-of": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/indexes-of/-/indexes-of-1.0.1.tgz", + "integrity": "sha1-8w9xbI4r00bHtn0985FVZqfAVgc=" + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true + }, + "inquirer": { + "version": "7.3.3", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.3.3.tgz", + "integrity": "sha512-JG3eIAj5V9CwcGvuOmoo6LB9kbAYT8HXffUl6memuszlwDC/qvFAJw49XJ5NROSFNPxp3iQg1GqkFhaY/CR0IA==", + "dev": true, + "requires": { + "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": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz", + "integrity": "sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==", + "dev": true, + "requires": { + "is-relative": "^1.0.0", + "is-windows": "^1.0.1" + } + }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "dev": true + }, + "is-bigint": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.2.tgz", + "integrity": "sha512-0JV5+SOCQkIdzjBK9buARcV804Ddu7A0Qet6sHi3FimE9ne6m4BGQZfRn+NZiXbBk4F4XmHfDZIipLj9pX8dSA==", + "dev": true + }, + "is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "requires": { + "binary-extensions": "^2.0.0" + } + }, + "is-boolean-object": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.1.tgz", + "integrity": "sha512-bXdQWkECBUIAcCkeH1unwJLIpZYaa5VvuygSyS/c2lf719mTKZDU5UdDRlpd01UjADgmW8RfqaP+mRaVPdr/Ng==", + "dev": true, + "requires": { + "call-bind": "^1.0.2" + } + }, + "is-callable": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.3.tgz", + "integrity": "sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ==", + "dev": true + }, + "is-core-module": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.4.0.tgz", + "integrity": "sha512-6A2fkfq1rfeQZjxrZJGerpLCTHRNEBiSgnu0+obeJpEPZRUooHgsizvzv0ZjJwOz3iWIHdJtVWJ/tmPr3D21/A==", + "requires": { + "has": "^1.0.3" + } + }, + "is-date-object": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.4.tgz", + "integrity": "sha512-/b4ZVsG7Z5XVtIxs/h9W8nvfLgSAyKYdtGWQLbqy6jA1icmgjf8WCoTKgeS4wy5tYaPePouzFMANbnj94c2Z+A==", + "dev": true + }, + "is-dotfile": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz", + "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=" + }, + "is-extglob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", + "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=" + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "requires": { + "is-extglob": "^2.1.1" + }, + "dependencies": { + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" + } + } + }, + "is-interactive": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", + "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", + "dev": true + }, + "is-lower-case": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-lower-case/-/is-lower-case-2.0.2.tgz", + "integrity": "sha512-bVcMJy4X5Og6VZfdOZstSexlEy20Sr0k/p/b2IlQJlfdKAQuMpiv5w2Ccxb8sKdRUNAG1PnHVHjFSdRDVS6NlQ==", + "dev": true, + "requires": { + "tslib": "^2.0.3" + } + }, + "is-negative-zero": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz", + "integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==", + "dev": true + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" + }, + "is-number-object": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.5.tgz", + "integrity": "sha512-RU0lI/n95pMoUKu9v1BZP5MBcZuNSVJkMkAG2dJqC4z2GlkGUNeH68SuHuBKBD/XFe+LHZ+f9BKkLET60Niedw==", + "dev": true + }, + "is-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", + "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=", + "dev": true + }, + "is-observable": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-observable/-/is-observable-1.1.0.tgz", + "integrity": "sha512-NqCa4Sa2d+u7BWc6CukaObG3Fh+CU9bvixbpcXYhy2VvYS7vVGIdAgnIS5Ks3A/cqk4rebLJ9s8zBstT2aKnIA==", + "dev": true, + "requires": { + "symbol-observable": "^1.1.0" + } + }, + "is-promise": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz", + "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==", + "dev": true + }, + "is-regex": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.3.tgz", + "integrity": "sha512-qSVXFz28HM7y+IWX6vLCsexdlvzT1PJNFSBuaQLQ5o0IEw8UDYW6/2+eCMVyIsbM8CNLX2a/QWmSpyxYEHY7CQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "has-symbols": "^1.0.2" + } + }, + "is-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz", + "integrity": "sha1-/S2INUXEa6xaYz57mgnof6LLUGk=", + "dev": true + }, + "is-relative": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz", + "integrity": "sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==", + "dev": true, + "requires": { + "is-unc-path": "^1.0.0" + } + }, + "is-relative-path": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-relative-path/-/is-relative-path-1.0.2.tgz", + "integrity": "sha1-CRtGoNZ8HtD+hfH4z93gBrslHUY=", + "dev": true + }, + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "dev": true + }, + "is-string": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.6.tgz", + "integrity": "sha512-2gdzbKUuqtQ3lYNrUTQYoClPhm7oQu4UdpSZMp1/DGgkHBT8E2Z1l0yMdb6D4zNAxwDiMv8MdulKROJGNl0Q0w==", + "dev": true + }, + "is-symbol": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "dev": true, + "requires": { + "has-symbols": "^1.0.2" + } + }, + "is-unc-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz", + "integrity": "sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==", + "dev": true, + "requires": { + "unc-path-regex": "^0.1.2" + } + }, + "is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true + }, + "is-upper-case": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-upper-case/-/is-upper-case-2.0.2.tgz", + "integrity": "sha512-44pxmxAvnnAOwBg4tHPnkfvgjPwbc5QIsSstNU+YcJ1ovxVzCWpSGosPJOZh/a1tdl81fbgnLc9LLv+x2ywbPQ==", + "dev": true, + "requires": { + "tslib": "^2.0.3" + } + }, + "is-url": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/is-url/-/is-url-1.2.4.tgz", + "integrity": "sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww==", + "dev": true + }, + "is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "dev": true + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "requires": { + "isarray": "1.0.0" + } + }, + "isomorphic-fetch": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-3.0.0.tgz", + "integrity": "sha512-qvUtwJ3j6qwsF3jLxkZ72qCgjMysPzDfeV240JHiGZsANBYd+EEuu35v7dfrJ9Up0Ak07D7GGSkGhCHTqg/5wA==", + "requires": { + "node-fetch": "^2.6.1", + "whatwg-fetch": "^3.4.1" + } + }, + "isomorphic-unfetch": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/isomorphic-unfetch/-/isomorphic-unfetch-3.1.0.tgz", + "integrity": "sha512-geDJjpoZ8N0kWexiwkX8F9NkTsXhetLPVbZFQ+JTW239QNOwvB0gniuR1Wc6f0AMTn7/mFGyXvHTifrCp/GH8Q==", + "requires": { + "node-fetch": "^2.6.1", + "unfetch": "^4.2.0" + } + }, + "isomorphic-ws": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz", + "integrity": "sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w==", + "dev": true + }, + "iterall": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/iterall/-/iterall-1.3.0.tgz", + "integrity": "sha512-QZ9qOMdF+QLHxy1QIpUHUU1D5pS2CG2P69LF6L6CPjPYA/XMOmKV3PZpawHoAjHNyB0swdVTRxdYT4tbBbxqwg==", + "dev": true + }, + "jest-worker": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-24.9.0.tgz", + "integrity": "sha512-51PE4haMSXcHohnSMdM42anbvZANYTqMrr52tVKPqqsPJMzoP6FYYDVqahX/HrAoKEKz3uUPzSvKs9A3qR4iVw==", + "requires": { + "merge-stream": "^2.0.0", + "supports-color": "^6.1.0" + }, + "dependencies": { + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "js-cookie": { + "version": "2.2.1" + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + }, + "js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "requires": { + "argparse": "^2.0.1" + } + }, + "jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true + }, + "json-buffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", + "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=", + "dev": true + }, + "json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true + }, + "json-stable-stringify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz", + "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=", + "dev": true, + "requires": { + "jsonify": "~0.0.0" + } + }, + "json-to-pretty-yaml": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/json-to-pretty-yaml/-/json-to-pretty-yaml-1.2.2.tgz", + "integrity": "sha1-9M0L0KXo/h3yWq9boRiwmf2ZLVs=", + "dev": true, + "requires": { + "remedial": "^1.0.7", + "remove-trailing-spaces": "^1.0.6" + } + }, + "json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "requires": { + "minimist": "^1.2.0" + } + }, + "jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "requires": { + "graceful-fs": "^4.1.6", + "universalify": "^2.0.0" + } + }, + "jsonify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", + "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=", + "dev": true + }, + "jsonwebtoken": { + "version": "8.5.1", + "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz", + "integrity": "sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==", + "dev": true, + "requires": { + "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" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + } + } + }, + "jwa": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", + "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", + "dev": true, + "requires": { + "buffer-equal-constant-time": "1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "jws": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", + "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", + "dev": true, + "requires": { + "jwa": "^1.4.1", + "safe-buffer": "^5.0.1" + } + }, + "keen-slider": { + "version": "5.4.1" + }, + "keyv": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz", + "integrity": "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==", + "dev": true, + "requires": { + "json-buffer": "3.0.0" + } + }, + "latest-version": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-5.1.0.tgz", + "integrity": "sha512-weT+r0kTkRQdCdYCNtkMwWXQTMEswKrFBkm4ckQOMVhhqhIMI1UT2hMj+1iigIhgSZm5gTmrRXBNoGUgaTY1xA==", + "dev": true, + "requires": { + "package-json": "^6.3.0" + } + }, + "levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + } + }, + "lines-and-columns": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", + "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=", + "dev": true + }, + "lint-staged": { + "version": "11.0.0", + "dev": true, + "requires": { + "chalk": "^4.1.1", + "cli-truncate": "^2.1.0", + "commander": "^7.2.0", + "cosmiconfig": "^7.0.0", + "debug": "^4.3.1", + "dedent": "^0.7.0", + "enquirer": "^2.3.6", + "execa": "^5.0.0", + "listr2": "^3.8.2", + "log-symbols": "^4.1.0", + "micromatch": "^4.0.4", + "normalize-path": "^3.0.0", + "please-upgrade-node": "^3.2.0", + "string-argv": "0.3.1", + "stringify-object": "^3.3.0" + }, + "dependencies": { + "chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "dev": true + }, + "log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dev": true, + "requires": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "dependencies": { + "is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true + } + } + }, + "micromatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", + "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", + "dev": true, + "requires": { + "braces": "^3.0.1", + "picomatch": "^2.2.3" + } + } + } + }, + "listr": { + "version": "0.14.3", + "resolved": "https://registry.npmjs.org/listr/-/listr-0.14.3.tgz", + "integrity": "sha512-RmAl7su35BFd/xoMamRjpIE4j3v+L28o8CT5YhAXQJm1fD+1l9ngXY8JAQRJ+tFK2i5njvi0iRUKV09vPwA0iA==", + "dev": true, + "requires": { + "@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" + }, + "dependencies": { + "is-promise": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz", + "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==", + "dev": true + } + } + }, + "listr-silent-renderer": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/listr-silent-renderer/-/listr-silent-renderer-1.1.1.tgz", + "integrity": "sha1-kktaN1cVN3C/Go4/v3S4u/P5JC4=", + "dev": true + }, + "listr-update-renderer": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/listr-update-renderer/-/listr-update-renderer-0.5.0.tgz", + "integrity": "sha512-tKRsZpKz8GSGqoI/+caPmfrypiaq+OQCbd+CovEC24uk1h952lVj5sC7SqyFUm+OaJ5HN/a1YLt5cit2FMNsFA==", + "dev": true, + "requires": { + "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" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "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" + } + }, + "cli-truncate": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-0.2.1.tgz", + "integrity": "sha1-nxXPuwcFAFNpIWxiasfQWrkN1XQ=", + "dev": true, + "requires": { + "slice-ansi": "0.0.4", + "string-width": "^1.0.1" + } + }, + "figures": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", + "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.5", + "object-assign": "^4.1.0" + } + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "dev": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "log-symbols": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-1.0.2.tgz", + "integrity": "sha1-N2/3tY6jCGoPCfrMdGF+ylAeGhg=", + "dev": true, + "requires": { + "chalk": "^1.0.0" + } + }, + "slice-ansi": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-0.0.4.tgz", + "integrity": "sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU=", + "dev": true + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true + } + } + }, + "listr-verbose-renderer": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/listr-verbose-renderer/-/listr-verbose-renderer-0.5.0.tgz", + "integrity": "sha512-04PDPqSlsqIOaaaGZ+41vq5FejI9auqTInicFRndCBgE3bXG8D6W1I+mWhk+1nqbHmyhla/6BUrd5OSiHwKRXw==", + "dev": true, + "requires": { + "chalk": "^2.4.1", + "cli-cursor": "^2.1.0", + "date-fns": "^1.27.2", + "figures": "^2.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "cli-cursor": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", + "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", + "dev": true, + "requires": { + "restore-cursor": "^2.0.0" + } + }, + "figures": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", + "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.5" + } + }, + "mimic-fn": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", + "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", + "dev": true + }, + "onetime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", + "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", + "dev": true, + "requires": { + "mimic-fn": "^1.0.0" + } + }, + "restore-cursor": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", + "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", + "dev": true, + "requires": { + "onetime": "^2.0.0", + "signal-exit": "^3.0.2" + } + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "listr2": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-3.9.0.tgz", + "integrity": "sha512-+JxQt7Vi4WEWgJsxmOEX9lDbCumrb3mrEYIeE1VI7I4lf2rXE4v9pq3RMVNp+a9s6mCgc/IsF0ppHsLrx2BEAw==", + "dev": true, + "requires": { + "cli-truncate": "^2.1.0", + "colorette": "^1.2.2", + "log-update": "^4.0.0", + "p-map": "^4.0.0", + "rxjs": "^6.6.7", + "through": "^2.3.8", + "wrap-ansi": "^7.0.0" + }, + "dependencies": { + "colorette": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.2.tgz", + "integrity": "sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==", + "dev": true + }, + "log-update": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/log-update/-/log-update-4.0.0.tgz", + "integrity": "sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==", + "dev": true, + "requires": { + "ansi-escapes": "^4.3.0", + "cli-cursor": "^3.1.0", + "slice-ansi": "^4.0.0", + "wrap-ansi": "^6.2.0" + }, + "dependencies": { + "wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + } + } + }, + "p-map": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", + "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "dev": true, + "requires": { + "aggregate-error": "^3.0.0" + } + }, + "slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + } + } + } + }, + "loader-utils": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.2.3.tgz", + "integrity": "sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA==", + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^2.0.0", + "json5": "^1.0.1" + } + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "requires": { + "p-locate": "^4.1.0" + } + }, + "lodash": { + "version": "4.17.20", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz", + "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==" + }, + "lodash._reinterpolate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", + "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=", + "dev": true + }, + "lodash.camelcase": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", + "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY=" + }, + "lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=" + }, + "lodash.debounce": { + "version": "4.0.8" + }, + "lodash.get": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", + "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=", + "dev": true + }, + "lodash.includes": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", + "integrity": "sha1-YLuYqHy5I8aMoeUTJUgzFISfVT8=" + }, + "lodash.isboolean": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", + "integrity": "sha1-bC4XHbKiV82WgC/UOwGyDV9YcPY=", + "dev": true + }, + "lodash.isdate": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.isdate/-/lodash.isdate-4.0.1.tgz", + "integrity": "sha1-NaVDZzuddhEN5BFLMsxXcEin82Y=" + }, + "lodash.isinteger": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", + "integrity": "sha1-YZwK89A/iwTDH1iChAt3sRzWg0M=", + "dev": true + }, + "lodash.isnumber": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", + "integrity": "sha1-POdoEMWSjQM1IwGsKHMX8RwLH/w=", + "dev": true + }, + "lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=" + }, + "lodash.isstring": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", + "integrity": "sha1-1SfftUVuynzJu5XV2ur4i6VKVFE=", + "dev": true + }, + "lodash.once": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", + "integrity": "sha1-DdOXEhPHxW34gJd9UEyI+0cal6w=", + "dev": true + }, + "lodash.random": { + "version": "3.2.0" + }, + "lodash.snakecase": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.snakecase/-/lodash.snakecase-4.1.1.tgz", + "integrity": "sha1-OdcUo1NXFHg3rv1ktdy7Fr7Nj40=" + }, + "lodash.sortby": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", + "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=" + }, + "lodash.template": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.5.0.tgz", + "integrity": "sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A==", + "dev": true, + "requires": { + "lodash._reinterpolate": "^3.0.0", + "lodash.templatesettings": "^4.0.0" + } + }, + "lodash.templatesettings": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.2.0.tgz", + "integrity": "sha512-stgLz+i3Aa9mZgnjr/O+v9ruKZsPsndy7qPZOchbqk2cnTU1ZaldKK+v7m54WoKIyxiuMZTKT2H81F8BeAc3ZQ==", + "dev": true, + "requires": { + "lodash._reinterpolate": "^3.0.0" + } + }, + "lodash.throttle": { + "version": "4.1.1" + }, + "lodash.toarray": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.toarray/-/lodash.toarray-4.4.0.tgz", + "integrity": "sha1-JMS/zWsvuji/0FlNsRedjptlZWE=" + }, + "lodash.topath": { + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/lodash.topath/-/lodash.topath-4.5.2.tgz", + "integrity": "sha1-NhY1Hzu6YZlKCTGYlmC9AyVP0Ak=" + }, + "lodash.uniq": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", + "integrity": "sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=" + }, + "log-symbols": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.0.0.tgz", + "integrity": "sha512-FN8JBzLx6CzeMrB0tg6pqlGU1wCrXW+ZXGH481kfsBqer0hToTIiHdjH4Mq8xJUbvATujKCvaREGWpGUionraA==", + "dev": true, + "requires": { + "chalk": "^4.0.0" + } + }, + "log-update": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/log-update/-/log-update-2.3.0.tgz", + "integrity": "sha1-iDKP19HOeTiykoN0bwsbwSayRwg=", + "dev": true, + "requires": { + "ansi-escapes": "^3.0.0", + "cli-cursor": "^2.0.0", + "wrap-ansi": "^3.0.1" + }, + "dependencies": { + "ansi-escapes": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", + "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==", + "dev": true + }, + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "cli-cursor": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", + "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", + "dev": true, + "requires": { + "restore-cursor": "^2.0.0" + } + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "mimic-fn": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", + "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", + "dev": true + }, + "onetime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", + "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", + "dev": true, + "requires": { + "mimic-fn": "^1.0.0" + } + }, + "restore-cursor": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", + "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", + "dev": true, + "requires": { + "onetime": "^2.0.0", + "signal-exit": "^3.0.2" + } + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + }, + "wrap-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-3.0.1.tgz", + "integrity": "sha1-KIoE2H7aXChuBg3+jxNc6NAH+Lo=", + "dev": true, + "requires": { + "string-width": "^2.1.1", + "strip-ansi": "^4.0.0" + } + } + } + }, + "loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "requires": { + "js-tokens": "^3.0.0 || ^4.0.0" + } + }, + "lower-case": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", + "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", + "dev": true, + "requires": { + "tslib": "^2.0.3" + } + }, + "lower-case-first": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/lower-case-first/-/lower-case-first-2.0.2.tgz", + "integrity": "sha512-EVm/rR94FJTZi3zefZ82fLWab+GX14LJN4HrWBcuo6Evmsl9hEfnqxgcHCKb9q+mNf6EVdsjx/qucYFIIB84pg==", + "dev": true, + "requires": { + "tslib": "^2.0.3" + } + }, + "lowercase-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", + "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", + "dev": true + }, + "lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "requires": { + "yallist": "^3.0.2" + } + }, + "madge": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/madge/-/madge-4.0.2.tgz", + "integrity": "sha512-l5bnA2dvyk0azLKDbOTCI+wDZ6nB007PhvPdmiYlPmqwVi49JPbhQrH/t4u8E6Akp3gwji1GZuA+v/F5q6yoWQ==", + "dev": true, + "requires": { + "chalk": "^4.1.0", + "commander": "^6.2.1", + "commondir": "^1.0.1", + "debug": "^4.0.1", + "dependency-tree": "^8.0.0", + "detective-amd": "^3.0.1", + "detective-cjs": "^3.1.1", + "detective-es6": "^2.1.0", + "detective-less": "^1.0.2", + "detective-postcss": "^4.0.0", + "detective-sass": "^3.0.1", + "detective-scss": "^2.0.1", + "detective-stylus": "^1.0.0", + "detective-typescript": "^7.0.0", + "graphviz": "0.0.9", + "ora": "^5.1.0", + "pluralize": "^8.0.0", + "precinct": "^7.0.0", + "pretty-ms": "^7.0.0", + "rc": "^1.2.7", + "typescript": "^3.9.5", + "walkdir": "^0.4.1" + }, + "dependencies": { + "typescript": { + "version": "3.9.9", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.9.tgz", + "integrity": "sha512-kdMjTiekY+z/ubJCATUPlRDl39vXYiMV9iyeMuEuXZh2we6zz80uovNN2WlAxmmdE/Z/YQe+EbOEXB5RHEED3w==", + "dev": true + } + } + }, + "make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "requires": { + "semver": "^6.0.0" + } + }, + "make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true + }, + "map-cache": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", + "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", + "dev": true + }, + "matcher": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/matcher/-/matcher-4.0.0.tgz", + "integrity": "sha512-S6x5wmcDmsDRRU/c2dkccDwQPXoFczc5+HpQ2lON8pnvHlnvHAHj5WlLVvw6n6vNyHuVugYrFohYxbS+pvFpKQ==", + "requires": { + "escape-string-regexp": "^4.0.0" + }, + "dependencies": { + "escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==" + } + } + }, + "md5.js": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", + "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "memory-fs": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.5.0.tgz", + "integrity": "sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA==", + "dev": true, + "requires": { + "errno": "^0.1.3", + "readable-stream": "^2.0.1" + } + }, + "merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==" + }, + "merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==" + }, + "meros": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/meros/-/meros-1.1.4.tgz", + "integrity": "sha512-E9ZXfK9iQfG9s73ars9qvvvbSIkJZF5yOo9j4tcwM5tN8mUKfj/EKN5PzOr3ZH0y5wL7dLAHw3RVEfpQV9Q7VQ==", + "dev": true + }, + "micromatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", + "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", + "requires": { + "braces": "^3.0.1", + "picomatch": "^2.0.5" + } + }, + "miller-rabin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", + "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", + "requires": { + "bn.js": "^4.0.0", + "brorand": "^1.0.1" + }, + "dependencies": { + "bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" + } + } + }, + "mime": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.5.2.tgz", + "integrity": "sha512-tqkh47FzKeCPD2PUiPB6pkbMzsCasjxAfC62/Wap5qrUWcb+sFasXUC5I3gYM5iBM8v/Qpn4UK0x+j0iHyFPDg==", + "dev": true + }, + "mime-db": { + "version": "1.48.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.48.0.tgz", + "integrity": "sha512-FM3QwxV+TnZYQ2aRqhlKBMHxk10lTbMt3bBkMAp54ddrNeVSfcQYOOKuGuy3Ddrm38I04If834fOUSq1yzslJQ==", + "dev": true + }, + "mime-types": { + "version": "2.1.31", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.31.tgz", + "integrity": "sha512-XGZnNzm3QvgKxa8dpzyhFTHmpP3l5YNusmne07VUOXxou9CqUqYa/HBy124RqtVh/O2pECas/MOcsDgpilPOPg==", + "dev": true, + "requires": { + "mime-db": "1.48.0" + } + }, + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true + }, + "mimic-response": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", + "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", + "dev": true + }, + "minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" + }, + "minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=" + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" + }, + "mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true + }, + "modern-normalize": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/modern-normalize/-/modern-normalize-1.0.0.tgz", + "integrity": "sha512-1lM+BMLGuDfsdwf3rsgBSrxJwAZHFIrQ8YR61xIqdHo0uNKI9M52wNpHSrliZATJp51On6JD0AfRxd4YGSU0lw==" + }, + "module-definition": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/module-definition/-/module-definition-3.3.1.tgz", + "integrity": "sha512-kLidGPwQ2yq484nSD+D3JoJp4Etc0Ox9P0L34Pu/cU4X4HcG7k7p62XI5BBuvURWMRX3RPyuhOcBHbKus+UH4A==", + "dev": true, + "requires": { + "ast-module-types": "^2.7.1", + "node-source-walk": "^4.0.0" + } + }, + "module-lookup-amd": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/module-lookup-amd/-/module-lookup-amd-7.0.1.tgz", + "integrity": "sha512-w9mCNlj0S8qviuHzpakaLVc+/7q50jl9a/kmJ/n8bmXQZgDPkQHnPBb8MUOYh3WpAYkXuNc2c+khsozhIp/amQ==", + "dev": true, + "requires": { + "commander": "^2.8.1", + "debug": "^4.1.0", + "glob": "^7.1.6", + "requirejs": "^2.3.5", + "requirejs-config-file": "^4.0.0" + }, + "dependencies": { + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + } + } + }, + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "mute-stream": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", + "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", + "dev": true + }, + "nanoid": { + "version": "3.1.23", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.23.tgz", + "integrity": "sha512-FiB0kzdP0FFVGDKlRLEQ1BgDzU87dy5NnzjeW9YZNt+/c3+q82EQDUwniSAUxp/F0gFNI1ZhKU1FqYsMuqZVnw==" + }, + "native-url": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/native-url/-/native-url-0.3.4.tgz", + "integrity": "sha512-6iM8R99ze45ivyH8vybJ7X0yekIcPf5GgLV5K0ENCbmRcaRIDoj37BC8iLEmaaBfqqb8enuZ5p0uhY+lVAbAcA==", + "requires": { + "querystring": "^0.2.0" + } + }, + "next": { + "version": "10.0.9-canary.5", + "requires": { + "@babel/runtime": "7.12.5", + "@hapi/accept": "5.0.1", + "@next/env": "10.0.9-canary.5", + "@next/polyfill-module": "10.0.9-canary.5", + "@next/react-dev-overlay": "10.0.9-canary.5", + "@next/react-refresh-utils": "10.0.9-canary.5", + "@opentelemetry/api": "0.14.0", + "ast-types": "0.13.2", + "browserslist": "4.16.1", + "buffer": "5.6.0", + "caniuse-lite": "^1.0.30001179", + "chalk": "2.4.2", + "chokidar": "3.5.1", + "crypto-browserify": "3.12.0", + "cssnano-simple": "1.2.2", + "etag": "1.8.1", + "find-cache-dir": "3.3.1", + "get-orientation": "1.1.2", + "jest-worker": "24.9.0", + "native-url": "0.3.4", + "node-fetch": "2.6.1", + "node-html-parser": "1.4.9", + "node-libs-browser": "^2.2.1", + "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", + "stream-browserify": "3.0.0", + "styled-jsx": "3.3.2", + "use-subscription": "1.5.1", + "vm-browserify": "1.1.2", + "watchpack": "2.1.1" + }, + "dependencies": { + "@babel/runtime": { + "version": "7.12.5", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.12.5.tgz", + "integrity": "sha512-plcc+hbExy3McchJCEQG3knOsuh3HH+Prx1P6cLIkET/0dLuQDEnrT+s27Axgc9bqfsmNUNHfscgMUdBpC9xfg==", + "requires": { + "regenerator-runtime": "^0.13.4" + } + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "requires": { + "color-convert": "^1.9.0" + } + }, + "browserslist": { + "version": "4.16.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.1.tgz", + "integrity": "sha512-UXhDrwqsNcpTYJBTZsbGATDxZbiVDsx6UjpmRUmtnP10pr8wAYr5LgFoEFw9ixriQH2mv/NX2SfGzE/o8GndLA==", + "requires": { + "caniuse-lite": "^1.0.30001173", + "colorette": "^1.2.1", + "electron-to-chromium": "^1.3.634", + "escalade": "^3.1.1", + "node-releases": "^1.1.69" + } + }, + "buffer": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.6.0.tgz", + "integrity": "sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw==", + "requires": { + "base64-js": "^1.0.2", + "ieee754": "^1.1.4" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "postcss": { + "version": "8.1.7", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.1.7.tgz", + "integrity": "sha512-llCQW1Pz4MOPwbZLmOddGM9eIJ8Bh7SZ2Oj5sxZva77uVaotYDsYTch1WBTNu7fUY0fpWp0fdt7uW40D4sRiiQ==", + "requires": { + "colorette": "^1.2.1", + "line-column": "^1.0.2", + "nanoid": "^3.1.16", + "source-map": "^0.6.1" + }, + "dependencies": { + "line-column": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/line-column/-/line-column-1.0.2.tgz", + "integrity": "sha1-0lryk2tvSEkXKzEuR5LR2Ye8NKI=", + "requires": { + "isarray": "^1.0.0", + "isobject": "^2.0.0" + } + }, + "nanoid": { + "version": "3.1.20", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.20.tgz", + "integrity": "sha512-a1cQNyczgKbLX9jwbS/+d7W8fX/RfgYR7lVWwWOGIPNgK2m0MWvrGF6/m4kk6U3QcFMnZf3RIhL0v2Jgh/0Uxw==" + } + } + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "next-seo": { + "version": "4.24.0" + }, + "next-themes": { + "version": "0.0.14" + }, + "next-unused": { + "version": "0.0.6", + "dev": true, + "requires": { + "madge": "^4.0.1", + "ts-loader": "^7.0.0", + "typescript": "^4.2.3" + }, + "dependencies": { + "typescript": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.3.2.tgz", + "integrity": "sha512-zZ4hShnmnoVnAHpVHWpTcxdv7dWP60S2FsydQLV8V5PbS3FifjWFFRiHSWpDJahly88PRyV5teTSLoq4eG7mKw==", + "dev": true + } + } + }, + "no-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", + "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", + "dev": true, + "requires": { + "lower-case": "^2.0.2", + "tslib": "^2.0.3" + } + }, + "node-emoji": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-1.10.0.tgz", + "integrity": "sha512-Yt3384If5H6BYGVHiHwTL+99OzJKHhgp82S8/dktEK73T26BazdgZ4JZh92xSVtGNJvz9UbXdNAc5hcrXV42vw==", + "requires": { + "lodash.toarray": "^4.4.0" + } + }, + "node-fetch": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", + "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==" + }, + "node-html-parser": { + "version": "1.4.9", + "resolved": "https://registry.npmjs.org/node-html-parser/-/node-html-parser-1.4.9.tgz", + "integrity": "sha512-UVcirFD1Bn0O+TSmloHeHqZZCxHjvtIeGdVdGMhyZ8/PWlEiZaZ5iJzR189yKZr8p0FXN58BUeC7RHRkf/KYGw==", + "requires": { + "he": "1.2.0" + } + }, + "node-int64": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", + "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=", + "dev": true + }, + "node-libs-browser": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz", + "integrity": "sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q==", + "requires": { + "assert": "^1.1.1", + "browserify-zlib": "^0.2.0", + "buffer": "^4.3.0", + "console-browserify": "^1.1.0", + "constants-browserify": "^1.0.0", + "crypto-browserify": "^3.11.0", + "domain-browser": "^1.1.1", + "events": "^3.0.0", + "https-browserify": "^1.0.0", + "os-browserify": "^0.3.0", + "path-browserify": "0.0.1", + "process": "^0.11.10", + "punycode": "^1.2.4", + "querystring-es3": "^0.2.0", + "readable-stream": "^2.3.3", + "stream-browserify": "^2.0.1", + "stream-http": "^2.7.2", + "string_decoder": "^1.0.0", + "timers-browserify": "^2.0.4", + "tty-browserify": "0.0.0", + "url": "^0.11.0", + "util": "^0.11.0", + "vm-browserify": "^1.0.1" + }, + "dependencies": { + "buffer": { + "version": "4.9.2", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", + "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", + "requires": { + "base64-js": "^1.0.2", + "ieee754": "^1.1.4", + "isarray": "^1.0.0" + } + }, + "path-browserify": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz", + "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==" + }, + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" + }, + "stream-browserify": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz", + "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==", + "requires": { + "inherits": "~2.0.1", + "readable-stream": "^2.0.2" + } + } + } + }, + "node-releases": { + "version": "1.1.70", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.70.tgz", + "integrity": "sha512-Slf2s69+2/uAD79pVVQo8uSiC34+g8GWY8UH2Qtqv34ZfhYrxpYpfzs9Js9d6O0mbDmALuxaTlplnBTnSELcrw==" + }, + "node-source-walk": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/node-source-walk/-/node-source-walk-4.2.0.tgz", + "integrity": "sha512-hPs/QMe6zS94f5+jG3kk9E7TNm4P2SulrKiLWMzKszBfNZvL/V6wseHlTd7IvfW0NZWqPtK3+9yYNr+3USGteA==", + "dev": true, + "requires": { + "@babel/parser": "^7.0.0" + } + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" + }, + "normalize-range": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", + "integrity": "sha1-LRDAa9/TEuqXd2laTShDlFa3WUI=" + }, + "normalize-url": { + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.1.tgz", + "integrity": "sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA==", + "dev": true + }, + "npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "requires": { + "path-key": "^3.0.0" + } + }, + "nullthrows": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/nullthrows/-/nullthrows-1.1.1.tgz", + "integrity": "sha512-2vPPEi+Z7WqML2jZYddDIfy5Dqb0r2fze2zTxNNknZaFpVHU3mFB3R+DWeJWGVx0ecvttSGlJTI+WG+8Z4cDWw==", + "dev": true + }, + "number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", + "dev": true + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + }, + "object-hash": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-2.1.1.tgz", + "integrity": "sha512-VOJmgmS+7wvXf8CjbQmimtCnEx3IAoLxI3fp2fbWehxrWBcAQFbk+vcwb6vzR0VZv/eNCJ/27j151ZTwqW/JeQ==" + }, + "object-inspect": { + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.10.3.tgz", + "integrity": "sha512-e5mCJlSH7poANfC8z8S9s9S2IN5/4Zb3aZ33f5s8YqoazCFzNLloLU8r5VCG+G7WoqLvAAZoVMcy3tp/3X0Plw==", + "dev": true + }, + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true + }, + "object-keys-normalizer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object-keys-normalizer/-/object-keys-normalizer-1.0.1.tgz", + "integrity": "sha1-2xeNu6Xkx7GLQIN8jvgzZe6TSOc=", + "requires": { + "lodash.camelcase": "^4.3.0", + "lodash.snakecase": "^4.1.1" + } + }, + "object-merge-advanced": { + "version": "12.0.3", + "resolved": "https://registry.npmjs.org/object-merge-advanced/-/object-merge-advanced-12.0.3.tgz", + "integrity": "sha512-xQIf2Vup1rpKiHr2tQca5jyNYgT4O0kNxOfAp3ZNonm2hS+5yaJgI0Czdk/QMy52bcRwQKX3uc3H8XtAiiYfVA==", + "requires": { + "@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.assign": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", + "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "has-symbols": "^1.0.1", + "object-keys": "^1.1.1" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "requires": { + "wrappy": "1" + } + }, + "onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "requires": { + "mimic-fn": "^2.1.0" + } + }, + "opener": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz", + "integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==", + "dev": true + }, + "optionator": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "dev": true, + "requires": { + "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": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz", + "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==", + "dev": true, + "requires": { + "bl": "^4.1.0", + "chalk": "^4.1.0", + "cli-cursor": "^3.1.0", + "cli-spinners": "^2.5.0", + "is-interactive": "^1.0.0", + "is-unicode-supported": "^0.1.0", + "log-symbols": "^4.1.0", + "strip-ansi": "^6.0.0", + "wcwidth": "^1.0.1" + }, + "dependencies": { + "log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dev": true, + "requires": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + } + } + } + }, + "os-browserify": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", + "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=" + }, + "os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", + "dev": true + }, + "p-cancelable": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz", + "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==", + "dev": true + }, + "p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "requires": { + "yocto-queue": "^0.1.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "requires": { + "p-limit": "^2.2.0" + }, + "dependencies": { + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "requires": { + "p-try": "^2.0.0" + } + } + } + }, + "p-map": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", + "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", + "dev": true + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" + }, + "package-json": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/package-json/-/package-json-6.5.0.tgz", + "integrity": "sha512-k3bdm2n25tkyxcjSKzB5x8kfVxlMdgsbPr0GkZcwHsLpba6cBjqCt1KlcChKEvxHIcTB1FVMuwoijZ26xex5MQ==", + "dev": true, + "requires": { + "got": "^9.6.0", + "registry-auth-token": "^4.0.0", + "registry-url": "^5.0.0", + "semver": "^6.2.0" + } + }, + "pako": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", + "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==" + }, + "param-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz", + "integrity": "sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==", + "dev": true, + "requires": { + "dot-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "requires": { + "callsites": "^3.0.0" + } + }, + "parse-asn1": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.6.tgz", + "integrity": "sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw==", + "requires": { + "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": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.2.tgz", + "integrity": "sha1-pjISf1Oq89FYdvWHLz/6x2PWyJE=", + "dev": true, + "requires": { + "is-absolute": "^1.0.0", + "map-cache": "^0.2.0", + "path-root": "^0.1.1" + } + }, + "parse-glob": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", + "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", + "requires": { + "glob-base": "^0.3.0", + "is-dotfile": "^1.0.0", + "is-extglob": "^1.0.0", + "is-glob": "^2.0.0" + }, + "dependencies": { + "is-glob": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", + "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", + "requires": { + "is-extglob": "^1.0.0" + } + } + } + }, + "parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "requires": { + "@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": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-2.1.0.tgz", + "integrity": "sha512-kHt7kzLoS9VBZfUsiKjv43mr91ea+U05EyKkEtqp7vNbHxmaVuEqN7XxeEVnGrMtYOAxGrDElSi96K7EgO1zCA==", + "dev": true + }, + "pascal-case": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz", + "integrity": "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==", + "dev": true, + "requires": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "path-browserify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", + "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==" + }, + "path-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/path-case/-/path-case-3.0.4.tgz", + "integrity": "sha512-qO4qCFjXqVTrcbPt/hQfhTQ+VhFsqNKOPtytgNKkKxSoEp3XPUQ8ObFuePylOIok5gjn69ry8XiULxCwot3Wfg==", + "dev": true, + "requires": { + "dot-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==" + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true + }, + "path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" + }, + "path-root": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/path-root/-/path-root-0.1.1.tgz", + "integrity": "sha1-mkpoFMrBwM1zNgqV8yCDyOpHRbc=", + "dev": true, + "requires": { + "path-root-regex": "^0.1.0" + } + }, + "path-root-regex": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/path-root-regex/-/path-root-regex-0.1.2.tgz", + "integrity": "sha1-v8zcjfWxLcUsi0PsONGNcsBLqW0=", + "dev": true + }, + "path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true + }, + "pbkdf2": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", + "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", + "requires": { + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "picomatch": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", + "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==" + }, + "pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "requires": { + "find-up": "^4.0.0" + } + }, + "platform": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/platform/-/platform-1.3.6.tgz", + "integrity": "sha512-fnWVljUchTro6RiCFvCXBbNhJc2NijN7oIQxbwsyL0buWJPG85v81ehlHI9fXrJsMNgTofEoWIQeClKpgxFLrg==" + }, + "please-upgrade-node": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz", + "integrity": "sha512-gQR3WpIgNIKwBMVLkpMUeR3e1/E1y42bqDQZfql+kDeXd8COYfM8PQA4X6y7a8u9Ua9FHmsrrmirW2vHs45hWg==", + "dev": true, + "requires": { + "semver-compare": "^1.0.0" + } + }, + "pluralize": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-8.0.0.tgz", + "integrity": "sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==", + "dev": true + }, + "pnp-webpack-plugin": { + "version": "1.6.4", + "resolved": "https://registry.npmjs.org/pnp-webpack-plugin/-/pnp-webpack-plugin-1.6.4.tgz", + "integrity": "sha512-7Wjy+9E3WwLOEL30D+m8TSTF7qJJUJLONBnwQp0518siuMxUQUbgZwssaFX+QKlZkjHZcw/IpZCt/H0srrntSg==", + "requires": { + "ts-pnp": "^1.1.6" + } + }, + "postcss-attribute-case-insensitive": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-attribute-case-insensitive/-/postcss-attribute-case-insensitive-4.0.2.tgz", + "integrity": "sha512-clkFxk/9pcdb4Vkn0hAHq3YnxBQ2p0CGD1dy24jN+reBck+EWxMbxSUqN4Yj7t0w8csl87K6p0gxBe1utkJsYA==", + "dev": true, + "requires": { + "postcss": "^7.0.2", + "postcss-selector-parser": "^6.0.2" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "dependencies": { + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "dev": true + }, + "postcss": { + "version": "7.0.36", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.36.tgz", + "integrity": "sha512-BebJSIUMwJHRH0HAQoxN4u1CN86glsrwsW0q7T+/m44eXOUAxSNdHRkNZPYz5vVUbg17hFgOQDE7fZk7li3pZw==", + "dev": true, + "requires": { + "chalk": "^2.4.2", + "source-map": "^0.6.1", + "supports-color": "^6.1.0" + } + }, + "postcss-selector-parser": { + "version": "6.0.6", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.6.tgz", + "integrity": "sha512-9LXrvaaX3+mcv5xkg5kFwqSzSH1JIObIx51PrndZwlmznwXRfxMddDvo9gve3gVR8ZTKgoFDdWkbRFmEhT4PMg==", + "dev": true, + "requires": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + } + }, + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "postcss-color-functional-notation": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/postcss-color-functional-notation/-/postcss-color-functional-notation-2.0.1.tgz", + "integrity": "sha512-ZBARCypjEDofW4P6IdPVTLhDNXPRn8T2s1zHbZidW6rPaaZvcnCS2soYFIQJrMZSxiePJ2XIYTlcb2ztr/eT2g==", + "dev": true, + "requires": { + "postcss": "^7.0.2", + "postcss-values-parser": "^2.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "dependencies": { + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "postcss": { + "version": "7.0.36", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.36.tgz", + "integrity": "sha512-BebJSIUMwJHRH0HAQoxN4u1CN86glsrwsW0q7T+/m44eXOUAxSNdHRkNZPYz5vVUbg17hFgOQDE7fZk7li3pZw==", + "dev": true, + "requires": { + "chalk": "^2.4.2", + "source-map": "^0.6.1", + "supports-color": "^6.1.0" + } + }, + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "postcss-color-gray": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/postcss-color-gray/-/postcss-color-gray-5.0.0.tgz", + "integrity": "sha512-q6BuRnAGKM/ZRpfDascZlIZPjvwsRye7UDNalqVz3s7GDxMtqPY6+Q871liNxsonUw8oC61OG+PSaysYpl1bnw==", + "dev": true, + "requires": { + "@csstools/convert-colors": "^1.4.0", + "postcss": "^7.0.5", + "postcss-values-parser": "^2.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "dependencies": { + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "postcss": { + "version": "7.0.36", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.36.tgz", + "integrity": "sha512-BebJSIUMwJHRH0HAQoxN4u1CN86glsrwsW0q7T+/m44eXOUAxSNdHRkNZPYz5vVUbg17hFgOQDE7fZk7li3pZw==", + "dev": true, + "requires": { + "chalk": "^2.4.2", + "source-map": "^0.6.1", + "supports-color": "^6.1.0" + } + }, + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "postcss-color-hex-alpha": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/postcss-color-hex-alpha/-/postcss-color-hex-alpha-5.0.3.tgz", + "integrity": "sha512-PF4GDel8q3kkreVXKLAGNpHKilXsZ6xuu+mOQMHWHLPNyjiUBOr75sp5ZKJfmv1MCus5/DWUGcK9hm6qHEnXYw==", + "dev": true, + "requires": { + "postcss": "^7.0.14", + "postcss-values-parser": "^2.0.1" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "dependencies": { + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "postcss": { + "version": "7.0.36", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.36.tgz", + "integrity": "sha512-BebJSIUMwJHRH0HAQoxN4u1CN86glsrwsW0q7T+/m44eXOUAxSNdHRkNZPYz5vVUbg17hFgOQDE7fZk7li3pZw==", + "dev": true, + "requires": { + "chalk": "^2.4.2", + "source-map": "^0.6.1", + "supports-color": "^6.1.0" + } + }, + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "postcss-color-mod-function": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/postcss-color-mod-function/-/postcss-color-mod-function-3.0.3.tgz", + "integrity": "sha512-YP4VG+xufxaVtzV6ZmhEtc+/aTXH3d0JLpnYfxqTvwZPbJhWqp8bSY3nfNzNRFLgB4XSaBA82OE4VjOOKpCdVQ==", + "dev": true, + "requires": { + "@csstools/convert-colors": "^1.4.0", + "postcss": "^7.0.2", + "postcss-values-parser": "^2.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "dependencies": { + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "postcss": { + "version": "7.0.36", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.36.tgz", + "integrity": "sha512-BebJSIUMwJHRH0HAQoxN4u1CN86glsrwsW0q7T+/m44eXOUAxSNdHRkNZPYz5vVUbg17hFgOQDE7fZk7li3pZw==", + "dev": true, + "requires": { + "chalk": "^2.4.2", + "source-map": "^0.6.1", + "supports-color": "^6.1.0" + } + }, + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "postcss-color-rebeccapurple": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-color-rebeccapurple/-/postcss-color-rebeccapurple-4.0.1.tgz", + "integrity": "sha512-aAe3OhkS6qJXBbqzvZth2Au4V3KieR5sRQ4ptb2b2O8wgvB3SJBsdG+jsn2BZbbwekDG8nTfcCNKcSfe/lEy8g==", + "dev": true, + "requires": { + "postcss": "^7.0.2", + "postcss-values-parser": "^2.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "dependencies": { + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "postcss": { + "version": "7.0.36", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.36.tgz", + "integrity": "sha512-BebJSIUMwJHRH0HAQoxN4u1CN86glsrwsW0q7T+/m44eXOUAxSNdHRkNZPYz5vVUbg17hFgOQDE7fZk7li3pZw==", + "dev": true, + "requires": { + "chalk": "^2.4.2", + "source-map": "^0.6.1", + "supports-color": "^6.1.0" + } + }, + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "postcss-custom-media": { + "version": "7.0.8", + "resolved": "https://registry.npmjs.org/postcss-custom-media/-/postcss-custom-media-7.0.8.tgz", + "integrity": "sha512-c9s5iX0Ge15o00HKbuRuTqNndsJUbaXdiNsksnVH8H4gdc+zbLzr/UasOwNG6CTDpLFekVY4672eWdiiWu2GUg==", + "dev": true, + "requires": { + "postcss": "^7.0.14" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "dependencies": { + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "postcss": { + "version": "7.0.36", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.36.tgz", + "integrity": "sha512-BebJSIUMwJHRH0HAQoxN4u1CN86glsrwsW0q7T+/m44eXOUAxSNdHRkNZPYz5vVUbg17hFgOQDE7fZk7li3pZw==", + "dev": true, + "requires": { + "chalk": "^2.4.2", + "source-map": "^0.6.1", + "supports-color": "^6.1.0" + } + }, + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "postcss-custom-properties": { + "version": "8.0.11", + "resolved": "https://registry.npmjs.org/postcss-custom-properties/-/postcss-custom-properties-8.0.11.tgz", + "integrity": "sha512-nm+o0eLdYqdnJ5abAJeXp4CEU1c1k+eB2yMCvhgzsds/e0umabFrN6HoTy/8Q4K5ilxERdl/JD1LO5ANoYBeMA==", + "dev": true, + "requires": { + "postcss": "^7.0.17", + "postcss-values-parser": "^2.0.1" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "dependencies": { + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "postcss": { + "version": "7.0.36", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.36.tgz", + "integrity": "sha512-BebJSIUMwJHRH0HAQoxN4u1CN86glsrwsW0q7T+/m44eXOUAxSNdHRkNZPYz5vVUbg17hFgOQDE7fZk7li3pZw==", + "dev": true, + "requires": { + "chalk": "^2.4.2", + "source-map": "^0.6.1", + "supports-color": "^6.1.0" + } + }, + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "postcss-custom-selectors": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/postcss-custom-selectors/-/postcss-custom-selectors-5.1.2.tgz", + "integrity": "sha512-DSGDhqinCqXqlS4R7KGxL1OSycd1lydugJ1ky4iRXPHdBRiozyMHrdu0H3o7qNOCiZwySZTUI5MV0T8QhCLu+w==", + "dev": true, + "requires": { + "postcss": "^7.0.2", + "postcss-selector-parser": "^5.0.0-rc.3" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "dependencies": { + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "postcss": { + "version": "7.0.36", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.36.tgz", + "integrity": "sha512-BebJSIUMwJHRH0HAQoxN4u1CN86glsrwsW0q7T+/m44eXOUAxSNdHRkNZPYz5vVUbg17hFgOQDE7fZk7li3pZw==", + "dev": true, + "requires": { + "chalk": "^2.4.2", + "source-map": "^0.6.1", + "supports-color": "^6.1.0" + } + }, + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "postcss-dir-pseudo-class": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/postcss-dir-pseudo-class/-/postcss-dir-pseudo-class-5.0.0.tgz", + "integrity": "sha512-3pm4oq8HYWMZePJY+5ANriPs3P07q+LW6FAdTlkFH2XqDdP4HeeJYMOzn0HYLhRSjBO3fhiqSwwU9xEULSrPgw==", + "dev": true, + "requires": { + "postcss": "^7.0.2", + "postcss-selector-parser": "^5.0.0-rc.3" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "dependencies": { + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "postcss": { + "version": "7.0.36", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.36.tgz", + "integrity": "sha512-BebJSIUMwJHRH0HAQoxN4u1CN86glsrwsW0q7T+/m44eXOUAxSNdHRkNZPYz5vVUbg17hFgOQDE7fZk7li3pZw==", + "dev": true, + "requires": { + "chalk": "^2.4.2", + "source-map": "^0.6.1", + "supports-color": "^6.1.0" + } + }, + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "postcss-double-position-gradients": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/postcss-double-position-gradients/-/postcss-double-position-gradients-1.0.0.tgz", + "integrity": "sha512-G+nV8EnQq25fOI8CH/B6krEohGWnF5+3A6H/+JEpOncu5dCnkS1QQ6+ct3Jkaepw1NGVqqOZH6lqrm244mCftA==", + "dev": true, + "requires": { + "postcss": "^7.0.5", + "postcss-values-parser": "^2.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "dependencies": { + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "postcss": { + "version": "7.0.36", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.36.tgz", + "integrity": "sha512-BebJSIUMwJHRH0HAQoxN4u1CN86glsrwsW0q7T+/m44eXOUAxSNdHRkNZPYz5vVUbg17hFgOQDE7fZk7li3pZw==", + "dev": true, + "requires": { + "chalk": "^2.4.2", + "source-map": "^0.6.1", + "supports-color": "^6.1.0" + } + }, + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "postcss-env-function": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/postcss-env-function/-/postcss-env-function-2.0.2.tgz", + "integrity": "sha512-rwac4BuZlITeUbiBq60h/xbLzXY43qOsIErngWa4l7Mt+RaSkT7QBjXVGTcBHupykkblHMDrBFh30zchYPaOUw==", + "dev": true, + "requires": { + "postcss": "^7.0.2", + "postcss-values-parser": "^2.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "dependencies": { + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "postcss": { + "version": "7.0.36", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.36.tgz", + "integrity": "sha512-BebJSIUMwJHRH0HAQoxN4u1CN86glsrwsW0q7T+/m44eXOUAxSNdHRkNZPYz5vVUbg17hFgOQDE7fZk7li3pZw==", + "dev": true, + "requires": { + "chalk": "^2.4.2", + "source-map": "^0.6.1", + "supports-color": "^6.1.0" + } + }, + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "postcss-flexbugs-fixes": { + "version": "5.0.2", + "dev": true + }, + "postcss-focus-visible": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/postcss-focus-visible/-/postcss-focus-visible-4.0.0.tgz", + "integrity": "sha512-Z5CkWBw0+idJHSV6+Bgf2peDOFf/x4o+vX/pwcNYrWpXFrSfTkQ3JQ1ojrq9yS+upnAlNRHeg8uEwFTgorjI8g==", + "dev": true, + "requires": { + "postcss": "^7.0.2" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "dependencies": { + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "postcss": { + "version": "7.0.36", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.36.tgz", + "integrity": "sha512-BebJSIUMwJHRH0HAQoxN4u1CN86glsrwsW0q7T+/m44eXOUAxSNdHRkNZPYz5vVUbg17hFgOQDE7fZk7li3pZw==", + "dev": true, + "requires": { + "chalk": "^2.4.2", + "source-map": "^0.6.1", + "supports-color": "^6.1.0" + } + }, + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "postcss-focus-within": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postcss-focus-within/-/postcss-focus-within-3.0.0.tgz", + "integrity": "sha512-W0APui8jQeBKbCGZudW37EeMCjDeVxKgiYfIIEo8Bdh5SpB9sxds/Iq8SEuzS0Q4YFOlG7EPFulbbxujpkrV2w==", + "dev": true, + "requires": { + "postcss": "^7.0.2" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "dependencies": { + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "postcss": { + "version": "7.0.36", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.36.tgz", + "integrity": "sha512-BebJSIUMwJHRH0HAQoxN4u1CN86glsrwsW0q7T+/m44eXOUAxSNdHRkNZPYz5vVUbg17hFgOQDE7fZk7li3pZw==", + "dev": true, + "requires": { + "chalk": "^2.4.2", + "source-map": "^0.6.1", + "supports-color": "^6.1.0" + } + }, + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "postcss-font-variant": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-font-variant/-/postcss-font-variant-4.0.1.tgz", + "integrity": "sha512-I3ADQSTNtLTTd8uxZhtSOrTCQ9G4qUVKPjHiDk0bV75QSxXjVWiJVJ2VLdspGUi9fbW9BcjKJoRvxAH1pckqmA==", + "dev": true, + "requires": { + "postcss": "^7.0.2" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "dependencies": { + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "postcss": { + "version": "7.0.36", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.36.tgz", + "integrity": "sha512-BebJSIUMwJHRH0HAQoxN4u1CN86glsrwsW0q7T+/m44eXOUAxSNdHRkNZPYz5vVUbg17hFgOQDE7fZk7li3pZw==", + "dev": true, + "requires": { + "chalk": "^2.4.2", + "source-map": "^0.6.1", + "supports-color": "^6.1.0" + } + }, + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "postcss-functions": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postcss-functions/-/postcss-functions-3.0.0.tgz", + "integrity": "sha1-DpTQFERwCkgd4g3k1V+yZAVkJQ4=", + "requires": { + "glob": "^7.1.2", + "object-assign": "^4.1.1", + "postcss": "^6.0.9", + "postcss-value-parser": "^3.3.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "postcss": { + "version": "6.0.23", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz", + "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", + "requires": { + "chalk": "^2.4.1", + "source-map": "^0.6.1", + "supports-color": "^5.4.0" + } + }, + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "postcss-gap-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postcss-gap-properties/-/postcss-gap-properties-2.0.0.tgz", + "integrity": "sha512-QZSqDaMgXCHuHTEzMsS2KfVDOq7ZFiknSpkrPJY6jmxbugUPTuSzs/vuE5I3zv0WAS+3vhrlqhijiprnuQfzmg==", + "dev": true, + "requires": { + "postcss": "^7.0.2" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "dependencies": { + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "postcss": { + "version": "7.0.36", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.36.tgz", + "integrity": "sha512-BebJSIUMwJHRH0HAQoxN4u1CN86glsrwsW0q7T+/m44eXOUAxSNdHRkNZPYz5vVUbg17hFgOQDE7fZk7li3pZw==", + "dev": true, + "requires": { + "chalk": "^2.4.2", + "source-map": "^0.6.1", + "supports-color": "^6.1.0" + } + }, + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "postcss-image-set-function": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/postcss-image-set-function/-/postcss-image-set-function-3.0.1.tgz", + "integrity": "sha512-oPTcFFip5LZy8Y/whto91L9xdRHCWEMs3e1MdJxhgt4jy2WYXfhkng59fH5qLXSCPN8k4n94p1Czrfe5IOkKUw==", + "dev": true, + "requires": { + "postcss": "^7.0.2", + "postcss-values-parser": "^2.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "dependencies": { + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "postcss": { + "version": "7.0.36", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.36.tgz", + "integrity": "sha512-BebJSIUMwJHRH0HAQoxN4u1CN86glsrwsW0q7T+/m44eXOUAxSNdHRkNZPYz5vVUbg17hFgOQDE7fZk7li3pZw==", + "dev": true, + "requires": { + "chalk": "^2.4.2", + "source-map": "^0.6.1", + "supports-color": "^6.1.0" + } + }, + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "postcss-initial": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/postcss-initial/-/postcss-initial-3.0.2.tgz", + "integrity": "sha512-ugA2wKonC0xeNHgirR4D3VWHs2JcU08WAi1KFLVcnb7IN89phID6Qtg2RIctWbnvp1TM2BOmDtX8GGLCKdR8YA==", + "dev": true, + "requires": { + "lodash.template": "^4.5.0", + "postcss": "^7.0.2" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "dependencies": { + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "postcss": { + "version": "7.0.36", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.36.tgz", + "integrity": "sha512-BebJSIUMwJHRH0HAQoxN4u1CN86glsrwsW0q7T+/m44eXOUAxSNdHRkNZPYz5vVUbg17hFgOQDE7fZk7li3pZw==", + "dev": true, + "requires": { + "chalk": "^2.4.2", + "source-map": "^0.6.1", + "supports-color": "^6.1.0" + } + }, + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "postcss-js": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-3.0.3.tgz", + "integrity": "sha512-gWnoWQXKFw65Hk/mi2+WTQTHdPD5UJdDXZmX073EY/B3BWnYjO4F4t0VneTCnCGQ5E5GsCdMkzPaTXwl3r5dJw==", + "requires": { + "camelcase-css": "^2.0.1", + "postcss": "^8.1.6" + }, + "dependencies": { + "colorette": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.2.tgz", + "integrity": "sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==" + }, + "postcss": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.3.2.tgz", + "integrity": "sha512-y1FK/AWdZlBF5lusS5j5l4/vF67+vQZt1SXPVJ32y1kRGDQyrs1zk32hG1cInRTu14P0V+orPz+ifwW/7rR4bg==", + "requires": { + "colorette": "^1.2.2", + "nanoid": "^3.1.23", + "source-map-js": "^0.6.2" + } + } + } + }, + "postcss-lab-function": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/postcss-lab-function/-/postcss-lab-function-2.0.1.tgz", + "integrity": "sha512-whLy1IeZKY+3fYdqQFuDBf8Auw+qFuVnChWjmxm/UhHWqNHZx+B99EwxTvGYmUBqe3Fjxs4L1BoZTJmPu6usVg==", + "dev": true, + "requires": { + "@csstools/convert-colors": "^1.4.0", + "postcss": "^7.0.2", + "postcss-values-parser": "^2.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "dependencies": { + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "postcss": { + "version": "7.0.36", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.36.tgz", + "integrity": "sha512-BebJSIUMwJHRH0HAQoxN4u1CN86glsrwsW0q7T+/m44eXOUAxSNdHRkNZPYz5vVUbg17hFgOQDE7fZk7li3pZw==", + "dev": true, + "requires": { + "chalk": "^2.4.2", + "source-map": "^0.6.1", + "supports-color": "^6.1.0" + } + }, + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "postcss-logical": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postcss-logical/-/postcss-logical-3.0.0.tgz", + "integrity": "sha512-1SUKdJc2vuMOmeItqGuNaC+N8MzBWFWEkAnRnLpFYj1tGGa7NqyVBujfRtgNa2gXR+6RkGUiB2O5Vmh7E2RmiA==", + "dev": true, + "requires": { + "postcss": "^7.0.2" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "dependencies": { + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "postcss": { + "version": "7.0.36", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.36.tgz", + "integrity": "sha512-BebJSIUMwJHRH0HAQoxN4u1CN86glsrwsW0q7T+/m44eXOUAxSNdHRkNZPYz5vVUbg17hFgOQDE7fZk7li3pZw==", + "dev": true, + "requires": { + "chalk": "^2.4.2", + "source-map": "^0.6.1", + "supports-color": "^6.1.0" + } + }, + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "postcss-media-minmax": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/postcss-media-minmax/-/postcss-media-minmax-4.0.0.tgz", + "integrity": "sha512-fo9moya6qyxsjbFAYl97qKO9gyre3qvbMnkOZeZwlsW6XYFsvs2DMGDlchVLfAd8LHPZDxivu/+qW2SMQeTHBw==", + "dev": true, + "requires": { + "postcss": "^7.0.2" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "dependencies": { + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "postcss": { + "version": "7.0.36", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.36.tgz", + "integrity": "sha512-BebJSIUMwJHRH0HAQoxN4u1CN86glsrwsW0q7T+/m44eXOUAxSNdHRkNZPYz5vVUbg17hFgOQDE7fZk7li3pZw==", + "dev": true, + "requires": { + "chalk": "^2.4.2", + "source-map": "^0.6.1", + "supports-color": "^6.1.0" + } + }, + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "postcss-nested": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-5.0.5.tgz", + "integrity": "sha512-GSRXYz5bccobpTzLQZXOnSOfKl6TwVr5CyAQJUPub4nuRJSOECK5AqurxVgmtxP48p0Kc/ndY/YyS1yqldX0Ew==", + "requires": { + "postcss-selector-parser": "^6.0.4" + }, + "dependencies": { + "cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==" + }, + "postcss-selector-parser": { + "version": "6.0.6", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.6.tgz", + "integrity": "sha512-9LXrvaaX3+mcv5xkg5kFwqSzSH1JIObIx51PrndZwlmznwXRfxMddDvo9gve3gVR8ZTKgoFDdWkbRFmEhT4PMg==", + "requires": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + } + } + } + }, + "postcss-nesting": { + "version": "8.0.1" + }, + "postcss-overflow-shorthand": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postcss-overflow-shorthand/-/postcss-overflow-shorthand-2.0.0.tgz", + "integrity": "sha512-aK0fHc9CBNx8jbzMYhshZcEv8LtYnBIRYQD5i7w/K/wS9c2+0NSR6B3OVMu5y0hBHYLcMGjfU+dmWYNKH0I85g==", + "dev": true, + "requires": { + "postcss": "^7.0.2" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "dependencies": { + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "postcss": { + "version": "7.0.36", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.36.tgz", + "integrity": "sha512-BebJSIUMwJHRH0HAQoxN4u1CN86glsrwsW0q7T+/m44eXOUAxSNdHRkNZPYz5vVUbg17hFgOQDE7fZk7li3pZw==", + "dev": true, + "requires": { + "chalk": "^2.4.2", + "source-map": "^0.6.1", + "supports-color": "^6.1.0" + } + }, + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "postcss-page-break": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postcss-page-break/-/postcss-page-break-2.0.0.tgz", + "integrity": "sha512-tkpTSrLpfLfD9HvgOlJuigLuk39wVTbbd8RKcy8/ugV2bNBUW3xU+AIqyxhDrQr1VUj1RmyJrBn1YWrqUm9zAQ==", + "dev": true, + "requires": { + "postcss": "^7.0.2" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "dependencies": { + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "postcss": { + "version": "7.0.36", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.36.tgz", + "integrity": "sha512-BebJSIUMwJHRH0HAQoxN4u1CN86glsrwsW0q7T+/m44eXOUAxSNdHRkNZPYz5vVUbg17hFgOQDE7fZk7li3pZw==", + "dev": true, + "requires": { + "chalk": "^2.4.2", + "source-map": "^0.6.1", + "supports-color": "^6.1.0" + } + }, + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "postcss-place": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-place/-/postcss-place-4.0.1.tgz", + "integrity": "sha512-Zb6byCSLkgRKLODj/5mQugyuj9bvAAw9LqJJjgwz5cYryGeXfFZfSXoP1UfveccFmeq0b/2xxwcTEVScnqGxBg==", + "dev": true, + "requires": { + "postcss": "^7.0.2", + "postcss-values-parser": "^2.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "dependencies": { + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "postcss": { + "version": "7.0.36", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.36.tgz", + "integrity": "sha512-BebJSIUMwJHRH0HAQoxN4u1CN86glsrwsW0q7T+/m44eXOUAxSNdHRkNZPYz5vVUbg17hFgOQDE7fZk7li3pZw==", + "dev": true, + "requires": { + "chalk": "^2.4.2", + "source-map": "^0.6.1", + "supports-color": "^6.1.0" + } + }, + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "postcss-preset-env": { + "version": "6.7.0", + "dev": true, + "requires": { + "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" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "autoprefixer": { + "version": "9.8.6", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.8.6.tgz", + "integrity": "sha512-XrvP4VVHdRBCdX1S3WXVD8+RyG9qeb1D5Sn1DeLiG2xfSpzellk5k54xbUERJ3M5DggQxes39UGOTP8CFrEGbg==", + "dev": true, + "requires": { + "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" + }, + "dependencies": { + "num2fraction": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/num2fraction/-/num2fraction-1.2.2.tgz", + "integrity": "sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4=", + "dev": true + } + } + }, + "browserslist": { + "version": "4.16.3", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.3.tgz", + "integrity": "sha512-vIyhWmIkULaq04Gt93txdh+j02yX/JzlyhLYbV3YQCn/zvES3JnY7TifHHvvr1w5hTDluNKMkV05cs4vy8Q7sw==", + "dev": true, + "requires": { + "caniuse-lite": "^1.0.30001181", + "colorette": "^1.2.1", + "electron-to-chromium": "^1.3.649", + "escalade": "^3.1.1", + "node-releases": "^1.1.70" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "dependencies": { + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "postcss": { + "version": "7.0.35", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.35.tgz", + "integrity": "sha512-3QT8bBJeX/S5zKTTjTCIjRF3If4avAT6kqxcASlTWEtAFCb9NH0OUxNDfgZSWdP5fJnBYCMEWkIFfWeugjzYMg==", + "dev": true, + "requires": { + "chalk": "^2.4.2", + "source-map": "^0.6.1", + "supports-color": "^6.1.0" + } + }, + "postcss-nesting": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/postcss-nesting/-/postcss-nesting-7.0.1.tgz", + "integrity": "sha512-FrorPb0H3nuVq0Sff7W2rnc3SmIcruVC6YwpcS+k687VxyxO33iE1amna7wHuRVzM8vfiYofXSBHNAZ3QhLvYg==", + "dev": true, + "requires": { + "postcss": "^7.0.2" + } + }, + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "postcss-pseudo-class-any-link": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/postcss-pseudo-class-any-link/-/postcss-pseudo-class-any-link-6.0.0.tgz", + "integrity": "sha512-lgXW9sYJdLqtmw23otOzrtbDXofUdfYzNm4PIpNE322/swES3VU9XlXHeJS46zT2onFO7V1QFdD4Q9LiZj8mew==", + "dev": true, + "requires": { + "postcss": "^7.0.2", + "postcss-selector-parser": "^5.0.0-rc.3" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "dependencies": { + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "postcss": { + "version": "7.0.36", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.36.tgz", + "integrity": "sha512-BebJSIUMwJHRH0HAQoxN4u1CN86glsrwsW0q7T+/m44eXOUAxSNdHRkNZPYz5vVUbg17hFgOQDE7fZk7li3pZw==", + "dev": true, + "requires": { + "chalk": "^2.4.2", + "source-map": "^0.6.1", + "supports-color": "^6.1.0" + } + }, + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "postcss-replace-overflow-wrap": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postcss-replace-overflow-wrap/-/postcss-replace-overflow-wrap-3.0.0.tgz", + "integrity": "sha512-2T5hcEHArDT6X9+9dVSPQdo7QHzG4XKclFT8rU5TzJPDN7RIRTbO9c4drUISOVemLj03aezStHCR2AIcr8XLpw==", + "dev": true, + "requires": { + "postcss": "^7.0.2" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "dependencies": { + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "postcss": { + "version": "7.0.36", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.36.tgz", + "integrity": "sha512-BebJSIUMwJHRH0HAQoxN4u1CN86glsrwsW0q7T+/m44eXOUAxSNdHRkNZPYz5vVUbg17hFgOQDE7fZk7li3pZw==", + "dev": true, + "requires": { + "chalk": "^2.4.2", + "source-map": "^0.6.1", + "supports-color": "^6.1.0" + } + }, + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "postcss-selector-matches": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/postcss-selector-matches/-/postcss-selector-matches-4.0.0.tgz", + "integrity": "sha512-LgsHwQR/EsRYSqlwdGzeaPKVT0Ml7LAT6E75T8W8xLJY62CE4S/l03BWIt3jT8Taq22kXP08s2SfTSzaraoPww==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "postcss": "^7.0.2" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "dependencies": { + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "postcss": { + "version": "7.0.36", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.36.tgz", + "integrity": "sha512-BebJSIUMwJHRH0HAQoxN4u1CN86glsrwsW0q7T+/m44eXOUAxSNdHRkNZPYz5vVUbg17hFgOQDE7fZk7li3pZw==", + "dev": true, + "requires": { + "chalk": "^2.4.2", + "source-map": "^0.6.1", + "supports-color": "^6.1.0" + } + }, + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "postcss-selector-not": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-selector-not/-/postcss-selector-not-4.0.1.tgz", + "integrity": "sha512-YolvBgInEK5/79C+bdFMyzqTg6pkYqDbzZIST/PDMqa/o3qtXenD05apBG2jLgT0/BQ77d4U2UK12jWpilqMAQ==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "postcss": "^7.0.2" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "dependencies": { + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "postcss": { + "version": "7.0.36", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.36.tgz", + "integrity": "sha512-BebJSIUMwJHRH0HAQoxN4u1CN86glsrwsW0q7T+/m44eXOUAxSNdHRkNZPYz5vVUbg17hFgOQDE7fZk7li3pZw==", + "dev": true, + "requires": { + "chalk": "^2.4.2", + "source-map": "^0.6.1", + "supports-color": "^6.1.0" + } + }, + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "postcss-selector-parser": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-5.0.0.tgz", + "integrity": "sha512-w+zLE5Jhg6Liz8+rQOWEAwtwkyqpfnmsinXjXg6cY7YIONZZtgvE0v2O0uhQBs0peNomOJwWRKt6JBfTdTd3OQ==", + "dev": true, + "requires": { + "cssesc": "^2.0.0", + "indexes-of": "^1.0.1", + "uniq": "^1.0.1" + } + }, + "postcss-value-parser": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz", + "integrity": "sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ==" + }, + "postcss-values-parser": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/postcss-values-parser/-/postcss-values-parser-2.0.1.tgz", + "integrity": "sha512-2tLuBsA6P4rYTNKCXYG/71C7j1pU6pK503suYOmn4xYrQIzW+opD+7FAFNuGSdZC/3Qfy334QbeMu7MEb8gOxg==", + "dev": true, + "requires": { + "flatten": "^1.0.2", + "indexes-of": "^1.0.1", + "uniq": "^1.0.1" + } + }, + "precinct": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/precinct/-/precinct-7.1.0.tgz", + "integrity": "sha512-I1RkW5PX51/q6Xl39//D7x9NgaKNGHpR5DCNaoxP/b2+KbzzXDNhauJUMV17KSYkJA41CSpwYUPRtRoNxbshWA==", + "dev": true, + "requires": { + "commander": "^2.20.3", + "debug": "^4.3.1", + "detective-amd": "^3.0.1", + "detective-cjs": "^3.1.1", + "detective-es6": "^2.2.0", + "detective-less": "^1.0.2", + "detective-postcss": "^4.0.0", + "detective-sass": "^3.0.1", + "detective-scss": "^2.0.1", + "detective-stylus": "^1.0.0", + "detective-typescript": "^6.0.0", + "module-definition": "^3.3.1", + "node-source-walk": "^4.2.0" + }, + "dependencies": { + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + }, + "detective-typescript": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/detective-typescript/-/detective-typescript-6.0.0.tgz", + "integrity": "sha512-vTidcSDK3QostdbrH2Rwf9FhvrgJ4oIaVw5jbolgruTejexk6nNa9DShGpuS8CFVDb1IP86jct5BaZt1wSxpkA==", + "dev": true, + "requires": { + "@typescript-eslint/typescript-estree": "^4.8.2", + "ast-module-types": "^2.7.1", + "node-source-walk": "^4.2.0", + "typescript": "^3.9.7" + } + }, + "typescript": { + "version": "3.9.9", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.9.tgz", + "integrity": "sha512-kdMjTiekY+z/ubJCATUPlRDl39vXYiMV9iyeMuEuXZh2we6zz80uovNN2WlAxmmdE/Z/YQe+EbOEXB5RHEED3w==", + "dev": true + } + } + }, + "prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "dev": true + }, + "prepend-http": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", + "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=", + "dev": true + }, + "prettier": { + "version": "2.3.1", + "dev": true + }, + "pretty-hrtime": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz", + "integrity": "sha1-t+PqQkNaTJsnWdmeDyAesZWALuE=" + }, + "pretty-ms": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-7.0.1.tgz", + "integrity": "sha512-973driJZvxiGOQ5ONsFhOF/DtzPMOMtgC11kCpUrPGMTgqp2q/1gwzCquocrN33is0VZ5GFHXZYMM9l6h67v2Q==", + "dev": true, + "requires": { + "parse-ms": "^2.1.0" + } + }, + "process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=" + }, + "process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + }, + "promise": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", + "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==", + "dev": true, + "requires": { + "asap": "~2.0.3" + } + }, + "prop-types": { + "version": "15.7.2", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz", + "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==", + "requires": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.8.1" + } + }, + "prr": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", + "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", + "dev": true + }, + "public-encrypt": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", + "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", + "requires": { + "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" + }, + "dependencies": { + "bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" + } + } + }, + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" + }, + "purgecss": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/purgecss/-/purgecss-3.1.3.tgz", + "integrity": "sha512-hRSLN9mguJ2lzlIQtW4qmPS2kh6oMnA9RxdIYK8sz18QYqd6ePp4GNDl18oWHA1f2v2NEQIh51CO8s/E3YGckQ==", + "requires": { + "commander": "^6.0.0", + "glob": "^7.0.0", + "postcss": "^8.2.1", + "postcss-selector-parser": "^6.0.2" + }, + "dependencies": { + "colorette": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.2.tgz", + "integrity": "sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==" + }, + "cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==" + }, + "postcss": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.3.2.tgz", + "integrity": "sha512-y1FK/AWdZlBF5lusS5j5l4/vF67+vQZt1SXPVJ32y1kRGDQyrs1zk32hG1cInRTu14P0V+orPz+ifwW/7rR4bg==", + "requires": { + "colorette": "^1.2.2", + "nanoid": "^3.1.23", + "source-map-js": "^0.6.2" + } + }, + "postcss-selector-parser": { + "version": "6.0.6", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.6.tgz", + "integrity": "sha512-9LXrvaaX3+mcv5xkg5kFwqSzSH1JIObIx51PrndZwlmznwXRfxMddDvo9gve3gVR8ZTKgoFDdWkbRFmEhT4PMg==", + "requires": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + } + } + } + }, + "qs": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", + "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==" + }, + "querystring": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.1.tgz", + "integrity": "sha512-wkvS7mL/JMugcup3/rMitHmd9ecIGd2lhFhK9N3UUQ450h66d1r3Y9nvXzQAW1Lq+wyx61k/1pfKS5KuKiyEbg==" + }, + "querystring-es3": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", + "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=" + }, + "queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==" + }, + "quick-lru": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", + "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==" + }, + "randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "requires": { + "safe-buffer": "^5.1.0" + } + }, + "randomfill": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", + "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", + "requires": { + "randombytes": "^2.0.5", + "safe-buffer": "^5.1.0" + } + }, + "raw-body": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.1.tgz", + "integrity": "sha512-9WmIKF6mkvA0SLmA2Knm9+qj89e+j1zqgyn8aXGd7+nAduPoqgI9lO57SAZNn/Byzo5P7JhXTyg9PzaJbH73bA==", + "requires": { + "bytes": "3.1.0", + "http-errors": "1.7.3", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + } + }, + "rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "dev": true, + "requires": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + } + }, + "react": { + "version": "17.0.2", + "requires": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1" + } + }, + "react-dom": { + "version": "17.0.2", + "requires": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1", + "scheduler": "^0.20.2" + } + }, + "react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + }, + "react-merge-refs": { + "version": "1.1.0" + }, + "react-refresh": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.8.3.tgz", + "integrity": "sha512-X8jZHc7nCMjaCqoU+V2I0cOhNW+QMBwSUkeXnTi8IPe6zaRWfn60ZzvFDZqWPfmSJfjub7dDW1SP0jaHWLu/hg==" + }, + "react-ticker": { + "version": "1.2.2" + }, + "react-use-measure": { + "version": "2.0.4", + "requires": { + "debounce": "^1.2.0" + } + }, + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "requires": { + "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" + }, + "dependencies": { + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "readdirp": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz", + "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==", + "requires": { + "picomatch": "^2.2.1" + } + }, + "reduce-css-calc": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/reduce-css-calc/-/reduce-css-calc-2.1.8.tgz", + "integrity": "sha512-8liAVezDmUcH+tdzoEGrhfbGcP7nOV4NkGE3a74+qqvE7nt9i4sKLGBuZNOnpI4WiGksiNPklZxva80061QiPg==", + "requires": { + "css-unit-converter": "^1.1.1", + "postcss-value-parser": "^3.3.0" + }, + "dependencies": { + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" + } + } + }, + "regenerator-runtime": { + "version": "0.13.7", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz", + "integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew==" + }, + "registry-auth-token": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-4.2.1.tgz", + "integrity": "sha512-6gkSb4U6aWJB4SF2ZvLb76yCBjcvufXBqvvEx1HbmKPkutswjW1xNVRY0+daljIYRbogN7O0etYSlbiaEQyMyw==", + "dev": true, + "requires": { + "rc": "^1.2.8" + } + }, + "registry-url": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-5.1.0.tgz", + "integrity": "sha512-8acYXXTI0AkQv6RAOjE3vOaIXZkT9wo4LOFbBKYQEEnnMNBpKqdUrI6S4NT0KPIo/WVvJ5tE/X5LF/TQUf0ekw==", + "dev": true, + "requires": { + "rc": "^1.2.8" + } + }, + "relay-compiler": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/relay-compiler/-/relay-compiler-10.1.0.tgz", + "integrity": "sha512-HPqc3N3tNgEgUH5+lTr5lnLbgnsZMt+MRiyS0uAVNhuPY2It0X1ZJG+9qdA3L9IqKFUNwVn6zTO7RArjMZbARQ==", + "dev": true, + "requires": { + "@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" + }, + "dependencies": { + "cliui": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", + "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "dev": true, + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^6.2.0" + } + }, + "wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + }, + "y18n": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", + "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", + "dev": true + }, + "yargs": { + "version": "15.4.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", + "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", + "dev": true, + "requires": { + "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-parser": { + "version": "18.1.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", + "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + } + } + }, + "relay-runtime": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/relay-runtime/-/relay-runtime-10.1.0.tgz", + "integrity": "sha512-bxznLnQ1ST6APN/cFi7l0FpjbZVchWQjjhj9mAuJBuUqNNCh9uV+UTRhpQF7Q8ycsPp19LHTpVyGhYb0ustuRQ==", + "dev": true, + "requires": { + "@babel/runtime": "^7.0.0", + "fbjs": "^3.0.0" + } + }, + "remedial": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/remedial/-/remedial-1.0.8.tgz", + "integrity": "sha512-/62tYiOe6DzS5BqVsNpH/nkGlX45C/Sp6V+NtiN6JQNS1Viay7cWkazmRkrQrdFj2eshDe96SIQNIoMxqhzBOg==", + "dev": true + }, + "remove-trailing-separator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", + "dev": true + }, + "remove-trailing-spaces": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/remove-trailing-spaces/-/remove-trailing-spaces-1.0.8.tgz", + "integrity": "sha512-O3vsMYfWighyFbTd8hk8VaSj9UAGENxAtX+//ugIst2RMk5e03h6RoIS+0ylsFxY1gvmPuAY/PO4It+gPEeySA==", + "dev": true + }, + "replaceall": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/replaceall/-/replaceall-0.1.6.tgz", + "integrity": "sha1-gdgax663LX9cSUKt8ml6MiBojY4=", + "dev": true + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true + }, + "require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true + }, + "requirejs": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/requirejs/-/requirejs-2.3.6.tgz", + "integrity": "sha512-ipEzlWQe6RK3jkzikgCupiTbTvm4S0/CAU5GlgptkN5SO6F3u0UD0K18wy6ErDqiCyP4J4YYe1HuAShvsxePLg==", + "dev": true + }, + "requirejs-config-file": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/requirejs-config-file/-/requirejs-config-file-4.0.0.tgz", + "integrity": "sha512-jnIre8cbWOyvr8a5F2KuqBnY+SDA4NXr/hzEZJG79Mxm2WiFQz2dzhC8ibtPJS7zkmBEl1mxSwp5HhC1W4qpxw==", + "dev": true, + "requires": { + "esprima": "^4.0.0", + "stringify-object": "^3.2.1" + } + }, + "resolve": { + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", + "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", + "requires": { + "is-core-module": "^2.2.0", + "path-parse": "^1.0.6" + } + }, + "resolve-dependency-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/resolve-dependency-path/-/resolve-dependency-path-2.0.0.tgz", + "integrity": "sha512-DIgu+0Dv+6v2XwRaNWnumKu7GPufBBOr5I1gRPJHkvghrfCGOooJODFvgFimX/KRxk9j0whD2MnKHzM1jYvk9w==", + "dev": true + }, + "resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true + }, + "responselike": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", + "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=", + "dev": true, + "requires": { + "lowercase-keys": "^1.0.0" + } + }, + "restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dev": true, + "requires": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + } + }, + "retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", + "integrity": "sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs=" + }, + "reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==" + }, + "ripemd160": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", + "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" + } + }, + "run-async": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", + "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", + "dev": true + }, + "run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "requires": { + "queue-microtask": "^1.2.2" + } + }, + "rxjs": { + "version": "6.6.7", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", + "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", + "dev": true, + "requires": { + "tslib": "^1.9.0" + }, + "dependencies": { + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + } + } + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "sass-lookup": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/sass-lookup/-/sass-lookup-3.0.0.tgz", + "integrity": "sha512-TTsus8CfFRn1N44bvdEai1no6PqdmDiQUiqW5DlpmtT+tYnIt1tXtDIph5KA1efC+LmioJXSnCtUVpcK9gaKIg==", + "dev": true, + "requires": { + "commander": "^2.16.0" + }, + "dependencies": { + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + } + } + }, + "scheduler": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.20.2.tgz", + "integrity": "sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ==", + "requires": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1" + } + }, + "scuid": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/scuid/-/scuid-1.1.0.tgz", + "integrity": "sha512-MuCAyrGZcTLfQoH2XoBlQ8C6bzwN88XT/0slOGz0pn8+gIP85BOAfYa44ZXQUTOwRwPU0QvgU+V+OSajl/59Xg==", + "dev": true + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + }, + "semver-compare": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", + "integrity": "sha1-De4hahyUGrN+nvsXiPavxf9VN/w=", + "dev": true + }, + "sentence-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/sentence-case/-/sentence-case-3.0.4.tgz", + "integrity": "sha512-8LS0JInaQMCRoQ7YUytAo/xUu5W2XnQxV2HI/6uM6U7CITS1RqPElr30V6uIqyMKM9lJGRVFy5/4CuzcixNYSg==", + "dev": true, + "requires": { + "no-case": "^3.0.4", + "tslib": "^2.0.3", + "upper-case-first": "^2.0.2" + } + }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "dev": true + }, + "setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=" + }, + "setprototypeof": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", + "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" + }, + "sha.js": { + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true + }, + "shell-quote": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.2.tgz", + "integrity": "sha512-mRz/m/JVscCrkMyPqHc/bczi3OQHkLTqXHEFu0zDhK/qfv3UcOA4SVmRCLmos4bhjr9ekVQubj/R7waKapmiQg==" + }, + "shopify-buy": { + "version": "2.11.0" + }, + "signal-exit": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", + "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==", + "dev": true + }, + "signedsource": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/signedsource/-/signedsource-1.0.0.tgz", + "integrity": "sha1-HdrOSYF5j5O9gzlzgD2A1S6TrWo=", + "dev": true + }, + "simple-swizzle": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", + "integrity": "sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo=", + "requires": { + "is-arrayish": "^0.3.1" + }, + "dependencies": { + "is-arrayish": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", + "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" + } + } + }, + "sirv": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/sirv/-/sirv-1.0.12.tgz", + "integrity": "sha512-+jQoCxndz7L2tqQL4ZyzfDhky0W/4ZJip3XoOuxyQWnAwMxindLl3Xv1qT4x1YX/re0leShvTm8Uk0kQspGhBg==", + "dev": true, + "requires": { + "@polka/url": "^1.0.0-next.15", + "mime": "^2.3.1", + "totalist": "^1.0.0" + } + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true + }, + "slice-ansi": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz", + "integrity": "sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + } + }, + "snake-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/snake-case/-/snake-case-3.0.4.tgz", + "integrity": "sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==", + "dev": true, + "requires": { + "dot-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + }, + "source-map-js": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-0.6.2.tgz", + "integrity": "sha512-/3GptzWzu0+0MBQFrDKzw/DvvMTUORvgY6k6jd/VS6iCR4RDTKWH6v6WPwQoUO8667uQEf9Oe38DxAYWY5F/Ug==" + }, + "source-map-support": { + "version": "0.5.19", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", + "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "sponge-case": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/sponge-case/-/sponge-case-1.0.1.tgz", + "integrity": "sha512-dblb9Et4DAtiZ5YSUZHLl4XhH4uK80GhAZrVXdN4O2P4gQ40Wa5UIOPUHlA/nFd2PLblBZWUioLMMAVrgpoYcA==", + "dev": true, + "requires": { + "tslib": "^2.0.3" + } + }, + "stacktrace-parser": { + "version": "0.1.10", + "resolved": "https://registry.npmjs.org/stacktrace-parser/-/stacktrace-parser-0.1.10.tgz", + "integrity": "sha512-KJP1OCML99+8fhOHxwwzyWrlUuVX5GQ0ZpJTd1DFXhdkrvg1szxfHhawXUZ3g9TkXORQd4/WG68jMlQZ2p8wlg==", + "requires": { + "type-fest": "^0.7.1" + }, + "dependencies": { + "type-fest": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.7.1.tgz", + "integrity": "sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg==" + } + } + }, + "statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" + }, + "stream-browserify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-3.0.0.tgz", + "integrity": "sha512-H73RAHsVBapbim0tU2JwwOiXUj+fikfiaoYAKHF3VJfA0pe2BCzkhAHBlLG6REzE+2WNZcxOXjK7lkso+9euLA==", + "requires": { + "inherits": "~2.0.4", + "readable-stream": "^3.5.0" + }, + "dependencies": { + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + } + } + }, + "stream-http": { + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz", + "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==", + "requires": { + "builtin-status-codes": "^3.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.3.6", + "to-arraybuffer": "^1.0.0", + "xtend": "^4.0.0" + } + }, + "stream-parser": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/stream-parser/-/stream-parser-0.3.1.tgz", + "integrity": "sha1-FhhUhpRCACGhGC/wrxkRwSl2F3M=", + "requires": { + "debug": "2" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, + "string-argv": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.1.tgz", + "integrity": "sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg==", + "dev": true + }, + "string-env-interpolation": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/string-env-interpolation/-/string-env-interpolation-1.0.1.tgz", + "integrity": "sha512-78lwMoCcn0nNu8LszbP1UA7g55OeE4v7rCeWnM5B453rnNr4aq+5it3FEYtZrSEiMvHZOZ9Jlqb0OD0M2VInqg==", + "dev": true + }, + "string-hash": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/string-hash/-/string-hash-1.1.3.tgz", + "integrity": "sha1-6Kr8CsGFW0Zmkp7X3RJ1311sgRs=" + }, + "string-width": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", + "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + } + }, + "string.prototype.trimend": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", + "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + } + }, + "string.prototype.trimstart": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", + "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + } + }, + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "requires": { + "safe-buffer": "~5.2.0" + } + }, + "stringify-object": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz", + "integrity": "sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==", + "dev": true, + "requires": { + "get-own-enumerable-property-symbols": "^3.0.0", + "is-obj": "^1.0.1", + "is-regexp": "^1.0.0" + } + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "requires": { + "ansi-regex": "^5.0.0" + } + }, + "strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true + }, + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "dev": true + }, + "styled-jsx": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-3.3.2.tgz", + "integrity": "sha512-daAkGd5mqhbBhLd6jYAjYBa9LpxYCzsgo/f6qzPdFxVB8yoGbhxvzQgkC0pfmCVvW3JuAEBn0UzFLBfkHVZG1g==", + "requires": { + "@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" + }, + "dependencies": { + "@babel/types": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.8.3.tgz", + "integrity": "sha512-jBD+G8+LWpMBBWvVcdr4QysjUE4mU/syrhN17o1u3gx0/WzJB1kwiVZAXRtWbsIPOwW8pF/YJV5+nmetPzepXg==", + "requires": { + "esutils": "^2.0.2", + "lodash": "^4.17.13", + "to-fast-properties": "^2.0.0" + } + }, + "source-map": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==" + } + } + }, + "stylis": { + "version": "3.5.4", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-3.5.4.tgz", + "integrity": "sha512-8/3pSmthWM7lsPBKv7NXkzn2Uc9W7NotcwGNpJaa3k7WMM1XDCA4MgT5k/8BIexd5ydZdboXtU90XH9Ec4Bv/Q==" + }, + "stylis-rule-sheet": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/stylis-rule-sheet/-/stylis-rule-sheet-0.0.10.tgz", + "integrity": "sha512-nTbZoaqoBnmK+ptANthb10ZRZOGC+EmTLLUxeYIuHNkEKcmKgXX1XWKkUBT2Ac4es3NybooPe0SmvKdhKJZAuw==" + }, + "stylus-lookup": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/stylus-lookup/-/stylus-lookup-3.0.2.tgz", + "integrity": "sha512-oEQGHSjg/AMaWlKe7gqsnYzan8DLcGIHe0dUaFkucZZ14z4zjENRlQMCHT4FNsiWnJf17YN9OvrCfCoi7VvOyg==", + "dev": true, + "requires": { + "commander": "^2.8.1", + "debug": "^4.1.0" + }, + "dependencies": { + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + } + } + }, + "subscriptions-transport-ws": { + "version": "0.9.19", + "resolved": "https://registry.npmjs.org/subscriptions-transport-ws/-/subscriptions-transport-ws-0.9.19.tgz", + "integrity": "sha512-dxdemxFFB0ppCLg10FTtRqH/31FNRL1y1BQv8209MK5I4CwALb7iihQg+7p65lFcIl8MHatINWBLOqpgU4Kyyw==", + "dev": true, + "requires": { + "backo2": "^1.0.2", + "eventemitter3": "^3.1.0", + "iterall": "^1.2.1", + "symbol-observable": "^1.0.4", + "ws": "^5.2.0 || ^6.0.0 || ^7.0.0" + } + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "requires": { + "has-flag": "^4.0.0" + }, + "dependencies": { + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + } + } + }, + "swap-case": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/swap-case/-/swap-case-2.0.2.tgz", + "integrity": "sha512-kc6S2YS/2yXbtkSMunBtKdah4VFETZ8Oh6ONSmSd9bRxhqTrtARUCBUiWXH3xVPpvR7tz2CSnkuXVE42EcGnMw==", + "dev": true, + "requires": { + "tslib": "^2.0.3" + } + }, + "swell-js": { + "version": "4.0.0-next.0", + "requires": { + "@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" + }, + "dependencies": { + "@babel/runtime": { + "version": "7.4.5", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.4.5.tgz", + "integrity": "sha512-TuI4qpWZP6lGOGIuGWtp9sPluqYICmbk8T/1vpSysqJxRPkudh/ofFWyqdcMsDf2s7KvDL4/YHgKyvcS3g9CJQ==", + "requires": { + "regenerator-runtime": "^0.13.2" + } + }, + "lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + } + } + }, + "swr": { + "version": "0.5.6", + "requires": { + "dequal": "2.0.2" + } + }, + "symbol-observable": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz", + "integrity": "sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ==", + "dev": true + }, + "sync-fetch": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/sync-fetch/-/sync-fetch-0.3.0.tgz", + "integrity": "sha512-dJp4qg+x4JwSEW1HibAuMi0IIrBI3wuQr2GimmqB7OXR50wmwzfdusG+p39R9w3R6aFtZ2mzvxvWKQ3Bd/vx3g==", + "dev": true, + "requires": { + "buffer": "^5.7.0", + "node-fetch": "^2.6.1" + } + }, + "tabbable": { + "version": "5.2.0" + }, + "tailwindcss": { + "version": "2.1.4", + "requires": { + "@fullhuman/postcss-purgecss": "^3.1.3", + "bytes": "^3.0.0", + "chalk": "^4.1.0", + "chokidar": "^3.5.1", + "color": "^3.1.3", + "detective": "^5.2.0", + "didyoumean": "^1.2.1", + "dlv": "^1.1.3", + "fast-glob": "^3.2.5", + "fs-extra": "^9.1.0", + "html-tags": "^3.1.0", + "lodash": "^4.17.21", + "lodash.topath": "^4.5.2", + "modern-normalize": "^1.0.0", + "node-emoji": "^1.8.1", + "normalize-path": "^3.0.0", + "object-hash": "^2.1.1", + "parse-glob": "^3.0.4", + "postcss-functions": "^3", + "postcss-js": "^3.0.3", + "postcss-nested": "5.0.5", + "postcss-selector-parser": "^6.0.4", + "postcss-value-parser": "^4.1.0", + "pretty-hrtime": "^1.0.3", + "quick-lru": "^5.1.1", + "reduce-css-calc": "^2.1.8", + "resolve": "^1.20.0" + }, + "dependencies": { + "cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==" + }, + "lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, + "postcss-selector-parser": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.4.tgz", + "integrity": "sha512-gjMeXBempyInaBqpp8gODmwZ52WaYsVOsfr4L4lDQ7n3ncD6mEyySiDtgzCT+NYC0mmeOLvtsF8iaEf0YT6dBw==", + "requires": { + "cssesc": "^3.0.0", + "indexes-of": "^1.0.1", + "uniq": "^1.0.1", + "util-deprecate": "^1.0.2" + } + } + } + }, + "tapable": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.0.tgz", + "integrity": "sha512-FBk4IesMV1rBxX2tfiK8RAmogtWn53puLOQlvO8XuwlgxcYbP4mVPS9Ph4aeamSyyVjOl24aYWAuc8U5kCVwMw==", + "dev": true + }, + "temp": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/temp/-/temp-0.4.0.tgz", + "integrity": "sha1-ZxrWPVe+D+nXKUZks/xABjZnimA=", + "dev": true + }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "dev": true + }, + "timers-browserify": { + "version": "2.0.12", + "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.12.tgz", + "integrity": "sha512-9phl76Cqm6FhSX9Xe1ZUAMLtm1BLkKj2Qd5ApyWkXzsMRaA7dgr81kf4wJmQf/hAvg8EEyJxDo3du/0KlhPiKQ==", + "requires": { + "setimmediate": "^1.0.4" + } + }, + "title-case": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/title-case/-/title-case-3.0.3.tgz", + "integrity": "sha512-e1zGYRvbffpcHIrnuqT0Dh+gEJtDaxDSoG4JAIpq4oDFyooziLBIiYQv0GBT4FUAnUop5uZ1hiIAj7oAF6sOCA==", + "dev": true, + "requires": { + "tslib": "^2.0.3" + } + }, + "tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dev": true, + "requires": { + "os-tmpdir": "~1.0.2" + } + }, + "to-arraybuffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", + "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=" + }, + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=" + }, + "to-readable-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz", + "integrity": "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==", + "dev": true + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "requires": { + "is-number": "^7.0.0" + } + }, + "toidentifier": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", + "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==" + }, + "totalist": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/totalist/-/totalist-1.1.0.tgz", + "integrity": "sha512-gduQwd1rOdDMGxFG1gEvhV88Oirdo2p+KjoYFU7k2g+i7n6AFFbDQ5kMPUsW0pNbfQsB/cwXvT1i4Bue0s9g5g==", + "dev": true + }, + "tr46": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz", + "integrity": "sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk=", + "requires": { + "punycode": "^2.1.0" + } + }, + "ts-loader": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-7.0.5.tgz", + "integrity": "sha512-zXypEIT6k3oTc+OZNx/cqElrsbBtYqDknf48OZos0NQ3RTt045fBIU8RRSu+suObBzYB355aIPGOe/3kj9h7Ig==", + "dev": true, + "requires": { + "chalk": "^2.3.0", + "enhanced-resolve": "^4.0.0", + "loader-utils": "^1.0.2", + "micromatch": "^4.0.0", + "semver": "^6.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "enhanced-resolve": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.5.0.tgz", + "integrity": "sha512-Nv9m36S/vxpsI+Hc4/ZGRs0n9mXqSWGGq49zxb/cJfPAQMbUtttJAlNPS4AQzaBdw/pKskw5bMbekT/Y7W/Wlg==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "memory-fs": "^0.5.0", + "tapable": "^1.0.0" + } + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "tapable": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", + "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==", + "dev": true + } + } + }, + "ts-log": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/ts-log/-/ts-log-2.2.3.tgz", + "integrity": "sha512-XvB+OdKSJ708Dmf9ore4Uf/q62AYDTzFcAdxc8KNML1mmAWywRFVt/dn1KYJH8Agt5UJNujfM3znU5PxgAzA2w==", + "dev": true + }, + "ts-node": { + "version": "9.1.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-9.1.1.tgz", + "integrity": "sha512-hPlt7ZACERQGf03M253ytLY3dHbGNGrAq9qIHWUY9XHYl1z7wYngSr3OQ5xmui8o2AaxsONxIzjafLUiWBo1Fg==", + "dev": true, + "requires": { + "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": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/ts-pnp/-/ts-pnp-1.2.0.tgz", + "integrity": "sha512-csd+vJOb/gkzvcCHgTGSChYpy5f1/XKNsmvBGO4JXS+z1v2HobugDz4s1IeFXM3wZB44uczs+eazB5Q/ccdhQw==" + }, + "tslib": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.2.0.tgz", + "integrity": "sha512-gS9GVHRU+RGn5KQM2rllAlR3dU6m7AcpJKdtH8gFvQiC4Otgk98XnmMU+nZenHt/+VhnBPWwgrJsyrdcw6i23w==", + "dev": true + }, + "tsutils": { + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", + "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", + "dev": true, + "requires": { + "tslib": "^1.8.1" + }, + "dependencies": { + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + } + } + }, + "tty-browserify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", + "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=" + }, + "type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2" + } + }, + "type-fest": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.11.0.tgz", + "integrity": "sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ==", + "dev": true + }, + "typescript": { + "version": "4.2.4", + "dev": true + }, + "ua-parser-js": { + "version": "0.7.28", + "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.28.tgz", + "integrity": "sha512-6Gurc1n//gjp9eQNXjD9O3M/sMwVtN5S8Lv9bvOYBfKfDNiIIhqiyi01vMBO45u4zkDE420w/e0se7Vs+sIg+g==", + "dev": true + }, + "unbox-primitive": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", + "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1", + "has-bigints": "^1.0.1", + "has-symbols": "^1.0.2", + "which-boxed-primitive": "^1.0.2" + } + }, + "unc-path-regex": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz", + "integrity": "sha1-5z3T17DXxe2G+6xrCufYxqadUPo=", + "dev": true + }, + "unfetch": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/unfetch/-/unfetch-4.2.0.tgz", + "integrity": "sha512-F9p7yYCn6cIW9El1zi0HI6vqpeIvBsr3dSuRO6Xuppb1u5rXpCPmMvLSyECLhybr9isec8Ohl0hPekMVrEinDA==" + }, + "uniq": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz", + "integrity": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=" + }, + "universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==" + }, + "unixify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unixify/-/unixify-1.0.0.tgz", + "integrity": "sha1-OmQcjC/7zk2mg6XHDwOkYpQMIJA=", + "dev": true, + "requires": { + "normalize-path": "^2.1.1" + }, + "dependencies": { + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dev": true, + "requires": { + "remove-trailing-separator": "^1.0.1" + } + } + } + }, + "unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" + }, + "upper-case": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/upper-case/-/upper-case-2.0.2.tgz", + "integrity": "sha512-KgdgDGJt2TpuwBUIjgG6lzw2GWFRCW9Qkfkiv0DxqHHLYJHmtmdUIKcZd8rHgFSjopVTlw6ggzCm1b8MFQwikg==", + "dev": true, + "requires": { + "tslib": "^2.0.3" + } + }, + "upper-case-first": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/upper-case-first/-/upper-case-first-2.0.2.tgz", + "integrity": "sha512-514ppYHBaKwfJRK/pNC6c/OxfGa0obSnAl106u97Ed0I625Nin96KAjttZF6ZL3e1XLtphxnqrOi9iWgm+u+bg==", + "dev": true, + "requires": { + "tslib": "^2.0.3" + } + }, + "url": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", + "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", + "requires": { + "punycode": "1.3.2", + "querystring": "0.2.0" + }, + "dependencies": { + "punycode": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", + "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=" + }, + "querystring": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", + "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=" + } + } + }, + "url-parse-lax": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", + "integrity": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=", + "dev": true, + "requires": { + "prepend-http": "^2.0.0" + } + }, + "use-subscription": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/use-subscription/-/use-subscription-1.5.1.tgz", + "integrity": "sha512-Xv2a1P/yReAjAbhylMfFplFKj9GssgTwN7RlcTxBujFQcloStWNDQdc4g4NRWH9xS4i/FDk04vQBptAXoF3VcA==", + "requires": { + "object-assign": "^4.1.1" + } + }, + "util": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz", + "integrity": "sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==", + "requires": { + "inherits": "2.0.3" + }, + "dependencies": { + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + } + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, + "util-nonempty": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/util-nonempty/-/util-nonempty-3.1.0.tgz", + "integrity": "sha512-OSZlWoCL74Go83Qw/aeZgSmFZnp9d06bF77b1eAOKipkPWhvxjRYB2nmKiGspoVjkJJEJimzxAgBFUQiUV/oZQ==", + "requires": { + "@babel/runtime": "^7.14.0", + "lodash.isplainobject": "^4.0.6" + } + }, + "valid-url": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/valid-url/-/valid-url-1.0.9.tgz", + "integrity": "sha1-HBRHm0DxOXp1eC8RXkCGRHQzogA=", + "dev": true + }, + "value-or-promise": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/value-or-promise/-/value-or-promise-1.0.6.tgz", + "integrity": "sha512-9r0wQsWD8z/BxPOvnwbPf05ZvFngXyouE9EKB+5GbYix+BYnAwrIChCUyFIinfbf2FL/U71z+CPpbnmTdxrwBg==", + "dev": true + }, + "vm-browserify": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", + "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==" + }, + "walkdir": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/walkdir/-/walkdir-0.4.1.tgz", + "integrity": "sha512-3eBwRyEln6E1MSzcxcVpQIhRG8Q1jLvEqRmCZqS3dsfXEDR/AhOF4d+jHg1qvDCpYaVRZjENPQyrVxAkQqxPgQ==", + "dev": true + }, + "watchpack": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.1.1.tgz", + "integrity": "sha512-Oo7LXCmc1eE1AjyuSBmtC3+Wy4HcV8PxWh2kP6fOl8yTlNS7r0K9l1ao2lrrUza7V39Y3D/BbJgY8VeSlc5JKw==", + "requires": { + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.1.2" + } + }, + "wcwidth": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", + "integrity": "sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g=", + "dev": true, + "requires": { + "defaults": "^1.0.3" + } + }, + "webidl-conversions": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", + "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==" + }, + "webpack-bundle-analyzer": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/webpack-bundle-analyzer/-/webpack-bundle-analyzer-4.3.0.tgz", + "integrity": "sha512-J3TPm54bPARx6QG8z4cKBszahnUglcv70+N+8gUqv2I5KOFHJbzBiLx+pAp606so0X004fxM7hqRu10MLjJifA==", + "dev": true, + "requires": { + "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" + }, + "dependencies": { + "commander": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz", + "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==", + "dev": true + } + } + }, + "whatwg-fetch": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.2.tgz", + "integrity": "sha512-bJlen0FcuU/0EMLrdbJ7zOnW6ITZLrZMIarMUVmdKtsGvZna8vxKYaexICWPfZ8qwf9fzNq+UEIZrnSaApt6RA==" + }, + "whatwg-url": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz", + "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==", + "requires": { + "lodash.sortby": "^4.7.0", + "tr46": "^1.0.1", + "webidl-conversions": "^4.0.2" + } + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "which-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "dev": true, + "requires": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + } + }, + "which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", + "dev": true + }, + "word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "dev": true + }, + "wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "ws": { + "version": "7.4.5", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.5.tgz", + "integrity": "sha512-xzyu3hFvomRfXKH8vOFMU3OguG6oOvhXMo3xsGy3xWExqaM2dxBbVxuD99O7m3ZUFMvvscsZDqxfgMaRr/Nr1g==", + "dev": true + }, + "xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" + }, + "y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true + }, + "yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" + }, + "yaml": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.0.tgz", + "integrity": "sha512-yr2icI4glYaNG+KWONODapy2/jDdMSDnrONSjblABjD9B4Z5LgiircSt8m8sRZFNi08kG9Sm0uSHtEmP3zaEGg==", + "dev": true + }, + "yaml-ast-parser": { + "version": "0.0.43", + "resolved": "https://registry.npmjs.org/yaml-ast-parser/-/yaml-ast-parser-0.0.43.tgz", + "integrity": "sha512-2PTINUwsRqSd+s8XxKaJWQlUuEMHJQyEuh2edBbW8KNJz0SJPwUSD2zRWqezFEdN7IzAgeuYHFUCF7o8zRdZ0A==", + "dev": true + }, + "yargs": { + "version": "17.0.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.0.1.tgz", + "integrity": "sha512-xBBulfCc8Y6gLFcrPvtqKz9hz8SO0l1Ni8GgDekvBX2ro0HRQImDGnikfc33cgzcYUSncapnNcZDjVFIH3f6KQ==", + "dev": true, + "requires": { + "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" + } + }, + "yargs-parser": { + "version": "20.2.7", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.7.tgz", + "integrity": "sha512-FiNkvbeHzB/syOjIUxFDCnhSfzAL8R5vs40MgLFBorXACCOAEaWu0gRZl14vG8MR9AOJIZbmkjhusqBYZ3HTHw==", + "dev": true + }, + "yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true + }, + "yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==" + } + } +} diff --git a/package.json b/package.json index 5034d7e0c..6f8ddedda 100644 --- a/package.json +++ b/package.json @@ -19,7 +19,7 @@ "node": ">=14.x" }, "dependencies": { - "@reach/portal": "^0.15.0", + "@react-spring/web": "^9.2.1", "@vercel/fetch": "^6.1.0", "autoprefixer": "^10.2.6", "body-scroll-lock": "^3.1.5", @@ -29,6 +29,7 @@ "dot-object": "^2.1.4", "email-validator": "^2.0.4", "immutability-helper": "^3.1.1", + "isomorphic-unfetch": "^3.1.0", "js-cookie": "^2.2.1", "keen-slider": "^5.4.1", "lodash.debounce": "^4.0.8", @@ -41,8 +42,9 @@ "postcss-nesting": "^8.0.1", "react": "^17.0.2", "react-dom": "^17.0.2", + "react-fast-marquee": "^1.1.3", "react-merge-refs": "^1.1.0", - "react-ticker": "^1.2.2", + "react-use-measure": "^2.0.4", "shopify-buy": "^2.11.0", "swell-js": "^4.0.0-next.0", "swr": "^0.5.6", diff --git a/pages/404.tsx b/pages/404.tsx new file mode 100644 index 000000000..bd085010f --- /dev/null +++ b/pages/404.tsx @@ -0,0 +1,35 @@ +import type { GetStaticPropsContext } from 'next' +import commerce from '@lib/api/commerce' +import { Layout } from '@components/common' +import { Text } from '@components/ui' + +export async function getStaticProps({ + preview, + locale, + locales, +}: GetStaticPropsContext) { + const config = { locale, locales } + const { pages } = await commerce.getAllPages({ config, preview }) + const { categories, brands } = await commerce.getSiteInfo({ config, preview }) + return { + props: { + pages, + categories, + brands, + }, + revalidate: 200, + } +} + +export default function NotFound() { + return ( +
    + Not Found + + The requested page doesn't exist or you don't have access to it. + +
    + ) +} + +NotFound.Layout = Layout diff --git a/pages/[...pages].tsx b/pages/[...pages].tsx index ab2f22d21..a8a24b3aa 100644 --- a/pages/[...pages].tsx +++ b/pages/[...pages].tsx @@ -8,6 +8,7 @@ import { Text } from '@components/ui' import { Layout } from '@components/common' import getSlug from '@lib/get-slug' import { missingLocaleInPages } from '@lib/usage-warns' +import type { Page } from '@commerce/types/page' import { useRouter } from 'next/router' export async function getStaticProps({ @@ -17,11 +18,15 @@ export async function getStaticProps({ locales, }: GetStaticPropsContext<{ pages: string[] }>) { const config = { locale, locales } - const { pages } = await commerce.getAllPages({ config, preview }) - const { categories } = await commerce.getSiteInfo({ config, preview }) + const pagesPromise = commerce.getAllPages({ config, preview }) + const siteInfoPromise = commerce.getSiteInfo({ config, preview }) + const { pages } = await pagesPromise + const { categories } = await siteInfoPromise const path = params?.pages.join('/') const slug = locale ? `${locale}/${path}` : path - const pageItem = pages.find((p) => (p.url ? getSlug(p.url) === slug : false)) + const pageItem = pages.find((p: Page) => + p.url ? getSlug(p.url) === slug : false + ) const data = pageItem && (await commerce.getPage({ @@ -45,7 +50,7 @@ export async function getStaticProps({ export async function getStaticPaths({ locales }: GetStaticPathsContext) { const config = { locales } - const { pages } = await commerce.getAllPages({ config }) + const { pages }: { pages: Page[] } = await commerce.getAllPages({ config }) const [invalidPaths, log] = missingLocaleInPages() const paths = pages .map((page) => page.url) diff --git a/pages/cart.tsx b/pages/cart.tsx index dff4a201e..3279301da 100644 --- a/pages/cart.tsx +++ b/pages/cart.tsx @@ -13,8 +13,10 @@ export async function getStaticProps({ locales, }: GetStaticPropsContext) { const config = { locale, locales } - const { pages } = await commerce.getAllPages({ config, preview }) - const { categories } = await commerce.getSiteInfo({ config, preview }) + const pagesPromise = commerce.getAllPages({ config, preview }) + const siteInfoPromise = commerce.getSiteInfo({ config, preview }) + const { pages } = await pagesPromise + const { categories } = await siteInfoPromise return { props: { pages, categories }, } @@ -49,7 +51,7 @@ export default function Cart() {

    Your cart is empty

    -

    +

    Biscuit oat cake wafer icing ice cream tiramisu pudding cupcake.

    @@ -76,8 +78,8 @@ export default function Cart() {
    My Cart Review your Order -