# @scayle/storefront-nuxt

## 8.61.3

### Patch Changes

- Updated dependency `@vercel/nft@1.4.0` to `@vercel/nft@1.5.0`
- Fix `updateTokens` and `updateUser` return type from `void` to `Promise<void>` in `ContextWithSession`. The underlying implementations were already async (`await session.save()`), but the incorrect `void` type prevented call sites from knowing they needed to await the result. All call sites in the RPC methods and customer API now correctly await these calls, ensuring session state is persisted before execution continues.

**Dependencies**

**@scayle/storefront-core v8.61.3**

- Patch
  - Fix `updateTokens` and `updateUser` return type from `void` to `Promise<void>` in `ContextWithSession`. The underlying implementations were already async (`await session.save()`), but the incorrect `void` type prevented call sites from knowing they needed to await the result. All call sites in the RPC methods and customer API now correctly await these calls, ensuring session state is persisted before execution continues.

## 8.61.2

### Patch Changes

- Improved build-time loading of custom RPC modules when generating the
  `#virtual/rpcHttpMethods` manifest so Nuxt string aliases (for example `#shared`) resolve the same way
  as in app code during HTTP verb inference.
  - Resolved aliases from `@nuxt/kit` `resolvePath` (including virtual templates)
    are passed to Jiti together with an app-root parent URL so imports inside `rpcMethods` match dev
    behavior.
  - If a module still cannot be resolved or imported, those methods continue to default to `POST` with a
    logged warning.

- Added dependency `jiti@^2.6.1`

**Dependencies**

**@scayle/storefront-core v8.61.2**

- No changes in this release.

## 8.61.1

### Patch Changes

- Updated to `@scayle/unstorage-compression-driver@1.5.0`.
  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.

**Dependencies**

**@scayle/storefront-core v8.61.1**

- No changes in this release.

## 8.61.0

### Minor Changes

- **[RPC]** Added HTTP method support so read-only RPCs can use `GET` and unlock CDN and browser caching for public data — no changes needed for existing handlers.

  Pass `{ method }` as the second argument to `defineRpcHandler`. Omit it to keep the default `POST`.

  ```ts
  // Safe reads — eligible for CDN / browser caching
  export const getNavigation = defineRpcHandler(handler, { method: 'GET' })

  // Mutations
  export const updateBasketItem = defineRpcHandler(handler, { method: 'PUT' })
  export const deleteWishlistItem = defineRpcHandler(handler, {
    method: 'DELETE',
  })
  ```

  RPCs returning user-specific data (basket, wishlist, tokens) should stay on `POST` to prevent unintended caching.

### Patch Changes

- Updated dependency `@scayle/unstorage-compression-driver@workspace:*` to `@scayle/unstorage-compression-driver@catalog:`

**Dependencies**

**@scayle/storefront-core v8.61.0**

