diff --git a/node/clients/intelligent-search-api.ts b/node/clients/intelligent-search-api.ts index 73c10f0b..6ad96124 100644 --- a/node/clients/intelligent-search-api.ts +++ b/node/clients/intelligent-search-api.ts @@ -85,6 +85,19 @@ export class IntelligentSearchApi extends ExternalClient { return this.http.get(`/banners/${path}`, {params: {...params, query: params.query, locale: this.locale}, metric: 'banners'}) } + public async product(params: { field: string, value: string, salesChannel: number }) { + const { field, value, salesChannel } = params + return this.http.get('/product', { + params: { + id: value, + type: field, + locale: this.locale, + salesChannel, + }, + metric: 'product', + }) + } + public async facets(params: FacetsArgs, path: string, shippingHeader?: string[]) { if (isPathTraversal(path)) { throw new Error("Malformed URL") diff --git a/node/resolvers/search/index.ts b/node/resolvers/search/index.ts index d28bbab7..e0ffd49f 100644 --- a/node/resolvers/search/index.ts +++ b/node/resolvers/search/index.ts @@ -369,7 +369,7 @@ export const queries = { product: async (_: any, rawArgs: ProductArgs, ctx: Context) => { const { - clients: { search }, + clients: { intelligentSearchApi }, } = ctx const args = @@ -388,27 +388,28 @@ export const queries = { const { field, value } = args.identifier let products = [] as SearchProduct[] - - const vtexSegment = (!cookie || (!cookie?.regionId && rawArgs.regionId)) ? buildVtexSegment(cookie, salesChannel, rawArgs.regionId) : ctx.vtex.segmentToken + let fieldId = '' switch (field) { case 'id': - products = await search.productById(value, vtexSegment, salesChannel) + fieldId = 'product.id' break case 'slug': - products = await search.product(value, vtexSegment, salesChannel) + fieldId = 'product.link' break case 'ean': - products = await search.productByEan(value, vtexSegment, salesChannel) + fieldId = 'sku.ean' break case 'reference': - products = await search.productByReference(value, vtexSegment, salesChannel) + fieldId = 'sku.reference' break case 'sku': - products = await search.productBySku(value, vtexSegment, salesChannel) + fieldId = 'sku.id' break } + products = await intelligentSearchApi.product({ field: fieldId, value, salesChannel}) + if (products.length > 0) { return head(products) } diff --git a/node/resolvers/search/offer.ts b/node/resolvers/search/offer.ts index b1135f58..bdcabb2d 100644 --- a/node/resolvers/search/offer.ts +++ b/node/resolvers/search/offer.ts @@ -79,7 +79,7 @@ export const resolvers = { }, giftSkuIds: propOr([], 'GiftSkuIds'), gifts: async ({ GiftSkuIds }: CommertialOffer, _: any, ctx: Context) => { - if (GiftSkuIds.length === 0) { + if (GiftSkuIds?.length === 0) { return [] } diff --git a/node/resolvers/search/product.ts b/node/resolvers/search/product.ts index d9fec90a..157d16f0 100644 --- a/node/resolvers/search/product.ts +++ b/node/resolvers/search/product.ts @@ -69,6 +69,8 @@ const knownNotPG = [ 'link', 'linkText', 'productReference', + 'origin', + 'cacheId', ] const removeTrailingSlashes = (str: string) => @@ -181,7 +183,7 @@ export const resolvers = { cacheId || linkText, clusterHighlights: ({origin, clusterHighlights }: SearchProduct) => { - if (origin === 'intelligent-search') { + if (origin === 'intelligent-search' || origin === 'search-document') { return clusterHighlights } @@ -201,7 +203,7 @@ export const resolvers = { }, productClusters: ({origin, productClusters }: SearchProduct) => { - if (origin === 'intelligent-search') { + if (origin === 'intelligent-search' || origin === 'search-document') { return productClusters } @@ -211,8 +213,8 @@ export const resolvers = { properties: async (product: SearchProduct, _: unknown, ctx: Context) => { let valuesUntranslated = [] - if (product.origin === 'intelligent-search') { - valuesUntranslated = product.properties ?? [] + if (product.origin === 'intelligent-search' || product.origin === 'search-document') { + valuesUntranslated = product.properties?.map((prop) => ({...prop, name: prop.originalName ?? prop.name })) ?? [] } else { valuesUntranslated = (product.allSpecifications ?? []).map((name: string) => { const value = (product as unknown as DynamicKey)[name] @@ -287,42 +289,54 @@ export const resolvers = { return product.specificationGroups } - const allSpecificationsGroups = (product.allSpecificationsGroups ?? []).concat(['allSpecifications']) - - const visibleSpecifications = product.completeSpecifications - ? product.completeSpecifications.reduce>((acc, specification) => { - acc[specification.Name] = specification.IsOnProductDetails - return acc - }, {}) - : null - - let noTranslationSpecificationGroups = allSpecificationsGroups.map( - (groupName: string) => { - let groupSpecifications = (product as unknown as DynamicKey)?.[groupName] ?? [] + let noTranslationSpecificationGroups = [] - groupSpecifications = groupSpecifications.filter(specificationName => { - if (visibleSpecifications && visibleSpecifications[specificationName] != null) - return visibleSpecifications[specificationName] - return true + if (product.origin === 'search-document') { + noTranslationSpecificationGroups = product.specificationGroups?.map( + (group) => ({ + ...group, + specifications: group.specifications.map((spec) => ({...spec, name: spec.originalName })) }) - - return { - originalName: groupName, - name: groupName, - specifications: groupSpecifications.map((name) => { - const values = (product as unknown as DynamicKey)[name] || [] - return { - originalName: name, - name, - values, + ) ?? [] + } else { + const allSpecificationsGroups = (product.allSpecificationsGroups ?? []).concat(['allSpecifications']) + + const visibleSpecifications = product.completeSpecifications + ? product.completeSpecifications.reduce>((acc, specification) => { + acc[specification.Name] = specification.IsOnProductDetails + return acc + }, {}) + : null + + noTranslationSpecificationGroups = allSpecificationsGroups.map( + (groupName: string) => { + let groupSpecifications = (product as unknown as DynamicKey)?.[groupName] ?? [] + + groupSpecifications = groupSpecifications.filter(specificationName => { + if (visibleSpecifications && visibleSpecifications[specificationName] != null) + return visibleSpecifications[specificationName] + return true + }) + + return { + originalName: groupName, + name: groupName, + specifications: groupSpecifications.map((name) => { + const values = (product as unknown as DynamicKey)[name] || [] + return { + originalName: name, + name, + values, + } } - } - ), + ), + } } - } - ) + ) - noTranslationSpecificationGroups = noTranslationSpecificationGroups.filter(group => group.specifications.length > 0) + noTranslationSpecificationGroups = noTranslationSpecificationGroups.filter(group => group.specifications.length > 0) + + } if (!shouldTranslateToUserLocale(ctx)) { return noTranslationSpecificationGroups diff --git a/node/resolvers/search/sku.ts b/node/resolvers/search/sku.ts index 3cd10d83..c1cb3acc 100644 --- a/node/resolvers/search/sku.ts +++ b/node/resolvers/search/sku.ts @@ -53,6 +53,11 @@ export const resolvers = { if (!sku) { return sku } + + if (sku.variations?.length && typeof sku.variations[0] !== 'string') { + return sku.variations + } + const variations = (sku.variations || []).map(variationObj => { const variationName = typeof variationObj === 'string' ? variationObj : (variationObj as {name: string}).name const fieldId = (sku.skuSpecifications || []).find(specification => specification.field.name === variationName)?.field?.id diff --git a/node/typings/Catalog.ts b/node/typings/Catalog.ts index 030a919f..84a30cc1 100644 --- a/node/typings/Catalog.ts +++ b/node/typings/Catalog.ts @@ -81,7 +81,7 @@ enum FacetsBehavior { interface SpecificationGroup { name: string originalName: string - specifications: { name: string; originalName: string; values: string[] } + specifications: { name: string; originalName: string; values: string[] }[] } interface SearchProduct { origin?: string @@ -112,7 +112,9 @@ interface SearchProduct { completeSpecifications?: CompleteSpecification[] skuSpecifications?: SkuSpecification[] specificationGroups?: SpecificationGroup[] - properties?: { name: string; values: string[] }[] + properties?: { + originalName?: string; name: string; values: string[] +}[] } interface SearchItem { @@ -220,7 +222,7 @@ interface CommertialOffer { }[] GetInfoErrorMessage: any | null CacheVersionUsedToCallCheckout: string - // Supports the Intelligent Search API which + // Supports the Intelligent Search API which // uses the same name from the simulation discountHighlights: any[] } diff --git a/node/yarn.lock b/node/yarn.lock index dc79d503..81e9c231 100644 --- a/node/yarn.lock +++ b/node/yarn.lock @@ -4684,7 +4684,7 @@ static-extend@^0.1.1: define-property "^0.2.5" object-copy "^0.1.0" -"stats-lite@github:vtex/node-stats-lite#dist": +stats-lite@vtex/node-stats-lite#dist: version "2.2.0" resolved "https://codeload.github.com/vtex/node-stats-lite/tar.gz/1b0d39cc41ef7aaecfd541191f877887a2044797" dependencies: