@scayle/storefront-nuxt 8.61.0 โ†’ 8.61.2

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 (42) hide show
  1. package/CHANGELOG-V7.md +3 -11
  2. package/CHANGELOG.md +240 -255
  3. package/dist/module.json +1 -1
  4. package/dist/module.mjs +95 -39
  5. package/dist/runtime/api/rpcHandler.js +1 -4
  6. package/dist/runtime/cached.js +1 -6
  7. package/dist/runtime/campaignKey.js +15 -15
  8. package/dist/runtime/composables/core/useIDP.js +11 -13
  9. package/dist/runtime/composables/core/useSession.js +1 -3
  10. package/dist/runtime/composables/core/useUser.js +24 -30
  11. package/dist/runtime/composables/storefront/useBasket.d.ts +1 -1
  12. package/dist/runtime/composables/storefront/useBasket.js +32 -45
  13. package/dist/runtime/composables/storefront/useBrand.js +1 -6
  14. package/dist/runtime/composables/storefront/useBrands.js +1 -6
  15. package/dist/runtime/composables/storefront/useCampaign.js +1 -6
  16. package/dist/runtime/composables/storefront/useCategories.js +12 -19
  17. package/dist/runtime/composables/storefront/useCategoryById.js +1 -6
  18. package/dist/runtime/composables/storefront/useCategoryByPath.js +1 -6
  19. package/dist/runtime/composables/storefront/useCurrentPromotions.js +7 -12
  20. package/dist/runtime/composables/storefront/useFilters.js +1 -6
  21. package/dist/runtime/composables/storefront/useNavigationTree.js +2 -12
  22. package/dist/runtime/composables/storefront/useNavigationTrees.js +1 -6
  23. package/dist/runtime/composables/storefront/useProduct.js +1 -6
  24. package/dist/runtime/composables/storefront/useProducts.js +1 -6
  25. package/dist/runtime/composables/storefront/useProductsByIds.js +1 -6
  26. package/dist/runtime/composables/storefront/useProductsByReferenceKeys.js +1 -6
  27. package/dist/runtime/composables/storefront/useProductsCount.js +1 -6
  28. package/dist/runtime/composables/storefront/usePromotions.js +1 -6
  29. package/dist/runtime/composables/storefront/usePromotionsByIds.js +1 -6
  30. package/dist/runtime/composables/storefront/useShopConfiguration.js +1 -6
  31. package/dist/runtime/composables/storefront/useUserAddresses.js +1 -6
  32. package/dist/runtime/composables/storefront/useVariant.js +1 -6
  33. package/dist/runtime/composables/storefront/useWishlist.d.ts +1 -1
  34. package/dist/runtime/composables/storefront/useWishlist.js +11 -25
  35. package/dist/runtime/context.js +2 -10
  36. package/dist/runtime/nitro/plugins/configValidation.js +6 -4
  37. package/dist/runtime/nitro/plugins/nitroStorageConfig.js +1 -4
  38. package/dist/runtime/server/middleware/bootstrap.js +3 -14
  39. package/dist/runtime/server/middleware/redirects.js +1 -3
  40. package/dist/runtime/utils/storage.js +1 -4
  41. package/dist/runtime/utils/zodSchema.js +33 -25
  42. package/package.json +9 -8
package/CHANGELOG.md CHANGED
@@ -1,5 +1,39 @@
1
1
  # @scayle/storefront-nuxt
2
2
 
3
+ ## 8.61.2
4
+
5
+ ### Patch Changes
6
+
7
+ - Improved build-time loading of custom RPC modules when generating the
8
+ `#virtual/rpcHttpMethods` manifest so Nuxt string aliases (for example `#shared`) resolve the same way
9
+ as in app code during HTTP verb inference.
10
+ - Resolved aliases from `@nuxt/kit` `resolvePath` (including virtual templates)
11
+ are passed to Jiti together with an app-root parent URL so imports inside `rpcMethods` match dev
12
+ behavior.
13
+ - If a module still cannot be resolved or imported, those methods continue to default to `POST` with a
14
+ logged warning.
15
+
16
+ - Added dependency `jiti@^2.6.1`
17
+
18
+ **Dependencies**
19
+
20
+ **@scayle/storefront-core v8.61.2**
21
+
22
+ - No changes in this release.
23
+
24
+ ## 8.61.1
25
+
26
+ ### Patch Changes
27
+
28
+ - Updated to `@scayle/unstorage-compression-driver@1.5.0`.
29
+ New optional params option on `CompressionDriverOptions` (and matching third arg on compress/decompress) is forwarded verbatim to the underlying `zlib` call. Brotli encoding now defaults to `BROTLI_PARAM_QUALITY: 6` when no params are supplied, resulting in same compression ratio as the prior implicit quality `11` default at ~300x the encode speed, removing up to several hundred ms of CPU per cold cache write on payloads in the hundreds of KB. Decompression of pre-existing entries is unaffected.
30
+
31
+ **Dependencies**
32
+
33
+ **@scayle/storefront-core v8.61.1**
34
+
35
+ - No changes in this release.
36
+
3
37
  ## 8.61.0
4
38
 
5
39
  ### Minor Changes
@@ -10,13 +44,13 @@
10
44
 
11
45
  ```ts
12
46
  // Safe reads โ€” eligible for CDN / browser caching
13
- export const getNavigation = defineRpcHandler(handler, { method: "GET" });
47
+ export const getNavigation = defineRpcHandler(handler, { method: 'GET' })
14
48
 
15
49
  // Mutations
16
- export const updateBasketItem = defineRpcHandler(handler, { method: "PUT" });
50
+ export const updateBasketItem = defineRpcHandler(handler, { method: 'PUT' })
17
51
  export const deleteWishlistItem = defineRpcHandler(handler, {
18
- method: "DELETE",
19
- });
52
+ method: 'DELETE',
53
+ })
20
54
  ```
21
55
 
22
56
  RPCs returning user-specific data (basket, wishlist, tokens) should stay on `POST` to prevent unintended caching.
@@ -30,29 +64,28 @@
30
64
  **@scayle/storefront-core v8.61.0**
31
65
 
32
66
  - Minor
33
-
34
67
  - **[RPC]** `defineRpcHandler` now accepts an optional `method` option (`'GET' | 'POST' | 'PUT' | 'DELETE'`) to declare the HTTP method for the handler. Defaults to `'POST'`, so existing handlers behave exactly as before. Updated built-in RPC methods to use `GET` for safe, cacheable reads and `PUT`/`POST`/`DELETE` for mutations, enabling CDN and browser caching for public data fetches.
35
68
 
36
69
  User- and session-specific RPCs (`getBasket`, `getUser`, `fetchUser`, `getWishlist`, `getAccessToken`, `getCheckoutToken`, `getOrderById`, `getCheckoutDataByCbd`, `getShopUserAddress`) intentionally stay on `POST` so their responses are never eligible for CDN or browser caching.
37
70
 
38
71
  ```ts
39
- import { defineRpcHandler, type RpcContext } from "@scayle/storefront-core";
72
+ import { defineRpcHandler, type RpcContext } from '@scayle/storefront-core'
40
73
 
41
74
  // Safe, public read โ€” eligible for CDN/browser caching
42
75
  export const getNavigation = defineRpcHandler(
43
76
  async (context: RpcContext) => {
44
77
  /* ... */
45
78
  },
46
- { method: "GET" }
47
- );
79
+ { method: 'GET' },
80
+ )
48
81
 
49
82
  // User-specific / Mutation โ€” uses POST to prevent cache leakage
50
83
  export const getBasket = defineRpcHandler(
51
84
  async (context: RpcContext) => {
52
85
  /* ... */
53
- }
86
+ },
54
87
  // method defaults to 'POST'
55
- );
88
+ )
56
89
  ```
57
90
 
58
91
  - Patch
@@ -84,7 +117,6 @@
84
117
  **@scayle/storefront-core v8.60.0**
85
118
 
86
119
  - Minor
