@scayle/storefront-core 8.15.1 → 8.17.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,17 @@
1
1
  # @scayle/storefront-core
2
2
 
3
+ ## 8.17.0
4
+
5
+ ### Minor Changes
6
+
7
+ - Fix return type of `RpcMethodCall` to reflect that it returns a `Promise<TResult>` instead of `TResult`. This change emphasizes that `callRpc` in `RpcContext` is indeed an asynchronous operation.
8
+
9
+ ### Patch Changes
10
+
11
+ - Ensure that `pricePromotionKey` set in the right place when calling the deletion wishlist item operation of SAPI.
12
+
13
+ ## 8.16.0
14
+
3
15
  ## 8.15.1
4
16
 
5
17
  ### Patch Changes
@@ -200,12 +212,12 @@ To get the default campaign key, you can call the RPC method:
200
212
  ```typescript
201
213
  // Before
202
214
  async function rpcMethod(context) {
203
- const campaignKey = { context };
215
+ const campaignKey = { context }
204
216
  // ...
205
217
  }
206
218
  // After
207
219
  async function rpcMethod(context) {
208
- const campaignKey = await context.callRpc?.("getCampaignKey");
220
+ const campaignKey = await context.callRpc?.('getCampaignKey')
209
221
  // ...
210
222
  }
211
223
  ```
@@ -394,43 +406,43 @@ See [Overriding core RPC Methods](https://scayle.dev/en/storefront-guide/develop
394
406
 
395
407
  ```ts
396
408
  const BadgeLabel = {
397
- NEW: "new",
398
- SOLD_OUT: "sold_out",
399
- ONLINE_EXCLUSIVE: "online_exclusive",
400
- SUSTAINABLE: "sustainable",
401
- PREMIUM: "premium",
402
- DEFAULT: "",
403
- } as const;
409
+ NEW: 'new',
410
+ SOLD_OUT: 'sold_out',
411
+ ONLINE_EXCLUSIVE: 'online_exclusive',
412
+ SUSTAINABLE: 'sustainable',
413
+ PREMIUM: 'premium',
414
+ DEFAULT: '',
415
+ } as const
404
416
 
405
417
  type BadgeLabelParamsKeys =
406
- | "isNew"
407
- | "isSoldOut"
408
- | "isOnlineOnly"
409
- | "isSustainable"
410
- | "isPremium";
411
- type BadgeLabelParams = Partial<Record<BadgeLabelParamsKeys, boolean>>;
418
+ | 'isNew'
419
+ | 'isSoldOut'
420
+ | 'isOnlineOnly'
421
+ | 'isSustainable'
422
+ | 'isPremium'
423
+ type BadgeLabelParams = Partial<Record<BadgeLabelParamsKeys, boolean>>
412
424
 
413
425
  const getBadgeLabel = (params: BadgeLabelParams = {}): string => {
414
426
  if (!params) {
415
- return BadgeLabel.DEFAULT;
427
+ return BadgeLabel.DEFAULT
416
428
  }
417
429
  const { isNew, isSoldOut, isOnlineOnly, isSustainable, isPremium } =
418
- params;
430
+ params
419
431
 
420
432
  if (isNew) {
421
- return BadgeLabel.NEW;
433
+ return BadgeLabel.NEW
422
434
  } else if (isSoldOut) {
423
- return BadgeLabel.SOLD_OUT;
435
+ return BadgeLabel.SOLD_OUT
424
436
  } else if (isOnlineOnly) {
425
- return BadgeLabel.ONLINE_EXCLUSIVE;
437
+ return BadgeLabel.ONLINE_EXCLUSIVE
426
438
  } else if (isSustainable) {
427
- return BadgeLabel.SUSTAINABLE;
439
+ return BadgeLabel.SUSTAINABLE
428
440
  } else if (isPremium) {
429
- return BadgeLabel.PREMIUM;
441
+ return BadgeLabel.PREMIUM
430
442
  } else {
431
- return BadgeLabel.DEFAULT;
443
+ return BadgeLabel.DEFAULT
432
444
  }
433
- };
445
+ }
434
446
  ```
435
447
 
436
448
  - **\[💥 BREAKING\]** We've standardized our configuration to use `sapi` (Storefront API) throughout the codebase, replacing the deprecated `bapi` keyword. This change improves clarity and consistency by removing the `initBapi` function, replacing the `bapiClient` property with `sapiClient` within the `RPCContext`, and updating all code references accordingly. `BapiConfig` is not exported anymore and has been superseded by `SapiConfig`.
@@ -446,15 +458,15 @@ See [Overriding core RPC Methods](https://scayle.dev/en/storefront-guide/develop
446
458
  storefront: {
447
459
  // ...
448
460
  bapi: {
449
- host: "...",
450
- token: "...",
461
+ host: '...',
462
+ token: '...',
451
463
  },
452
464
  // ...
453
465
  },
454
466
  // ...
455
467
  },
456
468
  // ...
457
- };
469
+ }
458
470
  ```
459
471
 
460
472
  - _Legacy Environment Variables:_
@@ -474,15 +486,15 @@ See [Overriding core RPC Methods](https://scayle.dev/en/storefront-guide/develop
474
486
  storefront: {
475
487
  // ...
476
488
  sapi: {
477
- host: "...",
478
- token: "...",
489
+ host: '...',
490
+ token: '...',
479
491
  },
480
492
  // ...
481
493
  },
482
494
  // ...
483
495
  },
484
496
  // ...
485
- };
497
+ }
486
498
  ```
487
499
 
488
500
  - _New Environment Variables:_
@@ -500,19 +512,19 @@ See [Overriding core RPC Methods](https://scayle.dev/en/storefront-guide/develop
500
512
 
501
513
  ```ts
502
514
  const { data, fetching, fetch, error, status } = useUser(
503
- "getUser"
515
+ 'getUser',
504
516
  // ...
505
- );
506
- data.value.user.authentication.storefrontAccessToken;
517
+ )
518
+ data.value.user.authentication.storefrontAccessToken
507
519
  ```
508
520
 
509
521
  - _Current Usage of dedicated `getAccessToken` RPC method:_
510
522
 
511
523
  ```ts
512
524
  const { data: accessToken } = useRpc(
513
- "getAccessToken"
525
+ 'getAccessToken',
514
526
  // ...
515
- );
527
+ )
516
528
  ```
517
529
 
518
530
  - **\[💥 BREAKING\]** We've enhanced security for basket and wishlist keys by switching the default hashing algorithm from MD5 to the more robust SHA256.
@@ -535,7 +547,7 @@ See [Overriding core RPC Methods](https://scayle.dev/en/storefront-guide/develop
535
547
  // ...
536
548
  },
537
549
  // ...
538
- });
550
+ })
539
551
  ```
540
552
 
541
553
  - **\[💥 BREAKING\]** The attribute `loginShopId` is removed from the `ShopUser` interface as the shop now uses session cookies.
@@ -544,23 +556,23 @@ See [Overriding core RPC Methods](https://scayle.dev/en/storefront-guide/develop
544
556
  - _Previous Usage of `searchProducts` RPC method:_
545
557
 
546
558
  ```ts
547
- const getSearchSuggestionsRpc = useRpcCall("searchProducts");
559
+ const getSearchSuggestionsRpc = useRpcCall('searchProducts')
548
560
 
549
561
  data.value = await searchProducts({
550
562
  term: String(searchQuery.value),
551
563
  ...params,
552
- });
564
+ })
553
565
  ```
554
566
 
555
567
  - _Current Usage of `getSearchSuggestions` RPC method:_
556
568
 
557
569
  ```ts
558
- const getSearchSuggestionsRpc = useRpcCall("getSearchSuggestions");
570
+ const getSearchSuggestionsRpc = useRpcCall('getSearchSuggestions')
559
571
 
