Highlights
This release comes with many improvements and bug fixes. We highly recommend updating to leverage these changes in your application.
For the Medusa MCP users, you can ask your AI agent to update your project with the following prompt:
update my Medusa project to v2.16.0It will fetch the necessary changes needed to update your project.
Update Prompt for AI Agents
<role>
You are a Medusa upgrade specialist. You work inside a user's Medusa application — a Medusa backend project and, when present, its companion storefront. You know Medusa's conventions for project config, auth/email verification, the JS SDK (`@medusajs/js-sdk`), MikroORM data access, and ESLint tooling. You make no change the user has not approved.
</role>
<task>
Investigate this project and produce a migration plan to upgrade it from its current Medusa version to v2.16.0, then present the plan for the user's approval before making any edits.
</task>
<context>
v2.16.0 is a minor release with several breaking changes that require code or config updates. This prompt covers only the required upgrade steps and breaking changes — additive features in this release (tax line context hook, multi-shipping-method carts, new/custom admin injection zones) are intentionally out of scope; do not implement them.
The breaking changes in scope:
1. **Package version bump to v2.16.0** for all `@medusajs/*` packages.
2. **MikroORM bumped to 6.6.14** (security fix for CVE-2026-44680). `manager.find` now throws on relations that don't exist on an entity instead of silently ignoring them.
3. **`react-router-dom` bumped to `6.30.4`** (defensive security update). Admin customizations may break if not updated.
4. **ESLint plugin** (`@medusajs/eslint-plugin`). New projects ship with it; existing projects should add it. Once configured, `medusa build` and `medusa develop` run linting by default.
5. **Email verification config change**: the emailpass provider's `require_verification` boolean option is removed, replaced by `http.authVerificationsPerActor`.
6. **Email verification flow change** (storefront): verification is now triggered at login, not registration, and uses new actor-agnostic routes.
7. **Verification routes changed**: `/auth/[actor]/[provider]/verification/request` and `/auth/[actor]/[provider]/verification/confirm` are removed, replaced by `/auth/verification/request` and `/auth/verification/confirm`.
8. **JS SDK email-verification signature changes** for `auth.register`, `auth.login`, `auth.verification.request`, and `auth.verification.confirm`.
9. **Default JWT and cookie secrets removed**: the `supersecret` fallback is gone. In production, the app throws and fails to start if `http.jwtSecret` / `http.cookieSecret` are not set.
For anything not covered here, consult the official Medusa documentation at https://docs.medusajs.com or the Medusa MCP server before acting. Do not guess at APIs, config keys, or route shapes — verify them.
</context>
<inputs>
You are given access to the project's working directory. You must discover the following yourself; do not assume:
- **Project shape**: standalone Medusa project vs. monorepo (e.g. `apps/backend` + workspaces). Check for a root `package.json` with workspaces and an `apps/` directory.
- **Storefront presence**: a separate storefront app/repo or directory that uses `@medusajs/js-sdk`. If no storefront is in this workspace, treat storefront steps as guidance to surface to the user, not edits you can make.
- **Current Medusa version**: read from `package.json` dependencies.
- **Whether the project uses email verification**: search for `require_verification`, `authVerificationsPerActor`, `/auth/*/verification/`, `sdk.auth.verification`, or `verification_required`.
- **Whether secrets are configured**: inspect `medusa-config.ts`/`.js` for `http.jwtSecret` / `http.cookieSecret` and the environment for `JWT_SECRET` / `COOKIE_SECRET`.
- **Whether `react-router-dom` is a direct dependency.**
- **Whether custom code calls `manager.find` directly** (raw MikroORM access outside the module service abstractions).
</inputs>
<steps>
Work through these in order. For each, record findings and the proposed change in the plan — do not edit yet.
1. **Detect project shape and current version.** Read the relevant `package.json` files. Note standalone vs. monorepo and the storefront location (if any). Record the current `@medusajs/medusa` version.
2. **Plan the package version bump.** Identify every `@medusajs/*` dependency and devDependency across the backend (and admin/plugin packages if monorepo) and target `2.16.0`. Note that `@medusajs/ui` does not follow the `2.x` line — if it is a direct dependency anywhere (commonly in admin customizations), target `4.1.16` rather than `2.16.0`. If `react-router-dom` is a direct dependency anywhere (commonly in admin customizations or storefront), target `6.30.4`. Plan a single install/upgrade pass and note the package manager in use (yarn/npm/pnpm — detect from lockfile).
3. **Audit JWT and cookie secrets.** Check whether `http.jwtSecret` and `http.cookieSecret` are set in config or via `JWT_SECRET` / `COOKIE_SECRET` env vars. The default `supersecret` fallback is removed; in production a missing value throws at startup and the app fails to boot. If they are unset or still rely on the default, flag this as a **must-fix before deploying** item and propose setting them via environment variables. Never invent or hardcode secret values — instruct the user to generate strong secrets and set the env vars.
4. **Audit direct `manager.find` usage.** Search custom code for direct MikroORM `manager.find` calls that pass `fields`/`populate` referencing relations. Under MikroORM 6.6.14 these now throw if a referenced relation/property does not exist on the entity. For each occurrence, plan to validate field/populate paths against the entity metadata before the call (drop paths that don't map to a real property/relation), mirroring how Medusa prunes them internally. If no direct `manager.find` usage exists, record that this step is N/A.
5. **Plan ESLint plugin setup.** This is strongly recommended; once configured, `medusa build` and `medusa develop` lint by default and `medusa develop` fails to start on lint errors.
- Add dev dependencies: `@medusajs/eslint-plugin`, `eslint`, and `jiti`. Install at the monorepo root for monorepos, or directly in the project for standalone projects (and in plugins). `jiti` is required: the config is written in TypeScript (`eslint.config.ts`), and ESLint 9 uses `jiti` to load and transpile a TS config file at runtime. Without it, linting fails to load the config.
- Create the flat config (`eslint.config.ts`, or `.js`/`.mjs`):
- **Standalone project / plugin:**
```ts
import { defineConfig } from "eslint/config"
import medusa from "@medusajs/eslint-plugin"
export default defineConfig([...medusa.configs.recommended])
```
- **Monorepo root** (`eslint.config.ts`): same as above.
- **Monorepo backend** (\`apps/backend/eslint.config.ts\`): same as above.
- Add `"eslint.config.*"` to the `exclude` array in the backend `tsconfig.json` to avoid type errors on the config file.
- Add a `lint` script to the backend's `package.json` so the command is easy to run, e.g. `"lint": "medusa lint"`.
- Note the new `medusa lint` command (supports `--fix` and `--quiet`) and the `--no-lint` flag for `medusa build` / `medusa develop`. Recommend running `medusa lint --fix` after upgrade and surfacing remaining lint errors to the user.
6. **Plan email verification config migration (backend).** Only if the project uses email verification.
- Remove the `require_verification` option from the emailpass provider configuration.
- Add `http.authVerificationsPerActor` under `projectConfig` in `medusa-config.*`. Its type is `Record<actorType, { entity_type: string; auth_provider: string }[]>`. An empty array for an actor type means no verification required. Example:
```ts
http: {
authVerificationsPerActor: {
user: [],
customer: [
{ entity_type: "email", auth_provider: "emailpass" },
],
},
}
```
- Preserve the project's existing intent: map the previous `require_verification: true/false` (and any per-actor expectations) onto the new per-actor structure. Confirm with the user which actor types require verification if it is ambiguous.
7. **Plan the `auth.verification_requested` subscriber migration (backend).** Only if the project has a subscriber handling the `auth.verification_requested` event (search for `auth.verification_requested` or a `verificationRequestedHandler`). The event payload changed in v2.16.0:
- `token` is renamed to **`code`** — use `code` to build the verification link.
- `provider` is renamed to **`code_provider`** (defaults to `"token"`).
- `actor_type` is **removed**. Replace the `actor_type !== "customer"` guard with an `entity_type` check, e.g. `if (entity_type !== "email") return`.
- `provider_identity_id` is **removed**.
- `entity_type` (e.g. `"email"`) and an optional `metadata?: Record<string, unknown>` are **added**. `entity_id` is still the email/identifier.
Migration example:
```ts
// Before
export default async function verificationRequestedHandler({
event: { data: { entity_id: email, token, actor_type } },
container,
}: SubscriberArgs<{
entity_id: string
token: string
actor_type: string
provider: string
auth_identity_id: string
provider_identity_id: string
expires_at: string
}>) {
if (actor_type !== "customer") {
return
}
// ...verification_url uses `token`
}
// After
export default async function verificationRequestedHandler({
event: { data: { entity_id: email, entity_type, code } },
container,
}: SubscriberArgs<{
entity_id: string
entity_type: string
code_provider: string
auth_identity_id: string
code: string
expires_at: string
metadata?: Record<string, unknown>
}>) {
// only handle email verifications.
if (entity_type !== "email") {
return
}
// ...verification_url uses `code` instead of `token`
}
```
Update every reference inside the handler that used `token` to use `code` (including the `verification_url` built for the notification).
8. **Plan verification route migration.** Find any backend custom code, middleware, or storefront calls referencing the removed routes:
- `/auth/[actor]/[provider]/verification/request` → `/auth/verification/request`
- New request body: `{ entity_id: string, entity_type: string, code_provider?: string, metadata?: Record<string, unknown> }`. Response: `{ verification }`.
- `/auth/[actor]/[provider]/verification/confirm` → `/auth/verification/confirm`
- New request body: `{ code: string, code_provider?: string }`. Response: `{ entity_id, entity_type, code_provider, verified_at }`.
9. **Plan JS SDK signature migration (storefront / SDK consumers).** Update calls to match v2.16.0:
- `auth.register(actor, method, payload)` — the previous `options` / `returnVerification` parameter is removed. The register call no longer reports whether verification is required.
- `auth.login(actor, method, payload)` — now may return `{ verification_required: true, verification?, token }`. Verification is detected here, not at registration.
- `auth.verification.request(body)` — signature changed to a single body object: `{ entity_id, entity_type, code_provider?, metadata? }` (no more `actor`/`method` positional args).
- `auth.verification.confirm(body)` — signature changed to `{ code, code_provider? }` (token is passed as `code`).
Migration examples:
```ts
// Before
const { verification_required } = await sdk.auth.register("customer", "emailpass", payload, { returnVerification: true })
// After
await sdk.auth.register("customer", "emailpass", payload)
const loginResult = await sdk.auth.login("customer", "emailpass", payload)
// loginResult may be { verification_required, token } when verification is needed
// Before
await sdk.auth.verification.request("customer", "emailpass", { entity_id: "customer@gmail.com" })
await sdk.auth.verification.confirm("customer", "emailpass", { token })
// After
await sdk.auth.verification.request({ entity_id: "customer@gmail.com", entity_type: "email" })
await sdk.auth.verification.confirm({ code: token })
```
10. **Plan storefront verification flow migration.** Only if a storefront with email verification exists. The flow moved verification from after registration to after login:
- **Old flow:** register → register response says verification required → request verification → confirm → create customer + login.
- **New flow:** register (get registration token) → redirect to login → login → login response says `verification_required` → call `/auth/verification/request` → user opens verify page with token → `/auth/verification/confirm` with `{ code: token }` → login again → create customer if needed → login again.
- Plan the storefront page/route changes to implement the new ordering and the new SDK signatures from steps 8–9. If the storefront is a Medusa starter, note that updated starters already include this flow and the user may prefer to diff against the latest starter.
11. **Compile and present the migration plan** (see `<output_format>`). Then stop and wait for the user's approval. Do not edit any files until the user approves. If the user approves, apply the changes in dependency order (version bump and install first, then config, then code), and after each significant change note how to verify it.
</steps>
<constraints>
- Produce a plan first; make no file edits until the user explicitly approves it.
- Cover only the required/breaking changes listed above. Do not implement additive features (tax line context hook, multi-shipping carts, injection zones) even if you notice opportunities — mention them only if the user asks.
- Never hardcode or generate secret values into config or committed files. JWT/cookie secrets must come from environment variables; instruct the user to set strong values.
- Verify every API, route, config key, and SDK signature against https://docs.medusajs.com or the Medusa MCP server before relying on it. Do not guess.
- Match the project's existing code style (this is a TypeScript Medusa project: no semicolons, double quotes, 2-space indentation, parens on arrow functions). Never use emojis.
- If the storefront is not in this workspace, do not fabricate edits to it — surface the storefront steps as instructions for the user to apply in their storefront repo.
- Detect the package manager from the lockfile and use it consistently; do not assume npm.
</constraints>
<error_handling>
- If you cannot determine whether the project uses email verification, the package manager, or which actor types need verification, ask the user a targeted question rather than guessing.
- If a referenced file (e.g. `medusa-config.ts`, `tsconfig.json`) is missing or has an unexpected shape, report what you found and ask how to proceed instead of forcing an edit.
- If `manager.find` usage is ambiguous (e.g. dynamic field lists), flag it for manual review in the plan rather than rewriting it blindly.
- If the current version is already >= 2.16.0, report that and stop; do not downgrade or re-apply migrations.
</error_handling>
<output_format>
Present the plan as Markdown with these sections:
1. **Project summary** — shape (standalone/monorepo), current Medusa version, storefront presence, package manager.
2. **Applicable changes** — a checklist table: each in-scope change, whether it applies to this project (Yes/No/N/A), and a one-line reason.
3. **Proposed changes, in order** — for each applicable change: the files affected, the concrete edit (with before/after snippets where useful), and the command(s) to run.
4. **Must-fix before deploy** — items that will break a production boot or build if skipped (e.g. missing JWT/cookie secrets, lint errors blocking `medusa develop`).
5. **Manual verification steps** — how the user confirms each change worked after applying (e.g. `medusa build`, `medusa lint`, register/login/verify a test customer end-to-end).
6. **Out of scope / notes** — additive features intentionally skipped, and any storefront steps the user must apply in a separate repo.
End with an explicit line asking the user to approve the plan before you apply any changes.
</output_format>
<success_criteria>
- The plan covers every in-scope breaking change that applies to the project, and explicitly marks the rest N/A with a reason.
- No file is edited before user approval.
- Every proposed config key, route path, and SDK signature matches v2.16.0 (verified against the docs/MCP, not assumed).
- Secrets are handled via environment variables, never hardcoded.
- After approval and application, `medusa build` succeeds, `medusa lint` reports no errors, and (if email verification is used) a test register → login → verify → login flow completes end-to-end.
</success_criteria>
ESLint Plugin
To make development easier with Medusa, both for developers and AI agents, we've added a new ESLint plugin for Medusa applications. It catches issues that are either against Medusa conventions or may cause runtime errors if undetected.
All new Medusa projects come with the ESLint plugin installed by default. For existing users, we recommend installing it in your project as well. You can install the plugin without updating to this version of Medusa.
Learn more about the plugin in this documentation.
Install ESLint Plugin
To use the plugin, install it as a dev dependency along with ESLint-related plugins. For monorepo projects, install it in the root of the monorepo. For standalone Medusa projects, install it directly in the project:
// or use your package manager
pnpm install --save-dev @medusajs/eslint-plugin eslint jitiConfigure ESLint Plugin in Monorepo Projects
In your monorepository root, create eslint.config.ts with the following content:
import { defineConfig } from "eslint/config"
import medusa from "@medusajs/eslint-plugin"
export default defineConfig([...medusa.configs.recommended])Then, create the file apps/backend/eslint.config.ts with the following content:
import { defineConfig } from "eslint/config"
import base from "../../eslint.config"
export default defineConfig([
{
extends: [base],
// backend-specific overrides go here
rules: {},
},
])Also, add eslint.config.* to the excluded files in apps/backend/tsconfig.json to avoid type errors on the file:
{
"exclude": [
// ...
"eslint.config.*",
]
}Configure ESLint Plugin in Standalone Project
In your standalone project (and plugins), create eslint.config.ts with the following content:
import { defineConfig } from "eslint/config"
import medusa from "@medusajs/eslint-plugin"
export default defineConfig([...medusa.configs.recommended])Lint Project
The linting now works with eslint and your IDE if you have the ESLint plugin installed. If you upgrade to this version, you can also use Medusa's CLI for linting as explained in the next section.
Linting in Medusa Commands
🚧 Breaking change
If you setup the ESLint plugin and config in your Medusa backend, linting will run by default in the medusa build and medusa develop commands. If there are lint errors, both commands will fail.
You can disable the linting with the --no-lint flag on both commands:
pnpm medusa build --no-lint
pnpm medusa develop --no-lintThis release also includes a new lint command that runs the linting based on your configurations:
pnpm medusa lintYou can also pass options like --fix and --quiet.
Learn more in the CLI documentation.
MikroORM version bump to 6.6.14
🚧 Breaking change
MikroORM 6.6.12 is affected by CVE-2026-44680. This doesn't impact Medusa applications by default, but can affect Medusa customizations if they're JSON inputs are not properly validated with Zod.
This version updates MikroORM to 6.6.14. This comes with a breaking change in how MikroORM's manager.find method works. Previously, it ignored all relations that don't exist on an entity. Now, it will fail with an error.
This has been resolved internally by this PR. However, if you use manager.find in your code, we encourage you to look at the changes made in the PR and apply them in your code.
react-router-dom update
🚧 Breaking change
react-router-dom has also been updated to 6.30.4 due to a recent advisory. The previous version didn't impact Medusa applications; the update is a defensive measure only.
If you have react-router-dom installed in your application, make sure to update it to 6.30.4. Otherwise, admin customizations may break.
Email Verification Changes
🚧 Breaking change
Email verification has been expanded to support for general verification for any user information, such as email or phone number. Also, it now supports specifying different verification requirement per actor type.
In the previous version, The require_verification option of the Emailpass provider accepted a boolean value to enable or disable verification for all actor types. Now, this option has been removed. Instead, use the http.authVerificationsPerActor:
// medusa-config.ts
module.exports = defineConfig({
projectConfig: {
http: {
authVerificationsPerActor: {
user: [], // No verification required for users
customer: [
{
entity_type: "email",
auth_provider: "emailpass",
}
]
},
},
// ...
},
// ...
})In this example, you require verification only for customers. The verification is for their email.
Learn more about setting up email verification in the backend in this documentation
Email Verification Flow Change
🚧 Breaking change
Following the above change, the email verification flow has now changed.
The default Medusa starter (
dtc-starter) has been updated to include this new flow in the storefront by default.
In the previous version, you implemented the following flow for email verification in the storefront:
- Send a request to
/auth/customer/emailpass/registerto obtain a registration token. - Request returns that the verification is required.
- Send a request to the
/auth/customer/emailpass/verification/requestroute to request a verification token for the customer. - The customer goes to the verification page in the storefront, with the token in the query parameter
- Send a request to the
/auth/customer/emailpass/verification/confirmroute to confirm the verification - If verification is successful, create customer + login
In this version, the flow has changed to the following:
- Send a request to
/auth/customer/emailpass/registerto obtain a registration token. - Request returns a successful response. Redirect the customer to the login page.
- Customer logs in. Send a request to
/auth/customer/emailpass. - Request returns that the verification is required.
- Send a request to the
/auth/verification/requestto request a verification token for the customer. - The customer goes to the verification page in the storefront, with the token in the query parameter
- Send a request to the
/auth/verification/confirmroute to confirm the verification - If verification is successful, create customer + login
Learn more about this new flow and how to implement it in this documentation
Change in Verification Routes
🚧 Breaking change
Following the above change in email verification flow, the following routes have been removed:
/auth/[actor]/[provider]/verification/request/auth/[actor]/[provider]/verification/confirm
They've been replaced by the following routes:
/auth/verification/request/auth/verification/confirm
Refer to the Admin and Store API references to learn more about these routes.
Change in JS SDK signature for email verification
🚧 Breaking change
The previous version introduced a new options parameter for the JS SDK's auth.register method that allows to configure the behavior when a registering user requires verification first. This option has been removed since the register route no longer returns whether verification is required, as explained in the verification flow changes section.
Instead, the sdk.auth.login route returns whether verification is required now. For example:
// Before
const { verification_required } = await sdk.auth.register(
"customer",
"emailpass",
{
email: "customer@gmail.com",
password: "supersecret"
},
{
returnVerification: true
}
)
// After
// get registration token
await sdk.auth.register(
"customer",
"emailpass",
{
email: "customer@gmail.com",
password: "supersecret"
},
)
// later, login
const { verification_required } = await sdk.auth.login(
"customer",
"emailpass",
{
email: "customer@gmail.com",
password: "supersecret"
},
)In addition, the signatures of the auth.verification.request and auth.verification.confirm have changed due to the changes to their routes:
// before
await sdk.auth.verification.request("customer", "emailpass", {
entity_id: "customer@gmail.com"
})
await sdk.auth.verification.confirm("customer", "emailpass", {
token
})
// after
await sdk.auth.verification.request({
entity_id: "customer@gmail.com",
entity_type: "email",
})
await sdk.auth.verification.confirm({ code: token })Tax Line Context Hook
A new setTaxLineContext hook allows customization of tax calculation context, providing greater flexibility for complex tax scenarios. The hook is added to the cart's upsertTaxLinesWorkflow and updateTaxLinesWorkflow workflows, and the order's updateOrderTaxLinesWorkflow.
For example:
import { updateOrderTaxLinesWorkflow } from "@medusajs/medusa/core-flows";
updateOrderTaxLinesWorkflow.hooks.setTaxLineContext(
async ({ order, items, shipping_methods }, { container }) => {
// do something
}
)Multi-Shipping Method Cart Support
Carts now support multiple shipping methods of different shipping profiles, enabling split shipments and complex fulfillment scenarios. This allows customers to choose different shipping options for different items within the same order.
You can now pass an array of shipping methods to add to the cart in the /store/carts/:id/shipping-methods API route:
sdk.store.cart.addShippingMethod("cart_123", [
// option 1 with shipping profile 1
{
option_id: "so_123",
data: {
// custom data for fulfillment provider.
}
},
// option 2 with shipping profile 2
{
option_id: "so_456",
data: {
// custom data for fulfillment provider.
}
}
])New Injection Zones
This release adds the following new injection zones in the admin dashboard:
// draft order pages
"draft_order.details.before"
"draft_order.details.after"
"draft_order.details.side.before"
"draft_order.details.side.after"
"draft_order.list.before"
"draft_order.list.after"
// gift card pages
"gift_card.details.before"
"gift_card.details.after"
"gift_card.details.side.before"
"gift_card.details.side.after"
"gift_card.list.before"
"gift_card.list.after"
"gift_card.list.side.before"
"gift_card.list.side.after"
// store credit account pages
"store_credit_account.details.before"
"store_credit_account.details.after"
"store_credit_account.details.side.before"
"store_credit_account.details.side.after"
"store_credit_account.list.before"
"store_credit_account.list.after"
Custom Injection Zones
The admin dashboard now supports adding custom injection zones in custom pages. This allows plugin developers to add widget injection zones in their UI routes.
Learn more in the Custom Injection Zones documentation.
Other dependency patches
This release bumps dependencies for OpenTelemetry and UUID due to recent security advisories in these packages. Medusa applications before this version are not impacted by these advisories, as we don't use any of the affected code, so this is a defensive measure only.
Tighten Payment webhook handling
This release handles edge cases when a payment provider's getWebhookActionAndData returns an undefined data.session_id field. Previously, this led to an arbitrary payment session being processed. Now, webhook handling exists early.
Properly escape JSON containment filters with Index Module
This release properly escapes single quotes in filters passed to the /store/products route when the Index Module is used. Previously, passing single quotes in filters like title caused SQL syntax errors. Now, single quotes are escaped in those filters.
Removed default JWT and Cookie secrets
This release removes the default supersecret value set for JWT and cookie secrets. In production, if those keys aren't set manually, the application will throw an error and fail to start.
Features
- feat(eslint-plugin): add query rules by @shahednasser in #15682
- feat(eslint-plugin): add module link rules by @shahednasser in #15674
- feat(eslint-plugin): added rules for modules by @shahednasser in #15667
- feat(medusa,utils): plugin type augmentations by @leobenzol in #15595
- feat(medusa,core-flows,js-sdk,types): allow provider_id when marking a payment collection as paid by @GBreg19 in #15561
- feat(eslint-plugin): add rules for services by @shahednasser in #15665
- feat(eslint-plugin): added rules for workflows (2/2) by @shahednasser in #15655
- feat(eslint-plugin): added rules for workflows (1/2) by @shahednasser in #15650
- feat(eslint-plugin): add Medusa ESLint plugin by @shahednasser in #15649
- feat: Update register SDK to not use an options parameter by @sradevski in #15642
Bugs
- fix(cli): replace unmaintained pg-god with direct pg.Pool CREATE DATA… by @dsumeet14 in #15635
- fix: product organization combobox search and cache invalidation by @PrathamRanka in #15634
- fix(dashboard): enforce locale-specific plural forms in translations by @radeknapora in #13268
- fix(index): subscribe to restored events and re-index on restore by @Tusharkhadde in #15654
- fix(payment-stripe): warn when webhookSecret is missing by @dsumeet14 in #15684
- fix(dashboard): fix refund form rounding for sub-cent amounts by @Metbcy in #15349
- fix(dashboard): prevent duplicate items in return create form by @Metbcy in #15348
- fix: pin peter-evans/create-pull-request to a commit SHA (supply-chain hardening) by @eliottreich in #15664
- fix(js-sdk): add RBAC ESM import extensions by @puneetdixit200 in #15597
- fix(core-flows): skip tax on gift card line items when cart taxes are recalculated by @cainydev in #15545
- fix(utils): InjectManager error message shows "undefined" instead of "baseRepository_" by @Tusharkhadde in #15662
- fix(core-flows): apply customer-group price lists when creating a dra… by @shafi-VM in #15538
- fix(medusa): allow updating buyget promotions via PATCH /admin/promotions/:id by @sanidhyasin in #15619
- fix(medusa): type product category create response by @Zbl1007 in #15588
- fix: correct "occured" → "occurred" typo in error messages and docs by @DucMinhNe in #15549
- fix(product): Support non-Latin characters in product handles with Un… by @Cpidar in #15346
- fix(admin): fix Copy API Key behavior in secret key created dialog by @Tusharkhadde in #15531
- fix(plugin:develop): invoke yalc via process.execPath on Windows by @addemod in #15523
- fix(medusa): clear session cookie on DELETE /auth/session by @shafi-VM in #15510
- fix(medusa): include address_name in customer address defaults by @puneetdixit200 in #15511
- fix(utils): preserve context index overrides by @puneetdixit200 in #15503
- fix(core-flows): include shipping_method.name in tax calculation context by @NicolasGorga in #15575
- fix(index): use parameterized binding for JSONB containment filter by @shahednasser in #15599
- fix(framework): change for session cookies by @shahednasser in #15601
- fix(utils,product): handle array of mikroORM entities serialization and fix variant image assignment serialization issue by @NicolasGorga in #15591
- fix: use unique order country column id by @xonaib in #15486
- fix: support csv mime types by @aritradhabal in #15483
- fix(dashboard): preserve zero-amount shipping option prices on re-save by @Ultron03 in #15468
- fix(dashboard): prevent crash when deleting the last image from product media gallery by @appinteractive in #15444
- fix(file-local, core-flows): improve file resolution + invalid csv file handling by @shahednasser in #15558
Documentation
- docs: add TSDocs for "verify OAuth id_token signatures via JWKS by @shahednasser in #15669
- docs: fix workflow-sdk import paths in quote management guide by @Jeri436 in #15543
- docs: fix images not showing in references by @shahednasser in #15651
- docs: add missing export keyword by @bodasooqa in #15567
- docs: fix typo "Recieve" → "Receive" in workflows tutorial by @DucMinhNe in #15564
- docs: resolve events from multiple source files + generate references by @shahednasser in #15576
- docs: added documentation for MFA by @shahednasser in #15570
- docs: add documentation on email verification by @shahednasser in #15568
- docs: generate OpenAPI specs for v2.15.5 by @shahednasser in #15563
- docs: remove ai variant by @shahednasser in #15559
- docs(cloud): add create first project page by @shahednasser in #15509
- docs: add TSDocs for Emailpass email verification primitives by @shahednasser in #15526
- docs: add TSDocs for "correctly generate types for OperatorMap by @shahednasser in #15551
- docs: fix links in reference pages by @shahednasser in #15553
- docs: add TSDocs for add multi shipping method carts support by @shahednasser in #15616
- docs: add TSDocs for delete payment method by @shahednasser in #15627
- docs: add TSDocs for a46961e by @shahednasser in #15629
- docs: add TSDocs for 06b0534 by @shahednasser in #15633
- docs: add MCP server prompts by @shahednasser in #15639
- docs: add TSDocs for MFA providers by @shahednasser in #15579
Chores
- chore(plugins): add consistent watch scripts to draft-order and loyalty by @archievi in #15637
- chore(auth-google, auth): verify OAuth id_token signatures via JWKS by @shahednasser in #15607
- chore: fix since tag versions by @shahednasser in #15670
- chore(product, order, utils, deps): update MikroORM to v6.6.14 by @shahednasser in #15632
- chore(dashboard): cleanup build, export components and hooks by @leobenzol in #15590
- chore: change DX triage action to run once a day by @shahednasser in #15652
- chore(docs): cloud doc changes (automated) by @shahednasser in #15641
- chore(docs): cloud doc changes (automated) by @shahednasser in #15631
- chore(deps): bump OpenTelemtry packages by @shahednasser in #15587
- chore(create-medusa-app, telemetry, dashboard, medusa): update react-router-dom and uuid packages by @shahednasser in #15630
- chore(docs): cloud doc changes (automated) by @shahednasser in #15514
- chore: fix syntax errors in triage issues and pr reviewer by @shahednasser in #15617
- chore: improvements to reviewer and triager by @shahednasser in #15608
- chore: allow releasing from branch by @shahednasser in #15613
- chore(docs): automated cloud documentation update by @shahednasser in #15611
- chore(dashboard, medusa): validate http(s) scheme on fulfillment label URLs by @shahednasser in #15605
- chore(framework, utils, medusa): centralize NODE_ENV production check and tighten secret defaults by @shahednasser in #15600
- chore: fixes to MFA tsdocs by @shahednasser in #15581
- chore(dashboard,js-sdk,types,auth): extract MFA and recovery code provider interfaces to types package by @shahednasser in #15571
- chore(docs): doc changes for next release (automated) by @shahednasser in #15466
- chore(docs): Generated References (automated) by @github-actions in #15557
- chore(docs): Generated DML JSON files (automated) by @github-actions in #15555
- chore(docs): Updated UI Reference (automated) by @github-actions in #15556
- chore(docs): Update version in documentation (automated) by @github-actions in #15554
- chore(docs): cloud doc changes (automated) by @shahednasser in #15517
Other Changes
- Preserve auth MFA defaults by @christiananese in #15584
- perf(product): skip option work on scalar-only variant updates by @srindom in #15585
- fix(medusa): add missing policies for translation module by @NicolasGorga in #15528
New Contributors
- @dsumeet14 made their first contribution in #15635
- @PrathamRanka made their first contribution in #15634
- @archievi made their first contribution in #15637
- @radeknapora made their first contribution in #13268
- @Tusharkhadde made their first contribution in #15654
- @NicolasGorga made their first contribution in #15685
- @Metbcy made their first contribution in #15349
- @eliottreich made their first contribution in #15664
- @puneetdixit200 made their first contribution in #15597
- @cainydev made their first contribution in #15545
- @shafi-VM made their first contribution in #15538
- @sanidhyasin made their first contribution in #15619
- @leobenzol made their first contribution in #15595
- @Zbl1007 made their first contribution in #15588
- @GBreg19 made their first contribution in #15561
- @DucMinhNe made their first contribution in #15549
- @Jeri436 made their first contribution in #15543
- @Cpidar made their first contribution in #15346
- @addemod made their first contribution in #15523
- @christiananese made their first contribution in #15584
- @xonaib made their first contribution in #15486
- @aritradhabal made their first contribution in #15483
- @bodasooqa made their first contribution in #15567
- @Ultron03 made their first contribution in #15468
- @appinteractive made their first contribution in #15444
Full Changelog: v2.15.5...v2.16.0