87
-
88
120
  - All packages now require Node.js 22 or later, in line with the current Node.js LTS release schedule. See the [Node.js release schedule](https://nodejs.org/en/about/previous-releases#release-schedule) for details.
89
121
 
90
122
  If your project is still running an older Node.js version, now is a good time to upgrade to Node.js 22 at minimum, or ideally Node.js 24, for the latest security patches and stability improvements.
@@ -138,7 +170,6 @@
138
170
  **@scayle/storefront-core v8.59.4**
139
171
 
140
172
  - Patch
141
-
142
173
  - Fixed error handling in `oauthRegister` and other OAuth-related RPC methods to properly propagate HTTP status codes like 409 Conflict instead of converting them to 500 Internal Server Error.
143
174
 
144
175
  The `convertErrorForRpcCall` function now correctly handles `OAuthRequestError` instances that wrap `FetchError` objects. Previously, when OAuth API errors occurred (such as attempting to register with an existing email), the error handling only checked for direct `FetchError` instances, causing wrapped errors to fall through to a generic 500 error response. Now the function extracts the underlying `FetchError` from `OAuthRequestError` instances, ensuring that the correct HTTP status codes are returned to the frontend.
@@ -166,7 +197,6 @@
166
197
  **@scayle/storefront-core v8.59.2**
167
198
 
168
199
  - Patch
169
-
170
200
  - Deprecated the `slugify` and `getProductPath` functions in `productHelpers.ts` due to compatibility issues with Nuxt 4.
171
201
 
172
202
  To maintain compatibility with Nuxt 4, these functions have been deprecated. Developers should migrate to using `useRouteHelpers().slugify()` instead. Additionally, the `slugify` package must be added as a direct dependency in your Storefront Application.
@@ -174,33 +204,33 @@
174
204
  **Migration:**
175
205
 
176
206
  ```ts
177
- import baseSlugify from "slugify";
207
+ import baseSlugify from 'slugify'
178
208
 
179
209
  const slugify = (url: string | undefined): string => {
180
- return baseSlugify(url ?? "", {
210
+ return baseSlugify(url ?? '', {
181
211
  lower: true,
182
212
  remove: /[*+~.()'"!:@/#?]/g,
183
- });
184
- };
213
+ })
214
+ }
185
215
 
186
- const localePath = useLocalePath();
216
+ const localePath = useLocalePath()
187
217
 
188
218
  const getProductDetailRoute = (
189
219
  id: number,
190
220
  name?: string,
191
- locale?: Locale
221
+ locale?: Locale,
192
222
  ): string => {
193
223
  return localePath(
194
224
  {
195
- name: "p-productName-id",
225
+ name: 'p-productName-id',
196
226
  params: {
197
227
  productName: slugify(name),
198
228
  id: `${id}`,
199
229
  },
200
230
  },
201
- locale
202
- );
203
- };
231
+ locale,
232
+ )
233
+ }
204
234
  ```
205
235
 
206
236
  ## 8.59.1
@@ -215,7 +245,6 @@
215
245
  **@scayle/storefront-core v8.59.1**
216
246
 
217
247
  - Patch
218
-
219
248
  - Fixed import compatibility issue with the `slugify` package in `productHelpers.ts` to support both ESM and CommonJS module formats.
220
249
 
221
250
  The import was changed from a default import to a namespace import with a fallback, ensuring the `baseSlugify` function works correctly across different module systems and build configurations.
@@ -239,7 +268,6 @@
239
268
 
240
269
  - Introduced support for Nuxt 4 while maintaining full backward compatibility with Nuxt 3.
241
270
  This enables consumers to migrate to Nuxt 4 ahead of the Nuxt 3 end of support on 31 Jan 2026.
242
-
243
271
  - **Version Requirements:**
244
272
  - Nuxt 3: `v3.13.0+`
245
273
  - Nuxt 4: `v4.2.0+`
@@ -323,11 +351,9 @@
323
351
  **@scayle/storefront-core v8.57.0**
324
352
 
325
353
  - Minor
326
-
327
354
  - **\[Navigation\]** Exported Navigation V2 API types to provide TypeScript support for the new navigation endpoints.
328
355
 
329
356
  The following types are now available from `@scayle/storefront-core`:
330
-
331
357
  - `GetNavigationV2Parameters` - Parameters for fetching navigation trees via the V2 API
332
358
  - `NavigationV2AllEndpointResponseData` - Response type for fetching all navigation trees
333
359
  - `NavigationV2ByReferenceEndpointResponseData` - Response type for fetching a navigation tree by reference key
@@ -343,7 +369,6 @@
343
369
  The `RpcContext` now exposes a `sessionCustomData` property to read custom session data and an `updateSessionCustomData` method to update it.
344
370
  The `sessionCustomData` property may be `undefined` when no session exists or when no custom data has been set.
345
371
  The `SessionCustomData` interface can be augmented with TypeScript module augmentation to provide type safety for custom session properties.
346
-
347
372
  - **Type Augmentation Example:**
348
373
 
349
374
  ```ts
@@ -361,39 +386,39 @@
361
386
 
362
387
  ```ts
363
388
  // server/plugins/session-plugin.ts
364
- import { hasSession } from "@scayle/storefront-nuxt";
365
- import { defineNitroPlugin } from "#imports";
389
+ import { hasSession } from '@scayle/storefront-nuxt'
390
+ import { defineNitroPlugin } from '#imports'
366
391
 
367
392
  export default defineNitroPlugin((nitroApp) => {
368
- nitroApp.hooks.hook("storefront:afterLogin", async (_data, context) => {
393
+ nitroApp.hooks.hook('storefront:afterLogin', async (_data, context) => {
369
394
  // Check if we actually have a RpcContext with proper session data
370
395
  if (!hasSession(context)) {
371
- return;
396
+ return
372
397
  }
373
398
 
374
399
  // Should you have set custom session data already in another hook,
375
400
  // it might be necessary to get existing data first.
376
- const sessionCustomData = context.sessionCustomData;
401
+ const sessionCustomData = context.sessionCustomData
377
402
 
378
403
  // The update functions overrides the customData object on a session.
379
404
  // Should you have set custom session data already in another hooks,
380
405
  // you need to pass it in addition to your new custom session data.
381
406
  context.updateSessionCustomData({
382
407
  ...sessionCustomData,
383
- yourCustomDataKey: "Your Session CustomData Value",
384
- });
408
+ yourCustomDataKey: 'Your Session CustomData Value',
409
+ })
385
410
 
386
411
  // Before accessing your session custom data, you might want to use an
387
412
  // explicit early return conditional.
388
413
  if (!sessionCustomData) {
389
- return;
414
+ return
390
415
  }
391
416
 
392
417
  // Your custom session data can also be accessedd directly via
393
418
  // nullish coalescing depending on your needs.
394
- console.log(context.sessionCustomData?.yourCustomDataKey);
395
- });
396
- });
419
+ console.log(context.sessionCustomData?.yourCustomDataKey)
420
+ })
421
+ })
397
422
  ```
398
423
 
399
424
  ### Patch Changes
@@ -405,7 +430,6 @@
405
430
  **@scayle/storefront-core v8.56.0**
406
431
 
407
432
  - Minor
408
-
409
433
  - Added support for custom session data in the RPC context type definitions.
410
434
 
411
435
  The `ContextWithSession` interface now includes a `sessionCustomData` property (which may be `undefined`) to read custom session data and an `updateSessionCustomData` method to update it.
@@ -447,26 +471,25 @@
447
471
  - Enhanced data fetching composables to support reactive keys, aligning with [Nuxt 3.17 data fetching improvements](https://nuxt.com/blog/v3-17#data-fetching-improvements).
448
472
 
449
473
  You can now pass a `ref`, `computed`, or getter function as the `key` parameter to `useRpc` and derived composables (like `useProducts`, `useBrand` etc.). When the reactive key changes, the data will automatically re-fetch.
450
-
451
474
  - **Before:** Keys were static strings.
452
475
  - **After:** Keys can be reactive, enabling dynamic caching and automatic updates.
453
476
 
454
477
  ```ts
455
478
  // Before
456
- const { data } = await useRpc("getProduct", "my-static-product-key", {
479
+ const { data } = await useRpc('getProduct', 'my-static-product-key', {
457
480
  productId: 123,
458
- });
481
+ })
459
482
 
460
483
  // After
461
- const productId = ref(123);
484
+ const productId = ref(123)
462
485
 
463
486
  // The key is now reactive. If `productId` changes, the key updates
464
487
  // to 'product-456' (for example) and triggers a new fetch.
