Vue Storefront is now Alokai! Learn More
Change Log

Change Log

2.0.0

Major Changes

  • ADDED Circuit Breaker

Automatically protects your application from cascading failures when backend services become unavailable. When errors exceed a threshold, the circuit breaker blocks requests immediately instead of waiting for timeouts, giving failing services time to recover.

  • Works out of the box with sensible defaults - no code changes required
  • All circuit breaker events logged with structured metadata
  • Prometheus metrics for monitoring state transitions and request outcomes
  • Configurable presets (PRODUCTION, DEVELOPMENT, AGGRESSIVE, TOLERANT, FAST_FAILURE, HARD_FAIL, RELAXED_DEBUG, EXTREME_DEBUG)
    Please, check Circuit Breaker for more details.
  • FIXED Default error handler now returns JSON for 5xx server errors (consistent with 4xx responses) instead of a plain text message.
  const response = await fetch(url);
  if (response.status >= 500) {
-   const text = await response.text();
-   console.error(text);
+   const body = await response.json();
+   console.error(body.message);
  }
  • [CHANGED]BREAKING Improved error handling in middleware with better type safety and more reliable error responses.

What this means for you:

Error responses from the middleware are now more consistent and predictable. If you're catching and handling errors from API calls, you may notice:

  • More detailed error information in 4xx responses (validation errors, not found errors, etc.)
  • Better structured error objects with proper error types
  • Improved error messages for authentication and token-related issues

Minor Changes

@alokai/connect package

  • ADDED withData method to HttpError class useful for adding context to errors without reconstructing the entire error.
  • ADDED New HTTP Client adapter types related with error handling on the middleware layer.
  • ADDED New error classes for common error scenarios: AppError (base error class with cause support), NotFoundError (for resource not found errors), UnauthorizedError (for authentication/authorization errors), and ValidationError (for input validation errors with detailed field-level error messages), HttpError (for HTTP errors). All error classes support proper inheritance, stack traces, and JSON serialization.
  • ADDED New function normalizeAxiosError to normalize Axios-like errors to HttpError instances.
  • CHANGED allow headers to accept async functions and promised header objects.
  • ADDED normalizeGraphQLError helper for normalizing GraphQL errors from any client (Apollo Client, urql, graphql-request) to HttpError. This helper maps GraphQL error codes to appropriate HTTP status codes (e.g., UNAUTHENTICATED → 401, FORBIDDEN → 403, GRAPHQL_VALIDATION_FAILED → 422) and preserves error metadata for debugging and observability. The normalizer is client-agnostic and works without requiring the graphql package as a dependency.
  • CHANGED The @alokai/connect's InferCustom type alias now falls back to Record<string, unknown> instead of object. ADDED Add defineIntegrationExtension factory to @alokai/connect/integration-kit for creating typed custom extensions with full type inference for API methods, hooks configuration, and extendApp.

Patch Changes

Changed lodash to lodash-es for better ESM compatibility in @alokai/connect.

  • FIXED Circuit breaker config now normalizes integration-level presets case-insensitively, falling back to BALANCED when an invalid integration preset is provided.
  • CHANGED When using the middlewareModule from @alokai/connect/sdk, it no longer throws when trying to access a method by a non-string property name and it returns undefined instead. This is to avoid errors in edge cases where React's built-in development hooks try to inspect SDK modules by accessing Symbol properties.
  • CHANGED Align dependency versions across SDKs, tooling, and shared configs.
  • FIXED @alokai/connect: Fixed CONFIG type inference when providing extensions property in identify functions using the Integration interface.

Example identity function

import type { Integration } from "@alokai/connect/middleware";

function defineConfig<TConfig>(
  config: Integration<TConfig>,
): Integration<TConfig> {
  return config;
}

Before

const config = defineConfig({
  extensions: (existing) => existing,
  location: "@alokai/compass/server",
  configuration: {
    workflows: {
      a: {},
      b: {},
      c: {},
    },
  },
});

type WorkflowIds = keyof typeof config.configuration.workflows; // type WorkflowIds = string | number | symbol

After

const config = defineConfig({
  extensions: (existing) => existing,
  location: "@alokai/compass/server",
  configuration: {
    workflows: {
      a: {},
      b: {},
      c: {},
    },
  },
});

