# Changelog

All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).


## Unreleased

## 3.4.0 - 2025-05-12

This version adds support for [Retail Media](https://docs.elevate.voyado.cloud/elevate/4/retail-media/),
which is currently in a closed beta.

### Added

- Add new notify method `notify.adImpression(ticket)` to match new
  [Storefront API endpoint](https://docs.elevate.voyado.cloud/elevate/4/integration/api/specifications/storefront/v3/notifications/ad-impression/)
- Add new query method `query.sponsoredPage()` to match new
  [Storefront API endpoint](https://docs.elevate.voyado.cloud/elevate/4/integration/api/specifications/storefront/v3/queries/sponsored-page/)


## 3.3.3 - 2025-03-20

### Fixed

- Added `json` type property to `product.typedCustom` to match returned data
  from [Elevate Server](https://docs.elevate.voyado.cloud/elevate/4/integration/api/specifications/storefront/v3/queries/product-page/#typedcustomresult)


## 3.3.2 - 2024-12-12

### Fixed

- When using `localStorageBackedSession()` there is now code that checks
  that the data stored in `localStorage` for the provided key (defaults to
  `voyado.session`) is valid, and repairs the stored data if it is not.

  So it should no longer be possible to get `undefined` values for
  `customerKey` and/or `sessionKey`.

  - If the stored data is not a JSON object, generates new UUIDv4 values
    for each key in an object
  - If both or one of the keys are missing, generates a new key for the
    missing ones
  - If `customerKey` or `sessionKey` are not strings, the invalid key
    will be replaced by a newly generated UUIDv4
  
  This way, any prior data stored where there is not a valid `customerKey`
  & `sessionKey` pair, it should now ensure they exist.


## 3.3.1 - 2024-10-02

### Added

- Add new query parameter `q` to the `LandingPageParams` type
- Add new query parameter `includeNavigation` to the `LandingPageParams` type


## 3.3.0 - 2024-08-27

### Added

- Export types for all request query parameters and bodies. For instance,
  `AutocompleteParams` and `AutocompleteBody` for the `autocomplete()`
  endpoint
- Added `templateId` query parameter to endpoints returning product- or
  recommendation-lists
- Added `presentPrices` query parameter for list of prices to include


## 3.2.1 - 2024-06-12

### Added

- Added support for numbers in custom typed attributes.


## 3.2.0 - 2023-12-18

### Added

- `Add To Cart Popup` query to get recommendations for a product that has just been added to the cart.


## 3.1.1 - 2023-11-02

### Added

- Sort orders for length, width, height, depth, volume and title.


## 3.1.0 - 2023-09-08

### Added

- Added weight property to `Product` & `Variant` interfaces


## 3.0.0 - 2023-08-29

As a result of the changes below, this package is now supported in
NodeJS and Deno. NodeJS requires version 18+ (or 16.15+ with 
`--experimental-fetch` flag active), since `fetch()` is used to make
cross platform network requests. In Deno the `npm:` prefix before
the package name should be used.


### Added

- Added CommonJS build of this package, which will be used automatically
  by Node if this package is used with `require()`.
- The package has been made more friendly to tree-shaking, in order for
  bundlers to remove unused code. Two new initialization methods have been
  introduced: `queries()` and `notifications()`. Each method only has
  access to their respective parts of the Storefront API.
  
  **Before (minified):**
  - All exports: 5.82 kB
  - `esales()`: 5.66 kB
  
  **After (minified):**
  - All exports: 4.44 kB
  - `elevate()` + `localStorageBackedSession()`: 4.09 kB
  - `elevate()`: 3.42 kB
  - `queries()`: 2.6 kB
  - `notifications()`: 1.83 kB
- Added a `localStorageBackedSession()` method, which uses the same
  session metadata handling as in version 2 on this package. The returned
  value can be passed directly to the `session` property in the API initialization.
  
  The returned object also has methods for updating customer key, as well as
  resetting both session- and customerKey to new UUID's.

### Changed

- (BREAKING) Made the type `CheckboxFacet.count` optional, since it's 
  only available when `CheckboxFacet.selected` is `true`
- (BREAKING) New required property `session` in the initialization config.
  This property should be a method returning an object - or a promise with
  an object - that has `sessionKey` and `customerKey`.

  ```ts
  import { elevate } from '@apptus/esales-api';
  
  const api = elevate({
    clusterId: '...',
    // ...,
    session: async () => {
      const { id, sessionId } = await visitorInfo();
      return { customerKey: id, sessionKey: sessionId };
    }
  });
  ```
- (BREAKING) All notification methods now return promises. In v2
  `Navigator.sendBeacon()` was used to synchronously schedule POST
  requests in the browser. This has been changed in v3, where `fetch()` is
  used instead.
  ```ts
  // Before
  api.notify.click(); // would throw if failing to queue POST
  > undefined

  // After
  api.notify.click();
  > Promise<void>
  ```

  Any code using notifications should update the code to handle the
  promises, to avoid potential uncaught promise errors.
- It is now possible to send a `Variant.key` to `addFavorite()` and
  `removeFavorite()` notification methods, by passing an object instead of
  a string. Such as `api.notify.addFavorite({ variantKey: '...' })`
- Now uses `crypto.randomUUID()` over the `uuid` npm package, and thus
  there are 0 dependencies for this package anymore. This API is only used
  and required when `localStorageBackedSession()` is used (which is
  intended only for browsers).
- [Apptus eSales has been renamed Voyado Elevate](https://docs.elevate.voyado.cloud/elevate/4/changelog/#esales-is-voyado-elevate).
  Documentation, comments, and more has changed to match this.
  The `esales()` method has been deprecated in favor of the new 
  `elevate()` method for initializing the API.
- Documentation for code has been improved, with better descriptions
  and less ambiguous information. Many links to [the Elevate docs](https://docs.elevate.voyado.cloud/elevate/4/)
  has been added to more easily find more information about the API.
- This package now supports Node.js and Deno, by avoiding browser-only
  API's in core code paths. Moving session data via `LocalStorage` to it's
  own method, and replacing `navigator.sendBeacon()` with `fetch()` are
  the core changes that allows this.
  
  There's also been a lot of internal updates made to the project,
  unit test runner, and more as part of this effort.

### Removed

- (BREAKING) The `session` property on the API object returned by
  `elevate()`/`esales()` has been removed. When using session information
  with `LocalStorage`, the same functionality can be found on the object
  returned by the `localStorageBackedSession()` method.
- (BREAKING) Removed the `api.notify.payment()` notification method,
  since it's no longer possible to notify payments via the Storefront API.
- Removed the minified build artifact `lib.min.mjs`. There were several
  reasons it was deemed unnecessary to keep this file:
  - Most bundlers already do minification of code as a final step
  - Tooling that bundled packages had to be configured with this modified
    entrypoint manually
  - With multiple module formats (ESM, CJS), having minified versions of 
    each adds more "bloat"/configuration to the package


## 2.4.9 - 2023-08-18

### Changed

- Corrected a code example in the README.md


## 2.4.8 - 2023-07-07

### Changed

- Reverted back format of `CustomData` in the `LandingPage` interface.


## 2.4.7 - 2023-07-05

### Changed

- Updated the format of `CustomData` in the `LandingPage` interface to include the locale information.


## 2.4.6 - 2023-06-20

### Changed

- Add property `published` to the `LandingPage` interface


## 2.4.5 - 2023-06-20

### Changed

- Measurements such as width, height, depth, length, volume are included on listings
  if they exist in the product data


## 2.4.4 - 2023-06-15

### Added

- Added Algorithm type `RECENTLY_VIEWED` to recommendation lists


## 2.4.3 - 2023-06-09

### Added

- Added properties to `Product` & `Variant` interfaces for measurements
- Added property `typedCustom` to `Product` & `Variant`, which is typed custom attributes for lengths


## 2.4.2 - 2023-05-23

### Added

- Added `remaining` property to `ProductGroup`, which lists the number of
  `Product`'s not included in the group due to Elevate server settings.
- Added `unit` property to `RangeFacet`, which is a property that will exist
  on `'MEASUREMENT'` type facets.


## 2.4.1 - 2023-05-11

### Changed

- Corrected `CHANGELOG.md` version and date for previous version


## 2.4.0 - 2023-05-11

### Added

- Added Algorithm type `MORE_FROM_SERIES` to recommendation lists


## 2.3.0 - 2023-05-03

### Added

- Added property `custom` to the `Image` type, which is a map of custom
  values added to the image during import
- Added property `prices` to the `Variant` type, which is a list of custom
  prices for the Variant
- Added property `custom` to the `Variant` type, which is a map of custom
  attributes available on the Variant
- Added type `'NATURAL'` as a possible facet sort order
- Added `isCheckboxFacet` helper method

### Changed

- Improve JSDoc descriptions for a bunch of properites on types


## 2.2.1 - 2023-03-30

### Added

- Add properties `name` and `series` to the `Product` type
- Add `'NAME'` as a possible sort order for product lists


## 2.2.0 - 2023-03-27

### Added

- Added property `recentlyViewed` to the `Autocomplete` body response
- New notification method `.removeRecentlyViewed()`, that can remove
  individual or all products from the list of recently viewed products
- Added missing property `height` to `ImageSource`
- `iconPath` has been added to nodes in navigation tree.


## 2.1.0 - 2023-02-01

### Added

- Added property `label` to the `Variant` interface


## 2.0.2 - 2023-01-16

### Added

- Added newly released functionality to add `customData` to `LandingPage`.
  `LandingPage.customData` is a key-value map of string values, where an
  integrator can add additional data to a Page.


## 2.0.1 - 2022-10-25

### Changed

- Made the validation on the `clusterId` initialization property less strict


## 2.0.0 - 2022-10-21

This release is migrating from the eSales v2 API, to eSales Storefront v3 API.
In the new version of the API, it is now required to provide `locale` in 
addition to market, to support multi-lingual markets. The remaining breaking
changes are mostly doing some cleanup of the API that _should not_ affect
any Apptus eSales customers using this library.

### Added

- (BREAKING) Added a required `locale` configuration option, which is required
  by eSales Storefront API v3.
- Added a `esales(...).clusterUrl` string property, which is the base URL to
  to eSales cluster

### Changed

- (BREAKING) `webApiId` and `webApiUrl` has been replaced by `clusterId`,
  to better match terminology in eSales documentation.

  The `clusterId` property supports using both ID and URL to the
  eSales cluster. When using a URL, no path should be specified,
  only the base origin to the server.

  ```ts
  // Before
  const api = esales({ webApiId: 'w00000000' });
  const api2 = esales({ webApiUrl: 'https://w00000000.api.esales.apptus.cloud/api/v2/' });

  // After
  const api = esales({ clusterId: 'w00000000' });
  const api2 = esales({ clusterId: 'https://w00000000.api.esales.apptus.cloud/' });
  ```
- (BREAKING) Renamed the parameter `pageId` to `pageReference` for the
  `query.landingPage()` request. This change matches the
  [change in the Storefront API](https://docs.elevate.voyado.cloud/elevate/4/integration/api/specifications/storefront/v3/#changes).
- Changed to use Storefront v3 API, instead of API v2.

### Removed

- (BREAKING) Submodule `@apptus/esales-api/mock` removed, which provided methods
  for creating mock objects matching response data from varios endpoints. The
  only use case for this submodule was in testing, but was likely not too helpful
  enough to warrant including this code.
- (BREAKING) Removes the method `esales(...).query.settings()` for a
  private/undocumented `/settings` endpoint.


## 1.15.0 - 2022-08-24

### Added

- Added support for recent searches handled by eSales, by utilizing `customerKey`:
  - Added `Autocomplete.recentSearches` property, which is a list of recent searches
  - Added `api.notify.removeRecentSearches()` method, which can be used to
    clear individual or all stored recent searches
  - Added search origin `RECENT_SEARCH` (query param `?origin=RECENT_SEARCH`
    can be added to search page requests)


## 1.14.0 - 2022-08-10

- This version has been unpublished. The changes intended in this version was
  released in v1.15.0.


## 1.13.0 - 2022-05-16

### Added

- Support for types related to Query Relaxation for `api.query.searchPage()`:
  - Added `boolean` parameter `viewAllSecondary`
  - Added `secondaryList` and `relatedSearches` to returned interface
  - Added `RELATED_SEARCHES` as possible value for the `origin` parameter
- Added Store Availability to the `Variant` interface for returned Products (`Variant.availability`)


## 1.12.0 - 2022-05-03

### Added

- Added support for `productRules` for primary and recommendation lists
  - Property `productRules`added to the `RecommendationListConfiguration` interface
  - Property `productRules` added to `primaryList` in the `PageBodyConfiguration` interface 


## 1.11.1 - 2022-04-26

### Changed

- Corrected a few JSDoc `@example`'s code to correct usage


## 1.11.0 - 2022-03-10

### Added

- A new parameter has been added to query endpoints; `presentCustom`. Using this parameter
  it's possible to configure which custom attributes will be available on products
  in product listings. This parameter is available for the following endpoints:
  - `autocomplete`
  - `cartPage`
  - `landingPage`
  - `productPage`
  - `searchPage`


## 1.10.0 - 2022-02-04

### Added

- A new property `count` has been added to the `'CHECKBOX'` facet type.
  At this moment, this will only affect the `onlyInStock` facet, where it's
  now possible to preview the number of products that match when `onlyInStock` would be selected.


## 1.9.0 - 2022-01-28

### Added

- Now allows `boolean` as a value for facets, compatible with for instance `onlyInStock`.


## 1.8.1 - 2022-01-21

### Changed

- The `RecommendationListConfiguration.algorithm` was incorrectly using a global
  Typescript interface instead of our own type, and has been corrected to the correct
  type.


## 1.8.0 - 2022-01-20

### Added

- Properties `algorithm` and `visible` to the `RecommendationList` interface
- Property `productFilter` to the `RecommendationListConfiguration` interface
  
### Changed

- Made `limit`, `algorithm` & `visaulization` optional on the `RecommendationListConfiguration` interface
- Renamed `requestParams` to `params` on the `RecommendationListConfiguration` interface.
  This is technically not a breaking change, since the `requestParams` was simply ignored by the API.


## 1.7.0 - 2022-01-18

### Added

- Added parameters `channels` and `stores` to all queries. For more information, [read further on this topic in Apptus docs](https://docs.elevate.voyado.cloud/elevate/4/integration/api/common/query-parameters/?h=channel#optional-parameters).


## 1.6.0 - 2021-11-10

### Changed

- It is now possible for the server to respond with a price facet included, but where it's `min`/`max` fields are `undefined`. This can happen if there are no products included in the current selection. The types for returned objects now reflect this fact.


## 1.5.1 - 2021-10-20

### Added

- Include `CHANGELOG.md` in the npm package


## 1.5.0 - 2021-10-20

### Added

- Add type support for `contentLists` to `autocomplete()`, `landingPage()` and `searchPage()` (body and return value)
- Added `api.query.contentInformation()` method
- Added `api.query.contentSearchPage()` method
- Add `number` and `number[]` as allowed values to the Typescript interface for `ProductFilter` ([see docs example](https://docs.elevate.voyado.cloud/elevate/4/integration/api/http-api/queries/common/page-configuration/#numeric-product-filters))

### Changed

- Made `RecommendationList.label` optional. It's possible for API to no return this property
  if the app overrides the POST request with an empty label.


## 1.4.0 - 2021-06-30

### Added

- Added the `notify.end()` method for notifying that a session has ended
- Added the `notify.payment()` method for notifying client-side payments
  (client-side payments must be enabled on the cluster)


## 1.3.0 - 2021-05-12

### Docs

- Updated some property documentation for landing pages


## 1.2.1 - 2021-04-29

### Fixed

- Correct the `/add-to-cart` notification endpoint


## 1.2.0 - 2021-03-01

Internal changes.


## 1.1.1 - 2021-02-11

### Added

- Add missing properties to `NavigationNode`


## 1.1.0 - 2021-02-11

### Added

- Added `'STYLE_WITH'` as possible `Algorithm` value

### Changed

- Updated `NavigationNode` with the `'SPACER'` type


## 1.0.2 - 2021-01-25

### Added

- Added `stockNumber` property to `Variant` interface
- Added `alt` and `caption` properties to `Image` interface


## 1.0.1 - 2020-11-06

### Docs
- Minor updates to `README.md` spelling
- Added keywords to `package.json`


## 1.0.0 - 2020-11-05

### Changed
- The `exports` field of `package.json` has been updated to better match intended usage

### Docs
- Restructured the `README.md` into new sections
- Added more information on how to build a project with this library
- Added missing `window.fetch` and `window.URL` to the list of possible required polyfills