465
488
  const { data } = await useRpc(
466
- "getProduct",
489
+ 'getProduct',
467
490
  () => `product-${productId.value}`,
468
- { productId }
469
- );
491
+ { productId },
492
+ )
470
493
  ```
471
494
 
472
495
  - Deprecated the `CheckoutEvent` type, which will be removed in the next major version.
@@ -478,22 +501,22 @@
478
501
  The type definition remains unchanged, so you can copy it directly:
479
502
 
480
503
  ```ts
481
- import type { ShopUser } from "@scayle/storefront-nuxt";
504
+ import type { ShopUser } from '@scayle/storefront-nuxt'
482
505
 
483
506
  export interface CheckoutEvent {
484
507
  /** Action. */
485
- action?: "authenticated";
508
+ action?: 'authenticated'
486
509
  /** Type. */
487
- type?: "tracking";
510
+ type?: 'tracking'
488
511
  /** User. */
489
- user: ShopUser;
512
+ user: ShopUser
490
513
  /**
491
514
  * The OAuth 2.0 access token for the authenticated user.
492
515
  * This token can be used to access protected resources on behalf of the user.
493
516
  *
494
517
  * @see https://www.rfc-editor.org/rfc/rfc6749
495
518
  */
496
- accessToken: string;
519
+ accessToken: string
497
520
  /**
498
521
  * Details about a specific event within the checkout process.
499
522
  * This field is optional and is only used when tracking specific actions
@@ -503,25 +526,25 @@
503
526
  */
504
527
  event?: {
505
528
  /** Event name. */
506
- event: "login" | "add_to_cart" | "remove_from_cart";
529
+ event: 'login' | 'add_to_cart' | 'remove_from_cart'
507
530
  /** Event status. */
508
- status: "successful" | "error";
509
- };
531
+ status: 'successful' | 'error'
532
+ }
510
533
  }
511
534
  ```
512
535
 
513
536
  - Updated the `StorefrontRuntimeConfig` type to ensure configured `shops` correctly incorporates all extended properties from `AdditionalShopConfig`.
514
537
 
515
538
  ```ts
516
- declare module "@scayle/storefront-nuxt" {
539
+ declare module '@scayle/storefront-nuxt' {
517
540
  // Extend the shop config
518
541
  export interface AdditionalShopConfig {
519
- extendedProp: string;
542
+ extendedProp: string
520
543
  }
521
544
  }
522
545
 
523
546
  // `extendedProp` is now properly typed
524
- useRuntimeConfig().storefront.shops?.[shopId]?.extendedProp;
547
+ useRuntimeConfig().storefront.shops?.[shopId]?.extendedProp
525
548
  ```
526
549
 
527
550
  **Dependencies**
@@ -541,11 +564,11 @@
541
564
  ```ts
542
565
  // Before (or when `rpcDefaultLazy: false`)
543
566
  // You had to explicitly opt-in to lazy behavior
544
- const { data } = useRpc("someMethod", { some: "param" }, { lazy: true });
567
+ const { data } = useRpc('someMethod', { some: 'param' }, { lazy: true })
545
568
 
546
569
  // After (when `rpcDefaultLazy: true`)
547
570
  // Lazy behavior is now the default
548
- const { data } = useRpc("someMethod", { some: "param" });
571
+ const { data } = useRpc('someMethod', { some: 'param' })
549
572
  ```
550
573
 
551
574
  **Dependencies**
@@ -578,7 +601,6 @@
578
601
  **@scayle/storefront-core v8.53.0**
579
602
 
580
603
  - Minor
581
-
582
604
  - Added support for promotions on order items by introducing the `OrderItemPromotion` interface and extending the `OrderItem` type with an optional `promotions` field.
583
605
 
584
606
  This enables developers to access promotion information (`id`, `name`, and `version`) directly from order items, improving visibility into which promotions were applied to each item in an order.
@@ -608,7 +630,6 @@
608
630
  **@scayle/storefront-core v8.51.0**
609
631
 
610
632
  - Minor
611
-
612
633
  - Added an email hash (`emailHash`) property to the user object returned by the `fetchUser` RPC method.
613
634
 
614
635
  The `emailHash` property is automatically included in all user objects returned by the RPCs.
@@ -620,7 +641,6 @@
620
641
  ### Minor Changes
621
642
 
622
643
  - Introduced validation for domain configuration when `shopSelector: 'domain'` is enabled. This ensures that any domain-related misconfigurations are detected early during development. The validation requires the use of `@nuxtjs/i18n` and includes the following checks:
623
-
624
644
  - Ensures every shop has a domain property configured
625
645
  - Verifies that domains configured in the shop config are also present in the `@nuxtjs/i18n` configuration
626
646
  - Checks that all domains in the i18n configuration are unique (no duplicates)
@@ -648,7 +668,6 @@
648
668
  **@scayle/storefront-core v8.49.0**
649
669
 
650
670
  - Minor
651
-
652
671
  - Exported the `sha256` utility function as part of the public API.
653
672
 
654
673
  This function provides a convenient way to calculate SHA256 hashes of strings using the Web Crypto API, returning hexadecimal strings.
@@ -657,10 +676,10 @@
657
676
  Example:
658
677
 
659
678
  ```ts
660
- import { sha256 } from "@scayle/storefront-core";
679
+ import { sha256 } from '@scayle/storefront-core'
661
680
 
662
- const hash = await sha256("hello");
663
- console.log(hash); // '2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824'
681
+ const hash = await sha256('hello')
682
+ console.log(hash) // '2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824'
664
683
  ```
665
684
 
666
685
  ## 8.48.1
@@ -674,11 +693,9 @@
674
693
  **@scayle/storefront-core v8.48.1**
675
694
 
676
695
  - Patch
677
-
678
696
  - Export `SmartSortingKey` constant containing all predefined smart sorting keys for intelligent product sorting. Smart sorting keys provide advanced sorting algorithms that consider multiple factors like discounts, inventory levels, sales performance, and recency to optimize product listings.
679
697
 
680
698
  Available keys:
681
-
682
699
  - `SmartSortingKey.SALES_PUSH` - Promotes items with highest discounts and oldest inventory
683
700
  - `SmartSortingKey.NEW_ARRIVALS` - Prioritizes recently added products with good availability
684
701
  - `SmartSortingKey.BALANCED_OFFERINGS` - Balances recency, availability, discounts, and sales data
@@ -721,7 +738,6 @@
721
738
  **@scayle/storefront-core v8.47.0**
722
739
 
723
740
  - Minor
724
-
725
741
  - Enhanced basket RPC methods to support order custom data functionality.
726
742
 
727
743
  All basket RPC methods now integrate with the `getOrderCustomData` RPC method to fetch and include order custom data in SAPI requests.
@@ -740,12 +756,11 @@
740
756
  customer: {
741
757
  groups: context.user?.groups,
742
758
  },
743
- };
744
- });
759
+ }
760
+ })
745
761
  ```
746
762
 
747
763
  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).
748
-
749
764
  - Updated all basket RPC methods to pass the customer access token to the SAPI client, enabling the `X-Customer-Token` header for promotion validation.
750
765
 
751
766
  The customer access token is now automatically included in basket requests when available.
@@ -762,7 +777,6 @@
762
777
  **@scayle/storefront-core v8.46.0**
763
778
 
764
779
  - Minor
765
-
766
780
  - Added `getAttributeValuesByGroupId` function to the `attributeHelpers` helper for retrieving attribute values by their numeric attribute group ID.
767
781
 
768
782
  This function allows you to retrieve attribute values filtered by a specific attribute group ID, providing a more targeted approach when working with grouped product attributes.
@@ -775,37 +789,36 @@
775
789
  #### Looking up by name (existing, now renamed):
776
790
 
777
791
  ```typescript
778
- import { getAttributeValuesByName } from "@scayle/storefront-core";
792
+ import { getAttributeValuesByName } from '@scayle/storefront-core'
779
793
 
780
794
  // Single-select attribute
781
- const sizes = getAttributeValuesByName(product.attributes, "size");
795
+ const sizes = getAttributeValuesByName(product.attributes, 'size')
782
796
  // Returns: [{ id: 1, label: 'M', value: 'medium' }]
783
797
 
784
798
  // Multi-select attribute
785
- const colors = getAttributeValuesByName(product.attributes, "color");
799
+ const colors = getAttributeValuesByName(product.attributes, 'color')
786
800
  // Returns: [{ id: 1, label: 'Red' }, { id: 2, label: 'Blue' }]
787
801
 
788
802
  // Non-existent attribute
789
- const missing = getAttributeValuesByName(product.attributes, "doesNotExist");
803
+ const missing = getAttributeValuesByName(product.attributes, 'doesNotExist')
790
804
  // Returns: []
791
805
  ```
