Releases: medusajs/medusa
v2.1.3
Highlights
Calculated shipping option price
This release introduces dynamically calculated shipping option prices, which comprise three key changes:
- Admin support for creating dynamically priced options
When creating a shipping option, choose the "calculated" price type. Upon sending the request to create the option, our fulfillment module verifies if the provider and method support calculated prices.
- New storefront endpoint to calculate shipping option prices
To display calculated prices on the storefront, use the endpoint below. Calculated shipping options do not include a price in the regular request to retrieve options for a cart. These are calculated separatelyβone request for each option.
POST /store/shipping-options/:id/calculate
{ cart_id: "cart_1234", data: { ... } }
Pass custom data in the data
property of the payload. The data
is passed down to the provider and can be used for the calculation, e.g. distance to destination.
Our Next.js starter has been updated to include this feature. Check it out here.
- Changes to the addShippingMethodToCartWorkflow
When adding a calculated shipping option to a cart, the price is computed dynamically similarly to the calculation endpoint.
Module DML migrations
More core modules have been migrated from MikroORM to DML. These migrations come with non-breaking schema changes, primarily around index renaming and adding default timestamp columns.
Removed orphan deletion
Additionally, we've removed the default orphanRemoval: true
configuration from one-to-one relationships. This is a less aggressive approach to cascade removal, meaning that disconnecting entities in such a relation will not delete the "child" of the association.
Required action
Run migrations to ensure your server functions as expected after upgrading:
npx medusa db:migrate
As part of migrating modules to use DML, we've uncovered a range of minor bugs (not affecting end-users) and improvements. You can read more about those in this PR.
Line items with custom prices
This release allows for custom prices on line items by decoupling variants and line items in the cart and order workflows.
Our core API doesn't support custom prices out of the box, however the underlying addToCartWorkflow
does.
Here's an example of how to use it in a custom API Route:
// POST /store/carts/:id/custom-line-items
import { addToCartWorkflow } from "@medusajs/medusa/core-flows"
async function thirdPartyCallToComputePrice(item: any) {
return {
...item,
unit_price: Math.floor(Math.random() * 900) + 100,
}
}
export const POST = async (req, res) => {
const { id } = req.params
const { items } = req.body
const query = req.scope.resolve("query")
const itemsWithDynamicPrice = await Promise.all(
items.map((item) => {
return thirdPartyCallToComputePrice(item)
})
)
const workflowInput = {
items: itemsWithDynamicPrice,
cart_id: id,
}
await addToCartWorkflow(req.scope).run({
input: workflowInput,
})
const updatedCart = await query.graph({
entity: "cart",
filters: { id },
fields: ["id", "items.*"],
})
res.status(200).json({ cart: updatedCart })
}
Nesting Admin UI Routes under existing domains
This release introduces support for nesting a UI Route under an existing domain in the sidebar instead of in the extensions section.
For example, you can locate Brands under Products:
import { defineRouteConfig } from "@medusajs/admin-sdk"
import { Container, Heading } from "@medusajs/ui"
const NestedProductsPage = () => {
return (
<Container className="divide-y p-0">
<div className="flex items-center justify-between px-6 py-4">
<Heading level="h1">Nested Products Page</Heading>
</div>
</Container>
)
}
export const config = defineRouteConfig({
label: "Nested Products",
nested: "/products",
})
export default NestedProductsPage
This improvement to our existing UI Routes tooling was a community contribution from @eugenepro2.
Features
- feat(core-flows,dashboard,js-sdk,medusa,types): support Fulfillment Options by @fPolic in #10622
- feat: Custom line items by @olivermrbl in #10408
- feat(order, types): Add Credit Line to order module by @riqwan in #10636
- feat(core-flows): pass fields variant details when creating fulfillment by @fPolic in #10665
Bugs
- fix(core-flows): export getItemTaxLinesStep by @shahednasser in #10640
- fix(medusa): Missing metadata field on order by @olivermrbl in #10651
- fix(dashboard): order details status by @fPolic in #10650
- fix(notification): Only use enabled providers for notis by @olivermrbl in #10659
- fix(core-flows): use useQueryGraphStep instead of useQueryStep by @shahednasser in #10643
- fix(core-flows): data passed to to fulfillment provider context by @fPolic in #10660
- fix(core-flows): refresh payment collections upon shipping changes by @riqwan in #10673
- fix(product): updating collections with products fix by @riqwan in #10668
- fix(core-flows): select stock locations for reservation from correct SC by @fPolic in #10661
Documentation
- docs: document float property (for v2.1.2) by @shahednasser in #10575
- docs-util: infer resolved resources in workflow + steps by @shahednasser in #10637
- docs: generate references manually for v2.1.2 by @shahednasser in #10639
- chore: fix redocly circular dependencies by @shahednasser in #10642
- docs: add tags package to generate tags by @shahednasser in #10666
- docs: support generating sidebar items with tags by @shahednasser in #10672
- docs: add tags manually to doc pages by @shahednasser in #10675
- docs: remove duplicate parsed tag items by @shahednasser in #10676
Chores
- chore(types): Keep intelisense while being more loosen by @adrien2p in #10657
- chore: improve tsdocs of fulfillment provider by @shahednasser in #10649
- chore(fulfillment, utils): Migrate module to DML by @adrien2p in #10617
Other Changes
- Add FilterableRefundReason filter by description and label by @vethan in #10606
- feat(dashboard): ability to locate new admin route under existing route by @eugenepro2 in #10587
New Contributors
- @vethan made their first contribution in #10606
- @eugenepro2 made their first contribution in #10587
Full Changelog: v2.1.2...v2.1.3
v2.1.2
Highlights
Breaking changes
The input shape of two core workflows have changed:
updateLineItemInCartWorkflow
export interface UpdateLineItemInCartWorkflowInputDTO {
+ cart_id: string
+ item_id: string
- cart: CartDTO
- item: CartLineItemDTO
update: Partial<UpdateLineItemDTO>
}
addToCartWorkflow
export interface AddToCartWorkflowInputDTO {
+ cart_id: string
- cart: CartDTO
items: CreateCartCreateLineItemDTO[]
}
Patches a regression with the Cart Module
Warning
Schema changes
In an earlier release, we migrated the data models of the Cart Module from MikroORM to our DML. As part of that migration, the tax rate
column on line item tax lines and shipping method tax lines was mistakenly changed from a numeric to an integer. This led to issues with tax rates with decimal points, as they would get rounded to the nearest integer.
In this release, we are changing the rate
column to real
(or float()
in our DML) to be consistent with how tax rates are generally represented across the codebase.
Required action
Run migrations to ensure your server functions as expected after upgrading:
npx medusa db:migrate
Features
- refactor: migration stock location module by @thetutlage in #10471
- refactor: migrate promotion module by @thetutlage in #10410
- feat(core-flows, dashboard, fulfillment, fulfillment-manual, utils, types): create shipping options with calculated prices by @fPolic in #10495
- feat: Migrate customer module to DML by @thetutlage in #10499
- feat(file-s3): Add support for IAM role authentication to file-s3 provider by @sradevski in #10528
- feat: add support for float properties by @thetutlage in #10551
- feat(medusa, core-flows, fulfillment): calculate SO price endpoint by @fPolic in #10532
- Feat/tax dml by @thetutlage in #10525
- feat(types,fulfillment): ability to delete a canceled fulfillment by @riqwan in #10602
- feat(core-flows): calculate SO price on cart ops by @fPolic in #10563
- feat(medusa,pricing): Cart pricing context with customer group by @riqwan in #10579
Bugs
- fix(product): Only apply default order to products if user has not specified one by @kasperkristensen in #10535
- fix(dashboard): Prevent fulfillment provider modal from re-rendering before form submission is complete by @kasperkristensen in #10547
- breaking: pluralization rule for the info word by @thetutlage in #10599
- fix(core-flows): use customer create workflow to reuse the emit event by @riqwan in #10601
- fix(cart): tax rate data type by @carlos-r-l-rodrigues in #10626
Documentation
- docs: documented fetchCredentials options of JS SDK by @shahednasser in #10510
- docs: added restock notification guide by @shahednasser in #10413
- docs: fix page title in reference pagesnot showing + refactor workflows reference by @shahednasser in #10537
- docs: generate references manually for 2.1.1 by @shahednasser in #10534
- docs: regenerate references for core flows by @shahednasser in #10538
- docs: document when-then name by @shahednasser in #10543
- docs: fix typo in code in module isolation documentation by @shahednasser in #10546
- docs: revise recipe examples by @shahednasser in #10545
- docs: revise architectural modules documentation by @shahednasser in #10548
- chore: fixes to tsdocs + docs-util related to providers by @shahednasser in #10555
- docs: fix bugs in API reference by @shahednasser in #10557
- Nits by @MedusaNick in #10558
- docs: fix imports in createBrandStep by @shahednasser in #10567
- docs: clarify that stripe module provider is available in application by @shahednasser in #10577
- docs: add documentation on sending requests to custom routes with JS SDK by @shahednasser in #10582
- docs: updates to contribution guidelines by @shahednasser in #10578
- docs: document many-to-many with extra columns by @shahednasser in #10586
- docs: improve examples in module link direction by @shahednasser in #10590
- docs: add section on updating medusa by @shahednasser in #10589
- docs: document alternatives for conditional operators by @shahednasser in #10588
- docs-util: support @Version tag by @shahednasser in #10591
- chore: fix docs freshness check action by @shahednasser in #10592
- docs: add pivotTable in digital product recipe by @shahednasser in #10605
- docs: add customize stripe integration in next.js guide by @shahednasser in #10583
- docs: small wording fix by @shahednasser in #10616
- docs: remove unnecessary log by @shahednasser in #10619
- docs: add stripe events to provider guide by @shahednasser in #10618
- docs: add example of Table component with pagination by @shahednasser in #10621
- docs: fix expanding of custom relations in customer and product category routes by @shahednasser in #10620
Chores
- chore(payment): Payment module DML by @carlos-r-l-rodrigues in #10553
- chore: small tsdoc update to dml float property. by @shahednasser in #10576
- chore(inventory): convert to dml by @carlos-r-l-rodrigues in #10569
Other Changes
- feat: added Ukrainian translations by @Avia-Code in #10536
New Contributors
- @Avia-Code made their first contribution in #10536
Full Changelog: v2.1.1...v2.1.2
v2.1.1
Highlights
Shipping option rules
We've introduced support for pricing rules on shipping options. Initially, the feature allows you to define prices based on the cart item total. For example, you could have a free shipping option that is only available when the item total is above 100 EUR.
Every time the cart is updated, e.g. with new items, we refresh the shipping methods to ensure the correct price is applied at all times.
You'll find the new setting in the admin dashboard under "Settings > Locations & Shipping > View details > Edit prices (on shipping option)".
New languages
Our admin dashboard has been translated into Japanese.
DML Migrations
Warning
Schema changes
We've migrated our Cart, Sales Channel, API Key, Store, Workflow Engine, and Locking modules to use our Data Model API. These migrations include minor changes to the database schema, primarily around renaming indexes to respect our autogenerated naming conventions.
Read more about each of the schema changes in the PRs below.
Changes to hasOne
As part of our DML work, the behavior of hasOne
has been updated in use cases where it is only defined on one side of the relation. In these cases, the mappedBy
configuration of the hasOne
definition needs to be set to undefined
as it is not present on the other model.
For example:
const email = model.define("email", {
email: model.text(),
isVerified: model.boolean(),
})
const user = model.define("user", {
id: model.number(),
username: model.text(),
email: model.hasOne(() => email, { mappedBy: undefined }), // <------------ Required config
})
Required actions
Run migrations to ensure your server functions as expected after upgrading to v2.1.0:
npx medusa db:migrate
Features
- feat: add support for defining hasOne with FK by @thetutlage in #10441
- refactor: migrate cart module to DML by @thetutlage in #10385
- refactor: migrate sales-channel to DML by @thetutlage in #10452
- refactor: migrate api key module to DML by @thetutlage in #10450
- feat(js-sdk): Make credentials configurable in SDK by @sradevski in #10464
- refactor: migrate store module to DML by @thetutlage in #10467
- feat(core-flows, types): update shipping methods upon cart ops by @riqwan in #10382
- feat(dashboard): SO cart item total rules UI by @kasperkristensen in #10386
Bugs
- fix(dashboard,types): Add missing Metadata form for Region domain and fix payload types by @kasperkristensen in #10449
- fix(core/js-sdk) Add the credentials field in the fetch() only if supported by @sgirones in #10446
- fix(dashboard): Cleanup unsafe accesses to possibly undefined values in order timeline by @kasperkristensen in #10454
- fix(): Deleted default sales channel should be prevented by @adrien2p in #10193
- fix(utils): DML one to one definition by @adrien2p in #10415
- fix(workflows-sdk): name for when/then step by @carlos-r-l-rodrigues in #10459
- fix(framework): add missing query type argument in request types by @shahednasser in #10456
- fix(dashboard): Prevent sending off empty string as handle for product category by @kasperkristensen in #10473
- fix(utils): avoid optional properties on graphql generated file by @carlos-r-l-rodrigues in #10476
- fix(dashboard,types): Fix TS errors by @kasperkristensen in #10457
- fix(promotion, core-flows): updating cart with removed promotion removes adjustments by @riqwan in #10489
- fix(medusa): add query type argument to RequestWithContext by @shahednasser in #10469
- fix(medusa): calculate sales channel availability correctly for variants by @srindom in #10448
Documentation
- docs: add documentation for check constraints by @shahednasser in #10425
- docs: add note about default owner table in many-to-many by @shahednasser in #10426
- docs: generate references manually by @shahednasser in #10438
- docs: revise extend create product by @shahednasser in #10444
- docs: revise query linked records by @shahednasser in #10447
- docs: fix links in extend product guide by @shahednasser in #10472
- docs-util: support new query type argument by @shahednasser in #10468
- docs: revise admin customization pages by @shahednasser in #10466
- docs: revise last chapters of customizations by @shahednasser in #10480
- docs: support detecting broken link cross-projects by @shahednasser in #10483
- docs: fix self hosting deployments not showing by @shahednasser in #10486
- docs: revise main docs outline by @shahednasser in #10502
- docs: fix links to steps in workflow references by @shahednasser in #10503
- docs-util: normalize RelationNullableModifier in model references by @shahednasser in #10505
Chores
- chore(utils): DML#hasOne allow mappedBy to not be defined by @adrien2p in #10442
- chore: locking-postgres provider dml by @carlos-r-l-rodrigues in #10478
- chore(workflow-engine): Migrate to DML by @adrien2p in #10477
Other Changes
New Contributors
Full Changelog: v2.1.0...v2.1.1
v2.1.0
Highlights
Improved order management
We've improved our order management with support for updating email, shipping address, and billing address.
New languages
Our admin dashboard has been translated into Italian.
Support for check constraint in Data Model API
We've added support for Postgres check constraints in our Data Model API.
For example:
const shippingMethod = model.define('ShippingMethod', {
amount: model.bigNumber(),
})
.checks([
(columns) => `${columns.amount} >= 0`
])
DML Migrations
Warning
Schema changes
We've migrated our Pricing, User, and Auth modules to use our Data Model API. These migrations include minor changes to the database schema:
Pricing module
- Added column
operator
toprice_rule
table (defaults toeq
) - Created index on
(operator)
inprice_rule
table - Created index on
(price_id)
inprice_rule
table - Created unique index on
(price_id, attribute, operator)
inprice_rule
table - Changed type of
max_quantity
column inprice
table from numeric to integer - Changed type of
min_quantity
column inprice
table from numeric to integer
Auth module
- Added column
deleted_at
toauth_identity
table - Added column
deleted_at
toprovider_identity
table - Created index on
(deleted_at)
inauth_identity
table - Created index on
(deleted_at)
inprovider_identity
table
User module
- Renamed unique index on
(email)
ininvite
table - Renamed unique index on
(email)
inuser
table
Required actions
Run migrations to ensure your server functions as expected after upgrading to v2.1.0:
npx medusa db:migrate
Features
- feat(pricing,utils,types): add operator field to price rule by @riqwan in #10315
- feat(pricing, types): add price rule operators to price calculations by @riqwan in #10350
- feat(core-flows,types,medusa): ability to update/create custom shipping prices by @riqwan in #10368
- feat(core-flows,framework,medusa): list shipping options pass in cart as pricing context by @riqwan in #10374
- refactor: migrate pricing entities to DML models by @thetutlage in #10335
- feature: add support for check constraints in DML by @thetutlage in #10391
- feat(core-flows,medusa,order,types): update orders by @fPolic in #10373
- feat(admin, js-sdk, types): update order forms by @fPolic in #10418
Bugs
- fix(medusa): remove request body type argument from cancel order transfer routes by @shahednasser in #10327
- fix(product): change export name of ProductImage by @shahednasser in #10326
- fix: Use the correct defaults for the invite token expiry by @sradevski in #10344
- fix: do not initialize FKs to null by @thetutlage in #10337
- fix(order): archive order status update by @fPolic in #10340
- fix: do not rely on model loading order to find an implicit owner by @thetutlage in #10360
- fix(ui,icons,ui-preset): Fix CodeBlock and Command components by @kasperkristensen in #10369
- fix: Ensure tax lines are generated for all items and shipping methods in cart by @olivermrbl in #10372
- fix(stock-location): Fix export of StockLocation module by @kasperkristensen in #10406
- fix(dashboard): Fix broken number input in adjust inventory form by @kasperkristensen in #10416
- fix(dashboard): Add default value to inventory item combobox by @kasperkristensen in #10412
- fix(dashboard): Prevent language ptBR from breaking dashboard by @kasperkristensen in #10422
- fix(framework): Ensure that CORS and Auth middleware is applied for routes only defined in middlewares.ts by @kasperkristensen in #10339
- fix(dashboard): Add Shipping Profile metadata route by @kasperkristensen in #10430
Documentation
- docs: update sanity guide + marketplace recipe to use permanentFailure by @shahednasser in #10310
- docs: update details on retrieving nested categories by @shahednasser in #10317
- docs: add note about actor_type in reset password event in v2.0.7 by @shahednasser in #10322
- docs: update many-to-many docs by @shahednasser in #10323
- docs: generate references manually by @shahednasser in #10325
- docs: revise implement brand module by @shahednasser in #10341
- docs: revised build custom features chapter by @shahednasser in #10338
- docs: revise create brand workflow by @shahednasser in #10346
- docs: changes to deployment + remove admin deployment guides by @shahednasser in #10345
- docs: document permanentFailure by @shahednasser in #10356
- docs: add note about retryInterval making workflow long-running by @shahednasser in #10355
- docs: intro + basic chapter fixes by @shahednasser in #10361
- docs: remove v2 branch of next js starter installation by @shahednasser in #10402
- docs: add missing import to db operations documentation by @shahednasser in #10390
- docs: revise brand API route by @shahednasser in #10352
- docs-util: add user, pricing, and auth as modules with DML by @shahednasser in #10423
- docs: fixes and improvements to Sanity guide by @shahednasser in #10414
Chores
- Fix(dml): DML default/nullable management by @adrien2p in #10363
- chore(utils): Ensure DML name convention follow the same as the class name for simplicity by @adrien2p in #10370
- feat(auth): Migrate auth module to DML by @adrien2p in #10387
- feat(user): Migrate user module to DML by @adrien2p in #10389
- chore(workflows-sdk): add unit test by @carlos-r-l-rodrigues in #10419
Other Changes
- German language corrections by @pixelwiese in #10394
- feat: added Italian translations by @MarcoSan19 in #10362
- Fix French translation typos by @lucienbl in #10348
New Contributors
- @MarcoSan19 made their first contribution in #10362
- @lucienbl made their first contribution in #10348
Full Changelog: v2.0.7...v2.1.0
v2.0.7
Highlights
Order transfers
You can now transfer order ownership between customers. We've added UI support in three places:
- Order details page in Medusa Admin
- Customer details page (Order list) in Medusa Admin
- Self-serve in our Next.js and B2B starters
The high-level flow is as follows:
- Initiate transfer
POST /admin/orders/:id/transfer { customer_id: string }
Send a request to generate a transfer token and emit an event with the order ID.
- Event subscriber
A subscriber picks up the event and emails the orderβs current customer with the token.
- Accept Transfer
Customer accepts the order transfer.
POST /store/orders/:id/transfer/accept { token: string }
Product Module DML migration
Warning
Breaking changes (avoidable)
The Product module now uses our DML for data model definitions instead of MikroORM. This migration introduces improvements and fixes but results in breaking changes to some relationship APIs. These can be avoided through explicit configurations.
Required actions
- Relation ownership on
manyToMany
relation
Previously, the manyToMany
API inferred the owning side of relations based on the order of loading models. If the first-loaded model used mappedBy
, it became the owner. Now, ownership is determined by examining both sides of the relation, before defaulting to the old behavior. This change might lead to unexpected behavior, and we therefore recommend explicitly defining the owner.
Explicitly define the owner using joinColumn
, inverseJoinColumn
, or pivotTable
:
const ProductVariant = model
.define("ProductVariant", {
id: model.id({ prefix: "variant" }).primaryKey(),
...
options: model.manyToMany(() => ProductOptionValue, {
pivotTable: "product_variant_option",
mappedBy: "variants",
joinColumn: "variant_id",
inverseJoinColumn: "option_value_id",
}),
})
- Pivot table naming
Aside from the relation ownership, we have also updated how pivot table names are generated.
Before
We used the model names in alphabetical order and pluralized the last one of them.
Now
We use the model's table names in alphabetical order and pluralize the last one of them.
To avoid issues with your project, explicitly set pivotTable
in manyToMany
relations to match your existing table names:
For example:
const user = model.define('User', () => {
addresses: model.manyToMany(() => Address, { pivotTable: 'address_users' })
})
New languages
Our admin dashboard has been translated into Brazilian Portuguese, French, Thai, and Spanish.
Features
- feat(dashboard): Allow setting a tooltip for disabled action items by @kasperkristensen in #10234
- feat(dashboard, js-sdk): customer page transfer order + cancel request in timeline by @fPolic in #10250
- feat: convert MikroORM entities to DML entities by @thetutlage in #10043
- feat: add ptBR (Brazilian Portuguese) in translations by @DanSilva41 in #10188
- feat: add Thai language support by @oDestroyeRo in #10249
- feat: French translation V2 by @triplecasquette in #10301
Bugs
- fix: Fix product module creation example by @sradevski in #10228
- fix: Inventory module schema by @olivermrbl in #10262
- fix(dashboard): Add Metadata form to variant page by @kasperkristensen in #10285
- fix(dashboard): Truncate long product organization tags by @kasperkristensen in #10261
- fix(core-flows): aggregate payment status by @carlos-r-l-rodrigues in #10278
- fix(dashboard): Align casing of fields in reset password event by @kasperkristensen in #10313
- fix(dashboard): adjust transfer SVG for theme by @fPolic in #10307
- fix(dashboard): Prevent product metadata form from throwing error by @kasperkristensen in #10312
- fix(utils): read dir recursive by @carlos-r-l-rodrigues in #10318
- fix(dashboard): Correct Spain provinces in country-states.ts by @anthid in #10264
Documentation
- docs: update injection zones for v2.0.5 by @shahednasser in #10225
- docs: add details on updating a cart's customer by @shahednasser in #10226
- docs: added section on medusa cloud by @shahednasser in #10265
- docs-util: fix references generator by @shahednasser in #10271
- docs-util: fix build errors by @shahednasser in #10275
- docs: fixes to Medusa Cloud sections by @shahednasser in #10270
- docs: changes for CLI tools by @shahednasser in #10284
- docs: fix link to payment session by @shahednasser in #10286
- docs: fix links in API reference workflows section by @shahednasser in #10269
- docs: revise scheduled jobs by @shahednasser in #10291
- docs: fix links in examples guide by @shahednasser in #10296
- docs: revise workflows docs by @shahednasser in #10294
- docs: fix link to medusa container by @shahednasser in #10298
- docs: revise admin customization pages by @shahednasser in #10297
- docs: clarify medusa_url in Stripe docs by @shahednasser in #10305
- docs: update list of events by @shahednasser in #10308
- docs: add resend integration guide by @shahednasser in #10268
- docs: fix database URL in railway guide by @shahednasser in #10311
- docs: fix updateProvider edit user's password example by @xqSimone in #10253
- docs: Update Redis connection string instructions for Railway by @qbitdoge in #10246
Chores
- chore: fix CI branch in test by @shahednasser in #10274
- chore(dashboard): Add missing keys to i18n translation files by @kasperkristensen #10260
New Contributors
- @DanSilva41 made their first contribution in #10188
- @xqSimone made their first contribution in #10253
- @qbitdoge made their first contribution in #10246
- @anthid made their first contribution in #10301
Full Changelog: v2.0.6...v2.0.7
v2.0.6
Highlights
Product image reordering
An issue with duplicated images on product create and update in v2.0.5 has been patched. For information about the feature, see the release notes for v2.0.5.
Bugs
- fix(product, dashboard): manual cleanup of uploaded images by @kasperkristensen in #10254
Full Changelog: v2.0.5...v2.0.6
v2.0.5
Highlights
Product image reordering
Warning
Schema changes
We have introduced support for re-ordering product images. Product images now have a rank
field. The field is set based on the index of the image in the images
payload to create and update products.
For example:
POST /admin/products
{ images: [{ url: "one" }, { url: "two" }]
Will translate to the following:
{ ..., images: [{ url: "one", rank: 0 }, { url: "two", rank: 1 }]
The same pattern is followed when updating the product.
Images are always sorted by the rank.
Schema changes
This feature comes with changes to the data models of the product module:
- The relationship between product and images has changed from a many-to-many to one-to-many. As a result, the pivot table
product_images
has been dropped rank
has been added to theimage
tableproduct_id
has been added to theimage
table
Upgrade guide
To apply the latest migrations run the following command:
npx medusa db:migrate
Cart customer transfers
We have added support for transferring carts from a guest to a registered customer.
The flow is as follows:
Create cart with guest customer
POST /store/carts
{ email: "guest@customer.com" }
Transfer cart to registered customer
POST /store/carts/:id/customer
The call to transfer assumes you are signed in and uses the customer ID from the authentication context on the request.
New languages
Our admin dashboard has been translated into German, Spaning, Turkish, and Polish
Features
- feat(core-flows): order add quantity diff by @carlos-r-l-rodrigues in #10065
- feat(product): Make product option value linkable by @adrien2p in #10116
- feat(medusa, types, utils, core-flows, order) request & accept order transfer by @fPolic in #10106
- feat: add optional fields by @thetutlage in #10150
- fix(dashboard): order edit - display item quantity change correctly by @fPolic in #10078
- feat(core-flows,medusa): Add API to update cart's customer by @riqwan in #10151
- feat(medusa): request order transfer storefront API by @fPolic in #10156
- feat(types, js-sdk): add updateCustomer to js-sdk by @riqwan in #10158
- feat: add support for making relationships searchable by @thetutlage in #10172
- feat(workflows-sdk): add response to permanent failure by @carlos-r-l-rodrigues in #10177
- feat(medusa): skip draft orders on order list by @riqwan in #10195
- feat(core-flows,medusa): remove cart customer validation + rename workflow by @riqwan in #10207
- feat(dashboard): transfer order admin by @fPolic in #10189
- feat(medusa,core-flows,types,js-sdk): decline / cancel order transfer by @fPolic in #10202
- feat(product,dashboard): Allow re-ordering images by @kasperkristensen in #10187
Bugs
- fix(orchestration): fix set step failure by @carlos-r-l-rodrigues in #10031
- fix(core-flows): capture before order created by @carlos-r-l-rodrigues in #9980
- fix: do not update the .env.template file with the database name by @thetutlage in #10073
- fix(core-flows): Fix date usage accross workflows by @adrien2p in #10100
- fix(admin-shared,dashboard): Add missing injection zones by @kasperkristensen in #10098
- fix(dashboard): Fix active nav link styling for built-in routes by @kasperkristensen in #10082
- fix(dashboard): Add missing inventory list zones by @kasperkristensen in #10117
- fix(dashboard): Add Breadcrumb components by @kasperkristensen in #10079
- fix(product): wrong snapshot name and inexistent script by @adrien2p in #10119
- fix(inventory): update reservation quantity by @carlos-r-l-rodrigues in #10139
- fix(payment): Idempotent cancellation and proper creationg fail handling by @adrien2p in #10135
- fix: add address and customer metadata to tax calc context by @srindom in #10122
- fix(core-flows): Add missing cart sales channel id fields to be part of the application context by @adrien2p in #10142
- fix(product): Update full descendant tree mpath when updating parent category id by @adrien2p in #10144
- fix(dashboard): updated variant title is used when creating product by @riqwan in #10155
- fix(framework,types): correct example of database driver options by @riqwan in #10166
- fix: Remove undefined from events in update by @olivermrbl in #10170
- fix(types): fix AdminBatchProductRequest to have product ID by @shahednasser in #10168
- fix: incorrect changeset breaks preview builds by @riqwan in #10173
- fix: move transfer cart under cart by @riqwan in #10175
- fix(framework): handle deprecated Dirent path by @carlos-r-l-rodrigues in #10179
- feat(medusa): enable price list prices for product endpoints by @riqwan in #10197
- fix: Update js-sdk with token by @olivermrbl in #10211
- fix(types): Graph types fixes by @adrien2p in #10220
- fix(js-sdk): Preserve
path
inbaseUrl
by @kasperkristensen in #10222 - fix(admin-vite-plugin): Move @babel/types to dependencies from devDependencies to make it compatible with Yarn PnP by @kasperkristensen in #10236
Documentation
- Fix grammar issue in the doc by @webgodo in #10064
- Fix Typo in Documentation by @hadicph in #9989
- docs: fix slugs pointing to admin rather than store routes by @shahednasser in #10063
- docs: remove duplicate buttons in code actions by @shahednasser in #10061
- docs: add documentation on validateAndTransformQuery by @shahednasser in #10060
- docs: fix error to medusa configuration guide by @shahednasser in #10059
- docs: update event module guide by @shahednasser in #10056
- docs: document multiple steps usage in a workflow by @shahednasser in #10053
- docs: change useRemoteQueryStep to useQueryGraphStep by @shahednasser in #10051
- docs-util: fix helper step settings by @shahednasser in #10045
- docs: added note about test timeout by @shahednasser in #10041
- docs: fix outdated links by @shahednasser in #10040
- docs: add emit events + types documentation by @shahednasser in #10026
- docs: fix types of injection zone props by @shahednasser in #10074
- docs: added + updated build and deployment guides by @shahednasser in #10019
- docs: update to next 15 + eslint 9 by @shahednasser in #9839
- docs: fix oneOf design hiding more than three items by @shahednasser in #10077
- docs-utils: make reference table of content in alphabetical order by @shahednasser in #10084
- docs: improv version detection + fix breadcrumbs by @shahednasser in #10083
- docs: add missing import in digital product recipe by @shahednasser in #10094
- docs: fix client error for learning path by @shahednasser in #10102
- docs: add guide on how to translate admin by @shahednasser in #10095
- docs: update admin injection zones list by @shahednasser in #10103
- docs: add note about using dates in workflows by @shahednasser in #10107
- docs: document nested UI routes by @shahednasser in #10104
- docs: fix copy in code blocks with tabs by @shahednasser in #10123
- docs: add missing prerequisite in stripe's storefront integration by @shahednasser in #10097
- docs: S3 p...
v2.0.4
Highlights
Improved pluralization of MedusaService
types
Warning
Breaking change: If you have created data models using the uncountable nouns and special rules below, you might be affected.
We've updated the type helper used to generate types for the methods of the MedusaService
. It now has two conditional checks when converting a singular value to a plural value at the types level.
- First, it checks for uncountable nouns in a dictionary.
- Second, it looks for special rules for certain words like tooth, man, etc.
You can find the reference of uncountable nouns and special rules here.
Bugs
- breaking: pluralize type helper to account for uncountable nouns and special rules by @thetutlage in #10011
- fix(types): Add AdminBatchUpdateProductVariant type by @kasperkristensen in #10009
- fix(medusa, types): filter product by external_id by @fPolic in #10010
- fix(dashboard): handle deleted products/variants in the order domain by @fPolic in #9841
- fix(dashboard): Load product variant edit page and fix product detail query key by @kasperkristensen in #10029
Documentation
- docs: improve transform docs by @shahednasser in #10023
- docs: fix link to testing tools by @shahednasser in #10030
- docs: improve getting started chapters by @shahednasser in #10014
- docs: fix cart completion in subscriptions recipe by @shahednasser in #10021
Chores
- chore(medusa): show success message after user is created by @shahednasser in #10027
Other Changes
- docs: add changeset for #10011 by @thetutlage in #10018
Full Changelog: v2.0.3...v2.0.4
v2.0.3
Highlights
Replaced email
with sub
for Google entity ID
The Google authentication provider incorrectly used the email as the entity_id,
which is an issue in case a Google account has multiple emails attached to it. This release fixes that and switches the usage to the sub
field as a globally unique identifier.
If you have been using the Google authentication provider, the easiest way to migrate existing data is to hot patch @medusajs/auth-google
using https://www.npmjs.com/package/patch-package so that when validating the callback, both the email
and sub
fields are used to retrieve the user, but only the sub
is written.
See this PR for more.
Patched security issue
This release contains an important security fix for the email-password authentication provider. Please update your project as soon as possible.
The security issue was found in the password reset flow when using the email-password authentication provider. By obtaining a password reset token, it was possible to update the provider_metadata
of other usersβ provider identities by including a specific payload in the password reset request. To minimize risk to affected users, we will not disclose the structure of the payload.
Bugs
- fix: Use sub instead of email for google entity ID by @sradevski in #9949
- fix: commands to run from within the
.medusa/server
directory by @thetutlage in #9941 - fix(dashboard): user invite search by @fPolic in #9973
- fix(core-flows): pass metadata on order fulfillment create by @fPolic in #9974
- fix(framework): exclude nested fields when excluding requested field by @carlos-r-l-rodrigues in #9979
- fix(link-modules): generate graphql type of read only links by @carlos-r-l-rodrigues in #9955
- fix: define ssl options when specified in the connection string by @thetutlage in #9992
- fix(dashboard): Reduce data loaded by product details page by @kasperkristensen in #9991
- fix(core-flows): keep same customer on cart update by @carlos-r-l-rodrigues in #9977
Documentation
- docs: add common redirects to v1 docs by @shahednasser in #9832
- docs: fix resolve of custom file module guide by @shahednasser in #9840
- docs: remove upgrade guides doc by @shahednasser in #9845
- docs: add instructions on how to roll back a migration by @shahednasser in #9870
- docs: add more context and description to recipe steps by @shahednasser in #9861
- docs: fix server worker mode in railway deployment by @shahednasser in #9842
Chores
- chore: remove husky by @thetutlage in #9967
- chore: Add new i18n validation workflows for the admin by @adrien2p in #9948
- chore: update doc links in README by @shahednasser in #9860
Other Changes
- feat(stripe): add promptpay by @oDestroyeRo in #9789
New Contributors
- @oDestroyeRo made their first contribution in #9789
Full Changelog: v2.0.2...v2.0.3
v2.0.2
This version fixes a range of bugs reported in the 2.0.0 release.
Highlights
Fixed mismatch with tax rate rule override
We identified a mismatch between how tax rate rule overrides were referenced in the dashboard and in the tax engine. When created through the dashboard, the overrides were created with an attribute key in plural form, but our tax engine expects them to be in the singular form.
For example, if you defined a tax rate rule override for a Product Collection, the dashboard would pass product_collections
upon creating the override while the tax engine would look for product_collection
.
Additionally, we fixed an issue with missing product type IDs on cart and order line items, which would mean tax calculations were not performed for product types.
These bugs were fixed in #9796 and #9951
Required actions
- Re-create your tax rate rule overrides
- Run migrations
npx medusa db:migrate
Features
- chore(dashboard): Setup test and script for validating i18n by @kasperkristensen in #9799
- refactor: move to a form based bug report template by @thetutlage in #9930
Bugs
- fix(dashboard): Allow float values for product prices by @kasperkristensen in #9859
- fix(core-flows, dashboard): adjust stock levels when doing partial fulfilments by @fPolic in #9736
- fix(dashboard): tax override reference by @fPolic in #9796
- fix: consider --host flag and HOST env variable by @thetutlage in #9912
- fix: disable admin when running integration tests by @thetutlage in #9915
- fix(dashboard): truncate price cell titles by @fPolic in #9715
- fix(utils): Mikro orm repository update many to many should detach all items by default by @adrien2p in #9917
- fix(workflows-sdk): Paralellize steps rollback issue with config by @adrien2p in #9921
- fix(dashboard): Allow using enter key to create newline in Textarea by @kasperkristensen in #9913
- fix(types): Prev limit wrong values by @adrien2p in #9935
- fix(utils/dml): set-relationship graphql generator from DML wrong managed belongsTo by @adrien2p in #9932
- fix(telemetry): Pointing and resolving packages wrongly by @adrien2p in #9939
- fix: Support relative path in SDK by @sradevski in #9942
- fix(medusa): POST carts/[id]/complete missing early return by @SGFGOV in #9914
- fix: Default to a relative path for the admin backend URL by @sradevski in #9947
- fix: log cause property from the error by @thetutlage in #9944
- fix(core-flows,medusa): Include region_id in shipping option retrieval by @olivermrbl in #9929
- fix: do not set default host to localhost by @thetutlage in #9957
- fix(types): add
display_id
toOrderDTO
by @fPolic in #9953
Documentation
- docs: added documentation on environment variables by @shahednasser in #9798
- docs : Update page.mdx referring by @Ratnadeep2k in #9820
- docs: add a note in 404 page about v1 docs by @shahednasser in #9815
- fix(docs): small error by @0xflotus in #9868
- docs: small improvement to first customization guide by @shahednasser in #9843
Chores
- chore(js-sdk,types): add tsdocs for admin JS SDK methods [4/n] by @shahednasser in #9745
- chore: Sync PR and Discussions to Linear by @olivermrbl in #9938
- chore: Use PR author name by @olivermrbl in #9940
- chore(locking): disable default provider warning by @carlos-r-l-rodrigues in #9956
New Contributors
- @Ratnadeep2k made their first contribution in #9820
- @eltociear made their first contribution in #9818
Full Changelog: v2.0.1...v2.0.2