@scayle/storefront-nuxt 8.61.1 → 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 +227 -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 +4 -3
package/CHANGELOG.md CHANGED
@@ -1,5 +1,26 @@
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
+
3
24
  ## 8.61.1
4
25
 
5
26
  ### Patch Changes
@@ -23,13 +44,13 @@
23
44
 
24
45
  ```ts
25
46
  // Safe reads — eligible for CDN / browser caching
26
- export const getNavigation = defineRpcHandler(handler, { method: "GET" });
47
+ export const getNavigation = defineRpcHandler(handler, { method: 'GET' })
27
48
 
28
49
  // Mutations
29
- export const updateBasketItem = defineRpcHandler(handler, { method: "PUT" });
50
+ export const updateBasketItem = defineRpcHandler(handler, { method: 'PUT' })
30
51
  export const deleteWishlistItem = defineRpcHandler(handler, {
31
- method: "DELETE",
32
- });
52
+ method: 'DELETE',
53
+ })
33
54
  ```
34
55
 
35
56
  RPCs returning user-specific data (basket, wishlist, tokens) should stay on `POST` to prevent unintended caching.
@@ -43,29 +64,28 @@
43
64
  **@scayle/storefront-core v8.61.0**
44
65
 
45
66
  - Minor
46
-
47
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.
48
68
 
49
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.
50
70
 
51
71
  ```ts
52
- import { defineRpcHandler, type RpcContext } from "@scayle/storefront-core";
72
+ import { defineRpcHandler, type RpcContext } from '@scayle/storefront-core'
53
73
 
54
74
  // Safe, public read — eligible for CDN/browser caching
55
75
  export const getNavigation = defineRpcHandler(
56
76
  async (context: RpcContext) => {
57
77
  /* ... */
58
78
  },
59
- { method: "GET" }
60
- );
79
+ { method: 'GET' },
80
+ )
61
81
 
62
82
  // User-specific / Mutation — uses POST to prevent cache leakage
63
83
  export const getBasket = defineRpcHandler(
64
84
  async (context: RpcContext) => {
65
85
  /* ... */
66
- }
86
+ },
67
87
  // method defaults to 'POST'
68
- );
88
+ )
69
89
  ```
70
90
 
71
91
  - Patch
@@ -97,7 +117,6 @@
97
117
  **@scayle/storefront-core v8.60.0**
98
118
 
99
119
  - Minor
100
-
101
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.
102
121
 
103
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.
@@ -151,7 +170,6 @@
151
170
  **@scayle/storefront-core v8.59.4**
152
171
 
153
172
  - Patch
154
-
155
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.
156
174
 
157
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.
@@ -179,7 +197,6 @@
179
197
  **@scayle/storefront-core v8.59.2**
180
198
 
181
199
  - Patch
182
-
183
200
  - Deprecated the `slugify` and `getProductPath` functions in `productHelpers.ts` due to compatibility issues with Nuxt 4.
184
201
 
185
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.
@@ -187,33 +204,33 @@
187
204
  **Migration:**
188
205
 
189
206
  ```ts
190
- import baseSlugify from "slugify";
207
+ import baseSlugify from 'slugify'
191
208
 
192
209
  const slugify = (url: string | undefined): string => {
193
- return baseSlugify(url ?? "", {
210
+ return baseSlugify(url ?? '', {
194
211
  lower: true,
195
212
  remove: /[*+~.()'"!:@/#?]/g,
196
- });
197
- };
213
+ })
214
+ }
198
215
 
199
- const localePath = useLocalePath();
216
+ const localePath = useLocalePath()
200
217
 
201
218
  const getProductDetailRoute = (
202
219
  id: number,
203
220
  name?: string,
204
- locale?: Locale
221
+ locale?: Locale,
205
222
  ): string => {
206
223
  return localePath(
207
224
  {
208
- name: "p-productName-id",
225
+ name: 'p-productName-id',
209
226
  params: {
210
227
  productName: slugify(name),
211
228
  id: `${id}`,
212
229
  },
213
230
  },
214
- locale
215
- );
216
- };
231
+ locale,
232
+ )
233
+ }
217
234
  ```
218
235
 
219
236
  ## 8.59.1
@@ -228,7 +245,6 @@
228
245
  **@scayle/storefront-core v8.59.1**
229
246
 
230
247
  - Patch
231
-
232
248
  - Fixed import compatibility issue with the `slugify` package in `productHelpers.ts` to support both ESM and CommonJS module formats.
233
249
 
234
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.
@@ -252,7 +268,6 @@
252
268
 
253
269
  - Introduced support for Nuxt 4 while maintaining full backward compatibility with Nuxt 3.
254
270
  This enables consumers to migrate to Nuxt 4 ahead of the Nuxt 3 end of support on 31 Jan 2026.
255
-
256
271
  - **Version Requirements:**
257
272
  - Nuxt 3: `v3.13.0+`
258
273
  - Nuxt 4: `v4.2.0+`
@@ -336,11 +351,9 @@
336
351
  **@scayle/storefront-core v8.57.0**
337
352
 
338
353
  - Minor
339
-
340
354
  - **\[Navigation\]** Exported Navigation V2 API types to provide TypeScript support for the new navigation endpoints.
341
355
 
342
356
  The following types are now available from `@scayle/storefront-core`:
343
-
344
357
  - `GetNavigationV2Parameters` - Parameters for fetching navigation trees via the V2 API
345
358
  - `NavigationV2AllEndpointResponseData` - Response type for fetching all navigation trees
346
359
  - `NavigationV2ByReferenceEndpointResponseData` - Response type for fetching a navigation tree by reference key
@@ -356,7 +369,6 @@
356
369
  The `RpcContext` now exposes a `sessionCustomData` property to read custom session data and an `updateSessionCustomData` method to update it.
357
370
  The `sessionCustomData` property may be `undefined` when no session exists or when no custom data has been set.
358
371
  The `SessionCustomData` interface can be augmented with TypeScript module augmentation to provide type safety for custom session properties.
359
-
360
372
  - **Type Augmentation Example:**
361
373
 
362
374
  ```ts
@@ -374,39 +386,39 @@
374
386
 
375
387
  ```ts
376
388
  // server/plugins/session-plugin.ts
377
- import { hasSession } from "@scayle/storefront-nuxt";
378
- import { defineNitroPlugin } from "#imports";
389
+ import { hasSession } from '@scayle/storefront-nuxt'
390
+ import { defineNitroPlugin } from '#imports'
379
391
 
380
392
  export default defineNitroPlugin((nitroApp) => {
381
- nitroApp.hooks.hook("storefront:afterLogin", async (_data, context) => {
393
+ nitroApp.hooks.hook('storefront:afterLogin', async (_data, context) => {
382
394
  // Check if we actually have a RpcContext with proper session data
383
395
  if (!hasSession(context)) {
384
- return;
396
+ return
385
397
  }
386
398
 
387
399
  // Should you have set custom session data already in another hook,
388
400
  // it might be necessary to get existing data first.
389
- const sessionCustomData = context.sessionCustomData;
401
+ const sessionCustomData = context.sessionCustomData
390
402
 
391
403
  // The update functions overrides the customData object on a session.
392
404
  // Should you have set custom session data already in another hooks,
393
405
  // you need to pass it in addition to your new custom session data.
394
406
  context.updateSessionCustomData({
395
407
  ...sessionCustomData,
396
- yourCustomDataKey: "Your Session CustomData Value",
397
- });
408
+ yourCustomDataKey: 'Your Session CustomData Value',
409
+ })
398
410
 
399
411
  // Before accessing your session custom data, you might want to use an
400
412
  // explicit early return conditional.
401
413
  if (!sessionCustomData) {
402
- return;
414
+ return
403
415
  }
404
416
 
405
417
  // Your custom session data can also be accessedd directly via
406
418
  // nullish coalescing depending on your needs.
407
- console.log(context.sessionCustomData?.yourCustomDataKey);
408
- });
409
- });
419
+ console.log(context.sessionCustomData?.yourCustomDataKey)
420
+ })
421
+ })
410
422
  ```
411
423
 
412
424
  ### Patch Changes
@@ -418,7 +430,6 @@
418
430
  **@scayle/storefront-core v8.56.0**
419
431
 
420
432
  - Minor
421
-
422
433
  - Added support for custom session data in the RPC context type definitions.
423
434
 
424
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.
@@ -460,26 +471,25 @@
460
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).
461
472
 
462
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.
463
-
464
474
  - **Before:** Keys were static strings.
465
475
  - **After:** Keys can be reactive, enabling dynamic caching and automatic updates.
466
476
 
467
477
  ```ts
468
478
  // Before
469
- const { data } = await useRpc("getProduct", "my-static-product-key", {
479
+ const { data } = await useRpc('getProduct', 'my-static-product-key', {
470
480
  productId: 123,
471
- });
481
+ })
472
482
 
473
483
  // After
474
- const productId = ref(123);
484
+ const productId = ref(123)
475
485
 
476
486
  // The key is now reactive. If `productId` changes, the key updates
477
487
  // to 'product-456' (for example) and triggers a new fetch.
478
488
  const { data } = await useRpc(
479
- "getProduct",
489
+ 'getProduct',
480
490
  () => `product-${productId.value}`,
481
- { productId }
482
- );
491
+ { productId },
492
+ )
483
493
  ```
484
494
 
485
495
  - Deprecated the `CheckoutEvent` type, which will be removed in the next major version.
@@ -491,22 +501,22 @@
491
501
  The type definition remains unchanged, so you can copy it directly:
492
502
 
493
503
  ```ts
494
- import type { ShopUser } from "@scayle/storefront-nuxt";
504
+ import type { ShopUser } from '@scayle/storefront-nuxt'
495
505
 
496
506
  export interface CheckoutEvent {
497
507
  /** Action. */
498
- action?: "authenticated";
508
+ action?: 'authenticated'
499
509
  /** Type. */
500
- type?: "tracking";
510
+ type?: 'tracking'
501
511
  /** User. */
502
- user: ShopUser;
512
+ user: ShopUser
503
513
  /**
504
514
  * The OAuth 2.0 access token for the authenticated user.
505
515
  * This token can be used to access protected resources on behalf of the user.
506
516
  *
507
517
  * @see https://www.rfc-editor.org/rfc/rfc6749
508
518
  */
509
- accessToken: string;
519
+ accessToken: string
510
520
  /**
511
521
  * Details about a specific event within the checkout process.
512
522
  * This field is optional and is only used when tracking specific actions
@@ -516,25 +526,25 @@
516
526
  */
517
527
  event?: {
518
528
  /** Event name. */
519
- event: "login" | "add_to_cart" | "remove_from_cart";
529
+ event: 'login' | 'add_to_cart' | 'remove_from_cart'
520
530
  /** Event status. */
521
- status: "successful" | "error";
522
- };
531
+ status: 'successful' | 'error'
532
+ }
523
533
  }
524
534
  ```
525
535
 
526
536
  - Updated the `StorefrontRuntimeConfig` type to ensure configured `shops` correctly incorporates all extended properties from `AdditionalShopConfig`.
527
537
 
528
538
  ```ts
529
- declare module "@scayle/storefront-nuxt" {
539
+ declare module '@scayle/storefront-nuxt' {
530
540
  // Extend the shop config
531
541
  export interface AdditionalShopConfig {
532
- extendedProp: string;
542
+ extendedProp: string
533
543
  }
534
544
  }
535
545
 
536
546
  // `extendedProp` is now properly typed
537
- useRuntimeConfig().storefront.shops?.[shopId]?.extendedProp;
547
+ useRuntimeConfig().storefront.shops?.[shopId]?.extendedProp
538
548
  ```
539
549
 
540
550
  **Dependencies**
@@ -554,11 +564,11 @@
554
564
  ```ts
555
565
  // Before (or when `rpcDefaultLazy: false`)
556
566
  // You had to explicitly opt-in to lazy behavior
557
- const { data } = useRpc("someMethod", { some: "param" }, { lazy: true });
567
+ const { data } = useRpc('someMethod', { some: 'param' }, { lazy: true })
558
568
 
559
569
  // After (when `rpcDefaultLazy: true`)
560
570
  // Lazy behavior is now the default
561
- const { data } = useRpc("someMethod", { some: "param" });
571
+ const { data } = useRpc('someMethod', { some: 'param' })
562
572
  ```
563
573
 
564
574
  **Dependencies**
@@ -591,7 +601,6 @@
591
601
  **@scayle/storefront-core v8.53.0**
592
602
 
593
603
  - Minor
594
-
595
604
  - Added support for promotions on order items by introducing the `OrderItemPromotion` interface and extending the `OrderItem` type with an optional `promotions` field.
596
605
 
597
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.
@@ -621,7 +630,6 @@
621
630
  **@scayle/storefront-core v8.51.0**
622
631
 
623
632
  - Minor
624
-
625
633
  - Added an email hash (`emailHash`) property to the user object returned by the `fetchUser` RPC method.
626
634
 
627
635
  The `emailHash` property is automatically included in all user objects returned by the RPCs.
@@ -633,7 +641,6 @@
633
641
  ### Minor Changes
634
642
 
635
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:
636
-
637
644
  - Ensures every shop has a domain property configured
638
645
  - Verifies that domains configured in the shop config are also present in the `@nuxtjs/i18n` configuration
639
646
  - Checks that all domains in the i18n configuration are unique (no duplicates)
@@ -661,7 +668,6 @@
661
668
  **@scayle/storefront-core v8.49.0**
662
669
 
663
670
  - Minor
664
-
665
671
  - Exported the `sha256` utility function as part of the public API.
666
672
 
667
673
  This function provides a convenient way to calculate SHA256 hashes of strings using the Web Crypto API, returning hexadecimal strings.
@@ -670,10 +676,10 @@
670
676
  Example:
671
677
 
672
678
  ```ts
673
- import { sha256 } from "@scayle/storefront-core";
679
+ import { sha256 } from '@scayle/storefront-core'
674
680
 
675
- const hash = await sha256("hello");
676
- console.log(hash); // '2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824'
681
+ const hash = await sha256('hello')
682
+ console.log(hash) // '2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824'
677
683
  ```
678
684
 
679
685
  ## 8.48.1
@@ -687,11 +693,9 @@
687
693
  **@scayle/storefront-core v8.48.1**
688
694
 
689
695
  - Patch
690
-
691
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.
692
697
 
693
698
  Available keys:
694
-
695
699
  - `SmartSortingKey.SALES_PUSH` - Promotes items with highest discounts and oldest inventory
696
700
  - `SmartSortingKey.NEW_ARRIVALS` - Prioritizes recently added products with good availability
697
701
  - `SmartSortingKey.BALANCED_OFFERINGS` - Balances recency, availability, discounts, and sales data
@@ -734,7 +738,6 @@
734
738
  **@scayle/storefront-core v8.47.0**
735
739
 
736
740
  - Minor
737
-
738
741
  - Enhanced basket RPC methods to support order custom data functionality.
739
742
 
740
743
  All basket RPC methods now integrate with the `getOrderCustomData` RPC method to fetch and include order custom data in SAPI requests.
@@ -753,12 +756,11 @@
753
756
  customer: {
754
757
  groups: context.user?.groups,
755
758
  },
756
- };
757
- });
759
+ }
760
+ })
758
761
  ```
759
762
 
760
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).
761
-
762
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.
763
765
 
764
766
  The customer access token is now automatically included in basket requests when available.
@@ -775,7 +777,6 @@
775
777
  **@scayle/storefront-core v8.46.0**
776
778
 
777
779
  - Minor
778
-
779
780
  - Added `getAttributeValuesByGroupId` function to the `attributeHelpers` helper for retrieving attribute values by their numeric attribute group ID.
780
781
 
781
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.
@@ -788,37 +789,36 @@
788
789
  #### Looking up by name (existing, now renamed):
789
790
 
790
791
  ```typescript
791
- import { getAttributeValuesByName } from "@scayle/storefront-core";
792
+ import { getAttributeValuesByName } from '@scayle/storefront-core'
792
793
 
793
794
  // Single-select attribute
794
- const sizes = getAttributeValuesByName(product.attributes, "size");
795
+ const sizes = getAttributeValuesByName(product.attributes, 'size')
795
796
  // Returns: [{ id: 1, label: 'M', value: 'medium' }]
796
797
 
797
798
  // Multi-select attribute
798
- const colors = getAttributeValuesByName(product.attributes, "color");
799
+ const colors = getAttributeValuesByName(product.attributes, 'color')
799
800
  // Returns: [{ id: 1, label: 'Red' }, { id: 2, label: 'Blue' }]
800
801
 
801
802
  // Non-existent attribute
802
- const missing = getAttributeValuesByName(product.attributes, "doesNotExist");
803
+ const missing = getAttributeValuesByName(product.attributes, 'doesNotExist')
803
804
  // Returns: []
804
805
  ```
805
806
 
806
807
  #### Looking up by group ID (new):
807
808
 
808
809
  ```typescript
809
- import { getAttributeValuesByGroupId } from "@scayle/storefront-core";
810
+ import { getAttributeValuesByGroupId } from '@scayle/storefront-core'
810
811
 
811
812
  // Look up attribute by its numeric ID from the SCAYLE API
812
- const promotionValues = getAttributeValuesByGroupId(product.attributes, 42);
813
+ const promotionValues = getAttributeValuesByGroupId(product.attributes, 42)
813
814
  // Returns: [{ id: 123, label: 'Summer Sale', value: 'summer-2024' }]
814
815
 
815
816
  // Non-existent attribute group
816
- const missing = getAttributeValuesByGroupId(product.attributes, 9999);
817
+ const missing = getAttributeValuesByGroupId(product.attributes, 9999)
817
818
  // Returns: []
818
819
  ```
819
820
 
820
821
  ### When to Use Each Function
821
-
822
822
  - **`getAttributeValuesByName`**: Use when you know the attribute name key (e.g., 'color', 'size'). This is the most common use case in application code.
823
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.
824
824
 
@@ -876,27 +876,27 @@
876
876
  // nuxt.config.ts
877
877
  export default defineNuxtConfig({
878
878
  storefront: {
879
- apiBasePath: "/custom-api", // ✅ Configure globally for all shops
879
+ apiBasePath: '/custom-api', // ✅ Configure globally for all shops
880
880
  },
881
881
  runtimeConfig: {
882
882
  storefront: {
883
883
  shops: {
884
884
  1001: {
885
885
  shopId: 1001,
886
- path: "de",
886
+ path: 'de',
887
887
  // ✅ apiBasePath removed from shop config
888
888
  // ... other shop config
889
889
  },
890
890
  1002: {
891
891
  shopId: 1002,
892
- path: "en",
892
+ path: 'en',
893
893
  // ✅ apiBasePath removed from shop config
894
894
  // ... other shop config
895
895
  },
896
896
  },
897
897
  },
898
898
  },
899
- });
899
+ })
900
900
  ```
901
901
 
902
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.
@@ -1003,7 +1003,6 @@
1003
1003
  **@scayle/storefront-core v8.43.0**
1004
1004
 
1005
1005
  - Minor
1006
-
1007
1006
  - Added an export of the new promotion type `ComboDealEffect`
1008
1007
 
1009
1008
  This type is also included in the `PromotionEffectType` type and can be used to check if the promotion is of type `ComboDealEffect`.
@@ -1012,10 +1011,10 @@
1012
1011
 
1013
1012
  ```ts
1014
1013
  const isComboDealType = (
1015
- promotion?: Promotion | null
1014
+ promotion?: Promotion | null,
1016
1015
  ): promotion is Promotion<ComboDealEffect> => {
1017
- return promotion?.effect?.type === PromotionEffectType.COMBO_DEAL;
1018
- };
1016
+ return promotion?.effect?.type === PromotionEffectType.COMBO_DEAL
1017
+ }
1019
1018
  ```
1020
1019
 
1021
1020
  ## 8.42.2
@@ -1079,68 +1078,68 @@
1079
1078
  Before:
1080
1079
 
1081
1080
  ```ts
1082
- const updateBasketItemRpc = useRpcCall("updateBasketItem");
1083
- const addItemToBasketRpc = useRpcCall("addItemToBasket");
1081
+ const updateBasketItemRpc = useRpcCall('updateBasketItem')
1082
+ const addItemToBasketRpc = useRpcCall('addItemToBasket')
1084
1083
 
1085
1084
  updateBasketItemRpc({
1086
1085
  // ...
1087
- promotionId: "promotionId",
1088
- promotionCode: "promotionCode",
1089
- });
1086
+ promotionId: 'promotionId',
1087
+ promotionCode: 'promotionCode',
1088
+ })
1090
1089
 
1091
1090
  addItemToBasketRpc({
1092
1091
  // ...
1093
- promotionId: "promotionId",
1094
- promotionCode: "promotionCode",
1095
- });
1092
+ promotionId: 'promotionId',
1093
+ promotionCode: 'promotionCode',
1094
+ })
1096
1095
 
1097
1096
  // Or with useBasket composable
1098
1097
 
1099
- const { addItem } = useBasket();
1098
+ const { addItem } = useBasket()
1100
1099
  addItem({
1101
1100
  // ...
1102
- promotionId: "promotionId",
1103
- });
1101
+ promotionId: 'promotionId',
1102
+ })
1104
1103
  ```
1105
1104
 
1106
1105
  After:
1107
1106
 
1108
1107
  ```ts
1109
- const updateBasketItemRpc = useRpcCall("updateBasketItem");
1110
- const addItemToBasketRpc = useRpcCall("addItemToBasket");
1108
+ const updateBasketItemRpc = useRpcCall('updateBasketItem')
1109
+ const addItemToBasketRpc = useRpcCall('addItemToBasket')
1111
1110
 
1112
1111
  updateBasketItemRpc({
1113
1112
  // ...
1114
1113
  promotions: [
1115
- { id: "promotionId", code: "promotionCode" },
1114
+ { id: 'promotionId', code: 'promotionCode' },
1116
1115
  {
1117
- id: "promotionId2",
1116
+ id: 'promotionId2',
1118
1117
  },
1119
1118
  ],
1120
- });
1119
+ })
1121
1120
 
1122
1121
  addItemToBasketRpc({
1123
1122
  // ...
1124
1123
  promotions: [
1125
- { id: "promotionId", code: "promotionCode" },
1124
+ { id: 'promotionId', code: 'promotionCode' },
1126
1125
  {
1127
- id: "promotionId2",
1126
+ id: 'promotionId2',
1128
1127
  },
1129
1128
  ],
1130
- });
1129
+ })
1131
1130
 
1132
1131
  // Or for useBasket with composable
1133
1132
 
1134
- const { addItem } = useBasket();
1133
+ const { addItem } = useBasket()
1135
1134
  addItem({
1136
1135
  // ...
1137
1136
  promotions: [
1138
- { id: "promotionId", code: "promotionCode" },
1137
+ { id: 'promotionId', code: 'promotionCode' },
1139
1138
  {
1140
- id: "promotionId2",
1139
+ id: 'promotionId2',
1141
1140
  },
1142
1141
  ],
1143
- });
1142
+ })
1144
1143
  ```
1145
1144
 
1146
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.
@@ -1152,7 +1151,6 @@
1152
1151
  **@scayle/storefront-core v8.42.0**
1153
1152
 
1154
1153
  - Minor
1155
-
1156
1154
  - Added `promotions` field to `BasketItem` type to support multiple promotions per basket item.
1157
1155
 
1158
1156
  The `promotions` field is an array of `BasketItemPromotion` objects.
@@ -1260,7 +1258,7 @@
1260
1258
  </template>
1261
1259
 
1262
1260
  <script setup lang="ts">
1263
- const { relativeReductions } = useProductPrice(price);
1261
+ const { relativeReductions } = useProductPrice(price)
1264
1262
  </script>
1265
1263
  ```
1266
1264
 
@@ -1275,7 +1273,7 @@
1275
1273
  </template>
1276
1274
 
1277
1275
  <script setup lang="ts">
1278
- const { appliedReductions } = useProductPrice(price);
1276
+ const { appliedReductions } = useProductPrice(price)
1279
1277
  </script>
1280
1278
  ```
1281
1279
 
@@ -1413,7 +1411,6 @@
1413
1411
  **@scayle/storefront-core v8.36.0**
1414
1412
 
1415
1413
  - Minor
1416
-
1417
1414
  - Created a new RPC method `getCampaign` to retrieve the first active campaign.
1418
1415
 
1419
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).
@@ -1501,7 +1498,6 @@
1501
1498
  **@scayle/storefront-core v8.33.0**
1502
1499
 
1503
1500
  - Minor
1504
-
1505
1501
  - Added test factories for order and all related types.
1506
1502
 
1507
1503
  It is now possible to build orders with factory functions for testing purposes.
@@ -1541,27 +1537,26 @@
1541
1537
  **@scayle/storefront-core v8.31.0**
1542
1538
 
1543
1539
  - Minor
1544
-
1545
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.
1546
1541
 
1547
1542
  ```ts
1548
- const { data } = useRpc("getFilters", "getFiltersKey", () => ({
1543
+ const { data } = useRpc('getFilters', 'getFiltersKey', () => ({
1549
1544
  where: {
1550
1545
  minReduction: 10,
1551
1546
  maxReduction: 20,
1552
1547
  },
1553
- }));
1548
+ }))
1554
1549
 
1555
1550
  const { data } = useRpc(
1556
- "getProductsByCategory",
1557
- "getProductsByCategoryKey",
1551
+ 'getProductsByCategory',
1552
+ 'getProductsByCategoryKey',
1558
1553
  () => ({
1559
1554
  where: {
1560
1555
  minReduction: 10,
1561
1556
  maxReduction: 20,
1562
1557
  },
1563
- })
1564
- );
1558
+ }),
1559
+ )
1565
1560
  ```
1566
1561
 
1567
1562
  ## 8.30.3
@@ -1606,35 +1601,34 @@
1606
1601
  **@scayle/storefront-core v8.30.0**
1607
1602
 
1608
1603
  - Minor
1609
-
1610
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.
1611
1605
 
1612
1606
  Existing RPC handlers can be easily migrated to use `defineRpcHandler` by passing the existing handler to `defineRpcHandler`.
1613
1607
 
1614
1608
  ```ts
1615
1609
  export const existingHandlerWithoutParams = async (_context: RpcContext) => {
1616
- return "existing handler";
1617
- };
1610
+ return 'existing handler'
1611
+ }
1618
1612
 
1619
1613
  export const existingHandlerWithParams = async (
1620
1614
  { name }: { name: string },
1621
- _context: RpcContext
1615
+ _context: RpcContext,
1622
1616
  ) => {
1623
- return name;
1624
- };
1617
+ return name
1618
+ }
1625
1619
 
1626
1620
  // will become
1627
1621
 
1628
1622
  export const existingHandlerWithoutParams = defineRpcHandler(
1629
1623
  async (_context: RpcContext) => {
1630
- return "existing handler";
1631
- }
1632
- );
1624
+ return 'existing handler'
1625
+ },
1626
+ )
1633
1627
  export const existingHandlerWithParams = defineRpcHandler(
1634
1628
  async ({ name }: { name: string }, _context: RpcContext) => {
1635
- return name;
1636
- }
1637
- );
1629
+ return name
1630
+ },
1631
+ )
1638
1632
  ```
1639
1633
 
1640
1634
  - Patch
@@ -1649,22 +1643,21 @@
1649
1643
  **@scayle/storefront-core v8.29.0**
1650
1644
 
1651
1645
  - Minor
1652
-
1653
1646
  - Added an `includeProductSorting` boolean parameter to all category RPC method endpoints (`getRootCategories`, `getCategoryByPath`, `getCategoriesByPath`, `getCategoryById`, `getCategoryTree`).
1654
1647
  This flag allows consumers to retrieve product sorting data, including the `smartSortingKey` and `customSortingKey` properties.
1655
1648
  Developers can leverage this data to seamlessly apply smart sorting keys on the product listing page by passing those parameters when fetching products.
1656
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.
1657
1650
 
1658
1651
  ```ts
1659
- import { rpcMethods } from "@scayle/storefront-core";
1652
+ import { rpcMethods } from '@scayle/storefront-core'
1660
1653
 
1661
- rpcMethods.getCategoryTree({ hideEmptyCategories: true }, rpcContext);
1654
+ rpcMethods.getCategoryTree({ hideEmptyCategories: true }, rpcContext)
1662
1655
  ```
1663
1656
 
1664
1657
  or
1665
1658
 
1666
1659
  ```ts
1667
- import { useCategoryTree } from "#storefront/composables";
1660
+ import { useCategoryTree } from '#storefront/composables'
1668
1661
 
1669
1662
  const { data: rootCategories, status } = useCategoryTree(
1670
1663
  {
@@ -1672,8 +1665,8 @@
1672
1665
  hideEmptyCategories: true,
1673
1666
  },
1674
1667
  },
1675
- "category-navigation-tree"
1676
- );
1668
+ 'category-navigation-tree',
1669
+ )
1677
1670
  ```
1678
1671
 
1679
1672
  ## 8.28.7
@@ -1770,9 +1763,9 @@
1770
1763
  params: {
1771
1764
  children: 10,
1772
1765
  includeHidden: true,
1773
- properties: { withName: ["sale"] },
1766
+ properties: { withName: ['sale'] },
1774
1767
  },
1775
- });
1768
+ })
1776
1769
  ```
1777
1770
 
1778
1771
  ### Patch Changes
@@ -1943,16 +1936,16 @@
1943
1936
  nitro: {
1944
1937
  storage: {
1945
1938
  redis: {
1946
- driver: "redis",
1947
- host: "localhost",
1939
+ driver: 'redis',
1940
+ host: 'localhost',
1948
1941
  },
1949
1942
  db: {
1950
- driver: "fs",
1951
- base: "./.data/db",
1943
+ driver: 'fs',
1944
+ base: './.data/db',
1952
1945
  },
1953
1946
  },
1954
1947
  },
1955
- });
1948
+ })
1956
1949
  ```
1957
1950
 
1958
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.
@@ -2008,7 +2001,6 @@
2008
2001
  **@scayle/storefront-core v8.23.0**
2009
2002
 
2010
2003
  - Minor
2011
-
2012
2004
  - Deprecated attribute group specific utilities `getFlattenedVariantCrosssellings` and
2013
2005
  `getFlattenedMaterialComposition`.
2014
2006
 
@@ -2025,9 +2017,9 @@
2025
2017
  ```typescript
2026
2018
  const idp = useIDP({
2027
2019
  authUrlParameters: {
2028
- theme: "dark",
2020
+ theme: 'dark',
2029
2021
  },
2030
- });
2022
+ })
2031
2023
  ```
2032
2024
 
2033
2025
  ### Patch Changes
@@ -2049,7 +2041,6 @@
2049
2041
  **@scayle/storefront-core v8.21.0**
2050
2042
 
2051
2043
  - Minor
2052
-
2053
2044
  - Expose the following filter types from `storefront-api`:
2054
2045
 
2055
2046
  - `FilterItemWithValues`
@@ -2169,25 +2160,22 @@
2169
2160
  storefront: {
2170
2161
  redirects: {
2171
2162
  enabled: true,
2172
- strategy: "on-missing",
2163
+ strategy: 'on-missing',
2173
2164
  },
2174
2165
  },
2175
2166
  },
2176
- });
2167
+ })
2177
2168
  ```
2178
2169
 
2179
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.
2180
-
2181
2171
  1. No route found
2182
2172
 
2183
- If there is no matching route for the request's path, the framework will return a 404 response.
2184
-
2185
- 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
2186
2174
 
2187
2175
  If the request handler returns a `Response` object with a `status` of 404, a 404 response will be returned to the client.
2188
2176
 
2189
2177
  ```typescript
2190
- return new Response(null, { status: 404 });
2178
+ return new Response(null, { status: 404 })
2191
2179
  ```
2192
2180
 
2193
2181
  3. Thrown H3Error with 404 status
@@ -2195,8 +2183,8 @@
2195
2183
  If the request handler throws an H3Error with a `statusCode` 404, a 404 response will be returned to the client.
2196
2184
 
2197
2185
  ```typescript
2198
- import { createError } from "h3";
2199
- throw createError({ statusCode: 404 });
2186
+ import { createError } from 'h3'
2187
+ throw createError({ statusCode: 404 })
2200
2188
  ```
2201
2189
 
2202
2190
  ### Patch Changes
@@ -2431,7 +2419,6 @@
2431
2419
  - Deprecate `key`, `packages`, `shippingDates`, `isEmpty`, `countWithoutSoldOutItems`, `removeItem`, `contains`, `findItem`, `products`, `generateBasketKey` and `mergeBaskets` from `useBasket`.
2432
2420
 
2433
2421
  Required updates:
2434
-
2435
2422
  - `key`:
2436
2423
 
2437
2424
  ```TypeScript
@@ -2638,28 +2625,28 @@
2638
2625
  **rpc-methods.ts**
2639
2626
 
2640
2627
  ```typescript
2641
- import type { RpcContext, RpcHandler } from "@scayle/storefront-nuxt";
2628
+ import type { RpcContext, RpcHandler } from '@scayle/storefront-nuxt'
2642
2629
 
2643
2630
  export const foo: RpcHandler<string, number> = function testing(
2644
2631
  param: string,
2645
- _: RpcContext
2632
+ _: RpcContext,
2646
2633
  ) {
2647
- return param.length;
2648
- };
2634
+ return param.length
2635
+ }
2649
2636
  ```
2650
2637
 
2651
2638
  **module.ts**
2652
2639
 
2653
2640
  ```typescript
2654
2641
  function setup() {
2655
- const resolver = createResolver(import.meta.url);
2642
+ const resolver = createResolver(import.meta.url)
2656
2643
 
2657
- nuxt.hook("storefront:custom-rpc:extend", (customRpcImports) => {
2644
+ nuxt.hook('storefront:custom-rpc:extend', (customRpcImports) => {
2658
2645
  customRpcImports.push({
2659
- source: resolver.resolve("./rpc-methods.ts"),
2660
- names: ["foo"],
2661
- });
2662
- });
2646
+ source: resolver.resolve('./rpc-methods.ts'),
2647
+ names: ['foo'],
2648
+ })
2649
+ })
2663
2650
  }
2664
2651
  ```
2665
2652
 
@@ -2870,7 +2857,6 @@
2870
2857
 
2871
2858
  You'll need to migrate your existing storage settings to the new `storefront.storage` format.
2872
2859
  Check the [SCAYLE Resource Center](https://scayle.dev/en/core-documentation/storefront-guide/storefront-application/technical-foundation/storage) for more details.
2873
-
2874
2860
  - _No Longer Supported: Legacy Storage Setup in (`nuxt.config.ts`):_
2875
2861
 
2876
2862
  ```ts
@@ -2881,23 +2867,23 @@
2881
2867
  storefront: {
2882
2868
  // ...
2883
2869
  redis: {
2884
- host: "localhost",
2870
+ host: 'localhost',
2885
2871
  port: 6379,
2886
- prefix: "",
2887
- user: "",
2888
- password: "",
2872
+ prefix: '',
2873
+ user: '',
2874
+ password: '',
2889
2875
  sslTransit: false,
2890
2876
  },
2891
2877
  // ...
2892
2878
  session: {
2893
2879
  // ...
2894
- provider: "redis",
2880
+ provider: 'redis',
2895
2881
  },
2896
2882
  },
2897
2883
  // ...
2898
2884
  },
2899
2885
  // ...
2900
- });
2886
+ })
2901
2887
  ```
2902
2888
 
2903
2889
  - _Current Unified Storage Approach (`nuxt.config.ts`):_
@@ -2911,13 +2897,13 @@
2911
2897
  // ...
2912
2898
  storage: {
2913
2899
  cache: {
2914
- driver: "redis",
2915
- host: "localhost",
2900
+ driver: 'redis',
2901
+ host: 'localhost',
2916
2902
  port: 6379,
2917
2903
  },
2918
2904
  session: {
2919
- driver: "redis",
2920
- host: "localhost",
2905
+ driver: 'redis',
2906
+ host: 'localhost',
2921
2907
  port: 6379,
2922
2908
  },
2923
2909
  // ...
@@ -2927,11 +2913,10 @@
2927
2913
  // ...
2928
2914
  },
2929
2915
  // ...
2930
- });
2916
+ })
2931
2917
  ```
2932
2918
 
2933
2919
  - **\[💥 BREAKING\]** The composable `useSearch` has been replaced by `useStorefrontSearch`, consolidating and transitioning to SCAYLE Search v2.
2934
-
2935
2920
  - _Previous Usage of `useSearch`:_
2936
2921
 
2937
2922
  ```ts
@@ -2953,7 +2938,6 @@
2953
2938
  ```
2954
2939
 
2955
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:
2956
-
2957
2941
  - `useProductsByCategory`: Replaces `useFacet` for fetching products within a specific category.
2958
2942
  - `useFilters` or `useProductListFilters`: Provide focused filter management capabilities.
2959
2943
 
@@ -2989,14 +2973,13 @@
2989
2973
 
2990
2974
  - **\[💥 BREAKING\]** We've renamed the `useNavigationTree` composable to `useNavigationTreeById` for better clarity. Its functionality, parameters and return values stay identical.
2991
2975
  - **\[💥 BREAKING\]** The composable `useQueryFilterState` has been superseded by the `useFilter` and `useAppliedFilters` (part of `@scayle/storefront-product-listing`) composables.
2992
-
2993
2976
  - _Previous Usage of `useQueryFilterState`:_
2994
2977
 
2995
2978
  ```ts
2996
2979
  const { activeFilters, applyFilters, resetFilterUrl, productConditions } =
2997
- useQueryFilterState();
2980
+ useQueryFilterState()
2998
2981
 
2999
- applyFilters({ brand: 23, sale: true, maxPrice: 100, minPrice: 0 });
2982
+ applyFilters({ brand: 23, sale: true, maxPrice: 100, minPrice: 0 })
3000
2983
  ```
3001
2984
 
3002
2985
  - _Current Usage of `useFilter` and `useAppliedFilters`:_
@@ -3009,70 +2992,68 @@
3009
2992
  resetFilters,
3010
2993
  resetPriceFilter,
3011
2994
  resetFilter,
3012
- } = useFilter();
2995
+ } = useFilter()
3013
2996
 
3014
- applyPriceFilter([0, 100]);
3015
- applyBooleanFilter("sale", true);
3016
- applyAttributeFilter("brand", 23);
2997
+ applyPriceFilter([0, 100])
2998
+ applyBooleanFilter('sale', true)
2999
+ applyAttributeFilter('brand', 23)
3017
3000
 
3018
- const route = useRoute();
3001
+ const route = useRoute()
3019
3002
  const {
3020
3003
  appliedFilter,
3021
3004
  appliedFiltersCount,
3022
3005
  appliedAttributeValues,
3023
3006
  appliedBooleanValues,
3024
3007
  areFiltersApplied,
3025
- } = useAppliedFilters(route);
3008
+ } = useAppliedFilters(route)
3026
3009
  ```
3027
3010
 
3028
3011
  - **\[💥 BREAKING\]** The `getBadgeLabel` helper function has been removed, giving you more control over badge label display.
3029
-
3030
3012
  - **Note:** This change doesn't affect projects using SCAYLE Storefront Boilerplate v1.0 or later.
3031
3013
  - For applications based on older versions or using `getBadgeLabel`, you can refer to the previous implementation below:
3032
3014
 
3033
3015
  ```ts
3034
3016
  const BadgeLabel = {
3035
- NEW: "new",
3036
- SOLD_OUT: "sold_out",
3037
- ONLINE_EXCLUSIVE: "online_exclusive",
3038
- SUSTAINABLE: "sustainable",
3039
- PREMIUM: "premium",
3040
- DEFAULT: "",
3041
- } 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
3042
3024
 
3043
3025
  type BadgeLabelParamsKeys =
3044
- | "isNew"
3045
- | "isSoldOut"
3046
- | "isOnlineOnly"
3047
- | "isSustainable"
3048
- | "isPremium";
3049
- type BadgeLabelParams = Partial<Record<BadgeLabelParamsKeys, boolean>>;
3026
+ | 'isNew'
3027
+ | 'isSoldOut'
3028
+ | 'isOnlineOnly'
3029
+ | 'isSustainable'
3030
+ | 'isPremium'
3031
+ type BadgeLabelParams = Partial<Record<BadgeLabelParamsKeys, boolean>>
3050
3032
 
3051
3033
  const getBadgeLabel = (params: BadgeLabelParams = {}): string => {
3052
3034
  if (!params) {
3053
- return BadgeLabel.DEFAULT;
3035
+ return BadgeLabel.DEFAULT
3054
3036
  }
3055
3037
  const { isNew, isSoldOut, isOnlineOnly, isSustainable, isPremium } =
3056
- params;
3038
+ params
3057
3039
 
3058
3040
  if (isNew) {
3059
- return BadgeLabel.NEW;
3041
+ return BadgeLabel.NEW
3060
3042
  } else if (isSoldOut) {
3061
- return BadgeLabel.SOLD_OUT;
3043
+ return BadgeLabel.SOLD_OUT
3062
3044
  } else if (isOnlineOnly) {
3063
- return BadgeLabel.ONLINE_EXCLUSIVE;
3045
+ return BadgeLabel.ONLINE_EXCLUSIVE
3064
3046
  } else if (isSustainable) {
3065
- return BadgeLabel.SUSTAINABLE;
3047
+ return BadgeLabel.SUSTAINABLE
3066
3048
  } else if (isPremium) {
3067
- return BadgeLabel.PREMIUM;
3049
+ return BadgeLabel.PREMIUM
3068
3050
  } else {
3069
- return BadgeLabel.DEFAULT;
3051
+ return BadgeLabel.DEFAULT
3070
3052
  }
3071
- };
3053
+ }
3072
3054
  ```
3073
3055
 
3074
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.
3075
-
3076
3057
  - For more information, please refer to the [documentation](https://scayle.dev/en/core-documentation/storefront-guide/storefront-application/technical-foundation/configuration#shops).
3077
3058
  - **NOTE:** These changes might impact your environment variables used for deployments. Please check your infrastructure and deployment setup and adapt accordingly!
3078
3059
  - _Previous Store Configuration in `nuxt.config.ts`:_
@@ -3092,7 +3073,7 @@
3092
3073
  // ...
3093
3074
  },
3094
3075
  // ...
3095
- });
3076
+ })
3096
3077
  ```
3097
3078
 
3098
3079
  - _Previous Environment Variables for Store Configuration:_
@@ -3121,7 +3102,7 @@
3121
3102
  // ...
3122
3103
  },
3123
3104
  // ...
3124
- });
3105
+ })
3125
3106
  ```
3126
3107
 
3127
3108
  - _Current Environment Variables for Shops Configuration:_
@@ -3135,14 +3116,13 @@
3135
3116
 
3136
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.
3137
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.
3138
-
3139
3119
  - _Previous `key` as options parameter:_
3140
3120
 
3141
3121
  ```ts
3142
3122
  useProduct({
3143
3123
  // ...
3144
- key: "productKey",
3145
- });
3124
+ key: 'productKey',
3125
+ })
3146
3126
  ```
3147
3127
 
3148
3128
  - _Current `key` as dedicated composables argument:_
@@ -3152,13 +3132,12 @@
3152
3132
  {
3153
3133
  // ...
3154
3134
  },
3155
- "productKey"
3156
- );
3135
+ 'productKey',
3136
+ )
3157
3137
  ```
3158
3138
 
3159
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.
3160
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.
3161
-
3162
3141
  - _Cookie format before `@scayle/storefront-nuxt@7.68.0`:_
3163
3142
  - `Set-Cookie: $session=s:fa3746f9-88c8-4065-a6c9-0c7bee473dd8.pSoaN6Q7iFHHyWKE7s9gQAqdDzGb9fS8a478P7PHLxw; Path=/de`
3164
3143
  - _Cookie format after `@scayle/storefront-nuxt@7.68.0`:_
@@ -3166,61 +3145,57 @@
3166
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.
3167
3146
 
3168
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.
3169
-
3170
3148
  - _Previous Usage of `handleIDPLoginCallback`:_
3171
3149
 
3172
3150
  ```ts
3173
- const { handleIDPLoginCallback } = await useIDP();
3151
+ const { handleIDPLoginCallback } = await useIDP()
3174
3152
 
3175
3153
  watch(
3176
3154
  () => route.query,
3177
3155
  async (query) => {
3178
3156
  if (query.code && isString(query.code)) {
3179
- await handleIDPLoginCallback(query.code);
3157
+ await handleIDPLoginCallback(query.code)
3180
3158
  }
3181
3159
  },
3182
- { immediate: true }
3183
- );
3160
+ { immediate: true },
3161
+ )
3184
3162
  ```
3185
3163
 
3186
3164
  - _Current Usage of `loginIDP`:_
3187
3165
 
3188
3166
  ```ts
3189
- const { loginIDP } = useAuthentication("login");
3167
+ const { loginIDP } = useAuthentication('login')
3190
3168
 
3191
3169
  onMounted(async () => {
3192
- await loginIDP(props.code);
3193
- });
3170
+ await loginIDP(props.code)
3171
+ })
3194
3172
  ```
3195
3173
 
3196
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.
3197
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`.
3198
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`.
3199
-
3200
3177
  - _Previous `useRpc` with `autoFetch`:_
3201
3178
 
3202
3179
  ```ts
3203
- useRpc("rpcMethod", key, params, { autoFetch: true });
3180
+ useRpc('rpcMethod', key, params, { autoFetch: true })
3204
3181
 
3205
- useUser({ autoFetch: true });
3182
+ useUser({ autoFetch: true })
3206
3183
  ```
3207
3184
 
3208
3185
  - _Current `useRpc` with `immediate`:_
3209
3186
 
3210
3187
  ```ts
3211
- useRpc("rpcMethod", key, params, { immediate: true });
3188
+ useRpc('rpcMethod', key, params, { immediate: true })
3212
3189
 
3213
- useUser({ immediate: true });
3190
+ useUser({ immediate: true })
3214
3191
  ```
3215
3192
 
3216
3193
  - **\[💥 BREAKING\]** The attribute `isCmsPreview` has been removed from `RpcContext`.
3217
3194
  - **\[💥 BREAKING\]** The attribute `storeCampaignKeyword` has been removed from `RpcContext`.
3218
-
3219
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.
3220
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.
3221
3197
 
3222
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`.
3223
-
3224
3199
  - _Previous `useStorefrontSearch` returning `fetching`:_
3225
3200
 
3226
3201
  ```ts
@@ -3230,24 +3205,23 @@
3230
3205
  getSearchSuggestions,
3231
3206
  fetching,
3232
3207
  ...searchData
3233
- } = useStorefrontSearch(searchQuery, { key });
3208
+ } = useStorefrontSearch(searchQuery, { key })
3234
3209
 
3235
- fetching.value; // true or false
3210
+ fetching.value // true or false
3236
3211
  ```
3237
3212
 
3238
3213
  - _Current `useStorefrontSearch` returning `status`:_
3239
3214
 
3240
3215
  ```ts
3241
3216
  const { data, resolveSearch, getSearchSuggestions, status, ...searchData } =
3242
- useStorefrontSearch(searchQuery, {}, key);
3217
+ useStorefrontSearch(searchQuery, {}, key)
3243
3218
 
3244
- status.value; // 'idle', 'pending', 'error' or 'success'
3219
+ status.value // 'idle', 'pending', 'error' or 'success'
3245
3220
  ```
3246
3221
 
3247
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.
3248
3223
 
3249
3224
  Old config
3250
-
3251
3225
  - _Previous `disableDefaultGetCachedDataOverride` in `nuxt.config.ts`:_
3252
3226
 
3253
3227
  ```ts
@@ -3266,7 +3240,7 @@
3266
3240
  // ...
3267
3241
  },
3268
3242
  // ...
3269
- });
3243
+ })
3270
3244
  ```
3271
3245
 
3272
3246
  - _Current `enableDefaultGetCachedDataOverride`in `nuxt.config.ts`:_
@@ -3291,14 +3265,13 @@
3291
3265
  // ...
3292
3266
  },
3293
3267
  // ...
3294
- });
3268
+ })
3295
3269
  ```
3296
3270
 
3297
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).
3298
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.
3299
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`.
3300
3274
  These changes enhance the developer experience and provide greater clarity and control over data fetching operations within components.
3301
-
3302
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`!
3303
3276
 
3304
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.
@@ -3306,14 +3279,13 @@
3306
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`.
3307
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.
3308
3281
  In order to have an RPC method use a specific status code, it should return a `Response` object.
3309
-
3310
3282
  - _Previous Usage with `BaseError`:_
3311
3283
 
3312
3284
  ```ts
3313
3285
  function myCustomRpc() {
3314
3286
  // ...
3315
3287
 
3316
- throw new BaseError(404);
3288
+ throw new BaseError(404)
3317
3289
  }
3318
3290
  ```
3319
3291
 
@@ -3323,7 +3295,7 @@
3323
3295
  function myCustomRpc() {
3324
3296
  // ...
3325
3297
 
3326
- return new Response(null, { status: 404 });
3298
+ return new Response(null, { status: 404 })
3327
3299
  }
3328
3300
  ```
3329
3301