792
806
 
793
807
  #### Looking up by group ID (new):
794
808
 
795
809
  ```typescript
796
- import { getAttributeValuesByGroupId } from "@scayle/storefront-core";
810
+ import { getAttributeValuesByGroupId } from '@scayle/storefront-core'
797
811
 
798
812
  // Look up attribute by its numeric ID from the SCAYLE API
799
- const promotionValues = getAttributeValuesByGroupId(product.attributes, 42);
813
+ const promotionValues = getAttributeValuesByGroupId(product.attributes, 42)
800
814
  // Returns: [{ id: 123, label: 'Summer Sale', value: 'summer-2024' }]
801
815
 
802
816
  // Non-existent attribute group
803
- const missing = getAttributeValuesByGroupId(product.attributes, 9999);
817
+ const missing = getAttributeValuesByGroupId(product.attributes, 9999)
804
818
  // Returns: []
805
819
  ```
806
820
 
807
821
  ### When to Use Each Function
808
-
809
822
  - **`getAttributeValuesByName`**: Use when you know the attribute name key (e.g., 'color', 'size'). This is the most common use case in application code.
810
823
  - **`getAttributeValuesByGroupId`**: Use when you have the numeric attribute group ID from the SCAYLE API, such as when processing API configurations, handling dynamic attribute mappings, or working with attribute group references.
811
824
 
@@ -863,27 +876,27 @@
863
876
  // nuxt.config.ts
864
877
  export default defineNuxtConfig({
865
878
  storefront: {
866
- apiBasePath: "/custom-api", // โœ… Configure globally for all shops
879
+ apiBasePath: '/custom-api', // โœ… Configure globally for all shops
867
880
  },
868
881
  runtimeConfig: {
869
882
  storefront: {
870
883
  shops: {
871
884
  1001: {
872
885
  shopId: 1001,
873
- path: "de",
886
+ path: 'de',
874
887
  // โœ… apiBasePath removed from shop config
875
888
  // ... other shop config
876
889
  },
877
890
  1002: {
878
891
  shopId: 1002,
879
- path: "en",
892
+ path: 'en',
880
893
  // โœ… apiBasePath removed from shop config
881
894
  // ... other shop config
882
895
  },
883
896
  },
884
897
  },
885
898
  },
886
- });
899
+ })
887
900
  ```
888
901
 
889
902
  Additionally, the types for the Storefront module options and Storefront runtime configuration have been cleaned up to properly reflect which settings can be set at runtime and which cannot. This clarifies the distinction between configuration that is static (set at build/module level) and configuration that is dynamic (set at runtime), improving type safety and developer experience.
@@ -990,7 +1003,6 @@
990
1003
  **@scayle/storefront-core v8.43.0**
991
1004
 
992
1005
  - Minor
993
-
994
1006
  - Added an export of the new promotion type `ComboDealEffect`
995
1007
 
996
1008
  This type is also included in the `PromotionEffectType` type and can be used to check if the promotion is of type `ComboDealEffect`.
@@ -999,10 +1011,10 @@
999
1011
 
1000
1012
  ```ts
1001
1013
  const isComboDealType = (
1002
- promotion?: Promotion | null
1014
+ promotion?: Promotion | null,
1003
1015
  ): promotion is Promotion<ComboDealEffect> => {
1004
- return promotion?.effect?.type === PromotionEffectType.COMBO_DEAL;
1005
- };
1016
+ return promotion?.effect?.type === PromotionEffectType.COMBO_DEAL
1017
+ }
1006
1018
  ```
1007
1019
 
1008
1020
  ## 8.42.2
@@ -1066,68 +1078,68 @@
1066
1078
  Before:
1067
1079
 
1068
1080
  ```ts
1069
- const updateBasketItemRpc = useRpcCall("updateBasketItem");
1070
- const addItemToBasketRpc = useRpcCall("addItemToBasket");
1081
+ const updateBasketItemRpc = useRpcCall('updateBasketItem')
1082
+ const addItemToBasketRpc = useRpcCall('addItemToBasket')
1071
1083
 
1072
1084
  updateBasketItemRpc({
1073
1085
  // ...
1074
- promotionId: "promotionId",
1075
- promotionCode: "promotionCode",
1076
- });
1086
+ promotionId: 'promotionId',
1087
+ promotionCode: 'promotionCode',
1088
+ })
1077
1089
 
1078
1090
  addItemToBasketRpc({
1079
1091
  // ...
1080
- promotionId: "promotionId",
1081
- promotionCode: "promotionCode",
1082
- });
1092
+ promotionId: 'promotionId',
1093
+ promotionCode: 'promotionCode',
1094
+ })
1083
1095
 
1084
1096
  // Or with useBasket composable
1085
1097
 
1086
- const { addItem } = useBasket();
1098
+ const { addItem } = useBasket()
1087
1099
  addItem({
1088
1100
  // ...
1089
- promotionId: "promotionId",
1090
- });
1101
+ promotionId: 'promotionId',
1102
+ })
1091
1103
  ```
1092
1104
 
1093
1105
  After:
1094
1106
 
1095
1107
  ```ts
1096
- const updateBasketItemRpc = useRpcCall("updateBasketItem");
1097
- const addItemToBasketRpc = useRpcCall("addItemToBasket");
1108
+ const updateBasketItemRpc = useRpcCall('updateBasketItem')
1109
+ const addItemToBasketRpc = useRpcCall('addItemToBasket')
1098
1110
 
1099
1111
  updateBasketItemRpc({
1100
1112
  // ...
1101
1113
  promotions: [
1102
- { id: "promotionId", code: "promotionCode" },
1114
+ { id: 'promotionId', code: 'promotionCode' },
1103
1115
  {
1104
- id: "promotionId2",
1116
+ id: 'promotionId2',
1105
1117
  },
1106
1118
  ],
1107
- });
1119
+ })
1108
1120
 
1109
1121
  addItemToBasketRpc({
1110
1122
  // ...
1111
1123
  promotions: [
1112
- { id: "promotionId", code: "promotionCode" },
1124
+ { id: 'promotionId', code: 'promotionCode' },
1113
1125
  {
1114
- id: "promotionId2",
1126
+ id: 'promotionId2',
1115
1127
  },
1116
1128
  ],
1117
- });
1129
+ })
1118
1130
 
1119
1131
  // Or for useBasket with composable
1120
1132
 
1121
- const { addItem } = useBasket();
1133
+ const { addItem } = useBasket()
1122
1134
  addItem({
1123
1135
  // ...
1124
1136
  promotions: [
1125
- { id: "promotionId", code: "promotionCode" },
1137
+ { id: 'promotionId', code: 'promotionCode' },
1126
1138
  {
1127
- id: "promotionId2",
1139
+ id: 'promotionId2',
1128
1140
  },
1129
1141
  ],
1130
- });
1142
+ })
1131
1143
  ```
1132
1144
 
1133
1145
  For more details, see the [Add a variant](https://scayle.dev/en/api-guides/storefront-api/resources/baskets/add-a-variant) and [Update an item](https://scayle.dev/en/api-guides/storefront-api/resources/baskets/update-an-item) guides.
@@ -1139,7 +1151,6 @@
1139
1151
  **@scayle/storefront-core v8.42.0**
1140
1152
 
1141
1153
  - Minor
1142
-
1143
1154
  - Added `promotions` field to `BasketItem` type to support multiple promotions per basket item.
1144
1155
 
1145
1156
  The `promotions` field is an array of `BasketItemPromotion` objects.
@@ -1247,7 +1258,7 @@
1247
1258
  </template>
1248
1259
 
1249
1260
  <script setup lang="ts">
1250
- const { relativeReductions } = useProductPrice(price);
1261
+ const { relativeReductions } = useProductPrice(price)
1251
1262
  </script>
1252
1263
  ```
1253
1264
 
@@ -1262,7 +1273,7 @@
1262
1273
  </template>
1263
1274
 
1264
1275
  <script setup lang="ts">
1265
- const { appliedReductions } = useProductPrice(price);
1276
+ const { appliedReductions } = useProductPrice(price)
1266
1277
  </script>
