@decocms/apps 0.23.3 → 0.24.0

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.
Files changed (110) hide show
  1. package/LICENSE +21 -0
  2. package/commerce/components/Image.tsx +129 -143
  3. package/commerce/components/JsonLd.tsx +192 -201
  4. package/commerce/components/Picture.tsx +65 -75
  5. package/commerce/sdk/analytics.ts +15 -15
  6. package/commerce/sdk/formatPrice.ts +13 -16
  7. package/commerce/sdk/url.ts +7 -7
  8. package/commerce/sdk/useOffer.ts +46 -57
  9. package/commerce/sdk/useVariantPossibilities.ts +25 -25
  10. package/commerce/types/commerce.ts +868 -875
  11. package/commerce/utils/canonical.ts +5 -8
  12. package/commerce/utils/constants.ts +5 -6
  13. package/commerce/utils/filters.ts +4 -4
  14. package/commerce/utils/productToAnalyticsItem.ts +52 -56
  15. package/commerce/utils/stateByZip.ts +42 -42
  16. package/package.json +23 -4
  17. package/shopify/actions/cart/addItems.ts +24 -25
  18. package/shopify/actions/cart/updateCoupons.ts +19 -20
  19. package/shopify/actions/cart/updateItems.ts +19 -20
  20. package/shopify/actions/user/signIn.ts +25 -30
  21. package/shopify/actions/user/signUp.ts +19 -24
  22. package/shopify/client.ts +24 -24
  23. package/shopify/index.ts +20 -18
  24. package/shopify/init.ts +18 -21
  25. package/shopify/loaders/ProductDetailsPage.ts +16 -20
  26. package/shopify/loaders/ProductList.ts +66 -69
  27. package/shopify/loaders/ProductListingPage.ts +150 -158
  28. package/shopify/loaders/RelatedProducts.ts +24 -27
  29. package/shopify/loaders/cart.ts +53 -52
  30. package/shopify/loaders/shop.ts +22 -27
  31. package/shopify/loaders/user.ts +27 -32
  32. package/shopify/utils/admin/admin.ts +33 -34
  33. package/shopify/utils/admin/queries.ts +2 -2
  34. package/shopify/utils/cart.ts +18 -14
  35. package/shopify/utils/cookies.ts +62 -65
  36. package/shopify/utils/enums.ts +424 -424
  37. package/shopify/utils/graphql.ts +44 -55
  38. package/shopify/utils/storefront/queries.ts +24 -29
  39. package/shopify/utils/storefront/storefront.graphql.gen.ts +55 -55
  40. package/shopify/utils/transform.ts +370 -376
  41. package/shopify/utils/types.ts +118 -118
  42. package/shopify/utils/user.ts +11 -11
  43. package/shopify/utils/utils.ts +135 -140
  44. package/vtex/actions/address.ts +86 -86
  45. package/vtex/actions/auth.ts +14 -27
  46. package/vtex/actions/checkout.ts +36 -49
  47. package/vtex/actions/masterData.ts +10 -27
  48. package/vtex/actions/misc.ts +101 -111
  49. package/vtex/actions/newsletter.ts +48 -52
  50. package/vtex/actions/orders.ts +13 -16
  51. package/vtex/actions/profile.ts +55 -55
  52. package/vtex/actions/session.ts +36 -35
  53. package/vtex/actions/trigger.ts +25 -25
  54. package/vtex/actions/wishlist.ts +51 -53
  55. package/vtex/client.ts +14 -42
  56. package/vtex/hooks/index.ts +4 -4
  57. package/vtex/hooks/useAutocomplete.ts +42 -48
  58. package/vtex/hooks/useCart.ts +153 -165
  59. package/vtex/hooks/useUser.ts +40 -40
  60. package/vtex/hooks/useWishlist.ts +70 -70
  61. package/vtex/inline-loaders/productDetailsPage.ts +1 -3
  62. package/vtex/inline-loaders/productList.ts +121 -127
  63. package/vtex/inline-loaders/productListingPage.ts +10 -34
  64. package/vtex/inline-loaders/relatedProducts.ts +1 -3
  65. package/vtex/inline-loaders/suggestions.ts +36 -39
  66. package/vtex/inline-loaders/workflowProducts.ts +45 -49
  67. package/vtex/invoke.ts +159 -194
  68. package/vtex/loaders/address.ts +49 -54
  69. package/vtex/loaders/brands.ts +19 -26
  70. package/vtex/loaders/cart.ts +24 -21
  71. package/vtex/loaders/catalog.ts +51 -53
  72. package/vtex/loaders/collections.ts +25 -27
  73. package/vtex/loaders/legacy.ts +487 -534
  74. package/vtex/loaders/logistics.ts +33 -37
  75. package/vtex/loaders/navbar.ts +5 -8
  76. package/vtex/loaders/orders.ts +28 -39
  77. package/vtex/loaders/pageType.ts +41 -35
  78. package/vtex/loaders/payment.ts +27 -37
  79. package/vtex/loaders/profile.ts +38 -38
  80. package/vtex/loaders/promotion.ts +5 -8
  81. package/vtex/loaders/search.ts +56 -59
  82. package/vtex/loaders/session.ts +22 -30
  83. package/vtex/loaders/user.ts +39 -41
  84. package/vtex/loaders/wishlist.ts +35 -35
  85. package/vtex/loaders/wishlistProducts.ts +3 -15
  86. package/vtex/loaders/workflow.ts +220 -227
  87. package/vtex/middleware.ts +116 -119
  88. package/vtex/types.ts +201 -201
  89. package/vtex/utils/batch.ts +13 -16
  90. package/vtex/utils/cookies.ts +76 -80
  91. package/vtex/utils/enrichment.ts +62 -42
  92. package/vtex/utils/fetchCache.ts +1 -4
  93. package/vtex/utils/index.ts +6 -6
  94. package/vtex/utils/intelligentSearch.ts +48 -57
  95. package/vtex/utils/legacy.ts +108 -124
  96. package/vtex/utils/pickAndOmit.ts +15 -20
  97. package/vtex/utils/proxy.ts +136 -146
  98. package/vtex/utils/resourceRange.ts +3 -3
  99. package/vtex/utils/segment.ts +100 -111
  100. package/vtex/utils/similars.ts +1 -2
  101. package/vtex/utils/sitemap.ts +91 -91
  102. package/vtex/utils/slugCache.ts +2 -6
  103. package/vtex/utils/slugify.ts +9 -9
  104. package/vtex/utils/transform.ts +1012 -1105
  105. package/vtex/utils/types.ts +1381 -1381
  106. package/vtex/utils/vtexId.ts +44 -47
  107. package/.github/workflows/release.yml +0 -34
  108. package/.releaserc.json +0 -28
  109. package/knip.json +0 -19
  110. package/tsconfig.json +0 -11
@@ -12,93 +12,96 @@
12
12
  * @see https://developers.vtex.com/docs/api-reference/catalog-api
13
13
  */
14
14
  import type {
15
- Offer,
16
- Product,
17
- PropertyValue,
18
- UnitPriceSpecification,
15
+ Offer,
16
+ Product,
17
+ PropertyValue,
18
+ UnitPriceSpecification,
19
19
  } from "../../commerce/types/commerce";
20
20
  import { vtexFetch } from "../client";
21
21
  import {
22
- aggregateOffers,
23
- toAdditionalPropertyCategory,
24
- toAdditionalPropertyCluster,
25
- toAdditionalPropertyReferenceId,
26
- toAdditionalPropertySpecification,
22
+ aggregateOffers,
23
+ toAdditionalPropertyCategory,
24
+ toAdditionalPropertyCluster,
25
+ toAdditionalPropertyReferenceId,
26
+ toAdditionalPropertySpecification,
27
27
  } from "../utils/transform";
28
28
 
29
+ /** VTEX prices come in cents — divide by this to get the currency value. */
30
+ const CENTS_DIVISOR = 100;
31
+
29
32
  // ---------------------------------------------------------------------------
30
33
  // Types for pvt Catalog APIs
31
34
  // ---------------------------------------------------------------------------