560
572
  data.value = await getSearchSuggestionsRpc({
561
573
  term: String(searchQuery.value),
562
574
  ...params,
563
- });
575
+ })
564
576
  ```
565
577
 
566
578
  - **\[💥 BREAKING\]** Improved basket updating: Adding an item to your basket with a reduced quantity will now correctly update the basket contents.
package/dist/index.d.ts CHANGED
@@ -67,5 +67,5 @@ export type RpcMethodParameters<N extends RpcMethodName> = Parameters<RpcMethod<
67
67
  * @template N The name of the RPC method.
68
68
  */
69
69
  export type RpcMethodReturnType<N extends RpcMethodName> = ReturnType<RpcMethod<N>>;
70
- export type RpcMethodCall = <N extends RpcMethodName, P extends RpcMethodParameters<N>, TResult extends Exclude<Awaited<RpcMethodReturnType<N>>, Response>>(...args: P extends RpcContext ? [N] : [N, P]) => TResult;
70
+ export type RpcMethodCall = <N extends RpcMethodName, P extends RpcMethodParameters<N>, TResult extends Exclude<Awaited<RpcMethodReturnType<N>>, Response>>(...args: P extends RpcContext ? [N] : [N, P]) => Promise<TResult>;
71
71
  export { ExistingItemHandling, AddToBasketFailureKind, UpdateBasketItemFailureKind, AddToWishlistFailureKind, PromotionEffectType, FilterTypes, APISortOption, APISortOrder, type ProductSortConfig, } from '@scayle/storefront-api';
@@ -36,7 +36,7 @@ export const getCheckoutToken = async function getCheckoutToken2(jwtPayload = {}
36
36
  carrier,
37
37
  basketId: context.basketKey,
38
38
  campaignKey
39
- }).setIssuedAt(now).setNotBefore(now).setExpirationTime("1h").setIssuer(`${"@scayle/storefront-core"}@${"8.15.1"}`).setProtectedHeader({ alg: "HS256", typ: "JWT" }).sign(secret);
39
+ }).setIssuedAt(now).setNotBefore(now).setExpirationTime("1h").setIssuer(`${"@scayle/storefront-core"}@${"8.17.0"}`).setProtectedHeader({ alg: "HS256", typ: "JWT" }).sign(secret);
40
40
  return {
41
41
  accessToken: refreshedAccessToken,
42
42
  checkoutJwt
@@ -20,13 +20,15 @@ export const getWishlist = async function getWishlist2(options, context) {
20
20
  }
21
21
  const { sapiClient, wishlistKey } = context;
22
22
  const campaignKey = await context.callRpc?.("getCampaignKey");
23
- const resolvedWith = getWithParams({ with: options }, context);
23
+ const { pricePromotionKey, ...resolvedWith } = getWithParams({
24
+ with: options
25
+ }, context);
24
26
  return await mapSAPIFetchErrorToResponse(sapiClient.wishlist.get)(
25
27
  wishlistKey,
26
28
  {
27
29
  with: resolvedWith,
28
30
  campaignKey,
29
- pricePromotionKey: resolvedWith?.pricePromotionKey ?? ""
31
+ pricePromotionKey: pricePromotionKey ?? ""
30
32
  }
31
33
  );
32
34
  };
@@ -41,8 +43,7 @@ export const addItemToWishlist = async function addItemToWishlist2(options, cont
41
43
  const { sapiClient, wishlistKey } = context;
42
44
  const campaignKey = await context.callRpc?.("getCampaignKey");
43
45
  const { productId, variantId } = options;
44
- const resolvedWith = getWithParams(options, context);
45
- const pricePromotionKey = resolvedWith?.pricePromotionKey ?? "";
46
+ const { pricePromotionKey, ...resolvedWith } = getWithParams(options, context);
46
47
  if (!productId && !variantId) {
47
48
  return new ErrorResponse(
48
49
  HttpStatusCode.BAD_REQUEST,
@@ -56,7 +57,7 @@ export const addItemToWishlist = async function addItemToWishlist2(options, cont
56
57
  {
57
58
  with: resolvedWith,
58
59
  campaignKey,
59
- pricePromotionKey
60
+ pricePromotionKey: pricePromotionKey ?? ""
60
61
  }
61
62
  );
62
63
  if (result.type === "success") {
@@ -77,13 +78,14 @@ export const removeItemFromWishlist = async function removeItemFromWishlist2(opt
77
78
  }
78
79
  const { sapiClient, wishlistKey } = context;
79
80
  const campaignKey = await context.callRpc?.("getCampaignKey");
80
- const resolvedWith = getWithParams(options, context);
81
+ const { pricePromotionKey, ...resolvedWith } = getWithParams(options, context);
81
82
  return await mapSAPIFetchErrorToResponse(sapiClient.wishlist.deleteItem)(
82
83
  wishlistKey,
83
84
  options.itemKey,
84
85
  {
85
86
  with: resolvedWith,
86
- campaignKey
87
+ campaignKey,
88
+ pricePromotionKey: pricePromotionKey ?? ""
87
89
  }
88
90
  );
89
91
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@scayle/storefront-core",
3
- "version": "8.15.1",
3
+ "version": "8.17.0",
4
4
  "description": "Collection of essential utilities to work with the Storefront API",
5
5
  "author": "SCAYLE Commerce Engine",
6
6
  "license": "MIT",
@@ -76,7 +76,7 @@
76
76
  "devDependencies": {
77
77
  "@scayle/eslint-config-storefront": "4.5.0",
78
78
  "@types/crypto-js": "4.2.2",
79
- "@types/node": "22.13.16",
79
+ "@types/node": "22.14.0",
80
80
  "@types/webpack-env": "1.18.8",
81
81
  "@vitest/coverage-v8": "2.1.9",
82
82
  "dprint": "0.49.1",
@@ -1,415 +0,0 @@
1
- export declare const product: {
2
- id: number;
3
- isActive: boolean;
4
- isSoldOut: boolean;
5
- isNew: boolean;
6
- createdAt: string;
7
- updatedAt: string;
8
- masterKey: string;
9
- referenceKey: string;
10
- firstLiveAt: string;
11
- attributes: {
12
- color: {
13
- id: number;
14
- key: string;
15
- label: string;
16
- type: string;
17
- multiSelect: boolean;
18
- values: {
19
- id: number;
20
- label: string;
21
- value: string;
22
- };
23
- };
24
- brand: {
25
- id: number;
26
- key: string;
27
- label: string;
28
- type: string;
29
- multiSelect: boolean;
30
- values: {
31
- id: number;
32
- label: string;
33
- value: string;
34
- };
35
- };
36
- name: {
37
- id: number;
38
- key: string;
39
- label: string;
40
- type: null;
41
- multiSelect: boolean;
42
- values: {
43
- label: string;
44
- };
45
- };
46
- };
47
- lowestPriorPrice: {
48
- withTax: null;
49
- relativeDifferenceToPrice: null;
50
- };
51
- images: {
52
- hash: string;
53
- attributes: {};
54
- }[];
55
- variants: {
56
- id: number;
57
- referenceKey: string;
58
- firstLiveAt: string;
59
- createdAt: string;
60
- updatedAt: string;
61
- price: {
62
- currencyCode: string;
63
- withTax: number;
64
- withoutTax: number;
65
- appliedReductions: never[];
66
- recommendedRetailPrice: null;
67
- tax: {
68
- vat: {
69
- amount: number;
70
- rate: number;
71
- };
72
- };
73
- };
74
- stock: {
75
- supplierId: number;
76
- warehouseId: number;
77
- quantity: number;
78
- isSellableWithoutStock: boolean;
79
- };
80
- attributes: {
81
- shopSize: {
82
- id: number;
83
- key: string;
84
- label: string;
85
- type: string;
86
- multiSelect: boolean;
87
- values: {
88
- id: number;
89
- label: string;
90
- value: string;
91
- };
92
- };
93
- };
94
- }[];
95
- siblings: never[];
96
- priceRange: {
97
- min: {
98
- currencyCode: string;
99
- withTax: number;
100
- withoutTax: number;
101
- appliedReductions: never[];
102
- recommendedRetailPrice: null;
103
- tax: {
104
- vat: {
105
- amount: number;
106
- rate: number;
107
- };
108
- };
109
- };
110
- max: {
111
- currencyCode: string;
112
- withTax: number;
113
- withoutTax: number;
114
- appliedReductions: never[];
115
- recommendedRetailPrice: null;
116
- tax: {
117
- vat: {
118
- amount: number;
119
- rate: number;
120
- };
121
- };
122
- };
123
- };
124
- categories: {
125
- categoryId: number;
126
- categoryName: string;
127
- categorySlug: string;
128
- categoryUrl: string;
129
- categoryHidden: boolean;
130
- categoryProperties: never[];
131
- }[][];
132
- };
133
- export declare const productFromEDT: {
134
- id: number;
135
- isActive: boolean;
136
- isSoldOut: boolean;
137
- isNew: boolean;
138
- createdAt: string;
139
- updatedAt: string;
140
- masterKey: string;
141
- referenceKey: string;
142
- firstLiveAt: string;
143
- attributes: {
144
- brand: {
145
- id: number;
146
- key: string;
147
- label: string;
148
- type: string;
149
- multiSelect: boolean;
150
- values: {
151
- id: number;
152
- label: string;
153
- value: string;
154
- };
155
- };
156
- colorDetail: {
157
- id: number;
158
- key: string;
159
- label: string;
160
- type: string;
161
- multiSelect: boolean;
162
- values: {
163
- id: number;
164
- label: string;
165
- value: string;
166
- }[];
167
- };
168
- name: {
169
- id: number;
170
- key: string;
171
- label: string;
172
- type: string;
173
- multiSelect: boolean;
174
- values: {
175
- id: number;
176
- label: string;
177
- value: string;
178
- };
179
- };
180
- };
181
- lowestPriorPrice: {
182
- withTax: null;
183
- relativeDifferenceToPrice: null;
184
- };
185
- images: ({
186
- hash: string;
187
- attributes: {
188
- imageBackground: {
189
- id: number;
190
- key: string;
191
- label: string;
192
- type: string;
193
- multiSelect: boolean;
194
- values: {
195
- id: number;
196
- label: string;
197
- value: string;
198
- };
199
- };
200
- imageKind: {
201
- id: number;
202
- key: string;
203
- label: string;
204
- type: string;
205
- multiSelect: boolean;
206
- values: {
207
- id: number;
208
- label: string;
209
- value: string;
210
- };
211
- };
212
- imageView: {
213
- id: number;
214
- key: string;
215
- label: string;
216
- type: string;
217
- multiSelect: boolean;
218
- values: {
219
- id: number;
220
- label: string;
221
- value: string;
222
- };
223
- };
224
- imageType: {
225
- id: number;
226
- key: string;
227
- label: string;
228
- type: string;
229
- multiSelect: boolean;
230
- values: {
231
- id: number;
232
- label: string;
233
- value: string;
234
- };
235
- };
236
- };
237
- } | {
238
- hash: string;
239
- attributes: {
240
- imageBackground: {
241
- id: number;
242
- key: string;
243
- label: string;
244
- type: string;
245
- multiSelect: boolean;
246
- values: {
247
- id: number;
248
- label: string;
249
- value: string;
250
- };
251
- };
252
- imageKind: {
253
- id: number;
254
- key: string;
255
- label: string;
256
- type: string;
257
- multiSelect: boolean;
258
- values: {
259
- id: number;
260
- label: string;
261
- value: string;
262
- };
263
- };
264
- imageType: {
265
- id: number;
266
- key: string;
267
- label: string;
268
- type: string;
269
- multiSelect: boolean;
270
- values: {
271
- id: number;
272
- label: string;
273
- value: string;
274
- };
275
- };
276
- imageView?: undefined;
277
- };
278
- })[];
279
- variants: {
280
- id: number;
281
- referenceKey: string;
282
- firstLiveAt: string;
283
- createdAt: string;
284
- updatedAt: string;
285
- price: {
286
- currencyCode: string;
287
- withTax: number;
288
- withoutTax: number;
289
- appliedReductions: {
290
- category: string;
291
- type: string;
292
- amount: {
293
- relative: number;
294
- absoluteWithTax: number;
295
- };
296
- }[];
297
- recommendedRetailPrice: null;
298
- tax: {
299
- vat: {
300
- amount: number;
301
- rate: number;
302
- };
303
- };
304
- };
305
- stock: {
306
- supplierId: number;
307
- warehouseId: number;
308
- quantity: number;
309
- isSellableWithoutStock: boolean;
310
- };
311
- attributes: {};
312
- advancedAttributes: {
313
- variantCrosssellings: {
314
- id: number;
315
- key: string;
316
- label: string;
317
- type: string;
318
- values: {
319
- fieldSet: {
320
- value: string;
321
- }[][];
322
- groupSet: never[];
323
- }[];
324
- };
325
- };
326
- lowestPriorPrice: {
327
- withTax: null;
328
- relativeDifferenceToPrice: null;
329
- };
330
- }[];
331
- siblings: never[];
332
- priceRange: {
333
- min: {
334
- currencyCode: string;
335
- withTax: number;
336
- withoutTax: number;
337
- appliedReductions: {
338
- category: string;
339
- type: string;
340
- amount: {
341
- relative: number;
342
- absoluteWithTax: number;
343
- };
344
- }[];
345
- recommendedRetailPrice: null;
346
- tax: {
347
- vat: {
348
- amount: number;
349
- rate: number;
350
- };
351
- };
352
- };
353
- max: {
354
- currencyCode: string;
355
- withTax: number;
356
- withoutTax: number;
357
- appliedReductions: {
358
- category: string;
359
- type: string;
360
- amount: {
361
- relative: number;
362
- absoluteWithTax: number;
363
- };
364
- }[];
365
- recommendedRetailPrice: null;
366
- tax: {
367
- vat: {
368
- amount: number;
369
- rate: number;
370
- };
371
- };
372
- };
373
- };
374
- categories: {
375
- categoryId: number;
376
- categoryName: string;
377
- categorySlug: string;
378
- categoryUrl: string;
379
- categoryHidden: boolean;
380
- categoryProperties: never[];
381
- }[][];
382
- };
383
- export declare const priceFixture: {
384
- currencyCode: string;
385
- withTax: number;
386
- withoutTax: number;
387
- appliedReductions: never[];
388
- recommendedRetailPrice: null;
389
- tax: {
390
- vat: {
391
- amount: number;
392
- rate: number;
393
- };
394
- };
395
- };
396
- export declare const priceFixtureWithReductions: {
397
- currencyCode: string;
398
- withTax: number;
399
- withoutTax: number;
400
- appliedReductions: {
401
- category: string;
402
- type: string;
403
- amount: {
404
- relative: number;
405
- absoluteWithTax: number;
406
- };
407
- }[];
408
- recommendedRetailPrice: null;
409
- tax: {
410
- vat: {
411
- amount: number;
412
- rate: number;
413
- };
414
- };
415
- };