1267
1278
  ```
1268
1279
 
@@ -1400,7 +1411,6 @@
1400
1411
  **@scayle/storefront-core v8.36.0**
1401
1412
 
1402
1413
  - Minor
1403
-
1404
1414
  - Created a new RPC method `getCampaign` to retrieve the first active campaign.
1405
1415
 
1406
1416
  More details can be found in the official SCAYLE Resource Center under [API Guides / Storefront API / Campaigns / List Campaigns](https://scayle.dev/en/api-guides/storefront-api/resources/campaigns/list-campaigns).
@@ -1488,7 +1498,6 @@
1488
1498
  **@scayle/storefront-core v8.33.0**
1489
1499
 
1490
1500
  - Minor
1491
-
1492
1501
  - Added test factories for order and all related types.
1493
1502
 
1494
1503
  It is now possible to build orders with factory functions for testing purposes.
@@ -1528,27 +1537,26 @@
1528
1537
  **@scayle/storefront-core v8.31.0**
1529
1538
 
1530
1539
  - Minor
1531
-
1532
1540
  - Added `minReduction` and `maxReduction` filter parameters to `FetchProductsByCategoryParams.where` and `FetchFiltersParams.where` types, and updated the `getProductsByCategory` and `getFilters` RPC methods to accept and handle these new reduction-based filtering conditions.
1533
1541
 
1534
1542
  ```ts
1535
- const { data } = useRpc("getFilters", "getFiltersKey", () => ({
1543
+ const { data } = useRpc('getFilters', 'getFiltersKey', () => ({
1536
1544
  where: {
1537
1545
  minReduction: 10,
1538
1546
  maxReduction: 20,
1539
1547
  },
1540
- }));
1548
+ }))
1541
1549
 
1542
1550
  const { data } = useRpc(
1543
- "getProductsByCategory",
1544
- "getProductsByCategoryKey",
1551
+ 'getProductsByCategory',
1552
+ 'getProductsByCategoryKey',
1545
1553
  () => ({
1546
1554
  where: {
1547
1555
  minReduction: 10,
1548
1556
  maxReduction: 20,
1549
1557
  },
1550
- })
1551
- );
1558
+ }),
1559
+ )
1552
1560
  ```
1553
1561
 
1554
1562
  ## 8.30.3
@@ -1593,35 +1601,34 @@
1593
1601
  **@scayle/storefront-core v8.30.0**
1594
1602
 
1595
1603
  - Minor
1596
-
1597
1604
  - Added `defineRpcHandler` utility function that enhances RPC handlers with type-safe metadata for improved registration and invocation of RPC handlers. While defining RPC handlers without this utility remains supported, its usage is recommended and may become mandatory in a future major release.
1598
1605
 
1599
1606
  Existing RPC handlers can be easily migrated to use `defineRpcHandler` by passing the existing handler to `defineRpcHandler`.
1600
1607
 
1601
1608
  ```ts
1602
1609
  export const existingHandlerWithoutParams = async (_context: RpcContext) => {
1603
- return "existing handler";
1604
- };
1610
+ return 'existing handler'
1611
+ }
1605
1612
 
1606
1613
  export const existingHandlerWithParams = async (
1607
1614
  { name }: { name: string },
1608
- _context: RpcContext
1615
+ _context: RpcContext,
1609
1616
  ) => {
1610
- return name;
1611
- };
1617
+ return name
1618
+ }
1612
1619
 
1613
1620
  // will become
1614
1621
 
1615
1622
  export const existingHandlerWithoutParams = defineRpcHandler(
1616
1623
  async (_context: RpcContext) => {
1617
- return "existing handler";
1618
- }
1619
- );
1624
+ return 'existing handler'
1625
+ },
1626
+ )
1620
1627
  export const existingHandlerWithParams = defineRpcHandler(
1621
1628
  async ({ name }: { name: string }, _context: RpcContext) => {
1622
- return name;
1623
- }
1624
- );
1629
+ return name
1630
+ },
1631
+ )
1625
1632
  ```
1626
1633
 
1627
1634
  - Patch
@@ -1636,22 +1643,21 @@
1636
1643
  **@scayle/storefront-core v8.29.0**
1637
1644
 
1638
1645
  - Minor
1639
-
1640
1646
  - Added an `includeProductSorting` boolean parameter to all category RPC method endpoints (`getRootCategories`, `getCategoryByPath`, `getCategoriesByPath`, `getCategoryById`, `getCategoryTree`).
1641
1647
  This flag allows consumers to retrieve product sorting data, including the `smartSortingKey` and `customSortingKey` properties.
1642
1648
  Developers can leverage this data to seamlessly apply smart sorting keys on the product listing page by passing those parameters when fetching products.
1643
1649
  - Added an optional `hideEmptyCategories` parameter to `getCategoryTree`. When enabled, the product count for each category is retrieved, and categories (including their children) without any products are removed. Enabling this option may increase response times, especially for large category trees.
1644
1650
 
1645
1651
  ```ts
1646
- import { rpcMethods } from "@scayle/storefront-core";
1652
+ import { rpcMethods } from '@scayle/storefront-core'
1647
1653
 
1648
- rpcMethods.getCategoryTree({ hideEmptyCategories: true }, rpcContext);
1654
+ rpcMethods.getCategoryTree({ hideEmptyCategories: true }, rpcContext)
1649
1655
  ```
1650
1656
 
1651
1657
  or
1652
1658
 
1653
1659
  ```ts
1654
- import { useCategoryTree } from "#storefront/composables";
1660
+ import { useCategoryTree } from '#storefront/composables'
1655
1661
 
1656
1662
  const { data: rootCategories, status } = useCategoryTree(
1657
1663
  {
@@ -1659,8 +1665,8 @@
1659
1665
  hideEmptyCategories: true,
1660
1666
  },
1661
1667
  },
1662
- "category-navigation-tree"
1663
- );
1668
+ 'category-navigation-tree',
1669
+ )
1664
1670
  ```
1665
1671
 
1666
1672
  ## 8.28.7
@@ -1757,9 +1763,9 @@
1757
1763
  params: {
1758
1764
  children: 10,
1759
1765
  includeHidden: true,
1760
- properties: { withName: ["sale"] },
1766
+ properties: { withName: ['sale'] },
1761
1767
  },
1762
- });
1768
+ })
1763
1769
  ```
1764
1770
 
1765
1771
  ### Patch Changes
@@ -1930,16 +1936,16 @@
1930
1936
  nitro: {
1931
1937
  storage: {
1932
1938
  redis: {
1933
- driver: "redis",
1934
- host: "localhost",
1939
+ driver: 'redis',
1940
+ host: 'localhost',
1935
1941
  },
1936
1942
  db: {
1937
- driver: "fs",
1938
- base: "./.data/db",
1943
+ driver: 'fs',
1944
+ base: './.data/db',
1939
1945
  },
1940
1946
  },
1941
1947
  },
1942
- });
1948
+ })
1943
1949
  ```
1944
1950
 
1945
1951
  With the introduction of the new approach for configuring storefront storage mounts, the global and shop-specific `storage` option within the `@scayle/storefront-nuxt` runtime configuration has been deprecated.
@@ -1995,7 +2001,6 @@
1995
2001
  **@scayle/storefront-core v8.23.0**
1996
2002
 
1997
2003
  - Minor
1998
-
1999
2004
  - Deprecated attribute group specific utilities `getFlattenedVariantCrosssellings` and
2000
2005
  `getFlattenedMaterialComposition`.
2001
2006
 
@@ -2012,9 +2017,9 @@
2012
2017
  ```typescript
2013
2018
  const idp = useIDP({
2014
2019
  authUrlParameters: {
2015
- theme: "dark",
2020
+ theme: 'dark',
2016
2021
  },
2017
- });
2022
+ })
2018
2023
  ```
2019
2024
 
2020
2025
  ### Patch Changes
@@ -2036,7 +2041,6 @@
2036
2041
  **@scayle/storefront-core v8.21.0**
2037
2042
 
2038
2043
  - Minor
2039
-
2040
2044
  - Expose the following filter types from `storefront-api`:
2041
2045
 
2042
2046
  - `FilterItemWithValues`
@@ -2156,25 +2160,22 @@
2156
2160
  storefront: {
2157
2161
  redirects: {
2158
2162
  enabled: true,
2159
- strategy: "on-missing",
2163
+ strategy: 'on-missing',
2160
2164
  },
2161
2165
  },
2162
2166
  },
2163
- });
2167
+ })
2164
2168
  ```