- Minor
  - **[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.

  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.

  ```ts
  import { defineRpcHandler, type RpcContext } from '@scayle/storefront-core'

  // Safe, public read — eligible for CDN/browser caching
  export const getNavigation = defineRpcHandler(
    async (context: RpcContext) => {
      /* ... */
    },
    { method: 'GET' },
  )

  // User-specific / Mutation — uses POST to prevent cache leakage
  export const getBasket = defineRpcHandler(
    async (context: RpcContext) => {
      /* ... */
    },
    // method defaults to 'POST'
  )
  ```

- Patch
  - Updated dependency `@scayle/storefront-api@workspace:*` to `@scayle/storefront-api@catalog:`
  - Updated dependency `@scayle/unstorage-scayle-kv-driver@workspace:*` to `@scayle/unstorage-scayle-kv-driver@catalog:`

## 8.60.1

### Patch Changes

**Dependencies**

**@scayle/storefront-core v8.60.1**

- No changes in this release.

## 8.60.0

### Minor Changes

- 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.

  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.

### Patch Changes

**Dependencies**

**@scayle/storefront-core v8.60.0**

- Minor
  - 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.

  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.

## 8.59.7

### Patch Changes

- Updated dependency `@vercel/nft@1.3.1` to `@vercel/nft@1.4.0`

**Dependencies**

- Updated dependency to @scayle/h3-session@0.6.3
- Updated dependency to @scayle/unstorage-compression-driver@1.3.0

**@scayle/storefront-core v8.59.7**

- Patch
  - Updated dependency `slugify@^1.6.6` to `slugify@^1.6.8`

## 8.59.6

### Patch Changes

**Dependencies**

- Updated dependency to @scayle/unstorage-compression-driver@1.3.0

**@scayle/storefront-core v8.59.6**

- No changes in this release.

## 8.59.5

### Patch Changes

**Dependencies**

- Updated dependency to @scayle/unstorage-compression-driver@1.3.0

**@scayle/storefront-core v8.59.5**

- No changes in this release.

## 8.59.4

### Patch Changes

**Dependencies**

**@scayle/storefront-core v8.59.4**

- Patch
  - 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.

  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.

## 8.59.3

### Patch Changes

- Updated dependency `@vercel/nft@1.2.0` to `@vercel/nft@1.3.0`

**Dependencies**

**@scayle/storefront-core v8.59.3**

- No changes in this release.

## 8.59.2

### Patch Changes

- Updated dependency `@vercel/nft@1.2.0` to `@vercel/nft@1.3.0`

**Dependencies**

**@scayle/storefront-core v8.59.2**

- Patch
  - Deprecated the `slugify` and `getProductPath` functions in `productHelpers.ts` due to compatibility issues with Nuxt 4.

  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.

  **Migration:**

  ```ts
  import baseSlugify from 'slugify'

  const slugify = (url: string | undefined): string => {
    return baseSlugify(url ?? '', {
      lower: true,
      remove: /[*+~.()'"!:@/#?]/g,
    })
  }

  const localePath = useLocalePath()

  const getProductDetailRoute = (
    id: number,
    name?: string,
    locale?: Locale,
  ): string => {
    return localePath(
      {
        name: 'p-productName-id',
        params: {
          productName: slugify(name),
          id: `${id}`,
        },
      },
      locale,
    )
  }
  ```

## 8.59.1

### Patch Changes

**Dependencies**

- Updated dependency to @scayle/h3-session@0.6.3
- Updated dependency to @scayle/unstorage-compression-driver@1.2.5

**@scayle/storefront-core v8.59.1**

- Patch
  - Fixed import compatibility issue with the `slugify` package in `productHelpers.ts` to support both ESM and CommonJS module formats.

  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.

## 8.59.0

### Patch Changes

**Dependencies**

- Updated dependency to @scayle/unstorage-compression-driver@1.2.5

**@scayle/storefront-core v8.59.0**

- Minor
  - Added type exports for similar products functionality by re-exporting `SimilarProductsEndpointParameters` and `SimilarProductsEndpointResponseData` from `@scayle/storefront-api`. These types enable type-safe usage of similar products endpoints throughout the storefront core.

## 8.58.0

### Minor Changes

- Introduced support for Nuxt 4 while maintaining full backward compatibility with Nuxt 3.
  This enables consumers to migrate to Nuxt 4 ahead of the Nuxt 3 end of support on 31 Jan 2026.
  - **Version Requirements:**
    - Nuxt 3: `v3.13.0+`
    - Nuxt 4: `v4.2.0+`

  **NOTE:** Please be aware that the SCAYLE Storefront Application itself does not yet support Nuxt 4. These package updates are a prerequisite. We recommend remaining on Nuxt 3 for your Storefront implementation until further notice.

  See the [Nuxt 4 Migration Guide](https://nuxt.com/docs/4.x/getting-started/upgrade) for general upgrade details.

### Patch Changes

**Dependencies**

**@scayle/storefront-core v8.58.0**

- No changes in this release.

## 8.57.3

### Patch Changes

- Updated dependency `@vercel/nft@1.1.1` to `@vercel/nft@1.2.0`

**Dependencies**

**@scayle/storefront-core v8.57.3**

- No changes in this release.

## 8.57.2

### Patch Changes

- Updated dependency `@opentelemetry/api@^1.9.0` to `@opentelemetry/api@catalog:`
- Updated dependency `@scayle/h3-session@0.6.2` to `@scayle/h3-session@workspace:*`
- Updated dependency `consola@^3.2.3` to `consola@catalog:`
- Updated dependency `defu@^6.1.4` to `defu@catalog:`
- Updated dependency `hookable@^5.5.3` to `hookable@catalog:`
- Updated dependency `jose@^6.0.8` to `jose@catalog:`
- Updated dependency `knitwork@^1.1.0` to `knitwork@catalog:`
- Updated dependency `schema-dts@1.1.5` to `schema-dts@catalog:`
- Updated dependency `ufo@^1.5.4` to `ufo@catalog:`
- Updated dependency `uncrypto@^0.1.3` to `uncrypto@catalog:`
- Updated dependency `utility-types@^3.11.0` to `utility-types@catalog:`
- This is an internal change only. The packages now use the PNPM catalog feature to ensure dependencies use the identical version across packages.

**Dependencies**

- Updated dependency to @scayle/h3-session@0.6.3
- Updated dependency to @scayle/unstorage-compression-driver@1.2.5

**@scayle/storefront-core v8.57.2**

- Patch
  - Updated dependency `hookable@^5.5.3` to `hookable@catalog:`
  - Updated dependency `jose@^6.0.8` to `jose@catalog:`
  - Updated dependency `ufo@^1.5.3` to `ufo@catalog:`
  - Updated dependency `uncrypto@^0.1.3` to `uncrypto@catalog:`
  - Updated dependency `utility-types@^3.11.0` to `utility-types@catalog:`
    - This is an internal change only. The packages now use the PNPM catalog feature to ensure dependencies use the identical version across packages.

## 8.57.1

### Patch Changes

- Updated dependency `@vueuse/core@13.9.0` to `@vueuse/core@catalog:`

**Dependencies**

**@scayle/storefront-core v8.57.1**

- No changes in this release.

## 8.57.0

### Patch Changes

**Dependencies**

- Updated dependency to @scayle/unstorage-compression-driver@1.2.4

**@scayle/storefront-core v8.57.0**

- Minor
  - **\[Navigation\]** Exported Navigation V2 API types to provide TypeScript support for the new navigation endpoints.

  The following types are now available from `@scayle/storefront-core`:
  - `GetNavigationV2Parameters` - Parameters for fetching navigation trees via the V2 API
  - `NavigationV2AllEndpointResponseData` - Response type for fetching all navigation trees
  - `NavigationV2ByReferenceEndpointResponseData` - Response type for fetching a navigation tree by reference key

  These types enable full TypeScript support when working with the Navigation V2 API, which uses reference keys instead of numeric IDs for more flexible navigation management.

## 8.56.0

### Minor Changes

- **\[Session\]** Added support for storing and managing custom data in sessions through the RPC context.

  The `RpcContext` now exposes a `sessionCustomData` property to read custom session data and an `updateSessionCustomData` method to update it.
  The `sessionCustomData` property may be `undefined` when no session exists or when no custom data has been set.
  The `SessionCustomData` interface can be augmented with TypeScript module augmentation to provide type safety for custom session properties.
  - **Type Augmentation Example:**

        ```ts
        // types/session.ts
        import '@scayle/storefront-nuxt'

        declare module '@scayle/storefront-nuxt' {
          interface SessionCustomData {
            yourCustomDataKey?: string
          }
        }
        ```

  - **Setting Custom Session Data Example:**

    ```ts
    // server/plugins/session-plugin.ts
    import { hasSession } from '@scayle/storefront-nuxt'
    import { defineNitroPlugin } from '#imports'

    export default defineNitroPlugin((nitroApp) => {
      nitroApp.hooks.hook('storefront:afterLogin', async (_data, context) => {
        // Check if we actually have a RpcContext with proper session data
        if (!hasSession(context)) {
          return
        }

        // Should you have set custom session data already in another hook,
        // it might be necessary to get existing data first.
        const sessionCustomData = context.sessionCustomData

        // The update functions overrides the customData object on a session.
        // Should you have set custom session data already in another hooks,
        // you need to pass it in addition to your new custom session data.
        context.updateSessionCustomData({
          ...sessionCustomData,
          yourCustomDataKey: 'Your Session CustomData Value',
        })

        // Before accessing your session custom data, you might want to use an
        // explicit early return conditional.
        if (!sessionCustomData) {
          return
        }

        // Your custom session data can also be accessedd directly via
        // nullish coalescing  depending on your needs.
        console.log(context.sessionCustomData?.yourCustomDataKey)
      })
    })
    ```

### Patch Changes

**Dependencies**

- Updated dependency to @scayle/unstorage-compression-driver@1.2.4

**@scayle/storefront-core v8.56.0**

- Minor
  - Added support for custom session data in the RPC context type definitions.

  The `ContextWithSession` interface now includes a `sessionCustomData` property (which may be `undefined`) to read custom session data and an `updateSessionCustomData` method to update it.
  The `ContextWithoutSession` interface has been updated accordingly to maintain type consistency.
  The `SessionCustomData` interface can be augmented using TypeScript module augmentation to provide type safety for custom session properties.

## 8.55.0

### Patch Changes

**Dependencies**

- Updated dependency to @scayle/unstorage-compression-driver@1.2.4

**@scayle/storefront-core v8.55.0**

- Minor
  - Updated the type of the `removeItemFromBasket` RPC to accurately reflect that error responses can be returned if removing an item from the basket fails (these error responses were already being returned before; only the type was updated). Additionally, the `clearBasket` RPC now removes items sequentially to avoid conflicts between basket updates and returns an error response if any items in the basket could not be removed.

## 8.54.0

### Patch Changes

- Updated dependency `@vercel/nft@1.0.0` to `@vercel/nft@1.1.1`

**Dependencies**

- Updated dependency to @scayle/unstorage-compression-driver@1.2.4

**@scayle/storefront-core v8.54.0**

- Minor
  - The `getCheckoutToken` RPC was updated to refresh the access token only when it was about to expire within 30 minutes. This change reduced unnecessary access token generation and minimized the risk of using outdated or revoked tokens.

## 8.53.3

### Patch Changes

- 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).

  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.
  - **Before:** Keys were static strings.
  - **After:** Keys can be reactive, enabling dynamic caching and automatic updates.

  ```ts
  // Before
  const { data } = await useRpc('getProduct', 'my-static-product-key', {
    productId: 123,
  })

  // After
  const productId = ref(123)

  // The key is now reactive. If `productId` changes, the key updates
  // to 'product-456' (for example) and triggers a new fetch.
  const { data } = await useRpc(
    'getProduct',
    () => `product-${productId.value}`,
    { productId },
  )
  ```

- Deprecated the `CheckoutEvent` type, which will be removed in the next major version.

  This type has been moved to the Storefront Application to better align with application-specific tracking requirements.

  If you are currently importing `CheckoutEvent` from `@scayle/storefront-nuxt`, you should migrate to using the type definition from the Storefront Application or define it locally in your codebase.

  The type definition remains unchanged, so you can copy it directly:

  ```ts
  import type { ShopUser } from '@scayle/storefront-nuxt'

  export interface CheckoutEvent {
    /** Action. */
    action?: 'authenticated'
    /** Type. */
    type?: 'tracking'
    /** User. */
    user: ShopUser
    /**
     * The OAuth 2.0 access token for the authenticated user.
     * This token can be used to access protected resources on behalf of the user.
     *
     * @see https://www.rfc-editor.org/rfc/rfc6749
     */
    accessToken: string
    /**
     * Details about a specific event within the checkout process.
     * This field is optional and is only used when tracking specific actions
     * like `add_to_cart` or `remove_from_cart`.
     *
     * @see https://scayle.dev/en/core-documentation/storefront/checkout-guide/tracking
     */
    event?: {
      /** Event name. */
      event: 'login' | 'add_to_cart' | 'remove_from_cart'
      /** Event status. */
      status: 'successful' | 'error'
    }
  }
  ```

- Updated the `StorefrontRuntimeConfig` type to ensure configured `shops` correctly incorporates all extended properties from `AdditionalShopConfig`.

  ```ts
  declare module '@scayle/storefront-nuxt' {
    // Extend the shop config
    export interface AdditionalShopConfig {
      extendedProp: string
    }
  }

  // `extendedProp` is now properly typed
  useRuntimeConfig().storefront.shops?.[shopId]?.extendedProp
  ```

**Dependencies**

**@scayle/storefront-core v8.53.3**

- No changes in this release.

## 8.53.2

### Patch Changes

- Introduced the `rpcDefaultLazy` configuration flag to streamline data fetching. When enabled via the `NUXT_PUBLIC_STOREFRONT_RPC_DEFAULT_LAZY` environment variable or by setting `rpcDefaultLazy` in your `nuxt.config.ts`, `useRpc` and derived composables like `useProducts` or `useBasket` will behave lazily by default. This eliminates the need to repeatedly pass `{ lazy: true }` in your component logic.

  **Examples:**

  ```ts
  // Before (or when `rpcDefaultLazy: false`)
  // You had to explicitly opt-in to lazy behavior
  const { data } = useRpc('someMethod', { some: 'param' }, { lazy: true })

  // After (when `rpcDefaultLazy: true`)
  // Lazy behavior is now the default
  const { data } = useRpc('someMethod', { some: 'param' })
  ```

**Dependencies**

**@scayle/storefront-core v8.53.2**

- No changes in this release.

## 8.53.1

### Patch Changes

- Updated dependency `@vercel/nft@0.30.3` to `@vercel/nft@1.0.0`

**Dependencies**

- Updated dependency to @scayle/unstorage-compression-driver@1.2.4

**@scayle/storefront-core v8.53.1**

- Patch
  - Updated `fetchAllFiltersForCategory`, `getFilters`, `getProductsCount`, and `getProductsByCategory` RPC methods to support `includeSoldOut`, `includeSellableForFree`, and `orFiltersOperator` parameters. These parameters are now correctly passed to the Storefront API client, ensuring consistent filtering behavior.

## 8.53.0

### Patch Changes

**Dependencies**

**@scayle/storefront-core v8.53.0**

- Minor
  - Added support for promotions on order items by introducing the `OrderItemPromotion` interface and extending the `OrderItem` type with an optional `promotions` field.

  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.
  Additionally, the `appliedReductions` array within the order item price now includes an optional `id` field, allowing for better tracking and identification of specific discount reductions.

  For further details, see the [Order API](https://scayle.dev/en/api-guides/storefront-api/resources/orders).

## 8.52.0

### Patch Changes

**Dependencies**

- Updated dependency to @scayle/unstorage-compression-driver@1.2.3

**@scayle/storefront-core v8.52.0**

- Minor
  - Extended the `OrderItem` type to support `'promotion'` as a valid category in `appliedReductions`, enabling proper type checking for promotion-based discounts in order items.

## 8.51.0

### Patch Changes

**Dependencies**

**@scayle/storefront-core v8.51.0**

- Minor
  - Added an email hash (`emailHash`) property to the user object returned by the `fetchUser` RPC method.

  The `emailHash` property is automatically included in all user objects returned by the RPCs.
  The email hash is calculated server-side using SHA256 and is automatically included when a user has an email address.
  This can be used e.g., for compliant user tracking and analytics without exposing sensitive email information.

## 8.50.0

### Minor Changes

- 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:
  - Ensures every shop has a domain property configured
  - Verifies that domains configured in the shop config are also present in the `@nuxtjs/i18n` configuration
  - Checks that all domains in the i18n configuration are unique (no duplicates)

  This validation can be disabled by setting the environment variable `SFC_PLUGIN_DOMAIN_CONFIG_VALIDATION_ENABLED` to `false` when building the application.

### Patch Changes

**Dependencies**

- Updated dependency to @scayle/unstorage-compression-driver@1.2.3

**@scayle/storefront-core v8.50.0**

- No changes in this release.

## 8.49.0

### Patch Changes

**Dependencies**

- Updated dependency to @scayle/unstorage-compression-driver@1.2.2

**@scayle/storefront-core v8.49.0**

- Minor
  - Exported the `sha256` utility function as part of the public API.

  This function provides a convenient way to calculate SHA256 hashes of strings using the Web Crypto API, returning hexadecimal strings.
  Developers can now use this utility directly instead of implementing their own hashing logic or importing external cryptographic libraries.

  Example:

  ```ts
  import { sha256 } from '@scayle/storefront-core'

  const hash = await sha256('hello')
  console.log(hash) // '2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824'
  ```

## 8.48.1

### Patch Changes

**Dependencies**

- Updated dependency to @scayle/unstorage-compression-driver@1.2.2

**@scayle/storefront-core v8.48.1**

- Patch
  - 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.

  Available keys:
  - `SmartSortingKey.SALES_PUSH` - Promotes items with highest discounts and oldest inventory
  - `SmartSortingKey.NEW_ARRIVALS` - Prioritizes recently added products with good availability
  - `SmartSortingKey.BALANCED_OFFERINGS` - Balances recency, availability, discounts, and sales data
  - `SmartSortingKey.INVENTORY_OPTIMIZATION` - Optimizes inventory turnover for high stock products
  - `SmartSortingKey.LUXURY_PROMOTION` - Highlights high-value luxury items with discounts
  - `SmartSortingKey.STOCK_COVERAGE` - Ensures broad variant availability across products
  - `SmartSortingKey.TOPSELLER` - Prioritizes products with strong sales performance
  - `SmartSortingKey.REVENUE_MAX` - Maximizes revenue by prioritizing high revenue products
  - `SmartSortingKey.RECENTLY_POPULAR` - Favors products with high recent sales performance

  These keys can be used with the `sortingKey` parameter in product queries and are intended to be used with descending sort order to return most relevant results first.

  For further information on smart product sorting and how to use smart sorting keys, visit: https://scayle.dev/en/core-documentation/the-basics/products/product-sorting

## 8.48.0

### Minor Changes

- Upgraded to `nuxt@3.20`.

  For more details check the [official Nuxt v3.20 release notes](https://github.com/nuxt/nuxt/releases/tag/v3.20.0).

### Patch Changes

**Dependencies**

**@scayle/storefront-core v8.48.0**

- No changes in this release.

## 8.47.0

### Patch Changes

**Dependencies**

- Updated dependency to @scayle/unstorage-compression-driver@1.2.2
- Updated dependency to @scayle/h3-session@0.6.2

**@scayle/storefront-core v8.47.0**

- Minor
  - Enhanced basket RPC methods to support order custom data functionality.

  All basket RPC methods now integrate with the `getOrderCustomData` RPC method to fetch and include order custom data in SAPI requests.
  This enables developers to attach order-specific custom metadata, business rules, or additional context to orders throughout the basket lifecycle.
  The existing `orderCustomData` parameter is deprecated and will be removed in the next major version.
  For now, both parameters are supported and merged together, where attributes from the parameter take precedence.

  On default, this RPC returns an empty object but can be overridden by the developer to return a custom object.

  Example `getOrderCustomData` RPC:

  ```typescript
  export const getOrderCustomData: RpcHandler<Record<string, unknown>> =
    defineRpcHandler<Record<string, unknown>>(async (context: RpcContext) => {
      return {
        customer: {
          groups: context.user?.groups,
        },
      }
    })
  ```

  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).
  - Updated all basket RPC methods to pass the customer access token to the SAPI client, enabling the `X-Customer-Token` header for promotion validation.

  The customer access token is now automatically included in basket requests when available.
  If the token has expired, it will be omitted from the request to prevent validation errors.

## 8.46.0

### Patch Changes

**Dependencies**

- Updated dependency to @scayle/unstorage-compression-driver@1.2.1

**@scayle/storefront-core v8.46.0**

- Minor
  - Added `getAttributeValuesByGroupId` function to the `attributeHelpers` helper for retrieving attribute values by their numeric attribute group ID.

  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.
  The existing `getAttributeValues` function has been renamed to `getAttributeValuesByName` to better differentiate between the two lookup methods.

  ### Usage Examples

  Both functions return an array of values for consistency, making them safe to use in iterations. For single-select attributes, the value is wrapped in an array. For multi-select attributes, the array is returned directly.

  #### Looking up by name (existing, now renamed):

  ```typescript
  import { getAttributeValuesByName } from '@scayle/storefront-core'

  // Single-select attribute
  const sizes = getAttributeValuesByName(product.attributes, 'size')
  // Returns: [{ id: 1, label: 'M', value: 'medium' }]

  // Multi-select attribute
  const colors = getAttributeValuesByName(product.attributes, 'color')
  // Returns: [{ id: 1, label: 'Red' }, { id: 2, label: 'Blue' }]

  // Non-existent attribute
  const missing = getAttributeValuesByName(product.attributes, 'doesNotExist')
  // Returns: []
  ```

  #### Looking up by group ID (new):

  ```typescript
  import { getAttributeValuesByGroupId } from '@scayle/storefront-core'

  // Look up attribute by its numeric ID from the SCAYLE API
  const promotionValues = getAttributeValuesByGroupId(product.attributes, 42)
  // Returns: [{ id: 123, label: 'Summer Sale', value: 'summer-2024' }]

  // Non-existent attribute group
  const missing = getAttributeValuesByGroupId(product.attributes, 9999)
  // Returns: []
  ```

  ### When to Use Each Function
  - **`getAttributeValuesByName`**: Use when you know the attribute name key (e.g., 'color', 'size'). This is the most common use case in application code.
  - **`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.

## 8.45.1

### Patch Changes

- Updated dependency `@vercel/nft@0.30.2` to `@vercel/nft@0.30.3`
- Updated SCAYLE Resource Center references

**Dependencies**

- Updated dependency to @scayle/unstorage-compression-driver@1.2.1

**@scayle/storefront-core v8.45.1**

- Patch
  - Updated SCAYLE Resource Center references

## 8.45.0

### Minor Changes

- The API routes structure was updated for multi-shop environments. The `apiBasePath` option was removed from per-shop configuration but remains configurable at the module level.

  NOTE: Update your `nuxt.config.ts` to ensure `routeRules` for `/api/**` uses the manually set `apiBasePath` value to prevent caching issues with session-related RPC's and potentially failing requests!

  **Before (per-shop apiBasePath):**

  ```typescript
  // This configuration is no longer supported
  runtimeConfig: {
    storefront: {
      shops: {
        1001: {
          shopId: 1001,
          path: 'de',
          apiBasePath: '/custom-api', // ❌ No longer supported
          // ... other shop config
        },
        1002: {
          shopId: 1002,
          path: 'en',
          apiBasePath: '/different-api', // ❌ No longer supported
          // ... other shop config
        }
      }
    }
  }
  ```

  **After (module-level apiBasePath):**

  ```typescript
  // nuxt.config.ts
  export default defineNuxtConfig({
    storefront: {
      apiBasePath: '/custom-api', // ✅ Configure globally for all shops
    },
    runtimeConfig: {
      storefront: {
        shops: {
          1001: {
            shopId: 1001,
            path: 'de',
            // ✅ apiBasePath removed from shop config
            // ... other shop config
          },
          1002: {
            shopId: 1002,
            path: 'en',
            // ✅ apiBasePath removed from shop config
            // ... other shop config
          },
        },
      },
    },
  })
  ```

  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.

### Patch Changes

**Dependencies**

**@scayle/storefront-core v8.45.0**

- No changes in this release.

## 8.44.2

### Patch Changes

- Updated dependency `@vercel/nft@0.30.1` to `@vercel/nft@0.30.2`

**Dependencies**

- Updated dependency to @scayle/unstorage-compression-driver@1.2.1

**@scayle/storefront-core v8.44.2**

- No changes in this release.

## 8.44.1

### Patch Changes

- Use latest `nuxt@3.19.2` for build. Compatibility with previous version has not changed and is specified via package `peerDependencies` and Nuxt `compatibility` flag.

**Dependencies**

**@scayle/storefront-core v8.44.1**

- No changes in this release.

## 8.44.0

### Patch Changes

**Dependencies**

- Updated dependency to @scayle/unstorage-compression-driver@1.2.1

**@scayle/storefront-core v8.44.0**

- Minor
  - Export `unwrap`, `generateBasketKey`, `generateWishlistKey` and `UnstorageCache`.

## 8.43.4

### Patch Changes

**Dependencies**

**@scayle/storefront-core v8.43.4**

- No changes in this release.

## 8.43.3

### Patch Changes

**Dependencies**

- Updated dependency to @scayle/unstorage-compression-driver@1.2.0

**@scayle/storefront-core v8.43.3**

- No changes in this release.

## 8.43.2

### Patch Changes

- Updated dependency `@vueuse/core@13.8.0` to `@vueuse/core@13.9.0`

**Dependencies**

**@scayle/storefront-core v8.43.2**

- No changes in this release.

## 8.43.1

### Patch Changes

**Dependencies**

**@scayle/storefront-core v8.43.1**

- No changes in this release.

## 8.43.0

### Patch Changes

**Dependencies**

- Updated dependency to @scayle/unstorage-compression-driver@1.2.0

**@scayle/storefront-core v8.43.0**

- Minor
  - Added an export of the new promotion type `ComboDealEffect`

  This type is also included in the `PromotionEffectType` type and can be used to check if the promotion is of type `ComboDealEffect`.

  Example:

  ```ts
  const isComboDealType = (
    promotion?: Promotion | null,
  ): promotion is Promotion<ComboDealEffect> => {
    return promotion?.effect?.type === PromotionEffectType.COMBO_DEAL
  }
  ```

## 8.42.2

### Patch Changes

**Dependencies**

**@scayle/storefront-core v8.42.2**

- No changes in this release.

## 8.42.1

### Patch Changes

- Updated dependency `@vueuse/core@13.7.0` to `@vueuse/core@13.8.0`

**Dependencies**

**@scayle/storefront-core v8.42.1**

- Patch
  - Increased the default cache timeout to 1000ms to reduce cases of prematurely skipping the cache.

## 8.42.0

### Minor Changes

- Added `promotions` field to `BasketItem` type to support multiple promotions per basket item.

  The `promotions` field is an array of `BasketItemPromotion` objects.
  With the introduction of the new `promotions` array field, the `promotion` field is now deprecated.

  Before:

  ```json
  "promotion": {
      "id": "123",
      "name": "Promotion 1",
      "isActive": true,
  }
  ```

  After:

  ```json
  "promotions": [{
      "id": "123",
      "name": "Promotion 1",
      "isActive": true,
  }]
  ```

  For more details, see the [Storefront API documentation](https://scayle.dev/en/api-guides/storefront-api/resources/baskets/get-a-basket).

- Updated the parameters of the RPC functions `updateBasketItemRpc` and `updateBasketItem` with the new `promotions` attribute.

  This attribute is used to support multiple promotions on basket items.

  Before:

  ```ts
  const updateBasketItemRpc = useRpcCall('updateBasketItem')
  const addItemToBasketRpc = useRpcCall('addItemToBasket')

  updateBasketItemRpc({
    // ...
    promotionId: 'promotionId',
    promotionCode: 'promotionCode',
  })

  addItemToBasketRpc({
    // ...
    promotionId: 'promotionId',
    promotionCode: 'promotionCode',
  })

  // Or with useBasket composable

  const { addItem } = useBasket()
  addItem({
    // ...
    promotionId: 'promotionId',
  })
  ```

  After:

  ```ts
  const updateBasketItemRpc = useRpcCall('updateBasketItem')
  const addItemToBasketRpc = useRpcCall('addItemToBasket')

  updateBasketItemRpc({
    // ...
    promotions: [
      { id: 'promotionId', code: 'promotionCode' },
      {
        id: 'promotionId2',
      },
    ],
  })

  addItemToBasketRpc({
    // ...
    promotions: [
      { id: 'promotionId', code: 'promotionCode' },
      {
        id: 'promotionId2',
      },
    ],
  })

  // Or for useBasket with composable

  const { addItem } = useBasket()
  addItem({
    // ...
    promotions: [
      { id: 'promotionId', code: 'promotionCode' },
      {
        id: 'promotionId2',
      },
    ],
  })
  ```

  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.

### Patch Changes

**Dependencies**

**@scayle/storefront-core v8.42.0**

- Minor
  - Added `promotions` field to `BasketItem` type to support multiple promotions per basket item.

  The `promotions` field is an array of `BasketItemPromotion` objects.
  With the introduction of the new `promotions` array field, the `promotion` field is now deprecated.

  Before:

  ```json
  "promotion": {
      "id": "123",
      "name": "Promotion 1",
      "isActive": true,
  }
  ```

  After:

  ```json
  "promotions": [{
      "id": "123",
      "name": "Promotion 1",
      "isActive": true,
  }]
  ```

  For more details, see the [Storefront API documentation](https://scayle.dev/en/api-guides/storefront-api/resources/baskets/get-a-basket).

## 8.41.4

### Patch Changes

- Updated dependency `@vercel/nft@0.30.0` to `@vercel/nft@0.30.1`

**Dependencies**

- Updated dependency to @scayle/unstorage-compression-driver@1.1.0

**@scayle/storefront-core v8.41.4**

- No changes in this release.

## 8.41.3

### Patch Changes

**Dependencies**

- Updated dependency to @scayle/unstorage-compression-driver@1.0.2

**@scayle/storefront-core v8.41.3**

- Patch
  - Fixed the case where a `postLogin` function was inadvertently registered as an RPC method.

## 8.41.2

### Patch Changes

**Dependencies**

**@scayle/storefront-core v8.41.2**

- No changes in this release.

## 8.41.1

### Patch Changes

**Dependencies**

**@scayle/storefront-core v8.41.1**

- Patch
  - Improved logging around cache errors to provide more details.

## 8.41.0

### Patch Changes

**Dependencies**

**@scayle/storefront-core v8.41.0**

- Minor
  - Introduce a new `updatePromotions` RPC method to wrap the Storefront API "Bulk update promotions" endpoint.
    This allows to update all promotions applied to basket's items in a single API call.
    For more details, see the [Storefront API documentation](https://scayle.dev/en/api-guides/storefront-api/resources/baskets/bulk-update-promotions).

## 8.40.0

### Minor Changes

- Deprecated `relativeReductions` in `useProductPrice` in favor of `appliedReductions`.

  Previously, `relativeReductions` did not return absolute reductions in the correct format.
  The new `appliedReductions` property returns all reductions as raw values, leaving formatting responsibilities to the component.

  Before:

  ```html
  <template>
    <span v-for="({ value, category }, index) in relativeReductions">
      -{{ value }}%
    </span>
  </template>

  <script setup lang="ts">
    const { relativeReductions } = useProductPrice(price)
  </script>
  ```

  After:

  ```html
  <template>
    <span v-for="({ amount, category, type }, index) in appliedReductions">
      -{{ type === 'relative' ? `${formatPercentage(amount.relative)}` :
      `${formatCurrency(amount.absoluteWithTax)}` }}
    </span>
  </template>

  <script setup lang="ts">
    const { appliedReductions } = useProductPrice(price)
  </script>
  ```

### Patch Changes

- Updated dependency `@vueuse/core@13.6.0` to `@vueuse/core@13.7.0`

**Dependencies**

- Updated dependency to @scayle/unstorage-compression-driver@1.0.1

**@scayle/storefront-core v8.40.0**

- No changes in this release.

## 8.39.1

### Patch Changes

**Dependencies**

- Updated dependency to @scayle/unstorage-compression-driver@1.0.1

**@scayle/storefront-core v8.39.1**

- Patch
  - Added `'token'` and `'code'` to the list of default `blacklistedKeys`. This will more proactively redact server logs to prevent leaked data.

## 8.39.0

### Minor Changes

- [OTEL] When recording span exceptions, also include the `error.cause` if it exists.

### Patch Changes

- Updated dependency `@vercel/nft@0.29.4` to `@vercel/nft@0.30.0`

**Dependencies**

**@scayle/storefront-core v8.39.0**

- Patch
  - Use a custom error type for OAuth API errors to improve troubleshooting OAuth errors.

## 8.38.4

### Patch Changes

- Updated dependency `@vueuse/core@13.5.0` to `@vueuse/core@13.6.0`

**Dependencies**

**@scayle/storefront-core v8.38.4**

- No changes in this release.

## 8.38.3

### Patch Changes

**Dependencies**

**@scayle/storefront-core v8.38.3**

- Patch
  - Refactored internals of `getOrderDataByCbd`. This change has no noticable impact.

## 8.38.2

### Patch Changes

- Fixed a compatibility issue with the Nuxt 4 directory structure where the `rpcDir` was not resolved correctly.

**Dependencies**

- Updated dependency to @scayle/unstorage-compression-driver@1.0.1

**@scayle/storefront-core v8.38.2**

- No changes in this release.

## 8.38.1

### Patch Changes

**Dependencies**

- Updated dependency to @scayle/unstorage-compression-driver@1.0.1

**@scayle/storefront-core v8.38.1**

- Patch
  - Resolved an issue where `Pagination` was not exported correctly as a `type`.

## 8.38.0

### Minor Changes

- Refined the `ContextWithoutSession` type to accurately represent actual data: `wishlistKey`, `basketKey`, and `sessionId` are now typed as `string` instead of `undefined`, since even logged-out users have these values set.

### Patch Changes

**Dependencies**

**@scayle/storefront-core v8.38.0**

- Minor
  - Refined the `ContextWithoutSession` type to accurately represent actual data: `wishlistKey`, `basketKey`, and `sessionId` are now typed as `string` instead of `undefined`, since even logged-out users have these values set.
  - Made `getCheckoutToken` callable by logged-in and not logged-in users. When called by a not logged-in user, the RPC returns only the `checkoutJWT`. For logged-in users, it continues to return both the `checkoutJWT` and a refreshed `accessToken` as before.

## 8.37.0

### Minor Changes

- Created the composable `useCampaign` which uses the RPC `getCampaign` to fetch the first active campaign

### Patch Changes

**Dependencies**

**@scayle/storefront-core v8.37.0**

- Minor
  - The `where` parameter for the `getProductsByCategory` and `getProductsCount` RPCs was extended to include the previously missing options `sellableAt`, `hasCampaignReduction`, and `containsSearch`.
- Patch
  - Added missing export of the RPC `getCampaign`

## 8.36.0

### Patch Changes

**Dependencies**

**@scayle/storefront-core v8.36.0**

- Minor
  - Created a new RPC method `getCampaign` to retrieve the first active campaign.

  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).

## 8.35.0

### Patch Changes

**Dependencies**

**@scayle/storefront-core v8.35.0**

- Minor
  - Removed optional key `fbook` from `ShopUser` interface
  - Renamed incorrectly formatted function `getBackurlFromBreadcrumbs` to `getBackURLFromBreadcrumbs`
- Patch
  - Renamed interface incorrectly named `IdenfitierFilterItemWithValues` to `IdentifierFilterItemWithValues`

## 8.34.1

### Patch Changes

- Updated dependency `zod@^3.23.8` to `zod@^4.0.0`

**Dependencies**

- Updated dependency to @scayle/unstorage-compression-driver@1.0.0

**@scayle/storefront-core v8.34.1**

- No changes in this release.

## 8.34.0

### Patch Changes

**Dependencies**

- Updated dependency to @scayle/unstorage-compression-driver@1.0.0

**@scayle/storefront-core v8.34.0**

- Minor
  - Added export of `Pagination` type.
  - **Breaking:** Improved type safety of the `mergeBaskets` RPC method. The method now returns the correct type `Promise<BasketResponse<Product, Variant> | AddManyItemsBasketResponse<Product, Variant> | undefined>` instead of `any`.

## 8.33.2

### Patch Changes

- Updated dependency `@scayle/storefront-core@8.32.0` to `@scayle/storefront-core@workspace:*`
- Updated dependency `@scayle/unstorage-compression-driver@^1.0.0` to `@scayle/unstorage-compression-driver@workspace:*`
- Updated dependency `@vueuse/core@13.4.0` to `@vueuse/core@13.5.0`

**Dependencies**

**@scayle/storefront-core v8.33.2**

- Patch
  - Updated dependency `@scayle/storefront-api@18.9.0` to `@scayle/storefront-api@workspace:*`
  - Updated dependency `@scayle/unstorage-scayle-kv-driver@1.0.2` to `@scayle/unstorage-scayle-kv-driver@workspace:*`

## 8.33.1

### Patch Changes

- Updated dependency `@scayle/storefront-core@8.32.0` to `@scayle/storefront-core@workspace:*`
- Updated dependency `@scayle/unstorage-compression-driver@^1.0.0` to `@scayle/unstorage-compression-driver@workspace:*`
- Updated dependency `@vueuse/core@13.4.0` to `@vueuse/core@13.5.0`

**Dependencies**

**@scayle/storefront-core v8.33.1**

- Patch
  - Updated dependency `@scayle/storefront-api@18.9.0` to `@scayle/storefront-api@workspace:*`
  - Updated dependency `@scayle/unstorage-scayle-kv-driver@1.0.2` to `@scayle/unstorage-scayle-kv-driver@workspace:*`

## 8.33.0

### Patch Changes

**Dependencies**

**@scayle/storefront-core v8.33.0**

- Minor
  - Added test factories for order and all related types.

  It is now possible to build orders with factory functions for testing purposes.
  This will reduce the amount of boilerplate code needed to create test data.

## 8.32.1

### Patch Changes

- Updated dependency `@scayle/storefront-core@8.31.0` to `@scayle/storefront-core@8.32.0`

**Dependencies**

**@scayle/storefront-core v8.32.1**

- No changes in this release.

## 8.32.0

### Patch Changes

**Dependencies**

**@scayle/storefront-core v8.32.0**

- Minor
  - Added `minReduction` and `maxReduction` filter parameters to the `FetchProductsCountParams.where` type and updated the `getProductsCount` RPC method to accept and handle these new reduction-based filtering conditions.
- Patch
  - Fixed the `getFilters` RPC method to properly apply `minReduction` and `maxReduction` filter parameters when fetching product counts.

## 8.31.0

### Patch Changes

**Dependencies**

**@scayle/storefront-core v8.31.0**

- Minor
  - 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.

  ```ts
  const { data } = useRpc('getFilters', 'getFiltersKey', () => ({
    where: {
      minReduction: 10,
      maxReduction: 20,
    },
  }))

  const { data } = useRpc(
    'getProductsByCategory',
    'getProductsByCategoryKey',
    () => ({
      where: {
        minReduction: 10,
        maxReduction: 20,
      },
    }),
  )
  ```

## 8.30.3

### Patch Changes

- Updated dependency `@vueuse/core@13.3.0` to `@vueuse/core@13.4.0`

**Dependencies**

**@scayle/storefront-core v8.30.3**

- No changes in this release.

## 8.30.2

### Patch Changes

**Dependencies**

**@scayle/storefront-core v8.30.2**

- Patch
  - Fixed an incorrect internal import for category related RPC methods. This should resolve potential type issues.

## 8.30.1

### Patch Changes

**Dependencies**

**@scayle/storefront-core v8.30.1**

- No changes in this release.

## 8.30.0

### Patch Changes

**Dependencies**

**@scayle/storefront-core v8.30.0**

- Minor
  - 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.

  Existing RPC handlers can be easily migrated to use `defineRpcHandler` by passing the existing handler to `defineRpcHandler`.

  ```ts
  export const existingHandlerWithoutParams = async (_context: RpcContext) => {
    return 'existing handler'
  }

  export const existingHandlerWithParams = async (
    { name }: { name: string },
    _context: RpcContext,
  ) => {
    return name
  }

  // will become

  export const existingHandlerWithoutParams = defineRpcHandler(
    async (_context: RpcContext) => {
      return 'existing handler'
    },
  )
  export const existingHandlerWithParams = defineRpcHandler(
    async ({ name }: { name: string }, _context: RpcContext) => {
      return name
    },
  )
  ```

- Patch
  - Removed unused `Awaited` and `PromiseReturnType` types.

## 8.29.0

### Patch Changes

**Dependencies**

**@scayle/storefront-core v8.29.0**

- Minor
  - Added an `includeProductSorting` boolean parameter to all category RPC method endpoints (`getRootCategories`, `getCategoryByPath`, `getCategoriesByPath`, `getCategoryById`, `getCategoryTree`).
    This flag allows consumers to retrieve product sorting data, including the `smartSortingKey` and `customSortingKey` properties.
    Developers can leverage this data to seamlessly apply smart sorting keys on the product listing page by passing those parameters when fetching products.
  - 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.

  ```ts
  import { rpcMethods } from '@scayle/storefront-core'

  rpcMethods.getCategoryTree({ hideEmptyCategories: true }, rpcContext)
  ```

  or

  ```ts
  import { useCategoryTree } from '#storefront/composables'

  const { data: rootCategories, status } = useCategoryTree(
    {
      params: {
        hideEmptyCategories: true,
      },
    },
    'category-navigation-tree',
  )
  ```

## 8.28.7

### Patch Changes

**Dependencies**

**@scayle/storefront-core v8.28.7**

- Patch
  - Fixed the return type of `flattenFieldSet` to reflect the flattened field set.

## 8.28.6

### Patch Changes

**Dependencies**

**@scayle/storefront-core v8.28.6**

- No changes in this release.

## 8.28.5

### Patch Changes

- Updated dependency `@vercel/nft@0.29.3` to `@vercel/nft@0.29.4`

**Dependencies**

- Updated dependency to @scayle/unstorage-compression-driver@1.0.0

**@scayle/storefront-core v8.28.5**

- No changes in this release.

## 8.28.4

### Patch Changes

- Added dependency `utility-types@^3.11.0`

**Dependencies**

**@scayle/storefront-core v8.28.4**

- No changes in this release.

## 8.28.3

### Patch Changes

- Updated `FormatCurrencyOptions` to mark `currency` as an optional param. When `currency` is not provided, the currency code for the current shop will be used. However, attempting to use this fallback could result in a TypeScript error due to the incorrect typing.

**Dependencies**

**@scayle/storefront-core v8.28.3**

- No changes in this release.

## 8.28.2

### Patch Changes

- Updated dependency `@vueuse/core@13.2.0` to `@vueuse/core@13.3.0`

**Dependencies**

**@scayle/storefront-core v8.28.2**

- No changes in this release.

## 8.28.1

### Patch Changes

- Exposed `useCategoryTree` through the `#storefront/composables` alias.

**Dependencies**

**@scayle/storefront-core v8.28.1**

- No changes in this release.

## 8.28.0

### Minor Changes

- Introduced the `useCategoryTree` composable for streamlined category tree retrieval.

  ```ts
  const { data, status, error } = useCategoryTree({
    params: {
      children: 10,
      includeHidden: true,
      properties: { withName: ['sale'] },
    },
  })
  ```

### Patch Changes

**Dependencies**

**@scayle/storefront-core v8.28.0**

- Minor
  - Introduced the `getCategoryTree` RPC for retrieving the complete category tree.

## 8.27.0

### Minor Changes

- Updated `useBasket` to include a `getApplicablePromotionsByCode` function. This function fetches the applicable promotions for the current basket.

### Patch Changes

**Dependencies**

**@scayle/storefront-core v8.27.0**

- Minor
  - Added a new `getApplicablePromotionsByCode` RPC method which can be used to fetch applicable promotions for a basket.

## 8.26.2

### Patch Changes

**Dependencies**

**@scayle/storefront-core v8.26.2**

- No changes in this release.

## 8.26.1

### Patch Changes

**Dependencies**

**@scayle/storefront-core v8.26.1**

- No changes in this release.

## 8.26.0

### Minor Changes

- **\[Utilities\]** Added `useProductPrice` composable to simplify accessing price data like total price, strike-through prices, and applied reductions.

### Patch Changes

**Dependencies**

**@scayle/storefront-core v8.26.0**

- No changes in this release.

## 8.25.6

### Patch Changes

**Dependencies**

**@scayle/storefront-core v8.25.6**

- No changes in this release.

## 8.25.5

### Patch Changes

- Updated dependency `@vueuse/core@13.1.0` to `@vueuse/core@13.2.0`

**Dependencies**

**@scayle/storefront-core v8.25.5**

- No changes in this release.

## 8.25.4

### Patch Changes

- Updated dependency `@vercel/nft@0.29.2` to `@vercel/nft@0.29.3`

**Dependencies**

**@scayle/storefront-core v8.25.4**

- No changes in this release.

## 8.25.3

### Patch Changes

**Dependencies**

**@scayle/storefront-core v8.25.3**

- Patch
  - Expose `MemberRole`, `FilterValuesEndpointParameters` and `GetRedirectsEndpointParameters` type

## 8.25.2

### Patch Changes

**Dependencies**

- Updated dependency to @scayle/unstorage-compression-driver@0.2.7

**@scayle/storefront-core v8.25.2**

- No changes in this release.

## 8.25.1

### Patch Changes

- Updated dependency `@scayle/h3-session@0.6.0` to `@scayle/h3-session@0.6.1`
- Updated dependency `@scayle/storefront-core@8.24.1` to `@scayle/storefront-core@8.25.0`

**Dependencies**

**@scayle/storefront-core v8.25.1**

- No changes in this release.

## 8.25.0

### Minor Changes

- This change introduces the ability for the host application to define its own storage mounts, enhancing the flexibility of managing cache and session storage options within the Nuxt project.
  To provide preconfigured storage mounts, the host application needs to mount storage drivers with specific names. The names `storefront-session` and `storefront-cache` are used for general cache and session storage, respectively. Additionally, shop-specific cache and session drivers can be configured by appending `:<shopId>` to the name, such as `storefront-session:1001` and `storefront-cache:1001`.

  Preconfigured storage mounts can be implemented via a Nuxt server plugin within `./server/plugins`. If necessary, the `runtimeConfig` can be utilized to store the drivers' configuration:

  ```ts
  import fsDriver from 'unstorage/drivers/fs'
  import compressionDriver from "@scayle/unstorage-compression-driver"
  import { defineNitroPlugin, useStorage } from '#imports'

  export default defineNitroPlugin(() => {
    const storage = useStorage()
    const config = useRuntimeConfig()
    // Configure global storage (used as base config for all shops)
    storage.mount('storefront-session', fsDriver({
      base: config.sessionStorageBase,
    }))
    storage.mount('storefront-cache', fsDriver({
      base: './cache',
    }))

    // The storage configuration can be overwritten on shop level if needed
    storage.mount('storefront-cache:1001', compressionDriver(
      encoding: 'brotli',
      passthroughDriver: fsDriver({ base: './cache_1001' })
    ))
  })
  ```

  In scenarios where the build must not be runtime agnostic, the storage can also be configured statically in the `nuxt.config.ts` file. However, this is not the recommended approach:

  ```ts
  export default defineNuxtConfig({
    nitro: {
      storage: {
        redis: {
          driver: 'redis',
          host: 'localhost',
        },
        db: {
          driver: 'fs',
          base: './.data/db',
        },
      },
    },
  })
  ```

  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.

### Patch Changes

- Fix `.d.ts` validation errors reported by AreTheTypesWrong.
- Fix an issue caused by Nitro 2.11.7 which caused the context to be lost between RPC requests.

**Dependencies**

- Updated dependency to @scayle/h3-session@0.6.1

**@scayle/storefront-core v8.25.0**

- Patch
  - **\[Code Style\]** Refactored brands and navigation tree RPCs to avoid destructuring the RPC context within function signatures

## 8.24.1

### Patch Changes

- Updated dependency `@scayle/storefront-core@8.23.0` to `@scayle/storefront-core@8.24.0`

**Dependencies**

**@scayle/storefront-core v8.24.1**

- No changes in this release.

## 8.24.0

### Minor Changes

- Update to `@nuxt/module-builder@1`. This version of Nuxt Module Builder is ESM-only, so CommonJS (`.cjs`) files will no longer be built or distributed with the package. However as of Nuxt 3, only esm is used so this should not have any impact as this module does not support Nuxt 2.

### Patch Changes

**Dependencies**

**@scayle/storefront-core v8.24.0**

- No changes in this release.

## 8.23.0

### Patch Changes

- Fix an issue where the `runtimeConfig` caching plugin returned a [frozen](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze) `runtimeConfig` object. The behavior should now match that of the `runtimeConfig` which is generated for each request and should ensure compatibility with any code which depends on modifying the `runtimeConfig` during a request.

**Dependencies**

**@scayle/storefront-core v8.23.0**

- Minor
  - Deprecated attribute group specific utilities `getFlattenedVariantCrosssellings` and
    `getFlattenedMaterialComposition`.

  These functions should be a part of the Storefront Application.

## 8.22.0

### Minor Changes

- The `useIDP` composable supports the `authUrlParameters` option for `getExternalIdpRedirects`. Values provided here will be processed by the Auth service and appended to the IDP URL.

  Example:

  ```typescript
  const idp = useIDP({
    authUrlParameters: {
      theme: 'dark',
    },
  })
  ```

### Patch Changes

**Dependencies**

**@scayle/storefront-core v8.22.0**

- Minor
  - Allow passing `authUrlParameters` to the `getExternalIdpRedirect` RPC method. This parameter is an optional `Record<string, string>`. Values provided here will be processed by the Auth service and appended to the final redirect URL.
  - Exported the `ShopCountryCustomData` interface.

## 8.21.0

### Patch Changes

**Dependencies**

**@scayle/storefront-core v8.21.0**

- Minor
  - Expose the following filter types from `storefront-api`:

  - `FilterItemWithValues`
  - `BooleanFilterItemWithValues`
  - `RangeFilterItemWithValues`
  - `IdentifierFilterItemWithValues`
  - `AttributesFilterValue`

## 8.20.1

### Patch Changes

**Dependencies**

**@scayle/storefront-core v8.20.1**

- Patch
  - Re-exported `BasketKey` and `ApplicablePromotion` from `@scayle/storefront-api`

## 8.20.0

### Minor Changes

- Add `originalIp` to the RPCContext which represents the IP address of the request without considering the `x-forwarded-for` header.

### Patch Changes

**Dependencies**

**@scayle/storefront-core v8.20.0**

- Minor
  - Include additional client information to Auth API requests to improve security.
  - Add `originalIp` to the RPCContext which represents the IP address of the request without considering the `x-forwarded-for` header.
- Patch
  - **\[Basket\]** Pass `campaignKey` to SAPI when updating an basket item using the `updateBasketItem` RPC.

## 8.19.1

### Patch Changes

**Dependencies**

**@scayle/storefront-core v8.19.1**

- Patch
  - Fix `getCategoriesByPath` RPC to return 404 for non-existing categories.

## 8.19.0

### Minor Changes

- Add a new `output` option to the log config. It controls where server-side logs are sent and can be set to `stderr`, `stdout` or `auto`. `stderr` and `stdout` will send all logs to the configured steam, while `auto` will send error logs `stderr` and other logs to `stdout`. `auto` is the default value.
- Add a new `json` option to the log config. When this is enabled via the nuxt.config or setting `NUXT_PUBLIC_STOREFRONT_LOG_JSON=true` in the `.env`, logs will be output in a JSON format.

### Patch Changes

- Updated dependency `@vueuse/core@13.0.0` to `@vueuse/core@13.1.0`

**@scayle/storefront-core v8.19.0**

**Dependencies**

## 8.18.0

### Patch Changes

**@scayle/storefront-core v8.18.0**

- Minor
  - Update RPC methods to use explicit typing. This is an internal change to enable Typescript's `isolatedDeclarations` option. It will not impact regular usage of RPC methods, however if you are importing one of the functions directly, the explicit rather than inferred type will be used.

**Dependencies**

## 8.17.1

### Patch Changes

- Updated dependency `@scayle/storefront-core@8.16.0` to `@scayle/storefront-core@8.17.0`
- Updated dependency `@scayle/unstorage-compression-driver@^0.2.4` to `@scayle/unstorage-compression-driver@^0.2.5`

**@scayle/storefront-core v8.17.1**

- Patch
  - Ensure that the `getAttribute` helper function can handle multi-value attributes.

**Dependencies**

- Updated dependency to @scayle/unstorage-compression-driver@0.2.6

## 8.17.0

### Patch Changes

**@scayle/storefront-core v8.17.0**

- Minor
  - Fix return type of `RpcMethodCall` to reflect that it returns a `Promise<TResult>` instead of `TResult`. This change emphasizes that `callRpc` in `RpcContext` is indeed an asynchronous operation.
- Patch
  - Ensure that `pricePromotionKey` set in the right place when calling the deletion wishlist item operation of SAPI.

**Dependencies**

- Updated dependency to @scayle/unstorage-compression-driver@0.2.5

## 8.16.0

### Minor Changes

- [Redirects] Extend the redirects feature with a new option: `redirects.strategy`. This property can be set to two values: `before-request` and `on-missing`. When set to `before-request`, the server will check for potential redirects before processing each request. This is the current behavior and will also be used when no value is set. When `on-missing` is used, the server will check for redirects only if the response for the request is a 404.

  To enable the new strategy, update your `nuxt.config.ts`.

  ```ts
  export default defineNuxtConfig({
    runtimeConfig: {
      storefront: {
        redirects: {
          enabled: true,
          strategy: 'on-missing',
        },
      },
    },
  })
  ```

  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.
  1. No route found

  If there is no matching route for the request's path, the framework will return a 404 response. 2. `Response` with 404 status

  If the request handler returns a `Response` object with a `status` of 404, a 404 response will be returned to the client.

  ```typescript
  return new Response(null, { status: 404 })
  ```

  3. Thrown H3Error with 404 status

  If the request handler throws an H3Error with a `statusCode` 404, a 404 response will be returned to the client.

  ```typescript
  import { createError } from 'h3'
  throw createError({ statusCode: 404 })
  ```

### Patch Changes

**@scayle/storefront-core v8.16.0**

**Dependencies**

## 8.15.1

### Patch Changes

**@scayle/storefront-core v8.15.1**

**Dependencies**

## 8.15.0

### Patch Changes

**@scayle/storefront-core v8.15.0**

- Minor
  - Filter out orders from `user.orderSummary` that are not associated with the current shop ID.

**Dependencies**

## 8.14.4

### Patch Changes

**@scayle/storefront-core v8.14.4**

**Dependencies**

## 8.12.4

### Patch Changes

**Dependencies**

- Updated dependency to @scayle/storefront-core@8.14.3

## 8.12.3

### Patch Changes

- [OTEL] Ensure the correct tracer is used when creating spans.

## 8.12.2

### Patch Changes

- [OTEL] Do not create bootstrap span when bootstrapping is skipped

**Dependencies**

- Updated dependency to @scayle/storefront-core@8.14.2

## 8.12.1

### Patch Changes

**Dependencies**

- Updated dependency to @scayle/storefront-core@8.14.1

## 8.12.0

### Minor Changes

- `OrderItem` and `Order` now accept generics: Both `OrderItem` and `Order` interfaces now accept generic type parameters for `Product` and `Variant`. Previously, these were implicitly typed as `Record<string, unknown>`. This change allows to strongly type the `product` and `variant` data within orders and order items, leading to better type checking and potentially fewer runtime errors. This allows for compile-time checks and autocompletion when working with `product` and `variant` properties of `OrderItem` and items property of `Order`.

### Patch Changes

**Dependencies**

- Updated dependency to @scayle/storefront-core@8.14.0

## 8.11.11

### Patch Changes

- Updated dependency `@vueuse/core@12.8.2` to `@vueuse/core@13.0.0`
- Added `@scayle/storefront-api@>=18.1.0` to `peerDependencies`.

**Dependencies**

- Updated dependency to @scayle/storefront-core@8.13.0

## 8.11.10

### Patch Changes

**Dependencies**

- Updated dependency to @scayle/storefront-core@8.12.3

## 8.11.9

### Patch Changes

**Dependencies**

- Updated dependency to @scayle/storefront-core@8.12.2

## 8.11.8

### Patch Changes

- Updated dependency `@vueuse/core@12.7.0` to `@vueuse/core@12.8.2`

## 8.11.7

### Patch Changes

**Dependencies**

- Updated dependency to @scayle/storefront-core@8.12.1

## 8.11.6

### Patch Changes

**Dependencies**

- Updated dependency to @scayle/storefront-core@8.12.0

## 8.11.5

### Patch Changes

**Dependencies**

- Updated dependency to @scayle/storefront-core@8.11.3

## 8.11.4

### Patch Changes

- Updated dependency `jose@^5.2.0` to `jose@^6.0.8`
- Updated dependency `schema-dts@1.1.2` to `schema-dts@1.1.5`

**Dependencies**

- Updated dependency to @scayle/storefront-core@8.11.2

## 8.11.3

### Patch Changes

- Support `@scayle/unstorage-scayle-kv-driver` for caching.

**Dependencies**

- Updated dependency to @scayle/storefront-core@8.11.1

## 8.11.2

### Patch Changes

- Updated dependency `@scayle/storefront-core@8.9.0` to `@scayle/storefront-core@8.10.0`

**Dependencies**

- Updated dependency to @scayle/storefront-core@8.11.0

## 8.11.1

### Patch Changes

**Dependencies**

- Updated dependency to @scayle/storefront-core@8.10.0

## 8.11.0

### Minor Changes

- Include `rpcCall` when building the context. This utility function can be used within RPC methods to invoke another RPC method.

### Patch Changes

**Dependencies**

- Updated dependency to @scayle/unstorage-compression-driver@0.2.4
- Updated dependency to @scayle/storefront-core@8.9.0

## 8.10.4

### Patch Changes

- Updated dependency `@vercel/nft@0.29.1` to `@vercel/nft@0.29.2`

## 8.10.3

### Patch Changes

**Dependencies**

- Updated dependency to @scayle/storefront-core@8.8.0

## 8.10.2

### Patch Changes

**Dependencies**

- Updated dependency to @scayle/storefront-core@8.7.1

## 8.10.1

### Patch Changes

- Added dependency `@vercel/nft@0.29.1`
- Add necessary runtime dependencies to nitro's external.inline config

## 8.10.0

### Minor Changes

- Remove explicit inline external for runtime helpers

### Patch Changes

- Updated dependency `@vueuse/core@12.6.1` to `@vueuse/core@12.7.0`

## 8.9.2

### Patch Changes

- Deprecate `key`, `packages`, `shippingDates`, `isEmpty`, `countWithoutSoldOutItems`, `removeItem`, `contains`, `findItem`, `products`, `generateBasketKey` and `mergeBaskets` from `useBasket`.

  Required updates:
  - `key`:

    ```TypeScript
    const { key } = useBasket()

    // will become

    const { data } = useBasket()
    const key = computed(() => data.value.key)
    ```

  - `packages`:

    ```TypeScript
    const { packages } = useBasket()

    // will become

    const { data } = useBasket()
    const packages = computed(() => data.value.packages)
    ```

  - `shippingDates`:

    ```TypeScript
    const { shippingDates } = useBasket()

    // will become
    import { getShippingDates } from '@scayle/storefront-nuxt'
    const { data } = useBasket()
    const shippingDates = computed(() => shippingDates(data.value.packages))
    ```

  - `isEmpty`:

    ```TypeScript
    const { isEmpty } = useBasket()

    // will become

    const { count } = useBasket()
    const isEmpty = computed(() => count.value === 0)
    ```

  - `countWithoutSoldOutItems`:

    ```TypeScript
    const { countWithoutSoldOutItems } = useBasket()

    // will become

    import { countAvailableBasketItems } from '#storefront-basket'
    const { items } = useBasket()
    const isEmpty = computed(() => countAvailableBasketItems(items.value ?? []))
    ```

  - `products`:

    ```TypeScript
    const { products } = useBasket()

    // will become

    import { findItem } from '#storefront-basket'
    const { items } = useBasket()
    const products = computed(() => items.value?.map((item) => item.product))
    ```

  - `removeItem`:

    ```TypeScript
    const { removeItem, items } = useBasket()
    removeItem({ variantId: items.value[0].variant.id })

    // will become

    const { removeItemByKey, items } = useBasket()
    removeItemByKey(items.value[0].key)
    ```

  - `contains`:

    ```TypeScript
    const { contains } = useBasket()
    const isInBasket = contains({ variantId: 1 })

    // will become

    import { contains } from '#storefront-basket'
    const { items } = useBasket()
    const isInBasket = contains({ variantId: 1 }, items.value ?? [])
    ```

  - `findItem`:

    ```TypeScript
    const { findItem } = useBasket()
    const basketItem = findItem({ variantId: 1 })

    // will become

    import { findItem } from '#storefront-basket'
    const { items } = useBasket()
    const basketItem = findItem({ variantId: 1 }, items.value ?? [])
    ```

  - `generateBasketKey`:

    ```TypeScript
    const { generateBasketKey } = useBasket()

    // will become

    import { generateBasketKey } from '@scayle/storefront-core/dist/utils/keys'
    ```

  - `generateBasketKey`:

    ```TypeScript
    const { mergeBaskets } = useBasket()
    mergeBaskets('oldKey', 'newKey')
    // will become

    const mergeBasket = useRpcCall('mergeBaskets')
    mergeBaskets('oldKey', 'newKey')
    ```

- Improve bootstrap performance by avoiding object merge and reflection

**Dependencies**

- Updated dependency to @scayle/storefront-core@8.7.0

## 8.9.1

### Patch Changes

- Updated dependency `@vueuse/core@12.5.0` to `@vueuse/core@12.6.1`

**Dependencies**

- Updated dependency to @scayle/storefront-core@8.6.1

## 8.9.0

### Minor Changes

- Update `ExistingItemHandling` names due to update to newest `@scayle/storefront-core` version.

### Patch Changes

**Dependencies**

- Updated dependency to @scayle/storefront-core@8.6.0

## 8.8.2

### Patch Changes

**Dependencies**

- Updated dependency to @scayle/storefront-core@8.5.0

## 8.8.1

### Patch Changes

- Deprecate `useSearchData` in favor of `useSearch` within the `@scayle/storefront-search` package.

## 8.8.0

### Minor Changes

- [Rpc] Add check for the existence of the rpc directory, in order to prevent errors when trying import custom Rpc's.

## 8.7.2

### Patch Changes

**Dependencies**

- Updated dependency to @scayle/storefront-core@8.4.0

## 8.7.1

### Patch Changes

**Dependencies**

- Updated dependency to @scayle/storefront-core@8.3.2

## 8.7.0

### Minor Changes

- Introduce a flexible interface for registering custom RPC methods from other modules

  Currently, applications can configure `rpcDir` and `rpcMethodNames` in the module configuration to register custom RPC methods, however this does not extend to modules.
  This release adds a new module hook `storefront:custom-rpc:extend` which can be used to register custom RPC methods.
  By registering a callback to this hook, other modules can add custom RPC methods to the application.

  The hook functions similarly to `rpcDir` and `rpcMethodNames`. Hook registrants receive an array of custom RPC imports and can add their own. The import definition should include a `source` which defines the file to import the RPC methods from and a `names` array which controls the exports of this file which should be registered as RPC methods.

  **rpc-methods.ts**

  ```typescript
  import type { RpcContext, RpcHandler } from '@scayle/storefront-nuxt'

  export const foo: RpcHandler<string, number> = function testing(
    param: string,
    _: RpcContext,
  ) {
    return param.length
  }
  ```

  **module.ts**

  ```typescript
  function setup() {
    const resolver = createResolver(import.meta.url)

    nuxt.hook('storefront:custom-rpc:extend', (customRpcImports) => {
      customRpcImports.push({
        source: resolver.resolve('./rpc-methods.ts'),
        names: ['foo'],
      })
    })
  }
  ```

  As part of this change, the `RPCMethod` types are automatically extended with all custom RPC methods.
  It is no longer necessary to extend `RpcMethodsStorefront`.
  This applies both for the `rpcDir` + `rpcMethodNames` strategy as well as the new hook-based implementation.

### Patch Changes

- [RPC] Improve warning about missing RPC method overrides
- Improve error handling when bootstrapping fails due to a missing shop.

## 8.6.1

### Patch Changes

- Consider `baseURL` configuration when bootstrapping error pages. This ensures error pages have the correct `currentShop`.

## 8.6.0

### Minor Changes

- [Basket] Add support to update existing basket items to `useBasket`

## 8.5.4

### Patch Changes

**Dependencies**

- Updated dependency to @scayle/storefront-core@8.3.1

## 8.5.3

### Patch Changes

**Dependencies**

- Updated dependency to @scayle/storefront-core@8.3.0

## 8.5.2

### Patch Changes

**Dependencies**

- Updated dependency to @scayle/storefront-core@8.2.2

## 8.5.1

### Patch Changes

- Updated dependency `@vueuse/core@12.4.0` to `@vueuse/core@12.5.0`

**Dependencies**

- Updated dependency to @scayle/storefront-core@8.2.1

## 8.5.0

### Minor Changes

- [Performance] Remove the 'autobinding' of the methods on the `Cached` instance. Instead the `execute` method only is bound when constructing the `RpcContext`. This simplifies the code and improves the performance of the `bootstrap` function. This change is internal to `storefront-core` and the API of `RpcContext` is unchanged.

### Patch Changes

**Dependencies**

- Updated dependency to @scayle/storefront-core@8.2.0
- Updated dependency to @scayle/h3-session@0.6.0

## 8.4.0

### Minor Changes

- Do not save empty sessions by default. This should significantly reduce the usage of the session database, especially in scenarios with many unique anonymous visitors.

### Patch Changes

- Use `consola` for config validation output to align with overall usage across Storefront and Nuxt.

## 8.3.4

### Patch Changes

**Dependencies**

- Updated dependency to @scayle/storefront-core@8.1.5

## 8.3.3

### Patch Changes

- Updated dependency `@vueuse/core@12.3.0` to `@vueuse/core@12.4.0`

## 8.3.2

### Patch Changes

- Removed dependency `@nuxt/kit@^3.12.2`
- Fixed misspelling of interface `BasketItemDisplayDataItem` to `BasketItemDisplayDataItem`

**Dependencies**

- Updated dependency to @scayle/storefront-core@8.1.4

## 8.3.1

### Patch Changes

**Dependencies**

- Updated dependency to @scayle/h3-session@0.5.1

## 8.3.0

### Minor Changes

- Complete removal of shop-prefixed API endpoints. In version 8.0.0, support for shop-prefixed API endpoints was dropped. However, not all the code was removed until now.

## 8.2.1

### Patch Changes

- Updated dependency `@vueuse/core@12.0.0` to `@vueuse/core@12.3.0`

**Dependencies**

- Updated dependency to @scayle/unstorage-compression-driver@0.2.3
- Updated dependency to @scayle/storefront-core@8.1.3

## 8.2.0

### Minor Changes

- `storefront-nuxt` now includes experimental support for OpenTelemetry spans covering the bootstrapping and redirects middlewares. This aims to provide better insights into their performance impact. Please note that this is an experimental feature and its implementation and API might change in future releases.

### Patch Changes

- Updated dependency `@scayle/h3-session@^0.5.0` to `@scayle/h3-session@0.5.0`

## 8.1.6

### Patch Changes

**Dependencies**

- Updated dependency to @scayle/h3-session@0.5.0
- Updated dependency to @scayle/unstorage-compression-driver@0.2.2

## 8.1.5

### Patch Changes

- Updated dependency `@scayle/h3-session@^0.4.1` to `@scayle/h3-session@^0.4.2`
- Updated to `@scayle/h3-session@0.4.2`

## 8.1.4

### Patch Changes

- We've updated to `nuxt@3.14`

## 8.1.3

### Patch Changes

**Dependencies**

- Updated dependency to @scayle/unstorage-compression-driver@0.2.0

## 8.1.2

### Patch Changes

**Dependencies**

- Updated dependency to @scayle/storefront-core@8.1.2

## 8.1.1

### Patch Changes

**Dependencies**

- Updated dependency to @scayle/storefront-core@8.1.1

## 8.1.0

### Minor Changes

- **Breaking:** `useBasket` no longer accepts `orderCustomData` in its parameters. This functionality was unintentionally added and was never officially supported. Now it has been removed.

## 8.0.1

### Patch Changes

**Dependencies**

- Updated dependency to @scayle/storefront-core@8.1.0

## 8.0.0

### Major Changes

- **\[💥 BREAKING\]** Removed deprecated `transformLegacyConfig` function in favor of the new unified `storefront.storage` configuration system.
  Legacy configuration options `provider` and `redis` configuration are no longer supported and have been deprecated since Storefront Boilerplate v1.0.0-rc.05.

  You'll need to migrate your existing storage settings to the new `storefront.storage` format.
  Check the [SCAYLE Resource Center](https://scayle.dev/en/core-documentation/storefront-guide/storefront-application/technical-foundation/storage) for more details.
  - _No Longer Supported: Legacy Storage Setup in (`nuxt.config.ts`):_

    ```ts
    export default defineNuxtConfig({
      // ...
      runtimeConfig: {
        // ...
        storefront: {
          // ...
          redis: {
            host: 'localhost',
            port: 6379,
            prefix: '',
            user: '',
            password: '',
            sslTransit: false,
          },
          // ...
          session: {
            // ...
            provider: 'redis',
          },
        },
        // ...
      },
      // ...
    })
    ```

  - _Current Unified Storage Approach (`nuxt.config.ts`):_

    ```ts
    export default defineNuxtConfig({
      // ...
      runtimeConfig: {
        // ...
        storefront: {
          // ...
          storage: {
            cache: {
              driver: 'redis',
              host: 'localhost',
              port: 6379,
            },
            session: {
              driver: 'redis',
              host: 'localhost',
              port: 6379,
            },
            // ...
          },
          // ...
        },
        // ...
      },
      // ...
    })
    ```

- **\[💥 BREAKING\]** The composable `useSearch` has been replaced by `useStorefrontSearch`, consolidating and transitioning to SCAYLE Search v2.
  - _Previous Usage of `useSearch`:_

    ```ts
    const { search, data } = useSearch({ params: { with: ...}, key: 'search' })

    search({term: 'searchTerm', slug: 'slug', productLimit: 10})
    ```

  - _Current Usage of `useStorefrontSearch`:_

    ```ts
    const searchTerm = ref()

    const { data, resolveSearch } = useStorefrontSearch(searchTerm, { categoryId: ..., with: { ... } }, 'search')
    //data contains search suggestions

    resolveSearch()
    //data contains search results
    ```

- **\[💥 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:
  - `useProductsByCategory`: Replaces `useFacet` for fetching products within a specific category.
  - `useFilters` or `useProductListFilters`: Provide focused filter management capabilities.

  - _Previous Usage of `useFacet`:_

    ```ts
    const {products, category, filters, ...} = useFacet()
    ```

  - _Current Usage of dedicated Category-Specific Composables:_

    ```ts
    const { data: category } = useCategoryById({
      params: {
        id,
        children: 0,
        properties: { withName: ['sale'] },
      },
    }, 'current-category-id')

    const {
      products,
      pagination,
      fetching,
      totalProductsCount,
      paginationOffset,
    } = useProductsByCategory(currentCategoryId, route)

    const { availableFilters } = useFilters({
      ...
    });
    ```

- **\[💥 BREAKING\]** We've renamed the `useNavigationTree` composable to `useNavigationTreeById` for better clarity. Its functionality, parameters and return values stay identical.
- **\[💥 BREAKING\]** The composable `useQueryFilterState` has been superseded by the `useFilter` and `useAppliedFilters` (part of `@scayle/storefront-product-listing`) composables.
  - _Previous Usage of `useQueryFilterState`:_

    ```ts
    const { activeFilters, applyFilters, resetFilterUrl, productConditions } =
      useQueryFilterState()

    applyFilters({ brand: 23, sale: true, maxPrice: 100, minPrice: 0 })
    ```

  - _Current Usage of `useFilter` and `useAppliedFilters`:_

    ```ts
    const {
      applyPriceFilter,
      applyBooleanFilter,
      applyAttributeFilter,
      resetFilters,
      resetPriceFilter,
      resetFilter,
    } = useFilter()

    applyPriceFilter([0, 100])
    applyBooleanFilter('sale', true)
    applyAttributeFilter('brand', 23)

    const route = useRoute()
    const {
      appliedFilter,
      appliedFiltersCount,
      appliedAttributeValues,
      appliedBooleanValues,
      areFiltersApplied,
    } = useAppliedFilters(route)
    ```

- **\[💥 BREAKING\]** The `getBadgeLabel` helper function has been removed, giving you more control over badge label display.
  - **Note:** This change doesn't affect projects using SCAYLE Storefront Boilerplate v1.0 or later.
  - For applications based on older versions or using `getBadgeLabel`, you can refer to the previous implementation below:

    ```ts
    const BadgeLabel = {
      NEW: 'new',
      SOLD_OUT: 'sold_out',
      ONLINE_EXCLUSIVE: 'online_exclusive',
      SUSTAINABLE: 'sustainable',
      PREMIUM: 'premium',
      DEFAULT: '',
    } as const

    type BadgeLabelParamsKeys =
      | 'isNew'
      | 'isSoldOut'
      | 'isOnlineOnly'
      | 'isSustainable'
      | 'isPremium'
    type BadgeLabelParams = Partial<Record<BadgeLabelParamsKeys, boolean>>

    const getBadgeLabel = (params: BadgeLabelParams = {}): string => {
      if (!params) {
        return BadgeLabel.DEFAULT
      }
      const { isNew, isSoldOut, isOnlineOnly, isSustainable, isPremium } =
        params

      if (isNew) {
        return BadgeLabel.NEW
      } else if (isSoldOut) {
        return BadgeLabel.SOLD_OUT
      } else if (isOnlineOnly) {
        return BadgeLabel.ONLINE_EXCLUSIVE
      } else if (isSustainable) {
        return BadgeLabel.SUSTAINABLE
      } else if (isPremium) {
        return BadgeLabel.PREMIUM
      } else {
        return BadgeLabel.DEFAULT
      }
    }
    ```

- **\[💥 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.
  - For more information, please refer to the [documentation](https://scayle.dev/en/core-documentation/storefront-guide/storefront-application/technical-foundation/configuration#shops).
  - **NOTE:** These changes might impact your environment variables used for deployments. Please check your infrastructure and deployment setup and adapt accordingly!
  - _Previous Store Configuration in `nuxt.config.ts`:_

    ```ts
    export default defineNuxtConfig({
      // ...
      runtimeConfig: {
        // ...
        storefront: {
          // ...
          store: {
            // ...
          },
          // ...
        },
        // ...
      },
      // ...
    })
    ```

  - _Previous Environment Variables for Store Configuration:_

    ```env
    NUXT_STOREFRONT_STORE_{UNIQUE_IDENTIFIER}_CHECKOUT_USER=''
    NUXT_STOREFRONT_STORE_{UNIQUE_IDENTIFIER}_CHECKOUT_TOKEN=''
    NUXT_STOREFRONT_STORE_{UNIQUE_IDENTIFIER}_CHECKOUT_SECRET=''
    NUXT_STOREFRONT_STORE_{UNIQUE_IDENTIFIER}_CHECKOUT_HOST=''
    ```

  - _Current Shops Configuration in `nuxt.config.ts`:_

    ```ts
    export default defineNuxtConfig({
      // ...
      runtimeConfig: {
        // ...
        storefront: {
          // ...
          shops: {
            // ...
          },
          // ...
        },
        // ...
      },
      // ...
    })
    ```

  - _Current Environment Variables for Shops Configuration:_

    ```env
    NUXT_STOREFRONT_SHOPS_{UNIQUE_IDENTIFIER}_CHECKOUT_USER=''
    NUXT_STOREFRONT_SHOPS_{UNIQUE_IDENTIFIER}_CHECKOUT_TOKEN=''
    NUXT_STOREFRONT_SHOPS_{UNIQUE_IDENTIFIER}_CHECKOUT_SECRET=''
    NUXT_STOREFRONT_SHOPS_{UNIQUE_IDENTIFIER}_CHECKOUT_HOST=''
    ```

- **\[💥 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.
  Instead of placing the key within the composable's options object, you'll now provide it as the second argument when calling the composable.
  - _Previous `key` as options parameter:_

    ```ts
    useProduct({
      // ...
      key: 'productKey',
    })
    ```

  - _Current `key` as dedicated composables argument:_

    ```ts
    useProduct(
      {
        // ...
      },
      'productKey',
    )
    ```

- **\[💥 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.
  Instead of relying on the Path attribute, each shop receives a distinct cookie name. This change is internal and should not require code modifications.
  - _Cookie format before `@scayle/storefront-nuxt@7.68.0`:_
    - `Set-Cookie: $session=s:fa3746f9-88c8-4065-a6c9-0c7bee473dd8.pSoaN6Q7iFHHyWKE7s9gQAqdDzGb9fS8a478P7PHLxw; Path=/de`
  - _Cookie format after `@scayle/storefront-nuxt@7.68.0`:_
    - `Set-Cookie: $session-1001=s:fa3746f9-88c8-4065-a6c9-0c7bee473dd8.pSoaN6Q7iFHHyWKE7s9gQAqdDzGb9fS8a478P7PHLxw; Path=/`
  - **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.

- **\[💥 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.
  - _Previous Usage of `handleIDPLoginCallback`:_

    ```ts
    const { handleIDPLoginCallback } = await useIDP()

    watch(
      () => route.query,
      async (query) => {
        if (query.code && isString(query.code)) {
          await handleIDPLoginCallback(query.code)
        }
      },
      { immediate: true },
    )
    ```

  - _Current Usage of `loginIDP`:_

    ```ts
    const { loginIDP } = useAuthentication('login')

    onMounted(async () => {
      await loginIDP(props.code)
    })
    ```

- **\[🧹 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.
- **\[💥 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`.
- **\[💥 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`.
  - _Previous `useRpc` with `autoFetch`:_

    ```ts
    useRpc('rpcMethod', key, params, { autoFetch: true })

    useUser({ autoFetch: true })
    ```

  - _Current `useRpc` with `immediate`:_

    ```ts
    useRpc('rpcMethod', key, params, { immediate: true })

    useUser({ immediate: true })
    ```

- **\[💥 BREAKING\]** The attribute `isCmsPreview` has been removed from `RpcContext`.
- **\[💥 BREAKING\]** The attribute `storeCampaignKeyword` has been removed from `RpcContext`.
  - 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.
  - 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.

- **\[💥 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`.
  - _Previous `useStorefrontSearch` returning `fetching`:_

    ```ts
    const {
      data,
      resolveSearch,
      getSearchSuggestions,
      fetching,
      ...searchData
    } = useStorefrontSearch(searchQuery, { key })

    fetching.value // true or false
    ```

  - _Current `useStorefrontSearch` returning `status`:_

    ```ts
    const { data, resolveSearch, getSearchSuggestions, status, ...searchData } =
      useStorefrontSearch(searchQuery, {}, key)

    status.value // 'idle', 'pending', 'error' or 'success'
    ```

- **\[💥 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.

  Old config
  - _Previous `disableDefaultGetCachedDataOverride` in `nuxt.config.ts`:_

    ```ts
    export default defineNuxtConfig({
      // ...
      runtimeConfig: {
        // ...
        public: {
          // ...
          storefront: {
            // ...
            disableDefaultGetCachedDataOverride: false,
          },
          // ...
        },
        // ...
      },
      // ...
    })
    ```

  - _Current `enableDefaultGetCachedDataOverride`in `nuxt.config.ts`:_

    ```ts
    export default defineNuxtConfig({
      // ...
      runtimeConfig: {
        // ...
        public: {
          // ...
          storefront: {
            // ...
            legacy: {
              // ...
              enableDefaultGetCachedDataOverride: true,
            },
            // ...
          },
          // ...
        },
        // ...
      },
      // ...
    })
    ```

- **\[💥 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).
  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.
  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`.
  These changes enhance the developer experience and provide greater clarity and control over data fetching operations within components.
  - **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`!

- **\[💥 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.
  However, they have been deprecated since January 2024 when the preferred approach was changed to return the native `Response` object. This provides performance benefits by limiting the transformations necessary in the response pipeline, and aligns `@scayle/storefront-nuxt` with web standards. It also simplifies the implementation and means `@scayle/storefront-nuxt` no longer needs to be aware of third-party libraries used and their possible errors.
  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`.
  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.
  In order to have an RPC method use a specific status code, it should return a `Response` object.
  - _Previous Usage with `BaseError`:_

    ```ts
    function myCustomRpc() {
      // ...

      throw new BaseError(404)
    }
    ```

  - _Current Usage with `Response` object and `status` code:_

    ```ts
    function myCustomRpc() {
      // ...

      return new Response(null, { status: 404 })
    }
    ```

- **\[💥 BREAKING\]** We've updated how API routes are structured in multi-shop environments using path-based selection (`path` or `path_except_default`). Instead of being nested under each shop's specific path, all API routes will now be mounted globally under a single path, which defaults to `/api`. This means the option to customize the `apiBasePath` on a per-shop basis has been removed. This change promotes consistency and makes API route management more straightforward.
- **\[💥 BREAKING\]** The methods `getBasket`, `removeItemFromBasket`, `addItemsToBasket`, and `addItemToBasket` have been updated. Instead of returning the basket object directly, the basket will now be accessible as a property within the response body. Furthermore, errors occurring during`addItemToBasket` and `addItemsToBasket` will from now on return HTTP 400. The error kind can be identified by checking the `error` property of the response.

### Patch Changes

- Updated dependency `@vueuse/core@11.3.0` to `@vueuse/core@12.0.0`
  **Dependencies**

- Updated dependency to @scayle/storefront-core@8.0.0