type WorkflowIds = keyof typeof config.configuration.workflows; // type WorkflowIds = "a" | "b" | "c"
  • CHANGED Replaced Rollup with tsdown for @vsf-enterprise and @alokai package builds.
  • FIXED Standardize type usage to always reference API type packages across integrations and SDKs.
  • CHANGED Improved stack trace logging strategy. Stack traces are now logged for 5xx HttpErrors (server errors) and non-HttpError exceptions (unhandled errors), but not for 4xx HttpErrors (client errors).
  • CHANGED Improved GCPStructuredDTO.severity typing by using GCPSeverity type union for better IDE autocomplete support.
  • CHANGED Updated @alokai/connect logger printer behaviour in dev mode. Logs are now printed in a single line as a formatted message instead of JSON.
  • FIXED Fixed ESM module loading for integrations. The middleware now prefers ESM modules and falls back to CommonJS when ESM fails, with a warning log for debugging.
  • FIXED SDK no longer crashes with "process is not defined" error when used with browser-first bundlers like Vite.
  • Updated dependencies:
    • @alokai/cookies-bridge@1.0.2
    • @alokai/instrumentation@2.0.0

1.2.1

Patch Changes

  • FIXED Resolved CommonJS module compatibility issue with pako library in Nuxt applications. Previously, Nuxt applications would fail to build or run due to the pako library being incompatible with the CommonJS module system, resulting in module resolution errors. Now, the pako library is properly configured to work with Nuxt's module system, allowing applications to build and run successfully. The issue was reported only in production builds, not in development mode.

1.2.0

Minor Changes

  • CHANGED context.getApiClient() can now be called without arguments to return the current integration's API client, providing a convenient shorthand for self-referring. When called without arguments, the method now returns fully typed results based on the current integration's API, CONFIG, and CLIENT types, eliminating the need for manual type annotations.

Example:

import type { Endpoints } from "@vsf-enterprise/sapcc-api";
import type { Endpoints as UnifiedEndpoints } from "@vsf-enterprise/unified-api-sapcc";

// Case 1: Using only base integration methods - no generics needed
const sapcc = await context.getApiClient();
const product = await sapcc.api.getProduct({ id: "123" });

// Case 2: Using extension methods - provide generics for extensions
const sapccWithExtensions = await context.getApiClient<
  Endpoints & { unified: UnifiedEndpoints }
>();
const unifiedProduct = await sapccWithExtensions.api.unified.getProductDetails({
  id: "123",
});

Note: When calling other integrations, you still need to pass the integration name as the first argument.

  • CHANGED context.api became deprecated and it will be removed in the next major version. Please use const { api } = await context.getApiClient() instead.
  • CHANGED Extensions typed as ApiClientExtension<Endpoints> must preserve the original method signatures when overriding built-in API methods.
  • ADDED Handling streamed responses from 3rd party services.
  • ADDED Body-Parser configuration can now be defined on a per-route basis
import { createServer } from "@alokai/connect/middleware";

import { config } from "@/middleware.config";

await createServer(config, {
  bodyParser: ({ functionName, integrationName }) => {
    if (integrationName === "commerce" && functionName === "uploadFile") {
      return { limit: "4000kb" };
    }

    return { limit: "100kb" };
  },
});
  • ADDED Built-in POST request body compression mechanism in the middlewareModule of @alokai/connect/sdk.
import { prepareConfig } from "@alokai/connect/sdk";

const response = await sdk.compass.invoke(
  {
    // ...
  },
  prepareConfig({
    compression: {
      algorithm: "gzip",
    },
  }),
);
  • ADDED metrics collection for request latency and error rate.
  • ADDED Global error handler configuration in middleware.config.ts. You can now define a single error handler that applies to all integrations, with the option to override it per integration.
  • FIXED Body parser errors (such as invalid JSON in request bodies) are now caught by custom error handlers.

Patch Changes

  • FIXED Metrics are now exposed for middleware and integration without adding it for specific methods (to be removed during release)
  • FIXED: Adjust Middleware Metrics to Console needs (to be delated later)
  • FIXED Nested calls to the context.getApiClient
  • Updated dependencies:
    • @alokai/instrumentation@1.1.0

1.1.2

Patch Changes

  • FIXED @alokai/connect: Fixed logger type in API Client extension hooks
  • Updated dependencies:
    • @alokai/cookies-bridge@1.0.1

