From 556a081fa3bb438904f55f3b374fea38c718a422 Mon Sep 17 00:00:00 2001 From: Bartosz Herba Date: Fri, 7 Feb 2025 09:54:07 +0100 Subject: [PATCH] chore: move part of docs to enterprise repository moved docs: middleware, sdk, integreations --- docs/content/3.middleware/1.index.md | 44 - .../3.middleware/2.guides/10.logging.md | 344 - .../2.guides/2.getting-started.md | 259 - .../3.middleware/2.guides/3.extensions.md | 282 - .../3.middleware/2.guides/4.federation.md | 162 - .../3.middleware/2.guides/5.caching.md | 718 -- .../3.middleware/2.guides/6.headers.md | 113 - .../3.middleware/2.guides/6.multistore.md | 115 - .../3.middleware/2.guides/7.api-client.md | 268 - .../2.guides/8.custom-error-handler.md | 29 - docs/content/3.middleware/2.guides/_dir.yml | 1 - .../3.middleware/3.api/middleware.api.json | 7576 ----------------- docs/content/3.middleware/3.api/middleware.md | 1 - .../3.middleware/3.api/multistore.api.json | 695 -- docs/content/3.middleware/3.api/multistore.md | 1 - .../3.middleware/4.reference/change-log.md | 382 - .../4.reference/multistore/change-log.md | 111 - docs/content/3.middleware/_dir.yml | 3 - .../3.middleware/img/extensions/data-flow.svg | 24 - .../img/overview/architecture.svg | 87 - docs/content/4.sdk/1.index.md | 55 - .../4.sdk/2.getting-started/1.index.md | 555 -- .../2.getting-started/2.state-management.md | 185 - .../2.getting-started/3.middleware-module.md | 512 -- .../4.sdk/2.getting-started/4.logger.md | 142 - docs/content/4.sdk/2.getting-started/_dir.yml | 1 - .../4.sdk/3.advanced/1.extending-module.md | 409 - .../4.sdk/3.advanced/2.custom-modules.md | 177 - docs/content/4.sdk/3.advanced/_dir.yml | 1 - docs/content/4.sdk/4.api/sdk.api.json | 3241 ------- docs/content/4.sdk/4.api/sdk.md | 1 - .../4.sdk/5.reference/sdk-change-log.md | 248 - .../4.sdk/5.reference/sdk-next-change-log.md | 225 - .../4.sdk/5.reference/sdk-nuxt-change-log.md | 186 - docs/content/4.sdk/6.migration-guide.md | 779 -- docs/content/4.sdk/_dir.yml | 3 - docs/content/5.integrations/1.index.md | 14 - .../2.guide/1.what-is-an-integration.md | 75 - docs/content/5.integrations/2.guide/_dir.yml | 1 - .../5.integrations/3.custom/2.quick-start.md | 76 - docs/content/5.integrations/3.custom/_dir.yml | 1 - docs/content/5.integrations/_dir.yml | 3 - .../content/5.integrations/_integrations.json | 123 - docs/content/5.integrations/_sidebar.json | 32 - docs/content/_sidebar.json | 8 +- docs/nuxt.config.ts | 5 - 46 files changed, 7 insertions(+), 18266 deletions(-) delete mode 100644 docs/content/3.middleware/1.index.md delete mode 100644 docs/content/3.middleware/2.guides/10.logging.md delete mode 100644 docs/content/3.middleware/2.guides/2.getting-started.md delete mode 100644 docs/content/3.middleware/2.guides/3.extensions.md delete mode 100644 docs/content/3.middleware/2.guides/4.federation.md delete mode 100644 docs/content/3.middleware/2.guides/5.caching.md delete mode 100644 docs/content/3.middleware/2.guides/6.headers.md delete mode 100644 docs/content/3.middleware/2.guides/6.multistore.md delete mode 100644 docs/content/3.middleware/2.guides/7.api-client.md delete mode 100644 docs/content/3.middleware/2.guides/8.custom-error-handler.md delete mode 100644 docs/content/3.middleware/2.guides/_dir.yml delete mode 100644 docs/content/3.middleware/3.api/middleware.api.json delete mode 100644 docs/content/3.middleware/3.api/middleware.md delete mode 100644 docs/content/3.middleware/3.api/multistore.api.json delete mode 100644 docs/content/3.middleware/3.api/multistore.md delete mode 100644 docs/content/3.middleware/4.reference/change-log.md delete mode 100644 docs/content/3.middleware/4.reference/multistore/change-log.md delete mode 100644 docs/content/3.middleware/_dir.yml delete mode 100644 docs/content/3.middleware/img/extensions/data-flow.svg delete mode 100644 docs/content/3.middleware/img/overview/architecture.svg delete mode 100644 docs/content/4.sdk/1.index.md delete mode 100644 docs/content/4.sdk/2.getting-started/1.index.md delete mode 100644 docs/content/4.sdk/2.getting-started/2.state-management.md delete mode 100644 docs/content/4.sdk/2.getting-started/3.middleware-module.md delete mode 100644 docs/content/4.sdk/2.getting-started/4.logger.md delete mode 100644 docs/content/4.sdk/2.getting-started/_dir.yml delete mode 100644 docs/content/4.sdk/3.advanced/1.extending-module.md delete mode 100644 docs/content/4.sdk/3.advanced/2.custom-modules.md delete mode 100644 docs/content/4.sdk/3.advanced/_dir.yml delete mode 100644 docs/content/4.sdk/4.api/sdk.api.json delete mode 100644 docs/content/4.sdk/4.api/sdk.md delete mode 100644 docs/content/4.sdk/5.reference/sdk-change-log.md delete mode 100644 docs/content/4.sdk/5.reference/sdk-next-change-log.md delete mode 100644 docs/content/4.sdk/5.reference/sdk-nuxt-change-log.md delete mode 100644 docs/content/4.sdk/6.migration-guide.md delete mode 100644 docs/content/4.sdk/_dir.yml delete mode 100644 docs/content/5.integrations/1.index.md delete mode 100644 docs/content/5.integrations/2.guide/1.what-is-an-integration.md delete mode 100644 docs/content/5.integrations/2.guide/_dir.yml delete mode 100644 docs/content/5.integrations/3.custom/2.quick-start.md delete mode 100644 docs/content/5.integrations/3.custom/_dir.yml delete mode 100644 docs/content/5.integrations/_dir.yml delete mode 100644 docs/content/5.integrations/_integrations.json delete mode 100644 docs/content/5.integrations/_sidebar.json diff --git a/docs/content/3.middleware/1.index.md b/docs/content/3.middleware/1.index.md deleted file mode 100644 index cf05276d16..0000000000 --- a/docs/content/3.middleware/1.index.md +++ /dev/null @@ -1,44 +0,0 @@ ---- -title: Overview ---- -# Middleware - -Alokai's **Server Middleware** is an Express.js application that provides a single place for you to connect to the multiple services that you need to run your storefront. - -It acts as a layer between your frontend application and the various services that you need to connect to, such as a commerce backend, CMS, or payment gateway. - -Our different [integrations](/integrations) add onto the middleware to provide additional API Clients specific for a certain integration that you can interact with using the [SDK](/sdk). - -## Features - -::list{type="success"} -- Connect multiple services using different technologies and libraries -- Create and [extend](/middleware/guides/extensions) integrations to add new capabilities or modify their behavior -- Control of the requests sent to the integration platform and responses sent back to the Nuxt.js application -- Securely store credentials on the server without exposing them to the end-users of your application -- Improve site performance by moving logic to the server abd shipping less code to the browser -:: - -## Getting Started - -If you're using our storefront, the middleware is set up for you. Our storefronts come with a middleware and frontend app already configured, so you can get started right away. - -But if you're building your Alokai application from scratch, you'll need to set up the middleware to connect to your backend services. - -::grid{:columns="2"} -#section-1 -:card{to="/middleware/guides/extensions" title="See Available Storefronts" description="Get started with one of our ready-to-customize storefronts." icon="material-symbols:storefront"} -#section-2 -:card{to="/middleware/guides/extensions" title="Start From Scratch" description="Set up your server middleware, configure it, and more." icon="gridicons:customize"} -:: - -## Architecture - -The easiest way to explain the Server Middleware architecture is to base the explanation on the Alokai Integration context. - -In the container, the server application uses the integration that can communicate with the external service provider (e.g. commerce backend). The integration can be extended by the integration extensions. Middleware config is provided for both integration and its extensions. - -Middleware Data Flow - - - diff --git a/docs/content/3.middleware/2.guides/10.logging.md b/docs/content/3.middleware/2.guides/10.logging.md deleted file mode 100644 index ea5fb38332..0000000000 --- a/docs/content/3.middleware/2.guides/10.logging.md +++ /dev/null @@ -1,344 +0,0 @@ -# Logger - -The middleware application provides a logger instance that automatically attaches metadata related to the scope of each call. By adding this contextual data, the logger makes it significantly easier to trace the origin of logs or errors, simplifying the debugging and monitoring process across the application. - -:::info -The logger has been available since version 5.1.0. Please refer to the [middleware changelog](https://docs.alokai.com/middleware/reference/change-log#_510) for more details. -::: - -## Using logger - -The middleware application provides access to the logger in various parts of the system, such as in extensions and integrations. This flexibility allows you to log important events, errors, and other data throughout the lifecycle of your application. - -In this section, we will explore how to access and use the logger in different parts of the application. - -The examples below demonstrate how to use the application logger to ensure that correct metadata is conveyed in the logs. To achieve that, we will use the `getLogger` function to extract the logger instance from the passed argument. - -:::tip -The logger is integrated into the middleware to provide additional metadata about the scope of call with every log out of the box. In case of error, it also provides an error boundary. -::: - -### Basic Logger usage - -To use the logger, you need to import the `getLogger` function from the middleware package. Depending on the context, you can obtain the logger from different sources, such as the `alokai` object, `context` object, or `params` object. All such cases are covered in the following examples. For this example, we will use the `context` object. - -```ts -import { getLogger } from "@vue-storefront/middleware"; - -// Assume that `context` is available in the current scope -const logger = getLogger(context); -logger.info("Middleware is running!"); -``` - -Prints: - -```json -{ - "message": "Middleware is running!", - "timestamp": "2024-10-22T19:04:18.791Z", - "severity": "INFO", - "alokai": { - "context": "middleware", - "scope": { - // ... - } - } -} -``` - -The provided logger has a second optional argument that allows you to include custom metadata to be attached to the JSON output. -For example: - -```ts -logger.info("I've just fetched a user!", { - userId: "123", -}); -``` - -Prints: - -```json -{ - "message": "I've just fetched a user!", - "timestamp": "2024-10-22T19:04:18.791Z", - "severity": "INFO", - "alokai": { - "context": "middleware", - "scope": { - // ... - } - }, - "userId": "123" -} -``` - -:::warning -It's forbidden to overwrite **alokai** key within provided metadata. Any attempt will be ineffective. If you need to provide additional metadata, use a different key. **alokai** key is reserved for internal use only. -::: - -### `extendApp` - -```ts -import { getLogger } from "@vue-storefront/middleware"; - -const someExtension = { - name: "some-extension", - extendApp(params) { - const logger = getLogger(params); - - logger.info( - "You can call a logger inside extendApp hook, called on bootstrap of the application" - ); - }, -}; -``` - -### Hooks - -Logger is available in hooks factory: - -```ts -import { getLogger } from "@vue-storefront/middleware"; - -const paypalExtension = { - name: "sapcc-paypal-extension", - hooks(req, res, alokai) { - const logger = getLogger(alokai); - logger.info( - "You can call a logger every time a hooks factory gets invoked" - ); - return { - // ... - }; - }, -}; -``` - -In order, to use logger in certain hooks like `beforeCall`, `beforeCreate`, `afterCall`, `afterCreate` obtain it from it's params: - -```ts -import { getLogger } from "@vue-storefront/middleware"; - -const paypalExtension = { - name: "sapcc-paypal-extension", - hooks(req, res, alokai) { - return { - beforeCall(params) { - const logger = getLogger(params); - logger.info("You can log every time a beforeCall hook gets invoked"); - return params.args; - }, - beforeCreate(params) { - const logger = getLogger(params); - logger.info("You can log every time a beforeCreate hook gets invoked"); - return params.configuration; - }, - afterCall(params) { - const logger = getLogger(params); - logger.info("You can log every time a afterCall hook gets invoked"); - return params.response; - }, - afterCreate(params) { - const logger = getLogger(params); - logger.info("You can log every time a afterCreate hook gets invoked"); - return params.configuration; - }, - }; - }, -}; -``` - -#### Caveat: Accessing logger via closure - -Consider the following snippet: - -```ts -import { getLogger } from "@vue-storefront/middleware"; - -const someExtension = { - name: "some-extension", - hooks(req, res, alokai) { - const hooksLogger = getLogger(alokai); - hooksLogger.info( - "You can call a logger every time a hooks factory gets invoked" - ); - return { - beforeCall(params) { - // Never access via closure a logger belonging to the hooks factory: - hooksLogger.info("Don't do that!"); - // Instead use own logger of every hook function: - const logger = getLogger(params); - logger.info("Do that!"); - return params.args; - }, - }; - }, -}; -``` - -:::warning -Attempt of using `hooksLogger` inside `beforeCall` or other hooks via closure corrupts information about scope of call of the log. Always use logger provided in params to the hook. -::: - -### extendApiMethods - -Inside extended api methods, obtain logger from `context` using `getLogger` function. - -```ts -import { getLogger } from "@vue-storefront/middleware"; - -const testingExtension = { - name: "some-extension", - extendApiMethods: { - addedCustomEndpoint(context) { - const logger = getLogger(context); - logger.info("You can log inside newly created handler!"); - return { - // ... - }; - }, - }, -}; -``` - -:::tip -You can derive logger from context the same way if you are creating an integration. -::: - -### onCreate - -The hook got a new parameter from which you can derive the logger with help of `getLogger` function. - -```ts -import { type AlokaiContainer, getLogger } from "@vue-storefront/middleware"; - -const onCreate = async ( - config: Record = {}, - alokai: AlokaiContainer -) => { - const logger = getLogger(alokai); - logger.info("You can log inside onCreate when creating a new integration"); - - return { - // ... - }; -}; -``` - -## Configuration - -The middleware logger offers flexible configuration options to control logging behavior across the application. These options allow you to manage the verbosity and level of detail in logs based on the needs of different environments, such as development or production. - -### Available Configuration Options - -```ts -/** - * Options for the logger. - */ -export interface LoggerOptions { - /** - * The log level aligned with RFC5424. - */ - verbosity?: LogVerbosity; // (def. "info") - - /** - * Whether to include the stack trace in the log message. - */ - includeStackTrace?: boolean; // (def. true) -} -``` - -#### 1. Verbosity - -This option sets the log verbosity level based on the [RFC 5424](https://datatracker.ietf.org/doc/html/rfc5424) syslog standard. It defines the severity of log messages that should be recorded. Available log levels are: - -- **emergency**: The highest severity level, indicating a system-wide emergency. -- **alert**: Indicates an urgent condition that requires immediate attention. -- **critical**: Highlights critical issues that need immediate action. -- **error**: Used to log error messages that could affect functionality. -- **warning**: Logs warnings about potential issues that should be monitored. -- **notice**: Records significant but non-critical events. -- **info**: Logs general informational messages indicating normal operation. -- **debug**: The most detailed log level, useful for tracing and debugging the application. - -**Example:** -Setting the log verbosity level to `error` ensures only error messages and above (i.e., critical, alert, emergency) will be captured: - -```json -{ - "logger": { - "verbosity": "error" - } -} -``` - -For a development environment, you might prefer a more verbose log level like `debug`: - -```json -{ - "logger": { - "verbosity": "debug" - } -} -``` - -#### 2. includeStackTrace - -This option specifies whether the stack trace should be included in the log messages. If set to `true`, stack traces will be included in error messages, which can be helpful during debugging. If set to `false`, logs will be more concise. - -```json -{ - "logger": { - "includeStackTrace": true - } -} -``` - -### Global configuration - -To configure the logger globally, add a `logger` object to the top-level configuration of the middleware. This configuration will apply to all integrations and parts of the application unless specifically overridden. Here’s an example of a global configuration where the stack trace is included in the logs, and the log level is set to `debug`: - -```js[middleware.config.js] -export const config = { - "logger": { - "includeStackTrace": true, - "verbosity": "debug" - }, - // The rest of the middleware configuration - "integrations": { - // ... - } -} -``` - -This global logger configuration ensures that all logs, regardless of the integration or scope, will follow these settings. - -### Per integration configuration - -If you need different logging settings for specific integrations, you can configure the logger separately within each integration. The logger configuration should be added at the same level as `location` and `configuration` keys within the integration’s object. - -For example, here is how you would configure the logger for an integration with the key `commerce`: - -```js[middleware.config.js] -export const config = { - "integrations": { - "commerce": { - "location": "@vsf-enterprise/sapcc-api/server", - - "configuration": { - // Configuration of integration itself - } - - // Configuration of the logger only for "commerce" integration - "logger": { - "includeStackTrace": true, - "verbosity": "debug" - }, - } - } -} -``` - -In this case, the logging configuration applies only to the `commerce` integration, overriding the global settings if they exist. The logger configuration can vary for each integration, allowing you to customize the level of logging detail based on the needs of specific integrations. - -This approach provides the flexibility to define global logging behavior while also giving control to fine-tune logging per integration, ensuring you capture the necessary details for debugging and monitoring in the most relevant areas. diff --git a/docs/content/3.middleware/2.guides/2.getting-started.md b/docs/content/3.middleware/2.guides/2.getting-started.md deleted file mode 100644 index 2ad8387130..0000000000 --- a/docs/content/3.middleware/2.guides/2.getting-started.md +++ /dev/null @@ -1,259 +0,0 @@ -# Installation - -If you're building your Alokai application from scratch, you'll need to set up the middleware to connect to your backend services. - -## Creating the Application - -Since the middleware is a separate app, it should be built outside of your frontend Alokai application. We recommend using a monorepo to keep both applications in a single repository. - -Our storefronts use an `apps/server` to store the middleware application, so most examples in our documentation will use this folder structure. - -```text -apps/ -| server/ <- your server middleware application -| web/ <- your frontend application -``` - -## Installing Dependencies - -To start, you need to install the `@vue-storefront/middleware` package. It contains the core functionality of the middleware that you can extend with integrations. - -::code-group - -```sh[npm] -npm i @vue-storefront/middleware consola ts-node-dev -``` - -```sh[yarn] -yarn add @vue-storefront/middleware consola ts-node-dev -``` - -```sh[pnpm] -pnpm i @vue-storefront/middleware consola ts-node-dev -``` - -:: - -If you just made a new folder for your middleware, this command will also create a `package.json` file to your project's root directory. - -## Running the Application - -The `@vue-storefront/middleware` package exposes a `createServer` function that you can use to initialize the Express application that runs the Alokai middleware. - -The `createServer` function accepts an `integrations` object and returns an Express.js application that can be used to listen on a port. - -```ts [src/index.ts] -import { createServer } from "@vue-storefront/middleware"; -import consola from "consola"; -import config from "../middleware.config"; - -(async () => { - const app = await createServer({ integrations: config.integrations }); - const host = process.argv[2] ?? "0.0.0.0"; - const port = Number(process.argv[3]) || 4000; - - app.listen(port, host, () => { - consola.success(`API server listening on http://${host}:${port}`); - }); -})(); -``` - -With our middleware file set up, we can use `ts-node-dev` to run our application. - -```json [package.json] -{ - "scripts": { - "dev": "ts-node-dev src/index.ts" - } -} -``` - -## Configuration Options - -The `createServer` function accepts a second parameter for configuring various middleware options: - -```ts [src/index.ts] -const app = await createServer( - { integrations: config.integrations }, - { - // CORS configuration - cors: { - origin: "http://localhost:3000", - credentials: true, - }, - // Body parser configuration - bodyParser: { - limit: "50mb", - }, - // Cookie parser configuration - cookieParser: { - secret: "secret", - }, - // File upload configuration - fileUpload: { - enabled: true, // Enable/disable file upload functionality - maxFileSize: 5242880, // Maximum file size in bytes (default: 5MB) - maxFiles: 5, // Maximum number of files per upload - allowedMimeTypes: ["image/*", "application/pdf"], // Allowed file types - fieldNames: [], // Accepted form field names for file uploads - }, - } -); -``` - -### CORS Configuration - -Configure Cross-Origin Resource Sharing (CORS) settings. By default, `http://localhost:4000` is included in the allowed origins. - -### Body Parser Configuration - -Configure the body-parser middleware settings for handling request bodies. - -### Cookie Parser Configuration - -Configure the cookie-parser middleware settings for handling cookies. - -### File Upload Configuration - -Configure file upload handling for `multipart/form-data` requests. You can either provide static options or a function that returns configuration based on the request: - -```ts -fileUpload: (req) => ({ - enabled: req.headers["x-enable-upload"] === "true", - maxFileSize: 5242880, - maxFiles: 5, - allowedMimeTypes: ["image/*", "application/pdf"], - fieldNames: [], -}); -``` - -Available options: - -- `enabled`: Enable/disable file upload functionality (default: `false`) -- `maxFileSize`: Maximum file size in bytes (default: 5MB) // Maximum file size is limited to 10MB -- `maxFiles`: Maximum number of files per upload (default: 5) -- `allowedMimeTypes`: Array of allowed MIME types (default: `["image/*", "application/pdf"]`) -- `fieldNames`: Array of accepted form field names for file uploads (default: `[]`) - -When file uploads are enabled, uploaded files are available in the `req.files` object within your API endpoints: - -```ts -export const upload = (context) => { - const { files } = context.req; - // Handle uploaded files - return Promise.resolve({ - status: 200, - message: "ok", - }); -}; -``` - -For the performance reasons, file uploads are disabled by default. It is recommended to enable them only when needed and use headers to control file upload behavior. - -You can also dynamically control file upload behavior on a per-request basis. This is particularly useful when you want to enable uploads only for specific scenarios, such as: - -- Authenticated requests -- Requests with specific headers -- Requests from certain origins -- Different file size limits for different endpoints - -Here's an example of dynamic configuration based on request headers: - -```ts [src/index.ts] -const app = await createServer( - { integrations: config.integrations }, - { - fileUpload: (req) => ({ - enabled: req.headers["x-enable-upload"] === "true", - maxFileSize: req.headers["x-upload-size"] - ? parseInt(req.headers["x-upload-size"]) - : 5242880, - maxFiles: 5, - allowedMimeTypes: ["image/*", "application/pdf"], - fieldNames: [], - }), - } -); -``` - -In this example: - -- File uploads are only enabled when the `x-enable-upload: true` header is present -- The maximum file size can be controlled via the `x-upload-size` header -- Other options remain static but could also be made dynamic based on your needs - -## Adding Integrations - -Integrations contain code extend the middleware with additional functionality to make it easy to work with different third-party services. - -Alokai has available integrations that you can use out of the box, but you can also create your own integrations to connect to any service that you need. - -Most integrations are made up of two parts: - -1. An SDK module that extends the Alokai SDK to add methods to your frontend -2. An API Client that extends the middleware to add new API endpoints or modify the Express.js application itself - -We recommend creating a `middleware.config.js` file located at the project's root that you can use to configure API Clients for your integrations. - -Each integration will be an object with a unique key that you can find in each integration's installation guide. This key is used for communication with the middleware, so changing it might cause the integration to break. - -The object for each integration can contain the following properties: - -- `location` - the path to the API Client file in your `node_modules` folder -- `configuration` - the configuration for the integration (see the integration's installation guide for details) -- `extensions` - an optional function that can be used to extend the integration with additional functionality -- `customQueries` - an optional object that can be used to add custom queries to the integration - -```ts [middleware.config.ts] -export const integrations = { - example: { - location: "@vue-storefront/example-api/server", - configuration: { - // configuration for the integration (see the integration's installation guide for details) - }, - extensions: (baseExtensions) => [ - ...baseExtensions, - // your additional extensions - ], - customQueries: {}, - }, -}; -``` - -## Local Development - -### TypeScript Configuration - -If you want to have the same `tsconfig.json` options as our boilerplate, you can reference the [boilerplate configuration](https://github.com/vuestorefront/storefront-nuxt3-boilerplate/blob/develop/apps/server/tsconfig.json). - -### Using `nodemon` - -To make local development smoother, you can use [`nodemon`](https://www.npmjs.com/package/nodemon) to watch for changes in your middleware application and restart the server automatically. - -```sh -npm i -D nodemon -``` - -Finally, we can create a `nodemon.json` file to set the files to watch and the command that we want to run when a change is made. - -```json [nodemon.json] -{ - "watch": ["**/*"], - "ext": "ts", - "exec": "ts-node-dev src/index.ts" -} -``` - -Then, you can add a script to your `package.json` file to run the middleware with `nodemon`. - -```json -{ - "scripts": { - "dev": "nodemon middleware.js" - } -} -``` - -## Next Steps - -:card{to="/middleware/guides/extensions" title="Creating Extensions" description="Use extensions to customize or extend the middleware to match your needs." icon="gridicons:customize"} diff --git a/docs/content/3.middleware/2.guides/3.extensions.md b/docs/content/3.middleware/2.guides/3.extensions.md deleted file mode 100644 index 8353ac9a91..0000000000 --- a/docs/content/3.middleware/2.guides/3.extensions.md +++ /dev/null @@ -1,282 +0,0 @@ -# Extending the Middleware - -When developing your storefront, there will be times when you need to customize the way the middleware and integrations run. For example, you might want to add or edit a new API endpoint or even modify the Express.js application itself. Alokai's Server Middleware allows you to do this using extensions. - -## Adding an extension - -Extensions can be added to any integration in your `middleware.config.ts` file by creating an `extensions` function. This function receives an array of existing extensions as the only argument and has to return an updated array of extensions (with your extension added). - -```js -export const integrations = { - sapcc: { - // ... - extensions: (extensions) => [ - ...extensions, // don't forget to include existing extensions - { - name: 'extension-name', - isNamespaced: `[true/false:default]`, - extendApiMethods: { /* ... */ }, - extendApp: (app) => { /* ... */ }, - hooks: () => { /* ... */ } - } - ] - } -} -``` - -## Creating an extension - -You can define as many extensions as you want. Each extension has the following structure: - -```js -const extension = { - name: "extension-name", - isNamespaced: `[true/false:default]`, - extendApiMethods: { - customMethod: (context, params) => { - /* ... */ - }, - }, - extendApp: (app) => { - /* ... */ - }, - hooks: (req, res) => { - return { - beforeCreate: ({ configuration }) => configuration, - afterCreate: ({ configuration }) => configuration, - beforeCall: ({ configuration, callName, args }) => args, - afterCall: ({ configuration, callName, args, response }) => response, - }; - }, -}; -``` - -- `name` - a unique name for your extension, -- `isNamespaced` - defines if the extension should be namespaced. Namespaced extensions are registered under `/{integration-name}/{extension-name}` extension of integration's namespace in opposition to non-namespaced extensions which are registered under `/{integration-name}` integration's namespace. Default value is `false`. Extensions without a namespace can potentially override existing endpoints, so it's recommended to use namespaced extensions whenever possible. -- `extendApiMethods` - overrides an integration's API Client to modify default behavior or add new API endpoints -- `extendApp` - gives you access to the Express.js app -- `hooks` - defines lifecycle hooks of API-client - - `beforeCreate` - called before API-client creates a connection. It accepts an integration configuration as an argument and must return it as well. You can use it to modify the configuration or merge it with the default values, - - `afterCreate` - similar to the previous function, but called after the connection has been created. It accepts an integration configuration as an argument and must return it as well. This hook is usually used for cleanup work after altering the configuration in `beforeCreate`, - - `beforeCall` - called before each API-client function. Gives you access to the integration configuration, function name, and arguments. Can be used to modify the arguments based on the input parameters and must return them, - - `afterCall` - called after each API-client function. Gives you access to the configuration, function name, arguments and response. Can be used to modify the response based on the input parameters and must return it. - -## Lifecycle Hooks - -Middleware extensions allow you to extend your Express.js server, register additional API endpoints, or hook into the -lifecycle of a request sent to a given Server Middleware integration from the application. - -Middleware Data Flow - -## Use Cases - -### Adding an Endpoint - -To register a new API endpoint, you can register a custom extension and use the `extendApiMethods` property. API -endpoints cannot be registered directly. Let's look at an example: - -```ts -export const integrations = { - sapcc: { - // ... - extensions: (extensions) => [ - ...extensions, - { - name: "example-extension", - extendApiMethods: { - baseSites: async (context) => { - // Using integration's HTTP client to make a request to SAP Commerce Cloud backend - // SAPCC integration is using `axios` as an HTTP client, so we want to retreive only the `data` property from the response. - const { data } = await context.client.get("/basesites"); - return data; - }, - }, - }, - ], - }, -}; -``` - -All integrations can be extended, however, this example extends the SAP Commerce Cloud integration, to give more context about real-life usage. We registered `baseSites` in `extendApiMethods` which creates a new `/api/sapcc/baseSites` endpoint. - -This method accepts two parameters: - -- `context` - integration context which includes: - - `config` - integration configuration - - `client` - HTTP client used by the integration - - `req` - HTTP request object - - `res` - HTTP response object - - `extensions` - extensions registered within an integration - - `customQueries` - custom GraphQL queries registered within integration (used only with GraphQL) - - `extendQuery` - helper function for handling custom queries (used only with GraphQL) -- `params` - parameters passed in the request's body - -#### Using extension methods in the frontend - -To call the extension endpoint, you should use the [middlewareModule](/sdk/getting-strated/middlewareModule). - -First, you need to prepare the type definition for the extension methods. It will be necessary to pass this type to the `middlewareModule`. To do it, let's aggregate the extension methods in a single object: - -```typescript [storefront-middleware/middleware.config.ts] -export const extensionMethods = { - baseSites: async (context, params) => { - const { data } = await context.client.get("/basesites"); - return data; - }, -}; - -export const integrations = { - sapcc: { - location: "@vsf-enterprise/sapcc-api/server", - configuration: { - // ... - }, - extensions: (extensions) => [ - ...extensions, - { - name: "example-extension", - extendApiMethods: { - ...extensionMethods, - }, - }, - ], - }, -}; -``` - -Then, let's use the `WithoutContext` type helper to prepare the type of the endpoints created by the extension methods. As a good practice, it's recommended to use a separate file for the types used in the middleware configuration: - -```typescript [storefront-middleware/types.ts] -import { type WithoutContext } from "@vue-storefront/middleware"; -import { extensionMethods } from "./middleware.config"; - -export { type Endpoints as SapccEndpoints } from "@vsf-enterprise/sapcc-api"; -export type ExtensionEndpoints = WithoutContext; -``` - -Finally, pass the `ExtensionEndpoints` type the `middlewareModule` type parameter: - -::code-group - -```typescript[Next.js] -import { CreateSdkOptions, createSdk } from "@vue-storefront/next"; -import { SapccEndpoints, ExtensionEndpoints } from "storefront-middleware/types"; - -const options: CreateSdkOptions = { - middleware: { - apiUrl: "http://localhost:4000", - }, -}; - -export const { getSdk } = createSdk( - options, - ({ buildModule, middlewareUrl, middlewareModule, getRequestHeaders }) => ({ - sapcc: buildModule(middlewareModule, { - apiUrl: middlewareUrl + "/sapcc", - defaultRequestConfig: { - headers: getRequestHeaders(), - }, - }), - }) -); -``` - -```typescript[Nuxt.js] -import { SapccEndpoints, ExtensionEndpoints } from "storefront-middleware/types"; - -export default defineSdkConfig( - ({ buildModule, middlewareUrl, middlewareModule getRequestHeaders }) => ({ - sapcc: buildModule(middlewareModule, { - apiUrl: middlewareUrl + "/sapcc", - defaultRequestConfig: { - headers: getRequestHeaders(), - }, - }), - }) -); -``` - -```typescript[Other] -import { initSDK, buildModule, middlewareModule } from "@vue-storefront/sdk"; -import { SapccEndpoints, ExtensionEndpoints } from "storefront-middleware/types"; - -const { sapcc } = initSDK({ - sapcc: buildModule(middlewareModule, { - apiUrl: "http://localhost:8181/sapcc", - }), -}); - -export { sapcc }; -``` - -:: - -Now, the SDK is aware of the extension methods, and you can call them as follows: - -```typescript -const baseSites = await sdk.sapcc.baseSites(); -``` - -### Creating a configurable extension - -In more complex cases, you might want to create an extension that can be configured. - -To avoid code duplication, you can prepare a closure that will create a new extension with a given configuration. - -Using closures is a recommended way to create a configurable extension. It allows you to reuse the same logic in multiple integrations and keeps your code clean and maintainable. - -```ts -const createCacheControlExtension = (config: Record) => { - return { - name: "cache-control-extension", - hooks(req, res) { - return { - afterCall({ response, callName }) { - if (req.method !== "GET") { - console.log("[CACHING] It's not a GET request, skipping caching"); - return response; - } - - if (res.getHeader("set-cookie")) { - console.log( - "[CACHING] Response containing Set-Cookie header, skipping caching" - ); - return response; - } - - if (callName in config) { - res.set("Cache-Control", config[callName]); - } - - return response; - }, - }; - }, - }; -}; -``` - -Then, you can use it in your `middleware.config.ts` file: - -```ts -export const integrations = { - sapcc: { - // ... - extensions: (extensions) => [ - ...extensions, - createCacheControlExtension({ - searchProducts: "public, max-age=3600", - }), - ], - }, - contentful: { - // ... - extensions: (extensions) => [ - ...extensions, - createCacheControlExtension({ - getEntries: "public, max-age=3600", - }), - ], - }, -}; -``` diff --git a/docs/content/3.middleware/2.guides/4.federation.md b/docs/content/3.middleware/2.guides/4.federation.md deleted file mode 100644 index 04d06b7912..0000000000 --- a/docs/content/3.middleware/2.guides/4.federation.md +++ /dev/null @@ -1,162 +0,0 @@ -# Data Federation - -Optimizing server requests through data federation is a common technique used within composable architectures that improves performance and reduces coupling between frotnend and backend API's. This guide shows how to use the `getApiClient` method to retrieve and interact with integrations within the context of another integration to mix them together in one request. - -## Why? - -- **Minimized Network Traffic**: Fewer server calls lead to reduced latency and enhanced responsiveness. -- **Simplified Frontend Architecture**: By grouping related server requests, the frontend logic becomes less complex and less coupled. -- **Data Unification**: You can retrieve data from multiple sources and unify it in one response under common data model unrelated to the details of underlying API's. - -## How? - -## Uisng `getApiClient` Method to access different API client - -If you want to retrieve a loaded integration within the context of another, you can use the `getApiClient` method. This method serves as a bridge between various integrations, ensuring seamless data flow and interaction. - -Usage: - -```javascript -const sapcc = await context.getApiClient("sapcc"); -``` - -The `getApiClient` method takes a single argument, which is the key of the api client you wish to retrieve. This is the key you would define in the `middleware.config.js` file for the integration you wish to retrieve. The key is essentially an identifier for the integration. - -Here's a basic example of what this might look like: - -```typescript [middleware.config.ts] -export const integrations = { - sapcc: { - location: "@vsf-enterprise/sapcc-api/server", - configuration: { - // ... - }, - extensions: (extensions) => [ - ...extensions, - { - name: "sapcc-contentful-extension", - extendApiMethods: { - getPDP: async (context, params: { id: string }) => { - const sapccApi = context.api; // You can access integration methods directly - const contentful = await context.getApiClient("contentful"); // You can access other integrations using getApiClient - - const [product, content] = Promise.all( - sapccApi.getProduct({ id: params.id }), - contentful.api.getEntries({ - content_type: "product", - "fields.sku": params.id, - }) - ); - - return { - product, - content, - }; - }, - }, - }, - ], - }, - contentful: { - location: "@vsf-enterprise/contentful-api/server", - configuration: { - // ... - }, - }, -}; -``` - -1. Extend the integration with new endpoint: Create a new endpoint that will act as the main entry point for the grouped requests. - -2. Group Server Requests: Within this endpoint, utilize the `getApiClient` method to retrieve and interact with the required integrations. - -3. Aggregate Data: Once data from all required integrations is retrieved, aggregate and format it as needed. - -4. Return Unified Response: Send a consolidated response back to the frontend. - -### Using federation methods in the frontend - -To call the federation endpoint, you can follow the [Using extension methods in the frontend guide](/middleware/guides/extensions#using-extension-methods-in-the-frontend). - -## Real-World Examples - -The examples provided demonstrate practical uses of data federation: - -### Example 1: Fetching Custom Product Properties from Legacy Systems - -This use case involves calling the commerce backend to fetch specific product data. Additionally, a separate call is made to a legacy custom system of the customer, to retrieve a custom product property (e.g., stock of the product). This data is used, for example, to display stock information on the product page. - -Example implementation might look like this: - -```typescript [middleware.config.ts] -export const integrations = { - sapcc: { - // ... - extensions: (extensions) => [ - ...extensions, - { - name: "federation-extension", - extendApiMethods: { - enrichedSearch: async (context, params: { productId: string }) => { - const sapccApi = context.api; - const legacyCustomSystem = await context.getApiClient("legacyCustomSystem"); - - const [prouctStock, product] = await Promise.all([ - legacyCustomSystem.api.getProductStock({ - productId: params.productId, - }), - sapccApi.getProduct({ - { id: params.productId }, - }), - ]); - - return { - ...product, - stock: productStock, - }; - }, - }, - }, - ], - }, - legacyCustomSystem: { - // ... - }, -}; -``` - -## TypeScript Support - -`getApiClient` helper returns the `ApiClient` interface, which is a generic type. It takes three type arguments: - -- `Api` - the type of the API object returned by the integration, -- `Config` - the type of the configuration object passed to the integration, -- `Client` - the type of the HTTP client object returned by the integration. - -Usually, an integration exports those types. For example, the `sapcc` integration exports the following types: - -```typescript -import { - Endpoints, - MiddlewareConfig, - AxiosInstance, -} from "@vsf-enterprise/sapcc-api"; -``` - -:::tip Type of endpoints - -Sometimes, the `Endpoints` type is not exported by the integration. If that's the case, you can import the `{xyz}IntegrationContext` type from the integration package. - -For example, the `sapcc` integration exports the `SapccIntegrationContext` type, which contains the following: - -```typescript -import { SapccIntegrationContext } from "@vsf-enterprise/sapcc-api"; - -SapccIntegrationContext.api // the endpoints type -SapccIntegrationContext.config // the configuration object type -SapccIntegrationContext.client // the HTTP client object type - -``` - -This applies to all integrations. -::: diff --git a/docs/content/3.middleware/2.guides/5.caching.md b/docs/content/3.middleware/2.guides/5.caching.md deleted file mode 100644 index bad125423c..0000000000 --- a/docs/content/3.middleware/2.guides/5.caching.md +++ /dev/null @@ -1,718 +0,0 @@ -# Caching - -::warning -#title -This guide is for setting cookie headers in in your Alokai application -#default -If you are looking to enable CDN caching, please contact the Alokai team. -:: - -Caching is another powerful technique that can boost the performance and reliability of your Alokai middleware application. In the following guide, we will cover the caching of responses from GET endpoints that can be cached. - -## What are the requirements to cache an endpoint's response? - -If you've created or modified an endpoint and wish to cache its response, the endpoint must: - -- Use the GET HTTP method. -- Be cookie-independent, meaning it shouldn't build the response based on cookie values. -- Send variables as URL query parameters. - -If the aforementioned requirements are met, you can safely cache the response. - -### What if I cache a response not fullfiling requirements? - -There's a possibility that the CDN either won't cache the response or will cache a response intended for a specific user, causing other users to receive that same response. - -You might wonder, how can we ensure the requirements are fulfilled? The answer is the caching extension! - -## Understanding the caching extension - -Given the myriad of edge cases that different clients might have, we've chosen to offer middleware caching extensions for each eCommerce integration. These extensions are freely available and serve as a starting point in your application. With this approach, you aren't limited. You have the flexibility to develop custom rules for specific endpoints, or groups of endpoints, in a way that best suits your business needs. - -In this section, we will build a sample caching extension from scratch and explain the thought process behind it. - -First, we assign a name to the extension and register the `afterCall` hook. This hook is triggered after the endpoint's code has executed but before sending a response to the client. It's the ideal location to perform essential checks and set the **Cache-Control** response header. Inside the hook, we must return the original `response`. This step is necessary to maintain the hook's contract, even though it's not directly related to the caching aspect. - -```js [middleware.config.js] -const cachingExtension = { - name: "caching-extension", - hooks(req, res) { - return { - afterCall({ response }) { - // ... - return response - } - } - } -}; -``` - -We start with a basic structure, and then we aim to filter out cases that aren't suitable for caching. To achieve this, we add a check for the HTTP method, since we only want to cache GET requests. -:::tip -We've intentionally made the extension code straightforward and repetitive to make it easy to understand and serve as a solid starting point for various approaches. While we've used console.log for simplicity, don't hesitate to modify, refactor, or adapt the code to suit your vision and address your business-specific edge cases. For instance, you might want to remove the log statement or replace it with a `debug` function from a `Logger` library. -::: - -```js [middleware.config.js] -const cachingExtension = { - name: "caching-extension", - hooks(req, res) { - return { - afterCall({ response }) { - if (req.method !== "GET") { - console.log("[CACHING] It's not a GET request, skipping caching"); - return response; - } - - return response - } - } - } -}; -``` - -We also need to account for another scenario: filtering out responses that contain the 'Set-Cookie' header. - -```js [middleware.config.js] -const cachingExtension = { - name: "caching-extension", - hooks(req, res) { - return { - afterCall({ response }) { - if (req.method !== "GET") { - console.log("[CACHING] It's not a GET request, skipping caching"); - return response; - } - - if (res.getHeader("set-cookie")) { - console.log( - "[CACHING] Response containing Set-Cookie header, skipping caching" - ); - return response; - } - - return response - } - } - } -}; -``` - -Then we prepare information needed to proceed to evaluate each endpoint. We create a constant and a variable containg name of the currently called API endpoint and it's params. As `req.query.body` might be missing or not contain correct JSON for some reason - we need to handle potential error. That's why we use try...catch block, so malicious requests won't break the application. - -```js [middleware.config.js] -const cachingExtension = { - name: "caching-extension", - hooks(req, res) { - return { - afterCall({ response }) { - if (req.method !== "GET") { - console.log("[CACHING] It's not a GET request, skipping caching"); - return response; - } - - if (res.getHeader("set-cookie")) { - console.log( - "[CACHING] Response containing Set-Cookie header, skipping caching" - ); - return response; - } - - const apiMethod = req.params.functionName; - let params; - try { - params = JSON.parse((req.query.body as string) || "{}"); - } catch (error) { - console.error( - "[CACHING] Couldn't read stringified body from query params, skipping caching. Error:", - error, - ); - return response; - } - - return response - } - } - } -}; -``` - -Once it's ready, we proceed to evaluate each endpoint. There are 3 cases we should consider. In the simplest one, which is for example `getReview` endpoint (we are basing on commercetools integration in this guide) - there weren't any cookie related operations so we could easily set **Cache-Control** headers if `apiMethod` equals `getReview`. - -```ts -const cachingExtension = { - name: "caching-extension", - hooks(req, res) { - return { - afterCall({ response }) { - if (req.method !== "GET") { - console.log("[CACHING] It's not a GET request, skipping caching"); - return response; - } - - if (res.getHeader("set-cookie")) { - console.log( - "[CACHING] Response containing Set-Cookie header, skipping caching" - ); - return response; - } - - const apiMethod = req.params.functionName; - let params; - try { - params = JSON.parse((req.query.body as string) || "{}"); - } catch (error) { - console.error( - "[CACHING] Couldn't read stringified body from query params, skipping caching. Error:", - error, - ); - return response; - } - - if (apiMethod === "getReview") { - console.log( - "[CACHING] It's a getReview request, caching requirements fulfilled!" - ); - res.set("Cache-Control", "public, max-age=315576"); - } - - return response - } - } - } -}; -``` - -Calling this endpoint via the SDK doesn't require any additional steps to cache the response. - -```ts -import { sdk } from '~/sdk.config.ts'; - -const { reviews } = await sdk.commerce.getProductReviews({ - productId: '891c95f8-7bf4-4945-9ab5-00906a5f76ba', // example id - limit: 20 // example limit -}); -``` - -The case for the `getStores` endpoint is a bit more complicated. It previously read the `locale` from the cookie, (which contradicts one of our [requirements](#what-are-requirements-to-cache-endpoints-response)). To maintain backward compatibility, we've retained this mechanism. However, it won't be used if you provide the `locale` via query parameters. With this in mind, we can cache responses for this endpoint only when the request's URL includes the `locale` query parameter. - -```js [middleware.config.js] -const cachingExtension = { - name: "caching-extension", - hooks(req, res) { - return { - afterCall({ response }) { - if (req.method !== "GET") { - console.log("[CACHING] It's not a GET request, skipping caching"); - return response; - } - - if (res.getHeader("set-cookie")) { - console.log( - "[CACHING] Response containing Set-Cookie header, skipping caching" - ); - return response; - } - - const apiMethod = req.params.functionName; - let params; - try { - params = JSON.parse((req.query.body as string) || "{}"); - } catch (error) { - console.error( - "[CACHING] Couldn't read stringified body from query params, skipping caching. Error:", - error, - ); - return response; - } - - if (apiMethod === "getReview") { - console.log( - "[CACHING] It's a getReview request, caching requirements fulfilled!" - ); - res.set("Cache-Control", "public, max-age=315576"); - } else if (apiMethod === "getStores") { - // Checking if obligatory param - `locale` has been provided - if (params.locale) { - console.log( - "[CACHING] It's a getStores request, caching requirements fulfilled!" - ); - res.set("Cache-Control", "public, max-age=31557600"); - } else { - console.log( - "[CACHING] It's a getStores request, caching requirements not fulfilled!" - ); - } - } - - return response - } - } - } -}; -``` - -To pass the `locale` via query parameters using the SDK, call the method as follows: - -```ts -import { sdk } from '~/sdk.config.ts'; - -const result = await sdk.commerce.getStores({ - locale: "en" -}); -``` - -A case of `getProduct` endpoint is similiar but a tiny bit more complicated. It used to read a few cookies that are always available and a two that are **optional**. Knowing that, we have to check optional fields the following way: `"channel" in params` and send theirs value as `{ channel: null }` in SDK method. Sending value equal `null` for optional fields prevents it from calling fallback mechanism using cookies, as the payload will be stringified and `null` value won't be lost in JSON standard. - -The case for the `getProduct` endpoint is similar, though slightly more intricate. It used to read several always-available cookies as well as two that are **optional**. Given this, we need to check the optional fields in the following manner: `"channel" in params`. Then, send their values as `{ channel: null }` in the SDK method. By sending a value of `null` for optional fields, it prevents the fallback mechanism from using cookies. This is because the payload will be stringified, and in the JSON standard, the `null` value is preserved. - -```js [middleware.config.js] -const cachingExtension = { - name: "caching-extension", - hooks(req, res) { - return { - afterCall({ response }) { - if (req.method !== "GET") { - console.log("[CACHING] It's not a GET request, skipping caching"); - return response; - } - - if (res.getHeader("set-cookie")) { - console.log( - "[CACHING] Response containing Set-Cookie header, skipping caching" - ); - return response; - } - - const apiMethod = req.params.functionName; - let params; - try { - params = JSON.parse((req.query.body as string) || "{}"); - } catch (error) { - console.error( - "[CACHING] Couldn't read stringified body from query params, skipping caching. Error:", - error, - ); - return response; - } - - if (apiMethod === "getReview") { - console.log( - "[CACHING] It's a getReview request, caching requirements fulfilled!" - ); - res.set("Cache-Control", "public, max-age=315576"); - } else if (apiMethod === "getStores") { - if (params.locale) { - console.log( - "[CACHING] It's a getStores request, caching requirements fulfilled!" - ); - res.set("Cache-Control", "public, max-age=31557600"); - } else { - console.log( - "[CACHING] It's a getStores request, caching requirements not fulfilled!" - ); - } - } else if (apiMethod === "getProduct") { - if ( - // Obligatory fields - params.country && - params.currency && - params.locale && - // Optional fields - "channel" in params && - "customerGroupId" in params - ) { - console.log( - "[CACHING] It's a getProduct request, caching requirements fulfilled!" - ); - res.set("Cache-Control", "public, max-age=31557600"); - } else { - console.log( - "[CACHING] It's a getProduct request, caching requirements not fulfilled!" - ); - } - } - - return response - } - } - } -}; -``` - -To pass the required values through SDK (optional and required), call the method as follows: - -```ts -import { sdk } from '~/sdk.config.ts'; - -const { products } = await sdk.commerce.getProduct({ - country: "PL", - currency: "USD", - locale: "en", - customerGroupId: null, - channel: null, -}); -``` - -## Why do I need to pass null values? - -When the object is passed to the SDK method, it will be stringified and set as the `body` query parameter in the request URL. In the JSON standard, a null value is retained. In contrast, an `undefined` value would be omitted, leading to the use of cookies as a fallback. - -## Can I set multiple response headers? - -For example **Cache-Control** & **CDN-Cache-Control**? Yes, it's absolutely fine to do so. - -## How do we know which SDK method calls which endpoint? - -Every SDK method comes with a detailed description and usage examples. To view this, you can either hover over the method in your IDE for a few seconds to see a tooltip or consult the API Reference of the SDK package in our documentation. There, you'll find information about the target URL associated with each SDK method. - -## Full implementation - -A caching strategy in the middleware needs to be tailored for each integration. Below, we provide a basic extension that demonstrates how to approach this for each of the following eCommerce integrations: SAP Commerce Cloud, Commercetools and BigCommerce. Copy the code for your specific eCommerce platform and assign it to a constant inside `middleware.config.js`: - -:::code-group -```js[commercetools] -// middleware.config.js -const cachingExtension = { - name: "caching-extension", - hooks(req, res) { - return { - afterCall({ response }) { - if (req.method !== "GET") { - console.log("[CACHING] It's not a GET request, skipping caching"); - return response; - } - - if (res.getHeader("set-cookie")) { - console.log( - "[CACHING] Response containing Set-Cookie header, skipping caching" - ); - return response; - } - - const apiMethod = req.params.functionName; - let params; - try { - params = JSON.parse((req.query.body as string) || "{}"); - } catch (error) { - console.error( - "[CACHING] Couldn't read stringified body from query params, skipping caching. Error:", - error, - ); - return response; - } - - if (apiMethod === "getReview") { - console.log( - "[CACHING] It's a getReview request, caching requirements fulfilled!" - ); - res.set("Cache-Control", "public, max-age=315576"); - } else if (apiMethod === "getStores") { - if (params.locale) { - console.log( - "[CACHING] It's a getStores request, caching requirements fulfilled!" - ); - res.set("Cache-Control", "public, max-age=31557600"); - } else { - console.log( - "[CACHING] It's a getStores request, caching requirements not fulfilled!" - ); - } - } else if (apiMethod === "getProduct") { - if ( - params.country && - params.currency && - params.locale && - "channel" in params && - "customerGroupId" in params - ) { - console.log( - "[CACHING] It's a getProduct request, caching requirements fulfilled!" - ); - res.set("Cache-Control", "public, max-age=31557600"); - } else { - console.log( - "[CACHING] It's a getProduct request, caching requirements not fulfilled!" - ); - } - } else if (apiMethod === "getCategory") { - console.log( - "[CACHING] It's a getCategory request, caching requirements fulfilled!" - ); - res.set("Cache-Control", "public, max-age=31557600"); - } else if (apiMethod === "getFacet") { - if ( - params.country && - params.currency && - params.locale && - "customerGroupId" in params - ) { - console.log( - "[CACHING] It's a getFacet request, caching requirements fulfilled!" - ); - res.set("Cache-Control", "public, max-age=315576"); - } else { - console.log( - "[CACHING] It's a getFacet request, caching requirements not fulfilled!" - ); - } - } - return response; - }, - }; - }, -}; -``` - -```js[bigcommerce] -// middleware.config.js -const cachingExtension = { - name: "caching-extension", - hooks(req, res) { - return { - afterCall({ response }) { - if (req.method !== "GET") { - console.log("[CACHING] It's not a GET request, skipping caching"); - return response; - } - - if (res.getHeader("set-cookie")) { - console.log( - "[CACHING] Response containing Set-Cookie header, skipping caching" - ); - return response; - } - - const apiMethod = req.params.functionName; - let params; - try { - params = JSON.parse((req.query.body as string) || '{}'); - } catch (error) { - console.error( - "[CACHING] Couldn't read stringified body from query params, skipping caching. Error: ", - error, - ); - return response; - } - - if (apiMethod === "getReview") { - console.log( - "[CACHING] It's a getReview request, caching requirements fulfilled!" - ); - res.set("Cache-Control", "public, max-age=315576"); - } else if (apiMethod === "getStores") { - if (params.locale) { - console.log( - "[CACHING] It's a getStores request, caching requirements fulfilled!" - ); - res.set("Cache-Control", "public, max-age=31557600"); - } else { - console.log( - "[CACHING] It's a getStores request, caching requirements not fulfilled!" - ); - } - } else if (apiMethod === "getProduct") { - if ( - params.country && - params.currency && - params.locale && - "channel" in params && - "customerGroupId" in params - ) { - console.log( - "[CACHING] It's a getProduct request, caching requirements fulfilled!" - ); - res.set("Cache-Control", "public, max-age=31557600"); - } else { - console.log( - "[CACHING] It's a getProduct request, caching requirements not fulfilled!" - ); - } - } else if (apiMethod === "getCategory") { - console.log( - "[CACHING] It's a getCategory request, caching requirements fulfilled!" - ); - res.set("Cache-Control", "public, max-age=31557600"); - } else if (apiMethod === "getFacet") { - if ( - params.country && - params.currency && - params.locale && - "customerGroupId" in params - ) { - console.log( - "[CACHING] It's a getFacet request, caching requirements fulfilled!" - ); - res.set("Cache-Control", "public, max-age=315576"); - } else { - console.log( - "[CACHING] It's a getFacet request, caching requirements not fulfilled!" - ); - } - } - return response; - }, - }; - }, -}; -``` - -```js[SAP Commerce] -// middleware.config.js -const cachingExtension = { - name: "caching-extension", - hooks(req, res) { - return { - afterCall({ response }) { - if (req.method !== "GET") { - console.log("[CACHING] It's not a GET request, skipping caching"); - return response; - } - - if (res.getHeader("set-cookie")) { - console.log( - "[CACHING] Response containing Set-Cookie header, skipping caching" - ); - return response; - } - - const apiMethod = req.params.functionName; - let params; - try { - params = JSON.parse((req.query.body as string) || '{}'); - } catch (error) { - console.error( - "[CACHING] Couldn't read stringified body from query params, skipping caching. Error: ", - error, - ); - return response; - } - - // Here we reverted conditions as each aforementioned endpoint requires exactly these 2 values - if (params.lang && params.currency) { - if (apiMethod === "getCatalogVersion") { - console.log( - "[CACHING] It's a getCatalogVersion request, caching requirements fulfilled!" - ); - res.set("Cache-Control", "public, max-age=31557600"); - } else if (apiMethod === "getCategory") { - console.log( - "[CACHING] It's a getCategory request, caching requirements fulfilled!" - ); - res.set("Cache-Control", "public, max-age=31557600"); - } else if (apiMethod === "getCountries") { - console.log( - "[CACHING] It's a getCountries request, caching requirements fulfilled!" - ); - res.set("Cache-Control", "public, max-age=31557600"); - } else if (apiMethod === "getCountryRegions") { - console.log( - "[CACHING] It's a getCountryRegions request, caching requirements fulfilled!" - ); - res.set("Cache-Control", "public, max-age=31557600"); - } else if (apiMethod === "getProduct") { - console.log( - "[CACHING] It's a getProduct request, caching requirements fulfilled!" - ); - res.set("Cache-Control", "public, max-age=31557600"); - } else if (apiMethod === "getProductReferences") { - console.log( - "[CACHING] It's a getProductReferences request, caching requirements fulfilled!" - ); - res.set("Cache-Control", "public, max-age=31557600"); - } else if (apiMethod === "getProductReviews") { - console.log( - "[CACHING] It's a getProductReviews request, caching requirements fulfilled!" - ); - res.set("Cache-Control", "public, max-age=31557600"); - } else if (apiMethod === "getProductSearchPageData") { - console.log( - "[CACHING] It's a getProductSearchPageData request, caching requirements fulfilled!" - ); - res.set("Cache-Control", "public, max-age=31557600"); - } else if (apiMethod === "getSuggestions") { - console.log( - "[CACHING] It's a getSuggestions request, caching requirements fulfilled!" - ); - res.set("Cache-Control", "public, max-age=31557600"); - } else if (apiMethod === "getTitles") { - console.log( - "[CACHING] It's a getTitles request, caching requirements fulfilled!" - ); - res.set("Cache-Control", "public, max-age=31557600"); - } else if (apiMethod === "searchProduct") { - console.log( - "[CACHING] It's a searchProduct request, caching requirements fulfilled!" - ); - res.set("Cache-Control", "public, max-age=31557600"); - } - } else { - console.log( - "[CACHING] 'lang' and 'currency' has to be provided as params to cache, skipping cache" - ); - } - return response; - }, - }; - }, -}; -``` -::: - -:::tip -Feel free to remove `console.log` or replace it with dedicated logger if you need. -::: - -Then add it to the `extensions` array: - -:::code-group -```js[commercetools] -// middleware.config.js -const middlewareConfig = { - integrations: { - ct: { - location: "@vsf-enterprise/commercetools-api/server", - extensions: (extensions) => [...extensions, cachingExtension] - configuration: { - // ... - }, - }, - }, -}; -``` - -```js[bigcommerce] -// middleware.config.js -const middlewareConfig = { - integrations: { - bigcommerce: { - location: "@vsf-enterprise/bigcommerce-api/server", - extensions: (extensions) => [...extensions, cachingExtension] - configuration: { - // ... - }, - }, - }, -}; -``` - -```js[SAP Commerce] -// middleware.config.js -const middlewareConfig = { - integrations: { - sapcc: { - location: "@vsf-enterprise/sapcc-api/server", - extensions: (extensions) => [...extensions, cachingExtension] - configuration: { - // ... - }, - }, - }, -}; -``` -::: - -From now on, if an endpoint is cookie-independent, the extension will set the **Cache-Control** response header, which should be respected by both your CDN and the user's browser. - -:::warning -The shared caching extension assumes you are using the newest version of the middleware's integration and that you haven't extended or overwritten the mentioned endpoints. If you have made such modifications, you must either exclude the endpoint from caching or take responsibility for customizing both the extension and the custom endpoint's code to ensure it's safe to cache. -::: diff --git a/docs/content/3.middleware/2.guides/6.headers.md b/docs/content/3.middleware/2.guides/6.headers.md deleted file mode 100644 index df7d387b9b..0000000000 --- a/docs/content/3.middleware/2.guides/6.headers.md +++ /dev/null @@ -1,113 +0,0 @@ -# Response Headers - -## Overview - -The Middleware Response Headers [extension](/middleware/guides/extensions) enables the addition of custom response headers, which can be particularly useful for managing application caching or establishing security rules. - -With this extension, you can overwrite or set headers for individual API methods or apply them globally across your application. -It can be implemented for any Unified Alokai backend, and third-party tool integration. - -## How it works? - -The extension can be used in two ways: - -- **Locally**: to set custom headers for individual API methods -- **Globally**: to set `Cache-Control` header for all the API methods - -Internally, the extension will identify all GET-type methods and add/overwrite the headers to their responses using the `afterCall` hook. Read the [Middleware Extensions guide](/middleware/guides/extensions#creating-an-extension) to learn more about the internals of an extension. - -## Installation - -To install the extension, run the following command in your `apps/storefront-middleware` folder: - -```bash -yarn add @vsf-enterprise/middleware-headers -``` - -## Configuration - -To configure the extension for a specific integration, add the following code to your `middleware.config.js` file: - -```typescript [middleware.config.ts] -import headersExtension from '@vsf-enterprise/middleware-headers'; - -import { extensionConfig } from './extensionConfig'; - -export default { - integrations: { - // ... other integrations - [integrationName]: { - extensions: (extensions: ApiClientExtension[]) => [ - ...extensions, - headersExtension({ ...extensionConfig }), - // ... other extensions - ] - } - }, -}; -``` - -## Usage - -### Local Usage - -Now, in the `extensionConfig.ts` file, you can set up your headers for individual API methods. - -```typescript [extensionConfig.ts] -export const extensionConfig = { - methods: { - [apiMethodName]: { - response: { - headers: { - 'Cache-Control': 'your-rules', - // ... other headers - } - } - } - } -}; -``` - -Here, your IDE will be able to suggest the available API methods and their names. You can also define your custom ones, making sure that the method name matches the one from the API. - -To provide proper types inference you can use generic type to define them, like this. - -```typescript [middleware.config.ts] -headersExtension<'fooMethod' | 'barMethod'>({ ...config }), -``` - -## Global Usage - -To apply global `Cache-Control` rules on every API method, you can set the `cacheControl` property in your extension's configuration. - -```typescript [extensionConfig.ts] -export const extensionConfig = { - cacheControl: 'your-rules', -}; -``` - -The extension also ships with a predefined `cacheControlRules` value. You can opt-in to using this by setting `cacheControl` to true. - -```typescript -/* This is just for presentation purposes; the code is part of the package internals. */ - -const SHORT_TTL = 60 * 5; // One hour -const cacheControlRules = `public, max-age=0, s-maxage=${SHORT_TTL}, must-revalidate`; -``` - -```typescript [extensionConfig.ts] -export const extensionConfig = { - cacheControl: true, -}; -``` - -## Signature - -```typescript -function extension( - config?: ExtensionConfig -): ApiClientExtension; -``` - - - diff --git a/docs/content/3.middleware/2.guides/6.multistore.md b/docs/content/3.middleware/2.guides/6.multistore.md deleted file mode 100644 index 5ed22af81f..0000000000 --- a/docs/content/3.middleware/2.guides/6.multistore.md +++ /dev/null @@ -1,115 +0,0 @@ -# Multistore - -## Overview - -This guide explains how to implement a multistore solution in Alokai apps. It allows different store configurations to coexist within a single middleware instance. - -### How it works? - -This approach assumes that each store has its domain. The extension uses the domain name to fetch the store-specific configuration. The configuration is then merged with the base configuration. The fetched configuration is cached to avoid unnecessary requests. - -## Prerequisites - -Ensure the following prerequisites are met for the unified multistore solution: - -- It works within the Alokai infrastructure. -- Requires three headers for proper functionality: - 1. `origin` for client-server communication. - 2. `x-forwarded-host` for server-server communication. - 3. `host` as a fallback for server-server communication if `x-forwarded-host` is absent. -- The client communicating with the middleware must include these headers in requests. - -## Setup Steps - -To configure multistore in your middleware, follow these steps: - -1. Prepare multistore configuration: - -- Create a `multistore.config.ts` file with methods: - - `fetchConfiguration({ domain })`: Returns store-specific configurations based on domain. - - `mergeConfigurations({ baseConfig, storeConfig })`: Merges base configuration with store-specific settings. - - `cacheManagerFactory()`: Implements cache manager with get and set methods. - -Example: Configuration that modifies the `api` parameter and uses `node-cache`. - -```ts [multistore.config.ts] -import NodeCache from "node-cache"; - -export const multistoreConfig = { - async fetchConfiguration(/* { domain } */) { - return { - "my-apparel-domain.io": { - baseSiteId: "apparel-uk", - defaultCurrency: "GBP", - // ... - }, - "my-electronics-domain.io": { - baseSiteId: "electronics", - defaultCurrency: "USD", - // ... - }, - }; - }, - mergeConfigurations({ baseConfig, storeConfig }) { - return { - ...baseConfig, - api: { - ...baseConfig.api, - ...storeConfig, - }, - }; - }, - cacheManagerFactory() { - const client = new NodeCache({ - stdTTL: 10, - }); - - return { - async get(key) { - return client.get(key); - }, - async set(key, value) { - return client.set(key, value); - }, - }; - }, -}; -``` - -2. Extend middleware config with multistore extension: - -- Import `createMultistoreExtension` from `@vue-storefront/multistore`. -- Import multistore configuration from `multistore.config.ts`. -- Extend the middleware config in `middleware.config.ts`. - -Example: Extending middleware config with multistore extension. - -```ts [middleware.config.ts] -import { multistoreExtension } from '@vue-storefront/multistore'; -import { multistoreConfig } from './multistore.config'; - -export default { - integrations: { - sapcc: { - location: '@vue-storefront/sapcc-api/server', - configuration: { ... }, - extensions: (predefinedExtensions) => [ - ...predefinedExtensions, - createMultistoreExtension(multistoreConfig) - ] - } - } -}; -``` - -## Architectural Overview - -To understand how the multistore solution works, see the following diagrams: - -### C4 diagram: Middleware component level - -![System component level](https://res.cloudinary.com/vue-storefront/image/upload/v1674577953/Unified%20multi-store/Integrations_Workspace_-_System_component_level_-_Middleware_with_multistore_1_at6dqq.jpg) - -### Sequence diagram - -![Sequence diagram](https://res.cloudinary.com/vue-storefront/image/upload/v1674577949/Unified%20multi-store/Unified_multi-store_1_kwbuu1.png) diff --git a/docs/content/3.middleware/2.guides/7.api-client.md b/docs/content/3.middleware/2.guides/7.api-client.md deleted file mode 100644 index a473ae2853..0000000000 --- a/docs/content/3.middleware/2.guides/7.api-client.md +++ /dev/null @@ -1,268 +0,0 @@ -# Creating an API Client - -The API client is used by the server middleware to create a server-to-server communication with your custom backend. - -## Creating the integration client - -To start, create a new folder called `api-client` in the `src` folder of your integration. This package will contain your integration API client. - -First, you should create the `index.server.ts` file. It will be the entry point for the server middleware. It should look like this: - -```ts -// index.server.ts -import { apiClientFactory } from "@vue-storefront/middleware"; - -const onCreate = (settings: any) => { - // TODO: create a client here and return it with the integration configuration -}; - -const { createApiClient } = apiClientFactory({ - onCreate, - api: {}, -}); - -export { createApiClient }; -``` - -The `apiClientFactory` is a function that creates a factory for creating API clients. - -The `onCreate` function is called when the server middleware is initialized. It should return an object with the integration configuration and the client. - -The `api` object is a set of functions that will be available in the integration client. - -Now, let's create the client. - -:::tip -In the following example we used the `axios` library to create a client. However, you can use any client that suits your needs. - -::: - -The `buildClient` function creates an instance of the `axios` client. It's a good practice to create a separate function for creating the client, so you can easily mock it in the tests. - -The `onCreate` function accepts the integration configuration, and we recommend that you create an interface for it. - -```ts -// types/config/index.ts - -/** - * Settings to be provided in the `middleware.config.js` file. - */ -export interface MiddlewareConfig { - // Add the fields provided in the `middleware.config.js` file. -} -``` - -You should use the `MiddlewareConfig` interface in the `onCreate` function. - -```ts -// index.server.ts -import { apiClientFactory } from "@vue-storefront/middleware"; -import axios from "axios"; -import { MiddlewareConfig } from "./types/config"; - -const buildClient = () => { - const axiosInstance = axios.create(); - return axiosInstance; -}; - -const onCreate = (config: MiddlewareConfig) => { - const client = buildClient(); - - return { - config, - client, - }; -}; - -const { createApiClient } = apiClientFactory({ - onCreate, - api: {}, -}); - -export { createApiClient }; -``` - -Now, we can initialize the server middleware, but it does not contain any API methods. Before adding them, let's create a type for the integration context. - -```ts -// types/context/index.ts -import { IntegrationContext } from "@vue-storefront/middleware"; -import { AxiosInstance } from "axios"; -import { MiddlewareConfig } from "../config"; - -export type TODO = any; - -/** - * Runtime integration context, which includes API client instance, settings, and endpoints that will be passed via middleware server. - * This interface name is starting with `MyIntegration`, but you should use your integration name in here. - **/ -export type MyIntegrationIntegrationContext = IntegrationContext< - AxiosInstance, // HTTP client instance - MiddlewareConfig, - TODO ->; -``` - -Now, you can create the first API method - an `exampleEndpoint` function. - -```ts -// api/exampleEndpoint/index.ts -import { MyIntegrationIntegrationContext, TODO } from "../../types"; - -export const exampleEndpoint = async ( - context: MyIntegrationIntegrationContext, - params: TODO -) => { - console.log("exampleEndpoint has been called"); - - // Example request could look like this: - // return await context.client.get(`example-url?id=${params.id}`); - return Promise.resolve({ success: true }); -}; -``` - -You should also export the `exampleEndpoint` function in the `api/index.ts` file. - -```ts -// api/index.ts -export * from "./exampleEndpoint"; -``` - -Then, let's create the `Endpoints` type. - -```ts -// types/api/endpoints.ts -import { WithoutContext } from "@vue-storefront/middleware"; -import * as apiMethods from "../../api"; - -export type ApiMethods = typeof apiMethods; - -export type Endpoints = WithoutContext; -``` - -Notice that we use the `WithoutContext` type from the `@vue-storefront/middleware` package. It's a utility type that removes the `context` parameter from the API methods. -Server Middleware creates the `context` object based on the middleware configuration and request that has been made. The `Endpoints` interface should reflect only the available API endpoints. - -Finally, let's add the `Endpoints` type to the `MyIntegrationIntegrationContext` interface. - -```ts -// types/context/index.ts -import { IntegrationContext } from "@vue-storefront/middleware"; -import { AxiosInstance } from "axios"; -import { MiddlewareConfig } from "../config"; -import { Endpoints } from "../api/endpoints"; - -export type TODO = any; - -export type MyIntegrationIntegrationContext = IntegrationContext< - AxiosInstance, // HTTP client instance, you should use your client type here - MiddlewareConfig, - Endpoints ->; -``` - -Remember to export all the types in the `types/index.ts` file. - -```ts -// types/index.ts -export * from "./config"; -export * from "./context"; -export * from "./api/endpoints"; -``` - -And from `index.ts` as well. - -```ts -// index.ts -export * from "./types"; -``` - -To be able to call the `exampleEndpoint` function, you should add it to the `api` object in the `index.server.ts` file. - -```ts -import { apiClientFactory } from "@vue-storefront/middleware"; -import axios from "axios"; -import * as api from "./api"; -import { MiddlewareConfig } from "./types/config"; - -const buildClient = () => { - const axiosInstance = axios.create(); - return axiosInstance; -}; - -const onCreate = (settings: MiddlewareConfig) => { - const client = buildClient(); - - return { - config: settings, - client, - }; -}; - -const { createApiClient } = apiClientFactory({ - onCreate, - api, -}); - -export { createApiClient }; -``` - -## Running the integration - -Your integration is ready to use. You can test it by setting up the `middleware.config.js` file and running the middleware - -:::warning Building your integration -This guide described the details of creating the integration, but it does not cover the details of the building process. You can find the tools and configuration we use by default in our integrations in our [integration boilerplate repository](https://github.com/vuestorefront/integration-boilerplate) -::: - -```js -// middleware.config.js - -module.exports = { - integrations: { - boilerplate: { - location: "@vsf-enterprise/my-integration-api/server", // This should be the path to your built index.server.js file - configuration: { - // Add your configuration here - }, - }, - }, -}; -``` - -You can run the server middleware with this example script: - -```js -// server.js -const { createServer } = require("@vue-storefront/middleware"); -const { integrations } = require("./middleware.config"); -const cors = require("cors"); - -(async () => { - const app = await createServer({ integrations }); - const host = process.argv[2] ?? "0.0.0.0"; - const port = process.argv[3] ?? 8181; - const CORS_MIDDLEWARE_NAME = "corsMiddleware"; - - const corsMiddleware = app._router.stack.find( - (middleware) => middleware.name === CORS_MIDDLEWARE_NAME - ); - - corsMiddleware.handle = cors({ - origin: ["http://localhost:3000"], - credentials: true, - }); - - app.listen(port, host, () => { - console.log(`Middleware started: ${host}:${port}`); - }); -})(); -``` - -To run the middleware, you should run the following command: - -```bash -node server.js -``` - -To call the endpoint, simply run a `POST` request to the `http://localhost:8181/myIntegration/exampleEndpoint` endpoint. diff --git a/docs/content/3.middleware/2.guides/8.custom-error-handler.md b/docs/content/3.middleware/2.guides/8.custom-error-handler.md deleted file mode 100644 index a79156556b..0000000000 --- a/docs/content/3.middleware/2.guides/8.custom-error-handler.md +++ /dev/null @@ -1,29 +0,0 @@ -## Customize the error handler - -The Server Middleware comes with a default error handler that logs errors to the console and sends a generic error response to the client. You can customize this behavior by providing your own error handler function in the `middleware.config.ts` file: - -```typescript -import type { Integration } from "@vue-storefront/middleware"; -import type { MiddlewareConfig } from "@vsf-enterprise/sapcc-api"; - -export default { - integrations: { - sapcc: { - location: '@vsf-enterprise/sapcc-api/server', - errorHandler: ( - error - req, - res, - ) => { - res.status(404); - res.send('Custom not-found error handler'); - }, - configuration: { ... }, - ... - // remaining configuration - } satisfies Integration - } -} -``` - -Custom error handlers are configured per integration, so you can have different error handlers for different integrations. \ No newline at end of file diff --git a/docs/content/3.middleware/2.guides/_dir.yml b/docs/content/3.middleware/2.guides/_dir.yml deleted file mode 100644 index e94549214a..0000000000 --- a/docs/content/3.middleware/2.guides/_dir.yml +++ /dev/null @@ -1 +0,0 @@ -title: Guides diff --git a/docs/content/3.middleware/3.api/middleware.api.json b/docs/content/3.middleware/3.api/middleware.api.json deleted file mode 100644 index d93962d8d0..0000000000 --- a/docs/content/3.middleware/3.api/middleware.api.json +++ /dev/null @@ -1,7576 +0,0 @@ -{ - "metadata": { - "toolPackage": "@microsoft/api-extractor", - "toolVersion": "7.42.3", - "schemaVersion": 1011, - "oldestForwardsCompatibleVersion": 1001, - "tsdocConfig": { - "$schema": "https://developer.microsoft.com/json-schemas/tsdoc/v0/tsdoc.schema.json", - "noStandardTags": true, - "tagDefinitions": [ - { - "tagName": "@alpha", - "syntaxKind": "modifier" - }, - { - "tagName": "@beta", - "syntaxKind": "modifier" - }, - { - "tagName": "@defaultValue", - "syntaxKind": "block" - }, - { - "tagName": "@decorator", - "syntaxKind": "block", - "allowMultiple": true - }, - { - "tagName": "@deprecated", - "syntaxKind": "block" - }, - { - "tagName": "@eventProperty", - "syntaxKind": "modifier" - }, - { - "tagName": "@example", - "syntaxKind": "block", - "allowMultiple": true - }, - { - "tagName": "@experimental", - "syntaxKind": "modifier" - }, - { - "tagName": "@inheritDoc", - "syntaxKind": "inline" - }, - { - "tagName": "@internal", - "syntaxKind": "modifier" - }, - { - "tagName": "@label", - "syntaxKind": "inline" - }, - { - "tagName": "@link", - "syntaxKind": "inline", - "allowMultiple": true - }, - { - "tagName": "@override", - "syntaxKind": "modifier" - }, - { - "tagName": "@packageDocumentation", - "syntaxKind": "modifier" - }, - { - "tagName": "@param", - "syntaxKind": "block", - "allowMultiple": true - }, - { - "tagName": "@privateRemarks", - "syntaxKind": "block" - }, - { - "tagName": "@public", - "syntaxKind": "modifier" - }, - { - "tagName": "@readonly", - "syntaxKind": "modifier" - }, - { - "tagName": "@remarks", - "syntaxKind": "block" - }, - { - "tagName": "@returns", - "syntaxKind": "block" - }, - { - "tagName": "@sealed", - "syntaxKind": "modifier" - }, - { - "tagName": "@see", - "syntaxKind": "block" - }, - { - "tagName": "@throws", - "syntaxKind": "block", - "allowMultiple": true - }, - { - "tagName": "@typeParam", - "syntaxKind": "block", - "allowMultiple": true - }, - { - "tagName": "@virtual", - "syntaxKind": "modifier" - }, - { - "tagName": "@betaDocumentation", - "syntaxKind": "modifier" - }, - { - "tagName": "@internalRemarks", - "syntaxKind": "block" - }, - { - "tagName": "@preapproved", - "syntaxKind": "modifier" - } - ], - "supportForTags": { - "@alpha": true, - "@beta": true, - "@defaultValue": true, - "@decorator": true, - "@deprecated": true, - "@eventProperty": true, - "@example": true, - "@experimental": true, - "@inheritDoc": true, - "@internal": true, - "@label": true, - "@link": true, - "@override": true, - "@packageDocumentation": true, - "@param": true, - "@privateRemarks": true, - "@public": true, - "@readonly": true, - "@remarks": true, - "@returns": true, - "@sealed": true, - "@see": true, - "@throws": true, - "@typeParam": true, - "@virtual": true, - "@betaDocumentation": true, - "@internalRemarks": true, - "@preapproved": true - }, - "reportUnsupportedHtmlElements": false - } - }, - "kind": "Package", - "canonicalReference": "@vue-storefront/middleware!", - "docComment": "", - "name": "@vue-storefront/middleware", - "preserveMemberOrder": false, - "members": [ - { - "kind": "EntryPoint", - "canonicalReference": "@vue-storefront/middleware!", - "name": "", - "preserveMemberOrder": false, - "members": [ - { - "kind": "TypeAlias", - "canonicalReference": "@vue-storefront/middleware!AfterCallArgs:type", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "export type AfterCallArgs = " - }, - { - "kind": "Content", - "text": "T" - }, - { - "kind": "Content", - "text": ";" - } - ], - "fileUrlPath": "src/types/common.ts", - "releaseTag": "Public", - "name": "AfterCallArgs", - "typeParameters": [ - { - "typeParameterName": "T", - "constraintTokenRange": { - "startIndex": 0, - "endIndex": 0 - }, - "defaultTypeTokenRange": { - "startIndex": 1, - "endIndex": 2 - } - } - ], - "typeTokenRange": { - "startIndex": 3, - "endIndex": 4 - } - }, - { - "kind": "Interface", - "canonicalReference": "@vue-storefront/middleware!AfterCallParams:interface", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "export interface AfterCallParams extends " - }, - { - "kind": "Reference", - "text": "CallHookParams", - "canonicalReference": "@vue-storefront/middleware!CallHookParams:interface" - }, - { - "kind": "Content", - "text": "" - }, - { - "kind": "Content", - "text": " " - } - ], - "fileUrlPath": "src/types/common.ts", - "releaseTag": "Public", - "typeParameters": [ - { - "typeParameterName": "C", - "constraintTokenRange": { - "startIndex": 0, - "endIndex": 0 - }, - "defaultTypeTokenRange": { - "startIndex": 0, - "endIndex": 0 - } - }, - { - "typeParameterName": "ARGS", - "constraintTokenRange": { - "startIndex": 0, - "endIndex": 0 - }, - "defaultTypeTokenRange": { - "startIndex": 0, - "endIndex": 0 - } - }, - { - "typeParameterName": "RESPONSE", - "constraintTokenRange": { - "startIndex": 0, - "endIndex": 0 - }, - "defaultTypeTokenRange": { - "startIndex": 0, - "endIndex": 0 - } - } - ], - "name": "AfterCallParams", - "preserveMemberOrder": false, - "members": [ - { - "kind": "PropertySignature", - "canonicalReference": "@vue-storefront/middleware!AfterCallParams#args:member", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "args: " - }, - { - "kind": "Reference", - "text": "BeforeCallArgs", - "canonicalReference": "@vue-storefront/middleware!BeforeCallArgs:type" - }, - { - "kind": "Content", - "text": "" - }, - { - "kind": "Content", - "text": ";" - } - ], - "isReadonly": false, - "isOptional": false, - "releaseTag": "Public", - "name": "args", - "propertyTypeTokenRange": { - "startIndex": 1, - "endIndex": 3 - } - }, - { - "kind": "PropertySignature", - "canonicalReference": "@vue-storefront/middleware!AfterCallParams#response:member", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "response: " - }, - { - "kind": "Reference", - "text": "AfterCallArgs", - "canonicalReference": "@vue-storefront/middleware!AfterCallArgs:type" - }, - { - "kind": "Content", - "text": "" - }, - { - "kind": "Content", - "text": ";" - } - ], - "isReadonly": false, - "isOptional": false, - "releaseTag": "Public", - "name": "response", - "propertyTypeTokenRange": { - "startIndex": 1, - "endIndex": 3 - } - } - ], - "extendsTokenRanges": [ - { - "startIndex": 1, - "endIndex": 3 - } - ] - }, - { - "kind": "TypeAlias", - "canonicalReference": "@vue-storefront/middleware!AlokaiContainer:type", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "export type AlokaiContainer = " - }, - { - "kind": "Content", - "text": "{\n logger: " - }, - { - "kind": "Reference", - "text": "LoggerInterface", - "canonicalReference": "@vue-storefront/logger!LoggerInterface:interface" - }, - { - "kind": "Content", - "text": ";\n}" - }, - { - "kind": "Content", - "text": ";" - } - ], - "fileUrlPath": "src/types/common.ts", - "releaseTag": "Public", - "name": "AlokaiContainer", - "typeTokenRange": { - "startIndex": 1, - "endIndex": 4 - } - }, - { - "kind": "TypeAlias", - "canonicalReference": "@vue-storefront/middleware!AlokaiLocal:type", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "export type AlokaiLocal = " - }, - { - "kind": "Content", - "text": "{\n metadata?: {\n context?: string;\n scope?: " - }, - { - "kind": "Reference", - "text": "LogScope", - "canonicalReference": "@vue-storefront/middleware!LogScope:type" - }, - { - "kind": "Content", - "text": ";\n errorBoundary?: " - }, - { - "kind": "Reference", - "text": "LogScope", - "canonicalReference": "@vue-storefront/middleware!LogScope:type" - }, - { - "kind": "Content", - "text": ";\n };\n}" - }, - { - "kind": "Content", - "text": ";" - } - ], - "fileUrlPath": "src/types/common.ts", - "releaseTag": "Public", - "name": "AlokaiLocal", - "typeTokenRange": { - "startIndex": 1, - "endIndex": 6 - } - }, - { - "kind": "TypeAlias", - "canonicalReference": "@vue-storefront/middleware!AlokaiRequest:type", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "export type AlokaiRequest = " - }, - { - "kind": "Reference", - "text": "Request", - "canonicalReference": "@types/express!e.Request:interface" - }, - { - "kind": "Content", - "text": " & {\n files?: {\n [fieldname: string]: " - }, - { - "kind": "Reference", - "text": "UploadedFile", - "canonicalReference": "@vue-storefront/middleware!UploadedFile:interface" - }, - { - "kind": "Content", - "text": "[];\n } | " - }, - { - "kind": "Reference", - "text": "UploadedFile", - "canonicalReference": "@vue-storefront/middleware!UploadedFile:interface" - }, - { - "kind": "Content", - "text": "[] | undefined;\n}" - }, - { - "kind": "Content", - "text": ";" - } - ], - "fileUrlPath": "src/types/common.ts", - "releaseTag": "Public", - "name": "AlokaiRequest", - "typeTokenRange": { - "startIndex": 1, - "endIndex": 7 - } - }, - { - "kind": "TypeAlias", - "canonicalReference": "@vue-storefront/middleware!AlokaiResponse:type", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "export type AlokaiResponse = " - }, - { - "kind": "Reference", - "text": "Response", - "canonicalReference": "@types/express!e.Response:interface" - }, - { - "kind": "Content", - "text": " any;\n fnOrigin?: string;\n [key: string]: any;\n}>" - }, - { - "kind": "Content", - "text": ";" - } - ], - "fileUrlPath": "src/types/common.ts", - "releaseTag": "Public", - "name": "AlokaiResponse", - "typeTokenRange": { - "startIndex": 1, - "endIndex": 5 - } - }, - { - "kind": "TypeAlias", - "canonicalReference": "@vue-storefront/middleware!AnyFunction:type", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "export type AnyFunction = " - }, - { - "kind": "Content", - "text": "(...args: any) => any" - }, - { - "kind": "Content", - "text": ";" - } - ], - "fileUrlPath": "src/types/index.ts", - "releaseTag": "Public", - "name": "AnyFunction", - "typeTokenRange": { - "startIndex": 1, - "endIndex": 2 - } - }, - { - "kind": "Interface", - "canonicalReference": "@vue-storefront/middleware!ApiClient:interface", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "export interface ApiClient " - } - ], - "fileUrlPath": "src/types/server.ts", - "releaseTag": "Public", - "typeParameters": [ - { - "typeParameterName": "API", - "constraintTokenRange": { - "startIndex": 0, - "endIndex": 0 - }, - "defaultTypeTokenRange": { - "startIndex": 1, - "endIndex": 2 - } - }, - { - "typeParameterName": "CONFIG", - "constraintTokenRange": { - "startIndex": 0, - "endIndex": 0 - }, - "defaultTypeTokenRange": { - "startIndex": 3, - "endIndex": 4 - } - }, - { - "typeParameterName": "CLIENT", - "constraintTokenRange": { - "startIndex": 0, - "endIndex": 0 - }, - "defaultTypeTokenRange": { - "startIndex": 5, - "endIndex": 6 - } - } - ], - "name": "ApiClient", - "preserveMemberOrder": false, - "members": [ - { - "kind": "PropertySignature", - "canonicalReference": "@vue-storefront/middleware!ApiClient#api:member", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "api: " - }, - { - "kind": "Content", - "text": "API" - }, - { - "kind": "Content", - "text": ";" - } - ], - "isReadonly": false, - "isOptional": false, - "releaseTag": "Public", - "name": "api", - "propertyTypeTokenRange": { - "startIndex": 1, - "endIndex": 2 - } - }, - { - "kind": "PropertySignature", - "canonicalReference": "@vue-storefront/middleware!ApiClient#client:member", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "client: " - }, - { - "kind": "Content", - "text": "CLIENT" - }, - { - "kind": "Content", - "text": ";" - } - ], - "isReadonly": false, - "isOptional": false, - "releaseTag": "Public", - "name": "client", - "propertyTypeTokenRange": { - "startIndex": 1, - "endIndex": 2 - } - }, - { - "kind": "PropertySignature", - "canonicalReference": "@vue-storefront/middleware!ApiClient#settings:member", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "settings: " - }, - { - "kind": "Content", - "text": "CONFIG & {\n integrationName: string;\n }" - }, - { - "kind": "Content", - "text": ";" - } - ], - "isReadonly": false, - "isOptional": false, - "releaseTag": "Public", - "name": "settings", - "propertyTypeTokenRange": { - "startIndex": 1, - "endIndex": 2 - } - } - ], - "extendsTokenRanges": [] - }, - { - "kind": "Interface", - "canonicalReference": "@vue-storefront/middleware!ApiClientConfig:interface", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "export interface ApiClientConfig " - } - ], - "fileUrlPath": "src/types/server.ts", - "releaseTag": "Public", - "typeParameters": [ - { - "typeParameterName": "CLIENT", - "constraintTokenRange": { - "startIndex": 0, - "endIndex": 0 - }, - "defaultTypeTokenRange": { - "startIndex": 1, - "endIndex": 2 - } - } - ], - "name": "ApiClientConfig", - "preserveMemberOrder": false, - "members": [ - { - "kind": "IndexSignature", - "canonicalReference": "@vue-storefront/middleware!ApiClientConfig:index(1)", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "[x: " - }, - { - "kind": "Content", - "text": "string" - }, - { - "kind": "Content", - "text": "]: " - }, - { - "kind": "Content", - "text": "any" - }, - { - "kind": "Content", - "text": ";" - } - ], - "isReadonly": false, - "returnTypeTokenRange": { - "startIndex": 3, - "endIndex": 4 - }, - "releaseTag": "Public", - "overloadIndex": 1, - "parameters": [ - { - "parameterName": "x", - "parameterTypeTokenRange": { - "startIndex": 1, - "endIndex": 2 - }, - "isOptional": false - } - ] - }, - { - "kind": "PropertySignature", - "canonicalReference": "@vue-storefront/middleware!ApiClientConfig#client:member", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "client?: " - }, - { - "kind": "Content", - "text": "CLIENT" - }, - { - "kind": "Content", - "text": ";" - } - ], - "isReadonly": false, - "isOptional": true, - "releaseTag": "Public", - "name": "client", - "propertyTypeTokenRange": { - "startIndex": 1, - "endIndex": 2 - } - }, - { - "kind": "PropertySignature", - "canonicalReference": "@vue-storefront/middleware!ApiClientConfig#extensions:member", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "extensions?: " - }, - { - "kind": "Reference", - "text": "ApiClientExtension", - "canonicalReference": "@vue-storefront/middleware!ApiClientExtension:interface" - }, - { - "kind": "Content", - "text": "[]" - }, - { - "kind": "Content", - "text": ";" - } - ], - "isReadonly": false, - "isOptional": true, - "releaseTag": "Public", - "name": "extensions", - "propertyTypeTokenRange": { - "startIndex": 1, - "endIndex": 3 - } - } - ], - "extendsTokenRanges": [] - }, - { - "kind": "Interface", - "canonicalReference": "@vue-storefront/middleware!ApiClientExtension:interface", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "export interface ApiClientExtension " - } - ], - "fileUrlPath": "src/types/common.ts", - "releaseTag": "Public", - "typeParameters": [ - { - "typeParameterName": "API", - "constraintTokenRange": { - "startIndex": 0, - "endIndex": 0 - }, - "defaultTypeTokenRange": { - "startIndex": 1, - "endIndex": 2 - } - }, - { - "typeParameterName": "CONTEXT", - "constraintTokenRange": { - "startIndex": 0, - "endIndex": 0 - }, - "defaultTypeTokenRange": { - "startIndex": 3, - "endIndex": 4 - } - }, - { - "typeParameterName": "CONFIG", - "constraintTokenRange": { - "startIndex": 0, - "endIndex": 0 - }, - "defaultTypeTokenRange": { - "startIndex": 5, - "endIndex": 6 - } - } - ], - "name": "ApiClientExtension", - "preserveMemberOrder": false, - "members": [ - { - "kind": "PropertySignature", - "canonicalReference": "@vue-storefront/middleware!ApiClientExtension#extendApiMethods:member", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "extendApiMethods?: " - }, - { - "kind": "Reference", - "text": "ExtendApiMethod", - "canonicalReference": "@vue-storefront/middleware!ExtendApiMethod:type" - }, - { - "kind": "Content", - "text": " | " - }, - { - "kind": "Reference", - "text": "ApiMethodsFactory", - "canonicalReference": "@vue-storefront/middleware!ApiMethodsFactory:type" - }, - { - "kind": "Content", - "text": "<" - }, - { - "kind": "Reference", - "text": "ExtendApiMethod", - "canonicalReference": "@vue-storefront/middleware!ExtendApiMethod:type" - }, - { - "kind": "Content", - "text": ", CONFIG>" - }, - { - "kind": "Content", - "text": ";" - } - ], - "isReadonly": false, - "isOptional": true, - "releaseTag": "Public", - "name": "extendApiMethods", - "propertyTypeTokenRange": { - "startIndex": 1, - "endIndex": 7 - } - }, - { - "kind": "PropertySignature", - "canonicalReference": "@vue-storefront/middleware!ApiClientExtension#extendApp:member", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "extendApp?: " - }, - { - "kind": "Content", - "text": "({ app, configuration, }: {\n app: " - }, - { - "kind": "Reference", - "text": "Express", - "canonicalReference": "@types/express!e.Express:interface" - }, - { - "kind": "Content", - "text": ";\n configuration: any;\n logger: " - }, - { - "kind": "Reference", - "text": "LoggerInterface", - "canonicalReference": "@vue-storefront/logger!LoggerInterface:interface" - }, - { - "kind": "Content", - "text": ";\n }) => " - }, - { - "kind": "Reference", - "text": "Promise", - "canonicalReference": "!Promise:interface" - }, - { - "kind": "Content", - "text": " | void" - }, - { - "kind": "Content", - "text": ";" - } - ], - "isReadonly": false, - "isOptional": true, - "releaseTag": "Public", - "name": "extendApp", - "propertyTypeTokenRange": { - "startIndex": 1, - "endIndex": 8 - } - }, - { - "kind": "PropertySignature", - "canonicalReference": "@vue-storefront/middleware!ApiClientExtension#hooks:member", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "hooks?: " - }, - { - "kind": "Content", - "text": "(req: " - }, - { - "kind": "Reference", - "text": "AlokaiRequest", - "canonicalReference": "@vue-storefront/middleware!AlokaiRequest:type" - }, - { - "kind": "Content", - "text": ", res: " - }, - { - "kind": "Reference", - "text": "AlokaiResponse", - "canonicalReference": "@vue-storefront/middleware!AlokaiResponse:type" - }, - { - "kind": "Content", - "text": ", hooksContext: " - }, - { - "kind": "Reference", - "text": "AlokaiContainer", - "canonicalReference": "@vue-storefront/middleware!AlokaiContainer:type" - }, - { - "kind": "Content", - "text": ") => " - }, - { - "kind": "Reference", - "text": "ApiClientExtensionHooks", - "canonicalReference": "@vue-storefront/middleware!ApiClientExtensionHooks:interface" - }, - { - "kind": "Content", - "text": ";" - } - ], - "isReadonly": false, - "isOptional": true, - "releaseTag": "Public", - "name": "hooks", - "propertyTypeTokenRange": { - "startIndex": 1, - "endIndex": 9 - } - }, - { - "kind": "PropertySignature", - "canonicalReference": "@vue-storefront/middleware!ApiClientExtension#isNamespaced:member", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "isNamespaced?: " - }, - { - "kind": "Content", - "text": "boolean" - }, - { - "kind": "Content", - "text": ";" - } - ], - "isReadonly": false, - "isOptional": true, - "releaseTag": "Public", - "name": "isNamespaced", - "propertyTypeTokenRange": { - "startIndex": 1, - "endIndex": 2 - } - }, - { - "kind": "PropertySignature", - "canonicalReference": "@vue-storefront/middleware!ApiClientExtension#name:member", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "name: " - }, - { - "kind": "Content", - "text": "string" - }, - { - "kind": "Content", - "text": ";" - } - ], - "isReadonly": false, - "isOptional": false, - "releaseTag": "Public", - "name": "name", - "propertyTypeTokenRange": { - "startIndex": 1, - "endIndex": 2 - } - } - ], - "extendsTokenRanges": [] - }, - { - "kind": "Interface", - "canonicalReference": "@vue-storefront/middleware!ApiClientExtensionHooks:interface", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "export interface ApiClientExtensionHooks " - } - ], - "fileUrlPath": "src/types/common.ts", - "releaseTag": "Public", - "typeParameters": [ - { - "typeParameterName": "C", - "constraintTokenRange": { - "startIndex": 0, - "endIndex": 0 - }, - "defaultTypeTokenRange": { - "startIndex": 1, - "endIndex": 2 - } - } - ], - "name": "ApiClientExtensionHooks", - "preserveMemberOrder": false, - "members": [ - { - "kind": "PropertySignature", - "canonicalReference": "@vue-storefront/middleware!ApiClientExtensionHooks#afterCall:member", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "afterCall?: " - }, - { - "kind": "Content", - "text": "(params: " - }, - { - "kind": "Reference", - "text": "AfterCallParams", - "canonicalReference": "@vue-storefront/middleware!AfterCallParams:interface" - }, - { - "kind": "Content", - "text": ") => " - }, - { - "kind": "Reference", - "text": "AfterCallArgs", - "canonicalReference": "@vue-storefront/middleware!AfterCallArgs:type" - }, - { - "kind": "Content", - "text": ";" - } - ], - "isReadonly": false, - "isOptional": true, - "releaseTag": "Public", - "name": "afterCall", - "propertyTypeTokenRange": { - "startIndex": 1, - "endIndex": 5 - } - }, - { - "kind": "PropertySignature", - "canonicalReference": "@vue-storefront/middleware!ApiClientExtensionHooks#afterCreate:member", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "afterCreate?: " - }, - { - "kind": "Content", - "text": "(params: " - }, - { - "kind": "Reference", - "text": "HookParams", - "canonicalReference": "@vue-storefront/middleware!HookParams:interface" - }, - { - "kind": "Content", - "text": ") => C" - }, - { - "kind": "Content", - "text": ";" - } - ], - "isReadonly": false, - "isOptional": true, - "releaseTag": "Public", - "name": "afterCreate", - "propertyTypeTokenRange": { - "startIndex": 1, - "endIndex": 4 - } - }, - { - "kind": "PropertySignature", - "canonicalReference": "@vue-storefront/middleware!ApiClientExtensionHooks#beforeCall:member", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "beforeCall?: " - }, - { - "kind": "Content", - "text": "(params: " - }, - { - "kind": "Reference", - "text": "BeforeCallParams", - "canonicalReference": "@vue-storefront/middleware!BeforeCallParams:interface" - }, - { - "kind": "Content", - "text": ") => " - }, - { - "kind": "Reference", - "text": "BeforeCallArgs", - "canonicalReference": "@vue-storefront/middleware!BeforeCallArgs:type" - }, - { - "kind": "Content", - "text": ";" - } - ], - "isReadonly": false, - "isOptional": true, - "releaseTag": "Public", - "name": "beforeCall", - "propertyTypeTokenRange": { - "startIndex": 1, - "endIndex": 5 - } - }, - { - "kind": "PropertySignature", - "canonicalReference": "@vue-storefront/middleware!ApiClientExtensionHooks#beforeCreate:member", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "beforeCreate?: " - }, - { - "kind": "Content", - "text": "(params: " - }, - { - "kind": "Reference", - "text": "HookParams", - "canonicalReference": "@vue-storefront/middleware!HookParams:interface" - }, - { - "kind": "Content", - "text": ") => C" - }, - { - "kind": "Content", - "text": ";" - } - ], - "isReadonly": false, - "isOptional": true, - "releaseTag": "Public", - "name": "beforeCreate", - "propertyTypeTokenRange": { - "startIndex": 1, - "endIndex": 4 - } - } - ], - "extendsTokenRanges": [] - }, - { - "kind": "Function", - "canonicalReference": "@vue-storefront/middleware!apiClientFactory:function(1)", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "apiClientFactory: (factoryParams: " - }, - { - "kind": "Reference", - "text": "ApiClientFactoryParams", - "canonicalReference": "@vue-storefront/middleware!ApiClientFactoryParams:interface" - }, - { - "kind": "Content", - "text": "" - }, - { - "kind": "Content", - "text": ") => " - }, - { - "kind": "Reference", - "text": "ApiClientFactory", - "canonicalReference": "@vue-storefront/middleware!ApiClientFactory:interface" - }, - { - "kind": "Content", - "text": "" - } - ], - "fileUrlPath": "src/apiClientFactory/index.ts", - "returnTypeTokenRange": { - "startIndex": 8, - "endIndex": 10 - }, - "releaseTag": "Public", - "overloadIndex": 1, - "parameters": [ - { - "parameterName": "factoryParams", - "parameterTypeTokenRange": { - "startIndex": 5, - "endIndex": 7 - }, - "isOptional": false - } - ], - "typeParameters": [ - { - "typeParameterName": "ALL_SETTINGS", - "constraintTokenRange": { - "startIndex": 1, - "endIndex": 2 - }, - "defaultTypeTokenRange": { - "startIndex": 0, - "endIndex": 0 - } - }, - { - "typeParameterName": "ALL_FUNCTIONS", - "constraintTokenRange": { - "startIndex": 3, - "endIndex": 4 - }, - "defaultTypeTokenRange": { - "startIndex": 0, - "endIndex": 0 - } - } - ], - "name": "apiClientFactory" - }, - { - "kind": "Interface", - "canonicalReference": "@vue-storefront/middleware!ApiClientFactory:interface", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "export interface ApiClientFactory " - } - ], - "fileUrlPath": "src/types/server.ts", - "releaseTag": "Public", - "typeParameters": [ - { - "typeParameterName": "CONFIG", - "constraintTokenRange": { - "startIndex": 1, - "endIndex": 2 - }, - "defaultTypeTokenRange": { - "startIndex": 3, - "endIndex": 4 - } - }, - { - "typeParameterName": "API", - "constraintTokenRange": { - "startIndex": 5, - "endIndex": 6 - }, - "defaultTypeTokenRange": { - "startIndex": 7, - "endIndex": 8 - } - } - ], - "name": "ApiClientFactory", - "preserveMemberOrder": false, - "members": [ - { - "kind": "PropertySignature", - "canonicalReference": "@vue-storefront/middleware!ApiClientFactory#createApiClient:member", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "createApiClient: " - }, - { - "kind": "Reference", - "text": "CreateApiClientFn", - "canonicalReference": "@vue-storefront/middleware!CreateApiClientFn:type" - }, - { - "kind": "Content", - "text": "" - }, - { - "kind": "Content", - "text": ";" - } - ], - "isReadonly": false, - "isOptional": false, - "releaseTag": "Public", - "name": "createApiClient", - "propertyTypeTokenRange": { - "startIndex": 1, - "endIndex": 3 - } - }, - { - "kind": "PropertySignature", - "canonicalReference": "@vue-storefront/middleware!ApiClientFactory#init:member", - "docComment": "/**\n * Sets up integration config, runs once.\n */\n", - "excerptTokens": [ - { - "kind": "Content", - "text": "init?: " - }, - { - "kind": "Content", - "text": "(configuration: " - }, - { - "kind": "Reference", - "text": "TObject", - "canonicalReference": "@vue-storefront/middleware!TObject:type" - }, - { - "kind": "Content", - "text": ", alokai: " - }, - { - "kind": "Reference", - "text": "AlokaiContainer", - "canonicalReference": "@vue-storefront/middleware!AlokaiContainer:type" - }, - { - "kind": "Content", - "text": ") => " - }, - { - "kind": "Reference", - "text": "TObject", - "canonicalReference": "@vue-storefront/middleware!TObject:type" - }, - { - "kind": "Content", - "text": ";" - } - ], - "isReadonly": false, - "isOptional": true, - "releaseTag": "Public", - "name": "init", - "propertyTypeTokenRange": { - "startIndex": 1, - "endIndex": 7 - } - } - ], - "extendsTokenRanges": [] - }, - { - "kind": "Interface", - "canonicalReference": "@vue-storefront/middleware!ApiClientFactoryParams:interface", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "export interface ApiClientFactoryParams " - } - ], - "fileUrlPath": "src/types/server.ts", - "releaseTag": "Public", - "typeParameters": [ - { - "typeParameterName": "CONFIG", - "constraintTokenRange": { - "startIndex": 1, - "endIndex": 2 - }, - "defaultTypeTokenRange": { - "startIndex": 0, - "endIndex": 0 - } - }, - { - "typeParameterName": "API", - "constraintTokenRange": { - "startIndex": 3, - "endIndex": 4 - }, - "defaultTypeTokenRange": { - "startIndex": 5, - "endIndex": 6 - } - }, - { - "typeParameterName": "CLIENT", - "constraintTokenRange": { - "startIndex": 0, - "endIndex": 0 - }, - "defaultTypeTokenRange": { - "startIndex": 7, - "endIndex": 8 - } - } - ], - "name": "ApiClientFactoryParams", - "preserveMemberOrder": false, - "members": [ - { - "kind": "PropertySignature", - "canonicalReference": "@vue-storefront/middleware!ApiClientFactoryParams#api:member", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "api: " - }, - { - "kind": "Content", - "text": "API | " - }, - { - "kind": "Reference", - "text": "ApiMethodsFactory", - "canonicalReference": "@vue-storefront/middleware!ApiMethodsFactory:type" - }, - { - "kind": "Content", - "text": "" - }, - { - "kind": "Content", - "text": ";" - } - ], - "isReadonly": false, - "isOptional": false, - "releaseTag": "Public", - "name": "api", - "propertyTypeTokenRange": { - "startIndex": 1, - "endIndex": 4 - } - }, - { - "kind": "PropertySignature", - "canonicalReference": "@vue-storefront/middleware!ApiClientFactoryParams#extensions:member", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "extensions?: " - }, - { - "kind": "Reference", - "text": "ApiClientExtension", - "canonicalReference": "@vue-storefront/middleware!ApiClientExtension:interface" - }, - { - "kind": "Content", - "text": "[]" - }, - { - "kind": "Content", - "text": ";" - } - ], - "isReadonly": false, - "isOptional": true, - "releaseTag": "Public", - "name": "extensions", - "propertyTypeTokenRange": { - "startIndex": 1, - "endIndex": 3 - } - }, - { - "kind": "PropertySignature", - "canonicalReference": "@vue-storefront/middleware!ApiClientFactoryParams#isProxy:member", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "isProxy?: " - }, - { - "kind": "Content", - "text": "boolean" - }, - { - "kind": "Content", - "text": ";" - } - ], - "isReadonly": false, - "isOptional": true, - "releaseTag": "Public", - "name": "isProxy", - "propertyTypeTokenRange": { - "startIndex": 1, - "endIndex": 2 - } - }, - { - "kind": "PropertySignature", - "canonicalReference": "@vue-storefront/middleware!ApiClientFactoryParams#onCreate:member", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "onCreate: " - }, - { - "kind": "Content", - "text": "(config: CONFIG, alokai: " - }, - { - "kind": "Reference", - "text": "AlokaiContainer", - "canonicalReference": "@vue-storefront/middleware!AlokaiContainer:type" - }, - { - "kind": "Content", - "text": ") => " - }, - { - "kind": "Reference", - "text": "Promise", - "canonicalReference": "!Promise:interface" - }, - { - "kind": "Content", - "text": "<{\n client: CLIENT;\n config: " - }, - { - "kind": "Reference", - "text": "ApiClientConfig", - "canonicalReference": "@vue-storefront/middleware!ApiClientConfig:interface" - }, - { - "kind": "Content", - "text": ";\n }> | {\n client: CLIENT;\n config: " - }, - { - "kind": "Reference", - "text": "ApiClientConfig", - "canonicalReference": "@vue-storefront/middleware!ApiClientConfig:interface" - }, - { - "kind": "Content", - "text": ";\n }" - }, - { - "kind": "Content", - "text": ";" - } - ], - "isReadonly": false, - "isOptional": false, - "releaseTag": "Public", - "name": "onCreate", - "propertyTypeTokenRange": { - "startIndex": 1, - "endIndex": 10 - } - } - ], - "extendsTokenRanges": [] - }, - { - "kind": "TypeAlias", - "canonicalReference": "@vue-storefront/middleware!ApiClientMethod:type", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "export type ApiClientMethod = " - }, - { - "kind": "Content", - "text": "(...args: any) => " - }, - { - "kind": "Reference", - "text": "Promise", - "canonicalReference": "!Promise:interface" - }, - { - "kind": "Content", - "text": "" - }, - { - "kind": "Content", - "text": ";" - } - ], - "fileUrlPath": "src/types/base.ts", - "releaseTag": "Public", - "name": "ApiClientMethod", - "typeTokenRange": { - "startIndex": 1, - "endIndex": 4 - } - }, - { - "kind": "TypeAlias", - "canonicalReference": "@vue-storefront/middleware!ApiClientMethods:type", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "export type ApiClientMethods = " - }, - { - "kind": "Content", - "text": "{\n [K in keyof T]: T[K] extends (...args: any) => any ? (...args: [..." - }, - { - "kind": "Reference", - "text": "Parameters", - "canonicalReference": "!Parameters:type" - }, - { - "kind": "Content", - "text": ", " - }, - { - "kind": "Reference", - "text": "CustomQuery", - "canonicalReference": "@vue-storefront/middleware!CustomQuery:type" - }, - { - "kind": "Content", - "text": "?]) => " - }, - { - "kind": "Reference", - "text": "ReturnType", - "canonicalReference": "!ReturnType:type" - }, - { - "kind": "Content", - "text": " : T[K];\n}" - }, - { - "kind": "Content", - "text": ";" - } - ], - "fileUrlPath": "src/types/base.ts", - "releaseTag": "Public", - "name": "ApiClientMethods", - "typeParameters": [ - { - "typeParameterName": "T", - "constraintTokenRange": { - "startIndex": 0, - "endIndex": 0 - }, - "defaultTypeTokenRange": { - "startIndex": 0, - "endIndex": 0 - } - } - ], - "typeTokenRange": { - "startIndex": 1, - "endIndex": 8 - } - }, - { - "kind": "TypeAlias", - "canonicalReference": "@vue-storefront/middleware!ApiClientMethodWithContext:type", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "export type ApiClientMethodWithContext = " - }, - { - "kind": "Content", - "text": "(context: CONTEXT, ...args: any) => any" - }, - { - "kind": "Content", - "text": ";" - } - ], - "fileUrlPath": "src/types/common.ts", - "releaseTag": "Public", - "name": "ApiClientMethodWithContext", - "typeParameters": [ - { - "typeParameterName": "CONTEXT", - "constraintTokenRange": { - "startIndex": 0, - "endIndex": 0 - }, - "defaultTypeTokenRange": { - "startIndex": 0, - "endIndex": 0 - } - } - ], - "typeTokenRange": { - "startIndex": 1, - "endIndex": 2 - } - }, - { - "kind": "Interface", - "canonicalReference": "@vue-storefront/middleware!ApiContext:interface", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "export interface ApiContext " - } - ], - "fileUrlPath": "src/types/common.ts", - "releaseTag": "Public", - "typeParameters": [ - { - "typeParameterName": "CONFIG", - "constraintTokenRange": { - "startIndex": 0, - "endIndex": 0 - }, - "defaultTypeTokenRange": { - "startIndex": 0, - "endIndex": 0 - } - }, - { - "typeParameterName": "CLIENT", - "constraintTokenRange": { - "startIndex": 0, - "endIndex": 0 - }, - "defaultTypeTokenRange": { - "startIndex": 0, - "endIndex": 0 - } - }, - { - "typeParameterName": "REQUEST", - "constraintTokenRange": { - "startIndex": 0, - "endIndex": 0 - }, - "defaultTypeTokenRange": { - "startIndex": 0, - "endIndex": 0 - } - }, - { - "typeParameterName": "RESPONSE", - "constraintTokenRange": { - "startIndex": 0, - "endIndex": 0 - }, - "defaultTypeTokenRange": { - "startIndex": 0, - "endIndex": 0 - } - } - ], - "name": "ApiContext", - "preserveMemberOrder": false, - "members": [ - { - "kind": "PropertySignature", - "canonicalReference": "@vue-storefront/middleware!ApiContext#client:member", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "client: " - }, - { - "kind": "Content", - "text": "CLIENT" - }, - { - "kind": "Content", - "text": ";" - } - ], - "isReadonly": false, - "isOptional": false, - "releaseTag": "Public", - "name": "client", - "propertyTypeTokenRange": { - "startIndex": 1, - "endIndex": 2 - } - }, - { - "kind": "PropertySignature", - "canonicalReference": "@vue-storefront/middleware!ApiContext#config:member", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "config: " - }, - { - "kind": "Content", - "text": "CONFIG" - }, - { - "kind": "Content", - "text": ";" - } - ], - "isReadonly": false, - "isOptional": false, - "releaseTag": "Public", - "name": "config", - "propertyTypeTokenRange": { - "startIndex": 1, - "endIndex": 2 - } - }, - { - "kind": "PropertySignature", - "canonicalReference": "@vue-storefront/middleware!ApiContext#customQueries:member", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "customQueries: " - }, - { - "kind": "Reference", - "text": "Record", - "canonicalReference": "!Record:type" - }, - { - "kind": "Content", - "text": "" - }, - { - "kind": "Content", - "text": ";" - } - ], - "isReadonly": false, - "isOptional": false, - "releaseTag": "Public", - "name": "customQueries", - "propertyTypeTokenRange": { - "startIndex": 1, - "endIndex": 5 - } - }, - { - "kind": "PropertySignature", - "canonicalReference": "@vue-storefront/middleware!ApiContext#extendQuery:member", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "extendQuery: " - }, - { - "kind": "Reference", - "text": "ExtendQuery", - "canonicalReference": "@vue-storefront/middleware!ExtendQuery:type" - }, - { - "kind": "Content", - "text": ";" - } - ], - "isReadonly": false, - "isOptional": false, - "releaseTag": "Public", - "name": "extendQuery", - "propertyTypeTokenRange": { - "startIndex": 1, - "endIndex": 2 - } - }, - { - "kind": "PropertySignature", - "canonicalReference": "@vue-storefront/middleware!ApiContext#extensions:member", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "extensions: " - }, - { - "kind": "Content", - "text": "any" - }, - { - "kind": "Content", - "text": ";" - } - ], - "isReadonly": false, - "isOptional": false, - "releaseTag": "Public", - "name": "extensions", - "propertyTypeTokenRange": { - "startIndex": 1, - "endIndex": 2 - } - }, - { - "kind": "PropertySignature", - "canonicalReference": "@vue-storefront/middleware!ApiContext#req:member", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "req: " - }, - { - "kind": "Content", - "text": "REQUEST" - }, - { - "kind": "Content", - "text": ";" - } - ], - "isReadonly": false, - "isOptional": false, - "releaseTag": "Public", - "name": "req", - "propertyTypeTokenRange": { - "startIndex": 1, - "endIndex": 2 - } - }, - { - "kind": "PropertySignature", - "canonicalReference": "@vue-storefront/middleware!ApiContext#res:member", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "res: " - }, - { - "kind": "Content", - "text": "RESPONSE" - }, - { - "kind": "Content", - "text": ";" - } - ], - "isReadonly": false, - "isOptional": false, - "releaseTag": "Public", - "name": "res", - "propertyTypeTokenRange": { - "startIndex": 1, - "endIndex": 2 - } - } - ], - "extendsTokenRanges": [] - }, - { - "kind": "Interface", - "canonicalReference": "@vue-storefront/middleware!ApiInstance:interface", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "export interface ApiInstance " - } - ], - "fileUrlPath": "src/types/server.ts", - "releaseTag": "Public", - "typeParameters": [ - { - "typeParameterName": "CONFIG", - "constraintTokenRange": { - "startIndex": 0, - "endIndex": 0 - }, - "defaultTypeTokenRange": { - "startIndex": 0, - "endIndex": 0 - } - }, - { - "typeParameterName": "API", - "constraintTokenRange": { - "startIndex": 0, - "endIndex": 0 - }, - "defaultTypeTokenRange": { - "startIndex": 0, - "endIndex": 0 - } - }, - { - "typeParameterName": "CLIENT", - "constraintTokenRange": { - "startIndex": 0, - "endIndex": 0 - }, - "defaultTypeTokenRange": { - "startIndex": 0, - "endIndex": 0 - } - } - ], - "name": "ApiInstance", - "preserveMemberOrder": false, - "members": [ - { - "kind": "PropertySignature", - "canonicalReference": "@vue-storefront/middleware!ApiInstance#api:member", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "api: " - }, - { - "kind": "Content", - "text": "API" - }, - { - "kind": "Content", - "text": ";" - } - ], - "isReadonly": false, - "isOptional": false, - "releaseTag": "Public", - "name": "api", - "propertyTypeTokenRange": { - "startIndex": 1, - "endIndex": 2 - } - }, - { - "kind": "PropertySignature", - "canonicalReference": "@vue-storefront/middleware!ApiInstance#client:member", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "client: " - }, - { - "kind": "Content", - "text": "CLIENT" - }, - { - "kind": "Content", - "text": ";" - } - ], - "isReadonly": false, - "isOptional": false, - "releaseTag": "Public", - "name": "client", - "propertyTypeTokenRange": { - "startIndex": 1, - "endIndex": 2 - } - }, - { - "kind": "PropertySignature", - "canonicalReference": "@vue-storefront/middleware!ApiInstance#settings:member", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "settings: " - }, - { - "kind": "Content", - "text": "CONFIG" - }, - { - "kind": "Content", - "text": ";" - } - ], - "isReadonly": false, - "isOptional": false, - "releaseTag": "Public", - "name": "settings", - "propertyTypeTokenRange": { - "startIndex": 1, - "endIndex": 2 - } - } - ], - "extendsTokenRanges": [] - }, - { - "kind": "TypeAlias", - "canonicalReference": "@vue-storefront/middleware!ApiMethods:type", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "export type ApiMethods = " - }, - { - "kind": "Reference", - "text": "Record", - "canonicalReference": "!Record:type" - }, - { - "kind": "Content", - "text": "" - }, - { - "kind": "Content", - "text": ";" - } - ], - "fileUrlPath": "src/types/common.ts", - "releaseTag": "Public", - "name": "ApiMethods", - "typeTokenRange": { - "startIndex": 1, - "endIndex": 7 - } - }, - { - "kind": "TypeAlias", - "canonicalReference": "@vue-storefront/middleware!ApiMethodsFactory:type", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "export type ApiMethodsFactory = " - }, - { - "kind": "Content", - "text": "(configuration: CONFIG) => API" - }, - { - "kind": "Content", - "text": ";" - } - ], - "fileUrlPath": "src/types/common.ts", - "releaseTag": "Public", - "name": "ApiMethodsFactory", - "typeParameters": [ - { - "typeParameterName": "API", - "constraintTokenRange": { - "startIndex": 1, - "endIndex": 2 - }, - "defaultTypeTokenRange": { - "startIndex": 0, - "endIndex": 0 - } - }, - { - "typeParameterName": "CONFIG", - "constraintTokenRange": { - "startIndex": 3, - "endIndex": 4 - }, - "defaultTypeTokenRange": { - "startIndex": 0, - "endIndex": 0 - } - } - ], - "typeTokenRange": { - "startIndex": 5, - "endIndex": 6 - } - }, - { - "kind": "TypeAlias", - "canonicalReference": "@vue-storefront/middleware!ApolloError:type", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "export type ApolloError = " - }, - { - "kind": "Content", - "text": "{\n networkError?: number;\n code?: string | number;\n graphQLErrors: " - }, - { - "kind": "Reference", - "text": "Array", - "canonicalReference": "!Array:interface" - }, - { - "kind": "Content", - "text": ";\n}" - }, - { - "kind": "Content", - "text": ";" - } - ], - "fileUrlPath": "src/types/base.ts", - "releaseTag": "Public", - "name": "ApolloError", - "typeTokenRange": { - "startIndex": 1, - "endIndex": 4 - } - }, - { - "kind": "Interface", - "canonicalReference": "@vue-storefront/middleware!ApplyingContextHooks:interface", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "export interface ApplyingContextHooks " - } - ], - "fileUrlPath": "src/types/common.ts", - "releaseTag": "Public", - "typeParameters": [ - { - "typeParameterName": "CONFIG", - "constraintTokenRange": { - "startIndex": 0, - "endIndex": 0 - }, - "defaultTypeTokenRange": { - "startIndex": 1, - "endIndex": 2 - } - } - ], - "name": "ApplyingContextHooks", - "preserveMemberOrder": false, - "members": [ - { - "kind": "PropertySignature", - "canonicalReference": "@vue-storefront/middleware!ApplyingContextHooks#after:member", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "after: " - }, - { - "kind": "Content", - "text": "(params: " - }, - { - "kind": "Reference", - "text": "AfterCallParams", - "canonicalReference": "@vue-storefront/middleware!AfterCallParams:interface" - }, - { - "kind": "Content", - "text": ") => " - }, - { - "kind": "Reference", - "text": "AfterCallArgs", - "canonicalReference": "@vue-storefront/middleware!AfterCallArgs:type" - }, - { - "kind": "Content", - "text": ";" - } - ], - "isReadonly": false, - "isOptional": false, - "releaseTag": "Public", - "name": "after", - "propertyTypeTokenRange": { - "startIndex": 1, - "endIndex": 5 - } - }, - { - "kind": "PropertySignature", - "canonicalReference": "@vue-storefront/middleware!ApplyingContextHooks#before:member", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "before: " - }, - { - "kind": "Content", - "text": "(params: " - }, - { - "kind": "Reference", - "text": "BeforeCallParams", - "canonicalReference": "@vue-storefront/middleware!BeforeCallParams:interface" - }, - { - "kind": "Content", - "text": ") => " - }, - { - "kind": "Reference", - "text": "BeforeCallArgs", - "canonicalReference": "@vue-storefront/middleware!BeforeCallArgs:type" - }, - { - "kind": "Content", - "text": ";" - } - ], - "isReadonly": false, - "isOptional": false, - "releaseTag": "Public", - "name": "before", - "propertyTypeTokenRange": { - "startIndex": 1, - "endIndex": 5 - } - } - ], - "extendsTokenRanges": [] - }, - { - "kind": "TypeAlias", - "canonicalReference": "@vue-storefront/middleware!AxiosError:type", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "export type AxiosError = " - }, - { - "kind": "Content", - "text": "{\n isAxiosError: boolean;\n code: string;\n response?: {\n status: number;\n };\n}" - }, - { - "kind": "Content", - "text": ";" - } - ], - "fileUrlPath": "src/types/base.ts", - "releaseTag": "Public", - "name": "AxiosError", - "typeTokenRange": { - "startIndex": 1, - "endIndex": 2 - } - }, - { - "kind": "TypeAlias", - "canonicalReference": "@vue-storefront/middleware!BeforeCallArgs:type", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "export type BeforeCallArgs = " - }, - { - "kind": "Content", - "text": "T" - }, - { - "kind": "Content", - "text": ";" - } - ], - "fileUrlPath": "src/types/common.ts", - "releaseTag": "Public", - "name": "BeforeCallArgs", - "typeParameters": [ - { - "typeParameterName": "T", - "constraintTokenRange": { - "startIndex": 0, - "endIndex": 0 - }, - "defaultTypeTokenRange": { - "startIndex": 1, - "endIndex": 2 - } - } - ], - "typeTokenRange": { - "startIndex": 3, - "endIndex": 4 - } - }, - { - "kind": "Interface", - "canonicalReference": "@vue-storefront/middleware!BeforeCallParams:interface", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "export interface BeforeCallParams extends " - }, - { - "kind": "Reference", - "text": "CallHookParams", - "canonicalReference": "@vue-storefront/middleware!CallHookParams:interface" - }, - { - "kind": "Content", - "text": "" - }, - { - "kind": "Content", - "text": " " - } - ], - "fileUrlPath": "src/types/common.ts", - "releaseTag": "Public", - "typeParameters": [ - { - "typeParameterName": "C", - "constraintTokenRange": { - "startIndex": 0, - "endIndex": 0 - }, - "defaultTypeTokenRange": { - "startIndex": 0, - "endIndex": 0 - } - }, - { - "typeParameterName": "ARGS", - "constraintTokenRange": { - "startIndex": 0, - "endIndex": 0 - }, - "defaultTypeTokenRange": { - "startIndex": 0, - "endIndex": 0 - } - } - ], - "name": "BeforeCallParams", - "preserveMemberOrder": false, - "members": [ - { - "kind": "PropertySignature", - "canonicalReference": "@vue-storefront/middleware!BeforeCallParams#args:member", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "args: " - }, - { - "kind": "Reference", - "text": "BeforeCallArgs", - "canonicalReference": "@vue-storefront/middleware!BeforeCallArgs:type" - }, - { - "kind": "Content", - "text": "" - }, - { - "kind": "Content", - "text": ";" - } - ], - "isReadonly": false, - "isOptional": false, - "releaseTag": "Public", - "name": "args", - "propertyTypeTokenRange": { - "startIndex": 1, - "endIndex": 3 - } - } - ], - "extendsTokenRanges": [ - { - "startIndex": 1, - "endIndex": 3 - } - ] - }, - { - "kind": "TypeAlias", - "canonicalReference": "@vue-storefront/middleware!CallableContext:type", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "export type CallableContext = " - }, - { - "kind": "Content", - "text": "{\n middleware: " - }, - { - "kind": "Reference", - "text": "MiddlewareContext", - "canonicalReference": "@vue-storefront/middleware!MiddlewareContext:interface" - }, - { - "kind": "Content", - "text": ";\n integrationTag: string;\n}" - }, - { - "kind": "Content", - "text": ";" - } - ], - "fileUrlPath": "src/types/common.ts", - "releaseTag": "Public", - "name": "CallableContext", - "typeParameters": [ - { - "typeParameterName": "API", - "constraintTokenRange": { - "startIndex": 1, - "endIndex": 2 - }, - "defaultTypeTokenRange": { - "startIndex": 0, - "endIndex": 0 - } - } - ], - "typeTokenRange": { - "startIndex": 3, - "endIndex": 6 - } - }, - { - "kind": "Interface", - "canonicalReference": "@vue-storefront/middleware!CallHookParams:interface", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "export interface CallHookParams extends " - }, - { - "kind": "Reference", - "text": "HookParams", - "canonicalReference": "@vue-storefront/middleware!HookParams:interface" - }, - { - "kind": "Content", - "text": "" - }, - { - "kind": "Content", - "text": " " - } - ], - "fileUrlPath": "src/types/common.ts", - "releaseTag": "Public", - "typeParameters": [ - { - "typeParameterName": "C", - "constraintTokenRange": { - "startIndex": 0, - "endIndex": 0 - }, - "defaultTypeTokenRange": { - "startIndex": 0, - "endIndex": 0 - } - } - ], - "name": "CallHookParams", - "preserveMemberOrder": false, - "members": [ - { - "kind": "PropertySignature", - "canonicalReference": "@vue-storefront/middleware!CallHookParams#callName:member", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "callName: " - }, - { - "kind": "Content", - "text": "string" - }, - { - "kind": "Content", - "text": ";" - } - ], - "isReadonly": false, - "isOptional": false, - "releaseTag": "Public", - "name": "callName", - "propertyTypeTokenRange": { - "startIndex": 1, - "endIndex": 2 - } - } - ], - "extendsTokenRanges": [ - { - "startIndex": 1, - "endIndex": 3 - } - ] - }, - { - "kind": "Interface", - "canonicalReference": "@vue-storefront/middleware!ClientContext:interface", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "export interface ClientContext " - } - ], - "fileUrlPath": "src/types/server.ts", - "releaseTag": "Public", - "typeParameters": [ - { - "typeParameterName": "CLIENT", - "constraintTokenRange": { - "startIndex": 0, - "endIndex": 0 - }, - "defaultTypeTokenRange": { - "startIndex": 1, - "endIndex": 2 - } - }, - { - "typeParameterName": "CONFIG", - "constraintTokenRange": { - "startIndex": 0, - "endIndex": 0 - }, - "defaultTypeTokenRange": { - "startIndex": 3, - "endIndex": 4 - } - } - ], - "name": "ClientContext", - "preserveMemberOrder": false, - "members": [ - { - "kind": "IndexSignature", - "canonicalReference": "@vue-storefront/middleware!ClientContext:index(1)", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "[x: " - }, - { - "kind": "Content", - "text": "string" - }, - { - "kind": "Content", - "text": "]: " - }, - { - "kind": "Content", - "text": "any" - }, - { - "kind": "Content", - "text": ";" - } - ], - "isReadonly": false, - "returnTypeTokenRange": { - "startIndex": 3, - "endIndex": 4 - }, - "releaseTag": "Public", - "overloadIndex": 1, - "parameters": [ - { - "parameterName": "x", - "parameterTypeTokenRange": { - "startIndex": 1, - "endIndex": 2 - }, - "isOptional": false - } - ] - }, - { - "kind": "PropertySignature", - "canonicalReference": "@vue-storefront/middleware!ClientContext#client:member", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "client: " - }, - { - "kind": "Content", - "text": "CLIENT" - }, - { - "kind": "Content", - "text": ";" - } - ], - "isReadonly": false, - "isOptional": false, - "releaseTag": "Public", - "name": "client", - "propertyTypeTokenRange": { - "startIndex": 1, - "endIndex": 2 - } - }, - { - "kind": "PropertySignature", - "canonicalReference": "@vue-storefront/middleware!ClientContext#config:member", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "config: " - }, - { - "kind": "Content", - "text": "CONFIG" - }, - { - "kind": "Content", - "text": ";" - } - ], - "isReadonly": false, - "isOptional": false, - "releaseTag": "Public", - "name": "config", - "propertyTypeTokenRange": { - "startIndex": 1, - "endIndex": 2 - } - } - ], - "extendsTokenRanges": [] - }, - { - "kind": "TypeAlias", - "canonicalReference": "@vue-storefront/middleware!ComposableFunctionArgs:type", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "export type ComposableFunctionArgs = " - }, - { - "kind": "Content", - "text": "T & {\n customQuery?: " - }, - { - "kind": "Reference", - "text": "CustomQuery", - "canonicalReference": "@vue-storefront/middleware!CustomQuery:type" - }, - { - "kind": "Content", - "text": ";\n}" - }, - { - "kind": "Content", - "text": ";" - } - ], - "fileUrlPath": "src/types/base.ts", - "releaseTag": "Public", - "name": "ComposableFunctionArgs", - "typeParameters": [ - { - "typeParameterName": "T", - "constraintTokenRange": { - "startIndex": 0, - "endIndex": 0 - }, - "defaultTypeTokenRange": { - "startIndex": 0, - "endIndex": 0 - } - } - ], - "typeTokenRange": { - "startIndex": 1, - "endIndex": 4 - } - }, - { - "kind": "Interface", - "canonicalReference": "@vue-storefront/middleware!Context:interface", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "export interface Context " - } - ], - "fileUrlPath": "src/types/server.ts", - "releaseTag": "Public", - "typeParameters": [ - { - "typeParameterName": "CLIENT", - "constraintTokenRange": { - "startIndex": 0, - "endIndex": 0 - }, - "defaultTypeTokenRange": { - "startIndex": 1, - "endIndex": 2 - } - }, - { - "typeParameterName": "CONFIG", - "constraintTokenRange": { - "startIndex": 0, - "endIndex": 0 - }, - "defaultTypeTokenRange": { - "startIndex": 3, - "endIndex": 4 - } - }, - { - "typeParameterName": "API", - "constraintTokenRange": { - "startIndex": 0, - "endIndex": 0 - }, - "defaultTypeTokenRange": { - "startIndex": 5, - "endIndex": 6 - } - }, - { - "typeParameterName": "EXTENDED_API", - "constraintTokenRange": { - "startIndex": 0, - "endIndex": 0 - }, - "defaultTypeTokenRange": { - "startIndex": 7, - "endIndex": 8 - } - } - ], - "name": "Context", - "preserveMemberOrder": false, - "members": [ - { - "kind": "IndexSignature", - "canonicalReference": "@vue-storefront/middleware!Context:index(1)", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "[x: " - }, - { - "kind": "Content", - "text": "string" - }, - { - "kind": "Content", - "text": "]: " - }, - { - "kind": "Reference", - "text": "IntegrationContext", - "canonicalReference": "@vue-storefront/middleware!IntegrationContext:interface" - }, - { - "kind": "Content", - "text": " | any" - }, - { - "kind": "Content", - "text": ";" - } - ], - "isReadonly": false, - "returnTypeTokenRange": { - "startIndex": 3, - "endIndex": 5 - }, - "releaseTag": "Public", - "overloadIndex": 1, - "parameters": [ - { - "parameterName": "x", - "parameterTypeTokenRange": { - "startIndex": 1, - "endIndex": 2 - }, - "isOptional": false - } - ] - } - ], - "extendsTokenRanges": [] - }, - { - "kind": "TypeAlias", - "canonicalReference": "@vue-storefront/middleware!ContextedPlatformApi:type", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "export type ContextedPlatformApi = " - }, - { - "kind": "Content", - "text": "{\n [P in keyof T]: T[P] extends (context: " - }, - { - "kind": "Reference", - "text": "Context", - "canonicalReference": "@vue-storefront/middleware!Context:interface" - }, - { - "kind": "Content", - "text": ", ...arg: infer X) => " - }, - { - "kind": "Reference", - "text": "Promise", - "canonicalReference": "!Promise:interface" - }, - { - "kind": "Content", - "text": " ? (...arg: X) => " - }, - { - "kind": "Reference", - "text": "Promise", - "canonicalReference": "!Promise:interface" - }, - { - "kind": "Content", - "text": " : never;\n}" - }, - { - "kind": "Content", - "text": ";" - } - ], - "fileUrlPath": "src/types/server.ts", - "releaseTag": "Public", - "name": "ContextedPlatformApi", - "typeParameters": [ - { - "typeParameterName": "T", - "constraintTokenRange": { - "startIndex": 1, - "endIndex": 2 - }, - "defaultTypeTokenRange": { - "startIndex": 0, - "endIndex": 0 - } - } - ], - "typeTokenRange": { - "startIndex": 3, - "endIndex": 10 - } - }, - { - "kind": "TypeAlias", - "canonicalReference": "@vue-storefront/middleware!ContextQuery:type", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "export type ContextQuery = " - }, - { - "kind": "Content", - "text": "{\n [Key in T]: " - }, - { - "kind": "Reference", - "text": "ContextQueryParams", - "canonicalReference": "@vue-storefront/middleware!ContextQueryParams:interface" - }, - { - "kind": "Content", - "text": ";\n}" - }, - { - "kind": "Content", - "text": ";" - } - ], - "fileUrlPath": "src/types/base.ts", - "releaseTag": "Public", - "name": "ContextQuery", - "typeParameters": [ - { - "typeParameterName": "T", - "constraintTokenRange": { - "startIndex": 1, - "endIndex": 2 - }, - "defaultTypeTokenRange": { - "startIndex": 3, - "endIndex": 4 - } - } - ], - "typeTokenRange": { - "startIndex": 5, - "endIndex": 8 - } - }, - { - "kind": "Interface", - "canonicalReference": "@vue-storefront/middleware!ContextQueryParams:interface", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "export interface ContextQueryParams " - } - ], - "fileUrlPath": "src/types/base.ts", - "releaseTag": "Public", - "name": "ContextQueryParams", - "preserveMemberOrder": false, - "members": [ - { - "kind": "PropertySignature", - "canonicalReference": "@vue-storefront/middleware!ContextQueryParams#query:member", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "query: " - }, - { - "kind": "Content", - "text": "string" - }, - { - "kind": "Content", - "text": ";" - } - ], - "isReadonly": false, - "isOptional": false, - "releaseTag": "Public", - "name": "query", - "propertyTypeTokenRange": { - "startIndex": 1, - "endIndex": 2 - } - }, - { - "kind": "PropertySignature", - "canonicalReference": "@vue-storefront/middleware!ContextQueryParams#variables:member", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "variables: " - }, - { - "kind": "Reference", - "text": "TObject", - "canonicalReference": "@vue-storefront/middleware!TObject:type" - }, - { - "kind": "Content", - "text": ";" - } - ], - "isReadonly": false, - "isOptional": false, - "releaseTag": "Public", - "name": "variables", - "propertyTypeTokenRange": { - "startIndex": 1, - "endIndex": 2 - } - } - ], - "extendsTokenRanges": [] - }, - { - "kind": "TypeAlias", - "canonicalReference": "@vue-storefront/middleware!ContextualizedApi:type", - "docComment": "/**\n * All available API methods without first argument - `context`, because this prop is set automatically.\n */\n", - "excerptTokens": [ - { - "kind": "Content", - "text": "export type ContextualizedApi = " - }, - { - "kind": "Content", - "text": "{\n [T in keyof API]: API[T] extends (context: any, ...arguments_: infer P) => infer R ? (...arguments_: P) => R : never;\n}" - }, - { - "kind": "Content", - "text": ";" - } - ], - "fileUrlPath": "src/types/server.ts", - "releaseTag": "Public", - "name": "ContextualizedApi", - "typeParameters": [ - { - "typeParameterName": "API", - "constraintTokenRange": { - "startIndex": 0, - "endIndex": 0 - }, - "defaultTypeTokenRange": { - "startIndex": 0, - "endIndex": 0 - } - } - ], - "typeTokenRange": { - "startIndex": 1, - "endIndex": 2 - } - }, - { - "kind": "TypeAlias", - "canonicalReference": "@vue-storefront/middleware!CreateApiClientFn:type", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "export type CreateApiClientFn = " - }, - { - "kind": "Content", - "text": "{\n (givenConfig: CONFIG, customApi?: " - }, - { - "kind": "Reference", - "text": "ApiMethods", - "canonicalReference": "@vue-storefront/middleware!ApiMethods:type" - }, - { - "kind": "Content", - "text": "): " - }, - { - "kind": "Reference", - "text": "Promise", - "canonicalReference": "!Promise:interface" - }, - { - "kind": "Content", - "text": "<" - }, - { - "kind": "Reference", - "text": "ApiInstance", - "canonicalReference": "@vue-storefront/middleware!ApiInstance:interface" - }, - { - "kind": "Content", - "text": ">;\n _predefinedExtensions?: " - }, - { - "kind": "Reference", - "text": "ApiClientExtension", - "canonicalReference": "@vue-storefront/middleware!ApiClientExtension:interface" - }, - { - "kind": "Content", - "text": "[];\n}" - }, - { - "kind": "Content", - "text": ";" - } - ], - "fileUrlPath": "src/types/server.ts", - "releaseTag": "Public", - "name": "CreateApiClientFn", - "typeParameters": [ - { - "typeParameterName": "CONFIG", - "constraintTokenRange": { - "startIndex": 1, - "endIndex": 2 - }, - "defaultTypeTokenRange": { - "startIndex": 0, - "endIndex": 0 - } - }, - { - "typeParameterName": "API", - "constraintTokenRange": { - "startIndex": 3, - "endIndex": 4 - }, - "defaultTypeTokenRange": { - "startIndex": 0, - "endIndex": 0 - } - } - ], - "typeTokenRange": { - "startIndex": 5, - "endIndex": 18 - } - }, - { - "kind": "TypeAlias", - "canonicalReference": "@vue-storefront/middleware!CreateApiProxyFn:type", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "export type CreateApiProxyFn = " - }, - { - "kind": "Content", - "text": "(givenConfig: any, customApi?: any) => " - }, - { - "kind": "Reference", - "text": "ApiInstance", - "canonicalReference": "@vue-storefront/middleware!ApiInstance:interface" - }, - { - "kind": "Content", - "text": "" - }, - { - "kind": "Content", - "text": ";" - } - ], - "fileUrlPath": "src/types/server.ts", - "releaseTag": "Public", - "name": "CreateApiProxyFn", - "typeTokenRange": { - "startIndex": 1, - "endIndex": 4 - } - }, - { - "kind": "Function", - "canonicalReference": "@vue-storefront/middleware!createServer:function(1)", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "declare function createServer" - }, - { - "kind": "Content", - "text": ">(config: " - }, - { - "kind": "Reference", - "text": "MiddlewareConfig", - "canonicalReference": "@vue-storefront/middleware!MiddlewareConfig:interface" - }, - { - "kind": "Content", - "text": "" - }, - { - "kind": "Content", - "text": ", options?: " - }, - { - "kind": "Reference", - "text": "CreateServerOptions", - "canonicalReference": "@vue-storefront/middleware!CreateServerOptions:interface" - }, - { - "kind": "Content", - "text": "): " - }, - { - "kind": "Reference", - "text": "Promise", - "canonicalReference": "!Promise:interface" - }, - { - "kind": "Content", - "text": "<" - }, - { - "kind": "Reference", - "text": "Server", - "canonicalReference": "!\"\\\"http\\\"\".Server:class" - }, - { - "kind": "Content", - "text": ">" - }, - { - "kind": "Content", - "text": ";" - } - ], - "fileUrlPath": "src/createServer.ts", - "returnTypeTokenRange": { - "startIndex": 11, - "endIndex": 15 - }, - "releaseTag": "Public", - "overloadIndex": 1, - "parameters": [ - { - "parameterName": "config", - "parameterTypeTokenRange": { - "startIndex": 6, - "endIndex": 8 - }, - "isOptional": false - }, - { - "parameterName": "options", - "parameterTypeTokenRange": { - "startIndex": 9, - "endIndex": 10 - }, - "isOptional": true - } - ], - "typeParameters": [ - { - "typeParameterName": "TIntegrationContext", - "constraintTokenRange": { - "startIndex": 1, - "endIndex": 5 - }, - "defaultTypeTokenRange": { - "startIndex": 0, - "endIndex": 0 - } - } - ], - "name": "createServer" - }, - { - "kind": "Interface", - "canonicalReference": "@vue-storefront/middleware!CreateServerOptions:interface", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "export interface CreateServerOptions " - } - ], - "fileUrlPath": "src/types/server.ts", - "releaseTag": "Public", - "name": "CreateServerOptions", - "preserveMemberOrder": false, - "members": [ - { - "kind": "PropertySignature", - "canonicalReference": "@vue-storefront/middleware!CreateServerOptions#bodyParser:member", - "docComment": "/**\n * The options for the `express.json` middleware. If not provided, the default options will be used.\n *\n * @see\n *\n * https://www.npmjs.com/package/body-parser\n */\n", - "excerptTokens": [ - { - "kind": "Content", - "text": "bodyParser?: " - }, - { - "kind": "Reference", - "text": "bodyParser.OptionsJson", - "canonicalReference": "@types/body-parser!bodyParser.OptionsJson:interface" - }, - { - "kind": "Content", - "text": ";" - } - ], - "isReadonly": false, - "isOptional": true, - "releaseTag": "Public", - "name": "bodyParser", - "propertyTypeTokenRange": { - "startIndex": 1, - "endIndex": 2 - } - }, - { - "kind": "PropertySignature", - "canonicalReference": "@vue-storefront/middleware!CreateServerOptions#cookieParser:member", - "docComment": "/**\n * The options for the `cookie-parser` middleware. If not provided, the default options will be used.\n *\n * @see\n *\n * https://www.npmjs.com/package/cookie-parser\n */\n", - "excerptTokens": [ - { - "kind": "Content", - "text": "cookieParser?: " - }, - { - "kind": "Content", - "text": "{\n secret: string | string[];\n options: " - }, - { - "kind": "Reference", - "text": "cookieParser.CookieParseOptions", - "canonicalReference": "@types/cookie-parser!cookieParser.CookieParseOptions:interface" - }, - { - "kind": "Content", - "text": ";\n }" - }, - { - "kind": "Content", - "text": ";" - } - ], - "isReadonly": false, - "isOptional": true, - "releaseTag": "Public", - "name": "cookieParser", - "propertyTypeTokenRange": { - "startIndex": 1, - "endIndex": 4 - } - }, - { - "kind": "PropertySignature", - "canonicalReference": "@vue-storefront/middleware!CreateServerOptions#cors:member", - "docComment": "/**\n * The options for the `cors` middleware. If not provided, the following configuration will be used:\n * ```json\n * {\n * \"credentials\": true,\n * \"origin\": [\"http://localhost:3000\", \"http://localhost:4000\"]\n * }\n * ```\n *\n * @see\n *\n * https://www.npmjs.com/package/cors\n */\n", - "excerptTokens": [ - { - "kind": "Content", - "text": "cors?: " - }, - { - "kind": "Reference", - "text": "CorsOptions", - "canonicalReference": "@types/cors!e.CorsOptions:interface" - }, - { - "kind": "Content", - "text": " | " - }, - { - "kind": "Reference", - "text": "CorsOptionsDelegate", - "canonicalReference": "@types/cors!e.CorsOptionsDelegate:type" - }, - { - "kind": "Content", - "text": ";" - } - ], - "isReadonly": false, - "isOptional": true, - "releaseTag": "Public", - "name": "cors", - "propertyTypeTokenRange": { - "startIndex": 1, - "endIndex": 4 - } - }, - { - "kind": "PropertySignature", - "canonicalReference": "@vue-storefront/middleware!CreateServerOptions#fileUpload:member", - "docComment": "/**\n * Configuration options for handling file uploads.\n *\n * @see\n *\n * FileUploadOptions\n */\n", - "excerptTokens": [ - { - "kind": "Content", - "text": "fileUpload?: " - }, - { - "kind": "Reference", - "text": "FileUploadOptions", - "canonicalReference": "@vue-storefront/middleware!FileUploadOptions:interface" - }, - { - "kind": "Content", - "text": " | ((req: " - }, - { - "kind": "Reference", - "text": "FileUploadRequest", - "canonicalReference": "@vue-storefront/middleware!FileUploadRequest:interface" - }, - { - "kind": "Content", - "text": ") => " - }, - { - "kind": "Reference", - "text": "FileUploadOptions", - "canonicalReference": "@vue-storefront/middleware!FileUploadOptions:interface" - }, - { - "kind": "Content", - "text": ")" - }, - { - "kind": "Content", - "text": ";" - } - ], - "isReadonly": false, - "isOptional": true, - "releaseTag": "Public", - "name": "fileUpload", - "propertyTypeTokenRange": { - "startIndex": 1, - "endIndex": 7 - } - }, - { - "kind": "PropertySignature", - "canonicalReference": "@vue-storefront/middleware!CreateServerOptions#readinessProbes:member", - "docComment": "/**\n * Array of functions that will be called in parallel every time the /readyz endpoint receives a GET request If at least one function throws an exception, the response from the /readyz endpoint will report an error\n *\n * @see\n *\n * https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/#define-readiness-probes\n */\n", - "excerptTokens": [ - { - "kind": "Content", - "text": "readinessProbes?: " - }, - { - "kind": "Reference", - "text": "ReadinessProbe", - "canonicalReference": "@vue-storefront/middleware!ReadinessProbe:type" - }, - { - "kind": "Content", - "text": "[]" - }, - { - "kind": "Content", - "text": ";" - } - ], - "isReadonly": false, - "isOptional": true, - "releaseTag": "Public", - "name": "readinessProbes", - "propertyTypeTokenRange": { - "startIndex": 1, - "endIndex": 3 - } - } - ], - "extendsTokenRanges": [] - }, - { - "kind": "TypeAlias", - "canonicalReference": "@vue-storefront/middleware!CustomQuery:type", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "export type CustomQuery = " - }, - { - "kind": "Content", - "text": "{\n [P in T]?: string;\n} & {\n metadata?: unknown;\n}" - }, - { - "kind": "Content", - "text": ";" - } - ], - "fileUrlPath": "src/types/base.ts", - "releaseTag": "Public", - "name": "CustomQuery", - "typeParameters": [ - { - "typeParameterName": "T", - "constraintTokenRange": { - "startIndex": 1, - "endIndex": 2 - }, - "defaultTypeTokenRange": { - "startIndex": 3, - "endIndex": 4 - } - } - ], - "typeTokenRange": { - "startIndex": 5, - "endIndex": 6 - } - }, - { - "kind": "TypeAlias", - "canonicalReference": "@vue-storefront/middleware!CustomQueryFunction:type", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "export type CustomQueryFunction = " - }, - { - "kind": "Content", - "text": "({ query, variables, metadata, }: {\n query: string;\n variables: T;\n metadata: unknown;\n}) => {\n query: string;\n variables: T;\n metadata?: unknown;\n}" - }, - { - "kind": "Content", - "text": ";" - } - ], - "fileUrlPath": "src/types/base.ts", - "releaseTag": "Public", - "name": "CustomQueryFunction", - "typeParameters": [ - { - "typeParameterName": "T", - "constraintTokenRange": { - "startIndex": 0, - "endIndex": 0 - }, - "defaultTypeTokenRange": { - "startIndex": 1, - "endIndex": 2 - } - } - ], - "typeTokenRange": { - "startIndex": 3, - "endIndex": 4 - } - }, - { - "kind": "TypeAlias", - "canonicalReference": "@vue-storefront/middleware!ErrorHandler:type", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "export type ErrorHandler = " - }, - { - "kind": "Content", - "text": "(error: unknown, req: " - }, - { - "kind": "Reference", - "text": "AlokaiRequest", - "canonicalReference": "@vue-storefront/middleware!AlokaiRequest:type" - }, - { - "kind": "Content", - "text": ", res: " - }, - { - "kind": "Reference", - "text": "AlokaiResponse", - "canonicalReference": "@vue-storefront/middleware!AlokaiResponse:type" - }, - { - "kind": "Content", - "text": ") => void" - }, - { - "kind": "Content", - "text": ";" - } - ], - "fileUrlPath": "src/types/common.ts", - "releaseTag": "Public", - "name": "ErrorHandler", - "typeTokenRange": { - "startIndex": 1, - "endIndex": 6 - } - }, - { - "kind": "TypeAlias", - "canonicalReference": "@vue-storefront/middleware!ErrorObject:type", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "export type ErrorObject = " - }, - { - "kind": "Reference", - "text": "AxiosError", - "canonicalReference": "@vue-storefront/middleware!AxiosError:type" - }, - { - "kind": "Content", - "text": " | " - }, - { - "kind": "Reference", - "text": "ApolloError", - "canonicalReference": "@vue-storefront/middleware!ApolloError:type" - }, - { - "kind": "Content", - "text": " | " - }, - { - "kind": "Reference", - "text": "UnknownError", - "canonicalReference": "@vue-storefront/middleware!UnknownError:type" - }, - { - "kind": "Content", - "text": "" - }, - { - "kind": "Content", - "text": ";" - } - ], - "fileUrlPath": "src/types/base.ts", - "releaseTag": "Public", - "name": "ErrorObject", - "typeParameters": [ - { - "typeParameterName": "T", - "constraintTokenRange": { - "startIndex": 1, - "endIndex": 2 - }, - "defaultTypeTokenRange": { - "startIndex": 0, - "endIndex": 0 - } - } - ], - "typeTokenRange": { - "startIndex": 3, - "endIndex": 9 - } - }, - { - "kind": "TypeAlias", - "canonicalReference": "@vue-storefront/middleware!ExtendApiMethod:type", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "export type ExtendApiMethod = " - }, - { - "kind": "Content", - "text": "{\n [K in keyof API]?: " - }, - { - "kind": "Reference", - "text": "ApiClientMethodWithContext", - "canonicalReference": "@vue-storefront/middleware!ApiClientMethodWithContext:type" - }, - { - "kind": "Content", - "text": ";\n} & {\n [key: string]: " - }, - { - "kind": "Reference", - "text": "ApiClientMethodWithContext", - "canonicalReference": "@vue-storefront/middleware!ApiClientMethodWithContext:type" - }, - { - "kind": "Content", - "text": ";\n}" - }, - { - "kind": "Content", - "text": ";" - } - ], - "fileUrlPath": "src/types/common.ts", - "releaseTag": "Public", - "name": "ExtendApiMethod", - "typeParameters": [ - { - "typeParameterName": "API", - "constraintTokenRange": { - "startIndex": 0, - "endIndex": 0 - }, - "defaultTypeTokenRange": { - "startIndex": 0, - "endIndex": 0 - } - }, - { - "typeParameterName": "CONTEXT", - "constraintTokenRange": { - "startIndex": 0, - "endIndex": 0 - }, - "defaultTypeTokenRange": { - "startIndex": 0, - "endIndex": 0 - } - } - ], - "typeTokenRange": { - "startIndex": 1, - "endIndex": 6 - } - }, - { - "kind": "TypeAlias", - "canonicalReference": "@vue-storefront/middleware!ExtendQuery:type", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "export type ExtendQuery = " - }, - { - "kind": "Content", - "text": ", Key extends keyof T>(customQuery: " - }, - { - "kind": "Reference", - "text": "CustomQuery", - "canonicalReference": "@vue-storefront/middleware!CustomQuery:type" - }, - { - "kind": "Content", - "text": " | null, defaults: T) => " - }, - { - "kind": "Reference", - "text": "ContextQuery", - "canonicalReference": "@vue-storefront/middleware!ContextQuery:type" - }, - { - "kind": "Content", - "text": "" - }, - { - "kind": "Content", - "text": ";" - } - ], - "fileUrlPath": "src/types/common.ts", - "releaseTag": "Public", - "name": "ExtendQuery", - "typeTokenRange": { - "startIndex": 1, - "endIndex": 8 - } - }, - { - "kind": "TypeAlias", - "canonicalReference": "@vue-storefront/middleware!ExtensionEndpointHandler:type", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "export type ExtensionEndpointHandler = " - }, - { - "kind": "Reference", - "text": "ApiClientMethod", - "canonicalReference": "@vue-storefront/middleware!ApiClientMethod:type" - }, - { - "kind": "Content", - "text": " & {\n _extensionName?: string;\n}" - }, - { - "kind": "Content", - "text": ";" - } - ], - "fileUrlPath": "src/types/common.ts", - "releaseTag": "Public", - "name": "ExtensionEndpointHandler", - "typeTokenRange": { - "startIndex": 1, - "endIndex": 3 - } - }, - { - "kind": "TypeAlias", - "canonicalReference": "@vue-storefront/middleware!ExtensionHookWith:type", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "export type ExtensionHookWith = " - }, - { - "kind": "Reference", - "text": "WithRequired", - "canonicalReference": "@vue-storefront/middleware!WithRequired:type" - }, - { - "kind": "Content", - "text": "<" - }, - { - "kind": "Reference", - "text": "ApiClientExtensionHooks", - "canonicalReference": "@vue-storefront/middleware!ApiClientExtensionHooks:interface" - }, - { - "kind": "Content", - "text": ", T> & {\n name: string;\n}" - }, - { - "kind": "Content", - "text": ";" - } - ], - "fileUrlPath": "src/types/common.ts", - "releaseTag": "Public", - "name": "ExtensionHookWith", - "typeParameters": [ - { - "typeParameterName": "T", - "constraintTokenRange": { - "startIndex": 1, - "endIndex": 3 - }, - "defaultTypeTokenRange": { - "startIndex": 0, - "endIndex": 0 - } - } - ], - "typeTokenRange": { - "startIndex": 4, - "endIndex": 8 - } - }, - { - "kind": "TypeAlias", - "canonicalReference": "@vue-storefront/middleware!ExtensionWith:type", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "export type ExtensionWith = " - }, - { - "kind": "Reference", - "text": "WithRequired", - "canonicalReference": "@vue-storefront/middleware!WithRequired:type" - }, - { - "kind": "Content", - "text": "<" - }, - { - "kind": "Reference", - "text": "ApiClientExtension", - "canonicalReference": "@vue-storefront/middleware!ApiClientExtension:interface" - }, - { - "kind": "Content", - "text": ", T>" - }, - { - "kind": "Content", - "text": ";" - } - ], - "fileUrlPath": "src/types/common.ts", - "releaseTag": "Public", - "name": "ExtensionWith", - "typeParameters": [ - { - "typeParameterName": "T", - "constraintTokenRange": { - "startIndex": 1, - "endIndex": 3 - }, - "defaultTypeTokenRange": { - "startIndex": 0, - "endIndex": 0 - } - } - ], - "typeTokenRange": { - "startIndex": 4, - "endIndex": 8 - } - }, - { - "kind": "Interface", - "canonicalReference": "@vue-storefront/middleware!FactoryParams:interface", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "export interface FactoryParams " - } - ], - "fileUrlPath": "src/types/server.ts", - "releaseTag": "Public", - "typeParameters": [ - { - "typeParameterName": "API", - "constraintTokenRange": { - "startIndex": 1, - "endIndex": 2 - }, - "defaultTypeTokenRange": { - "startIndex": 3, - "endIndex": 4 - } - } - ], - "name": "FactoryParams", - "preserveMemberOrder": false, - "members": [ - { - "kind": "PropertySignature", - "canonicalReference": "@vue-storefront/middleware!FactoryParams#api:member", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "api?: " - }, - { - "kind": "Reference", - "text": "Partial", - "canonicalReference": "!Partial:type" - }, - { - "kind": "Content", - "text": "" - }, - { - "kind": "Content", - "text": ";" - } - ], - "isReadonly": false, - "isOptional": true, - "releaseTag": "Public", - "name": "api", - "propertyTypeTokenRange": { - "startIndex": 1, - "endIndex": 3 - } - }, - { - "kind": "PropertySignature", - "canonicalReference": "@vue-storefront/middleware!FactoryParams#provide:member", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "provide?: " - }, - { - "kind": "Content", - "text": "(context: " - }, - { - "kind": "Reference", - "text": "Context", - "canonicalReference": "@vue-storefront/middleware!Context:interface" - }, - { - "kind": "Content", - "text": ") => any" - }, - { - "kind": "Content", - "text": ";" - } - ], - "isReadonly": false, - "isOptional": true, - "releaseTag": "Public", - "name": "provide", - "propertyTypeTokenRange": { - "startIndex": 1, - "endIndex": 4 - } - } - ], - "extendsTokenRanges": [] - }, - { - "kind": "Interface", - "canonicalReference": "@vue-storefront/middleware!FileUploadOptions:interface", - "docComment": "/**\n * Options for file upload middleware\n */\n", - "excerptTokens": [ - { - "kind": "Content", - "text": "export interface FileUploadOptions " - } - ], - "fileUrlPath": "src/types/fileUpload.ts", - "releaseTag": "Public", - "name": "FileUploadOptions", - "preserveMemberOrder": false, - "members": [ - { - "kind": "PropertySignature", - "canonicalReference": "@vue-storefront/middleware!FileUploadOptions#allowedMimeTypes:member", - "docComment": "/**\n * Allowed MIME types @default [\"image/*\", \"application/pdf\"]\n */\n", - "excerptTokens": [ - { - "kind": "Content", - "text": "allowedMimeTypes?: " - }, - { - "kind": "Content", - "text": "string[]" - }, - { - "kind": "Content", - "text": ";" - } - ], - "isReadonly": false, - "isOptional": true, - "releaseTag": "Public", - "name": "allowedMimeTypes", - "propertyTypeTokenRange": { - "startIndex": 1, - "endIndex": 2 - } - }, - { - "kind": "PropertySignature", - "canonicalReference": "@vue-storefront/middleware!FileUploadOptions#enabled:member", - "docComment": "/**\n * Whether file upload is enabled @default true\n */\n", - "excerptTokens": [ - { - "kind": "Content", - "text": "enabled?: " - }, - { - "kind": "Content", - "text": "boolean" - }, - { - "kind": "Content", - "text": ";" - } - ], - "isReadonly": false, - "isOptional": true, - "releaseTag": "Public", - "name": "enabled", - "propertyTypeTokenRange": { - "startIndex": 1, - "endIndex": 2 - } - }, - { - "kind": "PropertySignature", - "canonicalReference": "@vue-storefront/middleware!FileUploadOptions#fieldNames:member", - "docComment": "/**\n * Specific field names to accept @default []\n */\n", - "excerptTokens": [ - { - "kind": "Content", - "text": "fieldNames?: " - }, - { - "kind": "Content", - "text": "string[]" - }, - { - "kind": "Content", - "text": ";" - } - ], - "isReadonly": false, - "isOptional": true, - "releaseTag": "Public", - "name": "fieldNames", - "propertyTypeTokenRange": { - "startIndex": 1, - "endIndex": 2 - } - }, - { - "kind": "PropertySignature", - "canonicalReference": "@vue-storefront/middleware!FileUploadOptions#maxFiles:member", - "docComment": "/**\n * Maximum number of files @default 5\n */\n", - "excerptTokens": [ - { - "kind": "Content", - "text": "maxFiles?: " - }, - { - "kind": "Content", - "text": "number" - }, - { - "kind": "Content", - "text": ";" - } - ], - "isReadonly": false, - "isOptional": true, - "releaseTag": "Public", - "name": "maxFiles", - "propertyTypeTokenRange": { - "startIndex": 1, - "endIndex": 2 - } - }, - { - "kind": "PropertySignature", - "canonicalReference": "@vue-storefront/middleware!FileUploadOptions#maxFileSize:member", - "docComment": "/**\n * Maximum file size in bytes @default 5MB\n */\n", - "excerptTokens": [ - { - "kind": "Content", - "text": "maxFileSize?: " - }, - { - "kind": "Content", - "text": "number" - }, - { - "kind": "Content", - "text": ";" - } - ], - "isReadonly": false, - "isOptional": true, - "releaseTag": "Public", - "name": "maxFileSize", - "propertyTypeTokenRange": { - "startIndex": 1, - "endIndex": 2 - } - } - ], - "extendsTokenRanges": [] - }, - { - "kind": "Interface", - "canonicalReference": "@vue-storefront/middleware!FileUploadRequest:interface", - "docComment": "/**\n * Request object for file upload middleware\n */\n", - "excerptTokens": [ - { - "kind": "Content", - "text": "export interface FileUploadRequest " - } - ], - "fileUrlPath": "src/types/fileUpload.ts", - "releaseTag": "Public", - "name": "FileUploadRequest", - "preserveMemberOrder": false, - "members": [ - { - "kind": "PropertySignature", - "canonicalReference": "@vue-storefront/middleware!FileUploadRequest#headers:member", - "docComment": "/**\n * Request headers\n */\n", - "excerptTokens": [ - { - "kind": "Content", - "text": "headers: " - }, - { - "kind": "Reference", - "text": "IncomingHttpHeaders", - "canonicalReference": "!\"\\\"http\\\"\".IncomingHttpHeaders:interface" - }, - { - "kind": "Content", - "text": ";" - } - ], - "isReadonly": false, - "isOptional": false, - "releaseTag": "Public", - "name": "headers", - "propertyTypeTokenRange": { - "startIndex": 1, - "endIndex": 2 - } - } - ], - "extendsTokenRanges": [] - }, - { - "kind": "TypeAlias", - "canonicalReference": "@vue-storefront/middleware!GetConstructorArgs:type", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "export type GetConstructorArgs = " - }, - { - "kind": "Content", - "text": "T extends new (...args: infer U) => any ? U : never" - }, - { - "kind": "Content", - "text": ";" - } - ], - "fileUrlPath": "src/types/index.ts", - "releaseTag": "Public", - "name": "GetConstructorArgs", - "typeParameters": [ - { - "typeParameterName": "T", - "constraintTokenRange": { - "startIndex": 0, - "endIndex": 0 - }, - "defaultTypeTokenRange": { - "startIndex": 0, - "endIndex": 0 - } - } - ], - "typeTokenRange": { - "startIndex": 1, - "endIndex": 2 - } - }, - { - "kind": "Interface", - "canonicalReference": "@vue-storefront/middleware!Helmet:interface", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "export interface Helmet extends " - }, - { - "kind": "Reference", - "text": "HelmetOptions", - "canonicalReference": "helmet!HelmetOptions:interface" - }, - { - "kind": "Content", - "text": " " - } - ], - "fileUrlPath": "src/types/config.ts", - "releaseTag": "Public", - "name": "Helmet", - "preserveMemberOrder": false, - "members": [ - { - "kind": "PropertySignature", - "canonicalReference": "@vue-storefront/middleware!Helmet#helmet:member", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "helmet?: " - }, - { - "kind": "Content", - "text": "boolean | " - }, - { - "kind": "Reference", - "text": "HelmetOptions", - "canonicalReference": "helmet!HelmetOptions:interface" - }, - { - "kind": "Content", - "text": ";" - } - ], - "isReadonly": false, - "isOptional": true, - "releaseTag": "Public", - "name": "helmet", - "propertyTypeTokenRange": { - "startIndex": 1, - "endIndex": 3 - } - } - ], - "extendsTokenRanges": [ - { - "startIndex": 1, - "endIndex": 2 - } - ] - }, - { - "kind": "Interface", - "canonicalReference": "@vue-storefront/middleware!HookParams:interface", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "export interface HookParams " - } - ], - "fileUrlPath": "src/types/common.ts", - "releaseTag": "Public", - "typeParameters": [ - { - "typeParameterName": "C", - "constraintTokenRange": { - "startIndex": 0, - "endIndex": 0 - }, - "defaultTypeTokenRange": { - "startIndex": 0, - "endIndex": 0 - } - } - ], - "name": "HookParams", - "preserveMemberOrder": false, - "members": [ - { - "kind": "PropertySignature", - "canonicalReference": "@vue-storefront/middleware!HookParams#configuration:member", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "configuration?: " - }, - { - "kind": "Content", - "text": "C" - }, - { - "kind": "Content", - "text": ";" - } - ], - "isReadonly": false, - "isOptional": true, - "releaseTag": "Public", - "name": "configuration", - "propertyTypeTokenRange": { - "startIndex": 1, - "endIndex": 2 - } - }, - { - "kind": "PropertySignature", - "canonicalReference": "@vue-storefront/middleware!HookParams#logger:member", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "logger?: " - }, - { - "kind": "Reference", - "text": "LoggerInterface", - "canonicalReference": "@vue-storefront/logger!LoggerInterface:interface" - }, - { - "kind": "Content", - "text": ";" - } - ], - "isReadonly": false, - "isOptional": true, - "releaseTag": "Public", - "name": "logger", - "propertyTypeTokenRange": { - "startIndex": 1, - "endIndex": 2 - } - } - ], - "extendsTokenRanges": [] - }, - { - "kind": "Interface", - "canonicalReference": "@vue-storefront/middleware!Integration:interface", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "export interface Integration " - } - ], - "fileUrlPath": "src/types/common.ts", - "releaseTag": "Public", - "typeParameters": [ - { - "typeParameterName": "CONFIG", - "constraintTokenRange": { - "startIndex": 1, - "endIndex": 2 - }, - "defaultTypeTokenRange": { - "startIndex": 3, - "endIndex": 4 - } - }, - { - "typeParameterName": "API", - "constraintTokenRange": { - "startIndex": 5, - "endIndex": 6 - }, - "defaultTypeTokenRange": { - "startIndex": 7, - "endIndex": 8 - } - }, - { - "typeParameterName": "CONTEXT", - "constraintTokenRange": { - "startIndex": 9, - "endIndex": 10 - }, - "defaultTypeTokenRange": { - "startIndex": 11, - "endIndex": 12 - } - } - ], - "name": "Integration", - "preserveMemberOrder": false, - "members": [ - { - "kind": "PropertySignature", - "canonicalReference": "@vue-storefront/middleware!Integration#configuration:member", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "configuration: " - }, - { - "kind": "Content", - "text": "CONFIG" - }, - { - "kind": "Content", - "text": ";" - } - ], - "isReadonly": false, - "isOptional": false, - "releaseTag": "Public", - "name": "configuration", - "propertyTypeTokenRange": { - "startIndex": 1, - "endIndex": 2 - } - }, - { - "kind": "PropertySignature", - "canonicalReference": "@vue-storefront/middleware!Integration#customQueries:member", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "customQueries?: " - }, - { - "kind": "Reference", - "text": "Record", - "canonicalReference": "!Record:type" - }, - { - "kind": "Content", - "text": "" - }, - { - "kind": "Content", - "text": ";" - } - ], - "isReadonly": false, - "isOptional": true, - "releaseTag": "Public", - "name": "customQueries", - "propertyTypeTokenRange": { - "startIndex": 1, - "endIndex": 5 - } - }, - { - "kind": "PropertySignature", - "canonicalReference": "@vue-storefront/middleware!Integration#errorHandler:member", - "docComment": "/**\n * Custom error handler for middleware.\n *\n * This function is invoked whenever an error occurs during middleware execution. Alokai provides a default error handler, which will be used if this property is not set.\n *\n * @param error - The error object or value that triggered the handler.\n *\n * @param req - The HTTP request object associated with the error.\n *\n * @param res - The HTTP response object for sending a response.\n *\n * @example\n * ```ts\n * {\n * errorHandler: (error, req, res) => {\n * if (typeof error === \"object\" && error !== null && \"message\" in error) {\n * res.status(500).send({ message: (error as any).message });\n * } else {\n * res.status(500).send({ message: \"An unknown error occurred\" });\n * }\n * }\n * }\n * ```\n *\n * @example\n *\n * Using the default error handler with custom behavior\n * ```ts\n * import { defaultErrorHandler } from \"@vue-storefront/middleware\";\n *\n * {\n * errorHandler: (error, req, res) => {\n * // Perform custom actions before delegating to the default error handler\n * defaultErrorHandler(error, req, res);\n * }\n * };\n * ```\n *\n */\n", - "excerptTokens": [ - { - "kind": "Content", - "text": "errorHandler?: " - }, - { - "kind": "Reference", - "text": "ErrorHandler", - "canonicalReference": "@vue-storefront/middleware!ErrorHandler:type" - }, - { - "kind": "Content", - "text": ";" - } - ], - "isReadonly": false, - "isOptional": true, - "releaseTag": "Public", - "name": "errorHandler", - "propertyTypeTokenRange": { - "startIndex": 1, - "endIndex": 2 - } - }, - { - "kind": "PropertySignature", - "canonicalReference": "@vue-storefront/middleware!Integration#extensions:member", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "extensions?: " - }, - { - "kind": "Content", - "text": "(extensions: " - }, - { - "kind": "Reference", - "text": "ApiClientExtension", - "canonicalReference": "@vue-storefront/middleware!ApiClientExtension:interface" - }, - { - "kind": "Content", - "text": "[]) => " - }, - { - "kind": "Reference", - "text": "ApiClientExtension", - "canonicalReference": "@vue-storefront/middleware!ApiClientExtension:interface" - }, - { - "kind": "Content", - "text": "[]" - }, - { - "kind": "Content", - "text": ";" - } - ], - "isReadonly": false, - "isOptional": true, - "releaseTag": "Public", - "name": "extensions", - "propertyTypeTokenRange": { - "startIndex": 1, - "endIndex": 6 - } - }, - { - "kind": "PropertySignature", - "canonicalReference": "@vue-storefront/middleware!Integration#initConfig:member", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "initConfig?: " - }, - { - "kind": "Reference", - "text": "TObject", - "canonicalReference": "@vue-storefront/middleware!TObject:type" - }, - { - "kind": "Content", - "text": ";" - } - ], - "isReadonly": false, - "isOptional": true, - "releaseTag": "Public", - "name": "initConfig", - "propertyTypeTokenRange": { - "startIndex": 1, - "endIndex": 2 - } - }, - { - "kind": "PropertySignature", - "canonicalReference": "@vue-storefront/middleware!Integration#location:member", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "location: " - }, - { - "kind": "Content", - "text": "string" - }, - { - "kind": "Content", - "text": ";" - } - ], - "isReadonly": false, - "isOptional": false, - "releaseTag": "Public", - "name": "location", - "propertyTypeTokenRange": { - "startIndex": 1, - "endIndex": 2 - } - }, - { - "kind": "PropertySignature", - "canonicalReference": "@vue-storefront/middleware!Integration#logger:member", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "logger?: " - }, - { - "kind": "Reference", - "text": "LoggerOptions", - "canonicalReference": "@vue-storefront/middleware!LoggerOptions:interface" - }, - { - "kind": "Content", - "text": ";" - } - ], - "isReadonly": false, - "isOptional": true, - "releaseTag": "Public", - "name": "logger", - "propertyTypeTokenRange": { - "startIndex": 1, - "endIndex": 2 - } - } - ], - "extendsTokenRanges": [] - }, - { - "kind": "Interface", - "canonicalReference": "@vue-storefront/middleware!IntegrationContext:interface", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "export interface IntegrationContext extends " - }, - { - "kind": "Reference", - "text": "MiddlewareContext", - "canonicalReference": "@vue-storefront/middleware!MiddlewareContext:interface" - }, - { - "kind": "Content", - "text": " " - } - ], - "fileUrlPath": "src/types/server.ts", - "releaseTag": "Public", - "typeParameters": [ - { - "typeParameterName": "CLIENT", - "constraintTokenRange": { - "startIndex": 0, - "endIndex": 0 - }, - "defaultTypeTokenRange": { - "startIndex": 1, - "endIndex": 2 - } - }, - { - "typeParameterName": "CONFIG", - "constraintTokenRange": { - "startIndex": 0, - "endIndex": 0 - }, - "defaultTypeTokenRange": { - "startIndex": 3, - "endIndex": 4 - } - }, - { - "typeParameterName": "API", - "constraintTokenRange": { - "startIndex": 0, - "endIndex": 0 - }, - "defaultTypeTokenRange": { - "startIndex": 5, - "endIndex": 6 - } - }, - { - "typeParameterName": "EXTENDED_API", - "constraintTokenRange": { - "startIndex": 0, - "endIndex": 0 - }, - "defaultTypeTokenRange": { - "startIndex": 7, - "endIndex": 8 - } - } - ], - "name": "IntegrationContext", - "preserveMemberOrder": false, - "members": [ - { - "kind": "IndexSignature", - "canonicalReference": "@vue-storefront/middleware!IntegrationContext:index(1)", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "[x: " - }, - { - "kind": "Content", - "text": "string" - }, - { - "kind": "Content", - "text": "]: " - }, - { - "kind": "Content", - "text": "any" - }, - { - "kind": "Content", - "text": ";" - } - ], - "isReadonly": false, - "returnTypeTokenRange": { - "startIndex": 3, - "endIndex": 4 - }, - "releaseTag": "Public", - "overloadIndex": 1, - "parameters": [ - { - "parameterName": "x", - "parameterTypeTokenRange": { - "startIndex": 1, - "endIndex": 2 - }, - "isOptional": false - } - ] - }, - { - "kind": "PropertySignature", - "canonicalReference": "@vue-storefront/middleware!IntegrationContext#api:member", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "api: " - }, - { - "kind": "Content", - "text": "API" - }, - { - "kind": "Content", - "text": ";" - } - ], - "isReadonly": false, - "isOptional": false, - "releaseTag": "Public", - "name": "api", - "propertyTypeTokenRange": { - "startIndex": 1, - "endIndex": 2 - } - }, - { - "kind": "PropertySignature", - "canonicalReference": "@vue-storefront/middleware!IntegrationContext#client:member", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "client: " - }, - { - "kind": "Content", - "text": "CLIENT" - }, - { - "kind": "Content", - "text": ";" - } - ], - "isReadonly": false, - "isOptional": false, - "releaseTag": "Public", - "name": "client", - "propertyTypeTokenRange": { - "startIndex": 1, - "endIndex": 2 - } - }, - { - "kind": "PropertySignature", - "canonicalReference": "@vue-storefront/middleware!IntegrationContext#config:member", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "config: " - }, - { - "kind": "Content", - "text": "CONFIG" - }, - { - "kind": "Content", - "text": ";" - } - ], - "isReadonly": false, - "isOptional": false, - "releaseTag": "Public", - "name": "config", - "propertyTypeTokenRange": { - "startIndex": 1, - "endIndex": 2 - } - }, - { - "kind": "PropertySignature", - "canonicalReference": "@vue-storefront/middleware!IntegrationContext#extendedApi:member", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "extendedApi: " - }, - { - "kind": "Content", - "text": "EXTENDED_API" - }, - { - "kind": "Content", - "text": ";" - } - ], - "isReadonly": false, - "isOptional": false, - "releaseTag": "Public", - "name": "extendedApi", - "propertyTypeTokenRange": { - "startIndex": 1, - "endIndex": 2 - } - } - ], - "extendsTokenRanges": [ - { - "startIndex": 9, - "endIndex": 10 - } - ] - }, - { - "kind": "Interface", - "canonicalReference": "@vue-storefront/middleware!IntegrationLoaded:interface", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "export interface IntegrationLoaded " - } - ], - "fileUrlPath": "src/types/common.ts", - "releaseTag": "Public", - "typeParameters": [ - { - "typeParameterName": "CONFIG", - "constraintTokenRange": { - "startIndex": 1, - "endIndex": 2 - }, - "defaultTypeTokenRange": { - "startIndex": 0, - "endIndex": 0 - } - }, - { - "typeParameterName": "API", - "constraintTokenRange": { - "startIndex": 3, - "endIndex": 4 - }, - "defaultTypeTokenRange": { - "startIndex": 0, - "endIndex": 0 - } - } - ], - "name": "IntegrationLoaded", - "preserveMemberOrder": false, - "members": [ - { - "kind": "PropertySignature", - "canonicalReference": "@vue-storefront/middleware!IntegrationLoaded#apiClient:member", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "apiClient: " - }, - { - "kind": "Reference", - "text": "ApiClientFactory", - "canonicalReference": "@vue-storefront/middleware!ApiClientFactory:interface" - }, - { - "kind": "Content", - "text": "" - }, - { - "kind": "Content", - "text": ";" - } - ], - "isReadonly": false, - "isOptional": false, - "releaseTag": "Public", - "name": "apiClient", - "propertyTypeTokenRange": { - "startIndex": 1, - "endIndex": 3 - } - }, - { - "kind": "PropertySignature", - "canonicalReference": "@vue-storefront/middleware!IntegrationLoaded#configuration:member", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "configuration: " - }, - { - "kind": "Content", - "text": "CONFIG" - }, - { - "kind": "Content", - "text": ";" - } - ], - "isReadonly": false, - "isOptional": false, - "releaseTag": "Public", - "name": "configuration", - "propertyTypeTokenRange": { - "startIndex": 1, - "endIndex": 2 - } - }, - { - "kind": "PropertySignature", - "canonicalReference": "@vue-storefront/middleware!IntegrationLoaded#customQueries:member", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "customQueries?: " - }, - { - "kind": "Reference", - "text": "Record", - "canonicalReference": "!Record:type" - }, - { - "kind": "Content", - "text": "" - }, - { - "kind": "Content", - "text": ";" - } - ], - "isReadonly": false, - "isOptional": true, - "releaseTag": "Public", - "name": "customQueries", - "propertyTypeTokenRange": { - "startIndex": 1, - "endIndex": 5 - } - }, - { - "kind": "PropertySignature", - "canonicalReference": "@vue-storefront/middleware!IntegrationLoaded#errorHandler:member", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "errorHandler: " - }, - { - "kind": "Content", - "text": "(error: unknown, req: " - }, - { - "kind": "Reference", - "text": "Request", - "canonicalReference": "@types/express!e.Request:interface" - }, - { - "kind": "Content", - "text": ", res: " - }, - { - "kind": "Reference", - "text": "AlokaiResponse", - "canonicalReference": "@vue-storefront/middleware!AlokaiResponse:type" - }, - { - "kind": "Content", - "text": ") => void" - }, - { - "kind": "Content", - "text": ";" - } - ], - "isReadonly": false, - "isOptional": false, - "releaseTag": "Public", - "name": "errorHandler", - "propertyTypeTokenRange": { - "startIndex": 1, - "endIndex": 6 - } - }, - { - "kind": "PropertySignature", - "canonicalReference": "@vue-storefront/middleware!IntegrationLoaded#extensions:member", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "extensions: " - }, - { - "kind": "Reference", - "text": "ApiClientExtension", - "canonicalReference": "@vue-storefront/middleware!ApiClientExtension:interface" - }, - { - "kind": "Content", - "text": "[]" - }, - { - "kind": "Content", - "text": ";" - } - ], - "isReadonly": false, - "isOptional": false, - "releaseTag": "Public", - "name": "extensions", - "propertyTypeTokenRange": { - "startIndex": 1, - "endIndex": 3 - } - }, - { - "kind": "PropertySignature", - "canonicalReference": "@vue-storefront/middleware!IntegrationLoaded#initConfig:member", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "initConfig: " - }, - { - "kind": "Reference", - "text": "TObject", - "canonicalReference": "@vue-storefront/middleware!TObject:type" - }, - { - "kind": "Content", - "text": ";" - } - ], - "isReadonly": false, - "isOptional": false, - "releaseTag": "Public", - "name": "initConfig", - "propertyTypeTokenRange": { - "startIndex": 1, - "endIndex": 2 - } - } - ], - "extendsTokenRanges": [] - }, - { - "kind": "TypeAlias", - "canonicalReference": "@vue-storefront/middleware!Integrations:type", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "export type Integrations = " - }, - { - "kind": "Content", - "text": "{\n [IntegrationCode in keyof TIntegrationsContext]: IntegrationCode extends string ? " - }, - { - "kind": "Reference", - "text": "Integration", - "canonicalReference": "@vue-storefront/middleware!Integration:interface" - }, - { - "kind": "Content", - "text": " : never;\n}" - }, - { - "kind": "Content", - "text": ";" - } - ], - "fileUrlPath": "src/types/config.ts", - "releaseTag": "Public", - "name": "Integrations", - "typeParameters": [ - { - "typeParameterName": "TIntegrationsContext", - "constraintTokenRange": { - "startIndex": 1, - "endIndex": 2 - }, - "defaultTypeTokenRange": { - "startIndex": 3, - "endIndex": 4 - } - } - ], - "typeTokenRange": { - "startIndex": 5, - "endIndex": 8 - } - }, - { - "kind": "TypeAlias", - "canonicalReference": "@vue-storefront/middleware!IntegrationsLoaded:type", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "export type IntegrationsLoaded = " - }, - { - "kind": "Reference", - "text": "Record", - "canonicalReference": "!Record:type" - }, - { - "kind": "Content", - "text": ">" - }, - { - "kind": "Content", - "text": ";" - } - ], - "fileUrlPath": "src/types/common.ts", - "releaseTag": "Public", - "name": "IntegrationsLoaded", - "typeParameters": [ - { - "typeParameterName": "CONFIG", - "constraintTokenRange": { - "startIndex": 1, - "endIndex": 2 - }, - "defaultTypeTokenRange": { - "startIndex": 3, - "endIndex": 4 - } - }, - { - "typeParameterName": "API", - "constraintTokenRange": { - "startIndex": 5, - "endIndex": 6 - }, - "defaultTypeTokenRange": { - "startIndex": 7, - "endIndex": 8 - } - } - ], - "typeTokenRange": { - "startIndex": 9, - "endIndex": 13 - } - }, - { - "kind": "Interface", - "canonicalReference": "@vue-storefront/middleware!LoadInitConfigProps:interface", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "export interface LoadInitConfigProps " - } - ], - "fileUrlPath": "src/types/common.ts", - "releaseTag": "Public", - "name": "LoadInitConfigProps", - "preserveMemberOrder": false, - "members": [ - { - "kind": "PropertySignature", - "canonicalReference": "@vue-storefront/middleware!LoadInitConfigProps#alokai:member", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "alokai: " - }, - { - "kind": "Reference", - "text": "AlokaiContainer", - "canonicalReference": "@vue-storefront/middleware!AlokaiContainer:type" - }, - { - "kind": "Content", - "text": ";" - } - ], - "isReadonly": false, - "isOptional": false, - "releaseTag": "Public", - "name": "alokai", - "propertyTypeTokenRange": { - "startIndex": 1, - "endIndex": 2 - } - }, - { - "kind": "PropertySignature", - "canonicalReference": "@vue-storefront/middleware!LoadInitConfigProps#apiClient:member", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "apiClient: " - }, - { - "kind": "Reference", - "text": "ApiClientFactory", - "canonicalReference": "@vue-storefront/middleware!ApiClientFactory:interface" - }, - { - "kind": "Content", - "text": ";" - } - ], - "isReadonly": false, - "isOptional": false, - "releaseTag": "Public", - "name": "apiClient", - "propertyTypeTokenRange": { - "startIndex": 1, - "endIndex": 2 - } - }, - { - "kind": "PropertySignature", - "canonicalReference": "@vue-storefront/middleware!LoadInitConfigProps#integration:member", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "integration: " - }, - { - "kind": "Reference", - "text": "Integration", - "canonicalReference": "@vue-storefront/middleware!Integration:interface" - }, - { - "kind": "Content", - "text": ";" - } - ], - "isReadonly": false, - "isOptional": false, - "releaseTag": "Public", - "name": "integration", - "propertyTypeTokenRange": { - "startIndex": 1, - "endIndex": 2 - } - }, - { - "kind": "PropertySignature", - "canonicalReference": "@vue-storefront/middleware!LoadInitConfigProps#tag:member", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "tag: " - }, - { - "kind": "Content", - "text": "string" - }, - { - "kind": "Content", - "text": ";" - } - ], - "isReadonly": false, - "isOptional": false, - "releaseTag": "Public", - "name": "tag", - "propertyTypeTokenRange": { - "startIndex": 1, - "endIndex": 2 - } - } - ], - "extendsTokenRanges": [] - }, - { - "kind": "Interface", - "canonicalReference": "@vue-storefront/middleware!LoggerOptions:interface", - "docComment": "/**\n * Options for the logger.\n */\n", - "excerptTokens": [ - { - "kind": "Content", - "text": "export interface LoggerOptions " - } - ], - "fileUrlPath": "src/types/config.ts", - "releaseTag": "Public", - "name": "LoggerOptions", - "preserveMemberOrder": false, - "members": [ - { - "kind": "PropertySignature", - "canonicalReference": "@vue-storefront/middleware!LoggerOptions#includeStackTrace:member", - "docComment": "/**\n * Whether to include the stack trace in the log message.\n */\n", - "excerptTokens": [ - { - "kind": "Content", - "text": "includeStackTrace?: " - }, - { - "kind": "Content", - "text": "boolean" - }, - { - "kind": "Content", - "text": ";" - } - ], - "isReadonly": false, - "isOptional": true, - "releaseTag": "Public", - "name": "includeStackTrace", - "propertyTypeTokenRange": { - "startIndex": 1, - "endIndex": 2 - } - }, - { - "kind": "PropertySignature", - "canonicalReference": "@vue-storefront/middleware!LoggerOptions#verbosity:member", - "docComment": "/**\n * The log verbosity level aligned with RFC5424.\n */\n", - "excerptTokens": [ - { - "kind": "Content", - "text": "verbosity?: " - }, - { - "kind": "Reference", - "text": "LogVerbosity", - "canonicalReference": "@vue-storefront/middleware!LogVerbosity:type" - }, - { - "kind": "Content", - "text": ";" - } - ], - "isReadonly": false, - "isOptional": true, - "releaseTag": "Public", - "name": "verbosity", - "propertyTypeTokenRange": { - "startIndex": 1, - "endIndex": 2 - } - } - ], - "extendsTokenRanges": [] - }, - { - "kind": "TypeAlias", - "canonicalReference": "@vue-storefront/middleware!LogScope:type", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "export type LogScope = " - }, - { - "kind": "Content", - "text": "{\n integrationName: string;\n extensionName?: string;\n functionName?: string;\n hookName?: \"extendApp\" | \"hooks\" | \"onCreate\" | \"init\" | \"beforeCall\" | \"beforeCreate\" | \"afterCall\" | \"afterCreate\";\n type: \"endpoint\" | \"bootstrapHook\" | \"requestHook\";\n}" - }, - { - "kind": "Content", - "text": ";" - } - ], - "fileUrlPath": "src/types/common.ts", - "releaseTag": "Public", - "name": "LogScope", - "typeTokenRange": { - "startIndex": 1, - "endIndex": 2 - } - }, - { - "kind": "TypeAlias", - "canonicalReference": "@vue-storefront/middleware!LogVerbosity:type", - "docComment": "/**\n * Based on the syslog levels defined in RFC 5424.\n *\n * @see\n *\n * https://datatracker.ietf.org/doc/html/rfc5424\n */\n", - "excerptTokens": [ - { - "kind": "Content", - "text": "export type LogVerbosity = " - }, - { - "kind": "Content", - "text": "\"emergency\" | \"alert\" | \"critical\" | \"error\" | \"warning\" | \"notice\" | \"info\" | \"debug\"" - }, - { - "kind": "Content", - "text": ";" - } - ], - "fileUrlPath": "src/types/config.ts", - "releaseTag": "Public", - "name": "LogVerbosity", - "typeTokenRange": { - "startIndex": 1, - "endIndex": 2 - } - }, - { - "kind": "Interface", - "canonicalReference": "@vue-storefront/middleware!MiddlewareConfig:interface", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "export interface MiddlewareConfig" - }, - { - "kind": "Content", - "text": " = " - }, - { - "kind": "Reference", - "text": "Record", - "canonicalReference": "!Record:type" - }, - { - "kind": "Content", - "text": "" - }, - { - "kind": "Content", - "text": "> " - } - ], - "fileUrlPath": "src/types/config.ts", - "releaseTag": "Public", - "typeParameters": [ - { - "typeParameterName": "TIntegrationsContext", - "constraintTokenRange": { - "startIndex": 1, - "endIndex": 5 - }, - "defaultTypeTokenRange": { - "startIndex": 6, - "endIndex": 10 - } - } - ], - "name": "MiddlewareConfig", - "preserveMemberOrder": false, - "members": [ - { - "kind": "PropertySignature", - "canonicalReference": "@vue-storefront/middleware!MiddlewareConfig#helmet:member", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "helmet?: " - }, - { - "kind": "Content", - "text": "boolean | " - }, - { - "kind": "Reference", - "text": "Readonly", - "canonicalReference": "!Readonly:type" - }, - { - "kind": "Content", - "text": "<" - }, - { - "kind": "Reference", - "text": "HelmetOptions", - "canonicalReference": "helmet!HelmetOptions:interface" - }, - { - "kind": "Content", - "text": ">" - }, - { - "kind": "Content", - "text": ";" - } - ], - "isReadonly": false, - "isOptional": true, - "releaseTag": "Public", - "name": "helmet", - "propertyTypeTokenRange": { - "startIndex": 1, - "endIndex": 6 - } - }, - { - "kind": "PropertySignature", - "canonicalReference": "@vue-storefront/middleware!MiddlewareConfig#integrations:member", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "integrations: " - }, - { - "kind": "Reference", - "text": "Integrations", - "canonicalReference": "@vue-storefront/middleware!Integrations:type" - }, - { - "kind": "Content", - "text": "" - }, - { - "kind": "Content", - "text": ";" - } - ], - "isReadonly": false, - "isOptional": false, - "releaseTag": "Public", - "name": "integrations", - "propertyTypeTokenRange": { - "startIndex": 1, - "endIndex": 3 - } - }, - { - "kind": "PropertySignature", - "canonicalReference": "@vue-storefront/middleware!MiddlewareConfig#logger:member", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "logger?: " - }, - { - "kind": "Reference", - "text": "LoggerOptions", - "canonicalReference": "@vue-storefront/middleware!LoggerOptions:interface" - }, - { - "kind": "Content", - "text": ";" - } - ], - "isReadonly": false, - "isOptional": true, - "releaseTag": "Public", - "name": "logger", - "propertyTypeTokenRange": { - "startIndex": 1, - "endIndex": 2 - } - } - ], - "extendsTokenRanges": [] - }, - { - "kind": "Interface", - "canonicalReference": "@vue-storefront/middleware!MiddlewareContext:interface", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "export interface MiddlewareContext " - } - ], - "fileUrlPath": "src/types/common.ts", - "releaseTag": "Public", - "typeParameters": [ - { - "typeParameterName": "API", - "constraintTokenRange": { - "startIndex": 1, - "endIndex": 2 - }, - "defaultTypeTokenRange": { - "startIndex": 3, - "endIndex": 4 - } - } - ], - "name": "MiddlewareContext", - "preserveMemberOrder": false, - "members": [ - { - "kind": "PropertySignature", - "canonicalReference": "@vue-storefront/middleware!MiddlewareContext#customQueries:member", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "customQueries: " - }, - { - "kind": "Reference", - "text": "Record", - "canonicalReference": "!Record:type" - }, - { - "kind": "Content", - "text": "" - }, - { - "kind": "Content", - "text": ";" - } - ], - "isReadonly": false, - "isOptional": false, - "releaseTag": "Public", - "name": "customQueries", - "propertyTypeTokenRange": { - "startIndex": 1, - "endIndex": 5 - } - }, - { - "kind": "PropertySignature", - "canonicalReference": "@vue-storefront/middleware!MiddlewareContext#extensions:member", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "extensions: " - }, - { - "kind": "Reference", - "text": "ApiClientExtension", - "canonicalReference": "@vue-storefront/middleware!ApiClientExtension:interface" - }, - { - "kind": "Content", - "text": "[]" - }, - { - "kind": "Content", - "text": ";" - } - ], - "isReadonly": false, - "isOptional": false, - "releaseTag": "Public", - "name": "extensions", - "propertyTypeTokenRange": { - "startIndex": 1, - "endIndex": 3 - } - }, - { - "kind": "PropertySignature", - "canonicalReference": "@vue-storefront/middleware!MiddlewareContext#getApiClient:member", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "getApiClient: " - }, - { - "kind": "Content", - "text": "(integrationName: string) => " - }, - { - "kind": "Reference", - "text": "ApiClient", - "canonicalReference": "@vue-storefront/middleware!ApiClient:interface" - }, - { - "kind": "Content", - "text": "" - }, - { - "kind": "Content", - "text": ";" - } - ], - "isReadonly": false, - "isOptional": false, - "releaseTag": "Public", - "name": "getApiClient", - "propertyTypeTokenRange": { - "startIndex": 1, - "endIndex": 4 - } - }, - { - "kind": "PropertySignature", - "canonicalReference": "@vue-storefront/middleware!MiddlewareContext#integrations:member", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "integrations: " - }, - { - "kind": "Reference", - "text": "IntegrationsLoaded", - "canonicalReference": "@vue-storefront/middleware!IntegrationsLoaded:type" - }, - { - "kind": "Content", - "text": ";" - } - ], - "isReadonly": false, - "isOptional": false, - "releaseTag": "Public", - "name": "integrations", - "propertyTypeTokenRange": { - "startIndex": 1, - "endIndex": 2 - } - }, - { - "kind": "PropertySignature", - "canonicalReference": "@vue-storefront/middleware!MiddlewareContext#integrationTag:member", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "integrationTag: " - }, - { - "kind": "Content", - "text": "string" - }, - { - "kind": "Content", - "text": ";" - } - ], - "isReadonly": false, - "isOptional": false, - "releaseTag": "Public", - "name": "integrationTag", - "propertyTypeTokenRange": { - "startIndex": 1, - "endIndex": 2 - } - }, - { - "kind": "PropertySignature", - "canonicalReference": "@vue-storefront/middleware!MiddlewareContext#req:member", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "req: " - }, - { - "kind": "Reference", - "text": "AlokaiRequest", - "canonicalReference": "@vue-storefront/middleware!AlokaiRequest:type" - }, - { - "kind": "Content", - "text": ";" - } - ], - "isReadonly": false, - "isOptional": false, - "releaseTag": "Public", - "name": "req", - "propertyTypeTokenRange": { - "startIndex": 1, - "endIndex": 2 - } - }, - { - "kind": "PropertySignature", - "canonicalReference": "@vue-storefront/middleware!MiddlewareContext#res:member", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "res: " - }, - { - "kind": "Reference", - "text": "AlokaiResponse", - "canonicalReference": "@vue-storefront/middleware!AlokaiResponse:type" - }, - { - "kind": "Content", - "text": ";" - } - ], - "isReadonly": false, - "isOptional": false, - "releaseTag": "Public", - "name": "res", - "propertyTypeTokenRange": { - "startIndex": 1, - "endIndex": 2 - } - } - ], - "extendsTokenRanges": [] - }, - { - "kind": "TypeAlias", - "canonicalReference": "@vue-storefront/middleware!NullableRecord:type", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "export type NullableRecord = " - }, - { - "kind": "Content", - "text": "V | null" - }, - { - "kind": "Content", - "text": ";" - } - ], - "fileUrlPath": "src/types/index.ts", - "releaseTag": "Public", - "name": "NullableRecord", - "typeParameters": [ - { - "typeParameterName": "V", - "constraintTokenRange": { - "startIndex": 0, - "endIndex": 0 - }, - "defaultTypeTokenRange": { - "startIndex": 0, - "endIndex": 0 - } - } - ], - "typeTokenRange": { - "startIndex": 1, - "endIndex": 2 - } - }, - { - "kind": "TypeAlias", - "canonicalReference": "@vue-storefront/middleware!ObjectItemRecord:type", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "export type ObjectItemRecord = " - }, - { - "kind": "Content", - "text": "{\n [keyof in K as string]: V;\n}" - }, - { - "kind": "Content", - "text": ";" - } - ], - "fileUrlPath": "src/types/index.ts", - "releaseTag": "Public", - "name": "ObjectItemRecord", - "typeParameters": [ - { - "typeParameterName": "V", - "constraintTokenRange": { - "startIndex": 0, - "endIndex": 0 - }, - "defaultTypeTokenRange": { - "startIndex": 1, - "endIndex": 2 - } - }, - { - "typeParameterName": "K", - "constraintTokenRange": { - "startIndex": 0, - "endIndex": 0 - }, - "defaultTypeTokenRange": { - "startIndex": 3, - "endIndex": 4 - } - } - ], - "typeTokenRange": { - "startIndex": 5, - "endIndex": 6 - } - }, - { - "kind": "TypeAlias", - "canonicalReference": "@vue-storefront/middleware!ObjectRecord:type", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "export type ObjectRecord = " - }, - { - "kind": "Content", - "text": "{\n [K in keyof O]: O[K];\n}" - }, - { - "kind": "Content", - "text": ";" - } - ], - "fileUrlPath": "src/types/index.ts", - "releaseTag": "Public", - "name": "ObjectRecord", - "typeParameters": [ - { - "typeParameterName": "O", - "constraintTokenRange": { - "startIndex": 0, - "endIndex": 0 - }, - "defaultTypeTokenRange": { - "startIndex": 0, - "endIndex": 0 - } - } - ], - "typeTokenRange": { - "startIndex": 1, - "endIndex": 2 - } - }, - { - "kind": "TypeAlias", - "canonicalReference": "@vue-storefront/middleware!ParamType:type", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "export type ParamType = " - }, - { - "kind": "Content", - "text": "string | number | symbol" - }, - { - "kind": "Content", - "text": ";" - } - ], - "fileUrlPath": "src/types/base.ts", - "releaseTag": "Public", - "name": "ParamType", - "typeTokenRange": { - "startIndex": 1, - "endIndex": 2 - } - }, - { - "kind": "TypeAlias", - "canonicalReference": "@vue-storefront/middleware!PartialRecord:type", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "export type PartialRecord = " - }, - { - "kind": "Content", - "text": "{\n [K in keyof O]?: O[K];\n}" - }, - { - "kind": "Content", - "text": ";" - } - ], - "fileUrlPath": "src/types/index.ts", - "releaseTag": "Public", - "name": "PartialRecord", - "typeParameters": [ - { - "typeParameterName": "O", - "constraintTokenRange": { - "startIndex": 0, - "endIndex": 0 - }, - "defaultTypeTokenRange": { - "startIndex": 0, - "endIndex": 0 - } - } - ], - "typeTokenRange": { - "startIndex": 1, - "endIndex": 2 - } - }, - { - "kind": "TypeAlias", - "canonicalReference": "@vue-storefront/middleware!PlatformApi:type", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "export type PlatformApi = " - }, - { - "kind": "Content", - "text": "{\n [functionName: string]: (context: " - }, - { - "kind": "Reference", - "text": "Context", - "canonicalReference": "@vue-storefront/middleware!Context:interface" - }, - { - "kind": "Content", - "text": ", ...args: any[]) => " - }, - { - "kind": "Reference", - "text": "Promise", - "canonicalReference": "!Promise:interface" - }, - { - "kind": "Content", - "text": ";\n}" - }, - { - "kind": "Content", - "text": ";" - } - ], - "fileUrlPath": "src/types/server.ts", - "releaseTag": "Public", - "name": "PlatformApi", - "typeTokenRange": { - "startIndex": 1, - "endIndex": 6 - } - }, - { - "kind": "TypeAlias", - "canonicalReference": "@vue-storefront/middleware!ReadinessProbe:type", - "docComment": "/**\n * Function that will be called to determine readiness of middleware to accept connections\n *\n * @returns Return value is never considered - only thrown exceptions\n *\n * @throws\n *\n * The implementation *must* throw an exception at some point in the code, which means that the readiness check should fail\n */\n", - "excerptTokens": [ - { - "kind": "Content", - "text": "export type ReadinessProbe = " - }, - { - "kind": "Content", - "text": "() => " - }, - { - "kind": "Reference", - "text": "Promise", - "canonicalReference": "!Promise:interface" - }, - { - "kind": "Content", - "text": "" - }, - { - "kind": "Content", - "text": ";" - } - ], - "fileUrlPath": "src/types/server.ts", - "releaseTag": "Public", - "name": "ReadinessProbe", - "typeTokenRange": { - "startIndex": 1, - "endIndex": 4 - } - }, - { - "kind": "TypeAlias", - "canonicalReference": "@vue-storefront/middleware!RecordOverloadedReturnType:type", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "export type RecordOverloadedReturnType = " - }, - { - "kind": "Content", - "text": "T extends {\n (...args: any[]): infer R;\n (...args: any[]): infer R;\n (...args: any[]): infer R;\n (...args: any[]): infer R;\n} ? R : T extends {\n (...args: any[]): infer R;\n (...args: any[]): infer R;\n (...args: any[]): infer R;\n} ? R : T extends {\n (...args: any[]): infer R;\n (...args: any[]): infer R;\n} ? R : T extends (...args: any[]) => infer R ? R : any" - }, - { - "kind": "Content", - "text": ";" - } - ], - "fileUrlPath": "src/types/index.ts", - "releaseTag": "Public", - "name": "RecordOverloadedReturnType", - "typeParameters": [ - { - "typeParameterName": "T", - "constraintTokenRange": { - "startIndex": 0, - "endIndex": 0 - }, - "defaultTypeTokenRange": { - "startIndex": 0, - "endIndex": 0 - } - } - ], - "typeTokenRange": { - "startIndex": 1, - "endIndex": 2 - } - }, - { - "kind": "Interface", - "canonicalReference": "@vue-storefront/middleware!RequestParams:interface", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "export interface RequestParams " - } - ], - "fileUrlPath": "src/types/common.ts", - "releaseTag": "Public", - "name": "RequestParams", - "preserveMemberOrder": false, - "members": [ - { - "kind": "PropertySignature", - "canonicalReference": "@vue-storefront/middleware!RequestParams#functionName:member", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "functionName: " - }, - { - "kind": "Content", - "text": "string" - }, - { - "kind": "Content", - "text": ";" - } - ], - "isReadonly": false, - "isOptional": false, - "releaseTag": "Public", - "name": "functionName", - "propertyTypeTokenRange": { - "startIndex": 1, - "endIndex": 2 - } - }, - { - "kind": "PropertySignature", - "canonicalReference": "@vue-storefront/middleware!RequestParams#integrationName:member", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "integrationName: " - }, - { - "kind": "Content", - "text": "string" - }, - { - "kind": "Content", - "text": ";" - } - ], - "isReadonly": false, - "isOptional": false, - "releaseTag": "Public", - "name": "integrationName", - "propertyTypeTokenRange": { - "startIndex": 1, - "endIndex": 2 - } - } - ], - "extendsTokenRanges": [] - }, - { - "kind": "TypeAlias", - "canonicalReference": "@vue-storefront/middleware!StatusCode:type", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "export type StatusCode = " - }, - { - "kind": "Content", - "text": "number | null" - }, - { - "kind": "Content", - "text": ";" - } - ], - "fileUrlPath": "src/types/base.ts", - "releaseTag": "Public", - "name": "StatusCode", - "typeTokenRange": { - "startIndex": 1, - "endIndex": 2 - } - }, - { - "kind": "TypeAlias", - "canonicalReference": "@vue-storefront/middleware!TObject:type", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "export type TObject = " - }, - { - "kind": "Reference", - "text": "Record", - "canonicalReference": "!Record:type" - }, - { - "kind": "Content", - "text": "" - }, - { - "kind": "Content", - "text": ";" - } - ], - "fileUrlPath": "src/types/base.ts", - "releaseTag": "Public", - "name": "TObject", - "typeTokenRange": { - "startIndex": 1, - "endIndex": 3 - } - }, - { - "kind": "TypeAlias", - "canonicalReference": "@vue-storefront/middleware!TODO:type", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "export type TODO = " - }, - { - "kind": "Content", - "text": "any" - }, - { - "kind": "Content", - "text": ";" - } - ], - "fileUrlPath": "src/types/index.ts", - "releaseTag": "Public", - "name": "TODO", - "typeTokenRange": { - "startIndex": 1, - "endIndex": 2 - } - }, - { - "kind": "TypeAlias", - "canonicalReference": "@vue-storefront/middleware!UnknownError:type", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "export type UnknownError = " - }, - { - "kind": "Content", - "text": "{\n [K in T]?: number;\n} & {\n [x: string]: " - }, - { - "kind": "Reference", - "text": "UnknownError", - "canonicalReference": "@vue-storefront/middleware!UnknownError:type" - }, - { - "kind": "Content", - "text": " | any;\n}" - }, - { - "kind": "Content", - "text": ";" - } - ], - "fileUrlPath": "src/types/base.ts", - "releaseTag": "Public", - "name": "UnknownError", - "typeParameters": [ - { - "typeParameterName": "T", - "constraintTokenRange": { - "startIndex": 1, - "endIndex": 2 - }, - "defaultTypeTokenRange": { - "startIndex": 0, - "endIndex": 0 - } - } - ], - "typeTokenRange": { - "startIndex": 3, - "endIndex": 6 - } - }, - { - "kind": "Interface", - "canonicalReference": "@vue-storefront/middleware!UploadedFile:interface", - "docComment": "/**\n * Uploaded file object\n */\n", - "excerptTokens": [ - { - "kind": "Content", - "text": "export interface UploadedFile " - } - ], - "fileUrlPath": "src/types/fileUpload.ts", - "releaseTag": "Public", - "name": "UploadedFile", - "preserveMemberOrder": false, - "members": [ - { - "kind": "PropertySignature", - "canonicalReference": "@vue-storefront/middleware!UploadedFile#buffer:member", - "docComment": "/**\n * File buffer\n *\n * @see\n *\n * https://nodejs.org/api/buffer.html\n */\n", - "excerptTokens": [ - { - "kind": "Content", - "text": "buffer: " - }, - { - "kind": "Reference", - "text": "Buffer", - "canonicalReference": "!\"\\\"buffer\\\"\".__global.Buffer:interface" - }, - { - "kind": "Content", - "text": ";" - } - ], - "isReadonly": false, - "isOptional": false, - "releaseTag": "Public", - "name": "buffer", - "propertyTypeTokenRange": { - "startIndex": 1, - "endIndex": 2 - } - }, - { - "kind": "PropertySignature", - "canonicalReference": "@vue-storefront/middleware!UploadedFile#encoding:member", - "docComment": "/**\n * Encoding eg. 7bit, 8bit\n */\n", - "excerptTokens": [ - { - "kind": "Content", - "text": "encoding: " - }, - { - "kind": "Content", - "text": "string" - }, - { - "kind": "Content", - "text": ";" - } - ], - "isReadonly": false, - "isOptional": false, - "releaseTag": "Public", - "name": "encoding", - "propertyTypeTokenRange": { - "startIndex": 1, - "endIndex": 2 - } - }, - { - "kind": "PropertySignature", - "canonicalReference": "@vue-storefront/middleware!UploadedFile#fieldname:member", - "docComment": "/**\n * Field name Identifies the field name of the file\n */\n", - "excerptTokens": [ - { - "kind": "Content", - "text": "fieldname: " - }, - { - "kind": "Content", - "text": "string" - }, - { - "kind": "Content", - "text": ";" - } - ], - "isReadonly": false, - "isOptional": false, - "releaseTag": "Public", - "name": "fieldname", - "propertyTypeTokenRange": { - "startIndex": 1, - "endIndex": 2 - } - }, - { - "kind": "PropertySignature", - "canonicalReference": "@vue-storefront/middleware!UploadedFile#mimetype:member", - "docComment": "/**\n * MIME type eg. image/jpeg, application/pdf\n */\n", - "excerptTokens": [ - { - "kind": "Content", - "text": "mimetype: " - }, - { - "kind": "Content", - "text": "string" - }, - { - "kind": "Content", - "text": ";" - } - ], - "isReadonly": false, - "isOptional": false, - "releaseTag": "Public", - "name": "mimetype", - "propertyTypeTokenRange": { - "startIndex": 1, - "endIndex": 2 - } - }, - { - "kind": "PropertySignature", - "canonicalReference": "@vue-storefront/middleware!UploadedFile#originalname:member", - "docComment": "/**\n * Original file name\n */\n", - "excerptTokens": [ - { - "kind": "Content", - "text": "originalname: " - }, - { - "kind": "Content", - "text": "string" - }, - { - "kind": "Content", - "text": ";" - } - ], - "isReadonly": false, - "isOptional": false, - "releaseTag": "Public", - "name": "originalname", - "propertyTypeTokenRange": { - "startIndex": 1, - "endIndex": 2 - } - }, - { - "kind": "PropertySignature", - "canonicalReference": "@vue-storefront/middleware!UploadedFile#size:member", - "docComment": "/**\n * File size in bytes\n */\n", - "excerptTokens": [ - { - "kind": "Content", - "text": "size: " - }, - { - "kind": "Content", - "text": "number" - }, - { - "kind": "Content", - "text": ";" - } - ], - "isReadonly": false, - "isOptional": false, - "releaseTag": "Public", - "name": "size", - "propertyTypeTokenRange": { - "startIndex": 1, - "endIndex": 2 - } - } - ], - "extendsTokenRanges": [] - }, - { - "kind": "TypeAlias", - "canonicalReference": "@vue-storefront/middleware!WithoutContext:type", - "docComment": "/**\n * Removes the `context` from the methods of an API Client. `context` is an internal parameter added by the Server Middleware to the methods of the API Client. Removing it allows to define the contract of the endpoints exposed by the Server Middleware.\n *\n * @example\n * ```ts\n * type ApiClientMethods = {\n * getProduct: (context: any, id: string) => Promise;\n * }\n *\n * type Endpoints = WithoutContext;\n * // { getProduct: (id: string) => Promise }\n * ```\n *\n */\n", - "excerptTokens": [ - { - "kind": "Content", - "text": "export type WithoutContext = " - }, - { - "kind": "Content", - "text": "{\n [T in keyof Methods]: Methods[T] extends (context: any, ...arguments_: infer P) => infer R ? (...arguments_: P) => R : never;\n}" - }, - { - "kind": "Content", - "text": ";" - } - ], - "fileUrlPath": "src/types/common.ts", - "releaseTag": "Public", - "name": "WithoutContext", - "typeParameters": [ - { - "typeParameterName": "Methods", - "constraintTokenRange": { - "startIndex": 1, - "endIndex": 2 - }, - "defaultTypeTokenRange": { - "startIndex": 0, - "endIndex": 0 - } - } - ], - "typeTokenRange": { - "startIndex": 3, - "endIndex": 4 - } - }, - { - "kind": "TypeAlias", - "canonicalReference": "@vue-storefront/middleware!WithRequired:type", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "export type WithRequired = " - }, - { - "kind": "Content", - "text": "T & {\n [P in K]-?: T[P];\n}" - }, - { - "kind": "Content", - "text": ";" - } - ], - "fileUrlPath": "src/types/index.ts", - "releaseTag": "Public", - "name": "WithRequired", - "typeParameters": [ - { - "typeParameterName": "T", - "constraintTokenRange": { - "startIndex": 0, - "endIndex": 0 - }, - "defaultTypeTokenRange": { - "startIndex": 0, - "endIndex": 0 - } - }, - { - "typeParameterName": "K", - "constraintTokenRange": { - "startIndex": 1, - "endIndex": 2 - }, - "defaultTypeTokenRange": { - "startIndex": 0, - "endIndex": 0 - } - } - ], - "typeTokenRange": { - "startIndex": 3, - "endIndex": 4 - } - } - ] - } - ] -} diff --git a/docs/content/3.middleware/3.api/middleware.md b/docs/content/3.middleware/3.api/middleware.md deleted file mode 100644 index 2dd68c22c8..0000000000 --- a/docs/content/3.middleware/3.api/middleware.md +++ /dev/null @@ -1 +0,0 @@ -# `@vue-storefront/middleware` diff --git a/docs/content/3.middleware/3.api/multistore.api.json b/docs/content/3.middleware/3.api/multistore.api.json deleted file mode 100644 index 6a7641ac35..0000000000 --- a/docs/content/3.middleware/3.api/multistore.api.json +++ /dev/null @@ -1,695 +0,0 @@ -{ - "metadata": { - "toolPackage": "@microsoft/api-extractor", - "toolVersion": "7.42.3", - "schemaVersion": 1011, - "oldestForwardsCompatibleVersion": 1001, - "tsdocConfig": { - "$schema": "https://developer.microsoft.com/json-schemas/tsdoc/v0/tsdoc.schema.json", - "noStandardTags": true, - "tagDefinitions": [ - { - "tagName": "@alpha", - "syntaxKind": "modifier" - }, - { - "tagName": "@beta", - "syntaxKind": "modifier" - }, - { - "tagName": "@defaultValue", - "syntaxKind": "block" - }, - { - "tagName": "@decorator", - "syntaxKind": "block", - "allowMultiple": true - }, - { - "tagName": "@deprecated", - "syntaxKind": "block" - }, - { - "tagName": "@eventProperty", - "syntaxKind": "modifier" - }, - { - "tagName": "@example", - "syntaxKind": "block", - "allowMultiple": true - }, - { - "tagName": "@experimental", - "syntaxKind": "modifier" - }, - { - "tagName": "@inheritDoc", - "syntaxKind": "inline" - }, - { - "tagName": "@internal", - "syntaxKind": "modifier" - }, - { - "tagName": "@label", - "syntaxKind": "inline" - }, - { - "tagName": "@link", - "syntaxKind": "inline", - "allowMultiple": true - }, - { - "tagName": "@override", - "syntaxKind": "modifier" - }, - { - "tagName": "@packageDocumentation", - "syntaxKind": "modifier" - }, - { - "tagName": "@param", - "syntaxKind": "block", - "allowMultiple": true - }, - { - "tagName": "@privateRemarks", - "syntaxKind": "block" - }, - { - "tagName": "@public", - "syntaxKind": "modifier" - }, - { - "tagName": "@readonly", - "syntaxKind": "modifier" - }, - { - "tagName": "@remarks", - "syntaxKind": "block" - }, - { - "tagName": "@returns", - "syntaxKind": "block" - }, - { - "tagName": "@sealed", - "syntaxKind": "modifier" - }, - { - "tagName": "@see", - "syntaxKind": "block" - }, - { - "tagName": "@throws", - "syntaxKind": "block", - "allowMultiple": true - }, - { - "tagName": "@typeParam", - "syntaxKind": "block", - "allowMultiple": true - }, - { - "tagName": "@virtual", - "syntaxKind": "modifier" - }, - { - "tagName": "@betaDocumentation", - "syntaxKind": "modifier" - }, - { - "tagName": "@internalRemarks", - "syntaxKind": "block" - }, - { - "tagName": "@preapproved", - "syntaxKind": "modifier" - } - ], - "supportForTags": { - "@alpha": true, - "@beta": true, - "@defaultValue": true, - "@decorator": true, - "@deprecated": true, - "@eventProperty": true, - "@example": true, - "@experimental": true, - "@inheritDoc": true, - "@internal": true, - "@label": true, - "@link": true, - "@override": true, - "@packageDocumentation": true, - "@param": true, - "@privateRemarks": true, - "@public": true, - "@readonly": true, - "@remarks": true, - "@returns": true, - "@sealed": true, - "@see": true, - "@throws": true, - "@typeParam": true, - "@virtual": true, - "@betaDocumentation": true, - "@internalRemarks": true, - "@preapproved": true - }, - "reportUnsupportedHtmlElements": false - } - }, - "kind": "Package", - "canonicalReference": "@vue-storefront/multistore!", - "docComment": "", - "name": "@vue-storefront/multistore", - "preserveMemberOrder": false, - "members": [ - { - "kind": "EntryPoint", - "canonicalReference": "@vue-storefront/multistore!", - "name": "", - "preserveMemberOrder": false, - "members": [ - { - "kind": "Interface", - "canonicalReference": "@vue-storefront/multistore!CacheManager:interface", - "docComment": "/**\n * Cache manager is responsible for caching configuration and retreiving configuration from cache.\n */\n", - "excerptTokens": [ - { - "kind": "Content", - "text": "export interface CacheManager " - } - ], - "fileUrlPath": "src/types.ts", - "releaseTag": "Public", - "name": "CacheManager", - "preserveMemberOrder": false, - "members": [ - { - "kind": "MethodSignature", - "canonicalReference": "@vue-storefront/multistore!CacheManager#get:member(1)", - "docComment": "/**\n * Gets a store configuration from cache storage based on the `key` value.\n */\n", - "excerptTokens": [ - { - "kind": "Content", - "text": "get(key: " - }, - { - "kind": "Content", - "text": "string" - }, - { - "kind": "Content", - "text": "): " - }, - { - "kind": "Reference", - "text": "MaybePromise", - "canonicalReference": "@vue-storefront/multistore!~MaybePromise:type" - }, - { - "kind": "Content", - "text": "<" - }, - { - "kind": "Reference", - "text": "StoreConfig", - "canonicalReference": "@vue-storefront/multistore!StoreConfig:type" - }, - { - "kind": "Content", - "text": " | undefined>" - }, - { - "kind": "Content", - "text": ";" - } - ], - "isOptional": false, - "returnTypeTokenRange": { - "startIndex": 3, - "endIndex": 7 - }, - "releaseTag": "Public", - "overloadIndex": 1, - "parameters": [ - { - "parameterName": "key", - "parameterTypeTokenRange": { - "startIndex": 1, - "endIndex": 2 - }, - "isOptional": false - } - ], - "name": "get" - }, - { - "kind": "MethodSignature", - "canonicalReference": "@vue-storefront/multistore!CacheManager#set:member(1)", - "docComment": "/**\n * Sets a store configuration in the cache storage with identifier equals `key` value.\n */\n", - "excerptTokens": [ - { - "kind": "Content", - "text": "set(key: " - }, - { - "kind": "Content", - "text": "string" - }, - { - "kind": "Content", - "text": ", value: " - }, - { - "kind": "Reference", - "text": "StoreConfig", - "canonicalReference": "@vue-storefront/multistore!StoreConfig:type" - }, - { - "kind": "Content", - "text": "): " - }, - { - "kind": "Reference", - "text": "MaybePromise", - "canonicalReference": "@vue-storefront/multistore!~MaybePromise:type" - }, - { - "kind": "Content", - "text": "" - }, - { - "kind": "Content", - "text": ";" - } - ], - "isOptional": false, - "returnTypeTokenRange": { - "startIndex": 5, - "endIndex": 7 - }, - "releaseTag": "Public", - "overloadIndex": 1, - "parameters": [ - { - "parameterName": "key", - "parameterTypeTokenRange": { - "startIndex": 1, - "endIndex": 2 - }, - "isOptional": false - }, - { - "parameterName": "value", - "parameterTypeTokenRange": { - "startIndex": 3, - "endIndex": 4 - }, - "isOptional": false - } - ], - "name": "set" - } - ], - "extendsTokenRanges": [] - }, - { - "kind": "Function", - "canonicalReference": "@vue-storefront/multistore!createMultistoreExtension:function(1)", - "docComment": "", - "excerptTokens": [ - { - "kind": "Content", - "text": "createMultistoreExtension: (multistoreConfig: " - }, - { - "kind": "Reference", - "text": "MultistoreExtensionMethods", - "canonicalReference": "@vue-storefront/multistore!MultistoreExtensionMethods:interface" - }, - { - "kind": "Content", - "text": ") => " - }, - { - "kind": "Content", - "text": "{\n name: string;\n isNamespaced: false;\n extendApp: () => void;\n hooks: (req: " - }, - { - "kind": "Reference", - "text": "Request", - "canonicalReference": "@types/express!e.Request:interface" - }, - { - "kind": "Content", - "text": ") => {\n beforeCreate: ({ " - }, - { - "kind": "Reference", - "text": "configuration", - "canonicalReference": "@vue-storefront/middleware!HookParams#configuration" - }, - { - "kind": "Content", - "text": ": baseConfig }: import(\"@vue-storefront/middleware\")." - }, - { - "kind": "Reference", - "text": "HookParams", - "canonicalReference": "@vue-storefront/middleware!HookParams:interface" - }, - { - "kind": "Content", - "text": ") => " - }, - { - "kind": "Reference", - "text": "Promise", - "canonicalReference": "!Promise:interface" - }, - { - "kind": "Content", - "text": ";\n };\n}" - } - ], - "fileUrlPath": "src/extension.ts", - "returnTypeTokenRange": { - "startIndex": 3, - "endIndex": 14 - }, - "releaseTag": "Public", - "overloadIndex": 1, - "parameters": [ - { - "parameterName": "multistoreConfig", - "parameterTypeTokenRange": { - "startIndex": 1, - "endIndex": 2 - }, - "isOptional": false - } - ], - "name": "createMultistoreExtension" - }, - { - "kind": "Interface", - "canonicalReference": "@vue-storefront/multistore!FetchConfigWithCacheParams:interface", - "docComment": "/**\n * Parameters for updateConfig utility function.\n */\n", - "excerptTokens": [ - { - "kind": "Content", - "text": "export interface FetchConfigWithCacheParams " - } - ], - "fileUrlPath": "src/types.ts", - "releaseTag": "Public", - "name": "FetchConfigWithCacheParams", - "preserveMemberOrder": false, - "members": [ - { - "kind": "PropertySignature", - "canonicalReference": "@vue-storefront/multistore!FetchConfigWithCacheParams#cacheManager:member", - "docComment": "/**\n * Cache manager.\n */\n", - "excerptTokens": [ - { - "kind": "Content", - "text": "cacheManager: " - }, - { - "kind": "Reference", - "text": "CacheManager", - "canonicalReference": "@vue-storefront/multistore!CacheManager:interface" - }, - { - "kind": "Content", - "text": ";" - } - ], - "isReadonly": false, - "isOptional": false, - "releaseTag": "Public", - "name": "cacheManager", - "propertyTypeTokenRange": { - "startIndex": 1, - "endIndex": 2 - } - }, - { - "kind": "PropertySignature", - "canonicalReference": "@vue-storefront/multistore!FetchConfigWithCacheParams#domain:member", - "docComment": "/**\n * Domain of the request.\n */\n", - "excerptTokens": [ - { - "kind": "Content", - "text": "domain: " - }, - { - "kind": "Content", - "text": "string" - }, - { - "kind": "Content", - "text": ";" - } - ], - "isReadonly": false, - "isOptional": false, - "releaseTag": "Public", - "name": "domain", - "propertyTypeTokenRange": { - "startIndex": 1, - "endIndex": 2 - } - }, - { - "kind": "PropertySignature", - "canonicalReference": "@vue-storefront/multistore!FetchConfigWithCacheParams#multistore:member", - "docComment": "/**\n * Extension methods defined in the middleware multistore configuration.\n */\n", - "excerptTokens": [ - { - "kind": "Content", - "text": "multistore: " - }, - { - "kind": "Reference", - "text": "MultistoreExtensionMethods", - "canonicalReference": "@vue-storefront/multistore!MultistoreExtensionMethods:interface" - }, - { - "kind": "Content", - "text": ";" - } - ], - "isReadonly": false, - "isOptional": false, - "releaseTag": "Public", - "name": "multistore", - "propertyTypeTokenRange": { - "startIndex": 1, - "endIndex": 2 - } - } - ], - "extendsTokenRanges": [] - }, - { - "kind": "Interface", - "canonicalReference": "@vue-storefront/multistore!MultistoreExtensionMethods:interface", - "docComment": "/**\n * Extension methods defined in the middleware multistore configuration.\n */\n", - "excerptTokens": [ - { - "kind": "Content", - "text": "export interface MultistoreExtensionMethods " - } - ], - "fileUrlPath": "src/types.ts", - "releaseTag": "Public", - "name": "MultistoreExtensionMethods", - "preserveMemberOrder": false, - "members": [ - { - "kind": "PropertySignature", - "canonicalReference": "@vue-storefront/multistore!MultistoreExtensionMethods#cacheManagerFactory:member", - "docComment": "/**\n * Cache manager factory creates cache manager.\n */\n", - "excerptTokens": [ - { - "kind": "Content", - "text": "cacheManagerFactory: " - }, - { - "kind": "Content", - "text": "() => " - }, - { - "kind": "Reference", - "text": "CacheManager", - "canonicalReference": "@vue-storefront/multistore!CacheManager:interface" - }, - { - "kind": "Content", - "text": ";" - } - ], - "isReadonly": false, - "isOptional": false, - "releaseTag": "Public", - "name": "cacheManagerFactory", - "propertyTypeTokenRange": { - "startIndex": 1, - "endIndex": 3 - } - }, - { - "kind": "PropertySignature", - "canonicalReference": "@vue-storefront/multistore!MultistoreExtensionMethods#fetchConfiguration:member", - "docComment": "/**\n * Fetches configuration from external service.\n */\n", - "excerptTokens": [ - { - "kind": "Content", - "text": "fetchConfiguration: " - }, - { - "kind": "Content", - "text": "(params: {\n domain: string;\n }) => " - }, - { - "kind": "Reference", - "text": "MaybePromise", - "canonicalReference": "@vue-storefront/multistore!~MaybePromise:type" - }, - { - "kind": "Content", - "text": "<" - }, - { - "kind": "Reference", - "text": "Record", - "canonicalReference": "!Record:type" - }, - { - "kind": "Content", - "text": ">" - }, - { - "kind": "Content", - "text": ";" - } - ], - "isReadonly": false, - "isOptional": false, - "releaseTag": "Public", - "name": "fetchConfiguration", - "propertyTypeTokenRange": { - "startIndex": 1, - "endIndex": 8 - } - }, - { - "kind": "PropertySignature", - "canonicalReference": "@vue-storefront/multistore!MultistoreExtensionMethods#mergeConfigurations:member", - "docComment": "/**\n * Overwrites base configuration with store configuration.\n */\n", - "excerptTokens": [ - { - "kind": "Content", - "text": "mergeConfigurations: " - }, - { - "kind": "Content", - "text": "(params: {\n baseConfig: " - }, - { - "kind": "Reference", - "text": "StoreConfig", - "canonicalReference": "@vue-storefront/multistore!StoreConfig:type" - }, - { - "kind": "Content", - "text": ";\n storeConfig: " - }, - { - "kind": "Reference", - "text": "StoreConfig", - "canonicalReference": "@vue-storefront/multistore!StoreConfig:type" - }, - { - "kind": "Content", - "text": ";\n }) => " - }, - { - "kind": "Reference", - "text": "StoreConfig", - "canonicalReference": "@vue-storefront/multistore!StoreConfig:type" - }, - { - "kind": "Content", - "text": ";" - } - ], - "isReadonly": false, - "isOptional": false, - "releaseTag": "Public", - "name": "mergeConfigurations", - "propertyTypeTokenRange": { - "startIndex": 1, - "endIndex": 7 - } - } - ], - "extendsTokenRanges": [] - }, - { - "kind": "TypeAlias", - "canonicalReference": "@vue-storefront/multistore!StoreConfig:type", - "docComment": "/**\n * Type alias for any store configuration.\n */\n", - "excerptTokens": [ - { - "kind": "Content", - "text": "export type StoreConfig = " - }, - { - "kind": "Reference", - "text": "Record", - "canonicalReference": "!Record:type" - }, - { - "kind": "Content", - "text": "" - }, - { - "kind": "Content", - "text": ";" - } - ], - "fileUrlPath": "src/types.ts", - "releaseTag": "Public", - "name": "StoreConfig", - "typeTokenRange": { - "startIndex": 1, - "endIndex": 3 - } - } - ] - } - ] -} diff --git a/docs/content/3.middleware/3.api/multistore.md b/docs/content/3.middleware/3.api/multistore.md deleted file mode 100644 index 45f1c50504..0000000000 --- a/docs/content/3.middleware/3.api/multistore.md +++ /dev/null @@ -1 +0,0 @@ -# `@vue-storefront/multistore` diff --git a/docs/content/3.middleware/4.reference/change-log.md b/docs/content/3.middleware/4.reference/change-log.md deleted file mode 100644 index 85f8cf3661..0000000000 --- a/docs/content/3.middleware/4.reference/change-log.md +++ /dev/null @@ -1,382 +0,0 @@ -# Change log - -## 5.3.2 - -### Patch Changes - -- **[FIXED]** Fix /readyz returning 503 if readinessProbes not passed in middleware.config.ts - -Before this fix, sending a GET request to `http://localhost:4000/readyz` would return { "status": "error" } and a HTTP 503 status. This happened only when `readinessProbes` wasn't added to middleware options (the default behavior) - -## 5.3.1 - -### Patch Changes - -**[FIXED]** type of `defaultErrorHandler` - -## 5.3.0 - -### Minor Changes - -**[ADDED]** `defaultErrorHandler` is now exported from the package. Example usage: - -```ts -import type { Integration } from "@vue-storefront/middleware"; -import type { MiddlewareConfig } from "@vsf-enterprise/sapcc-api"; -import { defaultErrorHandler } from "@vue-storefront/middleware"; - -export const config = { - integrations: { - commerce: { - errorHandler: (error, req, res) => { - // Perform custom actions before delegating to the default error handler - defaultErrorHandler(error, req, res); - }, - } satisfies Integration, - }, -}; -``` - -## 5.2.0 - -### Minor Changes - -**[ADDED]** Support for file uploads -Now you can upload files to the server with a `multipart/form-data` content type. Files are available in the `req.files` object. - -```ts -// Example of an endpoint that handles file uploads -export const upload = (context) => { - // Files are available in the `req.files` object - const { files } = context.req; - - // Do something with files - - return Promise.resolve({ - status: 200, - message: "ok", - }); -}; -``` - -Please, read the [Getting Started guide](https://docs.alokai.com/middleware/guides/getting-started#file-upload-configuration) for more information about file uploads. - -## 5.1.1 - -### Patch Changes - -** [CHANGED] ** - -- added more verbose message with a troubleshooting guide in case that the `getLogger` method was not able to retrieve the logger instance. - -** [FIXED] ** - -- changed `level` property to `verbosity` in the `LoggerConfig` interface. - -## 5.1.0 - -### Minor Changes - -- **[ADDED]** The middleware application now offers a robust logger instance accessible across various parts of the system, including extensions, integrations, hooks, and API methods. This provides greater flexibility for logging critical events and errors throughout the application lifecycle. For more information, see the [Logger](https://docs.alokai.com/middleware/guides/logging) guide. - -## 5.0.1 - -### Patch Changes - -- **[FIXED]** a potential XSS (Cross-Site Scripting) vulnerability in the middleware. Now, each parameter is properly sanitized and validated before being used in the middleware. - -## 5.0.0 - -### Major Changes - -- [CHANGED] [BREAKING] Changed return type of `createServer()` from `Express` to `Server` (from built-in `node:http` package). Both of those types' interfaces have the `.listen()` method with the same shape. In some older templates for starting the middleware (`middleware.js` in your repo) you come across: - -```ts -async function runMiddleware(app: Express) { -``` - -If you're using that older template, please change the `Express` type to `Server`: - -```diff -+ import { Server } from "node:http" -+ async function runMiddleware(app: Server) { -- async function runMiddleware(app: Express) { -``` - -- [ADDED] New GET /readyz endpoint for middleware for using with Kubernetes readiness probes. Please see https://docs.alokai.com/middleware/guides/readiness-probes for more information - -## 4.3.1 - -### Patch Changes - -- **[FIX]** Rollback the changes to the `ApiMethodsFactory` config generic type. It was causing incompatibility for some older packages. - -## 4.3.0 - -### Minor Changes - -- **[ADDED]** Added factory function for the extension API. Previously the extension API was an object with a set of methods. Now it can be created using a factory function the same way as the base API. - -Previously only object was allowed: - -```ts -export const extension: ApiClientExtension = { - name: "extension", - extendApiMethods: { - ...extendedMethods, //methods as an object - }, -}; -``` - -Now you can either use an object or a factory function: - -```ts -export const extension: ApiClientExtension = { - name: "extension", - // methods as a factory function with injected config object - extendApiMethods: ({ config }) => { - return createMyMethods(config); - }, -}; -``` - -## 4.2.0 - -### Minor Changes - -- **[ADDED]** Provided easy access to methods added by middleware extensions via the `context.extendedApi` property. - -```ts -const extensionA = { - name: 'extensionA', - extendApiMethods: { - methodA: async () => { ... } - } -} - -const extensionB = { - name: 'extensionB', - extendApiMethods: { - methodB: async () => { ... } - } -} - -const extensionC = { - name: 'extensionC', - extendApiMethods: { - methodC: async (context) => { - context.extendedApi.methodA(); - context.extendedApi.extensionB.methodB(); - } - } -} -``` - -## 4.1.0 - -### Minor Changes - -- **[CHANGED]** [Middleware extension](https://docs.alokai.com/middleware/guides/extensions) hooks and the [onCreate](https://docs.alokai.com/middleware/guides/api-client#creating-the-integration-client) function can now be asynchronous. Examples: - -```ts -// middleware.config.ts -const middlewareExtension = { - name: "example-extension", - hooks: () => ({ - beforeCreate: async ({ configuration }) => Promise.resolve(configuration), - afterCreate: async ({ configuration }) => Promise.resolve(configuration), - beforeCall: async ({ args }) => Promise.resolve(args), - afterCall: async ({ response }) => Promise.resolve(response), - }), -}; -``` - -```ts -// index.server.ts -import { apiClientFactory } from "@vue-storefront/middleware"; - -const { createApiClient } = apiClientFactory({ - onCreate: async (config) => - Promise.resolve({ - config, - client: {}, - }), - api: {}, -}); - -export { createApiClient }; -``` - -## 4.0.1 - -### Patch Changes - -- **[CHANGED]** Fix typo in default error handler - Now the default error message for error responses bearing a 4xx status code will be - "Request failed with status code ${status}" instead of "Request faileds [...]". - -## 4.0.0 - -### Major Changes - -- **[CHANGED]** Changed minimum Node version from 16 to 18. The condition that was forcing the Node version to be lower than 19 is also removed. - -## 3.10.0 - -### Minor Changes - -- **[ADDED]** Options as a second parameter of `createServer`. This allows you to pass additional options to `cors`, `body-parser` and `cookie-parser` express middlewares. - -```ts -import { createServer } from "@vue-storefront/middleware"; -import config from "../middleware.config"; - -createServer(config, { - cors: { - origin: "http://localhost:3000", - credentials: true, - }, - bodyParser: { - limit: "50mb", - }, - cookieParser: { - secret: "secret", - }, -}); -``` - -- **[ADDED]** `http://localhost:4000` to the default cors origin. - -## 3.9.0 - -### Minor Changes - -- 712ba85a6: [ADDED] Adds WithoutContext type helper. - - ```ts - type ApiClientMethods = { - getProduct: (context: any, id: string) => Promise; - }; - - type Endpoints = WithoutContext; - ``` - -## 3.8.1 - -### Patch Changes - -- c4534b523: [CHANGED] Returning HTTP Code 408 in case of ECONNABORTED from 3rd party service, and 500 in case of ECONNRESET instead of general fallback to HTTP Code 500, to provide more precise information about the case. - -## 3.8.0 - -### Minor Changes - -- 1e9fe5366: It is now possible to add namespaced extensions to integrations. Namespaced extensions are registered under `/{integration-name}/{extension-name}` extension of integration's namespace in opposition to non-namespaced extensions which are registered under `/{integration-name}` integration's namespace. Default value is `false`. Extensions without a namespace can potentially override existing endpoints, so it's recommended to use namespaced extensions whenever possible. - - Read more about extensions in our [docs](https://docs.vuestorefront.io/middleware/guides/extensions). - -## 3.7.1 - -### Patch Changes - -- 76e5f92e6: Fix the issue with error handling during the timeouted requests - -## 3.7.0 - -### Minor Changes - -- 496bfb840: Hide error data from the response, now only the message will be exposed to the client. - -## 3.6.2 - -### Patch Changes - -- 6c769c7a8: Fix status code resolving for the apollo client - -## 3.6.1 - -### Patch Changes - -- 3335b9b48: `getApiClient` helper returns now ApiClient interface - - Usage: - - ```typescript - const sapcc = context.getApiClient("sapcc"); - // typeof sapcc === ApiClient - ``` - -## 3.6.0 - -### Minor Changes - -- 1caa56efb: Add orchestration possibility by receiving loaded integrations from `context` -- 1caa56efb: Extend `IntegrationContext` type with `MiddlewareContext` -- 1caa56efb: Add new interface: `ApiClient` - -### Patch Changes - -- 1caa56efb: Remove singleton app from createServer function - -## 3.5.1 - -### Patch Changes - -- f8a7893: Enhanced error handling in **getAxiosStatusCode** for greater reliability, reducing the risk of unexpected errors and crashes when retrieving status codes from Axios errors. - -## 3.5.0 - -### Minor Changes - -- 50a0cd7: Added HTTP `GET` method support. Divided dynamic route logic into smaller, unit-tested middlewares. - -## 3.4.0 - -### Minor Changes - -- e2ff011: The `extendApp` callback which can be registered in extensions is now asynchronous and can be awaited to perform necessary operations while building the app. - -## 3.3.1 - -### Patch Changes - -- 5df8936: Fixed error objects detection - -## 3.3.0 - -### Minor Changes - -- 93e7c7c: Added possibility to pass API methods to createApiClient both as a plain object and a factory. - -## 3.2.1 - -### Patch Changes - -- Removed terser from the build process - -## 3.2.0 - -### Features - -- expose integration methods inside extensions context -- make integration name available within the `extendApp` extension method - -## 3.1.0 - -### Features - -- add configurable error handler - -## 3.0.1 - -### Bug Fixes - -- all 4xx error code respond with error not just generic message (#6) - -## 3.0.0 - -This release decoupled the middleware from the core. - -### Chores - -- stable release. diff --git a/docs/content/3.middleware/4.reference/multistore/change-log.md b/docs/content/3.middleware/4.reference/multistore/change-log.md deleted file mode 100644 index 3dfbfb5399..0000000000 --- a/docs/content/3.middleware/4.reference/multistore/change-log.md +++ /dev/null @@ -1,111 +0,0 @@ -# Change log - -## 4.1.2 - -### Patch Changes - -- Updated dependencies: - - @vue-storefront/middleware@5.1.0 - -## 4.1.1 - -### Patch Changes - -- Updated dependencies: - - @vue-storefront/middleware@5.0.0 - -## 4.1.0 - -### Minor Changes - -- **[ADDED]** Support for asynchronous `fetchConfiguration()` and cacheManagerFactory's `get()` / `set()` methods. - -```diff -import { createMultistoreExtension } from "@vue-storefront/multistore"; - -export const multistoreExtension = createMultistoreExtension({ -- fetchConfiguration: () => ({ -+ fetchConfiguration: async () => ({ ... }), - mergeConfigurations: () => ({ ... }), - cacheManagerFactory: () => ({ -- get(key) { ... }, -+ async get(key) { ... }, -- set(key, value) { ... }, -+ async set(key, value) { ... }, - }), -}); - -``` - -## 4.0.0 - -### Major Changes - -- **[CHANGED]** Changed minimum Node version from 16 to 18. The condition that was forcing the Node version to be lower than 19 is also removed. - -### Patch Changes - -- Updated dependencies: - - @vue-storefront/middleware@4.0.0 - -## 3.0.0 - -### Patch Changes - -- Updated dependencies: - - @vue-storefront/middleware@3.9.0 - -```diff [package.json] -dependencies: { -- "@vue-storefront/middleware": "3.x.x", -- "@vue-storefront/multistore": "2.x.x", -+ "@vue-storefront/middleware": "^3.9.0", -+ "@vue-storefront/multistore": "^3.0.0", -} -``` - -## 2.0.1 - -### Patch Changes - -- d95379e91: [FIXED] Type issue in multistore package. Cache control `set` method returns `any` type and `get` returns `StoreConfig | undefined`. Also, `MiddlewareConfiguration` type has been removed as it is no longer necessary. - -## 2.0.0 - -### Major Changes - -- 8ea533e05: [CHANGED] We standardized the way of creating and configuring multistore extension. - Previously, the extension was created by importing `multistoreExtension` from `@vue-storefront/multistore` and passing it to the `extensions` function. - Configuration was passed to the extension by adding `multistore` property to the `configuration` object. - Now, the extension is created by calling `createMultistoreExtension` from `@vue-storefront/multistore` and passing the multistore configuration to it. - - ```diff [middleware.config.ts] - - import { multistoreExtension } from "@vue-storefront/multistore"; - + import { createMultistoreExtension } from "@vue-storefront/multistore"; - import { multistoreConfig } from "./multistore.config"; - - export default { - integrations: { - sapcc: { - location: "@vue-storefront/sapcc-api/server", - configuration: { - // ... - - multistore: multistoreConfig, - }, - extensions: (predefinedExtensions) => [ - ...predefinedExtensions, - - multistoreExtension, - + createMultistoreExtension(multistoreConfig), - ], - }, - }, - }; - ``` - -- 8ea533e05: [FIXED] singleton cache issue, previously the cache was a singleton which could lead to unexpected behaviour when extension was used in different integrations in parallel. Now, the cache is being created during extension creation, what ensures proper cache behaviour. - -## 1.0.2 - -### Patch Changes - -- 3410b778a: [FIXED] Unified Multistore not exposing types at its entrypoint; previously, type definitions were inaccessible, leading to integration issues. Now, types are correctly exposed, enhancing TypeScript integration and accessibility. diff --git a/docs/content/3.middleware/_dir.yml b/docs/content/3.middleware/_dir.yml deleted file mode 100644 index dfd0723cfd..0000000000 --- a/docs/content/3.middleware/_dir.yml +++ /dev/null @@ -1,3 +0,0 @@ -title: Middleware -sidebarRoot: true -navigation.icon: 'fa6-solid:layer-group' diff --git a/docs/content/3.middleware/img/extensions/data-flow.svg b/docs/content/3.middleware/img/extensions/data-flow.svg deleted file mode 100644 index c07d63dae2..0000000000 --- a/docs/content/3.middleware/img/extensions/data-flow.svg +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/docs/content/3.middleware/img/overview/architecture.svg b/docs/content/3.middleware/img/overview/architecture.svg deleted file mode 100644 index 94fa9d73b1..0000000000 --- a/docs/content/3.middleware/img/overview/architecture.svg +++ /dev/null @@ -1,87 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/docs/content/4.sdk/1.index.md b/docs/content/4.sdk/1.index.md deleted file mode 100644 index c32a63b23c..0000000000 --- a/docs/content/4.sdk/1.index.md +++ /dev/null @@ -1,55 +0,0 @@ ---- -title: Overview ---- - -# SDK - -The Alokai SDK simplifies the development process by providing pre-built functionality to enables seamless interaction between your storefront and various Commerce Platforms and third-party services. - -By utilizing the Alokai SDK, you can establish a type-safe contract between your storefront and various APIs with the help of the Server Middleware acting as a proxy. - -:card{to="/sdk/getting-started" title="Get Started" description="Learn how to initialize the SDK in your storefronts" icon="ic:baseline-rocket"} - -Along with the Alokai SDK, we're providing tools for the State Management. Those are already preconfigured and ready to use. Available both for Next.js and Nuxt through our dedicated packages. - -:card{to="/sdk/getting-started/state-management" title="State Management" description="Learn how to use built in State Manager" icon="grommet-icons:storage"} - - -## Key Features - -::list{type="success"} -- **Type-safe** - The SDK is fully typed, so you can use it with confidence. -- **Plugin architecture** - The SDK is built on a plugin architecture that allows you to extend its functionality with ease. -- **Modular** - You can use multiple integrations at once, and they won't interfere with each other. -- **Customizable** - You can extend the SDK to add new methods, modify existing methods, and more -- **Framework-agnostic** - The SDK is written in TypeScript, so you can use it with any JS framework -:: - - -## Architecture - -The SDK has two components: - -1. The SDK Core - the core package, `@vue-storefront/sdk`, that initializes all modules and implements the plug-in architecture -2. Modules - pluggable pieces of code as standalone packages that integrate into the core to add functionality (eg.: `middlewareModule`) - -In most cases, you would use `middlewareModule` with different configurations - but you can also create your own modules. - -:card{to="/integrations" title="Integrations" description="See all of the available integrations that you can use with the SDK" icon="fluent:puzzle-cube-piece-20-filled"} - -## Example Usage - -Once a module is initialized, it can be used to interact with the server middleware. - -```ts -import { sdk } from '~/sdk' - -await sdk.exampleModule.doSomething(); // <- fully-typed -``` - -These SDK methods will then call a corresponding middleware endpoint. This means that you don't have to worry about creating your own API calls to work a service's API. Instead, you can use the integration SDK to get the data you need. - -And since the SDK is written in TypeScript, the data returned from the methods will be fully typed - meaning you can catch some errors earlier. - - - diff --git a/docs/content/4.sdk/2.getting-started/1.index.md b/docs/content/4.sdk/2.getting-started/1.index.md deleted file mode 100644 index 22960e80ec..0000000000 --- a/docs/content/4.sdk/2.getting-started/1.index.md +++ /dev/null @@ -1,555 +0,0 @@ -# Getting Started - -If you're setting your Alokai application from scratch, you'll need to configure a type-safe SDK that communicates with your [Server Middleware](/middleware). - -:::tip -In the examples below, we assume that you have an Alokai app with the Unified Data Model. However, the approach for non-unified Alokai applications is similar. -::: - -There are various ways to configure the SDK, depending on your chosen framework. For Next.js and Nuxt, you can use the `@vue-storefront/next` and `@vue-storefront/nuxt` packages respectively. -These packages also provide tools for handling the global state management. - -If you're looking for framework agnostic experience, you can use the `@vue-storefront/sdk` package. - -::tabs{:titles='["Next.js", "Nuxt", "Other"]' class="mt-8"} - -#tab-1 - -## Installation - -To get started with the SDK within Next.js, first you have to install the `@vue-storefront/next` package. In the root of your Storefront project run: - -```bash [Next.js] -# Using yarn -yarn add --dev @vue-storefront/next - -# Using pnpm -pnpm add -D @vue-storefront/next - -# Using npm -npm install --save-dev @vue-storefront/next -``` - -## Initializing the SDK - -To use SDK in our application, we need to initialize it first. To do so, follow these steps: - -1. Create an `sdk` directory in the root of your project. - -2. Create the SDK Options file — `sdk.options.ts` in the `sdk` directory. In this file, we create a configuration object used to pass information to the SDK Factory about the address of the middleware, both in client and SSR mode, the identifier for cache busting, etc. - -::info -If you want to keep your Storefront more configurable, we highly recommend using the `next-runtime-env` library to read the environment variables from the runtime rather than hard-coding them during the build process. -:: - -```ts [sdk/options.ts] -import { resolveSdkOptions } from '@vue-storefront/next'; -import { env } from 'next-runtime-env'; - -export function getSdkOptions() { - const apiUrl = env('NEXT_PUBLIC_ALOKAI_MIDDLEWARE_API_URL') ?? ''; - const ssrApiUrl = env('NEXT_PUBLIC_ALOKAI_MIDDLEWARE_SSR_API_URL'); - const cdnCacheBustingId = env('NEXT_PUBLIC_ALOKAI_MIDDLEWARE_CDN_CACHE_BUSTING_ID') ?? 'no-cache-busting-id-set'; - const isMultiStoreEnabled = env('NEXT_PUBLIC_ALOKAI_MULTISTORE_ENABLED') === 'true'; - if (!apiUrl) { - throw new Error('NEXT_PUBLIC_ALOKAI_MIDDLEWARE_API_URL is required to run the app'); - } - - const options = resolveSdkOptions({ - middleware: { - apiUrl, - cdnCacheBustingId, - ssrApiUrl, - }, - multistore: { - enabled: isMultiStoreEnabled, - }, - }); - - return options; -} -``` - -3. Create SDK Config file - `config.ts`. In this file, we define the configuration of different modules. We are making it a separate file to easily import it both on the server and the client. Create the SDK configuration by importing the `createSdk` function from the Next.js SDK and using the `middlewareModule` it provides. You should also import other modules you want to use. - -```ts [sdk/config.ts] -import { contentfulModule } from "@vsf-enterprise/contentful-sdk"; -import { defineSdkConfig } from "@vue-storefront/next"; -import type { CommerceEndpoints, UnifiedEndpoints } from "storefront-middleware/types"; - -export function getSdkConfig() { - return defineSdkConfig(({ buildModule, config, middlewareModule, getRequestHeaders }) => ({ - commerce: buildModule(middlewareModule, { - apiUrl: config.middlewareUrl + "/commerce", - defaultRequestConfig: { - headers: getRequestHeaders(), - }, - }), - cms: buildModule(contentfulModule, { - apiUrl: config.middlewareUrl + "/cms", - }), - })); -} -``` - -- The `buildModule` function is used to build the module. It expects the module and the module configuration as arguments. - -- The `config` is object containg data that is needed in module configuration such as: - - the URL of the middleware instance - - or the busting ID for CDN cache - -- The `middlewareModule` is an SDK module that ensures communication with the Server Middleware. It takes the `UnifiedEndpoints` type as a generic parameter. The `UnifiedEndpoints` type is a type that represents the endpoints of the Server Middleware. - -- The `getRequestHeaders` function is used to provide the incoming headers within your requests. You can use `getRequestHeaders` to access and proxy the initial cookie headers to SDK requests during SSR. Initial headers could be provided by the [`getSdk`](#getsdk) method. - Check out examples there: - - Next Pages Router [link](https://github.com/vuestorefront/vue-storefront/tree/main/packages/storefront/packages/next/__tests__/apps/pages-router) - - Next App Router [link](https://github.com/vuestorefront/vue-storefront/tree/main/packages/storefront/packages/next/__tests__/apps/app-router) - - Nuxt app [link](https://github.com/vuestorefront/vue-storefront/tree/main/packages/storefront/packages/nuxt/__tests__/app) - -::info -In the browser, `getRequestHeaders` will return an empty object. -:: - -- The `defineSdkConfig` function returns the factory function for the SDK configuration as a second argument in `createSdk`. This factory function receives context, which is useful for creating the SDK configuration. - -4. Create SDK instance for server components. Let's do it in the `sdk.server.ts` in the `sdk` directory. - -::info -It is not necessary to name the file `sdk.server.ts` specifically or to keep it in the `sdk` directory, but it is recommended to keep it consistent with the rest of the Alokai project. -:: - -```ts [sdk/sdk.server.ts] -import { createSdk } from "@vue-storefront/next"; -import { getSdkOptions } from "./options"; -import { getSdkConfig } from "./config"; - -export const { getSdk } = createSdk( - getSdkOptions(), - getSdkConfig() -); - -export type Sdk = ReturnType; -``` - -Let's break down the code above: - -- The `createSdk` function expects - - - base SDK options including the middleware and (optionally) the multistore configuration as a first argument, - - and a factory function for the SDK configuration as a second argument. Those factory function receives a context, useful for creating the SDK configuration. - -- The `createSdk` function returns the `getSdk` function, which is used to retreive the new SDK instance. - -## Registering the SDK - -Once you have initialized the SDK, you can register it in your application. - -Alokai SDK can be used in two ways: - -- `getSdk` - returns the SDK instance, which can be used to call the SDK methods directly. This is useful for server-side rendering, as it allows you to call the SDK methods directly in your application. - -- `createSdkContext` - returns the SDK context, which can be used to share the same SDK instance on the Client side. This is useful for client-side rendering, as it allows you to share the same SDK instance across your application. - -### getSdk - -`getSdk` is used to create the new SDK instance. This is especially useful for server-side fetching, as it returns a new SDK instance that can be used to call the SDK methods directly in your application. - -Below is an example of how you can use `getSdk` in your application: - -```ts -import { getSdk } from "@/sdk/sdk.server"; - -const sdk = getSdk(); -``` - -### createAlokaiContext - -For client-side rendering, you can use `createAlokaiContext`. This function serves for two purposes: -- providing the SDK context -- providing the global state management context and hooks for handling the state of the application - -To use it, you'll need to create a new file in your application, for example `sdk/alokai-context.tsx`: - -```ts -'use client'; - -import { createAlokaiContext } from '@vue-storefront/next/client'; -import type { SfContract } from 'storefront-middleware/types'; - -import type { Sdk } from './sdk.server'; - -export const { - AlokaiProvider, - useSdk, - useSfCartState, - useSfCurrenciesState, - useSfCurrencyState, - useSfCustomerState, - useSfLocaleState, - useSfLocalesState, -} = createAlokaiContext(); -``` - -The `SfContract` interface is used to define the contract between the SDK and the state management. It contains the types for: - -- cart (`SfCart` type) -- customer (`SfCurrency` type) -- currency (`SfCurrency` type) -- locale (`SfLocale` type) - -This is needed to ensure that the state management is aware of the types that you have within the middleware, as those types can be changed within the middleware. - -You can read more about the state management in the [State Management](/sdk/getting-started/state-management) page. - -Once you have created the Alokai context, you can create client-side SDK instance and register it in your application. - -You can do it in two steps: - -1. Retrieve the SDK config in the server component in `app/[locale]/layout.tsx`: - -```tsx -// app/[locale]/layout.tsx - -import { ReactNode } from "react"; -import { PublicEnvProvider } from "next-runtime-env"; -import { Providers } from "./providers"; -import { getSdkOptions } from "@/sdk/options"; - -export default function RootLayout({ children }: { children: ReactNode }) { - const sdkOptions = getSdkOptions(); - - return ( - - - - {children} - - - - ); -} -``` - -2. Pass the SDK options to the `Providers` client component and initialize the SDK instance along with the `AlokaiProvider`: - -```tsx -// components/providers.tsx - -"use client"; - -import { ReactNode } from "react"; -import type { CreateSdkOptions } from '@vue-storefront/next'; -import { SdkProvider } from "@/sdk"; -import { getSdkOptions } from "@/sdk/options"; -import { getSdkConfig } from "@/sdk/config"; - -export function Providers({ children, sdkOptions }: { children: ReactNode, sdkOptions: CreateSdkOptions }) { - const { getSdk } = createSdk( - sdkOptions, - getSdkConfig() - ); - return ( - - {children} - - ) -} -``` - -::info -Don't be alarmed if you see a `use client` directive in the `components/providers.tsx` file. This will not turn your application into a client-side rendered application. All children inside the provider will be still rendered on the server-side by default. You can read more about `use client` directive in [React Documentation](https://react.dev/reference/react/use-client). -:: - -## Usage - -Once you have registered the SDK in your application, you can start using it. Here's an example of how you can use the SAP Commerce Cloud SDK module in your application: - -::code-group - -```tsx [Pages Router] -import { getSdk } from "@/sdk"; - -export async function getServersideProps() { - const sdk = getSdk(); - const { products } = await sdk.commerce.searchProduct(); - - return { - props: { - products, - }, - }; -} -``` - -```tsx [App Router] -import { getSdk } from "@/sdk"; - -const sdk = getSdk(); - -const { products } = await sdk.commerce.searchProduct(); -``` - -```tsx [Client Side Rendering] -import { useEffect, useState } from "react"; -import { useSdk } from '@/sdk/sdk-context'; - -export function ClientComponentUsingSDK() { - const sdk = useSdk(); - const [cart, setCart] = useState([]); - - useEffect(() => { - const fetchCart = async () => { - const newCart = await sdk.commerce.getCart({ - cartId: "", - fields: "code,guid,user(FULL)", - }); - setCart(newCart); - }; - - fetchCart(); - }, []); -} -``` - -:: - -Code above is just an example of how you can use the SDK in your application. For more information about the available methods, please refer to the respective [Integration's documentation](/integrations). - -That's it! You can now use VueStorefront SDK Module in your Next.js app ✨ - -#tab-2 - -## Installation - -To get started with the SDK within Nuxt, first you have to install and configure the `@vue-storefront/nuxt` module. - -1. In the root of your Storefront project run: - -```bash [Nuxt] -# Using yarn -yarn add --dev @vue-storefront/nuxt - -# Using pnpm -pnpm add -D @vue-storefront/nuxt - -# Using npm -npm install --save-dev @vue-storefront/nuxt -``` - -2. Add `@vue-storefront/nuxt` to the `modules` section of `nuxt.config.ts` - -```ts [nuxt.config.ts] -export default defineNuxtConfig({ - modules: ["@vue-storefront/nuxt"], -}); -``` - -3. Configure the module - -To configure the module, use `vsf` key in the Nuxt configuration object and provide necessary information such as the Middleware instance address: - -```ts [nuxt.config.ts] -export default defineNuxtConfig({ - modules: ["@vue-storefront/nuxt"], - vsf: { - middleware: { - apiUrl: "http://localhost:4000", - }, - }, -}); -``` - -## Initializing the SDK - -To use SDK in our application, we need to initialize it first. To do so, follow these steps: - -Create SDK Config file - `sdk.config.ts` in root directory of your project. - -::info -For Nuxt framework it's necessary to name the file `sdk.config.ts` and keep it in the root of your project. -:: - -You should import all other SDK configuration components. See the example below illustrating the SDK configuration with SAP Commerce Cloud and Contentful modules. - -```ts [sdk.config.ts] -import { contentfulModule } from "@vsf-enterprise/contentful-sdk"; -import { UnifiedEndpoints } from "storefront-middleware/types"; - -export default defineSdkConfig( - ({ buildModule, config, middlewareModule getRequestHeaders }) => ({ - commerce: buildModule(middlewareModule, { - apiUrl: config.middlewareUrl + "/commerce", // SAP Commerce Cloud integration is available at /commerce endpoint - defaultRequestConfig: { - headers: getRequestHeaders(), - }, - }), - cms: buildModule(contentfulModule, { - apiUrl: config.middlewareUrl + "/cms", - }), - }) -); -``` - -Let's break down the code above: - -The `defineSdkConfig` function is used for initializing the SDK. The parameter for calling this function should be an anonymous function that receives an injected context from the module, containing: - -- the `buildModule` function, -- the configuration object that contains data useful in module configuration such as: middleware URL (`middlewareUrl`), or cache busting identifier (`cdnCacheBustingId`) -- the `middlewareModule` - an SDK module that ensures communication with the Server Middleware. It takes the `UnifiedEndpoints` type as a generic parameter. The `UnifiedEndpoints` type is a type that represents the endpoints of the Server Middleware, -- a function for retrieving request header, including cookie header (`getRequestHeaders`). - -## Usage - -Once you have initialized the SDK, you can start using it. Here's an example of how you can use the SAP Commerce Cloud SDK module in your application: - -```vue - - - -``` - -Code above is just an example of how you can use the SDK in your application. For more information about the available methods, please refer to the respective [Integration's documentation](/integrations). - -That's it! You can now use VueStorefront SDK Module in your Nuxt app ✨ - -#tab-3 - -## Installation - -To install the SDK Core, run the following command: - -::code-group - -```bash [npm] -# Using npm -npm install @vue-storefront/sdk - -# Using yarn -yarn add @vue-storefront/sdk - -# Using pnpm -pnpm install @vue-storefront/sdk -``` - -:: - -## Initializing the SDK - -Next, you have to initialize the SDK, along with any integrations' SDK modules in your frontend project. To do so, follow these steps: - -1. Create SDK Config file - `sdk.config.ts` in root directory of your project. - -::info -It is not necessary to name the file `sdk.config.ts` specifically or to keep it in the root of your project, but it is recommended to keep it consistent with the rest of the Alokai project. -:: - -2. Create the SDK configuration by importing the `initSDK` function from the SDK Core and the modules you want to use. - -::tip -The examples below use the SAP Commerce Cloud and Contentful SDK modules. However, the same principles apply to all modules. -:: - -When it comes to managing multiple SDK modules, there are two options for this: - -1. **Individual exports (recommended)** - initialize each integration as a separate SDK instance, allowing for better code-splitting -2. **Single Instance** - combine multiple modules in one SDK instance - -### Individual Exports - -```ts [sdk.config.ts] -import { initSDK, buildModule, middlewareModule } from "@vue-storefront/sdk"; -import { contentfulModule } from "@vsf-enterprise/contentful-sdk"; -import { UnifiedEndpoints } from "storefront-middleware/types"; - -const { commerce } = initSDK({ - commerce: buildModule(middlewareModule, { - apiUrl: "http://localhost:8181/commerce", - }), -}); - -const { cms } = initSDK({ - cms: buildModule(contentfulModule, { - apiUrl: "http://localhost:8181/cms", - }), -}); - -export { commerce, cms }; -``` - -### Single Instance - -```ts [sdk.config.ts] -import { initSDK, buildModule, middlewareModule } from "@vue-storefront/sdk"; -import { contentfulModule } from "@vsf-enterprise/contentful-sdk"; -import { UnifiedEndpoints } from "storefront-middleware/types"; - -const sdkConfig = { - commerce: buildModule(middlewareModule, { - apiUrl: "http://localhost:8181/commerce", - }), - cms: buildModule(contentfulModule, { - apiUrl: "http://localhost:8181/cms", - }), -}; - -export const sdk = initSDK(sdkConfig); -``` - -The SDK Core exposes two methods to help with this, `buildModules`, which takes in SDK modules and uses them to extend the SDK Core, and `initSDK`, which takes multiple modules and converts them into a type-safe interface. - -::tip -#title -You can name the modules anything you want. - -#default -For example, you can rename `commerce` to `sapcc` and `cms` to `contentful`. `initSDK` will return an object with the same keys as the one passed to it. -:: - -### Usage - -Once you have initialized the SDK, you can start using it. Here's an example of how you can use the SAP Commerce Cloud SDK module in your application: - -::code-group - -```ts[Individual Exports] -import { commerce } from "../sdk.config"; - -const { products } = await commerce.searchProduct(); -``` - -```ts[Single Instance] -import { sdk } from "../sdk.config"; - -const { products } = await sdk.commerce.searchProduct(); -``` - -:: - -Code above is just an example of how you can use the SDK in your application. For more information about the available methods, please refer to the respective [Integration's documentation](/integrations). - -That's it! You can now use VueStorefront SDK Module in any JavaScript app ✨ - -:: - -## Next Steps - -::grid{:columns="2"} -#section-1 -:card{to="/sdk/getting-started/state-management" title="State Management" description="Learn how to use built in State Manager" icon="grommet-icons:storage"} -#section-2 -:card{to="/sdk/advanced/extending-module" title="Extending the SDK" description="Learn how to customize, override, or extend any default functionality in the SDK" icon="ri:terminal-box-fill"} -#section-3 -:card{to="/sdk/advanced/middleware-module" title="The middlewareModule" description="Understand how to use the default SDK module" icon="fa6-solid:layer-group"} -#section-4 -:card{to="/sdk/advanced/custom-modules" title="Create a custom SDK module" description="Create your own custom SDK module" icon="fluent:puzzle-cube-piece-20-filled"} -#section-5 -:card{to="/integrations" title="View all Integrations" description="View our ready-to-use integrations for popular e-commerce services" icon="fluent:puzzle-cube-piece-20-filled"} - -:: diff --git a/docs/content/4.sdk/2.getting-started/2.state-management.md b/docs/content/4.sdk/2.getting-started/2.state-management.md deleted file mode 100644 index 6146d5a03b..0000000000 --- a/docs/content/4.sdk/2.getting-started/2.state-management.md +++ /dev/null @@ -1,185 +0,0 @@ -# State Management - -We offer ready-to-use tools for handling global state management tailored for both Next.js and Nuxt3 frameworks through our dedicated packages: `@vue-storefront/next` and `@vue-storefront/nuxt`. - -For Next.js, we utilize [Zustand](https://zustand.docs.pmnd.rs/), a small, fast, and scalable state-management solution. For Nuxt3, we leverage [Pinia](https://pinia.vuejs.org/), a state management library that is intuitive and integrates seamlessly with Vue 3. These tools are designed to simplify state management in your applications, providing robust and efficient solutions out of the box. - -Our state management solutions store core data such as: -- customer -- cart -- currently selected currency -- available currencies -- currently selected locale -- available locales - -They also provide methods for reading and updating this data, making it easy to manage and access global state across your application. - -::tabs{:titles='["Next.js", "Nuxt"]' class="mt-8"} - -#tab-1 - -## Installation - -To use the State Manager within Next.js, you need to have the `@vue-storefront/next` package installed. This step is already done if you have followed the [getting started](/sdk/getting-started). If not, you'll find installation instructions there. - -## Usage - -To use the state management, you need to extend the `alokai-context.tsx` file with the state management part. -All of the hooks that are returned from the `createAlokaiContext` function are straightforward to use. They follow the React's `useState` pattern, so you can read and write to the state like you would with the `useState`. - -```ts -// sdk/alokai-context.tsx -'use client'; - -import { createAlokaiContext } from '@vue-storefront/next/client'; -import type { SfContract } from 'storefront-middleware/types'; - -import type { Sdk } from './sdk.server'; - -export const { AlokaiProvider, useSdk } = createAlokaiContext(); // [!code --] -// [!code ++:11] -export const { - AlokaiProvider, - useSdk, - useSfCartState, - useSfCurrenciesState, - useSfCurrencyState, - useSfCustomerState, - useSfLocaleState, - useSfLocalesState, -} = createAlokaiContext(); -``` - -The `SfContract` interface is used to define the contract between the SDK and the state management. It contains the types for: -- cart -- customer -- currency -- locale - -This is needed to ensure that the state management is aware of the types that you have within the middleware, as those types can be changed within the middleware. - -## Initial data - -There is also an option to pass initial data to the `AlokaiProvider`. This can be useful when you want to set the initial state of the application. You can pass the initial currencies, currency, locale, and locales to the `AlokaiProvider`. To do this, you need to pass the `initialData` prop to the `AlokaiProvider` component. - -```tsx -// components/providers.tsx - -"use client"; - -import type { ReactNode } from "react"; -import type { CreateSdkOptions } from '@vue-storefront/next'; -import { SdkProvider } from "@/sdk"; -import { getSdkOptions } from "@/sdk/options"; -import { getSdkConfig } from "@/sdk/config"; - -export function Providers({ children, sdkOptions }: { children: ReactNode, sdkOptions: CreateSdkOptions }) { - const { getSdk } = createSdk( - sdkOptions, - getSdkConfig() - ); - return ( - // [!code --] - // [!code ++:10] - - {children} - - ) -} -``` - -Note that the `Providers` component is a client component. If you want to fetch some data on the server side and pass it to the client component you can fetch the data in the server component (for Alokai Storefront it will be in the `app/[locale]/layout.tsx` file) and pass it to the client component through props. - - -## Usage - -The state is being updated on the Storefront side. State handling is already provided with the App Router based Alokai Storefront. You can use the state management in your components or hooks and modify the state as needed. -Here is an example of how you can use the state management in your components: - -```tsx -import { useQuery } from "@tanstack/react-query"; -import { - useSdk, - useSfCartState, - useSfCustomerState, - useSfCurrencyState, - useSfLocaleState, -} from "@/sdk/alokai-context"; - -function Component() { - const sdk = useSdk(); - const [cart, setCart] = useSfCartState(); - const [customer] = useSfCustomerState(); - const [currency] = useSfCurrencyState(); - const [locale] = useSfLocaleState(); - - const result = useQuery({ - queryFn: () => sdk.unified.getCart(), - queryKey: ["cart", "main"], - }); - // updating the cart state - useEffect(() => { - setCart(result.data); - }, [result.data]); - - return ( -
-