2165
2169
 
2166
2170
  Also, keep in mind that when this option is enabled, the redirect logic will only be executed when the request would otherwise result in a 404. There are three ways in which a 404 can occur.
2167
-
2168
2171
  1. No route found
2169
2172
 
2170
- If there is no matching route for the request's path, the framework will return a 404 response.
2171
-
2172
- 2. `Response` with 404 status
2173
+ If there is no matching route for the request's path, the framework will return a 404 response. 2. `Response` with 404 status
2173
2174
 
2174
2175
  If the request handler returns a `Response` object with a `status` of 404, a 404 response will be returned to the client.
2175
2176
 
2176
2177
  ```typescript
2177
- return new Response(null, { status: 404 });
2178
+ return new Response(null, { status: 404 })
2178
2179
  ```
2179
2180
 
2180
2181
  3. Thrown H3Error with 404 status
@@ -2182,8 +2183,8 @@
2182
2183
  If the request handler throws an H3Error with a `statusCode` 404, a 404 response will be returned to the client.
2183
2184
 
2184
2185
  ```typescript
2185
- import { createError } from "h3";
2186
- throw createError({ statusCode: 404 });
2186
+ import { createError } from 'h3'
2187
+ throw createError({ statusCode: 404 })
2187
2188
  ```
2188
2189
 
2189
2190
  ### Patch Changes
@@ -2418,7 +2419,6 @@
2418
2419
  - Deprecate `key`, `packages`, `shippingDates`, `isEmpty`, `countWithoutSoldOutItems`, `removeItem`, `contains`, `findItem`, `products`, `generateBasketKey` and `mergeBaskets` from `useBasket`.
2419
2420
 
2420
2421
  Required updates:
2421
-
2422
2422
  - `key`:
2423
2423
 
2424
2424
  ```TypeScript
@@ -2625,28 +2625,28 @@
2625
2625
  **rpc-methods.ts**
2626
2626
 
2627
2627
  ```typescript
2628
- import type { RpcContext, RpcHandler } from "@scayle/storefront-nuxt";
2628
+ import type { RpcContext, RpcHandler } from '@scayle/storefront-nuxt'
2629
2629
 
2630
2630
  export const foo: RpcHandler<string, number> = function testing(
2631
2631
  param: string,
2632
- _: RpcContext
2632
+ _: RpcContext,
2633
2633
  ) {
2634
- return param.length;
2635
- };
2634
+ return param.length
2635
+ }
2636
2636
  ```
2637
2637
 
2638
2638
  **module.ts**
2639
2639
 
2640
2640
  ```typescript
2641
2641
  function setup() {
2642
- const resolver = createResolver(import.meta.url);
2642
+ const resolver = createResolver(import.meta.url)
2643
2643
 
2644
- nuxt.hook("storefront:custom-rpc:extend", (customRpcImports) => {
2644
+ nuxt.hook('storefront:custom-rpc:extend', (customRpcImports) => {
2645
2645
  customRpcImports.push({
2646
- source: resolver.resolve("./rpc-methods.ts"),
2647
- names: ["foo"],
2648
- });
2649
- });
2646
+ source: resolver.resolve('./rpc-methods.ts'),
2647
+ names: ['foo'],
2648
+ })
2649
+ })
2650
2650
  }
2651
2651
  ```
2652
2652
 
@@ -2857,7 +2857,6 @@
2857
2857
 
2858
2858
  You'll need to migrate your existing storage settings to the new `storefront.storage` format.
2859
2859
  Check the [SCAYLE Resource Center](https://scayle.dev/en/core-documentation/storefront-guide/storefront-application/technical-foundation/storage) for more details.
2860
-
2861
2860
  - _No Longer Supported: Legacy Storage Setup in (`nuxt.config.ts`):_
2862
2861
 
2863
2862
  ```ts
@@ -2868,23 +2867,23 @@
2868
2867
  storefront: {
2869
2868
  // ...
2870
2869
  redis: {
2871
- host: "localhost",
2870
+ host: 'localhost',
2872
2871
  port: 6379,
2873
- prefix: "",
2874
- user: "",
2875
- password: "",
2872
+ prefix: '',
2873
+ user: '',
2874
+ password: '',
2876
2875
  sslTransit: false,
2877
2876
  },
2878
2877
  // ...
2879
2878
  session: {
2880
2879
  // ...
2881
- provider: "redis",
2880
+ provider: 'redis',
2882
2881
  },
2883
2882
  },
2884
2883
  // ...
2885
2884
  },
2886
2885
  // ...
2887
- });
2886
+ })
2888
2887
  ```
2889
2888
 
2890
2889
  - _Current Unified Storage Approach (`nuxt.config.ts`):_
@@ -2898,13 +2897,13 @@
2898
2897
  // ...
2899
2898
  storage: {
2900
2899
  cache: {
2901
- driver: "redis",
2902
- host: "localhost",
2900
+ driver: 'redis',
2901
+ host: 'localhost',
2903
2902
  port: 6379,
2904
2903
  },
2905
2904
  session: {
2906
- driver: "redis",
2907
- host: "localhost",
2905
+ driver: 'redis',
2906
+ host: 'localhost',
2908
2907
  port: 6379,
2909
2908
  },
2910
2909
  // ...
@@ -2914,11 +2913,10 @@
2914
2913
  // ...
2915
2914
  },
2916
2915
  // ...
2917
- });
2916
+ })
2918
2917
  ```
2919
2918
 
2920
2919
  - **\[๐Ÿ’ฅ BREAKING\]** The composable `useSearch` has been replaced by `useStorefrontSearch`, consolidating and transitioning to SCAYLE Search v2.
2921
-
2922
2920
  - _Previous Usage of `useSearch`:_
2923
2921
 
2924
2922
  ```ts
@@ -2940,7 +2938,6 @@
2940
2938
  ```
2941
2939
 
2942
2940
  - **\[๐Ÿ’ฅ BREAKING\]** The previous use of the `useFacet` composable for category-related product listings was overly complex and difficult to customize. To simplify things, dedicated composables are being introduced:
2943
-
2944
2941
  - `useProductsByCategory`: Replaces `useFacet` for fetching products within a specific category.
2945
2942
  - `useFilters` or `useProductListFilters`: Provide focused filter management capabilities.
2946
2943
 
@@ -2976,14 +2973,13 @@
2976
2973
 
2977
2974
  - **\[๐Ÿ’ฅ BREAKING\]** We've renamed the `useNavigationTree` composable to `useNavigationTreeById` for better clarity. Its functionality, parameters and return values stay identical.
2978
2975
  - **\[๐Ÿ’ฅ BREAKING\]** The composable `useQueryFilterState` has been superseded by the `useFilter` and `useAppliedFilters` (part of `@scayle/storefront-product-listing`) composables.
2979
-
2980
2976
  - _Previous Usage of `useQueryFilterState`:_
2981
2977
 
2982
2978
  ```ts
2983
2979
  const { activeFilters, applyFilters, resetFilterUrl, productConditions } =
2984
- useQueryFilterState();
2980
+ useQueryFilterState()
2985
2981
 
2986
- applyFilters({ brand: 23, sale: true, maxPrice: 100, minPrice: 0 });
2982
+ applyFilters({ brand: 23, sale: true, maxPrice: 100, minPrice: 0 })
2987
2983
  ```
2988
2984
 
2989
2985
  - _Current Usage of `useFilter` and `useAppliedFilters`:_
@@ -2996,70 +2992,68 @@
2996
2992
  resetFilters,
2997
2993
  resetPriceFilter,
2998
2994
  resetFilter,
2999
- } = useFilter();
2995
+ } = useFilter()
3000
2996
 
3001
- applyPriceFilter([0, 100]);
3002
- applyBooleanFilter("sale", true);
3003
- applyAttributeFilter("brand", 23);
2997
+ applyPriceFilter([0, 100])
2998
+ applyBooleanFilter('sale', true)
2999
+ applyAttributeFilter('brand', 23)
3004
3000
 
