diff --git a/packages/gatsby-plugin-cms/package.json b/packages/gatsby-plugin-cms/package.json index 7e2531dc2a..153f387692 100644 --- a/packages/gatsby-plugin-cms/package.json +++ b/packages/gatsby-plugin-cms/package.json @@ -37,7 +37,7 @@ "@babel/register": "^7.12.1", "chokidar": "^3.5.0", "fs-extra": "^9.0.1", - "gatsby-graphql-source-toolkit": "^0.6.3", + "gatsby-graphql-source-toolkit": "^2.0.1", "p-map": "^4.0.0" } } diff --git a/packages/gatsby-plugin-pixel-facebook/src/pixel/handler.ts b/packages/gatsby-plugin-pixel-facebook/src/pixel/handler.ts index 112f794284..1609ab4018 100644 --- a/packages/gatsby-plugin-pixel-facebook/src/pixel/handler.ts +++ b/packages/gatsby-plugin-pixel-facebook/src/pixel/handler.ts @@ -31,7 +31,7 @@ export const handler: PixelEventHandler = (event) => { const items = product?.items fbq('track', 'ViewContent', { - content_ids: items?.map((item) => item?.itemId), + content_ids: items?.map((item: any) => item?.itemId), content_name: product?.productName, content_type: 'product', // TODO: send currency diff --git a/packages/gatsby-source-vtex/package.json b/packages/gatsby-source-vtex/package.json index dd0510fedd..0514b7fff1 100644 --- a/packages/gatsby-source-vtex/package.json +++ b/packages/gatsby-source-vtex/package.json @@ -15,7 +15,8 @@ "files": [ "dist", "gatsby-*", - "index.js" + "index.js", + "src" ], "engines": { "node": ">=10" @@ -28,8 +29,9 @@ "prepare": "tsdx build" }, "dependencies": { - "@graphql-tools/delegate": "^6.0.15", - "@graphql-tools/wrap": "^6.0.15", + "@graphql-tools/delegate": "^7.1.5", + "@graphql-tools/wrap": "^7.0.8", + "gatsby-graphql-source-toolkit": "^2.0.1", "isomorphic-unfetch": "^3.0.0", "p-map": "^4.0.0", "slugify": "^1.4.6", diff --git a/packages/gatsby-source-vtex/src/api.ts b/packages/gatsby-source-vtex/src/api.ts index 4a958dee50..a63b00e940 100644 --- a/packages/gatsby-source-vtex/src/api.ts +++ b/packages/gatsby-source-vtex/src/api.ts @@ -1,31 +1,4 @@ -interface SearchOptions { - query?: string - page: number - count: number - sort: 'orders:desc' - operator: 'and' | 'or' - fuzzy?: string - locale?: string - bgy_leap?: boolean - 'hide-unavailable-items'?: boolean -} - export const api = { - is: { - search: (params: SearchOptions) => { - const searchParams = new URLSearchParams() - - Object.keys(params).forEach((key) => { - const value = params[key as keyof SearchOptions] - - if (value) { - searchParams.set(key, `${value}`) - } - }) - - return `/api/split/product_search/trade-policy/1?${searchParams}` - }, - }, catalog: { brand: { list: ({ page, pageSize }: { page: number; pageSize: number }) => diff --git a/packages/gatsby-source-vtex/src/fetch.ts b/packages/gatsby-source-vtex/src/fetch.ts index 3e463ed995..21ce208aa2 100644 --- a/packages/gatsby-source-vtex/src/fetch.ts +++ b/packages/gatsby-source-vtex/src/fetch.ts @@ -1,3 +1,5 @@ +import { inspect } from 'util' + import fetch from 'isomorphic-unfetch' export interface VTEXOptions { @@ -54,14 +56,13 @@ export const fetchGraphQL = async ( retryCount += 1 console.error( - `[gatsby-source-vtex]: Error while fetching graphql data. Retry ${retryCount}`, - response.errors + `[gatsby-source-vtex]: Error while fetching graphql data. Retry ${retryCount}` ) } if (response) { for (const error of response.errors) { - console.error(error) + console.error(inspect(error, false, 100, true)) } throw new Error( @@ -92,24 +93,3 @@ export const fetchVTEX = async ( throw err } } - -export const fetchIS = async ( - path: string, - options: VTEXOptions, - init?: RequestInit -): Promise => { - try { - const url = `https://search.biggylabs.com.br/search-api/v1/${options.tenant}${path}` - - return await fetchRetry(url, { - ...init, - headers: { - ...headers, - ...init?.headers, - }, - }) - } catch (err) { - console.error(err) - throw err - } -} diff --git a/packages/gatsby-source-vtex/src/gatsby-node.ts b/packages/gatsby-source-vtex/src/gatsby-node.ts index 8e45f07e10..d529bb2c16 100644 --- a/packages/gatsby-source-vtex/src/gatsby-node.ts +++ b/packages/gatsby-source-vtex/src/gatsby-node.ts @@ -1,23 +1,41 @@ +import { readFile } from 'fs/promises' +import { join } from 'path' + import { FilterObjectFields, introspectSchema, PruneSchema, + RenameTypes, wrapSchema, } from '@graphql-tools/wrap' -import { print } from 'graphql' +import { + buildNodeDefinitions, + compileNodeQueries, + createSchemaCustomization as toolkitCreateSchemaCustomization, + sourceAllNodes, + sourceNodeChanges, + wrapQueryExecutorWithQueue, +} from 'gatsby-graphql-source-toolkit' +import { execute, parse } from 'graphql' import pMap from 'p-map' -import type { AsyncExecutor } from '@graphql-tools/delegate' import type { GatsbyNode, PluginOptions, SourceNodesArgs, CreatePagesArgs, PluginOptionsSchemaArgs, + CreateSchemaCustomizationArgs, + CreateResolversArgs, } from 'gatsby' +import type { + ISourcingConfig, + NodeEvent, +} from 'gatsby-graphql-source-toolkit/dist/types' import { api } from './api' -import { fetchGraphQL, fetchVTEX } from './fetch' -import { md5 } from './md5' +import { fetchVTEX } from './fetch' +import { ProductPaginationAdapter } from './graphql/pagination/product' +import { getExecutor } from './graphql/executor' import { assertRedirects } from './redirects' import defaultStaticPaths from './staticPaths' import { @@ -29,9 +47,6 @@ import { import type { VTEXOptions } from './fetch' import type { Category, PageType, Redirect, Tenant } from './types' -const getGraphQLUrl = (tenant: string, workspace: string) => - `http://${workspace}--${tenant}.myvtex.com/graphql` - export interface Options extends PluginOptions, VTEXOptions { /** * @description function to return the paths to statically generate @@ -51,74 +66,109 @@ export interface Options extends PluginOptions, VTEXOptions { } const DEFAULT_PAGE_TYPES_WHITELIST = [ - 'Product', 'Department', 'Category', 'Brand', 'SubCategory', ] +/** + * Add VTEX GraphQL API as 3p schema. + * + * VTEX schema contains some extra fields that should not be queryable by pages, like + * the `pages` field. This field contains the VTEX CMS data and is already handled by + * gatsby-plugin-cms. + * + * Also, we remove the `product` field from type VTEX for two reasons: + * 1. This field must return type StoreProduct instead of the original VTEX_Product so our type + * generation works correctly with user defined queries and fragments + * 2. Because we can't allow pages to query this field during SSG so we can't correctly use Gatsby's + * data model for incremental site generation + */ +export const createSchemaCustomization = async ( + args: CreateSchemaCustomizationArgs, + options: Options +) => { + const { + reporter, + actions: { addThirdPartySchema }, + } = args + + const activity = reporter.activityTimer( + '[gatsby-source-vtex]: adding VTEX Gateway GraphQL Schema' + ) + + activity.start() + + // Create executor to run queries against schema + const executor = getExecutor(options) + + const schema = wrapSchema({ + schema: await introspectSchema(executor), + executor, + transforms: [ + // Filter CMS fields so people use the VTEX CMS plugin instead of this one + new FilterObjectFields( + (typeName, fieldName) => + !( + typeName === 'VTEX' && + (fieldName === 'pages' || fieldName === 'product') + ) + ), + new PruneSchema({}), + ], + }) + + addThirdPartySchema({ schema }, { name: 'gatsby-source-vtex' }) + + activity.end() +} + +/** + * Creates dummy resolvers so we don't allow developers to query for these fields + * during SSG and uses the Gatsby data model correctly + */ +export const createResolvers = ({ + createResolvers: createGatsbyResolvers, +}: CreateResolversArgs) => { + const resolvers = { + VTEX: { + product: { + type: 'StoreProduct!', + args: { + slug: 'String!', + regionId: 'String', + }, + resolve: () => { + throw new Error('Client-side only route. Can not be used on SSG') + }, + }, + }, + } + + createGatsbyResolvers(resolvers) +} + export const sourceNodes: GatsbyNode['sourceNodes'] = async ( args: SourceNodesArgs, options: Options ) => { const { tenant, - workspace, getStaticPaths, pageTypes: pageTypesWhitelist = DEFAULT_PAGE_TYPES_WHITELIST, concurrency = 20, ignorePaths = [], } = options - const { - actions: { addThirdPartySchema }, - reporter, - } = args + const { reporter } = args - const promisses = [] as Array<() => Promise> + /** Reset last build time on this machine */ + const lastBuildTime = await args.cache.get(`LAST_BUILD_TIME`) - /** - * Add VTEX GraphQL API as 3p schema - */ - promisses.push(async () => { - const activity = reporter.activityTimer( - '[gatsby-source-vtex]: adding VTEX GraphQL Schema' - ) + await args.cache.set(`LAST_BUILD_TIME`, Date.now()) - activity.start() - - // Create executor to run queries against schema - const url = getGraphQLUrl(tenant, workspace) - - const executor: AsyncExecutor = ({ document, variables }) => - fetchGraphQL(url, { - method: 'POST', - headers: { - accept: 'application/json', - 'Content-Type': 'application/json', - }, - body: JSON.stringify({ query: print(document), variables }), - }) - - const schema = wrapSchema( - { - schema: await introspectSchema(executor), - executor, - }, - [ - // Filter CMS fields so people use the VTEX CMS plugin instead of this one - new FilterObjectFields( - (typeName, fieldName) => typeName !== 'VTEX' || fieldName !== 'pages' - ), - new PruneSchema({}), - ] - ) - - addThirdPartySchema({ schema }) - - activity.end() - }) + const promisses = [] as Array<() => Promise> /** * Add VTEX bindings @@ -190,22 +240,6 @@ export const sourceNodes: GatsbyNode['sourceNodes'] = async ( activity.start() const fetchPageTypes = async (path: string): Promise => { - const isProduct = /\/(.)+\/p$/g - - // When the page is a product page, we skip calling the pageType backend to speedup the process considerably. - // This makes us have to synthetically generate some data. However, it shouldn't be a problem since we don't - // use these synthetic attributes - if (isProduct.test(path)) { - return { - id: md5(path), - name: path.split('/p')[0], - url: path, - title: '', - metaTagDescription: '', - pageType: 'Product', - } - } - return fetchVTEX(api.catalog.portal.pageType(path), options) } @@ -237,6 +271,113 @@ export const sourceNodes: GatsbyNode['sourceNodes'] = async ( activity.end() }) + /** + * Source products so we can use Gatsby's file system route api for creating pages. + * https://www.gatsbyjs.com/docs/reference/routing/file-system-route-api/ + * + * Also, the steps below follow the tutorial from gatsby-graphql-toolkit. + * Take a look at their docs for more info + * https://github.com/gatsbyjs/gatsby-graphql-toolkit#how-it-works + */ + promisses.push(async () => { + // Step1. Set up remote schema: + const executor = getExecutor(options) + const gatewaySchema = await introspectSchema(executor) + const schema = wrapSchema({ + schema: gatewaySchema, + executor, + transforms: [ + new RenameTypes((typeName: string) => { + const newTypeName = typeName.replace('VTEX_', '') + const isTypeNameAvailable = !gatewaySchema.getType(newTypeName) + + return isTypeNameAvailable ? newTypeName : typeName + }), + new PruneSchema(), + ], + }) + + // Step2. Configure Gatsby node types + const gatsbyNodeTypes = [ + { + remoteTypeName: `Product`, + queries: ` + # Write your query or mutation here + query LIST_PRODUCTS($from: number, $to: number) { + vtex { + productSearch( + orderBy: "orders:desc", + from: $from, + to: $to + simulationBehavior: skip + ){ + products { + ..._ProductFragment_ + } + } + } + } + fragment _ProductFragment_ on Product { + id: productId + __typename + } + `, + }, + ] + + // Step3. Provide (or generate) fragments with fields to be fetched + const fragments = new Map() + const ProductFragment = await readFile( + join(__dirname, '../src/graphql/fragments/ProductFragment.graphql') + ) + + fragments.set('Product', ProductFragment.toString()) + + // Step4. Compile sourcing queries + const documents = compileNodeQueries({ + schema, + gatsbyNodeTypes, + customFragments: fragments, + }) + + // Define how to execute a query into the schema + const run = wrapQueryExecutorWithQueue(async (opts) => + execute({ + schema, + document: parse(opts.query), + operationName: opts.operationName, + variableValues: opts.variables, + }) + ) + + const config: ISourcingConfig = { + gatsbyApi: args, + schema, + execute: run, + gatsbyTypePrefix: `Store`, + gatsbyNodeDefs: buildNodeDefinitions({ gatsbyNodeTypes, documents }), + paginationAdapters: [ProductPaginationAdapter], + } + + // Step5. Add explicit types to gatsby schema + await toolkitCreateSchemaCustomization(config) + + // Step6. Source nodes either from delta changes or scratch + if (lastBuildTime) { + reporter.info( + '[gatsby-source-vtex]: CACHE FOUND! We are about to go FAST! Skipping FETCH' + ) + const nodeEvents: NodeEvent[] = [] + + await sourceNodeChanges(config, { nodeEvents }) + } else { + reporter.info( + '[gatsby-source-vtex]: No cache found. Sourcing all data from scratch' + ) + await sourceAllNodes(config) + } + }) + await Promise.all(promisses.map((x) => x())) } @@ -250,7 +391,7 @@ export const createPages = async ( const { data: { searches: { nodes: searches }, - products: { nodes: products }, + allStoreProduct: { totalCount: pdps }, }, } = await graphql(` query GetAllStaticPaths { @@ -260,24 +401,18 @@ export const createPages = async ( } ) { nodes { - ...staticPath + id + path + pageType } } - products: allStaticPath(filter: { pageType: { eq: "Product" } }) { - nodes { - ...staticPath - } + allStoreProduct { + totalCount } } - - fragment staticPath on StaticPath { - id - path - pageType - } `) - reporter.info(`[gatsby-source-vtex]: Available pdps: ${products.length}`) + reporter.info(`[gatsby-source-vtex]: Available pdps: ${pdps}`) reporter.info(`[gatsby-source-vtex]: Available plps: ${searches.length}`) /** diff --git a/packages/gatsby-source-vtex/src/graphql/executor.ts b/packages/gatsby-source-vtex/src/graphql/executor.ts new file mode 100644 index 0000000000..ca7791b620 --- /dev/null +++ b/packages/gatsby-source-vtex/src/graphql/executor.ts @@ -0,0 +1,22 @@ +import { print } from 'graphql' +import type { AsyncExecutor } from '@graphql-tools/delegate' + +import { fetchGraphQL } from '../fetch' +import type { Options } from '../gatsby-node' + +const getGraphQLUrl = ({ tenant, workspace }: Options) => + `http://${workspace}--${tenant}.myvtex.com/graphql` + +export const getExecutor = (options: Options): AsyncExecutor => { + const url = getGraphQLUrl(options) + + return ({ document, variables }) => + fetchGraphQL(url, { + method: 'POST', + headers: { + accept: 'application/json', + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ query: print(document), variables }), + }) +} diff --git a/packages/gatsby-source-vtex/src/graphql/fragments/ProductFragment.graphql b/packages/gatsby-source-vtex/src/graphql/fragments/ProductFragment.graphql new file mode 100644 index 0000000000..5eec4e8bdc --- /dev/null +++ b/packages/gatsby-source-vtex/src/graphql/fragments/ProductFragment.graphql @@ -0,0 +1,398 @@ +fragment Product on Product { + slug: linkText + name: productName + productID: productId + id: productId + brand + description + categoryTree { + ... on Category { + cacheId + href + slug + id + name + titleTag + hasChildren + metaTagDescription + children { + remoteTypeName: __typename + } + } + } + clusterHighlights { + ... on ClusterHighlight { + id + name + } + } + productClusters { + ... on ProductClusters { + id + name + } + } + items { + ... on SKU { + itemId + name + nameComplete + complementName + ean + referenceId { + ... on Reference { + Key + Value + } + } + measurementUnit + unitMultiplier + kitItems { + ... on KitItem { + itemId + amount + product { + ... on OnlyProduct { + brand + categoryId + categoryTree { + ... on Category { + cacheId + href + slug + id + name + titleTag + hasChildren + metaTagDescription + children { + remoteTypeName: __typename + } + } + } + clusterHighlights { + ... on ClusterHighlight { + id + name + } + } + productClusters { + ... on ProductClusters { + id + name + } + } + description + link + linkText + productId + productName + properties { + ... on Property { + originalName + name + values + } + } + propertyGroups { + ... on PropertyGroup { + name + properties + } + } + productReference + recommendations { + ... on Recommendation { + buy { + ... on Product { + remoteTypeName: __typename + id: productId + } + } + view { + ... on Product { + remoteTypeName: __typename + id: productId + } + } + similars { + ... on Product { + remoteTypeName: __typename + id: productId + } + } + } + } + jsonSpecifications + } + } + sku { + remoteTypeName: __typename + } + } + } + images { + ... on Image { + cacheId + imageId + imageLabel + imageTag + imageUrl + imageText + } + } + videos { + ... on Video { + videoUrl + } + } + sellers { + ... on Seller { + sellerId + sellerName + addToCartLink + sellerDefault + commertialOffer { + ... on Offer { + Installments(criteria: ALL) { + Name + TotalValuePlusInterestRate + Value + NumberOfInstallments + InterestRate + PaymentSystemName + PaymentSystemGroupName + } + AvailableQuantity + Price + ListPrice + spotPrice + teasers { + name + } + Price + ListPrice + spotPrice + PriceWithoutDiscount + RewardValue + PriceValidUntil + AvailableQuantity + Tax + taxPercentage + CacheVersionUsedToCallCheckout + DeliverySlaSamples { + ... on DeliverySlaSamples { + DeliverySlaPerTypes { + ... on DeliverySlaPerTypes { + TypeName + Price + EstimatedTimeSpanToDelivery + } + } + Region { + ... on Region { + IsPersisted + IsRemoved + Id + Name + CountryCode + ZipCode + CultureInfoName + } + } + } + } + discountHighlights { + ... on Discount { + name + } + } + teasers { + ... on Teaser { + name + conditions { + ... on TeaserCondition { + minimumQuantity + parameters { + ... on TeaserValue { + name + value + } + } + } + } + effects { + ... on TeaserEffects { + parameters { + ... on TeaserValue { + name + value + } + } + } + } + } + } + giftSkuIds + gifts { + ... on Gift { + productName + skuName + brand + linkText + description + images { + ... on GiftImage { + imageUrl + imageLabel + imageText + } + } + } + } + } + } + } + } + variations { + ... on Property { + originalName + name + values + } + } + attachments { + ... on Attachment { + id + name + required + domainValues { + ... on DomainValues { + FieldName + MaxCaracters + DomainValues + } + } + content + } + } + estimatedDateArrival + } + } + skuSpecifications { + ... on SkuSpecification { + field { + ... on SKUSpecificationField { + originalName + name + } + } + values { + ... on SKUSpecificationValue { + originalName + name + } + } + } + } + link + linkText + productId + productName + properties { + ... on Property { + originalName + name + values + } + } + propertyGroups { + ... on PropertyGroup { + name + properties + } + } + productReference + titleTag + metaTagDescription + recommendations { + ... on Recommendation { + buy { + ... on Product { + remoteTypeName: __typename + id: productId + } + } + view { + ... on Product { + remoteTypeName: __typename + id: productId + } + } + similars { + ... on Product { + remoteTypeName: __typename + id: productId + } + } + } + } + jsonSpecifications + benefits { + ... on Benefit { + featured + id + name + items { + ... on BenefitItem { + benefitProduct { + ... on Product { + remoteTypeName: __typename + id: productId + } + } + benefitSKUIds + discount + minQuantity + } + } + teaserType + } + } + specificationGroups { + ... on SpecificationGroup { + originalName + name + specifications { + ... on SpecificationGroupProperty { + originalName + name + values + } + } + } + } + priceRange { + ... on ProductPriceRange { + sellingPrice { + ... on PriceRange { + highPrice + lowPrice + } + } + listPrice { + ... on PriceRange { + highPrice + lowPrice + } + } + } + } + releaseDate + selectedProperties { + ... on SelectedProperty { + key + value + } + } +} diff --git a/packages/gatsby-source-vtex/src/graphql/pagination/product.ts b/packages/gatsby-source-vtex/src/graphql/pagination/product.ts new file mode 100644 index 0000000000..23a3591c94 --- /dev/null +++ b/packages/gatsby-source-vtex/src/graphql/pagination/product.ts @@ -0,0 +1,41 @@ +import type { IPaginationAdapter } from 'gatsby-graphql-source-toolkit' + +// Define pagination adapters +interface IProduct { + productId: string +} + +interface IPage { + products: IProduct[] +} + +// Current max page size supported by VTEX API +// TODO: Increasing this number could help on our build times +const PAGE_SIZE = 100 + +export const ProductPaginationAdapter: IPaginationAdapter = { + name: 'ProductPaginationAdapter', + expectedVariableNames: [`from`, `to`], + start: () => ({ + // Our search is inclusive, so 0 -> PAGE_SIZE - 1 fetches PAGE_SIZE items + variables: { from: 0, to: PAGE_SIZE - 1 }, + hasNextPage: true, + }), + next: (state, page) => { + const from = Number(state.variables.from) + PAGE_SIZE + const to = Number(state.variables.to) + PAGE_SIZE + + return { + variables: { + from, + to, + }, + // VTEX Search API hard limits us to 2500 products at most + hasNextPage: page.products.length > 0 && to < 2500, + } + }, + concat: (result, page) => ({ + products: result.products.concat(page.products), + }), + getItems: (pageOrResult) => pageOrResult.products, +} diff --git a/packages/gatsby-source-vtex/src/md5.ts b/packages/gatsby-source-vtex/src/md5.ts deleted file mode 100644 index 49dfaef9ff..0000000000 --- a/packages/gatsby-source-vtex/src/md5.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { createHash } from 'crypto' - -export const md5 = (x: string) => createHash('md5').update(x).digest('hex') diff --git a/packages/gatsby-source-vtex/src/staticPaths.ts b/packages/gatsby-source-vtex/src/staticPaths.ts index 7c20de8853..bd88936fae 100644 --- a/packages/gatsby-source-vtex/src/staticPaths.ts +++ b/packages/gatsby-source-vtex/src/staticPaths.ts @@ -3,10 +3,9 @@ import { join } from 'path' import { readFile } from 'fs' import slugify from 'slugify' -import pMap from 'p-map' import { api } from './api' -import { fetchIS, fetchVTEX } from './fetch' +import { fetchVTEX } from './fetch' import type { Brand, Category } from './types' interface Options { @@ -16,13 +15,6 @@ interface Options { maxNumPaths?: number // max number of staticPaths to generate } -interface SearchResult { - products: Array<{ url: string }> - pagination: { - count: number - } -} - const readFileAsync = promisify(readFile) const dfs = (root: Category, paths: string[]) => { @@ -46,7 +38,6 @@ const staticPaths = async ({ tenant, workspace = 'master', environment = 'vtexcommercestable', - maxNumPaths = 100, }: Options): Promise => { const paths: string[] = await staticPathsFromJson() // final array containing all paths @@ -89,35 +80,7 @@ const staticPaths = async ({ ) } - // Add product paths into the final array - - // This generates at least `itemsPerPage` and at most 2500 product paths - // `itemsPerPage` is an arbritary number, however 2500 is hard coded in VTEX search - const itemsPerPage = 100 - const totalItems = Math.min( - 2500, - Math.max(itemsPerPage, maxNumPaths - paths.length) - ) - - const pages = new Array(Math.ceil(totalItems / itemsPerPage)).fill(null) - - const productUrls = await pMap( - pages, - (_, page) => - fetchIS( - api.is.search({ - 'hide-unavailable-items': false, - sort: 'orders:desc', - count: itemsPerPage, - operator: 'and', - page: page + 1, - }), - options - ).then(({ products }) => products.map((x) => x.url)), - { concurrency: 10 } - ).then((x) => x.flat()) - - return [...paths, ...productUrls] + return paths } export default staticPaths diff --git a/packages/gatsby-source-vtex/test/api.test.ts b/packages/gatsby-source-vtex/test/api.test.ts index 4741c4107f..689cce7860 100644 --- a/packages/gatsby-source-vtex/test/api.test.ts +++ b/packages/gatsby-source-vtex/test/api.test.ts @@ -1,19 +1,6 @@ import { api } from '../src/api' describe('API module url handling', () => { - it('Generates a simple IS url', () => { - const url = api.is.search({ - page: 1, - count: 10, - sort: 'orders:desc', - operator: 'or', - }) - - expect(url).toBe( - '/api/split/product_search/trade-policy/1?page=1&count=10&sort=orders%3Adesc&operator=or' - ) - }) - it('Generates a simple brand list url', () => { const url = api.catalog.brand.list({ page: 10, pageSize: 10 }) diff --git a/packages/gatsby-theme-store/src/templates/__generated__/BrowserProductPageQuery.graphql.ts b/packages/gatsby-theme-store/src/[slug]/__generated__/BrowserProductPageQuery.graphql.ts similarity index 57% rename from packages/gatsby-theme-store/src/templates/__generated__/BrowserProductPageQuery.graphql.ts rename to packages/gatsby-theme-store/src/[slug]/__generated__/BrowserProductPageQuery.graphql.ts index 7fd0614d0f..e28ff054ec 100644 --- a/packages/gatsby-theme-store/src/templates/__generated__/BrowserProductPageQuery.graphql.ts +++ b/packages/gatsby-theme-store/src/[slug]/__generated__/BrowserProductPageQuery.graphql.ts @@ -22,14 +22,14 @@ export type BrowserProductPageQueryQueryVariables = Exact<{ }>; -export type BrowserProductPageQueryQuery = { vtex: { product: Maybe<{ productReference: Maybe, productName: Maybe, linkText: Maybe, description: Maybe, brand: Maybe, titleTag: Maybe, metaTagDescription: Maybe, id: Maybe, items: Maybe, complementName: Maybe, itemId: Maybe, ean: Maybe, referenceId: Maybe }>>>, images: Maybe, imageText: Maybe }>>>, videos: Maybe }>>>, sellers: Maybe, price: Maybe, listPrice: Maybe, availableQuantity: Maybe, priceValidUntil: Maybe }> }>>> }>>>, productClusters: Maybe, name: Maybe }>>>, properties: Maybe, originalName: Maybe, values: Maybe>> }>>>, categoryTree: Maybe, name: Maybe }>>> }> } }; +export type BrowserProductPageQueryQuery = { vtex: { product: { productReference: Maybe, productName: Maybe, linkText: Maybe, description: Maybe, brand: Maybe, titleTag: Maybe, metaTagDescription: Maybe, id: Maybe, items: Maybe, complementName: Maybe, itemId: Maybe, ean: Maybe, referenceId: Maybe }>>>, images: Maybe, imageText: Maybe }>>>, videos: Maybe }>>>, sellers: Maybe, price: Maybe, listPrice: Maybe, availableQuantity: Maybe, priceValidUntil: Maybe }> }>>> }>>>, productClusters: Maybe, name: Maybe }>>>, properties: Maybe, originalName: Maybe, values: Maybe>> }>>>, categoryTree: Maybe, name: Maybe }>>> } } }; // Query Related Code export const BrowserProductPageQuery = { query: process.env.NODE_ENV === 'production' ? undefined : "query BrowserProductPageQuery($slug: String!) {\n vtex {\n product(slug: $slug) {\n productReference\n productName\n linkText\n items {\n name\n complementName\n itemId\n referenceId {\n value: Value\n }\n images {\n imageUrl\n imageText\n }\n videos {\n videoUrl\n }\n sellers {\n commercialOffer: commertialOffer {\n price: Price\n listPrice: ListPrice\n availableQuantity: AvailableQuantity\n priceValidUntil: PriceValidUntil\n spotPrice\n }\n }\n ean\n }\n productClusters {\n id\n name\n }\n properties {\n name\n originalName\n values\n }\n description\n brand\n categoryTree {\n href\n name\n }\n titleTag\n metaTagDescription\n id: productId\n }\n }\n}\n", - sha256Hash: "3d4c4e6b89a742c6e0d444b5ae19a555388f1c23f777fabf5dd53c34bac5eacf", + sha256Hash: "5ae30d87517efb2108496f7b19f96404f7dda779f30a2f520eca2f6c88b738ee", operationName: "BrowserProductPageQuery", } diff --git a/packages/gatsby-theme-store/src/gatsby-node.ts b/packages/gatsby-theme-store/src/gatsby-node.ts index 82a2e4fa42..32bee4bce7 100644 --- a/packages/gatsby-theme-store/src/gatsby-node.ts +++ b/packages/gatsby-theme-store/src/gatsby-node.ts @@ -52,7 +52,6 @@ export const createPages = async ({ const { data: staticPaths, errors } = await graphql<{ searches: { nodes: StaticPath[] } - products: { nodes: StaticPath[] } }>(` query GetAllStaticPaths { searches: allStaticPath( @@ -61,20 +60,11 @@ export const createPages = async ({ } ) { nodes { - ...staticPath + id + path + pageType } } - products: allStaticPath(filter: { pageType: { eq: "Product" } }) { - nodes { - ...staticPath - } - } - } - - fragment staticPath on StaticPath { - id - path - pageType } `) @@ -88,7 +78,6 @@ export const createPages = async ({ const { searches: { nodes: searches = [] }, - products: { nodes: products = [] }, } = staticPaths! /** @@ -136,32 +125,10 @@ export const createPages = async ({ }) } - /** - * Create product static paths - */ - for (const product of products) { - const { path } = product - const [, slug] = path.split('/') - - createPage({ - path, - component: resolve(__dirname, './src/templates/product.server.tsx'), - context: { slug }, - }) - } - /** * CLIENT ONLY PATHS */ - // Client-side rendered product pages - createPage({ - path: '/__client_side_product__/p', - matchPath: '/:slug/p', - component: resolve(__dirname, './src/templates/product.browser.tsx'), - context: {}, - }) - // Client side, full text, search page createPage({ path: '/s/__client_side_search__', diff --git a/packages/gatsby-theme-store/src/templates/product.browser.tsx b/packages/gatsby-theme-store/src/pages/[slug]/p.tsx similarity index 61% rename from packages/gatsby-theme-store/src/templates/product.browser.tsx rename to packages/gatsby-theme-store/src/pages/[slug]/p.tsx index 871ec1c22e..bf2031a0f3 100644 --- a/packages/gatsby-theme-store/src/templates/product.browser.tsx +++ b/packages/gatsby-theme-store/src/pages/[slug]/p.tsx @@ -1,35 +1,34 @@ -import { useMatch } from '@reach/router' import { gql } from '@vtex/gatsby-plugin-graphql' import React from 'react' import type { PageProps } from 'gatsby' import type { FC } from 'react' -import HybridWrapper from '../components/HybridWrapper' -import Layout from '../components/Layout' -import { useQuery } from '../sdk/graphql/useQuery' -import ProductView from '../views/product' -import AboveTheFoldPreview from '../views/product/AboveTheFoldPreview' -import { BrowserProductPageQuery } from './__generated__/BrowserProductPageQuery.graphql' +import HybridWrapper from '../../components/HybridWrapper' +import Layout from '../../components/Layout' +import { useQuery } from '../../sdk/graphql/useQuery' +import ProductView from '../../views/product' +import AboveTheFoldPreview from '../../views/product/AboveTheFoldPreview' +import { BrowserProductPageQuery } from '../../[slug]/__generated__/BrowserProductPageQuery.graphql' import type { BrowserProductPageQueryQuery, BrowserProductPageQueryQueryVariables, -} from './__generated__/BrowserProductPageQuery.graphql' +} from '../../[slug]/__generated__/BrowserProductPageQuery.graphql' -export type BrowserProductPageProps = PageProps +export type BrowserProductPageProps = PageProps & { slug: string } const ProductPage: FC = (props) => { - const { slug } = useMatch(props.pageResources.page.matchPath!)! - const { data } = useQuery< BrowserProductPageQueryQuery, BrowserProductPageQueryQueryVariables >({ ...BrowserProductPageQuery, - variables: { slug }, + variables: { slug: props.slug }, suspense: true, }) - return + return ( + + ) } const Page: FC = (props) => ( diff --git a/packages/gatsby-theme-store/src/pages/{StoreProduct.slug}/p.tsx b/packages/gatsby-theme-store/src/pages/{StoreProduct.slug}/p.tsx new file mode 100644 index 0000000000..cae77036a3 --- /dev/null +++ b/packages/gatsby-theme-store/src/pages/{StoreProduct.slug}/p.tsx @@ -0,0 +1,45 @@ +import { graphql } from 'gatsby' +import React from 'react' +import type { PageProps } from 'gatsby' +import type { FC } from 'react' + +import Layout from '../../components/Layout' +import ProductView from '../../views/product' +import type { + ServerProductPageQueryQuery, + ServerProductPageQueryQueryVariables, +} from '../../{StoreProduct.slug}/__generated__/ServerProductPageQuery.graphql' + +export type ServerProductPageProps = PageProps< + ServerProductPageQueryQuery, + ServerProductPageQueryQueryVariables +> + +const Page: FC = (props) => ( + + + +) + +export const query = graphql` + query ServerProductPageQuery($id: String!) { + product: storeProduct(id: { eq: $id }) { + ...ProductDetailsTemplate_product + ...StructuredProductFragment_product + titleTag + metaTagDescription + id: productId + description + categoryTree { + name + href + } + } + } +` + +export default Page diff --git a/packages/gatsby-theme-store/src/sdk/channel/__generated__/DefaultSalesChannelQuery.graphql.ts b/packages/gatsby-theme-store/src/sdk/channel/__generated__/DefaultSalesChannelQuery.graphql.ts index 20528f75e4..70a21b992c 100644 --- a/packages/gatsby-theme-store/src/sdk/channel/__generated__/DefaultSalesChannelQuery.graphql.ts +++ b/packages/gatsby-theme-store/src/sdk/channel/__generated__/DefaultSalesChannelQuery.graphql.ts @@ -20,7 +20,7 @@ type Scalars = { export type DefaultSalesChannelQueryQueryVariables = Exact<{ [key: string]: never; }>; -export type DefaultSalesChannelQueryQuery = { allChannel: { edges: Array<{ node: { salesChannel: Maybe } }> } }; +export type DefaultSalesChannelQueryQuery = { allChannel: { edges: Array<{ node: { salesChannel: Maybe } }> } }; // Query Related Code diff --git a/packages/gatsby-theme-store/src/sdk/pixel/events.ts b/packages/gatsby-theme-store/src/sdk/pixel/events.ts index f08f7502a4..796bdfcbd7 100644 --- a/packages/gatsby-theme-store/src/sdk/pixel/events.ts +++ b/packages/gatsby-theme-store/src/sdk/pixel/events.ts @@ -1,5 +1,5 @@ -import type { ServerProductPageQueryQuery } from '../../templates/__generated__/ServerProductPageQuery.graphql' import type { ProductSummary_ProductFragment } from '../../components/ProductSummary/__generated__/ProductSummary_product.graphql' +import type { ServerProductPageQueryQuery } from '../../{StoreProduct.slug}/__generated__/ServerProductPageQuery.graphql' import type { OrderFormFragment_OrderFormFragment } from '../orderForm/controller/__generated__/OrderFormFragment_orderForm.graphql' import type { OrderFormItem } from '../orderForm/types' @@ -60,7 +60,7 @@ export type OrderPlacedData = Order export type OrderPlacedTrackedData = Order export interface ProductViewData { - product: ServerProductPageQueryQuery['vtex']['product'] + product: ServerProductPageQueryQuery['product'] } export interface ProductClickData { diff --git a/packages/gatsby-theme-store/src/templates/__generated__/ServerProductPageQuery.graphql.ts b/packages/gatsby-theme-store/src/templates/__generated__/ServerProductPageQuery.graphql.ts deleted file mode 100644 index 17504c7906..0000000000 --- a/packages/gatsby-theme-store/src/templates/__generated__/ServerProductPageQuery.graphql.ts +++ /dev/null @@ -1,35 +0,0 @@ - -/** - * Warning: This is an autogenerated file. - * - * Changes in this file won't take effect and will be overwritten - */ - -// Base Types -type Exact = { [K in keyof T]: T[K] }; -type Maybe = T | null | undefined -type Scalars = { - Boolean: boolean - String: string - Float: number - Int: number - ID: string -} - -// Operation related types -export type ServerProductPageQueryQueryVariables = Exact<{ - slug: Scalars['String']; -}>; - - -export type ServerProductPageQueryQuery = { vtex: { product: Maybe<{ productReference: Maybe, productName: Maybe, linkText: Maybe, description: Maybe, brand: Maybe, titleTag: Maybe, metaTagDescription: Maybe, id: Maybe, items: Maybe, complementName: Maybe, itemId: Maybe, ean: Maybe, referenceId: Maybe }>>>, images: Maybe, imageText: Maybe }>>>, videos: Maybe }>>>, sellers: Maybe, price: Maybe, listPrice: Maybe, availableQuantity: Maybe, priceValidUntil: Maybe }> }>>> }>>>, productClusters: Maybe, name: Maybe }>>>, properties: Maybe, originalName: Maybe, values: Maybe>> }>>>, categoryTree: Maybe, name: Maybe }>>> }> } }; - - -// Query Related Code - -export const ServerProductPageQuery = { - query: process.env.NODE_ENV === 'production' ? undefined : "query ServerProductPageQuery($slug: String!) {\n vtex {\n product(slug: $slug) {\n productReference\n productName\n linkText\n items {\n name\n complementName\n itemId\n referenceId {\n value: Value\n }\n images {\n imageUrl\n imageText\n }\n videos {\n videoUrl\n }\n sellers {\n commercialOffer: commertialOffer {\n price: Price\n listPrice: ListPrice\n availableQuantity: AvailableQuantity\n priceValidUntil: PriceValidUntil\n spotPrice\n }\n }\n ean\n }\n productClusters {\n id\n name\n }\n properties {\n name\n originalName\n values\n }\n description\n brand\n categoryTree {\n href\n name\n }\n titleTag\n metaTagDescription\n id: productId\n }\n }\n}\n", - sha256Hash: "50c19934f23574377d34c26b53baf6b462e66b247152266fcf0bce69a1dd39f0", - operationName: "ServerProductPageQuery", -} - diff --git a/packages/gatsby-theme-store/src/templates/product.server.tsx b/packages/gatsby-theme-store/src/templates/product.server.tsx deleted file mode 100644 index 60c1230802..0000000000 --- a/packages/gatsby-theme-store/src/templates/product.server.tsx +++ /dev/null @@ -1,43 +0,0 @@ -import { graphql } from 'gatsby' -import React from 'react' -import type { PageProps } from 'gatsby' -import type { FC } from 'react' - -import Layout from '../components/Layout' -import ProductView from '../views/product' -import type { - ServerProductPageQueryQuery, - ServerProductPageQueryQueryVariables, -} from './__generated__/ServerProductPageQuery.graphql' - -export type ServerProductPageProps = PageProps< - ServerProductPageQueryQuery, - ServerProductPageQueryQueryVariables -> - -const Page: FC = (props) => ( - - - -) - -export const query = graphql` - query ServerProductPageQuery($slug: String!) { - vtex { - product(slug: $slug) { - ...ProductDetailsTemplate_product - ...StructuredProductFragment_product - titleTag - metaTagDescription - id: productId - description - categoryTree { - name - href - } - } - } - } -` - -export default Page diff --git a/packages/gatsby-theme-store/src/views/product/AboveTheFold.tsx b/packages/gatsby-theme-store/src/views/product/AboveTheFold.tsx index 9b047cef14..37ad7d5260 100644 --- a/packages/gatsby-theme-store/src/views/product/AboveTheFold.tsx +++ b/packages/gatsby-theme-store/src/views/product/AboveTheFold.tsx @@ -49,7 +49,7 @@ const AboveTheFold: FC = (props) => ( ) export const fragment = graphql` - fragment ProductDetailsTemplate_product on VTEX_Product { + fragment ProductDetailsTemplate_product on StoreProduct { productReference productName linkText diff --git a/packages/gatsby-theme-store/src/views/product/SEO/useBreadcrumbJsonLd.ts b/packages/gatsby-theme-store/src/views/product/SEO/useBreadcrumbJsonLd.ts index ad01cf6dda..936856fb09 100644 --- a/packages/gatsby-theme-store/src/views/product/SEO/useBreadcrumbJsonLd.ts +++ b/packages/gatsby-theme-store/src/views/product/SEO/useBreadcrumbJsonLd.ts @@ -12,12 +12,7 @@ type BreadcrumbJSONLD = ComponentPropsWithoutRef export const useBreadcrumbJsonLd = ( options: Options ): BreadcrumbJSONLD | null => { - const { - data: { - vtex: { product }, - }, - } = options - + const { product } = options const { host, pathname } = useLocation() return useMemo(() => { @@ -31,7 +26,7 @@ export const useBreadcrumbJsonLd = ( const { categoryTree, productName } = product - const itemListElements = categoryTree.map((item, index: number) => ({ + const itemListElements = categoryTree.map((item: any, index: number) => ({ position: index + 1, name: item!.name!, item: `https://${host}${item!.href}`, diff --git a/packages/gatsby-theme-store/src/views/product/SEO/useMetadata.ts b/packages/gatsby-theme-store/src/views/product/SEO/useMetadata.ts index 4c6fe66048..88782ab7be 100644 --- a/packages/gatsby-theme-store/src/views/product/SEO/useMetadata.ts +++ b/packages/gatsby-theme-store/src/views/product/SEO/useMetadata.ts @@ -38,18 +38,13 @@ export const useMetadata = ( ` ) - const { - data: { - vtex: { product }, - }, - } = options - + const { product } = options const title = product?.titleTag || siteMetadata.title const description = product?.metaTagDescription || siteMetadata.description const canonical = `https://${host}${pathname}` const images = useMemo( () => - product?.items?.[0]?.images?.map((image) => ({ + product?.items?.[0]?.images?.map((image: any) => ({ url: image?.imageUrl, alt: image?.imageText, })), diff --git a/packages/gatsby-theme-store/src/views/product/SEO/useProductJsonLd.ts b/packages/gatsby-theme-store/src/views/product/SEO/useProductJsonLd.ts index a602261fd1..197935b35e 100644 --- a/packages/gatsby-theme-store/src/views/product/SEO/useProductJsonLd.ts +++ b/packages/gatsby-theme-store/src/views/product/SEO/useProductJsonLd.ts @@ -12,12 +12,7 @@ type Options = ProductViewProps type ProductJSONLD = ComponentPropsWithoutRef export const useProductJsonLd = (options: Options): ProductJSONLD | null => { - const { - data: { - vtex: { product }, - }, - } = options - + const { product } = options const { host, pathname } = useLocation() const [currency] = useCurrency() @@ -29,7 +24,7 @@ export const useProductJsonLd = (options: Options): ProductJSONLD | null => { const { productName: name, items, description, brand } = product const [sku] = items! - const images = sku!.images!.map((i) => i!.imageUrl!) + const images = sku!.images!.map((i: any) => i!.imageUrl!) const seller = sku!.sellers?.[0] if (!images || !seller || !brand) { @@ -60,7 +55,7 @@ export const useProductJsonLd = (options: Options): ProductJSONLD | null => { } export const fragment = graphql` - fragment StructuredProductFragment_product on VTEX_Product { + fragment StructuredProductFragment_product on StoreProduct { productName description brand diff --git a/packages/gatsby-theme-store/src/views/product/__generated__/AsyncProductQuery.graphql.ts b/packages/gatsby-theme-store/src/views/product/__generated__/AsyncProductQuery.graphql.ts index c9c0998611..899ff5ddfc 100644 --- a/packages/gatsby-theme-store/src/views/product/__generated__/AsyncProductQuery.graphql.ts +++ b/packages/gatsby-theme-store/src/views/product/__generated__/AsyncProductQuery.graphql.ts @@ -18,19 +18,19 @@ type Scalars = { // Operation related types export type AsyncProductQueryQueryVariables = Exact<{ - slug: Maybe; + slug: Scalars['String']; regionId: Maybe; }>; -export type AsyncProductQueryQuery = { vtex: { product: Maybe<{ productName: Maybe, productReference: Maybe, description: Maybe, linkText: Maybe, id: Maybe, specificationGroups: Maybe, specifications: Maybe, values: Maybe>> }>>> }>>>, items: Maybe, variations: Maybe, values: Maybe>> }>>>, images: Maybe, imageText: Maybe }>>>, sellers: Maybe, commercialOffer: Maybe<{ spotPrice: Maybe, availableQuantity: Maybe, price: Maybe, listPrice: Maybe, maxInstallments: Maybe, numberOfInstallments: Maybe }>>>, installments: Maybe, numberOfInstallments: Maybe, interestRate: Maybe }>>>, gifts: Maybe, images: Maybe }>>> }>>>, teasers: Maybe }>> }> }>>> }>>> }> } }; +export type AsyncProductQueryQuery = { vtex: { product: { productName: Maybe, productReference: Maybe, description: Maybe, linkText: Maybe, id: Maybe, specificationGroups: Maybe, specifications: Maybe, values: Maybe>> }>>> }>>>, items: Maybe, variations: Maybe, values: Maybe>> }>>>, images: Maybe, imageText: Maybe }>>>, sellers: Maybe, commercialOffer: Maybe<{ spotPrice: Maybe, availableQuantity: Maybe, price: Maybe, listPrice: Maybe, installments: Maybe, numberOfInstallments: Maybe, interestRate: Maybe }>>>, gifts: Maybe, images: Maybe }>>> }>>>, teasers: Array }>> }> }>>> }>>> } } }; // Query Related Code export const AsyncProductQuery = { - query: process.env.NODE_ENV === 'production' ? undefined : "query AsyncProductQuery($slug: String, $regionId: String) {\n vtex {\n product(slug: $slug, regionId: $regionId) {\n id: productId\n productName\n productReference\n description\n linkText\n specificationGroups {\n name\n specifications {\n name\n values\n }\n }\n items {\n variations {\n name\n values\n }\n itemId\n images {\n imageUrl\n imageText\n }\n sellers {\n sellerId\n commercialOffer: commertialOffer {\n maxInstallments: Installments(criteria: MAX_WITHOUT_INTEREST) {\n value: Value\n numberOfInstallments: NumberOfInstallments\n }\n installments: Installments(criteria: ALL) {\n value: Value\n numberOfInstallments: NumberOfInstallments\n interestRate: InterestRate\n }\n availableQuantity: AvailableQuantity\n price: Price\n listPrice: ListPrice\n gifts {\n skuName\n images {\n imageUrl\n }\n }\n spotPrice\n teasers {\n name\n }\n }\n }\n }\n }\n }\n}\n", - sha256Hash: "fa11f45992190b5d303d06eecc28f19ea5750264baf37ef74397557240e80fb8", + query: process.env.NODE_ENV === 'production' ? undefined : "query AsyncProductQuery($slug: String!, $regionId: String) {\n vtex {\n product(slug: $slug, regionId: $regionId) {\n id: productId\n productName\n productReference\n description\n linkText\n specificationGroups {\n name\n specifications {\n name\n values\n }\n }\n items {\n variations {\n name\n values\n }\n itemId\n images {\n imageUrl\n imageText\n }\n sellers {\n sellerId\n commercialOffer: commertialOffer {\n installments: Installments {\n value: Value\n numberOfInstallments: NumberOfInstallments\n interestRate: InterestRate\n }\n availableQuantity: AvailableQuantity\n price: Price\n listPrice: ListPrice\n gifts {\n skuName\n images {\n imageUrl\n }\n }\n spotPrice\n teasers {\n name\n }\n }\n }\n }\n }\n }\n}\n", + sha256Hash: "67e948cb833f6e27c0c160df6f8c0338f0d53430e1eb16f7ca8ef1d0070e02cb", operationName: "AsyncProductQuery", } diff --git a/packages/gatsby-theme-store/src/views/product/index.tsx b/packages/gatsby-theme-store/src/views/product/index.tsx index 31a2d351e7..a5e6a041c1 100644 --- a/packages/gatsby-theme-store/src/views/product/index.tsx +++ b/packages/gatsby-theme-store/src/views/product/index.tsx @@ -6,18 +6,18 @@ import { usePixelSendEvent } from '../../sdk/pixel/usePixelSendEvent' import AboveTheFold from './AboveTheFold' import BelowTheFoldPreview from './BelowTheFoldPreview' import SEO from './SEO' -import type { ServerProductPageProps } from '../../templates/product.server' +import type { ServerProductPageProps } from '../../pages/{StoreProduct.slug}/p' const belowTheFoldPreloader = () => import('./BelowTheFold') const BelowTheFold = lazy(belowTheFoldPreloader) export type ProductViewProps = { - data: ServerProductPageProps['data'] + product: ServerProductPageProps['data']['product'] slug: string } const ProductView: FC = (props) => { - const { data } = props + const { product } = props usePixelSendEvent( () => [ @@ -34,11 +34,11 @@ const ProductView: FC = (props) => { { type: 'vtex:productView', data: { - product: data?.vtex.product, + product, }, }, ], - data?.vtex.product?.id ?? '' + product?.id ?? '' ) return ( diff --git a/packages/gatsby-theme-store/src/views/product/useAsyncProduct.ts b/packages/gatsby-theme-store/src/views/product/useAsyncProduct.ts index 48d5ce4369..d184ae43c2 100644 --- a/packages/gatsby-theme-store/src/views/product/useAsyncProduct.ts +++ b/packages/gatsby-theme-store/src/views/product/useAsyncProduct.ts @@ -33,7 +33,7 @@ export const useAsyncProduct = ( } export const query = gql` - query AsyncProductQuery($slug: String, $regionId: String) { + query AsyncProductQuery($slug: String!, $regionId: String) { vtex { product(slug: $slug, regionId: $regionId) { id: productId @@ -61,11 +61,7 @@ export const query = gql` sellers { sellerId commercialOffer: commertialOffer { - maxInstallments: Installments(criteria: MAX_WITHOUT_INTEREST) { - value: Value - numberOfInstallments: NumberOfInstallments - } - installments: Installments(criteria: ALL) { + installments: Installments { value: Value numberOfInstallments: NumberOfInstallments interestRate: InterestRate diff --git a/packages/gatsby-theme-store/src/views/search/SEO/useBreadcrumbJsonLd.tsx b/packages/gatsby-theme-store/src/views/search/SEO/useBreadcrumbJsonLd.tsx index dd6150c5c3..2a97398385 100644 --- a/packages/gatsby-theme-store/src/views/search/SEO/useBreadcrumbJsonLd.tsx +++ b/packages/gatsby-theme-store/src/views/search/SEO/useBreadcrumbJsonLd.tsx @@ -25,7 +25,7 @@ export const useBreadcrumb = ({ } return { - itemListElements: breadcrumb.map((item, index: number) => ({ + itemListElements: breadcrumb.map((item: any, index: number) => ({ position: index + 1, name: item!.name!, item: `${siteUrl}${item!.href}`, diff --git a/packages/gatsby-theme-store/src/{StoreProduct.slug}/__generated__/ServerProductPageQuery.graphql.ts b/packages/gatsby-theme-store/src/{StoreProduct.slug}/__generated__/ServerProductPageQuery.graphql.ts new file mode 100644 index 0000000000..799825ae73 --- /dev/null +++ b/packages/gatsby-theme-store/src/{StoreProduct.slug}/__generated__/ServerProductPageQuery.graphql.ts @@ -0,0 +1,35 @@ + +/** + * Warning: This is an autogenerated file. + * + * Changes in this file won't take effect and will be overwritten + */ + +// Base Types +type Exact = { [K in keyof T]: T[K] }; +type Maybe = T | null | undefined +type Scalars = { + Boolean: boolean + String: string + Float: number + Int: number + ID: string +} + +// Operation related types +export type ServerProductPageQueryQueryVariables = Exact<{ + id: Scalars['String']; +}>; + + +export type ServerProductPageQueryQuery = { product: Maybe<{ productReference: Maybe, productName: Maybe, linkText: Maybe, description: Maybe, brand: Maybe, titleTag: Maybe, metaTagDescription: Maybe, id: Maybe, items: Maybe, complementName: Maybe, itemId: Maybe, ean: Maybe, referenceId: Maybe }>>>, images: Maybe, imageText: Maybe }>>>, videos: Maybe }>>>, sellers: Maybe, price: Maybe, listPrice: Maybe, availableQuantity: Maybe, priceValidUntil: Maybe }> }>>> }>>>, productClusters: Maybe, name: Maybe }>>>, properties: Maybe, originalName: Maybe, values: Maybe>> }>>>, categoryTree: Maybe, name: Maybe }>>> }> }; + + +// Query Related Code + +export const ServerProductPageQuery = { + query: process.env.NODE_ENV === 'production' ? undefined : "query ServerProductPageQuery($id: String!) {\n product: storeProduct(id: {eq: $id}) {\n productReference\n productName\n linkText\n items {\n name\n complementName\n itemId\n referenceId {\n value: Value\n }\n images {\n imageUrl\n imageText\n }\n videos {\n videoUrl\n }\n sellers {\n commercialOffer: commertialOffer {\n price: Price\n listPrice: ListPrice\n availableQuantity: AvailableQuantity\n priceValidUntil: PriceValidUntil\n spotPrice\n }\n }\n ean\n }\n productClusters {\n id\n name\n }\n properties {\n name\n originalName\n values\n }\n description\n brand\n categoryTree {\n href\n name\n }\n titleTag\n metaTagDescription\n id: productId\n }\n}\n", + sha256Hash: "2197822cbee5e25df38fca975fb2b2a3c802db3590fd2e72a4897255e59614d3", + operationName: "ServerProductPageQuery", +} + diff --git a/yarn.lock b/yarn.lock index b716047458..f50902ca49 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2024,17 +2024,15 @@ is-promise "4.0.0" tslib "~2.1.0" -"@graphql-tools/delegate@^6.0.15", "@graphql-tools/delegate@^6.2.4": - version "6.2.4" - resolved "https://registry.yarnpkg.com/@graphql-tools/delegate/-/delegate-6.2.4.tgz#db553b63eb9512d5eb5bbfdfcd8cb1e2b534699c" - integrity sha512-mXe6DfoWmq49kPcDrpKHgC2DSWcD5q0YCaHHoXYPAOlnLH8VMTY8BxcE8y/Do2eyg+GLcwAcrpffVszWMwqw0w== +"@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: - "@ardatan/aggregate-error" "0.0.6" - "@graphql-tools/schema" "^6.2.4" - "@graphql-tools/utils" "^6.2.4" + "@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/delegate@^7.0.1", "@graphql-tools/delegate@^7.0.7": version "7.1.1" @@ -2049,6 +2047,19 @@ is-promise "4.0.0" tslib "~2.1.0" +"@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/graphql-file-loader@^6.0.0": version "6.2.7" resolved "https://registry.yarnpkg.com/@graphql-tools/graphql-file-loader/-/graphql-file-loader-6.2.7.tgz#d3720f2c4f4bb90eb2a03a7869a780c61945e143" @@ -2114,14 +2125,6 @@ relay-compiler "10.1.0" tslib "~2.0.1" -"@graphql-tools/schema@^6.2.4": - version "6.2.4" - resolved "https://registry.yarnpkg.com/@graphql-tools/schema/-/schema-6.2.4.tgz#cc4e9f5cab0f4ec48500e666719d99fc5042481d" - integrity sha512-rh+14lSY1q8IPbEv2J9x8UBFJ5NrDX9W5asXEUlPp+7vraLp/Tiox4GXdgyA92JhwpYco3nTf5Bo2JDMt1KnAQ== - dependencies: - "@graphql-tools/utils" "^6.2.4" - 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" @@ -2130,6 +2133,15 @@ "@graphql-tools/utils" "^7.1.2" tslib "~2.1.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.2.0" + value-or-promise "1.0.6" + "@graphql-tools/url-loader@^6.0.0": version "6.8.2" resolved "https://registry.yarnpkg.com/@graphql-tools/url-loader/-/url-loader-6.8.2.tgz#a62b3e1988b4c49c6c488aaba66b1c7078886023" @@ -2153,7 +2165,7 @@ valid-url "1.0.9" ws "7.4.4" -"@graphql-tools/utils@^6", "@graphql-tools/utils@^6.0.0", "@graphql-tools/utils@^6.2.4": +"@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== @@ -2171,16 +2183,14 @@ camel-case "4.1.2" tslib "~2.1.0" -"@graphql-tools/wrap@^6.0.15": - version "6.2.4" - resolved "https://registry.yarnpkg.com/@graphql-tools/wrap/-/wrap-6.2.4.tgz#2709817da6e469753735a9fe038c9e99736b2c57" - integrity sha512-cyQgpybolF9DjL2QNOvTS1WDCT/epgYoiA8/8b3nwv5xmMBQ6/6nYnZwityCZ7njb7MMyk7HBEDNNlP9qNJDcA== +"@graphql-tools/utils@^7.8.1": + version "7.10.0" + resolved "https://registry.yarnpkg.com/@graphql-tools/utils/-/utils-7.10.0.tgz#07a4cb5d1bec1ff1dc1d47a935919ee6abd38699" + integrity sha512-d334r6bo9mxdSqZW6zWboEnnOOFRrAPVQJ7LkU8/6grglrbcu6WhwCLzHb90E94JI3TD3ricC3YGbUqIi9Xg0w== dependencies: - "@graphql-tools/delegate" "^6.2.4" - "@graphql-tools/schema" "^6.2.4" - "@graphql-tools/utils" "^6.2.4" - is-promise "4.0.0" - tslib "~2.0.1" + "@ardatan/aggregate-error" "0.0.6" + camel-case "4.1.2" + tslib "~2.2.0" "@graphql-tools/wrap@^7.0.4": version "7.0.5" @@ -2193,6 +2203,17 @@ is-promise "4.0.0" tslib "~2.0.1" +"@graphql-tools/wrap@^7.0.8": + 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.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/address@2.x.x": version "2.1.4" resolved "https://registry.yarnpkg.com/@hapi/address/-/address-2.1.4.tgz#5d67ed43f3fd41a69d4b9ff7b56e7c0d1d0a81e5" @@ -5454,28 +5475,27 @@ integrity sha512-S9q47ByT2pPvD65IvrWp7qppVMpk9WGMbVq9wbWZOHg6tnXSD4vyhao6nOSBwwfDdV2p3Kx9evA9vI+XWTfDvw== "@typescript-eslint/eslint-plugin@^2.10.0", "@typescript-eslint/eslint-plugin@^2.12.0", "@typescript-eslint/eslint-plugin@^4", "@typescript-eslint/eslint-plugin@^4.15.2", "@typescript-eslint/eslint-plugin@^4.18.0": - version "4.27.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.27.0.tgz#0b7fc974e8bc9b2b5eb98ed51427b0be529b4ad0" - integrity sha512-DsLqxeUfLVNp3AO7PC3JyaddmEHTtI9qTSAs+RB6ja27QvIM0TA8Cizn1qcS6vOu+WDLFJzkwkgweiyFhssDdQ== + version "4.28.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.28.0.tgz#1a66f03b264844387beb7dc85e1f1d403bd1803f" + integrity sha512-KcF6p3zWhf1f8xO84tuBailV5cN92vhS+VT7UJsPzGBm9VnQqfI9AsiMUFUCYHTYPg1uCCo+HyiDnpDuvkAMfQ== dependencies: - "@typescript-eslint/experimental-utils" "4.27.0" - "@typescript-eslint/scope-manager" "4.27.0" + "@typescript-eslint/experimental-utils" "4.28.0" + "@typescript-eslint/scope-manager" "4.28.0" debug "^4.3.1" functional-red-black-tree "^1.0.1" - lodash "^4.17.21" regexpp "^3.1.0" semver "^7.3.5" tsutils "^3.21.0" -"@typescript-eslint/experimental-utils@4.27.0": - version "4.27.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-4.27.0.tgz#78192a616472d199f084eab8f10f962c0757cd1c" - integrity sha512-n5NlbnmzT2MXlyT+Y0Jf0gsmAQzCnQSWXKy4RGSXVStjDvS5we9IWbh7qRVKdGcxT0WYlgcCYUK/HRg7xFhvjQ== +"@typescript-eslint/experimental-utils@4.28.0": + version "4.28.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-4.28.0.tgz#13167ed991320684bdc23588135ae62115b30ee0" + integrity sha512-9XD9s7mt3QWMk82GoyUpc/Ji03vz4T5AYlHF9DcoFNfJ/y3UAclRsfGiE2gLfXtyC+JRA3trR7cR296TEb1oiQ== dependencies: "@types/json-schema" "^7.0.7" - "@typescript-eslint/scope-manager" "4.27.0" - "@typescript-eslint/types" "4.27.0" - "@typescript-eslint/typescript-estree" "4.27.0" + "@typescript-eslint/scope-manager" "4.28.0" + "@typescript-eslint/types" "4.28.0" + "@typescript-eslint/typescript-estree" "4.28.0" eslint-scope "^5.1.1" eslint-utils "^3.0.0" @@ -5504,13 +5524,13 @@ eslint-utils "^2.0.0" "@typescript-eslint/parser@^2.10.0", "@typescript-eslint/parser@^2.12.0", "@typescript-eslint/parser@^4", "@typescript-eslint/parser@^4.15.2", "@typescript-eslint/parser@^4.18.0": - version "4.27.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-4.27.0.tgz#85447e573364bce4c46c7f64abaa4985aadf5a94" - integrity sha512-XpbxL+M+gClmJcJ5kHnUpBGmlGdgNvy6cehgR6ufyxkEJMGP25tZKCaKyC0W/JVpuhU3VU1RBn7SYUPKSMqQvQ== + version "4.28.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-4.28.0.tgz#2404c16751a28616ef3abab77c8e51d680a12caa" + integrity sha512-7x4D22oPY8fDaOCvkuXtYYTQ6mTMmkivwEzS+7iml9F9VkHGbbZ3x4fHRwxAb5KeuSkLqfnYjs46tGx2Nour4A== dependencies: - "@typescript-eslint/scope-manager" "4.27.0" - "@typescript-eslint/types" "4.27.0" - "@typescript-eslint/typescript-estree" "4.27.0" + "@typescript-eslint/scope-manager" "4.28.0" + "@typescript-eslint/types" "4.28.0" + "@typescript-eslint/typescript-estree" "4.28.0" debug "^4.3.1" "@typescript-eslint/scope-manager@4.19.0": @@ -5529,13 +5549,13 @@ "@typescript-eslint/types" "4.22.0" "@typescript-eslint/visitor-keys" "4.22.0" -"@typescript-eslint/scope-manager@4.27.0": - version "4.27.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.27.0.tgz#b0b1de2b35aaf7f532e89c8e81d0fa298cae327d" - integrity sha512-DY73jK6SEH6UDdzc6maF19AHQJBFVRf6fgAXHPXCGEmpqD4vYgPEzqpFz1lf/daSbOcMpPPj9tyXXDPW2XReAw== +"@typescript-eslint/scope-manager@4.28.0": + version "4.28.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.28.0.tgz#6a3009d2ab64a30fc8a1e257a1a320067f36a0ce" + integrity sha512-eCALCeScs5P/EYjwo6se9bdjtrh8ByWjtHzOkC4Tia6QQWtQr3PHovxh3TdYTuFcurkYI4rmFsRFpucADIkseg== dependencies: - "@typescript-eslint/types" "4.27.0" - "@typescript-eslint/visitor-keys" "4.27.0" + "@typescript-eslint/types" "4.28.0" + "@typescript-eslint/visitor-keys" "4.28.0" "@typescript-eslint/types@4.19.0": version "4.19.0" @@ -5547,10 +5567,10 @@ resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.22.0.tgz#0ca6fde5b68daf6dba133f30959cc0688c8dd0b6" integrity sha512-sW/BiXmmyMqDPO2kpOhSy2Py5w6KvRRsKZnV0c4+0nr4GIcedJwXAq+RHNK4lLVEZAJYFltnnk1tJSlbeS9lYA== -"@typescript-eslint/types@4.27.0": - version "4.27.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.27.0.tgz#712b408519ed699baff69086bc59cd2fc13df8d8" - integrity sha512-I4ps3SCPFCKclRcvnsVA/7sWzh7naaM/b4pBO2hVxnM3wrU51Lveybdw5WoIktU/V4KfXrTt94V9b065b/0+wA== +"@typescript-eslint/types@4.28.0": + version "4.28.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.28.0.tgz#a33504e1ce7ac51fc39035f5fe6f15079d4dafb0" + integrity sha512-p16xMNKKoiJCVZY5PW/AfILw2xe1LfruTcfAKBj3a+wgNYP5I9ZEKNDOItoRt53p4EiPV6iRSICy8EPanG9ZVA== "@typescript-eslint/typescript-estree@4.19.0": version "4.19.0" @@ -5578,13 +5598,13 @@ semver "^7.3.2" tsutils "^3.17.1" -"@typescript-eslint/typescript-estree@4.27.0": - version "4.27.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.27.0.tgz#189a7b9f1d0717d5cccdcc17247692dedf7a09da" - integrity sha512-KH03GUsUj41sRLLEy2JHstnezgpS5VNhrJouRdmh6yNdQ+yl8w5LrSwBkExM+jWwCJa7Ct2c8yl8NdtNRyQO6g== +"@typescript-eslint/typescript-estree@4.28.0": + version "4.28.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.28.0.tgz#e66d4e5aa2ede66fec8af434898fe61af10c71cf" + integrity sha512-m19UQTRtxMzKAm8QxfKpvh6OwQSXaW1CdZPoCaQuLwAq7VZMNuhJmZR4g5281s2ECt658sldnJfdpSZZaxUGMQ== dependencies: - "@typescript-eslint/types" "4.27.0" - "@typescript-eslint/visitor-keys" "4.27.0" + "@typescript-eslint/types" "4.28.0" + "@typescript-eslint/visitor-keys" "4.28.0" debug "^4.3.1" globby "^11.0.3" is-glob "^4.0.1" @@ -5607,12 +5627,12 @@ "@typescript-eslint/types" "4.22.0" eslint-visitor-keys "^2.0.0" -"@typescript-eslint/visitor-keys@4.27.0": - version "4.27.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.27.0.tgz#f56138b993ec822793e7ebcfac6ffdce0a60cb81" - integrity sha512-es0GRYNZp0ieckZ938cEANfEhsfHrzuLrePukLKtY3/KPXcq1Xd555Mno9/GOgXhKzn0QfkDLVgqWO3dGY80bg== +"@typescript-eslint/visitor-keys@4.28.0": + version "4.28.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.28.0.tgz#255c67c966ec294104169a6939d96f91c8a89434" + integrity sha512-PjJyTWwrlrvM5jazxYF5ZPs/nl0kHDZMVbuIcbpawVXaDPelp3+S9zpOz5RmVUfS/fD5l5+ZXNKnWhNYjPzCvw== dependencies: - "@typescript-eslint/types" "4.27.0" + "@typescript-eslint/types" "4.28.0" eslint-visitor-keys "^2.0.0" "@vtex-components/accordion@^0.2.3": @@ -12214,10 +12234,10 @@ gatsby-graphiql-explorer@^1.5.0: dependencies: "@babel/runtime" "^7.12.5" -gatsby-graphql-source-toolkit@^0.6.3: - version "0.6.3" - resolved "https://registry.yarnpkg.com/gatsby-graphql-source-toolkit/-/gatsby-graphql-source-toolkit-0.6.3.tgz#bb7bdc90a006c0ec1c0451fd0a362ec03353909c" - integrity sha512-Dd/tnd9fxy1mObft9fkDeyKB0WAtKAzL6RLR+Iq3GOXRXnrz/GVZhdWrZrwJEHPjhOGAe35cfAwoqlqNCu7COw== +gatsby-graphql-source-toolkit@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/gatsby-graphql-source-toolkit/-/gatsby-graphql-source-toolkit-2.0.1.tgz#9f48fc67733bb413ba9c43753f8c6642c51b80a9" + integrity sha512-oRKIaLlZNGPN2fqygvnlU47x/FFpTEHHxN7l1ztTXk1c26v4I0TAZDFokB75kKYrpUgpuqqUTP7D/eVdiGYA7w== dependencies: "@types/node-fetch" "^2.5.7" fs-extra "^9.0.1" @@ -24564,7 +24584,7 @@ tslib@^2, tslib@^2.0.0, tslib@^2.0.3, tslib@^2.1.0, tslib@~2.1.0: resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.1.0.tgz#da60860f1c2ecaa5703ab7d39bc05b6bf988b97a" integrity sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A== -tslib@^2.0.1, tslib@^2.2.0: +tslib@^2.0.1, tslib@^2.2.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== @@ -25242,6 +25262,11 @@ value-equal@^1.0.1: resolved "https://registry.yarnpkg.com/value-equal/-/value-equal-1.0.1.tgz#1e0b794c734c5c0cade179c437d356d931a34d6c" integrity sha512-NOJ6JZCAWr0zlxZt+xqCHNTEKOsrks2HQd4MqhP1qy4z1SkbEP467eNx6TgDKXMvUOb+OENfJCZwM+16n7fRfw== +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== + vary@^1, vary@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc"