Vue Storefront is now Alokai! Learn More
Migration guide

Migration guide

The version v1.0.0 of @vsf-enterprise/unified-api-[commerce] packages brings the following changes:

  • Simplified the extension initialization
  • A new addCustomFields API which simplifies adding custom fields to the normalizers
  • Redefined a way to add custom methods
  • New utilities, such as defineNormalizer, which allow you to override the normalizer with the inferred typed of the raw data
  • Deprecation of the unifiedSdk in favor of the middlewareModule

The following guide covers the steps required to migrate the Alokai Enterprise application to the version 1.0.0 of the Unified.

Middleware

Prerequisites

Before you start the migration process, make sure that your project meet the following prerequisites:

  • Update your dependencies to the supported versions:
    • @vsf-enterprise/unified-api-bigcommerce: 1.0.0,
    • @vsf-enterprise/unified-api-commercetools: 1.0.0,
    • @vsf-enterprise/unified-api-magento: 1.0.0,
    • @vsf-enterprise/unified-api-mocks: 1.0.0,
    • @vsf-enterprise/unified-api-sapcc: 1.0.0,
    • @vsf-enterprise/unified-api-sfcc: 1.0.0,

You can run following command to update the package version. Replace the package name with the one you are using in your project.

storefront-middleware
yarn add -W @vsf-enterprise/unified-api-[integration]@^1.0.0

Update file structure

This step is optional, but will provide you a structure that will help to scale and maintain your Middleware config. In the following guide, we will refer to the updated the file structure of your Middleware app.

The recommended structure is as follows:

storefront-middleware/
├─ integrations/
│  ├─ <integration_name>/
│     ├─ config.ts
│     ├─ extensions/
│        ├─ index.ts
│        ├─ multistore.ts
│        ├─ unified.ts
│     ├─ index.ts
│     ├─ types.ts
├─ multistore/
├─ src/
│  ├─ index.ts
├─ .env.example
├─ package.json
├─ middleware.config.ts
├─ tsconfig.json
├─ types.ts

This new structure provides a more organized approach to managing Middleware integrations.

  • integrations/ - contains directories with the integration-specific configuration.
    • <integration_name>/ - contains the configuration for a specific integration.
      • config.ts - contains the configuration for a specific integration.
      • extensions/ - contains the extension files for a specific integration.
        • index.ts - exports all extensions for a specific integration.
        • multistore.ts - contains the Multistore extension for a specific integration.
        • unified.ts - contains the Unified API extension for a specific integration.
  • multistore/ - contains the multistore configuration.
  • src/ - contains the main Middleware configuration.
    • index.ts - Middleware server entry file.
  • .env.example - contains the example environment variables.
  • package.json - contains the dependencies and scripts.
  • middleware.config.ts - contains the main Middleware configuration.
  • tsconfig.json - contains the TypeScript configuration.
  • types.ts - contains the types for the Middleware app.

Replace sapcc with the name of the eCommerce platform you are migrating to.

In the following steps, we will use the sapcc integration as an example, but the same steps can be applied to any other integration.

To update the file structure, you can follow these steps:

1

Move the integration-specific configuration from the /config/<ecommerce-name>.ts to the integration/<ecommerce-name/config.js>.

For example, move the SAPCC middleware configuration content from the /config/sapcc.ts file to the /integrations/sapcc/config.ts file. All middleware extensions could be placed in the dedicated module for better code maintainability. This will be covered in the next sections.

The example config.ts file content for a SAPCC integration would look as follows:

storefront-middleware/integrations/sapcc/config.ts
// Some of the lines was omitted intentionally for brevity

import { MiddlewareConfig } from "@vsf-enterprise/sapcc-api";
import { ApiClientExtension, Integration } from "@vue-storefront/middleware";
import { multistoreExtension, unifiedApiExtension } from "./extensions";

const {
  IS_MULTISTORE_ENABLED,
  // other environment variables
} = process.env;

export const sapccConfig = {
  location: "@vsf-enterprise/sapcc-api/server",
  configuration: {
    OAuth: {
      // Your configuration here
    },
    api: {
      // Your configuration here
    },
  },
  extensions: (extensions: ApiClientExtension[]) => [
    ...extensions,
    unifiedApiExtension,
    ...(IS_MULTISTORE_ENABLED ? [multistoreExtension] : []),
  ],
} satisfies Integration<MiddlewareConfig>;

2

Move the Unified API extension setup from the middleware.config.ts into the /integrations/<ecommerce-name>/extensions/unified.ts file. Ignore all the import errors you may receive at this point, these will be fixed in the next chapters or jump to the Migrate Unified Extension section for more information on how to migrate the Unified extension.

3

Export extensions from the middleware.config.ts file into the /integrations/<ecommerce-name>/extensions/ directory.

The Alokai team recommends to create a dedicated file for each extension for better maintainability. The file should be named accordingly to the extension name, for example, multistore.ts or normalizerExtension.ts. The example structure will look as follows:

storefront-middleware/
├─ integrations/
│  ├─ <integration_name>/
│     ├─ config.ts
│     ├─ extensions/
│        ├─ index.ts
│        ├─ unified.ts
│        ├─ multistore.ts
│        ├─ extension2.ts
│        ├─ extension3.ts
│        ├─ ...
│     ├─ index.ts
│     ├─ types.ts
├─ ...

Refer to the Multistore section for more information on how to migrate the Multistore extension.

4

Register all the extensions in /integrations/<ecommerce-name>/config.ts file.

storefront-middleware/integrations/sapcc/config.ts
// Some of the lines was omitted intentionally for brevity

import { MiddlewareConfig } from "@vsf-enterprise/sapcc-api";
import { ApiClientExtension, Integration } from "@vue-storefront/middleware";
import { multistoreExtension, unifiedApiExtension, myCustomExtension } from "./extensions";

export const sapccConfig = {
  location: "@vsf-enterprise/sapcc-api/server",
  configuration: {
    //...
  },
+ extensions: (extensions: ApiClientExtension[]) => [
+   ...extensions,
+    unifiedApiExtension,
+    ...(IS_MULTISTORE_ENABLED ? [multistoreExtension] : []),
+    myCustomExtension,
+ ],
} satisfies Integration<MiddlewareConfig>;

5

Export the UnifiedEndpoints type from the /integrations/<ecommerce-name>/types.ts file.

storefront-middleware/integrations/sapcc/types.ts
export type { Endpoints as UnifiedEndpoints } from "@vsf-enterprise/unified-api-sapcc";

6

Create the integrations/sapcc/index.ts file to export the configuration for the SAPCC integration and all declared types.

storefront-middleware/integrations/sapcc/index.ts
export * from "./config";
export * from "./types";

7

Export the UnifiedEndpoints type from the /integrations/<ecommerce-name> file and the Unified Data Layer types from the @vsf-enterprise/unified-api-<ecommerce-name> package.

storefront-middleware/types.ts
export { type UnifiedEndpoints } from "./integrations/sapcc/types";

export * from "@vsf-enterprise/unified-api-sapcc/udl";

8

Clean up the middleware.config.ts file to include only the integrations configuration.

apps/storefront-middleware/middleware.config.ts
import { config as commerceConfig } from "./integrations/sapcc";
import { config as contentfulConfig } from "./integrations/contentful";

export const config = {
  integrations: {
    cntf: contentfulConfig,
    commerce: commerceConfig,
  },
};

Migrate Unified Extensions

The version 1.0.0 of the Unified Data Layer introduces a breaking change to the Unified Extension.

Updating the createUnifiedExtension function to the new architecture involves the following steps:

  • Remove apiMethods and normalizers properties from the createUnifiedExtension function. If you have any custom methods or normalizers, refer to the Migrate Methods section and Migrate Normalizers sections for more information on how to migrate them.
  • Remove Context and Config types from the createUnifiedExtension function.

Here is what the updated createUnifiedExtension declaration should look like:

storefront-middleware/integrations/sapcc/extensions/unified.ts
import { createUnifiedExtension } from "@vsf-enterprise/unified-api-sapcc";
// other imports

export const unifiedApiExtension = createUnifiedExtension({
  normalizers: {
    addCustomFields: [{}],
  },
  config: {
    // Your configuration here
  },
});

With the new architecture, the createUnifiedExtension function will infer the Context and Config types from the normalizers and methods properties, so it is not require to provide them explicitly.

Unified Extension Extensibility

The update 1.0.0 of the Unified introduces a breaking change to the Unified Extension extendibility. These changes affect how you customize normalizers, create custom methods, and add custom fields to the normalizers.

Migrate API Methods

If you were defining custom methods in the createUnifiedExtension function, your code may currently look like this:

import { createPaymentAndPlaceOrder } from "@sf-modules-middleware/checkout";
import {
  Config,
  Context,
  createUnifiedExtension,
  methods,
  normalizers,
} from "@vsf-enterprise/unified-api-sapcc";

const apiMethods = methods<typeof normalizers>();

export const unifiedApiExtension = createUnifiedExtension<Context, Config>()({
  normalizers,
  apiMethods: {
    ...apiMethods,
    createPaymentAndPlaceOrder,
    anotherCustomMethod: async (context, params) => {
      // Your custom method logic here
    },
  },
  config: {
    // Your configuration here
  },
});

In the updated architecture, custom methods can no longer be defined in the createUnifiedExtension function. Instead, should be defined as a dedicated middleware extension.

1

Create a new file in the /integrations/<ecommerce-name>/extensions/ directory and name it accordingly to the custom method you want to migrate. For example, customMethods.ts.

storefront-middleware/integrations/sapcc/extensions/customMethods.ts
import { createPaymentAndPlaceOrder } from "@sf-modules-middleware/checkout";

export const customMethodsExtension = {
  name: "customMethods",
  extendApiMethods: {
    createPaymentAndPlaceOrder,
    anotherCustomMethod(context, params) {
      //...
      return Promise.resolve({});
    },
  },
};

Then, export the customMethodsExtension in the barrel file /integrations/<ecommerce-name>/extensions/index.ts file. This will provide a singular entry point for all extensions that can be imported and used in your app.

storefront-middleware/integrations/sapcc/extensions/index.ts
export * from "./customMethods";

2

Use the barrel export to create type definitions for the custom methods in the /integrations/<ecommerce-name>/types.ts file. These types will make the custom methods accessible in the SDK.

storefront-middleware/integrations/sapcc/types.ts
import { customMethodsExtension } from "./extensions";

export type CustomMethodsExtension = typeof customMethodsExtension;
export type CustomMethodsEndpoints = WithoutContext<CustomMethodsExtension["extendApiMethods"]>;

3

Register custom extensions in the configuration file /integrations/<ecommerce-name>/config.ts.

storefront-middleware/integrations/sapcc/config.ts
import { MiddlewareConfig } from "@vsf-enterprise/sapcc-api";
import { ApiClientExtension, Integration } from "@vue-storefront/middleware";
-import { multistoreExtension, unifiedApiExtension } from "./extensions";
+import { multistoreExtension, unifiedApiExtension, customMethodsExtension } from "./extensions";

export const sapccConfig = {
  location: "@vsf-enterprise/sapcc-api/server",
  configuration: {
    //...
  },
  extensions: (extensions: ApiClientExtension[]) => [
    ...extensions,
     unifiedApiExtension,
     ...(IS_MULTISTORE_ENABLED ? [multistoreExtension] : []),
+    customMethodsExtension,
  ],
} satisfies Integration<MiddlewareConfig>;

4

Register custom methods in the SDK:

sdk.config.ts

- import type { UnifiedEndpoints } from 'storefront-middleware/types';
+ import type { UnifiedEndpoints, CustomMethodsEndpoints } from 'storefront-middleware/types';

  unified: buildModule(middlewareModule<UnifiedEndpoints>, {
    apiUrl: `${middlewareUrl}/commerce`,
    defaultRequestConfig: {
      headers: getRequestHeaders(),
    },
  }),
+ customExtension: buildModule(middlewareModule<CustomMethodsEndpoints>, {
+   apiUrl: `${middlewareUrl}/commerce`,
+   defaultRequestConfig: {
+     headers: getRequestHeaders(),
+   },
+ }),

Now, createPaymentAndPlaceOrder and anotherCustomMethod methods are available in the SDK under the customExtension namespace. Update all references to these methods in your app. The namespace can be changed by changing the key name in the SDK configuration.

// const result = await sdk.unified.createPaymentAndPlaceOrder({ params });

const result = await sdk.customExtension.createPaymentAndPlaceOrder({ params });

You can create as many API extensions as required. For each custom extension you want to migrate, follow these steps:

  1. Create a new extension in the /integrations/<ecommerce-name>/extensions/ folder.
  2. Register extension it in the config.ts file.
  3. Register a new module in the sdk.config.ts file.