3005
- const route = useRoute();
3001
+ const route = useRoute()
3006
3002
  const {
3007
3003
  appliedFilter,
3008
3004
  appliedFiltersCount,
3009
3005
  appliedAttributeValues,
3010
3006
  appliedBooleanValues,
3011
3007
  areFiltersApplied,
3012
- } = useAppliedFilters(route);
3008
+ } = useAppliedFilters(route)
3013
3009
  ```
3014
3010
 
3015
3011
  - **\[๐Ÿ’ฅ BREAKING\]** The `getBadgeLabel` helper function has been removed, giving you more control over badge label display.
3016
-
3017
3012
  - **Note:** This change doesn't affect projects using SCAYLE Storefront Boilerplate v1.0 or later.
3018
3013
  - For applications based on older versions or using `getBadgeLabel`, you can refer to the previous implementation below:
3019
3014
 
3020
3015
  ```ts
3021
3016
  const BadgeLabel = {
3022
- NEW: "new",
3023
- SOLD_OUT: "sold_out",
3024
- ONLINE_EXCLUSIVE: "online_exclusive",
3025
- SUSTAINABLE: "sustainable",
3026
- PREMIUM: "premium",
3027
- DEFAULT: "",
3028
- } as const;
3017
+ NEW: 'new',
3018
+ SOLD_OUT: 'sold_out',
3019
+ ONLINE_EXCLUSIVE: 'online_exclusive',
3020
+ SUSTAINABLE: 'sustainable',
3021
+ PREMIUM: 'premium',
3022
+ DEFAULT: '',
3023
+ } as const
3029
3024
 
3030
3025
  type BadgeLabelParamsKeys =
3031
- | "isNew"
3032
- | "isSoldOut"
3033
- | "isOnlineOnly"
3034
- | "isSustainable"
3035
- | "isPremium";
3036
- type BadgeLabelParams = Partial<Record<BadgeLabelParamsKeys, boolean>>;
3026
+ | 'isNew'
3027
+ | 'isSoldOut'
3028
+ | 'isOnlineOnly'
3029
+ | 'isSustainable'
3030
+ | 'isPremium'
3031
+ type BadgeLabelParams = Partial<Record<BadgeLabelParamsKeys, boolean>>
3037
3032
 
3038
3033
  const getBadgeLabel = (params: BadgeLabelParams = {}): string => {
3039
3034
  if (!params) {
3040
- return BadgeLabel.DEFAULT;
3035
+ return BadgeLabel.DEFAULT
3041
3036
  }
3042
3037
  const { isNew, isSoldOut, isOnlineOnly, isSustainable, isPremium } =
3043
- params;
3038
+ params
3044
3039
 
3045
3040
  if (isNew) {
3046
- return BadgeLabel.NEW;
3041
+ return BadgeLabel.NEW
3047
3042
  } else if (isSoldOut) {
3048
- return BadgeLabel.SOLD_OUT;
3043
+ return BadgeLabel.SOLD_OUT
3049
3044
  } else if (isOnlineOnly) {
3050
- return BadgeLabel.ONLINE_EXCLUSIVE;
3045
+ return BadgeLabel.ONLINE_EXCLUSIVE
3051
3046
  } else if (isSustainable) {
3052
- return BadgeLabel.SUSTAINABLE;
3047
+ return BadgeLabel.SUSTAINABLE
3053
3048
  } else if (isPremium) {
3054
- return BadgeLabel.PREMIUM;
3049
+ return BadgeLabel.PREMIUM
3055
3050
  } else {
3056
- return BadgeLabel.DEFAULT;
3051
+ return BadgeLabel.DEFAULT
3057
3052
  }
3058
- };
3053
+ }
3059
3054
  ```
3060
3055
 
3061
3056
  - **\[๐Ÿ’ฅ BREAKING\]** The `store` option in the module configuration has been removed. `@scayle/storefront-nuxt@7.84.0` introduced the `shops` option as a replacement, but maintained backward compatibility with the `store` option. Going forward, configuring shops must be done using the `shops` keyword.
3062
-
3063
3057
  - For more information, please refer to the [documentation](https://scayle.dev/en/core-documentation/storefront-guide/storefront-application/technical-foundation/configuration#shops).
3064
3058
  - **NOTE:** These changes might impact your environment variables used for deployments. Please check your infrastructure and deployment setup and adapt accordingly!
3065
3059
  - _Previous Store Configuration in `nuxt.config.ts`:_
@@ -3079,7 +3073,7 @@
3079
3073
  // ...
3080
3074
  },
3081
3075
  // ...
3082
- });
3076
+ })
3083
3077
  ```
3084
3078
 
3085
3079
  - _Previous Environment Variables for Store Configuration:_
@@ -3108,7 +3102,7 @@
3108
3102
  // ...
3109
3103
  },
3110
3104
  // ...
3111
- });
3105
+ })
3112
3106
  ```
3113
3107
 
3114
3108
  - _Current Environment Variables for Shops Configuration:_
@@ -3122,14 +3116,13 @@
3122
3116
 
3123
3117
  - **\[๐Ÿ’ฅ BREAKING\]** To better align with the current Nuxt 3 architecture make key handling more explicit, we've simplified how you interact with the key parameter in RPC composables from version 8 onwards.
3124
3118
  Instead of placing the key within the composable's options object, you'll now provide it as the second argument when calling the composable.
3125
-
3126
3119
  - _Previous `key` as options parameter:_
3127
3120
 
3128
3121
  ```ts
3129
3122
  useProduct({
3130
3123
  // ...
3131
- key: "productKey",
3132
- });
3124
+ key: 'productKey',
3125
+ })
3133
3126
  ```
3134
3127
 
3135
3128
  - _Current `key` as dedicated composables argument:_
@@ -3139,13 +3132,12 @@
3139
3132
  {
3140
3133
  // ...
3141
3134
  },
3142
- "productKey"
3143
- );
3135
+ 'productKey',
3136
+ )
3144
3137
  ```
3145
3138
 
3146
3139
  - **\[๐Ÿ’ฅ BREAKING\]** Introducing a new feature flag `storefront.legacy.enableSessionMigration` to control the automatic migration of legacy session data, set to `false` by default. Starting with `@scayle/storefront-nuxt@7.68.0` Storefront uses unique session cookie names for each shop, simplifying implementation and enhancing stability.
3147
3140
  Instead of relying on the Path attribute, each shop receives a distinct cookie name. This change is internal and should not require code modifications.
3148
-
3149
3141
  - _Cookie format before `@scayle/storefront-nuxt@7.68.0`:_
3150
3142
  - `Set-Cookie: $session=s:fa3746f9-88c8-4065-a6c9-0c7bee473dd8.pSoaN6Q7iFHHyWKE7s9gQAqdDzGb9fS8a478P7PHLxw; Path=/de`
3151
3143
  - _Cookie format after `@scayle/storefront-nuxt@7.68.0`:_
@@ -3153,61 +3145,57 @@
3153
3145
  - **NOTE:** Upgrading directly to this version from a version prior to `@scayle/storefront-nuxt@7.68.0` without enabling the `storefront.legacy.enableSessionMigration` feature flag will lead to loss of user sessions. Ensure version `@scayle/storefront-nuxt@7.68.0` or higher has been deployed in production for a period exceeding the configured session TTL before upgrading to this version. This ensures all legacy sessions have been migrated. Consult the updated documentation for details on the cookie format changes and migration procedures.
3154
3146
 
3155
3147
  - **\[๐Ÿ’ฅ BREAKING\]** We've optimized the way Identity Provider (IDP) logins are handled. Instead of using the `handleIDPLoginCallback` RPC method, which has been removed, from the `useIDP` composable, you'll now use the `loginIDP` function, which has been moved to the `useAuthentication` composable. This change consolidates IDP login functionality within `useAuthentication` for a more unified approach.
3156
-
3157
3148
  - _Previous Usage of `handleIDPLoginCallback`:_
3158
3149
 
3159
3150
  ```ts
3160
- const { handleIDPLoginCallback } = await useIDP();
3151
+ const { handleIDPLoginCallback } = await useIDP()
3161
3152
 
3162
3153
  watch(
3163
3154
  () => route.query,
3164
3155
  async (query) => {
3165
3156
  if (query.code && isString(query.code)) {
3166
- await handleIDPLoginCallback(query.code);
3157
+ await handleIDPLoginCallback(query.code)
3167
3158
  }
3168
3159
  },
3169
- { immediate: true }
3170
- );
3160
+ { immediate: true },
3161
+ )
3171
3162
  ```
