feature: add support for dynamoDB for storing sessions and some types cleanup (#12140)
This commit is contained in:
1 parent
fe48f825f8
commit
b890263725
13 files changed
+1792
-1053
No files matched your search
@@ -0,0 +1,7 @@
|
|||||||
|
---
|
||||||
|
"@medusajs/framework": patch
|
||||||
|
"@medusajs/types": patch
|
||||||
|
"@medusajs/utils": patch
|
||||||
|
---
|
||||||
|
|
||||||
|
Add support for dynamoDB for storing sessions and some types cleanup
|
||||||
@@ -54,6 +54,7 @@
|
|||||||
"test": "jest --runInBand --bail --forceExit -- src/**/__tests__/**/*.ts"
|
"test": "jest --runInBand --bail --forceExit -- src/**/__tests__/**/*.ts"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@aws-sdk/client-dynamodb": "^3.218.0",
|
||||||
"@medusajs/cli": "2.7.0",
|
"@medusajs/cli": "2.7.0",
|
||||||
"@mikro-orm/core": "6.4.3",
|
"@mikro-orm/core": "6.4.3",
|
||||||
"@mikro-orm/knex": "6.4.3",
|
"@mikro-orm/knex": "6.4.3",
|
||||||
@@ -64,6 +65,7 @@
|
|||||||
"@types/cors": "^2.8.17",
|
"@types/cors": "^2.8.17",
|
||||||
"@types/jsonwebtoken": "^8.5.9",
|
"@types/jsonwebtoken": "^8.5.9",
|
||||||
"awilix": "^8.0.1",
|
"awilix": "^8.0.1",
|
||||||
|
"connect-dynamodb": "^3.0.5",
|
||||||
"ioredis": "^5.4.1",
|
"ioredis": "^5.4.1",
|
||||||
"jest": "^29.7.0",
|
"jest": "^29.7.0",
|
||||||
"pg": "^8.13.0",
|
"pg": "^8.13.0",
|
||||||
@@ -98,6 +100,7 @@
|
|||||||
"zod": "3.22.4"
|
"zod": "3.22.4"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
|
"@aws-sdk/client-dynamodb": "^3.218.0",
|
||||||
"@medusajs/cli": "2.7.0",
|
"@medusajs/cli": "2.7.0",
|
||||||
"@mikro-orm/cli": "6.4.3",
|
"@mikro-orm/cli": "6.4.3",
|
||||||
"@mikro-orm/core": "6.4.3",
|
"@mikro-orm/core": "6.4.3",
|
||||||
@@ -105,14 +108,21 @@
|
|||||||
"@mikro-orm/migrations": "6.4.3",
|
"@mikro-orm/migrations": "6.4.3",
|
||||||
"@mikro-orm/postgresql": "6.4.3",
|
"@mikro-orm/postgresql": "6.4.3",
|
||||||
"awilix": "^8.0.1",
|
"awilix": "^8.0.1",
|
||||||
|
"connect-dynamodb": "^3.0.5",
|
||||||
"ioredis": "^5.4.1",
|
"ioredis": "^5.4.1",
|
||||||
"pg": "^8.13.0",
|
"pg": "^8.13.0",
|
||||||
"vite": "^5.4.14"
|
"vite": "^5.4.14"
|
||||||
},
|
},
|
||||||
"peerDependenciesMeta": {
|
"peerDependenciesMeta": {
|
||||||
|
"@aws-sdk/client-dynamodb": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
"@mikro-orm/cli": {
|
"@mikro-orm/cli": {
|
||||||
"optional": true
|
"optional": true
|
||||||
},
|
},
|
||||||
|
"connect-dynamodb": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
"ioredis": {
|
"ioredis": {
|
||||||
"optional": true
|
"optional": true
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -164,7 +164,9 @@ export class ConfigManager {
|
|||||||
|
|
||||||
this.#config = {
|
this.#config = {
|
||||||
projectConfig: normalizedProjectConfig,
|
projectConfig: normalizedProjectConfig,
|
||||||
admin: projectConfig.admin ?? {},
|
admin: projectConfig.admin ?? {
|
||||||
|
path: "/app",
|
||||||
|
},
|
||||||
modules: projectConfig.modules ?? {},
|
modules: projectConfig.modules ?? {},
|
||||||
featureFlags: projectConfig.featureFlags ?? {},
|
featureFlags: projectConfig.featureFlags ?? {},
|
||||||
plugins: projectConfig.plugins ?? [],
|
plugins: projectConfig.plugins ?? [],
|
||||||
|
|||||||
@@ -1,978 +1,8 @@
|
|||||||
import {
|
export {
|
||||||
ExternalModuleDeclaration,
|
AdminOptions,
|
||||||
InternalModuleDeclaration,
|
SessionOptions,
|
||||||
|
ProjectConfigOptions,
|
||||||
|
HttpCompressionOptions,
|
||||||
|
ConfigModule,
|
||||||
|
PluginDetails,
|
||||||
} from "@medusajs/types"
|
} from "@medusajs/types"
|
||||||
|
|
||||||
import type { RedisOptions } from "ioredis"
|
|
||||||
import { ConnectionOptions } from "node:tls"
|
|
||||||
// @ts-expect-error
|
|
||||||
import type { InlineConfig } from "vite"
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @interface
|
|
||||||
*
|
|
||||||
* Admin dashboard configurations.
|
|
||||||
*/
|
|
||||||
export type AdminOptions = {
|
|
||||||
/**
|
|
||||||
* Whether to disable the admin dashboard. If set to `true`, the admin dashboard is disabled,
|
|
||||||
* in both development and production environments. The default value is `false`.
|
|
||||||
*
|
|
||||||
* @example
|
|
||||||
* ```ts title="medusa-config.ts"
|
|
||||||
* module.exports = defineConfig({
|
|
||||||
* admin: {
|
|
||||||
* disable: process.env.ADMIN_DISABLED === "true" ||
|
|
||||||
* false
|
|
||||||
* },
|
|
||||||
* // ...
|
|
||||||
* })
|
|
||||||
* ```
|
|
||||||
*/
|
|
||||||
disable?: boolean
|
|
||||||
/**
|
|
||||||
* The path to the admin dashboard. The default value is `/app`.
|
|
||||||
*
|
|
||||||
* The value cannot be one of the reserved paths:
|
|
||||||
* - `/admin`
|
|
||||||
* - `/store`
|
|
||||||
* - `/auth`
|
|
||||||
* - `/`
|
|
||||||
*
|
|
||||||
* :::note
|
|
||||||
*
|
|
||||||
* When using Docker, make sure that the root path of the Docker image doesn't path the admin's `path`. For example, if the Docker image's root path is `/app`, change
|
|
||||||
* the value of the `path` configuration, as it's `/app` by default.
|
|
||||||
*
|
|
||||||
* :::
|
|
||||||
*
|
|
||||||
* @example
|
|
||||||
* ```ts title="medusa-config.ts"
|
|
||||||
* module.exports = defineConfig({
|
|
||||||
* admin: {
|
|
||||||
* path: process.env.ADMIN_PATH || `/app`,
|
|
||||||
* },
|
|
||||||
* // ...
|
|
||||||
* })
|
|
||||||
* ```
|
|
||||||
*/
|
|
||||||
path?: `/${string}`
|
|
||||||
/**
|
|
||||||
* The directory where the admin build is outputted when you run the `build` command.
|
|
||||||
* The default value is `./build`.
|
|
||||||
*
|
|
||||||
* @example
|
|
||||||
* ```ts title="medusa-config.ts"
|
|
||||||
* module.exports = defineConfig({
|
|
||||||
* admin: {
|
|
||||||
* outDir: process.env.ADMIN_BUILD_DIR || `./build`,
|
|
||||||
* },
|
|
||||||
* // ...
|
|
||||||
* })
|
|
||||||
* ```
|
|
||||||
*/
|
|
||||||
outDir?: string
|
|
||||||
/**
|
|
||||||
* The URL of your Medusa application. Defaults to the browser origin. This is useful to set when running the admin on a separate domain.
|
|
||||||
*
|
|
||||||
* @example
|
|
||||||
* ```ts title="medusa-config.ts"
|
|
||||||
* module.exports = defineConfig({
|
|
||||||
* admin: {
|
|
||||||
* backendUrl: process.env.MEDUSA_BACKEND_URL ||
|
|
||||||
* "http://localhost:9000"
|
|
||||||
* },
|
|
||||||
* // ...
|
|
||||||
* })
|
|
||||||
* ```
|
|
||||||
*/
|
|
||||||
backendUrl?: string
|
|
||||||
/**
|
|
||||||
* The URL of your Medusa storefront application. This URL is used as a prefix to some
|
|
||||||
* links in the admin that require performing actions in the storefront. For example,
|
|
||||||
* this URL is used as a prefix to shareable payment links for orders with
|
|
||||||
* outstanding amounts.
|
|
||||||
*
|
|
||||||
* @example
|
|
||||||
* ```js title="medusa-config.js"
|
|
||||||
* module.exports = defineConfig({
|
|
||||||
* admin: {
|
|
||||||
* storefrontUrl: process.env.MEDUSA_STOREFRONT_URL ||
|
|
||||||
* "http://localhost:8000"
|
|
||||||
* },
|
|
||||||
* // ...
|
|
||||||
* })
|
|
||||||
* ```
|
|
||||||
*/
|
|
||||||
storefrontUrl?: string
|
|
||||||
/**
|
|
||||||
* Configure the Vite configuration for the admin dashboard. This function receives the default Vite configuration
|
|
||||||
* and returns the modified configuration. The default value is `undefined`.
|
|
||||||
*
|
|
||||||
* Learn about configurations you can pass to Vite in [Vite's documentation](https://vite.dev/config/).
|
|
||||||
*
|
|
||||||
* @example
|
|
||||||
* For example, if you're using a third-party library that isn't ESM-compatible, add it to Vite's `optimizeDeps` configuration:
|
|
||||||
*
|
|
||||||
* ```ts title="medusa-config.ts"
|
|
||||||
* module.exports = defineConfig({
|
|
||||||
* admin: {
|
|
||||||
* vite: () => {
|
|
||||||
* return {
|
|
||||||
* optimizeDeps: {
|
|
||||||
* include: ["qs"],
|
|
||||||
* },
|
|
||||||
* };
|
|
||||||
* },
|
|
||||||
* },
|
|
||||||
* // ...
|
|
||||||
* })
|
|
||||||
* ```
|
|
||||||
*/
|
|
||||||
vite?: (config: InlineConfig) => InlineConfig
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @interface
|
|
||||||
*
|
|
||||||
* Options to pass to `express-session`.
|
|
||||||
*/
|
|
||||||
type SessionOptions = {
|
|
||||||
/**
|
|
||||||
* The name of the session ID cookie to set in the response (and read from in the request). The default value is `connect.sid`.
|
|
||||||
* Refer to [express-session’s documentation](https://www.npmjs.com/package/express-session#name) for more details.
|
|
||||||
*/
|
|
||||||
name?: string
|
|
||||||
/**
|
|
||||||
* Whether the session should be saved back to the session store, even if the session was never modified during the request. The default value is `true`.
|
|
||||||
* Refer to [express-session’s documentation](https://www.npmjs.com/package/express-session#resave) for more details.
|
|
||||||
*/
|
|
||||||
resave?: boolean
|
|
||||||
/**
|
|
||||||
* Whether the session identifier cookie should be force-set on every response. The default value is `false`.
|
|
||||||
* Refer to [express-session’s documentation](https://www.npmjs.com/package/express-session#rolling) for more details.
|
|
||||||
*/
|
|
||||||
rolling?: boolean
|
|
||||||
/**
|
|
||||||
* Whether a session that is "uninitialized" is forced to be saved to the store. The default value is `true`.
|
|
||||||
* Refer to [express-session’s documentation](https://www.npmjs.com/package/express-session#saveUninitialized) for more details.
|
|
||||||
*/
|
|
||||||
saveUninitialized?: boolean
|
|
||||||
/**
|
|
||||||
* The secret to sign the session ID cookie. By default, the value of `http.cookieSecret` is used.
|
|
||||||
* Refer to [express-session’s documentation](https://www.npmjs.com/package/express-session#secret) for details.
|
|
||||||
*/
|
|
||||||
secret?: string
|
|
||||||
/**
|
|
||||||
* Used when calculating the `Expires` `Set-Cookie` attribute of cookies. By default, its value is `10 * 60 * 60 * 1000`.
|
|
||||||
* Refer to [express-session’s documentation](https://www.npmjs.com/package/express-session#cookiemaxage) for details.
|
|
||||||
*/
|
|
||||||
ttl?: number
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @interface
|
|
||||||
*
|
|
||||||
* HTTP compression configurations.
|
|
||||||
*/
|
|
||||||
export type HttpCompressionOptions = {
|
|
||||||
/**
|
|
||||||
* Whether HTTP compression is enabled. By default, it's `false`.
|
|
||||||
*/
|
|
||||||
enabled?: boolean
|
|
||||||
/**
|
|
||||||
* The level of zlib compression to apply to responses. A higher level will result in better compression but will take longer to complete.
|
|
||||||
* A lower level will result in less compression but will be much faster. The default value is `6`.
|
|
||||||
*/
|
|
||||||
level?: number
|
|
||||||
/**
|
|
||||||
* How much memory should be allocated to the internal compression state. It's an integer in the range of 1 (minimum level) and 9 (maximum level).
|
|
||||||
* The default value is `8`.
|
|
||||||
*/
|
|
||||||
memLevel?: number
|
|
||||||
/**
|
|
||||||
* The minimum response body size that compression is applied on. Its value can be the number of bytes or any string accepted by the
|
|
||||||
* [bytes](https://www.npmjs.com/package/bytes) module. The default value is `1024`.
|
|
||||||
*/
|
|
||||||
threshold?: number | string
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @interface
|
|
||||||
*
|
|
||||||
* Essential configurations related to the Medusa application, such as database and CORS configurations.
|
|
||||||
*/
|
|
||||||
export type ProjectConfigOptions = {
|
|
||||||
/**
|
|
||||||
* The name of the database to connect to. If the name is specified in `databaseUrl`, then you don't have to use this configuration.
|
|
||||||
*
|
|
||||||
* Make sure to create the PostgreSQL database before using it. You can check how to create a database in
|
|
||||||
* [PostgreSQL's documentation](https://www.postgresql.org/docs/current/sql-createdatabase.html).
|
|
||||||
*
|
|
||||||
* @example
|
|
||||||
* ```ts title="medusa-config.ts"
|
|
||||||
* module.exports = defineConfig({
|
|
||||||
* projectConfig: {
|
|
||||||
* databaseName: process.env.DATABASE_NAME ||
|
|
||||||
* "medusa-store",
|
|
||||||
* // ...
|
|
||||||
* },
|
|
||||||
* // ...
|
|
||||||
* })
|
|
||||||
* ```
|
|
||||||
*/
|
|
||||||
databaseName?: string
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The PostgreSQL connection URL of the database, which is of the following format:
|
|
||||||
*
|
|
||||||
* ```bash
|
|
||||||
* postgres://[user][:password]@[host][:port]/[dbname]
|
|
||||||
* ```
|
|
||||||
*
|
|
||||||
* Where:
|
|
||||||
*
|
|
||||||
* - `[user]`: (required) your PostgreSQL username. If not specified, the system's username is used by default. The database user that you use must have create privileges. If you're using the `postgres` superuser, then it should have these privileges by default. Otherwise, make sure to grant your user create privileges. You can learn how to do that in [PostgreSQL's documentation](https://www.postgresql.org/docs/current/ddl-priv.html).
|
|
||||||
* - `[:password]`: an optional password for the user. When provided, make sure to put `:` before the password.
|
|
||||||
* - `[host]`: (required) your PostgreSQL host. When run locally, it should be `localhost`.
|
|
||||||
* - `[:port]`: an optional port that the PostgreSQL server is listening on. By default, it's `5432`. When provided, make sure to put `:` before the port.
|
|
||||||
* - `[dbname]`: (required) the name of the database.
|
|
||||||
*
|
|
||||||
* You can learn more about the connection URL format in [PostgreSQL’s documentation](https://www.postgresql.org/docs/current/libpq-connect.html).
|
|
||||||
*
|
|
||||||
* @example
|
|
||||||
* For example, set the following database URL in your environment variables:
|
|
||||||
*
|
|
||||||
* ```bash
|
|
||||||
* DATABASE_URL=postgres://postgres@localhost/medusa-store
|
|
||||||
* ```
|
|
||||||
*
|
|
||||||
* Then, use the value in `medusa-config.ts`:
|
|
||||||
*
|
|
||||||
* ```ts title="medusa-config.ts"
|
|
||||||
* module.exports = defineConfig({
|
|
||||||
* projectConfig: {
|
|
||||||
* databaseUrl: process.env.DATABASE_URL,
|
|
||||||
* // ...
|
|
||||||
* },
|
|
||||||
* // ...
|
|
||||||
* })
|
|
||||||
* ```
|
|
||||||
*/
|
|
||||||
databaseUrl?: string
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The database schema to connect to. This is not required to provide if you’re using the default schema, which is `public`.
|
|
||||||
*
|
|
||||||
* ```ts title="medusa-config.ts"
|
|
||||||
* module.exports = defineConfig({
|
|
||||||
* projectConfig: {
|
|
||||||
* databaseSchema: process.env.DATABASE_SCHEMA ||
|
|
||||||
* "custom",
|
|
||||||
* // ...
|
|
||||||
* },
|
|
||||||
* // ...
|
|
||||||
* })
|
|
||||||
* ```
|
|
||||||
*/
|
|
||||||
databaseSchema?: string
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This configuration specifies whether database messages should be logged.
|
|
||||||
*
|
|
||||||
* @example
|
|
||||||
* ```ts title="medusa-config.ts"
|
|
||||||
* module.exports = defineConfig({
|
|
||||||
* projectConfig: {
|
|
||||||
* databaseLogging: false
|
|
||||||
* // ...
|
|
||||||
* },
|
|
||||||
* // ...
|
|
||||||
* })
|
|
||||||
* ```
|
|
||||||
*/
|
|
||||||
databaseLogging?: boolean
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This configuration is used to pass additional options to the database connection. You can pass any configuration. For example, pass the
|
|
||||||
* `ssl` property that enables support for TLS/SSL connections.
|
|
||||||
*
|
|
||||||
* This is useful for production databases, which can be supported by setting the `rejectUnauthorized` attribute of `ssl` object to `false`.
|
|
||||||
* During development, it’s recommended not to pass this option.
|
|
||||||
*
|
|
||||||
* :::note
|
|
||||||
*
|
|
||||||
* Make sure to add to the end of the database URL `?ssl_mode=disable` as well when disabling `rejectUnauthorized`.
|
|
||||||
*
|
|
||||||
* :::
|
|
||||||
*
|
|
||||||
* @example
|
|
||||||
* ```ts title="medusa-config.ts"
|
|
||||||
* module.exports = defineConfig({
|
|
||||||
* projectConfig: {
|
|
||||||
* databaseDriverOptions: process.env.NODE_ENV !== "development" ?
|
|
||||||
* { connection: { ssl: { rejectUnauthorized: false } } } : {}
|
|
||||||
* // ...
|
|
||||||
* },
|
|
||||||
* // ...
|
|
||||||
* })
|
|
||||||
* ```
|
|
||||||
*/
|
|
||||||
databaseDriverOptions?: Record<string, any> & {
|
|
||||||
connection?: {
|
|
||||||
/**
|
|
||||||
* Configure support for TLS/SSL connection
|
|
||||||
*/
|
|
||||||
ssl?: boolean | ConnectionOptions
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This configuration specifies the connection URL to Redis to store the Medusa server's session.
|
|
||||||
*
|
|
||||||
* :::note
|
|
||||||
*
|
|
||||||
* You must first have Redis installed. You can refer to [Redis's installation guide](https://redis.io/docs/getting-started/installation/).
|
|
||||||
*
|
|
||||||
* :::
|
|
||||||
*
|
|
||||||
* The Redis connection URL has the following format:
|
|
||||||
*
|
|
||||||
* ```bash
|
|
||||||
* redis[s]://[[username][:password]@][host][:port][/db-number]
|
|
||||||
* ```
|
|
||||||
*
|
|
||||||
* For a local Redis installation, the connection URL should be `redis://localhost:6379` unless you’ve made any changes to the Redis configuration during installation.
|
|
||||||
*
|
|
||||||
* @example
|
|
||||||
* ```ts title="medusa-config.ts"
|
|
||||||
* module.exports = defineConfig({
|
|
||||||
* projectConfig: {
|
|
||||||
* redisUrl: process.env.REDIS_URL ||
|
|
||||||
* "redis://localhost:6379",
|
|
||||||
* // ...
|
|
||||||
* },
|
|
||||||
* // ...
|
|
||||||
* })
|
|
||||||
* ```
|
|
||||||
*/
|
|
||||||
redisUrl?: string
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This configuration defines a prefix on all keys stored in Redis for the Medusa server's session. The default value is `sess:`.
|
|
||||||
*
|
|
||||||
* If this configuration option is provided, it is prepended to `sess:`.
|
|
||||||
*
|
|
||||||
* @example
|
|
||||||
* ```ts title="medusa-config.ts"
|
|
||||||
* module.exports = defineConfig({
|
|
||||||
* projectConfig: {
|
|
||||||
* redisPrefix: process.env.REDIS_URL || "medusa:",
|
|
||||||
* // ...
|
|
||||||
* },
|
|
||||||
* // ...
|
|
||||||
* })
|
|
||||||
* ```
|
|
||||||
*/
|
|
||||||
redisPrefix?: string
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This configuration defines options to pass ioredis for the Redis connection used to store the Medusa server's session. Refer to [ioredis’s RedisOptions documentation](https://redis.github.io/ioredis/index.html#RedisOptions)
|
|
||||||
* for the list of available options.
|
|
||||||
*
|
|
||||||
* @example
|
|
||||||
* ```ts title="medusa-config.ts"
|
|
||||||
* module.exports = defineConfig({
|
|
||||||
* projectConfig: {
|
|
||||||
* redisOptions: {
|
|
||||||
* connectionName: process.env.REDIS_CONNECTION_NAME ||
|
|
||||||
* "medusa",
|
|
||||||
* }
|
|
||||||
* // ...
|
|
||||||
* },
|
|
||||||
* // ...
|
|
||||||
* })
|
|
||||||
* ```
|
|
||||||
*/
|
|
||||||
redisOptions?: RedisOptions
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This configuration defines additional options to pass to [express-session](https://www.npmjs.com/package/express-session), which is used to store the Medusa server's session.
|
|
||||||
*
|
|
||||||
* @example
|
|
||||||
* ```ts title="medusa-config.ts"
|
|
||||||
* module.exports = defineConfig({
|
|
||||||
* projectConfig: {
|
|
||||||
* sessionOptions: {
|
|
||||||
* name: process.env.SESSION_NAME || "custom",
|
|
||||||
* }
|
|
||||||
* // ...
|
|
||||||
* },
|
|
||||||
* // ...
|
|
||||||
* })
|
|
||||||
* ```
|
|
||||||
*/
|
|
||||||
sessionOptions?: SessionOptions
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Configure the number of staged jobs that are polled from the database. Default is `1000`.
|
|
||||||
*
|
|
||||||
* @example
|
|
||||||
* ```ts title="medusa-config.ts"
|
|
||||||
* module.exports = defineConfig({
|
|
||||||
* projectConfig: {
|
|
||||||
* jobsBatchSize: 100
|
|
||||||
* // ...
|
|
||||||
* },
|
|
||||||
* // ...
|
|
||||||
* })
|
|
||||||
* ```
|
|
||||||
*
|
|
||||||
* @ignore
|
|
||||||
*
|
|
||||||
* @privateRemarks
|
|
||||||
* Couldn't find any use for this option.
|
|
||||||
*/
|
|
||||||
jobsBatchSize?: number
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Configure the application's worker mode.
|
|
||||||
*
|
|
||||||
* Workers are processes running separately from the main application. They're useful for executing long-running or resource-heavy tasks in the background, such as importing products.
|
|
||||||
*
|
|
||||||
* With a worker, these tasks are offloaded to a separate process. So, they won't affect the performance of the main application.
|
|
||||||
*
|
|
||||||
* 
|
|
||||||
*
|
|
||||||
* Medusa has three runtime modes:
|
|
||||||
*
|
|
||||||
* - Use `shared` to run the application in a single process.
|
|
||||||
* - Use `worker` to run the a worker process only.
|
|
||||||
* - Use `server` to run the application server only.
|
|
||||||
*
|
|
||||||
* In production, it's recommended to deploy two instances:
|
|
||||||
*
|
|
||||||
* 1. One having the `workerMode` configuration set to `server`.
|
|
||||||
* 2. Another having the `workerMode` configuration set to `worker`.
|
|
||||||
*
|
|
||||||
* @example
|
|
||||||
* ```ts title="medusa-config.ts"
|
|
||||||
* module.exports = defineConfig({
|
|
||||||
* projectConfig: {
|
|
||||||
* workerMode: process.env.WORKER_MODE || "shared"
|
|
||||||
* // ...
|
|
||||||
* },
|
|
||||||
* // ...
|
|
||||||
* })
|
|
||||||
* ```
|
|
||||||
*/
|
|
||||||
workerMode?: "shared" | "worker" | "server"
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This property configures the application's http-specific settings.
|
|
||||||
*
|
|
||||||
* @example
|
|
||||||
* ```ts title="medusa-config.ts"
|
|
||||||
* module.exports = defineConfig({
|
|
||||||
* projectConfig: {
|
|
||||||
* http: {
|
|
||||||
* cookieSecret: "supersecret",
|
|
||||||
* compression: {
|
|
||||||
* // ...
|
|
||||||
* }
|
|
||||||
* }
|
|
||||||
* // ...
|
|
||||||
* },
|
|
||||||
* // ...
|
|
||||||
* })
|
|
||||||
* ```
|
|
||||||
*/
|
|
||||||
http: {
|
|
||||||
/**
|
|
||||||
* A random string used to create authentication tokens in the http layer. Although this configuration option is not required, it’s highly recommended to set it for better security.
|
|
||||||
*
|
|
||||||
* In a development environment, if this option is not set the default secret is `supersecret`. However, in production, if this configuration is not set, an
|
|
||||||
* error is thrown and the application crashes.
|
|
||||||
*
|
|
||||||
* @example
|
|
||||||
* ```ts title="medusa-config.ts"
|
|
||||||
* module.exports = defineConfig({
|
|
||||||
* projectConfig: {
|
|
||||||
* http: {
|
|
||||||
* jwtSecret: "supersecret",
|
|
||||||
* }
|
|
||||||
* // ...
|
|
||||||
* },
|
|
||||||
* // ...
|
|
||||||
* })
|
|
||||||
* ```
|
|
||||||
*/
|
|
||||||
jwtSecret?: string
|
|
||||||
/**
|
|
||||||
* The expiration time for the JWT token. Its format is based off the [ms package](https://github.com/vercel/ms).
|
|
||||||
*
|
|
||||||
* If not provided, the default value is `24h`.
|
|
||||||
*
|
|
||||||
* @example
|
|
||||||
* ```ts title="medusa-config.ts"
|
|
||||||
* module.exports = defineConfig({
|
|
||||||
* projectConfig: {
|
|
||||||
* http: {
|
|
||||||
* jwtExpiresIn: "2d"
|
|
||||||
* }
|
|
||||||
* // ...
|
|
||||||
* },
|
|
||||||
* // ...
|
|
||||||
* })
|
|
||||||
* ```
|
|
||||||
*/
|
|
||||||
jwtExpiresIn?: string
|
|
||||||
/**
|
|
||||||
* A random string used to create cookie tokens in the http layer. Although this configuration option is not required, it’s highly recommended to set it for better security.
|
|
||||||
*
|
|
||||||
* In a development environment, if this option is not set, the default secret is `supersecret`. However, in production, if this configuration is not set, an error is thrown and
|
|
||||||
* the application crashes.
|
|
||||||
*
|
|
||||||
* @example
|
|
||||||
* ```ts title="medusa-config.ts"
|
|
||||||
* module.exports = defineConfig({
|
|
||||||
* projectConfig: {
|
|
||||||
* http: {
|
|
||||||
* cookieSecret: "supersecret"
|
|
||||||
* }
|
|
||||||
* // ...
|
|
||||||
* },
|
|
||||||
* // ...
|
|
||||||
* })
|
|
||||||
* ```
|
|
||||||
*/
|
|
||||||
cookieSecret?: string
|
|
||||||
/**
|
|
||||||
* The Medusa application's API Routes are protected by Cross-Origin Resource Sharing (CORS). So, only allowed URLs or URLs matching a specified pattern can send requests to the backend’s API Routes.
|
|
||||||
*
|
|
||||||
* `cors` is a string used to specify the accepted URLs or patterns for API Routes starting with `/auth`. It can either be one accepted origin, or a comma-separated list of accepted origins.
|
|
||||||
*
|
|
||||||
* Every origin in that list must either be:
|
|
||||||
*
|
|
||||||
* 1. A URL. For example, `http://localhost:7001`. The URL must not end with a backslash;
|
|
||||||
* 2. Or a regular expression pattern that can match more than one origin. For example, `.example.com`. The regex pattern that Medusa tests for is `^([\/~@;%#'])(.*?)\1([gimsuy]*)$`.
|
|
||||||
*
|
|
||||||
* @example
|
|
||||||
* Some example values of common use cases:
|
|
||||||
*
|
|
||||||
* ```bash
|
|
||||||
* # Allow different ports locally starting with 700
|
|
||||||
* AUTH_CORS=/http:\/\/localhost:700\d+$/
|
|
||||||
*
|
|
||||||
* # Allow any origin ending with vercel.app. For example, admin.vercel.app
|
|
||||||
* AUTH_CORS=/vercel\.app$/
|
|
||||||
*
|
|
||||||
* # Allow all HTTP requests
|
|
||||||
* AUTH_CORS=/http:\/\/.+/
|
|
||||||
* ```
|
|
||||||
*
|
|
||||||
* Then, set the configuration in `medusa-config.ts`:
|
|
||||||
*
|
|
||||||
* ```ts title="medusa-config.ts"
|
|
||||||
* module.exports = defineConfig({
|
|
||||||
* projectConfig: {
|
|
||||||
* http: {
|
|
||||||
* authCors: process.env.AUTH_CORS
|
|
||||||
* }
|
|
||||||
* // ...
|
|
||||||
* },
|
|
||||||
* // ...
|
|
||||||
* })
|
|
||||||
* ```
|
|
||||||
*
|
|
||||||
* If you’re adding the value directly within `medusa-config.ts`, make sure to add an extra escaping `/` for every backslash in the pattern. For example:
|
|
||||||
*
|
|
||||||
* ```ts title="medusa-config.ts"
|
|
||||||
* module.exports = defineConfig({
|
|
||||||
* projectConfig: {
|
|
||||||
* http: {
|
|
||||||
* authCors: "/http:\\/\\/localhost:700\\d+$/",
|
|
||||||
* }
|
|
||||||
* // ...
|
|
||||||
* },
|
|
||||||
* // ...
|
|
||||||
* })
|
|
||||||
* ```
|
|
||||||
*/
|
|
||||||
authCors: string
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* Configure HTTP compression from the application layer. If you have access to the HTTP server, the recommended approach would be to enable it there.
|
|
||||||
* However, some platforms don't offer access to the HTTP layer and in those cases, this is a good alternative.
|
|
||||||
*
|
|
||||||
* If you enable HTTP compression and you want to disable it for specific API Routes, you can pass in the request header `"x-no-compression": true`.
|
|
||||||
* Learn more in the [API Reference](https://docs.medusajs.com/api/store#http-compression).
|
|
||||||
*
|
|
||||||
* @example
|
|
||||||
* ```ts title="medusa-config.ts"
|
|
||||||
* module.exports = defineConfig({
|
|
||||||
* projectConfig: {
|
|
||||||
* http: {
|
|
||||||
* compression: {
|
|
||||||
* enabled: true,
|
|
||||||
* level: 6,
|
|
||||||
* memLevel: 8,
|
|
||||||
* threshold: 1024
|
|
||||||
* }
|
|
||||||
* }
|
|
||||||
* // ...
|
|
||||||
* },
|
|
||||||
* // ...
|
|
||||||
* })
|
|
||||||
* ```
|
|
||||||
*/
|
|
||||||
compression?: HttpCompressionOptions
|
|
||||||
/**
|
|
||||||
* The Medusa application's API Routes are protected by Cross-Origin Resource Sharing (CORS). So, only allowed URLs or URLs matching a specified pattern can send requests to the backend’s API Routes.
|
|
||||||
*
|
|
||||||
* `store_cors` is a string used to specify the accepted URLs or patterns for store API Routes. It can either be one accepted origin, or a comma-separated list of accepted origins.
|
|
||||||
*
|
|
||||||
* Every origin in that list must either be:
|
|
||||||
*
|
|
||||||
* 1. A URL. For example, `http://localhost:8000`. The URL must not end with a backslash;
|
|
||||||
* 2. Or a regular expression pattern that can match more than one origin. For example, `.example.com`. The regex pattern that the backend tests for is `^([\/~@;%#'])(.*?)\1([gimsuy]*)$`.
|
|
||||||
*
|
|
||||||
* @example
|
|
||||||
* Some example values of common use cases:
|
|
||||||
*
|
|
||||||
* ```bash
|
|
||||||
* # Allow different ports locally starting with 800
|
|
||||||
* STORE_CORS=/http:\/\/localhost:800\d+$/
|
|
||||||
*
|
|
||||||
* # Allow any origin ending with vercel.app. For example, storefront.vercel.app
|
|
||||||
* STORE_CORS=/vercel\.app$/
|
|
||||||
*
|
|
||||||
* # Allow all HTTP requests
|
|
||||||
* STORE_CORS=/http:\/\/.+/
|
|
||||||
* ```
|
|
||||||
*
|
|
||||||
* Then, set the configuration in `medusa-config.ts`:
|
|
||||||
*
|
|
||||||
* ```ts title="medusa-config.ts"
|
|
||||||
* module.exports = defineConfig({
|
|
||||||
* projectConfig: {
|
|
||||||
* http: {
|
|
||||||
* storeCors: process.env.STORE_CORS,
|
|
||||||
* }
|
|
||||||
* // ...
|
|
||||||
* },
|
|
||||||
* // ...
|
|
||||||
* })
|
|
||||||
* ```
|
|
||||||
*
|
|
||||||
* If you’re adding the value directly within `medusa-config.ts`, make sure to add an extra escaping `/` for every backslash in the pattern. For example:
|
|
||||||
*
|
|
||||||
* ```ts title="medusa-config.ts"
|
|
||||||
* module.exports = defineConfig({
|
|
||||||
* projectConfig: {
|
|
||||||
* http: {
|
|
||||||
* storeCors: "/vercel\\.app$/",
|
|
||||||
* }
|
|
||||||
* // ...
|
|
||||||
* },
|
|
||||||
* // ...
|
|
||||||
* })
|
|
||||||
* ```
|
|
||||||
*/
|
|
||||||
storeCors: string
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The Medusa application's API Routes are protected by Cross-Origin Resource Sharing (CORS). So, only allowed URLs or URLs matching a specified pattern can send requests to the backend’s API Routes.
|
|
||||||
*
|
|
||||||
* `admin_cors` is a string used to specify the accepted URLs or patterns for admin API Routes. It can either be one accepted origin, or a comma-separated list of accepted origins.
|
|
||||||
*
|
|
||||||
* Every origin in that list must either be:
|
|
||||||
*
|
|
||||||
* 1. A URL. For example, `http://localhost:7001`. The URL must not end with a backslash;
|
|
||||||
* 2. Or a regular expression pattern that can match more than one origin. For example, `.example.com`. The regex pattern that the backend tests for is `^([\/~@;%#'])(.*?)\1([gimsuy]*)$`.
|
|
||||||
*
|
|
||||||
* @example
|
|
||||||
* Some example values of common use cases:
|
|
||||||
*
|
|
||||||
* ```bash
|
|
||||||
* # Allow different ports locally starting with 700
|
|
||||||
* ADMIN_CORS=/http:\/\/localhost:700\d+$/
|
|
||||||
*
|
|
||||||
* # Allow any origin ending with vercel.app. For example, admin.vercel.app
|
|
||||||
* ADMIN_CORS=/vercel\.app$/
|
|
||||||
*
|
|
||||||
* # Allow all HTTP requests
|
|
||||||
* ADMIN_CORS=/http:\/\/.+/
|
|
||||||
* ```
|
|
||||||
*
|
|
||||||
* Then, set the configuration in `medusa-config.ts`:
|
|
||||||
*
|
|
||||||
* ```ts title="medusa-config.ts"
|
|
||||||
* module.exports = defineConfig({
|
|
||||||
* projectConfig: {
|
|
||||||
* http: {
|
|
||||||
* adminCors: process.env.ADMIN_CORS,
|
|
||||||
* }
|
|
||||||
* // ...
|
|
||||||
* },
|
|
||||||
* // ...
|
|
||||||
* })
|
|
||||||
* ```
|
|
||||||
*
|
|
||||||
* If you’re adding the value directly within `medusa-config.ts`, make sure to add an extra escaping `/` for every backslash in the pattern. For example:
|
|
||||||
*
|
|
||||||
* ```ts title="medusa-config.ts"
|
|
||||||
* module.exports = defineConfig({
|
|
||||||
* projectConfig: {
|
|
||||||
* http: {
|
|
||||||
* adminCors: "/vercel\\.app$/",
|
|
||||||
* }
|
|
||||||
* // ...
|
|
||||||
* },
|
|
||||||
* // ...
|
|
||||||
* })
|
|
||||||
* ```
|
|
||||||
*/
|
|
||||||
adminCors: string
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This configuration specifies the supported authentication providers per actor type (such as `user`, `customer`, or any custom actors).
|
|
||||||
* For example, you only want to allow SSO logins for `users`, while you want to allow email/password logins for `customers` to the storefront.
|
|
||||||
*
|
|
||||||
* `authMethodsPerActor` is a a map where the actor type (eg. 'user') is the key, and the value is an array of supported auth provider IDs.
|
|
||||||
*
|
|
||||||
* @example
|
|
||||||
* Some example values of common use cases:
|
|
||||||
*
|
|
||||||
* Then, set the configuration in `medusa-config.ts`:
|
|
||||||
*
|
|
||||||
* ```ts title="medusa-config.ts"
|
|
||||||
* module.exports = defineConfig({
|
|
||||||
* projectConfig: {
|
|
||||||
* http: {
|
|
||||||
* authMethodsPerActor: {
|
|
||||||
* user: ["email"],
|
|
||||||
* customer: ["emailpass", "google"]
|
|
||||||
* }
|
|
||||||
* }
|
|
||||||
* // ...
|
|
||||||
* },
|
|
||||||
* // ...
|
|
||||||
* })
|
|
||||||
* ```
|
|
||||||
*/
|
|
||||||
authMethodsPerActor?: Record<string, string[]>
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Specifies the fields that can't be selected in the response unless specified in the allowed query config.
|
|
||||||
* This is useful to restrict sensitive fields from being exposed in the API.
|
|
||||||
*
|
|
||||||
* @example
|
|
||||||
*
|
|
||||||
* ```js title="medusa-config.js"
|
|
||||||
* module.exports = defineConfig({
|
|
||||||
* projectConfig: {
|
|
||||||
* http: {
|
|
||||||
* restrictedFields: {
|
|
||||||
* store: ["order", "orders"],
|
|
||||||
* }
|
|
||||||
* }
|
|
||||||
* ```
|
|
||||||
*/
|
|
||||||
restrictedFields?: {
|
|
||||||
store?: string[]
|
|
||||||
/*admin?: string[]*/
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @interface
|
|
||||||
*
|
|
||||||
* The configurations for your Medusa application are set in `medusa-config.ts` located in the root of your Medusa project. The configurations include configurations for database, modules, and more.
|
|
||||||
*
|
|
||||||
* :::note
|
|
||||||
*
|
|
||||||
* Some Medusa configurations are set through environment variables, which you can find in [this documentation](https://docs.medusajs.com/learn/fundamentals/environment-variables#predefined-medusa-environment-variables).
|
|
||||||
*
|
|
||||||
* :::
|
|
||||||
*
|
|
||||||
* `medusa-config.ts` exports the value returned by the `defineConfig` utility function imported from `@medusajs/framework/utils`.
|
|
||||||
*
|
|
||||||
* `defineConfig` accepts as a parameter an object with the following properties:
|
|
||||||
*
|
|
||||||
* - {@link ConfigModule.projectConfig | projectConfig} (required): An object that holds general configurations related to the Medusa application, such as database or CORS configurations.
|
|
||||||
* - {@link ConfigModule.plugins | plugins}: An array of strings or objects that hold the configurations of the plugins installed in the Medusa application.
|
|
||||||
* - {@link ConfigModule.admin | admin}: An object that holds admin-related configurations.
|
|
||||||
* - {@link ConfigModule.modules | modules}: An object that configures the Medusa application's modules.
|
|
||||||
* - {@link ConfigModule.featureFlags | featureFlags}: An object that enables or disables features guarded by a feature flag.
|
|
||||||
*
|
|
||||||
* For example:
|
|
||||||
*
|
|
||||||
* ```ts title="medusa-config.ts"
|
|
||||||
* module.exports = defineConfig({
|
|
||||||
* projectConfig: {
|
|
||||||
* // ...
|
|
||||||
* },
|
|
||||||
* admin: {
|
|
||||||
* // ...
|
|
||||||
* },
|
|
||||||
* modules: {
|
|
||||||
* // ...
|
|
||||||
* },
|
|
||||||
* featureFlags: {
|
|
||||||
* // ...
|
|
||||||
* }
|
|
||||||
* })
|
|
||||||
* ```
|
|
||||||
*
|
|
||||||
* ---
|
|
||||||
*
|
|
||||||
* ## Environment Variables
|
|
||||||
*
|
|
||||||
* It's highly recommended to store the values of configurations in environment variables, then reference them within `medusa-config.ts`.
|
|
||||||
*
|
|
||||||
* During development, you can set your environment variables in the `.env` file at the root of your Medusa application project. In production,
|
|
||||||
* setting the environment variables depends on the hosting provider.
|
|
||||||
*
|
|
||||||
* ---
|
|
||||||
*/
|
|
||||||
export type ConfigModule = {
|
|
||||||
/**
|
|
||||||
* This property holds essential configurations related to the Medusa application, such as database and CORS configurations.
|
|
||||||
*/
|
|
||||||
projectConfig: ProjectConfigOptions
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This property holds configurations for the Medusa Admin dashboard.
|
|
||||||
*
|
|
||||||
* @example
|
|
||||||
* ```ts title="medusa-config.ts"
|
|
||||||
* module.exports = defineConfig({
|
|
||||||
* admin: {
|
|
||||||
* backendUrl: process.env.MEDUSA_BACKEND_URL ||
|
|
||||||
* "http://localhost:9000"
|
|
||||||
* },
|
|
||||||
* // ...
|
|
||||||
* })
|
|
||||||
* ```
|
|
||||||
*/
|
|
||||||
admin?: AdminOptions
|
|
||||||
|
|
||||||
/**
|
|
||||||
* On your Medusa server, you can use [Plugins](https://docs.medusajs.com/learn/fundamentals/plugins) to add re-usable Medusa customizations. Plugins
|
|
||||||
* can include modules, workflows, API Routes, and other customizations. Plugins are available starting from [Medusa v2.3.0](https://github.com/medusajs/medusa/releases/tag/v2.3.0).
|
|
||||||
*
|
|
||||||
* Aside from installing the plugin with NPM, you need to pass the plugin you installed into the `plugins` array defined in `medusa-config.ts`.
|
|
||||||
*
|
|
||||||
* The items in the array can either be:
|
|
||||||
*
|
|
||||||
* - A string, which is the name of the plugin's package as specified in the plugin's `package.json` file. You can pass a plugin as a string if it doesn’t require any options.
|
|
||||||
* - An object having the following properties:
|
|
||||||
* - `resolve`: The name of the plugin's package as specified in the plugin's `package.json` file.
|
|
||||||
* - `options`: An object that includes options to be passed to the modules within the plugin. Learn more in [this documentation](https://docs.medusajs.com/learn/fundamentals/modules/options).
|
|
||||||
*
|
|
||||||
* Learn how to create a plugin in [this documentation](https://docs.medusajs.com/learn/fundamentals/plugins/create).
|
|
||||||
*
|
|
||||||
* @example
|
|
||||||
* ```ts title="medusa-config.ts"
|
|
||||||
* module.exports = {
|
|
||||||
* plugins: [
|
|
||||||
* `medusa-my-plugin-1`,
|
|
||||||
* {
|
|
||||||
* resolve: `medusa-my-plugin`,
|
|
||||||
* options: {
|
|
||||||
* apiKey: process.env.MY_API_KEY ||
|
|
||||||
* `test`,
|
|
||||||
* },
|
|
||||||
* },
|
|
||||||
* // ...
|
|
||||||
* ],
|
|
||||||
* // ...
|
|
||||||
* }
|
|
||||||
* ```
|
|
||||||
*/
|
|
||||||
plugins: (
|
|
||||||
| {
|
|
||||||
/**
|
|
||||||
* The name of the plugin's package as specified in the plugin's `package.json` file.
|
|
||||||
*/
|
|
||||||
resolve: string
|
|
||||||
/**
|
|
||||||
* An object that includes options to be passed to the modules within the plugin.
|
|
||||||
* Learn more in [this documentation](https://docs.medusajs.com/learn/fundamentals/modules/options).
|
|
||||||
*/
|
|
||||||
options: Record<string, unknown>
|
|
||||||
}
|
|
||||||
| string
|
|
||||||
)[]
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This property holds all custom modules installed in your Medusa application.
|
|
||||||
*
|
|
||||||
* :::note
|
|
||||||
*
|
|
||||||
* Medusa's commerce modules are configured by default, so only
|
|
||||||
* add them to this property if you're changing their configurations or adding providers to a module.
|
|
||||||
*
|
|
||||||
* :::
|
|
||||||
*
|
|
||||||
* `modules` is an array of objects, each holding a module's registration configurations. Each object has the following properties:
|
|
||||||
*
|
|
||||||
* 1. `resolve`: a string indicating the path to the module relative to `src`, or the module's NPM package name. For example, `./modules/my-module`.
|
|
||||||
* 2. `options`: (optional) an object indicating the options to pass to the module.
|
|
||||||
*
|
|
||||||
* @example
|
|
||||||
* ```ts title="medusa-config.ts"
|
|
||||||
* module.exports = defineConfig({
|
|
||||||
* modules: [
|
|
||||||
* {
|
|
||||||
* resolve: "./modules/hello"
|
|
||||||
* }
|
|
||||||
* ]
|
|
||||||
* // ...
|
|
||||||
* })
|
|
||||||
* ```
|
|
||||||
*/
|
|
||||||
modules?: Record<
|
|
||||||
string,
|
|
||||||
boolean | Partial<InternalModuleDeclaration | ExternalModuleDeclaration>
|
|
||||||
>
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Some features in the Medusa application are guarded by a feature flag. This ensures constant shipping of new features while maintaining the engine’s stability.
|
|
||||||
*
|
|
||||||
* You can enable a feature in your application by enabling its feature flag. Feature flags are enabled through either environment
|
|
||||||
* variables or through this configuration property exported in `medusa-config.ts`.
|
|
||||||
*
|
|
||||||
* The `featureFlags`'s value is an object. Its properties are the names of the feature flags, and their value is a boolean indicating whether the feature flag is enabled.
|
|
||||||
*
|
|
||||||
* You can find available feature flags and their key name [here](https://github.com/medusajs/medusa/tree/develop/packages/medusa/src/loaders/feature-flags).
|
|
||||||
*
|
|
||||||
* @example
|
|
||||||
* ```ts title="medusa-config.ts"
|
|
||||||
* module.exports = defineConfig({
|
|
||||||
* featureFlags: {
|
|
||||||
* analytics: true,
|
|
||||||
* // ...
|
|
||||||
* }
|
|
||||||
* // ...
|
|
||||||
* })
|
|
||||||
* ```
|
|
||||||
*
|
|
||||||
* :::note
|
|
||||||
*
|
|
||||||
* After enabling a feature flag, make sure to run migrations as it may require making changes to the database.
|
|
||||||
*
|
|
||||||
* :::
|
|
||||||
*/
|
|
||||||
featureFlags: Record<string, boolean | string | Record<string, boolean>>
|
|
||||||
}
|
|
||||||
|
|
||||||
export type PluginDetails = {
|
|
||||||
resolve: string
|
|
||||||
name: string
|
|
||||||
id: string
|
|
||||||
options: Record<string, unknown>
|
|
||||||
version: string
|
|
||||||
}
|
|
||||||
@@ -11,7 +11,7 @@ import supertest from "supertest"
|
|||||||
|
|
||||||
import { config } from "../mocks"
|
import { config } from "../mocks"
|
||||||
import { MedusaContainer } from "@medusajs/types"
|
import { MedusaContainer } from "@medusajs/types"
|
||||||
import { configManager, ConfigModule } from "../../../config"
|
import { configManager } from "../../../config"
|
||||||
import { container } from "../../../container"
|
import { container } from "../../../container"
|
||||||
import { featureFlagsLoader } from "../../../feature-flags"
|
import { featureFlagsLoader } from "../../../feature-flags"
|
||||||
import { logger } from "../../../logger"
|
import { logger } from "../../../logger"
|
||||||
@@ -44,7 +44,7 @@ export const createServer = async (rootDir) => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
configManager.loadConfig({
|
configManager.loadConfig({
|
||||||
projectConfig: config as ConfigModule,
|
projectConfig: config,
|
||||||
baseDir: rootDir,
|
baseDir: rootDir,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import path from "path"
|
|||||||
import { logger } from "../logger"
|
import { logger } from "../logger"
|
||||||
import { configManager } from "../config"
|
import { configManager } from "../config"
|
||||||
import { MedusaRequest, MedusaResponse } from "./types"
|
import { MedusaRequest, MedusaResponse } from "./types"
|
||||||
|
import { dynamicImport } from "@medusajs/utils"
|
||||||
|
|
||||||
const NOISY_ENDPOINTS_CHUNKS = ["@fs", "@id", "@vite", "@react", "node_modules"]
|
const NOISY_ENDPOINTS_CHUNKS = ["@fs", "@id", "@vite", "@react", "node_modules"]
|
||||||
|
|
||||||
@@ -37,7 +38,7 @@ export async function expressLoader({ app }: { app: Express }): Promise<{
|
|||||||
name: sessionOptions?.name ?? "connect.sid",
|
name: sessionOptions?.name ?? "connect.sid",
|
||||||
resave: sessionOptions?.resave ?? true,
|
resave: sessionOptions?.resave ?? true,
|
||||||
rolling: sessionOptions?.rolling ?? false,
|
rolling: sessionOptions?.rolling ?? false,
|
||||||
saveUninitialized: sessionOptions?.saveUninitialized ?? true,
|
saveUninitialized: sessionOptions?.saveUninitialized ?? false,
|
||||||
proxy: true,
|
proxy: true,
|
||||||
secret: sessionOptions?.secret ?? http?.cookieSecret,
|
secret: sessionOptions?.secret ?? http?.cookieSecret,
|
||||||
cookie: {
|
cookie: {
|
||||||
@@ -50,7 +51,17 @@ export async function expressLoader({ app }: { app: Express }): Promise<{
|
|||||||
|
|
||||||
let redisClient: Redis
|
let redisClient: Redis
|
||||||
|
|
||||||
if (configModule?.projectConfig?.redisUrl) {
|
if (configModule?.projectConfig.sessionOptions?.dynamodbOptions) {
|
||||||
|
const storeFactory = await dynamicImport("connect-dynamodb")
|
||||||
|
const client = await dynamicImport("@aws-sdk/client-dynamodb")
|
||||||
|
const DynamoDBStore = storeFactory({ session })
|
||||||
|
sessionOpts.store = new DynamoDBStore({
|
||||||
|
...configModule.projectConfig.sessionOptions.dynamodbOptions,
|
||||||
|
client: new client.DynamoDBClient(
|
||||||
|
configModule.projectConfig.sessionOptions.dynamodbOptions.clientOptions
|
||||||
|
),
|
||||||
|
})
|
||||||
|
} else if (configModule?.projectConfig?.redisUrl) {
|
||||||
const RedisStore = createStore(session)
|
const RedisStore = createStore(session)
|
||||||
redisClient = new Redis(
|
redisClient = new Redis(
|
||||||
configModule.projectConfig.redisUrl,
|
configModule.projectConfig.redisUrl,
|
||||||
|
|||||||
@@ -115,8 +115,10 @@ export class MedusaAppLoader {
|
|||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
const driverOptions = { ...(configManager.config.projectConfig.databaseDriverOptions ?? {}) }
|
const driverOptions = {
|
||||||
const pool = driverOptions.pool ?? {}
|
...(configManager.config.projectConfig.databaseDriverOptions ?? {}),
|
||||||
|
}
|
||||||
|
const pool = (driverOptions.pool as Record<string, unknown>) ?? {}
|
||||||
delete driverOptions.pool
|
delete driverOptions.pool
|
||||||
|
|
||||||
const sharedResourcesConfig: ModuleServiceInitializeOptions = {
|
const sharedResourcesConfig: ModuleServiceInitializeOptions = {
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ export interface AdminOptions {
|
|||||||
* in both development and production environments. The default value is `false`.
|
* in both development and production environments. The default value is `false`.
|
||||||
*
|
*
|
||||||
* @example
|
* @example
|
||||||
* ```js title="medusa-config.js"
|
* ```js title="medusa-config.ts"
|
||||||
* module.exports = defineConfig({
|
* module.exports = defineConfig({
|
||||||
* admin: {
|
* admin: {
|
||||||
* disable: process.env.ADMIN_DISABLED === "true" ||
|
* disable: process.env.ADMIN_DISABLED === "true" ||
|
||||||
@@ -30,6 +30,7 @@ export interface AdminOptions {
|
|||||||
* ```
|
* ```
|
||||||
*/
|
*/
|
||||||
disable?: boolean
|
disable?: boolean
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The path to the admin dashboard. The default value is `/app`.
|
* The path to the admin dashboard. The default value is `/app`.
|
||||||
*
|
*
|
||||||
@@ -40,7 +41,7 @@ export interface AdminOptions {
|
|||||||
* - `/`
|
* - `/`
|
||||||
*
|
*
|
||||||
* @example
|
* @example
|
||||||
* ```js title="medusa-config.js"
|
* ```ts title="medusa-config.ts"
|
||||||
* module.exports = defineConfig({
|
* module.exports = defineConfig({
|
||||||
* admin: {
|
* admin: {
|
||||||
* path: process.env.ADMIN_PATH || `/app`,
|
* path: process.env.ADMIN_PATH || `/app`,
|
||||||
@@ -50,11 +51,12 @@ export interface AdminOptions {
|
|||||||
* ```
|
* ```
|
||||||
*/
|
*/
|
||||||
path: `/${string}`
|
path: `/${string}`
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The URL of your Medusa application. Defaults to the browser origin. This is useful to set when running the admin on a separate domain.
|
* The URL of your Medusa application. Defaults to the browser origin. This is useful to set when running the admin on a separate domain.
|
||||||
*
|
*
|
||||||
* @example
|
* @example
|
||||||
* ```js title="medusa-config.js"
|
* ```js title="medusa-config.ts"
|
||||||
* module.exports = defineConfig({
|
* module.exports = defineConfig({
|
||||||
* admin: {
|
* admin: {
|
||||||
* backendUrl: process.env.MEDUSA_BACKEND_URL ||
|
* backendUrl: process.env.MEDUSA_BACKEND_URL ||
|
||||||
@@ -65,12 +67,13 @@ export interface AdminOptions {
|
|||||||
* ```
|
* ```
|
||||||
*/
|
*/
|
||||||
backendUrl?: string
|
backendUrl?: string
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The URL of your Medusa storefront application. This will help generate links from the admin
|
* The URL of your Medusa storefront application. This will help generate links from the admin
|
||||||
* to provide to customers to complete any processes
|
* to provide to customers to complete any processes
|
||||||
*
|
*
|
||||||
* @example
|
* @example
|
||||||
* ```js title="medusa-config.js"
|
* ```js title="medusa-config.ts"
|
||||||
* module.exports = defineConfig({
|
* module.exports = defineConfig({
|
||||||
* admin: {
|
* admin: {
|
||||||
* storefrontUrl: process.env.MEDUSA_STOREFRONT_URL ||
|
* storefrontUrl: process.env.MEDUSA_STOREFRONT_URL ||
|
||||||
@@ -81,6 +84,13 @@ export interface AdminOptions {
|
|||||||
* ```
|
* ```
|
||||||
*/
|
*/
|
||||||
storefrontUrl?: string
|
storefrontUrl?: string
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The directory where the admin build is output. This is where the build process places the generated files.
|
||||||
|
* The default value is `./build`.
|
||||||
|
*/
|
||||||
|
outDir?: string
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configure the Vite configuration for the admin dashboard. This function receives the default Vite configuration
|
* Configure the Vite configuration for the admin dashboard. This function receives the default Vite configuration
|
||||||
* and returns the modified configuration. The default value is `undefined`.
|
* and returns the modified configuration. The default value is `undefined`.
|
||||||
@@ -95,7 +105,7 @@ export interface AdminOptions {
|
|||||||
*
|
*
|
||||||
* Options to pass to `express-session`.
|
* Options to pass to `express-session`.
|
||||||
*/
|
*/
|
||||||
type SessionOptions = {
|
export type SessionOptions = {
|
||||||
/**
|
/**
|
||||||
* The name of the session ID cookie to set in the response (and read from in the request). The default value is `connect.sid`.
|
* The name of the session ID cookie to set in the response (and read from in the request). The default value is `connect.sid`.
|
||||||
* Refer to [express-session’s documentation](https://www.npmjs.com/package/express-session#name) for more details.
|
* Refer to [express-session’s documentation](https://www.npmjs.com/package/express-session#name) for more details.
|
||||||
@@ -126,6 +136,36 @@ type SessionOptions = {
|
|||||||
* Refer to [express-session’s documentation](https://www.npmjs.com/package/express-session#cookiemaxage) for details.
|
* Refer to [express-session’s documentation](https://www.npmjs.com/package/express-session#cookiemaxage) for details.
|
||||||
*/
|
*/
|
||||||
ttl?: number
|
ttl?: number
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specify the options for storing session data to dynamoDB. Make
|
||||||
|
* sure to install the following dependencies first.
|
||||||
|
*
|
||||||
|
* - @aws-sdk/client-dynamodb@^3.218.0
|
||||||
|
* - connect-dynamodb@^3.0.5
|
||||||
|
*/
|
||||||
|
dynamodbOptions?: {
|
||||||
|
clientOptions?: {
|
||||||
|
endpoint?: string
|
||||||
|
}
|
||||||
|
table?: string
|
||||||
|
/** Defaults to 'sess:' */
|
||||||
|
prefix?: string
|
||||||
|
/** Defaults to 'id' */
|
||||||
|
hashKey?: string
|
||||||
|
readCapacityUnits?: number
|
||||||
|
writeCapacityUnits?: number
|
||||||
|
specialKeys?: {
|
||||||
|
name: string
|
||||||
|
type: string
|
||||||
|
}[]
|
||||||
|
skipThrowMissingSpecialKeys?: boolean
|
||||||
|
/**
|
||||||
|
* Disable initialization.
|
||||||
|
* Useful if the table already exists or if you want to skip existence checks in a serverless environment such as AWS Lambda.
|
||||||
|
*/
|
||||||
|
initialized?: boolean
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -168,7 +208,7 @@ export type ProjectConfigOptions = {
|
|||||||
* [PostgreSQL's documentation](https://www.postgresql.org/docs/current/sql-createdatabase.html).
|
* [PostgreSQL's documentation](https://www.postgresql.org/docs/current/sql-createdatabase.html).
|
||||||
*
|
*
|
||||||
* @example
|
* @example
|
||||||
* ```js title="medusa-config.js"
|
* ```js title="medusa-config.ts"
|
||||||
* module.exports = defineConfig({
|
* module.exports = defineConfig({
|
||||||
* projectConfig: {
|
* projectConfig: {
|
||||||
* databaseName: process.env.DATABASE_NAME ||
|
* databaseName: process.env.DATABASE_NAME ||
|
||||||
@@ -205,9 +245,9 @@ export type ProjectConfigOptions = {
|
|||||||
* DATABASE_URL=postgres://postgres@localhost/medusa-store
|
* DATABASE_URL=postgres://postgres@localhost/medusa-store
|
||||||
* ```
|
* ```
|
||||||
*
|
*
|
||||||
* Then, use the value in `medusa-config.js`:
|
* Then, use the value in `medusa-config.ts`:
|
||||||
*
|
*
|
||||||
* ```js title="medusa-config.js"
|
* ```js title="medusa-config.ts"
|
||||||
* module.exports = defineConfig({
|
* module.exports = defineConfig({
|
||||||
* projectConfig: {
|
* projectConfig: {
|
||||||
* databaseUrl: process.env.DATABASE_URL,
|
* databaseUrl: process.env.DATABASE_URL,
|
||||||
@@ -222,7 +262,7 @@ export type ProjectConfigOptions = {
|
|||||||
/**
|
/**
|
||||||
* The database schema to connect to. This is not required to provide if you’re using the default schema, which is `public`.
|
* The database schema to connect to. This is not required to provide if you’re using the default schema, which is `public`.
|
||||||
*
|
*
|
||||||
* ```js title="medusa-config.js"
|
* ```js title="medusa-config.ts"
|
||||||
* module.exports = defineConfig({
|
* module.exports = defineConfig({
|
||||||
* projectConfig: {
|
* projectConfig: {
|
||||||
* databaseSchema: process.env.DATABASE_SCHEMA ||
|
* databaseSchema: process.env.DATABASE_SCHEMA ||
|
||||||
@@ -239,7 +279,7 @@ export type ProjectConfigOptions = {
|
|||||||
* This configuration specifies whether database messages should be logged.
|
* This configuration specifies whether database messages should be logged.
|
||||||
*
|
*
|
||||||
* @example
|
* @example
|
||||||
* ```js title="medusa-config.js"
|
* ```js title="medusa-config.ts"
|
||||||
* module.exports = defineConfig({
|
* module.exports = defineConfig({
|
||||||
* projectConfig: {
|
* projectConfig: {
|
||||||
* databaseLogging: false
|
* databaseLogging: false
|
||||||
@@ -265,7 +305,7 @@ export type ProjectConfigOptions = {
|
|||||||
* :::
|
* :::
|
||||||
*
|
*
|
||||||
* @example
|
* @example
|
||||||
* ```js title="medusa-config.js"
|
* ```js title="medusa-config.ts"
|
||||||
* module.exports = defineConfig({
|
* module.exports = defineConfig({
|
||||||
* projectConfig: {
|
* projectConfig: {
|
||||||
* databaseDriverOptions: process.env.NODE_ENV !== "development" ?
|
* databaseDriverOptions: process.env.NODE_ENV !== "development" ?
|
||||||
@@ -303,7 +343,7 @@ export type ProjectConfigOptions = {
|
|||||||
* For a local Redis installation, the connection URL should be `redis://localhost:6379` unless you’ve made any changes to the Redis configuration during installation.
|
* For a local Redis installation, the connection URL should be `redis://localhost:6379` unless you’ve made any changes to the Redis configuration during installation.
|
||||||
*
|
*
|
||||||
* @example
|
* @example
|
||||||
* ```js title="medusa-config.js"
|
* ```js title="medusa-config.ts"
|
||||||
* module.exports = defineConfig({
|
* module.exports = defineConfig({
|
||||||
* projectConfig: {
|
* projectConfig: {
|
||||||
* redisUrl: process.env.REDIS_URL ||
|
* redisUrl: process.env.REDIS_URL ||
|
||||||
@@ -322,7 +362,7 @@ export type ProjectConfigOptions = {
|
|||||||
* If this configuration option is provided, it is prepended to `sess:`.
|
* If this configuration option is provided, it is prepended to `sess:`.
|
||||||
*
|
*
|
||||||
* @example
|
* @example
|
||||||
* ```js title="medusa-config.js"
|
* ```js title="medusa-config.ts"
|
||||||
* module.exports = defineConfig({
|
* module.exports = defineConfig({
|
||||||
* projectConfig: {
|
* projectConfig: {
|
||||||
* redisPrefix: process.env.REDIS_URL || "medusa:",
|
* redisPrefix: process.env.REDIS_URL || "medusa:",
|
||||||
@@ -339,7 +379,7 @@ export type ProjectConfigOptions = {
|
|||||||
* for the list of available options.
|
* for the list of available options.
|
||||||
*
|
*
|
||||||
* @example
|
* @example
|
||||||
* ```js title="medusa-config.js"
|
* ```js title="medusa-config.ts"
|
||||||
* module.exports = defineConfig({
|
* module.exports = defineConfig({
|
||||||
* projectConfig: {
|
* projectConfig: {
|
||||||
* redisOptions: {
|
* redisOptions: {
|
||||||
@@ -358,7 +398,7 @@ export type ProjectConfigOptions = {
|
|||||||
* This configuration defines additional options to pass to [express-session](https://www.npmjs.com/package/express-session), which is used to store the Medusa server's session.
|
* This configuration defines additional options to pass to [express-session](https://www.npmjs.com/package/express-session), which is used to store the Medusa server's session.
|
||||||
*
|
*
|
||||||
* @example
|
* @example
|
||||||
* ```js title="medusa-config.js"
|
* ```js title="medusa-config.ts"
|
||||||
* module.exports = defineConfig({
|
* module.exports = defineConfig({
|
||||||
* projectConfig: {
|
* projectConfig: {
|
||||||
* sessionOptions: {
|
* sessionOptions: {
|
||||||
@@ -376,7 +416,7 @@ export type ProjectConfigOptions = {
|
|||||||
* Configure the number of staged jobs that are polled from the database. Default is `1000`.
|
* Configure the number of staged jobs that are polled from the database. Default is `1000`.
|
||||||
*
|
*
|
||||||
* @example
|
* @example
|
||||||
* ```js title="medusa-config.js"
|
* ```js title="medusa-config.ts"
|
||||||
* module.exports = defineConfig({
|
* module.exports = defineConfig({
|
||||||
* projectConfig: {
|
* projectConfig: {
|
||||||
* jobsBatchSize: 100
|
* jobsBatchSize: 100
|
||||||
@@ -414,7 +454,7 @@ export type ProjectConfigOptions = {
|
|||||||
* 2. Another having the `workerMode` configuration set to `worker`.
|
* 2. Another having the `workerMode` configuration set to `worker`.
|
||||||
*
|
*
|
||||||
* @example
|
* @example
|
||||||
* ```js title="medusa-config.js"
|
* ```js title="medusa-config.ts"
|
||||||
* module.exports = defineConfig({
|
* module.exports = defineConfig({
|
||||||
* projectConfig: {
|
* projectConfig: {
|
||||||
* workerMode: process.env.WORKER_MODE || "shared"
|
* workerMode: process.env.WORKER_MODE || "shared"
|
||||||
@@ -430,7 +470,7 @@ export type ProjectConfigOptions = {
|
|||||||
* This property configures the application's http-specific settings.
|
* This property configures the application's http-specific settings.
|
||||||
*
|
*
|
||||||
* @example
|
* @example
|
||||||
* ```js title="medusa-config.js"
|
* ```js title="medusa-config.ts"
|
||||||
* module.exports = defineConfig({
|
* module.exports = defineConfig({
|
||||||
* projectConfig: {
|
* projectConfig: {
|
||||||
* http: {
|
* http: {
|
||||||
@@ -453,7 +493,7 @@ export type ProjectConfigOptions = {
|
|||||||
* error is thrown and the application crashes.
|
* error is thrown and the application crashes.
|
||||||
*
|
*
|
||||||
* @example
|
* @example
|
||||||
* ```js title="medusa-config.js"
|
* ```js title="medusa-config.ts"
|
||||||
* module.exports = defineConfig({
|
* module.exports = defineConfig({
|
||||||
* projectConfig: {
|
* projectConfig: {
|
||||||
* http: {
|
* http: {
|
||||||
@@ -472,7 +512,7 @@ export type ProjectConfigOptions = {
|
|||||||
* If not provided, the default value is `24h`.
|
* If not provided, the default value is `24h`.
|
||||||
*
|
*
|
||||||
* @example
|
* @example
|
||||||
* ```js title="medusa-config.js"
|
* ```js title="medusa-config.ts"
|
||||||
* module.exports = defineConfig({
|
* module.exports = defineConfig({
|
||||||
* projectConfig: {
|
* projectConfig: {
|
||||||
* http: {
|
* http: {
|
||||||
@@ -492,7 +532,7 @@ export type ProjectConfigOptions = {
|
|||||||
* the application crashes.
|
* the application crashes.
|
||||||
*
|
*
|
||||||
* @example
|
* @example
|
||||||
* ```js title="medusa-config.js"
|
* ```js title="medusa-config.ts"
|
||||||
* module.exports = defineConfig({
|
* module.exports = defineConfig({
|
||||||
* projectConfig: {
|
* projectConfig: {
|
||||||
* http: {
|
* http: {
|
||||||
@@ -529,9 +569,9 @@ export type ProjectConfigOptions = {
|
|||||||
* AUTH_CORS=/http:\/\/.+/
|
* AUTH_CORS=/http:\/\/.+/
|
||||||
* ```
|
* ```
|
||||||
*
|
*
|
||||||
* Then, set the configuration in `medusa-config.js`:
|
* Then, set the configuration in `medusa-config.ts`:
|
||||||
*
|
*
|
||||||
* ```js title="medusa-config.js"
|
* ```js title="medusa-config.ts"
|
||||||
* module.exports = defineConfig({
|
* module.exports = defineConfig({
|
||||||
* projectConfig: {
|
* projectConfig: {
|
||||||
* http: {
|
* http: {
|
||||||
@@ -543,9 +583,9 @@ export type ProjectConfigOptions = {
|
|||||||
* })
|
* })
|
||||||
* ```
|
* ```
|
||||||
*
|
*
|
||||||
* If you’re adding the value directly within `medusa-config.js`, make sure to add an extra escaping `/` for every backslash in the pattern. For example:
|
* If you’re adding the value directly within `medusa-config.ts`, make sure to add an extra escaping `/` for every backslash in the pattern. For example:
|
||||||
*
|
*
|
||||||
* ```js title="medusa-config.js"
|
* ```js title="medusa-config.ts"
|
||||||
* module.exports = defineConfig({
|
* module.exports = defineConfig({
|
||||||
* projectConfig: {
|
* projectConfig: {
|
||||||
* http: {
|
* http: {
|
||||||
@@ -567,7 +607,7 @@ export type ProjectConfigOptions = {
|
|||||||
* Learn more in the [API Reference](https://docs.medusajs.com/api/store#http-compression).
|
* Learn more in the [API Reference](https://docs.medusajs.com/api/store#http-compression).
|
||||||
*
|
*
|
||||||
* @example
|
* @example
|
||||||
* ```js title="medusa-config.js"
|
* ```js title="medusa-config.ts"
|
||||||
* module.exports = defineConfig({
|
* module.exports = defineConfig({
|
||||||
* projectConfig: {
|
* projectConfig: {
|
||||||
* http: {
|
* http: {
|
||||||
@@ -609,9 +649,9 @@ export type ProjectConfigOptions = {
|
|||||||
* STORE_CORS=/http:\/\/.+/
|
* STORE_CORS=/http:\/\/.+/
|
||||||
* ```
|
* ```
|
||||||
*
|
*
|
||||||
* Then, set the configuration in `medusa-config.js`:
|
* Then, set the configuration in `medusa-config.ts`:
|
||||||
*
|
*
|
||||||
* ```js title="medusa-config.js"
|
* ```js title="medusa-config.ts"
|
||||||
* module.exports = defineConfig({
|
* module.exports = defineConfig({
|
||||||
* projectConfig: {
|
* projectConfig: {
|
||||||
* http: {
|
* http: {
|
||||||
@@ -623,9 +663,9 @@ export type ProjectConfigOptions = {
|
|||||||
* })
|
* })
|
||||||
* ```
|
* ```
|
||||||
*
|
*
|
||||||
* If you’re adding the value directly within `medusa-config.js`, make sure to add an extra escaping `/` for every backslash in the pattern. For example:
|
* If you’re adding the value directly within `medusa-config.ts`, make sure to add an extra escaping `/` for every backslash in the pattern. For example:
|
||||||
*
|
*
|
||||||
* ```js title="medusa-config.js"
|
* ```js title="medusa-config.ts"
|
||||||
* module.exports = defineConfig({
|
* module.exports = defineConfig({
|
||||||
* projectConfig: {
|
* projectConfig: {
|
||||||
* http: {
|
* http: {
|
||||||
@@ -663,9 +703,9 @@ export type ProjectConfigOptions = {
|
|||||||
* ADMIN_CORS=/http:\/\/.+/
|
* ADMIN_CORS=/http:\/\/.+/
|
||||||
* ```
|
* ```
|
||||||
*
|
*
|
||||||
* Then, set the configuration in `medusa-config.js`:
|
* Then, set the configuration in `medusa-config.ts`:
|
||||||
*
|
*
|
||||||
* ```js title="medusa-config.js"
|
* ```js title="medusa-config.ts"
|
||||||
* module.exports = defineConfig({
|
* module.exports = defineConfig({
|
||||||
* projectConfig: {
|
* projectConfig: {
|
||||||
* http: {
|
* http: {
|
||||||
@@ -677,9 +717,9 @@ export type ProjectConfigOptions = {
|
|||||||
* })
|
* })
|
||||||
* ```
|
* ```
|
||||||
*
|
*
|
||||||
* If you’re adding the value directly within `medusa-config.js`, make sure to add an extra escaping `/` for every backslash in the pattern. For example:
|
* If you’re adding the value directly within `medusa-config.ts`, make sure to add an extra escaping `/` for every backslash in the pattern. For example:
|
||||||
*
|
*
|
||||||
* ```js title="medusa-config.js"
|
* ```js title="medusa-config.ts"
|
||||||
* module.exports = defineConfig({
|
* module.exports = defineConfig({
|
||||||
* projectConfig: {
|
* projectConfig: {
|
||||||
* http: {
|
* http: {
|
||||||
@@ -702,9 +742,9 @@ export type ProjectConfigOptions = {
|
|||||||
* @example
|
* @example
|
||||||
* Some example values of common use cases:
|
* Some example values of common use cases:
|
||||||
*
|
*
|
||||||
* Then, set the configuration in `medusa-config.js`:
|
* Then, set the configuration in `medusa-config.ts`:
|
||||||
*
|
*
|
||||||
* ```js title="medusa-config.js"
|
* ```js title="medusa-config.ts"
|
||||||
* module.exports = defineConfig({
|
* module.exports = defineConfig({
|
||||||
* projectConfig: {
|
* projectConfig: {
|
||||||
* http: {
|
* http: {
|
||||||
@@ -727,7 +767,7 @@ export type ProjectConfigOptions = {
|
|||||||
*
|
*
|
||||||
* @example
|
* @example
|
||||||
*
|
*
|
||||||
* ```js title="medusa-config.js"
|
* ```js title="medusa-config.ts"
|
||||||
* module.exports = defineConfig({
|
* module.exports = defineConfig({
|
||||||
* projectConfig: {
|
* projectConfig: {
|
||||||
* http: {
|
* http: {
|
||||||
@@ -747,20 +787,27 @@ export type ProjectConfigOptions = {
|
|||||||
/**
|
/**
|
||||||
* @interface
|
* @interface
|
||||||
*
|
*
|
||||||
* The configurations for your Medusa application are in `medusa-config.js` located in the root of your Medusa project. The configurations include configurations for database, modules, and more.
|
* The configurations for your Medusa application are set in `medusa-config.ts` located in the root of your Medusa project. The configurations include configurations for database, modules, and more.
|
||||||
*
|
*
|
||||||
* `medusa-config.js` exports the value returned by the `defineConfig` utility function imported from `@medusajs/utils`.
|
* :::note
|
||||||
|
*
|
||||||
|
* Some Medusa configurations are set through environment variables, which you can find in [this documentation](https://docs.medusajs.com/learn/fundamentals/environment-variables#predefined-medusa-environment-variables).
|
||||||
|
*
|
||||||
|
* :::
|
||||||
|
*
|
||||||
|
* `medusa-config.ts` exports the value returned by the `defineConfig` utility function imported from `@medusajs/framework/utils`.
|
||||||
*
|
*
|
||||||
* `defineConfig` accepts as a parameter an object with the following properties:
|
* `defineConfig` accepts as a parameter an object with the following properties:
|
||||||
*
|
*
|
||||||
* - {@link ConfigModule.projectConfig | projectConfig} (required): An object that holds general configurations related to the Medusa application, such as database or CORS configurations.
|
* - {@link ConfigModule.projectConfig | projectConfig} (required): An object that holds general configurations related to the Medusa application, such as database or CORS configurations.
|
||||||
|
* - {@link ConfigModule.plugins | plugins}: An array of strings or objects that hold the configurations of the plugins installed in the Medusa application.
|
||||||
* - {@link ConfigModule.admin | admin}: An object that holds admin-related configurations.
|
* - {@link ConfigModule.admin | admin}: An object that holds admin-related configurations.
|
||||||
* - {@link ConfigModule.modules | modules}: An object that configures the Medusa application's modules.
|
* - {@link ConfigModule.modules | modules}: An object that configures the Medusa application's modules.
|
||||||
* - {@link ConfigModule.featureFlags | featureFlags}: An object that enables or disables features guarded by a feature flag.
|
* - {@link ConfigModule.featureFlags | featureFlags}: An object that enables or disables features guarded by a feature flag.
|
||||||
*
|
*
|
||||||
* For example:
|
* For example:
|
||||||
*
|
*
|
||||||
* ```js title="medusa-config.js"
|
* ```ts title="medusa-config.ts"
|
||||||
* module.exports = defineConfig({
|
* module.exports = defineConfig({
|
||||||
* projectConfig: {
|
* projectConfig: {
|
||||||
* // ...
|
* // ...
|
||||||
@@ -781,7 +828,7 @@ export type ProjectConfigOptions = {
|
|||||||
*
|
*
|
||||||
* ## Environment Variables
|
* ## Environment Variables
|
||||||
*
|
*
|
||||||
* It's highly recommended to store the values of configurations in environment variables, then reference them within `medusa-config.js`.
|
* It's highly recommended to store the values of configurations in environment variables, then reference them within `medusa-config.ts`.
|
||||||
*
|
*
|
||||||
* During development, you can set your environment variables in the `.env` file at the root of your Medusa application project. In production,
|
* During development, you can set your environment variables in the `.env` file at the root of your Medusa application project. In production,
|
||||||
* setting the environment variables depends on the hosting provider.
|
* setting the environment variables depends on the hosting provider.
|
||||||
@@ -798,7 +845,7 @@ export type ConfigModule = {
|
|||||||
* This property holds configurations for the Medusa Admin dashboard.
|
* This property holds configurations for the Medusa Admin dashboard.
|
||||||
*
|
*
|
||||||
* @example
|
* @example
|
||||||
* ```js title="medusa-config.js"
|
* ```ts title="medusa-config.ts"
|
||||||
* module.exports = defineConfig({
|
* module.exports = defineConfig({
|
||||||
* admin: {
|
* admin: {
|
||||||
* backendUrl: process.env.MEDUSA_BACKEND_URL ||
|
* backendUrl: process.env.MEDUSA_BACKEND_URL ||
|
||||||
@@ -811,20 +858,22 @@ export type ConfigModule = {
|
|||||||
admin: AdminOptions
|
admin: AdminOptions
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* On your Medusa backend, you can use [Plugins](https://docs.medusajs.com/development/plugins/overview) to add custom features or integrate third-party services.
|
* On your Medusa server, you can use [Plugins](https://docs.medusajs.com/learn/fundamentals/plugins) to add re-usable Medusa customizations. Plugins
|
||||||
* For example, installing a plugin to use Stripe as a payment processor.
|
* can include modules, workflows, API Routes, and other customizations. Plugins are available starting from [Medusa v2.3.0](https://github.com/medusajs/medusa/releases/tag/v2.3.0).
|
||||||
*
|
*
|
||||||
* Aside from installing the plugin with NPM, you need to pass the plugin you installed into the `plugins` array defined in `medusa-config.js`.
|
* Aside from installing the plugin with NPM, you need to pass the plugin you installed into the `plugins` array defined in `medusa-config.ts`.
|
||||||
*
|
*
|
||||||
* The items in the array can either be:
|
* The items in the array can either be:
|
||||||
*
|
*
|
||||||
* - A string, which is the name of the plugin to add. You can pass a plugin as a string if it doesn’t require any configurations.
|
* - A string, which is the name of the plugin's package as specified in the plugin's `package.json` file. You can pass a plugin as a string if it doesn’t require any options.
|
||||||
* - An object having the following properties:
|
* - An object having the following properties:
|
||||||
* - `resolve`: The name of the plugin.
|
* - `resolve`: The name of the plugin's package as specified in the plugin's `package.json` file.
|
||||||
* - `options`: An object that includes the plugin’s options. These options vary for each plugin, and you should refer to the plugin’s documentation for available options.
|
* - `options`: An object that includes options to be passed to the modules within the plugin. Learn more in [this documentation](https://docs.medusajs.com/learn/fundamentals/modules/options).
|
||||||
|
*
|
||||||
|
* Learn how to create a plugin in [this documentation](https://docs.medusajs.com/learn/fundamentals/plugins/create).
|
||||||
*
|
*
|
||||||
* @example
|
* @example
|
||||||
* ```js title="medusa-config.js"
|
* ```ts title="medusa-config.ts"
|
||||||
* module.exports = {
|
* module.exports = {
|
||||||
* plugins: [
|
* plugins: [
|
||||||
* `medusa-my-plugin-1`,
|
* `medusa-my-plugin-1`,
|
||||||
@@ -840,15 +889,17 @@ export type ConfigModule = {
|
|||||||
* // ...
|
* // ...
|
||||||
* }
|
* }
|
||||||
* ```
|
* ```
|
||||||
*
|
|
||||||
* @ignore
|
|
||||||
*
|
|
||||||
* @privateRemarks
|
|
||||||
* Added the `@\ignore` tag for now so it's not generated in the main docs until we figure out what to do with plugins
|
|
||||||
*/
|
*/
|
||||||
plugins: (
|
plugins: (
|
||||||
| {
|
| {
|
||||||
|
/**
|
||||||
|
* The name of the plugin's package as specified in the plugin's `package.json` file.
|
||||||
|
*/
|
||||||
resolve: string
|
resolve: string
|
||||||
|
/**
|
||||||
|
* An object that includes options to be passed to the modules within the plugin.
|
||||||
|
* Learn more in [this documentation](https://docs.medusajs.com/learn/fundamentals/modules/options).
|
||||||
|
*/
|
||||||
options: Record<string, unknown>
|
options: Record<string, unknown>
|
||||||
}
|
}
|
||||||
| string
|
| string
|
||||||
@@ -864,21 +915,19 @@ export type ConfigModule = {
|
|||||||
*
|
*
|
||||||
* :::
|
* :::
|
||||||
*
|
*
|
||||||
* The keys of the `modules` configuration object refer to the module's registration name. Its value can be one of the following:
|
* `modules` is an array of objects, each holding a module's registration configurations. Each object has the following properties:
|
||||||
*
|
*
|
||||||
* 1. A boolean value indicating whether the module type is enabled. This is only supported for Medusa's commerce and architectural modules;
|
* 1. `resolve`: a string indicating the path to the module relative to `src`, or the module's NPM package name. For example, `./modules/my-module`.
|
||||||
* 2. Or an object having the following properties:
|
* 2. `options`: (optional) an object indicating the options to pass to the module.
|
||||||
* 1. `resolve`: a string indicating the path to the module relative to `src`, or the module's NPM package name. For example, `./modules/my-module`.
|
|
||||||
* 2. `options`: (optional) an object indicating the options to pass to the module.
|
|
||||||
*
|
*
|
||||||
* @example
|
* @example
|
||||||
* ```js title="medusa-config.js"
|
* ```ts title="medusa-config.ts"
|
||||||
* module.exports = defineConfig({
|
* module.exports = defineConfig({
|
||||||
* modules: {
|
* modules: [
|
||||||
* helloModuleService: {
|
* {
|
||||||
* resolve: "./modules/hello"
|
* resolve: "./modules/hello"
|
||||||
* }
|
* }
|
||||||
* }
|
* ]
|
||||||
* // ...
|
* // ...
|
||||||
* })
|
* })
|
||||||
* ```
|
* ```
|
||||||
@@ -892,14 +941,14 @@ export type ConfigModule = {
|
|||||||
* Some features in the Medusa application are guarded by a feature flag. This ensures constant shipping of new features while maintaining the engine’s stability.
|
* Some features in the Medusa application are guarded by a feature flag. This ensures constant shipping of new features while maintaining the engine’s stability.
|
||||||
*
|
*
|
||||||
* You can enable a feature in your application by enabling its feature flag. Feature flags are enabled through either environment
|
* You can enable a feature in your application by enabling its feature flag. Feature flags are enabled through either environment
|
||||||
* variables or through this configuration property exported in `medusa-config.js`.
|
* variables or through this configuration property exported in `medusa-config.ts`.
|
||||||
*
|
*
|
||||||
* The `featureFlags`'s value is an object. Its properties are the names of the feature flags, and their value is a boolean indicating whether the feature flag is enabled.
|
* The `featureFlags`'s value is an object. Its properties are the names of the feature flags, and their value is a boolean indicating whether the feature flag is enabled.
|
||||||
*
|
*
|
||||||
* You can find available feature flags and their key name [here](https://github.com/medusajs/medusa/tree/develop/packages/medusa/src/loaders/feature-flags).
|
* You can find available feature flags and their key name [here](https://github.com/medusajs/medusa/tree/develop/packages/medusa/src/loaders/feature-flags).
|
||||||
*
|
*
|
||||||
* @example
|
* @example
|
||||||
* ```js title="medusa-config.js"
|
* ```ts title="medusa-config.ts"
|
||||||
* module.exports = defineConfig({
|
* module.exports = defineConfig({
|
||||||
* featureFlags: {
|
* featureFlags: {
|
||||||
* analytics: true,
|
* analytics: true,
|
||||||
@@ -952,7 +1001,7 @@ export type InputConfigModules = Partial<
|
|||||||
*/
|
*/
|
||||||
export type InputConfig = Partial<
|
export type InputConfig = Partial<
|
||||||
Omit<ConfigModule, "admin" | "modules"> & {
|
Omit<ConfigModule, "admin" | "modules"> & {
|
||||||
admin: Partial<ConfigModule["admin"]>
|
admin?: Partial<ConfigModule["admin"]>
|
||||||
modules:
|
modules:
|
||||||
| InputConfigModules
|
| InputConfigModules
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -145,6 +145,7 @@ describe("defineConfig", function () {
|
|||||||
"redisOptions": {
|
"redisOptions": {
|
||||||
"retryStrategy": [Function],
|
"retryStrategy": [Function],
|
||||||
},
|
},
|
||||||
|
"sessionOptions": {},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
`)
|
`)
|
||||||
@@ -304,6 +305,7 @@ describe("defineConfig", function () {
|
|||||||
"redisOptions": {
|
"redisOptions": {
|
||||||
"retryStrategy": [Function],
|
"retryStrategy": [Function],
|
||||||
},
|
},
|
||||||
|
"sessionOptions": {},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
`)
|
`)
|
||||||
@@ -471,6 +473,7 @@ describe("defineConfig", function () {
|
|||||||
"redisOptions": {
|
"redisOptions": {
|
||||||
"retryStrategy": [Function],
|
"retryStrategy": [Function],
|
||||||
},
|
},
|
||||||
|
"sessionOptions": {},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
`)
|
`)
|
||||||
@@ -639,6 +642,7 @@ describe("defineConfig", function () {
|
|||||||
"redisOptions": {
|
"redisOptions": {
|
||||||
"retryStrategy": [Function],
|
"retryStrategy": [Function],
|
||||||
},
|
},
|
||||||
|
"sessionOptions": {},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
`)
|
`)
|
||||||
@@ -795,6 +799,7 @@ describe("defineConfig", function () {
|
|||||||
"redisOptions": {
|
"redisOptions": {
|
||||||
"retryStrategy": [Function],
|
"retryStrategy": [Function],
|
||||||
},
|
},
|
||||||
|
"sessionOptions": {},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
`)
|
`)
|
||||||
@@ -954,6 +959,7 @@ describe("defineConfig", function () {
|
|||||||
"redisOptions": {
|
"redisOptions": {
|
||||||
"retryStrategy": [Function],
|
"retryStrategy": [Function],
|
||||||
},
|
},
|
||||||
|
"sessionOptions": {},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
`)
|
`)
|
||||||
@@ -1147,6 +1153,599 @@ describe("defineConfig", function () {
|
|||||||
"retryStrategy": [Function],
|
"retryStrategy": [Function],
|
||||||
},
|
},
|
||||||
"redisUrl": "redis://localhost:6379",
|
"redisUrl": "redis://localhost:6379",
|
||||||
|
"sessionOptions": {},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
`)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("should include cloud-based config with dynamo db", function () {
|
||||||
|
const originalEnv = { ...process.env }
|
||||||
|
|
||||||
|
process.env.EXECUTION_CONTEXT = "medusa-cloud"
|
||||||
|
process.env.REDIS_URL = "redis://localhost:6379"
|
||||||
|
process.env.S3_FILE_URL = "https://s3.amazonaws.com/medusa-cloud-test"
|
||||||
|
process.env.S3_PREFIX = "test"
|
||||||
|
process.env.S3_REGION = "us-east-1"
|
||||||
|
process.env.S3_BUCKET = "medusa-cloud-test"
|
||||||
|
process.env.S3_ENDPOINT = "https://s3.amazonaws.com"
|
||||||
|
process.env.SESSION_STORE = "dynamodb"
|
||||||
|
const res = defineConfig({})
|
||||||
|
|
||||||
|
process.env = { ...originalEnv }
|
||||||
|
|
||||||
|
expect(res).toMatchInlineSnapshot(`
|
||||||
|
{
|
||||||
|
"admin": {
|
||||||
|
"backendUrl": "/",
|
||||||
|
"path": "/app",
|
||||||
|
},
|
||||||
|
"featureFlags": {},
|
||||||
|
"modules": {
|
||||||
|
"api_key": {
|
||||||
|
"resolve": "@medusajs/medusa/api-key",
|
||||||
|
},
|
||||||
|
"auth": {
|
||||||
|
"options": {
|
||||||
|
"providers": [
|
||||||
|
{
|
||||||
|
"id": "emailpass",
|
||||||
|
"resolve": "@medusajs/medusa/auth-emailpass",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
"resolve": "@medusajs/medusa/auth",
|
||||||
|
},
|
||||||
|
"cache": {
|
||||||
|
"options": {
|
||||||
|
"redisUrl": "redis://localhost:6379",
|
||||||
|
},
|
||||||
|
"resolve": "@medusajs/medusa/cache-redis",
|
||||||
|
},
|
||||||
|
"cart": {
|
||||||
|
"resolve": "@medusajs/medusa/cart",
|
||||||
|
},
|
||||||
|
"currency": {
|
||||||
|
"resolve": "@medusajs/medusa/currency",
|
||||||
|
},
|
||||||
|
"customer": {
|
||||||
|
"resolve": "@medusajs/medusa/customer",
|
||||||
|
},
|
||||||
|
"event_bus": {
|
||||||
|
"options": {
|
||||||
|
"redisUrl": "redis://localhost:6379",
|
||||||
|
},
|
||||||
|
"resolve": "@medusajs/medusa/event-bus-redis",
|
||||||
|
},
|
||||||
|
"file": {
|
||||||
|
"options": {
|
||||||
|
"providers": [
|
||||||
|
{
|
||||||
|
"id": "s3",
|
||||||
|
"options": {
|
||||||
|
"authentication_method": "s3-iam-role",
|
||||||
|
"bucket": "medusa-cloud-test",
|
||||||
|
"endpoint": "https://s3.amazonaws.com",
|
||||||
|
"file_url": "https://s3.amazonaws.com/medusa-cloud-test",
|
||||||
|
"prefix": "test",
|
||||||
|
"region": "us-east-1",
|
||||||
|
},
|
||||||
|
"resolve": "@medusajs/medusa/file-s3",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
"resolve": "@medusajs/medusa/file",
|
||||||
|
},
|
||||||
|
"fulfillment": {
|
||||||
|
"options": {
|
||||||
|
"providers": [
|
||||||
|
{
|
||||||
|
"id": "manual",
|
||||||
|
"resolve": "@medusajs/medusa/fulfillment-manual",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
"resolve": "@medusajs/medusa/fulfillment",
|
||||||
|
},
|
||||||
|
"inventory": {
|
||||||
|
"resolve": "@medusajs/medusa/inventory",
|
||||||
|
},
|
||||||
|
"locking": {
|
||||||
|
"options": {
|
||||||
|
"providers": [
|
||||||
|
{
|
||||||
|
"id": "locking-redis",
|
||||||
|
"is_default": true,
|
||||||
|
"options": {
|
||||||
|
"redisUrl": "redis://localhost:6379",
|
||||||
|
},
|
||||||
|
"resolve": "@medusajs/medusa/locking-redis",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
"resolve": "@medusajs/medusa/locking",
|
||||||
|
},
|
||||||
|
"notification": {
|
||||||
|
"options": {
|
||||||
|
"providers": [
|
||||||
|
{
|
||||||
|
"id": "local",
|
||||||
|
"options": {
|
||||||
|
"channels": [
|
||||||
|
"feed",
|
||||||
|
],
|
||||||
|
"name": "Local Notification Provider",
|
||||||
|
},
|
||||||
|
"resolve": "@medusajs/medusa/notification-local",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
"resolve": "@medusajs/medusa/notification",
|
||||||
|
},
|
||||||
|
"order": {
|
||||||
|
"resolve": "@medusajs/medusa/order",
|
||||||
|
},
|
||||||
|
"payment": {
|
||||||
|
"resolve": "@medusajs/medusa/payment",
|
||||||
|
},
|
||||||
|
"pricing": {
|
||||||
|
"resolve": "@medusajs/medusa/pricing",
|
||||||
|
},
|
||||||
|
"product": {
|
||||||
|
"resolve": "@medusajs/medusa/product",
|
||||||
|
},
|
||||||
|
"promotion": {
|
||||||
|
"resolve": "@medusajs/medusa/promotion",
|
||||||
|
},
|
||||||
|
"region": {
|
||||||
|
"resolve": "@medusajs/medusa/region",
|
||||||
|
},
|
||||||
|
"sales_channel": {
|
||||||
|
"resolve": "@medusajs/medusa/sales-channel",
|
||||||
|
},
|
||||||
|
"stock_location": {
|
||||||
|
"resolve": "@medusajs/medusa/stock-location",
|
||||||
|
},
|
||||||
|
"store": {
|
||||||
|
"resolve": "@medusajs/medusa/store",
|
||||||
|
},
|
||||||
|
"tax": {
|
||||||
|
"resolve": "@medusajs/medusa/tax",
|
||||||
|
},
|
||||||
|
"user": {
|
||||||
|
"options": {
|
||||||
|
"jwt_secret": "supersecret",
|
||||||
|
},
|
||||||
|
"resolve": "@medusajs/medusa/user",
|
||||||
|
},
|
||||||
|
"workflows": {
|
||||||
|
"options": {
|
||||||
|
"redis": {
|
||||||
|
"url": "redis://localhost:6379",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"resolve": "@medusajs/medusa/workflow-engine-redis",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"plugins": [],
|
||||||
|
"projectConfig": {
|
||||||
|
"databaseUrl": "postgres://localhost/medusa-starter-default",
|
||||||
|
"http": {
|
||||||
|
"adminCors": "http://localhost:7000,http://localhost:7001,http://localhost:5173",
|
||||||
|
"authCors": "http://localhost:7000,http://localhost:7001,http://localhost:5173",
|
||||||
|
"cookieSecret": "supersecret",
|
||||||
|
"jwtSecret": "supersecret",
|
||||||
|
"restrictedFields": {
|
||||||
|
"store": [
|
||||||
|
${DEFAULT_STORE_RESTRICTED_FIELDS.map((v) => `"${v}"`).join(
|
||||||
|
",\n "
|
||||||
|
)},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
"storeCors": "http://localhost:8000",
|
||||||
|
},
|
||||||
|
"redisOptions": {
|
||||||
|
"retryStrategy": [Function],
|
||||||
|
},
|
||||||
|
"redisUrl": "redis://localhost:6379",
|
||||||
|
"sessionOptions": {
|
||||||
|
"dynamodbOptions": {
|
||||||
|
"hashKey": "id",
|
||||||
|
"initialized": true,
|
||||||
|
"prefix": "sess:",
|
||||||
|
"readCapacityUnits": 5,
|
||||||
|
"skipThrowMissingSpecialKeys": true,
|
||||||
|
"table": "medusa-sessions",
|
||||||
|
"writeCapacityUnits": 5,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
`)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("should allow overriding cloud-only dynamodb config values via environment variables", function () {
|
||||||
|
const originalEnv = { ...process.env }
|
||||||
|
|
||||||
|
process.env.EXECUTION_CONTEXT = "medusa-cloud"
|
||||||
|
process.env.REDIS_URL = "redis://localhost:6379"
|
||||||
|
process.env.S3_FILE_URL = "https://s3.amazonaws.com/medusa-cloud-test"
|
||||||
|
process.env.S3_PREFIX = "test"
|
||||||
|
process.env.S3_REGION = "us-east-1"
|
||||||
|
process.env.S3_BUCKET = "medusa-cloud-test"
|
||||||
|
process.env.S3_ENDPOINT = "https://s3.amazonaws.com"
|
||||||
|
process.env.SESSION_STORE = "dynamodb"
|
||||||
|
process.env.DYNAMO_DB_SESSIONS_CREATE_TABLE = "true"
|
||||||
|
process.env.DYNAMO_DB_SESSIONS_HASH_KEY = "user_id"
|
||||||
|
process.env.DYNAMO_DB_SESSIONS_PREFIX = "my_session:"
|
||||||
|
process.env.DYNAMO_DB_SESSIONS_TABLE = "test-sessions"
|
||||||
|
process.env.DYNAMO_DB_SESSIONS_READ_UNITS = "10"
|
||||||
|
process.env.DYNAMO_DB_SESSIONS_WRITE_UNITS = "10"
|
||||||
|
const res = defineConfig({})
|
||||||
|
|
||||||
|
process.env = { ...originalEnv }
|
||||||
|
|
||||||
|
expect(res).toMatchInlineSnapshot(`
|
||||||
|
{
|
||||||
|
"admin": {
|
||||||
|
"backendUrl": "/",
|
||||||
|
"path": "/app",
|
||||||
|
},
|
||||||
|
"featureFlags": {},
|
||||||
|
"modules": {
|
||||||
|
"api_key": {
|
||||||
|
"resolve": "@medusajs/medusa/api-key",
|
||||||
|
},
|
||||||
|
"auth": {
|
||||||
|
"options": {
|
||||||
|
"providers": [
|
||||||
|
{
|
||||||
|
"id": "emailpass",
|
||||||
|
"resolve": "@medusajs/medusa/auth-emailpass",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
"resolve": "@medusajs/medusa/auth",
|
||||||
|
},
|
||||||
|
"cache": {
|
||||||
|
"options": {
|
||||||
|
"redisUrl": "redis://localhost:6379",
|
||||||
|
},
|
||||||
|
"resolve": "@medusajs/medusa/cache-redis",
|
||||||
|
},
|
||||||
|
"cart": {
|
||||||
|
"resolve": "@medusajs/medusa/cart",
|
||||||
|
},
|
||||||
|
"currency": {
|
||||||
|
"resolve": "@medusajs/medusa/currency",
|
||||||
|
},
|
||||||
|
"customer": {
|
||||||
|
"resolve": "@medusajs/medusa/customer",
|
||||||
|
},
|
||||||
|
"event_bus": {
|
||||||
|
"options": {
|
||||||
|
"redisUrl": "redis://localhost:6379",
|
||||||
|
},
|
||||||
|
"resolve": "@medusajs/medusa/event-bus-redis",
|
||||||
|
},
|
||||||
|
"file": {
|
||||||
|
"options": {
|
||||||
|
"providers": [
|
||||||
|
{
|
||||||
|
"id": "s3",
|
||||||
|
"options": {
|
||||||
|
"authentication_method": "s3-iam-role",
|
||||||
|
"bucket": "medusa-cloud-test",
|
||||||
|
"endpoint": "https://s3.amazonaws.com",
|
||||||
|
"file_url": "https://s3.amazonaws.com/medusa-cloud-test",
|
||||||
|
"prefix": "test",
|
||||||
|
"region": "us-east-1",
|
||||||
|
},
|
||||||
|
"resolve": "@medusajs/medusa/file-s3",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
"resolve": "@medusajs/medusa/file",
|
||||||
|
},
|
||||||
|
"fulfillment": {
|
||||||
|
"options": {
|
||||||
|
"providers": [
|
||||||
|
{
|
||||||
|
"id": "manual",
|
||||||
|
"resolve": "@medusajs/medusa/fulfillment-manual",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
"resolve": "@medusajs/medusa/fulfillment",
|
||||||
|
},
|
||||||
|
"inventory": {
|
||||||
|
"resolve": "@medusajs/medusa/inventory",
|
||||||
|
},
|
||||||
|
"locking": {
|
||||||
|
"options": {
|
||||||
|
"providers": [
|
||||||
|
{
|
||||||
|
"id": "locking-redis",
|
||||||
|
"is_default": true,
|
||||||
|
"options": {
|
||||||
|
"redisUrl": "redis://localhost:6379",
|
||||||
|
},
|
||||||
|
"resolve": "@medusajs/medusa/locking-redis",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
"resolve": "@medusajs/medusa/locking",
|
||||||
|
},
|
||||||
|
"notification": {
|
||||||
|
"options": {
|
||||||
|
"providers": [
|
||||||
|
{
|
||||||
|
"id": "local",
|
||||||
|
"options": {
|
||||||
|
"channels": [
|
||||||
|
"feed",
|
||||||
|
],
|
||||||
|
"name": "Local Notification Provider",
|
||||||
|
},
|
||||||
|
"resolve": "@medusajs/medusa/notification-local",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
"resolve": "@medusajs/medusa/notification",
|
||||||
|
},
|
||||||
|
"order": {
|
||||||
|
"resolve": "@medusajs/medusa/order",
|
||||||
|
},
|
||||||
|
"payment": {
|
||||||
|
"resolve": "@medusajs/medusa/payment",
|
||||||
|
},
|
||||||
|
"pricing": {
|
||||||
|
"resolve": "@medusajs/medusa/pricing",
|
||||||
|
},
|
||||||
|
"product": {
|
||||||
|
"resolve": "@medusajs/medusa/product",
|
||||||
|
},
|
||||||
|
"promotion": {
|
||||||
|
"resolve": "@medusajs/medusa/promotion",
|
||||||
|
},
|
||||||
|
"region": {
|
||||||
|
"resolve": "@medusajs/medusa/region",
|
||||||
|
},
|
||||||
|
"sales_channel": {
|
||||||
|
"resolve": "@medusajs/medusa/sales-channel",
|
||||||
|
},
|
||||||
|
"stock_location": {
|
||||||
|
"resolve": "@medusajs/medusa/stock-location",
|
||||||
|
},
|
||||||
|
"store": {
|
||||||
|
"resolve": "@medusajs/medusa/store",
|
||||||
|
},
|
||||||
|
"tax": {
|
||||||
|
"resolve": "@medusajs/medusa/tax",
|
||||||
|
},
|
||||||
|
"user": {
|
||||||
|
"options": {
|
||||||
|
"jwt_secret": "supersecret",
|
||||||
|
},
|
||||||
|
"resolve": "@medusajs/medusa/user",
|
||||||
|
},
|
||||||
|
"workflows": {
|
||||||
|
"options": {
|
||||||
|
"redis": {
|
||||||
|
"url": "redis://localhost:6379",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"resolve": "@medusajs/medusa/workflow-engine-redis",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"plugins": [],
|
||||||
|
"projectConfig": {
|
||||||
|
"databaseUrl": "postgres://localhost/medusa-starter-default",
|
||||||
|
"http": {
|
||||||
|
"adminCors": "http://localhost:7000,http://localhost:7001,http://localhost:5173",
|
||||||
|
"authCors": "http://localhost:7000,http://localhost:7001,http://localhost:5173",
|
||||||
|
"cookieSecret": "supersecret",
|
||||||
|
"jwtSecret": "supersecret",
|
||||||
|
"restrictedFields": {
|
||||||
|
"store": [
|
||||||
|
${DEFAULT_STORE_RESTRICTED_FIELDS.map((v) => `"${v}"`).join(
|
||||||
|
",\n "
|
||||||
|
)},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
"storeCors": "http://localhost:8000",
|
||||||
|
},
|
||||||
|
"redisOptions": {
|
||||||
|
"retryStrategy": [Function],
|
||||||
|
},
|
||||||
|
"redisUrl": "redis://localhost:6379",
|
||||||
|
"sessionOptions": {
|
||||||
|
"dynamodbOptions": {
|
||||||
|
"hashKey": "user_id",
|
||||||
|
"initialized": false,
|
||||||
|
"prefix": "my_session:",
|
||||||
|
"readCapacityUnits": 10,
|
||||||
|
"skipThrowMissingSpecialKeys": true,
|
||||||
|
"table": "test-sessions",
|
||||||
|
"writeCapacityUnits": 10,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
`)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("should allow custom dynamodb config", function () {
|
||||||
|
expect(
|
||||||
|
defineConfig({
|
||||||
|
projectConfig: {
|
||||||
|
http: {
|
||||||
|
adminCors: "http://localhost:3000",
|
||||||
|
} as any,
|
||||||
|
sessionOptions: {
|
||||||
|
dynamodbOptions: {
|
||||||
|
clientOptions: {
|
||||||
|
endpoint: "http://localhost:8000",
|
||||||
|
},
|
||||||
|
table: "medusa-sessions",
|
||||||
|
writeCapacityUnits: 25,
|
||||||
|
readCapacityUnits: 25,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
).toMatchInlineSnapshot(`
|
||||||
|
{
|
||||||
|
"admin": {
|
||||||
|
"backendUrl": "/",
|
||||||
|
"path": "/app",
|
||||||
|
},
|
||||||
|
"featureFlags": {},
|
||||||
|
"modules": {
|
||||||
|
"api_key": {
|
||||||
|
"resolve": "@medusajs/medusa/api-key",
|
||||||
|
},
|
||||||
|
"auth": {
|
||||||
|
"options": {
|
||||||
|
"providers": [
|
||||||
|
{
|
||||||
|
"id": "emailpass",
|
||||||
|
"resolve": "@medusajs/medusa/auth-emailpass",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
"resolve": "@medusajs/medusa/auth",
|
||||||
|
},
|
||||||
|
"cache": {
|
||||||
|
"resolve": "@medusajs/medusa/cache-inmemory",
|
||||||
|
},
|
||||||
|
"cart": {
|
||||||
|
"resolve": "@medusajs/medusa/cart",
|
||||||
|
},
|
||||||
|
"currency": {
|
||||||
|
"resolve": "@medusajs/medusa/currency",
|
||||||
|
},
|
||||||
|
"customer": {
|
||||||
|
"resolve": "@medusajs/medusa/customer",
|
||||||
|
},
|
||||||
|
"event_bus": {
|
||||||
|
"resolve": "@medusajs/medusa/event-bus-local",
|
||||||
|
},
|
||||||
|
"file": {
|
||||||
|
"options": {
|
||||||
|
"providers": [
|
||||||
|
{
|
||||||
|
"id": "local",
|
||||||
|
"resolve": "@medusajs/medusa/file-local",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
"resolve": "@medusajs/medusa/file",
|
||||||
|
},
|
||||||
|
"fulfillment": {
|
||||||
|
"options": {
|
||||||
|
"providers": [
|
||||||
|
{
|
||||||
|
"id": "manual",
|
||||||
|
"resolve": "@medusajs/medusa/fulfillment-manual",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
"resolve": "@medusajs/medusa/fulfillment",
|
||||||
|
},
|
||||||
|
"inventory": {
|
||||||
|
"resolve": "@medusajs/medusa/inventory",
|
||||||
|
},
|
||||||
|
"locking": {
|
||||||
|
"resolve": "@medusajs/medusa/locking",
|
||||||
|
},
|
||||||
|
"notification": {
|
||||||
|
"options": {
|
||||||
|
"providers": [
|
||||||
|
{
|
||||||
|
"id": "local",
|
||||||
|
"options": {
|
||||||
|
"channels": [
|
||||||
|
"feed",
|
||||||
|
],
|
||||||
|
"name": "Local Notification Provider",
|
||||||
|
},
|
||||||
|
"resolve": "@medusajs/medusa/notification-local",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
"resolve": "@medusajs/medusa/notification",
|
||||||
|
},
|
||||||
|
"order": {
|
||||||
|
"resolve": "@medusajs/medusa/order",
|
||||||
|
},
|
||||||
|
"payment": {
|
||||||
|
"resolve": "@medusajs/medusa/payment",
|
||||||
|
},
|
||||||
|
"pricing": {
|
||||||
|
"resolve": "@medusajs/medusa/pricing",
|
||||||
|
},
|
||||||
|
"product": {
|
||||||
|
"resolve": "@medusajs/medusa/product",
|
||||||
|
},
|
||||||
|
"promotion": {
|
||||||
|
"resolve": "@medusajs/medusa/promotion",
|
||||||
|
},
|
||||||
|
"region": {
|
||||||
|
"resolve": "@medusajs/medusa/region",
|
||||||
|
},
|
||||||
|
"sales_channel": {
|
||||||
|
"resolve": "@medusajs/medusa/sales-channel",
|
||||||
|
},
|
||||||
|
"stock_location": {
|
||||||
|
"resolve": "@medusajs/medusa/stock-location",
|
||||||
|
},
|
||||||
|
"store": {
|
||||||
|
"resolve": "@medusajs/medusa/store",
|
||||||
|
},
|
||||||
|
"tax": {
|
||||||
|
"resolve": "@medusajs/medusa/tax",
|
||||||
|
},
|
||||||
|
"user": {
|
||||||
|
"options": {
|
||||||
|
"jwt_secret": "supersecret",
|
||||||
|
},
|
||||||
|
"resolve": "@medusajs/medusa/user",
|
||||||
|
},
|
||||||
|
"workflows": {
|
||||||
|
"resolve": "@medusajs/medusa/workflow-engine-inmemory",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"plugins": [],
|
||||||
|
"projectConfig": {
|
||||||
|
"databaseUrl": "postgres://localhost/medusa-starter-default",
|
||||||
|
"http": {
|
||||||
|
"adminCors": "http://localhost:3000",
|
||||||
|
"authCors": "http://localhost:7000,http://localhost:7001,http://localhost:5173",
|
||||||
|
"cookieSecret": "supersecret",
|
||||||
|
"jwtSecret": "supersecret",
|
||||||
|
"restrictedFields": {
|
||||||
|
"store": [
|
||||||
|
${DEFAULT_STORE_RESTRICTED_FIELDS.map((v) => `"${v}"`).join(
|
||||||
|
",\n "
|
||||||
|
)},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
"storeCors": "http://localhost:8000",
|
||||||
|
},
|
||||||
|
"redisOptions": {
|
||||||
|
"retryStrategy": [Function],
|
||||||
|
},
|
||||||
|
"sessionOptions": {
|
||||||
|
"dynamodbOptions": {
|
||||||
|
"clientOptions": {
|
||||||
|
"endpoint": "http://localhost:8000",
|
||||||
|
},
|
||||||
|
"readCapacityUnits": 25,
|
||||||
|
"table": "medusa-sessions",
|
||||||
|
"writeCapacityUnits": 25,
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
`)
|
`)
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import {
|
|||||||
} from "../modules-sdk"
|
} from "../modules-sdk"
|
||||||
import { isObject } from "./is-object"
|
import { isObject } from "./is-object"
|
||||||
import { isString } from "./is-string"
|
import { isString } from "./is-string"
|
||||||
|
import { tryConvertToNumber } from "./try-convert-to-number"
|
||||||
import { normalizeImportPathWithSource } from "./normalize-import-path-with-source"
|
import { normalizeImportPathWithSource } from "./normalize-import-path-with-source"
|
||||||
import { resolveExports } from "./resolve-exports"
|
import { resolveExports } from "./resolve-exports"
|
||||||
|
|
||||||
@@ -310,7 +311,8 @@ function normalizeProjectConfig(
|
|||||||
projectConfig: InputConfig["projectConfig"],
|
projectConfig: InputConfig["projectConfig"],
|
||||||
{ isCloud }: { isCloud: boolean }
|
{ isCloud }: { isCloud: boolean }
|
||||||
): ConfigModule["projectConfig"] {
|
): ConfigModule["projectConfig"] {
|
||||||
const { http, redisOptions, ...restOfProjectConfig } = projectConfig || {}
|
const { http, redisOptions, sessionOptions, ...restOfProjectConfig } =
|
||||||
|
projectConfig || {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The defaults to use for the project config. They are shallow merged
|
* The defaults to use for the project config. They are shallow merged
|
||||||
@@ -347,8 +349,32 @@ function normalizeProjectConfig(
|
|||||||
},
|
},
|
||||||
...redisOptions,
|
...redisOptions,
|
||||||
},
|
},
|
||||||
|
sessionOptions: {
|
||||||
|
...(isCloud && process.env.SESSION_STORE === "dynamodb"
|
||||||
|
? {
|
||||||
|
dynamodbOptions: {
|
||||||
|
prefix: process.env.DYNAMO_DB_SESSIONS_PREFIX ?? "sess:",
|
||||||
|
hashKey: process.env.DYNAMO_DB_SESSIONS_HASH_KEY ?? "id",
|
||||||
|
initialized: process.env.DYNAMO_DB_SESSIONS_CREATE_TABLE
|
||||||
|
? false
|
||||||
|
: true,
|
||||||
|
table: process.env.DYNAMO_DB_SESSIONS_TABLE ?? "medusa-sessions",
|
||||||
|
readCapacityUnits: tryConvertToNumber(
|
||||||
|
process.env.DYNAMO_DB_SESSIONS_READ_UNITS,
|
||||||
|
5
|
||||||
|
),
|
||||||
|
writeCapacityUnits: tryConvertToNumber(
|
||||||
|
process.env.DYNAMO_DB_SESSIONS_WRITE_UNITS,
|
||||||
|
5
|
||||||
|
),
|
||||||
|
skipThrowMissingSpecialKeys: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
: {}),
|
||||||
|
...sessionOptions,
|
||||||
|
},
|
||||||
...restOfProjectConfig,
|
...restOfProjectConfig,
|
||||||
}
|
} satisfies ConfigModule["projectConfig"]
|
||||||
}
|
}
|
||||||
|
|
||||||
function normalizeAdminConfig(
|
function normalizeAdminConfig(
|
||||||
|
|||||||
@@ -80,6 +80,7 @@ export * from "./to-handle"
|
|||||||
export * from "./to-kebab-case"
|
export * from "./to-kebab-case"
|
||||||
export * from "./to-pascal-case"
|
export * from "./to-pascal-case"
|
||||||
export * from "./to-unix-slash"
|
export * from "./to-unix-slash"
|
||||||
|
export * from "./try-convert-to-number"
|
||||||
export * from "./trim-zeros"
|
export * from "./trim-zeros"
|
||||||
export * from "./unflatten-object-keys"
|
export * from "./unflatten-object-keys"
|
||||||
export * from "./upper-case-first"
|
export * from "./upper-case-first"
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
/**
|
||||||
|
* Transforms a value to number or returns the default value
|
||||||
|
* when original value cannot be casted to number
|
||||||
|
*/
|
||||||
|
export function tryConvertToNumber(value: unknown): number | undefined
|
||||||
|
export function tryConvertToNumber<T>(
|
||||||
|
value: unknown,
|
||||||
|
defaultValue: T
|
||||||
|
): number | T
|
||||||
|
export function tryConvertToNumber<T>(
|
||||||
|
value: unknown,
|
||||||
|
defaultValue?: T
|
||||||
|
): number | undefined | T {
|
||||||
|
const transformedValue = Number(value)
|
||||||
|
return Number.isNaN(transformedValue)
|
||||||
|
? defaultValue ?? undefined
|
||||||
|
: transformedValue
|
||||||
|
}
|
||||||
Reference in new issue
Block a user