Migrate Normalizers

Previously, if you were customizing the default set of normalizers using createUnifiedExtension, the code might look like this:

import { createPaymentAndPlaceOrder } from "@sf-modules-middleware/checkout";
import {
  Config,
  Context,
  createUnifiedExtension,
  normalizers,
} from "@vsf-enterprise/unified-api-sapcc";

export const unifiedApiExtension = createUnifiedExtension<Context, Config>()({
  normalizers: {
    normalizeCart(context, input) {
      return {
        ...normalizers.normalizeCart(context, input),
        customValue: input.customValue,
      };
    },
    normalizeCustomer(context, input) {
      const normalizedData = normalizers.normalizeCustomer(context, input);
      return {
        ...normalizedData,
        firstName: normalizedData.firstName.toUpperCase(),
        lastName: normalizedData.lastName.toUpperCase(),
      };
    },
    normalizeCustomData(context, input) {
      return {
        value: input.value,
      };
    },
  },
});

This example shows 3 common use cases of custom normalizers:

  • normalizeCart - extends the native normalizeCart normalizer with the customValue property
  • normalizeCustomer - customizes the native normalizeCustomer normalizer without changing the contract
  • normalizeCustomData - creates a new completely custom normalizer

Let's see how to handle each of these cases in the latest version of the Unified Data Layer.

Extend Native Normalizers

The Unified v1.0.0 simplifies the enhancement of the native normalizers. The new structure allows you to extend the native normalizers with custom fields without changing the type contract of the normalizers.

Instead of adding fields directly onto your normalized data, the new structure contains a $custom property that will contain the custom fields.

The process of extending the native normalizer with custom fields consists of two steps:

  1. Define custom fields in the Unfied Extension function that should enhance the native normalizer.
  2. Enable custom fields type inference by extending the AddCustomFields interface. With the InferAddCustomFields helper, you can infer the custom fields from the unifiedApiExtension object.

The complete example of extending the normalizeCart normalizer with the customValue field looks as follows:

storefront-middleware/integrations/sapcc/extensions/unified.ts
import {
  createUnifiedExtension,
  type AddCustomFields,
  type InferAddCustomFields,
} from "@vsf-enterprise/unified-api-sapcc";
// other imports

export const unifiedApiExtension = createUnifiedExtension({
  normalizers: {
    addCustomFields: [
      {
        normalizeCart(context, input) {
          return {
            customValue: input.customValue,
          };
        },
      },
    ],
  },
});

declare module "@vsf-enterprise/unified-api-sapcc" {
  export interface AddCustomFields extends InferAddCustomFields<typeof unifiedApiExtension> {}
}

Now, the customValue field is available in the normalizeCart normalizer result object under the $custom property. Update all references to the normalizeCart normalizer in your app.

const cart = await sdk.unified.getCart();

// before:
const customValue = cart.customValue;

// after:
const customValue = cart.$custom.customValue; // all custom fields are available under the $custom property

Customize Native Normalizers

To customize the native normalizer without changing the type contract, you can use the normalizers override mechanism. Here, you can define your custom normalizer implementation inside the normalizers.override property of the createUnifiedExtension function.

storefront-middleware/integrations/sapcc/extensions/unified.ts
import {
  createUnifiedExtension,
  normalizers as defaultNormalizers,
} from "@vsf-enterprise/unified-api-sapcc";
// other imports

export const unifiedApiExtension = createUnifiedExtension({
  normalizers: {
    override: {
      normalizeCustomer(context, input) {
        const normalizedData = defaultNormalizers.normalizeCustomer(context, input);
        return {
          ...normalizedData,
          firstName: normalizedData.firstName.toUpperCase(),
          lastName: normalizedData.lastName.toUpperCase(),
        };
      },
    },
  },
});

In this example, the normalizeCustomer normalizer is customized to capitalize the firstName and lastName fields.

Since the type contract (input/output) of the normalizeCustomer normalizer is preserved, no additional changes are required.

Custom Normalizers

In most cases, you won't need to create a completely custom normalizer. With the new extensibility options, you can customize API responses to handle the most common scenarios. However, if you need to provide a customized normalization that does not fit with the Unified Data Layer, the recommended approach is to create a custom normalizer as a separate module.

Create a new file in the /integrations/<ecommerce-name>/extensions/ directory and name it accordingly to the custom normalizer you want to migrate. For example, customNormalizers.ts and define your custom normalizers:

storefront-middleware/integrations/sapcc/extensions/customNormalizers.ts
import { NormalizerContext } from "@vsf-enterprise/unified-api-sapcc";

interface CustomDataType {
  value: string;
  // define your custom data structure
}

export const customNormalizers = {
  normalizeCustomData(context: NormalizerContext, input: CustomDataType) {
    return {
      value: input.value,
    };
  },
};

Then, you can use your custom normalizers directly in your custom extension.

storefront-middleware/integrations/sapcc/extensions/customExtension.ts
import { customNormalizers } from "./customNormalizers.ts";

export const customExtension = {
  name: "customExtension",
  extendApiMethods: {
    myCustomMethod(context, params) {
      //...
      const data = await context.api.getCustomData();
      return customNormalizers.normalizeCustomData(context.config.normalizerContext, data);
    },
  },
};

In this example, the normalizeCustomData normalizer is used in the myCustomMethod method of the customExtension extension. Also, a default normalization context provided by the Unified API context argument was used to facilitate the normalization process.

Multistore

This section will describe how to migrate the Multistore extension to the new structure.

1

Move the Multistore extension from the /config/multistore.config.ts file to the /integrations/<ecommerce-name>/extensions/multistore.ts file.

storefront-middleware/integrations/sapcc/extensions/multistore.ts
import { createMultistoreExtension } from "@vue-storefront/middleware";
// other imports

export const multistoreExtension = createMultistoreExtension({
  // Your configuration here
});

2

Register the Multistore extension in the configuration file /integrations/<ecommerce-name>/config.ts.

storefront-middleware/integrations/sapcc/config.ts
import { MiddlewareConfig } from "@vsf-enterprise/sapcc-api";
import { ApiClientExtension, Integration } from "@vue-storefront/middleware";
+ import { multistoreExtension, unifiedApiExtension } from "./extensions";

export const sapccConfig = {
  location: "@vsf-enterprise/sapcc-api/server",
  configuration: {
    //...
  },
  extensions: (extensions: ApiClientExtension[]) => [
    ...extensions,
    unifiedApiExtension,
+   multistoreExtension,
  ],
} satisfies Integration<MiddlewareConfig>;

3

Declare the available domain list.

The recommended approach is to define the available domains in the main middleware configuration file.

storefront-middleware/middeware.config.ts
/**
 * List of domains that are used in the multistore setup.
 */
export const listOfStoresDomains = ["dev.vsf.local", "dev.client.local"];

Then, adjust the import statements in the storefront-middleware app.

storefront-middleware/src/index.ts
+ import { listOfStoresDomains } from "../middleware.config";

// Another imports

4

Update the mutlistore script

In the updated file structure, the Multistore script is placed in the /multistore/ directory. Update the script to reflect the new structure.

storefront-middleware/multistore/multistore.ts

- import { listOfStoresDomains } from "../config/multistore.config";
+ import { listOfStoresDomains } from "../middleware.config";

// Update all paths in the script, for instance:

- mv ${store}.pem ./dev/temp/${store}.pem\n
+ mv ${store}.pem ./multistore/temp/${store}.pem\n

// ...

Algolia

To migrate the Algolia integration, follow these steps:

1

Create a dedicated integration module in the integrations directory and move the Algolia integration configuration to the dedicated config.ts file.

storefront-middleware/integrations/algolia/config.ts
import type { MiddlewareConfig } from "@vsf-enterprise/algolia-api";
import type { Integration } from "@vue-storefront/middleware";

export const config = {
  location: "@vsf-enterprise/algolia-api/server",
  configuration: {
    // Your configuration here
  },
} satisfies Integration<MiddlewareConfig>;

2

Update the Unified extension with the Algolia integration. Provide the Algolia configuration and register methods and normalizers provided by the Unified Algolia integration.

storefront-middleware/integrations/sapcc/extensions/unified.ts
import { createUnifiedExtension } from "@vsf-enterprise/unified-api-sapcc";
+ import "@vsf-enterprise/unified-api-sapcc/algolia";
+ import { methods as algoliaMethods, normalizers as algoliaNormalizers } from "@vsf-enterprise/unified-api-sapcc/algolia";

export const unifiedApiExtensionWithAlgolia = createUnifiedExtension({
+  methods: {
+    override: {
+     ...algoliaMethods,
+    },
+  },
  config: {
    // Unified configuration here
    algolia: {
+     ...algoliaNormalizers,
      // Algolia configuration here
    },
  },
});

3

Register the Algolia integration config in the middleware configuration file.

storefront-middleware/middleware.config.ts
+ import { config as algoliaConfig } from "./integrations/algolia";

export const config = {
  integrations: {
+    algolia: algoliaConfig,
    // other integrations
  },
};

Update SDK module

In the version 1.0.0 of the Unified Data Layer, the unifiedSdk has been deprecated and replaced with the middlewareModule property.

Next.js

1

Update the @vue-storefront/sdk and @vue-storefront/next packages

To begin the migration process, first update the @vue-storefront/sdk package to the version 1.4.0 or higher and the @vue-storefront/next package to the version 1.1.0 or higher.

apps/storefront-unified-nextjs
yarn add -W @vue-storefront/sdk@^1.4.0 @vue-storefront/next@^1.1.0

2

Export UnifiedEndpoints type from the storefront-middleware app.

Refer to the Middleware section for more information on how migrate the Middleware app.

apps/storefront-middleware/types.ts
export { type UnifiedEndpoints } from "./integrations/<ecommerce-name>/types";

3

Update the SDK module

Following the steps below to update the SDK module:

  • Replace the unifiedModule with the middlewareModule.
  • Register UnifiedEndpoints type within middlewareModule.
  • Configure the defaultRequestConfig property.
apps/storefront-unified-nextjs/sdk/sdk.config.ts
- import { unifiedModule } from '@vsf-enterprise/unified-sdk';
import { CreateSdkOptions, createSdk } from '@vue-storefront/next';
- import { UnifiedApiExtension } from 'storefront-middleware/middleware.config';
+ import type { UnifiedEndpoints } from 'storefront-middleware/types';

-export const { getSdk } = createSdk(options, ({ buildModule, middlewareUrl, getRequestHeaders }) => ({
+export const { getSdk } = createSdk(options, ({ buildModule, middlewareUrl, getRequestHeaders, middlewareModule }) => ({
- unified: buildModule(unifiedModule<UnifiedApiExtension>, {
+ unified: buildModule(middlewareModule<UnifiedEndpoints>, {
    apiUrl: `${middlewareUrl}/commerce`,
-   requestOptions: {
-     headers: () => getRequestHeaders() as Record<string, string>,
+   defaultRequestConfig: {
+     headers: getRequestHeaders(),
    },
  }),

4

Replace the @vsf-enterprise/unified-sdk references with @vue-storefront/sdk

- import { isSdkUnauthorizedError } from '@vsf-enterprise/unified-sdk';
+ import { isSdkUnauthorizedError } from '@vue-storefront/sdk';

Breaking Changes - renamed types and functions:

  • RENAMED SDKError to SdkHttpError
  • RENAMED isSpecificSdkError to isSpecificSdkHttpError

5

Update Unified Data Layer types

In this release, because of the addition of the $custom property, the Unified Data Layer types are now static and now can be used directly in your app. You can export them from the storefront-middleware app.

apps/storefront-middleware/types.ts
export * from "@vsf-enterprise/unified-api-<integration>/udl";

To make these types easily available from your storefront-unified-nextjs app, you can re-export them from your Next.js app.

apps/storefront-unified-nextjs/types/index.ts
export * from "storefront-middleware/types";

To finish migration to the new types, you can remove the InferSdk and InferSdkArgs helpers types and use the Unified Data Layer types directly in your app.

// import { InferSdk, InferSdkArgs } from '~/sdk'; 

// type GetProductsReturnType = InferSdk<'getProducts'>;
// type GetProductsArgs = InferSdkArgs<InferSdk<'getProducts'>>

import { GetProductsArgs, GetProducts, SfProduct } from "~/types";

type GetProductsReturnType = Awaited<ReturnType<GetProducts>>;

Make sure your components and services are consuming the new data types properly. For instance, update the compareAddresses helper method, provided by Alokai boilerplate, to handle data in updated structure correctly:

apps/storefront-unified-nextjs/helpers/address.ts
export const compareAddresses = (
  current?: SfAddress,
  address?: SfCustomerAddress | SfAddress | SfCreateAddressBody
) =>
  !!(
    current &&
    address &&
    (Object.keys(current) as (keyof SfAddress)[]).every(
      (key) => key === "$custom" || address[key] === current[key]
    )
  );

You may also completely remove the following files and directories:

  • types/unified-data-model/
  • sdk/types.ts

6

Uninstall the @vsf-enterprise/unified-sdk package

apps/storefront-unified-nextjs
yarn remove -W @vsf-enterprise/unified-sdk

7

Verify the changes with yarn build

To confirm that the application builds successfully with the provided changes, run the yarn build command.

apps/storefront-unified-nextjs
yarn build

Nuxt.js

1

Update the @vue-storefront/sdk and @vue-storefront/next packages

To begin the migration process, first update the @vue-storefront/sdk package to the version 1.4.0 or higher and the @vue-storefront/next package to the version 1.1.0 or highter.

apps/storefront-unified-nuxt
yarn add -W @vue-storefront/sdk@^1.4.0 @vue-storefront/nuxt@^3.1.0

2

Export UnifiedEndpoints type from the storefront-middelware app.

apps/storefront-middleware/types.ts
export type UnifiedEndpoints = WithoutContext<UnifiedApiExtension["extendApiMethods"]>;

3

Update the SDK module

  • Replace the unifiedModule with the middlewareModule.
  • Register UnifiedEndpoints type within middlewareModule.
  • Configure the defaultRequestConfig property.
apps/storefront-unified-nuxt/sdk.config.ts

- import { unifiedModule } from '@vsf-enterprise/unified-sdk';
- import { UnifiedApiExtension } from '../storefront-middleware/middleware.config';
+ import { UnifiedEndpoints } from '../storefront-middleware/types';

-export default defineSdkConfig(({ buildModule, middlewareUrl, getCookieHeader }) => ({
+export default defineSdkConfig(({ buildModule, middlewareUrl, getRequestHeaders, middlewareModule }) => ({
- unified: buildModule(unifiedModule<UnifiedApiExtension>, {
+ unified: buildModule(middlewareModule<UnifiedEndpoints>, {
    apiUrl: `${middlewareUrl}/commerce`,
-   requestOptions: {
-     headers: () => getCookieHeader(),
+   defaultRequestConfig: {
+     headers: getRequestHeaders(),
    },
  }),

4

Replace the @vsf-enterprise/unified-sdk references with @vue-storefront/sdk.

Example:

- import { isSdkUnauthorizedError } from '@vsf-enterprise/unified-sdk';
+ import { isSdkUnauthorizedError } from '@vue-storefront/sdk';

Breaking Changes - renamed types and functions:

  • RENAMED SDKError to SdkHttpError
  • RENAMED isSpecificSdkError to isSpecificSdkHttpError

5

Update Unified Data Layer types.

In this release, the Unified Data Layer types are now static and now can be used directly in your app. You can export them from the storefront-middleware app.

apps/storefront-middleware/types.ts
export * from "@vsf-enterprise/unified-api-<integration>/udl";

To make these types easily available from your storefront-unified-nuxt app, you can re-export them from your Nuxt app.

apps/storefront-unified-nuxt/types/index.ts
export * from "storefront-middleware/types";

To finish migration to the new types, you can remove the InferSdk and InferSdkArgs helpers types and use the Unified Data Layer types directly in your app.

// import { InferSdk, InferSdkArgs } from '~/types';

// type GetProductsReturnType = InferSdk<'getProducts'>;
// type GetProductsArgs = InferSdkArgs<InferSdk<'getProducts'>>

import { GetProductsArgs, GetProducts, SfProduct } from "~/types";

type GetProductsReturnType = Awaited<ReturnType<GetProducts>>;

You may also completely remove the following files and directories:

  • types/unified-data-model/
  • types/sdk.ts

6

Remove @vsf-enterprise/unified-sdk package from the package.json file.

apps/storefront-unified-nuxt
yarn remove -W @vsf-enterprise/unified-sdk

7

Verify the changes with yarn build

To confirm that the application builds successfully with the provided changes, run the yarn build command.

apps/storefront-unified-nuxt
yarn build

Summary

After following the steps above, you should have successfully migrated your Storefront to the latest version of the Alokai Starter. You can now take advantage of the new features and improvements that come with the latest version.