Cart total: {cart.total}

-

- Customer name: {customer.firstName} {customer.lastName} -

-

Currency: {currency}

-

Locale: {locale}

-
- ); -} -``` - -The same approach can be used in hooks or any other components. - -#tab-2 - -## Installation - -To use the State Manager within Nuxt, you need to have the `@vue-storefront/nuxt` package installed. This step is already done if you have followed the [getting started](/sdk/getting-started). If not, you'll find installation instructions there. - -## Usage - -To use it you don't need to do anything special. Just use the auto-imported `useSfState` composable in your components or composables. You can use parts of the state as refs so you can read and write to them easily. As mentioned before, the state is based on Pinia. To read more on how to use it, please refer to the [official documentation](https://pinia.vuejs.org/). - -Example usage of state management: - -```vue - - - -``` - -The same approach can be used in composables or any other components. - -:: diff --git a/docs/content/4.sdk/2.getting-started/3.middleware-module.md b/docs/content/4.sdk/2.getting-started/3.middleware-module.md deleted file mode 100644 index f25b9bcf99..0000000000 --- a/docs/content/4.sdk/2.getting-started/3.middleware-module.md +++ /dev/null @@ -1,512 +0,0 @@ -# The `middlewareModule` - -## Introduction - -The `middlewareModule` is an SDK module that ensures communication with the [Server Middleware](/middleware). - -## Setup - -Depending on which framework you are using, you can get the `middlewareModule` in different ways. However, the setup is always the same. - -In Next, `middlewareModule` is available in the `createSdk` function. - -```ts [Next] -// sdk/sdk.config.ts -import { CreateSdkOptions, createSdk } from "@vue-storefront/next"; -import { UnifiedEndpoints } from "storefront-middleware/types"; - -const options: CreateSdkOptions = { - middleware: { - apiUrl: "http://localhost:4000", - }, -}; - -export const { getSdk } = createSdk( - options, - ({ buildModule, config, middlewareModule, getRequestHeaders }) => ({ - commerce: buildModule(middlewareModule, { - apiUrl: config.middlewareUrl + "/commerce", - defaultRequestConfig: { - headers: getRequestHeaders(), - }, - }), - }) -); -``` - -In Nuxt, `middlewareModule` is available in the `defineSdkConfig` function. - -```ts [Nuxt] -// sdk.config.ts -import { UnifiedEndpoints } from "storefront-middleware/types"; - -export default defineSdkConfig( - ({ buildModule, config, middlewareModule, getRequestHeaders }) => ({ - commerce: buildModule(middlewareModule, { - apiUrl: config.middlewareUrl + "/commerce", // SAP Commerce Cloud integration is available at /commerce endpoint - defaultRequestConfig: { - headers: getRequestHeaders(), - }, - }) - }) -); -``` - -You can also import it directly from the `@vue-storefront/sdk` package. - -```ts [Other] -import { initSDK, buildModule, middlewareModule } from "@vue-storefront/sdk"; -import { UnifiedEndpoints } from "storefront-middleware/types"; - -export const sdk = initSDK({ - commerce: buildModule(middlewareModule, { - apiUrl: "http://localhost:8181/commerce", - }), -}); -``` - -## Configuration - -### Type definition - -As the `middlewareModule` is used to communicate with the Alokai Middleware and it's not limited to a specific backend, it requires a type definition of the endpoints. - -The type definition should be provided as a generic type to the `middlewareModule` function. - -```ts -type Endpoints = { - getProduct: ({ - id: string, - }) => Promise<{ id: string; title: string; description: string }>; -}; - -const sdk = initSDK({ - commerce: buildModule(middlewareModule, { - apiUrl: "http://localhost:8181/commerce", - }), -}); - -const product = await sdk.commerce.getProduct({ id: "123" }); -``` - -In Alokai Storefront, you can find the `UnifiedEndpoints` type in `storefront-middleware/types.ts` file. It's a type definition for the endpoints used in the middleware. - -::: tip Nuxt and Next examples -We're using `initSDK` approach in this examples to make it more universal. However, you can use `createSdk` and `defineSdkConfig` functions in Next and Nuxt as well. -::: - -```ts -import { UnifiedEndpoints } from "storefront-middleware/types"; - -export const sdk = initSDK({ - commerce: buildModule(middlewareModule, { - apiUrl: "http://localhost:8181/commerce", - }), -}); - -const product = await sdk.commerce.getProduct({ id: "123" }); -``` - -Also, you can import the `Endpoints` type from integration packages. - -```ts -import { Endpoints } from "@vsf-enterprise/sapcc-api"; - -export const sdk = initSDK({ - commerce: buildModule(middlewareModule, { - apiUrl: "http://localhost:8181/commerce", - }), -}); -``` - -### Options - -The `middlewareModule` accepts the following options: - -- `apiUrl` - the URL of the middleware server, -- `ssrApiUrl` - (Optional) the URL of the middleware server during SSR, -- `defaultRequestConfig` - (Optional) default request config for each request, -- `httpClient` - (Optional) a custom HTTP client, -- `errorHandler` - (Optional) a custom error handler for HTTP requests. -- `logger` - (Optional) a flag to enable logging of the requests and responses. You can also pass a custom logger. - -Example configuration: - -```ts -import { initSDK, buildModule, middlewareModule } from "@vue-storefront/sdk"; -import { UnifiedEndpoints } from "storefront-middleware/types"; - -export const sdk = initSDK({ - commerce: buildModule(middlewareModule, { - apiUrl: "/api/commerce", - ssrApiUrl: "http://localhost:8181/commerce", - defaultRequestConfig: { - headers: { - "X-Api-Key": "123", - }, - }, - httpClient: async (url, params, config) => { - // Custom HTTP client - }, - errorHandler: ({ error, methodName, url, params, config, httpClient }) => { - // Custom error handler - }, - logger: { - request: (url, config) => { - // custom request logger - }, - response: (response) => { - // custom response logger - }, - } - }), -}); -``` - -Once you have added the `middlewareModule` to your SDK, you can use it to make requests to the Alokai Middleware. - -## Usage - -Once you have added the `middlewareModule` to your SDK, you can use it to make requests to the Server Middleware. - -```ts -const product = await sdk.commerce.getProduct({ id: "123" }); -``` - -Additionally, each method of this module allows you to pass a custom request configuration. To do it, you need to import `prepareConfig` helper from `@vue-storefront/sdk` package. - -```ts -import { prepareConfig } from "@vue-storefront/sdk"; - -const product = await sdk.commerce.getProduct( - { id: "123" }, - prepareConfig({ - method: "GET", - headers: { - "X-Custom-Header": "123", - }, - }) -); -``` - -## Examples - -### Send a `GET` request - -By default, each request is a `POST` request. You can change it by passing a custom request configuration. - -```ts -const product = await sdk.commerce.getProduct( - { id: "123" }, - prepareConfig({ - method: "GET", - }) -); -``` - -### Use a `GET` method by default - -You can use a `GET` method by default by passing it in the `defaultRequestConfig` option of the `middlewareModule` function. - -```ts -export const sdk = initSDK({ - commerce: buildModule(middlewareModule, { - apiUrl: "http://localhost:8181/commerce", - defaultRequestConfig: { - method: "GET", - }, - }), -}); -``` - -### Add a header to each request - -You can add a header to each request by passing it in the `defaultRequestConfig` option of the `middlewareModule` function. - -```ts -export const sdk = initSDK({ - commerce: buildModule(middlewareModule, { - apiUrl: "http://localhost:8181/commerce", - defaultRequestConfig: { - headers: { - "X-Api-Key": "123", - }, - }, - }), -}); -``` - -### Add a header to single request - -You can add a header to a single request by passing it in the request configuration. - -```ts -const product = await sdk.commerce.getProduct( - { id: "123" }, - prepareConfig({ - headers: { - "X-Custom-Header": "123", - }, - }) -); -``` - -### Log requests and responses - -You can enable logging of the requests and responses by setting the `logger` option to `true` in the `middlewareModule` function. - -```ts -export const sdk = initSDK({ - commerce: buildModule(middlewareModule, { - apiUrl: "http://localhost:8181/commerce", - logger: true, - }), -}); -``` - -You can also enable logging of the requests and responses in all middleware modules by setting the environment variable `ALOKAI_SDK_DEBUG` to `true`. If `logger` is set to `false`, the environment variable will be ignored. - -If you want to override the default logger, you can pass a custom logger to the `logger` option. - -```ts -export const sdk = initSDK({ - commerce: buildModule(middlewareModule, { - apiUrl: "http://localhost:8181/commerce", - logger: { - request: (url, config) => { - console.log(`Request: ${url}`); - }, - response: (response) => { - console.log(`Response: ${response}`); - }, - }, - }), -}); -``` - - -### Replace the default HTTP client with `axios` - -By default, the SDK uses the `fetch` API. -You can replace the default HTTP client with `axios` by passing it in the `httpClient` option of the `middlewareModule` function. - -There are some requirements for the custom HTTP client. - -1. It must be an async function accepting the following parameters: - - `url` - the URL of the request, - - `params` - the parameters of the request, - - `config` - the request configuration, -2. It must include the `Access-Control-Allow-Credentials` response header (more info [here](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Credentials)), -3. It must throw an `SdkHttpError` if the request fails. - -```ts -import axios from "axios"; -import { SdkHttpError } from "@vue-storefront/sdk"; - -export const sdk = initSDK({ - commerce: buildModule(middlewareModule, { - apiUrl: "http://localhost:8181/commerce", - httpClient: async (url, params, config) => { - try { - const { data } = await axios(url, { - ...config, - data: params, - withCredentials: true, // Includes the `Access-Control-Allow-Credentials` response header - }); - - return data; - } catch (error: any) { - throw new SdkHttpError({ - statusCode: error.response?.status || 500, - message: error.response?.data?.message || error.message, - cause: error, - }); - } - }, - }), -}); -``` - -::: warning -It's important to include the `Access-Control-Allow-Credentials` response header in the custom HTTP client. Otherwise, the cookies won't be sent with the request. -::: - -### Add a custom error handler - -You can add a custom error handler by passing it in the `errorHandler` option of the `middlewareModule` function. - -```ts -import { SdkHttpError } from "@vue-storefront/sdk"; -import { refreshToken } from "./handlers/refreshToken"; // Custom implementation of the refresh token logic - -const options: Options = { - apiUrl: "https://api.example.com", - errorHandler: async ({ - error, - methodName, - url, - params, - config, - httpClient, - }) => { - if (error.status === 401 && methodName !== "login") { - // Refresh the token - await refreshToken(); - // Retry the request - return httpClient(url, params, config); - } - - throw error; - }, -}; -``` - -### Add cookies to the request during SSR - -Normally, the cookies are sent with the request during CSR. However, during SSR, you need to pass them manually. - -`@vue-storefront/next` and `@vue-storefront/nuxt` provide a `getRequestHeaders` helper that returns the cookies. - -To use it, you need to pass the `getRequestHeaders` function to the `defaultRequestConfig` option of the `middlewareModule` function. - -```ts [sdk/config.ts] -import { defineSdkConfig } from "@vue-storefront/next"; -import { UnifiedEndpoints } from "storefront-middleware/types"; - -export function getSdkConfig() { - return defineSdkConfig(({ buildModule, config, middlewareModule, getRequestHeaders }) => ({ - commerce: buildModule(middlewareModule, { - apiUrl: config.middlewareUrl + "/commerce", - defaultRequestConfig: { - headers: getRequestHeaders(), - }, - }), - })); -} -``` - -```ts [Nuxt] -// sdk.config.ts -import { defineSdkConfig } from "@vue-storefront/nuxt"; -import { UnifiedEndpoints } from "storefront-middleware/types"; - -export default defineSdkConfig( - ({ buildModule, config, middlewareModule, getRequestHeaders }) => ({ - commerce: buildModule(middlewareModule, { - apiUrl: config.middlewareUrl + "/commerce", - defaultRequestConfig: { - headers: getRequestHeaders(), - }, - }), - }) -); -``` - -While Nuxt ensures that cookies are sent with the request without any additional configuration, in Next, you need to pass the headers to `getSdk` function. - -```tsx [App Router] -import { headers } from "next/headers"; -import { getSdk } from "@/sdk"; - -export default async function SsrPage() { - const sdk = getSdk({ - getRequestHeaders: () => headers(), - }); - const product = await sdk.commerce.getProduct({ id: "123" }); - - return ( - // ... - ); -} -``` - -```tsx [Pages Router] -import { GetServerSideProps } from "next"; -import { getSdk } from "@/sdk"; - -export default function SsrPage({ result }: any) { - return ( - // ... - ); -} - -export const getServerSideProps: GetServerSideProps = async ({ req }) => { - const sdk = getSdk({ - getRequestHeaders: () => req.headers, - }); - - return { - props: { - result: await sdk.commerce.getProduct({ id: "123" }), - }, - }; -}; -``` - -### Add cookies to the request during CSR - -Cookies are being sent with the request during Client-Side Rendering by default. - -However, you can always specify the headers manually by passing them to the `defaultRequestConfig` option of the `middlewareModule`... - -```ts -export const sdk = initSDK({ - commerce: buildModule(middlewareModule, { - apiUrl: "http://localhost:8181/commerce", - defaultRequestConfig: { - headers: { - Cookie: "name=value", - }, - }, - }), -}); -``` - -...or by passing them to the request configuration. - -```ts -import { prepareConfig } from "@vue-storefront/sdk"; - -const product = await sdk.commerce.getProduct( - { id: "123" }, - prepareConfig({ - headers: { - Cookie: "name=value", - }, - }) -); -``` - -### Use the `middlewareModule` with a custom integration - -You can use the `middlewareModule` with a custom integration by providing a type definition of the endpoints. - -This example assumes that you have a custom Api Client that has been implemented as described in the [Creating an API Client](/middleware/guides/api-client) guide. It also assumes that the integration has been added to the `middleware.config.ts` and it's available at the `/custom` endpoint. - -First, let's export the `Endpoints` type as `CustomEndpoints` from the custom integration package. -That way, you won't need to install the custom integration package on the frontend and you'll avoid naming conflicts. - -```ts [storefront-middleware/types.ts] -export { Endpoints as CustomEndpoints } from "custom-integration-api-client"; - -// ... -``` - -Then, let's initialize the SDK with the `middlewareModule` and the `CustomEndpoints` type. - -```ts -import { initSDK, buildModule, middlewareModule } from "@vue-storefront/sdk"; -import { CustomEndpoints } from "storefront-middleware/types"; - -export const sdk = initSDK({ - custom: buildModule(middlewareModule, { - apiUrl: "http://localhost:8181/custom", - }), -}); -``` - -Now, you can use the `custom` module to make requests to the custom integration endpoints. - -```ts -const result = await sdk.custom.someMethod({ id: "123" }); -``` diff --git a/docs/content/4.sdk/2.getting-started/4.logger.md b/docs/content/4.sdk/2.getting-started/4.logger.md deleted file mode 100644 index d6ba9b74fa..0000000000 --- a/docs/content/4.sdk/2.getting-started/4.logger.md +++ /dev/null @@ -1,142 +0,0 @@ -# Logger - -The logger provides a logging utility for Alokai Storefront projects. It allows you to log messages at various levels and ability to provide additional context. - -It is created to provide a unified way of logging messages across the project along with providing a structured data. - -## Installation - -If the logger is already included in the Alokai Storefront, you can skip this step. - -The logger is provided by the SDK and the framework specific packages. - -In order to install the logger, you need to update following packages to at least the following versions: - -- `@vue-storefront/sdk` to `3.3.0` -- `@vue-storefront/nuxt` to `6.2.0` -- `@vue-storefront/next` to `4.3.0` - -After updating the packages, you need to provide the logger to the storefront. - -::tabs{:titles='["Next.js", "Nuxt"]' class="mt-8"} - -#tab-1 - -Create a file `logger.ts` in the `sdk` directory and add the following content: - -```ts -// apps/storefront-unified-nextjs/sdk/logger.ts - -import { createLogger } from '@vue-storefront/next'; - -export const logger = createLogger(); - -``` - -#tab-2 - -You don't need to do anything. The logger is automatically provided by the `@vue-storefront/nuxt` package. It is available via auto-import and ready to use within the Nuxt storefront. -:: - -## Configuration - -The default configuration is already provided, but you can customize it by providing the following options: - -- `verbosity` - the minimum level of the message to be logged. The default value is `info`. Available values are: - - `emergency` - - `alert` - - `critical` - - `error` - - `warning` - - `notice` - - `info` - - `debug` -- `includeStackTrace` - a boolean value that determines if the stack trace should be included in the log message. The default value is `false`. - -To provide the configuration for the logger, you need to update the following file: - -::tabs{:titles='["Next.js", "Nuxt"]' class="mt-8"} - -#tab-1 - -Navigate to the `logger.ts` file in the `sdk` directory and add the configuration object to the `createLogger` function, e.g.: - -```ts -// apps/storefront-unified-nextjs/sdk/logger.ts - -import { createLogger } from '@vue-storefront/next'; - -export const logger = createLogger(); // [!code --] -export const logger = createLogger({ // [!code ++] - verbosity: 'debug', // [!code ++] - includeStackTrace: true, // [!code ++] -}); // [!code ++] -``` - -#tab-2 - -Navigate to the `nuxt.config.ts` file and add the configuration object to the `@vue-storefront/nuxt` module, e.g.: -```ts -// apps/storefront-unified-nuxt/nuxt.config.ts - -export default defineNuxtConfig({ - // ... - modules: [ - // ... - '@vue-storefront/nuxt', // [!code --] - ['@vue-storefront/nuxt', { // [!code ++] - logger: { // [!code ++] - verbosity: 'debug', // [!code ++] - includeStackTrace: true, // [!code ++] - } // [!code ++] - }], // [!code ++] - // ... - ], -}); - -``` -:: - -## Usage - -You can use the logger similarly as you would use the common `console` object: - -::tabs{:titles='["Next.js", "Nuxt"]' class="mt-8"} - -#tab-1 - -No matter if this is a client or server side code, you can import the logger and use it to log messages the same way, e.g.: -```tsx -import { logger } from "@/sdk/logger"; - -function SomeComponent() { - logger.info("Example server side log"); - - // ... -} -``` - - -#tab-2 - -```vue -// component - -``` - -- **[BREAKING]** [CHANGED] module configKey is changed from `vsf` to `alokai`. Also, the support for the `vsf` key in Runtime Envs has been changed to `alokai`. - -```diff - meta: { - name: "@vue-storefront/nuxt", -- configKey: "vsf", -+ configKey: "alokai", - compatibility: { - nuxt: "^3.0.0", - }, -``` - -```diff -nuxt.options.runtimeConfig.public.alokai = defu( -- nuxt.options.runtimeConfig.public?.vsf as any, -+ nuxt.options.runtimeConfig.public?.alokai as any, - options -); -``` - -### Patch Changes - -- Updated dependencies: - - @vue-storefront/sdk@3.2.0 - -## 4.1.1 - -### Patch Changes - -**[FIXED]**: Added getCurrencies unified endpoint to be fetch by HTTP GET. This change enable caching this endpoint on CDN. - -## 4.1.0 - -### Minor Changes - -**[ADDED]**: Using the `GIT_SHA` environment variable as secondary input for `cdnCacheBustingId` option. You can still override this value through `NUXT_PUBLIC_ALOKAI_MIDDLEWARE_CDN_CACHE_BUSTING_ID`. -**[ADDED]** Value of Busting ID for CDN Cache. You can access it via `config.cdnCacheBustingId`. -**[CHANGED]** Deprecated `middlewareUrl` in `defineSdkConfig` context. Use `config.middlewareUrl` instead. -**[CHANGED]** Deprecated `defaults` in `defineSdkConfig` context. Use `config.defaultMethodsRequestConfig` instead. -**[CHANGED]** Depreacted `vsf` key in RuntimeConfig. Use `alokai` instead. You should change you environment variables. Example: Change from `NUXT_PUBLIC_VSF_MIDDLEWARE_API_URL` to `NUXT_PUBLIC_ALOKAI_MIDDLEWARE_API_URL`. -**[CHANGED]** Internal naming changed from VSF to Alokai. For e.g. we inject the SDK into the `$alokai` key in Nuxt App instead of `$vsf` as in previous versions. - -## 4.0.1 - -### Patch Changes - -- **[CHANGED]** shared package wasn't being bundled with the release of the package - -## 4.0.0 - -### Major Changes - -- **[CHANGED]** Updated core sdk dependency to latest version -- **[ADDED]** Added .config parameter in createSdk callback - -### Patch Changes - -- Updated dependencies: - - @vue-storefront/sdk@3.1.0 - -## 3.1.1 - -### Patch Changes - -- **[FIXED]** Using the runtime config is now working properly. You can use `NUXT_PUBLIC_VSF_MIDDLEWARE_API_URL`, `NUXT_PUBLIC_VSF_MIDDLEWARE_SSR_API_URL` and `NUXT_PUBLIC_VSF_MULTISTORE_ENABLED` environments variables to define config in the runtime. - -## 3.1.0 - -- **[ADDED]** `middlewareModule` to `defineSdkConfig` params. - -```diff [sdk.config.ts] -- import { UnifiedApiExtension } from "storefront-middleware/types" -+ import { UnifiedEndpoints } from "storefront-middleware/types" - -export default defineSdkConfig( -- ({ buildModule, middlewareUrl, getRequestHeaders }) => ({ -- commerce: buildModule(unifiedModule, { -- apiUrl: `${middlewareUrl}/commerce`, -- requestOptions: { headers: getRequestHeaders }, -+ ({ buildModule, middlewareModule, middlewareUrl, getRequestHeaders }) => ({ -+ commerce: buildModule(middlewareModule, { -+ apiUrl: `${middlewareUrl}/commerce`, -+ defaultRequestConfig: { headers: getRequestHeaders() }, - }), - }) -); -``` - -- **[CHANGED]** deprecate `getCookieHeader`, use `getRequestHeaders` instead - -```diff [sdk.config.ts] -export default defineSdkConfig( -- ({ buildModule, middlewareModule, middlewareUrl, getCookieHeader }) => ({ -+ ({ buildModule, middlewareModule, middlewareUrl, getRequestHeaders }) => ({ - commerce: buildModule(middlewareModule, { - apiUrl: `${middlewareUrl}/commerce`, -- defaultRequestConfig: { headers: getCookieHeader() }, // Only cookie header is included. -+ defaultRequestConfig: { headers: getRequestHeaders() }, // All headers are included. - }), - }) -); -``` - -## 3.0.3 - -- **[CHANGED]** `@nuxt/kit` locked `3.7.4` version to `@nuxt/kit@^3.7.4` - -## 3.0.2 - -- **[FIXED]** Multi-store URL calculation, now working correctly in the browser. - -## 3.0.1 - -- **[CHANGED]** Set `@vue-storefront/sdk` as a dependency instead of a peer dependency - -## 3.0.0 - -- **[BREAKING]** Rewritten from scratch. Now the package exports a Nuxt module which allows to initialize the Vue Storefront SDK. diff --git a/docs/content/4.sdk/6.migration-guide.md b/docs/content/4.sdk/6.migration-guide.md deleted file mode 100644 index 7e7fd97ece..0000000000 --- a/docs/content/4.sdk/6.migration-guide.md +++ /dev/null @@ -1,779 +0,0 @@ -# Migration to Runtime ENVs & Docker cached building process - -## Reasons & Benefits - -Version Sprint 22 of the Storefront contains frontend applications that using environment variables for configuration purposes. The way how they are used makes that values of those variables are hard-coded into the code of the frontend applications. - -During the Middleware application is fully configurable using the environment variables via Alokai Console, the frontend apps require a few of modifications to change the value of environment variables. To reduce those differences, we introduced changes in our modules for Next & Nuxt storefronts, to allow use environment variables in runtime. - -This brings us benefits in simplicity of making changes into configuration of Storefront, remove the need of rebuild and redeploy after every change. - -At the same time, we introduce the caching Docker build process in our deployment actions. Both of these changes are interconnected with each other, that's why we present them in a single migration guide. - -## Next.js (Pages Router) - -1. Update `@vue-storefront/next` package to version 3.0.0 and install `next-runtime-env` as dependency - -```bash -cd apps/storefront-unified-nextjs -yarn add next-runtime-env@1.7.4 @vue-storefront/next@3.0.1 @vue-storefront/sdk@3.1.0 -``` - -2. Update Next config, placed in `apps/storefront-unified-nextjs/next.config.js` - -```js -// Imports on the begining of the file -const { configureRuntimeEnv } = require('next-runtime-env/build/configure'); // [!code ++] -const { env } = require('next-runtime-env'); // [!code ++] - -configureRuntimeEnv(); // [!code ++] - -// ... rest of the config -const withPwa = require('next-pwa')({ -// ... -}); - -/** @type {import('next').NextConfig} */ -const nextConfig = { - reactStrictMode: true, - // ... - images: env('NEXT_PUBLIC_IMAGE_LOADER_FETCH_URL') ? cloudinaryConfig : defaultImageConfig, // [!code ++] - // ... - // [!code ++:14] - async headers() { - return [ - { - source: '/__ENV.js', - headers: [ - { - key: 'Cache-Control', - value: 'public, max-age=0, s-max-age=15', - }, - ], - }, - ]; - }, -}; -``` - -3. Update the environment variables - -For local development, update the `.env` file: - -```bash -# apps/storefront-unified-nextjs/.env -NEXT_PUBLIC_API_BASE_URL="http://localhost:4000" # [!code --] -NEXT_PUBLIC_ALOKAI_MIDDLEWARE_API_URL="http://localhost:4000" # [!code ++] -NEXT_PUBLIC_MULTISTORE_ENABLED=false # [!code --] -NEXT_PUBLIC_ALOKAI_MULTISTORE_ENABLED=false # [!code ++] -# For CDN cache busting, you can use a hash or a version number. By default, deployed version -# uses the git commit hash. For local development, you can use a random string or skip it. -NEXT_PUBLIC_ALOKAI_MIDDLEWARE_CDN_CACHE_BUSTING_ID="example-hash" # [!code ++] -# Default Image Loader fetch url. -# For Cloudinary check https://cloudinary.com/documentation/fetch_remote_images#fetch_and_deliver_remote_files -NEXT_PUBLIC_IMAGE_LOADER_FETCH_URL=https://res.cloudinary.com/dcqchkrzw/image/fetch/ -# Optional. Will be used when image url will not start with http. -# For Cloudinary check https://cloudinary.com/documentation/migration#lazy_migration_with_auto_upload -NEXT_PUBLIC_IMAGE_LOADER_UPLOAD_URL=https://res.cloudinary.com/vsf-sap/image/upload/ -NEXT_DEFAULT_HTML_CACHE_CONTROL="public, max-age=0, s-maxage=15, must-revalidate" -``` - -You can manage environment variables for your deployed project in the Console. Go to the **Settings** -> **Environment variables** -> Section **Storefront Application**. Click on the "Add variable", and use the modal fill the name & value of each environment variable. Repeat for all the variables needed to run the app. - -4. Update `_document.tsx` in the `apps/storefront-unified-nextjs/pages/` - -```tsx -/* [!code ++:2] */ -/* eslint-disable @next/next/no-sync-scripts */ -import Document, { Html, Head, Main, NextScript } from 'next/document'; - -class MyDocument extends Document { - render() { - return ( - - - - - - - - - /* [!code ++:2] */ -