1.1.1

Patch Changes

Security vulnerability fixes across multiple packages

This change addresses critical security vulnerabilities identified in the dependency audit across several packages. The fixes primarily target dependency updates and security patches to resolve high and critical severity issues.

Before fix:

  • 40 vulnerabilities found (Packages audited: 3081)
  • Severity breakdown: 23 Low | 8 Moderate | 2 High | 7 Critical

After fix:

  • 24 vulnerabilities found (Packages audited: 3115)
  • Severity breakdown: 22 Low | 2 Moderate | 0 High | 0 Critical

Key improvements:

  • Eliminated all 7 critical vulnerabilities
  • Resolved 2 high severity vulnerabilities
  • Reduced moderate vulnerabilities from 8 to 2
  • Overall 40% reduction in total vulnerabilities (40 → 24)

The remaining low and moderate vulnerabilities are either false positives or require major version updates that would introduce breaking changes.

1.1.0

Minor Changes

Introduced Alokai instrumentation support

Patch Changes

  • CHANGED The @alokai/connect/config-switcher now supports using no header with the extension, defaulting to the default value when no header is provided.
  • ADDED JSDoc for context.getApiClient in the @alokai/connect/middleware's MiddlewareContext.
  • CHANGED Update multer
  • Updated dependencies:
    • @alokai/instrumentation@1.0.0

1.0.0

Major Changes

  • CHANGED Guarantee compatibility with @alokai/connect package.
  • CHANGED Updated the package for compatibility with Node.js 22.

Key Updates:

  • Upgraded to the latest version of Node.js 22
  • Updated CI pipelines to use Node.js 22 for consistency.
  • Updated .nvmrc or .node-version files to specify Node.js version 22.14.
  • Upgraded @types/node to version ^22.13.17 for compatibility with the latest Node.js features.

Recommendations:

  • Use Node.js version 22.14.0 or higher for optimal performance, security, and compatibility.
  • While Node.js 20 is technically supported, it is not recommended as it may cause compatibility issues with certain packages and has not been thoroughly tested.

Minor Changes

  • CHANGED Update axios version to "^1.7.9"
  • ADDED getConfigSwitcherHeader to defaultRequestConfig in the middlewareModule of @alokai/connect/sdk. It allows setting the x-alokai-middleware-config-id header on the Storefront side for the Config Switcher extension.

Example usage:

export function getSdkConfig() {
  return defineSdkConfig(
    ({ buildModule, config, getRequestHeaders, middlewareModule }) => ({
      commerce: buildModule(middlewareModule<CommerceEndpoints>, {
        apiUrl: `${config.apiUrl}/commerce`,
        cdnCacheBustingId: config.cdnCacheBustingId,
        defaultRequestConfig: {
          getConfigSwitcherHeader: (computedHeaders) => "some-value",
          headers: getRequestHeaders(),
        },
        ssrApiUrl: `${config.ssrApiUrl}/commerce`,
      }),
    }),
  );
}
  • ADDED An option to specify RequestConfig.headers as a function in @alokai/connect/sdk middleware module. This might be helpful when you need to dynamically modify the headers before each request.

Example for Next.js:

// sdk/config.ts
export function getSdkConfig() {
  return defineSdkConfig(
    ({ buildModule, config, getRequestHeaders, middlewareModule }) => ({
      unified: buildModule(middlewareModule<UnifiedEndpoints>, {
        apiUrl: `${config.apiUrl}/commerce/unified`,
        cdnCacheBustingId: config.cdnCacheBustingId,
        defaultRequestConfig: {
          headers: getRequestHeaders,
        },
        methodsRequestConfig:
          config.defaultMethodsRequestConfig.unifiedCommerce.middlewareModule,
        ssrApiUrl: `${config.ssrApiUrl}/commerce/unified`,
      }),
    }),
  );
}
  • CHANGED Interface for the parameter received by getConfigSwitcherHeader. Now it is an object featuring 3 properties: headers, pathname and searchParams.
  • ADDED defineGetConfigSwitcherHeader type-safe function to define the getConfigSwitcherHeader callback in SDK configuration.
  • ADDED New feature for the middleware app. Now, for every request, the middleware will convert the x-alokai-locale header into vsf-locale cookie. This change is important in CDN support, as we cannot pass cookies to the CDN. The feature can also be implemented in the projects that are NOT using @alokai/connect package, by adding an extension to each registered integration:
  1. Install @alokai/cookies-bridge package:
yarn add @alokai/cookies-bridge
  1. Add the extension to the integration configuration:
apps/storefront-middleware/integrations/<your-integration>/config.ts
// Only in projects that are NOT using `@alokai/connect` package.

+ import { createCookiesBridgeExtension } from "@alokai/cookies-bridge";
+ const cookiesBridgeExtension = createCookiesBridgeExtension([{
+   header: 'x-alokai-locale',
+   cookie: 'vsf-locale',
+ }]);

export const config = {
  configuration: {
    // ...
  }

  extensions: (extensions: ApiClientExtension[]) => [
+    cookiesBridgeExtension,
    ...extensions,
    unifiedApiExtension,
    cdnExtension,
    ...(IS_MULTISTORE_ENABLED === 'true' ? [configSwitcherExtensionFactory()] : []),
  ],
};

Note: The extension should be added as first in the extensions list, as it should be executed before any other extension.

In some projects, the middleware configuration might be placed in middleware.config.ts file, but implementation is the same.

  • CHANGED The maximum file upload size limit has been increased to 20MB.

Patch Changes

  • FIXED Errors thrown in the integration extension's beforeCall hook now correctly propagate their statusCode property to the response, instead of defaulting to 404.
  • CHANGED Used custom merger function in the config-switcher API Client extension to handle merging objects featuring getters and setters.
  • CHANGED Updated the express version to ^4.20.0 to fix security vulnerabilities. See more in GitHub Vulnerability Alert.
  • Updated dependencies:
    • @alokai/cookies-bridge@1.0.0

1.0.0-rc.4

Minor Changes

  • ADDED An option to specify RequestConfig.headers as a function in @alokai/connect/sdk middleware module. This might be helpful when you need to dynamically modify the headers before each request.

Example for Next.js:

// sdk/config.ts
export function getSdkConfig() {
  return defineSdkConfig(
    ({ buildModule, config, getRequestHeaders, middlewareModule }) => ({
      unified: buildModule(middlewareModule<UnifiedEndpoints>, {
        apiUrl: `${config.apiUrl}/commerce/unified`,
        cdnCacheBustingId: config.cdnCacheBustingId,
        defaultRequestConfig: {
          headers: getRequestHeaders,
        },
        methodsRequestConfig:
          config.defaultMethodsRequestConfig.unifiedCommerce.middlewareModule,
        ssrApiUrl: `${config.ssrApiUrl}/commerce/unified`,
      }),
    }),
  );
}
  • CHANGED Interface for the parameter received by getConfigSwitcherHeader. Now it is an object featuring 3 properties: headers, pathname and searchParams.
  • ADDED defineGetConfigSwitcherHeader type-safe function to define the getConfigSwitcherHeader callback in SDK configuration.
  • CHANGED The maximum file upload size limit has been increased to 20MB.

Patch Changes

  • CHANGED Used custom merger function in the config-switcher API Client extension to handle merging objects featuring getters and setters.
  • CHANGED Updated the express version to ^4.20.0 to fix security vulnerabilities. See more in GitHub Vulnerability Alert.

1.0.0-rc.3

Major Changes

  • CHANGED Updated the package for compatibility with Node.js 22.

Key Updates:

  • Upgraded to the latest version of Node.js 22
  • Updated CI pipelines to use Node.js 22 for consistency.
  • Updated .nvmrc or .node-version files to specify Node.js version 22.14.
  • Upgraded @types/node to version ^22.13.17 for compatibility with the latest Node.js features.

Recommendations:

  • Use Node.js version 22.14.0 or higher for optimal performance, security, and compatibility.
  • While Node.js 20 is technically supported, it is not recommended as it may cause compatibility issues with certain packages and has not been thoroughly tested.

Minor Changes

  • ADDED getConfigSwitcherHeader to defaultRequestConfig in the middlewareModule of @alokai/connect/sdk. It allows setting the x-alokai-middleware-config-id header on the Storefront side for the Config Switcher extension.

Example usage:

export function getSdkConfig() {
  return defineSdkConfig(
    ({ buildModule, config, getRequestHeaders, middlewareModule }) => ({
      commerce: buildModule(middlewareModule<CommerceEndpoints>, {
        apiUrl: `${config.apiUrl}/commerce`,
        cdnCacheBustingId: config.cdnCacheBustingId,
        defaultRequestConfig: {
          getConfigSwitcherHeader: (computedHeaders) => "some-value",
          headers: getRequestHeaders(),
        },
        ssrApiUrl: `${config.ssrApiUrl}/commerce`,
      }),
    }),
  );
}

Patch Changes

  • Updated dependencies:
    • @alokai/cookies-bridge@1.0.0-rc.1

1.0.0-rc.2

Minor Changes

  • CHANGED Update axios version to "^1.7.9"

1.0.0-rc.1

Minor Changes

  • ADDED New feature for the middleware app. Now, for every request, the middleware will convert the x-alokai-locale header into vsf-locale cookie. This change is important in CDN support, as we cannot pass cookies to the CDN. The feature can also be implemented in the projects that are NOT using @alokai/connect package, by adding an extension to each registered integration:
  1. Install @alokai/cookies-bridge package:
yarn add @alokai/cookies-bridge
  1. Add the extension to the integration configuration:
apps/storefront-middleware/integrations/<your-integration>/config.ts
// Only in projects that are NOT using `@alokai/connect` package.

+ import { createCookiesBridgeExtension } from "@alokai/cookies-bridge";
+ const cookiesBridgeExtension = createCookiesBridgeExtension([{
+   header: 'x-alokai-locale',
+   cookie: 'vsf-locale',
+ }]);

export const config = {
  configuration: {
    // ...
  }

  extensions: (extensions: ApiClientExtension[]) => [
+    cookiesBridgeExtension,
    ...extensions,
    unifiedApiExtension,
    cdnExtension,
    ...(IS_MULTISTORE_ENABLED === 'true' ? [configSwitcherExtensionFactory()] : []),
  ],
};

Note: The extension should be added as first in the extensions list, as it should be executed before any other extension.

In some projects, the middleware configuration might be placed in middleware.config.ts file, but implementation is the same.

Patch Changes

  • FIXED Errors thrown in the integration extension's beforeCall hook now correctly propagate their statusCode property to the response, instead of defaulting to 404.

1.0.0-rc.0

Major Changes

Fix builds

Patch Changes

Update packages to work with connect rc version

1.0.0

Major Changes

Release of the package @alokai/connect version 1.0.0.

Middleware

CHANGED Updated the type of the hooks property in the ApiClientExtension interface so that the hooks' configuration param is typed properly. This is a breaking change if you are using legacy @vue-storefront/middleware version 4.1.2 or lower.

Config Switcher (previously multistore)

UPDATED Set the return type of the createMultistoreExtension helper to ApiClientExtension.

SDK

CHANGED The config parameter available in the callback passed to defineSdkConfig() no longer contains computed middlewareUrl property. It now exposes apiUrl and ssrApiUrl that should be used instead. CHANGED The middleware.ssrApiUrl parameter is now required in the resolveSdkOptions() method.

Migration guide

  1. Update environment variables

In the apps/storefront-unified-nextjs/sdk/options.ts file, verify the NEXT_PUBLIC_ALOKAI_MIDDLEWARE_SSR_API_URL environment variable exists:

const ssrApiUrl = env('NEXT_PUBLIC_ALOKAI_MIDDLEWARE_SSR_API_URL');

+ if (!ssrApiUrl) {
+   throw new Error('NEXT_PUBLIC_ALOKAI_MIDDLEWARE_SSR_API_URL is required to run the app');
+ }

See our guide on initializing the SDK for a complete version of the file.

  1. Update SDK configuration file

Update your SDK configuration file (apps/storefront-unified-nextjs/sdk/config.ts) so that registered modules use apiUrl and ssrApiUrl properties instead of middlewareUrl.

import { defineSdkConfig } from '@vue-storefront/next';

export function getSdkConfig() {
  return defineSdkConfig(({ buildModule, config, getRequestHeaders, middlewareModule }) => ({
    commerce: buildModule(middlewareModule, {
-     apiUrl: `${config.middlewareUrl}/commerce`,
+     apiUrl: `${config.apiUrl}/commerce`,
+     ssrApiUrl: `${config.ssrApiUrl}/commerce`,
    }),
  }));
}