@faststore/api 1.12.35 → 1.12.37
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.
- package/dist/api.cjs.development.js +19 -8
- package/dist/api.cjs.development.js.map +1 -1
- package/dist/api.cjs.production.min.js +1 -1
- package/dist/api.cjs.production.min.js.map +1 -1
- package/dist/api.esm.js +19 -8
- package/dist/api.esm.js.map +1 -1
- package/dist/platforms/vtex/clients/search/types/ProductSearchResult.d.ts +1 -0
- package/package.json +3 -3
- package/src/platforms/vtex/clients/search/types/ProductSearchResult.ts +1 -0
- package/src/platforms/vtex/resolvers/validateCart.ts +76 -66
- package/CHANGELOG.md +0 -1605
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@faststore/api",
|
|
3
|
-
"version": "1.12.
|
|
3
|
+
"version": "1.12.37",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"typings": "dist/index.d.ts",
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"p-limit": "^3.1.0"
|
|
31
31
|
},
|
|
32
32
|
"devDependencies": {
|
|
33
|
-
"@faststore/shared": "^1.12.
|
|
33
|
+
"@faststore/shared": "^1.12.37",
|
|
34
34
|
"@graphql-codegen/cli": "2.2.0",
|
|
35
35
|
"@graphql-codegen/typescript": "2.2.2",
|
|
36
36
|
"concurrently": "^6.2.1",
|
|
@@ -46,5 +46,5 @@
|
|
|
46
46
|
"peerDependencies": {
|
|
47
47
|
"graphql": "^15.6.0"
|
|
48
48
|
},
|
|
49
|
-
"gitHead": "
|
|
49
|
+
"gitHead": "d4dce561e18aaae368982240b4000d9242b984bc"
|
|
50
50
|
}
|
|
@@ -1,10 +1,15 @@
|
|
|
1
1
|
import deepEquals from 'fast-deep-equal'
|
|
2
2
|
|
|
3
3
|
import { md5 } from '../utils/md5'
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
attachmentToPropertyValue,
|
|
6
|
+
getPropertyId,
|
|
7
|
+
VALUE_REFERENCES,
|
|
8
|
+
} from '../utils/propertyValue'
|
|
9
|
+
import { mutateChannelContext, mutateLocaleContext } from '../utils/contex'
|
|
5
10
|
|
|
6
11
|
import type {
|
|
7
|
-
IStoreSession,
|
|
12
|
+
IStoreSession,
|
|
8
13
|
IStoreOffer,
|
|
9
14
|
IStoreOrder,
|
|
10
15
|
IStorePropertyValue,
|
|
@@ -17,6 +22,7 @@ import type {
|
|
|
17
22
|
OrderFormItem,
|
|
18
23
|
} from '../clients/commerce/types/OrderForm'
|
|
19
24
|
import type { Context } from '..'
|
|
25
|
+
|
|
20
26
|
type Indexed<T> = T & { index?: number }
|
|
21
27
|
|
|
22
28
|
const isAttachment = (value: IStorePropertyValue) =>
|
|
@@ -37,7 +43,7 @@ const getId = (item: IStoreOffer) =>
|
|
|
37
43
|
|
|
38
44
|
const orderFormItemToOffer = (
|
|
39
45
|
item: OrderFormItem,
|
|
40
|
-
index?: number
|
|
46
|
+
index?: number
|
|
41
47
|
): Indexed<IStoreOffer> => ({
|
|
42
48
|
listPrice: item.listPrice / 100,
|
|
43
49
|
price: item.sellingPrice / 100,
|
|
@@ -53,7 +59,7 @@ const orderFormItemToOffer = (
|
|
|
53
59
|
})
|
|
54
60
|
|
|
55
61
|
const offerToOrderItemInput = (
|
|
56
|
-
offer: Indexed<IStoreOffer
|
|
62
|
+
offer: Indexed<IStoreOffer>
|
|
57
63
|
): OrderFormInputItem => ({
|
|
58
64
|
quantity: offer.quantity,
|
|
59
65
|
seller: offer.seller.identifier,
|
|
@@ -99,18 +105,17 @@ const equals = (storeOrder: IStoreOrder, orderForm: OrderForm) => {
|
|
|
99
105
|
}
|
|
100
106
|
|
|
101
107
|
const joinItems = (form: OrderForm) => {
|
|
102
|
-
const itemsById = form.items
|
|
103
|
-
|
|
104
|
-
const id = getId(orderFormItemToOffer(item))
|
|
108
|
+
const itemsById = form.items.reduce((acc, item) => {
|
|
109
|
+
const id = getId(orderFormItemToOffer(item))
|
|
105
110
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
111
|
+
if (!acc[id]) {
|
|
112
|
+
acc[id] = []
|
|
113
|
+
}
|
|
109
114
|
|
|
110
|
-
|
|
115
|
+
acc[id].push(item)
|
|
111
116
|
|
|
112
|
-
|
|
113
|
-
|
|
117
|
+
return acc
|
|
118
|
+
}, {} as Record<string, OrderFormItem[]>)
|
|
114
119
|
|
|
115
120
|
return {
|
|
116
121
|
...form,
|
|
@@ -119,7 +124,7 @@ const joinItems = (form: OrderForm) => {
|
|
|
119
124
|
const quantity = items.reduce((acc, i) => acc + i.quantity, 0)
|
|
120
125
|
const totalPrice = items.reduce(
|
|
121
126
|
(acc, i) => acc + i.quantity * i.sellingPrice,
|
|
122
|
-
0
|
|
127
|
+
0
|
|
123
128
|
)
|
|
124
129
|
|
|
125
130
|
return {
|
|
@@ -133,14 +138,14 @@ const joinItems = (form: OrderForm) => {
|
|
|
133
138
|
|
|
134
139
|
const orderFormToCart = async (
|
|
135
140
|
form: OrderForm,
|
|
136
|
-
skuLoader: Context['loaders']['skuLoader']
|
|
141
|
+
skuLoader: Context['loaders']['skuLoader']
|
|
137
142
|
) => {
|
|
138
143
|
return {
|
|
139
144
|
order: {
|
|
140
145
|
orderNumber: form.orderFormId,
|
|
141
146
|
acceptedOffer: form.items.map(async (item) => ({
|
|
142
147
|
...item,
|
|
143
|
-
product: await skuLoader.load(item.id),
|
|
148
|
+
product: await skuLoader.load(item.id),
|
|
144
149
|
})),
|
|
145
150
|
},
|
|
146
151
|
messages: form.messages.map(({ text, status }) => ({
|
|
@@ -154,7 +159,7 @@ const getOrderFormEtag = ({ items }: OrderForm) => md5(JSON.stringify(items))
|
|
|
154
159
|
|
|
155
160
|
const setOrderFormEtag = async (
|
|
156
161
|
form: OrderForm,
|
|
157
|
-
commerce: Context['clients']['commerce']
|
|
162
|
+
commerce: Context['clients']['commerce']
|
|
158
163
|
) => {
|
|
159
164
|
try {
|
|
160
165
|
const orderForm = await commerce.checkout.setCustomData({
|
|
@@ -167,7 +172,7 @@ const setOrderFormEtag = async (
|
|
|
167
172
|
return orderForm
|
|
168
173
|
} catch (err) {
|
|
169
174
|
console.error(
|
|
170
|
-
'Error while setting custom data to orderForm.\n Make sure to add the following custom app to the orderForm: \n{"fields":["cartEtag"],"id":"faststore","major":1}.\n More info at: https://developers.vtex.com/vtex-rest-api/docs/customizable-fields-with-checkout-api'
|
|
175
|
+
'Error while setting custom data to orderForm.\n Make sure to add the following custom app to the orderForm: \n{"fields":["cartEtag"],"id":"faststore","major":1}.\n More info at: https://developers.vtex.com/vtex-rest-api/docs/customizable-fields-with-checkout-api'
|
|
171
176
|
)
|
|
172
177
|
|
|
173
178
|
throw err
|
|
@@ -181,7 +186,7 @@ const setOrderFormEtag = async (
|
|
|
181
186
|
*/
|
|
182
187
|
const isOrderFormStale = (form: OrderForm) => {
|
|
183
188
|
const faststoreData = form.customData?.customApps.find(
|
|
184
|
-
(app) => app.id === 'faststore'
|
|
189
|
+
(app) => app.id === 'faststore'
|
|
185
190
|
)
|
|
186
191
|
|
|
187
192
|
const oldEtag = faststoreData?.fields?.cartEtag
|
|
@@ -199,24 +204,24 @@ const isOrderFormStale = (form: OrderForm) => {
|
|
|
199
204
|
const getOrderForm = async (
|
|
200
205
|
id: string,
|
|
201
206
|
session: Maybe<IStoreSession> | undefined,
|
|
202
|
-
{ clients: { commerce } }: Context
|
|
207
|
+
{ clients: { commerce } }: Context
|
|
203
208
|
) => {
|
|
204
209
|
const orderForm = await commerce.checkout.orderForm({
|
|
205
210
|
id,
|
|
206
|
-
})
|
|
211
|
+
})
|
|
207
212
|
|
|
208
213
|
// Stores that are not yet providing the session while validating the cart
|
|
209
214
|
// should not be able to update the shipping data
|
|
210
215
|
//
|
|
211
216
|
// This was causing errors while validating regionalizated carts
|
|
212
217
|
// because the following code was trying to change the shippingData to an undefined address/session
|
|
213
|
-
if(!session) {
|
|
218
|
+
if (!session) {
|
|
214
219
|
return orderForm
|
|
215
220
|
}
|
|
216
221
|
|
|
217
222
|
const shouldUpdateShippingData =
|
|
218
223
|
typeof session.postalCode === 'string' &&
|
|
219
|
-
orderForm.shippingData?.address?.postalCode != session.postalCode
|
|
224
|
+
orderForm.shippingData?.address?.postalCode != session.postalCode
|
|
220
225
|
|
|
221
226
|
if (shouldUpdateShippingData) {
|
|
222
227
|
return commerce.checkout.shippingData({
|
|
@@ -224,11 +229,11 @@ const getOrderForm = async (
|
|
|
224
229
|
body: {
|
|
225
230
|
selectedAddresses: [session],
|
|
226
231
|
},
|
|
227
|
-
})
|
|
232
|
+
})
|
|
228
233
|
}
|
|
229
234
|
|
|
230
|
-
return orderForm
|
|
231
|
-
}
|
|
235
|
+
return orderForm
|
|
236
|
+
}
|
|
232
237
|
|
|
233
238
|
/**
|
|
234
239
|
* This resolver implements the optimistic cart behavior. The main idea in here
|
|
@@ -246,7 +251,7 @@ const getOrderForm = async (
|
|
|
246
251
|
export const validateCart = async (
|
|
247
252
|
_: unknown,
|
|
248
253
|
{ cart: { order }, session }: MutationValidateCartArgs,
|
|
249
|
-
ctx: Context
|
|
254
|
+
ctx: Context
|
|
250
255
|
) => {
|
|
251
256
|
const { enableOrderFormSync } = ctx.storage.flags
|
|
252
257
|
const { orderNumber, acceptedOffer } = order
|
|
@@ -255,6 +260,17 @@ export const validateCart = async (
|
|
|
255
260
|
loaders: { skuLoader },
|
|
256
261
|
} = ctx
|
|
257
262
|
|
|
263
|
+
const channel = session?.channel
|
|
264
|
+
const locale = session?.locale
|
|
265
|
+
|
|
266
|
+
if (channel) {
|
|
267
|
+
mutateChannelContext(ctx, channel)
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
if (locale) {
|
|
271
|
+
mutateLocaleContext(ctx, locale)
|
|
272
|
+
}
|
|
273
|
+
|
|
258
274
|
// Step1: Get OrderForm from VTEX Commerce
|
|
259
275
|
const orderForm = await getOrderForm(orderNumber, session, ctx)
|
|
260
276
|
|
|
@@ -266,7 +282,7 @@ export const validateCart = async (
|
|
|
266
282
|
|
|
267
283
|
if (isStale === true && orderNumber) {
|
|
268
284
|
const newOrderForm = await setOrderFormEtag(orderForm, commerce).then(
|
|
269
|
-
joinItems
|
|
285
|
+
joinItems
|
|
270
286
|
)
|
|
271
287
|
|
|
272
288
|
return orderFormToCart(newOrderForm, skuLoader)
|
|
@@ -276,54 +292,48 @@ export const validateCart = async (
|
|
|
276
292
|
// Step2: Process items from both browser and checkout so they have the same shape
|
|
277
293
|
const browserItemsById = groupById(acceptedOffer)
|
|
278
294
|
const originItemsById = groupById(orderForm.items.map(orderFormItemToOffer))
|
|
279
|
-
const originItems = Array.from(originItemsById.entries())
|
|
280
|
-
const browserItems = Array.from(browserItemsById.entries())
|
|
295
|
+
const originItems = Array.from(originItemsById.entries()) // items on the VTEX platform backend
|
|
296
|
+
const browserItems = Array.from(browserItemsById.entries()) // items on the user's browser
|
|
281
297
|
|
|
282
298
|
// Step3: Compute delta changes
|
|
283
|
-
const { itemsToAdd, itemsToUpdate } = browserItems
|
|
284
|
-
|
|
285
|
-
(
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
items.forEach((item) => acc.itemsToAdd.push(item))
|
|
291
|
-
|
|
292
|
-
return acc
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
// Update existing items
|
|
296
|
-
const [head, ...tail] = maybeOriginItem
|
|
297
|
-
const totalQuantity = items.reduce(
|
|
298
|
-
(acc, curr) => acc + curr.quantity,
|
|
299
|
-
0,
|
|
300
|
-
)
|
|
301
|
-
|
|
302
|
-
// set total quantity to first item
|
|
303
|
-
acc.itemsToUpdate.push({
|
|
304
|
-
...head,
|
|
305
|
-
quantity: totalQuantity,
|
|
306
|
-
})
|
|
307
|
-
|
|
308
|
-
// Remove all the rest
|
|
309
|
-
tail.forEach((item) =>
|
|
310
|
-
acc.itemsToUpdate.push({ ...item, quantity: 0 })
|
|
311
|
-
)
|
|
299
|
+
const { itemsToAdd, itemsToUpdate } = browserItems.reduce(
|
|
300
|
+
(acc, [id, items]) => {
|
|
301
|
+
const maybeOriginItem = originItemsById.get(id)
|
|
302
|
+
|
|
303
|
+
// Adding new items to cart
|
|
304
|
+
if (!maybeOriginItem) {
|
|
305
|
+
items.forEach((item) => acc.itemsToAdd.push(item))
|
|
312
306
|
|
|
313
307
|
return acc
|
|
314
|
-
}
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
// Update existing items
|
|
311
|
+
const [head, ...tail] = maybeOriginItem
|
|
312
|
+
const totalQuantity = items.reduce((acc, curr) => acc + curr.quantity, 0)
|
|
313
|
+
|
|
314
|
+
// set total quantity to first item
|
|
315
|
+
acc.itemsToUpdate.push({
|
|
316
|
+
...head,
|
|
317
|
+
quantity: totalQuantity,
|
|
318
|
+
})
|
|
319
|
+
|
|
320
|
+
// Remove all the rest
|
|
321
|
+
tail.forEach((item) => acc.itemsToUpdate.push({ ...item, quantity: 0 }))
|
|
322
|
+
|
|
323
|
+
return acc
|
|
324
|
+
},
|
|
325
|
+
{
|
|
326
|
+
itemsToAdd: [] as IStoreOffer[],
|
|
327
|
+
itemsToUpdate: [] as IStoreOffer[],
|
|
328
|
+
}
|
|
329
|
+
)
|
|
320
330
|
|
|
321
331
|
const itemsToDelete = originItems
|
|
322
332
|
.filter(([id]) => !browserItemsById.has(id))
|
|
323
333
|
.flatMap(([, items]) => items.map((item) => ({ ...item, quantity: 0 })))
|
|
324
334
|
|
|
325
335
|
const changes = [...itemsToAdd, ...itemsToUpdate, ...itemsToDelete].map(
|
|
326
|
-
offerToOrderItemInput
|
|
336
|
+
offerToOrderItemInput
|
|
327
337
|
)
|
|
328
338
|
|
|
329
339
|
if (changes.length === 0) {
|