@scayle/storefront-core 8.46.0 → 8.47.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.
- package/CHANGELOG.md +40 -0
- package/dist/rpc/methods/basket/basket.d.ts +7 -5
- package/dist/rpc/methods/basket/basket.mjs +55 -11
- package/dist/rpc/methods/checkout/checkout.d.ts +2 -0
- package/dist/rpc/methods/checkout/checkout.mjs +7 -3
- package/dist/rpc/methods/checkout/order.d.ts +1 -0
- package/dist/rpc/methods/checkout/order.mjs +3 -0
- package/dist/utils/basket.d.ts +41 -0
- package/dist/utils/basket.mjs +9 -0
- package/dist/utils/user.d.ts +8 -0
- package/dist/utils/user.mjs +15 -2
- package/package.json +7 -7
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,45 @@
|
|
|
1
1
|
# @scayle/storefront-core
|
|
2
2
|
|
|
3
|
+
## 8.47.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- Enhanced basket RPC methods to support order custom data functionality.
|
|
8
|
+
|
|
9
|
+
All basket RPC methods now integrate with the `getOrderCustomData` RPC method to fetch and include order custom data in SAPI requests.
|
|
10
|
+
This enables developers to attach order-specific custom metadata, business rules, or additional context to orders throughout the basket lifecycle.
|
|
11
|
+
The existing `orderCustomData` parameter is deprecated and will be removed in the next major version.
|
|
12
|
+
For now, both parameters are supported and merged together, where attributes from the parameter take precedence.
|
|
13
|
+
|
|
14
|
+
On default, this RPC returns an empty object but can be overridden by the developer to return a custom object.
|
|
15
|
+
|
|
16
|
+
Example `getOrderCustomData` RPC:
|
|
17
|
+
|
|
18
|
+
```typescript
|
|
19
|
+
export const getOrderCustomData: RpcHandler<Record<string, unknown>> =
|
|
20
|
+
defineRpcHandler<Record<string, unknown>>(async (context: RpcContext) => {
|
|
21
|
+
return {
|
|
22
|
+
customer: {
|
|
23
|
+
groups: context.user?.groups,
|
|
24
|
+
},
|
|
25
|
+
}
|
|
26
|
+
})
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
For further information, please refer to the [Overriding Core RPC Methods](https://scayle.dev/en/core-documentation/storefront-guide/storefront-application/technical-foundation/rpc-methods?sourceText=RPC%2520Methods#overriding-core-rpc-methods).
|
|
30
|
+
|
|
31
|
+
- Updated all basket RPC methods to pass the customer access token to the SAPI client, enabling the `X-Customer-Token` header for promotion validation.
|
|
32
|
+
|
|
33
|
+
The customer access token is now automatically included in basket requests when available.
|
|
34
|
+
If the token has expired, it will be omitted from the request to prevent validation errors.
|
|
35
|
+
|
|
36
|
+
### Patch Changes
|
|
37
|
+
|
|
38
|
+
**Dependencies**
|
|
39
|
+
|
|
40
|
+
- Updated dependency to @scayle/unstorage-scayle-kv-driver@2.0.7
|
|
41
|
+
- Updated dependency to @scayle/storefront-api@18.18.0
|
|
42
|
+
|
|
3
43
|
## 8.46.0
|
|
4
44
|
|
|
5
45
|
### Minor Changes
|
|
@@ -15,7 +15,7 @@ import { mergeBaskets as mergeBasketFunction } from '../../../utils/user';
|
|
|
15
15
|
* @param params.existingItemHandling How to handle existing items, default to `'AddQuantityToExisting'`.
|
|
16
16
|
* @param params.itemGroup The item group.
|
|
17
17
|
* @param params.with withParams for basket.
|
|
18
|
-
* @param params.orderCustomData
|
|
18
|
+
* @param params.orderCustomData @deprecated - will be removed in the next major version. Use `getOrderCustomData` RPC method instead.
|
|
19
19
|
* @param context The RPC context.
|
|
20
20
|
*
|
|
21
21
|
* @returns The updated basket, potentially with errors. It will return
|
|
@@ -36,7 +36,7 @@ export declare const addItemToBasket: RpcHandler<AddOrUpdateItemType & {
|
|
|
36
36
|
* @param params.items An array of items to add.
|
|
37
37
|
* @param params.existingItemHandling How to handle existing items.
|
|
38
38
|
* @param params.with withParams for basket.
|
|
39
|
-
* @param params.orderCustomData
|
|
39
|
+
* @param params.orderCustomData @deprecated - will be removed in the next major version. Use `getOrderCustomData` RPC method instead.
|
|
40
40
|
* @param context The RPC context.
|
|
41
41
|
*
|
|
42
42
|
* @returns The updated basket, potentially with errors. It will return
|
|
@@ -55,7 +55,7 @@ export declare const addItemsToBasket: RpcHandler<{
|
|
|
55
55
|
* Retrieves the current basket.
|
|
56
56
|
*
|
|
57
57
|
* @param options The options for retrieving the basket.
|
|
58
|
-
* @param options.orderCustomData
|
|
58
|
+
* @param options.orderCustomData @deprecated - will be removed in the next major version. Use `getOrderCustomData` RPC method instead.
|
|
59
59
|
* @param context The RPC context.
|
|
60
60
|
*
|
|
61
61
|
* @returns The basket data. It will return an `ErrorResponse` alternatively
|
|
@@ -72,7 +72,7 @@ export declare const getBasket: RpcHandler<BasketWithOptions & {
|
|
|
72
72
|
* @param options The options for removing the item.
|
|
73
73
|
* @param options.itemKey The key of the item to remove.
|
|
74
74
|
* @param options.with withParams for basket.
|
|
75
|
-
* @param options.orderCustomData
|
|
75
|
+
* @param options.orderCustomData @deprecated - will be removed in the next major version. Use `getOrderCustomData` RPC method instead.
|
|
76
76
|
* @param context The RPC context.
|
|
77
77
|
*
|
|
78
78
|
* @returns The updated basket. It will return an `ErrorResponse` alternatively
|
|
@@ -101,7 +101,7 @@ export declare const clearBasket: RpcHandler<boolean>;
|
|
|
101
101
|
* @param params.fromBasketKey The key of the source basket.
|
|
102
102
|
* @param params.toBasketKey The key of the target basket.
|
|
103
103
|
* @param params.with withParams for basket.
|
|
104
|
-
* @param params.orderCustomData
|
|
104
|
+
* @param params.orderCustomData @deprecated - will be removed in the next major version. Use `getOrderCustomData` RPC method instead.
|
|
105
105
|
* @param context The RPC context.
|
|
106
106
|
*
|
|
107
107
|
* @returns The new merged basket as result of the merge operation.
|
|
@@ -135,6 +135,7 @@ export interface UpdateBasketItemRequestParameter {
|
|
|
135
135
|
* An object describing which data the returned basket should contain.
|
|
136
136
|
*/
|
|
137
137
|
with?: BasketWithOptions;
|
|
138
|
+
orderCustomData?: Record<string, unknown>;
|
|
138
139
|
}
|
|
139
140
|
/**
|
|
140
141
|
* Applies the provided update data to a specific item in a basket.
|
|
@@ -143,6 +144,7 @@ export interface UpdateBasketItemRequestParameter {
|
|
|
143
144
|
* @param params.basketItemKey The key of the item to be updated.
|
|
144
145
|
* @param params.update The update data that should be applied to the basket item.
|
|
145
146
|
* @param params.with An object describing which data the returned basket should contain.
|
|
147
|
+
* @param params.orderCustomData Custom data for the order.
|
|
146
148
|
* @param context The RPC context.
|
|
147
149
|
*
|
|
148
150
|
* @returns A promise that resolves with the updated basket.
|
|
@@ -6,9 +6,16 @@ import {
|
|
|
6
6
|
HttpStatusMessage,
|
|
7
7
|
MIN_WITH_PARAMS_BASKET
|
|
8
8
|
} from "../../../constants/index.mjs";
|
|
9
|
-
import {
|
|
9
|
+
import {
|
|
10
|
+
mergeBaskets as mergeBasketFunction,
|
|
11
|
+
getValidatedAccessToken
|
|
12
|
+
} from "../../../utils/user.mjs";
|
|
10
13
|
import { unwrap } from "../../../utils/response.mjs";
|
|
11
|
-
import {
|
|
14
|
+
import {
|
|
15
|
+
defineRpcHandler,
|
|
16
|
+
mergeOrderCustomData,
|
|
17
|
+
wasAddedWithReducedQuantity
|
|
18
|
+
} from "../../../utils/index.mjs";
|
|
12
19
|
import { mapSAPIFetchErrorToResponse } from "../../../utils/sapi.mjs";
|
|
13
20
|
const SAPI_ERROR_NAME = "SAPI ERROR";
|
|
14
21
|
function getWithParams(params, context) {
|
|
@@ -35,6 +42,7 @@ export const addItemToBasket = defineRpcHandler(async ({
|
|
|
35
42
|
}
|
|
36
43
|
const { sapiClient, basketKey } = context;
|
|
37
44
|
const campaignKey = await context.callRpc?.("getCampaignKey");
|
|
45
|
+
const _orderCustomData = await context.callRpc?.("getOrderCustomData");
|
|
38
46
|
const resolvedWith = getWithParams(
|
|
39
47
|
{ with: _with },
|
|
40
48
|
context
|
|
@@ -60,7 +68,8 @@ export const addItemToBasket = defineRpcHandler(async ({
|
|
|
60
68
|
],
|
|
61
69
|
{
|
|
62
70
|
skipAvailabilityCheck: false,
|
|
63
|
-
orderCustomData
|
|
71
|
+
orderCustomData: mergeOrderCustomData(_orderCustomData, orderCustomData),
|
|
72
|
+
customerToken: getValidatedAccessToken(context.accessToken) ?? void 0
|
|
64
73
|
},
|
|
65
74
|
{
|
|
66
75
|
existingItemHandling
|
|
@@ -97,6 +106,7 @@ export const addItemsToBasket = defineRpcHandler(async (params, context) => {
|
|
|
97
106
|
}
|
|
98
107
|
const { sapiClient, basketKey } = context;
|
|
99
108
|
const campaignKey = await context.callRpc?.("getCampaignKey");
|
|
109
|
+
const _orderCustomData = await context.callRpc?.("getOrderCustomData");
|
|
100
110
|
const resolvedWith = getWithParams(params, context);
|
|
101
111
|
const itemsToBeAddedOrUpdated = params.items.map((item) => ({
|
|
102
112
|
variantId: item.variantId,
|
|
@@ -119,7 +129,11 @@ export const addItemsToBasket = defineRpcHandler(async (params, context) => {
|
|
|
119
129
|
{
|
|
120
130
|
skipAvailabilityCheck: false,
|
|
121
131
|
includeItemsWithoutProductData: resolvedWith?.includeItemsWithoutProductData,
|
|
122
|
-
orderCustomData:
|
|
132
|
+
orderCustomData: mergeOrderCustomData(
|
|
133
|
+
_orderCustomData,
|
|
134
|
+
params.orderCustomData
|
|
135
|
+
),
|
|
136
|
+
customerToken: getValidatedAccessToken(context.accessToken) ?? void 0
|
|
123
137
|
},
|
|
124
138
|
{
|
|
125
139
|
existingItemHandling: params.existingItemHandling || ExistingItemHandling.ADD_QUANTITY_TO_EXISTING
|
|
@@ -159,6 +173,7 @@ export const getBasket = defineRpcHandler(async (options, context) => {
|
|
|
159
173
|
}
|
|
160
174
|
const { sapiClient, basketKey } = context;
|
|
161
175
|
const campaignKey = await context.callRpc?.("getCampaignKey");
|
|
176
|
+
const _orderCustomData = await context.callRpc?.("getOrderCustomData");
|
|
162
177
|
const resolvedWith = getWithParams(
|
|
163
178
|
{ with: options },
|
|
164
179
|
context
|
|
@@ -167,7 +182,11 @@ export const getBasket = defineRpcHandler(async (options, context) => {
|
|
|
167
182
|
with: resolvedWith,
|
|
168
183
|
campaignKey,
|
|
169
184
|
includeItemsWithoutProductData: resolvedWith.includeItemsWithoutProductData,
|
|
170
|
-
orderCustomData:
|
|
185
|
+
orderCustomData: mergeOrderCustomData(
|
|
186
|
+
_orderCustomData,
|
|
187
|
+
options?.orderCustomData
|
|
188
|
+
),
|
|
189
|
+
customerToken: getValidatedAccessToken(context.accessToken) ?? void 0
|
|
171
190
|
});
|
|
172
191
|
if (response.type === "failure") {
|
|
173
192
|
const { statusCode, message } = parseBasketError(response);
|
|
@@ -192,6 +211,7 @@ export const removeItemFromBasket = defineRpcHandler(async (options, context) =>
|
|
|
192
211
|
}
|
|
193
212
|
const { sapiClient, basketKey } = context;
|
|
194
213
|
const campaignKey = await context.callRpc?.("getCampaignKey");
|
|
214
|
+
const _orderCustomData = await context.callRpc?.("getOrderCustomData");
|
|
195
215
|
const resolvedWith = getWithParams(options, context);
|
|
196
216
|
const basket = await sapiClient.basket.deleteItem(
|
|
197
217
|
basketKey,
|
|
@@ -200,7 +220,11 @@ export const removeItemFromBasket = defineRpcHandler(async (options, context) =>
|
|
|
200
220
|
with: resolvedWith,
|
|
201
221
|
campaignKey,
|
|
202
222
|
includeItemsWithoutProductData: resolvedWith?.includeItemsWithoutProductData,
|
|
203
|
-
orderCustomData:
|
|
223
|
+
orderCustomData: mergeOrderCustomData(
|
|
224
|
+
_orderCustomData,
|
|
225
|
+
options.orderCustomData
|
|
226
|
+
),
|
|
227
|
+
customerToken: getValidatedAccessToken(context.accessToken) ?? void 0
|
|
204
228
|
}
|
|
205
229
|
);
|
|
206
230
|
return { basket };
|
|
@@ -226,14 +250,18 @@ export const mergeBaskets = defineRpcHandler(async ({ fromBasketKey, toBasketKey
|
|
|
226
250
|
{ with: _with },
|
|
227
251
|
context
|
|
228
252
|
);
|
|
253
|
+
const _orderCustomData = await context.callRpc?.("getOrderCustomData");
|
|
229
254
|
return await mergeBasketFunction(
|
|
230
255
|
fromBasketKey,
|
|
231
256
|
toBasketKey,
|
|
232
|
-
{
|
|
257
|
+
{
|
|
258
|
+
...resolvedWith,
|
|
259
|
+
orderCustomData: mergeOrderCustomData(_orderCustomData, orderCustomData)
|
|
260
|
+
},
|
|
233
261
|
context
|
|
234
262
|
);
|
|
235
263
|
});
|
|
236
|
-
export const updateBasketItem = defineRpcHandler(async ({ basketItemKey, update, with: _with }, context) => {
|
|
264
|
+
export const updateBasketItem = defineRpcHandler(async ({ basketItemKey, update, with: _with, orderCustomData }, context) => {
|
|
237
265
|
if (!hasSession(context)) {
|
|
238
266
|
return new ErrorResponse(
|
|
239
267
|
HttpStatusCode.BAD_REQUEST,
|
|
@@ -248,11 +276,18 @@ export const updateBasketItem = defineRpcHandler(async ({ basketItemKey, update,
|
|
|
248
276
|
);
|
|
249
277
|
const { quantity, ...updateParams } = update;
|
|
250
278
|
const campaignKey = update.campaignKey ?? await context.callRpc?.("getCampaignKey");
|
|
279
|
+
const _orderCustomData = await context.callRpc?.("getOrderCustomData");
|
|
251
280
|
const result = await sapiClient.basket.updateItem(
|
|
252
281
|
basketKey,
|
|
253
282
|
basketItemKey,
|
|
254
283
|
quantity,
|
|
255
|
-
{
|
|
284
|
+
{
|
|
285
|
+
...updateParams,
|
|
286
|
+
campaignKey,
|
|
287
|
+
with: resolvedWith,
|
|
288
|
+
orderCustomData: mergeOrderCustomData(_orderCustomData, orderCustomData),
|
|
289
|
+
customerToken: getValidatedAccessToken(context.accessToken) ?? void 0
|
|
290
|
+
}
|
|
256
291
|
);
|
|
257
292
|
if (result.type === "success") {
|
|
258
293
|
return { basket: result.basket };
|
|
@@ -287,12 +322,18 @@ export const getApplicablePromotionsByCode = defineRpcHandler(async ({ promotion
|
|
|
287
322
|
context
|
|
288
323
|
);
|
|
289
324
|
const campaignKey = await context.callRpc?.("getCampaignKey");
|
|
325
|
+
const orderCustomData = await context.callRpc?.("getOrderCustomData");
|
|
290
326
|
const result = await mapSAPIFetchErrorToResponse(
|
|
291
327
|
sapiClient.basket.getApplicablePromotionsByCode
|
|
292
328
|
)(
|
|
293
329
|
basketKey,
|
|
294
330
|
promotionCode,
|
|
295
|
-
{
|
|
331
|
+
{
|
|
332
|
+
campaignKey,
|
|
333
|
+
with: resolvedWith,
|
|
334
|
+
orderCustomData,
|
|
335
|
+
customerToken: getValidatedAccessToken(context.accessToken) ?? void 0
|
|
336
|
+
}
|
|
296
337
|
);
|
|
297
338
|
if (result instanceof Response || result.type === "failure") {
|
|
298
339
|
context.log.info("Getting applicable promotion codes failed", {
|
|
@@ -318,6 +359,7 @@ export const updatePromotions = defineRpcHandler(async (params, context) => {
|
|
|
318
359
|
}
|
|
319
360
|
const { basketKey, sapiClient } = context;
|
|
320
361
|
const campaignKey = params.campaignKey ?? await context.callRpc?.("getCampaignKey");
|
|
362
|
+
const orderCustomData = await context.callRpc?.("getOrderCustomData");
|
|
321
363
|
const resolvedWith = getWithParams(
|
|
322
364
|
{ with: params.with },
|
|
323
365
|
context
|
|
@@ -329,7 +371,9 @@ export const updatePromotions = defineRpcHandler(async (params, context) => {
|
|
|
329
371
|
{
|
|
330
372
|
...params,
|
|
331
373
|
campaignKey,
|
|
332
|
-
with: resolvedWith
|
|
374
|
+
with: resolvedWith,
|
|
375
|
+
orderCustomData,
|
|
376
|
+
customerToken: getValidatedAccessToken(context.accessToken) ?? void 0
|
|
333
377
|
}
|
|
334
378
|
);
|
|
335
379
|
if (result instanceof Response || result.type === "failure") {
|
|
@@ -45,6 +45,8 @@ interface CheckoutJwtPayload {
|
|
|
45
45
|
* @param jwtPayload The payload for the JWT. Provides checkout-related data to embed within the token.
|
|
46
46
|
* @param context The RPC context.
|
|
47
47
|
*
|
|
48
|
+
* @see https://scayle.dev/en/core-documentation/storefront/checkout-guide/implementation/webcomponent#jwt-attribute
|
|
49
|
+
*
|
|
48
50
|
* @returns An object containing the access token and checkout JWT.
|
|
49
51
|
* It will return an `ErrorResponse` if no session is found, no access token is present.
|
|
50
52
|
*/
|
|
@@ -26,14 +26,18 @@ export const getCheckoutToken = defineRpcHandler(async (jwtPayload = {}, context
|
|
|
26
26
|
const now = /* @__PURE__ */ new Date();
|
|
27
27
|
const { voucher, customData, preferredCollectionPoint, carrier } = jwtPayload;
|
|
28
28
|
const campaignKey = await context.callRpc?.("getCampaignKey");
|
|
29
|
+
const orderCustomData = await context.callRpc?.("getOrderCustomData");
|
|
29
30
|
const checkoutJwt = await new SignJWT({
|
|
30
31
|
voucher,
|
|
31
|
-
customData,
|
|
32
32
|
preferredCollectionPoint,
|
|
33
33
|
carrier,
|
|
34
34
|
basketId: context.basketKey,
|
|
35
|
-
campaignKey
|
|
36
|
-
|
|
35
|
+
campaignKey,
|
|
36
|
+
customData: {
|
|
37
|
+
...customData,
|
|
38
|
+
...orderCustomData
|
|
39
|
+
}
|
|
40
|
+
}).setIssuedAt(now).setNotBefore(now).setExpirationTime("1h").setIssuer(`${"@scayle/storefront-core"}@${"8.47.0"}`).setProtectedHeader({ alg: "HS256", typ: "JWT" }).sign(secret);
|
|
37
41
|
return {
|
|
38
42
|
accessToken: refreshedAccessToken,
|
|
39
43
|
checkoutJwt
|
package/dist/utils/basket.d.ts
CHANGED
|
@@ -23,3 +23,44 @@ import type { AddOrUpdateItemError } from '@scayle/storefront-api';
|
|
|
23
23
|
* ```
|
|
24
24
|
*/
|
|
25
25
|
export declare const wasAddedWithReducedQuantity: (errors?: AddOrUpdateItemError[]) => boolean;
|
|
26
|
+
/**
|
|
27
|
+
* Merges the two orderCustomData objects when both RPC and parameter values are provided.
|
|
28
|
+
* If an attribute exists in both, the parameter value takes precedence.
|
|
29
|
+
*
|
|
30
|
+
* @param orderCustomDataRpc The order custom data from the RPC context.
|
|
31
|
+
* @param orderCustomDataParam The order custom data from the parameter.
|
|
32
|
+
*
|
|
33
|
+
* @example
|
|
34
|
+
* ```typescript
|
|
35
|
+
* const orderCustomDataRpc = {
|
|
36
|
+
* orderId: '1',
|
|
37
|
+
* }
|
|
38
|
+
* const orderCustomDataParam = {
|
|
39
|
+
* orderId: '2',
|
|
40
|
+
* }
|
|
41
|
+
* const mergedOrderCustomData = mergeOrderCustomData(orderCustomDataRpc, orderCustomDataParam) // { orderId: '2' }
|
|
42
|
+
*
|
|
43
|
+
* const orderCustomDataRpc = {
|
|
44
|
+
* orderId: '1',
|
|
45
|
+
* }
|
|
46
|
+
* const orderCustomDataParam = undefined
|
|
47
|
+
* const mergedOrderCustomData = mergeOrderCustomData(orderCustomDataRpc, orderCustomDataParam) // { orderId: '1' }
|
|
48
|
+
*
|
|
49
|
+
* const orderCustomDataRpc = undefined
|
|
50
|
+
* const orderCustomDataParam = {
|
|
51
|
+
* orderId: '2',
|
|
52
|
+
* }
|
|
53
|
+
* const mergedOrderCustomData = mergeOrderCustomData(orderCustomDataRpc, orderCustomDataParam) // { orderId: '2' }
|
|
54
|
+
*
|
|
55
|
+
* const orderCustomDataRpc = {
|
|
56
|
+
* orderId: '1',
|
|
57
|
+
* }
|
|
58
|
+
* const orderCustomDataParam = {
|
|
59
|
+
* orderName: 'Order 2',
|
|
60
|
+
* }
|
|
61
|
+
* const mergedOrderCustomData = mergeOrderCustomData(orderCustomDataRpc, orderCustomDataParam) // { orderId: '1', orderName: 'Order 2' }
|
|
62
|
+
* ```
|
|
63
|
+
*
|
|
64
|
+
* @returns The merged order custom data.
|
|
65
|
+
*/
|
|
66
|
+
export declare const mergeOrderCustomData: (orderCustomDataRpc?: Record<string, unknown>, orderCustomDataParam?: Record<string, unknown>) => Record<string, unknown>;
|
package/dist/utils/basket.mjs
CHANGED
|
@@ -10,3 +10,12 @@ export const wasAddedWithReducedQuantity = (errors) => {
|
|
|
10
10
|
(error) => error.operation === "add" && error.kind === AddToBasketFailureKind.ITEM_ADDED_WITH_REDUCED_QUANTITY || error.operation === "update" && error.kind === UpdateBasketItemFailureKind.ITEM_ADDED_WITH_REDUCED_QUANTITY
|
|
11
11
|
);
|
|
12
12
|
};
|
|
13
|
+
export const mergeOrderCustomData = (orderCustomDataRpc, orderCustomDataParam) => {
|
|
14
|
+
if (!orderCustomDataParam) {
|
|
15
|
+
return orderCustomDataRpc ?? {};
|
|
16
|
+
}
|
|
17
|
+
if (!orderCustomDataRpc) {
|
|
18
|
+
return orderCustomDataParam ?? {};
|
|
19
|
+
}
|
|
20
|
+
return { ...orderCustomDataRpc, ...orderCustomDataParam };
|
|
21
|
+
};
|
package/dist/utils/user.d.ts
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
import type { BasketResponse, AddManyItemsBasketResponse } from '@scayle/storefront-api';
|
|
2
2
|
import type { BasketWithOptions, Product, RpcContext, Variant } from '../types';
|
|
3
|
+
/**
|
|
4
|
+
* Checks if the access token is expired.
|
|
5
|
+
*
|
|
6
|
+
* @param accessToken The access token to validate.
|
|
7
|
+
*
|
|
8
|
+
* @returns The validated access token or undefined if the access token is not present or expired.
|
|
9
|
+
*/
|
|
10
|
+
export declare const getValidatedAccessToken: (accessToken?: string) => string | undefined;
|
|
3
11
|
/**
|
|
4
12
|
* Merges two baskets. Adds the items from the `fromBasketKey` basket to the `toBasketKey` basket
|
|
5
13
|
* and then clears the `fromBasketKey` basket. Handles existing items by adding quantities.
|
package/dist/utils/user.mjs
CHANGED
|
@@ -1,11 +1,23 @@
|
|
|
1
1
|
import { ExistingItemHandling } from "@scayle/storefront-api";
|
|
2
|
+
import { decodeJwt } from "jose";
|
|
3
|
+
export const getValidatedAccessToken = (accessToken) => {
|
|
4
|
+
if (!accessToken) {
|
|
5
|
+
return;
|
|
6
|
+
}
|
|
7
|
+
const payload = decodeJwt(accessToken);
|
|
8
|
+
if (!payload.exp || payload.exp < Date.now() / 1e3) {
|
|
9
|
+
return;
|
|
10
|
+
}
|
|
11
|
+
return accessToken;
|
|
12
|
+
};
|
|
2
13
|
export const mergeBaskets = async (fromBasketKey, toBasketKey, withOptions, context) => {
|
|
3
14
|
const { sapiClient } = context;
|
|
4
15
|
const campaignKey = await context.callRpc?.("getCampaignKey");
|
|
5
16
|
const fromOriginBasket = await sapiClient.basket.get(fromBasketKey, {
|
|
6
17
|
with: withOptions,
|
|
7
18
|
campaignKey,
|
|
8
|
-
orderCustomData: withOptions.orderCustomData
|
|
19
|
+
orderCustomData: withOptions.orderCustomData,
|
|
20
|
+
customerToken: getValidatedAccessToken(context.accessToken) ?? void 0
|
|
9
21
|
});
|
|
10
22
|
context.log.debug(`Merging basket ${fromBasketKey} to ${toBasketKey}`);
|
|
11
23
|
if (fromBasketKey === toBasketKey) {
|
|
@@ -31,7 +43,8 @@ export const mergeBaskets = async (fromBasketKey, toBasketKey, withOptions, cont
|
|
|
31
43
|
with: withOptions,
|
|
32
44
|
campaignKey,
|
|
33
45
|
includeItemsWithoutProductData: withOptions?.includeItemsWithoutProductData,
|
|
34
|
-
orderCustomData: withOptions.orderCustomData
|
|
46
|
+
orderCustomData: withOptions.orderCustomData,
|
|
47
|
+
customerToken: getValidatedAccessToken(context.accessToken) ?? void 0
|
|
35
48
|
},
|
|
36
49
|
{
|
|
37
50
|
existingItemHandling: ExistingItemHandling.ADD_QUANTITY_TO_EXISTING
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@scayle/storefront-core",
|
|
3
|
-
"version": "8.
|
|
3
|
+
"version": "8.47.0",
|
|
4
4
|
"description": "Collection of essential utilities to work with the Storefront API",
|
|
5
5
|
"author": "SCAYLE Commerce Engine",
|
|
6
6
|
"license": "MIT",
|
|
@@ -48,12 +48,12 @@
|
|
|
48
48
|
"ufo": "^1.5.3",
|
|
49
49
|
"uncrypto": "^0.1.3",
|
|
50
50
|
"utility-types": "^3.11.0",
|
|
51
|
-
"@scayle/storefront-api": "18.
|
|
52
|
-
"@scayle/unstorage-scayle-kv-driver": "2.0.
|
|
51
|
+
"@scayle/storefront-api": "18.18.0",
|
|
52
|
+
"@scayle/unstorage-scayle-kv-driver": "2.0.7"
|
|
53
53
|
},
|
|
54
54
|
"devDependencies": {
|
|
55
55
|
"@types/crypto-js": "4.2.2",
|
|
56
|
-
"@types/node": "22.18.
|
|
56
|
+
"@types/node": "22.18.13",
|
|
57
57
|
"@types/webpack-env": "1.18.8",
|
|
58
58
|
"@vitest/coverage-v8": "3.2.4",
|
|
59
59
|
"dprint": "0.50.2",
|
|
@@ -66,11 +66,11 @@
|
|
|
66
66
|
"unbuild": "3.6.1",
|
|
67
67
|
"unstorage": "1.17.1",
|
|
68
68
|
"vitest": "3.2.4",
|
|
69
|
-
"@scayle/
|
|
70
|
-
"@scayle/
|
|
69
|
+
"@scayle/eslint-config-storefront": "4.7.11",
|
|
70
|
+
"@scayle/vitest-config-storefront": "1.0.0"
|
|
71
71
|
},
|
|
72
72
|
"volta": {
|
|
73
|
-
"node": "22.
|
|
73
|
+
"node": "22.21.0"
|
|
74
74
|
},
|
|
75
75
|
"scripts": {
|
|
76
76
|
"clean": "rimraf ./dist",
|