@scayle/storefront-core 8.39.1 → 8.41.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 CHANGED
@@ -1,5 +1,28 @@
1
1
  # @scayle/storefront-core
2
2
 
3
+ ## 8.41.0
4
+
5
+ ### Minor Changes
6
+
7
+ - Introduce a new `updatePromotions` RPC method to wrap the Storefront API "Bulk update promotions" endpoint.
8
+ This allows to update all promotions applied to basket's items in a single API call.
9
+ For more details, see the [Storefront API documentation](https://scayle.dev/en/api-guides/storefront-api/resources/baskets/bulk-update-promotions).
10
+
11
+ ### Patch Changes
12
+
13
+ **Dependencies**
14
+
15
+ - Updated dependency to @scayle/storefront-api@18.13.0
16
+
17
+ ## 8.40.0
18
+
19
+ ### Patch Changes
20
+
21
+ **Dependencies**
22
+
23
+ - Updated dependency to @scayle/storefront-api@18.12.0
24
+ - Updated dependency to @scayle/unstorage-scayle-kv-driver@1.0.3
25
+
3
26
  ## 8.39.1
4
27
 
5
28
  ### Patch Changes
@@ -1,5 +1,5 @@
1
1
  import { ExistingItemHandling } from '@scayle/storefront-api';
2
- import type { AddOrUpdateItemError, UpdateBasketItemQuantity, GetApplicablePromotionsByCodeParameters } from '@scayle/storefront-api';
2
+ import type { AddOrUpdateItemError, UpdateBasketItemQuantity, GetApplicablePromotionsByCodeParameters, BulkUpdatePromotionsParameters } from '@scayle/storefront-api';
3
3
  import type { AddOrUpdateItemType, BasketResponseData, BasketWithOptions, Product, RpcHandler, Variant } from '../../../types';
4
4
  import { mergeBaskets as mergeBasketFunction } from '../../../utils/user';
5
5
  /**
@@ -165,3 +165,17 @@ export declare const updateBasketItem: RpcHandler<UpdateBasketItemRequestParamet
165
165
  export declare const getApplicablePromotionsByCode: RpcHandler<Omit<GetApplicablePromotionsByCodeParameters, 'basketKey'>, {
166
166
  basket: BasketResponseData<Product, Variant>;
167
167
  }>;
168
+ /**
169
+ * Updates the promotions for a basket item.
170
+ *
171
+ * @param params The parameters for updating the promotions for a basket item.
172
+ * @param params.itemId The ID of the item to update.
173
+ * @param params.promotions The promotions to update.
174
+ * @param context The RPC context.
175
+ *
176
+ * @returns A promise that resolves with the updated basket.
177
+ * It will return an `ErrorResponse` if no session is found or update operation fails.
178
+ */
179
+ export declare const updatePromotions: RpcHandler<Omit<BulkUpdatePromotionsParameters, 'basketKey'>, {
180
+ basket: BasketResponseData<Product, Variant>;
181
+ }>;
@@ -305,6 +305,43 @@ export const getApplicablePromotionsByCode = defineRpcHandler(async ({ promotion
305
305
  return { basket: result.basket };
306
306
  }
307
307
  });
308
+ export const updatePromotions = defineRpcHandler(async (params, context) => {
309
+ if (!hasSession(context)) {
310
+ return new ErrorResponse(
311
+ HttpStatusCode.BAD_REQUEST,
312
+ HttpStatusMessage.BAD_REQUEST,
313
+ "No Session found"
314
+ );
315
+ }
316
+ const { basketKey, sapiClient } = context;
317
+ const campaignKey = params.campaignKey ?? await context.callRpc?.("getCampaignKey");
318
+ const resolvedWith = getWithParams(
319
+ { with: params.with },
320
+ context
321
+ );
322
+ const result = await mapSAPIFetchErrorToResponse(
323
+ sapiClient.basket.bulkUpdatePromotions
324
+ )(
325
+ basketKey,
326
+ {
327
+ ...params,
328
+ campaignKey,
329
+ with: resolvedWith
330
+ }
331
+ );
332
+ if (result instanceof Response || result.type === "failure") {
333
+ context.log.info("Bulk updating promotions failed", {
334
+ basketKey,
335
+ items: params.items
336
+ });
337
+ return new ErrorResponse(
338
+ HttpStatusCode.BAD_REQUEST,
339
+ SAPI_ERROR_NAME,
340
+ "Bulk updating promotions failed"
341
+ );
342
+ }
343
+ return { basket: result.basket };
344
+ });
308
345
  function parseBasketError(response) {
309
346
  const parsedError = {
310
347
  message: "",
@@ -33,7 +33,7 @@ export const getCheckoutToken = defineRpcHandler(async (jwtPayload = {}, context
33
33
  carrier,
34
34
  basketId: context.basketKey,
35
35
  campaignKey
36
- }).setIssuedAt(now).setNotBefore(now).setExpirationTime("1h").setIssuer(`${"@scayle/storefront-core"}@${"8.39.1"}`).setProtectedHeader({ alg: "HS256", typ: "JWT" }).sign(secret);
36
+ }).setIssuedAt(now).setNotBefore(now).setExpirationTime("1h").setIssuer(`${"@scayle/storefront-core"}@${"8.41.0"}`).setProtectedHeader({ alg: "HS256", typ: "JWT" }).sign(secret);
37
37
  return {
38
38
  accessToken: refreshedAccessToken,
39
39
  checkoutJwt
@@ -1,13 +1,13 @@
1
1
  /**
2
- * Wraps a SAPI API function, catching SAPI FetchErrors and converting them to a structured Response.
2
+ * Wraps a Storefront API client function, catching Storefront API FetchErrors and converting them to a structured Response.
3
3
  * This allows handling SAPI errors in a consistent way, returning a JSON response with status information.
4
4
  *
5
- * @template T The type of the SAPI API function.
5
+ * @template T The type of the Storefront API client function.
6
6
  *
7
- * @param func The SAPI API function to wrap.
7
+ * @param func The Storefront API client function to wrap.
8
8
  *
9
9
  * @returns A wrapped function that returns a Promise resolving to either the original function's result or a JSON Response representing the error.
10
10
  *
11
- * @throws Re-throws any error that is not an instance of FetchError.
11
+ * @throws Re-throws any error that is not an instance of StorefrontAPI FetchError.
12
12
  */
13
13
  export declare function mapSAPIFetchErrorToResponse<T extends (...args: any[]) => any>(func: T): (...args: Parameters<T>) => Promise<Awaited<ReturnType<T>> | Response>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@scayle/storefront-core",
3
- "version": "8.39.1",
3
+ "version": "8.41.0",
4
4
  "description": "Collection of essential utilities to work with the Storefront API",
5
5
  "author": "SCAYLE Commerce Engine",
6
6
  "license": "MIT",
@@ -56,25 +56,25 @@
56
56
  "ufo": "^1.5.3",
57
57
  "uncrypto": "^0.1.3",
58
58
  "utility-types": "^3.11.0",
59
- "@scayle/storefront-api": "18.12.0",
59
+ "@scayle/storefront-api": "18.13.0",
60
60
  "@scayle/unstorage-scayle-kv-driver": "1.0.3"
61
61
  },
62
62
  "devDependencies": {
63
63
  "@types/crypto-js": "4.2.2",
64
- "@types/node": "22.17.0",
64
+ "@types/node": "22.17.2",
65
65
  "@types/webpack-env": "1.18.8",
66
66
  "@vitest/coverage-v8": "3.2.4",
67
67
  "dprint": "0.50.1",
68
68
  "eslint-formatter-gitlab": "6.0.1",
69
- "eslint": "9.32.0",
69
+ "eslint": "9.33.0",
70
70
  "fishery": "2.3.1",
71
71
  "publint": "0.3.12",
72
72
  "rimraf": "6.0.1",
73
73
  "typescript": "5.9.2",
74
- "unbuild": "3.6.0",
74
+ "unbuild": "3.6.1",
75
75
  "unstorage": "1.16.1",
76
76
  "vitest": "3.2.4",
77
- "@scayle/eslint-config-storefront": "4.7.3",
77
+ "@scayle/eslint-config-storefront": "4.7.5",
78
78
  "@scayle/vitest-config-storefront": "1.0.0"
79
79
  },
80
80
  "volta": {