32
35
 
33
36
  interface SkuImage {
34
- ImageUrl: string;
35
- ImageName?: string;
36
- FileId?: string;
37
+ ImageUrl: string;
38
+ ImageName?: string;
39
+ FileId?: string;
37
40
  }
38
41
 
39
42
  interface SkuSpecification {
40
- FieldName: string;
41
- FieldValues: string[];
42
- FieldValueIds: number[];
43
+ FieldName: string;
44
+ FieldValues: string[];
45
+ FieldValueIds: number[];
43
46
  }
44
47
 
45
48
  interface SkuSeller {
46
- SellerId: string;
49
+ SellerId: string;
47
50
  }
48
51
 
49
52
  interface SkuAlternateIds {
50
- RefId?: string;
51
- Ean?: string;
53
+ RefId?: string;
54
+ Ean?: string;
52
55
  }
53
56
 
54
57
  interface PvtSku {
55
- Id: number;
56
- ProductId: number;
57
- IsActive: boolean;
58
- SkuName: string;
59
- ProductName: string;
60
- ProductDescription: string;
61
- DetailUrl: string;
62
- BrandId: string;
63
- BrandName: string;
64
- ReleaseDate?: string;
65
- Images: SkuImage[];
66
- SkuSpecifications: SkuSpecification[];
67
- ProductSpecifications: SkuSpecification[];
68
- ProductCategories: Record<string, string>;
69
- ProductClusterNames: Record<string, string>;
70
- SalesChannels: number[];
71
- AlternateIds: SkuAlternateIds;
72
- SkuSellers: SkuSeller[];
58
+ Id: number;
59
+ ProductId: number;
60
+ IsActive: boolean;
61
+ SkuName: string;
62
+ ProductName: string;
63
+ ProductDescription: string;
64
+ DetailUrl: string;
65
+ BrandId: string;
66
+ BrandName: string;
67
+ ReleaseDate?: string;
68
+ Images: SkuImage[];
69
+ SkuSpecifications: SkuSpecification[];
70
+ ProductSpecifications: SkuSpecification[];
71
+ ProductCategories: Record<string, string>;
72
+ ProductClusterNames: Record<string, string>;
73
+ SalesChannels: number[];
74
+ AlternateIds: SkuAlternateIds;
75
+ SkuSellers: SkuSeller[];
73
76
  }
74
77
 
75
78
  interface PvtSkuListItem {
76
- Id: number;
77
- IsActive: boolean;
79
+ Id: number;
80
+ IsActive: boolean;
78
81
  }
79
82
 
80
83
  interface SalesChannel {
81
- Id: number;
82
- CurrencyCode: string;
84
+ Id: number;
85
+ CurrencyCode: string;
83
86
  }
84
87
 
85
88
  interface SimulationItem {
86
- sellingPrice: number;
87
- listPrice: number;
88
- price: number;
89
- seller: string;
90
- priceValidUntil: string;
91
- availability: string;
89
+ sellingPrice: number;
90
+ listPrice: number;
91
+ price: number;
92
+ seller: string;
93
+ priceValidUntil: string;
94
+ availability: string;
92
95
  }
93
96
 
94
97
  interface SimulationPaymentOption {
95
- paymentName: string;
96
- installments: Array<{ count: number; value: number; total: number }>;
98
+ paymentName: string;
99
+ installments: Array<{ count: number; value: number; total: number }>;
97
100
  }
98
101
 
99
102
  interface SimulationResponse {
100
- items?: SimulationItem[];
101
- paymentData?: { installmentOptions?: SimulationPaymentOption[] };
103
+ items?: SimulationItem[];
104
+ paymentData?: { installmentOptions?: SimulationPaymentOption[] };
102
105
  }
