@faststore/api 1.6.24 → 1.6.27

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"api.cjs.production.min.js","sources":["../src/platforms/vtex/clients/fetch.ts","../src/platforms/vtex/clients/commerce/index.ts","../src/platforms/vtex/clients/search/index.ts","../src/platforms/vtex/utils/errors.ts","../src/platforms/vtex/utils/enhanceSku.ts","../src/platforms/vtex/loaders/collection.ts","../src/platforms/vtex/resolvers/aggregateOffer.ts","../src/platforms/vtex/utils/slugify.ts","../src/platforms/vtex/resolvers/collection.ts","../src/platforms/vtex/resolvers/validateCart.ts","../src/platforms/vtex/utils/channel.ts","../src/platforms/vtex/resolvers/updateSession.ts","../src/platforms/vtex/resolvers/product.ts","../src/platforms/vtex/utils/facets.ts","../src/platforms/vtex/utils/sort.ts","../src/platforms/vtex/resolvers/query.ts","../src/platforms/vtex/resolvers/searchResult.ts","../src/platforms/vtex/index.ts","../src/platforms/vtex/resolvers/seo.ts","../src/platforms/vtex/resolvers/facet.ts","../src/platforms/vtex/resolvers/facetValue.ts","../src/platforms/vtex/resolvers/offer.ts","../src/platforms/vtex/resolvers/aggregateRating.ts","../src/platforms/vtex/resolvers/review.ts","../src/platforms/vtex/resolvers/productGroup.ts","../src/platforms/vtex/resolvers/mutation.ts","../src/typeDefs/index.ts","../src/index.ts","../src/platforms/vtex/clients/index.ts","../src/platforms/vtex/loaders/index.ts","../src/platforms/vtex/loaders/sku.ts","../src/platforms/vtex/loaders/simulation.ts"],"sourcesContent":["import fetch from 'isomorphic-unfetch'\n\nexport const fetchAPI = async (info: RequestInfo, init?: RequestInit) => {\n const response = await fetch(info, init)\n\n if (response.ok) {\n return response.json()\n }\n\n console.error(info, init, response)\n const text = await response.text()\n\n throw new Error(text)\n}\n","import type { Context, Options } from '../../index'\nimport { fetchAPI } from '../fetch'\nimport type { Brand } from './types/Brand'\nimport type { CategoryTree } from './types/CategoryTree'\nimport type { OrderForm, OrderFormInputItem } from './types/OrderForm'\nimport type { PortalPagetype } from './types/Portal'\nimport type { Region, RegionInput } from './types/Region'\nimport type {\n Simulation,\n SimulationArgs,\n SimulationOptions,\n} from './types/Simulation'\nimport type { Session } from './types/Session'\n\nconst BASE_INIT = {\n method: 'POST',\n headers: {\n 'content-type': 'application/json',\n },\n}\n\nexport const VtexCommerce = (\n { account, environment }: Options,\n ctx: Context\n) => {\n const base = `https://${account}.${environment}.com.br`\n\n return {\n catalog: {\n brand: {\n list: (): Promise<Brand[]> =>\n fetchAPI(`${base}/api/catalog_system/pub/brand/list`),\n },\n category: {\n tree: (depth = 3): Promise<CategoryTree[]> =>\n fetchAPI(`${base}/api/catalog_system/pub/category/tree/${depth}`),\n },\n portal: {\n pagetype: (slug: string): Promise<PortalPagetype> =>\n fetchAPI(`${base}/api/catalog_system/pub/portal/pagetype/${slug}`),\n },\n },\n checkout: {\n simulation: (\n args: SimulationArgs,\n { salesChannel }: SimulationOptions = {\n salesChannel: ctx.storage.channel,\n }\n ): Promise<Simulation> => {\n const params = new URLSearchParams({\n sc: salesChannel,\n })\n\n return fetchAPI(\n `${base}/api/checkout/pub/orderForms/simulation?${params.toString()}`,\n {\n ...BASE_INIT,\n body: JSON.stringify(args),\n }\n )\n },\n orderForm: ({\n id,\n refreshOutdatedData = true,\n salesChannel = ctx.storage.channel,\n }: {\n id: string\n refreshOutdatedData?: boolean\n salesChannel?: string\n }): Promise<OrderForm> => {\n const params = new URLSearchParams({\n refreshOutdatedData: refreshOutdatedData.toString(),\n sc: salesChannel,\n })\n\n return fetchAPI(\n `${base}/api/checkout/pub/orderForm/${id}?${params.toString()}`,\n BASE_INIT\n )\n },\n updateOrderFormItems: ({\n id,\n orderItems,\n allowOutdatedData = 'paymentData',\n salesChannel = ctx.storage.channel,\n }: {\n id: string\n orderItems: OrderFormInputItem[]\n allowOutdatedData?: 'paymentData'\n salesChannel?: string\n }): Promise<OrderForm> => {\n const params = new URLSearchParams({\n allowOutdatedData,\n sc: salesChannel,\n })\n\n return fetchAPI(\n `${base}/api/checkout/pub/orderForm/${id}/items?${params}`,\n {\n ...BASE_INIT,\n body: JSON.stringify({ orderItems }),\n method: 'PATCH',\n }\n )\n },\n region: async ({\n postalCode,\n country,\n salesChannel,\n }: RegionInput): Promise<Region> => {\n return fetchAPI(\n `${base}/api/checkout/pub/regions/?postalCode=${postalCode}&country=${country}&sc=${\n salesChannel ?? ''\n }`\n )\n },\n },\n session: (): Promise<Session> =>\n fetchAPI(\n `${base}/api/sessions?items=profile.id,profile.email,profile.firstName,profile.lastName`,\n {\n method: 'POST',\n headers: {\n 'content-type': 'application/json',\n cookie: ctx.headers.cookie,\n },\n body: '{}',\n }\n ),\n }\n}\n","import type { Context, Options } from '../../index'\nimport { fetchAPI } from '../fetch'\nimport type { SelectedFacet } from '../../utils/facets'\nimport type { ProductSearchResult } from './types/ProductSearchResult'\nimport type { AttributeSearchResult } from './types/AttributeSearchResult'\n\nexport type Sort =\n | 'price:desc'\n | 'price:asc'\n | 'orders:desc'\n | 'name:desc'\n | 'name:asc'\n | 'release:desc'\n | 'discount:desc'\n | ''\n\nexport interface SearchArgs {\n query?: string\n page: number\n count: number\n type: 'product_search' | 'attribute_search'\n sort?: Sort\n selectedFacets?: SelectedFacet[]\n fuzzy?: '0' | '1'\n hideUnavailableItems?: boolean\n}\n\nexport interface ProductLocator {\n field: 'id' | 'slug'\n value: string\n}\n\nexport const IntelligentSearch = (\n { account, environment, hideUnavailableItems }: Options,\n ctx: Context\n) => {\n const base = `http://portal.${environment}.com.br/search-api/v1/${account}`\n const policyFacet = { key: 'trade-policy', value: ctx.storage.channel }\n\n const addDefaultFacets = (facets: SelectedFacet[]) => {\n const facet = facets.find(({ key }) => key === policyFacet.key)\n\n if (facet === undefined) {\n return [...facets, policyFacet]\n }\n\n return facets\n }\n\n const search = <T>({\n query = '',\n page,\n count,\n sort = '',\n selectedFacets = [],\n type,\n fuzzy = '0',\n }: SearchArgs): Promise<T> => {\n const params = new URLSearchParams({\n page: (page + 1).toString(),\n count: count.toString(),\n query,\n sort,\n fuzzy,\n })\n\n if (hideUnavailableItems !== undefined) {\n params.append('hide-unavailable-items', hideUnavailableItems.toString())\n }\n\n const pathname = addDefaultFacets(selectedFacets)\n .map(({ key, value }) => `${key}/${value}`)\n .join('/')\n\n return fetchAPI(\n `${base}/api/split/${type}/${pathname}?${params.toString()}`\n )\n }\n\n const products = (args: Omit<SearchArgs, 'type'>) =>\n search<ProductSearchResult>({ ...args, type: 'product_search' })\n\n const facets = (args: Omit<SearchArgs, 'type'>) =>\n search<AttributeSearchResult>({ ...args, type: 'attribute_search' })\n\n return {\n facets,\n products,\n }\n}\n","export class BadRequestError extends Error {\n constructor(message: string) {\n super(message)\n this.name = 'BadRequestError'\n }\n}\n\nexport class NotFoundError extends Error {\n constructor(message: string) {\n super(message)\n this.name = 'NotFoundError'\n }\n}\n","import type { Product, Sku } from '../clients/search/types/ProductSearchResult'\n\nexport type EnhancedSku = Sku & { isVariantOf: Product }\n\nexport const enhanceSku = (sku: Sku, product: Product): EnhancedSku => ({\n ...sku,\n isVariantOf: product,\n})\n","import DataLoader from 'dataloader'\nimport pLimit from 'p-limit'\n\nimport { NotFoundError } from '../utils/errors'\nimport type { CollectionPageType } from '../clients/commerce/types/Portal'\nimport type { Options } from '..'\nimport type { Clients } from '../clients'\n\n// Limits concurrent requests to 20 so that they don't timeout\nconst CONCURRENT_REQUESTS_MAX = 20\n\nconst collectionPageTypes = new Set([\n 'brand',\n 'category',\n 'department',\n 'subcategory',\n] as const)\n\nexport const isCollectionPageType = (x: any): x is CollectionPageType =>\n typeof x.pageType === 'string' &&\n collectionPageTypes.has(x.pageType.toLowerCase())\n\nexport const getCollectionLoader = (_: Options, clients: Clients) => {\n const limit = pLimit(CONCURRENT_REQUESTS_MAX)\n\n const loader = async (\n slugs: readonly string[]\n ): Promise<CollectionPageType[]> => {\n return Promise.all(\n slugs.map((slug: string) =>\n limit(async () => {\n const page = await clients.commerce.catalog.portal.pagetype(slug)\n\n if (isCollectionPageType(page)) {\n return page\n }\n\n throw new NotFoundError(\n `Catalog returned ${page.pageType} for slug: ${slug}. This usually happens when there is more than one category with the same name in the same category tree level.`\n )\n })\n )\n )\n }\n\n return new DataLoader<string, CollectionPageType>(loader, {\n // DataLoader is being used to cache requests, not to batch them\n batch: false,\n })\n}\n","import type { EnhancedSku } from '../utils/enhanceSku'\nimport type { Simulation } from '../clients/commerce/types/Simulation'\n\ntype Resolvers = (root: Simulation & { product: EnhancedSku }) => unknown\n\nconst inStock = (item: Simulation['items'][0]) =>\n item.availability === 'available'\n\n// Smallest Available Selling Price First\nexport const sortOfferByPrice = (\n items: Simulation['items']\n): Simulation['items'] =>\n items.sort((a, b) => {\n if (inStock(a) && !inStock(b)) {\n return -1\n }\n\n if (!inStock(a) && inStock(b)) {\n return 1\n }\n\n return a.sellingPrice - b.sellingPrice\n })\n\nexport const StoreAggregateOffer: Record<string, Resolvers> = {\n highPrice: ({ items }) => {\n const availableItems = items.filter(inStock)\n const highPrice = availableItems.pop()?.sellingPrice\n\n return (highPrice ?? 0) / 1e2\n },\n lowPrice: ({ items }) => {\n const availableItems = items.filter(inStock)\n const lowPrice = availableItems[0]?.sellingPrice\n\n return (lowPrice ?? 0) / 1e2\n },\n offerCount: ({ items }) => items.length,\n priceCurrency: () => '',\n offers: ({ items, product }) => items.map((item) => ({ ...item, product })),\n}\n","import rawSlugify from '@sindresorhus/slugify'\n\nexport const slugify = (path: string) =>\n rawSlugify(path, { separator: '-', lowercase: true })\n","import { isCollectionPageType } from '../loaders/collection'\nimport { slugify as baseSlugify } from '../utils/slugify'\nimport type { Resolver } from '..'\nimport type { Brand } from '../clients/commerce/types/Brand'\nimport type { CategoryTree } from '../clients/commerce/types/CategoryTree'\nimport type { CollectionPageType } from '../clients/commerce/types/Portal'\n\ntype Root = Brand | (CategoryTree & { level: number }) | CollectionPageType\n\nconst isBrand = (x: any): x is Brand => x.type === 'brand'\n\nconst slugify = (root: Root) => {\n if (isBrand(root)) {\n return baseSlugify(root.name.toLowerCase())\n }\n\n if (isCollectionPageType(root)) {\n return new URL(`https://${root.url}`).pathname.slice(1)\n }\n\n return new URL(root.url).pathname.slice(1)\n}\n\nexport const StoreCollection: Record<string, Resolver<Root>> = {\n id: ({ id }) => id.toString(),\n slug: (root) => slugify(root),\n seo: (root) =>\n isBrand(root) || isCollectionPageType(root)\n ? {\n title: root.title,\n description: root.metaTagDescription,\n }\n : {\n title: root.Title,\n description: root.MetaTagDescription,\n },\n type: (root) =>\n isBrand(root)\n ? 'Brand'\n : isCollectionPageType(root)\n ? root.pageType\n : root.level === 0\n ? 'Department'\n : 'Category',\n meta: (root) =>\n isBrand(root)\n ? {\n selectedFacets: [{ key: 'brand', value: baseSlugify(root.name) }],\n }\n : {\n selectedFacets: new URL(\n isCollectionPageType(root) ? `https://${root.url}` : root.url\n ).pathname\n .slice(1)\n .split('/')\n .map((segment, index) => ({\n key: `category-${index + 1}`,\n value: baseSlugify(segment),\n })),\n },\n breadcrumbList: async (root, _, ctx) => {\n const {\n loaders: { collectionLoader },\n } = ctx\n\n const slug = slugify(root)\n\n /**\n * Split slug into segments so we fetch all data for\n * the breadcrumb. For instance, if we get `/foo/bar`\n * we need all metadata for both `/foo` and `/bar` and\n * thus we need to fetch pageType for `/foo` and `/bar`\n */\n const segments = slug.split('/').filter((segment) => Boolean(segment))\n const slugs = segments.map((__, index) =>\n segments.slice(0, index + 1).join('/')\n )\n\n const collections = await Promise.all(\n slugs.map((s) => collectionLoader.load(s))\n )\n\n return {\n itemListElement: collections.map((collection, index) => ({\n item: new URL(`https://${collection.url}`).pathname.toLowerCase(),\n name: collection.name,\n position: index + 1,\n })),\n numberOfItems: collections.length,\n }\n },\n}\n","import deepEquals from 'fast-deep-equal'\n\nimport type {\n IStoreOrder,\n IStoreCart,\n IStoreOffer,\n} from '../../../__generated__/schema'\nimport type {\n OrderForm,\n OrderFormItem,\n OrderFormInputItem,\n} from '../clients/commerce/types/OrderForm'\nimport type { Context } from '..'\n\ntype Indexed<T> = T & { index?: number }\n\nconst getId = (item: IStoreOffer) =>\n [item.itemOffered.sku, item.seller.identifier, item.price].join('::')\n\nconst orderFormItemToOffer = (\n item: OrderFormItem,\n index?: number\n): Indexed<IStoreOffer> => ({\n listPrice: item.listPrice / 100,\n price: item.sellingPrice / 100,\n quantity: item.quantity,\n seller: { identifier: item.seller },\n itemOffered: {\n sku: item.id,\n image: [],\n name: item.name,\n },\n index,\n})\n\nconst offerToOrderItemInput = (\n offer: Indexed<IStoreOffer>\n): OrderFormInputItem => ({\n quantity: offer.quantity,\n seller: offer.seller.identifier,\n id: offer.itemOffered.sku,\n index: offer.index,\n})\n\nconst groupById = (offers: IStoreOffer[]): Map<string, IStoreOffer> =>\n offers.reduce((acc, item) => {\n const id = getId(item)\n\n acc.set(id, acc.get(id) ?? item)\n\n return acc\n }, new Map<string, IStoreOffer>())\n\nconst equals = (storeOrder: IStoreOrder, orderForm: OrderForm) => {\n const pick = (item: Indexed<IStoreOffer>, index: number) => ({\n ...item,\n itemOffered: {\n sku: item.itemOffered.sku,\n },\n index,\n })\n\n const orderFormItems = orderForm.items.map(orderFormItemToOffer).map(pick)\n const storeOrderItems = storeOrder.acceptedOffer.map(pick)\n\n const isSameOrder = storeOrder.orderNumber === orderForm.orderFormId\n const orderItemsAreSync = deepEquals(orderFormItems, storeOrderItems)\n\n return isSameOrder && orderItemsAreSync\n}\n\n/**\n * This resolver implements the optimistic cart behavior. The main idea in here\n * is that we receive a cart from the UI (as query params) and we validate it with\n * the commerce platform. If the cart is valid, we return null, if the cart is\n * invalid according to the commerce platform, we return the new cart the UI should use\n * instead.\n *\n * The algorithm is something like:\n * 1. Fetch orderForm from VTEX\n * 2. Compute delta changes between the orderForm and the UI's cart\n * 3. Update the orderForm in VTEX platform accordingly\n * 4. If any changes were made, send to the UI the new cart. Null otherwise\n */\nexport const validateCart = async (\n _: unknown,\n { cart: { order } }: { cart: IStoreCart },\n ctx: Context\n) => {\n const { orderNumber, acceptedOffer } = order\n const {\n clients: { commerce },\n loaders: { skuLoader },\n } = ctx\n\n // Step1: Get OrderForm from VTEX Commerce\n const orderForm = await commerce.checkout.orderForm({\n id: orderNumber,\n })\n\n // Step2: Process items from both browser and checkout so they have the same shape\n const browserItemsById = groupById(acceptedOffer)\n const originItemsById = groupById(orderForm.items.map(orderFormItemToOffer))\n const browserItems = Array.from(browserItemsById.values()) // items on the user's browser\n const originItems = Array.from(originItemsById.values()) // items on the VTEX platform backend\n\n // Step3: Compute delta changes\n const { itemsToAdd, itemsToUpdate } = browserItems.reduce(\n (acc, item) => {\n const maybeOriginItem = originItemsById.get(getId(item))\n\n if (!maybeOriginItem) {\n acc.itemsToAdd.push(item)\n } else {\n acc.itemsToUpdate.push({\n ...maybeOriginItem,\n quantity: item.quantity,\n })\n }\n\n return acc\n },\n {\n itemsToAdd: [] as IStoreOffer[],\n itemsToUpdate: [] as IStoreOffer[],\n }\n )\n\n const itemsToDelete = originItems\n .filter((item) => !browserItemsById.has(getId(item)))\n .map((item) => ({ ...item, quantity: 0 }))\n\n const changes = [...itemsToAdd, ...itemsToUpdate, ...itemsToDelete].map(\n offerToOrderItemInput\n )\n\n if (changes.length === 0) {\n return null\n }\n\n // Step4: Apply delta changes to order form\n const updatedOrderForm = await commerce.checkout.updateOrderFormItems({\n id: orderForm.orderFormId,\n orderItems: changes,\n })\n\n // Step5: If no changes detected before/after updating orderForm, the order is validated\n if (equals(order, updatedOrderForm)) {\n return null\n }\n\n // Step6: There were changes, convert orderForm to StoreOrder\n return {\n order: {\n orderNumber: updatedOrderForm.orderFormId,\n acceptedOffer: updatedOrderForm.items.map((item) => ({\n ...item,\n product: skuLoader.load([{ key: 'id', value: item.id }]), // TODO: add channel\n })),\n },\n messages: updatedOrderForm.messages.map(({ text, status }) => ({\n text,\n status: status.toUpperCase(),\n })),\n }\n}\n","export interface Channel {\n regionId?: string\n salesChannel?: string\n}\n\nexport default class ChannelMarshal {\n public static parse(channelString: string): Channel {\n try {\n const parsedChannel = JSON.parse(channelString) as Channel\n\n return {\n regionId: parsedChannel.regionId ?? '',\n salesChannel: parsedChannel.salesChannel ?? '',\n }\n } catch (error) {\n console.error(error)\n\n throw new Error('Malformed channel string')\n }\n }\n\n public static stringify(channel: Channel): string {\n return JSON.stringify(channel)\n }\n}\n","import type { Context } from '..'\nimport type {\n MutationUpdateSessionArgs,\n StoreSession,\n} from '../../../__generated__/schema'\nimport ChannelMarshal from '../utils/channel'\n\nexport const updateSession = async (\n _: any,\n { session }: MutationUpdateSessionArgs,\n { clients }: Context\n): Promise<StoreSession> => {\n const channel = ChannelMarshal.parse(session.channel ?? '')\n const regionData = await clients.commerce.checkout.region({\n postalCode: String(session.postalCode ?? '').replace(/\\D/g, ''),\n country: session.country ?? '',\n })\n\n return {\n ...session,\n channel: ChannelMarshal.stringify({\n ...channel,\n regionId: regionData?.[0]?.id,\n }),\n }\n}\n","import { slugify } from '../utils/slugify'\nimport type { Resolver } from '..'\nimport type { EnhancedSku } from '../utils/enhanceSku'\nimport { sortOfferByPrice } from './aggregateOffer'\n\ntype Root = EnhancedSku\n\nconst DEFAULT_IMAGE = {\n name: 'image',\n value:\n 'https://storecomponents.vtexassets.com/assets/faststore/images/image___117a6d3e229a96ad0e0d0876352566e2.svg',\n}\n\nconst getSlug = (link: string, id: string) => `${link}-${id}`\nconst getPath = (link: string, id: string) => `/${getSlug(link, id)}/p`\nconst nonEmptyArray = <T>(array: T[] | null | undefined) =>\n Array.isArray(array) && array.length > 0 ? array : null\n\nexport const StoreProduct: Record<string, Resolver<Root>> = {\n productID: ({ id }) => id,\n name: ({ isVariantOf, name }) => name ?? isVariantOf.name,\n slug: ({ isVariantOf: { link }, id }) => getSlug(link, id),\n description: ({ isVariantOf: { description } }) => description,\n seo: ({ isVariantOf: { name, description } }) => ({\n title: name,\n description,\n }),\n brand: ({ isVariantOf: { brand } }) => ({ name: brand }),\n breadcrumbList: ({ isVariantOf: { categoryTrees, name, link }, id }) => ({\n itemListElement: [\n ...categoryTrees.reverse().map(({ categoryNames }, index) => ({\n name: categoryNames[categoryNames.length - 1],\n item: `/${categoryNames\n .map((categoryName) => slugify(categoryName))\n .join('/')}`,\n position: index + 1,\n })),\n {\n name,\n item: getPath(link, id),\n position: categoryTrees.length + 1,\n },\n ],\n numberOfItems: categoryTrees.length,\n }),\n image: ({ isVariantOf, images }) =>\n (\n nonEmptyArray(images) ??\n nonEmptyArray(isVariantOf.images) ?? [DEFAULT_IMAGE]\n ).map(({ name, value }) => ({\n alternateName: name ?? '',\n url: value.replace('vteximg.com.br', 'vtexassets.com'),\n })),\n sku: ({ id }) => id,\n gtin: ({ reference }) => reference ?? '',\n review: () => [],\n aggregateRating: () => ({}),\n offers: async (product, _, ctx) => {\n const {\n loaders: { simulationLoader },\n storage: { channel },\n } = ctx\n\n const { id, policies } = product\n const sellers = policies.find((policy) => policy.id === channel)?.sellers\n\n if (sellers == null) {\n // This error will likely happen when you forget to forward the channel somewhere in your code.\n // Make sure all queries that lead to a product are forwarding the channel in context corectly\n throw new Error(\n `Product with id ${id} has no sellers for channel ${channel}.`\n )\n }\n\n // Unique seller ids\n const sellerIds = sellers.map((seller) => seller.id)\n const items = Array.from(new Set(sellerIds)).map((seller) => ({\n quantity: 1,\n seller,\n id,\n }))\n\n const simulation = await simulationLoader.load(items)\n\n return {\n ...simulation,\n items: sortOfferByPrice(simulation.items),\n product,\n }\n },\n isVariantOf: ({ isVariantOf }) => isVariantOf,\n additionalProperty: ({ attributes = [] }) =>\n attributes.map((attribute) => ({\n name: attribute.key,\n value: attribute.value,\n })),\n}\n","export interface SelectedFacet {\n key: string\n value: string\n}\n\n/**\n * Transform facets from the store to VTEX platform facets.\n * For instance, the channel in Store becomes trade-policy in VTEX's realm\n * */\nexport const transformSelectedFacet = ({ key, value }: SelectedFacet) => {\n switch (key) {\n case 'channel':\n return { key: 'trade-policy', value }\n\n default:\n return { key, value }\n }\n}\n","export const SORT_MAP = {\n price_desc: 'price:desc',\n price_asc: 'price:asc',\n orders_desc: 'orders:desc',\n name_desc: 'name:desc',\n name_asc: 'name:asc',\n release_desc: 'release:desc',\n discount_desc: 'discount:desc',\n score_desc: '',\n} as const\n","import { enhanceSku } from '../utils/enhanceSku'\nimport { transformSelectedFacet } from '../utils/facets'\nimport { SORT_MAP } from '../utils/sort'\nimport { StoreCollection } from './collection'\nimport type {\n QueryProductArgs,\n QueryAllCollectionsArgs,\n QueryAllProductsArgs,\n QuerySearchArgs,\n QueryCollectionArgs,\n} from '../../../__generated__/schema'\nimport type { CategoryTree } from '../clients/commerce/types/CategoryTree'\nimport type { Context } from '../index'\n\nexport const Query = {\n product: async (_: unknown, { locator }: QueryProductArgs, ctx: Context) => {\n // Insert channel in context for later usage\n ctx.storage = {\n ...ctx.storage,\n channel:\n locator.find((facet) => facet.key === 'channel')?.value ??\n ctx.storage.channel,\n }\n\n const {\n loaders: { skuLoader },\n } = ctx\n\n return skuLoader.load(locator.map(transformSelectedFacet))\n },\n collection: (_: unknown, { slug }: QueryCollectionArgs, ctx: Context) => {\n const {\n loaders: { collectionLoader },\n } = ctx\n\n return collectionLoader.load(slug)\n },\n search: async (\n _: unknown,\n { first, after: maybeAfter, sort, term, selectedFacets }: QuerySearchArgs,\n ctx: Context\n ) => {\n // Insert channel in context for later usage\n ctx.storage = {\n ...ctx.storage,\n channel:\n selectedFacets?.find((facet) => facet.key === 'channel')?.value ??\n ctx.storage.channel,\n }\n\n const after = maybeAfter ? Number(maybeAfter) : 0\n const searchArgs = {\n page: Math.ceil(after / first),\n count: first,\n query: term,\n sort: SORT_MAP[sort ?? 'score_desc'],\n selectedFacets: selectedFacets?.map(transformSelectedFacet) ?? [],\n }\n\n return searchArgs\n },\n allProducts: async (\n _: unknown,\n { first, after: maybeAfter }: QueryAllProductsArgs,\n ctx: Context\n ) => {\n const {\n clients: { search },\n } = ctx\n\n const after = maybeAfter ? Number(maybeAfter) : 0\n const products = await search.products({\n page: Math.ceil(after / first),\n count: first,\n })\n\n const skus = products.products\n .map((product) => product.skus.map((sku) => enhanceSku(sku, product)))\n .flat()\n .filter((sku) => sku.sellers.length > 0)\n\n return {\n pageInfo: {\n hasNextPage: products.pagination.after.length > 0,\n hasPreviousPage: products.pagination.before.length > 0,\n startCursor: '0',\n endCursor: products.total.toString(),\n totalCount: products.total,\n },\n // after + index is bigger than after+first itself because of the array flat() above\n edges: skus.map((sku, index) => ({\n node: sku,\n cursor: (after + index).toString(),\n })),\n }\n },\n allCollections: async (\n _: unknown,\n { first, after: maybeAfter }: QueryAllCollectionsArgs,\n ctx: Context\n ) => {\n const {\n clients: { commerce },\n } = ctx\n\n const after = maybeAfter ? Number(maybeAfter) : 0\n\n const [brands, tree] = await Promise.all([\n commerce.catalog.brand.list(),\n commerce.catalog.category.tree(),\n ])\n\n const categories: Array<CategoryTree & { level: number }> = []\n const dfs = (node: CategoryTree, level: number) => {\n categories.push({ ...node, level })\n\n for (const child of node.children) {\n dfs(child, level + 1)\n }\n }\n\n for (const node of tree) {\n dfs(node, 0)\n }\n\n const collections = [\n ...brands\n .filter((brand) => brand.isActive)\n .map((x) => ({ ...x, type: 'brand' })),\n ...categories,\n ]\n\n const validCollections = collections\n // Nullable slugs may cause one route to override the other\n .filter((node) => Boolean(StoreCollection.slug(node, null, ctx, null)))\n\n return {\n pageInfo: {\n hasNextPage: validCollections.length - after > first,\n hasPreviousPage: after > 0,\n startCursor: '0',\n endCursor: (\n Math.min(first, validCollections.length - after) - 1\n ).toString(),\n totalCount: validCollections.length,\n },\n edges: validCollections\n .slice(after, after + first)\n .map((node, index) => ({\n node,\n cursor: (after + index).toString(),\n })),\n }\n },\n person: async (_: unknown, __: unknown, ctx: Context) => {\n const {\n clients: { commerce },\n } = ctx\n\n const {\n namespaces: { profile = null },\n } = await commerce.session()\n\n return (\n profile && {\n id: profile.id?.value ?? '',\n email: profile.email?.value ?? '',\n givenName: profile.firstName?.value ?? '',\n familyName: profile.lastName?.value ?? '',\n }\n )\n },\n}\n","import { enhanceSku } from '../utils/enhanceSku'\nimport type { Resolver } from '..'\nimport type { SearchArgs } from '../clients/search'\nimport type { Attribute } from '../clients/search/types/AttributeSearchResult'\n\ntype Root = Omit<SearchArgs, 'type'>\n\nconst REMOVED_FACETS_FROM_COLLECTION_PAGE = ['departamento']\n\nexport const StoreSearchResult: Record<string, Resolver<Root>> = {\n products: async (searchArgs, _, ctx) => {\n const {\n clients: { search },\n } = ctx\n\n const products = await search.products(searchArgs)\n\n const skus = products.products\n .map((product) => {\n const [maybeSku] = product.skus\n\n return maybeSku && enhanceSku(maybeSku, product)\n })\n .filter((sku) => !!sku)\n\n return {\n pageInfo: {\n hasNextPage: products.pagination.after.length > 0,\n hasPreviousPage: products.pagination.before.length > 0,\n startCursor: '0',\n endCursor: products.total.toString(),\n totalCount: products.total,\n },\n edges: skus.map((sku, index) => ({\n node: sku,\n cursor: index.toString(),\n })),\n }\n },\n facets: async (searchArgs, _, ctx) => {\n const {\n clients: { search: is },\n } = ctx\n\n const facets = await is.facets(searchArgs)\n\n const isCollectionPage = !searchArgs.query\n const filteredFacets = facets?.attributes?.reduce((acc, currentFacet) => {\n const shouldFilterFacet = REMOVED_FACETS_FROM_COLLECTION_PAGE.includes(\n currentFacet.key\n )\n\n const shouldRemoveFacetFromCollectionPage =\n isCollectionPage && shouldFilterFacet\n\n if (shouldRemoveFacetFromCollectionPage) {\n return acc\n }\n\n currentFacet.values.sort((a, b) => {\n const firstItemLabel = a.label ?? ''\n const secondItemLabel = b.label ?? ''\n\n return firstItemLabel.localeCompare(secondItemLabel)\n })\n\n acc.push(currentFacet)\n\n return acc\n }, [] as Attribute[])\n\n return filteredFacets ?? []\n },\n}\n","import { getClients } from './clients'\nimport { getLoaders } from './loaders'\nimport { StoreAggregateOffer } from './resolvers/aggregateOffer'\nimport { StoreAggregateRating } from './resolvers/aggregateRating'\nimport { StoreCollection } from './resolvers/collection'\nimport { StoreFacet } from './resolvers/facet'\nimport { StoreFacetValue } from './resolvers/facetValue'\nimport { Mutation } from './resolvers/mutation'\nimport { StoreOffer } from './resolvers/offer'\nimport { StoreProduct } from './resolvers/product'\nimport { StoreProductGroup } from './resolvers/productGroup'\nimport { Query } from './resolvers/query'\nimport { StoreReview } from './resolvers/review'\nimport { StoreSearchResult } from './resolvers/searchResult'\nimport { StoreSeo } from './resolvers/seo'\nimport type { Loaders } from './loaders'\nimport type { Clients } from './clients'\n\nexport interface Options {\n platform: 'vtex'\n account: string\n environment: 'vtexcommercestable' | 'vtexcommercebeta'\n // Default sales channel to use for fetching products\n channel: string\n hideUnavailableItems: boolean\n}\n\nexport interface Context {\n clients: Clients\n loaders: Loaders\n /**\n * @description Storage updated at each request.\n *\n * Use this datastructure to store and share small values in the context.\n * Use it with caution since dependecy injection leads to a more complex code\n * */\n storage: {\n channel: string\n }\n headers: Record<string, string>\n}\n\nexport type Resolver<R = unknown, A = unknown> = (\n root: R,\n args: A,\n ctx: Context,\n info: any\n) => any\n\nconst Resolvers = {\n StoreCollection,\n StoreAggregateOffer,\n StoreProduct,\n StoreSeo,\n StoreFacet,\n StoreFacetValue,\n StoreOffer,\n StoreAggregateRating,\n StoreReview,\n StoreProductGroup,\n StoreSearchResult,\n Query,\n Mutation,\n}\n\nexport const getContextFactory = (options: Options) => (ctx: any) => {\n ctx.storage = {\n channel: options.channel,\n }\n ctx.clients = getClients(options, ctx)\n ctx.loaders = getLoaders(options, ctx)\n\n return ctx\n}\n\nexport const getResolvers = (_: Options) => Resolvers\n","import type { Resolver } from '..'\n\ntype Root = { title?: string; description?: string }\n\nexport const StoreSeo: Record<string, Resolver<Root>> = {\n title: ({ title }) => title ?? '',\n description: ({ description }) => description ?? '',\n titleTemplate: () => '',\n canonical: () => '',\n}\n","import type { Resolver } from '..'\nimport type { Attribute } from '../clients/search/types/AttributeSearchResult'\n\ntype Root = Attribute\n\nexport const StoreFacet: Record<string, Resolver<Root>> = {\n key: ({ key }) => key,\n label: ({ label }) => label,\n values: ({ values }) => values,\n type: ({ type }) => (type === 'text' ? 'BOOLEAN' : 'RANGE'),\n}\n","import type { Resolver } from '..'\nimport type { Value } from '../clients/search/types/AttributeSearchResult'\n\ntype Root = Value\n\nexport const StoreFacetValue: Record<string, Resolver<Root>> = {\n value: ({ key, from, to }) => key ?? `${from}-to-${to}`,\n label: ({ label }) => label ?? 'unknown',\n selected: ({ active }) => active,\n quantity: ({ count }) => count,\n}\n","import type { EnhancedSku } from '../utils/enhanceSku'\nimport type { Resolver } from '..'\nimport type { Item } from '../clients/commerce/types/Simulation'\nimport type { OrderFormItem } from '../clients/commerce/types/OrderForm'\n\ntype Root =\n | (Item & { product: EnhancedSku }) // when querying search/product\n | (OrderFormItem & { product: Promise<EnhancedSku> }) // when querying order\n\nexport const StoreOffer: Record<string, Resolver<Root>> = {\n priceCurrency: () => '',\n priceValidUntil: ({ priceValidUntil }) => priceValidUntil ?? '',\n itemCondition: () => 'https://schema.org/NewCondition',\n availability: ({ availability }) =>\n availability === 'available'\n ? 'https://schema.org/InStock'\n : 'https://schema.org/OutOfStock',\n seller: ({ seller }) => ({\n identifier: seller,\n }),\n price: ({ sellingPrice }) => sellingPrice / 1e2, // TODO add spot price calculation\n sellingPrice: ({ sellingPrice }) => sellingPrice / 1e2,\n listPrice: ({ listPrice }) => listPrice / 1e2,\n itemOffered: ({ product }) => product,\n quantity: ({ quantity }) => quantity,\n}\n","import type { Resolver } from '..'\n\n// TODO: Add a review system integration\nexport const StoreAggregateRating: Record<string, Resolver> = {\n ratingValue: () => 5,\n reviewCount: () => 0,\n}\n","import type { Resolver } from '..'\n\nexport const StoreReview: Record<string, Resolver> = {\n reviewRating: () => ({\n ratingValue: 5,\n bestRating: 5,\n }),\n author: () => ({\n name: '',\n }),\n}\n","import { enhanceSku } from '../utils/enhanceSku'\nimport type { Product } from '../clients/search/types/ProductSearchResult'\nimport type { Resolver } from '..'\n\nexport const StoreProductGroup: Record<string, Resolver<Product>> = {\n hasVariant: (root) => root.skus.map((sku) => enhanceSku(sku, root)),\n productGroupID: ({ product }) => product,\n name: ({ name }) => name,\n additionalProperty: ({ textAttributes = [], productSpecifications = [] }) => {\n const specs = new Set(productSpecifications)\n\n return textAttributes\n .filter((attribute) => specs.has(attribute.labelKey))\n .map((attribute) => ({\n name: attribute.labelKey,\n value: attribute.labelValue,\n }))\n },\n}\n","import { validateCart } from './validateCart'\nimport { updateSession } from './updateSession'\n\nexport const Mutation = {\n validateCart,\n updateSession,\n}\n","import { print } from 'graphql'\n\nimport AggregateOffer from './aggregateOffer.graphql'\nimport AggregateRating from './aggregateRating.graphql'\nimport Author from './author.graphql'\nimport Brand from './brand.graphql'\nimport Breadcrumb from './breadcrumb.graphql'\nimport Collection from './collection.graphql'\nimport Facet from './facet.graphql'\nimport Image from './image.graphql'\nimport Mutation from './mutation.graphql'\nimport Offer from './offer.graphql'\nimport Order from './order.graphql'\nimport Organization from './organization.graphql'\nimport PageInfo from './pageInfo.graphql'\nimport Product from './product.graphql'\nimport ProductGroup from './productGroup.graphql'\nimport Query from './query.graphql'\nimport Review from './review.graphql'\nimport Seo from './seo.graphql'\nimport Cart from './cart.graphql'\nimport Status from './status.graphql'\nimport PropertyValue from './propertyValue.graphql'\nimport Person from './person.graphql'\n\nexport const typeDefs = [\n Query,\n Mutation,\n Brand,\n Breadcrumb,\n Collection,\n Facet,\n Image,\n PageInfo,\n Product,\n Seo,\n Offer,\n AggregateRating,\n Review,\n Author,\n ProductGroup,\n Organization,\n AggregateOffer,\n Order,\n Cart,\n Status,\n PropertyValue,\n Person,\n]\n .map(print)\n .join('\\n')\n","import { makeExecutableSchema } from '@graphql-tools/schema'\n\nimport {\n getContextFactory as getContextFactoryVTEX,\n getResolvers as getResolversVTEX,\n} from './platforms/vtex'\nimport { typeDefs } from './typeDefs'\nimport type { Options as OptionsVTEX } from './platforms/vtex'\n\nexport * from './__generated__/schema'\n\nexport type Options = OptionsVTEX\n\nconst platforms = {\n vtex: {\n getResolvers: getResolversVTEX,\n getContextFactory: getContextFactoryVTEX,\n },\n}\n\nexport const getTypeDefs = () => typeDefs\n\nexport const getResolvers = (options: Options) =>\n platforms[options.platform].getResolvers(options)\n\nexport const getContextFactory = (options: Options) =>\n platforms[options.platform].getContextFactory(options)\n\nexport const getSchema = async (options: Options) =>\n makeExecutableSchema({\n resolvers: getResolvers(options),\n typeDefs,\n })\n","import { VtexCommerce } from './commerce'\nimport { IntelligentSearch } from './search'\nimport type { Context, Options } from '..'\n\nexport type Clients = ReturnType<typeof getClients>\n\nexport const getClients = (options: Options, ctx: Context) => {\n const search = IntelligentSearch(options, ctx)\n const commerce = VtexCommerce(options, ctx)\n\n return {\n search,\n commerce,\n }\n}\n","import { getSimulationLoader } from './simulation'\nimport { getSkuLoader } from './sku'\nimport { getCollectionLoader } from './collection'\nimport type { Context, Options } from '..'\n\nexport type Loaders = ReturnType<typeof getLoaders>\n\nexport const getLoaders = (options: Options, { clients }: Context) => {\n const skuLoader = getSkuLoader(options, clients)\n const simulationLoader = getSimulationLoader(options, clients)\n const collectionLoader = getCollectionLoader(options, clients)\n\n return {\n skuLoader,\n simulationLoader,\n collectionLoader,\n }\n}\n","import DataLoader from 'dataloader'\n\nimport { BadRequestError } from '../utils/errors'\nimport { enhanceSku } from '../utils/enhanceSku'\nimport type { EnhancedSku } from '../utils/enhanceSku'\nimport type { Options } from '..'\nimport type { Clients } from '../clients'\nimport type { SelectedFacet } from '../utils/facets'\n\nexport const getSkuLoader = (_: Options, clients: Clients) => {\n const loader = async (facetsList: readonly SelectedFacet[][]) => {\n const skuIds = facetsList.map((facets) => {\n const maybeFacet = facets.find(({ key }) => key === 'id')\n\n if (!maybeFacet) {\n throw new BadRequestError(\n 'Error while loading SKU. Needs to pass an id to selected facets'\n )\n }\n\n return maybeFacet.value\n })\n\n const { products } = await clients.search.products({\n query: `sku:${skuIds.join(';')}`,\n page: 0,\n count: skuIds.length,\n })\n\n const skuBySkuId = products.reduce((acc, product) => {\n for (const sku of product.skus) {\n acc[sku.id] = enhanceSku(sku, product)\n }\n\n return acc\n }, {} as Record<string, EnhancedSku>)\n\n const skus = skuIds.map((skuId) => skuBySkuId[skuId])\n const missingSkus = skus.filter((sku) => !sku)\n\n if (missingSkus.length > 0) {\n throw new Error(\n `Search API did not return the following skus: ${missingSkus.join(',')}`\n )\n }\n\n return skus\n }\n\n return new DataLoader<SelectedFacet[], EnhancedSku>(loader, {\n maxBatchSize: 99, // Max allowed batch size of Search API\n })\n}\n","import DataLoader from 'dataloader'\nimport pLimit from 'p-limit'\n\nimport type {\n PayloadItem,\n Simulation,\n} from '../clients/commerce/types/Simulation'\nimport type { Options } from '..'\nimport type { Clients } from '../clients'\n\n// Limits concurrent requests to the API per request cycle\nconst CONCURRENT_REQUESTS_MAX = 1\n\nexport const getSimulationLoader = (_: Options, clients: Clients) => {\n const limit = pLimit(CONCURRENT_REQUESTS_MAX)\n\n const loader = async (allItems: readonly PayloadItem[][]) => {\n const items = [...allItems.flat()]\n const simulation = await clients.commerce.checkout.simulation({\n items,\n })\n\n // Sort and filter simulation since Checkout API may return\n // items that we didn't ask for\n const simulated = simulation.items.reduce((acc, item) => {\n const index = item.requestIndex\n\n if (typeof index === 'number' && index < acc.length) {\n acc[index] = item\n }\n\n return acc\n }, Array(items.length).fill(null) as Simulation['items'])\n\n const itemsIndices = allItems.reduce(\n (acc, curr) => [...acc, curr.length + acc[acc.length - 1]],\n [0]\n )\n\n return allItems.map((__, index) => ({\n ...simulation,\n items: simulated\n .slice(itemsIndices[index], itemsIndices[index + 1])\n .filter((item) => Boolean(item)),\n }))\n }\n\n const limited = async (allItems: readonly PayloadItem[][]) =>\n limit(loader, allItems)\n\n return new DataLoader<PayloadItem[], Simulation>(limited, {\n maxBatchSize: 50,\n })\n}\n"],"names":["fetchAPI","async","info","init","response","fetch","ok","json","console","error","text","Error","BASE_INIT","method","headers","IntelligentSearch","account","environment","hideUnavailableItems","ctx","base","policyFacet","key","value","storage","channel","search","query","page","count","sort","selectedFacets","type","fuzzy","params","URLSearchParams","toString","undefined","append","pathname","facets","find","map","join","args","products","BadRequestError","constructor","message","name","NotFoundError","enhanceSku","sku","product","isVariantOf","collectionPageTypes","Set","isCollectionPageType","x","pageType","has","toLowerCase","inStock","item","availability","sortOfferByPrice","items","a","b","sellingPrice","StoreAggregateOffer","highPrice","filter","pop","_availableItems$pop","lowPrice","_availableItems$","offerCount","length","priceCurrency","offers","slugify","path","rawSlugify","separator","lowercase","isBrand","root","baseSlugify","URL","url","slice","StoreCollection","id","slug","seo","title","description","metaTagDescription","Title","MetaTagDescription","level","meta","split","segment","index","breadcrumbList","_","loaders","collectionLoader","segments","Boolean","slugs","__","collections","Promise","all","s","load","itemListElement","collection","position","numberOfItems","getId","itemOffered","seller","identifier","price","orderFormItemToOffer","listPrice","quantity","image","offerToOrderItemInput","offer","groupById","reduce","acc","set","get","Map","ChannelMarshal","channelString","parsedChannel","JSON","parse","regionId","salesChannel","stringify","DEFAULT_IMAGE","getSlug","link","getPath","nonEmptyArray","array","Array","isArray","transformSelectedFacet","SORT_MAP","price_desc","price_asc","orders_desc","name_desc","name_asc","release_desc","discount_desc","score_desc","Query","locator","facet","_locator$find","skuLoader","first","after","maybeAfter","term","_selectedFacets$find","Number","Math","ceil","allProducts","clients","skus","flat","sellers","pageInfo","hasNextPage","pagination","hasPreviousPage","before","startCursor","endCursor","total","totalCount","edges","node","cursor","allCollections","commerce","brands","tree","catalog","brand","list","category","categories","dfs","push","child","children","validCollections","isActive","min","person","namespaces","profile","session","_profile$id","email","_profile$email","givenName","firstName","_profile$firstName","familyName","lastName","_profile$lastName","REMOVED_FACETS_FROM_COLLECTION_PAGE","Resolvers","StoreProduct","productID","categoryTrees","reverse","categoryNames","categoryName","images","alternateName","replace","gtin","reference","review","aggregateRating","simulationLoader","policies","policy","_policies$find","sellerIds","from","simulation","additionalProperty","attributes","attribute","StoreSeo","titleTemplate","canonical","StoreFacet","label","values","StoreFacetValue","to","selected","active","StoreOffer","priceValidUntil","itemCondition","StoreAggregateRating","ratingValue","reviewCount","StoreReview","reviewRating","bestRating","author","StoreProductGroup","hasVariant","productGroupID","textAttributes","productSpecifications","specs","labelKey","labelValue","StoreSearchResult","searchArgs","maybeSku","is","isCollectionPage","filteredFacets","_facets$attributes","currentFacet","shouldFilterFacet","includes","firstItemLabel","secondItemLabel","localeCompare","Mutation","validateCart","cart","order","orderNumber","acceptedOffer","orderForm","checkout","browserItemsById","originItemsById","browserItems","originItems","itemsToAdd","itemsToUpdate","maybeOriginItem","changes","updatedOrderForm","updateOrderFormItems","orderFormId","orderItems","storeOrder","pick","orderFormItems","storeOrderItems","isSameOrder","orderItemsAreSync","deepEquals","equals","messages","status","toUpperCase","updateSession","regionData","region","postalCode","String","country","_regionData$","typeDefs","Brand","Breadcrumb","Collection","Facet","Image","PageInfo","Product","Seo","Offer","AggregateRating","Review","Author","ProductGroup","Organization","AggregateOffer","Order","Cart","Status","PropertyValue","Person","print","platforms","vtex","getResolvers","getContextFactory","options","depth","portal","pagetype","sc","body","refreshOutdatedData","allowOutdatedData","cookie","VtexCommerce","getClients","DataLoader","skuIds","facetsList","maybeFacet","skuBySkuId","skuId","missingSkus","maxBatchSize","getSkuLoader","limit","pLimit","loader","allItems","simulated","requestIndex","fill","itemsIndices","curr","getSimulationLoader","batch","getCollectionLoader","getLoaders","platform","makeExecutableSchema","resolvers"],"mappings":"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"}
1
+ {"version":3,"file":"api.cjs.production.min.js","sources":["../src/platforms/vtex/clients/fetch.ts","../src/platforms/vtex/clients/commerce/index.ts","../src/platforms/vtex/clients/search/index.ts","../src/platforms/vtex/utils/errors.ts","../src/platforms/vtex/utils/enhanceSku.ts","../src/platforms/vtex/loaders/collection.ts","../src/platforms/vtex/resolvers/aggregateOffer.ts","../src/platforms/vtex/utils/slugify.ts","../src/platforms/vtex/resolvers/collection.ts","../src/platforms/vtex/resolvers/validateCart.ts","../src/platforms/vtex/utils/channel.ts","../src/platforms/vtex/resolvers/product.ts","../src/platforms/vtex/utils/facets.ts","../src/platforms/vtex/utils/sort.ts","../src/platforms/vtex/resolvers/query.ts","../src/platforms/vtex/resolvers/searchResult.ts","../src/platforms/vtex/index.ts","../src/platforms/vtex/resolvers/seo.ts","../src/platforms/vtex/resolvers/facet.ts","../src/platforms/vtex/resolvers/facetValue.ts","../src/platforms/vtex/resolvers/offer.ts","../src/platforms/vtex/resolvers/aggregateRating.ts","../src/platforms/vtex/resolvers/review.ts","../src/platforms/vtex/resolvers/productGroup.ts","../src/platforms/vtex/resolvers/mutation.ts","../src/platforms/vtex/resolvers/updateSession.ts","../src/typeDefs/index.ts","../src/index.ts","../src/platforms/vtex/clients/index.ts","../src/platforms/vtex/loaders/index.ts","../src/platforms/vtex/loaders/sku.ts","../src/platforms/vtex/loaders/simulation.ts"],"sourcesContent":["import fetch from 'isomorphic-unfetch'\n\nexport const fetchAPI = async (info: RequestInfo, init?: RequestInit) => {\n const response = await fetch(info, init)\n\n if (response.ok) {\n return response.json()\n }\n\n console.error(info, init, response)\n const text = await response.text()\n\n throw new Error(text)\n}\n","import type { Context, Options } from '../../index'\nimport { fetchAPI } from '../fetch'\nimport type { Brand } from './types/Brand'\nimport type { CategoryTree } from './types/CategoryTree'\nimport type { OrderForm, OrderFormInputItem } from './types/OrderForm'\nimport type { PortalPagetype } from './types/Portal'\nimport type { Region, RegionInput } from './types/Region'\nimport type {\n Simulation,\n SimulationArgs,\n SimulationOptions,\n} from './types/Simulation'\nimport type { Session } from './types/Session'\nimport type { Channel } from '../../utils/channel'\n\nconst BASE_INIT = {\n method: 'POST',\n headers: {\n 'content-type': 'application/json',\n },\n}\n\nexport const VtexCommerce = (\n { account, environment }: Options,\n ctx: Context\n) => {\n const base = `https://${account}.${environment}.com.br`\n\n return {\n catalog: {\n brand: {\n list: (): Promise<Brand[]> =>\n fetchAPI(`${base}/api/catalog_system/pub/brand/list`),\n },\n category: {\n tree: (depth = 3): Promise<CategoryTree[]> =>\n fetchAPI(`${base}/api/catalog_system/pub/category/tree/${depth}`),\n },\n portal: {\n pagetype: (slug: string): Promise<PortalPagetype> =>\n fetchAPI(`${base}/api/catalog_system/pub/portal/pagetype/${slug}`),\n },\n },\n checkout: {\n simulation: (\n args: SimulationArgs,\n { salesChannel }: SimulationOptions = ctx.storage.channel\n ): Promise<Simulation> => {\n const params = new URLSearchParams({\n sc: salesChannel,\n })\n\n return fetchAPI(\n `${base}/api/checkout/pub/orderForms/simulation?${params.toString()}`,\n {\n ...BASE_INIT,\n body: JSON.stringify(args),\n }\n )\n },\n orderForm: ({\n id,\n refreshOutdatedData = true,\n channel = ctx.storage.channel,\n }: {\n id: string\n refreshOutdatedData?: boolean\n channel?: Required<Channel>\n }): Promise<OrderForm> => {\n const { salesChannel } = channel\n const params = new URLSearchParams({\n refreshOutdatedData: refreshOutdatedData.toString(),\n sc: salesChannel,\n })\n\n return fetchAPI(\n `${base}/api/checkout/pub/orderForm/${id}?${params.toString()}`,\n BASE_INIT\n )\n },\n updateOrderFormItems: ({\n id,\n orderItems,\n allowOutdatedData = 'paymentData',\n salesChannel = ctx.storage.channel.salesChannel,\n }: {\n id: string\n orderItems: OrderFormInputItem[]\n allowOutdatedData?: 'paymentData'\n salesChannel?: string\n }): Promise<OrderForm> => {\n const params = new URLSearchParams({\n allowOutdatedData,\n sc: salesChannel,\n })\n\n return fetchAPI(\n `${base}/api/checkout/pub/orderForm/${id}/items?${params}`,\n {\n ...BASE_INIT,\n body: JSON.stringify({ orderItems }),\n method: 'PATCH',\n }\n )\n },\n region: async ({\n postalCode,\n country,\n salesChannel,\n }: RegionInput): Promise<Region> => {\n return fetchAPI(\n `${base}/api/checkout/pub/regions/?postalCode=${postalCode}&country=${country}&sc=${\n salesChannel ?? ''\n }`\n )\n },\n },\n session: (): Promise<Session> =>\n fetchAPI(\n `${base}/api/sessions?items=profile.id,profile.email,profile.firstName,profile.lastName`,\n {\n method: 'POST',\n headers: {\n 'content-type': 'application/json',\n cookie: ctx.headers.cookie,\n },\n body: '{}',\n }\n ),\n }\n}\n","import type { Context, Options } from '../../index'\nimport { fetchAPI } from '../fetch'\nimport type { SelectedFacet } from '../../utils/facets'\nimport type { ProductSearchResult } from './types/ProductSearchResult'\nimport type { AttributeSearchResult } from './types/AttributeSearchResult'\nimport type { IStoreSelectedFacet } from '../../../../__generated__/schema'\n\nexport type Sort =\n | 'price:desc'\n | 'price:asc'\n | 'orders:desc'\n | 'name:desc'\n | 'name:asc'\n | 'release:desc'\n | 'discount:desc'\n | ''\n\nexport interface SearchArgs {\n query?: string\n page: number\n count: number\n type: 'product_search' | 'attribute_search'\n sort?: Sort\n selectedFacets?: SelectedFacet[]\n fuzzy?: '0' | '1'\n hideUnavailableItems?: boolean\n}\n\nexport interface ProductLocator {\n field: 'id' | 'slug'\n value: string\n}\n\nexport const IntelligentSearch = (\n { account, environment, hideUnavailableItems }: Options,\n ctx: Context\n) => {\n const base = `http://portal.${environment}.com.br/search-api/v1/${account}`\n const policyFacet: IStoreSelectedFacet = {\n key: 'trade-policy',\n value: ctx.storage.channel.salesChannel,\n }\n\n const addDefaultFacets = (facets: SelectedFacet[]) => {\n const facet = facets.find(({ key }) => key === policyFacet.key)\n\n if (facet === undefined) {\n return [...facets, policyFacet]\n }\n\n return facets\n }\n\n const search = <T>({\n query = '',\n page,\n count,\n sort = '',\n selectedFacets = [],\n type,\n fuzzy = '0',\n }: SearchArgs): Promise<T> => {\n const params = new URLSearchParams({\n page: (page + 1).toString(),\n count: count.toString(),\n query,\n sort,\n fuzzy,\n })\n\n if (hideUnavailableItems !== undefined) {\n params.append('hide-unavailable-items', hideUnavailableItems.toString())\n }\n\n const pathname = addDefaultFacets(selectedFacets)\n .map(({ key, value }) => `${key}/${value}`)\n .join('/')\n\n return fetchAPI(\n `${base}/api/split/${type}/${pathname}?${params.toString()}`\n )\n }\n\n const products = (args: Omit<SearchArgs, 'type'>) =>\n search<ProductSearchResult>({ ...args, type: 'product_search' })\n\n const facets = (args: Omit<SearchArgs, 'type'>) =>\n search<AttributeSearchResult>({ ...args, type: 'attribute_search' })\n\n return {\n facets,\n products,\n }\n}\n","export class BadRequestError extends Error {\n constructor(message: string) {\n super(message)\n this.name = 'BadRequestError'\n }\n}\n\nexport class NotFoundError extends Error {\n constructor(message: string) {\n super(message)\n this.name = 'NotFoundError'\n }\n}\n","import type { Product, Sku } from '../clients/search/types/ProductSearchResult'\n\nexport type EnhancedSku = Sku & { isVariantOf: Product }\n\nexport const enhanceSku = (sku: Sku, product: Product): EnhancedSku => ({\n ...sku,\n isVariantOf: product,\n})\n","import DataLoader from 'dataloader'\nimport pLimit from 'p-limit'\n\nimport { NotFoundError } from '../utils/errors'\nimport type { CollectionPageType } from '../clients/commerce/types/Portal'\nimport type { Options } from '..'\nimport type { Clients } from '../clients'\n\n// Limits concurrent requests to 20 so that they don't timeout\nconst CONCURRENT_REQUESTS_MAX = 20\n\nconst collectionPageTypes = new Set([\n 'brand',\n 'category',\n 'department',\n 'subcategory',\n] as const)\n\nexport const isCollectionPageType = (x: any): x is CollectionPageType =>\n typeof x.pageType === 'string' &&\n collectionPageTypes.has(x.pageType.toLowerCase())\n\nexport const getCollectionLoader = (_: Options, clients: Clients) => {\n const limit = pLimit(CONCURRENT_REQUESTS_MAX)\n\n const loader = async (\n slugs: readonly string[]\n ): Promise<CollectionPageType[]> => {\n return Promise.all(\n slugs.map((slug: string) =>\n limit(async () => {\n const page = await clients.commerce.catalog.portal.pagetype(slug)\n\n if (isCollectionPageType(page)) {\n return page\n }\n\n throw new NotFoundError(\n `Catalog returned ${page.pageType} for slug: ${slug}. This usually happens when there is more than one category with the same name in the same category tree level.`\n )\n })\n )\n )\n }\n\n return new DataLoader<string, CollectionPageType>(loader, {\n // DataLoader is being used to cache requests, not to batch them\n batch: false,\n })\n}\n","import type { EnhancedSku } from '../utils/enhanceSku'\nimport type { Simulation } from '../clients/commerce/types/Simulation'\n\ntype Resolvers = (root: Simulation & { product: EnhancedSku }) => unknown\n\nconst inStock = (item: Simulation['items'][0]) =>\n item.availability === 'available'\n\n// Smallest Available Selling Price First\nexport const sortOfferByPrice = (\n items: Simulation['items']\n): Simulation['items'] =>\n items.sort((a, b) => {\n if (inStock(a) && !inStock(b)) {\n return -1\n }\n\n if (!inStock(a) && inStock(b)) {\n return 1\n }\n\n return a.sellingPrice - b.sellingPrice\n })\n\nexport const StoreAggregateOffer: Record<string, Resolvers> = {\n highPrice: ({ items }) => {\n const availableItems = items.filter(inStock)\n const highPrice = availableItems.pop()?.sellingPrice\n\n return (highPrice ?? 0) / 1e2\n },\n lowPrice: ({ items }) => {\n const availableItems = items.filter(inStock)\n const lowPrice = availableItems[0]?.sellingPrice\n\n return (lowPrice ?? 0) / 1e2\n },\n offerCount: ({ items }) => items.length,\n priceCurrency: () => '',\n offers: ({ items, product }) => items.map((item) => ({ ...item, product })),\n}\n","import rawSlugify from '@sindresorhus/slugify'\n\nexport const slugify = (path: string) =>\n rawSlugify(path, { separator: '-', lowercase: true })\n","import { isCollectionPageType } from '../loaders/collection'\nimport { slugify as baseSlugify } from '../utils/slugify'\nimport type { Resolver } from '..'\nimport type { Brand } from '../clients/commerce/types/Brand'\nimport type { CategoryTree } from '../clients/commerce/types/CategoryTree'\nimport type { CollectionPageType } from '../clients/commerce/types/Portal'\n\ntype Root = Brand | (CategoryTree & { level: number }) | CollectionPageType\n\nconst isBrand = (x: any): x is Brand => x.type === 'brand'\n\nconst slugify = (root: Root) => {\n if (isBrand(root)) {\n return baseSlugify(root.name.toLowerCase())\n }\n\n if (isCollectionPageType(root)) {\n return new URL(`https://${root.url}`).pathname.slice(1)\n }\n\n return new URL(root.url).pathname.slice(1)\n}\n\nexport const StoreCollection: Record<string, Resolver<Root>> = {\n id: ({ id }) => id.toString(),\n slug: (root) => slugify(root),\n seo: (root) =>\n isBrand(root) || isCollectionPageType(root)\n ? {\n title: root.title,\n description: root.metaTagDescription,\n }\n : {\n title: root.Title,\n description: root.MetaTagDescription,\n },\n type: (root) =>\n isBrand(root)\n ? 'Brand'\n : isCollectionPageType(root)\n ? root.pageType\n : root.level === 0\n ? 'Department'\n : 'Category',\n meta: (root) =>\n isBrand(root)\n ? {\n selectedFacets: [{ key: 'brand', value: baseSlugify(root.name) }],\n }\n : {\n selectedFacets: new URL(\n isCollectionPageType(root) ? `https://${root.url}` : root.url\n ).pathname\n .slice(1)\n .split('/')\n .map((segment, index) => ({\n key: `category-${index + 1}`,\n value: baseSlugify(segment),\n })),\n },\n breadcrumbList: async (root, _, ctx) => {\n const {\n loaders: { collectionLoader },\n } = ctx\n\n const slug = slugify(root)\n\n /**\n * Split slug into segments so we fetch all data for\n * the breadcrumb. For instance, if we get `/foo/bar`\n * we need all metadata for both `/foo` and `/bar` and\n * thus we need to fetch pageType for `/foo` and `/bar`\n */\n const segments = slug.split('/').filter((segment) => Boolean(segment))\n const slugs = segments.map((__, index) =>\n segments.slice(0, index + 1).join('/')\n )\n\n const collections = await Promise.all(\n slugs.map((s) => collectionLoader.load(s))\n )\n\n return {\n itemListElement: collections.map((collection, index) => ({\n item: new URL(`https://${collection.url}`).pathname.toLowerCase(),\n name: collection.name,\n position: index + 1,\n })),\n numberOfItems: collections.length,\n }\n },\n}\n","import deepEquals from 'fast-deep-equal'\n\nimport type {\n IStoreOrder,\n IStoreCart,\n IStoreOffer,\n} from '../../../__generated__/schema'\nimport type {\n OrderForm,\n OrderFormItem,\n OrderFormInputItem,\n} from '../clients/commerce/types/OrderForm'\nimport type { Context } from '..'\n\ntype Indexed<T> = T & { index?: number }\n\nconst getId = (item: IStoreOffer) =>\n [item.itemOffered.sku, item.seller.identifier, item.price].join('::')\n\nconst orderFormItemToOffer = (\n item: OrderFormItem,\n index?: number\n): Indexed<IStoreOffer> => ({\n listPrice: item.listPrice / 100,\n price: item.sellingPrice / 100,\n quantity: item.quantity,\n seller: { identifier: item.seller },\n itemOffered: {\n sku: item.id,\n image: [],\n name: item.name,\n },\n index,\n})\n\nconst offerToOrderItemInput = (\n offer: Indexed<IStoreOffer>\n): OrderFormInputItem => ({\n quantity: offer.quantity,\n seller: offer.seller.identifier,\n id: offer.itemOffered.sku,\n index: offer.index,\n})\n\nconst groupById = (offers: IStoreOffer[]): Map<string, IStoreOffer> =>\n offers.reduce((acc, item) => {\n const id = getId(item)\n\n acc.set(id, acc.get(id) ?? item)\n\n return acc\n }, new Map<string, IStoreOffer>())\n\nconst equals = (storeOrder: IStoreOrder, orderForm: OrderForm) => {\n const pick = (item: Indexed<IStoreOffer>, index: number) => ({\n ...item,\n itemOffered: {\n sku: item.itemOffered.sku,\n },\n index,\n })\n\n const orderFormItems = orderForm.items.map(orderFormItemToOffer).map(pick)\n const storeOrderItems = storeOrder.acceptedOffer.map(pick)\n\n const isSameOrder = storeOrder.orderNumber === orderForm.orderFormId\n const orderItemsAreSync = deepEquals(orderFormItems, storeOrderItems)\n\n return isSameOrder && orderItemsAreSync\n}\n\n/**\n * This resolver implements the optimistic cart behavior. The main idea in here\n * is that we receive a cart from the UI (as query params) and we validate it with\n * the commerce platform. If the cart is valid, we return null, if the cart is\n * invalid according to the commerce platform, we return the new cart the UI should use\n * instead.\n *\n * The algorithm is something like:\n * 1. Fetch orderForm from VTEX\n * 2. Compute delta changes between the orderForm and the UI's cart\n * 3. Update the orderForm in VTEX platform accordingly\n * 4. If any changes were made, send to the UI the new cart. Null otherwise\n */\nexport const validateCart = async (\n _: unknown,\n { cart: { order } }: { cart: IStoreCart },\n ctx: Context\n) => {\n const { orderNumber, acceptedOffer } = order\n const {\n clients: { commerce },\n loaders: { skuLoader },\n } = ctx\n\n // Step1: Get OrderForm from VTEX Commerce\n const orderForm = await commerce.checkout.orderForm({\n id: orderNumber,\n })\n\n // Step2: Process items from both browser and checkout so they have the same shape\n const browserItemsById = groupById(acceptedOffer)\n const originItemsById = groupById(orderForm.items.map(orderFormItemToOffer))\n const browserItems = Array.from(browserItemsById.values()) // items on the user's browser\n const originItems = Array.from(originItemsById.values()) // items on the VTEX platform backend\n\n // Step3: Compute delta changes\n const { itemsToAdd, itemsToUpdate } = browserItems.reduce(\n (acc, item) => {\n const maybeOriginItem = originItemsById.get(getId(item))\n\n if (!maybeOriginItem) {\n acc.itemsToAdd.push(item)\n } else {\n acc.itemsToUpdate.push({\n ...maybeOriginItem,\n quantity: item.quantity,\n })\n }\n\n return acc\n },\n {\n itemsToAdd: [] as IStoreOffer[],\n itemsToUpdate: [] as IStoreOffer[],\n }\n )\n\n const itemsToDelete = originItems\n .filter((item) => !browserItemsById.has(getId(item)))\n .map((item) => ({ ...item, quantity: 0 }))\n\n const changes = [...itemsToAdd, ...itemsToUpdate, ...itemsToDelete].map(\n offerToOrderItemInput\n )\n\n if (changes.length === 0) {\n return null\n }\n\n // Step4: Apply delta changes to order form\n const updatedOrderForm = await commerce.checkout.updateOrderFormItems({\n id: orderForm.orderFormId,\n orderItems: changes,\n })\n\n // Step5: If no changes detected before/after updating orderForm, the order is validated\n if (equals(order, updatedOrderForm)) {\n return null\n }\n\n // Step6: There were changes, convert orderForm to StoreOrder\n return {\n order: {\n orderNumber: updatedOrderForm.orderFormId,\n acceptedOffer: updatedOrderForm.items.map((item) => ({\n ...item,\n product: skuLoader.load([{ key: 'id', value: item.id }]), // TODO: add channel\n })),\n },\n messages: updatedOrderForm.messages.map(({ text, status }) => ({\n text,\n status: status.toUpperCase(),\n })),\n }\n}\n","import type { Context } from '..'\n\nexport interface Channel {\n regionId?: string\n salesChannel?: string\n}\n\nexport default class ChannelMarshal {\n public static parse(channelString: string): Required<Channel> {\n try {\n const parsedChannel = JSON.parse(channelString) as Channel\n\n return {\n regionId: parsedChannel.regionId ?? '',\n salesChannel: parsedChannel.salesChannel ?? '',\n }\n } catch (error) {\n console.error(error)\n\n throw new Error('Malformed channel string')\n }\n }\n\n public static stringify(channel: Channel): string {\n return JSON.stringify(channel)\n }\n}\n\nexport const mutateChannelContext = (ctx: Context, channelString: string) => {\n ctx.storage = {\n ...ctx.storage,\n channel: ChannelMarshal.parse(channelString),\n }\n}\n","import { slugify } from '../utils/slugify'\nimport type { Resolver } from '..'\nimport type { EnhancedSku } from '../utils/enhanceSku'\nimport { sortOfferByPrice } from './aggregateOffer'\n\ntype Root = EnhancedSku\n\nconst DEFAULT_IMAGE = {\n name: 'image',\n value:\n 'https://storecomponents.vtexassets.com/assets/faststore/images/image___117a6d3e229a96ad0e0d0876352566e2.svg',\n}\n\nconst getSlug = (link: string, id: string) => `${link}-${id}`\nconst getPath = (link: string, id: string) => `/${getSlug(link, id)}/p`\nconst nonEmptyArray = <T>(array: T[] | null | undefined) =>\n Array.isArray(array) && array.length > 0 ? array : null\n\nexport const StoreProduct: Record<string, Resolver<Root>> = {\n productID: ({ id }) => id,\n name: ({ isVariantOf, name }) => name ?? isVariantOf.name,\n slug: ({ isVariantOf: { link }, id }) => getSlug(link, id),\n description: ({ isVariantOf: { description } }) => description,\n seo: ({ isVariantOf: { name, description } }) => ({\n title: name,\n description,\n }),\n brand: ({ isVariantOf: { brand } }) => ({ name: brand }),\n breadcrumbList: ({ isVariantOf: { categoryTrees, name, link }, id }) => ({\n itemListElement: [\n ...categoryTrees.reverse().map(({ categoryNames }, index) => ({\n name: categoryNames[categoryNames.length - 1],\n item: `/${categoryNames\n .map((categoryName) => slugify(categoryName))\n .join('/')}`,\n position: index + 1,\n })),\n {\n name,\n item: getPath(link, id),\n position: categoryTrees.length + 1,\n },\n ],\n numberOfItems: categoryTrees.length,\n }),\n image: ({ isVariantOf, images }) =>\n (\n nonEmptyArray(images) ??\n nonEmptyArray(isVariantOf.images) ?? [DEFAULT_IMAGE]\n ).map(({ name, value }) => ({\n alternateName: name ?? '',\n url: value.replace('vteximg.com.br', 'vtexassets.com'),\n })),\n sku: ({ id }) => id,\n gtin: ({ reference }) => reference ?? '',\n review: () => [],\n aggregateRating: () => ({}),\n offers: async (product, _, ctx) => {\n const {\n loaders: { simulationLoader },\n storage: { channel },\n } = ctx\n\n const { id, policies } = product\n\n const sellers = policies.find(\n (policy) => policy.id === channel.salesChannel\n )?.sellers\n\n if (sellers === null || sellers === undefined) {\n // This error will likely happen when you forget to forward the channel somewhere in your code.\n // Make sure all queries that lead to a product are forwarding the channel in context corectly\n throw new Error(\n `Product with id ${id} has no sellers for sales channel ${channel.salesChannel}.`\n )\n }\n\n // Unique seller ids\n const sellerIds = sellers.map((seller) => seller.id)\n const items = Array.from(new Set(sellerIds)).map((seller) => ({\n quantity: 1,\n seller,\n id,\n }))\n\n const simulation = await simulationLoader.load(items)\n\n return {\n ...simulation,\n items: sortOfferByPrice(simulation.items),\n product,\n }\n },\n isVariantOf: ({ isVariantOf }) => isVariantOf,\n additionalProperty: ({ attributes = [] }) =>\n attributes.map((attribute) => ({\n name: attribute.key,\n value: attribute.value,\n })),\n}\n","import ChannelMarshal from './channel'\n\nexport interface SelectedFacet {\n key: string\n value: string\n}\n\n/**\n * Transform facets from the store to VTEX platform facets.\n * For instance, the channel in Store becomes trade-policy and regionId in VTEX's realm\n * */\nexport const transformSelectedFacet = ({ key, value }: SelectedFacet) => {\n switch (key) {\n case 'channel': {\n const channel = ChannelMarshal.parse(value)\n\n // This array should have all values from channel string\n return [{ key: 'trade-policy', value: channel.salesChannel }]\n }\n\n default:\n return { key, value }\n }\n}\n","export const SORT_MAP = {\n price_desc: 'price:desc',\n price_asc: 'price:asc',\n orders_desc: 'orders:desc',\n name_desc: 'name:desc',\n name_asc: 'name:asc',\n release_desc: 'release:desc',\n discount_desc: 'discount:desc',\n score_desc: '',\n} as const\n","import { enhanceSku } from '../utils/enhanceSku'\nimport { transformSelectedFacet } from '../utils/facets'\nimport { SORT_MAP } from '../utils/sort'\nimport { StoreCollection } from './collection'\nimport type {\n QueryProductArgs,\n QueryAllCollectionsArgs,\n QueryAllProductsArgs,\n QuerySearchArgs,\n QueryCollectionArgs,\n} from '../../../__generated__/schema'\nimport type { CategoryTree } from '../clients/commerce/types/CategoryTree'\nimport type { Context } from '../index'\nimport { mutateChannelContext } from '../utils/channel'\n\nexport const Query = {\n product: async (_: unknown, { locator }: QueryProductArgs, ctx: Context) => {\n // Insert channel in context for later usage\n const channelString = locator.find((facet) => facet.key === 'channel')\n ?.value\n\n if (channelString) {\n mutateChannelContext(ctx, channelString)\n }\n\n const {\n loaders: { skuLoader },\n } = ctx\n\n return skuLoader.load(locator.flatMap(transformSelectedFacet))\n },\n collection: (_: unknown, { slug }: QueryCollectionArgs, ctx: Context) => {\n const {\n loaders: { collectionLoader },\n } = ctx\n\n return collectionLoader.load(slug)\n },\n search: async (\n _: unknown,\n { first, after: maybeAfter, sort, term, selectedFacets }: QuerySearchArgs,\n ctx: Context\n ) => {\n // Insert channel in context for later usage\n const channelString = selectedFacets?.find(\n (facet) => facet.key === 'channel'\n )?.value\n\n if (channelString) {\n mutateChannelContext(ctx, channelString)\n }\n\n const after = maybeAfter ? Number(maybeAfter) : 0\n const searchArgs = {\n page: Math.ceil(after / first),\n count: first,\n query: term,\n sort: SORT_MAP[sort ?? 'score_desc'],\n selectedFacets: selectedFacets?.flatMap(transformSelectedFacet) ?? [],\n }\n\n return searchArgs\n },\n allProducts: async (\n _: unknown,\n { first, after: maybeAfter }: QueryAllProductsArgs,\n ctx: Context\n ) => {\n const {\n clients: { search },\n } = ctx\n\n const after = maybeAfter ? Number(maybeAfter) : 0\n const products = await search.products({\n page: Math.ceil(after / first),\n count: first,\n })\n\n const skus = products.products\n .map((product) => product.skus.map((sku) => enhanceSku(sku, product)))\n .flat()\n .filter((sku) => sku.sellers.length > 0)\n\n return {\n pageInfo: {\n hasNextPage: products.pagination.after.length > 0,\n hasPreviousPage: products.pagination.before.length > 0,\n startCursor: '0',\n endCursor: products.total.toString(),\n totalCount: products.total,\n },\n // after + index is bigger than after+first itself because of the array flat() above\n edges: skus.map((sku, index) => ({\n node: sku,\n cursor: (after + index).toString(),\n })),\n }\n },\n allCollections: async (\n _: unknown,\n { first, after: maybeAfter }: QueryAllCollectionsArgs,\n ctx: Context\n ) => {\n const {\n clients: { commerce },\n } = ctx\n\n const after = maybeAfter ? Number(maybeAfter) : 0\n\n const [brands, tree] = await Promise.all([\n commerce.catalog.brand.list(),\n commerce.catalog.category.tree(),\n ])\n\n const categories: Array<CategoryTree & { level: number }> = []\n const dfs = (node: CategoryTree, level: number) => {\n categories.push({ ...node, level })\n\n for (const child of node.children) {\n dfs(child, level + 1)\n }\n }\n\n for (const node of tree) {\n dfs(node, 0)\n }\n\n const collections = [\n ...brands\n .filter((brand) => brand.isActive)\n .map((x) => ({ ...x, type: 'brand' })),\n ...categories,\n ]\n\n const validCollections = collections\n // Nullable slugs may cause one route to override the other\n .filter((node) => Boolean(StoreCollection.slug(node, null, ctx, null)))\n\n return {\n pageInfo: {\n hasNextPage: validCollections.length - after > first,\n hasPreviousPage: after > 0,\n startCursor: '0',\n endCursor: (\n Math.min(first, validCollections.length - after) - 1\n ).toString(),\n totalCount: validCollections.length,\n },\n edges: validCollections\n .slice(after, after + first)\n .map((node, index) => ({\n node,\n cursor: (after + index).toString(),\n })),\n }\n },\n person: async (_: unknown, __: unknown, ctx: Context) => {\n const {\n clients: { commerce },\n } = ctx\n\n const {\n namespaces: { profile = null },\n } = await commerce.session()\n\n return (\n profile && {\n id: profile.id?.value ?? '',\n email: profile.email?.value ?? '',\n givenName: profile.firstName?.value ?? '',\n familyName: profile.lastName?.value ?? '',\n }\n )\n },\n}\n","import { enhanceSku } from '../utils/enhanceSku'\nimport type { Resolver } from '..'\nimport type { SearchArgs } from '../clients/search'\nimport type { Attribute } from '../clients/search/types/AttributeSearchResult'\n\ntype Root = Omit<SearchArgs, 'type'>\n\nconst REMOVED_FACETS_FROM_COLLECTION_PAGE = ['departamento']\n\nexport const StoreSearchResult: Record<string, Resolver<Root>> = {\n products: async (searchArgs, _, ctx) => {\n const {\n clients: { search },\n } = ctx\n\n const products = await search.products(searchArgs)\n\n const skus = products.products\n .map((product) => {\n const [maybeSku] = product.skus\n\n return maybeSku && enhanceSku(maybeSku, product)\n })\n .filter((sku) => !!sku)\n\n return {\n pageInfo: {\n hasNextPage: products.pagination.after.length > 0,\n hasPreviousPage: products.pagination.before.length > 0,\n startCursor: '0',\n endCursor: products.total.toString(),\n totalCount: products.total,\n },\n edges: skus.map((sku, index) => ({\n node: sku,\n cursor: index.toString(),\n })),\n }\n },\n facets: async (searchArgs, _, ctx) => {\n const {\n clients: { search: is },\n } = ctx\n\n const facets = await is.facets(searchArgs)\n\n const isCollectionPage = !searchArgs.query\n const filteredFacets = facets?.attributes?.reduce((acc, currentFacet) => {\n const shouldFilterFacet = REMOVED_FACETS_FROM_COLLECTION_PAGE.includes(\n currentFacet.key\n )\n\n const shouldRemoveFacetFromCollectionPage =\n isCollectionPage && shouldFilterFacet\n\n if (shouldRemoveFacetFromCollectionPage) {\n return acc\n }\n\n currentFacet.values.sort((a, b) => {\n const firstItemLabel = a.label ?? ''\n const secondItemLabel = b.label ?? ''\n\n return firstItemLabel.localeCompare(secondItemLabel)\n })\n\n acc.push(currentFacet)\n\n return acc\n }, [] as Attribute[])\n\n return filteredFacets ?? []\n },\n}\n","import { getClients } from './clients'\nimport { getLoaders } from './loaders'\nimport { StoreAggregateOffer } from './resolvers/aggregateOffer'\nimport { StoreAggregateRating } from './resolvers/aggregateRating'\nimport { StoreCollection } from './resolvers/collection'\nimport { StoreFacet } from './resolvers/facet'\nimport { StoreFacetValue } from './resolvers/facetValue'\nimport { Mutation } from './resolvers/mutation'\nimport { StoreOffer } from './resolvers/offer'\nimport { StoreProduct } from './resolvers/product'\nimport { StoreProductGroup } from './resolvers/productGroup'\nimport { Query } from './resolvers/query'\nimport { StoreReview } from './resolvers/review'\nimport { StoreSearchResult } from './resolvers/searchResult'\nimport { StoreSeo } from './resolvers/seo'\nimport type { Loaders } from './loaders'\nimport type { Clients } from './clients'\nimport type { Channel } from './utils/channel'\nimport ChannelMarshal from './utils/channel'\n\nexport interface Options {\n platform: 'vtex'\n account: string\n environment: 'vtexcommercestable' | 'vtexcommercebeta'\n // Default sales channel to use for fetching products\n channel: string\n hideUnavailableItems: boolean\n}\n\nexport interface Context {\n clients: Clients\n loaders: Loaders\n /**\n * @description Storage updated at each request.\n *\n * Use this datastructure to store and share small values in the context.\n * Use it with caution since dependecy injection leads to a more complex code\n * */\n storage: {\n channel: Required<Channel>\n }\n headers: Record<string, string>\n}\n\nexport type Resolver<R = unknown, A = unknown> = (\n root: R,\n args: A,\n ctx: Context,\n info: any\n) => any\n\nconst Resolvers = {\n StoreCollection,\n StoreAggregateOffer,\n StoreProduct,\n StoreSeo,\n StoreFacet,\n StoreFacetValue,\n StoreOffer,\n StoreAggregateRating,\n StoreReview,\n StoreProductGroup,\n StoreSearchResult,\n Query,\n Mutation,\n}\n\nexport const getContextFactory = (options: Options) => (ctx: any): Context => {\n ctx.storage = {\n channel: ChannelMarshal.parse(options.channel),\n }\n ctx.clients = getClients(options, ctx)\n ctx.loaders = getLoaders(options, ctx)\n\n return ctx\n}\n\nexport const getResolvers = (_: Options) => Resolvers\n","import type { Resolver } from '..'\n\ntype Root = { title?: string; description?: string }\n\nexport const StoreSeo: Record<string, Resolver<Root>> = {\n title: ({ title }) => title ?? '',\n description: ({ description }) => description ?? '',\n titleTemplate: () => '',\n canonical: () => '',\n}\n","import type { Resolver } from '..'\nimport type { Attribute } from '../clients/search/types/AttributeSearchResult'\n\ntype Root = Attribute\n\nexport const StoreFacet: Record<string, Resolver<Root>> = {\n key: ({ key }) => key,\n label: ({ label }) => label,\n values: ({ values }) => values,\n type: ({ type }) => (type === 'text' ? 'BOOLEAN' : 'RANGE'),\n}\n","import type { Resolver } from '..'\nimport type { Value } from '../clients/search/types/AttributeSearchResult'\n\ntype Root = Value\n\nexport const StoreFacetValue: Record<string, Resolver<Root>> = {\n value: ({ key, from, to }) => key ?? `${from}-to-${to}`,\n label: ({ label }) => label ?? 'unknown',\n selected: ({ active }) => active,\n quantity: ({ count }) => count,\n}\n","import type { EnhancedSku } from '../utils/enhanceSku'\nimport type { Resolver } from '..'\nimport type { Item } from '../clients/commerce/types/Simulation'\nimport type { OrderFormItem } from '../clients/commerce/types/OrderForm'\n\ntype Root =\n | (Item & { product: EnhancedSku }) // when querying search/product\n | (OrderFormItem & { product: Promise<EnhancedSku> }) // when querying order\n\nexport const StoreOffer: Record<string, Resolver<Root>> = {\n priceCurrency: () => '',\n priceValidUntil: ({ priceValidUntil }) => priceValidUntil ?? '',\n itemCondition: () => 'https://schema.org/NewCondition',\n availability: ({ availability }) =>\n availability === 'available'\n ? 'https://schema.org/InStock'\n : 'https://schema.org/OutOfStock',\n seller: ({ seller }) => ({\n identifier: seller,\n }),\n price: ({ sellingPrice }) => sellingPrice / 1e2, // TODO add spot price calculation\n sellingPrice: ({ sellingPrice }) => sellingPrice / 1e2,\n listPrice: ({ listPrice }) => listPrice / 1e2,\n itemOffered: ({ product }) => product,\n quantity: ({ quantity }) => quantity,\n}\n","import type { Resolver } from '..'\n\n// TODO: Add a review system integration\nexport const StoreAggregateRating: Record<string, Resolver> = {\n ratingValue: () => 5,\n reviewCount: () => 0,\n}\n","import type { Resolver } from '..'\n\nexport const StoreReview: Record<string, Resolver> = {\n reviewRating: () => ({\n ratingValue: 5,\n bestRating: 5,\n }),\n author: () => ({\n name: '',\n }),\n}\n","import { enhanceSku } from '../utils/enhanceSku'\nimport type { Product } from '../clients/search/types/ProductSearchResult'\nimport type { Resolver } from '..'\n\nexport const StoreProductGroup: Record<string, Resolver<Product>> = {\n hasVariant: (root) => root.skus.map((sku) => enhanceSku(sku, root)),\n productGroupID: ({ product }) => product,\n name: ({ name }) => name,\n additionalProperty: ({ textAttributes = [], productSpecifications = [] }) => {\n const specs = new Set(productSpecifications)\n\n return textAttributes\n .filter((attribute) => specs.has(attribute.labelKey))\n .map((attribute) => ({\n name: attribute.labelKey,\n value: attribute.labelValue,\n }))\n },\n}\n","import { validateCart } from './validateCart'\nimport { updateSession } from './updateSession'\n\nexport const Mutation = {\n validateCart,\n updateSession,\n}\n","import type { Context } from '..'\nimport type {\n MutationUpdateSessionArgs,\n StoreSession,\n} from '../../../__generated__/schema'\nimport ChannelMarshal from '../utils/channel'\n\nexport const updateSession = async (\n _: any,\n { session }: MutationUpdateSessionArgs,\n { clients }: Context\n): Promise<StoreSession> => {\n const channel = ChannelMarshal.parse(session.channel ?? '')\n const regionData = await clients.commerce.checkout.region({\n postalCode: String(session.postalCode ?? '').replace(/\\D/g, ''),\n country: session.country ?? '',\n })\n\n return {\n ...session,\n channel: ChannelMarshal.stringify({\n ...channel,\n regionId: regionData?.[0]?.id,\n }),\n }\n}\n","import { print } from 'graphql'\n\nimport AggregateOffer from './aggregateOffer.graphql'\nimport AggregateRating from './aggregateRating.graphql'\nimport Author from './author.graphql'\nimport Brand from './brand.graphql'\nimport Breadcrumb from './breadcrumb.graphql'\nimport Collection from './collection.graphql'\nimport Facet from './facet.graphql'\nimport Image from './image.graphql'\nimport Mutation from './mutation.graphql'\nimport Offer from './offer.graphql'\nimport Order from './order.graphql'\nimport Organization from './organization.graphql'\nimport PageInfo from './pageInfo.graphql'\nimport Product from './product.graphql'\nimport ProductGroup from './productGroup.graphql'\nimport Query from './query.graphql'\nimport Review from './review.graphql'\nimport Seo from './seo.graphql'\nimport Cart from './cart.graphql'\nimport Status from './status.graphql'\nimport PropertyValue from './propertyValue.graphql'\nimport Person from './person.graphql'\n\nexport const typeDefs = [\n Query,\n Mutation,\n Brand,\n Breadcrumb,\n Collection,\n Facet,\n Image,\n PageInfo,\n Product,\n Seo,\n Offer,\n AggregateRating,\n Review,\n Author,\n ProductGroup,\n Organization,\n AggregateOffer,\n Order,\n Cart,\n Status,\n PropertyValue,\n Person,\n]\n .map(print)\n .join('\\n')\n","import { makeExecutableSchema } from '@graphql-tools/schema'\n\nimport {\n getContextFactory as getContextFactoryVTEX,\n getResolvers as getResolversVTEX,\n} from './platforms/vtex'\nimport { typeDefs } from './typeDefs'\nimport type { Options as OptionsVTEX } from './platforms/vtex'\n\nexport * from './__generated__/schema'\n\nexport type Options = OptionsVTEX\n\nconst platforms = {\n vtex: {\n getResolvers: getResolversVTEX,\n getContextFactory: getContextFactoryVTEX,\n },\n}\n\nexport const getTypeDefs = () => typeDefs\n\nexport const getResolvers = (options: Options) =>\n platforms[options.platform].getResolvers(options)\n\nexport const getContextFactory = (options: Options) =>\n platforms[options.platform].getContextFactory(options)\n\nexport const getSchema = async (options: Options) =>\n makeExecutableSchema({\n resolvers: getResolvers(options),\n typeDefs,\n })\n","import { VtexCommerce } from './commerce'\nimport { IntelligentSearch } from './search'\nimport type { Context, Options } from '..'\n\nexport type Clients = ReturnType<typeof getClients>\n\nexport const getClients = (options: Options, ctx: Context) => {\n const search = IntelligentSearch(options, ctx)\n const commerce = VtexCommerce(options, ctx)\n\n return {\n search,\n commerce,\n }\n}\n","import { getSimulationLoader } from './simulation'\nimport { getSkuLoader } from './sku'\nimport { getCollectionLoader } from './collection'\nimport type { Context, Options } from '..'\n\nexport type Loaders = ReturnType<typeof getLoaders>\n\nexport const getLoaders = (options: Options, { clients }: Context) => {\n const skuLoader = getSkuLoader(options, clients)\n const simulationLoader = getSimulationLoader(options, clients)\n const collectionLoader = getCollectionLoader(options, clients)\n\n return {\n skuLoader,\n simulationLoader,\n collectionLoader,\n }\n}\n","import DataLoader from 'dataloader'\n\nimport { BadRequestError } from '../utils/errors'\nimport { enhanceSku } from '../utils/enhanceSku'\nimport type { EnhancedSku } from '../utils/enhanceSku'\nimport type { Options } from '..'\nimport type { Clients } from '../clients'\nimport type { SelectedFacet } from '../utils/facets'\n\nexport const getSkuLoader = (_: Options, clients: Clients) => {\n const loader = async (facetsList: readonly SelectedFacet[][]) => {\n const skuIds = facetsList.map((facets) => {\n const maybeFacet = facets.find(({ key }) => key === 'id')\n\n if (!maybeFacet) {\n throw new BadRequestError(\n 'Error while loading SKU. Needs to pass an id to selected facets'\n )\n }\n\n return maybeFacet.value\n })\n\n const { products } = await clients.search.products({\n query: `sku:${skuIds.join(';')}`,\n page: 0,\n count: skuIds.length,\n })\n\n const skuBySkuId = products.reduce((acc, product) => {\n for (const sku of product.skus) {\n acc[sku.id] = enhanceSku(sku, product)\n }\n\n return acc\n }, {} as Record<string, EnhancedSku>)\n\n const skus = skuIds.map((skuId) => skuBySkuId[skuId])\n const missingSkus = skus.filter((sku) => !sku)\n\n if (missingSkus.length > 0) {\n throw new Error(\n `Search API did not return the following skus: ${missingSkus.join(',')}`\n )\n }\n\n return skus\n }\n\n return new DataLoader<SelectedFacet[], EnhancedSku>(loader, {\n maxBatchSize: 99, // Max allowed batch size of Search API\n })\n}\n","import DataLoader from 'dataloader'\nimport pLimit from 'p-limit'\n\nimport type {\n PayloadItem,\n Simulation,\n} from '../clients/commerce/types/Simulation'\nimport type { Options } from '..'\nimport type { Clients } from '../clients'\n\n// Limits concurrent requests to the API per request cycle\nconst CONCURRENT_REQUESTS_MAX = 1\n\nexport const getSimulationLoader = (_: Options, clients: Clients) => {\n const limit = pLimit(CONCURRENT_REQUESTS_MAX)\n\n const loader = async (allItems: readonly PayloadItem[][]) => {\n const items = [...allItems.flat()]\n const simulation = await clients.commerce.checkout.simulation({\n items,\n })\n\n // Sort and filter simulation since Checkout API may return\n // items that we didn't ask for\n const simulated = simulation.items.reduce((acc, item) => {\n const index = item.requestIndex\n\n if (typeof index === 'number' && index < acc.length) {\n acc[index] = item\n }\n\n return acc\n }, Array(items.length).fill(null) as Simulation['items'])\n\n const itemsIndices = allItems.reduce(\n (acc, curr) => [...acc, curr.length + acc[acc.length - 1]],\n [0]\n )\n\n return allItems.map((__, index) => ({\n ...simulation,\n items: simulated\n .slice(itemsIndices[index], itemsIndices[index + 1])\n .filter((item) => Boolean(item)),\n }))\n }\n\n const limited = async (allItems: readonly PayloadItem[][]) =>\n limit(loader, allItems)\n\n return new DataLoader<PayloadItem[], Simulation>(limited, {\n maxBatchSize: 50,\n })\n}\n"],"names":["fetchAPI","async","info","init","response","fetch","ok","json","console","error","text","Error","BASE_INIT","method","headers","IntelligentSearch","account","environment","hideUnavailableItems","ctx","base","policyFacet","key","value","storage","channel","salesChannel","search","query","page","count","sort","selectedFacets","type","fuzzy","params","URLSearchParams","toString","undefined","append","pathname","facets","find","map","join","args","products","BadRequestError","constructor","message","name","NotFoundError","enhanceSku","sku","product","isVariantOf","collectionPageTypes","Set","isCollectionPageType","x","pageType","has","toLowerCase","inStock","item","availability","sortOfferByPrice","items","a","b","sellingPrice","StoreAggregateOffer","highPrice","filter","pop","_availableItems$pop","lowPrice","_availableItems$","offerCount","length","priceCurrency","offers","slugify","path","rawSlugify","separator","lowercase","isBrand","root","baseSlugify","URL","url","slice","StoreCollection","id","slug","seo","title","description","metaTagDescription","Title","MetaTagDescription","level","meta","split","segment","index","breadcrumbList","_","loaders","collectionLoader","segments","Boolean","slugs","__","collections","Promise","all","s","load","itemListElement","collection","position","numberOfItems","getId","itemOffered","seller","identifier","price","orderFormItemToOffer","listPrice","quantity","image","offerToOrderItemInput","offer","groupById","reduce","acc","set","get","Map","ChannelMarshal","channelString","parsedChannel","JSON","parse","regionId","stringify","mutateChannelContext","DEFAULT_IMAGE","getSlug","link","getPath","nonEmptyArray","array","Array","isArray","transformSelectedFacet","SORT_MAP","price_desc","price_asc","orders_desc","name_desc","name_asc","release_desc","discount_desc","score_desc","Query","locator","facet","_locator$find","skuLoader","flatMap","first","after","maybeAfter","term","_selectedFacets$find","Number","Math","ceil","allProducts","clients","skus","flat","sellers","pageInfo","hasNextPage","pagination","hasPreviousPage","before","startCursor","endCursor","total","totalCount","edges","node","cursor","allCollections","commerce","brands","tree","catalog","brand","list","category","categories","dfs","push","child","children","validCollections","isActive","min","person","namespaces","profile","session","_profile$id","email","_profile$email","givenName","firstName","_profile$firstName","familyName","lastName","_profile$lastName","REMOVED_FACETS_FROM_COLLECTION_PAGE","Resolvers","StoreProduct","productID","categoryTrees","reverse","categoryNames","categoryName","images","alternateName","replace","gtin","reference","review","aggregateRating","simulationLoader","policies","policy","_policies$find","sellerIds","from","simulation","additionalProperty","attributes","attribute","StoreSeo","titleTemplate","canonical","StoreFacet","label","values","StoreFacetValue","to","selected","active","StoreOffer","priceValidUntil","itemCondition","StoreAggregateRating","ratingValue","reviewCount","StoreReview","reviewRating","bestRating","author","StoreProductGroup","hasVariant","productGroupID","textAttributes","productSpecifications","specs","labelKey","labelValue","StoreSearchResult","searchArgs","maybeSku","is","isCollectionPage","filteredFacets","_facets$attributes","currentFacet","shouldFilterFacet","includes","firstItemLabel","secondItemLabel","localeCompare","Mutation","validateCart","cart","order","orderNumber","acceptedOffer","orderForm","checkout","browserItemsById","originItemsById","browserItems","originItems","itemsToAdd","itemsToUpdate","maybeOriginItem","changes","updatedOrderForm","updateOrderFormItems","orderFormId","orderItems","storeOrder","pick","orderFormItems","storeOrderItems","isSameOrder","orderItemsAreSync","deepEquals","equals","messages","status","toUpperCase","updateSession","regionData","region","postalCode","String","country","_regionData$","typeDefs","Brand","Breadcrumb","Collection","Facet","Image","PageInfo","Product","Seo","Offer","AggregateRating","Review","Author","ProductGroup","Organization","AggregateOffer","Order","Cart","Status","PropertyValue","Person","print","platforms","vtex","getResolvers","getContextFactory","options","depth","portal","pagetype","sc","body","refreshOutdatedData","allowOutdatedData","cookie","VtexCommerce","getClients","DataLoader","skuIds","facetsList","maybeFacet","skuBySkuId","skuId","missingSkus","maxBatchSize","getSkuLoader","limit","pLimit","loader","allItems","simulated","requestIndex","fill","itemsIndices","curr","getSimulationLoader","batch","getCollectionLoader","getLoaders","platform","makeExecutableSchema","resolvers"],"mappings":"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"}
package/dist/api.esm.js CHANGED
@@ -44,9 +44,7 @@ const VtexCommerce = ({
44
44
  checkout: {
45
45
  simulation: (args, {
46
46
  salesChannel
47
- } = {
48
- salesChannel: ctx.storage.channel
49
- }) => {
47
+ } = ctx.storage.channel) => {
50
48
  const params = new URLSearchParams({
51
49
  sc: salesChannel
52
50
  });
@@ -57,8 +55,11 @@ const VtexCommerce = ({
57
55
  orderForm: ({
58
56
  id,
59
57
  refreshOutdatedData = true,
60
- salesChannel = ctx.storage.channel
58
+ channel = ctx.storage.channel
61
59
  }) => {
60
+ const {
61
+ salesChannel
62
+ } = channel;
62
63
  const params = new URLSearchParams({
63
64
  refreshOutdatedData: refreshOutdatedData.toString(),
64
65
  sc: salesChannel
@@ -69,7 +70,7 @@ const VtexCommerce = ({
69
70
  id,
70
71
  orderItems,
71
72
  allowOutdatedData = 'paymentData',
72
- salesChannel = ctx.storage.channel
73
+ salesChannel = ctx.storage.channel.salesChannel
73
74
  }) => {
74
75
  const params = new URLSearchParams({
75
76
  allowOutdatedData,
@@ -109,7 +110,7 @@ const IntelligentSearch = ({
109
110
  const base = `http://portal.${environment}.com.br/search-api/v1/${account}`;
110
111
  const policyFacet = {
111
112
  key: 'trade-policy',
112
- value: ctx.storage.channel
113
+ value: ctx.storage.channel.salesChannel
113
114
  };
114
115
 
115
116
  const addDefaultFacets = facets => {
@@ -630,6 +631,11 @@ class ChannelMarshal {
630
631
  }
631
632
 
632
633
  }
634
+ const mutateChannelContext = (ctx, channelString) => {
635
+ ctx.storage = { ...ctx.storage,
636
+ channel: ChannelMarshal.parse(channelString)
637
+ };
638
+ };
633
639
 
634
640
  const updateSession = async (_, {
635
641
  session
@@ -790,12 +796,12 @@ const StoreProduct = {
790
796
  id,
791
797
  policies
792
798
  } = product;
793
- const sellers = (_policies$find = policies.find(policy => policy.id === channel)) == null ? void 0 : _policies$find.sellers;
799
+ const sellers = (_policies$find = policies.find(policy => policy.id === channel.salesChannel)) == null ? void 0 : _policies$find.sellers;
794
800
 
795
- if (sellers == null) {
801
+ if (sellers === null || sellers === undefined) {
796
802
  // This error will likely happen when you forget to forward the channel somewhere in your code.
797
803
  // Make sure all queries that lead to a product are forwarding the channel in context corectly
798
- throw new Error(`Product with id ${id} has no sellers for channel ${channel}.`);
804
+ throw new Error(`Product with id ${id} has no sellers for sales channel ${channel.salesChannel}.`);
799
805
  } // Unique seller ids
800
806
 
801
807
 
@@ -844,18 +850,23 @@ const StoreProductGroup = {
844
850
 
845
851
  /**
846
852
  * Transform facets from the store to VTEX platform facets.
847
- * For instance, the channel in Store becomes trade-policy in VTEX's realm
853
+ * For instance, the channel in Store becomes trade-policy and regionId in VTEX's realm
848
854
  * */
855
+
849
856
  const transformSelectedFacet = ({
850
857
  key,
851
858
  value
852
859
  }) => {
853
860
  switch (key) {
854
861
  case 'channel':
855
- return {
856
- key: 'trade-policy',
857
- value
858
- };
862
+ {
863
+ const channel = ChannelMarshal.parse(value); // This array should have all values from channel string
864
+
865
+ return [{
866
+ key: 'trade-policy',
867
+ value: channel.salesChannel
868
+ }];
869
+ }
859
870
 
860
871
  default:
861
872
  return {
@@ -880,18 +891,21 @@ const Query = {
880
891
  product: async (_, {
881
892
  locator
882
893
  }, ctx) => {
883
- var _locator$find$value, _locator$find;
894
+ var _locator$find;
884
895
 
885
896
  // Insert channel in context for later usage
886
- ctx.storage = { ...ctx.storage,
887
- channel: (_locator$find$value = (_locator$find = locator.find(facet => facet.key === 'channel')) == null ? void 0 : _locator$find.value) != null ? _locator$find$value : ctx.storage.channel
888
- };
897
+ const channelString = (_locator$find = locator.find(facet => facet.key === 'channel')) == null ? void 0 : _locator$find.value;
898
+
899
+ if (channelString) {
900
+ mutateChannelContext(ctx, channelString);
901
+ }
902
+
889
903
  const {
890
904
  loaders: {
891
905
  skuLoader
892
906
  }
893
907
  } = ctx;
894
- return skuLoader.load(locator.map(transformSelectedFacet));
908
+ return skuLoader.load(locator.flatMap(transformSelectedFacet));
895
909
  },
896
910
  collection: (_, {
897
911
  slug
@@ -910,19 +924,22 @@ const Query = {
910
924
  term,
911
925
  selectedFacets
912
926
  }, ctx) => {
913
- var _selectedFacets$find$, _selectedFacets$find, _selectedFacets$map;
927
+ var _selectedFacets$find, _selectedFacets$flatM;
914
928
 
915
929
  // Insert channel in context for later usage
916
- ctx.storage = { ...ctx.storage,
917
- channel: (_selectedFacets$find$ = selectedFacets == null ? void 0 : (_selectedFacets$find = selectedFacets.find(facet => facet.key === 'channel')) == null ? void 0 : _selectedFacets$find.value) != null ? _selectedFacets$find$ : ctx.storage.channel
918
- };
930
+ const channelString = selectedFacets == null ? void 0 : (_selectedFacets$find = selectedFacets.find(facet => facet.key === 'channel')) == null ? void 0 : _selectedFacets$find.value;
931
+
932
+ if (channelString) {
933
+ mutateChannelContext(ctx, channelString);
934
+ }
935
+
919
936
  const after = maybeAfter ? Number(maybeAfter) : 0;
920
937
  const searchArgs = {
921
938
  page: Math.ceil(after / first),
922
939
  count: first,
923
940
  query: term,
924
941
  sort: SORT_MAP[sort != null ? sort : 'score_desc'],
925
- selectedFacets: (_selectedFacets$map = selectedFacets == null ? void 0 : selectedFacets.map(transformSelectedFacet)) != null ? _selectedFacets$map : []
942
+ selectedFacets: (_selectedFacets$flatM = selectedFacets == null ? void 0 : selectedFacets.flatMap(transformSelectedFacet)) != null ? _selectedFacets$flatM : []
926
943
  };
927
944
  return searchArgs;
928
945
  },
@@ -1121,7 +1138,7 @@ const Resolvers = {
1121
1138
  };
1122
1139
  const getContextFactory = options => ctx => {
1123
1140
  ctx.storage = {
1124
- channel: options.channel
1141
+ channel: ChannelMarshal.parse(options.channel)
1125
1142
  };
1126
1143
  ctx.clients = getClients(options, ctx);
1127
1144
  ctx.loaders = getLoaders(options, ctx);