From ccb16339c6ab70bc5ff18294315b072d8ae4b30c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=8Dcaro=20Azevedo?= Date: Wed, 11 May 2022 17:00:11 -0300 Subject: [PATCH 1/5] feat(api): add attachments to additionalProperty --- .../src/platforms/vtex/resolvers/product.ts | 38 +++++++++++++++++-- .../platforms/vtex/resolvers/productGroup.ts | 7 +++- .../src/platforms/vtex/utils/propertyValue.ts | 5 +++ .../api/src/typeDefs/propertyValue.graphql | 7 ++++ 4 files changed, 52 insertions(+), 5 deletions(-) create mode 100644 packages/api/src/platforms/vtex/utils/propertyValue.ts diff --git a/packages/api/src/platforms/vtex/resolvers/product.ts b/packages/api/src/platforms/vtex/resolvers/product.ts index 433cb81654..011b920410 100644 --- a/packages/api/src/platforms/vtex/resolvers/product.ts +++ b/packages/api/src/platforms/vtex/resolvers/product.ts @@ -4,8 +4,16 @@ import type { EnhancedCommercialOffer } from '../utils/enhanceCommercialOffer' import type { Resolver } from '..' import type { PromiseType } from '../../../typings' import type { Query } from './query' +import { VALUE_REFERENCES } from '../utils/propertyValue' +import type { Attachment } from '../clients/commerce/types/OrderForm' -type Root = PromiseType> +type QueryProduct = PromiseType> + +type Root = Omit & { + attachments: AttachmentDefinition[] | Attachment[] +} + +type AttachmentDefinition = QueryProduct['attachments'][number] const DEFAULT_IMAGE = { imageText: 'image', @@ -18,6 +26,10 @@ const getPath = (link: string, id: string) => `/${getSlug(link, id)}/p` const nonEmptyArray = (array: T[] | null | undefined) => Array.isArray(array) && array.length > 0 ? array : null +const isAttachmentDefinition = ( + attachment: Root['attachments'][number] +): attachment is AttachmentDefinition => 'id' in attachment + export const StoreProduct: Record> & { offers: Resolver isVariantOf: Resolver @@ -77,9 +89,27 @@ export const StoreProduct: Record> & { ) .sort(bestOfferFirst), isVariantOf: (root) => root, - additionalProperty: ({ variations = [] }) => { - return variations.flatMap(({ name, values }) => - values.map((value) => ({ name, value })) + additionalProperty: ({ variations = [], attachments }) => { + const propertyValueVariations = variations.flatMap(({ name, values }) => + values.map((value) => ({ + name, + value, + valueReference: VALUE_REFERENCES.variation, + })) ) + + const propertyValueAttachments = attachments.map((attachment) => { + if (isAttachmentDefinition(attachment)) { + return + } + + return { + name: attachment.name, + value: attachment.content, + valueReference: VALUE_REFERENCES.attachment, + } + }) + + return [...propertyValueVariations, ...propertyValueAttachments] }, } diff --git a/packages/api/src/platforms/vtex/resolvers/productGroup.ts b/packages/api/src/platforms/vtex/resolvers/productGroup.ts index 06e79155f0..efb73765e9 100644 --- a/packages/api/src/platforms/vtex/resolvers/productGroup.ts +++ b/packages/api/src/platforms/vtex/resolvers/productGroup.ts @@ -2,6 +2,7 @@ import { enhanceSku } from '../utils/enhanceSku' import type { Resolver } from '..' import type { PromiseType } from '../../../typings' import type { StoreProduct } from './product' +import { VALUE_REFERENCES } from '../utils/propertyValue' type Root = PromiseType> @@ -22,7 +23,11 @@ export const StoreProductGroup: Record> = { // Transform specs back into product specs .flatMap(({ specifications }) => specifications.flatMap(({ name, values }) => - values.map((value) => ({ name, value })) + values.map((value) => ({ + name, + value, + valueReference: VALUE_REFERENCES.specification, + })) ) ), } diff --git a/packages/api/src/platforms/vtex/utils/propertyValue.ts b/packages/api/src/platforms/vtex/utils/propertyValue.ts new file mode 100644 index 0000000000..1086d3ea14 --- /dev/null +++ b/packages/api/src/platforms/vtex/utils/propertyValue.ts @@ -0,0 +1,5 @@ +export const VALUE_REFERENCES = { + variation: 'VARIATION', + attachment: 'ATTACHMENT', + specification: 'SPECIFICATION', +} as const diff --git a/packages/api/src/typeDefs/propertyValue.graphql b/packages/api/src/typeDefs/propertyValue.graphql index 0168bf06a9..76caffe3d3 100644 --- a/packages/api/src/typeDefs/propertyValue.graphql +++ b/packages/api/src/typeDefs/propertyValue.graphql @@ -10,4 +10,11 @@ type StorePropertyValue { Property name. """ name: String! + valueReference: ValueReference! +} + +enum ValueReference { + ATTRIBUTE + ATTACHMENT + PROPERTY } From 2626da7641d6eafd0ce2a0ba227310d02a9f1473 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=8Dcaro=20Azevedo?= Date: Thu, 12 May 2022 10:47:39 -0300 Subject: [PATCH 2/5] fix: typescript errors on enhanced commertial offers --- .../vtex/resolvers/aggregateOffer.ts | 3 +- .../src/platforms/vtex/resolvers/product.ts | 32 ++++++++++++------- .../vtex/utils/enhanceCommercialOffer.ts | 20 +++++------- 3 files changed, 30 insertions(+), 25 deletions(-) diff --git a/packages/api/src/platforms/vtex/resolvers/aggregateOffer.ts b/packages/api/src/platforms/vtex/resolvers/aggregateOffer.ts index b9fa69b508..d9e0be2ea8 100644 --- a/packages/api/src/platforms/vtex/resolvers/aggregateOffer.ts +++ b/packages/api/src/platforms/vtex/resolvers/aggregateOffer.ts @@ -1,5 +1,4 @@ import { inStock } from '../utils/productStock' -import type { EnhancedCommercialOffer } from '../utils/enhanceCommercialOffer' import type { StoreProduct } from './product' import type { PromiseType } from '../../../typings' import type { Resolver } from '..' @@ -7,7 +6,7 @@ import type { Resolver } from '..' type Root = PromiseType> export const StoreAggregateOffer: Record> & { - offers: Resolver + offers: Resolver } = { highPrice: (offers) => { const availableOffers = offers.filter(inStock) diff --git a/packages/api/src/platforms/vtex/resolvers/product.ts b/packages/api/src/platforms/vtex/resolvers/product.ts index 011b920410..a7cd830f33 100644 --- a/packages/api/src/platforms/vtex/resolvers/product.ts +++ b/packages/api/src/platforms/vtex/resolvers/product.ts @@ -31,7 +31,12 @@ const isAttachmentDefinition = ( ): attachment is AttachmentDefinition => 'id' in attachment export const StoreProduct: Record> & { - offers: Resolver + offers: Resolver< + Root, + any, + Array> + > + isVariantOf: Resolver } = { productID: ({ itemId }) => itemId, @@ -98,17 +103,22 @@ export const StoreProduct: Record> & { })) ) - const propertyValueAttachments = attachments.map((attachment) => { - if (isAttachmentDefinition(attachment)) { - return - } + // Typescript don't understand (A[] | B[]) as an array, only Array + const propertyValueAttachments = (attachments as Array< + Root['attachments'][number] + >) + .map((attachment: Root['attachments'][number]) => { + if (isAttachmentDefinition(attachment)) { + return + } - return { - name: attachment.name, - value: attachment.content, - valueReference: VALUE_REFERENCES.attachment, - } - }) + return { + name: attachment.name, + value: attachment.content, + valueReference: VALUE_REFERENCES.attachment, + } + }) + .filter(Boolean) return [...propertyValueVariations, ...propertyValueAttachments] }, diff --git a/packages/api/src/platforms/vtex/utils/enhanceCommercialOffer.ts b/packages/api/src/platforms/vtex/utils/enhanceCommercialOffer.ts index db0591bfd2..35d0a7f4cd 100644 --- a/packages/api/src/platforms/vtex/utils/enhanceCommercialOffer.ts +++ b/packages/api/src/platforms/vtex/utils/enhanceCommercialOffer.ts @@ -1,23 +1,19 @@ -import type { - CommertialOffer, - Seller, -} from '../clients/search/types/ProductSearchResult' -import type { EnhancedSku } from './enhanceSku' +import type { CommertialOffer } from '../clients/search/types/ProductSearchResult' -export type EnhancedCommercialOffer = CommertialOffer & { - seller: Seller - product: EnhancedSku +export type EnhancedCommercialOffer = CommertialOffer & { + seller: S + product: P } -export const enhanceCommercialOffer = ({ +export const enhanceCommercialOffer = ({ offer, seller, product, }: { offer: CommertialOffer - seller: Seller - product: EnhancedSku -}): EnhancedCommercialOffer => ({ + seller: S + product: P +}): EnhancedCommercialOffer => ({ ...offer, product, seller, From 495675aa78b0526086b73a7476ca0bc8b4734625 Mon Sep 17 00:00:00 2001 From: Emerson Laurentino Date: Tue, 17 May 2022 18:10:10 -0300 Subject: [PATCH 3/5] feat: validate cart with attachments (#1301) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: validate cart with attachments * feat: improve get id * Add attachment type Co-authored-by: Ícaro Azevedo --- packages/api/src/__generated__/schema.ts | 22 +++++++++++++ .../vtex/clients/commerce/types/OrderForm.ts | 6 ++++ .../platforms/vtex/resolvers/validateCart.ts | 33 ++++++++++++++++++- packages/api/src/typeDefs/product.graphql | 4 +++ .../api/src/typeDefs/propertyValue.graphql | 20 +++++++++++ 5 files changed, 84 insertions(+), 1 deletion(-) diff --git a/packages/api/src/__generated__/schema.ts b/packages/api/src/__generated__/schema.ts index b188de819e..5fb18213ce 100644 --- a/packages/api/src/__generated__/schema.ts +++ b/packages/api/src/__generated__/schema.ts @@ -9,6 +9,7 @@ export type Scalars = { Boolean: boolean; Int: number; Float: number; + Object: any; }; /** Shopping cart identification input. */ @@ -55,6 +56,8 @@ export type IStoreOrganization = { /** Product input. */ export type IStoreProduct = { + /** Custom Product Additional Properties. */ + additionalProperty?: Maybe>; /** Array of product images. */ image: Array; /** Product name. */ @@ -63,6 +66,15 @@ export type IStoreProduct = { sku: Scalars['String']; }; +export type IStorePropertyValue = { + /** Property name. */ + name: Scalars['String']; + /** Property value. */ + value: Scalars['Object']; + /** Property value reference. */ + valueReference: ValueReference; +}; + /** Selected facet input. */ export type IStoreSelectedFacet = { key: Scalars['String']; @@ -323,6 +335,8 @@ export type StoreListItem = { /** Offer information. */ export type StoreOffer = { __typename?: 'StoreOffer'; + /** An additional offer that can only be obtained in combination with the first base offer (e.g. supplements and extensions that are available for a surcharge). */ + addOn: Array>; /** Offer item availability. */ availability: Scalars['String']; /** Offer item condition. */ @@ -462,6 +476,8 @@ export type StorePropertyValue = { name: Scalars['String']; /** Property value. */ value: Scalars['String']; + /** Property value reference. */ + valueReference: ValueReference; }; /** Information of a given review. */ @@ -544,3 +560,9 @@ export type StoreSuggestions = { /** Array with suggestion terms. */ terms?: Maybe>; }; + +export const enum ValueReference { + Attachment = 'ATTACHMENT', + Attribute = 'ATTRIBUTE', + Property = 'PROPERTY' +}; diff --git a/packages/api/src/platforms/vtex/clients/commerce/types/OrderForm.ts b/packages/api/src/platforms/vtex/clients/commerce/types/OrderForm.ts index d8f9eac1a5..f9ae2f4a67 100644 --- a/packages/api/src/platforms/vtex/clients/commerce/types/OrderForm.ts +++ b/packages/api/src/platforms/vtex/clients/commerce/types/OrderForm.ts @@ -3,6 +3,12 @@ export interface OrderFormInputItem { quantity: number seller: string index?: number + attachments?: Attachment[] +} + +export interface Attachment { + name: string + content: Record } export interface OrderFormItem { diff --git a/packages/api/src/platforms/vtex/resolvers/validateCart.ts b/packages/api/src/platforms/vtex/resolvers/validateCart.ts index bae801422f..546d514056 100644 --- a/packages/api/src/platforms/vtex/resolvers/validateCart.ts +++ b/packages/api/src/platforms/vtex/resolvers/validateCart.ts @@ -12,11 +12,38 @@ import type { OrderFormItem, } from '../clients/commerce/types/OrderForm' import type { Context } from '..' +import { VALUE_REFERENCES } from '../utils/propertyValue' type Indexed = T & { index?: number } +const getAttachments = (item: IStoreOffer) => + item.itemOffered.additionalProperty?.filter( + (i) => i.valueReference === VALUE_REFERENCES.attachment + ) + +const serializeAttachment = (item: IStoreOffer) => { + const attachments = getAttachments(item) + + if (attachments?.length === 0) { + return null + } + + return attachments + ?.map( + (attachment) => `${attachment.name}:${JSON.stringify(attachment.value)}` + ) + .join('-') +} + const getId = (item: IStoreOffer) => - [item.itemOffered.sku, item.seller.identifier, item.price].join('::') + [ + item.itemOffered.sku, + item.seller.identifier, + item.price, + serializeAttachment(item), + ] + .filter(Boolean) + .join('::') const orderFormItemToOffer = ( item: OrderFormItem, @@ -41,6 +68,10 @@ const offerToOrderItemInput = ( seller: offer.seller.identifier, id: offer.itemOffered.sku, index: offer.index, + attachments: getAttachments(offer)?.map((attachment) => ({ + name: attachment.name, + content: attachment.value, + })), }) const groupById = (offers: IStoreOffer[]): Map => diff --git a/packages/api/src/typeDefs/product.graphql b/packages/api/src/typeDefs/product.graphql index b22f3b2db7..03b6294f94 100644 --- a/packages/api/src/typeDefs/product.graphql +++ b/packages/api/src/typeDefs/product.graphql @@ -80,4 +80,8 @@ input IStoreProduct { Array of product images. """ image: [IStoreImage!]! + """ + Custom Product Additional Properties. + """ + additionalProperty: [IStorePropertyValue!] } diff --git a/packages/api/src/typeDefs/propertyValue.graphql b/packages/api/src/typeDefs/propertyValue.graphql index 76caffe3d3..13b1b0419e 100644 --- a/packages/api/src/typeDefs/propertyValue.graphql +++ b/packages/api/src/typeDefs/propertyValue.graphql @@ -10,6 +10,9 @@ type StorePropertyValue { Property name. """ name: String! + """ + Property value reference. + """ valueReference: ValueReference! } @@ -18,3 +21,20 @@ enum ValueReference { ATTACHMENT PROPERTY } + +scalar Object + +input IStorePropertyValue { + """ + Property value. + """ + value: Object! + """ + Property name. + """ + name: String! + """ + Property value reference. + """ + valueReference: ValueReference! +} From fb39540eae1fafb0f31f75bc0d62c7d17a1e2a11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=8Dcaro=20Azevedo?= Date: Wed, 18 May 2022 12:34:12 -0300 Subject: [PATCH 4/5] fix: receiving and returning StorePropertyValue now works correctly --- packages/api/src/__generated__/schema.ts | 26 ++++------- .../vtex/clients/commerce/types/OrderForm.ts | 1 + packages/api/src/platforms/vtex/index.ts | 2 + .../vtex/resolvers/objectOrString.ts | 46 +++++++++++++++++++ .../api/src/platforms/vtex/resolvers/offer.ts | 12 ++++- .../src/platforms/vtex/resolvers/product.ts | 33 ++++--------- packages/api/src/typeDefs/index.ts | 2 + .../api/src/typeDefs/objectOrString.graphql | 1 + .../api/src/typeDefs/propertyValue.graphql | 24 ++++------ 9 files changed, 89 insertions(+), 58 deletions(-) create mode 100644 packages/api/src/platforms/vtex/resolvers/objectOrString.ts create mode 100644 packages/api/src/typeDefs/objectOrString.graphql diff --git a/packages/api/src/__generated__/schema.ts b/packages/api/src/__generated__/schema.ts index 5fb18213ce..1e2a5c9160 100644 --- a/packages/api/src/__generated__/schema.ts +++ b/packages/api/src/__generated__/schema.ts @@ -9,7 +9,7 @@ export type Scalars = { Boolean: boolean; Int: number; Float: number; - Object: any; + ObjectOrString: any; }; /** Shopping cart identification input. */ @@ -69,10 +69,10 @@ export type IStoreProduct = { export type IStorePropertyValue = { /** Property name. */ name: Scalars['String']; - /** Property value. */ - value: Scalars['Object']; - /** Property value reference. */ - valueReference: ValueReference; + /** Property value. May hold a string or the string representation of an object. */ + value: Scalars['ObjectOrString']; + /** Specifies the nature of the value */ + valueReference: Scalars['String']; }; /** Selected facet input. */ @@ -335,8 +335,6 @@ export type StoreListItem = { /** Offer information. */ export type StoreOffer = { __typename?: 'StoreOffer'; - /** An additional offer that can only be obtained in combination with the first base offer (e.g. supplements and extensions that are available for a surcharge). */ - addOn: Array>; /** Offer item availability. */ availability: Scalars['String']; /** Offer item condition. */ @@ -474,10 +472,10 @@ export type StorePropertyValue = { __typename?: 'StorePropertyValue'; /** Property name. */ name: Scalars['String']; - /** Property value. */ - value: Scalars['String']; - /** Property value reference. */ - valueReference: ValueReference; + /** Property value. May hold a string or the string representation of an object. */ + value: Scalars['ObjectOrString']; + /** Specifies the nature of the value */ + valueReference: Scalars['String']; }; /** Information of a given review. */ @@ -560,9 +558,3 @@ export type StoreSuggestions = { /** Array with suggestion terms. */ terms?: Maybe>; }; - -export const enum ValueReference { - Attachment = 'ATTACHMENT', - Attribute = 'ATTRIBUTE', - Property = 'PROPERTY' -}; diff --git a/packages/api/src/platforms/vtex/clients/commerce/types/OrderForm.ts b/packages/api/src/platforms/vtex/clients/commerce/types/OrderForm.ts index f9ae2f4a67..9cd77e4ec3 100644 --- a/packages/api/src/platforms/vtex/clients/commerce/types/OrderForm.ts +++ b/packages/api/src/platforms/vtex/clients/commerce/types/OrderForm.ts @@ -54,6 +54,7 @@ export interface OrderFormItem { sellingPrices: SellingPrice[] total: number } + attachments: Attachment[] } export interface SKUSpecification { diff --git a/packages/api/src/platforms/vtex/index.ts b/packages/api/src/platforms/vtex/index.ts index 43c8dc2091..7143019e03 100644 --- a/packages/api/src/platforms/vtex/index.ts +++ b/packages/api/src/platforms/vtex/index.ts @@ -13,6 +13,7 @@ import { Query } from './resolvers/query' import { StoreReview } from './resolvers/review' import { StoreSearchResult } from './resolvers/searchResult' import { StoreSeo } from './resolvers/seo' +import { ObjectOrString } from './resolvers/objectOrString' import type { Loaders } from './loaders' import type { Clients } from './clients' import type { Channel } from './utils/channel' @@ -67,6 +68,7 @@ const Resolvers = { StoreReview, StoreProductGroup, StoreSearchResult, + ObjectOrString, Query, Mutation, } diff --git a/packages/api/src/platforms/vtex/resolvers/objectOrString.ts b/packages/api/src/platforms/vtex/resolvers/objectOrString.ts new file mode 100644 index 0000000000..b72dd85513 --- /dev/null +++ b/packages/api/src/platforms/vtex/resolvers/objectOrString.ts @@ -0,0 +1,46 @@ +import type { GraphQLScalarSerializer } from 'graphql' +import { GraphQLScalarType } from 'graphql' +import { Kind } from 'graphql/language' + +export const ObjectOrString = new GraphQLScalarType({ + name: 'ObjectOrString', + description: + 'A string or the string representation of an object (a stringified object).', + parseValue: toObjectOrString, + serialize: stringify, + parseLiteral(ast) { + if (ast.kind === Kind.STRING) { + try { + return JSON.parse(ast.value) + } catch (e) { + return ast.value + } + } + + return null + }, +}) + +function toObjectOrString(value: GraphQLScalarSerializer) { + if (typeof value === 'string') { + try { + return JSON.parse(value) + } catch (e) { + return value + } + } + + return null +} + +function stringify(value: GraphQLScalarSerializer) { + if (typeof value === 'object') { + return JSON.stringify(value) + } + + if (typeof value === 'string') { + return value + } + + return null +} diff --git a/packages/api/src/platforms/vtex/resolvers/offer.ts b/packages/api/src/platforms/vtex/resolvers/offer.ts index 6e34c580f9..4e5a8513b5 100644 --- a/packages/api/src/platforms/vtex/resolvers/offer.ts +++ b/packages/api/src/platforms/vtex/resolvers/offer.ts @@ -96,7 +96,17 @@ export const StoreOffer: Record> = { return null }, - itemOffered: ({ product }) => product, + itemOffered: async (root) => { + if (isSearchItem(root)) { + return root.product + } + + if (isOrderFormItem(root)) { + return { ...(await root.product), attachmentsValues: root.attachments } + } + + return null + }, quantity: (root) => { if (isSearchItem(root)) { return root.AvailableQuantity ?? 0 diff --git a/packages/api/src/platforms/vtex/resolvers/product.ts b/packages/api/src/platforms/vtex/resolvers/product.ts index a7cd830f33..98b5691b09 100644 --- a/packages/api/src/platforms/vtex/resolvers/product.ts +++ b/packages/api/src/platforms/vtex/resolvers/product.ts @@ -9,12 +9,10 @@ import type { Attachment } from '../clients/commerce/types/OrderForm' type QueryProduct = PromiseType> -type Root = Omit & { - attachments: AttachmentDefinition[] | Attachment[] +type Root = QueryProduct & { + attachmentsValues?: Attachment[] } -type AttachmentDefinition = QueryProduct['attachments'][number] - const DEFAULT_IMAGE = { imageText: 'image', imageUrl: @@ -26,10 +24,6 @@ const getPath = (link: string, id: string) => `/${getSlug(link, id)}/p` const nonEmptyArray = (array: T[] | null | undefined) => Array.isArray(array) && array.length > 0 ? array : null -const isAttachmentDefinition = ( - attachment: Root['attachments'][number] -): attachment is AttachmentDefinition => 'id' in attachment - export const StoreProduct: Record> & { offers: Resolver< Root, @@ -94,7 +88,7 @@ export const StoreProduct: Record> & { ) .sort(bestOfferFirst), isVariantOf: (root) => root, - additionalProperty: ({ variations = [], attachments }) => { + additionalProperty: ({ variations = [], attachmentsValues }) => { const propertyValueVariations = variations.flatMap(({ name, values }) => values.map((value) => ({ name, @@ -103,22 +97,13 @@ export const StoreProduct: Record> & { })) ) - // Typescript don't understand (A[] | B[]) as an array, only Array - const propertyValueAttachments = (attachments as Array< - Root['attachments'][number] - >) - .map((attachment: Root['attachments'][number]) => { - if (isAttachmentDefinition(attachment)) { - return - } - - return { - name: attachment.name, - value: attachment.content, - valueReference: VALUE_REFERENCES.attachment, - } + const propertyValueAttachments = (attachmentsValues ?? []).map( + (attachment) => ({ + name: attachment.name, + value: attachment.content, + valueReference: VALUE_REFERENCES.attachment, }) - .filter(Boolean) + ) return [...propertyValueVariations, ...propertyValueAttachments] }, diff --git a/packages/api/src/typeDefs/index.ts b/packages/api/src/typeDefs/index.ts index 57a1c75e77..fe39270c43 100644 --- a/packages/api/src/typeDefs/index.ts +++ b/packages/api/src/typeDefs/index.ts @@ -22,6 +22,7 @@ import Cart from './cart.graphql' import Status from './status.graphql' import PropertyValue from './propertyValue.graphql' import Person from './person.graphql' +import ObjectOrString from './objectOrString.graphql' export const typeDefs = [ Query, @@ -46,6 +47,7 @@ export const typeDefs = [ Status, PropertyValue, Person, + ObjectOrString, ] .map(print) .join('\n') diff --git a/packages/api/src/typeDefs/objectOrString.graphql b/packages/api/src/typeDefs/objectOrString.graphql new file mode 100644 index 0000000000..fd8a401db7 --- /dev/null +++ b/packages/api/src/typeDefs/objectOrString.graphql @@ -0,0 +1 @@ +scalar ObjectOrString \ No newline at end of file diff --git a/packages/api/src/typeDefs/propertyValue.graphql b/packages/api/src/typeDefs/propertyValue.graphql index 13b1b0419e..665c166eb1 100644 --- a/packages/api/src/typeDefs/propertyValue.graphql +++ b/packages/api/src/typeDefs/propertyValue.graphql @@ -3,38 +3,30 @@ Properties that can be associated with products and products groups. """ type StorePropertyValue { """ - Property value. + Property value. May hold a string or the string representation of an object. """ - value: String! + value: ObjectOrString! """ Property name. """ name: String! """ - Property value reference. + Specifies the nature of the value """ - valueReference: ValueReference! + valueReference: String! } -enum ValueReference { - ATTRIBUTE - ATTACHMENT - PROPERTY -} - -scalar Object - input IStorePropertyValue { """ - Property value. + Property value. May hold a string or the string representation of an object. """ - value: Object! + value: ObjectOrString! """ Property name. """ name: String! """ - Property value reference. + Specifies the nature of the value """ - valueReference: ValueReference! + valueReference: String! } From 413494313171c200b247974b1b4c50b4a3c9a63f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=8Dcaro=20Azevedo?= Date: Wed, 18 May 2022 19:49:39 -0300 Subject: [PATCH 5/5] chore: move duplicated code to function --- .../vtex/resolvers/objectOrString.ts | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/packages/api/src/platforms/vtex/resolvers/objectOrString.ts b/packages/api/src/platforms/vtex/resolvers/objectOrString.ts index b72dd85513..d43021dbfc 100644 --- a/packages/api/src/platforms/vtex/resolvers/objectOrString.ts +++ b/packages/api/src/platforms/vtex/resolvers/objectOrString.ts @@ -10,11 +10,7 @@ export const ObjectOrString = new GraphQLScalarType({ serialize: stringify, parseLiteral(ast) { if (ast.kind === Kind.STRING) { - try { - return JSON.parse(ast.value) - } catch (e) { - return ast.value - } + return getValueAsObjectOrString(ast.value) } return null @@ -23,16 +19,20 @@ export const ObjectOrString = new GraphQLScalarType({ function toObjectOrString(value: GraphQLScalarSerializer) { if (typeof value === 'string') { - try { - return JSON.parse(value) - } catch (e) { - return value - } + return getValueAsObjectOrString(value) } return null } +function getValueAsObjectOrString(value: string) { + try { + return JSON.parse(value) + } catch (e) { + return value + } +} + function stringify(value: GraphQLScalarSerializer) { if (typeof value === 'object') { return JSON.stringify(value)