11import { NotFoundError , UserInputError , createMessagesLoader } from '@vtex/api'
2- import { head , isEmpty , isNil , pathOr , test } from 'ramda'
2+ import { pathOr , test } from 'ramda'
33
44import {
55 buildAttributePath ,
66 convertOrderBy ,
77} from '../../commons/compatibility-layer'
88import { getWorkspaceSearchParamsFromStorage } from '../../routes/workspaceSearchParams'
9+ import {
10+ buildVtexSegment ,
11+ ProductArgs ,
12+ ProductIdentifier ,
13+ resolveProduct ,
14+ } from '../../services/product'
915import { shouldTranslateToTenantLocale } from '../../utils/i18n'
1016import { resolvers as assemblyOptionResolvers } from './assemblyOption'
1117import { resolvers as autocompleteResolvers } from './autocomplete'
@@ -33,24 +39,13 @@ import {
3339 getShippingOptionsFromSelectedFacets ,
3440 validMapAndQuery ,
3541} from './utils'
36- import {
42+ import {
3743 fetchAutocompleteSuggestions ,
3844 fetchTopSearches ,
3945 fetchSearchSuggestions ,
4046 fetchCorrection ,
4147} from '../../services/autocomplete'
4248import { fetchBanners } from '../../services/banners'
43- interface ProductIndentifier {
44- field : 'id' | 'slug' | 'ean' | 'reference' | 'sku'
45- value : string
46- }
47-
48- interface ProductArgs {
49- slug ?: string
50- identifier ?: ProductIndentifier
51- regionId ?: string
52- salesChannel ?: number
53- }
5449
5550enum CrossSellingInput {
5651 view = 'view' ,
@@ -67,7 +62,7 @@ enum CrossSellingGroupByInput {
6762}
6863
6964interface ProductRecommendationArg {
70- identifier ?: ProductIndentifier
65+ identifier ?: ProductIdentifier
7166 type ?: CrossSellingInput
7267 groupBy ?: CrossSellingGroupByInput
7368}
@@ -88,25 +83,6 @@ const inputToSearchCrossSelling = {
8883 [ CrossSellingInput . suggestions ] : SearchCrossSellingTypes . suggestions ,
8984}
9085
91- const buildVtexSegment = (
92- vtexSegment ?: SegmentData ,
93- tradePolicy ?: number ,
94- regionId ?: string | null
95- ) : string => {
96- const cookie = {
97- regionId : regionId ,
98- channel : tradePolicy ,
99- utm_campaign : vtexSegment ?. utm_campaign || '' ,
100- utm_source : vtexSegment ?. utm_source || '' ,
101- utmi_campaign : vtexSegment ?. utmi_campaign || '' ,
102- currencyCode : vtexSegment ?. currencyCode || '' ,
103- currencySymbol : vtexSegment ?. currencySymbol || '' ,
104- countryCode : vtexSegment ?. countryCode || '' ,
105- cultureInfo : vtexSegment ?. cultureInfo || '' ,
106- }
107- return new Buffer ( JSON . stringify ( cookie ) ) . toString ( 'base64' )
108- }
109-
11086/**
11187 * There is an URL pattern in VTEX where the number of mapSegments doesn't match the number of querySegments. This function deals with these cases.
11288 * Since this should not be a search concern, this function will be removed soon.
@@ -261,9 +237,6 @@ const isLegacySearchFormat = ({
261237 return map . split ( MAP_VALUES_SEP ) . length === query . split ( PATH_SEPARATOR ) . length
262238}
263239
264- const isValidProductIdentifier = ( identifier : ProductIndentifier | undefined ) =>
265- ! ! identifier && ! isNil ( identifier . value ) && ! isEmpty ( identifier . value )
266-
267240const getTranslatedSearchTerm = async (
268241 query : SearchArgs [ 'query' ] ,
269242 map : SearchArgs [ 'map' ] ,
@@ -403,61 +376,21 @@ export const queries = {
403376 } ,
404377
405378 product : async ( _ : any , rawArgs : ProductArgs , ctx : Context ) => {
406- const {
407- clients : { search } ,
408- } = ctx
409-
410- const args =
411- rawArgs && isValidProductIdentifier ( rawArgs . identifier )
412- ? rawArgs
413- : { identifier : { field : 'slug' , value : rawArgs . slug ! } }
414-
415- if ( ! args . identifier ) {
416- throw new UserInputError ( 'No product identifier provided' )
417- }
418-
419- let cookie : SegmentData | undefined = ctx . vtex . segment
379+ const product = await resolveProduct ( ctx , rawArgs )
420380
421- const salesChannel = rawArgs . salesChannel || cookie ?. channel || 1
422-
423- const { field, value } = args . identifier
424-
425- let products = [ ] as SearchProduct [ ]
426-
427- const vtexSegment =
428- ! cookie || ( ! cookie ?. regionId && rawArgs . regionId )
429- ? buildVtexSegment ( cookie , salesChannel , rawArgs . regionId )
430- : ctx . vtex . segmentToken
431-
432- switch ( field ) {
433- case 'id' :
434- products = await search . productById ( value , vtexSegment , salesChannel )
435- break
436- case 'slug' :
437- products = await search . product ( value , vtexSegment , salesChannel )
438- break
439- case 'ean' :
440- products = await search . productByEan ( value , vtexSegment , salesChannel )
441- break
442- case 'reference' :
443- products = await search . productByReference (
444- value ,
445- vtexSegment ,
446- salesChannel
447- )
448- break
449- case 'sku' :
450- products = await search . productBySku ( value , vtexSegment , salesChannel )
451- break
452- }
453-
454- if ( products . length > 0 ) {
455- return head ( products )
381+ if ( ! product ) {
382+ const identifier = rawArgs ?. identifier || {
383+ field : 'slug' ,
384+ value : rawArgs . slug ! ,
385+ }
386+ throw new NotFoundError (
387+ `No product was found with requested ${
388+ identifier . field
389+ } ${ JSON . stringify ( { identifier } ) } `
390+ )
456391 }
457392
458- throw new NotFoundError (
459- `No product was found with requested ${ field } ${ JSON . stringify ( args ) } `
460- )
393+ return product
461394 } ,
462395
463396 products : async ( _ : any , args : ProductsInput , ctx : Context ) => {
@@ -516,11 +449,13 @@ export const queries = {
516449
517450 const vtexSegment =
518451 ! ctx . vtex . segment || ( ! ctx . vtex . segment ?. regionId && args . regionId )
519- ? buildVtexSegment (
520- ctx . vtex . segment ,
521- Number ( args . salesChannel ) ,
522- args . regionId
523- )
452+ ? buildVtexSegment ( {
453+ vtexSegment : ctx . vtex . segment as
454+ | SegmentData
455+ | undefined ,
456+ salesChannel : args . salesChannel ?. toString ( ) ,
457+ regionId : args . regionId ?? undefined ,
458+ } )
524459 : ctx . vtex . segmentToken
525460
526461 switch ( field ) {
0 commit comments