103
106
 
104
107
  // ---------------------------------------------------------------------------
@@ -106,10 +109,10 @@ interface SimulationResponse {
106
109
  // ---------------------------------------------------------------------------
107
110
 
108
111
  export interface WorkflowProductOptions {
109
- /** The SKU ID (stockKeepingUnitId) to load */
110
- productID: string;
111
- /** Sales channel for simulation. Defaults to 1. */
112
- salesChannel?: number;
112
+ /** The SKU ID (stockKeepingUnitId) to load */
113
+ productID: string;
114
+ /** Sales channel for simulation. Defaults to 1. */
115
+ salesChannel?: number;
113
116
  }
114
117
 
115
118
  /**
@@ -120,171 +123,163 @@ export interface WorkflowProductOptions {
120
123
  *
121
124
  * Ported from: vtex/loaders/workflow/product.ts
122
125
  */
123
- export async function workflowProduct(
124
- opts: WorkflowProductOptions,
125
- ): Promise<Product | null> {
126
- const sc = opts.salesChannel ?? 1;
126
+ export async function workflowProduct(opts: WorkflowProductOptions): Promise<Product | null> {
127
+ const sc = opts.salesChannel ?? 1;
127
128
 
128
- const sku = await vtexFetch<PvtSku>(
129
- `/api/catalog_system/pvt/sku/stockkeepingunitbyid/${opts.productID}`,
130
- );
129
+ const sku = await vtexFetch<PvtSku>(
130
+ `/api/catalog_system/pvt/sku/stockkeepingunitbyid/${opts.productID}`,
131
+ );
131
132
 
132
- if (!sku.IsActive) return null;
133
+ if (!sku.IsActive) return null;
133
134
 
134
- const [skus, salesChannels, ...simulations] = await Promise.all([
135
- vtexFetch<PvtSkuListItem[]>(
136
- `/api/catalog_system/pvt/sku/stockkeepingunitByProductId/${sku.ProductId}`,
137
- ),
138
- vtexFetch<SalesChannel[]>(
139
- "/api/catalog_system/pvt/saleschannel/list",
140
- ),
141
- ...sku.SkuSellers.map(({ SellerId }) =>
142
- vtexFetch<SimulationResponse>(
143
- `/api/checkout/pub/orderForms/simulation?RnbBehavior=1&sc=${sc}`,
144
- {
145
- method: "POST",
146
- body: JSON.stringify({
147
- items: [{ id: `${sku.Id}`, seller: SellerId, quantity: 1 }],
148
- }),
149
- },
150
- ),
151
- ),
152
- ]);
135
+ const [skus, salesChannels, ...simulations] = await Promise.all([
136
+ vtexFetch<PvtSkuListItem[]>(
137
+ `/api/catalog_system/pvt/sku/stockkeepingunitByProductId/${sku.ProductId}`,
138
+ ),
139
+ vtexFetch<SalesChannel[]>("/api/catalog_system/pvt/saleschannel/list"),
140
+ ...sku.SkuSellers.map(({ SellerId }) =>
141
+ vtexFetch<SimulationResponse>(
142
+ `/api/checkout/pub/orderForms/simulation?RnbBehavior=1&sc=${sc}`,
143
+ {
144
+ method: "POST",
145
+ body: JSON.stringify({
146
+ items: [{ id: `${sku.Id}`, seller: SellerId, quantity: 1 }],
147
+ }),
148
+ },
149
+ ),
150
+ ),
151
+ ]);
153
152
 
154
- const channel = salesChannels.find((c) => c.Id === sc);
155
- const productGroupID = `${sku.ProductId}`;
156
- const productID = `${sku.Id}`;
153
+ const channel = salesChannels.find((c) => c.Id === sc);
154
+ const productGroupID = `${sku.ProductId}`;
155
+ const productID = `${sku.Id}`;
157
156
 
158
- const additionalProperty = [
159
- sku.AlternateIds.RefId
160
- ? toAdditionalPropertyReferenceId({
161
- name: "RefId",
162
- value: sku.AlternateIds.RefId,
163
- })
164
- : null,
165
- ...Object.entries(sku.ProductCategories ?? {}).map(([propertyID, value]) =>
166
- toAdditionalPropertyCategory({ propertyID, value }),
167
- ),
168
- ...Object.entries(sku.ProductClusterNames ?? {}).map(
169
- ([propertyID, value]) =>
170
- toAdditionalPropertyCluster({ propertyID, value }),
171
- ),
172
- ...sku.SkuSpecifications.flatMap((spec) =>
173
- spec.FieldValues.map((value, it) =>
174
- toAdditionalPropertySpecification({
175
- propertyID: spec.FieldValueIds[it]?.toString(),
176
- name: spec.FieldName,
177
- value,
178
- }),
179
- ),
180
- ),
181
- ...sku.SalesChannels.map(
182
- (ch): PropertyValue => ({
183
- "@type": "PropertyValue",
184
- name: "salesChannel",
185
- propertyID: ch.toString(),
186
- }),
187
- ),
188
- ].filter((p): p is PropertyValue => Boolean(p));
157
+ const additionalProperty = [
158
+ sku.AlternateIds.RefId
159
+ ? toAdditionalPropertyReferenceId({
160
+ name: "RefId",
161
+ value: sku.AlternateIds.RefId,
162
+ })
163
+ : null,
164
+ ...Object.entries(sku.ProductCategories ?? {}).map(([propertyID, value]) =>
165
+ toAdditionalPropertyCategory({ propertyID, value }),
166
+ ),
167
+ ...Object.entries(sku.ProductClusterNames ?? {}).map(([propertyID, value]) =>
168
+ toAdditionalPropertyCluster({ propertyID, value }),
169
+ ),
170
+ ...sku.SkuSpecifications.flatMap((spec) =>
171
+ spec.FieldValues.map((value, it) =>
172
+ toAdditionalPropertySpecification({
173
+ propertyID: spec.FieldValueIds[it]?.toString(),
174
+ name: spec.FieldName,
175
+ value,
176
+ }),
177
+ ),
178
+ ),
179
+ ...sku.SalesChannels.map(
180
+ (ch): PropertyValue => ({
181
+ "@type": "PropertyValue",
182
+ name: "salesChannel",
183
+ propertyID: ch.toString(),
184
+ }),
185
+ ),
186
+ ].filter((p): p is PropertyValue => Boolean(p));
189
187
 
190
- const groupAdditionalProperty = sku.ProductSpecifications.flatMap((spec) =>
191
- spec.FieldValues.map((value, it) =>
192
- toAdditionalPropertySpecification({
193
- propertyID: spec.FieldValueIds[it]?.toString(),
194
- name: spec.FieldName,
195
- value,
196
- }),
197
- ),
198
- );
188
+ const groupAdditionalProperty = sku.ProductSpecifications.flatMap((spec) =>
189
+ spec.FieldValues.map((value, it) =>
190
+ toAdditionalPropertySpecification({
191
+ propertyID: spec.FieldValueIds[it]?.toString(),
192
+ name: spec.FieldName,
193
+ value,
194
+ }),
195
+ ),
196
+ );
199
197
 
200
- const offers = simulations
201
- .flatMap(({ items, paymentData }) =>
202
- items?.map((item): Offer | null => {
203
- const { sellingPrice, listPrice, price, seller, priceValidUntil, availability } = item;
204
- const spotPrice = sellingPrice || price;
205
- if (!spotPrice || !listPrice) return null;
198
+ const offers = simulations
199
+ .flatMap(({ items, paymentData }) =>
200
+ items?.map((item): Offer | null => {
201
+ const { sellingPrice, listPrice, price, seller, priceValidUntil, availability } = item;
202
+ const spotPrice = sellingPrice || price;
203
+ if (!spotPrice || !listPrice) return null;
206
204
 
207
- return {
208
- "@type": "Offer",
209
- price: spotPrice / 100,
210
- seller,
211
- priceValidUntil,
212
- inventoryLevel: {},
213
- availability:
214
- availability === "available"
215
- ? "https://schema.org/InStock"
216
- : "https://schema.org/OutOfStock",
217
- priceSpecification: [
218
- {
219
- "@type": "UnitPriceSpecification",
220
- priceType: "https://schema.org/ListPrice",
221
- price: listPrice / 100,
222
- },
223
- {
224
- "@type": "UnitPriceSpecification",
225
- priceType: "https://schema.org/SalePrice",
226
- price: spotPrice / 100,
227
- },
228
- ...(paymentData?.installmentOptions?.flatMap(
229
- (option): UnitPriceSpecification[] =>
230
- option.installments.map((i) => ({
231
- "@type": "UnitPriceSpecification",
232
- priceType: "https://schema.org/SalePrice",
233
- priceComponentType: "https://schema.org/Installment",
234
- name: option.paymentName,
235
- billingDuration: i.count,
236
- billingIncrement: i.value / 100,
237
- price: i.total / 100,
238
- })),
239
- ) ?? []),
240
- ],
241
- };
242
- }),
243
- )
244
- .filter((o): o is Offer => Boolean(o));
205
+ return {
206
+ "@type": "Offer",
207
+ price: spotPrice / CENTS_DIVISOR,
208
+ seller,
209
+ priceValidUntil,
210
+ inventoryLevel: {},
211
+ availability:
212
+ availability === "available"
213
+ ? "https://schema.org/InStock"
214
+ : "https://schema.org/OutOfStock",
215
+ priceSpecification: [
216
+ {
217
+ "@type": "UnitPriceSpecification",
218
+ priceType: "https://schema.org/ListPrice",
219
+ price: listPrice / CENTS_DIVISOR,
220
+ },
221
+ {
222
+ "@type": "UnitPriceSpecification",
223
+ priceType: "https://schema.org/SalePrice",
224
+ price: spotPrice / CENTS_DIVISOR,
225
+ },
226
+ ...(paymentData?.installmentOptions?.flatMap((option): UnitPriceSpecification[] =>
227
+ option.installments.map((i) => ({
228
+ "@type": "UnitPriceSpecification",
229
+ priceType: "https://schema.org/SalePrice",
230
+ priceComponentType: "https://schema.org/Installment",
231
+ name: option.paymentName,
232
+ billingDuration: i.count,
233
+ billingIncrement: i.value / CENTS_DIVISOR,
234
+ price: i.total / CENTS_DIVISOR,
235
+ })),
236
+ ) ?? []),
237
+ ],
238
+ };
239
+ }),
240
+ )
241
+ .filter((o): o is Offer => Boolean(o));
245
242
 
246
- return {
247
- "@type": "Product",
248
- productID,
249
- sku: productID,
250
- inProductGroupWithID: productGroupID,
251
- category: Object.values(sku.ProductCategories ?? {}).join(" > "),
252
- url: `${sku.DetailUrl}?skuId=${productID}`,
253
- name: sku.SkuName,
254
- gtin: sku.AlternateIds.Ean,
255
- image: sku.Images.map((img) => ({
256
- "@type": "ImageObject",
257
- encodingFormat: "image",
258
- alternateName: img.ImageName ?? img.FileId,
259
- url: img.ImageUrl,
260
- })),
261
- isVariantOf: {
262
- "@type": "ProductGroup",
263
- url: sku.DetailUrl,
264
- hasVariant:
265
- skus
266
- ?.filter((x) => x.IsActive)
267
- .map(({ Id }) => ({
268
- "@type": "Product",
269
- productID: `${Id}`,
270
- sku: `${Id}`,
271
- })) ?? [],
272
- additionalProperty: groupAdditionalProperty,
273
- productGroupID,
274
- name: sku.ProductName,
275
- description: sku.ProductDescription,
276
- },
277
- additionalProperty,
278
- releaseDate: sku.ReleaseDate
279
- ? new Date(sku.ReleaseDate).toISOString()
280
- : undefined,
281
- brand: {
282
- "@type": "Brand",
283
- "@id": sku.BrandId,
284
- name: sku.BrandName,
285
- },
286
- offers: aggregateOffers(offers, channel?.CurrencyCode),
287
- };
243
+ return {
244
+ "@type": "Product",
245
+ productID,
246
+ sku: productID,
247
+ inProductGroupWithID: productGroupID,
248
+ category: Object.values(sku.ProductCategories ?? {}).join(" > "),
249
+ url: `${sku.DetailUrl}?skuId=${productID}`,
250
+ name: sku.SkuName,
251
+ gtin: sku.AlternateIds.Ean,
252
+ image: sku.Images.map((img) => ({
253
+ "@type": "ImageObject",
254
+ encodingFormat: "image",
255
+ alternateName: img.ImageName ?? img.FileId,
256
+ url: img.ImageUrl,
257
+ })),
258
+ isVariantOf: {
259
+ "@type": "ProductGroup",
260
+ url: sku.DetailUrl,
261
+ hasVariant:
262
+ skus
263
+ ?.filter((x) => x.IsActive)
264
+ .map(({ Id }) => ({
265
+ "@type": "Product",
266
+ productID: `${Id}`,
267
+ sku: `${Id}`,
268
+ })) ?? [],
269
+ additionalProperty: groupAdditionalProperty,
270
+ productGroupID,
271
+ name: sku.ProductName,
272
+ description: sku.ProductDescription,
273
+ },
274
+ additionalProperty,
275
+ releaseDate: sku.ReleaseDate ? new Date(sku.ReleaseDate).toISOString() : undefined,
276
+ brand: {
277
+ "@type": "Brand",
278
+ "@id": sku.BrandId,
279
+ name: sku.BrandName,
280
+ },
281
+ offers: aggregateOffers(offers, channel?.CurrencyCode),
282
+ };
288
283
  }
289
284
 
290
285
  // ---------------------------------------------------------------------------
@@ -292,8 +287,8 @@ export async function workflowProduct(
292
287
  // ---------------------------------------------------------------------------
293
288
 
294
289
  export interface WorkflowProductsOptions {
295
- page: number;
296
- pagesize: number;
290
+ page: number;
291
+ pagesize: number;
297
292
  }
298
293
 
299
294
  /**
@@ -303,21 +298,19 @@ export interface WorkflowProductsOptions {
303
298
  *
304
299
  * Ported from: vtex/loaders/workflow/products.ts
305
300
  */
306
- export async function workflowProducts(
307
- opts: WorkflowProductsOptions,
308
- ): Promise<Product[]> {
309
- const params = new URLSearchParams({
310
- page: String(opts.page),
311
- pagesize: String(opts.pagesize),
312
- });
301
+ export async function workflowProducts(opts: WorkflowProductsOptions): Promise<Product[]> {
302
+ const params = new URLSearchParams({
303
+ page: String(opts.page),
304
+ pagesize: String(opts.pagesize),
305
+ });
313
306
 
314
- const ids = await vtexFetch<number[]>(
315
- `/api/catalog_system/pvt/sku/stockkeepingunitids?${params}`,
316
- );
307
+ const ids = await vtexFetch<number[]>(
308
+ `/api/catalog_system/pvt/sku/stockkeepingunitids?${params}`,
309
+ );
317
310
 
318
- return ids.map((productID) => ({
319
- "@type": "Product",
320
- productID: `${productID}`,
321
- sku: `${productID}`,
322
- }));
311
+ return ids.map((productID) => ({
312
+ "@type": "Product",
313
+ productID: `${productID}`,
314
+ sku: `${productID}`,
315
+ }));
323
316
  }