Releases: medusajs/medusa
v2.10.3: View configurations and Shipping Options context hook
Highlights
[Experimental] Customizable columns in Medusa Admin tables
In previous versions, tables that list Orders, Products, etc., had hard-coded columns that couldn’t be modified. However, columns have different relevance between businesses. The only way to get tables to show additional columns was to introduce admin extensions that duplicated the original table’s behavior. This was tedious and clunky.
In this release, we are rolling out experimental support for View Configurations, which allow you to change which columns are displayed in the Orders and Products tables. Click the columns dropdown to see the available columns and add the ones you want. The available columns are computed using Medusa’s module graph, meaning any custom data models linked to Orders or Products can also be included in your table config.
With the View Configurations feature, we also enable saved views so you can have the right view at hand for your workflow. Saved views hold both your column configurations and any filters you have applied.
To try View Configurations turn on the feature flag in your medusa-config.ts
module.exports = defineConfig({
...
featureFlags: {
view_configurations: true
}
})
Shipping options context hook
This release introduces a hook to customize the context used to list shipping options, allowing you to leverage custom rules for shipping options more easily.
The hook can be used like so:
import { listShippingOptionsForCartWithPricingWorkflow } from "@medusajs/medusa/core-flows"
import { StepResponse } from "@medusajs/workflows-sdk"
listShippingOptionsForCartWithPricingWorkflow.hooks.setShippingOptionsContext(
async ({ cart }, { container }) => {
if (cart.customer_id) {
return new StepResponse({
customer_id: cart.customer_id,
})
}
const query = container.resolve("query")
const { data: carts } = await query.graph({
entity: "cart",
filters: {
id: cart.id,
},
fields: ["customer_id"],
})
return new StepResponse({
customer_id: carts[0].customer_id,
})
}
)
In the example above, we add customer_id
to the context along with the fixed properties is_return
and enabled_in_store
. This means that if a shipping option rule includes a customer_id
attribute, the shipping option will be included in the result set.
The hook has been introduced in the following workflows:
listShippingOptionsForCartWithPricingWorkflow
listShippingOptionsForCartWorkflow
Please make sure to register the hook in both, since they are used for shipping option validation across workflows.
Features
- feat(medusa): allow filtering by id for collections by @willbouch in #13495
- feat(dashboard): reusable config datatable by @srindom in #13389
- feat(core-flows): hook to set shipping opt context when listing by @willbouch in #13468
- Feat(): promo prefilter top level rules in db by @adrien2p in #13524
- feat(dashboard): configurable product views by @srindom in #13408
Bugs
- fix(): pipeline missing suites by @adrien2p in #13457
- fix(types): cart item totals optional by @willbouch in #13509
- fix(types): pluralize words ending in s like status by @willbouch in #13461
- fix(medusa): Use the correct boolean validator by @adrien2p in #13510
- fix(core-flows, medusa): don't allow negative line item quantity by @fPolic in #13508
- fix(utils,core-flows): subtotal calculation and returns location by @carlos-r-l-rodrigues in #13497
Documentation
- chore(docs): Generated References (automated) by @github-actions[bot] in #13492
- docs: add manage promotions in cart storefront guide by @shahednasser in #13483
- chore: update API reference for 2.10.2 by @shahednasser in #13499
- docs: general improvements and updates by @shahednasser in #13485
- docs: regenerate core-flows reference to pick up locking steps by @shahednasser in #13502
- docs: documentation updates for v2.10.2 by @shahednasser in #13500
- docs: fix issues in product builder tutorial by @shahednasser in #13505
- docs: add clarification for set cart's customer API route by @shahednasser in #13506
- docs: add section on retrieve totals for cart items and shipping methods in storefront by @shahednasser in #13513
- docs: general improvements and fixes by @shahednasser in #13515
- docs: small update to invoice generator introduction by @shahednasser in #13519
- docs: add Next.js starter guides to llms-full.txt by @shahednasser in #13523
- docs: fixes to JS SDK + auth provider guides by @shahednasser in #13526
- docs: general improvements by @shahednasser in #13530
- docs: improve third-party auth in storefront guide by @shahednasser in #13534
Chores
- chore(docs): Updated UI Reference (automated) by @github-actions[bot] in #13491
- chore(docs): Update version in documentation (automated) by @github-actions[bot] in #13490
- chore(js-sdk): add ignore tag to views by @shahednasser in #13503
- chore: update TSDocs of JS SDK store methods to clarify required auth by @shahednasser in #13507
- chore(core-flows): use directory convention for locking steps by @shahednasser in #13501
- chore: add a link to the storefront docs for cart item totals type by @shahednasser in #13514
- test(): test dynamic max workers and improve CI by @adrien2p in #13516
- chore(): Shard unit tests jobs by @adrien2p in #13525
- fix(core-flows): Lock cart on shipping + taxes update by @olivermrbl in #13535
- chore: add tsdocs for latest changes by @shahednasser in #13539
- fix(): Prevent promotion filtering to exceed psql limits by @adrien2p in #13540
Other Changes
- fix(js-sdk): skip null values in query qs.stringify by @leobenzol in #13460
- feat(dashboard): update display of tracking/label URLs on order details by @docloulou in #11613
- fix(dashboard): added missing currencies by @tehaulp in #13214
- test(): Try to reproduce automatic promotion adjustments being applied twice by @adrien2p in #13533
Full Changelog: v2.10.2...v2.10.3
v2.10.2
Highlights
Indexing of core entities
Medusa Index was built to improve the developer experience of filtering data across modules while improving performance, especially for large data sets.
With this release, all entities in the core Medusa modules are now ingestible into Medusa Index. This unlocks cross-module filtering for all core and custom entities. The ingestion happens automatically, provided a link is defined between the entities, as described in our documentation.
For example, filtering Products by Sales Channels used to require the following steps:
// 🔴 BEFORE
const query = container.resolve("query")
// Sales Channels to filter by
const salesChannels = ["sc_1234"]
// Query the Sales Channel <> Product link table for matching links
const { data: links } = await query.graph({
entity: "product_sales_channel",
fields: ["product_id"],
filters: {
sales_channel_id: salesChannels
}
})
// Construct the products filter using the matched links
const productFilters = {
id: links.map(link => link.product_id)
}
// Finally query the products with the filters
const { data: products } = await query.graph({
entity: "product",
fields: ["id"],
filters: productFilters
})
With Index, the same example from above can be done with a single query:
// 🟢 NOW
const query = container.resolve("query")
// Sales Channels to filter by
const salesChannels = ["sc_1234"]
// Query the products with the sales channel filter
const { data: products } = await query.index({
entity: "product",
fields: ["id"],
filters: { sales_channels: { id: salesChannels } },
})
Note that in the second code snippet, we use query.index
instead of query.graph
to query Medusa Index.
For setup and usage details of Medusa Index, see our documentation.
Locking all cart operations
All cart workflows in Medusa's core are now locking the cart during execution to eliminate the risk of concurrent changes.
We would recommend that you introduce the same locking mechanism to your own custom cart workflows.
Here's how you would do it:
export const myCustomAddToCartWorkflow = createWorkflow("my-custom-add-to-cart-workflow",
(input) => {
// Acquire a lock on the cart ID as the first step in the workflow
acquireLockStep({
key: input.cart_id,
timeout: 2, // Attempt to acquire the lock for two seconds before timing out
ttl: 10, // Lock is only held for a maximum of ten seconds
})
// Run all regular cart operations
// Release the lock on the cart ID as the last step in the workflow
releaseLockStep({
key: cart.id,
})
return new WorkflowResponse({ ... })
}
)
Features
- feat(promotion): Allow buyget promotion to apply multiple times on cart by @riqwan in #13305
- feat(admin): add view configuration client infrastructure by @srindom in #13186
- Feat/datatable core enhancements by @srindom in #13193
- feat(ui): add column visibility and drag-and-drop reordering support by @srindom in #13198
- feat(admin): add configurable order views by @srindom in #13211
- feat(dashboard,cart,types,utils): refine order details summary by @willbouch in #13313
- chore(orchestration): add support for autoRetry, maxAwaitingRetries, retryStep by @adrien2p in #13391
Bugs
- fix(dashboard): rules form operator change by @fPolic in #13324
- fix(core-flows): handle cacluated shipping options on draft orders gracefully by @fPolic in #13353
- fix(utils): big bumber should give numeric value of 0 for small numbers by @willbouch in #13394
- fix(dashboard, ui): ensure radix deps version by @fPolic in #13392
- fix(dashboard): promotion decimal value definition by @fPolic in #13371
- fix(dashboard): customer
has_acccount
flag by @fPolic in #13414 - fix(dashboard): support more decimals for tx rates by @willbouch in #13407
- fix: Missing DB traces in instrumentation by @olivermrbl in #13429
- fix(index): index enum fields by @carlos-r-l-rodrigues in #13428
- fix(medusa): Use default logger in plugin:develop by @olivermrbl in #13375
- fix(medusa): stop loading entry points in exec command by @willbouch in #13438
- fix(dashboard): edit rules clear and reset by @fPolic in #13423
- fix(): Prevent ci to fail if lock file does not exists by @adrien2p in #13456
- fix(): missing events by @adrien2p in #13465
- fix(): product image missing index by @adrien2p in #13466
- fix(): temporary transform cached data by @adrien2p in #13467
- fix(): prepare list query for list by @adrien2p in #13476
- chore(): improve inventory module by @adrien2p in #13463
- fix(): update cart line item route fetching by @adrien2p in #13477
- fix(medusa,product): fix ordering product categories by @willbouch in #13487
Documentation
- docs-util: fix error in references pipeline by @shahednasser in #13343
- docs: generate references for 2.10.1 by @shahednasser in #13344
- docs-util: fix workflows not picked for some routes + generate OAS by @shahednasser in #13342
- docs: document scheduled jobs interval by @shahednasser in #13350
- docs: add troubleshooting guide for pnpm installations by @shahednasser in #13351
- docs: add lockin module provider to deployment guide by @shahednasser in #13361
- docs: document how prices are stored in Medusa by @shahednasser in #13362
- docs: add missing step in product builder guide by @shahednasser in #13370
- docs: added a section on figma mcp + workflows diagram fix by @shahednasser in #13367
- docs: general updates and fixes by @shahednasser in #13374
- docs: change digial products to digital products by @yoreljenkins in #13379
- docs: document feature flags by @shahednasser in #13388
- docs: add more examples for API route responses by @shahednasser in #13399
- docs: show the source code link in order models reference by @shahednasser in #13398
- docs: change text in Cloud homepage by @MedusaNick in #13401
- docs: fix scrollbar not clickable by @shahednasser in #13409
- docs: added a note about payload version by @shahednasser in #13410
- docs: general fixes and improvements by @shahednasser in #13417
- docs: add plan cancelation details by @shahednasser in #13416
- docs: fixes and improvements to price calculation guide by @shahednasser in #13419
- docs: update project creation steps by @shahednasser in #13436
- docs: add graphql dependency to payload guide by @shahednasser in #13440
- chore(): Upgrade mikro orm by @adrien2p in #13390
- docs: add product feed tutorial by @shahednasser in #13366
- docs: fix cancel order information in user guide by @shahednasser in #13447
- docs: fix relations missing from data model reference diagrams by @shahednasser in #13474
- docs: improvements to Cloud homepage by @shahednasser in #13479
- docs: fix saved payment method guide by @shahednasser in #13480
- docs: fix same page link not resolved correctly by @shahednasser in #13481
- docs: add cloud plans & pricing page by @shahednasser in #13420
- docs: ticket booking system guide by @shahednasser in #13471
Chores
- chore(docs): Update version in documentation (automated) by @github-actions[bot] in #13340
- chore(docs): Updat...
v2.10.1: Fixes regression in performance for cart operations
Highlights
We identified a performance regression affecting cart operations in the latest release. This issue resulted in slower response times for cart-related HTTP requests. The regression was caused by a change introduced to control concurrency in cart operations, which inadvertently impacted performance.
To address this issue, we have reverted the change, restoring cart operation performance to its previous state. To prevent similar issues in future releases, we are implementing regression tests as part of our release pipeline. These tests will help detect performance regressions early in the development process, ensuring a more stable and reliable experience.
We apologize for the inconvenience this may have caused for some applications.
Documentation
- docs: docs for next release by @shahednasser in #13303
- chore: fix release action of ui docs by @shahednasser in #13329
- docs: generate API reference for 2.10.0 by @shahednasser in #13330
- docs: added shipping option type injection zones by @shahednasser in #13332
- docs: update UI docs by @shahednasser in #13333
Chores
- chore(docs): Update version in documentation (automated) by @github-actions[bot] in #13327
- chore(docs): Generated DML JSON files (automated) by @github-actions[bot] in #13328
- chore: add since tag to shipping option type events by @shahednasser in #13331
- chore(core-flows): revert idempotent cart by @carlos-r-l-rodrigues in #13336
Full Changelog: v2.10.0...v2.10.1
v2.10.0: Draft Orders, Free shipping promotion, and Shipping Option Types
Highlights
This release contains breaking changes, so please read the release notes carefully. The breaking changes are all the result of fixing behavior that has not worked as intended until now.
Idempotency in our Workflow Engine
Warning
Breaking change
The idempotent
configuration on workflows no longer retains executions in the database after completion, unless a retention time is specified. Up until now, if the idempotent
flag was set, workflow executions were retained indefinitely, which was never the intention. The intention was to make a workflow idempotent for the duration of its execution, and only longer if the retention time was explicitly configured.
As part of this change, we are enabling the idempotent
flag on all cart workflows to prevent concurrent mutations on cart operations.
Return type of methods in MedusaService
Warning
Breaking change
The return types of update
and create
in MedusaService
have been corrected to properly handle the different shapes of inputs.
The behavior is now as follows:
createT({ ... }): T
createT([{ ... }]): T[]
updateT({ id: "br_1234", name: "Hermes" }): T
updateT([{ id: "br_1234", name: "Hermes" }, { id: "br_4321", name: "Loewe" }]): T[]
updateT({ selector: { country_of_origin: "France" }, data: { language: "French" }}): T[]
Compensating emitEventsStep
Warning
Breaking change
Previously, if the emitEventStep
queued an event and the workflow later failed, the compensating flow would emit that queued event instead of removing it. This caused unexpected behavior during rollback.
With this change, when a workflow is compensated, all queued events emitted in the workflow are cleared. This was the intended behavior from the get-go, but the bug was only discovered recently.
If you want to keep the previous behavior, you can create your own version of the emitEventsStep
without a compensation step.
Manage Shipping Option Types in Admin
Warning
Breaking change
The admin dashboard now supports managing shipping option types, making it easier to categorize options such as Standard and Express.
Key updates:
- Settings: New "Shipping Option Types" page (accessible from "Locations & Shipping")
- Create and update types with label, description, and code
- Shipping option creation flow: Choose a type from a dropdown
- Shipping option update flow: Change a type from a dropdown
This brings shipping option management to the dashboard, aligning it with existing backend support.
The introduction of Shipping Option Types comes with a migration, cleaning up old dummy types from the database. Up until now, we've created dummy types for Shipping Options as part of their creation flow. These types were placeholders, which is why we are now replacing them.
The migration will do the following:
- Delete all Shipping Option Types with code
type-code
from the database - Disassociate these types from Shipping Options
- Create a new Shipping Option Type named "Default" with code
default
- Associate the default type with Shipping Options
This migration will only affect Shipping Options that reference the type-code
type. If you have been using your own types, they will remain as is. On the contrary, if you have been relying on type-code
, this is a breaking change.
Draft Orders
The new Draft Order plugin adds flexible order management directly in Medusa Admin. Store admins can create, edit, and finalize orders through a dedicated UI, while developers gain a new primitive for building custom workflows.
Key features:
- Create and manage draft orders from Medusa Admin
- Support for custom pricing, line items, and shipping methods
- Streamlined handling of B2B and complex sales
The Draft Order plugin is installed by default from version >=2.10.0. It is usable for version >=2.4.0 but requires explicit installation and registration.
Read more in our documentation.
Free shipping Promotions
This release introduces support for free shipping promotions available directly from the admin dashboard. You can apply free shipping to specific Shipping Option Types, e.g., "Standard", but not "Express".
Custom Logger Support
You can now replace the default logger with your own implementation by providing a class that follows the Logger interface.
Example:
// medusa-config.ts
import { MyCustomLogger } from "./custom-logger"
export default defineConfig({
// ...
logger: MyCustomLogger,
})
The logger should implement the Logger interface.
Shipping Option Tax Rates
You can now create tax rates specifically for shipping options within tax regions, similar to product-specific tax rates.
Metadata for Product Tags
The product tag domain now supports metadata, with a UI for creating and managing metadata values.
Features
- feat(dashboard, js-sdk): shipping option type mngmt dashboard by @willbouch in #13208
- feat: view config feature flag by @srindom in #13171
- feat: add settings module by @srindom in #13175
- feat(api): add view configuration API routes by @srindom in #13177
- feat: add column introspection api by @srindom in #13183
- feat(dashboard, core-flows): associate shipping option to type by @willbouch in #13226
- feat(core-flows): Refresh adjustments when editing orders by @olivermrbl in #13189
- feat(dashboard): shipping option tax rate overrides UI by @fPolic in #13260
- feat(dashboard, core-flows, js-sdk, types, medusa): listing order's shipping options by @fPolic in #13242
- feat(dashboard,core,modules): free shipping promotion in dashboard by @willbouch in #13263
- feat(core, event-bus): Compensate emit event step utility by @adrien2p in #13281
- feat(utils): define file config by @carlos-r-l-rodrigues in #13283
- feat: Add Draft Order plugin by @olivermrbl in #13291
- feat(index): $nin and $not operators by @carlos-r-l-rodrigues in #13289
- fix(orchestration): Use the step definition max retries on set step failure by @adrien2p in #13319
- feat: custom logger by @carlos-r-l-rodrigues in #13156
Bugs
- fix(utils): fix promotion case of each allocation not applying its total amount by @riqwan in #13199
- fix(utils): auto generated update method return by @carlos-r-l-rodrigues in #13225
- fix(dashboard): table inclusive date filter by @fPolic in #13053
- fix(dashboard): create product selected inventory item display by @fPolic in #13111
- fix(core-flows, dashboard, types): improve allocation flows on Admin by @fPolic in #12572
- fix(dashboard): zero in float currency inputs by @fPolic in #13267
- fix(dashboard): show fulfilment option on SO edit by @fPolic in #13269
- fix(fulfillment): Geozone constraints builder by @olivermrbl in #13282
- fix(): Cart operation should calculate item prices accounting for quantity by @adrien2p in #13251
- fix(fulfillment): don't cascade shipping option delete to shipping option type by @fPolic in #13280
- fix: Add created_at to workflow execution filtering typings by @sradevski in #13295
- fix(dashboard): handle large resource count in tax rule override edit form by @fPolic in #13297
- fix(medusa): fetching a product without a category with
categories
filed passed by @fPolic in #13020 - fix(core-flows): pass backorder flag when recreating reservations after fulfilment cancelation by @fPolic in #13076
- fix(core-flows): list order shipping options param type by @fPolic in #13316
Documentation
- chore(docs): Generated References (automated) by @github-actions[bot] in #13206
- docs: fix subtotal description in storefront guides by @shahednasser in #13212
- docs: fixes to read-only links + add examples for filtering by relations by @shahednasser in #13218
- docs: add regions supported by Cloud by @shahednasser in #13220
- docs: update create project steps by @shahednasser in #13223
- docs: connect to database updates by @shahednasser in #13224
- docs: fix typos in index modules docs by @tedraykov in #12852
- ...
v2.9.0
Highlights
Throw error on invalid promotions
Warning
Breaking change
This release updates the promotion application logic to throw when applying an invalid promotion code. This change improves the experience for developers building storefronts by allowing them to handle invalid discount codes directly from the API response, rather than checking cart promotions after the API request.
The backend will respond with a 400 and a message like so:
The promotion code HELLOWORLD is invalid
Add support for logical operators on Index
This release introduces support for logical operators on Index queries, such as:
const { data: products } = await query.index({
entity: "product",
filters: {
$and: [
{ status: "published" },
{
$or: [
{ brand: { name: { $ilike: "%adidas%" } } }
]
}
]
}
})
In addition to this, this release also fixes a regression related to indexing custom module entities.
Resolve issue with promotion calculations in a tax-inclusive context
This release resolves an issue with the calculation of adjustments in a tax-inclusive calculation context.
When calculating the applicableTotal
(the maximum amount a promotion can apply to an item), it was incorrectly based on the line item’s subtotal (excluding tax), while the promotion value was based on the total (including tax), causing incorrect adjustment calculations.
Bugs
- fix(core-flows): guest customer updates email to another guest account by @fPolic in #13037
- fix(create-medusa-app): Don't allow dot in project name by @olivermrbl in #13042
- fix(promotion): check currency when computing actions for promotions by @riqwan in #13084
- fix(core-flows): refresh payment collection by @carlos-r-l-rodrigues in #13103
- chore(ui): sync Figma resources by @fPolic in #13088
- fix(pricing): Calculate prices with multiple rule values by @olivermrbl in #13079
- fix(dashboard): variants disappearing when removing an option on product creation by @willbouch in #13150
- fix(workflow-engine-inmemory): fix cron job schedule by @carlos-r-l-rodrigues in #13151
- fix(index): logical operators by @carlos-r-l-rodrigues in #13137
- fix(dashboard,promotion): Fix regression on applying percentage promotions by @riqwan in #13161
- fix: Allow getting the token from the SDK client by @sradevski in #13164
- fix(types): remove order_id in apis that do not handle it by @willbouch in #13185
- fix(tax): Use correct rule reference for shipping by @olivermrbl in #13195
Documentation
- docs: update order promotion link details by @shahednasser in #13023
- docs: fix vale lint errors by @shahednasser in #13024
- chore(docs): Updated UI Reference (automated) by @github-actions[bot] in #13026
- docs: fix to OAS generator following Zod update + generate API reference by @shahednasser in #13030
- docs: fix bug in layout change when using some chrome extensions by @shahednasser in #13031
- docs: document UI route breadcrumbs by @shahednasser in #13035
- docs: fix passing linkable for inverse read-only links by @shahednasser in #13041
- docs: add section on customer account deletion by @shahednasser in #13048
- docs: add how-to guides for retrieving cart and order totals by @shahednasser in #13044
- docs: improvements and additions to admin customization chapters by @shahednasser in #13049
- docs: document checks examples + migrations naming convention by @shahednasser in #13052
- docs: document auto-generated types by @shahednasser in #13050
- docs: added examples to DatePicker component by @shahednasser in #13054
- docs: general updates to documentation pages by @shahednasser in #13055
- docs: migration guide from v1 to v2 by @shahednasser in #12597
- docs: open AI assistant based on search query by @shahednasser in #13063
- docs: handle recaptcha loading before submitting AI assistant queries by @shahednasser in #13065
- Fix spelling error in documentation by @benwrk in #13061
- docs: document debugging workflows by @shahednasser in #13087
- docs: improved workflows integration tests guide by @shahednasser in #13090
- docs: document JSON properties by @shahednasser in #13099
- docs: add link to manage metadata section in OAS and API reference by @shahednasser in #13102
- docs: improve instructions to install Medusa UI in standalone projects by @shahednasser in #13104
- docs: add links to technical guides in user guides by @shahednasser in #13108
- docs: update list of resources in module containers + conventions on loaders by @shahednasser in #13107
- docs: add more totals to retrieve cart and totals guides by @shahednasser in #13110
- docs: updates to nested workflow docs by @shahednasser in #13117
- docs: fix search not opening sometimes by @shahednasser in #13118
- docs: fix code block titles not showing in UI docs by @shahednasser in #13119
- docs: added guide on sending invite user emails + updates to reset password guide by @shahednasser in #13122
- docs: add buffer example in workflows + tip for type error in admin global variables by @shahednasser in #13124
- docs: document the fetchStream method of the JS SDK by @shahednasser in #13125
- docs: change from detecting version to since tag by @shahednasser in #13127
- docs: general updates to documentation pages by @shahednasser in #13128
- feat: Add MCP instructions for Claude Code by @aldo-roman in #13134
- docs: generate invoice tutorial by @shahednasser in #13077
- Update page.mdx by @concaveinc in #13180
- docs: integrate reo.dev by @shahednasser in #13192
Chores
- chore(docs): Update version in documentation (automated) by @github-actions[bot] in #13025
- chore(docs): Generated References (automated) by @github-actions[bot] in #13027
- chore: fix example in createProductsWorkflow TSDocs by @shahednasser in #13112
- chore: add links to package.json by @shahednasser in #13100
- chore: use since instead of version tag in TSDocs by @shahednasser in #13126
- chore(dashboard): add missing US states by @fPolic in #13094
- chore: add willbouch to teams.yml by @willbouch in #13141
- chore(core-flows): throw error on invalid promo code by @willbouch in #13140
- chore(util): avoid promotion value precision limit by @carlos-r-l-rodrigues in #13145
- chore(core-flows): import zod by @carlos-r-l-rodrigues in #13197
Other Changes
- fix(dashboard): correct overflow in a few settings edit forms by @SteelRazor47 in #11982
- fix: createCustomerGroupsStep rollback, delete created customer groups… by @jbrigbyjs in #13056
- This fixes the discount_ calculation logic and promotion tax inclusiveness calculation by @scherddel in #12960
- feat: added pacific franc currency by @tehaulp in #13086
- fix(types,utils,promotion): Move from total to original_total to resolve edge case for adjustments calculation by @scherddel in #13106
- fix(utils):Fix on precision for high quantities for items when promotion is applied by @scherddel in #13131
- Made in operator work as In insted of equal logic by @mikkel-lindstrom in #13078
New Contributors
...
v2.8.8: Improved error logging and overall robustness of core operations
Highlights
Carry over cart promotions to order
The cart-completion workflow has been updated to transfer promotions from carts to orders upon completion. This means you can now access promotions on the order like so:
const { data } = await query.graph({
entity: "order",
fields: ["id", "promotions.*"]
})
const order = data[0]
console.log(order.promotions)
// [{
// "id": "promo_1234",
// "code": "10OFF",
// "is_automatic": false,
// "is_tax_inclusive": false,
// "type": "standard",
// "status": "active",
// "campaign_id": null,
// "campaign": null,
// }]
Previously, promotions had to be accessed via the line item adjustments on the order.
Align accepted values in product import template
The CSV product import functionality has been updated to correctly handle unexpected columns. These columns are now ignored during import, ensuring a smoother process for creating and updating products.
Improved error logging
Client-side 4xx responses (such as 404s) are no longer logged as errors. These responses typically indicate expected conditions. Only 5xx responses, which indicate server-side issues, are now logged as errors. This reduces unnecessary noise in logs, making it easier to focus on actual server problems.
Expanded order methods in the JS SDK
Added archive and complete methods to the admin.order
module of the JS SDK. These methods provide support for the POST /admin/orders/{id}/archive
and POST /admin/orders/{id}/complete
endpoints, giving developers full access to the order lifecycle directly from the SDK.
The methods are used like so:
await sdk.admin.order.archive("order_123");
await sdk.admin.order.complete("order_123");
Bugs
- fix(link-modules,core-flows): Carry over cart promotions to order promotions by @riqwan in #12920
- fix(core-flows): updating tax lines when draft order shipping is removed by @fPolic in #12919
- fix(types): add attachments to CreateNotificationDTO type by @shahednasser in #12936
- fix(dashboard): combobox multiitem clear by @fPolic in #12939
- fix(core-flows): useQueryGraph util return type by @adrien2p in #12962
- chore(workflow-engine-*): Align event subscribers management by @adrien2p in #12976
- fix(orchestration): Prevent workf. cancellation to execute while rescheduling by @adrien2p in #12903
- fix: accepted values in import with template by @juanzgc in #12969
- fix(core-flows): properly delete variant inventory item by @fPolic in #12958
- chore(link-modules): keep promotion alias by @riqwan in #12928
- fix(wfe): should notify when finished + add state info by @adrien2p in #12982
- fix(wfe): add missing state in inmemory notify on run finished by @adrien2p in #12987
- fix(dashboard): allocation UI for orders with more than 20 reservation items by @fPolic in #12989
- fix(pricing): fix pricing query when max_quantity is null by @riqwan in #12981
- fix: fix script migrations order by @peterlgh7 in #13007
- fix(workflows-sdk): fix step name config used before default by @carlos-r-l-rodrigues in #12926
- fix(modules-sdk): Entity types by @olivermrbl in #13002
- fix(dashboard, product): product attributes update with a relation update by @fPolic in #13019
Documentation
- docs: add missing prop to kapa by @shahednasser in #12934
- chore(docs): fix generate OAS for gift card by @shahednasser in #12937
- chore(docs): Updated UI Reference (automated) by @github-actions[bot] in #12941
- docs: changes for new releases + fixes by @shahednasser in #12945
- chore(docs): Generated References (automated) by @github-actions[bot] in #12942
- docs: fix overlap between input and clear button in search by @shahednasser in #12949
- docs: updates to long-lived environment and billing docs by @shahednasser in #12948
- docs: fix example of updatePayment method by @shahednasser in #12947
- docs: added a note linking to create-medusa-app reference by @shahednasser in #12950
- docs: update next.js to 15.3.5 by @shahednasser in #12952
- docs: fix complete cart workflow in marketplace vendors recipe by @shahednasser in #12953
- docs: update customize stripe in next.js storefront guide by @shahednasser in #12963
- docs: add a troubleshooting section on creating a payment session with zero total by @shahednasser in #12974
- docs: use mappedBy property for all relationship types by @shahednasser in #12973
- docs: add examples to price rules and tiers by @shahednasser in #12700
- docs: improvements to the "Expose a Workflow Hook" documentation by @shahednasser in #12992
- docs: add a section on shipping options and requirement + improvements by @shahednasser in #12990
- chore: Fix freshness check script + update Linear SDK by @shahednasser in #12991
- docs: add inject dependencies section in module tests + improvements by @shahednasser in #12993
- docs: fix spacing between workflow steps and tooltip by @shahednasser in #12994
- docs: fix input type of some hooks in workflow reference by @shahednasser in #12995
- docs: add section on type aliases in admin + note for removing items from orders by @shahednasser in #12996
- docs: fix jest.config.js by @SteelRazor47 in #12999
- docs: improve alt of images by @shahednasser in #12998
- docs: freshness check for some guides by @shahednasser in #13000
- docs: remove non-existing sidebar items by @shahednasser in #13013
- docs: fix typos in learn and recipes by @mathieuh in #13017
- docs: add MCP server by @shahednasser in #13018
- docs: added pre-orders guide by @shahednasser in #12984
- docs: added personalized products guide by @shahednasser in #13012
- docs: added Docker local installation guide by @shahednasser in #13022
Chores
- chore(docs): Update version in documentation (automated) by @github-actions[bot] in #12935
- chore(docs): Generated DML JSON files (automated) by @github-actions[bot] in #12940
- chore(docs): Updated API Reference (automated) by @github-actions[bot] in #12943
- chore: fix tsdocs of updatePayment method by @shahednasser in #12946
- chore: upgrade to latest zod v3 by @riqwan in #12938
- chore(orchestration): improve transaction errors by @carlos-r-l-rodrigues in #12951
- chore: remove codegen action by @shahednasser in #12954
- chore: add to TSDocs note about removing item from order edit by @shahednasser in #12997
- chore(payment): use generate schema by @carlos-r-l-rodrigues in #13004
Other Changes
- chore(medusa): fix typo by @OnlyWick in #12907
- chore(docs): Update worker_mode description as environment by @DanSilva41 in #12894
- feat(i18n): update translation for Vietnamese by @NuxTijNhaX in #12931
- fix: only log server errors by @peterlgh7 in #12957
- feat: Added Malawi kwacha to currency list by @sevenreup in #12440
- docs: add data migration scripts section by @SteelRazor47 in #12975
- chore: Expose Awilix resolution errors by @trevster344 in #13008
- fix(js-sdk): add missing admin order archive and complete methods by @anteprimorac in #12944
New Contributors
- @OnlyWick made their first contribution in https://git...
v2.8.7: Improved `create-medusa-app` and corrected tax calculations
Highlights
New --version
flag for create-medusa-app
This release introduces a new flag, --version
to the create-medusa-app
command, allowing you to create Medusa projects with a specific version installed.
npx create-medusa-app ---version 2.8.5
Correct tax calculations for order item adjustments
This release introduces the is_tax_inclusive
flag on order line item adjustments to ensure tax calculations are correct for tax-inclusive promotions.
Features
- feat(create-medusa-app): Allow to create project with specific medusa version by @adrien2p in #12882
Bugs
- fix(core-flows): Locations levels check in draft order and order edit flows by @olivermrbl in #12881
- fix(index): merge filterable fields schema by @carlos-r-l-rodrigues in #12888
- fix(): Order constraint and receive return by @adrien2p in #12889
- fix(order, core-flows): Tax inclusive order line item adjustments by @olivermrbl in #12875
- fix(orchestration): Handle expected lifecycle errors by @adrien2p in #12886
- fix(dashboard): show TIP flag only for fixed promotions by @fPolic in #12897
- fix(medusa, core-flows): Update TIP on promotions by @olivermrbl in #12885
Documentation
- chore: Bump Kapa SDK by @olivermrbl in #12870
Other Changes
- fix(admin): prevent excessive polling in notifications by @jessy2027 in #12868
New Contributors
- @jessy2027 made their first contribution in #12868
Full Changelog: v2.8.6...v2.8.7
v2.8.6: Strengthened workflow engine and improved account holder management
Highlights
Strengthen the workflow engine
This release improves the workflow engine's data flow. When resuming workflows, we now compile workflow data (i.e. input and outputs of previous steps) from Redis and Postgres to ensure the most recent workflow execution and associated data are used.
Improve payment account holder flows
This release improves how payment account holders are managed when creating payment sessions in the createPaymentSessionWorkflow
. In this workflow, we create a new payment account holder for the customer on the cart if it doesn't already exist. When the workflow fails in a later step, the compensation flow is triggered, and we now ensure we are only deleting the account holder if it was created as part of the invoke, i.e. it didn't exist before running the workflow.
Bugs
- fix: do not apply prefix when getting file contents as buffer or stream by @thetutlage in #12831
- fix(core-flows,workflows-sdk): compensate account holders only when its created by @riqwan in #12825
- fix(): test utils events + workflow storage by @adrien2p in #12834
- fix: fix onScroll in Select.Content by @peterlgh7 in #12855
Documentation
- docs: documentation changes for next release by @shahednasser in #12773
- doc: Updated cloudflare R2 description by @scherddel in #12598
- docs: added first-purchase promotion guide by @shahednasser in #12828
- docs: update OAS for loyalty plugin by @shahednasser in #12836
- docs: remove usages of ts-ignore in examples by @shahednasser in #12839
- docs: fix step detection of useQueryGraphStep by @shahednasser in #12842
- docs: small typo fix by @shahednasser in #12843
- docs: documet withDeleted by @shahednasser in #12841
- docs: design fixes to toc and related elements by @shahednasser in #12747
- docs: added gift message guide by @shahednasser in #12833
- docs: sort events in reference alphabetically by @shahednasser in #12845
- docs-util: throw when schema parsing fails by @shahednasser in #12846
- docs: remove empty storefront guides by @shahednasser in #12844
- docs: add build with AI & LLMs doc by @shahednasser in #12848
- docs: document tax-inclusive promotions concept by @shahednasser in #12849
Chores
- chore: add version and deprecated tags to import routes and methods by @shahednasser in #12829
- chore: add missing types in TSDocs example by @shahednasser in #12835
- chore: improve description of findOrCreateCustomerStep by @shahednasser in #12840
Other Changes
New Contributors
- @scherddel made their first contribution in #12598
- @redeyecz made their first contribution in #12837
Full Changelog: v2.8.5...v2.8.6
v2.8.5: Tax-inclusive Promotions, Improved Product Imports, and Faster Application Startup
Highlights
Improved Product Imports
This release overhauls the bulk import process to make it more performant and include strict validations to catch formatting issues or typos during the pre-processing phase.
Import phases
A CSV file with products to import goes through the following two phases.
- Pre-processing: In the pre-processing phase, we validate the contents of the entire file, check for typos, unknown columns, invalid data types, or missing values, and report errors as soon as you upload the file.
- Importing: Products are imported in the background (as it could be time-consuming with large product catalogs). Since the validations have already been performed during the pre-processing phase, the chances of failure during the import phase are rare. However, certain database constraints around duplicate data might result in a failure.
Changes to import template
Earlier, the import template (downloaded from the admin dashboard) was out of sync with our documentation and supported many columns that were part of Medusa V1.
However, now the import template strictly allows the columns mentioned in the documentation, and an error will be raised if an unknown column is specified in the CSV file.
Performance improvements
The following changes have been made to the internals to improve the import performance and memory consumption.
- Use S3 direct uploads instead of self-importing and storing huge CSV files on a Medusa server. For this, you must configure the S3 file provider in production.
- Read the CSV contents as a stream of chunks and process/validate 1000 rows at a time. As a result, we never read or process the entire CSV file in memory. From our tests, this led to a memory drop from 4GB to 500MB when processing a file with 62000 rows.
Tax-inclusive Promotions
This release introduces an option to specify if fixed promotions take effect before or after taxes. Up until now, fixed promotions would always be applied before taxes, which could lead to unexpected total calculations in scenarios where pricing was otherwise tax-inclusive.
For example, consider a fixed promotion with a value of $10 applied to a tax-inclusive cart of $100 in a tax region with a 25% tax rate.
Before promotion is applied:
- Cart total (tax-inclusive) -> $100 ($80 ex. 25% VAT)
After promotion is applied:
- Cart total (tax-inclusive) -> $87.5 ($70 ex. 25% VAT)
As you can see, the cart is reduced by $12.5 even though the promotion value was $10. The calculation we used to perform to find the promotion adjustment was:
const adjustmentTotal = (cartWithoutTax - promotion.value) * (1 + tax_rate)
In our example, this would be:
const adjustmentTotal = (80 - 10) * (1.25) = 87.5
In this release, we updated this calculation to ensure the correct adjustment total. It looks as follows:
const adjustmentTotal = (cartWithoutTax - (promotion.value / 1 + tax_rate)) * (1 + tax_rate)
In our example, this would be:
const adjustmentTotal = (80 - 8) * (1.25) = 90
The tax-inclusivity option on a promotion is part of the promotion creation flow in the admin dashboard.
Improved application startup time
This release reduces application startup time by around ~75%. For example, on Medusa Cloud, the startup time for a relatively simple Medusa application has gone from 20 seconds to around 4 seconds. This improvement comes from parallelizing the bootstrapping of modules. Modules are strictly independent from each other, so this should have no side effects.
Querying deleted records
This release fixes issues with querying for deleted database records.
Up until now, filtering data by providing any value to the deleted_at
filter would be treated as if you wanted to fetch deleted records.
For example:
const { data } = await query.graph({
entity: "product",
filters: { deleted_at: { $eq: null } }
})
In this query request, we are asking for all non-deleted records; however, we mistakenly assumed that any deleted_at
filter would always be filtering for deleted records, so in this case, the result set would contain deleted records.
In this release, we remove the autodetection mechanism in favor of an explicit flag withDeleted
.
To query deleted records, you now need to pass the flag to the request:
const { data } = await query.graph({
entity: "product",
filters: { deleted_at: { "<some timestamp>" } }
withDeleted: true
})
Features
- feat: wire up direct uploads with local file provider by @thetutlage in #12643
- feat(promotion, dashboard, core-flows, cart, types, utils, medusa): tax inclusive promotions by @fPolic in #12412
- feat(dashboard,types): add credit lines + loyalty changes by @riqwan in #11885
- feat: Improve startup time by parallelizing module and link loading by @sradevski in #12731
- feat: Normalize payment method data and options when passed to Stripe by @sradevski in #12757
- fix(dashboard, types): loyalty UI changes by @fPolic in #12764
- feat(): Add support for jwt asymetric keys by @adrien2p in #12813
- feat: add cookie options by @riqwan in #12720
Bugs
- fix(workflow-sdk): Async/nested runAsStep propagation by @adrien2p in #12675
- fix: update product import template by @thetutlage in #12697
- fix(create-medusa-app): remove "Created admin user" message by @shahednasser in #12707
- fix(promotion, types): non discountable items check by @fPolic in #12644
- fix: remote query types by @thetutlage in #12712
- fix(core-flows): cart complete order address creation by @fPolic in #12493
- fix(utils): medusa internal service returned data should match typings by @adrien2p in #12715
- fix(utils): Typecasting non-text fields in FTS by @olivermrbl in #12729
- fix: Disable ensure database checks when establishing DB connection by @sradevski in #12734
- fix(create-medusa-app): ensure the same package manager is used consistently by @shahednasser in #12714
- fix(payment): add account holder methods to the manual provider by @fPolic in #12751
- fix(core, medusa-test-utils): Fix medusa test runner plugin modules loading by @adrien2p in #12753
- fix: Add missing partially funded event handler for Stripe by @sradevski in #12763
- fix: initiate request container before other express middleware by @thetutlage in #12761
- fix(dashboard): fix subtitle for tax inclusive fields in promotions by @shahednasser in #12776
- fix(workflow-engine-redis): Ensure PK is set without errors by @olivermrbl in #12775
- fix: add operators to RemoteQueryFilters by @peterlgh7 in #12735
- fix: Return and set the correct status when a session is created with… by @sradevski in #12769
- fix: Allow setting the status of a payment session when updating by @sradevski in #12809
- fix(workflow-engine-*): Cleanup expired executions and reduce redis storage usage by @adrien2p in #12795
- fix(medusa): Query Config update Order By filter by @juanzgc in #12781
- fix(payment): round currency precision by @carlos-r-l-rodrigues in #12803
- fix(dashboard): fix currency input locale formatting by @fPolic in #12812
- fix(utils): build query withDeleted remove auto detection by @adrien2p in #12788
- fix: Add missing migration for payment statuses by @sradevski in #12821
Documentation
- docs: add options to feedback component by @shahednasser in #12698
- docs: remove databaseSchema configuration by @shahednasser in #12699
- docs: fixes to references for draft orders and files by @shahednasser in #12693
- docs: ensure files are always sorted when generating llms-full.txt by @shahednasser in #12701
- docs: add missing export for CreateBundledProduct component by @Amar2Kk in #12704
- docs: added cloud documentation app by @shahednasser in #12711
- docs: added cloud introduction page by @shahednasser in #12716
- docs: added slack integration guide by @shahednasser in https://githu...
v2.8.4: Strengthening of cart-completion flows
Highlights
Eliminate race condition in cart-completion flow
This release strengthens the cart-completion flow by eliminating a potential race condition that, in rare cases, could result in an incorrectly refunded payment.
The race condition occurs when cart completion is triggered from two sources: 1) the regular HTTP request to POST /store/carts/:id/complete
, and 2) a webhook event from the payment provider signaling successful payment authorization.
To reduce the risk of a conflict, we have, up until now, delayed webhook processing by 5 seconds. However, this mitigation proved insufficient in some cases.
Now, whenever the completeCartWorkflow
is executed whether via the API route or the webhook handler, we now hold a lock on the cart ID for the duration of the workflow. This lock ensures that multiple completion attempts for the same cart are processed sequentially. Once a cart is successfully completed (typically on the first attempt), subsequent attempts will detect the completed cart and exit early, returning the associated order.
Features
- feat: run workflow hooks inside a when/then block by @thetutlage in #11963
- feat: introduce bulkDelete method for IFileProvider by @thetutlage in #12614
- feat(core-flows,js-sdk,medusa,types): draft order delete by @fPolic in #12172
- feat: implement stream based processing of the files by @thetutlage in #12574
Bugs
- fix: Correctly list files for all ids that are passed by @sradevski in #12575
- fix(framework): Fix compiler to create the dist after clean-up by @adrien2p in #12582
- fix: module import paths to contain unix slash by @thetutlage in #12592
- fix: expand method ALL for bodyparser config and additional validator by @thetutlage in #12612
- fix(dashboard): combobox initial item cache by @fPolic in #12522
- fix(core-flows): reservation management on order edit and draft order confirm by @fPolic in #12546
- fix(utils): move payment events to core flows events by @shahednasser in #12636
- fix(analytics): fix type of provider option by @shahednasser in #12642
- fix(core-flows): complete cart improvements by @carlos-r-l-rodrigues in #12646
Documentation
- docs: fix example in marketplace recipe by @shahednasser in #12595
- docs: add support for ignoring hooks by @shahednasser in #12599
- docs: document using env vars in plugins by @shahednasser in #12618
- docs: add setup details to contribution guidelines by @shahednasser in #12619
- docs: add missing equal sign for DATABASE_URL in env example by @Amar2Kk in #12620
- docs: phone authentication + otp guide by @shahednasser in #12544
- chore(types): fix example for createProductOptionValues in TSDocs and docs by @shahednasser in #12623
- chore(core-flows, types): change base64 comment fo files in TSDocs to binary by @shahednasser in #12627
- docs: redesign search by @shahednasser in #12628
- docs: fix loading in order reference pages by @shahednasser in #12629
- docs: added segment guide by @shahednasser in #12616
- docs: fix broken links utility + uncaught broken links by @shahednasser in #12637
- docs: redesign table of content by @shahednasser in #12647
- docs: fix log levels list by @shahednasser in #12648
- fix(docs): correct module reference in useQueryGraphStep tip by @Amar2Kk in #12654
- docs: add an example of injecting dependencies in module providers by @shahednasser in #12663
Chores
- chore(modules-sdk): Log full error when a loader fail to run by @adrien2p in #12584
- chore(core-flows): ignore hooks in complete cart workflow by @shahednasser in #12600
Other Changes
- update Chinese translation files by @leosin in #12611
- feat: add hebrew admin translation by @GuyPaikowsky in #12603
- feat(admin): Add Bahasa Indonesia language support by @Slackluky in #12657
New Contributors
- @Amar2Kk made their first contribution in #12620
- @GuyPaikowsky made their first contribution in #12603
- @Slackluky made their first contribution in #12657
Full Changelog: v2.8.3...v2.8.4