3172
3163
 
3173
3164
  - _Current Usage of `loginIDP`:_
3174
3165
 
3175
3166
  ```ts
3176
- const { loginIDP } = useAuthentication("login");
3167
+ const { loginIDP } = useAuthentication('login')
3177
3168
 
3178
3169
  onMounted(async () => {
3179
- await loginIDP(props.code);
3180
- });
3170
+ await loginIDP(props.code)
3171
+ })
3181
3172
  ```
3182
3173
 
3183
3174
  - **\[๐Ÿงน NON-BREAKING\]** Addressed various type resolution errors that were present when using the `@scayle/storefront-nuxt` package with different Node.js versions and module systems. These errors manifested as internal resolution errors or ESM dynamic import only warnings. With this fix, the package now more consistently resolves types correctly across Node.js 16 (CJS and ESM), and bundlers, ensuring a smoother developer experience.
3184
3175
  - **\[๐Ÿ’ฅ BREAKING\]** The `useBasket` composable now gracefully handles cases where adding items to the basket results in a smaller quantity being added than originally requested by checking against `AddToBasketFailureKind`.
3185
3176
  - **\[๐Ÿ’ฅ BREAKING\]** The deprecated `autoFetch` option of `useRpc` has been removed in favor of the `immediate` option. This also applies to all data fetching composables provided by `@scayle/storefront-nuxt`.
3186
-
3187
3177
  - _Previous `useRpc` with `autoFetch`:_
3188
3178
 
3189
3179
  ```ts
3190
- useRpc("rpcMethod", key, params, { autoFetch: true });
3180
+ useRpc('rpcMethod', key, params, { autoFetch: true })
3191
3181
 
3192
- useUser({ autoFetch: true });
3182
+ useUser({ autoFetch: true })
3193
3183
  ```
3194
3184
 
3195
3185
  - _Current `useRpc` with `immediate`:_
3196
3186
 
3197
3187
  ```ts
3198
- useRpc("rpcMethod", key, params, { immediate: true });
3188
+ useRpc('rpcMethod', key, params, { immediate: true })
3199
3189
 
3200
- useUser({ immediate: true });
3190
+ useUser({ immediate: true })
3201
3191
  ```
3202
3192
 
3203
3193
  - **\[๐Ÿ’ฅ BREAKING\]** The attribute `isCmsPreview` has been removed from `RpcContext`.
3204
3194
  - **\[๐Ÿ’ฅ BREAKING\]** The attribute `storeCampaignKeyword` has been removed from `RpcContext`.
3205
-
3206
3195
  - The `campaignKey` is now automatically determined by fetching campaign data through the Storefront API client by retrieving a list of all campaigns from the API. It then narrows down the list by filtering for campaigns that are still active, ensuring any returned campaign is currently running. These active campaigns are then sorted by their start date, ensuring chronological order. Finally, it iterates through the sorted campaigns to find the first one that is currently active, returning its key as an identifier. If no active campaign is found or an error occurs, it returns nothing.
3207
3196
  - The `storeCampaignKeyword` is also no longer used to determine the active campaign key. The functionality to run only certain campaigns for specific countries is now supported through the SCAYLE Panel out of the box.
3208
3197
 
3209
3198
  - **\[๐Ÿ’ฅ BREAKING\]** The composable `useStorefrontSearch` is now consistent with `useRpc` return values. The `fetching` boolean is replaced by `status` with states `idle`, `pending`, `error` or `success`.
3210
-
3211
3199
  - _Previous `useStorefrontSearch` returning `fetching`:_
3212
3200
 
3213
3201
  ```ts
@@ -3217,24 +3205,23 @@
3217
3205
  getSearchSuggestions,
3218
3206
  fetching,
3219
3207
  ...searchData
3220
- } = useStorefrontSearch(searchQuery, { key });
3208
+ } = useStorefrontSearch(searchQuery, { key })
3221
3209
 
3222
- fetching.value; // true or false
3210
+ fetching.value // true or false
3223
3211
  ```
3224
3212
 
3225
3213
  - _Current `useStorefrontSearch` returning `status`:_
3226
3214
 
3227
3215
  ```ts
3228
3216
  const { data, resolveSearch, getSearchSuggestions, status, ...searchData } =
3229
- useStorefrontSearch(searchQuery, {}, key);
3217
+ useStorefrontSearch(searchQuery, {}, key)
3230
3218
 
3231
- status.value; // 'idle', 'pending', 'error' or 'success'
3219
+ status.value // 'idle', 'pending', 'error' or 'success'
3232
3220
  ```
3233
3221
 
3234
3222
  - **\[๐Ÿ’ฅ BREAKING\]** We've simplified composable caching and clarified the control you have over shared state behavior. The configuration option `disableDefaultGetCachedDataOverride` has been replaced with `legacy.enableDefaultGetCachedDataOverride`, and its logic has been reversed. Now, when `legacy.enableDefaultGetCachedDataOverride` is not set or set to `false`, the default behavior maintains the shared state functionality of `useRpc`, where multiple calls with the same key use the same cached data. Setting the option to `true` bypasses this shared caching, providing data isolation between calls. To maintain your existing caching behavior, simply change the value of `disableDefaultGetCachedDataOverride` to its opposite in your `nuxt.config.ts` file.
3235
3223
 
3236
3224
  Old config
3237
-
3238
3225
  - _Previous `disableDefaultGetCachedDataOverride` in `nuxt.config.ts`:_
3239
3226
 
3240
3227
  ```ts
@@ -3253,7 +3240,7 @@
3253
3240
  // ...
3254
3241
  },
3255
3242
  // ...
3256
- });
3243
+ })
3257
3244
  ```
3258
3245
 
3259
3246
  - _Current `enableDefaultGetCachedDataOverride`in `nuxt.config.ts`:_
@@ -3278,14 +3265,13 @@
3278
3265
  // ...
3279
3266
  },
3280
3267
  // ...
3281
- });
3268
+ })
3282
3269
  ```
3283
3270
 
3284
3271
  - **\[๐Ÿ’ฅ BREAKING\]** The `useRpc` composable has been updated to provide a more modern and robust data fetching experience, aligning its interface with the current and underlying [Nuxt 3 `useAsyncData`.](https://nuxt.com/docs/api/composables/use-async-data#return-values).
3285
3272
  The separate `fetch` function has been replaced with a single, intuitive `refresh` function that can be used to refresh the data returned by the `handler` function.
3286
3273
  Additionally, the boolean `pending` flag has been superseded by a more informative `status` return value, offering greater insight into the fetching lifecycle with possible states: `idle`, `pending`, `success`, and `error`.
3287
3274
  These changes enhance the developer experience and provide greater clarity and control over data fetching operations within components.
3288
-
3289
3275
  - **NOTE:** This update not only impacts the `useRpc` composable directly, but also extends to other RPC composables relying on it, such as `useProducts` and `useCategories`!
3290
3276
 
3291
3277
  - **\[๐Ÿ’ฅ BREAKING\]** Removed special handling for `BAPIError` and `BaseError` thrown in RPC methods. These custom `Error` classes were previously used in RPC methods to allow customizing the status code and message of errors.
@@ -3293,14 +3279,13 @@
3293
3279
  In this release, the legacy special handling for `BAPIError` and `BaseError` has been removed. Now they will be treated like any other `Error`. If they are thrown uncaught during the execution of an RPC method, a 500 status code will be used in the response. They have also been removed from `@scayle/storefront-nuxt`.
3294
3280
  For most users, this change will have no impact as the core RPC methods have been updated for some time. However, if you have custom RPC methods you should review their implementation.
3295
3281
  In order to have an RPC method use a specific status code, it should return a `Response` object.
3296
-
3297
3282
  - _Previous Usage with `BaseError`:_
3298
3283
 
3299
3284
  ```ts
3300
3285
  function myCustomRpc() {
3301
3286
  // ...
3302
3287
 
3303
- throw new BaseError(404);
3288
+ throw new BaseError(404)
3304
3289
  }
3305
3290
  ```
3306
3291
 
@@ -3310,7 +3295,7 @@
3310
3295
  function myCustomRpc() {
3311
3296
  // ...
3312
3297
 
3313
- return new Response(null, { status: 404 });
3298
+ return new Response(null, { status: 404 })
3314
3299
  }
3315
3300
  ```
3316
3301